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 / PACKET / RLI120.ARK / FILEIO.MAC < prev    next >
Text File  |  1986-08-12  |  14KB  |  752 lines

  1. ; FILEIO.MAC - 1/4/86 - Buffered file I/O.
  2. ; Two files may be open at once: one for read, one for write.
  3.  
  4.     .z80
  5.     maclib    TNC.LIB
  6.  
  7.     entry    @openn,@openr,@openw,@opena,@closew,rcv
  8.     entry    inibak,getbuf,copfil,kilfil,renfil,hidfil
  9.     entry    bkm1,bkm2,bkm3,bkm4,bkm5,bkm6,bkm7,bkm8
  10.     entry    tobuf,fmbuf,@ntobuf,@ctobuf,rdcmd,rdstr,rdmstr
  11.     entry    setb7,rfcb,wfcb,ioini,ckdrv,ckro,defdrv,maxdrv
  12.  
  13.     external    @mcmd,@cmpcmd,$memry,@outch,numb,bindec
  14.     external    eofs,leofs,addcr0,opt2,cmd,cmdlen
  15.     external    getdat,erexst,ercant,erdone,ername,erwhat,erfind
  16.     external    div8,memtop,ckname,fcb2,fcb3,@prtx,@fill
  17.  
  18.     asciictl
  19.     bdosdef
  20.     tncdefs
  21.  
  22.     dseg
  23. ro:    ds    1        ; Read only drives.
  24. online:    ds    1        ; Drives on line (logged in).
  25. maxdrv:    ds    1        ; Highest drive online.
  26. defdrv:    ds    1        ; Default drive.
  27.  
  28. rb:    ds    2        ; Address of read buffer.
  29. rbptr:    ds    2        ; Read buffer pointer.
  30. rbcnt:    ds    2        ; # bytes remaining in read buffer.
  31. rbeof:    ds    1        ; True if eof read.
  32. rbsec:    ds    1        ; # sectors read.
  33. rfcb:    ds    fcbsize        ; Read file control block.
  34.  
  35. wb:    ds    2        ; Address of write buffer.
  36. wbptr:    ds    2        ; Write buffer pointer.
  37. wbcnt:    ds    2        ; # Bytes left in write buffer.
  38. wbsec:    ds    1        ; # sectors in write buffer.
  39. wfcb:    ds    fcbsize        ; Write file control block.
  40. wfcbrc    equ    wfcb+15        ; FCB: record count.
  41. wfcbcr    equ    wfcb+32        ; FCB: current record.
  42. wfcbrn    equ    wfcb+33        ; FCB: random record number.
  43.  
  44. copst:    ds    1
  45. copbs:    ds    2
  46. copbp:    ds    2
  47. copbc:    ds    2
  48. copin:    ds    2
  49.  
  50. tfcb:    ds    2
  51. curdrv:    ds    1
  52.  
  53.     cseg
  54. dosrc:    ld    (tfcb),hl
  55.     dodosa    setdma,defdma
  56.     ld    hl,(tfcb)
  57.     ld    a,(hl)
  58.     ld    (curdrv),a
  59.     ld    (hl),0
  60.     ld    bc,12
  61.     add    hl,bc
  62.     ld    (hl),0
  63.     or    a        ; Drive specified?
  64.     jr    z,dosrca    ; No
  65.     dec    a
  66.     ld    e,a
  67.     dodosa    seldsk        ; Make this drive the default
  68. dosrca:    ld    de,(tfcb)
  69.     dodosa    search
  70.     push    psw
  71.     ld    hl,(tfcb)
  72.     ld    a,(curdrv)
  73.     ld    (hl),a
  74.     ld    a,(defdrv)
  75.     ld    e,a
  76.     dodosa    seldsk        ; Put back original default
  77.     pop    psw
  78.     inc    a
  79.     ret
  80.  
  81. ; Return in hl the number of sectors of free memory.
  82.  
  83. getbuf:    ld    de,($memry)    ; Start of free mem
  84.     ld    hl,(memtop)    ; End of free mem
  85.     or    a        ; Clear carry
  86.     sbc    hl,de        ; Bytes available
  87.     ld    e,128
  88.     call    div8
  89.     ld    h,0
  90.     ret
  91.  
  92. ; Read a bunch of sectors into buffer
  93.  
  94. copr:    movw    copbp,$memry    ; Point to start of buffer space
  95.     movw    copbc,copbs    ; Init avail buffer count
  96.     lxim    copin,0        ; Init count of records read
  97. copra:    ld    de,(copbp)
  98.     dodosa    setdma        ; Point IO to buffer
  99.     dodosa    read,fcb2    ; Read record
  100.     ld    (copst),a    ; Save read status
  101.     or    a        ; Done?
  102.     ret    nz        ; Yes
  103.     inxm    copin        ; Count records in buffer
  104.     ld    hl,(copbp)
  105.     ld    de,128
  106.     add    hl,de
  107.     ld    (copbp),hl    ; Point to next buffer
  108.     dcxm    copbc        ; One less available
  109.     ld    a,l
  110.     or    h        ; Any left
  111.     jr    nz,copra    ; Yes, read next
  112.     ret
  113.  
  114. ; Write the bunch of sectors from buffer.
  115.  
  116. copw:    movw    copbp,$memry
  117.     ld    hl,(copin)
  118. copwa:    ld    a,l
  119.     or    h        ; Done?
  120.     ret    z        ; Yes
  121.     ld    de,(copbp)
  122.     dodosa    setdma
  123.     dodosa    write,fcb3    ; Write record
  124.     ld    hl,(copbp)
  125.     ld    de,128
  126.     add    hl,de
  127.     ld    (copbp),hl
  128.     dcxm    copin
  129.     jr    copwa
  130.  
  131. ; The "copy file" command.
  132.  
  133. copfil:    ckname    fcb2        ; Input name legal?
  134.     jp    z,ername    ; No
  135.     ld    a,(fcb2)
  136.     call    ckdrv        ; Input drive on line?
  137.     jp    nc,erfind    ; No
  138.     ckname    fcb3        ; Output name legal?
  139.     jp    z,ername    ; No
  140.     ld    a,(fcb3)
  141.     call    ckdrv        ; Output drive on line?
  142.     jp    nc,erfind    ; No
  143.     ld    a,(fcb3)
  144.     call    ckro        ; Can we write on it?
  145.     jp    c,ercant    ; No
  146.     ld    hl,fcb3
  147.     call    dosrc        ; Output file already exist?
  148.     jp    nz,erexst    ; Yes
  149.     dodosa    open,fcb2    ; Open the input file
  150.     inc    a
  151.     jp    z,erfind    ; No input file
  152.     dodosa    make,fcb3    ; Create the output file
  153.     call    copyf        ; Do the copy
  154.     jp    erdone
  155.  
  156. ; Copy file from fcb2 to fcb3.
  157.  
  158. copyf:    call    getbuf
  159.     ld    (copbs),hl    ; Sectors of buffer available
  160. copfa:    call    copr        ; Read a bunch
  161.     call    copw        ; Write em
  162.     ld    a,(copst)
  163.     or    a        ; Done?
  164.     jr    z,copfa        ; No
  165.     dodosa    close,fcb3
  166.     ret
  167.  
  168. ; Delete a file.
  169.  
  170. kilfil:    ckname    fcb2        ; Legal file name?
  171.     jp    z,ername    ; No
  172.     ld    a,(fcb2)
  173.     call    ckdrv        ; Drive on line?
  174.     jp    nc,erfind    ; No
  175.     ld    a,(fcb2)
  176.     call    ckro        ; Can we write on it?
  177.     jp    c,ercant    ; No
  178.     dodosa    delete,fcb2    ; Delete the file
  179.     inc    a
  180.     jp    z,erfind    ; Delete failed
  181.     jp    erdone
  182.  
  183. ; Toggle $sys attribute on file.
  184.  
  185. hidfil:    ckname    fcb2        ; File name legal?
  186.     jp    z,ername    ; No
  187.     ld    a,(fcb2)
  188.     call    ckdrv        ; Drive on line?
  189.     jp    nc,erfind    ; No
  190.     ld    a,(fcb2)
  191.     call    ckro        ; Can we write on it?
  192.     jp    c,ercant    ; No
  193.     ld    hl,fcb2
  194.     call    dosrc        ; Get dir entry into buffer
  195.     jp    z,erfind    ; No such file
  196.     dec    a
  197.     add    a,a
  198.     add    a,a
  199.     add    a,a
  200.     add    a,a
  201.     add    a,a
  202.     ld    hl,defdma
  203.     ld    e,a
  204.     ld    d,0
  205.     add    hl,de        ; (HL) point to dir entry
  206.     ld    a,(fcb2)
  207.     ld    (hl),a        ; Set drive in dir entry
  208.     push    hl
  209.     ld    bc,10
  210.     ld    a,(opt2)
  211.     cp    'N'        ; Toggle new attribute?
  212.     jr    nz,hidfa    ; No, do $sys
  213.     ld    bc,4
  214. hidfa:    add    hl,bc
  215.     ld    a,(hl)
  216.     xor    80h        ; Toggle the bit
  217.     ld    (hl),a
  218.     pop    hl
  219.     ex    de,hl        ; (DE) point to dir entry
  220.     dodosa    setatr
  221.     jp    erdone
  222.  
  223. ; Rename a file.
  224.  
  225. renfil:    ckname    fcb2        ; Old name legal?
  226.     jp    z,ername    ; No
  227.     ckname    fcb3        ; New name legal?
  228.     jp    z,ername    ; No
  229.     ld    a,(fcb2)
  230.     call    ckdrv        ; This drive on line?
  231.     jp    nc,erfind    ; No
  232.     ld    a,(fcb2)
  233.     call    ckro        ; Can we write on it?
  234.     jp    c,ercant    ; No
  235.     zmov    fcb2+16,fcb3,12
  236.     ld    hl,fcb3
  237.     call    dosrc        ; New already exist?
  238.     jp    nz,erexst    ; Yes
  239.     dodosa    rename,fcb2    ; Rename the sucker
  240.     inc    a
  241.     jp    z,ercant    ; Could not rename
  242.     jp    erdone
  243.  
  244. ; Set attribute at (HL)
  245.  
  246. setb7:    ld    a,(hl)
  247.     or    80h
  248.     ld    (hl),a
  249.     ret
  250.  
  251. ; Initialize for backup.
  252. ; fcb2 contains file to be backed up (.DAT)
  253. ; fcb3 contains file to backup to (.BAK)
  254. ; Return zero cleared if success, set if failure.
  255.  
  256.     dseg
  257. renfcb:    ds    fcbsize
  258.     cseg
  259. bkm1:    ds    2
  260. bkm2:    ds    2
  261. bkm3:    ds    2
  262. bkm4:    ds    2
  263. bkm5:    ds    2
  264. bkm6:    ds    2
  265. bkm7:    ds    2
  266. bkm8:    ds    2
  267.  
  268. ; Check if .DAT exists.
  269.  
  270. inibak:    ld    hl,fcb2
  271.     call    dosrc        ; Is a .DAT file?
  272.     ld    hl,(bkm1)
  273.     jp    z,inibe        ; Tell no file
  274.     dodosa    close,fcb2    ; Close file.
  275.  
  276. ; Delete .BAK
  277.  
  278.     prtx    bkm5
  279.     dodosa    delete,fcb3
  280.     ld    hl,fcb3+10
  281.     call    setb7        ; Set $sys attribute
  282.  
  283. ; Rename or copy .DAT to .BAK
  284.  
  285.     ld    a,(fcb3)
  286.     ld    hl,fcb2
  287.     cp    m        ; DAT and BAK on same device?
  288.     jr    z,inibb        ; Yes
  289.  
  290. ; Different devices, must copy
  291.  
  292.     fill    fcb2+12,fcbsize-12,0
  293.     dodosa    open,fcb2
  294.     fill    fcb3+12,fcbsize-12,0
  295.     dodosa    make,fcb3
  296.     prtx    bkm7
  297.     call    copyf
  298.     dodosa    delete,fcb2    ; Delete .DAT
  299.     jr    inibc
  300.  
  301. ; Same device, can rename.
  302.  
  303. inibb:    prtx    bkm6
  304.     zmov    renfcb,fcb2,16
  305.     zmov    renfcb+16,fcb3,16
  306.     dodosa    rename,renfcb
  307.     dec    a
  308.     ld    hl,(bkm2)    ; Point to msg
  309.     jr    z,inibd        ; Tell error
  310.  
  311. ; Make the new .DAT
  312.  
  313. inibc:    prtx    bkm8
  314.     fill    fcb2+12,fcbsize-12,0
  315.     ld    hl,fcb2+10
  316.     call    setb7        ; Set $sys attribute
  317.     dodosa    make,fcb2
  318.  
  319. ; Open .BAK
  320.  
  321.     fill    fcb3+12,fcbsize-12,0
  322.     dodosa    open,fcb3
  323.     inc    a
  324.     ld    hl,(bkm3)    ; Point to msg
  325.     jr    z,inibd        ; Tell error
  326.     retnz            ; Return zero cleared, success
  327.  
  328. inibd:    call    @prtx        ; Tell what happened...
  329.     ld    hl,(bkm4)    ; and is serious
  330. inibe:    call    @prtx
  331.     retz            ; Return zero set, failure
  332.  
  333. ; Initialize buffered file I/O.
  334. ; Allocate fixed memory space.
  335.  
  336. ioini:    movw    rb,$memry
  337.     ld    de,secsize*bufsize
  338.     add    hl,de
  339.     ld    (wb),hl
  340.     add    hl,de
  341.     ld    ($memry),hl
  342.  
  343. ; Find out what drives available.
  344.  
  345.     dodosv    ckdsks
  346.     ld    a,l
  347.     ld    (online),a    ; Drives online
  348.     ld    c,9
  349. fndmax:    dec    c
  350.     rlca
  351.     jr    nc,fndmax
  352.     ld    a,c
  353.     ld    (maxdrv),a
  354.     dodosv    getro
  355.     ld    a,l
  356.     ld    (ro),a        ; Read only drives
  357.     dodosv    ckcur
  358.     ld    (defdrv),a    ; Current default drive
  359.     ret
  360.  
  361. ; Check if drive in (A) is online.
  362. ; Carry set if ok, cleared if not online.
  363.  
  364. ckdrv:    or    a
  365.     scf            ; Good status
  366.     ret    z        ; Default
  367.     ld    hl,maxdrv
  368.     ld    b,(hl)
  369.     inc    b
  370.     cp    b
  371.     ret    nc        ; No more than maxdrv drives
  372.     ld    c,a
  373.     ld    a,(online)
  374. ckdrva:    dec    c
  375.     rrca
  376.     jr    nz,ckdrva
  377.     ret
  378.  
  379. ; Check if drive in (A) is R/O.
  380. ; Carry set if R/O, cleared if R/W.
  381.  
  382. ckro:    or    a
  383.     ret    z        ; Default, carry cleared=R/W
  384.     ld    c,a
  385.     ld    a,(ro)
  386. ckroa:    dec    c
  387.     rrca
  388.     jr    nz,ckroa
  389.     ret
  390.  
  391. ; Check if drive exists and is R/W
  392. ; Return zero set if not.
  393.  
  394. ckwrt:    ld    a,(wfcb)
  395.     call    ckdrv
  396.     jr    nc,ckwrta
  397.     ld    a,(wfcb)
  398.     call    ckro
  399.     jr    c,ckwrta
  400.     retnz
  401. ckwrta:    retz
  402.  
  403. ; Write the buffers to file.
  404. ; Return zero set if error.
  405.  
  406. wtbuf:    push    bc
  407.     push    de
  408.     call    wtbufa
  409.     pop    de
  410.     pop    bc
  411.     ret
  412.  
  413. wtbufa:    ld    de,(wbcnt)    ; Bytes unused in buffer
  414.     ld    hl,secsize*bufsize
  415.     or    a        ; Clear carry
  416.     sbc    hl,de
  417.     ld    de,secsize-1
  418.     add    hl,de
  419. ; Divide (hl)=(hl)/128
  420.     ld    a,l
  421.     rla
  422.     ld    a,h
  423.     rla
  424.     ld    (wbsec),a    ; Sectors used in buffer
  425.     lxim    wbcnt,secsize*bufsize
  426.     movw    wbptr,wb
  427.     ex    de,hl
  428. wtbufb:    push    de
  429.     dodosa    setdma
  430.     dodosa    write,wfcb
  431.     pop    de
  432.     or    a
  433.     jr    z,wtbufc
  434.     retz            ; Error
  435. wtbufc:    ld    hl,secsize
  436.     add    hl,de
  437.     ex    de,hl
  438.     ld    hl,wbsec
  439.     dec    (hl)
  440.     jr    nz,wtbufb
  441.     retnz
  442.  
  443. ; Buffered read - fill the buffer.
  444. ; Return zero set if error.
  445.  
  446. rdbuf:    push    bc
  447.     push    de
  448.     call    rdbufa
  449.     pop    de
  450.     pop    bc
  451.     ret
  452.  
  453. rdbufa:    cmpm    rbeof,true
  454.     ret    z
  455.     mvim    rbsec,bufsize
  456.     movw    rbptr,rb
  457.     ex    de,hl
  458. rdbufb:    push    de
  459.     dodosa    setdma
  460.     dodosa    read,rfcb
  461.     pop    de
  462.     or    a
  463.     jr    z,rdbufc
  464.     mvim    rbeof,true
  465.     dtz    rbcnt
  466.     ret
  467. rdbufc:    ld    bc,secsize
  468.     ld    hl,(rbcnt)
  469.     add    hl,bc
  470.     ld    (rbcnt),hl
  471.     ld    hl,secsize
  472.     add    hl,de
  473.     ex    de,hl
  474.     ld    hl,rbsec
  475.     dec    (hl)
  476.     jr    nz,rdbufb
  477.     retnz
  478.  
  479. ; Put character in C into buffer.
  480. ; Return zero set if error.
  481.  
  482. tobuf:    push    hl
  483.     dtz    wbcnt
  484.     call    z,wtbuf
  485.     pop    hl
  486.     ret    z
  487.     push    hl
  488.     ld    hl,(wbptr)
  489.     ld    (hl),c
  490.     inc    hl
  491.     ld    (wbptr),hl
  492.     dcxm    wbcnt
  493.     pop    hl
  494.     retnz
  495.  
  496. ; Get char from file buffer, return in C.
  497. ; Return zero set if error/eof.
  498.  
  499. fmbuf:    push    hl
  500.     dtz    rbcnt
  501.     call    z,rdbuf
  502.     pop    hl
  503.     ret    z
  504.     push    hl
  505.     ld    hl,(rbptr)
  506.     ld    c,(hl)
  507.     inc    hl
  508.     ld    (rbptr),hl
  509.     dcxm    rbcnt
  510.     pop    hl
  511.     retnz
  512.  
  513. ; (B) characters from (HL) to file buffer.
  514.  
  515. @ntobuf:    ld    c,(hl)
  516.     call    tobuf
  517.     inc    hl
  518.     dec    b
  519.     jr    nz,@ntobuf
  520.     ret
  521.  
  522. ; Copy characters starting at (HL) to buffer until CR.
  523. ; Add LF after CR.
  524.  
  525. @ctobuf:    ld    c,(hl)
  526.     call    tobuf
  527.     inc    hl
  528.     ld    a,c
  529.     cp    cr
  530.     jr    nz,@ctobuf
  531.     ld    c,lf
  532.     call    tobuf
  533.     ret
  534.  
  535. crlf:    ld    c,cr
  536.     call    tobuf
  537.     ret    z
  538.     ld    c,lf
  539.     call    tobuf
  540.     ret
  541.  
  542. ; Collect a text file from the current console device.
  543.  
  544. rcv:    call    getdat
  545.     ckcmd    rcv,rcve,rcve
  546.     cmpm    cmd,eof        ; Just a ^Z?
  547.     jr    z,rcvd        ; Yes
  548.     ld    a,(cmdlen)
  549.     or    a        ; Just a CR?
  550.     jr    z,rcvb        ; Yes
  551.     ld    b,a
  552.     ld    hl,cmd
  553. rcva:    ld    a,(hl)
  554.     cp    eof
  555.     jr    z,rcvc
  556.     ld    c,a
  557.     call    tobuf
  558.     jr    z,rcve        ; Error
  559.     inc    hl
  560.     dec    b
  561.     jr    nz,rcva
  562. rcvb:    call    crlf
  563.     jr    z,rcve
  564.     jr    rcv
  565.  
  566. rcvc:    call    crlf
  567.     jr    z,rcve
  568. rcvd:    ld    c,eof
  569.     call    tobuf
  570.     jr    z,rcve        ; Error
  571.     closew
  572.     ret
  573.  
  574. rcve:    dodosa    close,wfcb
  575.     dodosa    delete,wfcb
  576.     retz
  577.  
  578. ; Open file for buffered read.
  579. ; Return zero set if error.
  580.  
  581. @openr:    call    openny
  582.     ret    z
  583.     mvim    rbeof,false
  584.     lxim    rbcnt,0
  585.     retnz
  586.  
  587. ; Open file. If drive not specified, look on all drives.
  588.  
  589. openny:    ld    a,(rfcb)
  590.     or    a
  591.     jr    nz,opn3
  592. opn1:    inc    a
  593.     ld    (rfcb),a
  594.     call    opn3
  595.     ret    nz
  596. opn2:    ld    a,(rfcb)
  597.     ld    hl,maxdrv
  598.     cp    (hl)
  599.     jr    nz,opn1
  600.     ret
  601.  
  602. opn3:    ld    a,(rfcb)
  603.     call    ckdrv
  604.     jr    c,opn4
  605.     retz
  606. opn4:    dodosa    open,rfcb
  607.     inc    a
  608.     ret
  609.  
  610. ; Open file for write, if it does not exist.
  611. ; Return zero set if not ok, cleared if ok.
  612.  
  613. @openn:    call    ckwrt
  614.     jr    z,opnwnb
  615.     ld    hl,wfcb
  616.     call    dosrc        ; File exist?
  617.     jr    nz,opnwna    ; Yes
  618.     call    opnwa
  619.     jr    z,opnwnb
  620.     retnz
  621. opnwna:    call    erexst
  622.     retz
  623.  
  624. opnwnb:    call    ercant
  625.     retz
  626.  
  627. ; Open file for buffered write. Delete existing.
  628. ; Return zero set if error.
  629.  
  630. @openw:    call    ckwrt
  631.     ret    z
  632.     dodosa    delete,wfcb
  633. opnwa:    dodosa    make,wfcb
  634.     inc    a
  635.     ret    z
  636.     lxim    wbcnt,secsize*bufsize
  637.     movw    wbptr,wb
  638.     retnz
  639.  
  640. ; Open file for append. Make file if not exist.
  641. ; Return zero set if error.
  642.  
  643. @opena:    call    ckwrt
  644.     ret    z
  645.     dodosa    open,wfcb
  646.     inc    a
  647.     jr    nz,opna
  648.     dodosa    make,wfcb
  649.     inc    a
  650.     ret    z
  651.     movw    wbptr,wb
  652.     lxim    wbcnt,secsize*bufsize
  653.     retnz
  654. opna:    dodosa    getend,wfcb
  655.     dcxm    wfcbrn
  656.     ld    de,(wb)
  657.     dodosa    setdma
  658.     dodosa    rrec,wfcb
  659.     ld    hl,(wb)
  660.     ld    c,secsize
  661.     ld    a,eof
  662. opnb:    cp    (hl)
  663.     jr    z,opnc
  664.     inc    hl
  665.     dec    c
  666.     jr    nz,opnb
  667.     ld    hl,(wb)
  668.     ld    c,secsize
  669.     jr    opnd
  670. ; Found eof, want to rewrite this record.
  671. opnc:    ld    a,(wfcbrc)
  672.     dec    a
  673.     ld    (wfcbrc),a
  674. opnd:    ld    (wbptr),hl
  675.     ld    hl,secsize*(bufsize-1)
  676.     ld    b,0
  677.     add    hl,bc
  678.     ld    (wbcnt),hl
  679.     retnz
  680.  
  681. ; Close file opened for buffered write.
  682. ; Return zero set if error.
  683.  
  684. @closew:    call    wtbuf    ; Drain the final buffer
  685.     dodosa    close,wfcb    ; Close the file
  686.     inc    a        ; Set flags
  687.     ret
  688.  
  689. ; Read a line from a file into the command line buffer.
  690. ; Return zero set if error/eof.
  691.  
  692. rdcmd:    ld    hl,cmdlen    ; Point to byte count
  693.     ld    (hl),0        ; Clear it
  694.     ld    b,cmdmax    ; Max length of string
  695.     ld    de,cmd        ; Point to buffer
  696. rdcmda:    call    fmbuf        ; Get byte from I/O buffer
  697.     ret    z        ; I/O error
  698.     ld    a,c
  699.     cp    lf        ; Was LF?
  700.     jr    z,rdcmda    ; Yes, ignore it
  701.     cp    cr        ; Was CR?
  702.     jr    z,rdcmdc    ; Yes, end of string
  703. rdcmdb:    cp    eof        ; Was end of file?
  704.     ret    z        ; Yes, error (no CR)
  705.     ld    (de),a        ; Store the byte
  706.     inc    de        ; Point where next byte goes
  707.     inc    (hl)        ; Incremement byte count
  708.     dec    b        ; Decrement # bytes left
  709.     jr    nz,rdcmda    ; Some left
  710. rdcmdc:    retnz            ; Overflowed buffer, truncate string
  711.  
  712. ; Read a line from a file into allocated memory.
  713. ; Add CR,0 at end. Return (HL)=start of line.
  714. ; Return zero set if I/O error.
  715.  
  716. rdstr:    call    rdcmd        ; Read the line
  717.     ret    z        ; I/O error or eof
  718.     ld    hl,($memry)    ; Address to put string
  719.     push    hl        ; Save it
  720.     movcmd    ,0,cmdmax    ; Move string there
  721.     call    addcr0        ; Put CR,0 at end of string
  722.     inc    hl
  723.     ld    ($memry),hl    ; Next available byte
  724.     pop    hl        ; Return start of string
  725.     retnz            ; and zero cleared
  726.  
  727. ; Read multiple lines from a file into allocated memory.
  728. ; Return (HL)=start of first line.
  729. ; Return zero set if I/O error.
  730.  
  731. ;
  732. rdmstr:    ld    hl,($memry)    ; Where to put the string
  733.     push    hl        ; Save it
  734.     ld    (hl),0        ; Mark end of string
  735.     inc    hl        ; Allocate it
  736.     ld    ($memry),hl    ; Next available byte
  737. rdma:    dcxm    $memry        ; Back up over the 0
  738.     call    rdstr        ; Read a line into memory
  739.     jr    z,rdmb        ; Error
  740.     push    hl        ; Save string start
  741.     cmpcmd    eofs,leofs
  742.     pop    hl        ; Restore string start
  743.     jr    nz,rdma        ; Not *** EOF
  744.     ld    (hl),0        ; Mark end of string
  745.     inc    hl        ; Next byte in memory
  746.     ld    ($memry),hl    ; Is next available
  747.     xor    a        ; Set zero flag
  748.     inc    a        ; and clear it
  749. rdmb:    pop    hl        ; Return start of string
  750.     ret
  751.     end
  752.