Как загрузить образ с диска на виртуальную машину

#assembly #kernel #osdev #fasm #video-memory

Вопрос:

Я пишу ОС в сборке fasm и столкнулся с проблемой. Я пытался нарисовать шрифт пиксель за пикселем, но это слишком сложно и странно. Я хочу сделать растровый пиксельный шрифт и сохранить его на жестком диске, а в коде ядра создать функцию, которая может загружать его в видеопамять. Я попытался погуглить его, но безуспешно. Помогите, пожалуйста

Код ядра:

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  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, '

Я надеюсь, что мой код будет более оптимизирован в будущем.


Ответ №1:

Я не могу понять, что у тебя за __код изображения! Вы собрали кучу инструкций, которые FASM даже не смог бы собрать.

И зачем вам загружать шрифт, изображение или любой другой файл с диска, если у вас нет файловой системы, которую вы могли бы использовать? На данный момент все, что вы можете сделать, это встроить набор символов в ядро, загруженный загрузчиком 1-го этапа в память.

Это неправильно: в вашем макро __video__init, где вы настраиваете 256-цветной видеорежим 320x200, прямоугольник с черным заполнением ( 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
 

Таким образом, вы можете создавать свои собственные шрифты и выбирать любую ширину и высоту, которые вам нравятся.

Рисование прозрачного текста

В прозрачном тексте отображаются только пиксели, имеющие цвет переднего плана. Фон просвечивает насквозь. Следующий код делает это:

 ; 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
 

Комментарии:

1. Я понимал, что совершил много беспомощных действий, но давайте подумаем, что шрифт помещен на жесткий диск без fs, без заголовка. просто кортеж байтов. и я хочу скопировать байты с жесткого диска в видеобуфер. это все. спасибо за советы

sym 0x0F, 0x40, 0x00, '%'
sym 0x0F, 0x50, 0x00, 'amp;'
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, 'Я надеюсь, что мой код будет более оптимизирован в будущем.

Ответ №1:

Я не могу понять, что у тебя за __код изображения! Вы собрали кучу инструкций, которые FASM даже не смог бы собрать.

И зачем вам загружать шрифт, изображение или любой другой файл с диска, если у вас нет файловой системы, которую вы могли бы использовать? На данный момент все, что вы можете сделать, это встроить набор символов в ядро, загруженный загрузчиком 1-го этапа в память.

Это неправильно: в вашем макро __video__init, где вы настраиваете 256-цветной видеорежим 320x200, прямоугольник с черным заполнением ( rect 0x00, 0, 0, 640*2, 480*2 ), который вы рисуете, слишком велик, и, честно говоря, он вам не нужен, так как при настройке видеорежима экран уже будет затемнен.

Растровое решение

Чтобы начать использовать растровый шрифт, вам нужно будет определить набор символов в вашей программе. Ниже приведен очень неполный пример набора символов, где каждый символ имеет ширину 8 пикселей и высоту 12 пикселей. Я включил битовые шаблоны для цифры "0" и заглавных букв "A" и "B".


Таким образом, вы можете создавать свои собственные шрифты и выбирать любую ширину и высоту, которые вам нравятся.

Рисование прозрачного текста

В прозрачном тексте отображаются только пиксели, имеющие цвет переднего плана. Фон просвечивает насквозь. Следующий код делает это:


Теперь вы можете выводить символ в любом месте экрана в зависимости от положения пикселя в его верхнем левом углу.


Рисование непрозрачного текста

В непрозрачном тексте вы рисуете не только пиксели, имеющие цвет переднего плана, но и те, которые составляют прямоугольник фона. Следующий код делает это:


Теперь вы можете выводить символ в любом месте экрана в зависимости от положения пикселя в его верхнем левом углу.


Комментарии:

1. Я понимал, что совершил много беспомощных действий, но давайте подумаем, что шрифт помещен на жесткий диск без fs, без заголовка. просто кортеж байтов. и я хочу скопировать байты с жесткого диска в видеобуфер. это все. спасибо за советы

je .dollar
cmp al, '%'
je .%
cmp al, 'amp;'
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

Я надеюсь, что мой код будет более оптимизирован в будущем.

Ответ №1:

Я не могу понять, что у тебя за __код изображения! Вы собрали кучу инструкций, которые FASM даже не смог бы собрать.

И зачем вам загружать шрифт, изображение или любой другой файл с диска, если у вас нет файловой системы, которую вы могли бы использовать? На данный момент все, что вы можете сделать, это встроить набор символов в ядро, загруженный загрузчиком 1-го этапа в память.

Это неправильно: в вашем макро __video__init, где вы настраиваете 256-цветной видеорежим 320×200, прямоугольник с черным заполнением ( rect 0x00, 0, 0, 640*2, 480*2 ), который вы рисуете, слишком велик, и, честно говоря, он вам не нужен, так как при настройке видеорежима экран уже будет затемнен.

Растровое решение

Чтобы начать использовать растровый шрифт, вам нужно будет определить набор символов в вашей программе. Ниже приведен очень неполный пример набора символов, где каждый символ имеет ширину 8 пикселей и высоту 12 пикселей. Я включил битовые шаблоны для цифры «0» и заглавных букв «A» и «B».


Таким образом, вы можете создавать свои собственные шрифты и выбирать любую ширину и высоту, которые вам нравятся.

Рисование прозрачного текста

В прозрачном тексте отображаются только пиксели, имеющие цвет переднего плана. Фон просвечивает насквозь. Следующий код делает это:


Теперь вы можете выводить символ в любом месте экрана в зависимости от положения пикселя в его верхнем левом углу.


Рисование непрозрачного текста

В непрозрачном тексте вы рисуете не только пиксели, имеющие цвет переднего плана, но и те, которые составляют прямоугольник фона. Следующий код делает это:


Теперь вы можете выводить символ в любом месте экрана в зависимости от положения пикселя в его верхнем левом углу.


Комментарии:

1. Я понимал, что совершил много беспомощных действий, но давайте подумаем, что шрифт помещен на жесткий диск без fs, без заголовка. просто кортеж байтов. и я хочу скопировать байты с жесткого диска в видеобуфер. это все. спасибо за советы