You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
217 lines
5.7 KiB
217 lines
5.7 KiB
;/*
|
|
; * Microsoft Confidential
|
|
; * Copyright (C) Microsoft Corporation 1988 - 1991
|
|
; * All Rights Reserved.
|
|
; */
|
|
; Check for existence of a VDisk header. Check the beginning of the segment
|
|
; addressed by the INT 19 vector, and, if XMS is available to give us
|
|
; A20 toggling, check at the 1Mb boundary. We don't do the latter check
|
|
; if we can't do the A20 switch.
|
|
;
|
|
; Return the size of the VDisk if found.
|
|
;
|
|
|
|
; Checking for a VDISK header at 1Mb is currently disabled. This is because
|
|
; the XMS calls used to access the HMA will cause INT 15 memory to
|
|
; be claimed if there are currently no Himem or XMS users, and the MEM
|
|
; command shouldn't disturb the memory environment in that way.
|
|
; We rely on VDisk allocators to use the INT 19 approach to signal
|
|
; their memory usage. According to Ray Duncan, this may not be
|
|
; entirely reliable, but this is probably better than adding the
|
|
; code necessary to do lots of INT 15 block moves to interrogate
|
|
; the extended memory arena.
|
|
|
|
CHECKXMS equ 0 ; set to non-zero to enable checking
|
|
; of the HMA for VDisk headers.
|
|
|
|
.MODEL SMALL
|
|
.CODE
|
|
|
|
extrn _XMM_Installed :Near
|
|
extrn _XMM_QueryA20 :Near
|
|
extrn _XMM_EnableA20 :Near
|
|
extrn _XMM_DisableA20 :Near
|
|
|
|
;----------------------------------------------------------------------------
|
|
;
|
|
; following piece of code will be moved into a para boundary. And the para
|
|
; address posted in seg of int 19h vector. Offset of int 19h will point to
|
|
; VDint19. This is to protect HMA from apps which use VDISK header method
|
|
; to determine free extended memory.
|
|
;
|
|
; For more details read "power programming" column by Ray Duncan in the
|
|
; May 30 1989 issue of PC Magazine (pp 377-388) [USING EXTENDED MEMORY,PART 1]
|
|
;
|
|
;----------------------------------------------------------------------------
|
|
;
|
|
StartVDHead label byte
|
|
;
|
|
;-------------- what follows is a dummy device driver header (not used by DOS)
|
|
;
|
|
dd 0 ; link to next device driver
|
|
dw 8000h ; device attribute
|
|
dw 0 ; strategy routine offset
|
|
dw 0 ; interrupt routine offset
|
|
db 1 ; number of units
|
|
db 7 dup(0) ; reserved area
|
|
VDiskSig1 db 'VDISK'
|
|
|
|
VLEN1 equ ($-offset VDiskSig1)
|
|
|
|
db ' V3.3' ; vdisk label
|
|
db 15 dup (0) ; pad
|
|
VDiskEnd1 dw 0 ; bits 0-15 of free HMA
|
|
db 11h ; bits 16-23 of free HMA (1M + 64K)
|
|
|
|
VDInt19:
|
|
db 0eah ; jmp to old vector
|
|
OldVDInt19 dd ? ; Saved int 19 vector
|
|
|
|
EndVDHead label byte
|
|
;
|
|
;
|
|
VDiskHMAHead db 0,0,0 ; non-bootable disk
|
|
VDiskSig2 db 'VDISK'
|
|
|
|
VLEN2 equ ($-offset VDiskSig2)
|
|
|
|
db '3.3' ; OEM - signature
|
|
dw 128 ; number of bytes/sector
|
|
db 1 ; sectors/cluster
|
|
dw 1 ; reserved sectors
|
|
db 1 ; number of FAT copies
|
|
dw 64 ; number of root dir entries
|
|
dw 512 ; number of sectors
|
|
db 0feh ; media descriptor
|
|
dw 6 ; number of sectors/FAT
|
|
dw 8 ; sectors per track
|
|
dw 1 ; number of heads
|
|
dw 0 ; number of hodden sectors
|
|
VDiskEnd2 dw 440h ; Start of free HMA in K (1M+64K)
|
|
EndVDiskHMAHead label byte
|
|
;
|
|
;
|
|
;----------------------------------------------------------------------------
|
|
;
|
|
; procedure : IsVDiskInstalled
|
|
;
|
|
; Checks for the presence of VDISK header at 1MB boundary
|
|
; & INT 19 vector. Returns number of Kb used as Vdisk
|
|
;
|
|
; Inputs : none
|
|
; Outputs : AX = size of VDisk in Kb, 0 if none found
|
|
; Uses : AX, CX
|
|
;
|
|
;----------------------------------------------------------------------------
|
|
;
|
|
public _CheckVDisk
|
|
|
|
_CheckVDisk proc near
|
|
push bp
|
|
push si ; Save regs
|
|
push di
|
|
push es
|
|
push ds
|
|
|
|
mov ax,3519h ; Get Int Vector 19h
|
|
int 21h
|
|
; set registers for CMPS
|
|
mov di, offset VDiskSig1 - offset StartVDHead
|
|
mov cx, VLEN1
|
|
push cs
|
|
pop ds
|
|
mov si, offset VDiskSig1
|
|
rep cmpsb
|
|
IF NOT CHECKXMS
|
|
jnz cvd_NoDisk
|
|
ELSE
|
|
jnz cvd_checkXMS ; jump if we didn't find it
|
|
ENDIF
|
|
|
|
;
|
|
; Get the first free address in Kb, and determine the number of Kb used
|
|
; above 1Mb. First free address in a 24-bit address, so divide by 1024
|
|
; to get number of Kb
|
|
;
|
|
mov di,offset VDiskEnd1 - offset StartVDHead
|
|
mov ax,es:[di]+1 ; load top 16 bits of end address
|
|
shr ax,1
|
|
shr ax,1 ; fast divide of 24 bits by 1024
|
|
test es:[di],03FFh ; check for rounding
|
|
jz @F
|
|
inc ax ; round up if needed
|
|
@@:
|
|
IF NOT CHECKXMS
|
|
jmp short cvd_End
|
|
|
|
ELSE
|
|
pop ds ; clear top of stack
|
|
jmp short cvd_End ; AX now has size in Kb
|
|
|
|
|
|
;
|
|
; Ensure that A20 is on before we check above 1Mb. If XMS is not
|
|
; installed, we punt, and assume no VDisk
|
|
;
|
|
|
|
cvd_checkXMS:
|
|
pop ds ; get DS again
|
|
call _XMM_Installed
|
|
or ax,ax
|
|
jz cvd_NoDisk ; No XMS, assume no VDisk
|
|
|
|
;
|
|
; Get and save current A20 state, get A20 on
|
|
;
|
|
call _XMM_QueryA20
|
|
push ax ; save current state
|
|
or ax,ax ; already on?
|
|
jnz cvd_A20On ; yes, don't turn it on
|
|
call _XMM_EnableA20 ; turn it on
|
|
|
|
cvd_A20On:
|
|
push ds ; save DS again
|
|
mov ax, 0ffffh
|
|
mov ds, ax
|
|
mov si, 10h+(offset VDiskSig2 - offset VDiskHMAHead)
|
|
mov ax,cs
|
|
mov es,ax
|
|
mov di, offset VDiskSig2
|
|
mov cx, VLEN2
|
|
rep cmpsb
|
|
jne @F ; if no header, turn off A20 now
|
|
; get first free address in Kb
|
|
mov si,offset VDiskEnd2 - offset VDiskHMAHead
|
|
mov ax,[si]
|
|
@@:
|
|
pop ds ; get original DS again
|
|
pop ax ; get original A20 state
|
|
pushf ; save result of header check
|
|
or ax,ax ; was A20 already on?
|
|
jnz @F ; jump if yes
|
|
call _XMM_DisableA20 ; else turn it off again
|
|
|
|
@@:
|
|
popf ; get result of header check
|
|
je cvd_End ; jump if present
|
|
|
|
ENDIF ; CHECKXMS
|
|
|
|
cvd_NoDisk:
|
|
mov ax,1024 ; set up to return 0
|
|
|
|
cvd_End:
|
|
sub ax,1024 ; discount first 1Mb from first
|
|
; free address to get size in Kb
|
|
IF NOT CHECKXMS
|
|
pop ds
|
|
ENDIF
|
|
pop es
|
|
pop di
|
|
pop si
|
|
pop bp
|
|
ret
|
|
_CheckVDisk endp
|
|
|
|
end
|
|
|