如何将映像从磁盘加载到 vmem

How to load image from disk to vmem

我正在用 fasm 汇编编写 OS,我遇到了问题。我试图逐个像素地绘制字体,但它太难太奇怪了。我想制作位图逐像素字体并将其保存在硬盘上,并在内核代码 make 函数中将其加载到视频内存中。我尝试 google 它,但没有成功。请帮忙

内核代码:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  Macroses
macro rect c, x, y, w, h {
    pusha
    mov bx, c
    mov cx, x
    mov dx, y
    mov si, w
    mov di, h
    call __rect
    popa
}
macro pixel c, x, y {rect c, x, y, 1, 1}
macro __video__init {
    pusha
    ;mov ax, 0x4F02
    ;mov bx, 0x101
    ;int 0x10
    mov   ah,     0x00
    mov   al,     0x13
    int   0x10
    rect  0x00,   0,      0,     640*2,   480*2
    popa
}
macro sym c, x, y, s {
    pusha
    xor bx, bx
    mov bx, c
    mov cx, x
    mov dx, y
    mov al, s
    call __sym
    popa
}
macro image x, y, w, h, addr {
    pusha
    mov si, x
    mov di, y
    mov [reg0], w
    mov [reg8], h
    mov bp, addr
    popa
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  Cosmetics
macro return value {
    mov eax, value
ret
}
macro far a {
    mov ax, a/16
    mov ds, ax
    mov es, ax
    mul ax, 16
    mov sp, ax
    div ax, 16
    jmp ax:0x0000
}
macro rint trr {
    pusha
    mov bp, trr
    cmp bp, 0x10
    popa
    je __r10h
}
macro retn {ret}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  Tests
macro __video__test {
    sym 0x0F, 0x00, 0x00, '!'
    sym 0x0F, 0x0F, 0x00, '"'
    sym 0x0F, 0x20, 0x00, '#'
    sym 0x0F, 0x30, 0x00, '$'
    sym 0x0F, 0x40, 0x00, '%'
    sym 0x0F, 0x50, 0x00, '&'
    sym 0x0F, 0x60, 0x00, "'"
    sym 0x0F, 0x70, 0x00, '('
    sym 0x0F, 0x80, 0x00, ')'
    sym 0x0F, 0x90, 0x00, '*'
    sym 0x0F, 0xA0, 0x00, '+'
    sym 0x0F, 0xB0, 0x00, ','
    sym 0x0F, 0xC0, 0x00, '-'
    sym 0x0F, 0xD0, 0x00, '.'
    sym 0x0F, 0xE0, 0x00, '/'
    sym 0x0F, 0xF0, 0x00, '0'
    sym 0x0F, 0x100,0x00, '1'
    image 0, 0, 320, 200, 0
    call __frame
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  Kernel
__kernel:
    org 0x7E00
    mov [bootdev], dl
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  Grafic Core
    __video__init
    ;rect 0x01, 0x00, 0x00, 0x280, 0x190
    __video__test

    jmp $
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  Bss
    buffer     db 1024 dup (?)
    bootdev    db 0x00
    reg0       db 0x0000
    reg1       db 0x0000
    hexstr     db '0x0000', 0x00
    rstr       db "Talisman's R-OS 0.0.1a", 0x00
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  Funcs
;;;;;;;;;;;;;;;;;;;;;;  Bitmap font func
__sym:
    cmp al, '!'
    je .!
    cmp al, '"'
    je ."
    cmp al, '#'
    je .sharp
    cmp al, '$'
    je .dollar
    cmp al, '%'
    je .%
    cmp al, '&'
    je .et
    cmp al, "'"
    je .'
    cmp al, '('
    je .brt
    cmp al, ')'
    je .brt2
    cmp al, '*'
    je .star
    cmp al, '+'
    je .plus
    cmp al, ','
    je .comma
    cmp al, '-'
    je .menos
    cmp al, '.'
    je .point
    cmp al, '/'
    je .slash
    cmp al, '0'
    je .0
    cmp al, '1'
    je .1
    retn
.!:
    add cx, 3
    add dx, 4
    rect bx, cx, dx, 2, 5
    add dx, 7
    rect bx, cx, dx, 2, 2
    retn
.":
    add cx, 2
    add dx, 3
    rect bx, cx, dx, 2, 3
    add cx, 3
    rect bx, cx, dx, 2, 3
    retn
.sharp:
    add cx, 2
    add dx, 4
    rect bx, cx, dx, 2, 8
    add cx, 3
    rect bx, cx, dx, 2, 8
    sub cx, 4
    inc dx
    rect bx, cx, dx, 7, 1
    add dx, 4
    rect bx, cx, dx, 7, 1
    retn
.dollar:
    add cx, 3
    add dx, 2
    rect bx, cx, dx, 2, 2
    dec cx
    add dx, 2
    rect bx, cx, dx, 4, 1
    dec cx
    inc dx
    rect bx, cx, dx, 2, 2
    add cx, 4
    rect bx, cx, dx, 2, 2
    sub cx, 3
    add dx, 2
    rect bx, cx, dx, 2, 1
    add cx, 2
    add dx, 1
    rect bx, cx, dx, 2, 1
    inc cx
    inc dx
    rect bx, cx, dx, 2, 2
    sub cx, 4
    rect bx, cx, dx, 2, 2
    inc cx
    add dx, 2
    rect bx, cx, dx, 4, 1
    inc cx
    inc dx
    rect bx, cx, dx, 2, 2
    retn
.%:
    inc cx
    inc dx
    rect bx, cx, dx, 2, 1
    dec cx
    inc dx
    rect bx, cx, dx, 1, 2
    add cx, 3
    rect bx, cx, dx, 1, 2
    sub cx, 2
    add dx, 2
    rect bx, cx, dx, 2, 1
    dec cx
    add dx, 5
    rect bx, cx, dx, 1, 3
    inc cx
    dec dx
    rect bx, cx, dx, 1, 3
    inc cx
    dec dx
    rect bx, cx, dx, 1, 3
    inc cx
    dec dx
    rect bx, cx, dx, 1, 3
    inc cx
    dec dx
    rect bx, cx, dx, 1, 3
    inc cx
    dec dx
    rect bx, cx, dx, 1, 3
    inc cx
    dec dx
    rect bx, cx, dx, 1, 3
    inc cx
    dec dx
    rect bx, cx, dx, 1, 3
    sub cx, 2
    add dx, 7
    rect bx, cx, dx, 2, 1
    dec cx
    inc dx
    rect bx, cx, dx, 1, 2
    add cx, 3
    rect bx, cx, dx, 1, 2
    sub cx, 2
    add dx, 2
    rect bx, cx, dx, 2, 1
    retn
.et:
    add cx, 2
    add dx, 3
    rect bx, cx, dx, 3, 1
    dec cx
    inc dx
    rect bx, cx, dx, 2 ,2
    add cx, 3
    rect bx, cx, dx, 2, 2
    sub cx, 2
    add dx, 2
    rect bx, cx, dx, 3, 1
    dec cx
    inc dx
    rect bx, cx, dx, 2, 4
    add cx, 3
    inc dx
    rect bx, cx, dx, 4, 1
    inc cx
    inc dx
    rect bx, cx, dx, 2, 2
    sub cx, 3
    add dx, 2
    rect bx, cx, dx, 3, 1
    add cx, 4
    rect bx, cx, dx, 2, 1
    retn
.':
    add cx, 3
    add dx, 2
    rect bx, cx, dx, 2, 3
    retn
.brt:
    add cx, 5
    add dx, 2
    pixel bx, cx, dx
    dec cx
    inc dx
    rect bx, cx, dx, 2, 1
    dec cx
    inc dx
    rect bx, cx, dx, 2, 1
    inc dx
    rect bx, cx, dx, 2, 1
    dec cx
    inc dx
    rect bx, cx, dx, 2, 1
    inc dx
    rect bx, cx, dx, 2, 1
    inc cx
    inc dx
    rect bx, cx, dx, 2, 1
    inc dx
    rect bx, cx, dx, 2, 1
    inc cx
    inc dx
    rect bx, cx, dx, 2, 1
    inc cx
    inc dx
    pixel bx, cx, dx
    retn
.brt2:
    add cx, 3
    add dx, 2
    rect bx, cx, dx, 1, 2
    ;inc cx
    ;inc dx
    ;rect bx, cx, dx, 1, 2
    inc cx
    inc dx
    pixel bx, cx, dx
    inc dx
    rect bx, cx, dx, 2, 2
    inc cx
    add dx, 2
    rect bx, cx, dx, 2, 2
    dec cx
    add dx, 2
    rect bx, cx, dx, 2, 2
    ;dec cx
    inc dx
    ;rect bx, cx, dx, 2, 1
    dec cx
    inc dx
    rect bx, cx, dx, 2, 1
    inc dx
    pixel bx, cx, dx
    retn
.star:
    add cx, 3
    add dx, 3
    pixel bx, cx, dx
    sub cx, 2
    inc dx
    rect bx, cx, dx, 5, 1
    inc cx
    inc dx
    rect bx, cx, dx, 3, 1
    inc dx
    pixel bx, cx, dx
    add cx, 2
    pixel bx, cx, dx
    retn
.plus:
    add cx, 3
    add dx, 5
    rect bx, cx, dx, 2, 5
    sub cx, 2
    add dx, 2
    rect bx, cx, dx, 6, 1
    retn
.comma:
    add cx, 3
    add dx, 10
    rect bx, cx, dx, 2, 2
    inc cx
    add dx, 2
    pixel bx, cx, dx
    retn
.menos:
    inc cx
    add dx, 7
    rect bx, cx, dx, 6, 1
    retn
.point:
    add cx, 3
    add dx, 10
    rect bx, cx, dx, 2, 2
    retn
.slash:
    add dx, 9
    rect bx, cx, dx, 1, 3
    inc cx
    dec dx
    rect bx, cx, dx, 1, 3
    inc cx
    dec dx
    rect bx, cx, dx, 1, 3
    inc cx
    dec dx
    rect bx, cx, dx, 1, 3
    inc cx
    dec dx
    rect bx, cx, dx, 1, 3
    inc cx
    dec dx
    rect bx, cx, dx, 1, 3
    inc cx
    dec dx
    rect bx, cx, dx, 1, 3
    inc cx
    dec dx
    rect bx, cx, dx, 1, 3
    retn
.0:
    inc cx
    add dx, 3
    rect bx, cx, dx, 2, 10
    add cx, 4
    rect bx, cx, dx, 2, 10
    dec cx
    inc dx
    rect bx, cx, dx, 1, 3
    dec cx
    add dx, 5
    rect bx, cx, dx, 1, 3
    dec cx
    sub dx, 7
    rect bx, cx, dx, 4, 1
    add dx, 11
    rect bx, cx, dx, 4, 1
    retn
.1:
    add cx, 4
    add dx, 2
    rect bx, cx, dx, 2, 10
    sub cx, 2
    add dx, 2
    rect bx, cx, dx, 3, 2
    add dx, 6
    rect bx, cx, dx, 6, 2
    retn
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  fast putpix func
__rect:
    push    ds    dx       di
    imul    dx,   320
    add dx,   cx
    mov ax,   0xA000
    mov ds,   ax
    jmp ._o
._o:
    push    si
    jmp ._i
._i:
    dec si
    mov byte  [edx+esi],       bl;bx
    jnz ._i
    pop si
    add dx,   320
    dec di
    jnz ._o
    pop di    dx       ds
    ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  Image func
__image:
    mov ah, 0x00
    int 0x13
    mov ah, 0x02
    mov al, [reg8]
    imul al, 320
    add al, 0x8700
    add al, [reg0]
    idiv al, 512
    mov bx, 0x8700+si+320*di
    mov es, 0x00
    mov ch, 0x00
    mov cl, (bp+512+0x7FFF-64000)/512
    mov dh, 0x00
    mov dl, [bootdev]
    int 0x13
    ret
__frame:
    mov ebx, 0x00000000
._l:
    mov byte [ebx+0xA000], [ebx+0x8700]
    cmp ebx, 6400
    je ._r
    jmp ._l
._r:
    ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  R interrupts
__r10h:
    sym bx, cx, dx, al
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  Footer
__footer:
    cli
    hlt
    jmp $-2
    times 0x7FFF-64000-$+$$ db 0x00

希望以后我的代码能更加优化

我对你的 __image 代码一头雾水!您已经拼凑了一堆 FASM 甚至无法 assemble.

的指令

而且 当您没有可以使用的文件系统时,为什么要从磁盘加载字体、图像或任何其他文件?现在,您所能做的就是将您的第一阶段引导加载程序加载到内存中的字符集嵌入到内核中。

这是错误的:在您设置 320x200 256 色视频模式的 __video__init 宏中,黑色填充矩形 (rect 0x00, 0, 0, 640*2, 480*2)你画的太大了,坦率地说你不需要它,因为设置视频模式已经黑屏了。

位图解决方案

要开始使用位图字体,您必须在程序中定义一个字符集。下面是一个非常不完整的字符集示例,其中每个字符的宽度为 8 像素,高度为 12 像素。我已经包含了数字“0”和大写字母“A”和“B”的位模式。

CharSet12:
    times (48 * 12) db 0                                         ; 0 -> 47
    db 0, 124, 198, 198, 198, 214, 214, 198, 198, 198, 124, 0    ; 48 = Char "0"
    times (16 * 12) db 0                                         ; 49 -> 64
    db 0, 16, 56, 108, 198, 198, 254, 198, 198, 198, 198, 0      ; 65 = Char "A"
    db 0, 252, 102, 102, 102, 124, 102, 102, 102, 102, 252, 0    ; 66 = Char "B"
    times (189 * 12) db 0                                        ; 67 -> 255

您可以通过这种方式设计自己的字体,并且 select 任何您喜欢的宽度和高度。

绘制透明文字

在透明文本中,您只绘制具有前景色的像素。 背景闪耀。下一个代码:

; IN (al,bl,cx,dx) OUT () MOD (ax)
DrawTransparentCharacter:
    push    es cx si di
    mov     ah, 12          ; OffsetInCharacterSet = CharacterHeight * ASCII
    mul     al
    mov     si, ax
    imul    di, dx, 320     ; OffsetInVideoMemory = (Y * 320) + X
    add     di, cx
    mov     ax, 0xA000
    mov     es, ax
    mov     ch, 12          ; CharacterHeight
.OuterLoop:
    mov     cl, 8           ; CharacterWidth
    mov     al, [CharSet12 + si]
.InnerLoop:
    shl     al, 1
    jnc     .Skip
    mov     [es:di], bl     ; Plot pixel
.Skip:
    inc     di
    dec     cl
    jnz     .InnerLoop
    inc     si              ; To next font byte
    add     di, 320 - 8     ; To next scanline
    dec     ch
    jnz     .OuterLoop
    pop     di si cx es
    ret

现在您可以根据左上角的像素位置在屏幕上的任何位置输出一个字符。

; This draws a light green "A" in the middle of the screen
mov     dx, 94      ; Y
mov     cx, 156     ; X
mov     bl, 10      ; Color LightGreen
mov     al, 65      ; "A"
call    DrawTransparentCharacter

绘制不透明文本

在不透明文本中,您不仅可以绘制具有前景色的像素,还可以绘制构成背景矩形的像素。下一个代码:

; IN (al,bx,cx,dx) OUT () MOD (ax)
DrawOpaqueCharacter:
    push    es cx dx si di
    mov     ah, 12          ; OffsetInCharacterSet = CharacterHeight * ASCII
    mul     al
    mov     si, ax
    imul    di, dx, 320     ; OffsetInVideoMemory = (Y * 320) + X
    add     di, cx
    mov     ax, 0xA000
    mov     es, ax
    mov     ch, 12          ; CharacterHeight
.OuterLoop:
    mov     cl, 8           ; CharacterWidth
    mov     al, [CharSet12 + si]
.InnerLoop:
    mov     dl, bl          ; Foreground color
    shl     al, 1
    jc      .Plot
    mov     dl, bh          ; Background color
.Plot:
    mov     [es:di], dl     ; Plot pixel
    inc     di
    dec     cl
    jnz     .InnerLoop
    inc     si              ; To next font byte
    add     di, 320 - 8     ; To next scanline
    dec     ch
    jnz     .OuterLoop
    pop     di si dx cx es
    ret

现在您可以根据左上角的像素位置在屏幕上的任何位置输出一个字符。

; This draws a green on bright white "B" in the bottom right corner of the screen
mov     dx, 188     ; Y
mov     cx, 312     ; X
mov     bx, 0x0F02  ; Colors GreenOnBrightWhite
mov     al, 66      ; "B"
call    DrawOpaqueCharacter