Day 07 - Small Step But Big Changes

The outcome of today’s work seems to be no big changes from Day 06 - Prepare to Step Into GUI, but we need to change a lot. Here is the checklist for changes:

Assembly Codes

C++ Code

Linking Template

Makefile

Change 1 - Increase the number of sectors to be loaded

Increase number sectors to be loaded to 20 => 20 * 512 B = 10 MB.

mov ah, 0x2     ; AH=0x02: read sectors. More can be found https://en.wikipedia.org/wiki/INT_13H
mov al, 20      ; Since we need more disk for bootsector, data, C++, we need more space. Here we load 20 sectors
mov ch, 0       ; cylinder idx
mov dh, 0       ; head idx
mov cl, 2       ; sector idx
mov dl, [disk]  ; disk idx
mov bx, copy_target ;target code pointer
int 0x13        ; Call BIOS interrupt to operate disk

Change 2 - Change the VGA mode from Text mode to Graphic mode

Change Graphic Mode to

; set vga to be graphic mode
    ; enter mode $(AL). details in https://cs.lmu.edu/~ray/notes/pcvideomodes/
    mov ax, 0x0013  ; 320x200x8bit G
    int 0x10

We also save the parameters of the screen resolution in the memroy to be loaded in C++.

; some constants will be loaded in struct BOOTINFO in C code.
CYLS        EQU             0x0ff0                  ; BOOTINFO address
LEDS        EQU             0x0ff1                  ;
VMODE       EQU             0x0ff2                  ; color info
SCRNX       EQU             0x0ff4                  ; screen x
SCRNY       EQU             0x0ff6                  ; screen y
VRAM        EQU             0x0ff8                  ; vram initial address

mov BYTE [VMODE],8  ;
    mov     WORD [SCRNX],320
    mov     WORD [SCRNY],200
    mov     DWORD [VRAM],0x000a0000

Change 3 - Draw a Desktop

With the help of the color palette we implement in Day 06 - Prepare to Step Into GUI, we can draw the background of the desktop in C++ with

boxfill8(vram, SCREENX, LIGHTDARKBLUE,  0,     0,   -1,  -19);
boxfill8(vram, SCREENX, LIGHTGREY,      0,   -18,   -1,  -18);
boxfill8(vram, SCREENX, WHITE,          0,   -17,   -1,  -17);
boxfill8(vram, SCREENX, LIGHTGREY,      0,   -16,   -1,   -1);

boxfill8(vram, SCREENX, WHITE,          3,   -14,   59,  -14);
boxfill8(vram, SCREENX, WHITE,          2,   -14,    2,   -4);
boxfill8(vram, SCREENX, DARKGREY,       3,    -4,   59,   -4);
boxfill8(vram, SCREENX, DARKGREY,      59,   -13,   59,   -5);
boxfill8(vram, SCREENX, BLACK,          2,    -3,   59,   -3);
boxfill8(vram, SCREENX, BLACK,         60,   -14,   60,   -3);

boxfill8(vram, SCREENX, DARKGREY,     -47,  -14,   -4,   -14);
boxfill8(vram, SCREENX, DARKGREY,     -47,  -13,  -47,    -4);
boxfill8(vram, SCREENX, WHITE,        -47,   -3,   -4,    -3);
boxfill8(vram, SCREENX, WHITE,         -3,  -14,   -3,    -3);

Change 4 - Draw charactor “A”

Different from all we do in previous 6 days, “printing” charactors is equivalent to manually setting corresponding pixels to another color. For a 8x16 pixel charactor “A”, it requires 16 8-bit data. The font data is

unsigned char charA[16] = {
0x00, // 00000000
0x00, // 00000000
0x10, // 00010000
0x38, // 00111000
0x6c, // 01101100
0xc6, // 11000110
0xc6, // 11000110
0xfe, // 11111110
0xc6, // 11000110
0xc6, // 11000110
0xc6, // 11000110
0xc6, // 11000110
0x00, // 00000000
0x00, // 00000000
0x00, // 00000000
0x00  // 00000000
};

To draw the font data, we write another function putfont8 which reads

void putfont8(char *vram, int xsize, int x, int y, char color, unsigned char *font){
    int i;
    char *p, d /* data */;
    for (i = 0; i < 16; i++) {
        p = vram + (y + i) * xsize + x;
        d = font[i];
        // set the color for the corresponding 8 pixels.
        if ((d & 0x80) != 0) { p[0] = color; }
        if ((d & 0x40) != 0) { p[1] = color; }
        if ((d & 0x20) != 0) { p[2] = color; }
        if ((d & 0x10) != 0) { p[3] = color; }
        if ((d & 0x08) != 0) { p[4] = color; }
        if ((d & 0x04) != 0) { p[5] = color; }
        if ((d & 0x02) != 0) { p[6] = color; }
        if ((d & 0x01) != 0) { p[7] = color; }
    }
    return;
}

In the main function, we do

putfont8(vram, SCREENX, 0, 16, BLACK, charA);

Result

../../../../_images/result6.png