VESA 显示驱动问题

harry_1523 2009-02-20 01:58:15
; Nasm 编译器
; [sdb + vbe_mode]指向由另外一个检测函数返回的vbe模式号
Entern_VESA_Mode:
mov ax,0x4f02
mov bx,word [sdb + vbe_mode]
int 0x10

...
...

ret

问题:
这个程序在vbox下运行是完全没有问题(模式切换与画点函数都正常),但在vpc2007sp1和bochs下都只是能切换到图形模式而画点是怎么画也是没有反应!
本人很是郁闷,请教各位高手如何解决,如果需要提供像GDT设置之类的其它信息我会跟帖发上来.先多谢各位高手!(流泪ing...)
...全文
533 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
houdeguo876 2009-12-21
  • 打赏
  • 举报
回复
这个问题解决了么?我现在好像也遇到了这个问题。实模式下设置1024*768*64K模式,在大部分PC机上都没问题,但在个别电脑上不能画图
harry_1523 2009-02-25
  • 打赏
  • 举报
回复
回cnzdgs的,我在bochs调试下发现切换到图形模式后(窗口大少变为800*600),向phys_base_ptr连续写大量0xcccccccc,但使用bochs的xp命令查看物理地址phys_base_ptr的内容是全部为0xffffffff,就像写不了数据到那里似的.是a20地址线打开有问题吗?
harry_1523 2009-02-25
  • 打赏
  • 举报
回复
回复mydo的,测试完vm,发觉原来vm都是没有显示.看来很有问题!
cxdzxc 2009-02-22
  • 打赏
  • 举报
回复
前段时间准备写DOS下的中文输入法,正好实现了这个,你可以加到BIOS与32位探究群67286087来找我
harry_1523 2009-02-21
  • 打赏
  • 举报
回复
回cnzdgs的:
我取坐标(0,0),撇弃编译量这个邪恶的东西,然后向其写颜色数据0x00ffffff也是没有反应.所以很是郁闷.........
  • 打赏
  • 举报
回复
VBE 2.0+支持保护模式接口,可以直接在保护模式下访问不分页的显存(LFB)。
harry_1523 2009-02-21
  • 打赏
  • 举报
回复
是呢,会不会和显存页有关?是否用了线性地址就不用理会显存分页呢?
cnzdgs 2009-02-21
  • 打赏
  • 举报
回复
你试试把从phys_base_ptr开始的4MB都填FF看看会不会有显示。
harry_1523 2009-02-21
  • 打赏
  • 举报
回复
DelphiGuy:
很抽象,现在应该怎么办?有没有什么很很很简单的pm下的vesa画点显示程序可以给我参考一下看看哪里出错了?
harry_1523 2009-02-20
  • 打赏
  • 举报
回复
回楼上的,vm还没试过,我现在下载一个来试试.
cnzdgs 2009-02-20
  • 打赏
  • 举报
回复
4f01功能应该把扫描线长度也取出来,用扫描线长度*y+x*每像素字节数来计算偏移量。
harry_1523 2009-02-20
  • 打赏
  • 举报
回复
回复DelphiGuy兄的:

我记得vpc2007应该支持,而且它们都能切换到图形模式(窗口大小改变了).另外,代码我已经补上,帮忙看看问题的所在,谢谢!~_~
harry_1523 2009-02-20
  • 打赏
  • 举报
回复
下面是vesa初始化,是更正一下楼上的保护模式初始化部分Init_Data_Segment是在标记为[BITS 32s]的代码段下.

;---------------------------------------------------------------------
; void Dectect_Video()
Global Dectect_Video
Dectect_Video:
; 返回 VBE 控制器信息
mov ax,VBE_INFO_BLOCK
mov es,ax
mov di,0x0
mov ax,0x4f00
int 0x10
; 检测调用是否成功
cmp ax,VBE_CALL_SUCCESSFUL
jnz .dead

; 保存显存大小
mov ax,word [es:di+memory_size]
mov word [sdb + vmemory_size],ax
; 保存水平分辨率
mov ax,0x0320
mov word [sdb + screen_width],ax
; 保存垂直分辨率
mov ax,0x0258
mov word [sdb + screen_height],ax
; 保存色彩深度
mov al,0x20
mov byte [sdb + bpp],al

mov ax,word [es:di + VideoModePtr + 2]
mov si,word [es:di + VideoModePtr + 0]
mov es,ax
mov di,si

; 开始遍历该系统所支持的显示模式
; 查找其中是否存在合适的显示模式值
;
.while:
mov ax,word [es:di]
cmp ax,0xffff
jz .endWhile

; 部分寄存器保存
push es
push di

; 查询详细模式信息
mov cx,word [es:di]
mov ax,VBE_INFO_BLOCK
mov es,ax
mov di,0x0400
mov ax,0x4f01
int 0x10

; 按下列条件查找显示模式号
cmp word [es:di+XResolution],800
jnz .continueWhile
cmp word [es:di+YResolution],600
jnz .continueWhile
cmp byte [es:di+BitsPerPixel],32
jnz .continueWhile

; 找到合适显示模式
; 保存线性内存地址到系统信息结构体
mov eax,dword [es:di + PhysBasePtr]
mov dword [sdb + phys_base_ptr],eax

; 获取VESA VBE的保护模式接口
mov ax,0x4f0a
mov bx,0x0
int 0x10

xor eax,eax
mov ax,es
shl eax,4
add ax,di
mov [sdb + pm_code],eax

mov ax,word [es:di]
mov [sdb + set_window],ax

pop di
pop es

; 保存显示模式号到系统信息结构体
mov ax,word [es:di]
mov word [sdb + vbe_mode],ax

jmp .endWhile

; 该轮循环未找到合适的显示模式
; 继续循环
.continueWhile:
pop di
pop es

add di,2
jmp .while

; 查找成功,返回
.endWhile:
ret

.dead:
push msg_get_vess_err
call Error

;---------------------------------------------------------------------
; void Entern_VESA_Mode()
Global Entern_VESA_Mode
Entern_VESA_Mode:
mov ax,0x4f02
mov bx,word [sdb + vbe_mode]
int 0x10

; 检测调用是否成功
cmp ax,VBE_CALL_SUCCESSFUL
jnz .dead

ret

.dead:
push msg_enter_vess_mode_err
call Error


// 下面将画点函数精简了一下,方便各位高手阅读,帮小弟指出问题所在
void Set_Pixel(s32 x,s32 y,u32 color)
{
u32 *p = sdb.phys_base_ptr + (sdb.screen_width*y+x);
*p = color;
}
harry_1523 2009-02-20
  • 打赏
  • 举报
回复
回cnzdgs,我将部分函数从文件中整理了出来
为清晰起见我分开两楼发,下面是保护模式初始化


;---------------------------------------------------------------------
; cpu.asm
; void Enable_PM()
; 本函数用于开启系统32位保护模式
Enable_PM:
; 移动kernel_gdt到GDT_ENTRY
; 其中6为gdt项个数
mov ax,ds
mov es,ax
cld
mov esi,kernel_gdt
mov edi,GDT_ENTRY
mov ecx,6*2
rep movsd

cli ; 关闭中断

lgdt [gdt_descriptor] ; 加载GDT描述符

; 开启A20地址线
in al,92h
or al,00000010b
out 92h,al

; 开启保护模式
mov eax,cr0
or eax,1
mov cr0,eax

jmp dword KERNEL_CS:Init_Data_Segment ; 正式进入保护模式

;---------------------------------------------------------------------
; start.asm
; void Init_Data_Segment()
; 初始化段寄存器
Init_Data_Segment:
mov ax,KERNEL_DS
mov ds,ax
mov es,ax
mov gs,ax
mov fs,ax
mov ss,ax
mov esp,dword [sdb + memory_size]




// 变量部分
GdtDescriptor gdt_descriptor = {0xffff,(Gdt *) GDT_ENTRY}; // 全局描述符描述符

u64 kernel_gdt[6] = {\
0x0,\
0x00cf9a000000ffff,\
0x00cf92000000ffff,\
0x00cffa000000ffff,\
0x00cff2000000ffff,\
0x0000890000000068\
}; // 全局描述符表


大熊猫侯佩 2009-02-20
  • 打赏
  • 举报
回复
vm下呢?
  • 打赏
  • 举报
回复
有些虚拟机就不支持VESA BIOS仿真。
cnzdgs 2009-02-20
  • 打赏
  • 举报
回复
把初始化显示模式以及画点的代码贴全。

21,459

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧