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

  1.  
  2. ;    TITLE    'ENTAB - REPLACE SPACES WITH TABS V1.5 '
  3. ;
  4. ; A SOFTWARE TOOL AS DESCRIBED BY KERNIGAN AND PLAUGHER
  5. ; WHICH COMPRESSES SPACES INTO APPROPRIATE TABS AS PER
  6. ; CP/M CONVENTIONS. IT IS USEFUL FOR COMPACTING A PROGRAM
  7. ; AFTER A MODEM TRANSFER WHICH EXPANDS THE TABS.
  8. ;
  9. ;
  10. ; REVISION HISTORY
  11. ;
  12. ;10/10/81.
  13. ;
  14. ; ADDED EQU FOR MODIFIED CP/M AND QUOTE AS DEFAULT DELIM. T. SHAPIN
  15. ;
  16. ; 9/5/81
  17. ;    1.    REWROTE    COMPRESSION ROUTINE TO WORK PROPERLY
  18. ;
  19. ;    2.    ADDED FEATURE TO DISABLE COMPRESSION INSIDE
  20. ;        QUOTED STRINGS,    SINCE SOME LANGUAGES AND
  21. ;        ASSEMBLERS DON'T LIKE TABS IN THEIR STRINGS.
  22. ;        FOR EXAMPLE,  AN ASSEMBLY FILE MAY HAVE    A LINE:
  23. ;
  24. ;            PASSWORD:    DB    '        '
  25. ;
  26. ;        IS THAT    THE SAME THING AS THIS LINE?
  27. ;
  28. ;            PASSWORD:    DB    09H
  29. ;
  30. ;        MOST DEFINITELY    NOT, BUT THAT IS WHAT WE WOULD
  31. ;        GET IF ENTAB COMPRESSED    THOSE BLANKS INTO 1 TAB
  32. ;        CHARACTER.   ENTAB WILL    PROMPT FOR THE STRING
  33. ;        FIELD DELIMITING CHARACTER EACH    TIME IT    IS RUN
  34. ;        (NORMALLY ' FOR ASSEMBLERS, AND " FOR BASICS).
  35. ;
  36. ;    3.    MODIFIED OUTPUT    FILE CODE TO SAVE THE ORIGINAL
  37. ;        FILE AS    A "BAK"    FILE IF    THE OUTPUT FILE    IS GOING
  38. ;        TO THE SAME DRIVE AS THE INPUT FILE.  IF THE
  39. ;        OUTPUT FILE IS GOING TO    A DIFFERENT DRIVE, THEN
  40. ;        THE ORIGINAL FILE WILL BE LEFT UNCHANGED.
  41. ;        PREVIOUSLY, THE    ORIGINAL FILE WAS ALWAYS ERASED.
  42. ;
  43. BIAS    EQU    0H       ; 0 FOR STANDARD CP/M, 4200H FOR MODIFIED
  44. BDOS    EQU    5+BIAS    ;CPM ENTRY
  45. FCB    EQU    5CH+BIAS ;DEFAULT FCB
  46. ;
  47. PRINT    EQU    9
  48. BUFFIN    EQU    10
  49. OPEN    EQU    15
  50. CLOSE    EQU    16
  51. DELETE    EQU    19
  52. READ    EQU    20
  53. WRITE    EQU    21
  54. CREATE    EQU    22
  55. RENAME    EQU    23
  56. SETDMA    EQU    26
  57.  
  58. BLANK    EQU    ' '
  59. TAB    EQU    9
  60. CR    EQU    0DH
  61. LF    EQU    0AH
  62. EOF    EQU    1AH        ;CONTROL Z
  63. DOLLAR    EQU    '$'
  64. ;
  65. REC    EQU    16        ;NUMBER    OF SECTORS PER TRANSFER
  66. ;
  67.     ORG    100H+BIAS
  68.     LXI    H,0        ;SET UP    OUR OWN    STACK
  69.     DAD    SP        ;SAVE THEIRS
  70.     SHLD    STACK
  71.     LXI    SP,STACK
  72. ;
  73.     LXI    D,SGNMSG    ;TELL THE FOLKS    OUR NAME
  74.     MVI    C,PRINT
  75.     CALL    BDOS
  76.     JMP    GETFCB
  77. ;
  78. SGNMSG:    DB    CR,LF,'ENTAB - VERS 1.5 - 10/9/81',CR,LF,LF,'$'
  79. ;
  80. GETFCB:    LXI    H,FCB        ;GET THE TYPED IN FILE NAME
  81.     LXI    D,FCB1
  82.     MVI    C,16
  83.     CALL    MOVE        ;AND MOVE IT TO    OUR OWN
  84.     LXI    H,FCB
  85.     LXI    D,FCB2
  86.     MVI    C,16
  87.     CALL    MOVE        ;AND AGAIN
  88. ;
  89.     LXI    D,FCB1
  90.     MVI    C,OPEN
  91.     CALL    BDOS        ;OPEN IT
  92.     INR    A
  93.     JNZ    FILSEC        ;NO ERROR
  94.     LXI    D,FNFMSG    ;'FILE NOT FOUND'
  95.     MVI    C,PRINT
  96.     CALL    BDOS
  97.     JMP    EXIT
  98. ;
  99. FNFMSG:    DB    'File Not Found',CR,LF,DOLLAR
  100. ;
  101. FILSEC:    LXI    H,FCB2+9    ;SEC NAME
  102.     MVI    M,DOLLAR    ;MAKE IT '.$$$'
  103.     INX    H
  104.     MVI    M,DOLLAR
  105.     INX    H
  106.     MVI    M,DOLLAR
  107.     LDA    FCB+16        ;IF USER ENTERS    A DESTINATION
  108.     ORA    A        ;.. DRIVE CODE ...
  109.     JNZ    DEFALT
  110.     LDA    FCB1
  111. DEFALT:    STA    FCB2        ;.. STASH IT IN    OUTPUT FILE FCB
  112. ;
  113. DEL:    MVI    A,0        ;MAKE NEXT RECORD 0
  114.     STA    FCB1+32
  115.     STA    FCB2+32
  116.     LXI    D,FCB2        ;DELETE    ANY EXISTING TEMPORARY FILES
  117.     MVI    C,DELETE
  118.     CALL    BDOS
  119. ;
  120.     LXI    D,FCB2
  121.     MVI    C,CREATE
  122.     CALL    BDOS        ;NOW CREATE TEMPORARY OUTPUT FILE
  123.     INR    A
  124.     JNZ    GTDEL        ;FILE CREATED
  125.     LXI    D,DSKMSG    ;'NO DIRECTORY SPACE'
  126.     MVI    C,PRINT
  127.     CALL    BDOS
  128.     JMP    EXIT        ;CAN'T KEEP GOING
  129. ;
  130. PROMPT:    DB    'Enter the String Delimiter (CR='') ? $'
  131. BEGMSG:    DB    CR,LF,'Beginning Blanks Compression',CR,LF,'$'
  132. ;
  133. GTDEL:    LXI    D,PROMPT    ;ASK FOR DELIMITER CHARACTER
  134.     MVI    C,PRINT
  135.     CALL    BDOS
  136. ;
  137. ;WE INPUT THE DELIMITER    CHARACTER BY USING THE BUFFER INPUT
  138. ;ROUTINE TO ALLOW THE USER TO CORRECT AN INPUT ERROR, OR TO
  139. ;ABORT TO CP/M.     A SINGLE CONIN    CALL, ALTHOUGH REQUIRING LESS
  140. ;CODE, WOULD NOT ALLOW ANY MARGIN FOR ERROR IN SPECIFYING THE
  141. ;DELIMITER CHARACTER.
  142. ;
  143.     LXI    D,CIBUF        ;SETUP CONSOLE INPUT BUFFER
  144.     MVI    A,2
  145.     STAX    D        ;ALLOW 2 CHARACTERS MAXIMUM
  146.     MVI    C,BUFFIN    ;GET THE DELIMITER CHARACTER
  147.     CALL    BDOS
  148.     LDA    CIBUF+1        ;HOW MANY CHARACTERS ENTERED?
  149.     ORA    A
  150.     MVI    A,''''        ;DEFAULT TO QUOTE
  151.     JZ    SAVDEL        ;USE DELIMITER OF 0 IF NO INPUT
  152.     LDA    CIBUF+2        ;ELSE, EXTRACT 1ST CHARACTER
  153. SAVDEL:    STA    DELIM+1        ;SAVE IT IN-LINE FOR COMPARISON
  154.  
  155.     LXI    D,BEGMSG    ;TELL USER WE'VE BEGUN
  156.     MVI    C,PRINT
  157.     CALL    BDOS
  158. ;
  159. ;BEGIN SCANNING    INPUT BUFFER AND PACK THE SPACES INTO TABS
  160. ;
  161. ENTAB:    XRA    A
  162.     STA    COLUMN        ;INITIALIZE TAB    POSITION
  163.     STA    BLANKS        ;CLEAR BLANK ACCUMULATOR
  164.     STA    SFLG        ;CLEAR STRING FLAG
  165. NEXCHR:    CALL    GETC        ;GET NEXT CHARACTER FROM FILE
  166.     STA    CHAR        ;SAVE INPUT CHARACTER
  167.     CPI    TAB
  168.     JNZ    NOTAB
  169.     CALL    DUMBLK        ;ON TAB, DUMP PENDING BLANKS
  170. TABIT:    MVI    A,TAB        ;PASS THE TAB ALONG
  171.     CALL    PUTC
  172.     XRA    A
  173.     STA    COLUMN        ;CLEAR TAB POSITION
  174.     JMP    NEXCHR        ;GET THE NEXT CHARACTER
  175. ;
  176. NOTAB:    CPI    LF        ;END OF    LINE MARKERS?
  177.     JZ    EOL
  178.     CPI    CR
  179.     JNZ    NOEOL
  180. EOL:    CALL    DUMBLK        ;DUMP TRAILING BLANKS IF SO
  181.     LDA    CHAR        ;THEN DUMP THE CR OR LF
  182.     CALL    PUTC
  183.     JMP    ENTAB        ;AND START NEXT    LINE
  184. ;
  185. NOEOL:    CPI    BLANK        ;SPACE CHARACTER?
  186.     JNZ    NOBLK
  187.     LXI    H,BLANKS    ;INCREMENT BLANK COUNTER
  188.     INR    M
  189.     LDA    SFLG        ;ARE WE    IN A QUOTED STRING?
  190.     ORA    A
  191.     JNZ    STRING        ;BLANK NOT SIGNIFICANT IF SO
  192.     CALL    BUMCOL        ;BUMP TAB POSITION
  193.     JNZ    NEXCHR        ;CONTINUE SCANNING IF NOT AT TAB STOP
  194.     STA    BLANKS        ;OTHERWISE, CLEAR BLANKS COUNTER
  195.     JMP    TABIT        ;PUT TAB INTO OUTPUT FILE
  196. ;
  197. STRING:    CALL    BUMCOL        ;INSIDE    QUOTED STRING, BUMP TAB    POSITION
  198.     JMP    NEXCHR        ;CONTINUE SCANNING TIL END OF STRING
  199. ;
  200. NOBLK:    CPI    EOF        ;CP/M FILE EOF?
  201.     JZ    EOFILE
  202.     CPI    0FFH        ;GETBUF    EOF?
  203.     JZ    EOFILE
  204.     CALL    DUMBLK        ;CHARACTER NONE    OF ABOVE - FLUSH BLANKS
  205.     CALL    BUMCOL        ;BUMP TAB POSITION
  206.     LDA    CHAR
  207.     PUSH    PSW
  208.     CALL    PUTC        ;SEND LITERAL CHARACTER
  209.     POP    PSW
  210. DELIM:    CPI    0        ;IS CHARACTER STRING DELIMITER?
  211.     JNZ    NEXCHR
  212.     LDA    SFLG        ;TOGGLE    STRING FLAG IF SO
  213.     CMA
  214.     STA    SFLG
  215.     JMP    NEXCHR        ;SCAN FOR NEXT CHARACTER
  216. ;
  217. DUMBLK:    LDA    BLANKS        ;FLUSH THE ACCUMULATED BLANKS
  218.     ORA    A
  219.     RZ
  220.     DCR    A
  221.     STA    BLANKS
  222.     MVI    A,' '
  223.     CALL    PUTC
  224.     JMP    DUMBLK
  225. ;
  226. BUMCOL:    LDA    COLUMN        ;INCREMENT TAB POSITION
  227.     INR    A
  228.     ANI    7
  229.     STA    COLUMN
  230.     RET
  231. ;
  232. EOFILE:    CALL    PUTC        ;OUTPUT    EOF CHARACTER
  233.     CALL    PUTBUF        ;WRITE UNFINISHED BUFFER
  234.     LXI    D,FCB2
  235.     MVI    C,CLOSE
  236.     CALL    BDOS        ;CLOSE THE NEW FILE
  237. ;
  238.     LDA    FCB2        ;GET DESTINATION DR CODE TO INPUT FCB
  239.     STA    FCB1
  240.     LXI    H,FCB1        ;SETUP RENAME FCB FOR ORIGINAL FILENAME
  241.     LXI    D,FCB1+16
  242.     PUSH    D        ;SAVE POINTER TO 2ND RENAME FIELD
  243.     PUSH    D
  244.     MVI    C,9
  245.     CALL    MOVE        ;MOVE FILENAME TO 2ND RENAME FIELD
  246.     XCHG
  247.     MVI    M,'B'        ;MAKE 2ND RENAME FILETYPE="BAK"
  248.     INX    H
  249.     MVI    M,'A'
  250.     INX    H
  251.     MVI    M,'K'
  252.     POP    D        ;RECALL    POINTER    TO 2ND RENAME FIELD
  253.     MVI    C,DELETE    ;ERASE ANY EXISTING BAK    FILE ON    OUTPUT DRIVE
  254.     CALL    BDOS
  255.     POP    H        ;RECALL    RENAME FIELD POINTER AGAIN
  256.     MVI    M,0        ;CLEAR DR IN 2ND RENAME    FIELD
  257. ;
  258.     LXI    D,FCB1        ;RENAME    ANY FILE ON OUTPUT DRIVE WITH INPUT
  259.     MVI    C,RENAME    ;..FILENAME TO TYPE "BAK"
  260.     CALL    BDOS
  261. ;
  262. KEEPIT:    LXI    H,FCB1+1    ;MOVE THE NEW FILE NAME
  263.     LXI    D,FCB2+16    ;TO FCB2
  264.     XRA    A
  265.     STAX    D
  266.     INX    D
  267.     MVI    C,11
  268.     CALL    MOVE
  269. ;
  270.     LXI    D,FCB2
  271.     MVI    C,RENAME
  272.     CALL    BDOS        ;RENAME    .$$$ TO    ORIGINAL
  273. ;
  274.     LXI    D,DNMSG        ;TELL THEM WE'RE DONE
  275.     MVI    C,PRINT
  276.     CALL    BDOS
  277.     JMP    EXIT
  278. ;
  279. DNMSG:    DB    'Blanks Compression Completed',CR,LF,DOLLAR
  280. ;
  281. EXIT:    LXI    D,80H+BIAS    ;RESET DEFAULT DMA
  282.     MVI    C,SETDMA
  283.     CALL    BDOS
  284. ;
  285.     LHLD    STACK
  286.     SPHL
  287.     RET            ;BACK TO CP/M
  288. ;
  289. ;
  290. ; MOVE -MOVE (HL -> (DE) FOR C BYTES
  291. ;
  292. MOVE:    MOV    A,M
  293.     STAX    D
  294.     INX    H
  295.     INX    D
  296.     DCR    C
  297.     JNZ    MOVE
  298.     RET
  299. ;
  300. ;
  301. GETC:    LHLD    CICNT        ;ANY CHAR IN BUFFER?
  302.     MOV    A,H
  303.     ORA    L
  304.     CZ    GETBUF        ;GET SOME IF NOT
  305.     LHLD    CIPNT        ;POINTER TO CHAR
  306.     MOV    A,M        ;GET THE CHARACTER
  307.     INX    H        ;INCREMENT THE POINTER
  308.     SHLD    CIPNT
  309.     LHLD    CICNT        ;REDUCE    THE COUNT
  310.     DCX    H
  311.     SHLD    CICNT
  312.     RET
  313.  
  314. ;
  315. GETBUF:    MVI    A,REC        ;RECORDS PER BUFFER
  316.     LXI    H,0
  317.     SHLD    CICNT        ;INIT FO READ
  318.     LXI    H,CIBUF
  319.     SHLD    CIPNT        ;INIT THE POINTER
  320. GBUF:    SHLD    DMAADD        ;IPDATE    DMA ADDRESS
  321.     XCHG            ;FOR BDOS CALL
  322.     STA    SECCNT        ;UPDATE    SECTORS    TO GO
  323.     ORA    A
  324.     RZ            ;RETURN    IF NONE
  325.     MVI    C,SETDMA
  326.     CALL    BDOS        ;SET LOAD ADDRESS
  327.     LXI    D,FCB1
  328.     MVI    C,READ
  329.     CALL    BDOS        ;GET A SECTOR
  330.     PUSH    PSW        ;SAVE DISK STATUS
  331.     LHLD    CICNT
  332.     LXI    D,128        ;# OF BYTES READ
  333.     DAD    D
  334.     SHLD    CICNT        ;UPDATE    IT
  335.     LHLD    DMAADD        ;UPDATE    POINTER
  336.     POP    PSW        ;GET DISK STATUS
  337.     ORA    A
  338.     JZ    ROK        ;READ WAS OK
  339.     MVI    M,0FFH        ;OUR OWN END OF    FILE
  340.     RET
  341.  
  342. ROK:    DAD    D        ;THIS TO
  343.     LDA    SECCNT
  344.     DCR    A        ;ONE LESS LEFT
  345.     JMP    GBUF
  346. ;
  347. PUTC:    LHLD    COPNT        ;POINTER
  348.     MOV    M,A        ;PUT CHAR IN BUFFER
  349.     INX    H
  350.     SHLD    COPNT        ;INCREMENT POINTER
  351.     LHLD    COCNT
  352.     INX    H        ;BUMP IT
  353.     SHLD    COCNT
  354.     MOV    A,H        ;SEE IF    END OF BUFFER
  355.     CPI    REC*128/256
  356.     CZ    PUTBUF
  357.     RET
  358. ;
  359. PUTBUF:    LHLD    COCNT        ;# OF CHAR IN BUFFER
  360.     SHLD    TEMP
  361.     LXI    H,0
  362.     SHLD    COCNT        ;REINIT    FOR NEXT TIME
  363.     LXI    H,COBUF
  364.     SHLD    COPNT        ;REINIT    FOR NEXT TIME
  365. PBUF:    SHLD    DMAADD        ;UPDATE    WRITE ADDRESS
  366.     XCHG            ;TO DE FOR CPM CALL
  367.     LHLD    TEMP        ;ANY LEFT TO WRITE
  368.     MOV    A,L
  369.     ORA    H
  370.     RZ            ;IF NOT
  371.     MVI    C,SETDMA
  372.     CALL    BDOS
  373.     LXI    D,FCB2        ;WRITE FILE BLOCK
  374.     MVI    C,WRITE
  375.     CALL    BDOS
  376.     ORA    A        ;CHECK FOR ERROR
  377.     JNZ    WRERR        ;.AND TAKE CARE    OF IT
  378.     LHLD    TEMP        ;BYTE COUNT
  379.     LXI    D,-128        ;PER SECTOR
  380.     DAD    D        ;THIS MANY LEFT
  381.     SHLD    TEMP
  382.     MOV    A,H        ;GET SIGN BIT
  383.     ORA    A        ;TEST IT
  384.     RM            ;ALL DATA WRITTEN (NOT A FULL BUFFER)
  385.     LHLD    DMAADD        ;UPDATE    BUFFER
  386.     LXI    D,128
  387.     DAD    D
  388.     JMP    PBUF
  389. ;
  390. WRERR:    LXI    D,DSKMSG    ;'WRITE ERROR'
  391.     MVI    C,PRINT
  392.     CALL    BDOS
  393.     JMP    EXIT        ;THIS WILL FIX STACK
  394. ;
  395. DSKMSG:    DB    'Disk or Directory Full',CR,LF,DOLLAR
  396. ;
  397.     DS    48        ;SOME STACK SPACE
  398. STACK:    DW    0
  399. COLUMN:    DB    0
  400. BLANKS:    DB    0
  401. SFLG:    DB    0
  402. CHAR:    DB    0        ;INPUT CHAR
  403. SECCNT:    DB    0        ;SECTORS TO READ
  404. CICNT:    DW    0
  405. COCNT:    DW    0
  406. TEMP:    DW    0
  407. DMAADD:    DW    0
  408. FCB1:    DS    33
  409. FCB2:    DS    33
  410. CIPNT:    DW    CIBUF
  411. COPNT:    DW    COBUF
  412. CIBUF:    DS    128*REC
  413. COBUF:    DS    128*REC
  414.     END
  415. @