📄 himem2.asm
字号:
call DispSignOnMsg ; make sure user sees signon msg
mov ah, 9
int 21h
DIM_ret:
ret
DispInfoMsg endp
DispInfoChar proc near
cmp cs:[fQuiet], 0
jnz short DIC_ret
call DispSignOnMsg ; make sure user sees signon msg
mov ah, 2
int 21h
DIC_ret:
ret
DispInfoChar endp
DispErrMsg proc near ; display an error msg
mov cs:[fQuiet], 0 ; no longer in QUIET mode
call DispSignOnMsg ; make sure user sees signon before
mov ah, 9 ; error msg
int 21h
ret
DispErrMsg endp
DispSignOnMsg proc near
cmp cs:[fQuiet], 0 ; don't signon if in QUIET mode
jnz short DSM_ret
cmp cs:[fSignOnMsg], 0 ; don't signon more than once
jnz short DSM_ret
push dx ; display the signon message
push ds
push cs ; in case ds != _text
pop ds
mov ah, 9
mov dx,offset SignOnMsg
int 21h
mov cs:[fSignOnMsg], 0FFh
pop ds
pop dx
DSM_ret:
ret
DispSignOnMsg endp
;
;----------------------------------------------------------------------------
; procedure : LocateHiSeg
;
; Locate the movable segment properly in the low seg.
; taking care of the stripped ORG zeroes. This function
; calculates the segment at which the hiseg should run
; with the ORG. If the segment cvalue goes below zero the
; code is moved up high enough to run the code from a seg value
; of zero.
;
; This function assumes that the 'funky' segment follows
; immediately after the text seg.
;
;----------------------------------------------------------------------------
;
LocateHiSeg proc near
push ds
mov ax, cs ; para start of text seg
mov cx, offset _text:EndText ; end of text seg
add cx, 15 ; para round it
shr cx, 1
shr cx, 1
shr cx, 1
shr cx, 1
add ax, cx ; para start of funky seg
cmp ax, (HISEG_ORG shr 4) ; will the seg go below zero?
jb MoveHiSeg ; yeah, we have to move it
sub ax, (HISEG_ORG shr 4) ; no, it fits in
pop ds
mov hiseg, ax ; update the segment in which
; it is going to run from.
ret
MoveHiSeg:
mov ds, ax ; segment at which funky
; resides without the ORG
xor ax, ax
mov es, ax ; we want to movve the code
; to 0:HISEG_ORG
mov di, offset funky:end_of_funky_seg
mov si, di
sub si, HISEG_ORG
mov cx, si
dec di
dec si
std ; move backward (safe when
; source & dest overlap
rep movsb
cld
pop ds
mov hiseg, 0 ; funky is going to run from
; segment zero
ret
LocateHiSeg endp
;*----------------------------------------------------------------------*
;* *
;* HookInt2F - *
;* *
;* Insert the INT 2F hook *
;* *
;* ARGS: None *
;* RETS: None *
;* REGS: AX, SI, ES and Flags are clobbered *
;* *
;*----------------------------------------------------------------------*
public HookInt2F
HookInt2F proc near
cli
xor ax,ax
mov es,ax
mov si,2Fh * 4 ; save previous int2f vector
mov ax,offset Int2FHandler ; and exchange with new one
xchg ax,es:[si][0]
mov word ptr [PrevInt2F][0],ax
mov ax,cs
xchg ax,es:[si][2]
mov word ptr [PrevInt2F][2],ax
sti
ret
HookInt2F endp
;*----------------------------------------------------------------------*
;* *
;* ShadowRAMOff - *
;* *
;* Attempt to turn off shadow RAM on selected machines. Add the *
;* memory to our free pool if successful. *
;* *
;* ARGS: None *
;* RETS: DX - Msg to show user (or 0), & *
;* CY clear - success, *
;* CY set - warning/failed *
;* REGS: AX destroyed *
;* *
;*----------------------------------------------------------------------*
public ShadowRAMOff
ShadowRAMOff proc near
push es
push di
push si
push cx
push bx
call Compaq386 ; on a Compaq 386?
jz SOIsCompaq
jmp SONotCompaq
; Disable shadow RAM on a Compaq 386
SOIsCompaq:
; check if the video bios points
xor ax,ax ; into the ROM copy, we don't
mov es,ax ; want to disable if someone has
mov ax,es:[10h*4+2] ; already hooked Int 10h, 1Fh, 43h,
call IsC000orE000 ; or 6Dh
jnz SORomHooked
mov ax,es:[1Fh*4+2]
call IsC000orE000
jnz SORomHooked
mov ax,es:[43h*4+2]
call IsC000orE000
jnz SORomHooked
cmp word ptr es:[6dh*4+2],0C000h ; finally, make sure Int 6Dh
jae SOVideoOkay ; points somewhere reasonable
SORomHooked:
mov dx,offset ROMHookedMsg ; somebody has video ROM hooked!
jmp short SONoCanDo
SOVideoOkay:
; Check to see if this machine allows the ROM to be unmapped
call unmap_permited
jc SOROMNotSupported
; Looks good, lets disable the RAM copy. This is done by doing
; an Int 15h blockmove of a command word to the Compaq diagnostic
; register. We share data structures with the Compaq BIM code.
mov si,pBIMGDT ; setup block move GDT
mov ax,cs
mov es,ax
mov cx,16
mul cx
add ax,offset BIMBuffer
adc dl,0
mov [si].S_BASE_LOW,ax
mov [si].S_BASE_HI,dl
mov cx,1
mov word ptr [BIMBuffer],0FFFFh ; disable ROM replace command
mov ah,87h
int 15h
; Point the video vectors back at the original ROM
mov ax,0
mov es,ax
mov ax,0C000h
mov es:[10h*4+2],ax
mov es:[1Fh*4+2],ax
mov es:[43h*4+2],ax
; If Int 6Dh points at the now disabled ROM, change that too
cmp word ptr es:[6Dh*4+2],0E000h
jnz @f
mov es:[6Dh*4+2],ax
@@:
; Add the ram space to our free list
mov ax,128 ;128k @ FE0000h
mov cx,3F80h ; (FE0000h / 1024)
xor dx, dx
mov bx, dx
mov di, pAddMem
push cs
call call_hi_in_di
mov dx,offset ROMDisabledMsg ; Success!
clc
SODone:
pop bx
pop cx
pop si
pop di
pop es
ret
SONotCompaq:
SOROMNotSupported:
mov dx,offset UnsupportedROMMsg ; don't know how to disable
SONoCanDo: ; only show msg if user wanted
cmp fShadowOFF,0FFh ; to disable--if trying cause
jnz SOFailed ; of too little extended mem,
xor dx,dx ; keep quiet.
SOFailed:
stc
jmp short SODone
ShadowRAMOff endp
IsC000orE000 proc
cmp ax,0C000h ; Video ROM pointers can
jz @f ; point to either of
cmp ax,0E000h ; these locations, but
@@: ret ; no others.
isC000orE000 endp
;------------------------------------------------------------------------
; UNMAP_PERMITED - This function will check if unmap roms is available.
;
; Entry: Nothing.
;
; Returns: Carry Flag Clear - Can Unmap
; Carry Flag Set - Can Not Unmap
;
;------------------------------------------------------------------------
MACHINE_ID equ 25h
unmap_permited proc near ; == Check if unmap roms permitted ==
mov al, MACHINE_ID ; CMOS location to read
out 70h, al ; Out CMOS location address
in al, 71h ; Read data at that location
or al, al ; Q: Is it Zero
jz unmap_permited_error ; Y: Can not unmap
test al, 1000b ; Q: can we unmap (Soft drive type)
jz unmap_permited_ok ; Y: continue
unmap_permited_error:
stc ; Set error condition - Can not unmap
unmap_permited_ok:
ret ; Done
unmap_permited endp
;*----------------------------------------------------------------------*
;* *
;* GetBIMMemory - *
;* *
;* Look for Compaq 'Built In Memory' and add it to the pool of *
;* available memory *
;* *
;* ARGS: None *
;* RETS: AX = Amount of BIM memory found *
;* REGS: AX, BX, CX, and Flags are clobbered *
;* *
;*----------------------------------------------------------------------*
; "Built In Memory" (BIM) starts at FE00:0000h and grows downward. It is
; controlled by a data structure at F000:FFE0h. Changing the data structure
; involves un-write-protecting the ROMs (!) by flipping bit 1 of 80C00000.
pBIMSTRUCT equ 0FFE0h
AVAILABLE equ 0 ; Set to -1 if BIM isn't around
TOTALBIM equ 2 ; Total amount of BIM in the system
AVAILBIM equ 4 ; Amount of BIM available in paragraphs
LASTUSED equ 6 ; Paragraph address of last (lowest) used
; paragraph of BIM
GDT_TYPE struc
dw 0,0,0,0
dw 0,0,0,0
S_LIMIT dw 1
S_BASE_LOW dw 0
S_BASE_HI db 0
S_RIGHTS db 93h
S_RESERVED dw 0
D_LIMIT dw 1
D_BASE_LOW dw 0000h
D_BASE_HI db 0C0h
D_RIGHTS db 93h
D_RES386 db 0
D_BASE_XHI db 080h
dw 0,0,0,0
dw 0,0,0,0
GDT_TYPE ends
BIMGDT GDT_TYPE <>
GetBIMMemory proc near
xor ax,ax
; Are we on a Compaq 386 machine?
push bx
push es
; Is there a 32-bit memory board installed?
mov es,cs:WORD PTR (pCOMPAQ+2) ; ROM segment
mov bx,pBIMSTRUCT
mov bx,es:[bx] ; De-reference the pointer
mov dx,es:[bx+AVAILABLE] ; -1 means no board is installed
inc dx
jz FCMNoMem2 ; Nope, return
; How much memory is available and where does it start?
mov dx,es:[bx+AVAILBIM] ; Size in paragraphs
or dx,dx ; Any left?
jz FCMNoMem2
mov cx,dx ; CX = Size in paragraphs
mov ax,es:[bx+LASTUSED]
sub ax,cx ; AX = Starting location - F0000h
; in paragraphs
push es ; Save for a rainy day...
push bx
push ax
shr ax,4 ; get base address in KBytes
add ax,0f000h
shr ax,2
shr cx,6 ; get the size in Kbytes
mov [BIMBase],ax ; store for use by HookInt15
mov [BIMLength],cx
; Un-WriteProtect the ROMs.
mov si,pBIMGDT ; Set up the BlockMove GDT
mov ax,cs
mov es,ax
mov cx,16
mul cx
add ax,offset BIMBuffer
adc dl,0
mov [si].S_BASE_LOW,ax
mov [si].S_BASE_HI,dl
mov cx,1
mov word ptr [BIMBuffer],0fefeh ; 0feh unlocks the ROMs
mov ah,87h ; Do the BlockMove
int 15h
or ah,ah ; Was there an error?
jz FCMReserve ; Nope - continue
; Return error.
pop ax ; Clean up
pop bx
pop es
xor ax,ax
mov [BIMBase],ax
mov [BIMLength],ax
FCMNoMem2:
jmp short FCMNoMem
; Change the ROM values to reserve the BIM stuff.
FCMReserve:
pop ax
pop bx
pop es
mov word ptr es:[bx+AVAILBIM],0 ; Reserve all remaining BIM
mov word ptr es:[bx+LASTUSED],ax
; Re-WriteProtect the ROMs.
push cs
pop es
mov si,pBIMGDT ; Set up the BlockMove GDT
mov word ptr [BIMBuffer],0fcfch ; 0fch locks the ROMs
mov ah,87h ; Do the BlockMove
int 15h
mov ax,1 ; Return success
FCMNoMem:
pop es
pop bx
ret
EndGetBIMMemory:
GetBIMMemory endp
;*----------------------------------------------------------------------*
;* *
;* CheckBIM - *
;* *
;* Check if Compaq built in memory is available *
;* *
;* ARGS: AX = Kbytes of int 15 memory *
;* RETS: AX = Amount of BIM and int 15 memory *
;* REGS: AX and Flags are clobbered *
;* *
;*----------------------------------------------------------------------*
public CheckBIM
CheckBIM proc near
push es
push bx
push dx
call Compaq386 ; Are we on a Compaq 386 machine?
jnz CBNoBIM ; N: return
mov bx,pBIMSTRUCT ; ROM data sructure
mov bx,es:[bx] ; pointer to BIM data structure
mov dx,es:[bx+AVAILABLE] ; -1 means no board is installed
inc dx ;Q: Is there a 32-bit memory board installed?
jz CBNoBIM ; N: return
; Y: How much memory is available?
mov dx,es:[bx+AVAILBIM] ; Size in paragraphs
or dx,dx ;Q: Any BIM available?
jz CBNoBIM ; N: return
call getBIMMemory ; allocate it and get base/size
; Just allocate the damn BIM memory now. (Used to be a big headache
; to install a deferred BIM driver, depending on whether Shadow
; RAM was disabled.)
mov cx,[BIMBase] ; add Compaq BIM to our free list
jcxz CBNoBIM
mov ax,[BIMLength]
xor dx, dx
mov bx, dx
mov di, pAddMem
push cs
call call_hi_in_di
CBNoBIM:
pop dx
pop bx
pop es
ret
CheckBIM endp
;*----------------------------------------------------------------------*
;* *
;* Compaq386 - *
;* *
;* Check if running on a Compaq 386 system. *
;* *
;* ARGS: none *
;* RETS: Z set - on a Compaq 386, NZ - not Compaq 386 *
;* ES = ROM segment *
;* REGS: Flags are clobbered *
;* *
;*----------------------------------------------------------------------*
szCOMPAQ db '03COMPAQ'
public Compaq386
Compaq386 proc near
push si
push di
push cx
les di,cs:pCOMPAQ ; Are we on a Compaq 386 machine?
mov si,offset szCOMPAQ
mov cx,8
cld
rep cmpsb ;Q: Are we?
pop cx
pop di
pop si
ret
Compaq386 endp
;*----------------------------------------------------------------------*
;* *
;* CheckZBim - *
;* *
;* Check if Zenith Bim (0fa0000h x 256K) is available *
;* Call AddMem with it if so *
;* *
;*----------------------------------------------------------------------*
ZDS_string db 'ZDS CORP'
ZDS_len = ($-ZDS_string)
f000 dw 0f000h
public CheckZBIM
CheckZBim proc near
call GetInt15Memory ; This code added for old systems with
cmp ax, 2048 ; low memory, skip it if 'sufficient'
jae no_ZBIM ; ext memory cause it scribbles on
; memory just below 16 meg
cld ; better safe than sorry
mov si,offset ZDS_string
mov es,f000
mov di,800ch ; look for ZDS CORP at f000:800c
mov cx,ZDS_len
repz cmpsb
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -