You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何以最简方式为自制小型操作系统实现720p/16位色图形模式?

问题描述

我正在开发一款小型操作系统,受够了VGA模式320x200分辨率、8位色的限制。不想重构全部代码,目标是以最简方式实现720p分辨率与16位色显示。以下是我的部分代码:

boot.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, bp

    jmp KERNEL_LOCATION

                                     

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

kernel.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);
        }
    }
}

内容的提问来源于stack exchange,提问作者user17400329

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 18:09:24