📄 cpu586.asm
字号:
; DH : Actual CPU clock index found
; DL : Single/Double/Trible
;-----------------------------------------------------------------
ALIGN 16
S_Cpu proc far
call far ptr XMeasureNoRDTSCCpuClck
mov ax,26f5h ;dividend low word
mov dx,005ah ;dividend high word
mov bh,byte ptr FIXED_DISK_STEP[bp]
and bh,CPU_TYPE_MASK
cmp bh,TYPE_AMD5K86 ;K86 CPU
jne AmdK86_CPU
mov dl,4AH ;for K86
AmdK86_CPU:
cmp bh,TYPE_M1
jne Not_M1
mov ax,0dbb8h
mov dl,56h
jmp Not_Cyrix_Cpu
Not_M1:
;Change frequency detection factor for Rise/mP6 CPU
call Check_RiseCpu ;is Rise mP6 CPU ?
jne NotMp6Cpu
mov ax,0000h ;factor high word
mov dl,34h ;factor low word
jmp Not_Cyrix_Cpu
NotMp6Cpu:
cmp byte ptr CPU_BRAND[bp],CPU_BRAND_CYRIX
je Yes_Cyrix_Cpu
jmp Not_Cyrix_Cpu
Yes_Cyrix_Cpu:
mov ax,64a8h
mov dl,4eh
Not_Cyrix_Cpu:
div cx
xor bl,bl
Sub_1:
inc bl
sub ax,100
jc Fin_0
jz No_Carry
jmp Sub_1
Fin_0:
add ax,100
cmp al,50
jae No_Carry
dec bl
No_Carry:
;------------------------------------------------------------------
;calculate system clock by checking CPU type (Single/Double/Treble)
;------------------------------------------------------------------
Xchg_CPU_Mode_OK:
xor bh,bh
mov ax,bx
mov bl,1
call Check_586_Cpu ;p5 class CPU ?
je Single_Freq ;yes,
Single_Freq:
div bl
add al,3 ;tolerance
Skip_Gap:
mov dh,al ;DH = Actual CPU clock found
mov dl,bl ;DL = Single/Double/Trible
mov si,offset Sys_Clock_Tbl
mov cx,Sys_Clock_Tbl_Len
;far call Round_Off_Clock
FAR_CALL <offset Round_Off_Clock>,0E000h
ret
Check_586_Cpu proc near
push bx
mov bh,byte ptr FIXED_DISK_STEP[bp]
and bh,CPU_TYPE_MASK
cmp bh,TYPE_AMD5K86 ;K86 CPU
je Yes_P5_Class
cmp bh,TYPE_586 ;Pentium CPU?
je Yes_P5_Class
cmp bh,TYPE_M1
je Yes_P5_Class
Yes_P5_Class:
pop bx
ret
Check_586_Cpu endp
even
Last_S_Cpu Label Near
S_Cpu endp
;[]--------------------------------------------------------------[]
;Input : AL = Clock to be compared
; SI = table offset
; (format: reference System_Clock_Table)
; CX = no of entries
;
;Output : BH = reference value (see System_Clock_Table)
; BL = round-offed value
; SI = offset which round-offed value locates
;[]--------------------------------------------------------------[]
Round_Off_Clock Proc Far
Next_Clk_Tbl:
mov bx,cs:[si]
cmp al,bh
jae @F
cmp byte ptr cs:[si+3],0 ;last table ?
je @F
add si,3 ;next table
jmp Next_Clk_Tbl
@@:
retf
Round_Off_Clock Endp
;--------------------------------------------------------------------
; round value value
; offed for to be put
; output reference into G_RAM:CPU_CLOCK
;--------------------------------------------------------------------
Sys_Clock_Tbl:
db CPU66, 66, CPU66
db CPU60, 60, CPU60
db CPU50, 50, CPU50
db CPU40, 40, CPU40
db CPU33, 33, CPU33
db CPU25, 25, CPU25
db CPU20, 20, CPU20
db CPU16, 16, CPU16
db 0 ;end of table
Sys_Clock_Tbl_Len EQU ($ - offset Sys_Clock_Tbl)/3
;--------------------------------------------------------------------
; round value value
; offed for to be put
; output reference into G_RAM:CPU_CLOCK
;--------------------------------------------------------------------
CPU_Int_Clock_Tbl:
;Add P55C-150,P54CT-150,P54CT-166 and P54CT-180
ifdef LOW_CLOCK_VALUE_FOR_P5
db 200, 193, CPU66 ;66x3
db 180, 174, CPU60 ;60x3
db 166, 161, CPU66 ;66x2.5
else; LOW_CLOCK_VALUE_FOR_P5
ifdef Higher_200MHz_Tbl
db 200, 197, CPU66 ;66x3
else ;Higher_200MHz_Tbl
db 200, 195, CPU66 ;66x3
endif ;Higher_200MHz_Tbl
ifdef LUCKY_START_166_CPU_DETECT
db 180, 180, CPU60 ;60x3
else ;LUCKY_START_166_CPU_DETECT
db 180, 179, CPU60 ;60x3
endif ;LUCKY_START_166_CPU_DETECT
db 166, 163, CPU66 ;66x2.5
endif; LOW_CLOCK_VALUE_FOR_P5
db 150, 145, CPU60 ;60x2.5
;add P54CS CPU support for 120 & 132 MHz
ifdef Higher_133MHz_Tbl
db 133, 129, CPU66 ;66x2
else ;Higher_133MHz_Tbl
db 133, 127, CPU66 ;66x2
endif ;Higher_133MHz_Tbl
db 125, 121, CPU50
db 120, 118, CPU60 ;60x2
ifndef No_55MHz
ifndef NO_110MHZ_CLOCK
ifdef Higher_110MHz_Tbl
db 110, 108, CPU50 ;55x2
else ;Higher_110MHz_Tbl
ifdef LOW_CLOCK_VALUE_FOR_P5
db 110, 105, CPU50 ;55x2
else; LOW_CLOCK_VALUE_FOR_P5
db 110, 107, CPU50 ;55x2
endif; LOW_CLOCK_VALUE_FOR_P5
endif ;Higher_110MHz_Tbl
endif; NO_110MHZ_CLOCK
endif ;No_55MHz
ifdef Force_100_EQU_50_Double
db 100, 95, CPU50
else ;Force_100_EQU_50_Double
ifdef Special_P54C_Clock
db 100, 100, CPU66 ;66x1.5
else ;Special_P54C_Clock
db 100, 95, CPU66 ;66x1.5
endif ;Special_P54C_Clock
endif ;Force_100_EQU_50_Double
db 90, 89, CPU60 ;60x1.5
db 83, 81, CPU50 ;55x1.5
db 75, 70, CPU50 ;50x1.5
db 66, 60, CPU66 ;66x1
db 0 ;end of table
;--------------------------------------------------------------------
; round value value
; offed for to be put
; output reference into G_RAM:CPU_CLOCK
;--------------------------------------------------------------------
M1_Int_Clock_Tbl:
ifdef LOW_CLOCK_VALUE_FOR_P5
db 200, 193, CPU66 ;66x3
db 180, 174, CPU60 ;60x3
else; LOW_CLOCK_VALUE_FOR_P5
db 200, 195, CPU66 ;66x3
db 180, 179, CPU60 ;60x3
endif; LOW_CLOCK_VALUE_FOR_P5
ifdef Lower_150MHz_Tbl
db 150, 143, CPU75 ;75*2
else; Lower_150MHz_Tbl
db 150, 145, CPU75 ;75*2
endif; Lower_150MHz_Tbl
ifdef Higher_133MHz_Tbl
ifdef Special_Cyrix_Tbl_For_VLSI59X
db 133, 130, CPU66 ;66x2
else ;Special_Cyrix_Tbl_For_VLSI59X
db 133, 129, CPU66 ;66x2
endif ;Special_Cyrix_Tbl_For_VLSI59X
else ;Higher_133MHz_Tbl
db 133, 127, CPU66 ;66x2
endif ;Higher_133MHz_Tbl
ifndef Higher_120MHz_Tbl
db 120, 118, CPU60 ;60x2
else ;Higher_120MHz_Tbl
db 120, 120, CPU60 ;60x2
endif ;Higher_120MHz_Tbl
ifndef No_55MHz
ifndef NO_110MHZ_CLOCK
ifdef Higher_110MHz_Tbl
ifdef Special_Cyrix_Tbl_For_VLSI59X
db 110, 109, CPU50 ;55x2
else ;Special_Cyrix_Tbl_For_VLSI59X
db 110, 108, CPU50 ;55x2
endif ;Special_Cyrix_Tbl_For_VSI59X
else ;Higher_110MHz_Tbl
ifdef LOW_CLOCK_VALUE_FOR_P5
db 110, 105, CPU50 ;55x2
else; LOW_CLOCK_VALUE_FOR_P5
db 110, 107, CPU50 ;55x2
endif; LOW_CLOCK_VALUE_FOR_P5
endif ;Higher_110MHz_Tbl
endif; NO_110MHZ_CLOCK
endif ;No_55MHz
ifdef Special_P54C_Clock
db 100, 100, CPU50 ;50x2
else ;Special_P54C_Clock
db 100, 95, CPU50 ;50x2
endif ;Special_P54C_Clock
db 80, 70, CPU40 ;40x2
db 66, 64, CPU66 ;66x1
db 60, 58, CPU60 ;60x1
db 50, 48, CPU50 ;50x1
db 0 ;end of table
;;;;; P24T_Int_Clock_Tbl:
;;;;; ifndef P6_BIOS_ONLY
;;;;; db 125, 110, CPU50
;;;;; db 100, 95, CPU40
;;;;; db 83, 75, CPU33
;;;;; db 63, 55, CPU25
;;;;; db 50, 45, CPU20
;;;;; db 0
;;;;; endif; P6_BIOS_ONLY
;;;;;
;;;;; Cpu_Speed_Msg: db 'CPU Clock',0
;Function : Program MTRR for CPUs like P6 or P55CT
;Input : AL = 0 - program MTRR for conventional memory (0-640K)
; = 1 - program MTRR for extended memory (1Mb to top of memory)
; Bit 7 = 1 - 15-16MB memory hole is disabled(P6 only)
; esi - extended memory size
; BL = 0 - L2 cache status (0-disabled, 1-enabled)
; BH = L2 Cacheable range 000=512Mb , 001=1Gb, 010=2Gb, 011=4Gb
; 100=8Gb , 101=16Gb,110=32Gb,111=64Gb
; only for Pentium II CPUs
;Output : none
ifdef Special_Align_for_M1_Clock_unstable
ALIGN 16
endif; Special_Align_for_M1_Clock_unstable
Public Set_Cpu_MtRR
Set_Cpu_MtRR proc near
;Program cacheable region for M1 CPU
;BIOS have to set cacheable memory size for M1 CPU according to detected
;memory.
;Table for M1 CPU cacheable region control
; memory size value of reg.
; ----------- -------------
; 1Mb 03H
; 2Mb 04H
; 4Mb 05H
; 8Mb 06H
; ... ...
; 4Gb 0FH
or al,al ;for extended memory ?
jz Not_M1Cpu
mov al,byte ptr FIXED_DISK_STEP[bp] ;get CPU type
and al,CPU_TYPE_MASK
cmp al,TYPE_M1 ;6x86 CPU ?
jne Not_M1Cpu
push esi
shl esi,10
and esi, 0fff00000h
shr esi,10
mov ebx,esi
add ebx,1024 ;add 1Mb base address
push ebx ;save ext memory size
shr ebx,10 ;convert to 1Mb unit
mov ah,3 ;value for 1Mb
mov si,1 ;minmum is 1Mb
Chk_MemSize:
cmp bx, si ;if main memory size <= cacheable
;memory size
jbe Value_Ok0 ;yes
shl si, 1 ;next memory size
inc ah ;next register value
jmp Chk_MemSize ;recheck again
Value_Ok0:
F000_call Unlock_Cyrix ;open cyrix register locked
;set cacheable region for M1 CPU in ARR7
mov cl, 0dbh ;ARR7
mov al, ah ;set cacheable region
call F000_Set_Cyrix
cmp bx, si ;if main memory = cacheable memory
pop ebx ;restore memory size
je Value_Ok ;yes , finish
push ebx ;Save memory size
shr ebx, 2 ;EBX b4-b23 -> A12-A31
shl ebx, 4
mov cl, 0d8h ;ARR6
mov al, bl ;set A15-A12 address
call F000_Set_Cyrix
shr ebx, 8 ;EBX bit 15-0 => A31-A16
mov cl, 0d6h ;ARR6
mov al, bh ;set A31-A24
call F000_Set_Cyrix
mov cl, 0d7h ;ARR6
mov al, bl ;set A23-A16
call F000_Set_Cyrix
mov cl, 0E2h
mov al, 1 ;ARR6 as non-cacheable
call F000_Set_Cyrix
pop ebx ;get onboard memory size
shr ebx, 10 ;ebx=ebx/1024 convert 1M
mov ax, bx ;ax= onboard memory size
mov bx, si ;Get Cacheable size
sub bx, ax ;bx=must set noncacheable memory size
mov ch, 0 ;ch=D8h value if bx=0
jz Value_Ok1 ;go to set D8h value
mov ch, 0Fh ;value for 32MB
mov si, 01000000b ;minnum is 32MB
xor dx, dx ;initial surplus value
Chk_MemSize1:
shr si, 1 ;next memory size
dec ch ;next register value
cmp bx, si ;if must set noncacheable memory size
;=> noncacheable memory size
jae Value_Ok1 ;then check it is on the times value
jmp Chk_MemSize1;next value to check
Value_Ok1:
push ax ;save onboard memory size
push dx ;save surplus value
div si ;onboard memory size DIV
;noncacheable memory size
or dx, dx ;if on the value
pop dx ;restore surplus value
pop ax ;restore onboard memory size
jnz Chk_MemSize1 ;go to set it
mov cl, 0D8h ;ARR6
call F000_Get_Cyrix
and al, 11110000b
or al, ch ;set REGION BLOCK size
call F000_Set_Cyrix
cmp bx, si ;if must set noncacheable memory size
;= set noncacheable memory size
je Value_Ok ;then set finish
push bx ;save next must noncacheable address
; MB is it unit
xor ebx, ebx ;clear ebx
mov cl, 0d6h ;ARR6 Noncacheable A31-A24
call F000_Get_Cyrix
mov bh, al
mov cl, 0d7h ;ARR6 Noncacheable A23-A16
call F000_Get_Cyrix
mov bl, al ;now BX is system memory size
shl ebx, 16 ;ebx Bit 31 - 16 is A31-A16
mov cl, 0d8h ;ARR6 Noncacheable A15-A12
call F000_Get_Cyrix
mov bh, al ;ebx Bit 31 - 12 is A31-A12
xor eax, eax ;clear eax
mov ax, si ;get last set cacheable memory size
shl eax, 20 ;EAX b31-b12 => A31-A12
add ebx, eax ;BX is next noncacheable start address
;Bit 31-12 is A31-A12
;now BX is next noncacheable address
mov al, bh ;set A15-A12
mov cl, 0d5h ;ARR5 A15-A12
call F000_Set_Cyrix
shr ebx, 16 ;EBX bit 15-0 is A31-A16
mov al, bl
mov cl, 0d4h ;ARR5 A23-A16
call F000_Set_Cyrix ;set A23-A16
mov al, bh
mov cl, 0d3h ;ARR5 A31-A24
call F000_Set_Cyrix ;set A31-A24
mov cl, 0e1h
mov al, 1 ;Set ARR5 noncacheable region
call F000_Set_Cyrix
pop bx ;get must noncacheable address
mov ax, si ;Get last Cacheable size
sub bx, ax ;if noncacheable address =
;Cacheable size
mov ax, bx ;ax is must noncacheable address
mov ch, 0 ;ch is D5 value
jz Value_Ok2 ;go set D5 value
mov ch, 0fh ;value for 32MB D5 value
mov si, 01000000b ;maxnum is 32MB
Chk_MemSize2:
shr si, 1 ;next memory size
dec ch ;next register value
cmp bx, si ;if must noncacheable address
;=> Cacheable size
jae Value_Ok2 ;go to check is it on the times value
jmp Chk_MemSize2;check next vlaue
Value_Ok2:
push ax ;save must noncacheable address
push dx ;save surplus value
div si ;onboard memory size DIV
;noncacheable memory size
or dx, dx ;if on the value
pop dx ;restore surplus value
pop ax ;restore onboard memory size
jnz Chk_MemSize2 ;go to set it
mov cl, 0D5h ;ARR5
call F000_Get_Cyrix
and al, 11110000b ;set REGION BLOCK value
or al, ch
call F000_Set_Cyrix
cmp bx, si ;if must set noncacheable memory size
;= set noncacheable memory size
je Value_Ok ;then set finish
push bx ;save must noncacheable address ( MB )
xor ebx, ebx ;clear ebx
mov cl, 0d3h ;ARR5 Noncacheable A31-A24
call F000_Get_Cyrix
mov bh, al
mov cl, 0d4h ;ARR5 Noncacheable A23-A16
call F000_Get_Cyrix
mov bl, al ;now BX is system memory size
shl ebx, 16 ;ebx Bit 31 - 16 is A31-A16
mov cl, 0d5h ;ARR5 Noncacheable A15-A12
call F000_Get_Cyrix
mov bh, al ;ebx Bit 31 - 12 is A31-A12
xor eax, eax ;clear EAX
mov ax, si ;ax is last set noncacheable size
shl eax, 20 ;eax bit 31-12 is noncacheable size
;A31-A12
add ebx, eax ;BX is next noncacheable start address
;Bit 31-12 is A31-A12
;now BX is next noncacheable address
mov al, bh
mov cl, 0d2h ;ARR4 A15-A12
call F000_Set_Cyrix
shr ebx, 16 ;EBX bit 15-0 is A31-A16
mov al, bl
mov cl, 0d1h ;ARR4 A23-A16
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -