home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / cpm / zcpr2 / compare.mqc / COMPARE.MAC
Text File  |  1985-02-09  |  13KB  |  592 lines

  1. ;  PROGRAM:  COMPARE
  2. ;  AUTHOR:  Richard Conn
  3. ;  VERSION:  1.4
  4. ;  DATE:  6 JAN 83
  5. ;  PREVIOUS VERSIONS:  1.3 (19 DEC 82)
  6. ;  PREVIOUS VERSIONS:  1.2 (8 DEC 82), 1.1 (21 JULY 82), 1.0 (11 JULY 82)
  7. VERS    EQU    14
  8.  
  9. ;
  10. ;    This program is Copyright (c) 1982, 1983 by Richard Conn
  11. ;    All Rights Reserved
  12. ;
  13. ;    ZCPR2 and its utilities, including this one, are released
  14. ; to the public domain.  Anyone who wishes to USE them may do so with
  15. ; no strings attached.  The author assumes no responsibility or
  16. ; liability for the use of ZCPR2 and its utilities.
  17. ;
  18. ;    The author, Richard Conn, has sole rights to this program.
  19. ; ZCPR2 and its utilities may not be sold without the express,
  20. ; written permission of the author.
  21. ;
  22.  
  23.  
  24. ;
  25. ;    COMPARE is designed to provide the user with a convenient method
  26. ; to compare the contents of two files.  It is invoked by one of two basic
  27. ; forms:
  28. ;
  29. ;        COMPARE filename.typ
  30. ; or
  31. ;        COMPARE file1.typ file2.typ
  32. ;
  33. ;    The first form compares the file named "filename.typ" on drive A:
  34. ; to the file of the same name on drive B:; the second form compares the
  35. ; file named "file1.typ" on drive A: to the file named "file2.typ" on drive
  36. ; B:.
  37. ;
  38.  
  39. ;  CP/M Constants
  40. CPM    equ    0    ; CP/M Warm Boot
  41. BUFF    equ    CPM+80H    ; Temporary Buffer
  42. CR    equ    0DH
  43. LF    equ    0AH
  44.  
  45. ;  CRC ROUTINES
  46.     EXT    CRCCLR,CRCUPD,CRCDONE
  47.  
  48. ;  SYSLIB ROUTINES
  49.     EXT    COMPHD,BDOS,INITFCB,LOGUD,RETUD
  50.     EXT    F$OPEN,F$CLOSE,F$READ
  51.     EXT    CAPS,CIN,COUT,CRLF
  52.     EXT    PADC,MOVEB,PRINT
  53.     EXT    ZGPINS,ZFNAME
  54.  
  55. ;
  56. ;  Branch to Start of Program
  57. ;
  58.     JMP    START
  59.  
  60. ;
  61. ;******************************************************************
  62. ;
  63. ;  SINSFORM -- ZCPR2 Utility Standard General Purpose Initialization Format
  64. ;
  65. ;    This data block precisely defines the data format for
  66. ; initial features of a ZCPR2 system which are required for proper
  67. ; initialization of the ZCPR2-Specific Routines in SYSLIB.
  68. ;
  69.  
  70. ;
  71. ;  EXTERNAL PATH DATA
  72. ;
  73. EPAVAIL:
  74.     DB    0FFH    ; IS EXTERNAL PATH AVAILABLE? (0=NO, 0FFH=YES)
  75. EPADR:
  76.     DW    40H    ; ADDRESS OF EXTERNAL PATH IF AVAILABLE
  77.  
  78. ;
  79. ;  INTERNAL PATH DATA
  80. ;
  81. INTPATH:
  82.     DB    0,0    ; DISK, USER FOR FIRST PATH ELEMENT
  83.             ; DISK = 1 FOR A, '$' FOR CURRENT
  84.             ; USER = NUMBER, '$' FOR CURRENT
  85.     DB    0,0
  86.     DB    0,0
  87.     DB    0,0
  88.     DB    0,0
  89.     DB    0,0
  90.     DB    0,0
  91.     DB    0,0    ; DISK, USER FOR 8TH PATH ELEMENT
  92.     DB    0    ; END OF PATH
  93.  
  94. ;
  95. ;  MULTIPLE COMMAND LINE BUFFER DATA
  96. ;
  97. MCAVAIL:
  98.     DB    0FFH    ; IS MULTIPLE COMMAND LINE BUFFER AVAILABLE?
  99. MCADR:
  100.     DW    0FF00H    ; ADDRESS OF MULTIPLE COMMAND LINE BUFFER IF AVAILABLE
  101.  
  102. ;
  103. ;  DISK/USER LIMITS
  104. ;
  105. MDISK:
  106.     DB    4    ; MAXIMUM NUMBER OF DISKS
  107. MUSER:
  108.     DB    31    ; MAXIMUM USER NUMBER
  109.  
  110. ;
  111. ;  FLAGS TO PERMIT LOG IN FOR DIFFERENT USER AREA OR DISK
  112. ;
  113. DOK:
  114.     DB    0FFH    ; ALLOW DISK CHANGE? (0=NO, 0FFH=YES)
  115. UOK:
  116.     DB    0FFH    ; ALLOW USER CHANGE? (0=NO, 0FFH=YES)
  117.  
  118. ;
  119. ;  PRIVILEGED USER DATA
  120. ;
  121. PUSER:
  122.     DB    10    ; BEGINNING OF PRIVILEGED USER AREAS
  123. PPASS:
  124.     DB    'chdir',0    ; PASSWORD FOR MOVING INTO PRIV USER AREAS
  125.     DS    41-($-PPASS)    ; 40 CHARS MAX IN BUFFER + 1 for ending NULL
  126.  
  127. ;
  128. ;  CURRENT USER/DISK INDICATOR
  129. ;
  130. CINDIC:
  131.     DB    '$'    ; USUAL VALUE (FOR PATH EXPRESSIONS)
  132.  
  133. ;
  134. ;  DMA ADDRESS FOR DISK TRANSFERS
  135. ;
  136. DMADR:
  137.     DW    80H    ; TBUFF AREA
  138.  
  139. ;
  140. ;  NAMED DIRECTORY INFORMATION
  141. ;
  142. NDRADR:
  143.     DW    00000H    ; ADDRESS OF MEMORY-RESIDENT NAMED DIRECTORY
  144. NDNAMES:
  145.     DB    64    ; MAX NUMBER OF DIRECTORY NAMES
  146. DNFILE:
  147.     DB    'NAMES   '    ; NAME OF DISK NAME FILE
  148.     DB    'DIR'        ; TYPE OF DISK NAME FILE
  149.  
  150. ;
  151. ;  REQUIREMENTS FLAGS
  152. ;
  153. EPREQD:
  154.     DB    0FFH    ; EXTERNAL PATH?
  155. MCREQD:
  156.     DB    0FFH    ; MULTIPLE COMMAND LINE?
  157. MXREQD:
  158.     DB    0FFH    ; MAX USER/DISK?
  159. UDREQD:
  160.     DB    0FFH    ; ALLOW USER/DISK CHANGE?
  161. PUREQD:
  162.     DB    000H    ; PRIVILEGED USER?
  163. CDREQD:
  164.     DB    0FFH    ; CURRENT INDIC AND DMA?
  165. NDREQD:
  166.     DB    0FFH    ; NAMED DIRECTORIES?
  167. Z2CLASS:
  168.     DB    0    ; CLASS 0
  169.     DB    'ZCPR2'
  170.     DS    10    ; RESERVED
  171.  
  172. ;
  173. ;  END OF SINSFORM -- STANDARD DEFAULT PARAMETER DATA
  174. ;
  175. ;******************************************************************
  176. ;
  177.  
  178. ;
  179. ;  Start of Program
  180. ;
  181. START:
  182.     CALL    ZGPINS    ; INIT ZCPR2 BUFFERS
  183.     XRA    A    ; SET NO MULTIPLE RUN
  184.     STA    MULT
  185.     CALL    RETUD    ; GET CURRENT USER/DISK
  186.     MOV    A,B    ; SAVE DISK
  187.     STA    CDISK
  188.     MOV    A,C    ; SAVE USER
  189.     STA    CUSER
  190.     LXI    H,BUFF    ; PROCESS OPTIONS IN BUFFER
  191.     MOV    A,M    ; GET CHAR COUNT
  192.     INX    H    ; PT TO FIRST CHAR
  193.     PUSH    H    ; SAVE PTR TO FIRST CHAR
  194.     ADD    L    ; HL=HL+A
  195.     MOV    L,A
  196.     MOV    A,H
  197.     ACI    0
  198.     MOV    H,A
  199.     MVI    M,0    ; STORE ENDING ZERO
  200.     POP    H    ; GET PTR TO FIRST CHAR
  201.     LXI    D,INLINE    ; PT TO INPUT LINE BUFFER
  202.     PUSH    D    ; SAVE PTR
  203. START0:
  204.     MOV    A,M    ; COPY INPUT LINE SO BUFF MAY BE USED
  205.     STAX    D    ; PUT BYTE
  206.     INX    H    ; PT TO NEXT
  207.     INX    D
  208.     ORA    A    ; EOL?
  209.     JNZ    START0
  210.     POP    H    ; PT TO FIRST CHAR
  211.     CALL    SBLANK    ; SKIP SPACES
  212.     ORA    A    ; EOL?
  213.     JZ    PRHELP    ; PRINT HELP IF SO
  214.     CPI    '/'    ; ASKING FOR HELP?
  215.     JZ    PRHELP
  216.     LXI    D,FCBS    ; PT TO SOURCE FCB
  217.     CALL    ZFNAME    ; EXTRACT NAME AND DIRECTORY DATA
  218.     JNZ    START1
  219. UDERR:
  220.     CALL    PRINT
  221.     DB    CR,LF,'Invalid Disk or User -- Aborting',0
  222.     RET
  223. START1:
  224.     MOV    A,B    ; SAVE SOURCE DISK
  225.     CPI    0FFH    ; CHECK FOR CURRENT
  226.     JNZ    SDISK1
  227.     LDA    CDISK    ; SPECIFY CURRENT DISK INSTEAD
  228.     INR    A    ; ADD 1 FOR FOLLOWING DECREMENT
  229. SDISK1:
  230.     DCR    A    ; DOWN 1 SO RANGE IS 0-F
  231.     STA    SDISK
  232.     MOV    A,C    ; SAVE SOURCE USER
  233.     CPI    0FFH    ; CHECK FOR CURRENT
  234.     JZ    SUSER0
  235.     CPI    '?'    ; WILD IS CURRENT
  236.     JNZ    SUSER1
  237. SUSER0:
  238.     LDA    CUSER    ; GET CURRENT USER
  239. SUSER1:
  240.     STA    SUSER
  241.     MOV    A,M    ; GET SEPARATION CHAR
  242.     CPI    ','    ; COMMA IF SECOND NAME SPECIFIED
  243.     JZ    START2
  244.     PUSH    H    ; SAVE PTR
  245.     LXI    H,FCBS+1    ; NO 2ND NAME, SO SET IT TO SAME AS FIRST
  246.     LXI    D,FCBD+1
  247.     MVI    B,11    ; 11 BYTES
  248.     CALL    MOVEB
  249.     LDA    CDISK    ; SET DISK AND USER TO CURRENT
  250.     STA    DDISK
  251.     LDA    CUSER
  252.     STA    DUSER
  253.     POP    H    ; GET PTR
  254.     JMP    START3
  255. START2:
  256.     INX    H    ; PT TO NEXT CHAR AFTER COMMA
  257.     LXI    D,FCBD    ; SET DEST FCB
  258.     CALL    ZFNAME    ; PROCESS NAME
  259.     JZ    UDERR
  260.     LDA    FCBD+1    ; CHECK FOR AMBIGUOUS NAME
  261.     CPI    '?'    ; ASSUME ALL IS AMBIGUOUS IF FIRST CHAR IS
  262.     JNZ    NOSET
  263.     PUSH    H    ; SAVE PTR
  264.     PUSH    B    ; SAVE USER/DISK
  265.     LXI    H,FCBS+1    ; SET NAMES THE SAME
  266.     LXI    D,FCBD+1    ; COPY SOURCE TO DEST
  267.     MVI    B,11    ; 11 BYTES
  268.     CALL    MOVEB
  269.     POP    B    ; RESTORE BC
  270.     POP    H    ; RESTORE PTR
  271. NOSET:
  272.     MOV    A,B    ; GET DISK
  273.     CPI    0FFH
  274.     JNZ    DDISK1
  275.     LDA    CDISK    ; SELECT CURRENT DISK IF DEFAULT
  276.     INR    A    ; ADD 1 FOR FOLLOWING DECREMENT
  277. DDISK1:
  278.     DCR    A
  279.     STA    DDISK
  280.     MOV    A,C    ; GET USER
  281.     CPI    0FFH    ; CURRENT?
  282.     JZ    DUSER0
  283.     CPI    '?'    ; WILD IS CURRENT
  284.     JNZ    DUSER1
  285. DUSER0:
  286.     LDA    CUSER
  287. DUSER1:
  288.     STA    DUSER    ; SET DEST USER
  289. START3:
  290.     CALL    SBLANK    ; SKIP SPACES
  291.     CPI    'M'    ; MULTIPLE OPTION?
  292.     JNZ    START4
  293.     MVI    A,0FFH    ; SET FLAG
  294.     STA    MULT
  295. START4:
  296.     LXI    H,FCBS    ; SET UP SOURCE FCB
  297.     CALL    QCHECK    ; NO AMBIGUOUS ENTRIES PERMITTED
  298.     LXI    H,FCBD    ; SET UP DESTINATION FCB
  299.     CALL    QCHECK    ; NO AMBIGUOUS ENTRIES PERMITTED
  300. MLOOP:
  301.     CALL    BANNER    ; PRINT BANNER
  302.     LDA    MULT    ; MULTIPLE RUNS?
  303.     ORA    A    ; 0=NO
  304.     JZ    MLOOP1
  305.     CALL    PRS1    ; PRINT SOURCE FILE 1
  306.     CALL    PRS2    ; PRINT SOURCE FILE 2
  307.     CALL    PRINT
  308.     DB    CR,LF,'  Change Disks if Desired and Type ^C or A to Abort or '
  309.     DB    '<RETURN> to Continue - ',0
  310.     CALL    CIN    ; GET RESPONSE
  311.     CALL    CAPS    ; CAPITALIZE
  312.     CPI    3    ; ABORT?
  313.     RZ
  314.     CPI    'A'    ; ABORT?
  315.     RZ
  316.     MVI    C,13    ; RESET DISKS
  317.     CALL    BDOS
  318. MLOOP1:
  319.     CALL    VERIFY    ; PERFORM VERIFICATION
  320.     CALL    CRLF    ; NEW LINE
  321.     LDA    MULT    ; MULTIPLE RUNS?
  322.     ORA    A    ; 0=NO
  323.     JNZ    MLOOP    ; CONTINUE IF SO
  324.     RET
  325.  
  326. ;
  327. ;  SKIP TO NON-BLANK CHAR
  328. ;
  329. SBLANK:
  330.     MOV    A,M    ; GET CHAR
  331.     INX    H    ; PT TO NEXT
  332.     CPI    ' '    ; BLANK?
  333.     JZ    SBLANK
  334.     DCX    H    ; PT TO NON-BLANK
  335.     RET
  336.  
  337. ;
  338. ;  PRINT HELP MESSAGE
  339. ;
  340. PRHELP:
  341.     CALL    BANNER    ; PRINT BANNER
  342.     CALL    PRINT
  343.     DB    CR,LF
  344.     DB    CR,LF,'COMPARE is used to quickly compare two files for '
  345.     DB    'equality'
  346.     DB    CR,LF
  347.     DB    CR,LF,'COMPARE is invoked by a command like:'
  348.     DB    CR,LF,'    COMPARE dir:file1.typ,dir:file2.typ M'
  349.     DB    CR,LF,'where:'
  350.     DB    CR,LF,'   "file1.typ" must be specified and is unambiguous'
  351.     DB    CR,LF,'   "dir:" is an optional named directory (or DU:)'
  352.     DB    CR,LF,'   "file2.typ" is optional and set equal to '
  353.     DB    '"file1.typ" if omitted'
  354.     DB    CR,LF,'   "M" is optional and allows Multiple Runs if given'
  355.     DB    CR,LF
  356.     DB    CR,LF,'Examples:'
  357.     DB    CR,LF,'Command                  Files Compared'
  358.     DB    CR,LF,'COMPARE T.COM,A1:        $$:T.COM, A1:T.COM'
  359.     DB    CR,LF,'COMPARE A:T.COM          A$:T.COM, $$:T.COM'
  360.     DB    CR,LF,'COMPARE A:T.COM,ROOT:    A$:T.COM, ROOT:T.COM'
  361.     DB    CR,LF,'COMPARE A:T.COM,B:S.COM  A$:T.COM, B$:S.COM'
  362.     DB    0
  363.     RET
  364.  
  365. ;
  366. ;  CHECK FOR ANY QUESTION MARKS FROM HL+1 TO HL+11
  367. ;  AFFECT ONLY AF REGISTERS IF OK
  368. ;
  369. QCHECK:
  370.     PUSH    H    ; SAVE HL
  371.     PUSH    B    ; SAVE BC
  372.     INX    H    ; PT TO FIRST CHAR
  373.     MVI    B,11    ; 11 BYTES
  374.     MVI    C,'?'    ; SCAN FOR '?'
  375. QC:
  376.     MOV    A,M    ; GET BYTE
  377.     CMP    C    ; '?'?
  378.     JZ    QC1
  379.     INX    H    ; PT TO NEXT
  380.     DCR    B    ; COUNT DOWN
  381.     JNZ    QC
  382.     POP    B    ; RESTORE
  383.     POP    H
  384.     RET
  385. QC1:
  386.     POP    B    ; RESTORE AND ABORT
  387.     POP    H
  388.     POP    D    ; CLEAR RETURN ADDRESS
  389.     XCHG        ; FCB PTR IN DE
  390.     CALL    BANNER    ; PRINT BANNER
  391.     CALL    CRLF
  392.     CALL    PRFN    ; PRINT FILE NAME
  393.     CALL    PRINT
  394.     DB    '  Ambiguous File Name not Allowed',CR,LF,0
  395.     RET
  396.  
  397. ;
  398. ;  PRINT BANNER
  399. ;
  400. BANNER:
  401.     CALL    PRINT
  402.     DB    'COMPARE  Version '
  403.     DB    VERS/10+'0','.',(VERS MOD 10)+'0'
  404.     DB    0
  405.     RET
  406.  
  407. ;
  408. ;  PRINT NAMES OF SOURCE FILES
  409. ;    PRS1 -- SOURCE FILE 1
  410. ;    PRS2 -- SOURCE FILE 2
  411. ;
  412. PRS1:
  413.     CALL    PRINT
  414.     DB    CR,LF,'Source File 1 -- ',0
  415.     LXI    H,SDISK    ; PT TO FIRST BYTE
  416.     CALL    PRUD
  417.     LXI    D,FCBS    ; COMPUTE CRC FOR SOURCE FCB
  418.     JMP    PRFN    ; PRINT FILE NAME
  419. PRS2:
  420.     CALL    PRINT
  421.     DB    CR,LF,'Source File 2 -- ',0
  422.     LXI    H,DDISK    ; PT TO FIRST BYTE
  423.     CALL    PRUD
  424.     LXI    D,FCBD    ; COMPUTE CRC FOR DESTINATION FCB
  425.     JMP    PRFN    ; PRINT FILE NAME
  426.  
  427. ;
  428. ;  MAIN VERIFY ROUTINE
  429. ;
  430. VERIFY:
  431.     CALL    PRS1    ; PRINT SOURCE 1
  432.     LDA    SDISK    ; SELECT DISK AND USER
  433.     MOV    B,A
  434.     LDA    SUSER
  435.     MOV    C,A
  436.     CALL    LOGUD    ; LOG IN DISK AND USER IN B,C
  437.     CALL    CRCCLR    ; CLEAR CRC
  438.     CALL    COMPCRC    ; READ IN FILE
  439.     CALL    CRCDONE    ; GET CRCK VALUE
  440.     SHLD    CRCVAL    ; SAVE IT
  441.     LDA    BCNT    ; GET OLD BLOCK COUNT
  442.     STA    BCNT1    ; SAVE IT
  443.     CALL    PRS2    ; PRINT NAME OF SOURCE 2
  444.     LDA    DDISK    ; SELECT DISK AND USER
  445.     MOV    B,A
  446.     LDA    DUSER
  447.     MOV    C,A
  448.     CALL    LOGUD    ; LOG IN DISK AND USER IN B,C
  449.     CALL    CRCCLR    ; CLEAR CRC
  450.     CALL    COMPCRC    ; READ IN FILE
  451.     LDA    BCNT    ; GET BLOCK COUNT
  452.     MOV    B,A    ; RESULT IN B
  453.     LDA    BCNT1    ; CHECK FOR SAME SIZE
  454.     CMP    B    ; COMPARE BLOCK SIZES
  455.     JNZ    NOMATCH    ; NO MATCH IF NOT SAME
  456.     LHLD    CRCVAL    ; GET OLD CRC VALUE
  457.     XCHG        ; VALUE IN DE
  458.     CALL    CRCDONE    ; UPDATE COMPLETE
  459.     CALL    COMPHD    ; COMPARE HL TO DE
  460.     JNZ    NOMATCH
  461.     CALL    PRINT
  462.     DB    CR,LF,'** Files are Identical **',0
  463.     RET
  464.  
  465. ;  VERIFY ERROR
  466. NOMATCH:
  467.     CALL    PRINT
  468.     DB    CR,LF,'** Files are Different **',0
  469.     RET
  470.  
  471. ;
  472. ;  READ IN FILE AND COMPUTE ITS CRC; DE PTS TO FILE'S FCB
  473. ;
  474. COMPCRC:
  475.     CALL    CRCCLR    ; CLEAR CRCK VALUE
  476.     CALL    INITFCB    ; INIT FCB FIELDS
  477.     CALL    F$OPEN    ; OPEN FILE
  478.     CPI    0FFH    ; FILE NOT FOUND?
  479.     JNZ    LOAD    ; LOAD DATA AND COMPUTE CRCVAL AND BCNT
  480.     POP    H    ; CLEAR 2 LEVELS OF RETURN ADDRESS
  481.     POP    H
  482.     CALL    CRLF
  483.     CALL    PRFN    ; PRINT FILE NAME
  484.     CALL    PRINT
  485.     DB    '  File Not Found',CR,LF,0
  486.     RET
  487.  
  488. ;
  489. ;  LOAD BUFFER FROM FILE WHOSE FCB IS PTED TO BY DE
  490. ;    ON OUTPUT, BCNT=NUMBER OF BLOCKS LOADED (UP TO 128) AND
  491. ;    CONT=0 IF DONE OR 128 IF NOT DONE
  492. ;
  493. LOAD:
  494.     XRA    A    ; A=0
  495.     STA    BCNT    ; SET BLOCK COUNT
  496.  
  497. ;  MAIN CRC EVALUATION LOOP
  498. LOAD1:
  499.     CALL    F$READ    ; READ IN BLOCK
  500.     ORA    A    ; END OF FILE?
  501.     JNZ    LOAD3    ; RETURN
  502.     LXI    H,BUFF    ; PT TO BUFFER TO COMPUTE CRC FROM
  503.     MVI    B,128    ; COPY 128 BYTES
  504. LOAD2:
  505.     MOV    A,M    ; GET BYTE
  506.     CALL    CRCUPD    ; UPDATE CRC
  507.     INX    H    ; PT TO NEXT
  508.     DCR    B    ; COUNT DOWN
  509.     JNZ    LOAD2
  510.     LDA    BCNT    ; GET BLOCK COUNT
  511.     INR    A    ; INCREMENT IT
  512.     STA    BCNT    ; SET IT
  513.     JMP    LOAD1    ; CONTINUE
  514. LOAD3:
  515.     CALL    F$CLOSE    ; CLOSE FILE
  516.     RET
  517.  
  518. ;
  519. ;  PRINT DISK/USER PTED TO BY HL (2 BYTES)
  520. ;
  521. PRUD:
  522.     MOV    A,M    ; GET DISK
  523.     ADI    'A'    ; CONVERT TO LETTER
  524.     CALL    COUT
  525.     INX    H    ; PT TO USER
  526.     MOV    A,M    ; GET USER
  527.     CALL    PADC    ; PRINT AS DEC
  528.     CALL    PRINT
  529.     DB    ': ',0
  530.     RET
  531.  
  532. ;
  533. ;  PRINT FILE NAME WHOSE FCB IS PTED TO BY DE
  534. ;
  535. PRFN:
  536.     PUSH    H    ; SAVE REGS
  537.     PUSH    D
  538.     PUSH    B
  539.     XCHG        ; FN PTED TO BY HL
  540.     INX    H    ; PT TO FIRST CHAR
  541.     MVI    B,8    ; 8 CHARS
  542.     CALL    PRFN1
  543.     MVI    A,'.'
  544.     CALL    COUT
  545.     MVI    B,3    ; 3 CHARS FOR FILE TYPE
  546.     CALL    PRFN1
  547.     POP    B    ; RESTORE REGS
  548.     POP    D
  549.     POP    H
  550.     RET
  551. PRFN1:
  552.     MOV    A,M    ; GET CHAR
  553.     INX    H    ; PT TO NEXT
  554.     CALL    COUT    ; PRINT
  555.     DCR    B    ; COUNT DOWN
  556.     JNZ    PRFN1
  557.     RET
  558.  
  559. ;
  560. ;  BUFFERS
  561. ;
  562. MULT:
  563.     DS    1    ; MULTIPLE RUN FLAG (0=NO MULT RUNS)
  564. CDISK:
  565.     DS    1    ; CURRENT DISK
  566. CUSER:
  567.     DS    1    ; CURRENT USER
  568. SDISK:
  569.     DS    1    ; SOURCE DISK (MUST BE FOLLOWED BY SUSER)
  570. SUSER:
  571.     DS    1    ; SOURCE USER
  572. FCBS:
  573.     DS    36    ; SOURCE FCB
  574. DDISK:
  575.     DS    1    ; DEST DISK (MUST BE FOLLOWED BY DUSER)
  576. DUSER:
  577.     DS    1    ; DEST USER
  578. FCBD:
  579.     DS    36    ; DESTINATION FCB
  580. CRCVAL:
  581.     DS    2    ; CRC VALUE
  582. CURDISK:
  583.     DS    1    ; CURRENT DISK NUMBER
  584. BCNT:
  585.     DS    1    ; BUFFER COUNT
  586. BCNT1:
  587.     DS    1    ; SECOND BUFFER COUNT
  588. INLINE:
  589.     DS    200    ; INPUT LINE BUFFER
  590.  
  591.     END
  592.