最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

今亮点!0x07_自制操作系统My-OS实现键盘输出字符到屏幕

来源:博客园

接上一课class04,这是他的运行结果

收到了键盘的中断,现在想的当然是怎么把输入的文字显示到屏幕上,做成一个最简单的IO


(资料图)

这是class04的目录结构,现在我们把他换成class05

我们现在要读取键盘的数据,然后显示在屏幕上面

interrupt.c

#include "include/head.h"void inthandler21(int *esp)/* 来自PS/2键盘的中断 */{    unsigned char data,s[256];    io_set8(PIC0_OCW2, 0x61); /* 通知PIC,说IRQ-01的受理已经完成 */    data = io_get8(PORT_KEYDAT);    struct BOOTINFO *binfo = (struct BOOTINFO *) ADR_BOOTINFO;    boxfill8(binfo->vram, binfo->scrnx, 0,0,0,binfo->scrnx, binfo->scrny);    sprintf(s, "key = %d", data);    putfonts8_asc(binfo->vram, binfo->scrnx, 8, 8, 7, s);    return;}

直接修改中断函数里面的代码即可,主要就是获取data然后输出

head.h

/*interrupt.c*/#define PORT_KEYDAT 0x0060

这个是数据的地址,你要修改一下head.h,刚刚的那个函数要用的

运行:

cd class05..\z_tools\make.exe run

如果你发现你的键盘按一下就没用了可能是现在的键盘有点新,你可以把大写锁定打开,如果你不想这么麻烦,你可以自己买老键盘,最好2010之前的也可以买罗技k120这个型号的我就是这个试着没问题

还有我把main.c的输出那几句删了避免显示重叠

今天还没完呢,我还得讲一下fifo,first in first out,这个东西是用来缓存数据的,我刚刚给你们的键盘输入是不是还行,但是这个有个问题就是你按键盘的时候pic完全为键盘+屏幕输出服务,比如你用pic搞计时器,计时器会受影响,屏幕输出要花时间的pic等不起,或许你看不出来但是这对pic影响很大,所以我们要先把数据保存下来然后慢慢的输出,这时候pic就只负责保存数据到内存,不要显示。

fifo.c

#include "include/head.h"void fifo8_init(struct FIFO8 *fifo, int size, unsigned char *buf){    fifo->size = size;    fifo->buf = buf;    fifo->free = size;    fifo->flags = 0;    fifo->p = 0;     fifo->q = 0;    return;}int fifo8_put(struct FIFO8 *fifo, unsigned char data){    if (fifo->free == 0) {        fifo->flags |= FLAGS_OVERRUN;        return -1;    }    fifo->buf[fifo->p] = data;    fifo->p++;    if (fifo->p == fifo->size) {        fifo->p = 0;    }    fifo->free--;    return 0;}int fifo8_get(struct FIFO8 *fifo){    int data;    if (fifo->free == fifo->size) {        return -1;    }    data = fifo->buf[fifo->q];    fifo->q++;    if (fifo->q == fifo->size) {        fifo->q = 0;    }    fifo->free++;    return data;}int fifo8_status(struct FIFO8 *fifo){    return fifo->size - fifo->free;}

代码给你们直接用就是,我解释也解释不清,我乃cv工程师不需要知道原理

/*fifo.c*/struct FIFO8 {    unsigned char *buf;    int p, q, size, free, flags;};#define FLAGS_OVERRUN    0x0001void fifo8_init(struct FIFO8 *fifo, int size, unsigned char *buf);int fifo8_put(struct FIFO8 *fifo, unsigned char data);int fifo8_get(struct FIFO8 *fifo);int fifo8_status(struct FIFO8 *fifo);

这个添加到head.h里面去都是fifo要用的

/*naskfunc.asm*/void io_stihlt();void io_hlt(void);void io_cli(void);void io_sti(void);int io_get8(int port);void io_set8(int port, int data);void write_mem8(int addr, int data);int io_load_eflags(void);void io_store_eflags(int eflags);void load_gdtr(int limit, int addr);void load_idtr(int limit, int addr);void asm_inthandler21(void);/* asmhead.nas */struct BOOTINFO { /* 0x0ff0-0x0fff */    char cyls; /* 启动区读磁盘读到此为止 */    char leds; /* 启动时键盘的LED的状态 */    char vmode; /* 显卡模式为多少位彩色 */    char reserve;    short scrnx, scrny; /* 画面分辨率 */    char *vram;};#define ADR_BOOTINFO 0x00000ff0/*graphic.c*/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 putfont8(char *vram, int xsize, int x, int y, char c, char *font);void putfonts8_asc(char *vram, int xsize, int x, int y, char c, unsigned char *s);/*font*/extern char font[4096];/* dsctbl.c */struct SEGMENT_DESCRIPTOR {    short limit_low, base_low;    char base_mid, access_right;    char limit_high, base_high;};struct GATE_DESCRIPTOR {    short offset_low, selector;    char dw_count, access_right;    short offset_high;};void init_gdtidt(void);void set_segmdesc(struct SEGMENT_DESCRIPTOR *sd, unsigned int limit, int base, int ar);void set_gatedesc(struct GATE_DESCRIPTOR *gd, int offset, int selector, int ar);#define ADR_IDT            0x0026f800#define LIMIT_IDT        0x000007ff#define ADR_GDT            0x00270000#define LIMIT_GDT        0x0000ffff#define ADR_BOTPAK        0x00280000#define LIMIT_BOTPAK    0x0007ffff#define AR_DATA32_RW    0x4092#define AR_CODE32_ER    0x409a#define AR_INTGATE32    0x008e/* pic.c */void init_pic(void);#define PIC0_ICW1        0x0020#define PIC0_OCW2        0x0020#define PIC0_IMR        0x0021#define PIC0_ICW2        0x0021#define PIC0_ICW3        0x0021#define PIC0_ICW4        0x0021#define PIC1_ICW1        0x00a0#define PIC1_OCW2        0x00a0#define PIC1_IMR        0x00a1#define PIC1_ICW2        0x00a1#define PIC1_ICW3        0x00a1#define PIC1_ICW4        0x00a1/*interrupt.c*/#define PORT_KEYDAT 0x0060void inthandler21(int *esp);/*fifo.c*/struct FIFO8 {    unsigned char *buf;    int p, q, size, free, flags;};#define FLAGS_OVERRUN    0x0001void fifo8_init(struct FIFO8 *fifo, int size, unsigned char *buf);int fifo8_put(struct FIFO8 *fifo, unsigned char data);int fifo8_get(struct FIFO8 *fifo);int fifo8_status(struct FIFO8 *fifo);

加粗你懂吧,都是新加的,上面单独这句也要,之前说了,是键盘接收数据的地址

修改interrupt.c

#include "include/head.h"struct FIFO8 keyfifo;void inthandler21(int *esp)/* 来自PS/2键盘的中断 */{    unsigned char data;    io_set8(PIC0_OCW2, 0x61); /* 通知PIC,说IRQ-01的受理已经完成 */    data = io_get8(PORT_KEYDAT);    fifo8_put(&keyfifo, data);    return;}

就是保存数据了,fifo还要初始化,我们在main里面初始化,在main的死循环里面读取

main.c

#include "include/head.h"#include struct BOOTINFO *binfo = (struct BOOTINFO *) ADR_BOOTINFO;extern struct FIFO8 keyfifo;void Main(void){    int i;char s[256];    char keybuf[256];init_gdtidt();    init_pic();    io_sti();    fifo8_init(&keyfifo, 32, keybuf);init_palette();    io_set8(PIC0_IMR, 0xf9); /* 开放PIC1和键盘中断(11111001) */    for (;;) {        io_hlt();        if (fifo8_status(&keyfifo)== 0) {            io_stihlt();        } else {            int i = fifo8_get(&keyfifo);            io_sti();                if(i<129)            {                boxfill8(binfo->vram, binfo->scrnx, 0,0,0,binfo->scrnx, binfo->scrny);                sprintf(s, "key = %d", i);                putfonts8_asc(binfo->vram, binfo->scrnx, 8, 8, 7, s);            }else{                boxfill8(binfo->vram, binfo->scrnx, 0,0,0,binfo->scrnx, binfo->scrny);                sprintf(s, "key = -");                putfonts8_asc(binfo->vram, binfo->scrnx, 8, 8, 7, s);            }                    }}}

加粗懂我意思吧,最后修改Makefile就可以编译运行了

运行:

cd class05..\z_tools\make.exe run
自制操作系统合集原文地址:https://www.cnblogs.com/Frank-dev-blog/category/2249116.html项目github地址rick521/My-OS (github.com)给我点颗star

关键词: 操作系统 这个型号 这么麻烦