📄 flsnvrg.asm
字号:
mov (nvr_header ptr [si]).nvrhd_nvram_checksum, bl
cld
write_nvram_cksum:
lodsb ;AL = next byte from caller's buffer
add bl, al
loop write_nvram_cksum
popf
pop si
pop cx ;Update NVRam cksum in caller's buffer
neg bl
mov (nvr_header ptr [si]).nvrhd_nvram_checksum, bl
pop bx
call flash_write
mov ax, 0 ;AX = Code for no error
jnc write_nvram_done ;Br if Flash written OK
mov ax, RT_ESCD_READ_ERROR
write_nvram_done:
pop edi
pop esi
pop ecx
ret
rthnvr_write endp
;---------------------------------------;
; flash_write ;
;---------------------------------------;--------------------------------------;
; This function erases and writes the NVRam contents in Flash from a buffer ;
; supplied by the caller. ;
; ;
; Input: DS:SI = Buffer of data to write to NVRam ;
; ES:DI = Seg/Offset of NVRam (caller passes in whatever is returned ;
; by the rtnvr_get_escd_size function) ;
; CX = Size of Flash block to write ;
; ;
; Output: CF = Set if error, cleared otherwise ;
; ;
; Destroys: Nothing ;
;------------------------------------------------------------------------------;
flash_write proc near
call check_flash_presence ; flash part found ?
jc fw_err ; no flash part found
push ds
push es
pushad
pushf ;Save state of IF
cli
movzx esi,si
movzx edi,di
push ds
call go_to_big_mode ; call go_to_flat_mode_stack
pop ds
pushf ; NC/CY = not/yes real mode when the routine was invoked
; if CY then ZR/NZ = GA20 status (dis/en)abled
jnc fw_00 ; not in real mode
add edi,cgroup:rth_nvram_base
fw_00:
call flash_write_enable ; make flash R/W
push es
push ds
push es
push ds
pop es ; ES:SI = source buffer
pop ds ; DS:DI = NVRAM storage
mov bx,cgroup:word ptr flash_found_table
call cs:word ptr [bx+2] ; erase
jc flash_skip_write ; Br if error erasing
call cs:word ptr [bx+4] ; program
flash_skip_write:
pushf ; save status of programming flash
call flash_write_disable ; make flash write protected
popf
pop ds
pop es
mov al,00h ; AL = 00 for success
jnc flash_write_done ; success
mov al,0ffh ; AL <> 00 for error
flash_write_done:
popf ; CY = real mode
; if CY then ZR/NZ = GA20 status (dis/en)abled
jnc fw_01 ; no, so assume protected mode
call comeback_from_big_mode ; call comeback_from_flat_mode_stack
fw_01:
popf
cmp al,1
cmc ; NC/CY = success/error
popad
pop es
pop ds
fw_err:
ret
flash_write endp
;---------------------------------------;
; CHECK_FLASH_PRESENCE ;
; input : ;
; none ;
; output: ;
; nc flash present ;
; cy flash not found ;
; register destroyed : None ;
;---------------------------------------;
check_flash_presence:
cmp cgroup:word ptr flash_found_table,0ffffh
jz cfp_00 ; flash support not present
cmp cgroup:rth_nvram_base,00000000h
jz cfp_00 ; no NVRAM
cmp cgroup:rth_nvram_size,0000h
jnz cfp_01 ; NC, flash & NVRAM present
cfp_00:
stc ; error
cfp_01:
ret
;---------------------------------------;
;*****************************************************************;
;*****************************************************************;
;** **;
;** (C)Copyright 1985-1996, American Megatrends, Inc. **;
;** **;
;** All Rights Reserved. **;
;** **;
;** 6145-F Northbelt Pkwy, Norcross, GA 30071 **;
;** **;
;** Phone (770)-246-8600 **;
;** **;
;*****************************************************************;
;*****************************************************************;
;-----------------------------------------------------------------------;
; GO_TO_BIG_MODE ;
; this routine checks whether this call is made in real mode or not. ;
; if the call is made in real mode, it goes to flat protected mode and ;
; sets DS, ES with 4GB limit starting at physical address 00000000 and ;
; comes back to real mode with DS, ES limit set to 4GB. ;
; input : ;
; stack available ;
; output: ;
; NMI and interrupts disabled ;
; DS, ES set to 4GB limit with base 0000h ;
; NC routine was called in (not real mode) ;
; so it is assumed the routine was called in protected mode
; CY routine was called in (real mode) ;
; so this routine went to big real mode ;
; ZF GA20 status ;
; ZR GA20 was disabled when the routine was invoked
; NZ GA20 was enabled when the routine was invoked
; registers destroyted: DS, ES ;
; NOTE: this routine is invoked by CALL ;
;-----------------------------------------------------------------------;
extrn enable_addr_bit_20:near
public go_to_big_mode ; (CORE0072+)
go_to_big_mode:
pushad
; (CORE0072+)>
extrn bios_scratch:byte
test cs:byte ptr bios_scratch,bios_post_complete_bit; POST/Runtime ?
jz short gtbm_02 ; POST, so real mode
; <(CORE0072+)
mov ax,cs
cmp ax,0f000h
clc ; NC for not in real mode
jnz gtbm_01 ; not in real mode
gtbm_02:
cli ; Disable interrupts
; check the GA20 status..
; compare 256bytes at 0:0 with FFFF:10
; if match, GA20 is disabled else GA20 is enabled
push 0000h
pop ds ; DS = 0000
push 0ffffh
pop es ; ES = FFFF
mov cx,100h/4 ; #of Dwords in 256bytes
xor si,si
mov di,0010h
repz cmpsd
pushf ; save GA20 status ZR/NZ = disabled/enabled
jnz gtbm_00 ; GA20 is already enabled
call enable_addr_bit_20 ; enable GateA20
gtbm_00:
mov dx,0018h ; selector for flat segment
call go_big_mode ; go to protected mode and comeback to real mode
popf ; ZR/NZ = GA20 status
stc ; routine went to big real mode
gtbm_01:
popad
ret ; return to caller
;-----------------------------------------------------------------------;
; COMEBACK_FROM_BIG_MODE ;
;-----------------------------------------------------------------------;
; this routine comes back to real mode with DS, ES with 64KB limit at ;
; starting address 0000:0000. ;
; input : ;
; GA20 is currently enabled ;
; ZF GA20 final status ;
; ZR final status of GA20 is disabled ;
; NZ final status of GA20 is enabled ;
; stack available ;
; output: ;
; NMI and interrupts disabled ;
; DS, ES set to 64KB limit with base 0000h ;
; registers destroyted: DS, ES ;
; NOTE: this routine is invoked by CALL ;
;-----------------------------------------------------------------------;
extrn disable_addr_bit_20:near
public comeback_from_big_mode ; (CORE0072+)
comeback_from_big_mode:
pushad
cli ; Disable interrupts
pushf
mov dx,0010h ; selector
call go_big_mode
popf
jnz cfbm_00 ; keep GA20 enabled
call disable_addr_bit_20 ; disable GateA20
cfbm_00:
popad
ret
;-----------------------------------------------------------------------;
; GO_BIG_MODE ;
; this routine goes to protected mode, sets the DS, ES to the given ;
; selector, comes back to real mode and sets DS, ES to 0000. ;
; input : ;
; dx selector ;
; output: ;
; DS, ES set to 0000 ;
; register destroyed..EAX, DS, ES ;
;-----------------------------------------------------------------------;
extrn big_gdt:byte
go_big_mode:
mov al,8dh ; Disable NMI
out 70h,al
lgdt cgroup:fword ptr big_gdt+8
mov eax,cr0
or al,01h
mov cr0,eax ; in protected mode
db 0e9h,00h,00h ; Flush instruction queue - JMP (NEAR)
; to next instruction
mov ax,dx ; selector
mov ds,ax ; DS = selector
mov es,ax ; ES = selector
mov eax,cr0 ; come back into real mode with DS,ES
and al,0feh
mov cr0,eax
db 0e9h,00h,00h ; Flush instruction queue - JMP (NEAR)
; to next instruction
xor ax,ax
mov ds,ax ; DS = ES = 0
mov es,ax ;
ret
;-----------------------------------------------------------------------;
_text ends
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -