|
|
;** SYSTEM.ASM ********************************************************** ; * ; Copyright (C) 1983,1984,1985,1986,1987,1988 by Microsoft Inc. * ; * ;************************************************************************ ; History ; 18 oct 88 peterbe Added fBootDrive and test for it, ; for diskless workstations. ;************************************************************************
TITLE SYSTEM - InquireSystem procedure to return info about devices
include system.inc
;; AT&T Machines running DOS 3.10, revisions 1.0 and 1.01 place ;; this value into SingleDriveLoc
ATT31Loc EQU 10d0h
ifdef NEC_98 IOSYSSEG EQU 0060H LPTABLEOFF EQU 006CH EXLPTABLE EQU 2C86H ;EXPANDED LPTABLEOFF SNGDRV_FLG EQU 0038H
BIOS_FLAG EQU ES:BYTE PTR[0100H] ; offset by seg 40h BIOS_FLAG1 EQU ES:BYTE PTR[0080H] ; "
EX_CPU_TYPE EQU 00001000B V30_BIT EQU 01000000B BIT286 EQU 00000001B endif ; NEC_98
MultHIMEM EQU 43h ; HIMEM.SYS int 2fh multiplex MHM_ReqInstall EQU 00h ; Installation check MHM_ReqInstall_Ret EQU 0FFh ; I'm here Return
ifndef NEC_98 externA __ROMBIOS endif ; NEC_98
externA __0040h
externFP NoHookDOSCall
ifdef NEC_98 externFP GetPrivateProfileInt ; 930206 endif ; NEC_98
ifdef HPSYSTEM ExternNP <EnableVectra, DisableVectra> ;~~vvr 091989 endif
assumes CS,CODE
sBegin DATA
externB timerTable
; ; InquireSystem(what,which) - returns oem specific information ; what is the code for the device ; which specifies which one of those devices ; ; WHAT = 0 Timer resolution ; Return the resolution of the timer specified by the which ; parameter in DX:AX. Windows always uses which == 0 ; ; WHAT = 1 Disk Drive Information (Drive A = 0) ; which is the disk drive (A = 0) ; Returns: ; ax = 0 means the drive does not exist. if dx != 0 then the drive ; maps to the drive in dx instead (A = 1) AND the drive is ; REMOVEABLE. ; ax = 1 means the drive does not exist. if dx != 0 then the drive ; maps to the drive in dx instead (A = 1) AND the drive is ; FIXED. ; ax = 2 means the drive is removable media ; ax = 3 means the drive is fixed media ; ax = 4 means the drive is fixed media and remote ; ; WHAT = 2 Enable/Disable one drive logic ; which = 0 means disable, which <> 0 means enable ; This code enables/disables the RAM BIOS message: ; "Please insert disk for drive B:" ; ifdef NEC_98 ; WHAT = 3 Coprocessor exception vector information ; which is unused. ; Returns: ; ax = 1 means we must save & restore coprocessor error vector ; ( really,always return 1 ) ; dx : coprocessor exception interrrupt vector number ; endif ; NEC_98
; ; The following flag deals with some unpleasantness in the fast boot code. ; The fast boot code delays our INIT call till to late because some code ; in KERNEL which uses InquireSystem is called first. We fix this problem ; with this flag...... ; globalB SystemIsInited,0
; Following from RAMDRIVE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Unfortunately the code in ramdrive is very machine dependent ; necessitating the use of a system flag to store the machine ; configuration. The system flag is initialised during init time ; and used when the caching services are requested. One bit which ; is set and tested during caching is the state of the a20 line ; when the cache code is entered. This is used because there are ; applications which enable the a20 line and leave it enabled ; throughout the duration of execution. Since ramdrive is a device ; driver it shouldn't change the state of the environment. ; ; The system flag bit assignments are: ; ; ------------------------------------------------- ; | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ; ------------------------------------------------- ; |-----| | | | | | | ; | | | | | | -----286 (and AT) ; | | | | | -----------386 (later than B0) ; not | | | -----------------PS/2 machine ; used | | -----------------------Olivetti (not used) ; | -----------------------------A20 state (enabled ?) ; -----------------------------------DOS 3.x >= 3.3
; The Olivetti guys have defined a flag of their own. This should be removed ; and the bit assigned out here for them should be used. ; sys_flg db 0 ; ; equates used for the system flag ; M_286 equ 00000001B M_386 equ 00000010B M_PS2 equ 00000100B M_OLI equ 00001000B A20_ST equ 00010000B DOS_33 equ 00100000B HAVE_FFFE equ 01000000B ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; A20 address line state determination addresses ; low_mem label dword dw 20h*4 dw 0
high_mem label dword dw 20h*4 + 10h dw 0ffffh
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; A20 PS2 equates ; PS2_PORTA equ 0092h GATE_A20 equ 010b
; End RAMDRIVE stuff
globalB numFloppies,0 globalB fBootDrive,0 globalB oneDriveFlag,0 globalW coProcFlag,0 globalD HiMem,0 globalW DosVer,0
ifdef NEC_98 savelptable db 0 NDP_CONTROL DW 0
EMM_DEVICE_NAME DB "EMMXXXX0" PUBLIC EMM_FLAG EMM_FLAG DB 0
DRVCNT DB 10H ;16 DRIVE
PUBLIC reflected reflected DB 0 ; 0 not reflected 930206 profinit DB 0 ; 0 is no initalized 930206 endif ; NEC_98
;; SingleDriveLoc defaults to the value of SingleDrive (104h) on other ;; than AT&T machines. Otherwise the value is changed during ;; the execution of single drive enable/disable.
SingleDriveLoc dw SingleDrive
sEnd
sBegin CODE
GlobalW MyCSDS, _DATA
;-----------------------------------------------------------------------; ; InquireSystem ; ; ; Entry: ; ; Returns: ; ; Registers Destroyed: ; ; History: ; Mon 21-Nov-1988 14:57:21 -by- David N. Weise [davidw] ; ;-----------------------------------------------------------------------;
assumes ds,nothing assumes es,nothing
cProc InquireSystem,<FAR,PUBLIC,NODATA> parmW what parmW which cBegin push ds mov ds, MyCSDS assumes ds,DATA
cmp SystemIsInited,0 ; Are we ready for this call? jnz DoInq ; Yes call far ptr InitSystem ; No, Set up DoInq: mov ax,what
;--------------------------------------- ; ; Timer information ; or ax,ax jnz is1 mov dx,res_high mov ax,res_low jmp ISDone
;--------------------------------------- ; ; Drive information ; is1: dec ax ; ax = 1? jz DriveInfo jmp is5
DriveInfo: mov ah,19h ; get the current disk cCall NoHookDOSCall mov bx,Which ; try to set to this disk cmp al,bl ; already there? jz DriveData ; yes, drive is good
push ax mov dx,bx mov ah,0Eh ; set to new disk cCall NoHookDOSCall mov ah,19h ; get the current disk cCall NoHookDOSCall mov bh,al pop dx mov ah,0Eh ; restore current disk cCall NoHookDOSCall cmp bh,bl ; Drive good? jz DriveData ; yes jmp is9 ; no, this drive totally bad
; First check if this is network. We must do this first because ; the removeable and phantom IOCTL calls return errors if you feed ; them network drives. If it is network then we know it is non-removable ; and not phantom.
DriveData: cmp DosVer,0400h jb no_4 cmp DosVer,0401h ja no_4 cCall Dos4IsRemote,<Which> or ax,ax jmp short well_is_it
no_4: mov ax,4409h ; IOCTL is Remote mov bx,Which inc bx ; A = 1 cCall NoHookDOSCall jc DoRem ; Call didn't work, go ahead test dx,0001000000000000B well_is_it: jz DoRem ; Drive is local mov cx,REMOTE ; Drive is not removeable jmp short NoRemap ; Drive is not phantom
; Now Check "removeability"
DoRem: mov ax,4408h ; IOCTL is removeable mov bx,Which inc bx ; A = 1 cCall NoHookDOSCall jc OLDRemove ; Call didn't work, use old method mov cx,FIXED test ax,1 jnz DrivePhantom mov cx,REMOVEABLE
; The drive is removable ... ; This code accounts for the fact that the code above on a PS/2 ; Mod 50 diskless workstation reports the existence of a floppy ; drive on A: or B: even if it's unplugged. If this is drive A: ; or B:, we need to test fBootDrive to see if this drive REALLY ; exists.
ifdef NEC_98 push es ; ins <91.01.14> Y.Ueno mov ax, 40h ; " mov es, ax ; " push si ; " mov si, Which ; mov al, byte ptr es:[si+26ch] and al, 0f0h cmp al, 0a0h pop si ; pop es ; jne DrivePhantom ; mov cx,FIXED ; else ; NEC_98 cmp Which, 2 ; this isn't likely, but.. jae DrivePhantom ; there ARE removable hard drives. test fBootDrive,1 ; Must be a floppy, does this system have any? jnz DrivePhantom ; if 0, jmp Is9 ; we assume there are none endif ; NEC_98
; Now check for phantom drives
DrivePhantom: mov ax,440EH ; IOCTL get logical map mov bx,Which inc bx ; A = 1 cCall NoHookDOSCall jc OLDPhantom ; Call didn't work, use old method or al,al ; If AL=0, drive is NOT phantom jz NoRemap cmp bl,al ; Drive maps to self? jz NoRemap ; Yes, drive is not phantom xor ah,ah mov dx,ax ; DX is real drive SetPhantomRet: xor ax,ax ; Set removeable return cmp cx,REMOVEABLE jz IsDoneV inc ax ; Set fixed return jmp short IsDoneV
NoRemap: xchg ax,cx ; AX = type of drive xor dx,dx ; Indicate no remapping IsDoneV: jmp ISDone
; Check removeability with equipment word
OLDRemove: ifdef NEC_98 mov cx,FIXED else ; NEC_98 xor ax,ax or al,numFloppies ; just one floppy on system? jnz OLDR1 ; no, continue inc ax ; pretend we have two floppies... OLDR1: cmp ax,which mov cx,FIXED jb DrivePhantom mov cx,REMOVEABLE endif ; NEC_98 jmp short DrivePhantom
; Check phantomness with equipment word
OLDPhantom: ifdef NEC_98 jmp short NoRemap ; No, drive B is real else ; NEC_98 cmp Which,1 ; Drive B is only phantom jnz NoRemap ; Not drive B, so not phantom cmp numFloppies,0 ; Single floppy system? jnz NoRemap ; No, drive B is real mov dx,1 ; Drive B is really drive A jmp short SetPhantomRet endif ; NEC_98
;--------------------------------------------------- ; ; Single Floppy enable/disable ; is5: dec ax ; floppy enable disable? ifdef NEC_98 jnz is9a ; " else ; NEC_98 jnz is9 endif ; NEC_98
is5b: cmp which,0 ; 0=disable jnz is6
; Disable various OEM things
cmp DosVer,0314h ; Below DOS 3.20? jae nosingdrv1 ; No, no ROM area diddle
;; ;; AT&T MS-DOS 3.10 does not keep information on the last floppy ;; drive accessed at 504h. The purpose of this section ;; of code is to locate the bytes and patch them accordingly. ;;
ifndef NEC_98 mov ax,__ROMBIOS ;; is this an AT&T machine ? mov es,ax ;; look for start of 'OLIVETTI' cmp es:[0C050h],'LO' jnz ATTCheckDone ;; No, continue mov SingleDriveLoc,ATT31Loc ATTCheckDone:
mov ax,__0040h mov es,ax mov bx,SingleDriveLoc ;; set to drive A xor ah, ah ; set to drive A: also! (A=0) xchg ah,es:[bx] mov oneDriveFlag,ah ; remember previous setting endif ; NEC_98 nosingdrv1: jmp short is9
; Enable various OEM things
is6: cmp DosVer,0314h ; Below DOS 3.20? jae nosingdrv2 ; No, no ROM diddle ifndef NEC_98 mov ax,__0040h mov es,ax mov bx,SingleDriveLoc ;; pointer to value mov ah,oneDriveFlag mov es:[bx],ah ;; restore to correct drive endif ; NEC_98 nosingdrv2: ifdef NEC_98 is9a: dec ax jz is9b ; what == 3 ? jmp is9 is9b: push es mov ax,40h ; get ROM BIOS segment mov es,ax test BIOS_FLAG1,BIT286 mov ax,1 jz I_V30 mov dx,10h ;80286/80386 coprocess error vector jmp short IOK I_V30: mov dx,16h ;8086/V30 coprocess error vector IOK: pop es jmp ISDone endif
is9: xor dx,dx xor ax,ax ISDone: pop ds
cEnd Inquire
;-----------------------------------------------------------------------; ; Get80x87SaveSize ; ; ; ; ; ; Arguments: ; ; ; ; Returns: ; ; ; ; Error Returns: ; ; ; ; Registers Preserved: ; ; ; ; Registers Destroyed: ; ; ; ; Calls: ; ; ; ; History: ; ; ; ; Thu Feb 05, 1987 10:15:13p -by- David N. Weise [davidw] ; ; Wrote it. ; ;-----------------------------------------------------------------------;
assumes ds,nothing assumes es,nothing
cProc Get80x87SaveSize,<PUBLIC,FAR> cBegin nogen push ds mov ds, MyCSDS assumes ds, DATA mov ax,CoProcFlag pop ds ret cEnd nogen
;-----------------------------------------------------------------------; ; Save80x87State ; ; ; ; ; ; Arguments: ; ; ; ; Returns: ; ; ; ; Error Returns: ; ; ; ; Registers Preserved: ; ; ; ; Registers Destroyed: ; ; ; ; Calls: ; ; ; ; History: ; ; ; ; Thu Feb 05, 1987 10:15:17p -by- David N. Weise [davidw] ; ; Wrote it. ; ;-----------------------------------------------------------------------;
assumes ds,nothing assumes es,nothing
cProc Save80x87State,<PUBLIC,FAR> ; parmD savearea cBegin nogen mov bx,sp les bx,[bx][4] fsave es:[bx] ret 4 cEnd nogen
;-----------------------------------------------------------------------; ; Restore80x87State ; ; ; ; ; ; Arguments: ; ; ; ; Returns: ; ; ; ; Error Returns: ; ; ; ; Registers Preserved: ; ; ; ; Registers Destroyed: ; ; ; ; Calls: ; ; ; ; History: ; ; ; ; Thu Feb 05, 1987 10:15:23p -by- David N. Weise [davidw] ; ; Wrote it. ; ;-----------------------------------------------------------------------;
assumes ds,nothing assumes es,nothing
cProc Restore80x87State,<PUBLIC,FAR> ; parmD savearea cBegin nogen mov bx,sp les bx,[bx][4] frstor es:[bx] ret 4 cEnd nogen
if2 %out Dummy A20 handler still here
endif
assumes ds,nothing assumes es,nothing
cProc A20_Proc,<PUBLIC,FAR> ; parmW enable cBegin nogen mov ax, 2 ; No himem area error code ret 2 cEnd nogen
; the following routine is added per DavidW's suggestion that the disable ; calls be made through WEP routine and this WEP will call any clean-up ; to be done by the driver.
ifdef HPSYSTEM
cProc WEP, <PUBLIC, FAR> parmW dummy cBegin call DisableVectra ;~~vvr 091989 mov ax, 1 ; by convention cEnd
else
cProc WEP,<PUBLIC,FAR> ; parmW dummy cBegin nogen mov ax,1 ret 2 cEnd nogen
endif ;HPSYSTEM
;-----------------------------------------------------------------------; ; ; ; BOOL Dos4IsRemote(int); ; ; ; ; ENTRY: Word, iPDrive: must be of the form ( logical volume A = 0 ) ; ; Physical Drive Spec. B = 1 ; ; C = 2 ; ; ect. ; ; EXIT: BOOL returned in AX True = Remote ; ; False = Local ; ; ; ; DESTROYS: AX. (preserves all registers except AX for return value) ; ; ; ; Wed 27-Sep-1989 20:08:18 -by- David N. Weise [davidw] ; ; Stole this from setup, made it smaller. ; ; ; ; AUTHOR: MC ; ;-----------------------------------------------------------------------;
cProc Dos4IsRemote,<NEAR,PUBLIC.ATOMIC,NODATA>, <si,di,ds,es>
ParmW iPDrive ; Int Physical drive spec 0 - 25 localV local_name,16 ; Buffer to hold redirected local name. localV net_name,128 ; Buffer to hold remote device name. ; redirected local device names. cBegin
; We have to use DOS call int 21h/5f02h because DOS call int 21h/4409h ; is not reliable under DOS versions 4.00 and 4.01.
xor cx,cx mov ax,ss ; Load segs for stack vars. mov es,ax mov ds,ax
next_entry: mov bx,cx ; CX = redirection list index. lea si,local_name ; ds:si = local_name lea di,net_name ; es:di = net_name push cx ; save CX mov ax,5F02h ; func 5f/02 Get redirection list. call NoHookDOSCall pop cx ; restore CX mov ax,0 ; don't change flags jc IsRemoteDone ; error, not supported or end of list.
cmp bl,04h ; Is redirected device a drive ? jne not_a_drive ; If not, we don't care !
mov al,ds:[si] ; Grab volume name. sub al,41h ; Convert to volume number A=0 ect. cmp ax,iPDrive jz remote_found
not_a_drive: inc cx ; CX = redirection list index. jmp short next_entry
remote_found: mov ax,1 ; Indicate Volume is remote !
IsRemoteDone:
cEnd
;-----------------------------------------------------------------------; ; InitSystem ; ; ; Entry: ; ; Returns: ; ; Registers Destroyed: ; ; History: ; Mon 21-Nov-1988 14:57:21 -by- David N. Weise [davidw] ; ;-----------------------------------------------------------------------;
assumes ds,nothing assumes es,nothing
ifdef NEC_98 sSysIni db "system.ini",0 ; name of file. 930206 sSystem db "system",0 ; [system] section.930206 sTimer db "reflecttimer", 0 ; 0 : no 1:yes 930206 endif ; NEC_98
cProc InitSystem,<PUBLIC,FAR> cBegin nogen push ds
mov ds, MyCSDS assumes ds, DATA
ifdef NEC_98 ;930206 cmp [profinit],0 jnz profinitdone inc [profinit] push es ; Get keyboard table type from WIN.INI. lea si, sSystem lea di, sTimer lea bx, sSysIni regptr cssi,cs,si ; lpAppName = "keyboard" regptr csdi,cs,di ; lpKeyName = "type" regptr csbx,cs,bx ; lpFile = "SYSTEM.INI" mov ax, 0 ; defualt is not reflect cCall GetPrivateProfileInt,<cssi, csdi, ax, csbx>
mov byte ptr [reflected], al pop es profinitdone: ;930206 endif ; NEC_98
cmp SystemIsInited,0 ; Have we already done this? jnz no_80x87 ; Yes inc SystemIsInited ; We will now init
mov ah,30h ; Get DOS version int 21h xchg ah,al ; major <-> minor mov DosVer,ax
ifdef HPSYSTEM call EnableVectra ;~~vvr 091889 endif
ifndef NEC_98 int 11h ; get equipment word push ax mov cl,6 shr ax,cl and al,00000011b ; isolate drive count mov numFloppies,al pop ax
; Set fBootDrive
mov fBootDrive,al ; bit 0 has boot volume installed flag endif ; NEC_98
; Set CoProcFlag
mov CoProcFlag,0 ifdef NEC_98 FINIT FINIT delay2 14 xor ax, ax mov NDP_CONTROL, ax ; clear temp FSTCW NDP_CONTROL delay2 14 and NDP_CONTROL, 0f3fh ; cmp NDP_CONTROL, 033fh ; jne no_80X87 FSTSW NDP_CONTROL delay2 14 inc ax test NDP_CONTROL, 0b8bfh jnz no_80X87 else ; NEC_98 test al,2 ; this is the IBM approved method jz no_80x87 ; to check for an 8087 endif ; NEC_98 mov CoProcFlag,94 ; size of save area FNINIT no_80x87: mov ax,1 pop ds ret
cEnd nogen
ifdef JAPAN ;-----------------------------------------------------------------------; ; JapanInquireSystem( what, which ) ; Get system information - Japanese specific. ; ; Entry: ; what - function code as; ; 0 - Inquire interrupt vector modification ; 'which' contains interrupt vector number (0-FF) ; to get it is can be changed. Returns zero if a ; vector cannot be changed ; 1 - Get Boot drive ; Returns boot drive. 0=A,1=B...etc. ; ;-----------------------------------------------------------------------;
assumes ds,nothing assumes es,nothing
cProc JapanInquireSystem,<PUBLIC,FAR> parmW what parmW which ifdef NEC_98 localW WKDRV ; 92.11.17 Win31 NEC endif ; NEC_98 cBegin mov ax,what test ax,ax ; what=1? jnz jis2 ; jump if not ifndef NEC_98 mov ax,which ; get vector number to examine cmp al,1bh ; try to change 1b? jz jis1 ; jump if so - cannot modify cmp al,1ch ; try to change 1c? jz jis1 ; jump if so - channot modify endif ; NEC_98 mov ax,1 ; OK to modify jmp jisx jis1: xor ax,ax ; cannot modify jmp jisx jis2: dec ax ; what=2? jnz jis3 ; jump if not ifdef NEC_98 mov ax,3000H ; Get DOS Version int 21H ; cmp al,05H jb jis3 mov ah,33H ; Get Boot Drive DOS5 mov al,05H int 21H mov dh,00h mov WKDRV,dx mov ax,WKDRV dec ax else ; NEC_98 mov ax,2 ; drive 'C:' is a default boot drive for ; industrial standard PC endif ; NEC_98 jmp jisx jis3: mov ax,-1 ; error! jisx: cEnd
endif ;JAPAN
sEnd CODE ; End of code segment
END InitSystem
|