1. 程式人生 > >10.繪製ascii字型/滑鼠指標

10.繪製ascii字型/滑鼠指標

簡介

上一節我們使用調色盤繪製了基本的桌面背景,對圖形的繪製有一定的瞭解。字型的繪製跟其他圖形一樣,都是通過將指定位置的畫素點設定成給定顏色而形成的最終圖形。
我們看到,要繪製給定的字母,我們可以把一塊圖形區域先全部染成白色,然後在將某個位置的畫素點的顏色設定成黑色,那麼,字型就顯示出來了。如果我們把字型的大小限定在一個8*16的長方形區域,那麼我們在這個區域內,將特定位置的畫素點設定成黑色,其他點設定成白色,那麼我們就可以得到一個白底黑色的字型:
在這裡插入圖片描述

目標

實現字形圖形的繪製滑鼠指標的繪製。ascii 字元點陣編碼ascii_font.h檔案如下:

//ascii 8x16點陣編碼。每一行一個位元組,共16行,為1表示顯示
//每個字元的顯示需要16個位元組
//編碼的都是可顯示字元從ascii編碼0x20-0x7f
//

static unsigned char ascii_array[] = {
				
		// space 0x20
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		// !
		0x00,0x00,0x18,0x3C,0x3C,0x3C,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00,
		// "
		0x00,0x63,0x63,0x63,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 
		// #
		0x00,0x00,0x00,0x36,0x36,0x7F,0x36,0x36,0x36,0x7F,0x36,0x36,0x00,0x00,0x00,0x00, 
		// $
		0x0C,0x0C,0x3E,0x63,0x61,0x60,0x3E,0x03,0x03,0x43,0x63,0x3E,0x0C,0x0C,0x00,0x00, 
		// %
		0x00,0x00,0x00,0x00,0x00,0x61,0x63,0x06,0x0C,0x18,0x33,0x63,0x00,0x00,0x00,0x00,
		// & 
		0x00,0x00,0x00,0x1C,0x36,0x36,0x1C,0x3B,0x6E,0x66,0x66,0x3B,0x00,0x00,0x00,0x00, 
		// '
		0x00,0x30,0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		// (
		0x00,0x00,0x0C,0x18,0x18,0x30,0x30,0x30,0x30,0x18,0x18,0x0C,0x00,0x00,0x00,0x00, 
		// )
		0x00,0x00,0x18,0x0C,0x0C,0x06,0x06,0x06,0x06,0x0C,0x0C,0x18,0x00,0x00,0x00,0x00, 
		// *
		0x00,0x00,0x00,0x00,0x42,0x66,0x3C,0xFF,0x3C,0x66,0x42,0x00,0x00,0x00,0x00,0x00,
		// +
		0x00,0x00,0x00,0x00,0x18,0x18,0x18,0xFF,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0x00, 
		// ,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00, 
		// -
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 
		// .
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00, 
		// / (forward slash)
		0x00,0x00,0x01,0x03,0x07,0x0E,0x1C,0x38,0x70,0xE0,0xC0,0x80,0x00,0x00,0x00,0x00, 
		// 0 0x30
		0x00,0x00,0x3E,0x63,0x63,0x63,0x6B,0x6B,0x63,0x63,0x63,0x3E,0x00,0x00,0x00,0x00,
		// 1
		0x00,0x00,0x0C,0x1C,0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3F,0x00,0x00,0x00,0x00, 
		// 2
		0x00,0x00,0x3E,0x63,0x03,0x06,0x0C,0x18,0x30,0x61,0x63,0x7F,0x00,0x00,0x00,0x00, 
		// 3
		0x00,0x00,0x3E,0x63,0x03,0x03,0x1E,0x03,0x03,0x03,0x63,0x3E,0x00,0x00,0x00,0x00, 
		// 4
		0x00,0x00,0x06,0x0E,0x1E,0x36,0x66,0x66,0x7F,0x06,0x06,0x0F,0x00,0x00,0x00,0x00, 
		// 5
		0x00,0x00,0x7F,0x60,0x60,0x60,0x7E,0x03,0x03,0x63,0x73,0x3E,0x00,0x00,0x00,0x00, 
		// 6
		0x00,0x00,0x1C,0x30,0x60,0x60,0x7E,0x63,0x63,0x63,0x63,0x3E,0x00,0x00,0x00,0x00, 
		// 7
		0x00,0x00,0x7F,0x63,0x03,0x06,0x06,0x0C,0x0C,0x18,0x18,0x18,0x00,0x00,0x00,0x00, 
		// 8
		0x00,0x00,0x3E,0x63,0x63,0x63,0x3E,0x63,0x63,0x63,0x63,0x3E,0x00,0x00,0x00,0x00, 
		// 9
		0x00,0x00,0x3E,0x63,0x63,0x63,0x63,0x3F,0x03,0x03,0x06,0x3C,0x00,0x00,0x00,0x00, 
		// :
		0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00, 
		 // ;
		0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00,
		// <
		0x00,0x00,0x00,0x06,0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x06,0x00,0x00,0x00,0x00,
		// =
		0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00, 
		// >
		0x00,0x00,0x00,0x60,0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x60,0x00,0x00,0x00,0x00, 
		// ?
		0x00,0x00,0x3E,0x63,0x63,0x06,0x0C,0x0C,0x0C,0x00,0x0C,0x0C,0x00,0x00,0x00,0x00, 
		// @ 0x40
		0x00,0x00,0x3E,0x63,0x63,0x6F,0x6B,0x6B,0x6E,0x60,0x60,0x3E,0x00,0x00,0x00,0x00, 
		// A
		0x00,0x00,0x08,0x1C,0x36,0x63,0x63,0x63,0x7F,0x63,0x63,0x63,0x00,0x00,0x00,0x00,
		// B
		0x00,0x00,0x7E,0x33,0x33,0x33,0x3E,0x33,0x33,0x33,0x33,0x7E,0x00,0x00,0x00,0x00, 
		// C
		0x00,0x00,0x1E,0x33,0x61,0x60,0x60,0x60,0x60,0x61,0x33,0x1E,0x00,0x00,0x00,0x00,
		// D
		0x00,0x00,0x7C,0x36,0x33,0x33,0x33,0x33,0x33,0x33,0x36,0x7C,0x00,0x00,0x00,0x00, 
		// E
		0x00,0x00,0x7F,0x33,0x31,0x34,0x3C,0x34,0x30,0x31,0x33,0x7F,0x00,0x00,0x00,0x00, 
		// F
		0x00,0x00,0x7F,0x33,0x31,0x34,0x3C,0x34,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00, 
		// G
		0x00,0x00,0x1E,0x33,0x61,0x60,0x60,0x6F,0x63,0x63,0x37,0x1D,0x00,0x00,0x00,0x00, 
		// H
		0x00,0x00,0x63,0x63,0x63,0x63,0x7F,0x63,0x63,0x63,0x63,0x63,0x00,0x00,0x00,0x00, 
		// I
		0x00,0x00,0x3C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00, 
		// J
		0x00,0x00,0x0F,0x06,0x06,0x06,0x06,0x06,0x06,0x66,0x66,0x3C,0x00,0x00,0x00,0x00, 
		// K
		0x00,0x00,0x73,0x33,0x36,0x36,0x3C,0x36,0x36,0x33,0x33,0x73,0x00,0x00,0x00,0x00, 
		// L
		0x00,0x00,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x33,0x7F,0x00,0x00,0x00,0x00, 
		// M
		0x00,0x00,0x63,0x77,0x7F,0x6B,0x63,0x63,0x63,0x63,0x63,0x63,0x00,0x00,0x00,0x00, 
		// N
		0x00,0x00,0x63,0x63,0x73,0x7B,0x7F,0x6F,0x67,0x63,0x63,0x63,0x00,0x00,0x00,0x00, 
		// O
		0x00,0x00,0x1C,0x36,0x63,0x63,0x63,0x63,0x63,0x63,0x36,0x1C,0x00,0x00,0x00,0x00, 
		 // P 0x50
		0x00,0x00,0x7E,0x33,0x33,0x33,0x3E,0x30,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00,
		// Q
		0x00,0x00,0x3E,0x63,0x63,0x63,0x63,0x63,0x63,0x6B,0x6F,0x3E,0x06,0x07,0x00,0x00, 
		// R
		0x00,0x00,0x7E,0x33,0x33,0x33,0x3E,0x36,0x36,0x33,0x33,0x73,0x00,0x00,0x00,0x00, 
		// S
		0x00,0x00,0x3E,0x63,0x63,0x30,0x1C,0x06,0x03,0x63,0x63,0x3E,0x00,0x00,0x00,0x00, 
		// T
		0x00,0x00,0xFF,0xDB,0x99,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00, 
		// U
		0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x3E,0x00,0x00,0x00,0x00, 
		// V
		0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x36,0x1C,0x08,0x00,0x00,0x00,0x00, 
		// W
		0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x6B,0x6B,0x7F,0x36,0x36,0x00,0x00,0x00,0x00, 
		// X
		0x00,0x00,0xC3,0xC3,0x66,0x3C,0x18,0x18,0x3C,0x66,0xC3,0xC3,0x00,0x00,0x00,0x00, 
		// Y
		0x00,0x00,0xC3,0xC3,0xC3,0x66,0x3C,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00, 
		// Z
		0x00,0x00,0x7F,0x63,0x43,0x06,0x0C,0x18,0x30,0x61,0x63,0x7F,0x00,0x00,0x00,0x00, 
		// [
		0x00,0x00,0x3C,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3C,0x00,0x00,0x00,0x00, 
		// \ (back slash)
		0x00,0x00,0x80,0xC0,0xE0,0x70,0x38,0x1C,0x0E,0x07,0x03,0x01,0x00,0x00,0x00,0x00, 
		// ]
		0x00,0x00,0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00,0x00,0x00,0x00, 
		// ^
		0x08,0x1C,0x36,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		// _
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 
		// ` 0x60
		0x18,0x18,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		// a
		0x00,0x00,0x00,0x00,0x00,0x3C,0x46,0x06,0x3E,0x66,0x66,0x3B,0x00,0x00,0x00,0x00, 
		// b
		0x00,0x00,0x70,0x30,0x30,0x3C,0x36,0x33,0x33,0x33,0x33,0x6E,0x00,0x00,0x00,0x00, 
		// c
		0x00,0x00,0x00,0x00,0x00,0x3E,0x63,0x60,0x60,0x60,0x63,0x3E,0x00,0x00,0x00,0x00, 
		// d
		0x00,0x00,0x0E,0x06,0x06,0x1E,0x36,0x66,0x66,0x66,0x66,0x3B,0x00,0x00,0x00,0x00, 
		// e
		0x00,0x00,0x00,0x00,0x00,0x3E,0x63,0x63,0x7E,0x60,0x63,0x3E,0x00,0x00,0x00,0x00, 
		// f
		0x00,0x00,0x1C,0x36,0x32,0x30,0x7C,0x30,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00, 
		// g
		0x00,0x00,0x00,0x00,0x00,0x3B,0x66,0x66,0x66,0x66,0x3E,0x06,0x66,0x3C,0x00,0x00, 
		// h
		0x00,0x00,0x70,0x30,0x30,0x36,0x3B,0x33,0x33,0x33,0x33,0x73,0x00,0x00,0x00,0x00, 
		// i
		0x00,0x00,0x0C,0x0C,0x00,0x1C,0x0C,0x0C,0x0C,0x0C,0x0C,0x1E,0x00,0x00,0x00,0x00, 
		// j
		0x00,0x00,0x06,0x06,0x00,0x0E,0x06,0x06,0x06,0x06,0x06,0x66,0x66,0x3C,0x00,0x00, 
		// k
		0x00,0x00,0x70,0x30,0x30,0x33,0x33,0x36,0x3C,0x36,0x33,0x73,0x00,0x00,0x00,0x00, 
		// l
		0x00,0x00,0x1C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x1E,0x00,0x00,0x00,0x00, 
		// m
		0x00,0x00,0x00,0x00,0x00,0x6E,0x7F,0x6B,0x6B,0x6B,0x6B,0x6B,0x00,0x00,0x00,0x00, 
		// n
		0x00,0x00,0x00,0x00,0x00,0x6E,0x33,0x33,0x33,0x33,0x33,0x33,0x00,0x00,0x00,0x00, 
		// o
		0x00,0x00,0x00,0x00,0x00,0x3E,0x63,0x63,0x63,0x63,0x63,0x3E,0x00,0x00,0x00,0x00, 
		// p 0x70
		0x00,0x00,0x00,0x00,0x00,0x6E,0x33,0x33,0x33,0x33,0x3E,0x30,0x30,0x78,0x00,0x00, 
		// q
		0x00,0x00,0x00,0x00,0x00,0x3B,0x66,0x66,0x66,0x66,0x3E,0x06,0x06,0x0F,0x00,0x00, 
		// r
		0x00,0x00,0x00,0x00,0x00,0x6E,0x3B,0x33,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00, 
		// s
		0x00,0x00,0x00,0x00,0x00,0x3E,0x63,0x38,0x0E,0x03,0x63,0x3E,0x00,0x00,0x00,0x00, 
		// t
		0x00,0x00,0x08,0x18,0x18,0x7E,0x18,0x18,0x18,0x18,0x1B,0x0E,0x00,0x00,0x00,0x00, 
		// u
		0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x66,0x3B,0x00,0x00,0x00,0x00, 
		// v
		0x00,0x00,0x00,0x00,0x00,0x63,0x63,0x36,0x36,0x1C,0x1C,0x08,0x00,0x00,0x00,0x00, 
		// w
		0x00,0x00,0x00,0x00,0x00,0x63,0x63,0x63,0x6B,0x6B,0x7F,0x36,0x00,0x00,0x00,0x00, 
		// x
		0x00,0x00,0x00,0x00,0x00,0x63,0x36,0x1C,0x1C,0x1C,0x36,0x63,0x00,0x00,0x00,0x00, 
		// y
		0x00,0x00,0x00,0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x3F,0x03,0x06,0x3C,0x00,0x00, 
		// z
		0x00,0x00,0x00,0x00,0x00,0x7F,0x66,0x0C,0x18,0x30,0x63,0x7F,0x00,0x00,0x00,0x00, 
		// {
		0x00,0x00,0x0E,0x18,0x18,0x18,0x70,0x18,0x18,0x18,0x18,0x0E,0x00,0x00,0x00,0x00, 
		// |
		0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00, 
		// }
		0x00,0x00,0x70,0x18,0x18,0x18,0x0E,0x18,0x18,0x18,0x18,0x70,0x00,0x00,0x00,0x00,
		// ~
		0x00,0x00,0x3B,0x6E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 
		// DEL
		0x00,0x70,0xD8,0xD8,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00

};

1、繪製ascii可顯示字元,修改os.c檔案如下:

// !compile method
// clang -m32 -c os.c -o os.o
// objconv -fnasm os.o -o os.s
//

#include "io.h"
#include "ascii_font.h"


//定義調色盤顏色
#define  COL8_000000  0
#define  COL8_FF0000  1
#define  COL8_00FF00  2
#define  COL8_FFFF00  3
#define  COL8_0000FF  4
#define  COL8_FF00FF  5
#define  COL8_00FFFF  6
#define  COL8_FFFFFF  7
#define  COL8_C6C6C6  8
#define  COL8_840000  9
#define  COL8_008400  10
#define  COL8_848400  11
#define  COL8_000084  12
#define  COL8_840084  13
#define  COL8_008484  14
#define  COL8_848484  15


//螢幕寬度
#define SCREEN_WIDTH 320
#define SCREEN_HEIGHT 200

//設定調色盤
void initPallet();


/**
 *繪製矩形
 *x             矩形左上角x座標
 *y             矩形左上角y座標
 *width         寬度
 *height        高度
 *colIndex      pallet_color 型別調色盤顏色索引,即矩形顏色
 */

void fillRect(int x,int y,int width,int height,char colIndex);


//繪製桌面背景
void drawBackground();


/**
 *繪製字型
 *@param	addr		繪製的起始視訊記憶體地址
 *@param 	x			繪製的x座標
 *@param	y			繪製的y座標
 *@param	col			繪製顏色
 *@param	pch			繪製的字元陣列8*16,每一行共8位,共16行
 *@param	screenWidth	螢幕寬度
 */
void putChar(char *addr,int x,int y,char col,unsigned char *ch,int screenWidth);

//作業系統C語言入口函式--可以指定為其他
void init_main() {

    initPallet();
	
	drawBackground();
	
	unsigned char *ascii = ascii_array;
	
	for(int i=0x20;i<=0x7f;i++){
		int x = (i-0x20)%32*10;
		int y = (i-0x20)/32*20;
		putChar((char *)0xa0000,x,y,COL8_FFFFFF,ascii+(i-0x20)*16,SCREEN_WIDTH);
		
	}
	
    for(; ;){
        io_hlt();
    }
    
}

void initPallet(){
    //定義調色盤
    static unsigned char table_rgb[16*3] = {
    
        0x00,  0x00,  0x00,		/*  0:黑色*/
        0xff,  0x00,  0x00,		/*  1:亮紅*/
        0x00,  0xff,  0x00,		/*  2:亮綠*/
        0xff,  0xff,  0x00,		/*  3:亮黃*/
        0x00,  0x00,  0xff,		/*  4:亮藍*/
        0xff,  0x00,  0xff,		/*  5:亮紫*/
        0x00,  0xff,  0xff,		/*  6:淺亮藍*/
        0xff,  0xff,  0xff,		/*  7:白色*/
        0xc6,  0xc6,  0xc6,		/*  8:亮灰*/
        0x84,  0x00,  0x00,		/*  9:暗紅*/
        0x00,  0x84,  0x00,		/* 10:暗綠*/
        0x84,  0x84,  0x00,		/* 11:暗黃*/
        0x00,  0x00,  0x84,		/* 12:暗青*/
        0x84,  0x00,  0x84,		/* 13:暗紫*/
        0x00,  0x84,  0x84,		/* 14:淺灰藍*/
        0x84,  0x84,  0x84,		/* 15:暗灰*/
        
    };
    
	unsigned char *rgb = table_rgb;
	int flag = io_readFlag();
    io_cli();
    io_out8(0x03c8, 0);
	for(int i=0;i<16;i++){
		io_out8(0x03c9,rgb[0] / 4);
        io_out8(0x03c9,rgb[1] / 4);
        io_out8(0x03c9,rgb[2] / 4);
    	rgb += 3;
	}
	io_writeFlag(flag);
}


void fillRect(int x,int y,int width,int height,char colIndex){
    char *vram = (char *)0xa0000;
    for(int i=y;i<=y+height;i++){
        for(int j=x;j<=x+width;j++){
            vram[i*SCREEN_WIDTH+j] = colIndex;
        }
    }
}

void drawBackground(){
	
	fillRect(0,0,SCREEN_WIDTH-1,SCREEN_HEIGHT-29, COL8_008484);
    fillRect(0,SCREEN_HEIGHT-28,SCREEN_WIDTH-1,28, COL8_848484);


	fillRect(0,SCREEN_HEIGHT-27,SCREEN_WIDTH,1, COL8_848484);
	fillRect(0,SCREEN_HEIGHT-26,SCREEN_WIDTH,25, COL8_C6C6C6);
	
	fillRect(3,SCREEN_HEIGHT-24,56,1, COL8_FFFFFF);
	fillRect(2,SCREEN_HEIGHT-24,1,20, COL8_FFFFFF);

	fillRect(3,SCREEN_HEIGHT-4,56,1, COL8_848484);
	fillRect(59,SCREEN_HEIGHT-23,1,19, COL8_848484);

	fillRect(2,SCREEN_HEIGHT-3,57,0, COL8_000000);
	fillRect(60,SCREEN_HEIGHT-24,0,19, COL8_000000);

	fillRect(SCREEN_WIDTH-47,SCREEN_HEIGHT-24,43,1, COL8_848484);
	fillRect(SCREEN_WIDTH-47,SCREEN_HEIGHT-23,0,19, COL8_848484);

	fillRect(SCREEN_WIDTH-47,SCREEN_HEIGHT-3,43,0, COL8_FFFFFF);
	fillRect(SCREEN_WIDTH-3,SCREEN_HEIGHT-24,0,21, COL8_FFFFFF);
}

void putChar(char *addr,int x,int y,char col,unsigned char *pch,int screenWidth){
	
	for(int i=0;i<16;i++){
		char ch = pch[i];
		int off = (y+i)*screenWidth;
		
		//顯示的字形最左邊的是低地址,右側的是高地址。例如:0x80,則高地址部分顯示在記憶體的低地址,
		//最低位的應該偏移7
		if((ch & 0x01) != 0){
			addr[off+x+7] = col;
		}
		if((ch & 0x02) != 0){
			addr[off+x+6] = col;
		}
		if((ch & 0x04) != 0){
			addr[off+x+5] = col;
		}
		if((ch & 0x08) != 0){
			addr[off+x+4] = col;
		}	
		if((ch & 0x10) != 0){
			addr[off+x+3] = col;
		}
		if((ch & 0x20) != 0){
			addr[off+x+2] = col;
		}
		if((ch & 0x40) != 0){
			addr[off+x+1] = col;
		}	
		if((ch & 0x80) != 0){
			addr[off+x+0] = col;
		}
	}
}

載入虛擬軟盤檔案效果如下:

在這裡插入圖片描述

至此繪製字元字型成功完成,如果有中文編碼點陣也可方便的顯示出中文,這不就是中文系統了麼!!

2、滑鼠指標的繪製原理和繪製字型圖形一樣,不過滑鼠指標的點陣為16x16。修改os.c檔案如下:

// !compile method
// clang -m32 -c os.c -o os.o
// objconv -fnasm os.o -o os.s
//

#include "io.h"
#include "ascii_font.h"


//定義調色盤顏色
#define  COL8_000000  0
#define  COL8_FF0000  1
#define  COL8_00FF00  2
#define  COL8_FFFF00  3
#define  COL8_0000FF  4
#define  COL8_FF00FF  5
#define  COL8_00FFFF  6
#define  COL8_FFFFFF  7
#define  COL8_C6C6C6  8
#define  COL8_840000  9
#define  COL8_008400  10
#define  COL8_848400  11
#define  COL8_000084  12
#define  COL8_840084  13
#define  COL8_008484  14
#define  COL8_848484  15


//螢幕寬度
#define SCREEN_WIDTH 320
#define SCREEN_HEIGHT 200


void initPallet();



/**
 *繪製矩形
 *x             矩形左上角x座標
 *y             矩形左上角y座標
 *width         寬度
 *height        高度
 *colIndex      pallet_color 型別調色盤顏色索引,即矩形顏色
 */

void fillRect(int x,int y,int width,int height,char colIndex);


//繪製桌面背景
void drawBackground();


/**
 *繪製字型
 *@param	addr		繪製的起始視訊記憶體地址
 *@param 	x			繪製的x座標
 *@param	y			繪製的y座標
 *@param	col			繪製顏色
 *@param	pch			繪製的字元陣列8*16,每一行共8位,共16行
 *@param	screenWidth	螢幕寬度
 */
void putChar(char *addr,int x,int y,char col,unsigned char *ch,int screenWidth);

    
 /*
 *初始化滑鼠指標
 *@param	vram		繪製的起始視訊記憶體地址
 *@param	x			繪製滑鼠指標最左上角x座標
 *@param	y			繪製滑鼠指標最左上角y座標
 *@param	bc			繪製的矩形填充顏色,和背景色一樣將能看到滑鼠指標
 */
void init_mouse_cursor(char *vram,int x,int y,char bc);

//作業系統C語言入口函式--可以指定為其他
void init_main() {

    initPallet();
	drawBackground();
	
	
	unsigned char *ascii = ascii_array;
	
	for(int i=0x20;i<=0x7f;i++){
		int x = (i-0x20)%32*10;
		int y = (i-0x20)/32*20;
		putChar((char *)0xa0000,x,y,COL8_FFFFFF,ascii+(i-0x20)*16,SCREEN_WIDTH);
		
	}

	init_mouse_cursor((char *)0xa0000,100,100,COL8_008484);
	
    for(; ;){
        io_hlt();
    }
    
}

void initPallet(){
    //定義調色盤
    static unsigned char table_rgb[16*3] = {
    
        0x00,  0x00,  0x00,		/*  0:黑色*/
        0xff,  0x00,  0x00,		/*  1:亮紅*/
        0x00,  0xff,  0x00,		/*  2:亮綠*/
        0xff,  0xff,  0x00,		/*  3:亮黃*/
        0x00,  0x00,  0xff,		/*  4:亮藍*/
        0xff,  0x00,  0xff,		/*  5:亮紫*/
        0x00,  0xff,  0xff,		/*  6:淺亮藍*/
        0xff,  0xff,  0xff,		/*  7:白色*/
        0xc6,  0xc6,  0xc6,		/*  8:亮灰*/
        0x84,  0x00,  0x00,		/*  9:暗紅*/
        0x00,  0x84,  0x00,		/* 10:暗綠*/
        0x84,  0x84,  0x00,		/* 11:暗黃*/
        0x00,  0x00,  0x84,		/* 12:暗青*/
        0x84,  0x00,  0x84,		/* 13:暗紫*/
        0x00,  0x84,  0x84,		/* 14:淺灰藍*/
        0x84,  0x84,  0x84,		/* 15:暗灰*/
        
    };
    
	unsigned char *rgb = table_rgb;
	int flag = io_readFlag();
    io_cli();
    io_out8(0x03c8, 0);
	for(int i=0;i<16;i++){
		io_out8(0x03c9,rgb[0] / 4);
        io_out8(0x03c9,rgb[1] / 4);
        io_out8(0x03c9,rgb[2] / 4);
    	rgb += 3;
	}
	io_writeFlag(flag);
}


void fillRect(int x,int y,int width,int height,char colIndex){
    char *vram = (char *)0xa0000;
    for(int i=y;i<=y+height;i++){
        for(int j=x;j<=x+width;j++){
            vram[i*SCREEN_WIDTH+j] = colIndex;
        }
    }
}


void drawBackground(){
	fillRect(0,0,SCREEN_WIDTH-1,SCREEN_HEIGHT-29, COL8_008484);
    fillRect(0,SCREEN_HEIGHT-28,SCREEN_WIDTH-1,28, COL8_848484);


	fillRect(0,SCREEN_HEIGHT-27,SCREEN_WIDTH,1, COL8_848484);
	fillRect(0,SCREEN_HEIGHT-26,SCREEN_WIDTH,25, COL8_C6C6C6);
	
	fillRect(3,SCREEN_HEIGHT-24,56,1, COL8_FFFFFF);
	fillRect(2,SCREEN_HEIGHT-24,1,20, COL8_FFFFFF);

	fillRect(3,SCREEN_HEIGHT-4,56,1, COL8_848484);
	fillRect(59,SCREEN_HEIGHT-23,1,19, COL8_848484);

	fillRect(2,SCREEN_HEIGHT-3,57,0, COL8_000000);
	fillRect(60,SCREEN_HEIGHT-24,0,19, COL8_000000);

	fillRect(SCREEN_WIDTH-47,SCREEN_HEIGHT-24,43,1, COL8_848484);
	fillRect(SCREEN_WIDTH-47,SCREEN_HEIGHT-23,0,19, COL8_848484);

	fillRect(SCREEN_WIDTH-47,SCREEN_HEIGHT-3,43,0, COL8_FFFFFF);
	fillRect(SCREEN_WIDTH-3,SCREEN_HEIGHT-24,0,21, COL8_FFFFFF);
}


void putChar(char *addr,int x,int y,char col,unsigned char *pch,int screenWidth){
	
	for(int i=0;i<16;i++){
		char ch = pch[i];
		int off = (y+i)*screenWidth;
		
		//顯示的字形最左邊的是低地址,右側的是高地址。例如:0x80,則高地址部分顯示在記憶體的低地址,
		//最低位的應該偏移7
		if((ch & 0x01) != 0){
			addr[off+x+7] = col;
		}
		if((ch & 0x02) != 0){
			addr[off+x+6] = col;
		}
		if((ch & 0x04) != 0){
			addr[off+x+5] = col;
		}
		if((ch & 0x08) != 0){
			addr[off+x+4] = col;
		}	
		if((ch & 0x10) != 0){
			addr[off+x+3] = col;
		}
		if((ch & 0x20) != 0){
			addr[off+x+2] = col;
		}
		if((ch & 0x40) != 0){
			addr[off+x+1] = col;
		}	
		if((ch & 0x80) != 0){
			addr[off+x+0] = col;
		}
	}
}


void init_mouse_cursor(char *vram,int x,int y,char bc){
	//16*16 Mouse 
    //滑鼠指標點陣
	static char cursor[16][16] = {
	 "*...............",
	 "**..............",
	 "*O*.............",
	 "*OO*............",
	 "*OOO*...........",
	 "*OOOO*..........",
	 "*OOOOO*.........",
	 "*OOOOOO*........",
	 "*OOOOOOO*.......",
	 "*OOOO*****......",
	 "*OO*O*..........",
	 "*O*.*O*.........",
	 "**..*O*.........",
	 "*....*O*........",
	 ".....*O*........",
	 "......*........."
	};
	
	for (int i = 0; i < 16; i++) {
		for (int j = 0; j < 16; j++) {
			int off = (i+y)*SCREEN_WIDTH+x+j;
			if (cursor[i][j] == '*') {
				vram[off] = COL8_000000;
			}
			if (cursor[i][j] == 'O') {
				vram[off] = COL8_FFFFFF;
			}
			if (cursor[i][j] == '.') {
				vram[off] = bc;
			}
		}
	}

}

載入該虛擬軟盤檔案效果如下:
在這裡插入圖片描述

注意

1.核心程式碼不斷增多,在製作虛擬軟盤過程中注意讀取的扇區數是否操過核心啟動器讀取的扇區數量;