⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 multi-add-slic.asm

📁 多PCI模块修改工具!可以多选OEM SLIC
💻 ASM
📖 第 1 页 / 共 4 页
字号:
	mov ax,bx				;BUFFER的偏移
	mov [si+4h],ax
	mov ax,ds				;BUFFER所在的段
	mov [si+6h],ax
	mov ax,HD_BlockNum-1			;扇区号,这里是第HD_BlockNum号扇区,这里减1就等于标准INT 13H下的HD_BlockNum
	mov [si+8h],ax				;在扩展INT 13H下,HD_BlockNum = 0是第一个扇区(MBR)
	xor eax,eax
	mov [si+0ah],ax
	mov [si+0ch],eax
	mov ah,dh				;入口:ds:si指向DAP的入口;DL驱动器号(80为第一个硬盘81为       
	mov dl,80h				;第二个);AH =功能代号 (42H=扩展读 42H=扩展写)
	int 13h
	sti
	retn
;---------------------------------------------------------------------------------------------
;----------------------------------------------------------------------------------------
;由于用堆栈保存读出来的数据的话,会导致INT 13H运行出错(INT 13H会对ES进行先进           -
;行打开写开关,然后关闭写开关的操作,如果ES指向SS(堆栈段)肯定会导致出错。             -
;ES:BX= 数据区中I/O缓冲区的地址                                                         -
;AH=02H 读磁盘  |       AL= 扇区数量 (这里读一个扇区[512字节=0x200H字节]               -
;(CL)6,7 (CH)0~7=柱面 | (CL)0~5= 扇区号 ,这里的扇区号 = HD_BlockNum                     -
;DH= 磁头号/盘面        DL= 驱动器号 (80指第一个硬盘)                                 -
;成功: AH=0, AL=读取的扇区数     失败: AH=错误码                                        -
;失败,CF=1,成功,CF = 0                                                               -
;----------------------------------------------------------------------------------------
;       cli
;       mov cx,HD_BlockNum                      ;在标准INT 13H下,HD_BlockNum =0/1 都指向MBR,只不过一般用1来表示MBR
;       mov ah,dh                               ;入口DH=读/写类型
;       mov al,01h
;       mov dx,0080h
;       int 13h
;       retn
;------------------------------------------------------------------------------------------------
	

;**************************************************************************************
  INIT:
	pushad					;这时的CS是可以写数据的!因为BIOS解压各模块时,各模块都设置为可写状态!
	popad
	retn





  FIRST_RUN:					;显示选择的模块内容,并进行设置
	pushad
	mov dh,02h				;入口:无       ;      出口:无
	call RW_HD_DATA
	jb @fr_ext
	and al,0f0h					; al
	jne @fr_Ch					; xy
	call CLEAR_SCREEN				; x      x = 0,show message;=1,hide message !
	mov si,MSG0					;  y     y = value of choice !
	call WRITE
	call Display_Choosed_slic
	mov si,MSG1
	call WRITE
	call WCRLF
	CALL Check_KB_Input
@fr_ext:Call CLEAR_SCREEN
	popad
	retn
@fr_Ch: mov ah,01h					;如果设置为不显示选择的模块的内容,可以在BIOS自建后按F5重新进入设置画面。
	int 16h
	cmp ah, ENTER_PRESS_KEY 			;ah = scan code
	jne @fr_ext
	call CLEAR_SCREEN
	mov si,MSG2
	call WRITE
	call Enter_Choice
	jmp @fr_ext



Display_Choosed_slic:				;显示选择的SLIC的品牌的信息
	pushad
	call read_hd_data			;入口:无       ;      出口:无
	mov esi,SLIC+176h
	add esi,eax
	call WRITE
	popad
	retn

Check_KB_Input: 				;检查键盘输入的按键,并进行相关的处理
	pusha					;入口:无       ;      出口:无
	mov ah,MSG1_SHOW_DELAY			;20*55ms
	call DELAY
	call Test_KB_Code
	popa
	retn

Test_KB_Code:
	pusha
	mov ah,01h
	int 16h
	cmp ah, ENTER_PRESS_KEY
	je  Is_The_Key
	popa
	retn
Is_The_Key:
	call CLEAR_SCREEN
	mov si,MSG2
	call WRITE
	call Enter_Choice
	popa
	retn

Enter_Choice:					;进入设置画面
	pushad					;入口:无       ;      出口:无
EC_loop:
	mov ah,0h
	int 16h
	cmp al,0dh				;0dH = 回车键的ASCII码
	je Enter_Choice_exit
	cmp al,30h
	jl EC_loop
	cmp al,39h
	jg EC_loop
	call DISPLAY_AL
	sub al,30h
	jmp ShowMSG_Choice
Enter_Choice_exit:
	mov dh,02h
	call RW_HD_DATA
ShowMSG_Choice:
	and eax,00fh
	push eax
	call WCRLF
	mov si,MSG2_C
	call WRITE
@EC_KL: mov ah,0h
	int 16h
	cmp al,30h
	je EC_K01
	cmp al,31h
	je EC_K01
	jmp @EC_KL
EC_K01: call DISPLAY_AL
	sub al,30h
	mov bl,al
	shl bl,4h
	pop eax
	add al,bl
	call WCRLF
	mov si,MSG_HD_1
	call WRITE
	call display_al_str
	mov dh,03h
	call RW_HD_DATA 				;Input eax ,only use al,others set to 0 !
	jb  write_data_wrong
	call WCRLF
	mov si,MSG3
	call WRITE
@EC_EXT:mov ah,50h					; 80 * 55 ms =4400 ms
	call DELAY
	call CLEAR_SCREEN
	popad
	retn

write_data_wrong:					;显示写硬盘出错的信息
	call WCRLF					;入口:无       ;      出口:无
	mov si,MSG_WRONG_1
	call WRITE
	mov al,ah
	call display_al_str
	call WCRLF
	jmp @EC_EXT


;*************************************************************************************************************

  BOOTSTRAP:				;这时的CS是绝对不可以写数据!必须另外想办法写!可以用堆栈!
	pushad				;必须使用BOOTSTRAP,是因为,ACPI很大程度上是在该PCI模块运行后,才生成的。
	push ds 			;而且,只有在BOOTSTRAP运行的情况下,才可以正常的读/写硬盘
	push es 			;经过多次的失败,证明了必须用BOOTSTRAP来解决!
	xor ecx,ecx
	call enableA20			;开启A20地址总线
	push ecx
	mov al,1
	call setRealMode		;设置实模式的状态
	call FIRST_RUN
	call main
	pop ecx
	cmp cl,01h
	je BOT_EXT
	call disableA20 		;关闭A20地址总线
BOT_EXT:pop es
	pop ds
	popad
	retf				;return to this rom's header

   enableA20:				;开启A20地址总线
	in al,92h			;入口;cl       ;      出口:cl
	test al,02h			;判断A20是否在执行该模块时就已经被开启了
	je OP_A20			;如果不是,就跳走,打开A20
	mov cl,01h
	retn
OP_A20: or al,02h
	out 92h,al
	retn

	
   disableA20:				;关闭A20地址总线
	in al,92h			;入口:无       ;      出口:无
	and al,0fdh
	out 92h,al
	retn

   setRealMode: 			;设置实模式的状态
	push eax			;入口:al       ;       出口:ds,es             
	cli					;关闭中断
;--------------------下面使用堆栈的方法因为部分AWARD主板的8800:AE00等区域是只读的,所以必须用回堆栈---------
	xor eax,eax
	xor ecx,ecx				;计算cs:GDT1的物理地址,用于LGDT
	mov ax,cs				;
	shl eax,4h				;
	mov cx,GDT1				;这里使用堆栈操作,可以不用考虑不可以改写伪GDTR的值的问题
	add eax,ecx
	push eax
	mov ax,GDTR_LEN
	push ax
	mov di,sp				;这里用堆栈来保存伪GDTR的值
	add sp,6h				;恢复原来的堆栈指针!6h = 伪GDTR的长度
	lgdt [ss:di]				;如果PC反复重启,绝大多数情况,是因为GDTR没有设置好。
;-----------------------------------------------------------------------------------------------------------
	mov eax,cr0				
	or al,1 				;将cr0的0位设置为1,就进入了保护模式
	mov cr0,eax				;进入保护模式
	jmp pm_flush_queue
pm_flush_queue:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -