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-2.ZZ0 / NVDS-2.Z80
Text File  |  2000-06-30  |  21KB  |  804 lines

  1. ;******************************************************************************
  2. ;*                                          *
  3. ;*     DISK FUNCTIONS                                  *
  4. ;*                                          *
  5. ;******************************************************************************
  6. ;
  7. ; Return version number
  8. ;
  9. cmnd12:    ld    a,22h            ; Set version number
  10.     jr    cmd25a            ; and exit
  11. ;
  12. ; Reset disk system
  13. ;
  14. cmnd13:    
  15.      if    resdsk and not resflag
  16. ; detect change between single and double sided disks if this function is
  17. ; supported.--b.h.
  18.     ld    a,(flags)        ; Check full system reset flag
  19.     bit    5,a
  20.     jr    z,cmnd13a            ; If not set, we can't do setdisk
  21.     call    setdsk        
  22.      endif    
  23. cmnd13a:ld    hl,0            ; Load zero
  24.     ld    (login),hl        ; All drives loged out
  25.      if    runlog
  26.     ld    (dskro),hl        ; All drives read/write
  27.      endif
  28.     ld    hl,ramlow+80h        ; Set up DMA address
  29.     ld    (dma),hl        ; And save it
  30.     call    stdma             ; Do P2bios call
  31.     xor    a            ; Set default drive = 'a'
  32.     ld    (defdrv),a        ; Save it
  33.     call    seldk            ; Select drive 'a'
  34.     ld    a,(subflg)        ; Get submit flag
  35.     jr    cmd25a            ; Exit
  36. ;
  37. ; Search for file
  38. ;
  39. cmnd17:    
  40.     call    seldrv            ; Select drive from FCB
  41.     ld    a,(ix+0)        ; Get drive number from FCB
  42.     sub    '?'            ; Test if '?'
  43.     jr    z,cmd17b        ; If so all entries match
  44.     ld    a,(ix+14)        ; Get system byte
  45.     cp    '?'            ; Test if '?' 
  46.     jr    z,cmd17a        ; Yes, jump
  47.     ld    (ix+14),0        ; Load system byte with zero
  48. cmd17a:    ld    a,15            ; Test first 15 items in FCB
  49. cmd17b:    call    search            ; Do search
  50. cmd17c:    ld    hl,(dirbuf)        ; Copy directory buffer 
  51.     ld    de,(dma)        ; To DMA address
  52.     ld    bc,128            ; Directory=128 bytes 
  53.     ldir
  54.     ret                ; Exit
  55. ;
  56. ; Search for next occurence file
  57. ;
  58. cmnd18:    ld    ix,(dcopy)        ; Get last FCB used by search
  59.     call    seldrv            ; Selext drive from FCB
  60.     call    searcn            ; Search next file match
  61.     jr    cmd17c            ; And copy directory to DMA address
  62. ;
  63. ; Delete file
  64. ;
  65. cmnd19:    
  66.     call    seldrv            ; Select drive from FCB
  67.     call    delete            ; Delete file
  68. cmd19a:    ld    a,(searex)        ; Get exit byte 00=file found,0ffh not
  69.     jr    cmd25a            ; And exit
  70. ;
  71. ; Rename file
  72. ;
  73. cmnd23:    
  74.     call    seldrv            ; Select drive from FCB
  75.     call    renam            ; Rename file
  76.     jr    cmd19a            ; And exit
  77.  
  78. ;
  79. ; Return permanent medium vector
  80. ;
  81.      if    hifuncs
  82. permdsk:
  83.     ld    hl,(pmedia)
  84.     jr    cmd24a
  85.      endif
  86. ;
  87. ; Return login vector
  88. ;
  89. cmnd24:    ld    hl,(login)        ; Get login vector
  90. cmd24a:    ld    (pexit),hl        ; Save it
  91.     ret                ; And exit
  92. ;
  93. ; Return current drive
  94. ;
  95. cmnd25:    ld    a,(defdrv)        ; Get current drive
  96. cmd25a:    jp    exit            ; And exit
  97. ;
  98. ; Return alv vector
  99. ;
  100. cmnd27:    ld    hl,(alv)        ; Get allocation vector
  101.     jr    cmd24a            ; And exit
  102. ;
  103. ; Return disk r/o vector
  104. ;
  105. cmnd29:    ld    hl,(dskro)        ; Get disk r/o vector
  106.     jr    cmd24a            ; And exit
  107. ;
  108. ; Change status
  109. ;
  110. cmnd30:    call    seldrv            ; Select drive from FCB
  111.     call    cstat            ; Change status
  112.     jr    cmd19a            ; And exit
  113. ;
  114. ; Return drive table
  115. ;
  116. cmnd31:    ld    hl,(ixp)        ; Get drive table
  117.     jr    cmd24a            ; And exit
  118.  
  119.     
  120.     if    hifuncs
  121. ;
  122. ; Return DMA address
  123. ;
  124. getdma:    ld    hl,(dma)
  125.     jr    cmd24a
  126.     
  127. ;
  128. ; Return a ZRDOS compatible version number
  129. ;
  130. zrdos:    ld    hl,zrvers
  131.     jr    cmd24a
  132.      endif
  133. ;
  134. ; Set/get user code
  135. ;
  136. cmnd32:    inc    a            ; Test if 0ffh
  137.     ld    a,(user)        ; Get old user code
  138.     jr    z,cmd25a        ; If 0ffh then exit
  139.     ld    a,e            ; Get new user code
  140.     and    01fh            ; Mask it
  141.     ld    (user),a        ; Save it
  142.     ret                ; And exit
  143. ;
  144. ; Compute file size command
  145. ;
  146. cmnd35:    call    seldrv            ; Select drive from FCB
  147.     call    filsz            ; Compute file size
  148.     jr    cmd19a            ; And exit
  149. ;
  150. ; Set random record count
  151. ;
  152. cmnd36:    ld    hl,32            ; Set pointer to next record
  153.     call    calrrc            ; Calculate random record count
  154. ldrrc:    ld    (ix+33),d        ; And save random record count
  155.     ld    (ix+34),c
  156.     ld    (ix+35),b
  157.     ret                ; And exit
  158. ;
  159. ; Reset multiple login drive
  160. ;
  161. cmnd37:    
  162.     cpl                ; Complement it
  163.     ld    e,a 
  164.     ld    a,d            ; Get mask MSB
  165.     cpl                ; Complement it
  166.     ld    d,a
  167.     ld    hl,(login)        ; Get login vector
  168.     ld    a,e            ; Mask login vector
  169.     and    l            ; LSB
  170.     ld    l,a
  171.     ld    a,d            ; Mask login vector
  172.     and    h            ; MSB
  173.     ld    h,a
  174.     ld    (login),hl        ; Save login vector
  175.      if    runlog            ; If resetting unlogged-in disks
  176.     ex    de,hl            ; Use login vector as mask
  177.      endif                ; Otherwise reset only those in mask
  178.     ld    hl,(dskro)        ; Get drive r/o vector
  179.     ld    a,e            ; Mask drive r/o vector
  180.     and    l            ; LSB
  181.     ld    l,a
  182.     ld    a,d            ; Mask drive r/o vector
  183.     and    h            ; LSB
  184.     ld    h,a
  185.     ld    (dskro),hl        ; Save drive r/o vector
  186. ;
  187. dbl:
  188. ; Code removed by L.H.  Resdsk causes problems on a fast boot system and
  189. ; clrdsk trashes the login vector which the above routine so carefully sets.
  190. ;
  191. ;    exx
  192. ;    if    resdsk
  193. ;    call    setdsk
  194. ;    endif
  195. ;    call    initdr
  196. ;    exx
  197.     ret
  198. ;
  199. ;********************************
  200. ;*     error routines        *
  201. ;*                *
  202. ;********************************
  203. ;
  204. ;
  205. ; Select error
  206. ;
  207. selerr:    ld    de,msel            ; Load select error message
  208.     ld    b,2
  209.     jr    derror            ; And diplay error
  210. ;
  211. ; File read only error
  212. ;
  213. filro:    ld    de,mfilro        ; Load file r/o message
  214.     ld    a,0ffh            ; Set file r/o message flag
  215.     ld    b,4
  216.     jr    error            ; And display error
  217. ;
  218. ; Read error message--b.h.
  219. ;
  220. rderr:    ld    de,mrderr
  221.     ld    b,1
  222.     jr    derror
  223. ;
  224. ; Write error message--b.h.
  225. wrterr:    ld    de,mwrter
  226.     ld    b,5
  227.     jr    derror
  228. ;
  229. ; Drive read only error
  230. ;
  231. rdonly:    ld    de,mro            ; Load drive r/o message
  232. derror:    xor    a            ; Set no file r/o message
  233. ;
  234. ;
  235. ; Display error message
  236. ;
  237. ; P2dos error on d: error message
  238. ; function = nn  [file = filename.typ]
  239. ;
  240. error:    ld    c,a            ; Save file r/o message flag
  241.     push    bc
  242.     push    de            ; Save error message pointer
  243.  
  244.     ld    a,(defdrv)        ; Get current drive
  245.     ld    e,a            ; Save drive in E in case of trap
  246.     add    a,'A'            ; Make ascii
  247.     ld    (mdrive),a        ; Save it
  248.  
  249.      if    hifuncs
  250.     ld    a,(trapflag)        ; If wb trap, then no messages
  251.     or    a
  252.     ld    a,b            ; Get ZRDOS error number in A
  253.     jp    nz,error5
  254.      endif
  255.     
  256.     call    crout            ; Diplay cr/lf
  257.  
  258.     ld    de,mberr        ; Load message "P2dos error on d:"
  259.     call    mess            ; Display message
  260.     pop    de            ; Get error message pointer
  261.     call    mess            ; Display message
  262.     call    crout            ; Display cr/lf
  263.     ld    de,mbfunc        ; Load message "function ="
  264.     call    mess            ; Display message
  265.     ld    a,(funct)        ; Get function number
  266.     push    af            ; Save it
  267.     ld    bc,100            ; Display number / 100
  268.     call    num
  269.     ld    c,10            ; Display number / 10
  270.     call    num
  271.     ld    bc,101h            ; Always display number / 1
  272.     call    num
  273.     pop    af            ; Get function number
  274.     pop    bc            ; Get file r/o flag
  275.     cp    15            ; Test if FCB used in command
  276.     jr    c,error3
  277.     cp    24
  278.     jr    c,error1
  279.     cp    30
  280.     jr    z,error1
  281.     cp    33
  282.     jr    c,error3
  283.     cp    37
  284.     jr    c,error1
  285.     cp    40
  286.     jr    nz,error3
  287. error1:    push    ix            ; Yes then display "file ="
  288.     sub    19            ; Test delete file function
  289.     jr    nz,error2        ; Not then jump
  290.     or    c            ; Test file r/o flag
  291.     jr    z,error2        ; No file r/o then jump
  292.     call    caldir            ; Get FCB from directory buffer
  293.     ex    (sp),hl            ; Save it
  294. error2:    ld    de,mfile        ; Get message " file ="
  295.     call    mess            ; Display message
  296.     pop    hl            ; Get pointer FCB
  297.     ld    b,8            ; Display fisrt 8 characters
  298.     call    filenm
  299.     ld    a,'.'            ; Load '.'
  300.     push    hl            ; Save FCB pointer
  301.     call    wrcon            ; Echo it
  302.     pop    hl            ; Restore FCB pointer
  303.     ld    b,3            ; Display last 3 characters 
  304.     call    filenm
  305. error3:    call    gconst            ; Test if character present
  306.     or    a
  307.     jr    z,error4        ; No then jump
  308.     call    getch            ; Get character
  309.     jr    error3            ; And test again
  310. error4:    call    getch            ; Get character
  311. ; P2dos had a bug which did not allow the user to ignore a read/write error
  312. ; by hitting a key other than control-c. This is the fix.--b.h.
  313. ;
  314. ; Modified by l.h. to escape errors ONLY if the error ignore key is entered.
  315. ; This key is defined in the header file.
  316. ;
  317.     pop    hl            ; Restore directory entry
  318.      if    erresc gt 0
  319.     push    af            ; Save it
  320.     ld    a,(retflg)        ; Get retflg
  321.     or    a
  322.     jr    z,error5
  323.     pop    af
  324.     cp    erresc
  325.     ret    z
  326.      endif
  327. trap    equ    $+1            ; Warm boot trap address
  328. error5:    jp    ramlow            ; And do warm boot
  329. error5a:xor    a
  330.     jr    error5
  331. ;
  332. ; Display number
  333. ;
  334. num:    ld    d,0ffh            ; Load number -1
  335. num1:    inc    d            ; Increment number
  336.     sub    c            ; Divide by c
  337.     jr    nc,num1            ; Not finished then loop
  338.     add    a,c            ; Restore last value
  339.     push    af            ; Save it
  340.     ld    a,d            ; Test if "0"
  341.     or    b            ; And if leading zero
  342.     jr    z,num2            ; Yes, then exit 
  343.     ld    b,d            ; Set no leading zero 
  344.     ld    a,d            ; Get number
  345.     add    a,'0'            ; Make ascii
  346.     push    bc            ; Save registers
  347.     call    wrcon            ; Echo number
  348.     pop    bc            ; Restore registers
  349. num2:    pop    af            ; Restore number
  350.     ret                ; And exit
  351. ;
  352. ; Display filname.typ
  353. ;
  354. filenm:    inc    hl            ; Increment pointer FCB
  355.     ld    a,(hl)            ; Get character from FCB
  356.     and    07fh            ; Mask it
  357.     push    hl            ; Save registers
  358.     push    bc
  359.     call    wrcon            ; Echo character
  360.     pop    bc            ; Restore registers
  361.     pop    hl
  362.     djnz    filenm            ; Repeat b times
  363.     ret                ; And exit
  364. ;
  365. ; Error messages
  366. ; made more meaningful-b.h.
  367. ;
  368. ; Bad sector message replaced by read/write error messages
  369. ;mbadsc:    db    'Bad sector$'
  370. ;
  371. msel:    db    'Drive ?$'
  372. ;
  373. mfilro:    db    'File '
  374. ;
  375. mro:    db    'R/O$'
  376. ;
  377. mberr:    db    'Error, Disk '
  378. mdrive:    db    0
  379.     db    drvsep
  380.     db    ' $'
  381. ;
  382. mbfunc:    db    'Fnc: $'
  383. ;
  384. mfile:    db    '; File: $'
  385. ;
  386. mrderr:    db    'Read Err$'
  387. ;
  388. mwrter:    db    'Write Err$'
  389. ;
  390. ; Select disk from FCB
  391. ;
  392. seldrv:    ld    a,0ffh            ; Set disk select done flag
  393.     ld    (fldrv),a
  394.     ld    a,(defdrv)        ; Get current drive
  395.     ld    (drive),a        ; Save it in memory
  396.     ld    e,a            ; Save it in register e
  397.     ld    a,(ix+0)        ; Get drive from FCB
  398.     ld    (fcb0),a        ; Save it
  399.     cp    '?'            ; Test if '?'
  400.     jr    z,cmnd14        ; Yes, then select drive from register e
  401.     and    01fh            ; Mask drive
  402.     ld    a,e            ; Test if zero
  403.     jr    z,seldr0        ; Select drive from register e
  404.     ld    a,(ix+0)        ; Get drive from FCB
  405.     dec    a            ; Decrement drive
  406. seldr0:    call    seldk            ; Select drive
  407.     ld    a,(ix+0)        ; Get drive from FCB
  408.     and    0e0h            ; Remove drive bits
  409.     ld    b,a            ; Save register
  410.     ld    a,(user)        ; Get user number
  411.     or    b            ; Insert user number in FCB
  412.     ld    (ix+0),a
  413.     ret                ; And exit
  414.  
  415. ;       
  416. ; Select disk
  417. ;
  418. cmnd14:    ld    a,e            ; Get drive in A
  419. ;
  420. ; Select disk
  421. ;
  422. seldk:    and    0fh            ; Mask drive number
  423.     ld    b,a            ; Save counter
  424.     ld    de,(login)        ; Get login vector
  425.     or    a            ; Test drive 'a'
  426.     jr    z,seldk1        ; Yes then jump
  427. seldk0:    rr    d            ; Shift login vector
  428.     rr    e            ; Until bit 0 register e
  429.     djnz    seldk0            ; Is current drive
  430. seldk1:    ld    hl,defdrv        ; Get pointer last drive
  431.     bit    0,e            ; Test if drive logged in
  432.     jr    z,seldk2        ; No, login drive
  433.     cp    (hl)            ; Test same drive
  434.     ret    z            ; Yes then exit
  435. seldk2:    ld    (hl),a            ; Save new current drive
  436.     push    de            ; Save drive logged in flag
  437.     ld    c,a            ; Copy drive number
  438.     call    seldsk            ; Do P2bios select 
  439.     ld    a,h            ; Test if error 
  440.     or    l
  441.     jr    z,seldk3        ; Yes, illegal drive number
  442.     ld    e,(hl)            ; Get LSB translation vector
  443.     inc    hl            ; Increment pointer
  444.     ld    d,(hl)            ; Get MSB translation vector
  445.     inc    hl            ; Increment pointer
  446.     ld    (trans),de        ; Save translation vector
  447.     ld    (temp0),hl        ; Save address temp0
  448.     ld    de,06            ; Increment to next address
  449.     add    hl,de
  450.     ld    de,dirbuf        ; Load dirbuf pointer
  451.     ld    bc,8            ; Copy 8 bytes
  452.     ldir
  453.     ld    hl,(ixp)        ; Get drive parameter address
  454.     ld    c,15            ; Copy 15 bytes
  455.     ldir
  456.     pop    de            ; Get drive logged in flag
  457.     bit    0,e            ; Test it
  458.     ret    nz            ; Drive logged in so return
  459.     ld    hl,(login)        ; Get login vector
  460.     call    sdrvb            ; Set drive bit in login vector
  461.     ld    (login),hl        ; Save login vector
  462.      if    hifuncs
  463.     ld    hl,(ncheck)        ; Get number of records to check
  464.     ld    a,h            ; If zero, then permanent medium 
  465.     or    l
  466.     jr    nz,initflpy        ; So don't set permedia table
  467.     ld    hl,(pmedia)        ; Get permanent medium vector
  468.     call    sdrvb            ; Set drive bit
  469.     ld    (pmedia),hl        ; Save perm. medium vector
  470.     sbc    hl,de            ; Check if drive just made perm
  471.     jr    nz,initdr        ; If bit added, then init
  472.     ld    hl,(temp0)
  473.     ld    a,(hl)            ; Get number of files
  474.     inc    hl            ; If it's zero, then init the dir
  475.     or    (hl)
  476.     jr    z,initdr
  477.     ld    a,(flags)        ; Check if auto-init
  478.     bit    5,a            ; Bit 5, pmedia auto-init
  479.     ret    z            ; If not set, then don't init drive. 
  480.      endif
  481.     jr    initdr            ; And setup drive tables
  482. seldk3:    ld    hl,(stsel)        ; Load error message address
  483.     jp    (hl)            ; And display error
  484. ;
  485. ; Init drive
  486. ;  clear alv bit buffer after drive reset
  487. ;
  488. initflpy:                ; If using resdsk, arrive here only
  489.      if    resdsk and resflag    ; for logging in floppy drives.
  490.     rflgmac                ; Code for macro in header file 
  491.      endif
  492. initdr:    ld    de,(maxlen)        ; Get length alv buffer-1 (bits)
  493.     ld    a,3            ; Divide by 8
  494. initd0:    srl    d            ; To get bytes
  495.     rr    e
  496.     dec    a
  497.     jr    nz,initd0
  498.     inc    de            ; Increment, so all bits are cleared
  499.     ld    hl,(alv)        ; Get pointer alv buffer
  500.     push    hl
  501. initd1:    ld    (hl),0            ; Clear 8 bits
  502.     inc    hl            ; Increment pointer
  503.     dec    de            ; Decrement counter
  504.     ld    a,d            ; Test if counter zero
  505.     or    e
  506.     jr    nz,initd1        ; Not then jump
  507.     pop    hl            ; Get alv pointer
  508.     ld    de,(ndir0)        ; Get first two bytes alv buffer 
  509.     ld    (hl),e            ; Save LSB
  510.     inc    hl            ; Increment pointer
  511.     ld    (hl),d            ; Save MSB
  512.     ld    hl,(temp0)        ; Clear number of files
  513.     xor    a            ; On this drive
  514.     ld    (hl),a            ; Clear LSB
  515.     inc    hl            ; Increment pointer
  516.     ld    (hl),a            ; Clear MSB
  517.     ld    (subflg),a        ; Clear submit flag (reset disk command)
  518.     call    setfct            ; Set file count
  519. initd2:    ld    a,0ffh            ; Update directory checksum
  520.     call    rddir            ; Read FCB's from directory
  521.     call    tstfct            ; Test last FCB
  522.     ret    z            ; Yes then exit
  523.     call    caldir            ; Calculate entry point FCB
  524.     ld    a,(hl)            ; Get first byte FCB
  525.     cp    0e5h            ; Test empty directory entry
  526.     jr    z,initd2        ; Yes then get next FCB
  527.     cp    021h            ; Test time stamp
  528.     jr    z,initd2        ; Yes then get next FCB
  529.  
  530. ; The next 3 lines must be removed if reset disk is to flag a $$*.* file on
  531. ; any user area rather than just the current user area. (Release E)
  532. ;    ld    a,(user)        ; Get user number
  533. ;    cp    (hl)            ; Test if user is same
  534. ;    jr    nz,initd3        ; No then jump
  535.     inc    hl            ; Point to file name
  536.     ld    a,(hl)            ; Get first char filename
  537.     cp    '$'            ; Test if '$'
  538.     jr    nz,initd3        ; Not then jump
  539.     inc    hl            ; Check for a second '$'
  540.     sub    (hl)            ; to compensate for public '$' files
  541.     jr    nz,initd3        ; Not there? then jump
  542.     dec    a            ; Load a with 0ffh
  543.     ld    (subflg),a        ; Save it in subflg 
  544. initd3:    ld    c,1            ; Set bit in alv buffer
  545.     call    fillbb            ; Set bits from FCB in alv buffer
  546.     call    setlf            ; Update last file count
  547.     jr    initd2            ; And get next FCB
  548. ;
  549. ; Set drive bit in hl
  550. ;
  551. sdrvb:    ex    de,hl            ; Copy hl=>de 
  552.     ld    hl,1            ; Get mask drive "a"
  553.     ld    a,(defdrv)        ; Get current drive
  554.     or    a            ; Test if drive "a"
  555.     jr    z,sdrvb1        ; Yes then done
  556. sdrvb0:    add    hl,hl            ; Get next mask
  557.     dec    a            ; Decrement drive counter
  558.     jr    nz,sdrvb0        ; And test if done
  559. sdrvb1:    ld    a,d            ; hl=hl or de
  560.     or    h
  561.     ld    h,a
  562.     ld    a,e
  563.     or    l
  564.     ld    l,a
  565.     ret                ; Exit
  566. ;
  567. ; Calculate sector/track directory
  568. ;
  569. stdir:    ld    hl,(filcnt)        ; Get FCB counter directory
  570.     srl    h            ; Divide by 4
  571.     rr    l            ; (4 FCB's / sector)
  572.     srl    h
  573.     rr    l
  574.     ld    (recdir),hl        ; Save value (used by checksum)
  575.     ex    de,hl            ; Copy it to de
  576.     ld    hl,0            ; Clear hl
  577. ;
  578. ; Calculate sector/track
  579. ;  entry: hl,de=sector number (128 byte sector)
  580. ;  result set track  =hl,de  /  maxsec
  581. ;         set sector =hl,de mod maxsec
  582. ;
  583. calst:    ld    bc,(maxsec)        ; Get sectors/track
  584.     ld    a,17            ; Set up loop counter
  585. calst0:    or    a            ; Test hl>=bc
  586.     sbc    hl,bc
  587.     ccf
  588.     jr    c,calst1        ; Yes then jump
  589.     add    hl,bc            ; No then retore hl
  590.     or    a            ; And clear carry
  591. calst1:    rl    e            ; Shift result in de
  592.     rl    d
  593.     dec    a            ; Test last bit done
  594.     jr    z,calst2        ; Yes then exit
  595.     rl    l            ; Shift next bit in hl
  596.     rl    h
  597.     jr    calst0            ; Continue
  598. calst2:    push    hl            ; Save sector number
  599.     ld    hl,(nftrk)        ; Get first track
  600.     add    hl,de            ; Add track number
  601.     ld    b,h            ; Copy it to bc
  602.     ld    c,l
  603.     call    settrk            ; P2bios call set track
  604.     pop    bc            ; Restore sector number
  605.     ld    de,(trans)        ; Get translation table address
  606.     call    sectrn            ; P2bios call sector translation 
  607.     ld    b,h            ; Copy result to bc
  608.     ld    c,l
  609.     jp    setsec            ; P2bios call set sector
  610. ;
  611. ; Get disk map block number from FCB
  612. ;  exit hl=address FCB
  613. ;       de=dm
  614. ;       bc=offset in dm
  615. ;
  616. getdm:    ld    c,(ix+32)        ; Get next record
  617.     ld    a,(nblock)        ; Get number of blocks
  618.     ld    b,a            ; Save it 
  619. getdm0:    srl    c            ; Shift next record 
  620.     djnz    getdm0            ; Number of blocks times
  621. getdm1:    cpl                ; Complement number of blocks
  622.     add    a,9            ; Add 9
  623.     ld    b,a            ; B=8-number of blocks
  624.     ld    a,(nextnd)        ; Get extent mask
  625.     and    (ix+12)            ; Mask with extent
  626.     rrca                ; Rotate one right
  627. getdm2:    rlca                ; Rotate one left
  628.     djnz    getdm2            ; 8-number of blocks times
  629. getdm3:    add    a,c            ; Add the two values to get entry FCB
  630. getdm4:    push    ix            ; Get FCB address
  631.     pop    hl
  632.     ld    c,16            ; Add offset 16 to point to dm
  633.     add    hl,bc
  634.     ld    c,a            ; Add entry FCB
  635.     add    hl,bc
  636.     ld    a,(maxlen+1)        ; Test 8 bits/16 bits FCB entry
  637.     or    a
  638.     jr    nz,getdm5        ; 16 bits => jump
  639.     ld    e,(hl)            ; Get 8 bit value
  640.     ld    d,0            ; Make MSB zero
  641.     ret                ; And exit
  642. getdm5:    add    hl,bc            ; Add twice (16 bit values)
  643.     ld    e,(hl)            ; Get LSB
  644.     inc    hl            ; Increment pointer
  645.     ld    d,(hl)            ; Get MSB
  646.     dec    hl            ; Decrement pointer
  647.     ret                ; And exit
  648. ;
  649. ; Calculate sector number 
  650. ;  entry: de=block number from FCB
  651. ;
  652. calsec:    ld    hl,0            ; Clear MSB sector number
  653.     ld    a,(nblock)        ; Get loop counter
  654.     ld    b,a            ; Save it in b
  655. calsc0:    sla    e            ; Shift l,d,e 
  656.     rl    d
  657.     rl    l
  658.     djnz    calsc0            ; B times
  659. calsc1:    ld    a,(nmask)        ; Get sector mask
  660.     and    (ix+32)            ; And whit next record
  661.     or    e            ; Set up LSB sector number
  662.     ld    e,a
  663.     ret                ; And exit
  664. ;
  665. ; Calculate dirbuf entry point
  666. ;
  667. caldir:    ld    hl,(dirbuf)        ; Get start address dirbuf
  668.     ld    a,(secpnt)        ; Get sector pointer
  669.     add    a,l            ; Add l=l+a
  670.     ld    l,a
  671.     ret    nc            ; No carry exit
  672.     inc    h            ; Increment h
  673.     ret                ; And exit
  674. ;
  675. ; Init file count
  676. ;
  677. setfct:    ld    hl,-1            ; Set up file count
  678.     ld    (filcnt),hl        ; Save it
  679.     ret                ; And exit
  680. ;
  681. ; Test file count
  682. ;
  683. tstfct:    ld    hl,(filcnt)        ; Test file count=0ffffh
  684.     ld    a,h            ; Get MSB 
  685.     and    l            ; And LSB
  686.     inc    a            ; Test if result=0ffh
  687.     ret                ; And exit
  688. ;
  689. ; Set last file
  690. ;
  691. setlf:    call    tstlf            ; Test last file
  692.     ret    c            ; No then exit
  693.     inc    de            ; Increment last file
  694.     ld    (hl),d            ; Save it in temp0
  695.     dec    hl
  696.     ld    (hl),e
  697.     ret                ; And exit
  698. ;
  699. ; Test last file
  700. ;
  701. tstlf:    ld    hl,(temp0)        ; Get pointer to last file 
  702.     ld    de,(filcnt)        ; Get file counter
  703.     ld    a,e            ; Subtract de-(hl)
  704.     sub    (hl)
  705.     inc    hl
  706.     ld    a,d
  707.     sbc    a,(hl)
  708.     ret                ; Exit
  709. ;
  710. ; Get next FCB from drive
  711. ; entry a=0 check checksum, a=0ffh update checksum
  712. ;
  713. rddir:    ld    c,a            ; Save checksum flag
  714.     ld    hl,(filcnt)        ; Get file counter
  715.     inc    hl            ; Increment it
  716.     ld    (filcnt),hl        ; And save it
  717.     ld    de,(nfiles)        ; Get maximum number of files
  718.     or    a            ; Clear carry
  719.     sbc    hl,de            ; Test if last file
  720.     add    hl,de
  721.     jr    z,rddir0        ; No jump
  722.     jr    nc,setfct        ; Yes set file count to 0ffffh
  723. rddir0:    ld    a,l            ; Get file count LSB
  724.     rrca                ; *32 
  725.     rrca
  726.     rrca
  727.     and    060h            ; Mask it
  728.     ld    (secpnt),a        ; Save it for later use
  729.     ret    nz            ; Return if not fisrt FCB sector
  730.     push    bc            ; Save checksum flag
  731.     call    stdir            ; Calculate sector/track directory
  732.     call    readdr            ; Read sector directory
  733.     pop    bc            ; Restore checksum flag
  734.     call    chkdir
  735.     ret    nc
  736.     push    bc
  737.     call    initdr            ; Relog drive
  738.     pop    bc
  739.     jr    rddir
  740. ;
  741. ; Update/check checksum directory
  742. ; entry c=0 check checksum, c=0ffh update checksum
  743. ;
  744. chkdir:    ld    hl,(ncheck)        ; Get number of checked records
  745.     ld    de,(recdir)        ; Get current record
  746.     or    a            ; Clear carry
  747.     sbc    hl,de            ; Test current record 
  748.     ret    z            ; Exit if zero
  749.     ccf
  750.     ret    nc            ; Exit if greater then ncheck
  751.     ld    hl,(dirbuf)        ; Get dirbuf
  752.     ld    b,128            ; Set up counter
  753.     xor    a            ; Clear checksum
  754. chkdr0:    add    a,(hl)            ; Add checksum
  755.     inc    hl            ; Increment pointer
  756.     djnz    chkdr0            ; 128 times
  757.     ld    hl,(csv)        ; Get pointer checksum directory
  758.     add    hl,de            ; Add current record
  759.     inc    c            ; Test checksum flag
  760.     jr    z,chkdr1        ; 0ffh=> update checksum
  761.     cp    (hl)            ; Test checksum
  762.     ret    z            ; Exit if ok
  763. ; automatic disk logging--instead of setting read/only flag when disk is
  764. ; changed, carry is returned set to calling routine if checksum error
  765. ;    jp    setwpd
  766.     scf                ; From Mod. 3 Suprbdos
  767.     jp    setfn            ; Set number of files
  768. chkdr1:    ld    (hl),a            ; Update checksum
  769.     ret                ; And exit
  770. ;
  771. ; Read sector from drive
  772. ;
  773. ;
  774. ; Readr and writer modified to give separate error messages--b.h.
  775. readr:    call    read            ; P2bios call read sector
  776.     ld    hl,(srderr)
  777.     jr    write0
  778. ;
  779. ; Write sector on drive
  780. ;
  781. writer:    call    write            ; P2bios call write sector
  782.     ld    hl,(swrter)
  783. write0:    or    a            ; Test exit code
  784.     ret    z            ; Exit if ok
  785.     ld    a,1            ; Allow a return to program if r/o
  786.     ld    (retflg),a
  787.     jp    (hl)            ; P2dos error on d: bad sector
  788. ;
  789. ; Read directory from drive
  790. ;
  791. readdr:    call    dmadir            ; Set up DMA directory
  792.     call    readr            ; Read record
  793.     jr    stdma            ; Set up DMA user
  794. ;
  795. ; Write directory on drive
  796. ;
  797. writdr:    ld    c,0ffh            ; Update checksum directory
  798.     call    chkdir
  799.     call    dmadir            ; Set up DMA directory 
  800.     ld    c,1            ; Write directory flag
  801.     call    writer            ; Write record
  802.     jr    stdma            ; Set up DMA user
  803.