home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / cpm / utils / asmutl / buffers.lbr / FDIFF.MZC / FDIFF.MAC
Encoding:
Text File  |  1987-01-14  |  9.1 KB  |  436 lines

  1. ; Binary compare file 1 and file 2.  By C.B. Falconer.
  2. ;
  3. ;   d>FDIFF [-o] [d[u]:]file1.typ [d[u]:][file2.typ]
  4. ;        compares file1.typ to file2.typ
  5. ;        (with full du addressing, across users, drives)
  6. ;    the (optional) -options cause:
  7. ;        n    no page pauses
  8. ;        number    offset for 1st file byte
  9. ;            (default 0, 0100h for .COM files)
  10. ;            (number must be the last option)
  11. ;
  12. ; 1.1    86/12/02 Minor changes to use BUFFLIB 1.4, keep under 2k
  13. ;
  14. ; EX: d>FDIFF -n100 c3:fdiff.obj
  15. ; compares c3:fdiff.obj against current du:fdiff.obj,
  16. ; with initial address set to 0100h.
  17. ; SEE BUFFERS.DOC for linking instructions
  18. ;
  19. ver    equ    11
  20. ;
  21. boot    equ    0
  22. tfcb    equ    boot+05ch
  23. defdma    equ    boot+080h
  24. @cin    equ    1
  25. @csta    equ    11
  26. ;
  27. cr    equ    0dh
  28. lf    equ    0ah
  29. tab    equ    9
  30. stksize    equ    128;        includes b.ohead
  31. multi    equ    1
  32. nopause    equ    2;        flag word bits
  33. delta    equ    080h;        a difference found
  34. ;
  35.     extrn    .dos, b.ohead, .bfgetc
  36.     extrn    .bfropen, .pfnmdu, .xltusr
  37.     extrn    .skipblks, .nextch, .qnum
  38.     extrn    .couta, .tadzs, .tfnam, .t2hx, .t4hx, .crlf
  39.     extrn    .endata;    End of data storage segment
  40. ;
  41.     jmp    begin;        around patch area
  42. ;
  43. ; patchable constants
  44. lpp:    db    20;        lines per page before pause
  45. ;
  46. begin:    lhld    6;        set stack at top of memory
  47.     mvi    l,0
  48.     sphl
  49. ;    "    "
  50. ; allocate the largest possible buffer
  51.     lxi    d,-.endata-stksize
  52.     dad    d;        form size of memory available
  53.     ora    a;        split into two buffers
  54.     mov a,h    ! rar ! mov h,a
  55.     mov a,l    ! rar ! mov l,a
  56.     push    h;        save buffer size
  57. ;    "    "
  58. ; mark end of command line, just in case.
  59. ; Done by most CCPs, but undocumented.  CCPLUS is documented
  60. ;    lxi    h,defdma
  61. ;    mov    a,m;        line length
  62. ;    inx h    ! add l ! mov l,a
  63. ;    adc h    ! sub l ! mov h,a
  64. ;    mvi    m,0;        mark eol
  65. ;    "    "
  66.     call    clear;        flags and counters
  67. ;    "    "
  68. ; check for a verify flag
  69.     lxi    d,defdma+1
  70.     call    .skipblks
  71.     cpi    '-'
  72.     jnz    parse;        no options
  73.     call    .nextch
  74. flgs1:    call    setup;        some flag
  75.     jc    parse;        not a valid flag, start over
  76.     cpi    ' '
  77.     jnz    flgs1;        check another
  78.     jmp    parse1;        field terminated. ptr past options
  79. ;
  80. ; parse the file names
  81. parse:    call    clear;        in case bad options altered
  82.     lxi    d,defdma+1;    set command scanning pointer
  83. ;    "    "
  84. ; Entry when command line options found
  85. parse1:    lxi    h,fcbin
  86.     call    .pfnmdu;    will parse an empty line into
  87.     lda    fcbin+1;    a blank FCB.
  88.     sui    ' '
  89.     jz    exit;        no file specified, give help
  90.     mov    a,b;        designated user
  91.     call    .xltusr;    convert 0 into current, etc
  92.     sta    inuser;        needed for chksame and show
  93.     mov    a,b;        but bfropen needs original form
  94.     pop    b;        get buffer size back
  95.     push    d;        save input scan pointer
  96.     lxi    d,fcbin
  97.     lxi    h,.endata
  98.     call    .bfropen;    open buffered file for read
  99.     mvi    a,1
  100.     jc    exit;        can't find it, abort
  101.     lxi    h,.endata+b.ohead
  102.     dad    b;        now rounded down to 128 mult.
  103.     shld    @outbuff;    allocate output buffer
  104.     pop    d;        restore input scan pointer
  105.     push    h;        @outbuff
  106.     push    b;        save buffer size
  107.     lxi    h,fcbout
  108.     push    h
  109.     call    .pfnmdu
  110.     mov    a,b;        designated user
  111.     call    .xltusr;    convert to standard form
  112.     sta    outuser;    save for future
  113.     lda    fcbout+1
  114.     cpi    ' '
  115.     cz    filejam;    no 2nd file, copy file1 name
  116.     mov    a,b
  117.     pop    d;        fcbout
  118.     pop    b;        buffer size
  119.     pop    h;        @outbuff
  120.     call    .bfropen;    open buffered file for read
  121.     mvi    a,2
  122.     jc    exit;        can't find file2
  123.     call    chksame;    ensure not comparing against self
  124.     call    chkcom;        to set base to 0100h for .COMs
  125. ;    "    "
  126. ; All files open, files different, and buffers assigned.
  127. ; Compare fcbin and fcbout in largest possible blocks
  128. diff:    lxi    h,address
  129.     call    incrm;        keep track of address
  130.     lxi    h,.endata
  131.     call    .bfgetc
  132.     jc    donea
  133.     mov    b,a
  134.     lhld    @outbuff
  135.     call    .bfgetc
  136.     jc    doneb
  137.     cmp    b
  138.     jz    diff
  139. ;    "    "
  140. ; show difference
  141.     mov    c,a
  142.     call    chkhdg;        and set delta flag
  143.     call    pausechk
  144.     lhld    base
  145.     lxi    d,address
  146.     ldax d    ! add l ! mov l,a ! inx d
  147.     ldax d    ! adc h ! mov h,a ! inx d
  148.     ldax d    ! aci 0
  149.     call    .t2hx
  150.     call    .t4hx
  151.     call    tabber
  152.     mov    a,b
  153.     xra    c
  154.     call    .t2hx;        show different bits
  155.  ;    "    "    
  156.     call    show;        show file 1
  157.     mov    b,c
  158.     call    show;        show file 2
  159.     call    .crlf
  160.     jmp    diff
  161. ;
  162. ; clear variables
  163. ; a,f,h,l
  164. clear:    xra a    ! mov h,a ! mov l,a
  165.     sta    flags;        default all off
  166.     sta    line;        on screen for differences
  167.     shld    base;        default 0
  168.     dcr a    ! dcx h;    all 0ffh
  169.     shld    address
  170.     sta    address+2;    set to -1 (will increment)
  171.     ret
  172. ;
  173. ; show values for b
  174. show:    call    tabber;        show file 1
  175.     mov    a,b
  176.     call    .t2hx;        show in hex
  177.     call    blks3
  178.     mov    a,b
  179.     call    ascii;        ascii char or blank
  180.     call    blks3
  181.     mov    a,b
  182.     jmp    .tadzs;        show in decimal
  183. ;
  184. ; 3 blanks
  185. blks3:    call    blk
  186. blks2:    call    blk
  187.     jmp    blk
  188. ;
  189. ; Check for the initial header.  Mark files not identical.
  190. ; a,f,d,e,h,l
  191. chkhdg:    lxi    h,flags
  192.     push    b
  193.     mov    c,m
  194.     mov    a,c
  195.     ori    delta
  196.     mov    m,a
  197.     xra    c
  198.     pop    b
  199.     rp;            delta was already set
  200. ;    "    "
  201. ; output page heading
  202. ; a,f,d,e,h,l
  203. hdg:    call    .crlf
  204.     call    tabber
  205.     call    tabber
  206.     lxi    d,fcbin
  207.     lda    inuser
  208.     call    .tfnam
  209.     call    tabber
  210.     lxi    d,fcbout
  211.     lda    outuser
  212.     call    .tfnam
  213.     call    .crlf
  214.     mvi    a,7
  215.     jmp    msg
  216. ;
  217. ; Tab console over
  218. ; a,f
  219. tabber:    mvi    a,tab
  220.     jmp    .couta
  221. ;
  222. ; show a as char if printable, else as blank
  223. ; a,f
  224. ascii:    ani    07fh
  225.     cpi    07fh
  226.     jz    blk
  227.     cpi    ' '
  228.     jnc    .couta
  229. ;    "    "
  230. ; blank to console
  231. ; a,f
  232. blk:    mvi    a,' '
  233.     jmp    .couta
  234. ;
  235. ; check for pagination pause
  236. pausechk:
  237.     mvi    a,@csta
  238.     call    .dos
  239.     ora    a
  240.     cnz    abtchk
  241.     lda    flags
  242.     ani    nopause
  243.     rnz
  244.     lxi    h,line
  245.     inr    m
  246.     lda    lpp;        lines per page
  247.     cmp    m
  248.     rnc
  249.     mvi    m,0
  250.     mvi    a,8
  251.     call    msg;        [more]
  252. pc1:    call    abtchk
  253.     cpi    cr
  254.     jnz    pc1
  255.     mvi    a,9
  256.     call    msg;        wipe out the [more]
  257.     jmp    hdg
  258. ;
  259. ; console char ready - check for abort. Return char.
  260. ; a,f
  261. abtchk:    mvi    a,@cin
  262.     call    .dos
  263.     cpi    3
  264.     jz    boot;        cntrl-c
  265.     ret
  266. ;
  267. ; EOF on file1, check for eof on file 2
  268. donea:    lhld    @outbuff
  269.     call    .bfgetc
  270.     mvi    a,5
  271.     jnc    exit;        file 1 shorter
  272.     lda    flags
  273.     ora    a
  274.     jm    boot;        differences
  275.     mvi    a,6;        same length
  276.     jmp    exit;        files identical    
  277. ;
  278. ; EOF on file2 and not file1
  279. doneb:    mvi    a,4
  280. ;    "    "
  281. ; Output message no. (a) and exit
  282. ; a,f,d,e,h,l
  283. exit:    call    msg
  284.     jmp    boot
  285. ;
  286. ; output message # (a)
  287. ; a,f,h,l
  288. msg:    lxi    h,msgtbl
  289.     add    a
  290.     mov e,a    ! mvi d,0 ! dad d
  291.     mov e,m    ! inx h ! mov d,m
  292.     mvi    a,9
  293.     jmp    .dos
  294. ;
  295. msgtbl:    dw    msg0, msg1, msg2, msg3, msg4
  296.     dw    msg5, msg6, msg7, msg8, msg9
  297. ;
  298. msg0:
  299.  db    'FDIFF v', ver/10+'0', '.', ver MOD 10 + '0'
  300.  db    ' by C.B. Falconer.',cr,lf,lf
  301.  db    'Usage: FDIFF [-n000] [d[u]:]file1.ft [d[u]:][file2.ft]'
  302.  db    cr,lf,lf
  303.  db    ' Default file2 is file1 when du''s different',cr,lf
  304.  db    ' Optional -n for no page pauses, -000 (hex) sets base'
  305.  db    cr,lf,lf
  306.  db    'ex: FDIFF -100 a3:fdiff.obj',cr,lf
  307.  db    'compare a3:fdiff.obj with current du:fdiff.obj,'
  308.  db        ' using addresses from 0100h'
  309.  db    cr,lf,'$'
  310. msg1:    db    'Can''t find file1$'
  311. msg2:    db    'Can''t find file2$'
  312. msg3:    db    'File2 is same file as file1$'
  313. msg4:    db    'file2 EOF before file1$'
  314. msg5:    db    'file1 EOF before file2$'
  315. msg6:    db    'No differences$'
  316. msg7:    db    'Addr.',tab,'bits',tab,'Hex Asc. Dec.',tab
  317.     db    'Hex Asc. Dec.',cr,lf,'$'
  318. msg8:    db    '[more]$'
  319. msg9:    db    '      $'
  320. ;
  321. ; jam file 2 name to file 1 name
  322. filejam:
  323.     push h    ! push d ! push b
  324.     lxi    d,fcbout+1
  325.     lxi    h,fcbin+1
  326.     mvi    b,11
  327. fj1:    mov a,m    ! ani 7fh;    delete attrib bits
  328.     stax d    ! inx h ! inx d
  329.     dcr b    ! jnz fj1;    more
  330.     pop b    ! pop d ! pop h
  331.     ret
  332. ;
  333. ; check for same output file as input, or no output
  334. ; a,f,b,c,d,e,h,l (allowed)
  335. chksame:
  336.     lda    outuser
  337.     mov    b,a
  338.     lda    inuser
  339.     xra    b
  340.     ani    01fh
  341.     rnz;            in/out different
  342.     lxi    h,fcbout
  343.     lxi    d,fcbin
  344.     mvi    b,12;        check for different drives
  345. chk4:    ldax d    ! xra m;    ignore attrib bits. 
  346.     ani 7fh    ! rnz;        in/out different
  347.     inx h    ! inx d
  348.     dcr b    ! jnz chk4;    check more
  349.     mvi    a,3
  350.     jmp    exit;        files same if here
  351. ;
  352. ; If either file is of type .COM, and base has not been set,
  353. ; jam the base value to 0100h.
  354. chkcom:    lhld    base
  355.     mov a,l    ! ora h ! rnz;    already set
  356.     lxi    d,fcbin+9
  357.     call    cmp
  358.     lxi    d,fcbout+9
  359.     cnz    cmp;        check fcbout if not fcbin.COM
  360.     rnz;            not a .com file
  361.     lxi    h,0100h
  362.     shld    base
  363.     ret
  364. ;
  365. ; compare de^ for "COM".  z flag if so
  366. cmp:    lxi    h,comtyp
  367.     mvi    b,3
  368. cmp1:    ldax d    ! cmp m ! rnz
  369.     dcr b    ! jnz cmp1
  370.     ret
  371. ;
  372. comtyp:    db    'COM'
  373. ;
  374. ; setup sets the appropriate flag and returns the next char
  375. ; a,f,h,l
  376. setup:    lxi    h,flags
  377.     cpi    'N'
  378.     jnz    setup3
  379.     mvi    a,nopause
  380.     ora m    ! mov m,a
  381.     jmp    .nextch
  382. ;
  383. ; check for numeric input    
  384. setup3:    call    .qnum
  385.     rc;            not a valid option
  386.     lxi    h,0
  387. setup4:    ani    0fh
  388.     dad h    ! dad h ! dad h ! dad h
  389.     ora l    ! mov l,a
  390.     call    .nextch
  391.     call    qhex
  392.     jnc    setup4
  393.     shld    base
  394.     cmc
  395.     ret
  396. ;
  397. ; check for valid hex digit, convert if so,
  398. ; else return carry and unchanged a 
  399. ; a,f
  400. qhex:    call    .qnum
  401.     rnc
  402.     cpi    'A'
  403.     rc
  404.     cpi    'F'+1
  405.     cmc
  406.     rc
  407.     sui    7
  408.     ret
  409. ;
  410. ; increment 24 bit long word hl^ in memory
  411. incrm:    inr m    ! rnz
  412.     inx h    ! inr m ! rnz
  413.     inx h    ! inr m
  414.     ret
  415. ;
  416. ;    ---------    Data Segment    --------
  417. ;    Link this AFTER all the code segments
  418. ;
  419.     dseg
  420. flags:        ds    1;    verify flag
  421. base:        ds    2;    display base
  422. address:    ds    3;    current display address
  423. line:        ds    1;    on current screen
  424. inuser:        ds    1;    user # for input file
  425. fcbin:        ds    36;    input file fcb
  426. outuser:    ds    1;    user # for output file
  427. fcbout:        ds    36;    output file fcb
  428. @outbuff:    ds    2;    location of 2nd file buffer
  429. ;
  430. ; This must be the last program storage, see linking above.
  431. ; Now uses BUFFLIB .endata.  Alternatively use a separate dseg file.
  432. ;buffer:    ds    0;    =.endata; actually rest of memory
  433. ;
  434.     end
  435. l╡