Date : Fri, 20 Jan 1984 20:52:00 EST
From : Eric Stork <STORK@mit-mc>
Subject: BDOS Function 37
Since I started this discussion, I felt an obligation to try
to get to the bottom of the issue. So I spent much of a day reading
and experimenting. I think I now understand what Function 37
does and does not do.
Frank Wancho pointed out that Function 37 is misnamed. It should
be called RESET WRITE PROTECT VECTOR, he said. That is NOT the
same as RESET DRIVE, he emphasized. He went on to suggest the
use of Function 13 as a correct and safe sequence, with associated
use of functions 25 and 14 to get back to the disk one started on.
Function 13 is OK if one can close ALL files. But when one wants
to continue to work out of a file on Drive A:, one cannot really
reset ALL drives. That's necessary wehn one wants to change disks
in a drive that holds data for a program. So Function 37 has a
legitimate use and seems OK if one is careful.
Others suggested that the trick is to close ALL files on the drive
to be reset before using Function 37. Failing to do that can result
in overwriting files or directories. But it seems that when all file
on the drive to be reset are closed, Function 37 can be safely used.
The most interesting thing that I demonstrated in my experiments is
that Function 37 does NOT reset the diskmap for the drive to be reset,
but that the diskmap for that drive is reset by the first file I/O
operation following function 37. I do not have a hard disk, which
Jerry Pournelle and Frank Wancho said could easily be trashed by
Function 37, but maybe someone who does have a hard disk can try
the experiment (without writing to the hard disk, just checking
out the disk map) and let us know how it goes. It should go OK,
from what I could figure out, but I can't be sure.
Eric.
For those who might want to repeat or expand my experiment, there
follows a short ASM file:
********************
* This is a test program
* to analyze the results of BDOS Function #37
*
* Assemble the program into a COM file, and put that on Drive A:.
* Put a disk with files on drive B:, and log it in with ^C.
* Then run this program (I call it TEST.COM) and when asked to do so,
* put a different disk on Drive B:
*
* The bitmap (as bytes) starts a 0300h for the first disk, and at
* 0330h for the second disk. I use Ward C.'s Q.COM to look at it,
* invoking it as Q @300 , and stopping the display with ^S
* or with ^C, so that I can compare the bytes.
bufbyts equ 31 ;this value is the number of GROUPS/8
; on your disks. The bitmap copnsists of
; one bit for each group. My system has
; 243 groups. 243/8=30.375, or 31 when
; we round up. Change this value for your
; system. If you have more than 384 groups,
; you must increase the size of BUF1: and BUF2:
; to hold them.
ORG 100H
MVI c,14 ;select logical disk
MVI e,1 ;select disk B:
CALL 5
MVI c,27 ;get address of disk alloc vector
call 5 ;returns with [HL] pointing to first of a
; block that holds the disk map
LXI D,BUF1 ;
MVI c,bufbyts ;use [C] as counter
LOOP1:
MOV A,M ;get byte of data into [A]
STAX D ;and store it in BUF1
INX H
INX D ;bump the pointers
DCR C ;reduce the counter
JNZ LOOP1 ;loop until done
LXI d,message
MVI c,9
CALL 5
xx: mvi c,11
CALL 5
ORA A ;0 if no char, FF if character typed
JZ XX
MVI c,37 ;now do the individual disk reset function
LXI d,0000$0000$0000$0010B ;drive b:
call 5
* ********** This is the key. The first disk operation seems to
* read the diskmap. Try running the program with the next three
* lines commented out -- you'll see that the two disk maps are
* the same, so function 37 alone does not reset the disk map.
LXI D,FCB
mvi c,15 ;open file (find file, or erase file work also)
call 5
*********************************************************
MVI c,27 ;get address of disk alloc vector
call 5 ;returns with [HL] pointing to first of 'n'-byte
; block with bitmap (31 for my system)
LXI D,BUF2 ;
MVI c,bufbyts ;use [C] as counter
LOOP2:
MOV A,M ;get byte of data into [A]
STAX D ;and store it in BUF2
INX H
INX D ;bump the pointers
DCR C ;reduce the counter
JNZ LOOP2 ;loop until done
JMP 0000h ;and quit
message:
DB 'Switch disk in B:, then type any key to continue ','$'
FCB:
db 1 ;drive b:
db 'JUNK '
db 0,0,0,0 ;extent, reserved, & records
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
ORG 300h
BUF1:
DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;plenty of extra space
DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
BUF2:
DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
END