📄 ali.8
字号:
;
; System specific code
;
; ALI M1487 chipset
;
; (C)1997-2001 Pascal Dornier / PC Engines; All rights reserved.
; This file is licensed pursuant to the COMMON PUBLIC LICENSE 0.5.
;
TOP_MEM equ 0400h ;memory size limit = 64 MB
;
; IDE timing parameters 25 / 30 MHz
;
CS_IDE8 equ 10 ;8 bit command time for 25/30 MHz
;8 for mode 3
CS_IDE8R equ 10 ;8 bit recovery time
CS_IDE16 equ 6 ;16 bit command time for 25/30 MHz
;3 for mode 3
CS_IDE16R equ 8 ;16 bit recovery time
;3 for mode 3
;
; IDE timing parameters 33 MHz
;
CS_IDE8b equ 10 ;8 bit command time
CS_IDE8Rb equ 14 ;8 bit recovery time
CS_IDE16b equ 6 ;16 bit command time
;5 for mode 3
CS_IDE16Rb equ 10 ;16 bit recovery time
;
; Equates
;
idx equ 22h ;configuration index register
dat equ 23h ;configuration data register
cxidx equ 22h ;Cyrix index register
cxdat equ 23h ;Cyrix data register
idelock equ 0f4h ;ALI IDE unlock register
ideidx equ 0f8h ;ALI IDE index register
idedat equ 0fch ;ALI IDE data register
pci_cfg equ 0cfbh ;PCI mechanism control register
;
; initialize chipset
;
; set all registers, detect memory size
; keep L2 cache disabled at this point
; set CPU specific registers if required
;
; initialize Cyrix CPU
cs_init:
; mov eax,cr0
; or eax,20000000h ;enable write back
; mov cr0,eax
; mov al,0c1h ;CPU configuration register 1:
; out cxidx,al
; mov al,00010000xb ;No LOCK#, no SMI, RPL pins
; out cxdat,al
; mov al,0c2h ;CPU configuration register 2:
; out cxidx,al
; mov al,01011110xb ;disable SUSP, write through 640K-1M,
; out cxdat,al ;lock NW, suspend on halt, enable INVAL,
; ;WM_RST, burst write
; get chipset registers from table
mov si,offset cs_tab
cs_ini1: cs: lodsw ;get index / data from table
cmp al,0ffh
jz cs_ini2 ;:end
out idx,al
mov al,ah
out dat,al
jmp cs_ini1
cs_ini2: mov dx,pci_cfg ;enable PCI configuration mechanism #1
mov al,1
out dx,al
; if shadow enabled, don't touch memory / shadow configuration
mov al,14h ;shadow read enabled ?
out idx,al
in al,dat
and al,10h
jz cs_ini3 ;:no
stc ;return, already in shadow
ret
cs_ini3: cs: lodsw ;get index / data from table
cmp al,0ffh
jz cs_ini4 ;:end
out idx,al
mov al,ah
out dat,al
jmp cs_ini3
cs_ini4: clc ;return, full initialization
ret
;
; CPU specific settings
;
cs_cpu: pushfd
pop eax
or eax,00200000h ;bit 21 modifiable -> CPUID supported
push eax
popfd
pushfd
pop eax
test eax,00200000h
jz cs_wt ;no CPU ID: stay in write through mode
; get CPU ID
xor eax,eax
cpuid
cmp ecx,444d4163h ;"cAMD"
jnz cs_notamd
; set correct mode for AMD CPU
cpuid ;get device type
and al,0f0h ;mask out stepping
cmp al,70h
jz cs_wb ;70: DX2 in WB mode
cmp al,90h
jz cs_wb ;90: DX4 in WB mode
cmp al,0f0h
jz cs_wb ;F0: DX5 in WB mode
jmp short cs_wt ;else write through
; set correct mode for Intel CPU
cs_notamd: cmp ecx,6c65746eh ;"ntel"
jnz cs_wt
cpuid ;get device type
and al,0f0h ;mask out stepping
cmp al,90h
jz cs_wb ;90: CPU in WB mode
jmp short cs_wt
; set Intel / AMD write back mode
cs_wb: mov al,19h ;set Intel / AMD write back mode
out idx,al
in al,dat
and al,3fh
or al,40h
out dat,al
mov al,16h ;enable L1 write back
out idx,al
in al,dat
or al,04
out dat,al
; enable L1 (CPU) cache
cs_wt: invd
mov eax,cr0
and eax,9fffffffh
mov cr0,eax
ret
;
; Detect memory
;
; EAX = scratch
; BX = DRAM configuration all banks (shifted left)
; CL = bank number (0..3)
; DX = scratch / return address
; SP = return pointer
; DS = 0
;
; Cache must be off !
;
cs_det: xor ax,ax ;set low 64K segment
mov ds,ax
mov cl,3 ;start with bank 3
; test a bank
cs_det2: shl bx,4 ;make space for next bank
mov ah,0100xb ;set bank to 16 Mb DRAM
mov dx,cs_det3
jmp cs_memset
; see whether there is any life in this bank - test first two words
cs_det3: mov eax,55aaff00h
mov [0],eax
not eax
mov [4],eax
not eax
cmp [0],eax
jnz cs_det4 ;:fail
not eax
cmp [4],eax
jz cs_det5 ;:ok
cs_det4: or bl,1111xb ;nothing in this bank
jmp cs_det91
; See how large the bank is
; This is done by determining how many row address bits there are.
; If a bit isn't there, we'll overwrite location 0. See M1487 data
; book page 109 for memory address mapping. Remember that we are
; in 16 Mbit mode.
cs_det5: mov [2048],eax
cmp [0],eax
jnz cs_det6
mov al,0000 ;256 Kbit bank
jmp short cs_det20
cs_det6: mov [4096],eax
cmp [0],eax
jnz cs_det7 ;overwrite -> 1 or 2 Mbit bank
mov ah,0101xb ;set 2 Mbit (2Mx8)
mov dx,cs_det6a
jmp cs_memset
; differentiate between 1Mx16 / 1Mx4 and 2Mx8 memory
cs_det6a: mov eax,55aaff00
mov [0],eax
not eax
mov [8192],eax
cmp [0],eax
mov al,0001xb ;overwrite -> 1 Mbit (1Mx16)
jz cs_det20
mov al,0101xb ;2Mx8
jmp short cs_det20
cs_det7: mov [8192],eax
cmp [0],eax
jnz cs_det8 ;overwrite -> 4 Mbit bank
mov al,0011xb ;4 Mbit bank
jmp short cs_det20
cs_det8: mov al,0100xb ;16 Mbit bank
; Test whether this bank is EDO
cs_det20: or bl,al ;store bank size in BX
mov ch,1
shl ch,cl ;EDO bit
or ch,20h ;EDO test mode bit
mov al,1ah ;enable EDO mode
out idx,al
in al,dat
or al,ch ;set bank EDO + EDO test mode bit
out dat,al
mov eax,55aaff00h ;write test pattern
mov [0],eax
cmp [0],eax ;verify
jnz cs_det29 ;:fast page mode, clear bank EDO bit
and ch,0f0h ;EDO - keep bank EDO bit as is.
cs_det29: mov al,1ah ;clear EDO (if bad)
out idx,al
in al,dat
xor al,ch
and al,1fh ;clear EDO test mode
out dat,al
; done with the bank - store result in BX, and disable bank
cs_det91: mov ah,1111xb ;disable this bank
mov dx,cs_det92
jmp short cs_memset
cs_det92: dec cl ;another bank ?
js cs_det99 ;:no
jmp cs_det2
; now set all banks according to BX
cs_det99: mov al,10h
out idx,al
mov al,bl
out dat,al
mov al,11h
out idx,al
mov al,bh
out dat,al
ret
;
; set memory bank [CL] -> value in AH; return to [DX]
;
cs_memset: mov al,10h ;bank -> 10h or 11h
test cl,2
jz cs_memst1
inc ax
cs_memst1: out idx,al
in al,dat
test cl,1 ;low or high nibble ?
jnz cs_memst2 ;:high
and al,0f0h ;set low nibble
jmp short cs_memst3
cs_memst2: shl ah,4
and al,0fh
cs_memst3: or al,ah
out dat,al
jmp dx ;return
;
; Copy BIOS to shadow RAM (skip if already enabled)
;
; Note: For fastest startup, this happens before DRAM test and
; BIOS checksum test. If DRAM or BIOS is bad, we might crash.
;
cs_shad: mov al,03h ;unlock configuration registers
out idx,al
mov al,0c5h
out dat,al
mov al,14h ;shadow read enabled ?
out idx,al
in al,dat
test al,10h
jnz cs_shad9 ;yes: don't do again (implicit clear C)
mov al,14h ;enable shadow write for F000..FFFF
out idx,al
mov al,00101100xb
out dat,al
mov ax,cs ;copy BIOS to shadow RAM
mov ds,ax
mov es,ax
xor si,si
xor di,di
mov cx,4000h
rep movsd
mov al,14h ;enable shadow read / write F000..FFFF
out idx,al
mov al,00011100xb
out dat,al
stc ;set C = new shadow
cs_shad9: jmp rstshad2
ret
;
; Copy video BIOS to shadow RAM
;
cs_vshad: push ds
push es
mov al,13h ;video shadow enabled ?
out idx,al
in al,dat
test al,00000011xb
jnz cs_vshad1 ;yes: don't touch
mov al,13h ;enable C000 shadow
out idx,al
mov al,00000011xb
out dat,al
mov al,14h ;set write only shadow
out idx,al
mov al,00101100xb ;F000..FFFF write shadow
out dat,al
mov ax,0c000h ;copy video BIOS from ROM to shadow
mov ds,ax
mov es,ax
xor si,si
xor di,di
mov cx,8000h/4
rep movsd
mov al,14h ;read only shadow
out idx,al
mov al,00011100xb
out dat,al
cs_vshad1: pop es ;restore segment
pop ds
ret
;
; Copy video BIOS from PCI ROM to shadow RAM
; DS:ESI = unreal mode pointer to BIOS
; ES = destroyed
;
cs_vshad2: mov al,13h ;video shadow enabled ?
out idx,al
in al,dat
test al,00000011xb
jnz cs_vshad9 ;yes: don't touch
mov al,13h ;enable C000 shadow
out idx,al
mov al,00000011xb
out dat,al
mov al,14h ;set write only shadow
out idx,al
mov al,00101100xb ;F000..FFFF write shadow
out dat,al
mov ax,0c000h ;copy video BIOS from PCI ROM
mov es,ax ;to shadow
xor edi,edi
mov ecx,8000h/4
a4 rep movsd
mov al,14h ;read only shadow
out idx,al
mov al,00011100xb
out dat,al
cs_vshad9: ret
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -