home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / sigm / vol279 / comp.asm < prev    next >
Encoding:
Assembly Source File  |  1986-06-11  |  12.8 KB  |  796 lines

  1. ;    THIS PROGRAM COMPARES THE CONTENTS OF TWO FILES, BYTE BY BYTE
  2. ;
  3. ;    USAGE:    COMP -n FILE1 FILE2
  4. ;        -n is optional, limits output to n lines
  5. ;
  6. ;    BY JON DART, DEPT. OF ANTHROPOLGY, UCSD C-001, LA JOLLA, CA 92093
  7. ;
  8. ;    VERSION 1.5: 15-MAR-85
  9. ;    VERSION 1.4: 19-JAN-85
  10. ;    VERSION 1.3: 15-JAN-85
  11. ;    VERSION 1.2: 03-JAN-85
  12. ;    VERSION 1.1: 12-JUN-84
  13. ;    MODIFIED FROM HDOS FOR CP/M: 06-APR-84
  14.  
  15. ;    CP/M SYSTEM DEFINITIONS:
  16.  
  17. BOOT    EQU    0
  18. BDOS    EQU    0005H
  19. DEFFCB    EQU    005CH
  20. DEFBUF    EQU    0080H
  21. FCBSIZ    EQU    36
  22. SECSIZ    EQU    128
  23. R0    EQU    33
  24. R2    EQU    35
  25.  
  26. LSTOUT    EQU    5
  27. DCIO    EQU    6
  28. CONIN    EQU    1
  29. CONOUT    EQU    2
  30. PRTSTR    EQU    09H
  31. CONSTAT EQU    0BH
  32. VERS    EQU    0CH
  33. SYSRES    EQU    0DH
  34. SELDSK    EQU    0EH
  35. FOPEN    EQU    0FH
  36. FCLOSE    EQU    10H
  37. SFF    EQU    11H
  38. SFN    EQU    12H
  39. FDELET    EQU    13H
  40. FMAKE    EQU    16H
  41. RCD    EQU    19H
  42. SETDMA    EQU    1AH
  43. GROV    EQU    1DH
  44. SFA    EQU    1EH
  45. GADP    EQU    1FH
  46. USRCODE EQU    20H
  47. RDRAND    EQU    21H
  48. WRRAND    EQU    22H
  49. CFS    EQU    23H
  50.  
  51. ;    ASCII CHARACTERS:
  52.  
  53. CTRL$C    EQU    3
  54. LF    EQU    0AH
  55. TAB    EQU    09H
  56. CR    EQU    0DH
  57. SPACE    EQU    20H
  58.  
  59.     ORG    100H
  60.  
  61. COMP    EQU    $
  62.     LXI    H,0
  63.     DAD    SP
  64.     SHLD    OLDSTK        ;SAVE OLD STACK POINTER
  65.     LXI    SP,STACK
  66.     LXI    D,SIGNON
  67.     MVI    C,PRTSTR
  68.     CALL    BDOS
  69.     CALL    CRLF
  70.     MVI    C,VERS
  71.     CALL    BDOS
  72.     MOV    A,L
  73.     CPI    20H
  74.     JNC    VERSOK        ;IF NOT CP/M 2.2
  75.     LXI    D,MSG0
  76.     MVI    C,PRTSTR
  77.     CALL    BDOS
  78.     JMP    EXIT2
  79. VERSOK: LXI    H,FCB1
  80.     MVI    B,FCBSIZ
  81.     CALL    ZERO        ;ZERO FCB1
  82.     LXI    H,FCB2
  83.     MVI    B,FCBSIZ
  84.     CALL    ZERO        ;AND FCB2
  85.     LXI    H,DEFBUF    ;GET BYTE COUNT FOR COMMAND LINE
  86.     MOV    A,M
  87.     ANA    A
  88.     JZ    NONAME        ;IF NO NAME
  89.     PUSH    H
  90.     MOV    E,M
  91.     MVI    D,0
  92.     DAD    D
  93.     INX    H
  94.     MVI    M,0        ;PUT 0 BYTE AT END OF COMMAND LINE
  95.     POP    H
  96.     INX    H
  97.     CALL    SKIPS        ;SKIP SPACES
  98.     JC    NONAME        ;IF END OF LINE
  99.     CPI    '-'
  100.     JNZ    NONUM        ;IF NO NUMBER SPECIFIED
  101.     INX    H
  102.     MVI    C,0
  103.     PUSH    H
  104. CD:    MOV    A,M        ;HAVE NUMBER, COUNT NUMBER OF DIGITS
  105.     CPI    '0'
  106.     JC    NODGT
  107.     CPI    '9'+1
  108.     JNC    NODGT
  109.     INX    H
  110.     INR    C
  111.     JMP    CD
  112. NODGT:    SHLD    NUMEND        ;SAVE ADDRESS AFTER NUMBER
  113.     POP    H
  114.     CALL    DTOBIN        ;CONVERT NUMBER TO BINARY
  115.     JC    NONAME        ;IF ERROR
  116.     XCHG
  117.     INX    H
  118.     SHLD    NUMLIN        ;STORE AS # LINES
  119.     LHLD    NUMEND        ;POINT TO 1 PAST NUMBER
  120.     CALL    SKIPS
  121. NONUM:    LXI    D,FCB1
  122.     CALL    PACK        ;MOVE NAME INTO FCB
  123.     CALL    SKIPS        ;SKIP SPACES
  124.     JC    NONAME
  125.     LXI    D,FCB2
  126.     CALL    PACK        ;MOVE 2ND NAME INTO FCB
  127.     JMP    NAMEOK
  128. NONAME: LXI    D,MSG1
  129.     MVI    C,PRTSTR
  130.     CALL    BDOS
  131.     JMP    EXIT2
  132. NAMEOK: LXI    D,FCB1
  133.     MVI    C,FOPEN
  134.     PUSH    D
  135.     CALL    BDOS        ;TRY TO OPEN 1ST FILE
  136.     POP    D
  137.     CPI    0FFH
  138.     JZ    BADOPN        ;IF CAN'T OPEN
  139.     LXI    D,FCB2
  140.     MVI    C,FOPEN
  141.     PUSH    D
  142.     CALL    BDOS        ;TRY TO OPEN 2ND FILE
  143.     POP    D
  144.     CPI    0FFH
  145.     JNZ    OPENOK        ;IF CAN'T OPEN
  146. BADOPN: XCHG
  147.     LXI    D,FILNAM
  148.     CALL    FCOPY        ;COPY FILE NAME INTO MESSAGE
  149.     LXI    D,MSG2
  150.     MVI    C,PRTSTR
  151.     CALL    BDOS        ;PRINT MESSAGE
  152.     JMP    EXIT
  153.  
  154. SKIPS1: INX    H
  155. SKIPS:    MOV    A,M
  156.     ANA    A
  157.     STC
  158.     RZ
  159.     CPI    SPACE
  160.     JZ    SKIPS1
  161.     CPI    TAB
  162.     JZ    SKIPS1
  163.     ANA    A
  164.     RET
  165.  
  166. ;    PACK - TRANSLATE FILE NAME ON COMMAND LINE INTO FCB FORMAT
  167. ;    ENTRY: (HL) POINTS TO FILE NAME
  168. ;           (DE) POINTS TO FCB
  169. ;
  170. PACK:    INX    H
  171.     MOV    A,M
  172.     CPI    ':'
  173.     DCX    H
  174.     JZ    HAVED        ;IF DRIVE SPECIFIED
  175.     XRA    A
  176.     STAX    D        ;ELSE PUT 0 IN 1ST BYTE
  177.     JMP    PACK2
  178. HAVED:    MOV    A,M
  179.     SUI    'A'-1
  180.     STAX    D
  181.     INX    H
  182.     INX    H
  183. PACK2:    INX    D
  184.     PUSH    H
  185.     PUSH    D
  186.     XCHG
  187.     MVI    B,11
  188.     MVI    A,SPACE
  189.     CALL    FILL        ;FILL NAME FIELD WITH SPACES
  190.     POP    D
  191.     POP    H
  192.     MVI    C,8
  193. PACK3:    MOV    A,M        ;COPY NAME
  194.     ANA    A
  195.     RZ
  196.     CPI    SPACE
  197.     RZ
  198.     INX    H
  199.     CPI    '.'
  200.     JZ    PACK4
  201.     STAX    D
  202.     INX    D
  203.     DCR    C
  204.     JNZ    PACK3
  205.     MOV    A,M                        ;15-MAR-85
  206.     ANA    A                        ;15-MAR-85
  207.     RZ                            ;15-MAR-85
  208.     INX    H        ;FIXES BUG            ;15-MAR-85
  209.     JMP    PACK5
  210. PACK4:    XCHG
  211.     MOV    B,C
  212.     MVI    A,SPACE
  213.     CALL    FILL
  214.     XCHG
  215. PACK5:    MVI    C,3        ;COPY EXTENSION
  216. PACK6:    MOV    A,M
  217.     ANA    A
  218.     RZ
  219.     CPI    SPACE
  220.     RZ
  221.     STAX    D
  222.     INX    H
  223.     INX    D
  224.     DCR    C
  225.     JNZ    PACK6
  226.     RET
  227.  
  228. ZERO:    XRA    A
  229. FILL:    MOV    M,A
  230.     INX    H
  231.     DCR    B
  232.     JNZ    FILL
  233.     RET 
  234.  
  235. OPENOK    EQU    $
  236.     LHLD    OLDSTK        ;GET START OF CCP
  237.     MOV    E,M
  238.     INX    H
  239.     MOV    D,M
  240.     XCHG
  241.     LXI    D,-10        ;SUBTRACT SLOP FACTOR
  242.     DAD    D
  243.     SHLD    TOPMEM        ;SAVE ADDRESS
  244.     LXI    H,ENDDATA+1    ;PUT 1ST BUFFER
  245.     SHLD    BUF1        ;DIRECTLY ABOVE PROGRAM.
  246.     XCHG
  247.     LHLD    TOPMEM
  248.     CALL    SUBHLDE        ;SUBTRACT FROM TOP OF MEMORY
  249.     DCR    H        ;-1 FOR SAFETY
  250.     MOV    A,H
  251.     ANI    0FEH        ;MAKE EVEN
  252.     STA    BUFSIZ        ;STORE # CP/M SECTORS IN EACH BUFFER
  253.     RRC            ;DIVIDE BY 2
  254.     MOV    H,A
  255.     MVI    L,0
  256.     XCHG
  257.     LHLD    BUF1
  258.     DAD    D        ;COMPUTE ADDRESS OF 2ND FILE BUFFER
  259.     SHLD    BUF2        ;SAVE IT
  260.  
  261. ;    HAVE OPENED BOTH FILES, NOW DO COMPARISON:
  262.  
  263.     LXI    H,0
  264.     SHLD    BLKNUM
  265.     SHLD    SEC1
  266.     SHLD    SEC2        ;ZERO SECTOR COUNTS
  267.     XRA    A
  268.     STA    EOF1        ;CLEAR END OF FILE FLAGS
  269.     STA    EOF2
  270.     STA    DIFF        ;AND DIFFERENCE FLAG
  271.     CALL    CRLF        ;WRITE CR/LF
  272.  
  273. RDLOOP: LDA    EOF1
  274.     LXI    H,EOF2
  275.     ORA    M        ;IF END OF FILE ON EITHER CHANNEL,
  276.     JNZ    DONE        ;DONE
  277.  
  278.     CALL    READ1        ;READ 1ST FILE INTO BUFFER
  279.     CALL    READ2        ;READ 2ND FILE INTO BUFFER
  280.  
  281. COMPARE: LHLD     BUF2
  282.     XCHG            ;(DE) POINTS TO 2ND BUFFER
  283.     LHLD    BUF1        ;(HL) POINTS TO 1ST BUFFER
  284.  
  285. CMPLUP: PUSH    H
  286.     LXI    H,SZTOCMP    ;GET SECTOR COUNT TO COMPARE
  287.     MOV    A,M
  288.     DCR    M        ;COUNT <-- COUNT -1
  289.     ANA    A
  290.     POP    H
  291.     JZ    RDLOOP        ;IF DONE W. BUFFERS, SEE IF MORE TO READ
  292.     CALL    CMPSEC        ;COMPARE A SECTOR (128 BYTES)
  293.     PUSH    H
  294.     LHLD    BLKNUM
  295.     INX    H        ;BUMP BLOCK COUNT
  296.     SHLD    BLKNUM
  297.     POP    H
  298.     JMP    CMPLUP        ;LOOP
  299.  
  300. ;    READ1 - READ 1ST FILE INTO BUFFER
  301. ;
  302. ;    ENTRY:    NONE
  303. ;
  304. ;    EXIT:    'C'=1 IF ERROR
  305. ;
  306. READ1    EQU    $
  307.     LHLD    BUF1
  308.     XCHG            ;BUFFER ADDRESS IN (DE)
  309.     LXI    B,0        ;(BC) = COUNT OF SECTORS READ
  310. READ11: PUSH    D
  311.     PUSH    B
  312.     MVI    C,SETDMA
  313.     CALL    BDOS        ;SET DMA ADDRESS
  314.     LHLD    SEC1
  315.     SHLD    FCB1+R0        ;PUT SECTOR COUNT IN FCB
  316.     XRA    A
  317.     STA    FCB1+R2        ;ZERO R2
  318.  
  319.     LXI    D,FCB1
  320.     MVI    C,RDRAND
  321.     CALL    BDOS        ;READ A SECTOR
  322.     ANA    A
  323.     POP    B
  324.     POP    D
  325.     JNZ    READ12        ;QUIT IF END OF FILE
  326.  
  327.     INX    B        ;BUMP # SECTORS READ
  328.     XCHG
  329.     LXI    D,SECSIZ
  330.     DAD    D        ;UPDATE BUFFER ADDRESS
  331.     XCHG
  332.     LHLD    SEC1
  333.     INX    H        ;UPDATE BLOCK COUNT
  334.     SHLD    SEC1
  335.     MOV    A,C        ;GET # SECTORS READ
  336.     LXI    H,BUFSIZ
  337.     CMP    M        ;COMPARE W. BUFFER SIZE
  338.     JC    READ11        ;LOOP TILL BUFFER FULL
  339.     JMP    READ13
  340.  
  341. READ12: MVI    A,0FFH
  342.     STA    EOF1        ;SET EOF FLAG
  343. READ13: MOV    A,C        ;GET # SECTORS READ
  344.     STA    SZTOCMP        ;STORE AS # SECTORS TO COMPARE
  345. READ14: ANA    A        ;CLEAR CARRY
  346.     RET
  347.  
  348. ;    READ2 - READ 2ND FILE INTO BUFFER
  349. ;
  350. ;    ENTRY:    NONE
  351. ;
  352. ;    EXIT:    'C'=1 IF ERROR
  353. ;
  354. READ2    EQU    $
  355.     LHLD    BUF2
  356.     XCHG            ;BUFFER ADDRESS IN (DE)
  357.     LXI    B,0        ;(BC) = COUNT OF SECTORS READ
  358. READ21: PUSH    D
  359.     PUSH    B
  360.     MVI    C,SETDMA
  361.     CALL    BDOS        ;SET DMA ADDRESS
  362.     LHLD    SEC2
  363.     SHLD    FCB2+R0        ;PUT SECTOR COUNT IN FCB
  364.     XRA    A
  365.     STA    FCB2+R2        ;ZERO R2
  366.  
  367.     LXI    D,FCB2
  368.     MVI    C,RDRAND
  369.     CALL    BDOS        ;READ A SECTOR
  370.     ANA    A
  371.     POP    B
  372.     POP    D
  373.     JNZ    READ22        ;QUIT IF END OF FILE
  374.  
  375.     INX    B        ;BUMP # SECTORS READ
  376.     XCHG
  377.     LXI    D,SECSIZ
  378.     DAD    D        ;UPDATE BUFFER ADDRESS
  379.     XCHG
  380.     LHLD    SEC2
  381.     INX    H        ;UPDATE SECTOR COUNT
  382.     SHLD    SEC2
  383.     MOV    A,C        ;GET # SECTORS READ
  384.     LXI    H,BUFSIZ
  385.     CMP    M        ;COMPARE W. BUFFER SIZE
  386.     JC    READ21        ;LOOP TILL BUFFER FULL
  387.     RET
  388. READ22: MVI    A,0FFH        ;COME HERE IF END OF FILE
  389.     STA    EOF2        ;SET EOF FLAG
  390.     MOV    A,C        ;GET # SECTORS READ
  391.     LXI    H,SZTOCMP
  392.     CMP    M
  393.     RNC            ;IF MORE THAN 1ST FILE
  394.     MOV    M,A        ;SET AMT. TO COMPARE = SIZE OF SMALLER FILE
  395.     ANA    A
  396.     RET
  397.  
  398. ;    COMPARE 1 SECTOR (128 BYTES):
  399. ;
  400. ;    ENTRY:    (DE), (HL) = ADDRESSES TO COMPARE
  401. ;
  402. ;    EXIT:    (DE), (HL) POINT TO START OF NEXT SECTORS
  403. ;
  404. CMPSEC: MVI    C,SECSIZ    ;(C) = BYTES TO COMPARE
  405.     XRA    A
  406.     STA    CHGFLG        ;CLEAR CHANGE FLAG
  407.  
  408. CSECT:    LDAX    D        ;COMPARE 2 BUFFERS
  409.     CMP    M
  410.     CNZ    NOTEQU
  411.     INX    H
  412.     INX    D
  413.     DCR    C
  414.     JNZ    CSECT
  415.     RET
  416.  
  417. NOTEQU: PUSH    H        ;FOUND A DIFFERENCE, TELL ABOUT IT
  418.     PUSH    D
  419.     PUSH    B
  420.     LHLD    NUMLIN
  421.     DCX    H
  422.     SHLD    NUMLIN
  423.     MOV    A,L
  424.     ORA    H
  425.     JZ    EXIT        ;IF PRINTED MAX. LINES
  426.     LXI    D,MSG3
  427.     MVI    C,PRTSTR
  428.     CALL    BDOS
  429.     LHLD    BLKNUM
  430.     XRA    A
  431.     CALL    DECOUT        ;SHOW SECTOR #
  432.     LXI    D,MSG4
  433.     MVI    C,PRTSTR
  434.     CALL    BDOS
  435.     POP    B
  436.     PUSH    B        ;GET COUNT REMAINING
  437.     MVI    A,SECSIZ
  438.     SUB    C        ;SUBTRACT FROM SECTOR SIZE
  439.     PUSH    PSW        ;SAVE OFFEST FR. START OF SECTOR
  440.     MOV    L,A
  441.     MVI    H,0        ;PUT IN (HL)
  442.     MVI    A,SPACE
  443.     CALL    DECOUT        ;SHOW IT
  444.     MVI    A,SPACE
  445.     CALL    COUT
  446.     MVI    A,'('
  447.     CALL    COUT
  448.     LDA    BLKNUM
  449.     ANA    A
  450.     RAR            ;DIVIDE SECTOR COUNT BY 2 TO GET PAGE
  451.     MOV    H,A        ;SAVE IT
  452.     MVI    B,0
  453.     JNC    EVEN        ;IF EVEN PAGE
  454.     MVI    B,80H
  455. EVEN:    POP    PSW
  456.     ADD    B        ;IF ODD PAGE, ADD 80H TO LOW BYTE
  457.     MOV    L,A
  458.     CALL    HEXOUT        ;SHOW HEX OFFSET FROM START OF FILE
  459.     LXI    D,MSG5
  460.     MVI    C,PRTSTR
  461.     CALL    BDOS
  462.     MVI    A,0FFH
  463.     STA    CHGFLG
  464.     STA    DIFF
  465.     POP    B
  466.     POP    D
  467.     POP    H
  468.     RET
  469.  
  470. ;    COME HERE WHEN DONE:
  471.  
  472. DONE:    LHLD    SEC1     
  473.     XCHG
  474.     LHLD    SEC2        ;FILES ARE SAME SIZE?
  475.     CALL    COMPRP 
  476.     PUSH    PSW        ;SAVE RESULT OF COMPARISON
  477.     JNZ    NOTIDEN        ;IF SIZES NOT IDENTICAL
  478.  
  479.     LDA    DIFF
  480.     ANA    A        ;DIFFERENCES FOUND? -
  481.     JNZ    NOTIDEN        ;- YES, FILES NOT IDENTICAL
  482.     POP    PSW        ;- NO, CLEAR STACK
  483.  
  484.     LXI    D,MSG6        ;GIVE "IDENTICAL" MESSAGE
  485.     MVI    C,PRTSTR
  486.     CALL    BDOS
  487.     JMP    EXIT
  488.  
  489. ;    COME HERE IF FILES NOT =
  490.  
  491. NOTIDEN EQU    $
  492.     POP    PSW
  493.     LXI    H,FCB1
  494.     JC    EOFON2        ;IF EOF ON FILE 2 BEFORE FILE 1
  495.     LXI    H,FCB2
  496. EOFON2: LXI    D,EOFNAM    ;SHOW FILE NAME
  497.     CALL    FCOPY
  498.     LXI    D,MSG7
  499.     MVI    C,PRTSTR
  500.     CALL    BDOS
  501. EXIT:    LXI    D,FCB1        ;CLOSE FILES
  502.     MVI    C,FCLOSE
  503.     CALL    BDOS
  504.     LXI    D,FCB2
  505.     MVI    C,FCLOSE
  506.     CALL    BDOS
  507. EXIT2:    LHLD    OLDSTK
  508.     SPHL
  509.     RET            ;RETURN TO CCP
  510.  
  511. FCOPY:    MOV    A,M
  512.     INX    H
  513.     ANA    A
  514.     JZ    NODRV
  515.     ADI    'A'-1
  516.     STAX    D
  517.     INX    D
  518.     MVI    A,':'
  519.     STAX    D
  520.     INX    D
  521. NODRV:    MVI    B,11
  522. FCOPY1: MOV    A,M
  523.     CPI    SPACE
  524.     JZ    NOCOPY
  525.     STAX    D
  526.     INX    D
  527. NOCOPY: INX    H
  528.     DCR    B
  529.     RZ
  530.     MOV    A,B
  531.     CPI    3
  532.     JNZ    FCOPY1
  533.     MVI    A,'.'
  534.     STAX    D
  535.     INX    D
  536.     JMP    FCOPY1
  537.  
  538. ;    UTILITY SUBROUTINES:
  539.  
  540. ;    CONVERT A 16-BIT UNSIGNED BINARY NUMBER TO DECIMAL AND OUTPUT
  541. ;    IT TO THE CONSOLE. LEADING ZEROS ARE SUPPRESSED.
  542. ;
  543. ;    ENTRY:    (HL) = NUMBER
  544. ;        (A) = CHAR. TO PRINT INSTEAD OF LEADING 0
  545. ;
  546. ;    EXIT:    NONE
  547. ;
  548. ;    USES:    ALL 8080 REGISTERS
  549. ;
  550. ZEROCHR: DS     1
  551.  
  552. DECOUT: STA    ZEROCHR
  553.     MVI    B,0
  554.     LXI    D,-10000
  555.     CALL    PRTDGT
  556.     LXI    D,-1000
  557.     CALL    PRTDGT
  558.     LXI    D,-100
  559.     CALL    PRTDGT
  560.     LXI    D,-10
  561.     CALL    PRTDGT
  562.     MOV    A,L
  563.     ADI    60Q
  564.     JMP    COUT
  565.  
  566. PRTDGT: MVI    C,0FFH
  567.     PUSH    H
  568. PRT1:    INR    C
  569.     INX    SP
  570.     INX    SP
  571.     PUSH    H
  572.     DAD    D
  573.     JC    PRT1
  574.     POP    H
  575.     MOV    A,C        ;IF DIGIT IS A 0
  576.     ORA    B        ;AND NO NON-ZERO DIGIT HAS BEEN PRINTED,
  577.     LDA    ZEROCHR        ;WRITE SPECIAL CHAR.
  578.     JZ    COUT
  579.     MOV    A,C        ;ELSE WRITE A DIGIT
  580.     ADI    60Q
  581.     MOV    B,A
  582.     JMP    COUT
  583.  
  584. ;    DTOBIN - CONVERT A 5-DIGIT (MAX.) UNSIGNED DECIMAL NUMBER INTO A
  585. ;    BINARY VALUE.
  586. ;
  587. ;    ENTRY:    (C) = NO. OF DIGITS
  588. ;        (HL)  POINTS TO CHAR. STRING (MSD FIRST)
  589. ;
  590. ;    EXIT:    (DE) = CONVERTED NUMBER
  591. ;        'C' FLAG SET IF OVERFLOW (>64384) OR ERROR
  592. ;
  593. ;    USES:    ALL 8080 REGS.
  594. ;
  595. DGTPTR: DS    2
  596. DTOBIN: XRA    A
  597.     MOV    D,A
  598.     MOV    E,A        ;CLEAR (DE) - SERVES AS ACCUMULATOR
  599.     CMP    C        ;MAKE SURE (C) NOT ZERO
  600.     RZ
  601.     PUSH    H
  602. DTOB:    SHLD    DGTPTR        ;SAVE (HL) AS DIGIT POINTER
  603.     MOV    A,M        ;GET DIGIT
  604.     POP    H
  605.     CALL    VALDGT        ;CHECK FOR VALID DECIMAL DIGIT
  606.     RC            ;RETURN WITH ERROR IF NOT
  607.     ANI    0FH        ;CONVERT ASCII DIGIT TO BINARY
  608.     XCHG            ;SAVE SUM IN (HL)
  609.     MOV    E,A        ;MOVE DIGIT TO (DE)
  610.     MVI    D,0
  611.     MOV    B,C
  612.     DCR    B        ;PUT COUNT IN (B) = DIGIT COUNT -1
  613.     JZ    DTOB$1        ;IF =0, SKIP X10 ROUTINE
  614. DEX10:    PUSH    H
  615.     CALL    MU10        ;MULTIPLY (DE) BY 10
  616.     XCHG
  617.     POP    H
  618.     RC            ;(B) TIMES - RETURN ON OVERFLOW
  619.     DCR    B
  620.     JNZ    DEX10
  621. DTOB$1: DAD    D        ;ADD PRODUCT TO RESULT
  622.     RC            ;RETURN ON OVERFLOW
  623.     XCHG            ;SAVE NEW SUM
  624.     DCR    C
  625.     RZ            ;FINISHED IF COUNT=0
  626.     PUSH    H
  627.     LHLD    DGTPTR
  628.     INX    H        ;ELSE BUMP DIGIT POINTER
  629.     JMP    DTOB        ;& CONVERT NEXT DIGIT
  630. MU10:    XCHG
  631.     DAD    H
  632.     RC
  633.     MOV    D,H
  634.     MOV    E,L
  635.     DAD    H
  636.     RC
  637.     DAD    H
  638.     RC
  639.     DAD    D
  640.     RET
  641.  
  642. ;    SUBROUTINE - RETURNS WITH 'C' FLAG SET IF CHAR. IN (A) IS NOT
  643. ;    IN THE RANGE 0-9
  644.  
  645. VALDGT: CPI    '0'
  646.     RC
  647.     CPI    ':'
  648.     CMC
  649.     RET
  650.  
  651. ;    HEXOUT - SHOW 16-BIT WORD IN HEX
  652. ;    ENTRY:    (HL) = WORD
  653.  
  654. HEXOUT: MVI B,0
  655.     MOV A,H
  656.     RRC
  657.     RRC
  658.     RRC
  659.     RRC
  660.     CALL HEXDGT
  661.     MOV A,H
  662.     CALL HEXDGT
  663.     MOV A,L
  664.     RRC
  665.     RRC
  666.     RRC
  667.     RRC
  668.     CALL HEXDGT
  669.     MOV A,L
  670.     ANI 0FH
  671.     JMP SHOWHX
  672.  
  673. ;    HEXDGT - WRITE NIBBLE IN (A) AS HEX DIGIT
  674.  
  675. HEXDGT: ANI 0FH
  676.     JNZ SHOWHX
  677.     PUSH PSW
  678.     MOV A,B
  679.     ANA A
  680.     JZ NOSHOW
  681.     POP PSW
  682. SHOWHX: INR B
  683.     CPI 10
  684.     JNC LETTER
  685.     ADI '0'
  686.     JMP COUT
  687. LETTER: ADI 'A'-10
  688.     JMP COUT
  689. NOSHOW: POP PSW
  690.     RET
  691.  
  692. ;    CHARACTER OUTPUT
  693. ;    ENTRY: (A) = CHAR. TO PRINT
  694.  
  695. COUT:    DS    0
  696.     PUSH    H
  697.     PUSH    D
  698.     PUSH    B
  699.     PUSH    PSW
  700.     ANI    07FH
  701.     MOV    E,A
  702.     MVI    C,CONOUT
  703.     CNZ    BDOS
  704.     POP    PSW
  705.     POP    B
  706.     POP    D
  707.     POP    H
  708.     RET
  709.  
  710. ;    WRITE CR + LF
  711.  
  712. CRLF:    MVI    A,CR
  713.     CALL    COUT
  714.     MVI    A,LF
  715.     JMP    COUT
  716.  
  717. ;    COMPRP = COMPARE REGISTER PAIR
  718. ;
  719. ;    ENTRY:    (HL), (DE) SET
  720. ;
  721. ;    EXIT:    'Z'=1 IF (HL)=(DE)
  722. ;        'C'=1 IF (HL)>(DE)
  723. ;
  724. COMPRP: MOV    A,D
  725.     CMP    H
  726.     RNZ
  727.     MOV    A,E
  728.     CMP    L
  729.     RET
  730.  
  731. ;    SUBHLDE = SUBTRACT (DE) FROM (HL)
  732. ;
  733. ;    ENTRY:    (HL), (DE) SET
  734. ;
  735. ;    EXIT:    (HL) = (HL) - (DE)
  736. ;        'C' AND 'Z' FLAGS REFLECT RESULTS OF SUBTRACTION
  737. ;
  738. ;    USES:    F,H,L  ONLY
  739. ;
  740. SUBHLDE: DS     0
  741.     PUSH    B
  742.     MOV    B,A        ;SAVE (A)
  743.     XCHG
  744.     CALL    COMPRP        ;SET FLAGS
  745.     XCHG
  746.     MOV    A,B        ;RESTORE (A)
  747.     POP    B
  748.     PUSH    PSW        ;SAVE (A) AND FLAGS
  749.     MOV    A,L
  750.     SUB    E
  751.     MOV    L,A        ;DO SUBTRACTION
  752.     MOV    A,H
  753.     SBB    D
  754.     MOV    H,A
  755.     POP    PSW        ;RESTORE (A) AND FLAGS
  756.     RET
  757.  
  758. ;    MEMORY DEFINITIONS:
  759. ;
  760. FCB1:    DS    FCBSIZ
  761. FCB2:    DS    FCBSIZ
  762. OLDSTK: DS    2        ;STACK POINTER ON ENTRY
  763. BLKNUM: DS    2        ;BLOCK NUMBER
  764. CHGFLG: DS    1        ;FLAG, <>0 IF DIFFERENCE IN SECTOR
  765. DIFF:    DS    1        ;FLAG, <>0 IF ANY DIFFERENCE FOUND
  766. TOPMEM: DS    2        ;TOP OF USER MEMORY
  767. BUFSIZ: DS    2        ;SIZE OF FILE BUFFERS
  768. BUF1:    DS    2        ;ADDRESS OF 1ST FILE BUFFER
  769. BUF2:    DS    2        ;ADDRESS OF 2ND FILE BUFFER
  770. EOF1:    DS    1        ;FLAG, <>0 WHEN END OF FILE ON FILE 1
  771. EOF2:    DS    1        ;FLAG, <>0 WHEN END OF FILE ON FILE 2
  772. SEC1:    DS    2        ;NO. OF SECTORS READ FROM FILE 1
  773. SEC2:    DS    2        ;"   "      "     "    "       "   2
  774. SZTOCMP: DS     1        ;# OF BLOCKS TO COMPARE
  775. NUMEND: DS    2        ;END OF NUMBER
  776.     DS    40        ;STACK AREA
  777. STACK:    DS    0        ;TOP OF STACK
  778. NUMLIN: DW    20        ;NUMBER OF LINES TO LIST
  779. SIGNON: DB    'COMP V. 1.5 BY JON DART (15-MAR-85)$'
  780. MSG0:    DB    CR,LF,'CP/M 2.X REQUIRED.',CR,LF,'$'
  781. MSG1:    DB    CR,LF,'USAGE: COMP -n filename1 filename2',CR,LF
  782.     DB    SPACE,SPACE,SPACE,SPACE,SPACE,SPACE,SPACE
  783.     DB    '-n is optional, limits output to n lines (default 20)','$'
  784. MSG2:    DB    CR,LF,'CAN''T OPEN: '
  785. FILNAM: DB    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,CR,LF,'$'
  786. MSG3:    DB    'FILES DIFFER AT SECTOR $'
  787. MSG4:    DB    ', BYTE $'
  788. MSG5:    DB    'H).',CR,LF,'$'
  789. MSG6:    DB    'FILES ARE IDENTICAL.',CR,LF,'$'
  790. MSG7:    DB    CR,LF,'END OF FILE ON '
  791. EOFNAM: DB    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,CR,LF,'$'
  792.  
  793. ENDDATA EQU    $
  794.     END
  795.  
  796.