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:
Increase the number of sectors to be loaded (loader.asm)
Change the VGA mode from Text mode to Graphic mode.
Draw a desktop
“Draw” charactor “A” onto the screen.
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);