《30天自制操作系统》第五天

首先就是对前一天程序的一些优化,引入了结构体:

void io_hlt(void);
void io_cli(void);
void io_out8(int port, int data);
int io_load_eflags(void);
void io_store_eflags(int eflags);

void init_palette(void);
void set_palette(int start, int end, unsigned char *rgb);
void boxfill8(unsigned char *vram, int xsize, unsigned char c, int x0, int y0, int x1, int y1);
void init_screen(char *vram, int x, int y);

#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

struct BOOTINFO {
    char cyls, leds, vmode, reserve;
    short scrnx, scrny;
    char *vram;
};

void HariMain(void)
{
    char *vram;
    int xsize, ysize;
    struct BOOTINFO *binfo;

    init_palette();
    binfo = (struct BOOTINFO *) 0x0ff0;
    xsize = (*binfo).scrnx;
    ysize = (*binfo).scrny;
    vram = (*binfo).vram;

    init_screen(vram, xsize, ysize);

    for (;;) {
        io_hlt();
    }
}

void init_palette(void)
{
    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:暗い灰色 */
    };
    set_palette(0, 15, table_rgb);
    return;

    /* static char 命令は、データにしか使えないけどDB命令相当 */
}

void set_palette(int start, int end, unsigned char *rgb)
{
    int i, eflags;
    eflags = io_load_eflags();    /* 割り込み許可フラグの値を記録する */
    io_cli();                     /* 許可フラグを0にして割り込み禁止にする */
    io_out8(0x03c8, start);
    for (i = start; i <= end; i++) {
        io_out8(0x03c9, rgb[0] / 4);
        io_out8(0x03c9, rgb[1] / 4);
        io_out8(0x03c9, rgb[2] / 4);
        rgb += 3;
    }
    io_store_eflags(eflags);    /* 割り込み許可フラグを元に戻す */
    return;
}

void boxfill8(unsigned char *vram, int xsize, unsigned char c, int x0, int y0, int x1, int y1)
{
    int x, y;
    for (y = y0; y <= y1; y++) {
        for (x = x0; x <= x1; x++)
            vram[y * xsize + x] = c;
    }
    return;
}

void init_screen(char *vram, int x, int y)
{
    boxfill8(vram, x, COL8_008484,  0,     0,      x -  1, y - 29);
    boxfill8(vram, x, COL8_C6C6C6,  0,     y - 28, x -  1, y - 28);
    boxfill8(vram, x, COL8_FFFFFF,  0,     y - 27, x -  1, y - 27);
    boxfill8(vram, x, COL8_C6C6C6,  0,     y - 26, x -  1, y -  1);

    boxfill8(vram, x, COL8_FFFFFF,  3,     y - 24, 59,     y - 24);
    boxfill8(vram, x, COL8_FFFFFF,  2,     y - 24,  2,     y -  4);
    boxfill8(vram, x, COL8_848484,  3,     y -  4, 59,     y -  4);
    boxfill8(vram, x, COL8_848484, 59,     y - 23, 59,     y -  5);
    boxfill8(vram, x, COL8_000000,  2,     y -  3, 59,     y -  3);
    boxfill8(vram, x, COL8_000000, 60,     y - 24, 60,     y -  3);

    boxfill8(vram, x, COL8_848484, x - 47, y - 24, x -  4, y - 24);
    boxfill8(vram, x, COL8_848484, x - 47, y - 23, x - 47, y -  4);
    boxfill8(vram, x, COL8_FFFFFF, x - 47, y -  3, x -  4, y -  3);
    boxfill8(vram, x, COL8_FFFFFF, x -  3, y - 24, x -  3, y -  3);
    return;
}

这里面用到的结构体BOOTINFO其实只是一个存储单元。

binfo = (struct BOOTINFO *) 0x0ff0;这句获取0x0ff0开始一连串值。

作用相当于binfo_scrnx = (short *)0xff4;等几句。

另外,作为参数时,可以不用传入那么多参数。

之后就是,字符显示:

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

这段代码显示字符A,具体原理就是用for语句将8个像素的程序循环16遍。需要在HariMain里,

初始化

static char font_A[16] = {

0x00, 0x18, 0x18, 0x18, 0x18, 0x24, 0x24, 0x24,

0x24, 0x7e, 0x42, 0x42, 0x42, 0xe7, 0x00, 0x00

};

作为参数。

一个A就出现这么多代码,肯定不行。所以作者引入了OSASK字体。加入hankaku.txt文件。另需编译器makefont.exe将之编译为hankaku.bin文件。

void HariMain(void)
{
    struct BOOTINFO *binfo = (struct BOOTINFO *) 0x0ff0;
    static char font_A[16] = {
        0x00, 0x18, 0x18, 0x18, 0x18, 0x24, 0x24, 0x24,
        0x24, 0x7e, 0x42, 0x42, 0x42, 0xe7, 0x00, 0x00
    };

    init_palette();
    init_screen(binfo->vram, binfo->scrnx, binfo->scrny);
    putfont8(binfo->vram, binfo->scrnx, 10, 10, COL8_FFFFFF, font_A);

    for (;;) {
        io_hlt();
    }
}
时间: 2024-08-06 07:02:11

《30天自制操作系统》第五天的相关文章

聚焦新相亲时代:女孩在京有五六套房哭着想嫁富2代

2017-09-20 07:31:00 来源: 中国青年报(北京)        举报 6984 分享到: 易信 微信 QQ空间 微博 更多 用微信扫码二维码 分享至好友和朋友圈 T + - (原标题:中青报聚焦新相亲时代:2亿人及其背后家庭组成的"擂台") 石家庄某相亲角.视觉中国 资料 平均算下来,每一分钟里,国内有22对新人拿着户口本走向民政局,进入婚姻生活:同时,8对夫妻在另外一个窗口签下离婚协议. 根据民政部公布的数字,中国的结婚率和离婚率曲线渐渐逼近一个闭合的大于号.婚姻的

今年黑科技趋势最具的五个看点

CES 2017年人工智能引爆全球最火黑科技盛会 CES 2017 1月5日-8日在美国拉斯维加斯举行,数千家企业.几十万人将参与到这次科技的狂欢秀中.本文为埃森哲技术总监带来的关于本年度CES 的5大看点.他认为:人工智能将统治本年度的CES,变得无处不在.另外,他还分析了智能助理.物联网安全.虚拟现实等多个领域在本届大会上的表现. 2017 年国际消费电子展(CES 2017)将于1月5号拉开帷幕,在这个荒漠之城举办为期5天的展会,保守估计会吸引超过177000名参会者. 这也是一年之中唯一

(十五)PL/SQL事务

数据库事务是一个工作的原子单元,其可以由一个或多个相关的SQL语句组成.所谓的原子性就是数据库的修改所带来的构成事务的SQL语句可以集体被提交,即永久到数据库或从数据库中(撤消)回滚.一个成功执行的SQL语句和提交的事务不一样.即使一个SQL语句执行成功,除非包含该语句的事务被提交,但也可以回滚和声明(S)的所有更改可以撤消. 一.开始事务事务都有开始和结束.事务开始时有下列事件之一:  连接到数据库后执行的第一个SQL语句.  在事务完成之后发出每一个新的SQL语句完成. 二.提交事务事务是通

每周进度条(第十五周)

第十五周进度条   第十五周 所花时间 1h 代码量(行)  100 博客量(篇)  1 学到的知识 对图片的处理 在Android程序中加入图片

201405644 嵌入式程序设计第五周学习总结

嵌入式课程设计第五周学习总结 标准 I/O 编程 标准 I/O 提供流缓冲的目的是尽可能减少使用 read()和 write()等系统调用的数量.标准 I/O 提供了 3 种类型 的缓冲存储.全缓冲.行缓冲.不带缓冲. 打开文件 打开文件有三个标准函数,分别为:fopen().fdopen()和 freopen().其中 fopen()可以指定打开文件的路径和模式,fdopen()可以指定打开的文件描述符和模式,而 freopen() 除可指定打开的文件.模式外,还可指定特定的 I/O 流. f

第五次作业+164+张增进

开发人员代码:http://www.cnblogs.com/wangkunhuang/p/6794401.html 1)被测项目界面. 2)测试用例设计表 等价类 输入条件 有效等价类 编号 无效等价类 编号 年 1912≤year≤2050 ① year<1912 ② Year>2050 ③ 非数字 月 Month= 1,3,5,7,8,10,12 ④ Month<1 ⑤ Month= 4,6,9,11 month>12 ⑥ Month= 2 非数字 日 1≤ day ≤31 ⑦

五分钟上手Git

团队开发中.遵循一个合理.清晰的Git使用流程.是非常重要的.否则,每一个人都提交一堆杂乱无章的commit,项目非常快就会变得难以协调和维护.以下是ThoughtBot 的Git使用规范流程.我从中学到了非常多,推荐你也这样使用Git. 第一步:新建分支 首先,每次开发新功能,都应该新建一个单独的分支(这方面能够參考<Git分支管理策略>). # 获取主干最新代码 $ git checkout master $ git pull # 新建一个开发分支myfeature $ git check

linux中五笔的安装

下载五笔安装包 链接: http://pan.baidu.com/s/1geAtlab 密码: 5z8z 进入解压的路径使用下面命令将文件拷贝到指定目录 cp vissible.db /usr/share/ibus-table/tables             cp vissible.gif /usr/share/ibus-table/icon 重启计算机 在区域与语言中选择Chinese再选择Chinese(vissible)

“黑五”的本土化难题,如何定位、立足?

黑五,或者黑色星期五,对大部分中国人来说都会觉得很陌生,但这个在欧美如同双十一的购物节日已经开始被一部分中国消费者所接受并且积极的进行消费购物.虽然在国内黑五还无法与双十一相提并论,但随着跨境电商的兴起,黑五的本土化氛围正越来越浓. "黑五"关注度持续升温 从特定人群向多元化.年轻化转变 从市场层面的变化来看,这两年跨境电商的持续发展为黑五提供了基本的市场促销环境,虽然国内的黑五发展程度尚不足以与双十一相提并论,但对跨境电商企业而言,这几年已经逐渐向市场传达到了"黑五&quo

QCustomplot使用分享(五) 布局

一.历史对比 关于QCPLayoutElement这个元素的讲解之前,我想先对1.3.2release版本和2.0.0beta版本的该元素做以简单的对比介绍,首先,1.3.2release版本时,鼠标单击时,如果按下的位置是一个布局元素,那么QCustomPlot首先会把这个事件回调给该被点击的元素,并且mouse系列的方法都是这样传递给QCPLayoutElement对象,该布局元素的声明会像这样QPointer<QCPLayoutElement> mMouseEventElement:但是