简体   繁体   English

获得更高分辨率图形模式的最简单方法是什么?

[英]What is the simplest way to get a higher resolution Graphics Mode?

I'm working on a little operating system, and I've decided that I've grown tired of VGA's 320x200 8-bit color limitations.我正在开发一个小型操作系统,我已经决定我已经厌倦了 VGA 的 320x200 8 位颜色限制。 I really don't want to refactor all my code, so my goal is implementing the simplest way to get 720p and 16-bit colors.我真的不想重构我所有的代码,所以我的目标是实现获得 720p 和 16 位颜色的最简单方法。 Here's some of my code (and a link to my GitHub ):这是我的一些代码(以及我的 GitHub 的链接):

boot.asm:启动.asm:

[org 0x7c00]                        
KERNEL_LOCATION equ 0x1000
                                    

mov [BOOT_DISK], dl                 

                                    
xor ax, ax                          
mov es, ax
mov ds, ax
mov bp, 0x8000
mov sp, bp

mov bx, KERNEL_LOCATION
mov dh, 32

mov ah, 0x02
mov al, dh 
mov ch, 0x00
mov dh, 0x00
mov cl, 0x02
mov dl, [BOOT_DISK]
int 0x13

                                    
mov ah, 0x00
mov al, 0x13
int 0x10                ; text mode


CODE_SEG equ GDT_code - GDT_start
DATA_SEG equ GDT_data - GDT_start

cli
lgdt [GDT_descriptor]
mov eax, cr0
or eax, 1
mov cr0, eax
jmp CODE_SEG:start_protected_mode

jmp $
                                    
BOOT_DISK: db 0

GDT_start:
    GDT_null:
        dd 0x0
        dd 0x0

    GDT_code:
        dw 0xffff
        dw 0x0
        db 0x0
        db 0b10011010
        db 0b11001111
        db 0x0

    GDT_data:
        dw 0xffff
        dw 0x0
        db 0x0
        db 0b10010010
        db 0b11001111
        db 0x0

GDT_end:

GDT_descriptor:
    dw GDT_end - GDT_start - 1
    dd GDT_start


[bits 32]
start_protected_mode:
    mov ax, DATA_SEG
    mov ds, ax
    mov ss, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    
    mov ebp, 0x90000        ; 32 bit stack base pointer
    mov esp, ebp

    jmp KERNEL_LOCATION

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

kernel.cpp:内核.cpp:

typedef unsigned char uint8_t;
typedef unsigned char u8;
typedef unsigned short uint16_t;
typedef unsigned int u32;
typedef u32 size_t;
#define SCREEN_WIDTH 320
#define SCREEN_HEIGHT 200
#define SCREEN_SIZE (SCREEN_WIDTH * SCREEN_HEIGHT)
#define FPS 30
#define PIT_HERTZ 1193131.666
#define CLOCK_HIT (int)(PIT_HERTZ/FPS)
#define KEY_LEFT 0x4B
#define KEY_UP 0x48
#define KEY_RIGHT 0x4D
#define KEY_DOWN 0x50

static uint8_t *BUFFER = (uint8_t *) 0xA0000;

// double buffers
uint8_t _sbuffers[2][SCREEN_SIZE];
uint8_t _sback = 0;

#define CURRENT (_sbuffers[_sback])
#define SWAP() (_sback = 1 - _sback)

#define screen_buffer() (_sbuffers[_sback])

#define screen_set(_p, _x, _y)\
    (_sbuffers[_sback][((_y) * SCREEN_WIDTH + (_x))]=(_p))

static inline void outb(uint16_t port, uint8_t val)
{
    asm volatile ( "outb %0, %1" : : "a"(val), "Nd"(port) );
}

static inline uint8_t inb(uint16_t port)
{
    uint8_t ret;
    asm volatile ( "inb %1, %0"
                   : "=a"(ret)
                   : "Nd"(port) );
    return ret;
}

const unsigned char font[128-32][8] = {
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0020 (space)
           /*deleted to aid in shorter code...*/
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}    // U+007F
};

static inline void *memcpy(void *dst, const void *src, size_t n)
{
    u8 *d = (u8*)dst;
    const u8 *s = (const u8*)src;

    while (n-- > 0) {
        *d++ = *s++;
    }

    return d;
}

void screen_swap() {
    memcpy(BUFFER, CURRENT, SCREEN_SIZE);
    SWAP();
}

unsigned read_pit(void) {
    unsigned count = 0;
 
    // al = channel in bits 6 and 7, remaining bits clear
    outb(0x43,0b0000000);
 
    count = inb(0x40);          // Low byte
    count |= inb(0x40)<<8;      // High byte
 
    return count;
}
 
void draw_char(char c, int x, int y, unsigned char color)
{
    const unsigned char *glyph = font[(int)c-32];
 
    for(int cy=0;cy<8;cy++){
        for(int cx=0;cx<8;cx++){
            if(((int)glyph[cy]&(1<<cx))==(1<<cx)){
                screen_set(color,x+cx,y+cy);
            }
        } 
    }
}

void draw_string(const char * s, int x, int y, unsigned char color) {
    int i = 0;
    while(s[i] != false) {
        draw_char(s[i],x+(i*8),y,color);
        i++;
    }
}

void draw_rect(int pos_x, int pos_y, int w, int h, unsigned char color) {
    for(int y = 0; y<h; y++) {
        for(int x = 0; x<w; x++) {
            screen_set(color,x+pos_x,y+pos_y);
        }
    }
}

Since you're targetting 16-bit color, suggesting to use the higher VGA 640x480 resolution isn't going to cut it for you!由于您的目标是 16 位颜色,因此建议使用更高的 VGA 640x480 分辨率不会为您解决问题!
What you need is switching to a VESA video mode.您需要切换到 VESA 视频模式。 The "VESA BIOS EXTENSION (VBE) Core Function Standard v3" from https://vesa.org/ is the document that you should read.来自https://vesa.org/的“VESA BIOS EXTENSION (VBE) Core Function Standard v3”是您应该阅读的文档。


Unrelated to your graphics question, but nonetheless important are the errors in your bootloader code.与您的图形问题无关,但重要的是引导加载程序代码中的错误。 And because I see that you keep re-posting these errors , I find it is urgent that you address these...而且因为我看到你不断重新发布这些错误,我发现你解决这些问题很紧迫......

  • Your mov [BOOT_DISK], dl instruction already depends on a correct DS segment register.您的mov [BOOT_DISK], dl指令已经依赖于正确的 DS 段寄存器。 You must store DL after setting up the segment registers.您必须在设置段寄存器存储 DL。
  • If you change (E)SP, then also change SS and do it in the instruction directly above it.如果您更改 (E)SP,那么也更改 SS 并在其正上方的指令中执行。
xor ax, ax
mov ds, ax
mov es, ax
mov ss, ax      ; \
mov sp, 0x8000  ; /
mov [BOOT_DISK], dl

and

mov ax, DATA_SEG
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax              ; \
mov esp, 0x00090000     ; /  32 bit stack base pointer
mov ebp, esp            ; Only if you need this!
  • You cannot omit checking the error status after the BIOS.LoadSectors function 02h!在 BIOS.LoadSectors 函数 02h 之后,您不能省略检查错误状态! Should an error occur, retry the operation a few times, then fail with a suitable message.如果发生错误,请重试操作几次,然后失败并显示合适的消息。

  • Comment your code, and write comments that are true!评论你的代码,写出真实的评论! With mov ah, 0x00 mov al, 0x13 int 0x10 ; text mode with mov ah, 0x00 mov al, 0x13 int 0x10 ; text mode int 0x10 ; text mode , you are setting up a graphics mode. int 0x10 ; text mode ,您正在设置图形模式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM