0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

VGA字体の変更

0
Posted at

目的

VGAの字体はA0000~の領域に格納されている。今回は自作の字体に切り替える前段階として、全字体を一つの字体に入れ替える実験をする。

font.asm
org 0x7C00

start:
    xor ax, ax
    mov ds, ax
    mov es, ax
    mov ss, ax
    mov sp, 0x7C00

    ; ディスクから第2セクタを 0x7E00 に読み込む
    mov ah, 0x02        ; INT 13h 2: 読み込み
    mov al, 1           ; 読み込むセクタ数 = 1
    mov ch, 0           ; シリンダ = 0
    mov cl, 2           ; セクタ番号 = 2(1始まり)
    mov dh, 0           ; ヘッド = 0
    mov dl, 0x80        ; ドライブ番号
    mov bx, 0x7E00      ; 読み込み先アドレス
    int 0x13
    jc disk_error       ; エラー時

    ; 読み込んだコードへ跳ぶ(第2セクタ)
    jmp 0x0000:0x7E00

disk_error:
    cli
    hlt

times 510-($-$$) db 0
dw 0xAA55

    mov ax, 0x0003
    int 0x10

; プレーン2 (フォント領域) への書き込み準備 ---
    mov dx, 0x3C4
    mov ax, 0x0402      ; Sequencer Index 2: Plane 2 に書き込み許可
    out dx, ax
    call delay
    mov ax, 0x0704      ; Sequencer Index 4: Sequential Access (Chain4解除)
    out dx, ax
    call delay
    mov dx, 0x3CE
    mov ax, 0x0004      ; Graphics Index 4: Read Plane 2
    out dx, ax
    call delay
    mov ax, 0x0005      ; Graphics Index 5: Write Mode 0
    out dx, ax
    call delay
    mov ax, 0x0406      ; Graphics Index 6: Map to 0xA0000 (64KB)
    out dx, ax
    call delay
    
; --- ここで256文字全部に豆腐を登録 ---

    mov ax, 0xA000
    mov es, ax
    xor di, di          ; ES:DI = A000:0000

    mov cx, 256         ; 256文字

.char_loop:
    push cx

    mov cx, 16          ; 1文字の高さ(16バイト)

.row_loop:
    mov byte [es:di], 0xFF  ; ■■■■■■■■
    inc di
    loop .row_loop

    add di, 16          ; 残り16バイト飛ばす

    pop cx
    loop .char_loop
    
 ; 空白文字(0x20)だけ0x00を変更(そうしないと下の処理で全画面に豆腐を書き込んでしまう)
mov di, 32 * 32  ; 0x20 * 32バイト

mov cx, 16       ; 1文字分(16行)
.blank_loop:
    mov byte [es:di], 0x00
    inc di
    loop .blank_loop
    
; 通常のテキストモード表示設定に戻す ---
    mov dx, 0x3C4
    mov ax, 0x0302      ; Sequencer Index 2: Plane 0,1 に書き込み許可
    out dx, ax
    call delay
    mov ax, 0x0304      ; Sequencer Index 4: Odd/Even モード
    out dx, ax
    call delay

    mov dx, 0x3CE
    mov ax, 0x1005      ; Graphics Index 5: Odd/Even モード
    out dx, ax
    call delay
    mov ax, 0x0E06      ; Graphics Index 6: Map to 0xB8000
    out dx, ax
    call delay

; --- VRAMにASCIIコードを順番に表示(字体の確認に使用) ---
    mov ax, 0xB800
    mov es, ax
    xor di, di          ; VRAM先頭

    xor cx, cx          ; CX = 文字コード 0~255

    .next_char:
        mov al, cl      ; AL = 文字コード(CLに0~255が入る)
        mov ah, 0x0E     ; 文字色(黄色)
        stosw            ; ES:[DI] = AX
        inc cl           ; 次の文字コード
        cmp cl, 0        ; CLは256bitなので8bitなので0に戻る
        jne .next_char   ; CL != 0 なら続行

    cli
    hlt

delay:
    push cx
    mov cx, 10000
.dl_loop:
    nop
    loop .dl_loop
    pop cx
    ret

times 1024-($-$$) db 0

QEMU

nasm -f bin font.asm -o font.bin
qemu-system-i386 -hda font.bin -boot a -no-reboot
1b33d38ddfc

実機

lsblk
sudo dd if=font.bin of=/dev/sdb bs=512 count=2 conv=notrunc

V30

38e0da9607be48

ThinkPad280

14f5684c53779 d2b01002b72fc8
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?