home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / CPM / ZCPR33 / A-R / CPA12.LBR / CPA12.ZZ0 / CPA12.Z80
Text File  |  2000-06-30  |  27KB  |  1,304 lines

  1.     title    ComPare Ascii utility 
  2.  
  3. ; Program:    CPA
  4. ; Author:    Carson Wilson <crw>
  5. ; Date:        February 20, 1989
  6. ; Version:    1.2
  7.  
  8. vers    equ    12
  9.  
  10. ; Changes:    Added Z3PLUS datestamp support.
  11. ;        Separated code from data segments.
  12. ;        Used SFXIO routines and 4k I/O buffers for better performance.
  13. ;        Fixed bug at GETNXTLN which caused read past end of file.
  14. ;        Added datestamp display to DISP_SCREEN.
  15. ;        For faster operation, CPA will not refresh the whole screen if 
  16. ;         keyboard input is available (G, ^E, ^X commands).
  17. ;        Allow user interrupt during long compares.
  18. ;        Use defaults for missing parts of command line (e.g., if 
  19. ;         second filename is missing, use first filename for both).
  20. ;        Added built-in help.
  21. ;        Added ZCPR environment detection (aborts unless ZCPR present).
  22. ;        Added comments to clarify code (hint: study the data 
  23. ;         structures at the end CPA.Z80 before tackling the code).
  24. ;        Commented .NEW's and renamed labels for Z80ASM.
  25.  
  26. ; Assembly:    VLIB, Z3LIB, ZSLIB, S0FILEIO, S1FILEIO, SYSLIB, Z80ASM, SLRNK
  27.  
  28. ;
  29. ; PREVIOUS VERSIONS
  30. ;
  31. ; Author:   Malcom Kemp
  32. ; Date:     January 7, 1987
  33. ; Version:  1.0
  34. ;
  35.  
  36. ctrl_c    equ    3
  37. ctrl_e    equ    5
  38. bs    equ    8
  39. tab    equ    9
  40. lf    equ    10
  41. cr    equ    13
  42. ctrl_x    equ    24
  43. ctrl_z    equ    26
  44. del    equ    7Fh        ; Delete character
  45.  
  46. no    equ    0
  47. yes    equ    not no
  48.  
  49. wboot    equ    0        ; Warm boot
  50. bdos    equ    5        ; BDOS entry 
  51. dfcb    equ    5Ch        ; Default FCB
  52. dfcb2    equ    6Ch        ; Second file
  53. fcb_length equ    36        ; Length of file control block
  54. dbuf    equ    80h        ; Default buffer
  55. llrec    equ    128        ; Length of logical record
  56.  
  57. iobufs    equ    32        ; Length of IO block in records
  58.  
  59.     public    $memry
  60.  
  61.     extrn    pa2hc,phl4hc
  62.     extrn    print,pstr,cout,pfn2,pafdc,phlfdc,phldc
  63.     extrn    retud,logud
  64.     extrn    z3vinit,tinit
  65.     extrn    capin
  66.     extrn    cls,ereol,gxymsg,at,gotoxy,vprint
  67.     extrn    fxi$open,fx$get,fxi$close
  68.  
  69.     extrn    cst,condin            ; SYSLIB
  70.  
  71.     extrn    prdat2,ptimm2,getstp,gstpcp    ; ZSLIB
  72.  
  73. test    equ    no            ; Include debugging routines
  74.  
  75. ; Start of routine
  76. ;
  77. ; External ZCPR3 Environment Descriptor
  78. ;
  79.     jp    start
  80.     db    'Z3ENV'        ; This is a zcpr3 utility
  81.     db    1        ; External environment descriptor
  82. z3eadr:
  83.     dw    0        ; Filled in by Z33 or installer
  84. start:    
  85.     call    print
  86.     db    cr,lf
  87.     db    'CPA, Version ',vers / 10 + '0','.',vers mod 10 + '0'
  88.     db    ' - Compare ASCII files.',cr,lf,0
  89.  
  90. ; Check for help
  91.  
  92.     ld    a,(dfcb+1)
  93.     cp    ' '
  94.     jr    z,help
  95.     cp    '/'
  96.     jr    nz,testz3
  97. help:
  98.     call    print
  99.     db    '  Syntax:',cr,lf
  100.     db    tab,'CPA [dir:]ufn [dir:][ufn]',cr,lf,0
  101.     ret
  102. testz3:
  103.     ld    hl,(z3eadr)    ; Hl -> zcpr3 environment
  104.     ld    a,h        ; Test ZCPR <crw>
  105.     or    l
  106.     jr    nz,gotz3
  107.     call    print
  108.     db    'Need ZCPR3',cr,lf,0
  109.     ret
  110. gotz3:
  111.     call    z3vinit
  112.     call    tinit
  113.  
  114. ; Get our home user/disk
  115.  
  116.     call    retud
  117.     ld    (home_ud),bc
  118.  
  119.     ld    hl,fm1        ; File 1 management
  120.     ld    (cur_file),hl
  121.     ld    hl,fm2
  122.     ld    (bak_file),hl    ; Initialize file pointers
  123.  
  124. ; Set up needed buffers:
  125. ;    line_buf    (lb_length bytes)
  126. ;    fm1.fm_b1    (b_length bytes)
  127. ;    fm1.fm_b2    (b_length bytes)
  128. ;    fm2.fm_b1    (b_length bytes)
  129. ;    fm2.fm_b2    (b_length bytes)
  130. ;
  131.     xor    a,a
  132.     ld    hl,fm1
  133.     ld    de,fm1+1
  134.     ld    bc,fm_ctl-1
  135.     ld    (hl),a
  136.     ldir            ; Clear Structure
  137.     inc    hl
  138.     ld    (hl),iobufs    ; Initialize SYSLIB IO block
  139.     ld    bc,fm_ptr-fm_ctl
  140.     add    hl,bc        ; Point to buffer ptr.
  141.     ld    e,l
  142.     ld    d,h        ; DE --> buffer ptr.
  143.     ld    bc,fm_buf-fm_ptr
  144.     add    hl,bc        ; HL --> buffer
  145.     ex    de,hl
  146.     ld    (hl),e
  147.     inc    hl
  148.     ld    (hl),d        ; Buffer ptr. --> buffer
  149.  
  150.     ld    hl,fm2
  151.     ld    de,fm2+1
  152.     ld    bc,fm_ctl-1
  153.     ld    (hl),a
  154.     ldir            ; Clear Structure
  155.     inc    hl
  156.     ld    (hl),iobufs
  157.     ld    bc,fm_ptr-fm_ctl
  158.     add    hl,bc        ; Point to buffer ptr.
  159.     ld    e,l
  160.     ld    d,h
  161.     ld    bc,fm_buf-fm_ptr
  162.     add    hl,bc
  163.     ex    de,hl
  164.     ld    (hl),e
  165.     inc    hl
  166.     ld    (hl),d
  167.  
  168.     ld    hl,(bdos+1)    ; Get protect address
  169.     ld    l,0        ; Make page aligned
  170.     dec    h        ; Leave room for stack
  171.     ld    sp,(bdos+1)    ; Set stack
  172. $memry    equ    $+1        ; <crw>
  173.     ld    de,0        ; HL = Ceil, DE = floor
  174.     or    a,a        ; Reset carry
  175.     sbc    hl,de        ; Available space
  176.     ld    de,lb_length    ; Space for line assembly buffer
  177.     sbc    hl,de        ; Space for line buffers
  178.     srl    h
  179.     rr    l        ; Divide by two
  180.     srl    h
  181.     rr    l        ; Divide by four
  182.     ld    (b_length),hl    ; Save buffer length
  183.  
  184.     ld    hl,($memry)
  185.     ld    (line_buf),hl    ; Set line assembly buffer
  186.  
  187.     ld    de,lb_length    ; Length of line assembly bufer
  188.     add    hl,de
  189.     ld    (fm1+fm_b1),hl    ; Set buffer 1
  190.     ld    de,(b_length)    ; Length of buffer 1
  191.     add    hl,de
  192.     ld    (fm1+fm_b2),hl    ; Set buffer 2
  193.  
  194.     ld    de,(b_length)    ; Length of buffer 2
  195.     add    hl,de
  196.     ld    (fm2+fm_b1),hl    ; Set buffer 1
  197.     ld    de,(b_length)    ; Length of buffer 1
  198.     add    hl,de
  199.     ld    (fm2+fm_b2),hl    ; Set buffer 2
  200.  
  201. ; Open files, set fm_ areas
  202.  
  203. fixf1:
  204.     ld    iy,fm1        ; IY -> current file structure
  205.  
  206.     ld    hl,dfcb        ; @5ch
  207.     ld    de,fm1+fm_fcb
  208.     ld    bc,16
  209.     ldir            ; Move fcb1 into place
  210.  
  211.     ld    hl,(fm1+fm_b1)
  212.     ld    (fm1+fm_empptr),hl
  213.     ld    hl,(b_length)
  214.     ld    (fm1+fm_empcnt),hl ; Set empty pointer
  215.     ld    a,1
  216.     ld    (fm1+fm_scrn),a    ; Set screen position
  217.  
  218.     ld    a,(fm1+fm_fcb+13) ; Get user
  219.     ld    c,a        ; Into C
  220.     ld    a,(fm1+fm_fcb)    ; Get disk
  221.     or    a,a        ; Is it default
  222.     jr    nz,a0$        ; No
  223.     ld    a,(home_ud+1)    ; Get default
  224.     jr    a1$        ; Use default
  225. a0$:
  226.     dec    a        ; Make into disk number
  227. a1$:
  228.     ld    b,a        ; Put in B
  229.     ld    (fm1+fm_ud),bc    ; And save in structure
  230.     xor    a,a        ; Get a zero
  231.     ld    (fm1+fm_fcb),a    ; And fix fcb disk
  232.  
  233.     ld    bc,(fm1+fm_ud)    ; Get our user/disk
  234.     call    logud
  235.     ld    de,fm1+fm_fcb    ; Get file control block
  236. ;
  237. ; Get stamp to STPBUF1 <crw>
  238. ;
  239.     ld    hl,stpbuf1
  240.     call    getstp        ; Got stamp? 
  241.     jr    z,save1
  242.     call    gstpcp        ; Try for CP/M Plus
  243. save1:    ld    (gots1),a    ; Save status
  244. ;
  245.     ld    de,fm1+fm_ctl    ; Get I/O control block
  246.     call    fxi$open
  247.     jp    z,openerr    ; No good, report error
  248.  
  249. fixfl2:
  250.     ld    iy,fm2        ; IY -> current file structure
  251.  
  252. ;    ld    hl,dfcb2
  253.  
  254. ; If filename2 missing, copy default to filename 1
  255.  
  256.     ld    de,dfcb2+1    ; Point to filename2 
  257.     push    de
  258.     ld    a,(de)
  259.     cp    ' '        ; DFCB2's name blank?
  260.     jr    nz,gotfn2    ; No
  261.     ld    hl,dfcb+1    ; Yes, default to DFCB's name
  262.     ld    bc,11
  263.     ldir
  264. gotfn2:
  265.     pop    hl        ; Point to filename2
  266.     dec    hl
  267.  
  268.     ld    de,fm2+fm_fcb
  269.     ld    bc,16
  270.     ldir            ; Put fcb in place
  271.  
  272.     ld    hl,(fm2+fm_b1)
  273.     ld    (fm2+fm_empptr),hl
  274.     ld    hl,(b_length)
  275.     ld    (fm2+fm_empcnt),hl ; Set empty pointer
  276.     ld    a,12
  277.     ld    (fm2+fm_scrn),a    ; Set screen position
  278.  
  279.     ld    a,(fm2+fm_fcb+13) ; Get user
  280.     ld    c,a        ; Into C
  281.     ld    a,(fm2+fm_fcb)    ; Get disk
  282.     or    a,a        ; Is it default
  283.     jr    nz,b0$        ; No
  284.     ld    a,(home_ud+1)    ; Get default
  285.     jr    b1$        ; Use default
  286. b0$:
  287.     dec    a        ; Make into disk number
  288. b1$:
  289.     ld    b,a        ; Put in B
  290.     ld    (fm2+fm_ud),bc    ; And save in structure
  291.     xor    a,a        ; Get a zero
  292.     ld    (fm2+fm_fcb),a    ; And fix fcb disk
  293.  
  294.     ld    bc,(fm2+fm_ud)    ; Get our user/disk
  295.     call    logud
  296.     ld    de,fm2+fm_fcb    ; Get file control block
  297. ;
  298. ; Get stamp to STPBUF2
  299. ;
  300.     ld    hl,stpbuf2
  301.     call    getstp        ; Got stamp? 
  302.     jr    z,save2
  303.     call    gstpcp        ; Try for CP/M Plus
  304. save2:    ld    (gots2),a
  305. ;
  306.     ld    de,fm2+fm_ctl    ; Get I/O control block
  307.     call    fxi$open
  308.     jp    z,openerr
  309.  
  310.     call    print
  311.     db    '  Working.. ',0
  312.  
  313. ;
  314. ; MAINLOOP
  315. ;
  316. mainloop:
  317.  
  318. ; Allow user to interrupt compare
  319.  
  320.     call    condin        ; User interrupt?
  321.     jr    nz,c2$        ; Yes
  322. ;
  323.     ld    a,(fm1+fm_eof)
  324.     ld    b,a
  325.     ld    a,(fm2+fm_eof)
  326.     or    a,b        ; Do we have an EOF?
  327.     jp    nz,c5$        ; Yes, quit
  328.     ld    iy,fm1
  329.     call    getnxtln    ; Get next line
  330.     ld    iy,fm2
  331.     call    getnxtln    ; In both files
  332.     ld    hl,(fm1+fm_curptr)
  333.     ld    (ptr1),hl
  334.     ld    hl,(fm2+fm_curptr)
  335.     ld    (ptr2),hl    ; Set pointers for compare
  336.     call    compare
  337.     jr    z,mainloop    ; Keep going
  338. c2$:
  339.     call    disp_screen
  340.     jr    z,c3$        ; Interrupted--process input
  341.  
  342. ;Command? (<sp>=Switch, ^e=Up, ^x=Down, g=Go): _
  343.  
  344. c2a$:
  345.     call    gxymsg
  346.     db    24,1
  347.     db    1,'Command? ('
  348.     db    2,'<sp>',1,'=Switch, ',2,'^e',1,'=Up, '
  349.     db    2,'^x',1,'=Down, ',2,'g',1,'=Go):     ',bs,bs,bs,bs,2,0
  350. c3$:
  351.     call    cin_e
  352. c4$:
  353.     cp    a,'G'
  354.     jp    z,do_g
  355.  
  356.     cp    a,'S'
  357.     jp    z,do_s
  358.     cp    ' '
  359.     jp    z,do_s
  360.  
  361.     cp    a,ctrl_e
  362.     jp    z,do_e
  363.     cp    a,'E'
  364.     jp    z,do_e
  365.  
  366.     cp    a,ctrl_x
  367.     jp    z,do_x
  368.     cp    a,'X'
  369.     jp    z,do_x
  370.  
  371.     call    gxymsg
  372.     db    24,47
  373.     db    2,'Huh? ',0
  374.     call    cin_e
  375.     push    af
  376.     call    gxymsg
  377.     db    24,47
  378.     db    '    ',0
  379.     pop    af
  380.     jr    c4$
  381.  
  382. do_g:
  383.     call    gxymsg
  384.     db    24,47
  385.     db    2,'Wait ',0
  386.     jp    mainloop
  387. do_s:
  388.     ld    hl,(cur_file)
  389.     ld    iy,(bak_file)
  390.     ld    (cur_file),iy
  391.     ld    (bak_file),hl
  392.     call    set_file_ptr
  393. ;    call    set_cur
  394. ;    jp    c3$
  395.     jp    c2a$
  396. do_e:
  397.     ld    iy,(cur_file)
  398.     ld    d,(iy+fm_curptr+1)
  399.     ld    e,(iy+fm_curptr)    ; Point to current line
  400.     ld    hl,lc_pptr
  401.     add    hl,de        ; HL -> previous line pointer
  402.     ld    a,(hl)
  403.     inc    hl
  404.     ld    h,(hl)
  405.     ld    l,a        ; HL -> previous line
  406.     or    a,h
  407.     jp    z,c2$        ; No previous, just return
  408.     ld    (iy+fm_curptr+1),h
  409.     ld    (iy+fm_curptr),l    ; Set to current
  410.     jp    c2$
  411.  
  412. do_x:
  413.     ld    iy,(cur_file)
  414.     call    getnxtln    ; Get next line
  415.     jp    c2$
  416. c5$:
  417.     call    disp_screen
  418.     call    gxymsg
  419.     db    24,1
  420.     db    2,'Type any key to return to system.',0
  421.     call    capin
  422.     call    exit
  423.  
  424. ;
  425. ; COMPARE - Compare lines pointed to by PTR1 and PTR2
  426. ;
  427. compare:
  428.     ld    hl,(ptr1)
  429.     ld    de,lc_cnt
  430.     add    hl,de
  431.     ld    c,(hl)
  432.     inc    hl
  433.     ld    b,(hl)        ; BC = length of line 1
  434.     ld    hl,(ptr2)
  435.     add    hl,de
  436.     ld    e,(hl)
  437.     inc    hl
  438.     ld    d,(hl)        ; DE = length of line 2
  439.     push    de
  440.     pop    hl
  441.     xor    a,a        ; Clear carry, set flag to equal
  442.     sbc    hl,bc        ; Length 2 - length 1
  443.     jr    z,d2$        ; Equal, don't flag on length
  444.     jr    nc,d1$
  445.     push    de
  446.     pop    bc
  447. d1$:                ; BC = count of shorter
  448.     or    a,0FFh        ; Show lengths different
  449. d2$:
  450.     ld    (mismatch),a    ; Set mismatch flag
  451.     ld    de,lc_string    ; Offset
  452.     ld    hl,(ptr1)
  453.     add    hl,de        ; Pointer
  454.     push    hl        ; Save
  455.     ld    hl,(ptr2)
  456.     add    hl,de
  457.     ex    de,hl
  458.     pop    hl        ; HL -> line 1, DE -> line 2 (string)
  459.     call    cpl        ; Compare strings
  460.     ld    (mism_off),bc    ; First byte of mismatch
  461.     jr    z,d4$        ; We have compare, leave mismatch flag alone
  462.     or    a,0FFh        ; Get true
  463.     ld    (mismatch),a    ; And set flag
  464. d4$:
  465.     ld    a,(mismatch)
  466.     or    a,a        ; Show mismatch
  467.     ret
  468.  
  469. ; Compare long--Compares strings -> by HL and DE, up to length in BC
  470. ;    Returns point of mismatch in BC (on match, BC unchanged)
  471. cpl:
  472.     ld    a,b
  473.     or    a,c
  474.     ret    z        ; Show they are the same
  475.  
  476.     push    bc        ; Save original count
  477. e1$:
  478.     ld    a,(de)
  479.     cp    a,(hl)
  480.     jr    nz,e2$
  481.     inc    hl
  482.     inc    de
  483.     dec    bc
  484.     ld    a,b
  485.     or    a,c
  486.     jr    nz,e1$
  487. e2$:
  488.     pop    hl        ; Get original count
  489.     push    af        ; Save psw
  490.     or    a,a        ; Reset carry
  491.     sbc    hl,bc        ; Set residual
  492.     push    hl
  493.     pop    bc        ; Count to difference
  494.     pop    af        ; Get psw
  495.  
  496.     ret
  497.  
  498. ;
  499. ; GETNXTLN - Get next line--Will point to next line in file at IY.
  500. ;
  501. getnxtln:
  502.     ld    d,(iy+fm_curptr+1)
  503.     ld    e,(iy+fm_curptr)    ; Point to current line
  504.     ld    a,d
  505.     or    a,e
  506.     jr    z,f1$        ; None, get first line
  507.     ld    hl,lc_nptr
  508.     add    hl,de        ; HL -> current line pointer
  509.     ld    a,(hl)
  510.     inc    hl
  511.     ld    h,(hl)
  512.     ld    l,a
  513.     and    a,h
  514.     inc    a        ; Is this EOF
  515.     ret    z        ; Yes, just leave it
  516.  
  517.     ld    a,h
  518.     or    a,l        ; Do we already have one
  519.     jr    z,f1$        ; No, go read one
  520.     ld    (iy+fm_curptr+1),h
  521.     ld    (iy+fm_curptr),l    ; Use the one we have
  522.     ret
  523. f1$:
  524.     push    de        ; Save curptr
  525.     call    getline
  526.     ld    b,(ix+lc_cnt+1)
  527.     ld    c,(ix+lc_cnt)    ; Get string length
  528.     ld    hl,lc_string    ; Get header length
  529.     add    hl,bc
  530.     push    hl
  531.     pop    bc        ; Length of line
  532.     ld    h,(iy+fm_empcnt+1)
  533.     ld    l,(iy+fm_empcnt) ; Get our space
  534.     or    a,a        ; Reset carry
  535.     sbc    hl,bc        ; Is there room
  536.     call    c,bufrev    ; No, get new buffer
  537.     ld    h,(iy+fm_empcnt+1)
  538.     ld    l,(iy+fm_empcnt) ; Get our space
  539.     or    a,a        ; Reset carry
  540.     sbc    hl,bc        ; Space left
  541.     ld    (iy+fm_empcnt+1),h
  542.     ld    (iy+fm_empcnt),l    ; Show it in structure
  543.     ld    hl,(line_buf)    ; HL -> source
  544.     ld    d,(iy+fm_empptr+1)
  545.     ld    e,(iy+fm_empptr)    ; DE -> destination
  546.     ld    (iy+fm_curptr+1),d
  547.     ld    (iy+fm_curptr),e    ; Set current ptr
  548.     push    de
  549.     pop    ix        ; IX -> line
  550.     ldir            ; BC = length from above
  551.     ld    (ix+lc_num+1),0
  552.     ld    (ix+lc_num),1    ; Set to one in case it is first
  553.     ld    (iy+fm_empptr+1),d
  554.     ld    (iy+fm_empptr),e    ; Post new empty pointer
  555.     pop    hl        ; Get old curptr
  556.     ld    (ix+lc_pptr+1),h
  557.     ld    (ix+lc_pptr),l    ; Set previous pointer
  558.  
  559. ; Preserve EOF flag <crw>. .
  560. ;    ld    (ix+lc_nptr+1),0
  561. ;    ld    (ix+lc_nptr),0    ; Set next pointer to zero
  562. ; . .<crw>
  563.  
  564.     ld    a,h
  565.     or    a,l
  566.     ret    z        ; No previous
  567.     push    hl        ; Save previous pointer
  568.     ld    de,lc_nptr
  569.     add    hl,de        ; HL -> nptr in previous
  570.     ld    a,(iy+fm_curptr)
  571.     ld    (hl),a
  572.     inc    hl
  573.     ld    a,(iy+fm_curptr+1)
  574.     ld    (hl),a        ; Put next pointer in place
  575.     pop    hl        ; Get pointer back
  576.     ld    de,lc_num
  577.     add    hl,de
  578.     ld    c,(hl)
  579.     inc    hl
  580.     ld    b,(hl)        ; Get old line number
  581.     inc    bc
  582.     ld    (ix+lc_num+1),b
  583.     ld    (ix+lc_num),c    ; Put in our line number
  584.     ret
  585.  
  586. ; Reverse buffers
  587.  
  588. bufrev:
  589.     push    de
  590.     push    hl            ; Save registers
  591.  
  592.     ld    h,(iy+fm_b1+1)
  593.     ld    l,(iy+fm_b1)
  594.     ld    de,lc_pptr
  595.     add    hl,de
  596.     ld    (hl),0
  597.     inc    hl
  598.     ld    (hl),0            ; Zero previos pointer for first entry
  599.     ld    h,(iy+fm_b1+1)
  600.     ld    l,(iy+fm_b1)
  601.     push    hl
  602.     ld    h,(iy+fm_b2+1)
  603.     ld    l,(iy+fm_b2)
  604.     ld    (iy+fm_b1+1),h
  605.     ld    (iy+fm_b1),l
  606.     ld    (iy+fm_empptr+1),h
  607.     ld    (iy+fm_empptr),l    ; Save new empty pointer
  608.     pop    hl
  609.     ld    (iy+fm_b2+1),h
  610.     ld    (iy+fm_b2),l        ; Reverse buffer ptrs
  611.     ld    hl,(b_length)
  612.     ld    (iy+fm_empcnt+1),h
  613.     ld    (iy+fm_empcnt),l    ; Set count
  614.  
  615.     pop    hl
  616.     pop    de            ; Restore registers
  617.     ret
  618.  
  619.     ret
  620.  
  621. ;
  622. ; GETLINE - Will get next line for file -> by IY
  623. ;
  624. ;    Will assemble the printable image in line_buf, with pointer and count
  625. ;    fields set (ptr will be zero).  CR LF pair will not be appended.
  626. ;
  627. ;  Destroys all registers
  628. ;
  629. getline:
  630.     ld    ix,(line_buf)    ; Set IX to assembly line
  631.     ld    b,(iy+fm_ud+1)
  632.     ld    c,(iy+fm_ud)    ; Get user/disk
  633.     call    logud        ; And go there
  634.     ld    (ix+lc_nptr+1),0
  635.     ld    (ix+lc_nptr),0
  636.     ld    (ix+lc_pptr+1),0
  637.     ld    (ix+lc_pptr),0    ; Zero pointers
  638.     ld    (ix+lc_cnt+1),0
  639.     ld    (ix+lc_cnt),0    ; Zero count
  640.     ld    hl,lc_string    ; Offset to string
  641.     ld    de,(line_buf)    ; Get buffer
  642.     add    hl,de
  643.     ex    de,hl        ; DE -> string data
  644. g1$:
  645.     call    getch        ; Get next character from file
  646.  
  647.     cp    a,cr
  648.     jr    z,pr_cr        ; Process return
  649.     cp    a,tab
  650.     jr    z,pr_tab    ; Process tab
  651.     cp    a,ctrl_z
  652.     jr    z,pr_eof    ; Process end of file
  653.     cp    a,del
  654.     jr    z,pr_del
  655.     cp    a,' '        ; Is it printable
  656.     jr    c,pr_ctr    ; No, go fix it
  657.      call    ass_char    ; Put in output line
  658.     jr    g1$
  659. pr_ctr:
  660.     push    af        ; Save character
  661.     ld    a,'^'
  662.     call    ass_char
  663.     pop    af        ; Get it back
  664.     or    a,40h        ; Make into printable char 
  665.     call    ass_char
  666.     jr    g1$
  667. pr_del:
  668.     ld    a,'D'
  669.     call    ass_char
  670.     jr    g1$
  671.  
  672. pr_tab:
  673.     ld    a,(ix+lc_cnt) ; Get count (lower byte)
  674.     and    a,7        ; Get lower bits (mod 8)
  675.     ld    b,a        ; Save
  676.     ld    a,8
  677.     sub    a,b        ; Get number to fill
  678.     ld    b,a        ; And put in counter
  679. pr_tab1:
  680.     ld    a,' '        ; Get filler
  681.     push    bc
  682.     call    ass_char
  683.     pop    bc
  684.     djnz    pr_tab1
  685.     jp    g1$
  686.  
  687. pr_eof:
  688.     ld    a,(ix+lc_cnt+1)
  689.     or    a,(ix+lc_cnt)        ; Do we have a line
  690.     jr    nz,pr_eol        ; Yes, get it next time
  691.     ld    (iy+fm_eof),0FFh    ; Show eof
  692.     ld    (ix+lc_nptr+1),0FFh
  693.     ld    (ix+lc_nptr),0FFh    ; And show last line
  694.     jr    pr_eol
  695.  
  696. pr_cr:
  697.     call    getch
  698.     cp    a,lf        ; Is it line feed
  699.     jr    z,pr_eol    ; Yes, process end of line
  700.     call    ungetch        ; Put character back
  701.     ld    a,cr        ; Get our character
  702.     jr    pr_ctr        ; And process as control character
  703.  
  704. pr_eol:
  705. ; Calculate number of lines for display
  706.     ld    h,(ix+lc_cnt+1)
  707.     ld    l,(ix+lc_cnt)    ; Get character count
  708.     ld    bc,lnm_length
  709.     add    hl,bc        ; Add what we need for line number
  710.     ld    a,1        ; Needs at least one
  711.     ld    bc,line_length    ; Number of characters per line on screen
  712. pr_eol1:
  713.     or    a,a        ; Reset carry
  714.     sbc    hl,bc
  715.     jr    c,pr_eol2    ; All done
  716.     jr    z,pr_eol2    ; Use what we have
  717.     inc    a
  718.     jr    pr_eol1
  719. pr_eol2:
  720.     ld    (ix+lc_lncnt),a ; Set line count
  721. ;set count, etc
  722.     ret
  723. ass_char:
  724.     ld    h,(ix+lc_cnt+1)
  725.     ld    l,(ix+lc_cnt)    ; HL = count
  726.  
  727.     ld    bc,max_line+1
  728.     or    a,a        ; Clear carry
  729.     push    hl        ; Save count
  730.     sbc    hl,bc
  731.     pop    hl        ; Get count
  732.     jr    nc,ac_err
  733.     inc    hl
  734.     ld    (ix+lc_cnt+1),h
  735.     ld    (ix+lc_cnt),l    ; Bump up
  736.     ld    (de),a        ; Save character
  737.     inc    de        ; Bump up
  738.     xor    a,a
  739.     ld    (de),a        ; Show end
  740.     ret
  741. ac_err:
  742.     call    print
  743.     db    cr,lf,'Line too long.',0
  744.  
  745.     call    exit
  746.  
  747. ;
  748. ; GETCH - Get character
  749. ;
  750. getch:
  751.     ld    a,(iy+fm_eof)
  752.     or    a,a        ; Do we have end of file
  753.     jr    z,getch1    ; No, go on
  754.     ld    a,ctrl_z    ; Show eof
  755.     ret
  756. getch1:
  757.     ld    a,(iy+fm_uf)    ; Do we already have one
  758.     or    a,a
  759.     jr    z,getch2    ; No, read file
  760.     ld    (iy+fm_uf),0    ; Reset switch
  761.     ld    a,(iy+fm_uc)    ; Get character
  762.     ret
  763. getch2:
  764.     push    de        ; Preserve line_buf ptr.
  765.     push    iy
  766.     pop    hl        ; Get FM
  767.     ld    bc,fm_ctl
  768.     add    hl,bc        ; Calculate IOCTL for FM at IY
  769.     ex    de,hl        ; Point with DE
  770.     call    fx$get        ; SYSLIB get char.
  771.     pop    de
  772.  
  773.     jr    z,getch3
  774.     and    a,07Fh        ; Get rid of high bit
  775.     ret
  776. getch3:
  777.     ld    (iy+fm_eof),0FFh ; Show eof
  778.     ld    a,ctrl_z
  779.     ret
  780.  
  781. ungetch:
  782.     ld    (iy+fm_uc),a    ; Save character
  783.     ld    (iy+fm_uf),0FFh    ; Set switch
  784.     ret
  785.  
  786. ;
  787. ; Character input with exit on ^C
  788. ;
  789. cin_e:
  790.     call    capin        ; <crw>
  791.     cp    a,ctrl_c
  792.     jp    z,exit
  793.     ret
  794.  
  795. ;
  796. ; DISP_SCREEN - Refresh full or partial screen.
  797. ;
  798. ;    Exit:    NZ - screen refreshed
  799. ;        Z  - interrupted by keyboard input <crw>
  800.  
  801. disp_screen:
  802.     call    cls
  803.  
  804.     ld    iy,fm1        ; Set structure pointer
  805.     call    gxymsg
  806.     db    1,10
  807.     db    1,'File 1: ',2,0
  808.     call    pr_file
  809.  
  810. ; Display Stamps as follows:
  811. ;
  812. ; Valid modify or create stamp found:
  813. ;        File 1: ALIAS.CMD - 12 Oct 88 12:09 - Line # 27
  814. ;
  815. ; Stamps found, but invalid (day not in 1..31):
  816. ;        File 1: ALIAS.CMD -  - Line # 27
  817. ;
  818. ; No stamps on disk:
  819. ;        File 1: ALIAS.CMD - Line # 27
  820.  
  821.     ld    a,(gots1)
  822.     or    a        ; Got stamp 1?
  823.     jr    nz,line1    ; No
  824.     call    prdash        ; Spacer
  825.     ld    hl,stpbuf1+10    ; Modified date
  826.     call    prdat2        ; Valid?
  827.     jr    z,prtim1    ; Yes
  828.     ld    hl,stpbuf1    ; No, fall back on create
  829.     call    prdat2
  830.     jr    nz,line1    ; No create, don't show
  831.     ld    a,'c'        ; Indicate create stamp
  832.     call    cout
  833. prtim1:
  834.     call    space
  835.     call    ptimm2        ; 24-hour time
  836. line1:
  837.     call    prlabl
  838.     ld    hl,(fm1+fm_curptr)
  839.     ld    de,lc_num
  840.     add    hl,de
  841.     ld    a,(hl)
  842.     inc    hl
  843.     ld    h,(hl)
  844.     ld    l,a        ; Get line number
  845.     call    phlfdc        ; And print it
  846.  
  847.     ld    iy,fm2        ; Set structure pointer
  848.     call    gxymsg
  849.     db    12,10
  850.     db    1,'File 2: ',2,0
  851.     call    pr_file
  852.  
  853.     ld    a,(gots2)
  854.     or    a        ; Got stamp 2?
  855.     jr    nz,line2    ; No
  856.     call    prdash
  857.     ld    hl,stpbuf2+10    ; Modified date
  858.     call    prdat2        ; Valid?
  859.     jr    z,prtim2    ; Yes
  860.     ld    hl,stpbuf2    ; No, fall back on create
  861.     call    prdat2
  862.     jr    nz,line2    ; No create, don't show
  863.     ld    a,'c'        ; Indicate create stamp
  864.     call    cout
  865. prtim2:
  866.     call    space
  867.     call    ptimm2
  868. line2:
  869.     call    prlabl
  870.     ld    hl,(fm2+fm_curptr)
  871.     ld    de,lc_num
  872.     add    hl,de
  873.     ld    a,(hl)
  874.     inc    hl
  875.     ld    h,(hl)
  876.     ld    l,a        ; Get line number
  877.     call    phlfdc        ; And print it
  878.  
  879. ; Check keyboard after displaying headers <crw>
  880.  
  881.     call    cst        ; Keyboard busy?
  882.     ret    z        ; Yes, quit now
  883. ;
  884. ; Display rest of screen
  885. ;
  886.     ld    iy,(cur_file)
  887.     call    set_file_ptr
  888.     ld    ix,disp_stru
  889.     ld    hl,(fm1+fm_curptr)
  890.     ld    (ptr1),hl
  891.     ld    (disp_stru+ds_ptr1),hl
  892.     ld    de,lc_lncnt
  893.     add    hl,de
  894.     ld    b,(hl)        ; Get lines needed
  895.     ld    hl,(fm2+fm_curptr)
  896.     ld    (ptr2),hl
  897.     ld    (disp_stru+ds_ptr2),hl    ; Set up our line pointers
  898.     ld    de,lc_lncnt
  899.     add    hl,de
  900.     ld    a,(hl)        ; Get lines needed
  901.     cp    a,b
  902.     jr    c,h1$
  903.     ld    b,a
  904. h1$:                ; B = larger
  905.     ld    a,wind_len    ; Get last line number
  906.     sub    a,b        ; Get out line
  907.     ld    (disp_stru+ds_ln),a    ; And save
  908.     or    a,0FFh
  909.     ld    (disp_stru+ds_last),a ; Show this is end
  910. h2$:
  911.     ld    hl,(ptr1)    ; Get our line
  912.     ld    de,lc_pptr
  913.     add    hl,de
  914.     ld    a,(hl)
  915.     inc    hl
  916.     ld    h,(hl)
  917.     ld    l,a
  918.     ld    (ptr1),hl    ; Update pointer
  919.     or    a,h        ; See if it is valid
  920.     jr    z,h4$        ; Get out, we are finished
  921.     ld    de,lc_lncnt
  922.     add    hl,de
  923.     ld    b,(hl)        ; Get lines needed
  924.  
  925.     ld    hl,(ptr2)    ; Get our line
  926.     ld    de,lc_pptr
  927.     add    hl,de
  928.     ld    a,(hl)
  929.     inc    hl
  930.     ld    h,(hl)
  931.     ld    l,a
  932.     ld    (ptr2),hl    ; Update pointer
  933.     or    a,h        ; See if it is valid
  934.     jr    z,h4$        ; Get out, we are finished
  935.     ld    de,lc_lncnt
  936.     add    hl,de
  937.     ld    a,(hl)        ; Get lines needed
  938.     cp    a,b
  939.     jr    c,h3$
  940.     ld    b,a
  941. h3$:                ; B = larger
  942.     ld    a,(ix+ds_ln)    ; Get previous line
  943.     sub    a,b        ; Get our new line
  944.     jr    c,h4$        ; No room, get out
  945.     ld    de,ds_length
  946.     add    ix,de        ; Bump up to next one
  947.     ld    (ix+ds_ln),a
  948.     xor    a,a
  949.     ld    (ix+ds_last),a    ; Show this is not end
  950.     ld    hl,(ptr1)
  951.     ld    (ix+ds_ptr1+1),h
  952.     ld    (ix+ds_ptr1),l    ; Set pointer
  953.     ld    hl,(ptr2)
  954.     ld    (ix+ds_ptr2+1),h
  955.     ld    (ix+ds_ptr2),l    ; Set pointer
  956.     jr    h2$
  957. h4$:
  958.     ld    h,(ix+ds_ptr1+1)
  959.     ld    l,(ix+ds_ptr1)
  960.     ld    (ptr1),hl
  961.     ld    h,(ix+ds_ptr2+1)
  962.     ld    l,(ix+ds_ptr2)
  963.     ld    (ptr2),hl    ; Set pointers for compare
  964.     call    compare
  965.     ld    hl,wind1    ; Get base
  966.     ld    a,(ix+ds_ln)
  967.     add    a,h
  968.     ld    h,a        ; Set location
  969.     call    gotoxy        ; Position cursor
  970.     ld    hl,(ptr1)
  971.     call    pr_line
  972.     ld    hl,wind2    ; Get base
  973.     ld    a,(ix+ds_ln)
  974.     add    a,h
  975.     ld    h,a        ; Set location
  976.     call    gotoxy        ; Position cursor
  977.     ld    hl,(ptr2)
  978.     call    pr_line
  979.  
  980.     ld    a,(ix+ds_last)
  981.     or    a,a        ; Check for end
  982.     ret    nz        ; All done
  983.     push    ix
  984.     pop    hl
  985.     ld    de,ds_length
  986.     or    a,a        ; Reset carry
  987.     sbc    hl,de        ; Back up pointer
  988.     push    hl
  989.     pop    ix
  990.  
  991. ; Also check keyboard after every line <crw>
  992.  
  993.     call    cst        ; Input detected?
  994.     ret    z        ; Yes, quit
  995.  
  996.     jr    h4$        ; Print next pair of lines
  997.  
  998. ; DISP_SCREEN subroutines
  999.  
  1000. prdash:
  1001.     call    vprint
  1002.     db    1,' - ',2,0
  1003.     ret
  1004.  
  1005. prlabl:
  1006.     call    vprint
  1007.     db    1,' - Line # ',2,0
  1008.      ret
  1009.  
  1010. ; -------------------------------------------------------
  1011. ;
  1012. ; PR_LINE - Print line--mismatch flag and mism_off are set.
  1013. ;    Entry:    HL -> line to print
  1014. ;
  1015. pr_line:
  1016.     push    hl
  1017.     pop    bc        ; BC -> line
  1018.     ld    hl,line_length-lnm_length
  1019.     ld    (work_ll),hl    ; Set max line length for first
  1020.     call    vprint
  1021.     db    2,0
  1022.     ld    hl,lc_num
  1023.     add    hl,bc        ; HL -> line number
  1024.     ld    a,(hl)
  1025.     inc    hl
  1026.     ld    h,(hl)
  1027.     ld    l,a
  1028.     call    phldc
  1029.     call    vprint
  1030.     db    1,'>',2,0
  1031. ;
  1032.     ld    hl,lc_nptr
  1033.     add    hl,bc
  1034.     ld    a,(hl)
  1035.     inc    hl
  1036.     and    a,(hl)
  1037.     inc    a
  1038.     jr    z,i5$        ; We have an end of file
  1039.  
  1040.     ld    hl,lc_cnt    ; Offset to count
  1041.     add    hl,bc
  1042.     ld    e,(hl)
  1043.     inc    hl
  1044.     ld    d,(hl)        ; Get count in BC
  1045.     ld    a,d
  1046.     or    a,e
  1047.     ret    z        ; No string to print
  1048.     ld    (work_line),de    ; Save length
  1049.  
  1050.     ld    hl,lc_string
  1051.     add    hl,bc
  1052.     push    hl
  1053.     pop    bc        ; BC -> string
  1054.  
  1055.     ld    hl,(mism_off)
  1056.     ld    a,(mismatch)
  1057.     or    a,a        ; Test for mismatch
  1058.     jr    nz,i1$        ; Mismatch, go on
  1059.     ld    hl,0FFFFh    ; No mismatch, move offset beyond line
  1060. i1$:
  1061.     ld    (work_mism),hl    ; Set our current mismatch
  1062. i2$:
  1063.     ld    de,(work_line)    ; Get our residual count
  1064.     ld    hl,0
  1065.     ld    (work_line),hl    ; Set residual count to zero
  1066.     ld    hl,(work_ll)    ; Get maximum line length
  1067.     or    a,a        ; Clear carry
  1068.     sbc    hl,de        ; Test for longer than a line
  1069.     jr    nc,i3$        ; It will all fit on this line
  1070.     ld    hl,(work_ll)
  1071.     ex    de,hl        ; Count in HL, max in DE
  1072.     or    a,a        ; Reset carry
  1073.     sbc    hl,de        ; Line length in DE, residual in HL
  1074.     ld    (work_line),hl    ; Save residual
  1075. i3$:
  1076.     ld    hl,line_length
  1077.     ld    (work_ll),hl    ; Set max line for other than first
  1078.     ld    hl,(work_mism)
  1079.     ld    a,h
  1080.     or    a,l
  1081.     dec    hl
  1082.     ld    (work_mism),hl
  1083.     jr    nz,i4$        ; Still matching (or not matching, as case)
  1084.     call    vprint
  1085.     db    1,0        ; Show mismatch
  1086. i4$:
  1087.     ld    a,(bc)
  1088.     call    cout
  1089.     inc    bc
  1090.     dec    de
  1091.     ld    a,d
  1092.     or    a,e
  1093.     jr    nz,i3$
  1094.     call    print
  1095.     db    cr,lf,' ',0
  1096.     ld    hl,(work_line)
  1097.     ld    a,h
  1098.     or    a,l        ; Check residual
  1099.     jr    nz,i2$
  1100.     ret
  1101. i5$:
  1102.     call    vprint
  1103.     db    1,' <<<',2,'end of file',1,'>>>',0
  1104.     ret
  1105.  
  1106.  
  1107. ; Print du:name of file whose FM block is pointed to by IY
  1108.  
  1109. pr_file:
  1110.     push    de
  1111.     push    hl
  1112.  
  1113.     ld    a,(iy+fm_ud+1)        ; Get disk
  1114.     add    a,'A'            ; Make printable
  1115.     call    cout
  1116.     ld    a,(iy+fm_ud)        ; Get user
  1117.     call    pafdc            ; Print it
  1118.     ld    a,':'
  1119.     call    cout
  1120.     push    iy
  1121.     pop    hl            ; Structure pointer
  1122.     ld    de,fm_fcb+1        ; Offset to file name
  1123.     add    hl,de
  1124.     ex    de,hl            ; Put in DE
  1125.     call    pfn2
  1126.  
  1127.     pop    hl
  1128.     pop    de
  1129.     ret
  1130.  
  1131. ; Display arrow indicating current file
  1132.  
  1133. set_file_ptr:
  1134.     call    gxymsg
  1135.     db    1,5
  1136.     db    '    ',0
  1137.     call    gxymsg
  1138.     db    12,5
  1139.     db    '    ',0
  1140.     ld    a,(iy+fm_scrn)
  1141.     ld    h,a
  1142.     ld    l,5
  1143.     call    gotoxy
  1144.     call    vprint
  1145.     db    2,'===>',0
  1146.     ret
  1147.  
  1148. ;set_cur:
  1149. ;    call    at
  1150. ;    db    24,47
  1151. ;    ret
  1152.  
  1153. ;
  1154. ; SPACE - print a space.  All registers preserved <crw>.
  1155. ;
  1156. space:
  1157.     push    af
  1158.     ld    a,' '
  1159.     call    cout
  1160.     pop    af
  1161.     ret
  1162. ;
  1163. ; File Open Error
  1164. ;
  1165. openerr:
  1166.     call    pr_file
  1167.     call    print
  1168.     db    ' not found',cr,lf,0
  1169.  
  1170. ;    fall    thru
  1171.  
  1172. ;
  1173. ; EXIT
  1174. ;
  1175. exit:
  1176.     ld    bc,(fm1+fm_ud)
  1177.     call    logud
  1178. ;ld    de,fm1+fm_fcb
  1179.     ld    de,fm1+fm_ctl
  1180.     call    fxi$close
  1181.  
  1182.     ld    bc,(fm2+fm_ud)
  1183.     call    logud
  1184. ;ld    de,fm2+fm_fcb
  1185.     ld    de,fm2+fm_ctl
  1186.     call    fxi$close
  1187.  
  1188.     ld    bc,(home_ud)
  1189.     call    logud
  1190.     jp    wboot
  1191.  
  1192.  
  1193. ; --------------------------------------------------------
  1194.  
  1195.  
  1196. ; Program parameters and data area
  1197.  
  1198.     DSEG            ; <crw>
  1199.  
  1200. ; Datestamp buffers <crw>
  1201.  
  1202. gots1:    ds    1        ; Status
  1203. stpbuf1:
  1204.     ds    128        ; Stamp
  1205.  
  1206. gots2:    ds    1
  1207. stpbuf2:
  1208.     ds    128
  1209.  
  1210. wind1    equ    2*256+1        ; Row 2 Column 1
  1211. wind2    equ    13*256+1    ; Row 13 Column 1
  1212.  
  1213. home_ud       ds    2        ; Home user/disk
  1214. mismatch   ds    1        ; Mismatch flag
  1215. mism_off   ds    2        ; Location of mismatch
  1216. ptr1       ds    2        ; Pointer for line 1
  1217. ptr2       ds    2        ; Pointer for line 2
  1218. cur_file   ds    2        ; Current file
  1219. bak_file   ds    2        ; File which is not current
  1220. work_line  ds    2        ; Residual line count for pr_line
  1221. work_mism  ds    2        ; Residual mism_off for pr_line
  1222. work_ll       ds    2        ; Length of current line
  1223.  
  1224. ; Structure for line
  1225.  
  1226. lb_length  equ    1024        ; 1k line assembley buffer
  1227. line_buf   ds    2        ; Pointer to line assembly buffer
  1228.  
  1229. lc_nptr       equ    0        ; Pointer to next line
  1230. lc_pptr       equ    2        ; Pointer to previous line
  1231. lc_num       equ    4        ; Line number
  1232. lc_cnt       equ    6        ; Number of characters in line
  1233. lc_lncnt   equ    8        ; Number of lines on screen for string
  1234. lc_string  equ    9        ; String
  1235. max_line   equ    lb_length-lc_string    ; Maximum line length
  1236.  
  1237. ; ----------------------------------------------------------------
  1238. ;
  1239. ; FM - File Management Structure
  1240. ;
  1241.  
  1242. fm_curptr  equ    0        ; Pointer to current line in buffer
  1243. fm_b1       equ    2        ; Pointer to line buffer 1 (current filling)
  1244. fm_b2       equ    4        ; Pointer to line buffer 2 (next to be filled)
  1245. fm_empptr  equ    6        ; Pointer to empty space in current buffer
  1246. fm_empcnt  equ    8        ; Count of bytes available in empty space
  1247.  
  1248. fm_ud       equ    10        ; File user/disk
  1249. fm_uf       equ    12        ; Unget flag
  1250. fm_uc      equ    13        ; Unget character
  1251. ;fm_get       equ    14        ; Get routine
  1252. fm_eof       equ    14        ; End of file indicator
  1253. fm_scrn    equ    15        ; Screen position for pointer
  1254. fm_ctl     equ    16        ; Begin SYSLIB FX I/O control block
  1255. fm_ptr       equ    22
  1256. fm_fcb     equ    24        ; File control block
  1257. fm_buf       equ    60
  1258.  
  1259. FM1:    ds    fm_ctl        ; File 1 management
  1260.                 ; SYSLIB IOctl1
  1261.     ds    1        ; Buffer size
  1262.     ds    5        ; Filled by FXIO
  1263.     ds    2        ; Buffer pointer
  1264.                 ; SYSLIB IOFCB1
  1265.     ds    1        ; Set to 0 by FXIO 
  1266.     ds    35        ; Rest of FCB
  1267.     ds    128*iobufs    ; SYSLIB working buffer
  1268.  
  1269.  
  1270. FM2:    ds    fm_ctl        ; File 2 management
  1271.                 ; SYSLIB IOctl2
  1272.     ds    1        ; Buffer size
  1273.     ds    5        ; Filled by FXIO
  1274.     ds    2        ; Buffer pointer
  1275.                 ; SYSLIB IOFCB2
  1276.     ds    1        ; Set to 0 by FXIO 
  1277.     ds    35        ; Rest of FCB
  1278.     ds    128*iobufs    ; SYSLIB working buffer
  1279.  
  1280.  
  1281. b_length  ds    2        ; CPA buffer length
  1282.  
  1283. ; --------------------------------------------------------
  1284. ; DS - Display Structure
  1285. ;
  1286.  
  1287. ds_last       equ    0        ; Flag for last (first) entry
  1288. ds_ptr1       equ    1        ; Pointer file 1
  1289. ds_ptr2       equ    3        ; Pointer file 2
  1290. ds_ln       equ    5        ; Line number (screen, relative)
  1291. ds_length  equ    6        ; Length of structure
  1292.  
  1293. wind_len    equ    10        ; Length of window
  1294. line_length equ    78        ; Length of line (leave one at beginning and end)
  1295. lnm_length  equ    5        ; Length of line number field
  1296.  
  1297. disp_stru:
  1298.     ds    wind_len*ds_length
  1299.  
  1300.     end
  1301.  
  1302. ; End of CPA.Z80
  1303.