forked from backup/30dayMakeOS
code from day6
This commit is contained in:
1
07_day/!cons_9x.bat
Normal file
1
07_day/!cons_9x.bat
Normal file
@@ -0,0 +1 @@
|
||||
command
|
||||
1
07_day/!cons_nt.bat
Normal file
1
07_day/!cons_nt.bat
Normal file
@@ -0,0 +1 @@
|
||||
cmd.exe
|
||||
93
07_day/Makefile
Normal file
93
07_day/Makefile
Normal file
@@ -0,0 +1,93 @@
|
||||
OBJS_BOOTPACK = bootpack.obj naskfunc.obj hankaku.obj graphic.obj dsctbl.obj \
|
||||
int.obj
|
||||
|
||||
TOOLPATH = ../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.lst
|
||||
|
||||
asmhead.bin : asmhead.nas Makefile
|
||||
$(NASK) asmhead.nas asmhead.bin asmhead.lst
|
||||
|
||||
hankaku.bin : hankaku.txt Makefile
|
||||
$(MAKEFONT) hankaku.txt hankaku.bin
|
||||
|
||||
hankaku.obj : hankaku.bin Makefile
|
||||
$(BIN2OBJ) hankaku.bin hankaku.obj _hankaku
|
||||
|
||||
bootpack.bim : $(OBJS_BOOTPACK) Makefile
|
||||
$(OBJ2BIM) @$(RULEFILE) out:bootpack.bim stack:3136k map:bootpack.map \
|
||||
$(OBJS_BOOTPACK)
|
||||
# 3MB+64KB=3136KB
|
||||
|
||||
bootpack.hrb : bootpack.bim Makefile
|
||||
$(BIM2HRB) bootpack.bim bootpack.hrb 0
|
||||
|
||||
haribote.sys : asmhead.bin bootpack.hrb Makefile
|
||||
copy /B asmhead.bin+bootpack.hrb haribote.sys
|
||||
|
||||
haribote.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 Makefile
|
||||
$(CC1) -o $*.gas $*.c
|
||||
|
||||
%.nas : %.gas Makefile
|
||||
$(GAS2NASK) $*.gas $*.nas
|
||||
|
||||
%.obj : %.nas Makefile
|
||||
$(NASK) $*.nas $*.obj $*.lst
|
||||
|
||||
# 运行程序
|
||||
|
||||
img :
|
||||
$(MAKE) haribote.img
|
||||
|
||||
run :
|
||||
$(MAKE) img
|
||||
$(COPY) haribote.img ..\z_tools\qemu\fdimage0.bin
|
||||
$(MAKE) -C ../z_tools/qemu
|
||||
|
||||
install :
|
||||
$(MAKE) img
|
||||
$(IMGTOL) w a: haribote.img
|
||||
|
||||
clean :
|
||||
-$(DEL) *.bin
|
||||
-$(DEL) *.lst
|
||||
-$(DEL) *.obj
|
||||
-$(DEL) bootpack.map
|
||||
-$(DEL) bootpack.bim
|
||||
-$(DEL) bootpack.hrb
|
||||
-$(DEL) haribote.sys
|
||||
|
||||
src_only :
|
||||
$(MAKE) clean
|
||||
-$(DEL) haribote.img
|
||||
146
07_day/asmhead.nas
Normal file
146
07_day/asmhead.nas
Normal file
@@ -0,0 +1,146 @@
|
||||
; haribote-os boot asm
|
||||
; TAB=4
|
||||
|
||||
BOTPAK EQU 0x00280000 ; 加载bootpack
|
||||
DSKCAC EQU 0x00100000 ; 磁盘缓存的位置
|
||||
DSKCAC0 EQU 0x00008000 ; 磁盘缓存的位置(实模式)
|
||||
|
||||
; BOOT_INFO相关
|
||||
CYLS EQU 0x0ff0 ; 引导扇区设置
|
||||
LEDS EQU 0x0ff1
|
||||
VMODE EQU 0x0ff2 ; 关于颜色的信息
|
||||
SCRNX EQU 0x0ff4 ; 分辨率X
|
||||
SCRNY EQU 0x0ff6 ; 分辨率Y
|
||||
VRAM EQU 0x0ff8 ; 图像缓冲区的起始地址
|
||||
|
||||
ORG 0xc200 ; 这个的程序要被装载的内存地址
|
||||
|
||||
; 画面モードを設定
|
||||
|
||||
MOV AL,0x13 ; VGA显卡,320x200x8bit
|
||||
MOV AH,0x00
|
||||
INT 0x10
|
||||
MOV BYTE [VMODE],8 ; 屏幕的模式(参考C语言的引用)
|
||||
MOV WORD [SCRNX],320
|
||||
MOV WORD [SCRNY],200
|
||||
MOV DWORD [VRAM],0x000a0000
|
||||
|
||||
; 通过BIOS获取指示灯状态
|
||||
|
||||
MOV AH,0x02
|
||||
INT 0x16 ; keyboard BIOS
|
||||
MOV [LEDS],AL
|
||||
|
||||
; 防止PIC接受所有中断
|
||||
; AT兼容机的规范、PIC初始化
|
||||
; 然后之前在CLI不做任何事就挂起
|
||||
; PIC在同意后初始化
|
||||
|
||||
MOV AL,0xff
|
||||
OUT 0x21,AL
|
||||
NOP ; 不断执行OUT指令
|
||||
OUT 0xa1,AL
|
||||
|
||||
CLI ; 进一步中断CPU
|
||||
|
||||
; 让CPU支持1M以上内存、设置A20GATE
|
||||
|
||||
CALL waitkbdout
|
||||
MOV AL,0xd1
|
||||
OUT 0x64,AL
|
||||
CALL waitkbdout
|
||||
MOV AL,0xdf ; enable A20
|
||||
OUT 0x60,AL
|
||||
CALL waitkbdout
|
||||
|
||||
; 保护模式转换
|
||||
|
||||
[INSTRSET "i486p"] ; 说明使用486指令
|
||||
|
||||
LGDT [GDTR0] ; 设置临时GDT
|
||||
MOV EAX,CR0
|
||||
AND EAX,0x7fffffff ; 使用bit31(禁用分页)
|
||||
OR EAX,0x00000001 ; bit0到1转换(保护模式过渡)
|
||||
MOV CR0,EAX
|
||||
JMP pipelineflush
|
||||
pipelineflush:
|
||||
MOV AX,1*8 ; 写32bit的段
|
||||
MOV DS,AX
|
||||
MOV ES,AX
|
||||
MOV FS,AX
|
||||
MOV GS,AX
|
||||
MOV SS,AX
|
||||
|
||||
; bootpack传递
|
||||
|
||||
MOV ESI,bootpack ; 源
|
||||
MOV EDI,BOTPAK ; 目标
|
||||
MOV ECX,512*1024/4
|
||||
CALL memcpy
|
||||
|
||||
; 传输磁盘数据
|
||||
|
||||
; 从引导区开始
|
||||
|
||||
MOV ESI,0x7c00 ; 源
|
||||
MOV EDI,DSKCAC ; 目标
|
||||
MOV ECX,512/4
|
||||
CALL memcpy
|
||||
|
||||
; 剩余的全部
|
||||
|
||||
MOV ESI,DSKCAC0+512 ; 源
|
||||
MOV EDI,DSKCAC+512 ; 目标
|
||||
MOV ECX,0
|
||||
MOV CL,BYTE [CYLS]
|
||||
IMUL ECX,512*18*2/4 ; 除以4得到字节数
|
||||
SUB ECX,512/4 ; IPL偏移量
|
||||
CALL memcpy
|
||||
|
||||
; 由于还需要asmhead才能完成
|
||||
; 完成其余的bootpack任务
|
||||
|
||||
; bootpack启动
|
||||
|
||||
MOV EBX,BOTPAK
|
||||
MOV ECX,[EBX+16]
|
||||
ADD ECX,3 ; ECX += 3;
|
||||
SHR ECX,2 ; ECX /= 4;
|
||||
JZ skip ; 传输完成
|
||||
MOV ESI,[EBX+20] ; 源
|
||||
ADD ESI,EBX
|
||||
MOV EDI,[EBX+12] ; 目标
|
||||
CALL memcpy
|
||||
skip:
|
||||
MOV ESP,[EBX+12] ; 堆栈的初始化
|
||||
JMP DWORD 2*8:0x0000001b
|
||||
|
||||
waitkbdout:
|
||||
IN AL,0x64
|
||||
AND AL,0x02
|
||||
JNZ waitkbdout ; AND结果不为0跳转到waitkbdout
|
||||
RET
|
||||
|
||||
memcpy:
|
||||
MOV EAX,[ESI]
|
||||
ADD ESI,4
|
||||
MOV [EDI],EAX
|
||||
ADD EDI,4
|
||||
SUB ECX,1
|
||||
JNZ memcpy ; 运算结果不为0跳转到memcpy
|
||||
RET
|
||||
; memcpy地址前缀大小
|
||||
|
||||
ALIGNB 16
|
||||
GDT0:
|
||||
RESB 8 ; 初始值
|
||||
DW 0xffff,0x0000,0x9200,0x00cf ; 写32bit位段寄存器
|
||||
DW 0xffff,0x0000,0x9a28,0x0047 ; 可执行的文件的32bit寄存器(bootpack用)
|
||||
|
||||
DW 0
|
||||
GDTR0:
|
||||
DW 8*3-1
|
||||
DD GDT0
|
||||
|
||||
ALIGNB 16
|
||||
bootpack:
|
||||
31
07_day/bootpack.c
Normal file
31
07_day/bootpack.c
Normal file
@@ -0,0 +1,31 @@
|
||||
/* bootpack */
|
||||
|
||||
#include "bootpack.h"
|
||||
#include <stdio.h>
|
||||
|
||||
void HariMain(void)
|
||||
{
|
||||
struct BOOTINFO *binfo = (struct BOOTINFO *) ADR_BOOTINFO;
|
||||
char s[40], mcursor[256];
|
||||
int mx, my;
|
||||
|
||||
init_gdtidt();
|
||||
init_pic();
|
||||
io_sti(); /* IDT/PICの初期化が終わったのでCPUの割り込み禁止を解除 */
|
||||
|
||||
init_palette();
|
||||
init_screen8(binfo->vram, binfo->scrnx, binfo->scrny);
|
||||
mx = (binfo->scrnx - 16) / 2; /* 计算画面的中心坐标*/
|
||||
my = (binfo->scrny - 28 - 16) / 2;
|
||||
init_mouse_cursor8(mcursor, COL8_008484);
|
||||
putblock8_8(binfo->vram, binfo->scrnx, 16, 16, mx, my, mcursor, 16);
|
||||
sprintf(s, "(%d, %d)", mx, my);
|
||||
putfonts8_asc(binfo->vram, binfo->scrnx, 0, 0, COL8_FFFFFF, s);
|
||||
|
||||
io_out8(PIC0_IMR, 0xf9); /* PIC1とキーボードを許可(11111001) */
|
||||
io_out8(PIC1_IMR, 0xef); /* マウスを許可(11101111) */
|
||||
|
||||
for (;;) {
|
||||
io_hlt();
|
||||
}
|
||||
}
|
||||
92
07_day/bootpack.h
Normal file
92
07_day/bootpack.h
Normal file
@@ -0,0 +1,92 @@
|
||||
/* asmhead.nas */
|
||||
struct BOOTINFO { /* 0x0ff0-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_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);
|
||||
void asm_inthandler21(void);
|
||||
void asm_inthandler27(void);
|
||||
void asm_inthandler2c(void);
|
||||
|
||||
/* 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 inthandler21(int *esp);
|
||||
void inthandler27(int *esp);
|
||||
void inthandler2c(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
|
||||
56
07_day/dsctbl.c
Normal file
56
07_day/dsctbl.c
Normal file
@@ -0,0 +1,56 @@
|
||||
/* 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;
|
||||
}
|
||||
157
07_day/graphic.c
Normal file
157
07_day/graphic.c
Normal file
@@ -0,0 +1,157 @@
|
||||
/* 关于绘图部分的处理 */
|
||||
|
||||
#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, 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;
|
||||
|
||||
/* 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 /* 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;
|
||||
}
|
||||
|
||||
void putfonts8_asc(char *vram, int xsize, int x, int y, char c, unsigned char *s)
|
||||
{
|
||||
extern char hankaku[4096];
|
||||
/* C语言中,字符串都是以0x00结尾 */
|
||||
for (; *s != 0x00; s++) {
|
||||
putfont8(vram, xsize, x, y, c, hankaku + *s * 16);
|
||||
x += 8;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void init_mouse_cursor8(char *mouse, char bc)
|
||||
/* 鼠标的数据准备(16x16) */
|
||||
{
|
||||
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;
|
||||
}
|
||||
4609
07_day/hankaku.txt
Normal file
4609
07_day/hankaku.txt
Normal file
File diff suppressed because it is too large
Load Diff
58
07_day/int.c
Normal file
58
07_day/int.c
Normal file
@@ -0,0 +1,58 @@
|
||||
/*初始化关系 */
|
||||
|
||||
#include "bootpack.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 inthandler21(int *esp)
|
||||
/* 来自PS/2键盘的中断 */
|
||||
{
|
||||
struct BOOTINFO *binfo = (struct BOOTINFO *) ADR_BOOTINFO;
|
||||
boxfill8(binfo->vram, binfo->scrnx, COL8_000000, 0, 0, 32 * 8 - 1, 15);
|
||||
putfonts8_asc(binfo->vram, binfo->scrnx, 0, 0, COL8_FFFFFF, "INT 21 (IRQ-1) : PS/2 keyboard");
|
||||
for (;;) {
|
||||
io_hlt();
|
||||
}
|
||||
}
|
||||
|
||||
void inthandler2c(int *esp)
|
||||
/* 来自PS/2鼠标的中断 */
|
||||
{
|
||||
struct BOOTINFO *binfo = (struct BOOTINFO *) ADR_BOOTINFO;
|
||||
boxfill8(binfo->vram, binfo->scrnx, COL8_000000, 0, 0, 32 * 8 - 1, 15);
|
||||
putfonts8_asc(binfo->vram, binfo->scrnx, 0, 0, COL8_FFFFFF, "INT 2C (IRQ-12) : PS/2 mouse");
|
||||
for (;;) {
|
||||
io_hlt();
|
||||
}
|
||||
}
|
||||
|
||||
void inthandler27(int *esp)
|
||||
/* PIC0中断的不完整策略 */
|
||||
/* 这个中断在Athlon64X2上通过芯片组提供的便利,只需执行一次 */
|
||||
/* 这个中断只是接收,不执行任何操作 */
|
||||
/* 为什么不处理?
|
||||
→ 因为这个中断可能是电气噪声引发的、只是处理一些重要的情况。*/
|
||||
{
|
||||
io_out8(PIC0_OCW2, 0x67); /* 通知PIC的IRQ-07(参考7-1) */
|
||||
return;
|
||||
}
|
||||
109
07_day/ipl10.nas
Normal file
109
07_day/ipl10.nas
Normal file
@@ -0,0 +1,109 @@
|
||||
; haribote-ipl
|
||||
; TAB=4
|
||||
|
||||
CYLS EQU 10 ; 声明CYLS=10
|
||||
|
||||
ORG 0x7c00 ; 指明程序装载地址
|
||||
|
||||
; 标准FAT12格式软盘专用的代码 Stand FAT12 format floppy code
|
||||
|
||||
JMP entry
|
||||
DB 0x90
|
||||
DB "HARIBOTE" ; 启动扇区名称(8字节)
|
||||
DW 512 ; 每个扇区(sector)大小(必须512字节)
|
||||
DB 1 ; 簇(cluster)大小(必须为1个扇区)
|
||||
DW 1 ; FAT起始位置(一般为第一个扇区)
|
||||
DB 2 ; FAT个数(必须为2)
|
||||
DW 224 ; 根目录大小(一般为224项)
|
||||
DW 2880 ; 该磁盘大小(必须为2880扇区1440*1024/512)
|
||||
DB 0xf0 ; 磁盘类型(必须为0xf0)
|
||||
DW 9 ; FAT的长度(必??9扇区)
|
||||
DW 18 ; 一个磁道(track)有几个扇区(必须为18)
|
||||
DW 2 ; 磁头数(必??2)
|
||||
DD 0 ; 不使用分区,必须是0
|
||||
DD 2880 ; 重写一次磁盘大小
|
||||
DB 0,0,0x29 ; 意义不明(固定)
|
||||
DD 0xffffffff ; (可能是)卷标号码
|
||||
DB "HARIBOTEOS " ; 磁盘的名称(必须为11字?,不足填空格)
|
||||
DB "FAT12 " ; 磁盘格式名称(必??8字?,不足填空格)
|
||||
RESB 18 ; 先空出18字节
|
||||
|
||||
; 程序主体
|
||||
|
||||
entry:
|
||||
MOV AX,0 ; 初始化寄存器
|
||||
MOV SS,AX
|
||||
MOV SP,0x7c00
|
||||
MOV DS,AX
|
||||
|
||||
; 读取磁盘
|
||||
|
||||
MOV AX,0x0820
|
||||
MOV ES,AX
|
||||
MOV CH,0 ; 柱面0
|
||||
MOV DH,0 ; 磁头0
|
||||
MOV CL,2 ; 扇区2
|
||||
|
||||
readloop:
|
||||
MOV SI,0 ; 记录失败次数寄存器
|
||||
|
||||
retry:
|
||||
MOV AH,0x02 ; AH=0x02 : 读入磁盘
|
||||
MOV AL,1 ; 1个扇区
|
||||
MOV BX,0
|
||||
MOV DL,0x00 ; A驱动器
|
||||
INT 0x13 ; 调用磁盘BIOS
|
||||
JNC next ; 没出错则跳转到fin
|
||||
ADD SI,1 ; 往SI加1
|
||||
CMP SI,5 ; 比较SI与5
|
||||
JAE error ; SI >= 5 跳转到error
|
||||
MOV AH,0x00
|
||||
MOV DL,0x00 ; A驱动器
|
||||
INT 0x13 ; 重置驱动器
|
||||
JMP retry
|
||||
next:
|
||||
MOV AX,ES ; 把内存地址后移0x200(512/16十六进制转换)
|
||||
ADD AX,0x0020
|
||||
MOV ES,AX ; ADD ES,0x020因为没有ADD ES,只能通过AX进行
|
||||
ADD CL,1 ; 往CL里面加1
|
||||
CMP CL,18 ; 比较CL与18
|
||||
JBE readloop ; CL <= 18 跳转到readloop
|
||||
MOV CL,1
|
||||
ADD DH,1
|
||||
CMP DH,2
|
||||
JB readloop ; DH < 2 跳转到readloop
|
||||
MOV DH,0
|
||||
ADD CH,1
|
||||
CMP CH,CYLS
|
||||
JB readloop ; CH < CYLS 跳转到readloop
|
||||
|
||||
; 读取完毕,跳转到haribote.sys执行!
|
||||
MOV [0x0ff0],CH ; IPLがどこまで読んだのかをメモ
|
||||
JMP 0xc200
|
||||
|
||||
error:
|
||||
MOV SI,msg
|
||||
|
||||
putloop:
|
||||
MOV AL,[SI]
|
||||
ADD SI,1 ; 给SI加1
|
||||
CMP AL,0
|
||||
JE fin
|
||||
MOV AH,0x0e ; 显示一个文字
|
||||
MOV BX,15 ; 指定字符颜色
|
||||
INT 0x10 ; 调用显卡BIOS
|
||||
JMP putloop
|
||||
|
||||
fin:
|
||||
HLT ; 让CPU停止,等待指令
|
||||
JMP fin ; 无限循环
|
||||
|
||||
msg:
|
||||
DB 0x0a, 0x0a ; 换行两次
|
||||
DB "load error"
|
||||
DB 0x0a ; 换行
|
||||
DB 0
|
||||
|
||||
RESB 0x7dfe-$ ; 填写0x00直到0x001fe
|
||||
|
||||
DB 0x55, 0xaa
|
||||
1
07_day/make.bat
Normal file
1
07_day/make.bat
Normal file
@@ -0,0 +1 @@
|
||||
..\z_tools\make.exe %1 %2 %3 %4 %5 %6 %7 %8 %9
|
||||
140
07_day/naskfunc.nas
Normal file
140
07_day/naskfunc.nas
Normal file
@@ -0,0 +1,140 @@
|
||||
; naskfunc
|
||||
; TAB=4
|
||||
|
||||
[FORMAT "WCOFF"] ; 制作目标文件的模式
|
||||
[INSTRSET "i486p"] ; 使用到486为止的指令
|
||||
[BITS 32] ; 3制作32位模式用的机器语言
|
||||
[FILE "naskfunc.nas"] ; 文件名
|
||||
|
||||
GLOBAL _io_hlt, _io_cli, _io_sti, _io_stihlt
|
||||
GLOBAL _io_in8, _io_in16, _io_in32
|
||||
GLOBAL _io_out8, _io_out16, _io_out32
|
||||
GLOBAL _io_load_eflags, _io_store_eflags
|
||||
GLOBAL _load_gdtr, _load_idtr
|
||||
GLOBAL _asm_inthandler21, _asm_inthandler27, _asm_inthandler2c
|
||||
EXTERN _inthandler21, _inthandler27, _inthandler2c
|
||||
|
||||
[SECTION .text]
|
||||
|
||||
_io_hlt: ; void io_hlt(void);
|
||||
HLT
|
||||
RET
|
||||
|
||||
_io_cli: ; void io_cli(void);
|
||||
CLI
|
||||
RET
|
||||
|
||||
_io_sti: ; void io_sti(void);
|
||||
STI
|
||||
RET
|
||||
|
||||
_io_stihlt: ; void io_stihlt(void);
|
||||
STI
|
||||
HLT
|
||||
RET
|
||||
|
||||
_io_in8: ; int io_in8(int port);
|
||||
MOV EDX,[ESP+4] ; port
|
||||
MOV EAX,0
|
||||
IN AL,DX
|
||||
RET
|
||||
|
||||
_io_in16: ; int io_in16(int port);
|
||||
MOV EDX,[ESP+4] ; port
|
||||
MOV EAX,0
|
||||
IN AX,DX
|
||||
RET
|
||||
|
||||
_io_in32: ; int io_in32(int port);
|
||||
MOV EDX,[ESP+4] ; port
|
||||
IN EAX,DX
|
||||
RET
|
||||
|
||||
_io_out8: ; void io_out8(int port, int data);
|
||||
MOV EDX,[ESP+4] ; port
|
||||
MOV AL,[ESP+8] ; data
|
||||
OUT DX,AL
|
||||
RET
|
||||
|
||||
_io_out16: ; void io_out16(int port, int data);
|
||||
MOV EDX,[ESP+4] ; port
|
||||
MOV EAX,[ESP+8] ; data
|
||||
OUT DX,AX
|
||||
RET
|
||||
|
||||
_io_out32: ; void io_out32(int port, int data);
|
||||
MOV EDX,[ESP+4] ; port
|
||||
MOV EAX,[ESP+8] ; data
|
||||
OUT DX,EAX
|
||||
RET
|
||||
|
||||
_io_load_eflags: ; int io_load_eflags(void);
|
||||
PUSHFD ; PUSH EFLAGS
|
||||
POP EAX
|
||||
RET
|
||||
|
||||
_io_store_eflags: ; void io_store_eflags(int eflags);
|
||||
MOV EAX,[ESP+4]
|
||||
PUSH EAX
|
||||
POPFD ; POP EFLAGS
|
||||
RET
|
||||
|
||||
_load_gdtr: ; void load_gdtr(int limit, int addr);
|
||||
MOV AX,[ESP+4] ; limit
|
||||
MOV [ESP+6],AX
|
||||
LGDT [ESP+6]
|
||||
RET
|
||||
|
||||
_load_idtr: ; void load_idtr(int limit, int addr);
|
||||
MOV AX,[ESP+4] ; limit
|
||||
MOV [ESP+6],AX
|
||||
LIDT [ESP+6]
|
||||
RET
|
||||
|
||||
_asm_inthandler21:
|
||||
PUSH ES
|
||||
PUSH DS
|
||||
PUSHAD
|
||||
MOV EAX,ESP
|
||||
PUSH EAX
|
||||
MOV AX,SS
|
||||
MOV DS,AX
|
||||
MOV ES,AX
|
||||
CALL _inthandler21
|
||||
POP EAX
|
||||
POPAD
|
||||
POP DS
|
||||
POP ES
|
||||
IRETD
|
||||
|
||||
_asm_inthandler27:
|
||||
PUSH ES
|
||||
PUSH DS
|
||||
PUSHAD
|
||||
MOV EAX,ESP
|
||||
PUSH EAX
|
||||
MOV AX,SS
|
||||
MOV DS,AX
|
||||
MOV ES,AX
|
||||
CALL _inthandler27
|
||||
POP EAX
|
||||
POPAD
|
||||
POP DS
|
||||
POP ES
|
||||
IRETD
|
||||
|
||||
_asm_inthandler2c:
|
||||
PUSH ES
|
||||
PUSH DS
|
||||
PUSHAD
|
||||
MOV EAX,ESP
|
||||
PUSH EAX
|
||||
MOV AX,SS
|
||||
MOV DS,AX
|
||||
MOV ES,AX
|
||||
CALL _inthandler2c
|
||||
POP EAX
|
||||
POPAD
|
||||
POP DS
|
||||
POP ES
|
||||
IRETD
|
||||
Reference in New Issue
Block a user