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 / BDOS / NOVADOSI.LBR / NVDS-3.ZZ0 / NVDS-3.Z80
Text File  |  2000-06-30  |  25KB  |  802 lines

  1. ;
  2. ; Set DMA address command
  3. ;
  4. cmnd26:    ld    (dma),de        ; Save DMA address
  5. ;
  6. ; Set DMA address
  7. ;
  8. stdma:    ld    bc,(dma)        ; Get DMA address
  9.     jr    dmadr0            ; And do P2bios call
  10. ;
  11. ; Set DMA address directory
  12. ;
  13. dmadir:    ld    bc,(dirbuf)        ; Get DMA address directory
  14. dmadr0:    jp    setdma            ; P2bios call set DMA
  15. ;
  16. ; Get bit from alv buffer
  17. ;  entry de=block number
  18. ;  exit  a =bit in LSB
  19. ;        b =bitnumber in a
  20. ;        hl=pointer in alv buffer
  21. ;
  22. getbit:    ld    a,e            ; Get bit number
  23.     and    7            ; Mask it
  24.     inc    a            ; Add 1
  25.     ld    b,a            ; Save it
  26.     ld    c,a            ; Twice
  27.     srl    d            ; Get byte number
  28.     rr    e            ; De=de/8
  29.     srl    d
  30.     rr    e
  31.     srl    d
  32.     rr    e
  33.     ld    hl,(alv)        ; Get start address alv buffer
  34.     add    hl,de            ; Add byte number
  35.     ld    a,(hl)            ; Get 8 bits
  36. getbt0:    rlca                ; Get correct bit
  37.     djnz    getbt0
  38.     ld    b,c            ; Restore bit number
  39.     ret                ; And return to caller
  40. ;
  41. ; Set/reset bit in alv buffer
  42. ;  entry de=block number
  43. ;        c =0 reset bit, c=1 set bit
  44. ;
  45. setbit:    push    bc            ; Save set/reset bit
  46.     call    getbit            ; Get bit
  47.     and    0feh            ; Mask it
  48.     pop    de            ; Get set/reset bit
  49.     or    e            ; Set/reset bit
  50. setbt0:    rrca                ; Rotate bit in correct position
  51.     djnz    setbt0
  52.     ld    (hl),a            ; Save 8 bits
  53.     ret                ; And return to caller
  54. ;
  55. ; Fill bit buffer from FCB in dirbuf
  56. ;  entry c=0 reset bit, c=1 set bit
  57. ;
  58. fillbb:    call    caldir            ; Get directory entry
  59.     ld    de,16            ; Get offset dm block
  60.     add    hl,de            ; Add offset
  61.     ld    b,e            ; Get block counter
  62. fillb0:    ld    e,(hl)            ; Get LSB block number
  63.     inc    hl            ; Increment pointer
  64.     ld    d,0            ; Reset MSB block number
  65.     ld    a,(maxlen+1)        ; Test >256 blocks present
  66.     or    a
  67.     jr    z,fillb1        ; No then jump
  68.     dec    b            ; Decrement block counter
  69.     ld    d,(hl)            ; Get correct MSB
  70.     inc    hl            ; Increment pointer
  71. fillb1:    ld    a,d            ; Test block number
  72.     or    e            
  73.     jr    z,fillb2        ; Zero then get next block
  74.     push    hl            ; Save pointer
  75.     push    bc            ; Save counter and set/reset bit
  76.      ld    hl,(maxlen)        ; Get maximum length alv buffer
  77.     or    a            ; Reset carry
  78.     sbc    hl,de            ; Test de<=maxlen alv buffer 
  79.     call    nc,setbit        ; Yes then insert bit
  80.     pop    bc            ; Get counter and set/reset bit
  81.     pop    hl            ; Get pointer
  82. fillb2:    djnz    fillb0            ; Repeat for all dm entries
  83.     ret                ; And return to caller
  84. ;
  85. ; Set write protect disk command
  86. ;
  87. cmnd28:
  88. ;
  89. ; Set write protect disk
  90. ;
  91. setwpd:    ld    hl,(dskro)        ; Get disk r/o vector
  92.     call    sdrvb            ; Include drive bit
  93.     ld    (dskro),hl        ; Save disk r/o bit
  94. setfn:    ld    de,(nfiles)        ; Get maximum number of files-1 
  95.     inc    de            ; Increment it 
  96.     ld    hl,(temp0)        ; Get pointer to disk parameter block 
  97.     ld    (hl),e            ; And save number of files
  98.     inc    hl
  99.     ld    (hl),d
  100.     ret                ; And return to caller
  101. ;
  102. ; Check file r/o bit.  Returns with results of caldir in HL
  103. ;
  104. chkfro:    call    caldir            ; Get directory entry
  105. chkfr0:    
  106. ; The following code added by l.h. to disable error checking for read 
  107. ; operations and to prevent error reporting on physical extents after the 
  108. ; first if error is overridden.
  109. ;
  110.     ld    a,(rdwr)        ; Get the read/write flag
  111.     or    a            ; Is a read operation in prog. 
  112.     ret    z            ; If so, just return.
  113.     ld    a,(passfg)        ; Pass flag set?
  114.     or    a
  115.     ret    nz            ; Not first extent, error already done
  116.     dec    a            ; Set Pass flag
  117.     ld    (passfg),a        ; And save it
  118. ;
  119.     push    hl            ; Save directory entry
  120.     ld    de,2            ; Offset to public file bit
  121.     add    hl,de            ; Add offset
  122.     ld    a,(flags)
  123.     bit    4,a            ; Public r/o flag
  124.     jr    z,nopub            ; Public file flag off, then no check
  125.     bit    7,(hl)            ; Test public file
  126.     jr    nz,chkf.5        ; Yes then error
  127. nopub:    ld    e,7            ; Offset to file r/o bit
  128.     add    hl,de            ; Add offset
  129.     bit    7,(hl)            ; Test file r/o
  130.     jr    nz,chkf.5        ; Yes then error
  131. ; System files should not be r/o for CP/M compatibility-b.h.
  132. ;    inc    hl            ; Increment to system file 
  133. ;    bit    7,(hl)            ; Test system file
  134. chkf.5:    pop    hl            ; Restore directory entry pointer
  135.     ret    z            ; No system file then ok
  136.  
  137. ; Beyond this point an an error has occurred.
  138. ;
  139. chkfr1:    push    hl            ; Save directory entry for error ret
  140.     ld    a,1
  141.     ld    (retflg),a
  142.     ld    hl,(sfilro)        ; Get pointer to file r/o message
  143.     jp    (hl)            ; Display message
  144. ;
  145. ; Check drive read only
  146. ;
  147. chkro:    ld    hl,(dskro)        ; Get drive r/o vector
  148.     call    sdrvb            ; Set drive bit
  149.     sbc    hl,de            ; Test extra bit added
  150.     ret    nz            ; Yes then drive not r/o
  151.     ld    hl,(stro)        ; Get pointer to drive r/o message
  152.     jp    (hl)            ; Display message
  153. ;
  154. ; Get free block from alv buffer
  155. ;  entry de=old block number
  156. ;  exit  de=new block number (0 if no free block)
  157. ;   hl counts up,de counts down
  158. ;
  159. getfre:    ld    h,d            ; Copy old block to hl
  160.     ld    l,e
  161. getfr0:    ld    a,d            ; Test down counter is zero
  162.     or    e
  163.     jr    z,getfr1        ; Yes then jump
  164.     dec    de            ; Decrememt down counter
  165.     push    hl            ; Save up/down counter
  166.     push    de
  167.     call    getbit            ; Get bit from alv buffer
  168.     rra                ; Test if zero
  169.     jr    nc,getfr3        ; Yes then found empty block
  170.     pop    de            ; Get up/down counter
  171.     pop    hl
  172. getfr1:    ld    bc,(maxlen)        ; Get maximum alv length-1 in bc
  173.     or    a            ; Clear carry
  174.     sbc    hl,bc            ; Test hl>=length alv-1
  175.     add    hl,bc            ; Restore hl (flags are not affected)
  176.     jr    nc,getfr2        ; End buffer then jump
  177.     inc    hl            ; Increment up counter
  178.     push    de            ; Save down/up counter
  179.     push    hl
  180.     ex    de,hl            ; Save up counter in de
  181.     call    getbit            ; Get bit from alv buffer
  182.     rra                ; Test if zero
  183.     jr    nc,getfr3        ; Yes then found empty block
  184.     pop    hl            ; Get down/up counter
  185.     pop    de
  186.     jr    getfr0            ; And test next block 
  187. getfr2:    ld    a,d            ; Test if last block tested
  188.     or    e
  189.     jr    nz,getfr0        ; No then test next block
  190.     ret                ; Exit (de=0)
  191. getfr3:    scf                ; Set block number used
  192.     rla                ; Save bit
  193.     call    setbt0            ; Put bit in alv buffer
  194.     pop    de            ; Get correct counter
  195.     pop    hl            ; Restore stack pointer
  196.     ret                ; Exit (de=block number)
  197. ;
  198. ; Search for file name
  199. ;  entry: a : number of bytes to search for
  200. ;
  201. search:    ld    (searnb),a        ; Save number of bytes
  202.     ld    a,0ffh            ; Set exit code to 0ffh (not found)
  203.     ld    (searex),a
  204.     ld    (dcopy),ix        ; Copy FCB pointer to ram (search next)
  205.     call    setfct            ; Initiate file counter
  206. ; Mod 0.1 had a bug in which the directory of a changed disk would not be
  207. ; read.  Adding call home forces a directory read--b.h.
  208. ;
  209. et:    call    home
  210. ;
  211. ; Search next file name
  212. ;
  213. searcn:    xor    a            ; Check checksum directory
  214.     call    rddir            ; Get FCB from directory
  215.     call    tstfct            ; Test if past last entry
  216.     jp    z,searc8        ; Yes then jump
  217.     ld    de,(dcopy)        ; Get FCB pointer
  218.     ld    a,(de)            ; Get first byte
  219.     cp    0e5h            ; Test if searching empty directory
  220.     jr    z,searc1        ; Yes then jump
  221.     push    de            ; Save FCB pointer
  222.     call    tstlf            ; Test last file on this drive
  223.     pop    de            ; Restore FCB pointer
  224.     jr    nc,searc8        ; Yes then jump
  225. searc1:    call    caldir            ; Get entry in directory
  226.      if    dotime
  227.     ld    a,(hl)            ; Get first byte directory entry
  228.     cp    021h            ; Test time stamp
  229.     jr    z,searcn        ; Yes then get next directory entry
  230.      endif
  231.     ld    a,(searnb)        ; Get number of bytes to search for
  232.     ld    b,a            ; Save it in counter
  233.     xor    a            ; Clear accu
  234.     ld    (searqu),a        ; Clear question mark detected flag
  235.     ld    (searpu),a        ; Clear public file flag
  236.     ld    c,a            ; Clear counter
  237. searc2:    ld    a,b            ; Test if counter is zero
  238.     or    a
  239.     jr    z,searc9        ; Yes then jump
  240.     ld    a,(de)            ; Get byte from FCB
  241.     sub    '?'            ; Test if question mark
  242.     jr    z,searc6        ; Yes then jump
  243.     ld    a,c            ; Get FCB counter
  244.     or    a            ; Test first byte
  245.     jr    nz,searc3        ; No then jump
  246.     ld    a,(flags)        ; Get flag byte
  247.     bit    0,a            ; Test public file enable
  248.     jr    z,searc3        ; No then jump
  249.     inc    hl            ; Check for public file
  250.     ld    a,(hl)            ; Test for public '$'
  251.     cp    '$'
  252.     jr    nz,no$
  253.     dec    hl
  254.     jr    is$
  255. no$:    inc    hl
  256.     bit    7,(hl)            ; Test public bit directory
  257.     dec    hl            ; Restore pointer
  258.     dec    hl
  259.     jr    z,searc3        ; No public file then jump
  260. is$:    ld    a,(de)            ; Get first byte FCB
  261.     cp    0e5h            ; Test if searching empty directory
  262.     jr    z,searc3        ; Yes then jump
  263.     xor    (hl)            ; Test FCB=directory entry
  264.     and    07fh            ; Mask it
  265.     jr    z,searc5        ; Yes then jump
  266.     and    0e0h            ; Mask user number
  267.     jr    nz,searc3        ; Not the same then jump
  268.     dec    a            ; A=0ffh
  269.     ld    (searpu),a        ; Set public file found
  270.     jr    searc5            ; Jump found
  271. searc3:    ld    a,c            ; Get FCB counter
  272.     cp    13            ; Test if user code
  273.     jr    z,searc5        ; Yes then no test
  274.     cp    12            ; Test if extent number
  275.     ld    a,(de)            ; Get byte from FCB
  276.     jr    z,searc7        ; Jump if extent number
  277.     xor    (hl)            ; Test byte FCB=byte directory entry
  278.     and    07fh            ; Mask it
  279. searc4:    jr    nz,searcn        ; Not the same then get next entry
  280. searc5:    inc    de            ; Increment pointer FCB
  281.     inc    hl            ; Increment pointer directory entry
  282.     inc    c            ; Increment counter
  283.     dec    b            ; Decrement counter
  284.     jr    searc2            ; Test next byte
  285. searc6:    dec    a            ; Set question mark found flag
  286.     ld    (searqu),a        
  287.     jr    searc5            ; Jump found
  288. searc7:    push    bc            ; Save counters
  289.     xor    (hl)            ; Test extents
  290.     ld    b,a            ; Save it
  291.     ld    a,(nextnd)        ; Get extent mask
  292.     cpl                ; Complement it
  293.     and    01fh            ; Mask it
  294.     and    b            ; Mask extents
  295.     pop    bc            ; Retore counters
  296.     jr    searc4            ; And test result
  297. searc8:    call    setfct            ; Error set file counter
  298.     ld    a,0ffh            ; And set exit code
  299.     ld    (pexit),a
  300.     ret                ; Return to caller
  301. searc9:    ld    a,(searqu)        ; Get question mark found flag
  302.     ld    b,a            ; Save it
  303.     ld    a,(searpu)        ; Get public file flag
  304.     and    b            ; Test if public file and question mark
  305.     jr    nz,searc4        ; Yes then search for next entry
  306.     call    setlf            ; Update last file count (empty FCB)
  307.     ld    a,(filcnt)        ; Get file counter
  308.     and    3            ; Mask it
  309.     ld    (pexit),a        ; And set exit code
  310.     xor    a            ; Clear exit code search
  311.     ld    (searex),a
  312.     ret                ; And return to caller
  313. ;
  314. ; Delete file
  315. ;
  316. delete:    call    chkro            ; Check disk r/o
  317.     ld    hl,rdwr
  318.     dec    (hl)            ; Yes, this is a write operation
  319.     ld    a,12            ; Number of bytes to search for
  320.     call    search            ; Search file
  321. del0:    call    tstfct            ; Test if file found
  322.     ret    z            ; Not then exit
  323.     call    chkfro            ; Check file r/o
  324. ; chkfro preserves caldir results in HL, so not necessary to call again
  325. ;    call    caldir            ; Get entry point directory
  326.     ld    (hl),0e5h        ; Remove file
  327.     ld    c,0            ; Remove bits alv buffer
  328.     call    fillbb 
  329.     call    wrfcb1            ; Write directory buffer on disk
  330.     call    searcn            ; Search next entry
  331.     jr    del0            ; And test it
  332. ;
  333. ; Rename file
  334. ;
  335. renam:    call    chkro            ; Check disk r/o
  336.     ld    a,12            ; Number of bytes to search for
  337.     call    search            ; Search file
  338. renam0:    call    tstfct            ; Test if file found
  339.     ret    z            ; Not then exit
  340.     ld    hl,rdwr            ; Get read write pointer (l.h.)
  341.     dec    (hl)            ; Define this as a write op.  (l.h.)
  342.     call    chkfro            ; Check file r/o
  343.     res    7,(ix+27)        ; Don't allow archive bit on rename
  344.     ld    bc,12*256+16        ; Copy FCB+16 to directory+0 12 times
  345.     call    wrfcb            ; And write directory on disk
  346.     call    searcn            ; Search next file
  347.     jr    renam0            ; And test it
  348. ;
  349. ; Change status file
  350. ;
  351. cstat:    call    chkro            ; Check disk r/o
  352.     ld    a,12            ; Number of bytes to search for
  353.     call    search            ; Search file
  354. cstat0:    call    tstfct            ; Test if file found
  355.     ret    z            ; Not then exit, A = 0
  356.     ld    bc,12*256+0        ; Copy FCB+0 to directory+0 12 times
  357.     call    wrfcb            ; And write directory to disk
  358.     call    searcn            ; Search next file
  359.     jr    cstat0            ; And test it
  360. ;
  361. ; Compute file size
  362. ;
  363. filsz:    ld    bc,0            ; Reset file size length
  364.     ld    d,c
  365.     call    ldrrc            ; Save it in FCB+33,34,35
  366.     ld    a,12            ; Number of bytes to search for
  367.     call    search            ; Search file
  368. filsz0:    call    tstfct            ; Test if file found
  369.     ret    z            ; Not then exit
  370.     call    caldir            ; Get directory entry
  371.     ex    de,hl            ; Copy to de
  372.     ld    hl,15            ; Offset to next record
  373.     call    calrrc            ; Calculate random record count
  374.     ld    a,d            ; Test LSB < (ix+33)
  375.     sub    (ix+33)
  376.     ld    a,c            ; Test ISB < (ix+34)
  377.     sbc    a,(ix+34)
  378.     ld    a,b            ; Test MSB < (ix+35)
  379.     sbc    a,(ix+35)
  380.     call    nc,ldrrc        ; Write new maximum
  381.     call    searcn            ; Search next file
  382.     jr    filsz0            ; And test it
  383. ;
  384. ; Write FCB on disk
  385. ;
  386. wrfcb:    call    caldir            ; Get directory entry
  387.     push    hl            ; Save pointer
  388. ;    ld    a,(funct)        ; Get the function code (l.h.)
  389. ;    cp    30            ; Are we resetting the status? (l.h.)
  390. ;    jr    z,wrfcb0        ; If so, don't reset archive bit (l.h.)
  391. ;    res    7,(ix+11)        ; Reset the archive bit (l.h.)
  392. wrfcb0:    ld    a,(hl)            ; Get user code
  393.     ex    de,hl            ; Copy to de
  394.     push    ix            ; Save FCB entry
  395.     pop    hl            ; Get it in hl
  396.     push    bc            ; Save bc
  397.     ld    b,0            ; Reset b for add
  398.     add    hl,bc            ; Add offset FCB
  399.     pop    bc            ; Restore bc
  400.     ld    c,b            ; Get number of bytes to move
  401.     ld    b,0            ; Reset b for ldir
  402.     ldir                ; Move bytes
  403.     pop    hl            ; Get pointer user code
  404.     ld    (hl),a            ; Restore it
  405. wrfcb1:    call    stdir            ; Calculate sector/track directory
  406.     jp    writdr            ; Write directory on disk
  407. ;    
  408. ; Find file
  409. ;
  410. ; Modified by l.h. To access public files as well as system files in the
  411. ; search path.  Now findf uses 0ffh as the path string terminator since this
  412. ; is what comes naturally to addresses 40h + when the kaypro 10 is powered up.
  413. ;
  414. findf:    ld    a,15            ; Number of bytes to search for 
  415.     call    search            ; Search file
  416.      if    ispath
  417.     call    tstfct            ; Test if file present
  418.     ret    nz            ; Yes then exit
  419.     ld    a,(rdwr)        ; Test if write function
  420.     or    a            
  421.     ret    nz            ; Yes then exit
  422.     ld    a,(searqu)        ; Test if question mark used
  423.     or    a
  424.     ret    nz            ; Yes then exit
  425.     ld    hl,(path)        ; Get path address
  426.     ld    a,h            ; Test if zero (no path)
  427.     or    l
  428.     ret    z            ; Yes then exit
  429. findf0:    ld    a,(hl)            ; Get first entry path name
  430.     inc    hl            ; Increment pointer
  431. ;    inc    a            ; Test if last entry (l.h.)
  432.      or    a            ; Test if last entry
  433.     jp    z,searc8        ; Yes then error exit 
  434.     and    07fh            ; Mask drive number
  435.     cp    '$'            ; Test if current drive
  436.     jr    nz,findf1        ; No then jump
  437.     ld    a,(drive)        ; Get current drive
  438.     inc    a            ; Increment drive number
  439. findf1:    dec    a            ; Decrement drive number
  440.     push    hl            ; Save path pointer
  441.     call    seldk            ; Select drive
  442.     pop    hl            ; Restore path pointer
  443.     ld    a,(hl)            ; Get user number
  444.     inc    hl            ; Advance pointer
  445.     and    07fh            ; Mask user number
  446.     cp    '$'            ; Test if current user
  447.     jr    nz,findf2        ; No then jump
  448.     ld    a,(user)        ; Get current user
  449. findf2:    and    01fh            ; Mask user number
  450.     ld    b,a            ; Save it
  451.     ld    a,(ix+0)        ; Get FCB byte 0
  452.     and    0e0h            ; Remove user number
  453.     or    b            ; Add new user number
  454.     ld    (ix+0),a        ; And save it
  455.     push    hl            ; Save path pointer
  456.     ld    a,15            ; Set number of bytes to search for
  457.     call    search            ; Search file 
  458.     call    tstfct            ; Test if file present
  459.     pop    hl            ; Restore path pointer
  460.     jr    z,findf0        ; No then test next path entry
  461.     push    hl            ; Save path pointer
  462.     call    caldir            ; Get directory entry
  463.     inc    hl            ; Add offset, public bit (l.h.)
  464.     ld    a,(hl)
  465.     cp    '$'
  466.     jr    z,findf3        ; Test for '$'
  467.     inc    hl
  468.     bit    7,(hl)            ; Test public file
  469.     jr    nz,findf3
  470.     ld    de,8            ; Add offset system bit
  471.     add    hl,de
  472.     bit    7,(hl)            ; Test system file
  473. findf3:    pop    hl            ; Restore path pointer
  474.     jr    z,findf0        ; No system file then test next path
  475.                     ;  entry
  476.     ld    a,(defdrv)        ; Get current drive
  477.     inc    a            ; Increment drive number
  478.     ld    (fcb0),a        ; Save it in exit FCB0
  479.      endif
  480.     ret                ; And return to caller
  481. ;
  482. ; Open file command
  483. ;
  484. cmnd15:    
  485.     call    seldrv            ; Select drive from FCB
  486.     ld    (ix+14),0        ; Clear FCB+14
  487. ;
  488. ; Open file
  489. ;
  490. openf:    call    findf            ; Find file (use path name)
  491.     call    tstfct            ; Test file found
  492.     ret    z            ; No then exit
  493. openf0:    ld    a,(ix+12)        ; Get extent number from FCB
  494.     push    af            ; Save it
  495.     call    caldir            ; Get directory entry
  496.     push    ix            ; Save FCB entry
  497.     pop    de            ; Get in in de
  498.     ld    bc,32            ; Number of bytes to move
  499.     ldir                ; Move directory to FCB
  500.     set    7,(ix+14)        ; Set FCB/file not modified
  501.     ld    b,(ix+12)        ; Get extent number
  502.     ld    c,(ix+15)        ; Get next record number
  503.     pop    af            ; Get old extent number
  504.     ld    (ix+12),a        ; Save it
  505.     cp    b            ; Compare old and new extent number
  506.     jr    z,openf1        ; Same then jump
  507.     ld    c,0            ; Set next record count to 0
  508.     jr    nc,openf1        ; Old extent >= new extent then jump
  509.     ld    c,80h            ; Set next record count to maximum
  510. openf1:    ld    (ix+15),c        ; Save next record count
  511.     ret                ; And return to caller
  512. ;
  513. ; Close file command
  514. ;
  515. cmnd16:    call    seldrv            ; Select drive from FCB
  516. ;
  517. ; Close file
  518. ;
  519. close:    bit    7,(ix+14)        ; Test FCB/file modified
  520.     ret    nz            ; Not then no close required
  521.     call    chkro            ; Test disk r/o
  522.     ld    a,15            ; Number of bytes to search for
  523.     call    search            ; Search file
  524.     call    tstfct            ; Test file present
  525.     ret    z            ; No then exit
  526.     call    chkfro            ; Check file r/o
  527. ; chkfro preserves results of caldir in HL
  528. ;    call    caldir            ; Get directory entry
  529.     ld    bc,16            ; Offset to dm block 
  530.     add    hl,bc            ; Add offset
  531.     ex    de,hl            ; Save hl in de
  532.     push    ix            ; Save FCB pointer
  533.     pop    hl            ; Get it in hl
  534.     add    hl,bc            ; Add offset
  535.     ld    a,(maxlen+1)        ; Test number of block >= 256
  536.     or    a            
  537.     jr    z,close0        ; No then jump
  538.     dec    b            ; Set flag
  539. close0:    call    copydm            ; Copy and test blocks
  540.     ex    de,hl            ; Exchange copy direction
  541.     call    copydm            ; Copy and test blocks
  542.     ex    de,hl            ; Exchange copy direction
  543.     jr    nz,close4        ; Block not the same then error
  544.     inc    hl            ; Increment pointer FCB
  545.     inc    de            ; Increment pointer directory
  546.     bit    0,b            ; Test number of block >= 256
  547.     jr    z,close1        ; No then jump
  548.     inc    hl            ; Increment pointer FCB
  549.     inc    de            ; Increment pointer directory
  550.     dec    c            ; Decrement counter
  551. close1:    dec    c            ; Decrement counter
  552.     jr    nz,close0        ; Not ready then jump
  553.     ld    hl,-20            ; Add -20 to get extent number
  554.     add    hl,de            ; Hl contains pointer to extent number
  555. ;    dec    hl            ; Hl points to byte with archive bit (l.h.)
  556. ;    res    7,(hl)            ; Reset the archive bit
  557. ;    inc    hl            ; Put hl back to extent number
  558.     ld    a,(ix+12)        ; Get extent number FCB
  559.      cp    (hl)            ; Compare with extent number directory
  560.     jr    c,close3        ; FCB < directory then jump
  561.     ld    (hl),a            ; Save extent number in directory
  562.     inc    hl            ; Get pointer to next record
  563.     inc    hl
  564.     inc    hl
  565.     ld    a,(ix+15)        ; Get next record FCB
  566. ;
  567. ; These lines have to be removed to let submit work correctly
  568. ;
  569. ;    Jr    nz,close2        ; Extents not equal then jump
  570. ;    cp    (hl)            ; Test FCB < directory
  571. ;    jr    c,close3        ; If so then jump
  572. ;
  573. close2:    ld    (hl),a            ; Save next record in directory
  574. close3:    
  575.     if    dotime
  576.     ld    e,5            ; Set last update date/time
  577.     call    stime            ; Update time
  578.     endif
  579.     jp    wrfcb1            ; Write FCB on disk
  580. close4:    ld    a,0ffh            ; Flag error
  581.     ld    (pexit),a 
  582.     ret                ; And return to caller
  583. ;
  584. ; Copy and test disk map
  585. ;  entry : hl : pointer to first FCB
  586. ;          de : pointer to second FCB
  587. ;          b  : 000h less then 256 blocks
  588. ;               0ffh more or equal to 256 blocks
  589. ;  exit  : zero : 1 blocks are the same
  590. ;                 0 blocks are not the same
  591. ;
  592. copydm:    ld    a,(hl)            ; Get byte first FCB
  593.     bit    0,b            ; Test number of blocks >=256
  594.     jr    z,copyd0        ; No then jump
  595.     inc    hl            ; Increment pointer
  596.     or    (hl)            ; Test byte =0
  597.     dec    hl            ; Decrement pointer
  598. copyd0:    or    a            ; Test block number is zero
  599.     jr    nz,copyd1        ; No then compare blocks
  600.     ld    a,(de)            ; Copy block from other FCB in empty 
  601.                     ; location
  602.     ld    (hl),a 
  603.     bit    0,b            ; Test number of blocks >=256
  604.     ret    z            ; No then exit
  605.     inc    hl            ; Increment to MSB block numbers
  606.     inc    de
  607.     ld    a,(de)            ; Copy block from other FCB in empty 
  608.                     ; location
  609.     ld    (hl),a
  610.     jr    copyd2            ; Jump trick to save space
  611. copyd1:    ld    a,(de)            ; Get block number first FCB
  612.     sub    (hl)            ; Test if the same
  613.     ret    nz            ; Not then return
  614.     or    b            ; Test if >=256 blocks
  615.     ret    z            ; No then return
  616.     inc    hl            ; Increment to MSB block numbers
  617.     inc    de
  618. copyd2:    ld    a,(de)            ; Get block number first FCB
  619.     sub    (hl)            ; Test if the same
  620.     dec    hl            ; Decrement block FCB pointers
  621.     dec    de
  622.     ret                ; And exit to caller
  623. ;
  624. ; Make file command
  625. ;
  626. cmnd22:    call    seldrv            ; Select drive from FCB
  627.     ld    (ix+14),0        ; Clear FCB+14
  628. ;
  629. ; Make file
  630. ;
  631. make:
  632.     call    chkro            ; Check drive r/o
  633.     ld    a,(ix+0)        ; Get first byte FCB
  634.     push    af            ; Save it
  635.     ld    (ix+0),0e5h        ; Set first byte to empty file
  636.     ld    a,1            ; Search for 1 byte
  637.     call    search            ; Search empty file
  638.     pop    af            ; Get first byte FCB
  639.     ld    (ix+0),a        ; Restore it
  640.     call    tstfct            ; Test empty file found
  641.     ret    z            ; No then return error
  642.     xor    a            ; Clear FCB+13
  643.     ld    (ix+13),a
  644.     push    ix            ; Save FCB pointer
  645.     pop    hl            ; Get it back in hl
  646.     ld    de,15            ; Prepare offset
  647.     add    hl,de            ; Add it
  648.     ld    b,17            ; Set loop counter
  649. make0:    ld    (hl),a            ; Clear FCB+15 unp to FCB+31
  650.     inc    hl            ; Increment pointer
  651.     djnz    make0            ; And clear all bytes
  652.     call    caldir            ; Get directory entry
  653.     ld    a,(ix+0)        ; Get first byte FCB
  654.     ld    (hl),a            ; Save it in directory (write FCB 
  655.                     ; needs this)
  656.     if    dotime
  657.     ld    e,1            ; Set creation date/time
  658.     call    stime            ; Update time in directory 
  659.     ld    e,5            ; Set last update date/time
  660.     call    stime            ; Update time in directory
  661.     endif
  662. ;
  663.     ld    bc,32*256+0        ; Copy FCB+0 to directoty+0 32 times
  664.     call    wrfcb            ; Write FCB on disk
  665.     set    7,(ix+14)        ; Set FCB/file not modified
  666.     ret                ; And return to caller
  667. ;
  668. ; Open next extent
  669. ;
  670. openex:    bit    7,(ix+14)        ; Test if FCB/file modified (write)
  671.     jr    nz,openx2        ; Not then jump
  672.     call    close            ; Close current FCB
  673.     ld    a,(pexit)        ; Get exit code
  674.     inc    a            ; Test if error
  675.     ret    z            ; Yes then exit
  676.     call    calnex            ; Calculate next extent
  677.     jr    c,openx3        ; Error then jump
  678.     jr    nz,openx5        ; FCB present from close then jump
  679. openx0:    ld    a,15            ; Search first 15 bytes
  680.     call    search            ; Search for file
  681. openx1:    call    tstfct            ; Test if file found
  682.     jr    nz,openx5        ; Yes then jump
  683.     ld    a,(rdwr)        ; Test read/write flag
  684.     or    a            ; Test if read
  685.     jr    z,openx3        ; Yes then error
  686.     call    make            ; Make new extent if write
  687.     call    tstfct            ; Test if succesfull
  688.     jr    nz,openx6        ; Yes then exit
  689.     jr    openx3            ; No then error
  690. ;
  691. openx2:    call    calnex            ; Calculate next extent
  692.     jr    c,openx3        ; Error then jump
  693.     bit    7,(ix+10)        ; Test system file bit
  694.     jr    z,openx0        ; No system file then jump
  695.     call    findf            ; Search path for file
  696.     jr    openx1            ; Use same routine
  697. ;
  698. openx3:    set    7,(ix+14)        ; Set FCB/file not modified 
  699.     ld    a,0ffh            ; Set exit code
  700. openx4:    ld    (pexit),a        
  701.     ret                ; And return to caller
  702. ;
  703. openx5:    call    openf0            ; Open file
  704. openx6:    xor    a            ; And clear exit code
  705.     jr    openx4            ; Use same routine 
  706. ;
  707. ; Calculate next extent
  708. ;  exit: carry=1 => overflow detected
  709. ;        zero =1 => search next extent
  710. ;     zero =0 => next extent present (close)
  711. ;
  712. calnex:    ld    b,(ix+12)        ; Get extent number
  713.     ld    c,(ix+14)        ; Get FCB+14
  714.     bit    6,c            ; Test error bit random record
  715.     scf                ; Set error flag
  716.     ret    nz            ; Non zero then error exit
  717.     inc    b            ; Increment extent number
  718.     ld    a,b            ; Get extent number
  719.     and    01fh            ; Mask it
  720.     ld    b,a            ; Save it in b
  721.     jr    nz,calnx0        ; Non zero then jump
  722.     inc    c            ; Increment FCB+14
  723.     ld    a,c            ; Get it in a
  724.     and    03fh            ; Mask it
  725.     ld    c,a            ; Save it in c
  726.     scf                ; Set error flag
  727.     ret    z            ; And return if file overflow
  728.     xor    a            ; Clear zero flag (not same extent)
  729.     jr    calnx1            ; And save extent number and FCB+14
  730. calnx0:    ld    a,(nextnd)        ; Get next extent mask
  731.     and    b            ; Test if same extent (close)
  732. calnx1:    ld    (ix+12),b        ; Save extent number
  733.     ld    (ix+14),c        ; Save FCB+14
  734.     ret                ; And return to caller
  735. ;
  736. ; Read random record command
  737. ;
  738. cmnd33:    call    seldrv            ; Select drive from FCB
  739. ;
  740. ; Read random sector
  741. ;
  742. rdran:    xor    a            ; Set read/write flag
  743.     call    ldfcb            ; Load random record in FCB
  744.     jr    z,reads            ; No error then read sector
  745.     ret                ; Return error 
  746. ;
  747. ; Read sequential
  748. ;
  749. cmnd20:    call    seldrv            ; Select drive from FCB
  750. ;
  751. ; Read sector
  752. ;
  753. reads:    xor    a            ; Set read/write flag
  754.     ld    (rdwr),a        ; Save it
  755.     ld    a,(ix+32)        ; Get record counter
  756.     cp    080h            ; Test if last record this extent
  757.     jr    nc,reads1        ; Yes then open next extent
  758.     cp    (ix+15)            ; Test if greater then current record
  759.     jr    c,reads2        ; No then get record
  760. reads0:    ld    a,1            ; Set end of file flag
  761.     ld    (pexit),a        ; Save it
  762.     ret                ; And return to caller
  763. reads1:    call    openex            ; Open next extent
  764.     ld    a,(pexit)        ; Get exit code
  765.     or    a
  766.     jr    nz,reads0        ; Yes then end of file
  767.     ld    (ix+32),a        ; Clear record counter
  768. reads2:    call    getdm            ; Get block number from dm in FCB
  769.     ld    a,d            ; Test block number = 0
  770.     or    e
  771.     jr    z,reads0        ; Yes then end file
  772.     call    calsec            ; Calculate sector number (128 bytes)
  773.     call    calst            ; Calculate sector/track number
  774.     call    readr            ; Read data
  775.     ld    a,(funct)        ; Get function number
  776.     cp    20            ; Test if read sequential
  777.     ret    nz            ; No then return
  778.     inc    (ix+32)            ; Increment next record counter
  779.     ret                ; And return to caller
  780. ;
  781. ; Write random sector with zero fill command
  782. ;
  783. cmnd40:    call    seldrv            ; Select drive from FCB
  784. ;
  785. ; Write random sector with zero fill
  786. ;
  787. wrranz:    ld    a,0ffh            ; Set read/write flag
  788.     call    ldfcb            ; Load FCB from random record
  789.     jr    z,writes        ; No error then write record
  790.     ret                ; Return error
  791. ;
  792. ; Write random record command
  793. ;
  794. cmnd34:    call    seldrv            ; Select drive from FCB
  795. ;
  796. ; Write random sector
  797. ;
  798. wrran:    ld    a,0ffh            ; Set read/write flag
  799.     call    ldfcb            ; Load FCB from random record
  800.     jr    z,writes        ; No error then write record
  801.     ret                ; Return error
  802.