home *** CD-ROM | disk | FTP | other *** search
- ; Routine: FRESET -- fast drive reset and login
- ; Author: Bridger Mitchell (Plu*Perfect Systems)
- ; CPU: Z80-compatible
- ; Date: January 2, 1988
- ; Version: 1.0
- ;
- ; This routine (fast-)resets and logs in the CP/M drive in register
- ; (A). When possible, it uses BDOS function 37 (logoff drives).
- ; In most cases FRESET is significantly faster than using function 13
- ; (reset all drives) to do a general reset.
- ;
- ; FRESET functions correctly with Digital Research's CP/M 2.2 BDOS,
- ; which contains a bug that does not allow the logged-in drive to
- ; be reset with function 37.
- ;
- ; Some CP/M BDOS emulators (such as ZRDOS, PZDOS, ...) have changed
- ; the operation of the general-reset function 13, in order to speed
- ; up warm-boots and disk-resets on systems with hard-drives. In this
- ; case, a non-removable drive (hard disk, ram disk), after it
- ; has been initially logged in, remains logged in after a general
- ; reset.
- ;
- ; On such systems it is **essential** that any program that uses
- ; BIOS disk functions to write to a non-removable drive also cause
- ; the disk's allocation map to be rebuilt before any BDOS disk
- ; functions are used. DU (DU3) and UNERASE are probably the most
- ; common examples of such programs; they modify the disk directory.
- ; For these systems, the drive must first be logged off with
- ; function 37 and then logged in. Calling FRESET within such
- ; programs will ensure that the disk's allocation map is recomputed.
- ;
- ; The FRESET algorithm:
- ;
- ; if requested_drive is logged in
- ; if a second drive is logged in
- ; log into the second drive
- ; logoff requested drive (fn.37)
- ; if no second drive was logged in
- ; do general reset (fn. 13)
- ; log into requested drive
- ;
- ; Note: Unnumbered version dated 12/27/87 did not provide for
- ; logging out the drive in one special case, namely when only that
- ; one drive is currently logged in. Thanks to Howard Goldstein
- ; for spotting the problem.
- ;
- xbdos equ 5
-
- ; Fast-reset drive (A)
- ; A = 0 ... 15 for A: ... P:
- ;
- CSEG
- freset:
- ld (reqdrv),a ; save requested drive
- push af
- ld c,24 ; get vector of logged-in drives
- call xbdos
- pop af ; (recover requested drive)
- push hl ; save logged-in vector
- call fshftr ; shift requested drive's bit to bit 0
- bit 0,l ; is requested drive logged in?
- pop hl ; (recover (unshifted) logged vector)
- jr z,flogit ; ..z - no, just log it in
- ld e,0 ; initialize drive index/count
- jr frese2
- ;
- frese1: ld a,1 ; shift vector right 1 bit
- call fshftr
- frese2: bit 0,l ; if drive is not logged in
- jr z,frese3 ; ..check next drive
- ld a,(reqdrv) ; or if it is the requested drive
- cp e ;
- jr z,frese3 ; ..check next drive
- ;
- ; found a second logged-in drive, so switch to it
- ;
- call fslctit ; select e'th drive
- call flogout ; log out requested drive
- jr flogit ; then log into it and exit.
- ;
- frese3: inc e ; increment drive count
- ld a,e
- cp 16
- jr c,frese1 ; .. and continue for 16 drives
- ;
- ; no second drive found,
- ;
- call flogout ; log out requested drive
- ld c,13 ; do general reset, then (re)log requested
- call xbdos ;
- ;
- ; log into requested drive
- ;
- flogit: ld a,(reqdrv)
- ld e,a
- ;
- fslctit:ld c,14 ; select bdos drive
- jxbdos: jp xbdos
- ;
- ; log out the requested drive
- ;
- flogout:ld a,(reqdrv) ; set up bit to log out drive
- ld hl,1
- call fshftl
- ex de,hl
- ld c,37 ; log out drive in DE vector
- jr jxbdos
- ;
- ;
- ; shift hl right (a) bits
- ;
- fshftr:
- inc a
- shftr1: dec a
- ret z
- srl h
- rr l
- jr shftr1
- ;
- ;
- ; shift hl left (a) bits
- ;
- fshftl:
- inc a
- shftl1: dec a
- ret z
- add hl,hl
- jr shftl1
-
- ;--------------------
- DSEG
- reqdrv: ds 1
-
- end
- z,frese3 ; ..check next drive
- ;
- ; found a second logged-in drive, so switch to it
- ;
- call fslctit ; select e'