📄 shadow.asm
字号:
;**************************************************************************
;*
;* SHADOW.ASM
;*
;* Copyright (c) 1999-2000 National Semiconductor Corporation.
;* All Rights Reserved.
;*
;* Function:
;* Routines copying ROM code and setting the R/W attributes for
;* xpress.rom code and other locations that may contain ROMs.
;*
;* $Revision:: 2 $
;*
;**************************************************************************
.386
INCLUDE ROMSORT.INC
INCLUDE DEF.INC
INCLUDE MACROS.INC
INCLUDE PORT80.INC
INCLUDE OPTIONS.INC
INCLUDE BDA.INC
_TEXT SEGMENT PUBLIC use16 'CODE'
EXTERN CpuMemRegRead:NEAR
EXTERN CpuMemRegWrite:NEAR
EXTERN optionRomChecksum:NEAR
;**************************************************************************
;*
;* shadowRom
;*
;* Shadow the F000 segment
;*
;* Entry:
;* Exit:
;* Destroys:
;*
;**************************************************************************
shadowRom PROC NEAR PUBLIC
push bx
;
; Enable F000:0 - F000:FFFF for writes to sdram
;
mov eax, CPU_BC_XMAP_3
NOSTACK bx, CpuMemRegRead
and edx, 00000ffffh
or edx, 022220000h
NOSTACK bx, CpuMemRegWrite
jmp $+2 ; Implicit Jump
mov eax, cr3 ; Force a TLB Flush
jmp $+2
push 0
pop es
;
; We need to leave a "flag" around for later code to use to see if we're
; booting off the MDOC or not. The way I chose to do this is to overwrite
; the MDOC boot vector with the signature 'MDOC' when we are booting from
; the MDOC. So we will check for this and do what's needed now!
;
mov ax, cs
cmp ax, 0F000h ; Booting from Flash ROM?
je @F ; Yep, nothing more to do...
; No, overwrite entry point with sig
mov eax, 'MDOC' ; so romCopy code can take appropriate
mov cs:[0FF00h], eax ; action when loading ROM images.
;
; We will also relocate the 3 lower segments of the ROM from 40000h-6FFFFh to
; 0002C0000h-0002EFFFFh. This gets it out of the way for PCATJUNK to clear
; RAM and allows VSA to clobber 6000h thru ...
;
mov esi, 040000h ; Starting here
mov edi, 2C0000h ; Copy to here
mov ecx, 030000h / 4 ; for 3 segments worth of stuff
cld
db 66h
db 67h
rep movsd es:[edi], es:[esi]
@@:
;
; mov esi, 0f0000h
; We use the current CS as the basis for where to copy from...
xor eax, eax
mov ax, cs
shl eax, 4
mov esi, eax
;
mov edi, 0f0000h
mov ecx, 004000h
cld
db 67h
rep movsd es:[edi], es:[esi]
pushf
cli ; Clear int's from occuring durings this critical portion
mov eax, CPU_BC_XMAP_3
NOSTACK bx, CpuMemRegRead
and edx, 000000000h
or edx, 099999999h
NOSTACK bx, CpuMemRegWrite
popf ; End Critical area
jmp $+2 ; Implicit Jump
mov eax, cr3 ; Force a TLB Flush
jmp $+2
; Now we have to do an intersegment jump to reach/switch to the F000h segment.
; If we're already running there it should cause no harm. If we were running
; from seg 7000h, we will now be running from seg F000h.
JUMP_FAR next_instruction; MACROS.INC
next_instruction:
pop bx
jmp bx
shadowRom ENDP
public videoshadowtable
videoshadowtable:
db (16*1024)/512 ; 16k size
dd 0fffffff0h ; +1 mask
dd 000000003h ; +5 result value
dd 000000002h ; +9 write enable only
dd 000000009h ; +13 read only
videoshadow_size EQU $-videoshadowtable
db (32*1024)/512 ; 32k size
dd 0ffffff00h ; +1 mask
dd 000000033h ; +5 result value
dd 000000022h ; +9 write enable only
dd 000000099h ; +13 read only
db (48*1024)/512 ; 48k size
dd 0fffff000h ; +1 mask
dd 000000333h ; +5 result value
dd 000000222h ; +9 write enable only
dd 000000999h ; +13 read only
db (64*1024)/512 ; 64k size
dd 0ffff0000h ; +1 mask
dd 000003333h ; +5 result value
dd 000002222h ; +9 write enable only
dd 000009999h ; +13 read only
db 0 ; end of table
;**************************************************************************
;*
;* shadowExtVGARom
;*
;* Shadow an external video rom.
;*
;* Entry:
;* ESI points to ROM to shadow
;* EDX points to orig value of XMAP_2
;*
;* Exit:
;* Destroys:
;*
;**************************************************************************
shadowExtVGARom PROC NEAR PUBLIC
push edi
push esi
push ebx
push ecx
push edx ; this MUST BE LAST PUSH!!!!
mov ax, 0
push ax
pop es ; 4gb selector
; check length - if 48k we need to shadow 1 more
mov di,offset videoshadowtable ; point to table
videoshadowloop:
mov al,cs:[di] ; get entry size
or al,al ; done?
jz donecopy ; too big - error
cmp al,byte ptr es:[esi+2] ; compare with rom
jae goshadow ; tab >=rom
add di,videoshadow_size ; point to next
jmp videoshadowloop
goshadow:
pop edx ; get final reg back
and edx,dword ptr cs:[di+1] ; mask off
or edx,dword ptr cs:[di+5] ; size to shadow
push edx ; resave
;
; now make c000:0 writeable only
;
push edi
mov eax, CPU_BC_XMAP_2 ; C000 and D000
NOSTACK bx, CpuMemRegRead
pop edi
and edx,cs:[di+1] ; mask
or edx,cs:[di+9] ; enable write
push edi
NOSTACK bx, CpuMemRegWrite ; Enable
pop edi
;
; now copy
;
mov ebx,0c0000h ; start address (dest)
xor cx,cx ; clear cx
mov cl,es:[esi+2] ; get length
shl cx,9 ; mult by 512
vgacopyloop:
mov al,es:[esi] ; get a byte
mov es:[ebx],al ; write it
inc ebx
inc esi
loop vgacopyloop
donecopy:
pop edx
pop ecx
pop ebx
pop esi
pop edi
ret
shadowExtVGARom ENDP
;**************************************************************************
;*
;* preUncompress
;*
;* Enable C000:0000 Through E000:FFFF for Read/Write
;*
;* Entry:
;* Exit:
;* Destroys:
;*
;**************************************************************************
preUncompress PROC NEAR PUBLIC
push eax
push ebx
push edx
mov eax, CPU_BC_XMAP_2 ; C000 and D000
NOSTACK bx, CpuMemRegRead
mov edx, 033333333h
NOSTACK bx, CpuMemRegWrite ; Enable all shadow
mov eax, CPU_BC_XMAP_3 ; E000
NOSTACK bx, CpuMemRegRead
mov edx, 011113333h
NOSTACK bx, CpuMemRegWrite ; Enable all shadow except F000
; Clear Shadow Ram
mov al, 0
mov ecx, 0C0000h ; For C000
mov edi, ecx ; Start at C000h
mov ecx, 030000h ; for 196k
cld
db 66h
rep stosb es:[edi]
mov eax, CPU_BC_XMAP_2 ; C000 and D000
mov edx, BCX2 ; setting for bc_xmap2 from bestfit
and edx, 0FFFFFF00h
or edx, 000000033h ; ensure c000-c800 rw
NOSTACK bx, CpuMemRegWrite
mov eax, CPU_BC_XMAP_3 ; E000 only
mov edx, BCX3 ; setting for bc_xmap3 from bestfit
and edx, 00000FFFFh
or edx, 033330000h ; enable the f000 region
NOSTACK bx, CpuMemRegWrite
pop edx
pop ebx
pop eax
ret
preUncompress ENDP
;**************************************************************************
;*
;* postUncompress
;*
;* Set C0000-C7FFF for Read Only
;*
;* Entry:
;* Exit:
;* Destroys:
;*
;**************************************************************************
postUncompress PROC NEAR PUBLIC
push eax
push ebx
push edx
push esi
push 0
pop es
; make video bios read only
; point to table for size
cmp word ptr es:[0c0000h],0aa55h ; isa rom here?
jne postnovid ; no
; check length - if 48k we need to shadow 1 more
mov si,offset videoshadowtable ; point to table
postvidloop:
mov al,cs:[si] ; get length
or al,al ; done?
jz postnovid ; too big - error
cmp al,byte ptr es:[0c0002h] ;compare with rom
jae setro ; tab >=rom
add si,videoshadow_size ; point to next
jmp postvidloop
setro:
mov eax, CPU_BC_XMAP_2 ; C0000 - C7FFF
NOSTACK bx, CpuMemRegRead
and edx,cs:[si+1] ; mask off
or edx,cs:[si+13] ; set ro
NOSTACK bx, CpuMemRegWrite
postnovid:
if 1 ;;;rjh 12/26/99 MDOC Needed to leave lowest 16 KB of E000 bank mapped
;;; to the PCI bus so we can see the DOC there! We'll
;;; only do this if we see the ROM at EBE0:0. This is
;;; an indication to us that the DOC H/W was found.
mov eax, CPU_BC_XMAP_3 ; E0000 - EFFFF
NOSTACK bx, CpuMemRegRead
and edx, 0FFFF0000h
or edx, 000009990h
mov ax, 0AA55h ; ROM signature
cmp ax, es:[0EBE00h] ; Find MDOC ROM there?
je @F ; Yep, map 16 KB @ E000 to PCI
or dl, 09h ; Nope, map all to shadow RAM
@@:
mov eax, CPU_BC_XMAP_3 ; E0000 - EFFFF
NOSTACK bx, CpuMemRegWrite
else ;;;rjh 12/26/99 MDOC
mov eax, CPU_BC_XMAP_3 ; E0000 - EFFFF
NOSTACK bx, CpuMemRegRead
and edx, 0FFFF0000h
or edx, 000009999h
NOSTACK bx, CpuMemRegWrite
endif;;;rjh 12/26/99 MDOC
pop esi
pop edx
pop ebx
pop eax
ret
postUncompress ENDP
_TEXT ENDS
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -