%include "386scd.inc"
%define SLICPTR 08c00h ;256字节对齐
;;auto search RSDT ptr
[bits 16]
segment .text align=16
start:
xor dx,dx
mov ax,data
mov ds,ax
mov ax,stack
mov ss,ax
;准备要加载到GDTR的伪描述符
mov bx,16
mul bx
add ax, GDT ;计算并设置基地址
adc dx,0 ;界限已在定义时设置好
mov [VGDTR+2],ax
mov [VGDTR+4],dx
;设置代码段描述符
mov ax,cs
mul bx
mov [Code+2],ax ;代码段开始偏移为0
mov [Code+4],dl ;代码段界限已在定义时设置好
mov [Code+7],dh
;设置Buff数据段描述符
mov ax,ds
mul bx ;计算并设置Buff数据段基址
add ax,Buffer
adc dx,0
mov [DataBuff+2],ax
mov [DataBuff+4],dl
mov [DataBuff+7],dh
;设置SLIC数据段描述符
mov ax,ds
mul bx ;计算并设置SLIC数据段基址
add ax,SLIC
adc dx,0
mov [DataSLIC+2],ax
mov [DataSLIC+4],dl
mov [DataSLIC+7],dh
;设置数据段描述符
mov ax,ds
mul bx ;计算并设置数据段基址
mov [Data+2],ax
mov [Data+4],dl
mov [Data+7],dh
;SEARCH RSD PTR IN BIOS
mov ebx,20000h ;bios length=20000h
mov ax,0f000h
mov es,ax
s1: cmp ebx,10000h
jnz s2
mov ax,0e000h
mov es,ax
s2: sub ebx,16
cmp dword [es:bx],'RSD '
jz f1
jmp nf1
f1: cmp dword [es:bx+4], 'PTR '
jz s1_found
nf1: cmp ebx,0
jnz s1
jmp exit ;no RSD PTR in bios
s1_found:
;设置Buff数据段描述符
mov eax,dword [es:bx+16]
mov [DataRSDT+2],ax
mov dword [RSDTPTR],eax ;save to RSDTPTR
shr eax,16
mov [DataRSDT+4],al
mov [DataRSDT+7],ah ;计算并设置RSDT数据段基址
;加载GDTR
lgdt [VGDTR]
cli ;关中断
EnableA20 ;打开地址线A20
;切换到保护方式
mov eax,cr0
or al,1
mov cr0,eax
;清指令预取队列,并真正进入保护方式
JUMP16 Code_Sel,Virtual
Virtual: ;现在开始在保护方式下运行
mov ax,DataRSDT_Sel
mov ds,ax ;加载源数据段描述符
mov ax,DataBuff_Sel
mov es,ax ;加载目标数据段描述符
cld
xor si,si
xor di,di ;设置指针初值
mov cx,BufLen/4 ;设置4字节为单位的缓冲区长度
repz movsd ;传送
call dispbuff ;debug
mov ax,Data_Sel
mov fs,ax
mov edx,dword [fs:RSDTPTR] ;restore rsdtptr
mov bx,36
mov cx,[4]
searchslic1: cmp bx,cx ;设置slic指针初值
jz noslic
cmp dword [bx],edx
jl searchslic2
mov edi,dword [bx]
mov eax,edi
sub edi,edx
cmp dword [edi],'SLIC'
jz hasslic
searchslic2: add bx,4
jmp searchslic1
noslic: mov eax,SLICPTR
add eax,edx
mov dword [bx],eax
add bx,4
mov [4],bx
mov di,SLICPTR
hasslic: mov ax,DataSLIC_Sel
mov ds,ax ;加载源数据段描述符
mov ax,DataRSDT_Sel
mov es,ax ;加载目标数据段描述符
cld
mov cx,14/2 ;设置2字节为单位的缓冲区长度
mov si,0ah ;6byte OEM id+8byte Table id
push di ;must equal with the one in slic
mov di,0ah
repz movsw
xor si,si ;设置指针初值
pop di
mov cx,SLICLen/4 ;设置4字节为单位的缓冲区长度
repz movsd ;传送
exitreal: ;切换回实模式
mov eax,cr0
and al,11111110b
mov cr0,eax
;清指令预取队列,进入实方式
JUMP16 seg Real,Real
dispbuff: push ax
push cx
push es
push ds
push si
push di
mov ax,DataBuff_Sel
mov ds,ax
mov ax,DataVBuf_Sel
mov es,ax
xor si,si
mov di,320
mov cx,BufLen
movtoVRAM: mov al,[ds:si]
mov [es:di],al
inc si
inc di
inc di
loop movtoVRAM
pop di
pop si
pop ds
pop es
pop cx
pop ax
ret
Real: ;现在又回到实方式
DisableA20
sti
exit: mov ax,4c00h
int 21h
segment data align=16
GDT: ;全局描述符表
DUMMY: Desc 0,0,0 ;空描述符
Code : Desc 0,0ffffh,ATCE ;代码段描述符
DataSLIC: Desc 0,0ffffh,ATDW ;SLIC数据段描述符
DataBuff: Desc 0,0ffffh,ATDW ;Buff数据段描述符
DataVBuf: Desc 0b8000h,0ffffh,ATDW ;显示缓冲数据段描述符
DataRSDT: Desc 0,0ffffh,ATDW ;RSDT数据段描述符
Data: Desc 0,0ffffh,ATDW ;数据段描述符
;----------------------------------------------------------------------------
GDTLen equ $-GDT ;全局描述符表长度
VGDTR: PDesc 0,GDTLen-1 ;伪描述符
;----------------------------------------------------------------------------
Code_Sel equ Code-GDT ;代码段选择子
DataSLIC_Sel equ DataSLIC-GDT ;SLIC数据段选择子
DataBuff_Sel equ DataBuff-GDT ;Buff数据段选择子
DataVBuf_Sel equ DataVBuf-GDT ;显示缓冲数据段选择子
DataRSDT_Sel equ DataRSDT-GDT ;RSDT Selector
Data_Sel equ Data-GDT ;Data 段选择子
;----------------------------------------------------------------------------
RSDTPTR dd 0 ;RSDTPTR
SLIC:
db 053h, 04Ch, 049h, 043h, 076h, 001h, 000h, 000h, 001h, 04Bh, 05Fh, 041h
db 053h, 055h, 053h, 05Fh, 04Eh, 06Fh, 074h, 065h, 062h, 06Fh, 06Fh, 06Bh
db 024h, 006h, 000h, 011h, 04Dh, 053h, 046h, 054h, 097h, 000h, 000h, 000h
db 000h, 000h, 000h, 000h, 09Ch, 000h, 000h, 000h, 006h, 002h, 000h, 000h
db 000h, 024h, 000h, 000h, 052h, 053h, 041h, 031h, 000h, 004h, 000h, 000h
db 001h, 000h, 001h, 000h, 06Fh, 092h, 09Dh, 0DCh, 0B3h, 079h, 0EEh, 027h
db 026h, 008h, 0F8h, 0DCh, 05Bh, 0D8h, 05Fh, 04Bh, 021h, 034h, 0ABh, 060h
db 0ECh, 090h, 0C7h, 0C2h, 0D5h, 060h, 0D5h, 0F5h, 0D9h, 082h, 0F9h, 02Eh
db 0BEh, 0E8h, 043h, 038h, 0D5h, 0C2h, 05Bh, 09Eh, 025h, 0B8h, 093h, 0CDh
db 015h, 0B8h, 01Bh, 0C3h, 030h, 07Dh, 0ADh, 055h, 069h, 079h, 0BDh, 01Ah
db 07Eh, 044h, 0C8h, 0BCh, 059h, 05Ah, 017h, 0BEh, 081h, 0ADh, 0EFh, 0EEh
db 096h, 021h, 037h, 0CCh, 08Ah, 042h, 062h, 0C6h, 014h, 005h, 009h, 021h
db 069h, 07Ah, 0E1h, 08Ch, 04Ah, 0CEh, 0D6h, 0C8h, 018h, 078h, 078h, 086h
db 02Bh, 030h, 063h, 0A6h, 0E5h, 064h, 0B7h, 0D2h, 014h, 05Eh, 02Bh, 044h
db 0BEh, 033h, 012h, 06Bh, 06Bh, 0A3h, 0BDh, 09Eh, 085h, 0BBh, 0BEh, 06Ch
db 0E1h, 0B1h, 033h, 0C2h, 0DAh, 091h, 080h, 0F3h, 044h, 0B4h, 0CAh, 09Fh
db 001h, 000h, 000h, 000h, 0B6h, 000h, 000h, 000h, 000h, 000h, 002h, 000h
db 05Fh, 041h, 053h, 055h, 053h, 05Fh, 04Eh, 06Fh, 074h, 065h, 062h, 06Fh
db 06Fh, 06Bh, 057h, 049h, 04Eh, 044h, 04Fh, 057h, 053h, 020h, 000h, 000h
db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
db 000h, 000h, 000h, 000h, 000h, 000h, 024h, 0B0h, 089h, 0CFh, 0B1h, 0F3h
db 01Dh, 0B8h, 07Ah, 080h, 035h, 0CBh, 0CDh, 04Ah, 0C8h, 02Fh, 084h, 0CEh
db 099h, 0A0h, 04Fh, 038h, 076h, 0B0h, 004h, 0F9h, 06Fh, 005h, 033h, 0C7h
db 0ECh, 0A8h, 058h, 0A6h, 0D7h, 0B7h, 03Fh, 05Bh, 082h, 0B1h, 0EEh, 02Bh
db 0A7h, 081h, 052h, 0F3h, 045h, 013h, 0CEh, 0EEh, 0D5h, 057h, 037h, 0FEh
db 075h, 05Fh, 05Ch, 062h, 0C4h, 053h, 0DAh, 086h, 0F1h, 034h, 0FAh, 0EDh
db 091h, 086h, 073h, 09Eh, 0D2h, 065h, 0FDh, 08Ah, 03Dh, 086h, 094h, 02Fh
db 02Ah, 065h, 018h, 05Ch, 0D9h, 0E5h, 07Ch, 015h, 01Eh, 0F2h, 008h, 0C5h
db 085h, 0C4h, 08Fh, 00Bh, 0FAh, 0A5h, 0C3h, 0A9h, 0B0h, 0F1h, 0B2h, 0E7h
db 06Ah, 046h, 0FBh, 018h, 001h, 05Dh, 04Ch, 036h, 033h, 0DEh, 0FBh, 0E7h
db 01Dh, 0E8h, 015h, 0C2h, 085h, 09Fh, 08Ah, 0A9h, 032h, 068h, 01Fh, 0B4h
db 0BCh, 0A8h
db 0,0
SLICLen equ $-SLIC ;SLIC字节长度
BufLen equ 2048
Buffer: times BufLen db 30
segment stack stack
times 128 db 0
%define SLICPTR 08c00h ;256字节对齐
;;auto search RSDT ptr
[bits 16]
segment .text align=16
start:
xor dx,dx
mov ax,data
mov ds,ax
mov ax,stack
mov ss,ax
;准备要加载到GDTR的伪描述符
mov bx,16
mul bx
add ax, GDT ;计算并设置基地址
adc dx,0 ;界限已在定义时设置好
mov [VGDTR+2],ax
mov [VGDTR+4],dx
;设置代码段描述符
mov ax,cs
mul bx
mov [Code+2],ax ;代码段开始偏移为0
mov [Code+4],dl ;代码段界限已在定义时设置好
mov [Code+7],dh
;设置Buff数据段描述符
mov ax,ds
mul bx ;计算并设置Buff数据段基址
add ax,Buffer
adc dx,0
mov [DataBuff+2],ax
mov [DataBuff+4],dl
mov [DataBuff+7],dh
;设置SLIC数据段描述符
mov ax,ds
mul bx ;计算并设置SLIC数据段基址
add ax,SLIC
adc dx,0
mov [DataSLIC+2],ax
mov [DataSLIC+4],dl
mov [DataSLIC+7],dh
;设置数据段描述符
mov ax,ds
mul bx ;计算并设置数据段基址
mov [Data+2],ax
mov [Data+4],dl
mov [Data+7],dh
;SEARCH RSD PTR IN BIOS
mov ebx,20000h ;bios length=20000h
mov ax,0f000h
mov es,ax
s1: cmp ebx,10000h
jnz s2
mov ax,0e000h
mov es,ax
s2: sub ebx,16
cmp dword [es:bx],'RSD '
jz f1
jmp nf1
f1: cmp dword [es:bx+4], 'PTR '
jz s1_found
nf1: cmp ebx,0
jnz s1
jmp exit ;no RSD PTR in bios
s1_found:
;设置Buff数据段描述符
mov eax,dword [es:bx+16]
mov [DataRSDT+2],ax
mov dword [RSDTPTR],eax ;save to RSDTPTR
shr eax,16
mov [DataRSDT+4],al
mov [DataRSDT+7],ah ;计算并设置RSDT数据段基址
;加载GDTR
lgdt [VGDTR]
cli ;关中断
EnableA20 ;打开地址线A20
;切换到保护方式
mov eax,cr0
or al,1
mov cr0,eax
;清指令预取队列,并真正进入保护方式
JUMP16 Code_Sel,Virtual
Virtual: ;现在开始在保护方式下运行
mov ax,DataRSDT_Sel
mov ds,ax ;加载源数据段描述符
mov ax,DataBuff_Sel
mov es,ax ;加载目标数据段描述符
cld
xor si,si
xor di,di ;设置指针初值
mov cx,BufLen/4 ;设置4字节为单位的缓冲区长度
repz movsd ;传送
call dispbuff ;debug
mov ax,Data_Sel
mov fs,ax
mov edx,dword [fs:RSDTPTR] ;restore rsdtptr
mov bx,36
mov cx,[4]
searchslic1: cmp bx,cx ;设置slic指针初值
jz noslic
cmp dword [bx],edx
jl searchslic2
mov edi,dword [bx]
mov eax,edi
sub edi,edx
cmp dword [edi],'SLIC'
jz hasslic
searchslic2: add bx,4
jmp searchslic1
noslic: mov eax,SLICPTR
add eax,edx
mov dword [bx],eax
add bx,4
mov [4],bx
mov di,SLICPTR
hasslic: mov ax,DataSLIC_Sel
mov ds,ax ;加载源数据段描述符
mov ax,DataRSDT_Sel
mov es,ax ;加载目标数据段描述符
cld
mov cx,14/2 ;设置2字节为单位的缓冲区长度
mov si,0ah ;6byte OEM id+8byte Table id
push di ;must equal with the one in slic
mov di,0ah
repz movsw
xor si,si ;设置指针初值
pop di
mov cx,SLICLen/4 ;设置4字节为单位的缓冲区长度
repz movsd ;传送
exitreal: ;切换回实模式
mov eax,cr0
and al,11111110b
mov cr0,eax
;清指令预取队列,进入实方式
JUMP16 seg Real,Real
dispbuff: push ax
push cx
push es
push ds
push si
push di
mov ax,DataBuff_Sel
mov ds,ax
mov ax,DataVBuf_Sel
mov es,ax
xor si,si
mov di,320
mov cx,BufLen
movtoVRAM: mov al,[ds:si]
mov [es:di],al
inc si
inc di
inc di
loop movtoVRAM
pop di
pop si
pop ds
pop es
pop cx
pop ax
ret
Real: ;现在又回到实方式
DisableA20
sti
exit: mov ax,4c00h
int 21h
segment data align=16
GDT: ;全局描述符表
DUMMY: Desc 0,0,0 ;空描述符
Code : Desc 0,0ffffh,ATCE ;代码段描述符
DataSLIC: Desc 0,0ffffh,ATDW ;SLIC数据段描述符
DataBuff: Desc 0,0ffffh,ATDW ;Buff数据段描述符
DataVBuf: Desc 0b8000h,0ffffh,ATDW ;显示缓冲数据段描述符
DataRSDT: Desc 0,0ffffh,ATDW ;RSDT数据段描述符
Data: Desc 0,0ffffh,ATDW ;数据段描述符
;----------------------------------------------------------------------------
GDTLen equ $-GDT ;全局描述符表长度
VGDTR: PDesc 0,GDTLen-1 ;伪描述符
;----------------------------------------------------------------------------
Code_Sel equ Code-GDT ;代码段选择子
DataSLIC_Sel equ DataSLIC-GDT ;SLIC数据段选择子
DataBuff_Sel equ DataBuff-GDT ;Buff数据段选择子
DataVBuf_Sel equ DataVBuf-GDT ;显示缓冲数据段选择子
DataRSDT_Sel equ DataRSDT-GDT ;RSDT Selector
Data_Sel equ Data-GDT ;Data 段选择子
;----------------------------------------------------------------------------
RSDTPTR dd 0 ;RSDTPTR
SLIC:
db 053h, 04Ch, 049h, 043h, 076h, 001h, 000h, 000h, 001h, 04Bh, 05Fh, 041h
db 053h, 055h, 053h, 05Fh, 04Eh, 06Fh, 074h, 065h, 062h, 06Fh, 06Fh, 06Bh
db 024h, 006h, 000h, 011h, 04Dh, 053h, 046h, 054h, 097h, 000h, 000h, 000h
db 000h, 000h, 000h, 000h, 09Ch, 000h, 000h, 000h, 006h, 002h, 000h, 000h
db 000h, 024h, 000h, 000h, 052h, 053h, 041h, 031h, 000h, 004h, 000h, 000h
db 001h, 000h, 001h, 000h, 06Fh, 092h, 09Dh, 0DCh, 0B3h, 079h, 0EEh, 027h
db 026h, 008h, 0F8h, 0DCh, 05Bh, 0D8h, 05Fh, 04Bh, 021h, 034h, 0ABh, 060h
db 0ECh, 090h, 0C7h, 0C2h, 0D5h, 060h, 0D5h, 0F5h, 0D9h, 082h, 0F9h, 02Eh
db 0BEh, 0E8h, 043h, 038h, 0D5h, 0C2h, 05Bh, 09Eh, 025h, 0B8h, 093h, 0CDh
db 015h, 0B8h, 01Bh, 0C3h, 030h, 07Dh, 0ADh, 055h, 069h, 079h, 0BDh, 01Ah
db 07Eh, 044h, 0C8h, 0BCh, 059h, 05Ah, 017h, 0BEh, 081h, 0ADh, 0EFh, 0EEh
db 096h, 021h, 037h, 0CCh, 08Ah, 042h, 062h, 0C6h, 014h, 005h, 009h, 021h
db 069h, 07Ah, 0E1h, 08Ch, 04Ah, 0CEh, 0D6h, 0C8h, 018h, 078h, 078h, 086h
db 02Bh, 030h, 063h, 0A6h, 0E5h, 064h, 0B7h, 0D2h, 014h, 05Eh, 02Bh, 044h
db 0BEh, 033h, 012h, 06Bh, 06Bh, 0A3h, 0BDh, 09Eh, 085h, 0BBh, 0BEh, 06Ch
db 0E1h, 0B1h, 033h, 0C2h, 0DAh, 091h, 080h, 0F3h, 044h, 0B4h, 0CAh, 09Fh
db 001h, 000h, 000h, 000h, 0B6h, 000h, 000h, 000h, 000h, 000h, 002h, 000h
db 05Fh, 041h, 053h, 055h, 053h, 05Fh, 04Eh, 06Fh, 074h, 065h, 062h, 06Fh
db 06Fh, 06Bh, 057h, 049h, 04Eh, 044h, 04Fh, 057h, 053h, 020h, 000h, 000h
db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
db 000h, 000h, 000h, 000h, 000h, 000h, 024h, 0B0h, 089h, 0CFh, 0B1h, 0F3h
db 01Dh, 0B8h, 07Ah, 080h, 035h, 0CBh, 0CDh, 04Ah, 0C8h, 02Fh, 084h, 0CEh
db 099h, 0A0h, 04Fh, 038h, 076h, 0B0h, 004h, 0F9h, 06Fh, 005h, 033h, 0C7h
db 0ECh, 0A8h, 058h, 0A6h, 0D7h, 0B7h, 03Fh, 05Bh, 082h, 0B1h, 0EEh, 02Bh
db 0A7h, 081h, 052h, 0F3h, 045h, 013h, 0CEh, 0EEh, 0D5h, 057h, 037h, 0FEh
db 075h, 05Fh, 05Ch, 062h, 0C4h, 053h, 0DAh, 086h, 0F1h, 034h, 0FAh, 0EDh
db 091h, 086h, 073h, 09Eh, 0D2h, 065h, 0FDh, 08Ah, 03Dh, 086h, 094h, 02Fh
db 02Ah, 065h, 018h, 05Ch, 0D9h, 0E5h, 07Ch, 015h, 01Eh, 0F2h, 008h, 0C5h
db 085h, 0C4h, 08Fh, 00Bh, 0FAh, 0A5h, 0C3h, 0A9h, 0B0h, 0F1h, 0B2h, 0E7h
db 06Ah, 046h, 0FBh, 018h, 001h, 05Dh, 04Ch, 036h, 033h, 0DEh, 0FBh, 0E7h
db 01Dh, 0E8h, 015h, 0C2h, 085h, 09Fh, 08Ah, 0A9h, 032h, 068h, 01Fh, 0B4h
db 0BCh, 0A8h
db 0,0
SLICLen equ $-SLIC ;SLIC字节长度
BufLen equ 2048
Buffer: times BufLen db 30
segment stack stack
times 128 db 0