Download Game! Currently 73 players and visitors. Last logged in:JosimSolvikBrurinRequiem

Blitzer's Blog >> 71395

Back to blogs index
Posted: 12 Jul 2026 09:54 [ permalink ]
TC$mC$ on **huikea onnistuminen**, vaikka ruudulla nC$kyykin "vC$rioksennusta"!

Jos katsot tarkkaan QEMU-ruutukaappaustasi ja vertaat sitC$ alkuperC$iseen
`KUVA.JPG` -tiedostoon, huomaat ettC$ **kuviot ja muodot tC$smC$C$vC$t
tC$ydellisesti!** Sateenkaaren diagonaaliset linjat ovat juuri oikeilla
paikoilla.

TC$mC$ tarkoittaa, ettC$ koko massiivinen arkkitehtuurisi toimi: 21 Kt
tiedosto luettiin suoraan ATA-laitteistolta, Bump Allocator antoi sille 2MB
muistia, NanoJPEG purki Huffman-taulut ja IDCT-matematiikan tC$ysin oikein
C-tasolla.

### Miksi vC$rit ovat sekaisin? (Paljaan metallin realiteetit)

Koodissamme on rivi: `uint8_t vga_color = 16 + (cr * 36) + (cg * 6) + cb;`

TC$mC$ kaava olettaa, ettC$ kC$ytC6ssC$ on modernien Linux-terminaalien (Xterm
256) standardipaletti, jossa indeksit 16231 muodostavat tC$ydellisen 6x6x6
RGB-vC$rikuution.

Mutta me olemme paljaalla metallilla! Kun Hauki OS kytkee VGA-kortin Mode 13h
-tilaan, laitteisto lataa BIOSistaan ikivanhan **vuoden 1987 DOS-oletuspaletin*
*. Tuossa paletissa indeksi 16 on musta, indeksit 1731 ovat harmaasC$vyjC$, ja
loput ovat tC$ysin satunnaisia vC$rejC$ ohjelmamme nC$kC6kulmasta. Siksi
oikeiden sC$vyjen tilalle tulee suuria mustia aukkoja ja kirkkaita
perusvC$rejC$.

### Ratkaisu: Ohjelmoidaan VGA DAC (Digital-to-Analog Converter)

Korjataksemme tC$mC$n, meidC$n tC$ytyy kertoa nC$ytC6nohjaimelle suoraan,
miltC$ haluamme indeksien 16231 nC$yttC$vC$n. Laitteistotasolla tC$mC$
tehdC$C$n puhumalla IO-porteille `0x3C8` (Paletin indeksi) ja `0x3C9`
(RGB-data).

VGA DAC on historiallisista syistC$ **6-bittinen**, eli vC$riarvot annetaan
asteikolla `0-63` (ei 0-255).

Avaa `kernel_js.c` ja korvaa nykyinen `render_jpeg_to_vga` -funktio tC$llC$
pC$ivitetyllC$ versiolla:

```c
/ =============================================================================
=
/ RGB -> VGA 13h (256-color) MUUNNIN & DAC PALETIN OHJELMOINTI
/ =============================================================================
=
extern uint8_t vga_backbuffer[64000];

void render_jpeg_to_vga(uint8_t* rgb, int w, int h) {
    
    // 1. Ohjelmoidaan VGA DAC sisC$ltC$mC$C$n 6x6x6 RGB-vC$rikuutio
    // Portti 0x3C8: Paletin aloitusindeksi
    // Portti 0x3C9: R, G, B arvot perC$kkC$in (0-63 asteikolla)
    outb(0x3C8, 16); 
    for (int r = 0; r < 6; r++) {
        for (int g = 0; g < 6; g++) {
            for (int b = 0; b < 6; b++) {
                // Skaalataan 0-5 arvo 0-63 VGA DAC-alueelle (5 * 51 / 4 = 63)
                outb(0x3C9, (r * 51) / 4);
                outb(0x3C9, (g * 51) / 4);
                outb(0x3C9, (b * 51) / 4);
            }
        }
    }

    // 2. PiirretC$C$n pikselit nC$yttC6muistiin uudella paletilla
    for (int y = 0; y < h && y < 200; y++) {
        for (int x = 0; x < w && x < 320; x++) {
            int idx = (y * w + x) * 3;
            uint8_t r = rgb[idx];
            uint8_t g = rgb[idx+1];
            uint8_t b = rgb[idx+2];
            
            // Skaalataan 255 -> 5 (eli 0-5)
            uint8_t cr = (r * 5) / 255;
            uint8_t cg = (g * 5) / 255;
            uint8_t cb = (b * 5) / 255;
            
            uint8_t vga_color = 16 + (cr * 36) + (cg * 6) + cb;
            vga_backbuffer[y * 320 + x] = vga_color;
        }
    }
}

```

Kun kC$C$nnC$t ytimen tC$llC$ (`./make_kernel.sh`) ja suoritat `/jpeg`, C-ydin
syC6ttC$C$ laitteistoporttiin oman kustomoidun palettimme juuri ennen kuvan
purkamista. Nyt pikselien muodot pysyvC$t samoina, mutta vC$rit asettuvat
kohdilleen ja nC$et upean, pehmeC$n plasmakuvion! TC$mC$n lC$hemmC$s rautaa ei
kuvankC$sittelyssC$ enC$C$ pC$C$se.