📄 optrinit.asm
字号:
;**************************************************************************
;*
;* OPTRINIT.ASM
;*
;* Copyright (c) 1998-1999 National Semiconductor Corporation.
;* All Rights Reserved.
;*
;* Function:
;* Routines for initializing and checksumming option ROMs.
;*
;* $Revision:: 4 $
;*
;**************************************************************************
.486P
INCLUDE MACROS.INC
INCLUDE DEF.INC
INCLUDE PORT80.INC
INCLUDE STRINGS.INC
INCLUDE OPTIONS.INC
_TEXT SEGMENT PUBLIC use16 'CODE'
ASSUME CS:SEGGROUP
EXTERN unReal:near
EXTERN CpuMemRegRead:NEAR
EXTERN CpuMemRegWrite:NEAR
OPTROM_SIG_1 equ 0
OPTROM_SIG_2 equ 1
OPTROM_LEN equ 2
OPTROM_INIT equ 3
;**************************************************************************
;*
;* optionRomChecksum
;*
;* Checksum an option rom
;*
;* Entry:
;* ESI - Address (linear) to checksum
;*
;* Exit:
;* AL = 0 if good checksum otherwise error
;* ZF - set if OK, cleared if error
;*
;* Destroys:
;* remainder of EAX
;*
;**************************************************************************
optionRomChecksum PROC NEAR PUBLIC
push dx ; save register
NOSTACK dx, unReal ; set es in unreal mode
pop dx ; restore
push esi ; save esi
push bx
push cx
xor bh, bh ; zero checksum
mov bl, fs:[esi+OPTROM_LEN]
cksum_new_block:
mov cx, 512/4 ; new block
cksum_loop:
mov eax,fs:[esi]
add esi, 4
add bh, al
add bh, ah
shr eax, 16
add bh, al
add bh, ah
loop cksum_loop
; one less block
dec bl ; done?
jnz cksum_new_block
; all done
mov al, bh ; checksum to al
pop cx ; restore cx
pop bx ; restore bx
pop esi ; restore esi
or al, al ; set ZF
ret
optionRomChecksum ENDP
;**************************************************************************
;*
;* optionRomInit
;*
;* Find and Call all Options roms from C800:0 to DFF0:0
;*
;* Entry:
;* Exit:
;* Destroys:
;*
;**************************************************************************
optionRomInit PROC NEAR PUBLIC
pusha ; Save return address
; Rom Scan 2000h & from C800 to EFF0h
push gs
mov ax, 02000h ; look for setup screen first
mov gs, ax
; xor di, di
nextRomPara:
mov gs, ax
cmp BYTE PTR gs:[OPTROM_SIG_1], 055h
jne IncRomScan
cmp BYTE PTR gs:[OPTROM_SIG_2], 0AAh
jne IncRomScan
; now call it
; but first see if checksum is valid!
xor esi, esi ; clear esi
mov si, gs ; get gs
shl esi, 4 ; convert to linear
call optionRomChecksum ; checksum
; if checksum == zero then we have a good option rom
jnz IncRomScan ; bad option rom
; call the rom
pusha
push gs
cld
push 0
pop ds
push 040h
pop es
push gs:[02H]
push cs
push OFFSET optionRomReturn
push gs
push OPTROM_INIT
retf
optionRomReturn:
pop cx ; Retrieve Size In 512 Byte Blobs
cmp byte ptr gs:[02H], 0
jne InitWorked ; If PCI ROM Failed (size is 0), Clear It Out
shl cx, 9 ; Convert To Actual Byte Count
DoItAgain:
mov bx, cx
mov byte ptr gs:[bx-1], 0ffH
loop DoItAgain
InitWorked:
; added code to reset limits and re-establish unreal mode as
; the option rom may (probably did) drop us out of unreal
; mode by using es
pop gs
popa
NOSTACK dx, unReal ; set es in unreal mode
; code to start looking at next rom AFTER the end of this one
mov ax, gs ; get base of this one
mov bl, byte ptr gs:[OPTROM_LEN] ; length in 512 byte blocks
xor bh, bh ; clear high
shl bx, 5 ; make paragraphs (32 paragraphs in 512)
add ax, bx ; add to old
jmp short CheckRomEnd
; look for rom at next 2k
IncRomScan:
cmp ax, 2000h
je GoToC800
mov ax, gs
add ax, 080h ; Next 2k
jmp CheckRomEnd
GoToC800:
mov ax, 0C800h ; move to the beginning of rom space
CheckRomEnd:
cmp ax, 0F000h ; We've reached the end of the E000 segment
jb nextRomPara ; change to jb in case misses F000
; clear memory used for working tables
call clearPCIWork
pop gs
popa
ret
optionRomInit ENDP
;**************************************************************************
;*
;* ClearPCIWork
;*
;* Entry:
;* Exit:
;* Destroys:
;*
;**************************************************************************
ClearPCIWork PROC NEAR PUBLIC
;code to make shadowed area READ ONLY
; get xmap_2
push ebx
mov eax, CPU_BC_XMAP_2 ; C000 and D000
NOSTACK bx, CpuMemRegRead
mov cx, 8
mov ebx,edx ; get current setting for xmap_2
and edx, NOT 22222222h ; turn off write
writeloop2:
mov ch, bl
and ch, 0fh
cmp ch, 0fh ;test for vsa
jne nextwriteloop2
or dl, 0h ;turn writes back on for vsa (not anymore)
and dl, 0fbh ;turn off cache
nextwriteloop2:
xor ch, ch
shr ebx, 4
ror edx, 4
loop writeloop2
mov ecx,edx ; get setting
and ecx,11111111h ; only shadowed
shl ecx,3 ; shift to high bit of nybble
or edx,ecx ; or in high bits if any
NOSTACK bx, CpuMemRegWrite
mov eax, CPU_BC_XMAP_3 ; E000
NOSTACK bx, CpuMemRegRead
mov cx, 8
mov ebx,edx ; get current setting for xmap_3
and edx, NOT 22222222h ; turn off write
writeloop3:
mov ch, bl
and ch, 0fh
cmp ch, 0fh ;test for vsa
jne nextwriteloop3
or dl, 0h ;turn writes back on for vsa (not anymore)
and dl, 0fbh ;turn off cache
nextwriteloop3:
xor ch, ch
shr ebx, 4
ror edx, 4
loop writeloop3
mov ecx,edx ; get setting
and ecx,11111111h ; only shadowed
shl ecx,3 ; shift to high bit of nybble
or edx,ecx ; or in high bits if any
NOSTACK bx, CpuMemRegWrite
wbinvd ; Flush cache of any VSM code
pop ebx
ret
ClearPCIWork ENDP
_TEXT ENDS
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -