30天自制操作系统第10天harib07d
第10天 叠加处理
提高叠加处理速度(2)
harib07d
准备材料(windows环境)
- VMware Workstation
- Visual Studio Code
- 程序和源代码:https://pan.baidu.com/s/1bFGAYgnA0m9KB7tzFrMD5g
提取码:d210 - Makefile
- windows 批处理
开始实验
在tolset文件夹下创建子文件侠harib07d。
打开记事本,输入以下代码并另存为 !cons_nt.bat文件(windows 批处理),存放在harib07d文件夹中。
cmd.exe
ps:当然也可以直接使用 win + r 快捷键也可以,不过最好还是创建一个比较好。因为以后打开时不需要再麻烦了。
3. 打开vc code,输入以下代码并保存为 naskfunc.nas,存放在harib07d文件夹中。
; naskfunc
; TAB=4[FORMAT "WCOFF"] ; 制作目标文件的模式
[INSTRSET "i486p"] ; 要使用486指令的语句
[BITS 32] ; 制作32位模式用的机器语言
[FILE "naskfunc.nas"] ; 原文件名信息GLOBAL _io_hlt, _io_cli, _io_sti, _io_stihltGLOBAL _io_in8, _io_in16, _io_in32GLOBAL _io_out8, _io_out16, _io_out32GLOBAL _io_load_eflags, _io_store_eflagsGLOBAL _load_gdtr, _load_idtrGLOBAL _load_cr0, _store_cr0GLOBAL _asm_inthandler21, _asm_inthandler27, _asm_inthandler2cGLOBAL _memtest_subEXTERN _inthandler21, _inthandler27, _inthandler2c[SECTION .text] _io_hlt: ; void io_hlt(void);HLTRET_io_cli: ; void io_cli(void);CLIRET_io_sti: ; void io_sti(void);STIRET_io_stihlt: ; void io_stihlt(void);STIHLTRET_io_in8: ; int io_in8(int port);MOV EDX,[ESP+4] ; portMOV EAX,0IN AL,DXRET_io_in16: ; int io_in16(int port);MOV EDX,[ESP+4] ; portMOV EAX,0IN AX,DXRET_io_in32: ; int io_in32(int port);MOV EDX,[ESP+4] ; portIN EAX,DXRET_io_out8: ; void io_out8(int port, int data);MOV EDX,[ESP+4] ; portMOV AL,[ESP+8] ; dataOUT DX,ALRET_io_out16: ; void io_out16(int port, int data);MOV EDX,[ESP+4] ; portMOV EAX,[ESP+8] ; dataOUT DX,AXRET_io_out32: ; void io_out32(int port, int data);MOV EDX,[ESP+4] ; portMOV EAX,[ESP+8] ; dataOUT DX,EAXRET_io_load_eflags: ; int io_load_eflags(void);PUSHFD ; 指 PUSH EFLAGSPOP EAXRET_io_store_eflags: ; void io_store_eflags(int eflags);MOV EAX,[ESP+4]PUSH EAXPOPFD ; 指 POP EFLAGSRET_load_gdtr: ; void load_gdtr(int limit, int addr);MOV AX,[ESP+4] ; limitMOV [ESP+6],AXLGDT [ESP+6]RET_load_idtr: ; void load_idtr(int limit, int addr);MOV AX,[ESP+4] ; limitMOV [ESP+6],AXLIDT [ESP+6]RET_load_cr0: ; int load_cr0(void);MOV EAX,CR0RET_store_cr0: ; void store_cr0(int cr0);MOV EAX,[ESP+4]MOV CR0,EAXRET_asm_inthandler21:PUSH ESPUSH DSPUSHADMOV EAX,ESPPUSH EAXMOV AX,SSMOV DS,AXMOV ES,AXCALL _inthandler21POP EAXPOPADPOP DSPOP ESIRETD_asm_inthandler27:PUSH ESPUSH DSPUSHADMOV EAX,ESPPUSH EAXMOV AX,SSMOV DS,AXMOV ES,AXCALL _inthandler27POP EAXPOPADPOP DSPOP ESIRETD_asm_inthandler2c:PUSH ESPUSH DSPUSHADMOV EAX,ESPPUSH EAXMOV AX,SSMOV DS,AXMOV ES,AXCALL _inthandler2cPOP EAXPOPADPOP DSPOP ESIRETD_memtest_sub: ; unsigned int memtest_sub(unsigned int start, unsigned int end)PUSH EDI ; (由于还要使用EBX, ESI, EDI)PUSH ESIPUSH EBXMOV ESI,0xaa55aa55 ; pat0 = 0xaa55aa55;MOV EDI,0x55aa55aa ; pat1 = 0x55aa55aa;MOV EAX,[ESP+12+4] ; i = start;
mts_loop:MOV EBX,EAXADD EBX,0xffc ; p = i + 0xffc;MOV EDX,[EBX] ; old = *p;MOV [EBX],ESI ; *p = pat0;XOR DWORD [EBX],0xffffffff ; *p ^= 0xffffffff;CMP EDI,[EBX] ; if (*p != pat1) goto fin;JNE mts_finXOR DWORD [EBX],0xffffffff ; *p ^= 0xffffffff;CMP ESI,[EBX] ; if (*p != pat0) goto fin;JNE mts_finMOV [EBX],EDX ; *p = old;ADD EAX,0x1000 ; i += 0x1000;CMP EAX,[ESP+12+8] ; if (i <= end) goto mts_loop;JBE mts_loopPOP EBXPOP ESIPOP EDIRET
mts_fin:MOV [EBX],EDX ; *p = old;POP EBXPOP ESIPOP EDIRET
- 打开vc code,输入以下代码并保存为 bootpack.c 存放在harib07d文件夹中。
/* bootpack 其他处理 */#include "bootpack.h"
#include <stdio.h>void HariMain(void)
{struct BOOTINFO *binfo = (struct BOOTINFO *) ADR_BOOTINFO;char s[40], keybuf[32], mousebuf[128];int mx, my, i;unsigned int memtotal;struct MOUSE_DEC mdec;struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR;struct SHTCTL *shtctl;struct SHEET *sht_back, *sht_mouse;unsigned char *buf_back, buf_mouse[256]; init_gdtidt();init_pic();io_sti(); /* 由于IDT / PIC的初始化已完成,因此请禁用CPU的中断。 */fifo8_init(&keyfifo, 32, keybuf);fifo8_init(&mousefifo, 128, mousebuf);io_out8(PIC0_IMR, 0xf9); /* 允许PIC1和键盘(11111001) */io_out8(PIC1_IMR, 0xef); /* 允许鼠标(11101111) */init_keyboard();enable_mouse(&mdec);memtotal = memtest(0x00400000, 0xbfffffff);memman_init(memman);memman_free(memman, 0x00001000, 0x0009e000); /* 0x00001000 - 0x0009efff */memman_free(memman, 0x00400000, memtotal - 0x00400000);init_palette();shtctl = shtctl_init(memman, binfo->vram, binfo->scrnx, binfo->scrny);sht_back = sheet_alloc(shtctl);sht_mouse = sheet_alloc(shtctl);buf_back = (unsigned char *) memman_alloc_4k(memman, binfo->scrnx * binfo->scrny);sheet_setbuf(sht_back, buf_back, binfo->scrnx, binfo->scrny, -1); /* 没有透明色 */sheet_setbuf(sht_mouse, buf_mouse, 16, 16, 99); /* 透明色号99 */init_screen8(buf_back, binfo->scrnx, binfo->scrny);init_mouse_cursor8(buf_mouse, 99); /* 背景色号99 */sheet_slide(shtctl, sht_back, 0, 0); mx = (binfo->scrnx - 16) / 2; /* 按显示在画面中央来计算坐标 */my = (binfo->scrny - 28 - 16) / 2;sheet_slide(shtctl, sht_mouse, mx, my);sheet_updown(shtctl, sht_back, 0);sheet_updown(shtctl, sht_mouse, 1);sprintf(s, "(%3d, %3d)", mx, my);putfonts8_asc(buf_back, binfo->scrnx, 0, 0, COL8_FFFFFF, s);sprintf(s, "memory %dMB free : %dKB",memtotal / (1024 * 1024), memman_total(memman) / 1024);putfonts8_asc(buf_back, binfo->scrnx, 0, 32, COL8_FFFFFF, s);sheet_refresh(shtctl, sht_back, 0, 0, binfo->scrnx, 48); /* 这里! */for (;;) {io_cli();if (fifo8_status(&keyfifo) + fifo8_status(&mousefifo) == 0) {io_stihlt();} else {if (fifo8_status(&keyfifo) != 0) {i = fifo8_get(&keyfifo);io_sti();sprintf(s, "%02X", i);boxfill8(buf_back, binfo->scrnx, COL8_008484, 0, 16, 15, 31);putfonts8_asc(buf_back, binfo->scrnx, 0, 16, COL8_FFFFFF, s);sheet_refresh(shtctl, sht_back, 0, 16, 16, 32);} else if (fifo8_status(&mousefifo) != 0) {i = fifo8_get(&mousefifo);io_sti();if (mouse_decode(&mdec, i) != 0) {/* 因为已得到3字节的数据所以显示 */sprintf(s, "[lcr %4d %4d]", mdec.x, mdec.y);if ((mdec.btn & 0x01) != 0) {s[1] = 'L';}if ((mdec.btn & 0x02) != 0) {s[3] = 'R';}if ((mdec.btn & 0x04) != 0) {s[2] = 'C';}boxfill8(buf_back, binfo->scrnx, COL8_008484, 32, 16, 32 + 15 * 8 - 1, 31);putfonts8_asc(buf_back, binfo->scrnx, 32, 16, COL8_FFFFFF, s);sheet_refresh(shtctl, sht_back, 32, 16, 32 + 15 * 8, 32); /* 这里! *//* 移动光标 */mx += mdec.x;my += mdec.y;if (mx < 0) {mx = 0;}if (my < 0) {my = 0;}if (mx > binfo->scrnx - 16) {mx = binfo->scrnx - 16;}if (my > binfo->scrny - 16) {my = binfo->scrny - 16;}sprintf(s, "(%3d, %3d)", mx, my);boxfill8(buf_back, binfo->scrnx, COL8_008484, 0, 0, 79, 15); /* 消去坐标 */putfonts8_asc(buf_back, binfo->scrnx, 0, 0, COL8_FFFFFF, s); /* 写出坐标 */sheet_refresh(shtctl, sht_back, 0, 0, 80, 16); /* 这里! */sheet_slide(shtctl, sht_mouse, mx, my);}}}}
}
- 打开vc code,输入以下代码并保存为 bootpack.h 存放在harib07d文件夹中。
/* asmhead.nas */
struct BOOTINFO { /* 0xff0-0x0fff */char cyls; /* 启动区读硬盘读到何处为止 */char leds; /* 启动时键盘LED的状态 */char vmode; /* 显卡模式为多少位彩色 */char reserve;short scrnx, scrny; /* 画面分辨率 */char *vram;
};
#define ADR_BOOTINFO 0x00000ff0/* naskfunc.nas */
void io_hlt(void);
void io_cli(void);
void io_sti(void);
void io_stihlt(void);
int io_in8(int port);
void io_out8(int port, 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);
int load_cr0(void);
void store_cr0(int cr0);
void asm_inthandler21(void);
void asm_inthandler27(void);
void asm_inthandler2c(void);
unsigned int memtest_sub(unsigned int start, unsigned int end);/* fifo.c */
struct FIFO8 {unsigned char *buf;int p, q, size, free, flags;
};
void 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);/* 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 init_screen8(char *vram, int x, int y);
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);
void init_mouse_cursor8(char *mouse, char bc);
void putblock8_8(char *vram, int vxsize, int pxsize,int pysize, int px0, int py0, char *buf, int bxsize);
#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/* 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/* int.c */
void init_pic(void);
void inthandler27(int *esp);
#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/* keyboard.c */
void inthandler21(int *esp);
void wait_KBC_sendready(void);
void init_keyboard(void);
extern struct FIFO8 keyfifo;
#define PORT_KEYDAT 0x0060
#define PORT_KEYCMD 0x0064/* mouse.c */
struct MOUSE_DEC {unsigned char buf[3], phase;int x, y, btn;
};
void inthandler2c(int *esp);
void enable_mouse(struct MOUSE_DEC *mdec);
int mouse_decode(struct MOUSE_DEC *mdec, unsigned char dat);
extern struct FIFO8 mousefifo;/* memory.c */
#define MEMMAN_FREES 4090 /* 大约是32KB */
#define MEMMAN_ADDR 0x003c0000
struct FREEINFO { /* 可用信息 */unsigned int addr, size;
};
struct MEMMAN { /* 内存管理 */int frees, maxfrees, lostsize, losts;struct FREEINFO free[MEMMAN_FREES];
};
unsigned int memtest(unsigned int start, unsigned int end);
void memman_init(struct MEMMAN *man);
unsigned int memman_total(struct MEMMAN *man);
unsigned int memman_alloc(struct MEMMAN *man, unsigned int size);
int memman_free(struct MEMMAN *man, unsigned int addr, unsigned int size);
unsigned int memman_alloc_4k(struct MEMMAN *man, unsigned int size);
int memman_free_4k(struct MEMMAN *man, unsigned int addr, unsigned int size);/* sheet.c */
#define MAX_SHEETS 256
struct SHEET {unsigned char *buf;int bxsize, bysize, vx0, vy0, col_inv, height, flags;
};
struct SHTCTL {unsigned char *vram;int xsize, ysize, top;struct SHEET *sheets[MAX_SHEETS];struct SHEET sheets0[MAX_SHEETS];
};
struct SHTCTL *shtctl_init(struct MEMMAN *memman, unsigned char *vram, int xsize, int ysize);
struct SHEET *sheet_alloc(struct SHTCTL *ctl);
void sheet_setbuf(struct SHEET *sht, unsigned char *buf, int xsize, int ysize, int col_inv);
void sheet_updown(struct SHTCTL *ctl, struct SHEET *sht, int height);
void sheet_refresh(struct SHTCTL *ctl, struct SHEET *sht, int bx0, int by0, int bx1, int by1);
void sheet_slide(struct SHTCTL *ctl, struct SHEET *sht, int vx0, int vy0);
void sheet_free(struct SHTCTL *ctl, struct SHEET *sht);
- 打开vc code,输入以下代码并保存为 dsctbl.c 存放在harib07d文件夹中。
/* 关于GDT,IDT等descriptor table的处理 */#include "bootpack.h"void init_gdtidt(void)
{struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *) ADR_GDT;struct GATE_DESCRIPTOR *idt = (struct GATE_DESCRIPTOR *) ADR_IDT;int i;/* GDT的初始化 */for (i = 0; i <= LIMIT_GDT / 8; i++) {set_segmdesc(gdt + i, 0, 0, 0);}set_segmdesc(gdt + 1, 0xffffffff, 0x00000000, AR_DATA32_RW);set_segmdesc(gdt + 2, LIMIT_BOTPAK, ADR_BOTPAK, AR_CODE32_ER);load_gdtr(LIMIT_GDT, ADR_GDT);/* IDT的初始化 */for (i = 0; i <= LIMIT_IDT / 8; i++) {set_gatedesc(idt + i, 0, 0, 0);}load_idtr(LIMIT_IDT, ADR_IDT);/* IDT的设定 */set_gatedesc(idt + 0x21, (int) asm_inthandler21, 2 * 8, AR_INTGATE32);set_gatedesc(idt + 0x27, (int) asm_inthandler27, 2 * 8, AR_INTGATE32);set_gatedesc(idt + 0x2c, (int) asm_inthandler2c, 2 * 8, AR_INTGATE32);return;
}void set_segmdesc(struct SEGMENT_DESCRIPTOR *sd, unsigned int limit, int base, int ar)
{if (limit > 0xfffff) {ar |= 0x8000; /* G_bit = 1 */limit /= 0x1000;}sd->limit_low = limit & 0xffff;sd->base_low = base & 0xffff;sd->base_mid = (base >> 16) & 0xff;sd->access_right = ar & 0xff;sd->limit_high = ((limit >> 16) & 0x0f) | ((ar >> 8) & 0xf0);sd->base_high = (base >> 24) & 0xff;return;
}void set_gatedesc(struct GATE_DESCRIPTOR *gd, int offset, int selector, int ar)
{gd->offset_low = offset & 0xffff;gd->selector = selector;gd->dw_count = (ar >> 8) & 0xff;gd->access_right = ar & 0xff;gd->offset_high = (offset >> 16) & 0xffff;return;
}
ps: 。
7. 打vc code,输入以下代码并保存为 fifo.c,存放在harib07d文件夹中。
/* FIFO库 */#include "bootpack.h"#define FLAGS_OVERRUN 0x0001void fifo8_init(struct FIFO8 *fifo, int size, unsigned char *buf)
/* 初始化 FIFO 缓冲区 */
{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)
/* 向 FIFO 传送数据并保存 */
{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)
/* 从 FIFO 取得一个数据 */
{int data;if (fifo->free == fifo->size) {/* 如果缓冲区为空,则返回-1 */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;
}
- 打vc code,输入以下代码并保存为 graphic.c,存放在harib07d文件夹中。
/* u关于描画的处理 */#include "bootpack.h"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, 0x00, 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;/* C语言中的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_screen8(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;
}void putfont8(char *vram, int xsize, int x, int y, char c, char *font)
{int i;char *p, d; /* date */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;
}void putfonts8_asc(char *vram, int xsize, int x, int y, char c, unsigned char *s)
{extern char hankaku[4096];for (; *s != 0x00; s++) {putfont8(vram, xsize, x, y, c, hankaku + *s * 16);x += 8;}return;
}void init_mouse_cursor8(char *mouse, char bc)
/* 准备鼠标指标 (16 x 16) */
{static char cursor[16][16] = {"**************..","*OOOOOOOOOOO*...","*OOOOOOOOOO*....","*OOOOOOOOO*.....","*OOOOOOOO*......","*OOOOOOO*.......","*OOOOOOO*.......","*OOOOOOOO*......","*OOOO**OOO*.....","*OOO*..*OOO*....","*OO*....*OOO*...","*O*......*OOO*..","**........*OOO*.","*..........*OOO*","............*OO*",".............***"};int x, y;for (y = 0; y < 16; y++) {for (x = 0; x < 16; x++) {if (cursor[y][x] == '*') {mouse[y * 16 + x] = COL8_000000;}if (cursor[y][x] == 'O') {mouse[y * 16 + x] = COL8_FFFFFF;}if (cursor[y][x] == '.') {mouse[y * 16 + x] = bc;}}}return;
}void putblock8_8(char *vram, int vxsize, int pxsize,int pysize, int px0, int py0, char *buf, int bxsize)
{int x, y;for (y = 0; y < pysize; y++) {for (x = 0; x < pxsize; x++) {vram[(py0 + y) * vxsize + (px0 + x)] = buf[y * bxsize + x];}}return;
}
- 打vc code,输入以下代码并保存为 int.c,存放在harib07d文件夹中。
/* 与中断有关 */#include "bootpack.h"
#include <stdio.h>void init_pic(void)
/* PIC的初始化 */
{io_out8(PIC0_IMR, 0xff ); /* 禁止所有中断 */io_out8(PIC1_IMR, 0xff ); /* 禁止所有中断 */io_out8(PIC0_ICW1, 0x11 ); /* 边沿触发模式 (edge trigger mode) */io_out8(PIC0_ICW2, 0x20 ); /* IRQ0-7 由 INT20-27 接收 */io_out8(PIC0_ICW3, 1 << 2); /* PIC1 由 IRQ2 连接 */io_out8(PIC0_ICW4, 0x01 ); /* 无缓冲区模式 */io_out8(PIC1_ICW1, 0x11 ); /* 边沿触发模式 (edge trigger mode) */io_out8(PIC1_ICW2, 0x28 ); /* IRQ8-15 由 INT28-2f 接收 */io_out8(PIC1_ICW3, 2 ); /* PIC1 由 IRQ2 连接 */io_out8(PIC1_ICW4, 0x01 ); /* 无缓冲区域 */io_out8(PIC0_IMR, 0xfb ); /* 11111011 PIC1 以外全部禁止 */io_out8(PIC1_IMR, 0xff ); /* 11111111 禁止所有中断 */return;
}void inthandler27(int *esp)
/* 防止来自PIC0的不完整中断的措施 */
/* 在Athlon64X2机器等中,由于芯片组的便利性,该中断在PIC初始化时仅发生一次 */
/* 此中断处理功能不执行中断 */
/* 您为什么不做任何事情? */
/* 由于此中断是由PIC初始化期间的电气噪声产生的,*/
/* 您不需要认真做任何事情。 */
{io_out8(PIC0_OCW2, 0x67); /* 通知PIC IRQ-07已被接受(见7-1)*/return;
}
- 打vc code,输入以下代码并保存为 keyboard.c,存放在harib07d文件夹中。
/* 与键盘相关 */#include "bootpack.h"struct FIFO8 keyfifo;void inthandler21(int *esp)
{unsigned char data;io_out8(PIC0_OCW2, 0x61); /* 通知PIC“IRQ-01”已经受理完毕 */data = io_in8(PORT_KEYDAT);fifo8_put(&keyfifo, data);return;
}#define PORT_KEYSTA 0x0064
#define KEYSTA_SEND_NOTREADY 0x02
#define KEYCMD_WRITE_MODE 0x60
#define KBC_MODE 0x47void wait_KBC_sendready(void)
{/* 等待键盘控制电路准备完毕 */for (;;) {if ((io_in8(PORT_KEYSTA) & KEYSTA_SEND_NOTREADY) == 0) {break;}}return;
}void init_keyboard(void)
{/* 初始化键盘控制电路 */wait_KBC_sendready();io_out8(PORT_KEYCMD, KEYCMD_WRITE_MODE);wait_KBC_sendready();io_out8(PORT_KEYDAT, KBC_MODE);return;
}
- 打vc code,输入以下代码并保存为 memory.c,存放在harib07d文件夹中。
/* 内存管理 */#include "bootpack.h"#define EFLAGS_AC_BIT 0x00040000
#define CR0_CACHE_DISABLE 0x60000000unsigned int memtest(unsigned int start, unsigned int end)
{char flg486 = 0;unsigned int eflg, cr0, i;/* 确认CPU是386还是486以上的 */eflg = io_load_eflags();eflg |= EFLAGS_AC_BIT; /* AC-bit = 1 */io_store_eflags(eflg);eflg = io_load_eflags();if ((eflg & EFLAGS_AC_BIT) != 0) { /* 如果是386,即使设定AC=1,AC的值还会自动回到0 */flg486 = 1;}eflg &= ~EFLAGS_AC_BIT; /* AC-bit = 0 */io_store_eflags(eflg);if (flg486 != 0) {cr0 = load_cr0();cr0 |= CR0_CACHE_DISABLE; /* 禁止缓存 */store_cr0(cr0);}i = memtest_sub(start, end);if (flg486 != 0) {cr0 = load_cr0();cr0 &= ~CR0_CACHE_DISABLE; /* 允许缓存 */store_cr0(cr0);}return i;
}void memman_init(struct MEMMAN *man)
{man->frees = 0; /* 可用信息数目 */man->maxfrees = 0; /* 用于观察可用状况:frees的最大值 */man->lostsize = 0; /* 释放失败的内在的大小总和 */man->losts = 0; /* 释放失败次数 */return;
}unsigned int memman_total(struct MEMMAN *man)
/* 报告空余内存大小的命令 */
{unsigned int i, t = 0;for (i = 0; i < man->frees; i++) {t += man->free[i].size;}return t;
}unsigned int memman_alloc(struct MEMMAN *man, unsigned int size)
/* 分配 */
{unsigned int i, a;for (i = 0; i < man->frees; i++) {if (man->free[i].size >= size) {/* 找到了足够大的内存 */a = man->free[i].addr;man->free[i].addr += size;man->free[i].size -= size;if (man->free[i].size == 0) {/* 如果free[i]变成了0,就减掉一条可用信息 */man->frees--;for (; i < man->frees; i++) {man->free[i] = man->free[i + 1]; /* 代入结构体 */}} return a;}}return 0; /* 没有可用空间 */
}int memman_free(struct MEMMAN *man, unsigned int addr, unsigned int size)
/* 释放 */
{int i, j;/* 为便于归纳内存,将free[]放按照addr的顺序排列 *//* 所以,先决定应该放在哪里 */for (i = 0; i < man->frees; i++) {if (man->free[i].addr > addr) {break;}}/* free[i - 1].addr < addr < free[i].addr */if (i > 0) {/* 前面有可用内在 */if (man->free[i - 1].addr + man->free[i - 1].size == addr) {/* 可以与前面的可用内存归纳到一起 */man->free[i - 1].size += size;if (i < man->frees) {/* 后面也有 */if (addr + size == man->free[i].addr) {/* 也可以与后面的可用内存归纳到一起 */man->free[i - 1].size += man->free[i].size;/* man-free[i]删除 *//* free[i]变成0后归纳到前面去 */man->frees--;for (; i < man->frees; i++) {man->free[i] = man->free[i + 1]; /* 结构体赋值 */}}}return 0; /* 成功完成 */}}/* 不能与前面的可用空间归纳到一起 */if (i < man->frees) {/* 后面还有 */if (addr + size == man->free[i].addr) {/* 可以与后面的内容归纳到一起 */man->free[i].addr = addr;man->free[i].size += size;return 0; /* 成功完成 */}}/* 既不能与前面归纳到一起,也不能与后面归纳到一起 */if (man->frees < MEMMAN_FREES) {/* free[i]之后的,向后移动,腾出一点可用空间 */for (j = man->frees; j > i; j--) {man->free[j] = man->free[j - 1];}man->frees++;if (man->maxfrees < man->frees) {man->maxfrees = man->frees; /* 更新最大值 */}man->free[i].addr = addr;man->free[i].size = size;return 0; /* 成功完成 */}/* 不能往后移动 */man->losts++;man->lostsize += size;return -1; /* 失败 */
}unsigned int memman_alloc_4k(struct MEMMAN *man, unsigned int size)
{unsigned int a;size = (size + 0xfff) & 0xfffff000;a = memman_alloc(man, size);return a;
}int memman_free_4k(struct MEMMAN *man, unsigned int addr, unsigned int size)
{int i;size = (size + 0xfff) & 0xfffff000;i = memman_free(man, addr, size);return i;
}
- 打vc code,输入以下代码并保存为 mouse.c,存放在harib07d文件夹中。
/* 与鼠标相关 */#include "bootpack.h"struct FIFO8 mousefifo;void inthandler2c(int *esp)
/* 来自PS/2键盘的中断 */
{unsigned char data;io_out8(PIC1_OCW2, 0x64); /* 通知PIC1 IRQ-12的受理已经完成 */io_out8(PIC0_OCW2, 0x62); /* 通知PIC0 IRQ-02的受理已经完成 */data = io_in8(PORT_KEYDAT);fifo8_put(&mousefifo, data);return;
}#define KEYCMD_SENDTO_MOUSE 0xd4
#define MOUSECMD_ENABLE 0xf4void enable_mouse(struct MOUSE_DEC *mdec)
{/* 激活鼠标 */wait_KBC_sendready();io_out8(PORT_KEYCMD, KEYCMD_SENDTO_MOUSE);wait_KBC_sendready();io_out8(PORT_KEYDAT, MOUSECMD_ENABLE);/* 顺利的话,ACK(0xfa)会被传送过来 */mdec->phase = 0; /* 等待0xfa的阶段 */return;
}int mouse_decode(struct MOUSE_DEC *mdec, unsigned char dat)
{if (mdec->phase == 0) {/* 等待鼠标的0xfa的阶段 */if (dat == 0xfa) {mdec->phase = 1;}return 0;}if (mdec->phase == 1) {/* 等待鼠标第一字节的阶段 */if ((dat & 0xc8) == 0x08) {/* 如果第一字节正确 */mdec->buf[0] = dat;mdec->phase = 2;}return 0;}if (mdec->phase == 2) {/* 等待鼠标第二字节的阶段 */mdec->buf[1] = dat;mdec->phase = 3;return 0;}if (mdec->phase == 3) {/* 等待鼠标第三字节的阶段 */mdec->buf[2] = dat;mdec->phase = 1;mdec->btn = mdec->buf[0] & 0x07;mdec->x = mdec->buf[1];mdec->y = mdec->buf[2];if ((mdec->buf[0] & 0x10) != 0) {mdec->x |= 0xffffff00;}if ((mdec->buf[0] & 0x20) != 0) {mdec->y |= 0xffffff00;}mdec->y = - mdec->y; /* 鼠标y方向与画面符号相反 */return 1;}return -1; /* 应该不可能到这里来 */
}
- 打vc code,输入以下代码并保存为 sheet.c,存放在harib07d文件夹中。
/* 画面叠加处理 */#include "bootpack.h"#define SHEET_USE 1struct SHTCTL *shtctl_init(struct MEMMAN *memman, unsigned char *vram, int xsize, int ysize)
{struct SHTCTL *ctl;int i;ctl = (struct SHTCTL *) memman_alloc_4k(memman, sizeof (struct SHTCTL));if (ctl == 0) {goto err;}ctl->vram = vram;ctl->xsize = xsize;ctl->ysize = ysize;ctl->top = -1; /* 一个SHEET都没有 */for (i = 0; i < MAX_SHEETS; i++) {ctl->sheets0[i].flags = 0; /* 标记为未使用 */}
err:return ctl;
}struct SHEET *sheet_alloc(struct SHTCTL *ctl)
{struct SHEET *sht;int i;for (i = 0; i < MAX_SHEETS; i++) {if (ctl->sheets0[i].flags == 0) {sht = &ctl->sheets0[i];sht->flags = SHEET_USE; /* 标记为正在使用 */sht->height = -1; /* 隐藏 */return sht;}}return 0; /* 所有的SHEET都处于正在使用状态 */
}void sheet_setbuf(struct SHEET *sht, unsigned char *buf, int xsize, int ysize, int col_inv)
{sht->buf = buf;sht->bxsize = xsize;sht->bysize = ysize;sht->col_inv = col_inv;return;
}void sheet_refreshsub(struct SHTCTL *ctl, int vx0, int vy0, int vx1, int vy1)
{int h, bx, by, vx, vy, bx0, by0, bx1, by1;unsigned char *buf, c, *vram = ctl->vram;struct SHEET *sht;for (h = 0; h <= ctl->top; h++) {sht = ctl->sheets[h];buf = sht->buf;/* 使用vx0~vy1,对bx0~by1进行转换 */bx0 = vx0 - sht->vx0;by0 = vy0 - sht->vy0;bx1 = vx1 - sht->vx0;by1 = vy1 - sht->vy0;if (bx0 < 0) { bx0 = 0; }if (by0 < 0) { by0 = 0; }if (bx1 > sht->bxsize) { bx1 = sht->bxsize; }if (by1 > sht->bysize) { by1 = sht->bysize; }for (by = by0; by < by1; by++) {vy = sht->vy0 + by;for (bx = bx0; bx < bx1; bx++) {vx = sht->vx0 + bx;c = buf[by * sht->bxsize + bx];if (c != sht->col_inv) {vram[vy * ctl->xsize + vx] = c;}}}}return;
}void sheet_updown(struct SHTCTL *ctl, struct SHEET *sht, int height)
{int h, old = sht->height; /* 存储设置前的高度信息 *//* 如果指定的高度过高或过低,则进行修正 */if (height > ctl->top + 1) {height = ctl->top + 1;}if (height < -1) {height = -1;}sht->height = height; /* 设定高度 *//* 下面主要是进行sheets[]的重新排列 */if (old > height) { /* 比以前低 */if (height >= 0) {/* 把中间的往上提 */for (h = old; h > height; h--) {ctl->sheets[h] = ctl->sheets[h - 1];ctl->sheets[h]->height = h;}ctl->sheets[height] = sht;} else { /* 隐藏 */if (ctl->top > old) {/* 把上面的降下来 */for (h = old; h < ctl->top; h++) {ctl->sheets[h] = ctl->sheets[h + 1];ctl->sheets[h]->height = h;}}ctl->top--; /* 由于显示中的图层减少了一个,所以最上面的图层高度下降 */}sheet_refreshsub(ctl, sht->vx0, sht->vy0, sht->vx0 + sht->bxsize, sht->vy0 + sht->bysize);} else if (old < height) { /* 比以前高 */if (old >= 0) {/* 把中间的拉下来 */for (h = old; h < height; h++) {ctl->sheets[h] = ctl->sheets[h + 1];ctl->sheets[h]->height = h;}ctl->sheets[height] = sht;} else { /* 由隐藏状态转为显示状态 *//* 奖已在上面的提上来 */for (h = ctl->top; h >= height; h--) {ctl->sheets[h + 1] = ctl->sheets[h];ctl->sheets[h + 1]->height = h + 1;}ctl->sheets[height] = sht;ctl->top++; /* 由于已显示的图层增加了1个,所以最上面的图层高度增加 */}sheet_refreshsub(ctl, sht->vx0, sht->vy0, sht->vx0 + sht->bxsize, sht->vy0 + sht->bysize);}return;
}void sheet_refresh(struct SHTCTL *ctl, struct SHEET *sht, int bx0, int by0, int bx1, int by1)
{if (sht->height >= 0) { /* 如果正在显示, 则按新图层的信息刷新画面 */sheet_refreshsub(ctl, sht->vx0 + bx0, sht->vy0 + by0, sht->vx0 + bx1, sht->vy0 + by1);}return;
}void sheet_slide(struct SHTCTL *ctl, struct SHEET *sht, int vx0, int vy0)
{int old_vx0 = sht->vx0, old_vy0 = sht->vy0;sht->vx0 = vx0;sht->vy0 = vy0;if (sht->height >= 0) { /* 如果正在显示, 则按新图层的信息刷新画面 */sheet_refreshsub(ctl, old_vx0, old_vy0, old_vx0 + sht->bxsize, old_vy0 + sht->bysize);sheet_refreshsub(ctl, vx0, vy0, vx0 + sht->bxsize, vy0 + sht->bysize);}return;
}void sheet_free(struct SHTCTL *ctl, struct SHEET *sht)
{if (sht->height >= 0) {sheet_updown(ctl, sht, -1); /* 如果牌显示状态,则先设定为隐藏 */}sht->flags = 0; /* "未使用"标志 */return;
}
- 打vc code,输入以下代码并保存为 asmhead.nas,存放在harib07d文件夹中。
; haribote-os boot asm
; TAB=4BOTPAK EQU 0x00280000 ; bootpack装载处
DSKCAC EQU 0x00100000 ; 磁盘缓存的地方
DSKCAC0 EQU 0x00008000 ; 磁盘高速缓存的场所(实时模式); 有关BOOT_INFO
CYLS EQU 0x0ff0 ; 设定启动区
LEDS EQU 0x0ff1
VMODE EQU 0x0ff2 ; 关于颜色数目的信息,颜色的位数
SCRNX EQU 0x0ff4 ; 分辨率的X(screen x)
SCRNY EQU 0x0ff6 ; 分辨率的Y(screen y)
VRAM EQU 0x0ff8 ; 图像缓冲区的开始地址ORG 0xc200 ; 这个程序要被装载到内存的什么地方呢?; 画面模式设定MOV AL,0x13 ; VGA显卡,320x200x8位彩色MOV AH,0x00INT 0x10MOV BYTE [VMODE],8 ; 记录画面模式(C语言参照)MOV WORD [SCRNX],320MOV WORD [SCRNY],200MOV DWORD [VRAM],0x000a0000; 用BIOS取得键盘各种LED指示灯的状态MOV AH,0x02INT 0x16 ; keyboard BIOSMOV [LEDS],AL; 使PIC不授受一切中断
; 如果要初始PIC的话,要在AT兼容的规范中,
; 如果不把这家伙放在CLI面前,我偶尔会举起来
; 稍后进行PIC的初始化MOV AL,0xffOUT 0x21,ALNOP ; 如果连续OUT命令的话,可能会有不太好的机型OUT 0xa1,ALCLI ; 甚至禁止CPU层面插队; cpu从1 mb以上的内存,a20gate设定CALL waitkbdoutMOV AL,0xd1OUT 0x64,ALCALL waitkbdoutMOV AL,0xdf ; enable A20OUT 0x60,ALCALL waitkbdout; 保护模式过渡[INSTRSET "i486p"] ; 用于记述想要使用的486命令LGDT [GDTR0] ; 暂定GDT设定MOV EAX,CR0AND EAX,0x7fffffff ; 使bit31为0(为子禁止寻乎)OR EAX,0x00000001 ; 使bit0为1(为子保护模式转移)MOV CR0,EAXJMP pipelineflush
pipelineflush:MOV AX,1*8 ; 可读区段32bitMOV DS,AXMOV ES,AXMOV FS,AXMOV GS,AXMOV SS,AX; bootpack的传送MOV ESI,bootpack ; 传输源MOV EDI,BOTPAK ; 传输目的地MOV ECX,512*1024/4CALL memcpy; 顺便磁盘数据也向原来的位置传送; 首先从引导扇区MOV ESI,0x7c00 ; 传输源MOV EDI,DSKCAC ; 传输目的地MOV ECX,512/4CALL memcpy; 剩下的全部MOV ESI,DSKCAC0+512 ; 传输源MOV EDI,DSKCAC+512 ; 传输目的地MOV ECX,0MOV CL,BYTE [CYLS]IMUL ECX,512*18*2/4 ; 从柱面数转换成字节数 /4SUB ECX,512/4 ; 通过IPL减去CALL memcpy; 我们已经完成了需要使用asmhead 进行的所有操作
; 放到bootpack中; 启动bootpackMOV EBX,BOTPAKMOV ECX,[EBX+16]ADD ECX,3 ; ECX += 3;SHR ECX,2 ; ECX /= 4;JZ skip ; 无需转移MOV ESI,[EBX+20] ; 传输源ADD ESI,EBXMOV EDI,[EBX+12] ; 传输目的地CALL memcpy
skip:MOV ESP,[EBX+12] ; 堆栈初始值JMP DWORD 2*8:0x0000001bwaitkbdout:IN AL,0x64AND AL,0x02JNZ waitkbdout ; 如果AND的结果不为0,请跳转至waitkbdouRETmemcpy:MOV EAX,[ESI]ADD ESI,4MOV [EDI],EAXADD EDI,4SUB ECX,1JNZ memcpy ; 如果减法不为0,则返回memcpyRET
; memcpy也可以用字符串指令编写,除非你忘记了地址大小写前缀ALIGNB 16
GDT0:RESB 8 ; 空选择器DW 0xffff,0x0000,0x9200,0x00cf ; 读/定段32bitDW 0xffff,0x0000,0x9a28,0x0047 ; 可执行段32bit(用于bootpack)DW 0
GDTR0:DW 8*3-1DD GDT0ALIGNB 16
bootpack:
- 打开 VC code 创建 ipl10.nas 文件,输入以下代码,也存放的harib07d中。
; haribote-ipl
; TAB=4CYLS EQU 10 ; 要读取到什么程度ORG 0x7c00 ; 启动装载程序; 以下记述用于标准FAT12格式软盘JMP entryDB 0x90DB "HARIBOTE" ; 磁盘名称(可以是任意字符串)DW 512 ; 每个扇区的大小(必须是512)DB 1 ; 簇的大小(必须为一个扇区)DW 1 ; FAT12的起始位置(一般从第一个扇区开始DB 2 ; FAT的个数(必须为2)DW 224 ; 根目录的大小(一般设成224项)DW 2880 ; 该磁盘的大小(必须是2880扇区)DB 0xf0 ; 该磁盘的种类(必须是0xf0DW 9 ; FAt的长度(必须是9扇区)DW 18 ; 一个磁道有几个扇区(必须是18)DW 2 ; 磁头数(必须是2)DD 0 ; 不使用分区,必须是0DD 2880 ; 磁盘大小DB 0,0,0x29 ; 意义不明固定DD 0xffffffff ; (可能是)卷标号码DB "HARIBOTEOS " ; 磁盘的名称(11字节)DB "FAT12 " ; 磁盘格式名称(8字节)RESB 18 ; 先空出18字节; 程序主体entry:MOV AX,0 ; 初始化寄存器MOV SS,AXMOV SP,0x7c00MOV DS,AX; 读磁盘MOV AX,0x0820MOV ES,AXMOV CH,0 ; 柱面 0MOV DH,0 ; 磁头 0MOV CL,2 ; 扇区 2
readloop:MOV SI,0 ; 记录失败次数的寄存器
retry:MOV AH,0x02 ; AH=0x02 : 读入磁盘MOV AL,1 ; 1 个扇区MOV BX,0MOV DL,0x00 ; A 驱动器INT 0x13 ; 调用磁盘BIOSJNC next ; 没出错时跳转到nextADD SI,1 ; SI 加 1CMP SI,5 ; 比较 SI 与 5JAE error ; SI >= 5 时,跳转到errorMOV AH,0x00MOV DL,0x00 ; A 驱动器INT 0x13 ; 重置驱动器JMP retry
next:MOV AX,ES ; 把内存地址后移0x200ADD AX,0x0020MOV ES,AX ; 因为没有 ADD ES,0x020 指令,所以这里稍微绕个弯ADD CL,1 ; CL 加 1CMP CL,18 ; 比较 CL 与 18JBE readloop ; 如果 CL <= 18,则跳转至readloop MOV CL,1ADD DH,1CMP DH,2JB readloop ; 如果 DH < 2, 则跳转到readloopMOV DH,0ADD CH,1CMP CH,CYLSJB readloop ; 如果 CH < CYLS,则跳转至readloop; 因为看完了实行haribote.sysMOV [0x0ff0],CH ; IPL读到什么地方结束JMP 0xc200error:MOV SI,msg
putloop:MOV AL,[SI]ADD SI,1 ; SI 加 1CMP AL,0JE finMOV AH,0x0e ; 显示一个文字MOV BX,15 ; 指定字符颜色INT 0x10 ; 调用显卡BIOSJMP putloop
fin:HLT ; 让CPu停止,等待指令JMP fin ; 无限循环
msg:DB 0x0a, 0x0a ; 换行两次DB "load error"DB 0x0a ; 换行DB 0RESB 0x7dfe-$ ; 重复0x00一直到0x7dfeDB 0x55, 0xaa
- 打开记事本,输入以下代码,另存为 make.bat, 同样放到harib07d中。
..\z_tools\make.exe %1 %2 %3 %4 %5 %6 %7 %8 %9
- 创建 Makefile,并输入以下代码并存放到harib07d中。
OBJS_BOOTPACK = bootpack.obj naskfunc.obj hankaku.obj graphic.obj dsctbl.obj \int.obj fifo.obj keyboard.obj mouse.obj memory.objTOOLPATH = ../z_tools/
INCPATH = ../z_tools/haribote/MAKE = $(TOOLPATH)make.exe -r
NASK = $(TOOLPATH)nask.exe
CC1 = $(TOOLPATH)cc1.exe -I$(INCPATH) -Os -Wall -quiet
GAS2NASK = $(TOOLPATH)gas2nask.exe -a
OBJ2BIM = $(TOOLPATH)obj2bim.exe
MAKEFONT = $(TOOLPATH)makefont.exe
BIN2OBJ = $(TOOLPATH)bin2obj.exe
BIM2HRB = $(TOOLPATH)bim2hrb.exe
RULEFILE = $(TOOLPATH)haribote/haribote.rul
EDIMG = $(TOOLPATH)edimg.exe
IMGTOL = $(TOOLPATH)imgtol.com
COPY = copy
DEL = del# 默认default :$(MAKE) img# 文件生成规则ipl10.bin : ipl10.nas Makefile$(NASK) ipl10.nas ipl10.bin ipl10.lstasmhead.bin : asmhead.nas Makefile$(NASK) asmhead.nas asmhead.bin asmhead.lsthankaku.bin : hankaku.txt Makefile$(MAKEFONT) hankaku.txt hankaku.binhankaku.obj : hankaku.bin Makefile$(BIN2OBJ) hankaku.bin hankaku.obj _hankakubootpack.bim : $(OBJS_BOOTPACK) Makefile$(OBJ2BIM) @$(RULEFILE) out:bootpack.bim stack:3136k map:bootpack.map \$(OBJS_BOOTPACK)
# 3MB+64KB=3136KBbootpack.hrb : bootpack.bim Makefile$(BIM2HRB) bootpack.bim bootpack.hrb 0haribote.sys : asmhead.bin bootpack.hrb Makefilecopy /B asmhead.bin+bootpack.hrb haribote.sysharibote.img : ipl10.bin haribote.sys Makefile$(EDIMG) imgin:../z_tools/fdimg0at.tek \wbinimg src:ipl10.bin len:512 from:0 to:0 \copy from:haribote.sys to:@: \imgout:haribote.img# 一般规则%.gas : %.c bootpack.h Makefile$(CC1) -o $*.gas $*.c%.nas : %.gas Makefile$(GAS2NASK) $*.gas $*.nas%.obj : %.nas Makefile$(NASK) $*.nas $*.obj $*.lst# 命令img :$(MAKE) haribote.imgrun :$(MAKE) img$(COPY) haribote.img ..\z_tools\qemu\fdimage0.bin$(MAKE) -C ../z_tools/qemuinstall :$(MAKE) img$(IMGTOL) w a: haribote.imgclean :-$(DEL) *.bin-$(DEL) *.lst-$(DEL) *.obj-$(DEL) bootpack.map-$(DEL) bootpack.bim-$(DEL) bootpack.hrb-$(DEL) haribote.syssrc_only :$(MAKE) clean-$(DEL) haribote.img
- 打开记事本,复制以下内容并保存为 hankaku.txt,且存放在harib07d中;ps:建议这一段代码直接复制不要看。
这段代码过多,无法贴出来,请在网盘资源复制,projects/05_day/harib02f中hankaku.txt
编译及运行
- 双击 !cons_nt.bat,并在打开的命令行中输入 make run
- VMware中运行结果,如下图
ps: 结果就是这样,因为本次实验的目的是提高叠加处理速度(2) (harib07d),可以试着移动鼠标看看,到鼠标画面移动了,以后会有更精彩。敬请期待!
好的今天到这里harib07d就张结束了,请大家多多支持!!!
30天自制操作系统第10天harib07d相关推荐
- 索骥馆-DIY操作系统之《30天自制操作系统》扫描版[PDF]
内容简介: <30天自制操作系统>是一本兼具趣味性.实用性与学习性的操作系统图书.作者从计算机的构造.汇编语言.C语言开始解说,让读者在实践中掌握算法.在这本书的指导下,从零编写所有代码, ...
- 为什么《30天自制操作系统》封面中的猫是两只尾巴
刚刚在一社区,发了一贴,被指出一问题,询一高人,得一答案.这便是我没有关注到的封面上的那只猫,我想这也是很多读者没有关注到的.因为在我微博的200转发贴中,并没有人提到封面中的猫为何有两只尾巴.于是咨 ...
- 《30天自制操作系统》笔记(01)——hello bitzhuwei’s OS!
<30天自制操作系统>笔记(01)--hello bitzhuwei's OS! 最初的OS代码 1 ; hello-os 2 ; TAB=4 3 4 ORG 0x7c00 ; 指明程序的 ...
- 《30天自制操作系统》笔记(04)——显示器256色
<30天自制操作系统>笔记(04)--显示器256色 进度回顾 从最开始的(01)篇到上一篇为止,已经解决了开发环境问题和OS项目的顶层设计问题. 本篇做一个小练习:设置显卡显示256色. ...
- 30天自制操作系统——第五天
第五天 参考<30天自制操作系统>GDT&IDT - 谷月轩 - 博客 梳理一下文件 现在我们拥有这么9个文件: ipl10.nas InitialProgramLoader, 占 ...
- 30天自制操作系统第三天
操作系统实验日志3 学号 201708010402 姓名 徐冰娜 专业年级班级 实验日期 2019.9.28 实验项目 第3天:进入32位模式并导入C语言 智能1701 30天自制操作系统第三天 操作 ...
- 【操作系统】30天自制操作系统--(14)多任务1
本章开始多任务的设计. 一 多任务的说明 多任务(multitask),指的是操作系统中,多个应用程序同时运行的状态.然而,对于单核CPU来说,同一个瞬间只能处理一个事情,不能做到左右互搏.一心二用的 ...
- 【操作系统】30天自制操作系统--(18)应用程序
本章主要介绍了文件处理的相关操作以及尝试制作第一个应用程序hlt. 一 type命令 与Linux里面的type命令不同,Windows命令行中的type命令是用来查看文件内容的.在自制的操作系统中, ...
- 《30天自制操作系统》-day3(MAC)
第3天 进入32位模式并导入C语言 基本配置 汇编语言内容 文件 hanbote.nas ipl.nas Makefile 原因 用法 基本配置 设备:Macbookpro(13-inch,2018) ...
- 30天自制操作系统——第1天 从计算机结构到汇编程序入门
落灰一学期的<30天自制操作系统>,希望能够利用大二最后这几个月完成操作系统的制作,以下是我阅读本书所记录的笔记以及学习过程,愿顺利完成. 1.先动手操作 (1)安装"二进制编辑 ...
最新文章
- 我被裁员了!让保安把身患绝症的我被强赶出公司,亲身经历的噩梦!
- python http服务器_超简单的Python HTTP服务
- 限制php输出图像的固定,限制要显示的图像数php
- ubuntu声卡相关
- livebos--iframe使用
- 五、python模块以及包
- 基于OpenCL的mean filter性能
- MySQL not in查询不出数据(MySQL not in 无效)
- django-模板语言-传输各种数据类型
- leetcode python3 简单题232. Implement Queue using Stacks
- LeetCode 394: DecodeString (Java)
- VueRouter基础知识记录1
- 静态嵌套类和非静态嵌套类
- SPI 机制-插件化扩展功能
- Unity写lua代码的vs插件:BabeLua
- 微信核酸检测预约小程序系统毕业设计毕设(6)开题答辩PPT
- KMPlayer播放mkv视频不出声音的解决办法
- 华为机试真题 Java实现【最短木板长度】【100%通过率】【2022.11 Q4 新题】
- Go Cloud项目开源发布:Go语言将成为云端应用开发的首选语言?
- ESD静电二极管端口信号防护应用产品型号——SM712