3. 检测并初始化VGA文本模式

任务目标

在BIOS启动阶段,检测系统是否存在标准VGA兼容硬件,将其初始化为80x25彩色文本模式,清屏后显示启动信息。本案例聚焦于实模式下的VGA硬件检测与文本模式初始化,不涉及图形模式或扩展显示设备。

实现原理

标准VGA硬件通过INT 10h中断提供显示服务。检测VGA是否存在可通过读取INT 10h返回的设备信息完成;设置80x25文本模式使用AH=00h功能;清屏与光标定位分别使用AH=06h和AH=02h。所有操作均在实模式(16位)下进行,代码使用NASM汇编编写,可直接编译为COM格式在DOS或实模式环境中运行。

完整代码

;----------------------------------------------------------
; VGA检测与文本模式初始化
; 编译: nasm -f bin vga_init.asm -o vga_init.com
; 运行: DOS实模式或QEMU + FreeDOS
;----------------------------------------------------------
CPU 8086
BITS 16
ORG 0x0100

start:
    ; 保存原视频模式
    mov ah, 0x0F
    int 0x10
    mov [old_mode], al

    ; 检测VGA是否存在
    mov ax, 0x1A00          ; VGA设备信息查询
    int 0x10
    cmp al, 0x1A            ; AL=1Ah 表示BIOS支持VGA功能
    jne .no_vga

    ; 检查显示设备代码
    cmp bl, 0x07            ; BL=07h 表示VGA彩色显示器
    je .vga_detected
    cmp bl, 0x08            ; BL=08h 表示VGA单色显示器
    je .vga_detected
    cmp bl, 0x0A            ; BL=0Ah 表示VGA彩色显示器(备用)
    je .vga_detected
    jmp .no_vga

.vga_detected:
    ; 设置80x25彩色文本模式(模式03h)
    mov ax, 0x0003
    int 0x10

    ; 清屏并设置背景色
    mov ax, 0x0600          ; AH=06h 滚动窗口, AL=00h 全屏
    mov bh, 0x07            ; 黑底白字
    mov cx, 0x0000          ; 左上角(0,0)
    mov dx, 0x184F          ; 右下角(24,79)
    int 0x10

    ; 定位光标到(0,0)
    mov ah, 0x02
    mov bh, 0x00            ; 页号0
    mov dx, 0x0000          ; 行=0, 列=0
    int 0x10

    ; 显示启动信息
    mov si, msg_boot
    call print_string

    ; 显示VGA检测结果
    mov si, msg_vga_ok
    call print_string

    jmp done

.no_vga:
    ; 恢复原模式并显示错误
    mov al, [old_mode]
    mov ah, 0x00
    int 0x10

    mov si, msg_no_vga
    call print_string

done:
    ; 等待按键后退出
    mov ah, 0x00
    int 0x16
    mov ax, 0x4C00
    int 0x21

;----------------------------------------------------------
; 打印字符串 (DS:SI指向以'$'结尾的字符串)
;----------------------------------------------------------
print_string:
    mov ah, 0x0E            ; TTY模式输出
.loop:
    lodsb
    cmp al, '$'
    je .end
    int 0x10
    jmp .loop
.end:
    ret

;----------------------------------------------------------
; 数据段
;----------------------------------------------------------
old_mode    db 0
msg_boot    db 'BIOS VGA Initialization', 0x0D, 0x0A, '$'
msg_vga_ok  db 'VGA detected: 80x25 text mode active.', 0x0D, 0x0A, '$'
msg_no_vga  db 'ERROR: VGA hardware not found!', 0x0D, 0x0A, '$'

编译与运行

  1. 编译:使用NASM编译生成COM文件:nasm -f bin vga_init.asm -o vga_init.com
  2. 运行环境:在DOS实模式、FreeDOS或QEMU虚拟机中运行vga_init.com
  3. QEMU快速验证:qemu-system-i386 -fda fdos.img(需预先准备含FreeDOS的软盘镜像)

验证方法

  • 通过条件:程序运行后屏幕清空,显示两行文本:BIOS VGA Initialization和VGA detected: 80x25 text mode active.,且无错误信息输出。
  • 检测失败路径:在非VGA环境(如纯CGA/EGA模拟器)中运行,应显示ERROR: VGA hardware not found!并恢复原视频模式。
  • 模式验证:程序运行后,可通过INT 10h AH=0Fh查询当前模式,返回值AL应为03h(80x25彩色文本)。

关键说明

INT 10h AH=1Ah功能仅在BIOS支持VGA扩展时有效,返回值AL=1Ah表示功能可用,BL返回设备代码(07h/08h/0Ah均为VGA兼容设备)。若BIOS不支持该功能(AL≠1Ah),程序直接判定为无VGA。清屏操作使用滚动窗口功能(AH=06h)而非直接写显存,这是BIOS标准做法,可确保与所有VGA兼容硬件协同工作。代码中字符串以$结尾,符合INT 21h功能09h的约定,但此处使用INT 10h逐字符输出,避免依赖DOS文件系统。