From 4d15dbaaba9433cb8ad66ac07aa99bc88798c450 Mon Sep 17 00:00:00 2001 From: Yourtion Date: Thu, 21 Apr 2016 11:51:08 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8F=90=E9=AB=98=E5=88=86=E8=BE=A8=E7=8E=87?= =?UTF-8?q?=EF=BC=882=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 14_day/asmhead.nas | 70 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 63 insertions(+), 7 deletions(-) diff --git a/14_day/asmhead.nas b/14_day/asmhead.nas index 85e9dd1..ad35d76 100644 --- a/14_day/asmhead.nas +++ b/14_day/asmhead.nas @@ -1,6 +1,16 @@ ; haribote-os boot asm ; TAB=4 +[INSTRSET "i486p"] + +VBEMODE EQU 0x105 ; 1024 x 768 x 8bit 彩色 +; 显示模式 +; 0x100 : 640 x 400 x 8bit 彩色 +; 0x101 : 640 x 480 x 8bit 彩色 +; 0x103 : 800 x 600 x 8bit 彩色 +; 0x105 : 1024 x 768 x 8bit 彩色 +; 0x107 : 1280 x 1024 x 8bit 彩色 + BOTPAK EQU 0x00280000 ; 加载bootpack DSKCAC EQU 0x00100000 ; 磁盘缓存的位置 DSKCAC0 EQU 0x00008000 ; 磁盘缓存的位置(实模式) @@ -15,18 +25,65 @@ VRAM EQU 0x0ff8 ; 图像缓冲区的起始地址 ORG 0xc200 ; 这个的程序要被装载的内存地址 +; 确认VBE是否存在 + + MOV AX,0x9000 + MOV ES,AX + MOV DI,0 + MOV AX,0x4f00 + INT 0x10 + CMP AX,0x004f + JNE scrn320 + +; 检查VBE的版本 + + MOV AX,[ES:DI+4] + CMP AX,0x0200 + JB scrn320 ; if (AX < 0x0200) goto scrn320 + +; 取得画面模式信息 + + MOV CX,VBEMODE + MOV AX,0x4f01 + INT 0x10 + CMP AX,0x004f + JNE scrn320 + +; 画面模式信息的确认 + CMP BYTE [ES:DI+0x19],8 ;颜色数必须为8 + JNE scrn320 + CMP BYTE [ES:DI+0x1b],4 ;颜色的指定方法必须为4(4是调色板模式) + JNE scrn320 + MOV AX,[ES:DI+0x00] ;模式属性bit7不是1就不能加上0x4000 + AND AX,0x0080 + JZ scrn320 ; 模式属性的bit7是0,所以放弃 + ; 画面设置 - MOV BX,0x4101 ; VBE的640x480x8bi彩色 + MOV BX,VBEMODE+0x4000 MOV AX,0x4f02 INT 0x10 MOV BYTE [VMODE],8 ; 屏幕的模式(参考C语言的引用) - MOV WORD [SCRNX],640 - MOV WORD [SCRNY],480 - MOV DWORD [VRAM],0xe0000000 + MOV AX,[ES:DI+0x12] + MOV [SCRNX],AX + MOV AX,[ES:DI+0x14] + MOV [SCRNY],AX + MOV EAX,[ES:DI+0x28] ;VRAM的地址 + MOV [VRAM],EAX + JMP keystatus + +scrn320: + MOV AL,0x13 ; VGA图、320x200x8bit彩色 + MOV AH,0x00 + INT 0x10 + MOV BYTE [VMODE],8 ; 记下画面模式(参考C语言) + MOV WORD [SCRNX],320 + MOV WORD [SCRNY],200 + MOV DWORD [VRAM],0x000a0000 ; 通过 BIOS 获取指示灯状态 +keystatus: MOV AH,0x02 INT 0x16 ; keyboard BIOS MOV [LEDS],AL @@ -115,9 +172,8 @@ skip: JMP DWORD 2*8:0x0000001b waitkbdout: - IN AL,0x64 - AND AL,0x02 - IN AL,0x60 ; 空读(为了清空数据接收缓冲区中的垃圾数据) + IN AL,0x64 + AND AL,0x02 JNZ waitkbdout ; AND的结果如果不是0,就跳到waitkbdout RET