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
/
JSAGE
/
ZSUS
/
PROGPACK
/
FRESET10.ASM
< prev
next >
Wrap
Assembly Source File
|
2000-06-30
|
4KB
|
139 lines
; 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'