mirror of
https://github.com/yourtion/30dayMakeOS.git
synced 2026-02-05 02:53:19 +08:00
Compare commits
41 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d63b8acd91 | ||
|
|
575c4ffce8 | ||
|
|
f3f9a6c178 | ||
|
|
01bbd98aa8 | ||
|
|
233fe16825 | ||
|
|
8785b46021 | ||
|
|
02e307eae1 | ||
|
|
87b1d4027c | ||
|
|
0c2b6c5934 | ||
|
|
884ddf242e | ||
|
|
6b7a4a13b0 | ||
|
|
935af85346 | ||
|
|
d2fc0dc0f5 | ||
|
|
e4a94836dd | ||
|
|
68781eba2a | ||
|
|
883213696f | ||
|
|
95dcc14025 | ||
|
|
9d45d34cce | ||
|
|
b2dc361194 | ||
|
|
a789f578a8 | ||
|
|
5bc0adee61 | ||
|
|
95542da7f7 | ||
|
|
24945ddb18 | ||
|
|
d1e4c44149 | ||
|
|
34fc4eca27 | ||
|
|
c512f3e391 | ||
|
|
d046ca64a4 | ||
|
|
b306606282 | ||
|
|
c8a0464c52 | ||
|
|
908570a673 | ||
|
|
d84bab78e1 | ||
|
|
907b8c61ce | ||
|
|
efb6028e00 | ||
|
|
9475d3d828 | ||
|
|
b27c562b98 | ||
|
|
bde8ac972b | ||
|
|
8264071442 | ||
|
|
d77f778b8e | ||
|
|
991da3f569 | ||
|
|
36da3e87a9 | ||
|
|
2281f38f62 |
1
24_day/!cons_9x.bat
Normal file
1
24_day/!cons_9x.bat
Normal file
@@ -0,0 +1 @@
|
||||
command
|
||||
1
24_day/!cons_nt.bat
Normal file
1
24_day/!cons_nt.bat
Normal file
@@ -0,0 +1 @@
|
||||
cmd.exe
|
||||
220
24_day/Makefile
Normal file
220
24_day/Makefile
Normal file
@@ -0,0 +1,220 @@
|
||||
OBJS_BOOTPACK = bootpack.obj naskfunc.obj hankaku.obj graphic.obj dsctbl.obj \
|
||||
int.obj fifo.obj keyboard.obj mouse.obj memory.obj sheet.obj timer.obj \
|
||||
mtask.obj window.obj console.obj file.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
|
||||
|
||||
hello.hrb : hello.nas Makefile
|
||||
$(NASK) hello.nas hello.hrb hello.lst
|
||||
|
||||
hello2.hrb : hello2.nas Makefile
|
||||
$(NASK) hello2.nas hello2.hrb hello2.lst
|
||||
|
||||
a.bim : a.obj a_nask.obj Makefile
|
||||
$(OBJ2BIM) @$(RULEFILE) out:a.bim map:a.map a.obj a_nask.obj
|
||||
|
||||
a.hrb : a.bim Makefile
|
||||
$(BIM2HRB) a.bim a.hrb 0
|
||||
|
||||
hello3.bim : hello3.obj a_nask.obj Makefile
|
||||
$(OBJ2BIM) @$(RULEFILE) out:hello3.bim map:hello3.map hello3.obj a_nask.obj
|
||||
|
||||
hello3.hrb : hello3.bim Makefile
|
||||
$(BIM2HRB) hello3.bim hello3.hrb 0
|
||||
|
||||
hello4.bim : hello4.obj a_nask.obj Makefile
|
||||
$(OBJ2BIM) @$(RULEFILE) out:hello4.bim stack:1k map:hello4.map \
|
||||
hello4.obj a_nask.obj
|
||||
|
||||
hello4.hrb : hello4.bim Makefile
|
||||
$(BIM2HRB) hello4.bim hello4.hrb 0
|
||||
|
||||
hello5.bim : hello5.obj Makefile
|
||||
$(OBJ2BIM) @$(RULEFILE) out:hello5.bim stack:1k map:hello5.map hello5.obj
|
||||
|
||||
hello5.hrb : hello5.bim Makefile
|
||||
$(BIM2HRB) hello5.bim hello5.hrb 0
|
||||
|
||||
bug2.bim : bug2.obj Makefile
|
||||
$(OBJ2BIM) @$(RULEFILE) out:bug2.bim map:bug2.map bug2.obj
|
||||
|
||||
bug2.hrb : bug2.bim Makefile
|
||||
$(BIM2HRB) bug2.bim bug2.hrb 0
|
||||
|
||||
bug3.bim : bug3.obj Makefile
|
||||
$(OBJ2BIM) @$(RULEFILE) out:bug3.bim map:bug3.map bug3.obj a_nask.obj
|
||||
|
||||
bug3.hrb : bug3.bim Makefile
|
||||
$(BIM2HRB) bug3.bim bug3.hrb 0
|
||||
|
||||
winhelo.bim : winhelo.obj a_nask.obj Makefile
|
||||
$(OBJ2BIM) @$(RULEFILE) out:winhelo.bim stack:1k map:winhelo.map \
|
||||
winhelo.obj a_nask.obj
|
||||
|
||||
winhelo.hrb : winhelo.bim Makefile
|
||||
$(BIM2HRB) winhelo.bim winhelo.hrb 0
|
||||
|
||||
winhelo2.bim : winhelo2.obj a_nask.obj Makefile
|
||||
$(OBJ2BIM) @$(RULEFILE) out:winhelo2.bim stack:1k map:winhelo2.map \
|
||||
winhelo2.obj a_nask.obj
|
||||
|
||||
winhelo2.hrb : winhelo2.bim Makefile
|
||||
$(BIM2HRB) winhelo2.bim winhelo2.hrb 0
|
||||
|
||||
winhelo3.bim : winhelo3.obj a_nask.obj Makefile
|
||||
$(OBJ2BIM) @$(RULEFILE) out:winhelo3.bim stack:1k map:winhelo3.map \
|
||||
winhelo3.obj a_nask.obj
|
||||
|
||||
winhelo3.hrb : winhelo3.bim Makefile
|
||||
$(BIM2HRB) winhelo3.bim winhelo3.hrb 40k
|
||||
|
||||
star1.bim : star1.obj a_nask.obj Makefile
|
||||
$(OBJ2BIM) @$(RULEFILE) out:star1.bim stack:1k map:star1.map \
|
||||
star1.obj a_nask.obj
|
||||
|
||||
star1.hrb : star1.bim Makefile
|
||||
$(BIM2HRB) star1.bim star1.hrb 47k
|
||||
|
||||
stars.bim : stars.obj a_nask.obj Makefile
|
||||
$(OBJ2BIM) @$(RULEFILE) out:stars.bim stack:1k map:stars.map \
|
||||
stars.obj a_nask.obj
|
||||
|
||||
stars.hrb : stars.bim Makefile
|
||||
$(BIM2HRB) stars.bim stars.hrb 47k
|
||||
|
||||
stars2.bim : stars2.obj a_nask.obj Makefile
|
||||
$(OBJ2BIM) @$(RULEFILE) out:stars2.bim stack:1k map:stars2.map \
|
||||
stars2.obj a_nask.obj
|
||||
|
||||
stars2.hrb : stars2.bim Makefile
|
||||
$(BIM2HRB) stars2.bim stars2.hrb 47k
|
||||
|
||||
lines.bim : lines.obj a_nask.obj Makefile
|
||||
$(OBJ2BIM) @$(RULEFILE) out:lines.bim stack:1k map:lines.map \
|
||||
lines.obj a_nask.obj
|
||||
|
||||
lines.hrb : lines.bim Makefile
|
||||
$(BIM2HRB) lines.bim lines.hrb 48k
|
||||
|
||||
walk.bim : walk.obj a_nask.obj Makefile
|
||||
$(OBJ2BIM) @$(RULEFILE) out:walk.bim stack:1k map:walk.map \
|
||||
walk.obj a_nask.obj
|
||||
|
||||
walk.hrb : walk.bim Makefile
|
||||
$(BIM2HRB) walk.bim walk.hrb 48k
|
||||
|
||||
noodle.bim : noodle.obj a_nask.obj Makefile
|
||||
$(OBJ2BIM) @$(RULEFILE) out:noodle.bim stack:1k map:noodle.map \
|
||||
noodle.obj a_nask.obj
|
||||
|
||||
noodle.hrb : noodle.bim Makefile
|
||||
$(BIM2HRB) noodle.bim noodle.hrb 40k
|
||||
|
||||
haribote.img : ipl10.bin haribote.sys Makefile \
|
||||
hello.hrb hello2.hrb a.hrb hello3.hrb hello4.hrb hello5.hrb \
|
||||
winhelo.hrb winhelo2.hrb winhelo3.hrb star1.hrb stars.hrb stars2.hrb \
|
||||
lines.hrb walk.hrb noodle.hrb
|
||||
$(EDIMG) imgin:../z_tools/fdimg0at.tek \
|
||||
wbinimg src:ipl10.bin len:512 from:0 to:0 \
|
||||
copy from:haribote.sys to:@: \
|
||||
copy from:ipl10.nas to:@: \
|
||||
copy from:make.bat to:@: \
|
||||
copy from:hello.hrb to:@: \
|
||||
copy from:hello2.hrb to:@: \
|
||||
copy from:a.hrb to:@: \
|
||||
copy from:hello3.hrb to:@: \
|
||||
copy from:hello4.hrb to:@: \
|
||||
copy from:hello5.hrb to:@: \
|
||||
copy from:winhelo.hrb to:@: \
|
||||
copy from:winhelo2.hrb to:@: \
|
||||
copy from:winhelo3.hrb to:@: \
|
||||
copy from:star1.hrb to:@: \
|
||||
copy from:stars.hrb to:@: \
|
||||
copy from:stars2.hrb to:@: \
|
||||
copy from:lines.hrb to:@: \
|
||||
copy from:walk.hrb to:@: \
|
||||
copy from:noodle.hrb 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.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
|
||||
8
24_day/a.c
Normal file
8
24_day/a.c
Normal file
@@ -0,0 +1,8 @@
|
||||
void api_putchar(int c);
|
||||
void api_end(void);
|
||||
|
||||
void HariMain(void)
|
||||
{
|
||||
api_putchar('A');
|
||||
api_end();
|
||||
}
|
||||
223
24_day/a_nask.nas
Normal file
223
24_day/a_nask.nas
Normal file
@@ -0,0 +1,223 @@
|
||||
[FORMAT "WCOFF"] ; 生成对象文件的模式
|
||||
[INSTRSET "i486p"] ; 表示使用486兼容指令集
|
||||
[BITS 32] ; 生成32位模式机器语言
|
||||
[FILE "a_nask.nas"] ; 源文件名信息
|
||||
|
||||
GLOBAL _api_putchar
|
||||
GLOBAL _api_putstr0
|
||||
GLOBAL _api_end
|
||||
GLOBAL _api_openwin
|
||||
GLOBAL _api_putstrwin
|
||||
GLOBAL _api_boxfilwin
|
||||
GLOBAL _api_initmalloc
|
||||
GLOBAL _api_malloc
|
||||
GLOBAL _api_free
|
||||
GLOBAL _api_point
|
||||
GLOBAL _api_refreshwin
|
||||
GLOBAL _api_linewin
|
||||
GLOBAL _api_closewin
|
||||
GLOBAL _api_getkey
|
||||
GLOBAL _api_alloctimer
|
||||
GLOBAL _api_inittimer
|
||||
GLOBAL _api_settimer
|
||||
GLOBAL _api_freetimer
|
||||
|
||||
[SECTION .text]
|
||||
|
||||
_api_putchar: ; void api_putchar(int c);
|
||||
MOV EDX,1
|
||||
MOV AL,[ESP+4] ; c
|
||||
INT 0x40
|
||||
RET
|
||||
|
||||
_api_putstr0: ; void api_putstr0(char *s);
|
||||
PUSH EBX
|
||||
MOV EDX,2
|
||||
MOV EBX,[ESP+8] ; s
|
||||
INT 0x40
|
||||
POP EBX
|
||||
RET
|
||||
|
||||
_api_end: ; void api_end(void);
|
||||
MOV EDX,4
|
||||
INT 0x40
|
||||
|
||||
_api_openwin: ; int api_openwin(char *buf, int xsiz, int ysiz, int col_inv, char *title);
|
||||
PUSH EDI
|
||||
PUSH ESI
|
||||
PUSH EBX
|
||||
MOV EDX,5
|
||||
MOV EBX,[ESP+16] ; buf
|
||||
MOV ESI,[ESP+20] ; xsiz
|
||||
MOV EDI,[ESP+24] ; ysiz
|
||||
MOV EAX,[ESP+28] ; col_inv
|
||||
MOV ECX,[ESP+32] ; title
|
||||
INT 0x40
|
||||
POP EBX
|
||||
POP ESI
|
||||
POP EDI
|
||||
RET
|
||||
|
||||
_api_putstrwin: ; void api_putstrwin(int win, int x, int y, int col, int len, char *str);
|
||||
PUSH EDI
|
||||
PUSH ESI
|
||||
PUSH EBP
|
||||
PUSH EBX
|
||||
MOV EDX,6
|
||||
MOV EBX,[ESP+20] ; win
|
||||
MOV ESI,[ESP+24] ; x
|
||||
MOV EDI,[ESP+28] ; y
|
||||
MOV EAX,[ESP+32] ; col
|
||||
MOV ECX,[ESP+36] ; len
|
||||
MOV EBP,[ESP+40] ; str
|
||||
INT 0x40
|
||||
POP EBX
|
||||
POP EBP
|
||||
POP ESI
|
||||
POP EDI
|
||||
RET
|
||||
|
||||
_api_boxfilwin: ; void api_boxfilwin(int win, int x0, int y0, int x1, int y1, int col);
|
||||
PUSH EDI
|
||||
PUSH ESI
|
||||
PUSH EBP
|
||||
PUSH EBX
|
||||
MOV EDX,7
|
||||
MOV EBX,[ESP+20] ; win
|
||||
MOV EAX,[ESP+24] ; x0
|
||||
MOV ECX,[ESP+28] ; y0
|
||||
MOV ESI,[ESP+32] ; x1
|
||||
MOV EDI,[ESP+36] ; y1
|
||||
MOV EBP,[ESP+40] ; col
|
||||
INT 0x40
|
||||
POP EBX
|
||||
POP EBP
|
||||
POP ESI
|
||||
POP EDI
|
||||
RET
|
||||
|
||||
_api_initmalloc: ; void api_initmalloc(void);
|
||||
PUSH EBX
|
||||
MOV EDX,8
|
||||
MOV EBX,[CS:0x0020] ; malloc内存空间的地址
|
||||
MOV EAX,EBX
|
||||
ADD EAX,32*1024 ; 加上32KB
|
||||
MOV ECX,[CS:0x0000] ; 数据段的大小
|
||||
SUB ECX,EAX
|
||||
INT 0x40
|
||||
POP EBX
|
||||
RET
|
||||
|
||||
_api_malloc: ; char *api_malloc(int size);
|
||||
PUSH EBX
|
||||
MOV EDX,9
|
||||
MOV EBX,[CS:0x0020]
|
||||
MOV ECX,[ESP+8] ; size
|
||||
INT 0x40
|
||||
POP EBX
|
||||
RET
|
||||
|
||||
_api_free: ; void api_free(char *addr, int size);
|
||||
PUSH EBX
|
||||
MOV EDX,10
|
||||
MOV EBX,[CS:0x0020]
|
||||
MOV EAX,[ESP+ 8] ; addr
|
||||
MOV ECX,[ESP+12] ; size
|
||||
INT 0x40
|
||||
POP EBX
|
||||
RET
|
||||
|
||||
_api_point: ; void api_point(int win, int x, int y, int col);
|
||||
PUSH EDI
|
||||
PUSH ESI
|
||||
PUSH EBX
|
||||
MOV EDX,11
|
||||
MOV EBX,[ESP+16] ; win
|
||||
MOV ESI,[ESP+20] ; x
|
||||
MOV EDI,[ESP+24] ; y
|
||||
MOV EAX,[ESP+28] ; col
|
||||
INT 0x40
|
||||
POP EBX
|
||||
POP ESI
|
||||
POP EDI
|
||||
RET
|
||||
|
||||
_api_refreshwin: ; void api_refreshwin(int win, int x0, int y0, int x1, int y1);
|
||||
PUSH EDI
|
||||
PUSH ESI
|
||||
PUSH EBX
|
||||
MOV EDX,12
|
||||
MOV EBX,[ESP+16] ; win
|
||||
MOV EAX,[ESP+20] ; x0
|
||||
MOV ECX,[ESP+24] ; y0
|
||||
MOV ESI,[ESP+28] ; x1
|
||||
MOV EDI,[ESP+32] ; y1
|
||||
INT 0x40
|
||||
POP EBX
|
||||
POP ESI
|
||||
POP EDI
|
||||
RET
|
||||
|
||||
_api_linewin: ; void api_linewin(int win, int x0, int y0, int x1, int y1, int col);
|
||||
PUSH EDI
|
||||
PUSH ESI
|
||||
PUSH EBP
|
||||
PUSH EBX
|
||||
MOV EDX,13
|
||||
MOV EBX,[ESP+20] ; win
|
||||
MOV EAX,[ESP+24] ; x0
|
||||
MOV ECX,[ESP+28] ; y0
|
||||
MOV ESI,[ESP+32] ; x1
|
||||
MOV EDI,[ESP+36] ; y1
|
||||
MOV EBP,[ESP+40] ; col
|
||||
INT 0x40
|
||||
POP EBX
|
||||
POP EBP
|
||||
POP ESI
|
||||
POP EDI
|
||||
RET
|
||||
|
||||
_api_closewin: ; void api_closewin(int win);
|
||||
PUSH EBX
|
||||
MOV EDX,14
|
||||
MOV EBX,[ESP+8] ; win
|
||||
INT 0x40
|
||||
POP EBX
|
||||
RET
|
||||
|
||||
_api_getkey: ; int api_getkey(int mode);
|
||||
MOV EDX,15
|
||||
MOV EAX,[ESP+4] ; mode
|
||||
INT 0x40
|
||||
RET
|
||||
|
||||
_api_alloctimer: ; int api_alloctimer(void);
|
||||
MOV EDX,16
|
||||
INT 0x40
|
||||
RET
|
||||
|
||||
_api_inittimer: ; void api_inittimer(int timer, int data);
|
||||
PUSH EBX
|
||||
MOV EDX,17
|
||||
MOV EBX,[ESP+ 8] ; timer
|
||||
MOV EAX,[ESP+12] ; data
|
||||
INT 0x40
|
||||
POP EBX
|
||||
RET
|
||||
|
||||
_api_settimer: ; void api_settimer(int timer, int time);
|
||||
PUSH EBX
|
||||
MOV EDX,18
|
||||
MOV EBX,[ESP+ 8] ; timer
|
||||
MOV EAX,[ESP+12] ; time
|
||||
INT 0x40
|
||||
POP EBX
|
||||
RET
|
||||
|
||||
_api_freetimer: ; void api_freetimer(int timer);
|
||||
PUSH EBX
|
||||
MOV EDX,19
|
||||
MOV EBX,[ESP+ 8] ; timer
|
||||
INT 0x40
|
||||
POP EBX
|
||||
RET
|
||||
202
24_day/asmhead.nas
Normal file
202
24_day/asmhead.nas
Normal file
@@ -0,0 +1,202 @@
|
||||
; haribote-os boot asm
|
||||
; TAB=4
|
||||
|
||||
[INSTRSET "i486p"]
|
||||
|
||||
VBEMODE EQU 0x105 ; 1024 x 768 x 8bit 彩色
|
||||
; 显示模式
|
||||
; 0x100 : 640 x 400 x 8bit 彩色
|
||||
; 0x101 : 640 x 480 x 8bit 彩色
|
||||
; 0x103 : 800 x 600 x 8bit 彩色
|
||||
; 0x105 : 1024 x 768 x 8bit 彩色
|
||||
; 0x107 : 1280 x 1024 x 8bit 彩色
|
||||
|
||||
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 ; 这个的程序要被装载的内存地址
|
||||
|
||||
; 确认VBE是否存在
|
||||
|
||||
MOV AX,0x9000
|
||||
MOV ES,AX
|
||||
MOV DI,0
|
||||
MOV AX,0x4f00
|
||||
INT 0x10
|
||||
CMP AX,0x004f
|
||||
JNE scrn320
|
||||
|
||||
; 检查VBE的版本
|
||||
|
||||
MOV AX,[ES:DI+4]
|
||||
CMP AX,0x0200
|
||||
JB scrn320 ; if (AX < 0x0200) goto scrn320
|
||||
|
||||
; 取得画面模式信息
|
||||
|
||||
MOV CX,VBEMODE
|
||||
MOV AX,0x4f01
|
||||
INT 0x10
|
||||
CMP AX,0x004f
|
||||
JNE scrn320
|
||||
|
||||
; 画面模式信息的确认
|
||||
CMP BYTE [ES:DI+0x19],8 ;颜色数必须为8
|
||||
JNE scrn320
|
||||
CMP BYTE [ES:DI+0x1b],4 ;颜色的指定方法必须为4(4是调色板模式)
|
||||
JNE scrn320
|
||||
MOV AX,[ES:DI+0x00] ;模式属性bit7不是1就不能加上0x4000
|
||||
AND AX,0x0080
|
||||
JZ scrn320 ; 模式属性的bit7是0,所以放弃
|
||||
|
||||
; 画面设置
|
||||
|
||||
MOV BX,VBEMODE+0x4000
|
||||
MOV AX,0x4f02
|
||||
INT 0x10
|
||||
MOV BYTE [VMODE],8 ; 屏幕的模式(参考C语言的引用)
|
||||
MOV AX,[ES:DI+0x12]
|
||||
MOV [SCRNX],AX
|
||||
MOV AX,[ES:DI+0x14]
|
||||
MOV [SCRNY],AX
|
||||
MOV EAX,[ES:DI+0x28] ;VRAM的地址
|
||||
MOV [VRAM],EAX
|
||||
JMP keystatus
|
||||
|
||||
scrn320:
|
||||
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 获取指示灯状态
|
||||
|
||||
keystatus:
|
||||
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能够访问1MB以上的内存空间,设定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为0(禁用分页)
|
||||
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 ; 可以读写的段(segment)32bit
|
||||
DW 0xffff,0x0000,0x9a28,0x0047 ; 可执行的文件的32bit寄存器(bootpack用)
|
||||
|
||||
DW 0
|
||||
GDTR0:
|
||||
DW 8*3-1
|
||||
DD GDT0
|
||||
|
||||
ALIGNB 16
|
||||
bootpack:
|
||||
371
24_day/bootpack.c
Normal file
371
24_day/bootpack.c
Normal file
@@ -0,0 +1,371 @@
|
||||
/* bootpack */
|
||||
|
||||
#include "bootpack.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#define KEYCMD_LED 0xed
|
||||
|
||||
int keywin_off(struct SHEET *key_win, struct SHEET *sht_win, int cur_c, int cur_x);
|
||||
int keywin_on(struct SHEET *key_win, struct SHEET *sht_win, int cur_c);
|
||||
|
||||
void HariMain(void)
|
||||
{
|
||||
struct BOOTINFO *binfo = (struct BOOTINFO *) ADR_BOOTINFO;
|
||||
struct SHTCTL *shtctl;
|
||||
char s[40];
|
||||
struct FIFO32 fifo, keycmd;
|
||||
int fifobuf[128], keycmd_buf[32];
|
||||
int mx, my, i, cursor_x, cursor_c;
|
||||
unsigned int memtotal;
|
||||
struct MOUSE_DEC mdec;
|
||||
struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR;
|
||||
unsigned char *buf_back, buf_mouse[256], *buf_win, *buf_cons;
|
||||
struct SHEET *sht_back, *sht_mouse, *sht_win, *sht_cons;
|
||||
struct TASK *task_a, *task_cons;
|
||||
struct TIMER *timer;
|
||||
static char keytable0[0x80] = {
|
||||
0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '^', 0, 0,
|
||||
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '@', '[', 0, 0, 'A', 'S',
|
||||
'D', 'F', 'G', 'H', 'J', 'K', 'L', ';', ':', 0, 0, ']', 'Z', 'X', 'C', 'V',
|
||||
'B', 'N', 'M', ',', '.', '/', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, '7', '8', '9', '-', '4', '5', '6', '+', '1',
|
||||
'2', '3', '0', '.', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0x5c, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x5c, 0, 0
|
||||
};
|
||||
static char keytable1[0x80] = {
|
||||
0, 0, '!', 0x22, '#', '$', '%', '&', 0x27, '(', ')', '~', '=', '~', 0, 0,
|
||||
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '`', '{', 0, 0, 'A', 'S',
|
||||
'D', 'F', 'G', 'H', 'J', 'K', 'L', '+', '*', 0, 0, '}', 'Z', 'X', 'C', 'V',
|
||||
'B', 'N', 'M', '<', '>', '?', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, '7', '8', '9', '-', '4', '5', '6', '+', '1',
|
||||
'2', '3', '0', '.', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, '_', 0, 0, 0, 0, 0, 0, 0, 0, 0, '|', 0, 0
|
||||
};
|
||||
int key_shift = 0, key_leds = (binfo->leds >> 4) & 7, keycmd_wait = -1;
|
||||
struct CONSOLE *cons;
|
||||
int j, x, y, mmx = -1, mmy = -1;
|
||||
struct SHEET *sht = 0, *key_win;
|
||||
|
||||
init_gdtidt();
|
||||
init_pic();
|
||||
io_sti(); /* IDT/PIC的初始化已经完成,于是开放CPU的中断 */
|
||||
fifo32_init(&fifo, 128, fifobuf, 0);
|
||||
init_pit();
|
||||
init_keyboard(&fifo, 256);
|
||||
enable_mouse(&fifo, 512, &mdec);
|
||||
io_out8(PIC0_IMR, 0xf8); /* 设定PIT和PIC1以及键盘为许可(11111000) */
|
||||
io_out8(PIC1_IMR, 0xef); /* 开放鼠标中断(11101111) */
|
||||
fifo32_init(&keycmd, 32, keycmd_buf, 0);
|
||||
|
||||
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);
|
||||
task_a = task_init(memman);
|
||||
fifo.task = task_a;
|
||||
task_run(task_a, 1, 2);
|
||||
*((int *) 0x0fe4) = (int) shtctl;
|
||||
|
||||
/* sht_back */
|
||||
sht_back = 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); /* 无透明色 */
|
||||
init_screen8(buf_back, binfo->scrnx, binfo->scrny);
|
||||
|
||||
/* sht_cons */
|
||||
sht_cons = sheet_alloc(shtctl);
|
||||
buf_cons = (unsigned char *) memman_alloc_4k(memman, 256 * 165);
|
||||
sheet_setbuf(sht_cons, buf_cons, 256, 165, -1); /* 无透明色 */
|
||||
make_window8(buf_cons, 256, 165, "console", 0);
|
||||
make_textbox8(sht_cons, 8, 28, 240, 128, COL8_000000);
|
||||
task_cons = task_alloc();
|
||||
task_cons->tss.esp = memman_alloc_4k(memman, 64 * 1024) + 64 * 1024 - 12;
|
||||
task_cons->tss.eip = (int) &console_task;
|
||||
task_cons->tss.es = 1 * 8;
|
||||
task_cons->tss.cs = 2 * 8;
|
||||
task_cons->tss.ss = 1 * 8;
|
||||
task_cons->tss.ds = 1 * 8;
|
||||
task_cons->tss.fs = 1 * 8;
|
||||
task_cons->tss.gs = 1 * 8;
|
||||
*((int *) (task_cons->tss.esp + 4)) = (int) sht_cons;
|
||||
*((int *) (task_cons->tss.esp + 8)) = memtotal;
|
||||
task_run(task_cons, 2, 2); /* level=2, priority=2 */
|
||||
|
||||
/* sht_win */
|
||||
sht_win = sheet_alloc(shtctl);
|
||||
buf_win = (unsigned char *) memman_alloc_4k(memman, 160 * 52);
|
||||
sheet_setbuf(sht_win, buf_win, 144, 52, -1); /* 无透明色 */
|
||||
make_window8(buf_win, 144, 52, "task_a", 1);
|
||||
make_textbox8(sht_win, 8, 28, 128, 16, COL8_FFFFFF);
|
||||
cursor_x = 8;
|
||||
cursor_c = COL8_FFFFFF;
|
||||
timer = timer_alloc();
|
||||
timer_init(timer, &fifo, 1);
|
||||
timer_settime(timer, 50);
|
||||
|
||||
/* sht_mouse */
|
||||
sht_mouse = sheet_alloc(shtctl);
|
||||
sheet_setbuf(sht_mouse, buf_mouse, 16, 16, 99);
|
||||
init_mouse_cursor8(buf_mouse, 99);
|
||||
mx = (binfo->scrnx - 16) / 2; /* 计算坐标使其位于画面中央 */
|
||||
my = (binfo->scrny - 28 - 16) / 2;
|
||||
|
||||
sheet_slide(sht_back, 0, 0);
|
||||
sheet_slide(sht_cons, 32, 4);
|
||||
sheet_slide(sht_win, 64, 56);
|
||||
sheet_slide(sht_mouse, mx, my);
|
||||
sheet_updown(sht_back, 0);
|
||||
sheet_updown(sht_cons, 1);
|
||||
sheet_updown(sht_win, 2);
|
||||
sheet_updown(sht_mouse, 3);
|
||||
key_win = sht_win;
|
||||
sht_cons->task = task_cons;
|
||||
sht_cons->flags |= 0x20; /*有光标*/
|
||||
|
||||
/*为了避免和键盘当前状态冲突,在一开始先进行设置*/
|
||||
fifo32_put(&keycmd, KEYCMD_LED);
|
||||
fifo32_put(&keycmd, key_leds);
|
||||
|
||||
for (;;) {
|
||||
if (fifo32_status(&keycmd) > 0 && keycmd_wait < 0) {
|
||||
/*如果存在向键盘控制器发送的数据,则发送它 */
|
||||
keycmd_wait = fifo32_get(&keycmd);
|
||||
wait_KBC_sendready();
|
||||
io_out8(PORT_KEYDAT, keycmd_wait);
|
||||
}
|
||||
io_cli();
|
||||
if (fifo32_status(&fifo) == 0) {
|
||||
task_sleep(task_a);
|
||||
io_sti();
|
||||
} else {
|
||||
i = fifo32_get(&fifo);
|
||||
io_sti();
|
||||
if (key_win->flags == 0) { /*输入窗口被关闭*/
|
||||
key_win = shtctl->sheets[shtctl->top - 1];
|
||||
cursor_c = keywin_on(key_win, sht_win, cursor_c);
|
||||
}
|
||||
if (256 <= i && i <= 511) { /* 键盘数据*/
|
||||
if (i < 0x80 + 256) { /*将按键编码转换为字符编码*/
|
||||
if (key_shift == 0) {
|
||||
s[0] = keytable0[i - 256];
|
||||
} else {
|
||||
s[0] = keytable1[i - 256];
|
||||
}
|
||||
} else {
|
||||
s[0] = 0;
|
||||
}
|
||||
if ('A' <= s[0] && s[0] <= 'Z') { /*当输入字符为英文字母时*/
|
||||
if (((key_leds & 4) == 0 && key_shift == 0) ||((key_leds & 4) != 0 && key_shift != 0)) {
|
||||
s[0] += 0x20; /*将大写字母转换为小写字母*/
|
||||
}
|
||||
}
|
||||
if (s[0] != 0) { /*一般字符*/
|
||||
if (key_win == sht_win) { /*发送给任务A */
|
||||
if (cursor_x < 128) {
|
||||
/*显示一个字符之后将光标后移一位*/
|
||||
s[1] = 0;
|
||||
putfonts8_asc_sht(sht_win, cursor_x, 28, COL8_000000, COL8_FFFFFF, s, 1);
|
||||
cursor_x += 8;
|
||||
}
|
||||
} else { /*发送给命令行窗口*/
|
||||
fifo32_put(&key_win->task->fifo, s[0] + 256);
|
||||
}
|
||||
}
|
||||
if (i == 256 + 0x0e) { /* 退格键 */
|
||||
if (key_win == sht_win) { /*发送给任务A */
|
||||
if (cursor_x > 8) {
|
||||
/*用空白擦除光标后将光标前移一位*/
|
||||
putfonts8_asc_sht(sht_win, cursor_x, 28, COL8_000000, COL8_FFFFFF, " ", 1);
|
||||
cursor_x -= 8;
|
||||
}
|
||||
} else { /*发送给命令行窗口*/
|
||||
fifo32_put(&key_win->task->fifo, 8 + 256);
|
||||
}
|
||||
}
|
||||
if (i == 256 + 0x1c) { /*回车键*/
|
||||
if (key_win != sht_win) { /*发送至命令行窗口*/
|
||||
fifo32_put(&key_win->task->fifo, 10 + 256);
|
||||
}
|
||||
}
|
||||
if (i == 256 + 0x0f) { /* Tab键 */
|
||||
cursor_c = keywin_off(key_win, sht_win, cursor_c, cursor_x);
|
||||
j = key_win->height - 1;
|
||||
if (j == 0) {
|
||||
j = shtctl->top - 1;
|
||||
}
|
||||
key_win = shtctl->sheets[j];
|
||||
cursor_c = keywin_on(key_win, sht_win, cursor_c);
|
||||
}
|
||||
if (i == 256 + 0x2a) { /*左Shift ON */
|
||||
key_shift |= 1;
|
||||
}
|
||||
if (i == 256 + 0x36) { /*右Shift ON */
|
||||
key_shift |= 2;
|
||||
}
|
||||
if (i == 256 + 0xaa) { /*左Shift OFF */
|
||||
key_shift &= ~1;
|
||||
}
|
||||
if (i == 256 + 0xb6) { /*右Shift OFF */
|
||||
key_shift &= ~2;
|
||||
}
|
||||
if (i == 256 + 0x3a) { /* CapsLock */
|
||||
key_leds ^= 4;
|
||||
fifo32_put(&keycmd, KEYCMD_LED);
|
||||
fifo32_put(&keycmd, key_leds);
|
||||
}
|
||||
if (i == 256 + 0x45) { /* NumLock */
|
||||
key_leds ^= 2;
|
||||
fifo32_put(&keycmd, KEYCMD_LED);
|
||||
fifo32_put(&keycmd, key_leds);
|
||||
}
|
||||
if (i == 256 + 0x46) { /* ScrollLock */
|
||||
key_leds ^= 1;
|
||||
fifo32_put(&keycmd, KEYCMD_LED);
|
||||
fifo32_put(&keycmd, key_leds);
|
||||
}
|
||||
if (i == 256 + 0x3b && key_shift != 0 && task_cons->tss.ss0 != 0) { /* Shift+F1 */
|
||||
cons = (struct CONSOLE *) *((int *) 0x0fec);
|
||||
cons_putstr0(cons, "\nBreak(key) :\n");
|
||||
io_cli(); /*不能在改变寄存器值时切换到其他任务*/
|
||||
task_cons->tss.eax = (int) &(task_cons->tss.esp0);
|
||||
task_cons->tss.eip = (int) asm_end_app;
|
||||
io_sti();
|
||||
}
|
||||
if (i == 256 + 0x57 && shtctl->top > 2) { /* F11 */
|
||||
sheet_updown(shtctl->sheets[1], shtctl->top - 1);
|
||||
}
|
||||
if (i == 256 + 0xfa) { /*键盘成功接收到数据*/
|
||||
keycmd_wait = -1;
|
||||
}
|
||||
if (i == 256 + 0xfe) { /*键盘没有成功接收到数据*/
|
||||
wait_KBC_sendready();
|
||||
io_out8(PORT_KEYDAT, keycmd_wait);
|
||||
}
|
||||
/*重新显示光标*/
|
||||
if (cursor_c >= 0) {
|
||||
boxfill8(sht_win->buf, sht_win->bxsize, cursor_c, cursor_x, 28, cursor_x + 7, 43);
|
||||
}
|
||||
sheet_refresh(sht_win, cursor_x, 28, cursor_x + 8, 44);
|
||||
} else if (512 <= i && i <= 767) { /* 鼠标数据*/
|
||||
if (mouse_decode(&mdec, i - 512) != 0) {
|
||||
/* 已经收集了3字节的数据,移动光标 */
|
||||
mx += mdec.x;
|
||||
my += mdec.y;
|
||||
if (mx < 0) {
|
||||
mx = 0;
|
||||
}
|
||||
if (my < 0) {
|
||||
my = 0;
|
||||
}
|
||||
if (mx > binfo->scrnx - 1) {
|
||||
mx = binfo->scrnx - 1;
|
||||
}
|
||||
if (my > binfo->scrny - 1) {
|
||||
my = binfo->scrny - 1;
|
||||
}
|
||||
|
||||
sheet_slide(sht_mouse, mx, my);/* 包含sheet_refresh含sheet_refresh */
|
||||
|
||||
if ((mdec.btn & 0x01) != 0) { /* 按下左键 */
|
||||
if (mmx < 0) {
|
||||
/*如果处于通常模式*/
|
||||
/*按照从上到下的顺序寻找鼠标所指向的图层*/
|
||||
for (j = shtctl->top - 1; j > 0; j--) {
|
||||
sht = shtctl->sheets[j];
|
||||
x = mx - sht->vx0;
|
||||
y = my - sht->vy0;
|
||||
if (0 <= x && x < sht->bxsize && 0 <= y && y < sht->bysize) {
|
||||
if (sht->buf[y * sht->bxsize + x] != sht->col_inv) {
|
||||
sheet_updown(sht, shtctl->top - 1);
|
||||
if (sht != key_win) {
|
||||
cursor_c = keywin_off(key_win, sht_win, cursor_c, cursor_x);
|
||||
key_win = sht;
|
||||
cursor_c = keywin_on(key_win, sht_win, cursor_c);/*到此结束*/
|
||||
}
|
||||
if (3 <= x && x < sht->bxsize - 3 && 3 <= y && y < 21) {
|
||||
mmx = mx; /*进入窗口移动模式*/
|
||||
mmy = my;
|
||||
}
|
||||
if (sht->bxsize - 21 <= x && x < sht->bxsize - 5 && 5 <=y && y < 19) {
|
||||
/*点击“×”按钮*/
|
||||
if ((sht->flags & 0x10) != 0) { /*该窗口是否为应用程序窗口?*/
|
||||
cons = (struct CONSOLE *) *((int *) 0x0fec);
|
||||
cons_putstr0(cons, "\nBreak(mouse) :\n");
|
||||
io_cli(); /*强制结束处理中禁止切换任务*/
|
||||
task_cons->tss.eax = (int)
|
||||
&(task_cons->tss.esp0);
|
||||
task_cons->tss.eip = (int) asm_end_app;
|
||||
io_sti();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/*如果处于窗口移动模式*/
|
||||
x = mx - mmx; /*计算鼠标的移动距离*/
|
||||
y = my - mmy;
|
||||
sheet_slide(sht, sht->vx0 + x, sht->vy0 + y);
|
||||
mmx = mx; /*更新为移动后的坐标*/
|
||||
mmy = my;
|
||||
}
|
||||
} else {
|
||||
/*没有按下左键*/
|
||||
mmx = -1; /*返回通常模式*/
|
||||
}
|
||||
|
||||
}
|
||||
} else if (i <= 1) { /* 光标用定时器*/
|
||||
if (i != 0) {
|
||||
timer_init(timer, &fifo, 0); /* 下面设定0 */
|
||||
if (cursor_c >= 0) {
|
||||
cursor_c = COL8_000000;
|
||||
}
|
||||
} else {
|
||||
timer_init(timer, &fifo, 1); /* 下面设定1 */
|
||||
if (cursor_c >= 0) {
|
||||
cursor_c = COL8_FFFFFF;
|
||||
}
|
||||
}
|
||||
timer_settime(timer, 50);
|
||||
if (cursor_c >= 0) {
|
||||
boxfill8(sht_win->buf, sht_win->bxsize, cursor_c, cursor_x, 28, cursor_x + 7, 43);
|
||||
sheet_refresh(sht_win, cursor_x, 28, cursor_x + 8, 44);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int keywin_off(struct SHEET *key_win, struct SHEET *sht_win, int cur_c, int cur_x)
|
||||
{
|
||||
change_wtitle8(key_win, 0);
|
||||
if (key_win == sht_win) {
|
||||
cur_c = -1; /*删除光标*/
|
||||
boxfill8(sht_win->buf, sht_win->bxsize, COL8_FFFFFF, cur_x, 28, cur_x + 7, 43);
|
||||
} else {
|
||||
if ((key_win->flags & 0x20) != 0) {
|
||||
fifo32_put(&key_win->task->fifo, 3); /*命令行窗口光标OFF */
|
||||
}
|
||||
}
|
||||
return cur_c;
|
||||
}
|
||||
|
||||
int keywin_on(struct SHEET *key_win, struct SHEET *sht_win, int cur_c)
|
||||
{
|
||||
change_wtitle8(key_win, 1);
|
||||
if (key_win == sht_win) {
|
||||
cur_c = COL8_000000; /*显示光标*/
|
||||
} else {
|
||||
if ((key_win->flags & 0x20) != 0) {
|
||||
fifo32_put(&key_win->task->fifo, 2); /*命令行窗口光标ON */
|
||||
}
|
||||
}
|
||||
return cur_c;
|
||||
}
|
||||
271
24_day/bootpack.h
Normal file
271
24_day/bootpack.h
Normal file
@@ -0,0 +1,271 @@
|
||||
/* asmhead.nas */
|
||||
struct BOOTINFO { /* 0x0ff0-0x0fff */
|
||||
char cyls; /* 启动区读磁盘读到此为止 */
|
||||
char leds; /* 启动时键盘的LED的状态 */
|
||||
char vmode; /* 显卡模式为多少位彩色 */
|
||||
char reserve;
|
||||
short scrnx, scrny; /* 画面分辨率 */
|
||||
char *vram;
|
||||
};
|
||||
#define ADR_BOOTINFO 0x00000ff0
|
||||
#define ADR_DISKIMG 0x00100000
|
||||
|
||||
/* 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 load_tr(int tr);
|
||||
void asm_inthandler0c(void);
|
||||
void asm_inthandler0d(void);
|
||||
void asm_inthandler20(void);
|
||||
void asm_inthandler21(void);
|
||||
void asm_inthandler27(void);
|
||||
void asm_inthandler2c(void);
|
||||
unsigned int memtest_sub(unsigned int start, unsigned int end);
|
||||
void farjmp(int eip, int cs);
|
||||
void farcall(int eip, int cs);
|
||||
void asm_hrb_api(void);
|
||||
void start_app(int eip, int cs, int esp, int ds, int *tss_esp0);
|
||||
void asm_end_app(void);
|
||||
|
||||
/* fifo.c */
|
||||
struct FIFO32 {
|
||||
int *buf;
|
||||
int p, q, size, free, flags;
|
||||
struct TASK *task;
|
||||
};
|
||||
void fifo32_init(struct FIFO32 *fifo, int size, int *buf, struct TASK *task);
|
||||
int fifo32_put(struct FIFO32 *fifo, int data);
|
||||
int fifo32_get(struct FIFO32 *fifo);
|
||||
int fifo32_status(struct FIFO32 *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_TSS32 0x0089
|
||||
#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(struct FIFO32 *fifo, int data0);
|
||||
#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 FIFO32 *fifo, int data0, struct MOUSE_DEC *mdec);
|
||||
int mouse_decode(struct MOUSE_DEC *mdec, unsigned char dat);
|
||||
|
||||
/* 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 *ctl;
|
||||
struct TASK *task;
|
||||
};
|
||||
struct SHTCTL {
|
||||
unsigned char *vram, *map;
|
||||
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 SHEET *sht, int height);
|
||||
void sheet_refresh(struct SHEET *sht, int bx0, int by0, int bx1, int by1);
|
||||
void sheet_slide(struct SHEET *sht, int vx0, int vy0);
|
||||
void sheet_free(struct SHEET *sht);
|
||||
|
||||
/* timer.c */
|
||||
#define MAX_TIMER 500
|
||||
struct TIMER {
|
||||
struct TIMER *next;
|
||||
unsigned int timeout;
|
||||
char flags, flags2;
|
||||
struct FIFO32 *fifo;
|
||||
int data;
|
||||
};
|
||||
struct TIMERCTL {
|
||||
unsigned int count, next;
|
||||
struct TIMER *t0;
|
||||
struct TIMER timers0[MAX_TIMER];
|
||||
};
|
||||
extern struct TIMERCTL timerctl;
|
||||
void init_pit(void);
|
||||
struct TIMER *timer_alloc(void);
|
||||
void timer_free(struct TIMER *timer);
|
||||
void timer_init(struct TIMER *timer, struct FIFO32 *fifo, int data);
|
||||
void timer_settime(struct TIMER *timer, unsigned int timeout);
|
||||
void inthandler20(int *esp);
|
||||
int timer_cancel(struct TIMER *timer);
|
||||
void timer_cancelall(struct FIFO32 *fifo);
|
||||
|
||||
/* mtask.c */
|
||||
#define MAX_TASKS 1000 /*最大任务数量*/
|
||||
#define TASK_GDT0 3 /*定义从GDT的几号开始分配给TSS */
|
||||
#define MAX_TASKS_LV 100
|
||||
#define MAX_TASKLEVELS 10
|
||||
struct TSS32 {
|
||||
int backlink, esp0, ss0, esp1, ss1, esp2, ss2, cr3;
|
||||
int eip, eflags, eax, ecx, edx, ebx, esp, ebp, esi, edi;
|
||||
int es, cs, ss, ds, fs, gs;
|
||||
int ldtr, iomap;
|
||||
};
|
||||
struct TASK {
|
||||
int sel, flags; /* sel用来存放GDT的编号*/
|
||||
int level, priority; /* 优先级 */
|
||||
struct FIFO32 fifo;
|
||||
struct TSS32 tss;
|
||||
};
|
||||
struct TASKLEVEL {
|
||||
int running; /*正在运行的任务数量*/
|
||||
int now; /*这个变量用来记录当前正在运行的是哪个任务*/
|
||||
struct TASK *tasks[MAX_TASKS_LV];
|
||||
};
|
||||
struct TASKCTL {
|
||||
int now_lv; /*现在活动中的LEVEL */
|
||||
char lv_change; /*在下次任务切换时是否需要改变LEVEL */
|
||||
struct TASKLEVEL level[MAX_TASKLEVELS];
|
||||
struct TASK tasks0[MAX_TASKS];
|
||||
};
|
||||
extern struct TIMER *task_timer;
|
||||
struct TASK *task_init(struct MEMMAN *memman);
|
||||
struct TASK *task_alloc(void);
|
||||
void task_run(struct TASK *task, int level, int priority);
|
||||
void task_switch(void);
|
||||
void task_sleep(struct TASK *task);
|
||||
|
||||
/* window.c */
|
||||
void make_window8(unsigned char *buf, int xsize, int ysize, char *title, char act);
|
||||
void putfonts8_asc_sht(struct SHEET *sht, int x, int y, int c, int b, char *s, int l);
|
||||
void make_textbox8(struct SHEET *sht, int x0, int y0, int sx, int sy, int c);
|
||||
void make_wtitle8(unsigned char *buf, int xsize, char *title, char act);
|
||||
void change_wtitle8(struct SHEET *sht, char act);
|
||||
|
||||
/* console.c */
|
||||
struct CONSOLE {
|
||||
struct SHEET *sht;
|
||||
int cur_x, cur_y, cur_c;
|
||||
struct TIMER *timer;
|
||||
};
|
||||
void console_task(struct SHEET *sheet, unsigned int memtotal);
|
||||
void cons_putchar(struct CONSOLE *cons, int chr, char move);
|
||||
void cons_newline(struct CONSOLE *cons);
|
||||
void cons_putstr0(struct CONSOLE *cons, char *s);
|
||||
void cons_putstr1(struct CONSOLE *cons, char *s, int l);
|
||||
void cons_runcmd(char *cmdline, struct CONSOLE *cons, int *fat, unsigned int memtotal);
|
||||
void cmd_mem(struct CONSOLE *cons, unsigned int memtotal);
|
||||
void cmd_cls(struct CONSOLE *cons);
|
||||
void cmd_dir(struct CONSOLE *cons);
|
||||
void cmd_type(struct CONSOLE *cons, int *fat, char *cmdline);
|
||||
int cmd_app(struct CONSOLE *cons, int *fat, char *cmdline);
|
||||
int *hrb_api(int edi, int esi, int ebp, int esp, int ebx, int edx, int ecx, int eax);
|
||||
int *inthandler0c(int *esp);
|
||||
int *inthandler0d(int *esp);
|
||||
|
||||
/* file.c */
|
||||
struct FILEINFO {
|
||||
unsigned char name[8], ext[3], type;
|
||||
char reserve[10];
|
||||
unsigned short time, date, clustno;
|
||||
unsigned int size;
|
||||
};
|
||||
void file_readfat(int *fat, unsigned char *img);
|
||||
void file_loadfile(int clustno, int size, char *buf, int *fat, char *img);
|
||||
struct FILEINFO *file_search(char *name, struct FILEINFO *finfo, int max);
|
||||
3
24_day/bug2.c
Normal file
3
24_day/bug2.c
Normal file
@@ -0,0 +1,3 @@
|
||||
void HariMain(void){
|
||||
for (;;) { }
|
||||
}
|
||||
9
24_day/bug3.c
Normal file
9
24_day/bug3.c
Normal file
@@ -0,0 +1,9 @@
|
||||
void api_putchar(int c);
|
||||
void api_end(void);
|
||||
|
||||
void HariMain(void)
|
||||
{
|
||||
for (;;) {
|
||||
api_putchar('a');
|
||||
}
|
||||
}
|
||||
505
24_day/console.c
Normal file
505
24_day/console.c
Normal file
@@ -0,0 +1,505 @@
|
||||
/* 命令行窗口相关 */
|
||||
|
||||
#include "bootpack.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
void console_task(struct SHEET *sheet, unsigned int memtotal)
|
||||
{
|
||||
struct TIMER *timer;
|
||||
struct TASK *task = task_now();
|
||||
struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR;
|
||||
int i, fifobuf[128], *fat = (int *) memman_alloc_4k(memman, 4 * 2880);
|
||||
struct CONSOLE cons;
|
||||
char cmdline[30];
|
||||
cons.sht = sheet;
|
||||
cons.cur_x = 8;
|
||||
cons.cur_y = 28;
|
||||
cons.cur_c = -1;
|
||||
*((int *) 0x0fec) = (int) &cons;
|
||||
|
||||
fifo32_init(&task->fifo, 128, fifobuf, task);
|
||||
timer = timer_alloc();
|
||||
timer_init(timer, &task->fifo, 1);
|
||||
timer_settime(timer, 50);
|
||||
file_readfat(fat, (unsigned char *) (ADR_DISKIMG + 0x000200));
|
||||
|
||||
/*显示提示符*/
|
||||
cons_putchar(&cons, '>', 1);
|
||||
for (;;) {
|
||||
io_cli();
|
||||
if (fifo32_status(&task->fifo) == 0) {
|
||||
task_sleep(task);
|
||||
io_sti();
|
||||
} else {
|
||||
i = fifo32_get(&task->fifo);
|
||||
io_sti();
|
||||
if (i <= 1) { /*光标用定时器*/
|
||||
if (i != 0) {
|
||||
timer_init(timer, &task->fifo, 0); /*下次置0 */
|
||||
if (cons.cur_c >= 0) {
|
||||
cons.cur_c = COL8_FFFFFF;
|
||||
}
|
||||
} else {
|
||||
timer_init(timer, &task->fifo, 1); /*下次置1 */
|
||||
if (cons.cur_c >= 0) {
|
||||
cons.cur_c = COL8_000000;
|
||||
}
|
||||
}
|
||||
timer_settime(timer, 50);
|
||||
}
|
||||
if (i == 2) { /*光标ON */
|
||||
cons.cur_c = COL8_FFFFFF;
|
||||
}
|
||||
if (i == 3) { /*光标OFF */
|
||||
boxfill8(sheet->buf, sheet->bxsize, COL8_000000, cons.cur_x, cons.cur_y, cons.cur_x + 7, cons.cur_y + 15);
|
||||
cons.cur_c = -1;
|
||||
}
|
||||
if (256 <= i && i <= 511) { /*键盘数据(通过任务A)*/
|
||||
if (i == 8 + 256) {
|
||||
/*退格键*/
|
||||
if (cons.cur_x > 16) {
|
||||
/*用空格擦除光标后将光标前移一位*/
|
||||
cons_putchar(&cons, ' ', 0);
|
||||
cons.cur_x -= 8;
|
||||
}
|
||||
} else if (i == 10 + 256) {
|
||||
/*回车键*/
|
||||
/*将光标用空格擦除后换行 */
|
||||
cons_putchar(&cons, ' ', 0);
|
||||
cmdline[cons.cur_x / 8 - 2] = 0;
|
||||
cons_newline(&cons);
|
||||
cons_runcmd(cmdline, &cons, fat, memtotal); /*运行命令*/
|
||||
/*显示提示符*/
|
||||
cons_putchar(&cons, '>', 1);
|
||||
} else {
|
||||
/*一般字符*/
|
||||
if (cons.cur_x < 240) {
|
||||
/*显示一个字符之后将光标后移一位*/
|
||||
cmdline[cons.cur_x / 8 - 2] = i - 256;
|
||||
cons_putchar(&cons, i - 256, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*重新显示光标*/
|
||||
if (cons.cur_c >= 0) {
|
||||
boxfill8(sheet->buf, sheet->bxsize, cons.cur_c, cons.cur_x, cons.cur_y, cons.cur_x + 7, cons.cur_y + 15);
|
||||
}
|
||||
sheet_refresh(sheet, cons.cur_x, cons.cur_y, cons.cur_x + 8, cons.cur_y + 16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cons_putchar(struct CONSOLE *cons, int chr, char move)
|
||||
{
|
||||
char s[2];
|
||||
s[0] = chr;
|
||||
s[1] = 0;
|
||||
if (s[0] == 0x09) { /*制表符*/
|
||||
for (;;) {
|
||||
putfonts8_asc_sht(cons->sht, cons->cur_x, cons->cur_y, COL8_FFFFFF, COL8_000000, " ", 1);
|
||||
cons->cur_x += 8;
|
||||
if (cons->cur_x == 8 + 240) {
|
||||
cons_newline(cons);
|
||||
}
|
||||
if (((cons->cur_x - 8) & 0x1f) == 0) {
|
||||
break; /*被32整除则break*/
|
||||
}
|
||||
}
|
||||
} else if (s[0] == 0x0a) { /*换行*/
|
||||
cons_newline(cons);
|
||||
} else if (s[0] == 0x0d) { /*回车*/
|
||||
/*先不做任何操作*/
|
||||
} else { /*一般字符*/
|
||||
putfonts8_asc_sht(cons->sht, cons->cur_x, cons->cur_y, COL8_FFFFFF, COL8_000000, s, 1);
|
||||
if (move != 0) {
|
||||
/* move为0时光标不后移*/
|
||||
cons->cur_x += 8;
|
||||
if (cons->cur_x == 8 + 240) {
|
||||
cons_newline(cons);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void cons_newline(struct CONSOLE *cons)
|
||||
{
|
||||
int x, y;
|
||||
struct SHEET *sheet = cons->sht;
|
||||
if (cons->cur_y < 28 + 112) {
|
||||
cons->cur_y += 16; /*到下一行*/
|
||||
} else {
|
||||
/*滚动*/
|
||||
for (y = 28; y < 28 + 112; y++) {
|
||||
for (x = 8; x < 8 + 240; x++) {
|
||||
sheet->buf[x + y * sheet->bxsize] = sheet->buf[x + (y + 16) * sheet->bxsize];
|
||||
}
|
||||
}
|
||||
for (y = 28 + 112; y < 28 + 128; y++) {
|
||||
for (x = 8; x < 8 + 240; x++) {
|
||||
sheet->buf[x + y * sheet->bxsize] = COL8_000000;
|
||||
}
|
||||
}
|
||||
sheet_refresh(sheet, 8, 28, 8 + 240, 28 + 128);
|
||||
}
|
||||
cons->cur_x = 8;
|
||||
return;
|
||||
}
|
||||
|
||||
void cons_putstr0(struct CONSOLE *cons, char *s)
|
||||
{
|
||||
for (; *s != 0; s++) {
|
||||
cons_putchar(cons, *s, 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void cons_putstr1(struct CONSOLE *cons, char *s, int l)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < l; i++) {
|
||||
cons_putchar(cons, s[i], 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void cons_runcmd(char *cmdline, struct CONSOLE *cons, int *fat, unsigned int memtotal)
|
||||
{
|
||||
if (strcmp(cmdline, "mem") == 0) {
|
||||
cmd_mem(cons, memtotal);
|
||||
} else if (strcmp(cmdline, "cls") == 0) {
|
||||
cmd_cls(cons);
|
||||
} else if (strcmp(cmdline, "dir") == 0 || strcmp(cmdline, "ls") == 0) {
|
||||
cmd_dir(cons);
|
||||
} else if (strncmp(cmdline, "type ", 5) == 0) {
|
||||
cmd_type(cons, fat, cmdline);
|
||||
} else if (cmdline[0] != 0) {
|
||||
if (cmd_app(cons, fat, cmdline) == 0) {
|
||||
/*不是命令,不是应用程序,也不是空行*/
|
||||
cons_putstr0(cons, "Bad command.\n\n");
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void cmd_mem(struct CONSOLE *cons, unsigned int memtotal)
|
||||
{
|
||||
struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR;
|
||||
char s[60];
|
||||
sprintf(s, "total %dMB\nfree %dKB\n\n", memtotal / (1024 * 1024), memman_total(memman) / 1024);
|
||||
cons_putstr0(cons, s);
|
||||
return;
|
||||
}
|
||||
|
||||
void cmd_cls(struct CONSOLE *cons)
|
||||
{
|
||||
int x, y;
|
||||
struct SHEET *sheet = cons->sht;
|
||||
for (y = 28; y < 28 + 128; y++) {
|
||||
for (x = 8; x < 8 + 240; x++) {
|
||||
sheet->buf[x + y * sheet->bxsize] = COL8_000000;
|
||||
}
|
||||
}
|
||||
sheet_refresh(sheet, 8, 28, 8 + 240, 28 + 128);
|
||||
cons->cur_y = 28;
|
||||
return;
|
||||
}
|
||||
|
||||
void cmd_dir(struct CONSOLE *cons)
|
||||
{
|
||||
struct FILEINFO *finfo = (struct FILEINFO *) (ADR_DISKIMG + 0x002600);
|
||||
int i, j;
|
||||
char s[30];
|
||||
for (i = 0; i < 224; i++) {
|
||||
if (finfo[i].name[0] == 0x00) {
|
||||
break;
|
||||
}
|
||||
if (finfo[i].name[0] != 0xe5) {
|
||||
if ((finfo[i].type & 0x18) == 0) {
|
||||
sprintf(s, "filename.ext %7d\n", finfo[i].size);
|
||||
for (j = 0; j < 8; j++) {
|
||||
s[j] = finfo[i].name[j];
|
||||
}
|
||||
s[ 9] = finfo[i].ext[0];
|
||||
s[10] = finfo[i].ext[1];
|
||||
s[11] = finfo[i].ext[2];
|
||||
cons_putstr0(cons, s);
|
||||
}
|
||||
}
|
||||
}
|
||||
cons_newline(cons);
|
||||
return;
|
||||
}
|
||||
|
||||
void cmd_type(struct CONSOLE *cons, int *fat, char *cmdline)
|
||||
{
|
||||
struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR;
|
||||
struct FILEINFO *finfo = file_search(cmdline + 5, (struct FILEINFO *) (ADR_DISKIMG + 0x002600), 224);
|
||||
char *p;
|
||||
if (finfo != 0) {
|
||||
/*找到文件的情况*/
|
||||
p = (char *) memman_alloc_4k(memman, finfo->size);
|
||||
file_loadfile(finfo->clustno, finfo->size, p, fat, (char *) (ADR_DISKIMG + 0x003e00));
|
||||
cons_putstr1(cons, p, finfo->size);
|
||||
memman_free_4k(memman, (int) p, finfo->size);
|
||||
} else {
|
||||
/*没有找到文件的情况*/
|
||||
cons_putstr0(cons, "File not found.\n");
|
||||
}
|
||||
cons_newline(cons);
|
||||
return;
|
||||
}
|
||||
|
||||
int cmd_app(struct CONSOLE *cons, int *fat, char *cmdline)
|
||||
{
|
||||
struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR;
|
||||
struct FILEINFO *finfo;
|
||||
struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *) ADR_GDT;
|
||||
char name[18], *p, *q;
|
||||
struct TASK *task = task_now();
|
||||
int i, segsiz, datsiz, esp, dathrb;
|
||||
struct SHTCTL *shtctl;
|
||||
struct SHEET *sht;
|
||||
|
||||
/*根据命令行生成文件名*/
|
||||
for (i = 0; i < 13; i++) {
|
||||
if (cmdline[i] <= ' ') {
|
||||
break;
|
||||
}
|
||||
name[i] = cmdline[i];
|
||||
}
|
||||
name[i] = 0; /*暂且将文件名的后面置为0*/
|
||||
|
||||
/*寻找文件 */
|
||||
finfo = file_search(name, (struct FILEINFO *) (ADR_DISKIMG + 0x002600), 224);
|
||||
if (finfo == 0 && name[i -1]!= '.') {
|
||||
/*由于找不到文件,故在文件名后面加上“.hrb”后重新寻找*/
|
||||
name[i ] = '.';
|
||||
name[i + 1] = 'H';
|
||||
name[i + 2] = 'R';
|
||||
name[i + 3] = 'B';
|
||||
name[i + 4] = 0;
|
||||
finfo = file_search(name, (struct FILEINFO *) (ADR_DISKIMG + 0x002600), 224);
|
||||
}
|
||||
|
||||
if (finfo != 0) {
|
||||
/*找到文件的情况*/
|
||||
p = (char *) memman_alloc_4k(memman, finfo->size);
|
||||
file_loadfile(finfo->clustno, finfo->size, p, fat, (char *) (ADR_DISKIMG + 0x003e00));
|
||||
if (finfo->size >= 36 && strncmp(p + 4, "Hari", 4) == 0 && *p == 0x00) {
|
||||
segsiz = *((int *) (p + 0x0000));
|
||||
esp = *((int *) (p + 0x000c));
|
||||
datsiz = *((int *) (p + 0x0010));
|
||||
dathrb = *((int *) (p + 0x0014));
|
||||
q = (char *) memman_alloc_4k(memman, segsiz);
|
||||
*((int *) 0xfe8) = (int) q;
|
||||
set_segmdesc(gdt + 1003, finfo->size - 1, (int) p, AR_CODE32_ER + 0x60);
|
||||
set_segmdesc(gdt + 1004, segsiz - 1, (int) q, AR_DATA32_RW + 0x60);
|
||||
for (i = 0; i < datsiz; i++) {
|
||||
q[esp + i] = p[dathrb + i];
|
||||
}
|
||||
start_app(0x1b, 1003 * 8, esp, 1004 * 8, &(task->tss.esp0));
|
||||
shtctl = (struct SHTCTL *) *((int *) 0x0fe4);
|
||||
for (i = 0; i < MAX_SHEETS; i++) {
|
||||
sht = &(shtctl->sheets0[i]);
|
||||
if ((sht->flags & 0x11) == 0x11 && sht->task == task) {
|
||||
/*找到被应用程序遗留的窗口*/
|
||||
sheet_free(sht); /*关闭*/
|
||||
}
|
||||
}
|
||||
timer_cancelall(&task->fifo);
|
||||
memman_free_4k(memman, (int) q, segsiz);
|
||||
} else {
|
||||
cons_putstr0(cons, ".hrb file format error.\n");
|
||||
}
|
||||
memman_free_4k(memman, (int) p, finfo->size);
|
||||
cons_newline(cons);
|
||||
return 1;
|
||||
}
|
||||
/*没有找到文件的情况*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
int *hrb_api(int edi, int esi, int ebp, int esp, int ebx, int edx, int ecx, int eax)
|
||||
{
|
||||
int ds_base = *((int *) 0xfe8);
|
||||
struct TASK *task = task_now();
|
||||
struct CONSOLE *cons = (struct CONSOLE *) *((int *) 0x0fec);
|
||||
struct SHTCTL *shtctl = (struct SHTCTL *) *((int *) 0x0fe4);
|
||||
struct SHEET *sht;
|
||||
int *reg = &eax + 1; /* eax后面的地址*/
|
||||
/*强行改写通过PUSHAD保存的值*/
|
||||
/* reg[0] : EDI, reg[1] : ESI, reg[2] : EBP, reg[3] : ESP */
|
||||
/* reg[4] : EBX, reg[5] : EDX, reg[6] : ECX, reg[7] : EAX */
|
||||
int i;
|
||||
|
||||
if (edx == 1) {
|
||||
cons_putchar(cons, eax & 0xff, 1);
|
||||
} else if (edx == 2) {
|
||||
cons_putstr0(cons, (char *) ebx + ds_base);
|
||||
} else if (edx == 3) {
|
||||
cons_putstr1(cons, (char *) ebx + ds_base, ecx);
|
||||
} else if (edx == 4) {
|
||||
return &(task->tss.esp0);
|
||||
} else if (edx == 5) {
|
||||
sht = sheet_alloc(shtctl);
|
||||
sht->task = task;
|
||||
sht->flags |= 0x10;
|
||||
sheet_setbuf(sht, (char *) ebx + ds_base, esi, edi, eax);
|
||||
make_window8((char *) ebx + ds_base, esi, edi, (char *) ecx + ds_base, 0);
|
||||
sheet_slide(sht, 100, 50);
|
||||
sheet_updown(sht, 3); /*背景层高度3位于task_a之上*/
|
||||
reg[7] = (int) sht;
|
||||
} else if (edx == 6) {
|
||||
sht = (struct SHEET *) (ebx & 0xfffffffe);
|
||||
putfonts8_asc(sht->buf, sht->bxsize, esi, edi, eax, (char *) ebp + ds_base);
|
||||
if ((ebx & 1) == 0) {
|
||||
sheet_refresh(sht, esi, edi, esi + ecx * 8, edi + 16);
|
||||
}
|
||||
} else if (edx == 7) {
|
||||
sht = (struct SHEET *) (ebx & 0xfffffffe);
|
||||
boxfill8(sht->buf, sht->bxsize, ebp, eax, ecx, esi, edi);
|
||||
if ((ebx & 1) == 0) {
|
||||
sheet_refresh(sht, eax, ecx, esi + 1, edi + 1);
|
||||
}
|
||||
} else if (edx == 8) {
|
||||
memman_init((struct MEMMAN *) (ebx + ds_base));
|
||||
ecx &= 0xfffffff0; /*以16字节为单位*/
|
||||
memman_free((struct MEMMAN *) (ebx + ds_base), eax, ecx);
|
||||
} else if (edx == 9) {
|
||||
ecx = (ecx + 0x0f) & 0xfffffff0; /*以16字节为单位进位取整*/
|
||||
reg[7] = memman_alloc((struct MEMMAN *) (ebx + ds_base), ecx);
|
||||
} else if (edx == 10) {
|
||||
ecx = (ecx + 0x0f) & 0xfffffff0; /*以16字节为单位进位取整*/
|
||||
memman_free((struct MEMMAN *) (ebx + ds_base), eax, ecx);
|
||||
} else if (edx == 11) {
|
||||
sht = (struct SHEET *) (ebx & 0xfffffffe);
|
||||
sht->buf[sht->bxsize * edi + esi] = eax;
|
||||
if ((ebx & 1) == 0) {
|
||||
sheet_refresh(sht, esi, edi, esi + 1, edi + 1);
|
||||
}
|
||||
} else if (edx == 12) {
|
||||
sht = (struct SHEET *) ebx;
|
||||
sheet_refresh(sht, eax, ecx, esi, edi);
|
||||
} else if (edx == 13) {
|
||||
sht = (struct SHEET *) (ebx & 0xfffffffe);
|
||||
hrb_api_linewin(sht, eax, ecx, esi, edi, ebp);
|
||||
if ((ebx & 1) == 0) {
|
||||
sheet_refresh(sht, eax, ecx, esi + 1, edi + 1);
|
||||
}
|
||||
} else if (edx == 14) {
|
||||
sheet_free((struct SHEET *) ebx);
|
||||
} else if (edx == 15) {
|
||||
for (;;) {
|
||||
io_cli();
|
||||
if (fifo32_status(&task->fifo) == 0) {
|
||||
if (eax != 0) {
|
||||
task_sleep(task); /* FIFO为空,休眠并等待*/
|
||||
} else {
|
||||
io_sti();
|
||||
reg[7] = -1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
i = fifo32_get(&task->fifo);
|
||||
io_sti();
|
||||
if (i <= 1) { /*光标用定时器*/
|
||||
/*应用程序运行时不需要显示光标,因此总是将下次显示用的值置为1*/
|
||||
timer_init(cons->timer, &task->fifo, 1); /*下次置为1*/
|
||||
timer_settime(cons->timer, 50);
|
||||
}
|
||||
if (i == 2) { /*光标ON */
|
||||
cons->cur_c = COL8_FFFFFF;
|
||||
}
|
||||
if (i == 3) { /*光标OFF */
|
||||
cons->cur_c = -1;
|
||||
}
|
||||
if (i >= 256) { /*键盘数据(通过任务A)等*/
|
||||
reg[7] = i - 256;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} else if (edx == 16) {
|
||||
reg[7] = (int) timer_alloc();
|
||||
((struct TIMER *) reg[7])->flags2 = 1; /*允许自动取消*/
|
||||
} else if (edx == 17) {
|
||||
timer_init((struct TIMER *) ebx, &task->fifo, eax + 256);
|
||||
} else if (edx == 18) {
|
||||
timer_settime((struct TIMER *) ebx, eax);
|
||||
} else if (edx == 19) {
|
||||
timer_free((struct TIMER *) ebx);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int *inthandler0c(int *esp)
|
||||
{
|
||||
struct CONSOLE *cons = (struct CONSOLE *) *((int *) 0x0fec);
|
||||
struct TASK *task = task_now();
|
||||
char s[30];
|
||||
cons_putstr0(cons, "\nINT 0C :\n Stack Exception.\n");
|
||||
sprintf(s, "EIP = %08X\n", esp[11]);
|
||||
cons_putstr0(cons, s);
|
||||
return &(task->tss.esp0); /*强制结束程序*/
|
||||
}
|
||||
|
||||
int *inthandler0d(int *esp)
|
||||
{
|
||||
struct CONSOLE *cons = (struct CONSOLE *) *((int *) 0x0fec);
|
||||
struct TASK *task = task_now();
|
||||
char s[30];
|
||||
cons_putstr0(cons, "\nINT 0D :\n General Protected Exception.\n");
|
||||
sprintf(s, "EIP = %08X\n", esp[11]);
|
||||
cons_putstr0(cons, s);
|
||||
return &(task->tss.esp0); /*强制结束程序*/
|
||||
}
|
||||
|
||||
void hrb_api_linewin(struct SHEET *sht, int x0, int y0, int x1, int y1, int col)
|
||||
{
|
||||
int i, x, y, len, dx, dy;
|
||||
|
||||
dx = x1 - x0;
|
||||
dy = y1 - y0;
|
||||
x = x0 << 10;
|
||||
y = y0 << 10;
|
||||
if (dx < 0) {
|
||||
dx = - dx;
|
||||
}
|
||||
if (dy < 0) {
|
||||
dy = - dy;
|
||||
}
|
||||
if (dx >= dy) {
|
||||
len = dx + 1;
|
||||
if (x0 > x1) {
|
||||
dx = -1024;
|
||||
} else {
|
||||
dx = 1024;
|
||||
}
|
||||
if (y0 <= y1) {
|
||||
dy = ((y1 - y0 + 1) << 10) / len;
|
||||
} else {
|
||||
dy = ((y1 - y0 - 1) << 10) / len;
|
||||
}
|
||||
} else {
|
||||
len = dy + 1;
|
||||
if (y0 > y1) {
|
||||
dy = -1024;
|
||||
} else {
|
||||
dy = 1024;
|
||||
}
|
||||
if (x0 <= x1) {
|
||||
dx = ((x1 - x0 + 1) << 10) / len;
|
||||
} else {
|
||||
dx = ((x1 - x0 - 1) << 10) / len;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
sht->buf[(y >> 10) * sht->bxsize + (x >> 10)] = col;
|
||||
x += dx;
|
||||
y += dy;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
60
24_day/dsctbl.c
Normal file
60
24_day/dsctbl.c
Normal file
@@ -0,0 +1,60 @@
|
||||
/* 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 + 0x0c, (int) asm_inthandler0c, 2 * 8, AR_INTGATE32);
|
||||
set_gatedesc(idt + 0x0d, (int) asm_inthandler0d, 2 * 8, AR_INTGATE32);
|
||||
set_gatedesc(idt + 0x20, (int) asm_inthandler20, 2 * 8, AR_INTGATE32);
|
||||
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);
|
||||
set_gatedesc(idt + 0x40, (int) asm_hrb_api, 2 * 8, AR_INTGATE32 + 0x60);
|
||||
|
||||
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;
|
||||
}
|
||||
63
24_day/fifo.c
Normal file
63
24_day/fifo.c
Normal file
@@ -0,0 +1,63 @@
|
||||
/* FIFO */
|
||||
|
||||
#include "bootpack.h"
|
||||
|
||||
#define FLAGS_OVERRUN 0x0001
|
||||
|
||||
void fifo32_init(struct FIFO32 *fifo, int size, int *buf, struct TASK *task)
|
||||
/* FIFO缓冲区的初始化*/
|
||||
{
|
||||
fifo->size = size;
|
||||
fifo->buf = buf;
|
||||
fifo->free = size; /*空*/
|
||||
fifo->flags = 0;
|
||||
fifo->p = 0; /*写入位置*/
|
||||
fifo->q = 0; /*读取位置*/
|
||||
fifo->task = task; /*有数据写入时需要唤醒的任务*/
|
||||
return;
|
||||
}
|
||||
|
||||
int fifo32_put(struct FIFO32 *fifo, int 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--;
|
||||
if (fifo->task != 0) {
|
||||
if (fifo->task->flags != 2) { /*如果任务处于休眠状态*/
|
||||
task_run(fifo->task, -1, 0); /*将任务唤醒*/
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fifo32_get(struct FIFO32 *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 fifo32_status(struct FIFO32 *fifo)
|
||||
/*报告已经存储了多少数据*/
|
||||
{
|
||||
return fifo->size - fifo->free;
|
||||
}
|
||||
74
24_day/file.c
Normal file
74
24_day/file.c
Normal file
@@ -0,0 +1,74 @@
|
||||
/* 文件相关函数 */
|
||||
|
||||
#include "bootpack.h"
|
||||
|
||||
void file_readfat(int *fat, unsigned char *img)
|
||||
/*将磁盘映像中的FAT解压缩 */
|
||||
{
|
||||
int i, j = 0;
|
||||
for (i = 0; i < 2880; i += 2) {
|
||||
fat[i + 0] = (img[j + 0] | img[j + 1] << 8) & 0xfff;
|
||||
fat[i + 1] = (img[j + 1] >> 4 | img[j + 2] << 4) & 0xfff;
|
||||
j += 3;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void file_loadfile(int clustno, int size, char *buf, int *fat, char *img)
|
||||
{
|
||||
int i;
|
||||
for (;;) {
|
||||
if (size <= 512) {
|
||||
for (i = 0; i < size; i++) {
|
||||
buf[i] = img[clustno * 512 + i];
|
||||
}
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < 512; i++) {
|
||||
buf[i] = img[clustno * 512 + i];
|
||||
}
|
||||
size -= 512;
|
||||
buf += 512;
|
||||
clustno = fat[clustno];
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
struct FILEINFO *file_search(char *name, struct FILEINFO *finfo, int max)
|
||||
{
|
||||
int i, j;
|
||||
char s[12];
|
||||
for (j = 0; j < 11; j++) {
|
||||
s[j] = ' ';
|
||||
}
|
||||
j = 0;
|
||||
for (i = 0; name[i] != 0; i++) {
|
||||
if (j >= 11) { return 0; /*没有找到*/ }
|
||||
if (name[i] == '.' && j <= 8) {
|
||||
j = 8;
|
||||
} else {
|
||||
s[j] = name[i];
|
||||
if ('a' <= s[j] && s[j] <= 'z') {
|
||||
/*将小写字母转换为大写字母*/
|
||||
s[j] -= 0x20;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < max; ) {
|
||||
if (finfo[i].name[0] == 0x00) {
|
||||
break;
|
||||
}
|
||||
if ((finfo[i].type & 0x18) == 0) {
|
||||
for (j = 0; j < 11; j++) {
|
||||
if (finfo[i].name[j] != s[j]) {
|
||||
goto next;
|
||||
}
|
||||
}
|
||||
return finfo + i; /*找到文件*/
|
||||
}
|
||||
next:
|
||||
i++;
|
||||
}
|
||||
return 0; /*没有找到*/
|
||||
}
|
||||
157
24_day/graphic.c
Normal file
157
24_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
24_day/hankaku.txt
Normal file
4609
24_day/hankaku.txt
Normal file
File diff suppressed because it is too large
Load Diff
16
24_day/hello.nas
Normal file
16
24_day/hello.nas
Normal file
@@ -0,0 +1,16 @@
|
||||
[INSTRSET "i486p"]
|
||||
[BITS 32]
|
||||
MOV ECX,msg
|
||||
MOV EDX,1
|
||||
putloop:
|
||||
MOV AL,[CS:ECX]
|
||||
CMP AL,0
|
||||
JE fin
|
||||
INT 0x40
|
||||
ADD ECX,1
|
||||
JMP putloop
|
||||
fin:
|
||||
MOV EDX,4
|
||||
INT 0x40
|
||||
msg:
|
||||
DB "hello",0
|
||||
9
24_day/hello2.nas
Normal file
9
24_day/hello2.nas
Normal file
@@ -0,0 +1,9 @@
|
||||
[INSTRSET "i486p"]
|
||||
[BITS 32]
|
||||
MOV EDX,2
|
||||
MOV EBX,msg
|
||||
INT 0x40
|
||||
MOV EDX,4
|
||||
INT 0x40
|
||||
msg:
|
||||
DB "hello",0
|
||||
12
24_day/hello3.c
Normal file
12
24_day/hello3.c
Normal file
@@ -0,0 +1,12 @@
|
||||
void api_putchar(int c);
|
||||
void api_end(void);
|
||||
|
||||
void HariMain(void)
|
||||
{
|
||||
api_putchar('h');
|
||||
api_putchar('e');
|
||||
api_putchar('l');
|
||||
api_putchar('l');
|
||||
api_putchar('o');
|
||||
api_end();
|
||||
}
|
||||
8
24_day/hello4.c
Normal file
8
24_day/hello4.c
Normal file
@@ -0,0 +1,8 @@
|
||||
void api_putstr0(char *s);
|
||||
void api_end(void);
|
||||
|
||||
void HariMain(void)
|
||||
{
|
||||
api_putstr0("hello, world\n");
|
||||
api_end();
|
||||
}
|
||||
20
24_day/hello5.nas
Normal file
20
24_day/hello5.nas
Normal file
@@ -0,0 +1,20 @@
|
||||
[FORMAT "WCOFF"]
|
||||
[INSTRSET "i486p"]
|
||||
[BITS 32]
|
||||
[FILE "hello5.nas"]
|
||||
|
||||
GLOBAL _HariMain
|
||||
|
||||
[SECTION .text]
|
||||
|
||||
_HariMain:
|
||||
MOV EDX,2
|
||||
MOV EBX,msg
|
||||
INT 0x40
|
||||
MOV EDX,4
|
||||
INT 0x40
|
||||
|
||||
[SECTION .data]
|
||||
|
||||
msg:
|
||||
DB "hello, world", 0x0a, 0
|
||||
37
24_day/int.c
Normal file
37
24_day/int.c
Normal file
@@ -0,0 +1,37 @@
|
||||
/*初始化关系 */
|
||||
|
||||
#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上通过芯片组提供的便利,只需执行一次 */
|
||||
/* 这个中断只是接收,不执行任何操作 */
|
||||
/* 为什么不处理?
|
||||
→ 因为这个中断可能是电气噪声引发的、只是处理一些重要的情况。*/
|
||||
{
|
||||
io_out8(PIC0_OCW2, 0x67); /* 通知PIC的IRQ-07(参考7-1) */
|
||||
return;
|
||||
}
|
||||
109
24_day/ipl10.nas
Normal file
109
24_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
|
||||
44
24_day/keyboard.c
Normal file
44
24_day/keyboard.c
Normal file
@@ -0,0 +1,44 @@
|
||||
/* 键盘控制代码 */
|
||||
|
||||
#include "bootpack.h"
|
||||
|
||||
struct FIFO32 *keyfifo;
|
||||
int keydata0;
|
||||
|
||||
void inthandler21(int *esp)
|
||||
{
|
||||
int data;
|
||||
io_out8(PIC0_OCW2, 0x61); /* 把IRQ-01接收信号结束的信息通知给PIC */
|
||||
data = io_in8(PORT_KEYDAT);
|
||||
fifo32_put(keyfifo, data + keydata0);
|
||||
return;
|
||||
}
|
||||
|
||||
#define PORT_KEYSTA 0x0064
|
||||
#define KEYSTA_SEND_NOTREADY 0x02
|
||||
#define KEYCMD_WRITE_MODE 0x60
|
||||
#define KBC_MODE 0x47
|
||||
|
||||
void wait_KBC_sendready(void)
|
||||
{
|
||||
/* 等待键盘控制电路准备完毕 */
|
||||
for (;;) {
|
||||
if ((io_in8(PORT_KEYSTA) & KEYSTA_SEND_NOTREADY) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void init_keyboard(struct FIFO32 *fifo, int data0)
|
||||
{
|
||||
/* 将FIFO缓冲区的信息保存到全局变量里 */
|
||||
keyfifo = fifo;
|
||||
keydata0 = data0;
|
||||
/* 键盘控制器的初始化 */
|
||||
wait_KBC_sendready();
|
||||
io_out8(PORT_KEYCMD, KEYCMD_WRITE_MODE);
|
||||
wait_KBC_sendready();
|
||||
io_out8(PORT_KEYDAT, KBC_MODE);
|
||||
return;
|
||||
}
|
||||
29
24_day/lines.c
Normal file
29
24_day/lines.c
Normal file
@@ -0,0 +1,29 @@
|
||||
int api_openwin(char *buf, int xsiz, int ysiz, int col_inv, char *title);
|
||||
void api_initmalloc(void);
|
||||
char *api_malloc(int size);
|
||||
void api_refreshwin(int win, int x0, int y0, int x1, int y1);
|
||||
void api_linewin(int win, int x0, int y0, int x1, int y1, int col);
|
||||
void api_closewin(int win);
|
||||
int api_getkey(int mode);
|
||||
void api_end(void);
|
||||
|
||||
void HariMain(void)
|
||||
{
|
||||
char *buf;
|
||||
int win, i;
|
||||
api_initmalloc();
|
||||
buf = api_malloc(160 * 100);
|
||||
win = api_openwin(buf, 160, 100, -1, "lines");
|
||||
for (i = 0; i < 8; i++) {
|
||||
api_linewin(win + 1, 8, 26, 77, i * 9 + 26, i);
|
||||
api_linewin(win + 1, 88, 26, i * 9 + 88, 89, i);
|
||||
}
|
||||
api_refreshwin(win, 6, 26, 154, 90);
|
||||
for (;;) {
|
||||
if (api_getkey(1) == 0x0a) {
|
||||
break; /*按下回车键则break; */
|
||||
}
|
||||
}
|
||||
api_closewin(win);
|
||||
api_end();
|
||||
}
|
||||
1
24_day/make.bat
Normal file
1
24_day/make.bat
Normal file
@@ -0,0 +1 @@
|
||||
..\z_tools\make.exe %1 %2 %3 %4 %5 %6 %7 %8 %9
|
||||
162
24_day/memory.c
Normal file
162
24_day/memory.c
Normal file
@@ -0,0 +1,162 @@
|
||||
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>W */
|
||||
|
||||
#include "bootpack.h"
|
||||
|
||||
#define EFLAGS_AC_BIT 0x00040000
|
||||
#define CR0_CACHE_DISABLE 0x60000000
|
||||
|
||||
unsigned 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;
|
||||
}
|
||||
76
24_day/mouse.c
Normal file
76
24_day/mouse.c
Normal file
@@ -0,0 +1,76 @@
|
||||
/* 鼠标控制代码 */
|
||||
|
||||
#include "bootpack.h"
|
||||
|
||||
struct FIFO32 *mousefifo;
|
||||
int mousedata0;
|
||||
|
||||
void inthandler2c(int *esp)
|
||||
/* 来自PS/2鼠标的中断 */
|
||||
{
|
||||
int data;
|
||||
io_out8(PIC1_OCW2, 0x64); /* 把IRQ-12接收信号结束的信息通知给PIC1 */
|
||||
io_out8(PIC0_OCW2, 0x62); /* 把IRQ-02接收信号结束的信息通知给PIC0 */
|
||||
data = io_in8(PORT_KEYDAT);
|
||||
fifo32_put(mousefifo, data + mousedata0);
|
||||
return;
|
||||
}
|
||||
|
||||
#define KEYCMD_SENDTO_MOUSE 0xd4
|
||||
#define MOUSECMD_ENABLE 0xf4
|
||||
|
||||
void enable_mouse(struct FIFO32 *fifo, int data0, struct MOUSE_DEC *mdec)
|
||||
{
|
||||
/* 将FIFO缓冲区的信息保存到全局变量里 */
|
||||
mousefifo = fifo;
|
||||
mousedata0 = data0;
|
||||
/* 鼠标有效 */
|
||||
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) {
|
||||
/* 等待鼠标第一字节的阶段 */
|
||||
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;
|
||||
}
|
||||
201
24_day/mtask.c
Normal file
201
24_day/mtask.c
Normal file
@@ -0,0 +1,201 @@
|
||||
/* 多任务管理 */
|
||||
|
||||
#include "bootpack.h"
|
||||
|
||||
struct TASKCTL *taskctl;
|
||||
struct TIMER *task_timer;
|
||||
|
||||
struct TASK *task_now(void)
|
||||
{
|
||||
struct TASKLEVEL *tl = &taskctl->level[taskctl->now_lv];
|
||||
return tl->tasks[tl->now];
|
||||
}
|
||||
|
||||
void task_add(struct TASK *task)
|
||||
{
|
||||
struct TASKLEVEL *tl = &taskctl->level[task->level];
|
||||
tl->tasks[tl->running] = task;
|
||||
tl->running++;
|
||||
task->flags = 2; /*活动中*/
|
||||
return;
|
||||
}
|
||||
|
||||
void task_remove(struct TASK *task)
|
||||
{
|
||||
int i;
|
||||
struct TASKLEVEL *tl = &taskctl->level[task->level];
|
||||
|
||||
/*寻找task所在的位置*/
|
||||
for (i = 0; i < tl->running; i++) {
|
||||
if (tl->tasks[i] == task) {
|
||||
/*在这里 */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
tl->running--;
|
||||
if (i < tl->now) {
|
||||
tl->now--; /*需要移动成员,要相应地处理 */
|
||||
}
|
||||
if (tl->now >= tl->running) {
|
||||
/*如果now的值出现异常,则进行修正*/
|
||||
tl->now = 0;
|
||||
}
|
||||
task->flags = 1; /* 休眠中 */
|
||||
|
||||
/* 移动 */
|
||||
for (; i < tl->running; i++) {
|
||||
tl->tasks[i] = tl->tasks[i + 1];
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void task_switchsub(void)
|
||||
{
|
||||
int i;
|
||||
/*寻找最上层的LEVEL */
|
||||
for (i = 0; i < MAX_TASKLEVELS; i++) {
|
||||
if (taskctl->level[i].running > 0) {
|
||||
break; /*找到了*/
|
||||
}
|
||||
}
|
||||
taskctl->now_lv = i;
|
||||
taskctl->lv_change = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
void task_idle(void)
|
||||
{
|
||||
for (;;) {
|
||||
io_hlt();
|
||||
}
|
||||
}
|
||||
|
||||
struct TASK *task_init(struct MEMMAN *memman)
|
||||
{
|
||||
int i;
|
||||
struct TASK *task, *idle;
|
||||
struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *) ADR_GDT;
|
||||
|
||||
|
||||
taskctl = (struct TASKCTL *) memman_alloc_4k(memman, sizeof (struct TASKCTL));
|
||||
for (i = 0; i < MAX_TASKS; i++) {
|
||||
taskctl->tasks0[i].flags = 0;
|
||||
taskctl->tasks0[i].sel = (TASK_GDT0 + i) * 8;
|
||||
set_segmdesc(gdt + TASK_GDT0 + i, 103, (int) &taskctl->tasks0[i].tss, AR_TSS32);
|
||||
}
|
||||
for (i = 0; i < MAX_TASKLEVELS; i++) {
|
||||
taskctl->level[i].running = 0;
|
||||
taskctl->level[i].now = 0;
|
||||
}
|
||||
|
||||
task = task_alloc();
|
||||
task->flags = 2; /*活动中标志*/
|
||||
task->priority = 2; /* 0.02秒*/
|
||||
task->level = 0; /*最高LEVEL */
|
||||
task_add(task);
|
||||
task_switchsub(); /* LEVEL 设置*/
|
||||
load_tr(task->sel);
|
||||
task_timer = timer_alloc();
|
||||
timer_settime(task_timer, task->priority);
|
||||
|
||||
idle = task_alloc();
|
||||
idle->tss.esp = memman_alloc_4k(memman, 64 * 1024) + 64 * 1024;
|
||||
idle->tss.eip = (int) &task_idle;
|
||||
idle->tss.es = 1 * 8;
|
||||
idle->tss.cs = 2 * 8;
|
||||
idle->tss.ss = 1 * 8;
|
||||
idle->tss.ds = 1 * 8;
|
||||
idle->tss.fs = 1 * 8;
|
||||
idle->tss.gs = 1 * 8;
|
||||
task_run(idle, MAX_TASKLEVELS - 1, 1);
|
||||
|
||||
return task;
|
||||
}
|
||||
|
||||
struct TASK *task_alloc(void)
|
||||
{
|
||||
int i;
|
||||
struct TASK *task;
|
||||
for (i = 0; i < MAX_TASKS; i++) {
|
||||
if (taskctl->tasks0[i].flags == 0) {
|
||||
task = &taskctl->tasks0[i];
|
||||
task->flags = 1; /*正在使用的标志*/
|
||||
task->tss.eflags = 0x00000202; /* IF = 1; */
|
||||
task->tss.eax = 0; /*这里先置为0*/
|
||||
task->tss.ecx = 0;
|
||||
task->tss.edx = 0;
|
||||
task->tss.ebx = 0;
|
||||
task->tss.ebp = 0;
|
||||
task->tss.esi = 0;
|
||||
task->tss.edi = 0;
|
||||
task->tss.es = 0;
|
||||
task->tss.ds = 0;
|
||||
task->tss.fs = 0;
|
||||
task->tss.gs = 0;
|
||||
task->tss.ldtr = 0;
|
||||
task->tss.iomap = 0x40000000;
|
||||
task->tss.ss0 = 0;
|
||||
return task;
|
||||
}
|
||||
}
|
||||
return 0; /*全部正在使用*/
|
||||
}
|
||||
|
||||
void task_run(struct TASK *task, int level, int priority)
|
||||
{
|
||||
if (level < 0) {
|
||||
level = task->level; /*不改变LEVEL */
|
||||
}
|
||||
if (priority > 0) {
|
||||
task->priority = priority;
|
||||
}
|
||||
if (task->flags == 2 && task->level != level) {
|
||||
/*改变活动中的LEVEL */
|
||||
task_remove(task); /*这里执行之后flag的值会变为1,于是下面的if语句块也会被执行*/
|
||||
}
|
||||
if (task->flags != 2) {
|
||||
/*从休眠状态唤醒的情形*/
|
||||
task->level = level;
|
||||
task_add(task);
|
||||
}
|
||||
taskctl->lv_change = 1; /*下次任务切换时检查LEVEL */
|
||||
return;
|
||||
}
|
||||
|
||||
void task_switch(void)
|
||||
{
|
||||
struct TASKLEVEL *tl = &taskctl->level[taskctl->now_lv];
|
||||
struct TASK *new_task, *now_task = tl->tasks[tl->now];
|
||||
tl->now++;
|
||||
if (tl->now == tl->running) {
|
||||
tl->now = 0;
|
||||
}
|
||||
if (taskctl->lv_change != 0) {
|
||||
task_switchsub();
|
||||
tl = &taskctl->level[taskctl->now_lv];
|
||||
}
|
||||
new_task = tl->tasks[tl->now];
|
||||
timer_settime(task_timer, new_task->priority);
|
||||
if (new_task != now_task) {
|
||||
farjmp(0, new_task->sel);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void task_sleep(struct TASK *task)
|
||||
{
|
||||
struct TASK *now_task;
|
||||
if (task->flags == 2) {
|
||||
/*如果处于活动状态*/
|
||||
now_task = task_now();
|
||||
task_remove(task); /*执行此语句的话flags将变为1 */
|
||||
if (task == now_task) {
|
||||
/*如果是让自己休眠,则需要进行任务切换*/
|
||||
task_switchsub();
|
||||
now_task = task_now(); /*在设定后获取当前任务的值*/
|
||||
farjmp(0, now_task->sel);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
307
24_day/naskfunc.nas
Normal file
307
24_day/naskfunc.nas
Normal file
@@ -0,0 +1,307 @@
|
||||
; 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 _load_cr0, _store_cr0
|
||||
GLOBAL _load_tr
|
||||
GLOBAL _asm_inthandler20, _asm_inthandler21
|
||||
GLOBAL _asm_inthandler27, _asm_inthandler2c
|
||||
GLOBAL _asm_inthandler0c, _asm_inthandler0d
|
||||
GLOBAL _asm_end_app, _memtest_sub
|
||||
GLOBAL _farjmp, _farcall
|
||||
GLOBAL _asm_hrb_api, _start_app
|
||||
EXTERN _inthandler20, _inthandler21
|
||||
EXTERN _inthandler27, _inthandler2c
|
||||
EXTERN _inthandler0c, _inthandler0d
|
||||
EXTERN _hrb_api
|
||||
|
||||
[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
|
||||
|
||||
_load_cr0: ; int load_cr0(void);
|
||||
MOV EAX,CR0
|
||||
RET
|
||||
|
||||
_store_cr0: ; void store_cr0(int cr0);
|
||||
MOV EAX,[ESP+4]
|
||||
MOV CR0,EAX
|
||||
RET
|
||||
|
||||
_load_tr: ; void load_tr(int tr);
|
||||
LTR [ESP+4] ; tr
|
||||
RET
|
||||
|
||||
_asm_inthandler20:
|
||||
PUSH ES
|
||||
PUSH DS
|
||||
PUSHAD
|
||||
MOV EAX,ESP
|
||||
PUSH EAX
|
||||
MOV AX,SS
|
||||
MOV DS,AX
|
||||
MOV ES,AX
|
||||
CALL _inthandler20
|
||||
POP EAX
|
||||
POPAD
|
||||
POP DS
|
||||
POP ES
|
||||
IRETD
|
||||
|
||||
_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
|
||||
|
||||
_asm_inthandler0c:
|
||||
STI
|
||||
PUSH ES
|
||||
PUSH DS
|
||||
PUSHAD
|
||||
MOV EAX,ESP
|
||||
PUSH EAX
|
||||
MOV AX,SS
|
||||
MOV DS,AX
|
||||
MOV ES,AX
|
||||
CALL _inthandler0c
|
||||
CMP EAX,0
|
||||
JNE _asm_end_app
|
||||
POP EAX
|
||||
POPAD
|
||||
POP DS
|
||||
POP ES
|
||||
ADD ESP,4 ; 在INT 0x0c中也需要这句
|
||||
IRETD
|
||||
|
||||
_asm_inthandler0d:
|
||||
STI
|
||||
PUSH ES
|
||||
PUSH DS
|
||||
PUSHAD
|
||||
MOV EAX,ESP
|
||||
PUSH EAX
|
||||
MOV AX,SS
|
||||
MOV DS,AX
|
||||
MOV ES,AX
|
||||
CALL _inthandler0d
|
||||
CMP EAX,0
|
||||
JNE _asm_end_app
|
||||
POP EAX
|
||||
POPAD
|
||||
POP DS
|
||||
POP ES
|
||||
ADD ESP,4 ; INT 0x0d需要这句
|
||||
IRETD
|
||||
|
||||
_memtest_sub: ; unsigned int memtest_sub(unsigned int start, unsigned int end)
|
||||
PUSH EDI ; (由于还要使用EBX, ESI, EDI)
|
||||
PUSH ESI
|
||||
PUSH EBX
|
||||
MOV ESI,0xaa55aa55 ; pat0 = 0xaa55aa55;
|
||||
MOV EDI,0x55aa55aa ; pat1 = 0x55aa55aa;
|
||||
MOV EAX,[ESP+12+4] ; i = start;
|
||||
mts_loop:
|
||||
MOV EBX,EAX
|
||||
ADD 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_fin
|
||||
XOR DWORD [EBX],0xffffffff ; *p ^= 0xffffffff;
|
||||
CMP ESI,[EBX] ; if (*p != pat0) goto fin;
|
||||
JNE mts_fin
|
||||
MOV [EBX],EDX ; *p = old;
|
||||
ADD EAX,0x1000 ; i += 0x1000;
|
||||
CMP EAX,[ESP+12+8] ; if (i <= end) goto mts_loop;
|
||||
JBE mts_loop
|
||||
POP EBX
|
||||
POP ESI
|
||||
POP EDI
|
||||
RET
|
||||
mts_fin:
|
||||
MOV [EBX],EDX ; *p = old;
|
||||
POP EBX
|
||||
POP ESI
|
||||
POP EDI
|
||||
RET
|
||||
|
||||
_farjmp: ; void farjmp(int eip, int cs);
|
||||
JMP FAR [ESP+4] ; eip, cs
|
||||
RET
|
||||
|
||||
_farcall: ; void farcall(int eip, int cs);
|
||||
CALL FAR [ESP+4] ; eip, cs
|
||||
RET
|
||||
|
||||
_asm_hrb_api:
|
||||
STI
|
||||
PUSH DS
|
||||
PUSH ES
|
||||
PUSHAD ; 用于保存的PUSH
|
||||
PUSHAD ; 用于向hrb_api传值的PUSH
|
||||
MOV AX,SS
|
||||
MOV DS,AX ; 将操作系统用段地址存入DS和ES
|
||||
MOV ES,AX
|
||||
CALL _hrb_api
|
||||
CMP EAX,0 ; 当EAX不为0时程序结束
|
||||
JNE _asm_end_app
|
||||
ADD ESP,32
|
||||
POPAD
|
||||
POP ES
|
||||
POP DS
|
||||
IRETD
|
||||
_asm_end_app:
|
||||
; EAX为tss.esp0的地址
|
||||
MOV ESP,[EAX]
|
||||
MOV DWORD [EAX+4],0
|
||||
POPAD
|
||||
RET ; 返回cmd_app
|
||||
|
||||
_start_app: ; void start_app(int eip, int cs, int esp, int ds, int *tss_esp0);
|
||||
PUSHAD ; 将32位寄存器的值全部保存起来
|
||||
MOV EAX,[ESP+36] ; 应用程序用EIP
|
||||
MOV ECX,[ESP+40] ; 应用程序用CS
|
||||
MOV EDX,[ESP+44] ; 应用程序用ESP
|
||||
MOV EBX,[ESP+48] ; 应用程序用DS/SS
|
||||
MOV EBP,[ESP+52] ; tss.esp0的地址
|
||||
MOV [EBP ],ESP ; 保存操作系统用ESP
|
||||
MOV [EBP+4],SS ; 保存操作系统用SS
|
||||
MOV ES,BX
|
||||
MOV DS,BX
|
||||
MOV FS,BX
|
||||
MOV GS,BX
|
||||
; 下面调整栈,以免用RETF跳转到应用程序
|
||||
OR ECX,3 ; 将应用程序用段号和3进行OR运算
|
||||
OR EBX,3 ; 将应用程序用段号和3进行OR运算
|
||||
PUSH EBX ; 应用程序的SS
|
||||
PUSH EDX ; 应用程序的ESP
|
||||
PUSH ECX ; 应用程序的CS
|
||||
PUSH EAX ; 应用程序的EIP
|
||||
RETF
|
||||
; 应用程序结束后不会回到这里
|
||||
42
24_day/noodle.c
Normal file
42
24_day/noodle.c
Normal file
@@ -0,0 +1,42 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int api_openwin(char *buf, int xsiz, int ysiz, int col_inv, char *title);
|
||||
void api_putstrwin(int win, int x, int y, int col, int len, char *str);
|
||||
void api_boxfilwin(int win, int x0, int y0, int x1, int y1, int col);
|
||||
void api_initmalloc(void);
|
||||
char *api_malloc(int size);
|
||||
int api_getkey(int mode);
|
||||
int api_alloctimer(void);
|
||||
void api_inittimer(int timer, int data);
|
||||
void api_settimer(int timer, int time);
|
||||
void api_end(void);
|
||||
|
||||
void HariMain(void)
|
||||
{
|
||||
char *buf, s[12];
|
||||
int win, timer, sec = 0, min = 0, hou = 0;
|
||||
api_initmalloc();
|
||||
buf = api_malloc(150 * 50);
|
||||
win = api_openwin(buf, 150, 50, -1, "noodle");
|
||||
timer = api_alloctimer();
|
||||
api_inittimer(timer, 128);
|
||||
for (;;) {
|
||||
sprintf(s, "%5d:%02d:%02d", hou, min, sec);
|
||||
api_boxfilwin(win, 28, 27, 115, 41, 7);/*白色*/
|
||||
api_putstrwin(win, 28, 27, 0, 11, s); /*黑色*/
|
||||
api_settimer(timer, 100); /* 1秒 */
|
||||
if (api_getkey(1) != 128) {
|
||||
break;
|
||||
}
|
||||
sec++;
|
||||
if (sec == 60) {
|
||||
sec = 0;
|
||||
min++;
|
||||
if (min == 60) {
|
||||
min = 0;
|
||||
hou++;
|
||||
}
|
||||
}
|
||||
}
|
||||
api_end();
|
||||
}
|
||||
217
24_day/sheet.c
Normal file
217
24_day/sheet.c
Normal file
@@ -0,0 +1,217 @@
|
||||
/* sheet */
|
||||
|
||||
#include "bootpack.h"
|
||||
|
||||
#define SHEET_USE 1
|
||||
|
||||
struct 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->map = (unsigned char *) memman_alloc_4k(memman, xsize * ysize);
|
||||
if (ctl->map == 0) {
|
||||
memman_free_4k(memman, (int) ctl, sizeof (struct SHTCTL));
|
||||
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; /* 标记为未使用 */
|
||||
ctl->sheets0[i].ctl = ctl; /* 记录所属*/
|
||||
}
|
||||
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; /* 隐藏 */
|
||||
sht->task = 0; /*不使用自动关闭功能*/
|
||||
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_refreshmap(struct SHTCTL *ctl, int vx0, int vy0, int vx1, int vy1, int h0)
|
||||
{
|
||||
int h, bx, by, vx, vy, bx0, by0, bx1, by1;
|
||||
unsigned char *buf, sid, *map = ctl->map;
|
||||
struct SHEET *sht;
|
||||
if (vx0 < 0) { vx0 = 0; }
|
||||
if (vy0 < 0) { vy0 = 0; }
|
||||
if (vx1 > ctl->xsize) { vx1 = ctl->xsize; }
|
||||
if (vy1 > ctl->ysize) { vy1 = ctl->ysize; }
|
||||
for (h = h0; h <= ctl->top; h++) {
|
||||
sht = ctl->sheets[h];
|
||||
sid = sht - ctl->sheets0; /* 将进行了减法计算的地址作为图层号码使用 */
|
||||
buf = sht->buf;
|
||||
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;
|
||||
if (buf[by * sht->bxsize + bx] != sht->col_inv) {
|
||||
map[vy * ctl->xsize + vx] = sid;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void sheet_refreshsub(struct SHTCTL *ctl, int vx0, int vy0, int vx1, int vy1, int h0, int h1)
|
||||
{
|
||||
int h, bx, by, vx, vy, bx0, by0, bx1, by1;
|
||||
unsigned char *buf, *vram = ctl->vram, *map = ctl->map, sid;
|
||||
struct SHEET *sht;
|
||||
|
||||
/* 如果refresh的范围超出了画面则修正 */
|
||||
if (vx0 < 0) { vx0 = 0; }
|
||||
if (vy0 < 0) { vy0 = 0; }
|
||||
if (vx1 > ctl->xsize) { vx1 = ctl->xsize; }
|
||||
if (vy1 > ctl->ysize) { vy1 = ctl->ysize; }
|
||||
for (h = h0; h <= h1; h++) {
|
||||
sht = ctl->sheets[h];
|
||||
buf = sht->buf;
|
||||
sid = sht - ctl->sheets0;
|
||||
|
||||
/* 使用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;
|
||||
if (map[vy * ctl->xsize + vx] == sid) {
|
||||
vram[vy * ctl->xsize + vx] = buf[by * sht->bxsize + bx];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void sheet_updown(struct SHEET *sht, int height)
|
||||
{
|
||||
struct SHTCTL *ctl = sht->ctl;
|
||||
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;
|
||||
sheet_refreshmap(ctl, sht->vx0, sht->vy0, sht->vx0 + sht->bxsize, sht->vy0 + sht->bysize, height + 1);
|
||||
sheet_refreshsub(ctl, sht->vx0, sht->vy0, sht->vx0 + sht->bxsize, sht->vy0 + sht->bysize, height + 1, old);
|
||||
} 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_refreshmap(ctl, sht->vx0, sht->vy0, sht->vx0 + sht->bxsize, sht->vy0 + sht->bysize, 0);
|
||||
sheet_refreshsub(ctl, sht->vx0, sht->vy0, sht->vx0 + sht->bxsize, sht->vy0 + sht->bysize, 0, old - 1);
|
||||
}
|
||||
} 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_refreshmap(ctl, sht->vx0, sht->vy0, sht->vx0 + sht->bxsize, sht->vy0 + sht->bysize, height);
|
||||
sheet_refreshsub(ctl, sht->vx0, sht->vy0, sht->vx0 + sht->bxsize, sht->vy0 + sht->bysize, height, height); /* 按新图层信息重新绘制画面 */
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void sheet_refresh(struct SHEET *sht, int bx0, int by0, int bx1, int by1)
|
||||
{
|
||||
if (sht->height >= 0) { /* 如果正在显示,则按新图层的信息刷新画面*/
|
||||
sheet_refreshsub(sht->ctl, sht->vx0 + bx0, sht->vy0 + by0, sht->vx0 + bx1, sht->vy0 + by1, sht->height, sht->height);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void sheet_slide(struct SHEET *sht, int vx0, int vy0)
|
||||
{
|
||||
struct SHTCTL *ctl = sht->ctl;
|
||||
int old_vx0 = sht->vx0, old_vy0 = sht->vy0;
|
||||
sht->vx0 = vx0;
|
||||
sht->vy0 = vy0;
|
||||
if (sht->height >= 0) { /* 如果正在显示,则按新图层的信息刷新画面 */
|
||||
sheet_refreshmap(ctl, old_vx0, old_vy0, old_vx0 + sht->bxsize, old_vy0 + sht->bysize, 0);
|
||||
sheet_refreshmap(ctl, vx0, vy0, vx0 + sht->bxsize, vy0 + sht->bysize, sht->height);
|
||||
sheet_refreshsub(ctl, old_vx0, old_vy0, old_vx0 + sht->bxsize, old_vy0 + sht->bysize, 0, sht->height - 1);
|
||||
sheet_refreshsub(ctl, vx0, vy0, vx0 + sht->bxsize, vy0 + sht->bysize, sht->height, sht->height);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void sheet_free(struct SHEET *sht)
|
||||
{
|
||||
if (sht->height >= 0) {
|
||||
sheet_updown(sht, -1); /* 如果处于显示状态,则先设定为隐藏 */
|
||||
}
|
||||
sht->flags = 0; /* "未使用"标志 */
|
||||
return;
|
||||
}
|
||||
18
24_day/star1.c
Normal file
18
24_day/star1.c
Normal file
@@ -0,0 +1,18 @@
|
||||
int api_openwin(char *buf, int xsiz, int ysiz, int col_inv, char *title);
|
||||
void api_boxfilwin(int win, int x0, int y0, int x1, int y1, int col);
|
||||
void api_initmalloc(void);
|
||||
char *api_malloc(int size);
|
||||
void api_point(int win, int x, int y, int col);
|
||||
void api_end(void);
|
||||
|
||||
void HariMain(void)
|
||||
{
|
||||
char *buf;
|
||||
int win;
|
||||
api_initmalloc();
|
||||
buf = api_malloc(150 * 100);
|
||||
win = api_openwin(buf, 150, 100, -1, "star1");
|
||||
api_boxfilwin(win, 6, 26, 143, 93, 0);/*黑色*/
|
||||
api_point(win, 75, 59, 3);/*黄色*/
|
||||
api_end();
|
||||
}
|
||||
24
24_day/stars.c
Normal file
24
24_day/stars.c
Normal file
@@ -0,0 +1,24 @@
|
||||
int api_openwin(char *buf, int xsiz, int ysiz, int col_inv, char *title);
|
||||
void api_boxfilwin(int win, int x0, int y0, int x1, int y1, int col);
|
||||
void api_initmalloc(void);
|
||||
char *api_malloc(int size);
|
||||
void api_point(int win, int x, int y, int col);
|
||||
void api_end(void);
|
||||
|
||||
int rand(void); /*产生0~32767之间的随机数*/
|
||||
|
||||
void HariMain(void)
|
||||
{
|
||||
char *buf;
|
||||
int win, i, x, y;
|
||||
api_initmalloc();
|
||||
buf = api_malloc(150 * 100);
|
||||
win = api_openwin(buf, 150, 100, -1, "stars");
|
||||
api_boxfilwin(win, 6, 26, 143, 93, 0);/*黑色*/
|
||||
for (i = 0; i < 50; i++) {
|
||||
x = (rand() % 137) + 6;
|
||||
y = (rand() % 67) + 26;
|
||||
api_point(win, x, y, 3);/*黄色*/
|
||||
}
|
||||
api_end();
|
||||
}
|
||||
26
24_day/stars2.c
Normal file
26
24_day/stars2.c
Normal file
@@ -0,0 +1,26 @@
|
||||
int api_openwin(char *buf, int xsiz, int ysiz, int col_inv, char *title);
|
||||
void api_boxfilwin(int win, int x0, int y0, int x1, int y1, int col);
|
||||
void api_initmalloc(void);
|
||||
char *api_malloc(int size);
|
||||
void api_point(int win, int x, int y, int col);
|
||||
void api_refreshwin(int win, int x0, int y0, int x1, int y1);
|
||||
void api_end(void);
|
||||
|
||||
int rand(void); /*产生0~32767的随机数*/
|
||||
|
||||
void HariMain(void)
|
||||
{
|
||||
char *buf;
|
||||
int win, i, x, y;
|
||||
api_initmalloc();
|
||||
buf = api_malloc(150 * 100);
|
||||
win = api_openwin(buf, 150, 100, -1, "stars2");
|
||||
api_boxfilwin(win + 1, 6, 26, 143, 93, 0);/*黑色*/
|
||||
for (i = 0; i < 50; i++) {
|
||||
x = (rand() % 137) + 6;
|
||||
y = (rand() % 67) + 26;
|
||||
api_point(win + 1, x, y, 3);/*黄色*/
|
||||
}
|
||||
api_refreshwin(win, 6, 26, 144, 94);
|
||||
api_end();
|
||||
}
|
||||
169
24_day/timer.c
Normal file
169
24_day/timer.c
Normal file
@@ -0,0 +1,169 @@
|
||||
/* 定时器 */
|
||||
|
||||
#include "bootpack.h"
|
||||
|
||||
#define PIT_CTRL 0x0043
|
||||
#define PIT_CNT0 0x0040
|
||||
|
||||
struct TIMERCTL timerctl;
|
||||
|
||||
#define TIMER_FLAGS_ALLOC 1 /* 已配置状态 */
|
||||
#define TIMER_FLAGS_USING 2 /* 定时器运行中 */
|
||||
|
||||
void init_pit(void)
|
||||
{
|
||||
int i;
|
||||
struct TIMER *t;
|
||||
io_out8(PIT_CTRL, 0x34);
|
||||
io_out8(PIT_CNT0, 0x9c);
|
||||
io_out8(PIT_CNT0, 0x2e);
|
||||
timerctl.count = 0;
|
||||
for (i = 0; i < MAX_TIMER; i++) {
|
||||
timerctl.timers0[i].flags = 0; /* 没有使用 */
|
||||
}
|
||||
t = timer_alloc(); /* 取得一个 */
|
||||
t->timeout = 0xffffffff;
|
||||
t->flags = TIMER_FLAGS_USING;
|
||||
t->next = 0; /* 末尾 */
|
||||
timerctl.t0 = t; /* 因为现在只有哨兵,所以他就在最前面*/
|
||||
timerctl.next = 0xffffffff; /* 因为只有哨兵,所以下一个超时时刻就是哨兵的时刻 */
|
||||
return;
|
||||
}
|
||||
|
||||
struct TIMER *timer_alloc(void)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < MAX_TIMER; i++) {
|
||||
if (timerctl.timers0[i].flags == 0) {
|
||||
timerctl.timers0[i].flags = TIMER_FLAGS_ALLOC;
|
||||
timerctl.timers0[i].flags2 = 0;
|
||||
return &timerctl.timers0[i];
|
||||
}
|
||||
}
|
||||
return 0; /* 没找到 */
|
||||
}
|
||||
|
||||
void timer_free(struct TIMER *timer)
|
||||
{
|
||||
timer->flags = 0; /* 未使用 */
|
||||
return;
|
||||
}
|
||||
|
||||
void timer_init(struct TIMER *timer, struct FIFO32 *fifo, int data)
|
||||
{
|
||||
timer->fifo = fifo;
|
||||
timer->data = data;
|
||||
return;
|
||||
}
|
||||
|
||||
void timer_settime(struct TIMER *timer, unsigned int timeout)
|
||||
{
|
||||
int e;
|
||||
struct TIMER *t, *s;
|
||||
timer->timeout = timeout + timerctl.count;
|
||||
timer->flags = TIMER_FLAGS_USING;
|
||||
e = io_load_eflags();
|
||||
io_cli();
|
||||
t = timerctl.t0;
|
||||
if (timer->timeout <= t->timeout) {
|
||||
/* 插入最前面的情况 */
|
||||
timerctl.t0 = timer;
|
||||
timer->next = t; /* 下面是设定t */
|
||||
timerctl.next = timer->timeout;
|
||||
io_store_eflags(e);
|
||||
return;
|
||||
}
|
||||
for (;;) {
|
||||
s = t;
|
||||
t = t->next;
|
||||
if (timer->timeout <= t->timeout) {
|
||||
/* 插入s和t之间的情况 */
|
||||
s->next = timer; /* s下一个是timer */
|
||||
timer->next = t; /* timer的下一个是t */
|
||||
io_store_eflags(e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void inthandler20(int *esp)
|
||||
{
|
||||
struct TIMER *timer;
|
||||
char ts = 0;
|
||||
io_out8(PIC0_OCW2, 0x60); /* 把IRQ-00接收信号结束的信息通知给PIC */
|
||||
timerctl.count++;
|
||||
if (timerctl.next > timerctl.count) {
|
||||
return;
|
||||
}
|
||||
timer = timerctl.t0; /* 首先把最前面的地址赋给timer */
|
||||
for (;;) {
|
||||
/* 因为timers的定时器都处于运行状态,所以不确认flags */
|
||||
if (timer->timeout > timerctl.count) {
|
||||
break;
|
||||
}
|
||||
/* 超时 */
|
||||
timer->flags = TIMER_FLAGS_ALLOC;
|
||||
if (timer != task_timer) {
|
||||
fifo32_put(timer->fifo, timer->data);
|
||||
} else {
|
||||
ts = 1; /* mt_timer超时*/
|
||||
}
|
||||
timer = timer->next; /* 将下一个定时器的地址赋给timer*/
|
||||
}
|
||||
timerctl.t0 = timer;
|
||||
timerctl.next = timer->timeout;
|
||||
if (ts != 0) {
|
||||
task_switch();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int timer_cancel(struct TIMER *timer)
|
||||
{
|
||||
int e;
|
||||
struct TIMER *t;
|
||||
e = io_load_eflags();
|
||||
io_cli(); /*在设置过程中禁止改变定时器状态*/
|
||||
if (timer->flags == TIMER_FLAGS_USING) { /*是否需要取消?*/
|
||||
if (timer == timerctl.t0) {
|
||||
/*第一个定时器的取消处理*/
|
||||
t = timer->next;
|
||||
timerctl.t0 = t;
|
||||
timerctl.next = t->timeout;
|
||||
} else {
|
||||
/*非第一个定时器的取消处理*/
|
||||
/*找到timer前一个定时器*/
|
||||
t = timerctl.t0;
|
||||
for (;;) {
|
||||
if (t->next == timer) {
|
||||
break;
|
||||
}
|
||||
t = t->next;
|
||||
}
|
||||
t->next = timer->next;
|
||||
/*将之前“timer的下一个”指向“timer的下一个”*/
|
||||
}
|
||||
timer->flags = TIMER_FLAGS_ALLOC;
|
||||
io_store_eflags(e);
|
||||
return 1; /*取消处理成功*/
|
||||
}
|
||||
io_store_eflags(e);
|
||||
return 0; /*不需要取消处理*/
|
||||
}
|
||||
|
||||
void timer_cancelall(struct FIFO32 *fifo)
|
||||
{
|
||||
int e, i;
|
||||
struct TIMER *t;
|
||||
e = io_load_eflags();
|
||||
io_cli(); /*在设置过程中禁止改变定时器状态*/
|
||||
for (i = 0; i < MAX_TIMER; i++) {
|
||||
t = &timerctl.timers0[i];
|
||||
if (t->flags != 0 && t->flags2 != 0 && t->fifo == fifo) {
|
||||
timer_cancel(t);
|
||||
timer_free(t);
|
||||
}
|
||||
}
|
||||
io_store_eflags(e);
|
||||
return;
|
||||
}
|
||||
35
24_day/walk.c
Normal file
35
24_day/walk.c
Normal file
@@ -0,0 +1,35 @@
|
||||
int api_openwin(char *buf, int xsiz, int ysiz, int col_inv, char *title);
|
||||
void api_putstrwin(int win, int x, int y, int col, int len, char *str);
|
||||
void api_boxfilwin(int win, int x0, int y0, int x1, int y1, int col);
|
||||
void api_initmalloc(void);
|
||||
char *api_malloc(int size);
|
||||
void api_refreshwin(int win, int x0, int y0, int x1, int y1);
|
||||
void api_linewin(int win, int x0, int y0, int x1, int y1, int col);
|
||||
void api_closewin(int win);
|
||||
int api_getkey(int mode);
|
||||
void api_end(void);
|
||||
|
||||
void HariMain(void)
|
||||
{
|
||||
char *buf;
|
||||
int win, i, x, y;
|
||||
api_initmalloc();
|
||||
buf = api_malloc(160 * 100);
|
||||
win = api_openwin(buf, 160, 100, -1, "walk");
|
||||
api_boxfilwin(win, 4, 24, 155, 95, 0);/*黑色*/
|
||||
x = 76;
|
||||
y = 56;
|
||||
api_putstrwin(win, x, y, 3, 1, "*");/*黄色*/
|
||||
for (;;) {
|
||||
i = api_getkey(1);
|
||||
api_putstrwin(win, x, y, 0 , 1, "*"); /*用黑色擦除*/
|
||||
if (i == '4' && x > 4) { x -= 8; }
|
||||
if (i == '6' && x < 148) { x += 8; }
|
||||
if (i == '8' && y > 24) { y -= 8; }
|
||||
if (i == '2' && y < 80) { y += 8; }
|
||||
if (i == 0x0a) { break; } /*按回车键结束*/
|
||||
api_putstrwin(win, x, y, 3 , 1, "*");/*黄色*/
|
||||
}
|
||||
api_closewin(win);
|
||||
api_end();
|
||||
}
|
||||
118
24_day/window.c
Normal file
118
24_day/window.c
Normal file
@@ -0,0 +1,118 @@
|
||||
/* 窗口相关函数 */
|
||||
|
||||
#include "bootpack.h"
|
||||
|
||||
void make_window8(unsigned char *buf, int xsize, int ysize, char *title, char act)
|
||||
{
|
||||
boxfill8(buf, xsize, COL8_C6C6C6, 0, 0, xsize - 1, 0 );
|
||||
boxfill8(buf, xsize, COL8_FFFFFF, 1, 1, xsize - 2, 1 );
|
||||
boxfill8(buf, xsize, COL8_C6C6C6, 0, 0, 0, ysize - 1);
|
||||
boxfill8(buf, xsize, COL8_FFFFFF, 1, 1, 1, ysize - 2);
|
||||
boxfill8(buf, xsize, COL8_848484, xsize - 2, 1, xsize - 2, ysize - 2);
|
||||
boxfill8(buf, xsize, COL8_000000, xsize - 1, 0, xsize - 1, ysize - 1);
|
||||
boxfill8(buf, xsize, COL8_C6C6C6, 2, 2, xsize - 3, ysize - 3);
|
||||
boxfill8(buf, xsize, COL8_848484, 1, ysize - 2, xsize - 2, ysize - 2);
|
||||
boxfill8(buf, xsize, COL8_000000, 0, ysize - 1, xsize - 1, ysize - 1);
|
||||
make_wtitle8(buf, xsize, title, act);
|
||||
return;
|
||||
}
|
||||
|
||||
void make_wtitle8(unsigned char *buf, int xsize, char *title, char act)
|
||||
{
|
||||
static char closebtn[14][16] = {
|
||||
"OOOOOOOOOOOOOOO@",
|
||||
"OQQQQQQQQQQQQQ$@",
|
||||
"OQQQQQQQQQQQQQ$@",
|
||||
"OQQQ@@QQQQ@@QQ$@",
|
||||
"OQQQQ@@QQ@@QQQ$@",
|
||||
"OQQQQQ@@@@QQQQ$@",
|
||||
"OQQQQQQ@@QQQQQ$@",
|
||||
"OQQQQQ@@@@QQQQ$@",
|
||||
"OQQQQ@@QQ@@QQQ$@",
|
||||
"OQQQ@@QQQQ@@QQ$@",
|
||||
"OQQQQQQQQQQQQQ$@",
|
||||
"OQQQQQQQQQQQQQ$@",
|
||||
"O$$$$$$$$$$$$$$@",
|
||||
"@@@@@@@@@@@@@@@@"
|
||||
};
|
||||
int x, y;
|
||||
char c, tc, tbc;
|
||||
if (act != 0) {
|
||||
tc = COL8_FFFFFF;
|
||||
tbc = COL8_000084;
|
||||
} else {
|
||||
tc = COL8_C6C6C6;
|
||||
tbc = COL8_848484;
|
||||
}
|
||||
boxfill8(buf, xsize, tbc, 3, 3, xsize - 4, 20);
|
||||
putfonts8_asc(buf, xsize, 24, 4, tc, title);
|
||||
for (y = 0; y < 14; y++) {
|
||||
for (x = 0; x < 16; x++) {
|
||||
c = closebtn[y][x];
|
||||
if (c == '@') {
|
||||
c = COL8_000000;
|
||||
} else if (c == '$') {
|
||||
c = COL8_848484;
|
||||
} else if (c == 'Q') {
|
||||
c = COL8_C6C6C6;
|
||||
} else {
|
||||
c = COL8_FFFFFF;
|
||||
}
|
||||
buf[(5 + y) * xsize + (xsize - 21 + x)] = c;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void putfonts8_asc_sht(struct SHEET *sht, int x, int y, int c, int b, char *s, int l)
|
||||
{
|
||||
boxfill8(sht->buf, sht->bxsize, b, x, y, x + l * 8 - 1, y + 15);
|
||||
putfonts8_asc(sht->buf, sht->bxsize, x, y, c, s);
|
||||
sheet_refresh(sht, x, y, x + l * 8, y + 16);
|
||||
return;
|
||||
}
|
||||
|
||||
void make_textbox8(struct SHEET *sht, int x0, int y0, int sx, int sy, int c)
|
||||
{
|
||||
int x1 = x0 + sx, y1 = y0 + sy;
|
||||
boxfill8(sht->buf, sht->bxsize, COL8_848484, x0 - 2, y0 - 3, x1 + 1, y0 - 3);
|
||||
boxfill8(sht->buf, sht->bxsize, COL8_848484, x0 - 3, y0 - 3, x0 - 3, y1 + 1);
|
||||
boxfill8(sht->buf, sht->bxsize, COL8_FFFFFF, x0 - 3, y1 + 2, x1 + 1, y1 + 2);
|
||||
boxfill8(sht->buf, sht->bxsize, COL8_FFFFFF, x1 + 2, y0 - 3, x1 + 2, y1 + 2);
|
||||
boxfill8(sht->buf, sht->bxsize, COL8_000000, x0 - 1, y0 - 2, x1 + 0, y0 - 2);
|
||||
boxfill8(sht->buf, sht->bxsize, COL8_000000, x0 - 2, y0 - 2, x0 - 2, y1 + 0);
|
||||
boxfill8(sht->buf, sht->bxsize, COL8_C6C6C6, x0 - 2, y1 + 1, x1 + 0, y1 + 1);
|
||||
boxfill8(sht->buf, sht->bxsize, COL8_C6C6C6, x1 + 1, y0 - 2, x1 + 1, y1 + 1);
|
||||
boxfill8(sht->buf, sht->bxsize, c, x0 - 1, y0 - 1, x1 + 0, y1 + 0);
|
||||
return;
|
||||
}
|
||||
|
||||
void change_wtitle8(struct SHEET *sht, char act)
|
||||
{
|
||||
int x, y, xsize = sht->bxsize;
|
||||
char c, tc_new, tbc_new, tc_old, tbc_old, *buf = sht->buf;
|
||||
if (act != 0) {
|
||||
tc_new = COL8_FFFFFF;
|
||||
tbc_new = COL8_000084;
|
||||
tc_old = COL8_C6C6C6;
|
||||
tbc_old = COL8_848484;
|
||||
} else {
|
||||
tc_new = COL8_C6C6C6;
|
||||
tbc_new = COL8_848484;
|
||||
tc_old = COL8_FFFFFF;
|
||||
tbc_old = COL8_000084;
|
||||
}
|
||||
for (y = 3; y <= 20; y++) {
|
||||
for (x = 3; x <= xsize - 4; x++) {
|
||||
c = buf[y * xsize + x];
|
||||
if (c == tc_old && x <= xsize - 22) {
|
||||
c = tc_new;
|
||||
} else if (c == tbc_old) {
|
||||
c = tbc_new;
|
||||
}
|
||||
buf[y * xsize + x] = c;
|
||||
}
|
||||
}
|
||||
sheet_refresh(sht, 3, 3, xsize, 21);
|
||||
return;
|
||||
}
|
||||
11
24_day/winhelo.c
Normal file
11
24_day/winhelo.c
Normal file
@@ -0,0 +1,11 @@
|
||||
int api_openwin(char *buf, int xsiz, int ysiz, int col_inv, char *title);
|
||||
void api_end(void);
|
||||
|
||||
char buf[150 * 50];
|
||||
|
||||
void HariMain(void)
|
||||
{
|
||||
int win;
|
||||
win = api_openwin(buf, 150, 50, -1, "hello");
|
||||
api_end();
|
||||
}
|
||||
15
24_day/winhelo2.c
Normal file
15
24_day/winhelo2.c
Normal file
@@ -0,0 +1,15 @@
|
||||
int api_openwin(char *buf, int xsiz, int ysiz, int col_inv, char *title);
|
||||
void api_putstrwin(int win, int x, int y, int col, int len, char *str);
|
||||
void api_boxfilwin(int win, int x0, int y0, int x1, int y1, int col);
|
||||
void api_end(void);
|
||||
|
||||
char buf[150 * 50];
|
||||
|
||||
void HariMain(void)
|
||||
{
|
||||
int win;
|
||||
win = api_openwin(buf, 150, 50, -1, "hello");
|
||||
api_boxfilwin(win, 8, 36, 141, 43, 3); /*黄色*/
|
||||
api_putstrwin(win, 28, 28, 0 /*黑色*/, 12, "hello, world");
|
||||
api_end();
|
||||
}
|
||||
19
24_day/winhelo3.c
Normal file
19
24_day/winhelo3.c
Normal file
@@ -0,0 +1,19 @@
|
||||
int api_openwin(char *buf, int xsiz, int ysiz, int col_inv, char *title);
|
||||
void api_putstrwin(int win, int x, int y, int col, int len, char *str);
|
||||
void api_boxfilwin(int win, int x0, int y0, int x1, int y1, int col);
|
||||
void api_initmalloc(void);
|
||||
char *api_malloc(int size);
|
||||
void api_end(void);
|
||||
|
||||
void HariMain(void)
|
||||
{
|
||||
char *buf;
|
||||
int win;
|
||||
|
||||
api_initmalloc();
|
||||
buf = api_malloc(150 * 50);
|
||||
win = api_openwin(buf, 150, 50, -1, "hello");
|
||||
api_boxfilwin(win, 8, 36, 141, 43, 6); /*浅蓝色*/
|
||||
api_putstrwin(win, 28, 28, 0 , 12, "hello, world");/*黑色*/
|
||||
api_end();
|
||||
}
|
||||
1
25_day/!cons_9x.bat
Normal file
1
25_day/!cons_9x.bat
Normal file
@@ -0,0 +1 @@
|
||||
command
|
||||
1
25_day/!cons_nt.bat
Normal file
1
25_day/!cons_nt.bat
Normal file
@@ -0,0 +1 @@
|
||||
cmd.exe
|
||||
232
25_day/Makefile
Normal file
232
25_day/Makefile
Normal file
@@ -0,0 +1,232 @@
|
||||
OBJS_BOOTPACK = bootpack.obj naskfunc.obj hankaku.obj graphic.obj dsctbl.obj \
|
||||
int.obj fifo.obj keyboard.obj mouse.obj memory.obj sheet.obj timer.obj \
|
||||
mtask.obj window.obj console.obj file.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
|
||||
|
||||
hello.hrb : hello.nas Makefile
|
||||
$(NASK) hello.nas hello.hrb hello.lst
|
||||
|
||||
hello2.hrb : hello2.nas Makefile
|
||||
$(NASK) hello2.nas hello2.hrb hello2.lst
|
||||
|
||||
a.bim : a.obj a_nask.obj Makefile
|
||||
$(OBJ2BIM) @$(RULEFILE) out:a.bim map:a.map a.obj a_nask.obj
|
||||
|
||||
a.hrb : a.bim Makefile
|
||||
$(BIM2HRB) a.bim a.hrb 0
|
||||
|
||||
hello3.bim : hello3.obj a_nask.obj Makefile
|
||||
$(OBJ2BIM) @$(RULEFILE) out:hello3.bim map:hello3.map hello3.obj a_nask.obj
|
||||
|
||||
hello3.hrb : hello3.bim Makefile
|
||||
$(BIM2HRB) hello3.bim hello3.hrb 0
|
||||
|
||||
hello4.bim : hello4.obj a_nask.obj Makefile
|
||||
$(OBJ2BIM) @$(RULEFILE) out:hello4.bim stack:1k map:hello4.map \
|
||||
hello4.obj a_nask.obj
|
||||
|
||||
hello4.hrb : hello4.bim Makefile
|
||||
$(BIM2HRB) hello4.bim hello4.hrb 0
|
||||
|
||||
hello5.bim : hello5.obj Makefile
|
||||
$(OBJ2BIM) @$(RULEFILE) out:hello5.bim stack:1k map:hello5.map hello5.obj
|
||||
|
||||
hello5.hrb : hello5.bim Makefile
|
||||
$(BIM2HRB) hello5.bim hello5.hrb 0
|
||||
|
||||
winhelo.bim : winhelo.obj a_nask.obj Makefile
|
||||
$(OBJ2BIM) @$(RULEFILE) out:winhelo.bim stack:1k map:winhelo.map \
|
||||
winhelo.obj a_nask.obj
|
||||
|
||||
winhelo.hrb : winhelo.bim Makefile
|
||||
$(BIM2HRB) winhelo.bim winhelo.hrb 0
|
||||
|
||||
winhelo2.bim : winhelo2.obj a_nask.obj Makefile
|
||||
$(OBJ2BIM) @$(RULEFILE) out:winhelo2.bim stack:1k map:winhelo2.map \
|
||||
winhelo2.obj a_nask.obj
|
||||
|
||||
winhelo2.hrb : winhelo2.bim Makefile
|
||||
$(BIM2HRB) winhelo2.bim winhelo2.hrb 0
|
||||
|
||||
winhelo3.bim : winhelo3.obj a_nask.obj Makefile
|
||||
$(OBJ2BIM) @$(RULEFILE) out:winhelo3.bim stack:1k map:winhelo3.map \
|
||||
winhelo3.obj a_nask.obj
|
||||
|
||||
winhelo3.hrb : winhelo3.bim Makefile
|
||||
$(BIM2HRB) winhelo3.bim winhelo3.hrb 40k
|
||||
|
||||
star1.bim : star1.obj a_nask.obj Makefile
|
||||
$(OBJ2BIM) @$(RULEFILE) out:star1.bim stack:1k map:star1.map \
|
||||
star1.obj a_nask.obj
|
||||
|
||||
star1.hrb : star1.bim Makefile
|
||||
$(BIM2HRB) star1.bim star1.hrb 47k
|
||||
|
||||
stars.bim : stars.obj a_nask.obj Makefile
|
||||
$(OBJ2BIM) @$(RULEFILE) out:stars.bim stack:1k map:stars.map \
|
||||
stars.obj a_nask.obj
|
||||
|
||||
stars.hrb : stars.bim Makefile
|
||||
$(BIM2HRB) stars.bim stars.hrb 47k
|
||||
|
||||
stars2.bim : stars2.obj a_nask.obj Makefile
|
||||
$(OBJ2BIM) @$(RULEFILE) out:stars2.bim stack:1k map:stars2.map \
|
||||
stars2.obj a_nask.obj
|
||||
|
||||
stars2.hrb : stars2.bim Makefile
|
||||
$(BIM2HRB) stars2.bim stars2.hrb 47k
|
||||
|
||||
lines.bim : lines.obj a_nask.obj Makefile
|
||||
$(OBJ2BIM) @$(RULEFILE) out:lines.bim stack:1k map:lines.map \
|
||||
lines.obj a_nask.obj
|
||||
|
||||
lines.hrb : lines.bim Makefile
|
||||
$(BIM2HRB) lines.bim lines.hrb 48k
|
||||
|
||||
walk.bim : walk.obj a_nask.obj Makefile
|
||||
$(OBJ2BIM) @$(RULEFILE) out:walk.bim stack:1k map:walk.map \
|
||||
walk.obj a_nask.obj
|
||||
|
||||
walk.hrb : walk.bim Makefile
|
||||
$(BIM2HRB) walk.bim walk.hrb 48k
|
||||
|
||||
noodle.bim : noodle.obj a_nask.obj Makefile
|
||||
$(OBJ2BIM) @$(RULEFILE) out:noodle.bim stack:1k map:noodle.map \
|
||||
noodle.obj a_nask.obj
|
||||
|
||||
noodle.hrb : noodle.bim Makefile
|
||||
$(BIM2HRB) noodle.bim noodle.hrb 40k
|
||||
|
||||
beepdown.bim : beepdown.obj a_nask.obj Makefile
|
||||
$(OBJ2BIM) @$(RULEFILE) out:beepdown.bim stack:1k map:beepdown.map \
|
||||
beepdown.obj a_nask.obj
|
||||
|
||||
beepdown.hrb : beepdown.bim Makefile
|
||||
$(BIM2HRB) beepdown.bim beepdown.hrb 40k
|
||||
|
||||
color.bim : color.obj a_nask.obj Makefile
|
||||
$(OBJ2BIM) @$(RULEFILE) out:color.bim stack:1k map:color.map \
|
||||
color.obj a_nask.obj
|
||||
|
||||
color.hrb : color.bim Makefile
|
||||
$(BIM2HRB) color.bim color.hrb 56k
|
||||
|
||||
color2.bim : color2.obj a_nask.obj Makefile
|
||||
$(OBJ2BIM) @$(RULEFILE) out:color2.bim stack:1k map:color2.map \
|
||||
color2.obj a_nask.obj
|
||||
|
||||
color2.hrb : color2.bim Makefile
|
||||
$(BIM2HRB) color2.bim color2.hrb 56k
|
||||
|
||||
haribote.img : ipl10.bin haribote.sys Makefile \
|
||||
hello.hrb hello2.hrb a.hrb hello3.hrb hello4.hrb hello5.hrb \
|
||||
winhelo.hrb winhelo2.hrb winhelo3.hrb star1.hrb stars.hrb stars2.hrb \
|
||||
lines.hrb walk.hrb noodle.hrb beepdown.hrb color.hrb color2.hrb
|
||||
$(EDIMG) imgin:../z_tools/fdimg0at.tek \
|
||||
wbinimg src:ipl10.bin len:512 from:0 to:0 \
|
||||
copy from:haribote.sys to:@: \
|
||||
copy from:ipl10.nas to:@: \
|
||||
copy from:make.bat to:@: \
|
||||
copy from:hello.hrb to:@: \
|
||||
copy from:hello2.hrb to:@: \
|
||||
copy from:a.hrb to:@: \
|
||||
copy from:hello3.hrb to:@: \
|
||||
copy from:hello4.hrb to:@: \
|
||||
copy from:hello5.hrb to:@: \
|
||||
copy from:winhelo.hrb to:@: \
|
||||
copy from:winhelo2.hrb to:@: \
|
||||
copy from:winhelo3.hrb to:@: \
|
||||
copy from:star1.hrb to:@: \
|
||||
copy from:stars.hrb to:@: \
|
||||
copy from:stars2.hrb to:@: \
|
||||
copy from:lines.hrb to:@: \
|
||||
copy from:walk.hrb to:@: \
|
||||
copy from:noodle.hrb to:@: \
|
||||
copy from:beepdown.hrb to:@: \
|
||||
copy from:color.hrb to:@: \
|
||||
copy from:color2.hrb 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.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
|
||||
8
25_day/a.c
Normal file
8
25_day/a.c
Normal file
@@ -0,0 +1,8 @@
|
||||
void api_putchar(int c);
|
||||
void api_end(void);
|
||||
|
||||
void HariMain(void)
|
||||
{
|
||||
api_putchar('A');
|
||||
api_end();
|
||||
}
|
||||
230
25_day/a_nask.nas
Normal file
230
25_day/a_nask.nas
Normal file
@@ -0,0 +1,230 @@
|
||||
[FORMAT "WCOFF"] ; 生成对象文件的模式
|
||||
[INSTRSET "i486p"] ; 表示使用486兼容指令集
|
||||
[BITS 32] ; 生成32位模式机器语言
|
||||
[FILE "a_nask.nas"] ; 源文件名信息
|
||||
|
||||
GLOBAL _api_putchar
|
||||
GLOBAL _api_putstr0
|
||||
GLOBAL _api_end
|
||||
GLOBAL _api_openwin
|
||||
GLOBAL _api_putstrwin
|
||||
GLOBAL _api_boxfilwin
|
||||
GLOBAL _api_initmalloc
|
||||
GLOBAL _api_malloc
|
||||
GLOBAL _api_free
|
||||
GLOBAL _api_point
|
||||
GLOBAL _api_refreshwin
|
||||
GLOBAL _api_linewin
|
||||
GLOBAL _api_closewin
|
||||
GLOBAL _api_getkey
|
||||
GLOBAL _api_alloctimer
|
||||
GLOBAL _api_inittimer
|
||||
GLOBAL _api_settimer
|
||||
GLOBAL _api_freetimer
|
||||
GLOBAL _api_beep
|
||||
|
||||
[SECTION .text]
|
||||
|
||||
_api_putchar: ; void api_putchar(int c);
|
||||
MOV EDX,1
|
||||
MOV AL,[ESP+4] ; c
|
||||
INT 0x40
|
||||
RET
|
||||
|
||||
_api_putstr0: ; void api_putstr0(char *s);
|
||||
PUSH EBX
|
||||
MOV EDX,2
|
||||
MOV EBX,[ESP+8] ; s
|
||||
INT 0x40
|
||||
POP EBX
|
||||
RET
|
||||
|
||||
_api_end: ; void api_end(void);
|
||||
MOV EDX,4
|
||||
INT 0x40
|
||||
|
||||
_api_openwin: ; int api_openwin(char *buf, int xsiz, int ysiz, int col_inv, char *title);
|
||||
PUSH EDI
|
||||
PUSH ESI
|
||||
PUSH EBX
|
||||
MOV EDX,5
|
||||
MOV EBX,[ESP+16] ; buf
|
||||
MOV ESI,[ESP+20] ; xsiz
|
||||
MOV EDI,[ESP+24] ; ysiz
|
||||
MOV EAX,[ESP+28] ; col_inv
|
||||
MOV ECX,[ESP+32] ; title
|
||||
INT 0x40
|
||||
POP EBX
|
||||
POP ESI
|
||||
POP EDI
|
||||
RET
|
||||
|
||||
_api_putstrwin: ; void api_putstrwin(int win, int x, int y, int col, int len, char *str);
|
||||
PUSH EDI
|
||||
PUSH ESI
|
||||
PUSH EBP
|
||||
PUSH EBX
|
||||
MOV EDX,6
|
||||
MOV EBX,[ESP+20] ; win
|
||||
MOV ESI,[ESP+24] ; x
|
||||
MOV EDI,[ESP+28] ; y
|
||||
MOV EAX,[ESP+32] ; col
|
||||
MOV ECX,[ESP+36] ; len
|
||||
MOV EBP,[ESP+40] ; str
|
||||
INT 0x40
|
||||
POP EBX
|
||||
POP EBP
|
||||
POP ESI
|
||||
POP EDI
|
||||
RET
|
||||
|
||||
_api_boxfilwin: ; void api_boxfilwin(int win, int x0, int y0, int x1, int y1, int col);
|
||||
PUSH EDI
|
||||
PUSH ESI
|
||||
PUSH EBP
|
||||
PUSH EBX
|
||||
MOV EDX,7
|
||||
MOV EBX,[ESP+20] ; win
|
||||
MOV EAX,[ESP+24] ; x0
|
||||
MOV ECX,[ESP+28] ; y0
|
||||
MOV ESI,[ESP+32] ; x1
|
||||
MOV EDI,[ESP+36] ; y1
|
||||
MOV EBP,[ESP+40] ; col
|
||||
INT 0x40
|
||||
POP EBX
|
||||
POP EBP
|
||||
POP ESI
|
||||
POP EDI
|
||||
RET
|
||||
|
||||
_api_initmalloc: ; void api_initmalloc(void);
|
||||
PUSH EBX
|
||||
MOV EDX,8
|
||||
MOV EBX,[CS:0x0020] ; malloc内存空间的地址
|
||||
MOV EAX,EBX
|
||||
ADD EAX,32*1024 ; 加上32KB
|
||||
MOV ECX,[CS:0x0000] ; 数据段的大小
|
||||
SUB ECX,EAX
|
||||
INT 0x40
|
||||
POP EBX
|
||||
RET
|
||||
|
||||
_api_malloc: ; char *api_malloc(int size);
|
||||
PUSH EBX
|
||||
MOV EDX,9
|
||||
MOV EBX,[CS:0x0020]
|
||||
MOV ECX,[ESP+8] ; size
|
||||
INT 0x40
|
||||
POP EBX
|
||||
RET
|
||||
|
||||
_api_free: ; void api_free(char *addr, int size);
|
||||
PUSH EBX
|
||||
MOV EDX,10
|
||||
MOV EBX,[CS:0x0020]
|
||||
MOV EAX,[ESP+ 8] ; addr
|
||||
MOV ECX,[ESP+12] ; size
|
||||
INT 0x40
|
||||
POP EBX
|
||||
RET
|
||||
|
||||
_api_point: ; void api_point(int win, int x, int y, int col);
|
||||
PUSH EDI
|
||||
PUSH ESI
|
||||
PUSH EBX
|
||||
MOV EDX,11
|
||||
MOV EBX,[ESP+16] ; win
|
||||
MOV ESI,[ESP+20] ; x
|
||||
MOV EDI,[ESP+24] ; y
|
||||
MOV EAX,[ESP+28] ; col
|
||||
INT 0x40
|
||||
POP EBX
|
||||
POP ESI
|
||||
POP EDI
|
||||
RET
|
||||
|
||||
_api_refreshwin: ; void api_refreshwin(int win, int x0, int y0, int x1, int y1);
|
||||
PUSH EDI
|
||||
PUSH ESI
|
||||
PUSH EBX
|
||||
MOV EDX,12
|
||||
MOV EBX,[ESP+16] ; win
|
||||
MOV EAX,[ESP+20] ; x0
|
||||
MOV ECX,[ESP+24] ; y0
|
||||
MOV ESI,[ESP+28] ; x1
|
||||
MOV EDI,[ESP+32] ; y1
|
||||
INT 0x40
|
||||
POP EBX
|
||||
POP ESI
|
||||
POP EDI
|
||||
RET
|
||||
|
||||
_api_linewin: ; void api_linewin(int win, int x0, int y0, int x1, int y1, int col);
|
||||
PUSH EDI
|
||||
PUSH ESI
|
||||
PUSH EBP
|
||||
PUSH EBX
|
||||
MOV EDX,13
|
||||
MOV EBX,[ESP+20] ; win
|
||||
MOV EAX,[ESP+24] ; x0
|
||||
MOV ECX,[ESP+28] ; y0
|
||||
MOV ESI,[ESP+32] ; x1
|
||||
MOV EDI,[ESP+36] ; y1
|
||||
MOV EBP,[ESP+40] ; col
|
||||
INT 0x40
|
||||
POP EBX
|
||||
POP EBP
|
||||
POP ESI
|
||||
POP EDI
|
||||
RET
|
||||
|
||||
_api_closewin: ; void api_closewin(int win);
|
||||
PUSH EBX
|
||||
MOV EDX,14
|
||||
MOV EBX,[ESP+8] ; win
|
||||
INT 0x40
|
||||
POP EBX
|
||||
RET
|
||||
|
||||
_api_getkey: ; int api_getkey(int mode);
|
||||
MOV EDX,15
|
||||
MOV EAX,[ESP+4] ; mode
|
||||
INT 0x40
|
||||
RET
|
||||
|
||||
_api_alloctimer: ; int api_alloctimer(void);
|
||||
MOV EDX,16
|
||||
INT 0x40
|
||||
RET
|
||||
|
||||
_api_inittimer: ; void api_inittimer(int timer, int data);
|
||||
PUSH EBX
|
||||
MOV EDX,17
|
||||
MOV EBX,[ESP+ 8] ; timer
|
||||
MOV EAX,[ESP+12] ; data
|
||||
INT 0x40
|
||||
POP EBX
|
||||
RET
|
||||
|
||||
_api_settimer: ; void api_settimer(int timer, int time);
|
||||
PUSH EBX
|
||||
MOV EDX,18
|
||||
MOV EBX,[ESP+ 8] ; timer
|
||||
MOV EAX,[ESP+12] ; time
|
||||
INT 0x40
|
||||
POP EBX
|
||||
RET
|
||||
|
||||
_api_freetimer: ; void api_freetimer(int timer);
|
||||
PUSH EBX
|
||||
MOV EDX,19
|
||||
MOV EBX,[ESP+ 8] ; timer
|
||||
INT 0x40
|
||||
POP EBX
|
||||
RET
|
||||
|
||||
_api_beep: ; void api_beep(int tone);
|
||||
MOV EDX,20
|
||||
MOV EAX,[ESP+4] ; tone
|
||||
INT 0x40
|
||||
RET
|
||||
202
25_day/asmhead.nas
Normal file
202
25_day/asmhead.nas
Normal file
@@ -0,0 +1,202 @@
|
||||
; haribote-os boot asm
|
||||
; TAB=4
|
||||
|
||||
[INSTRSET "i486p"]
|
||||
|
||||
VBEMODE EQU 0x105 ; 1024 x 768 x 8bit 彩色
|
||||
; 显示模式
|
||||
; 0x100 : 640 x 400 x 8bit 彩色
|
||||
; 0x101 : 640 x 480 x 8bit 彩色
|
||||
; 0x103 : 800 x 600 x 8bit 彩色
|
||||
; 0x105 : 1024 x 768 x 8bit 彩色
|
||||
; 0x107 : 1280 x 1024 x 8bit 彩色
|
||||
|
||||
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 ; 这个的程序要被装载的内存地址
|
||||
|
||||
; 确认VBE是否存在
|
||||
|
||||
MOV AX,0x9000
|
||||
MOV ES,AX
|
||||
MOV DI,0
|
||||
MOV AX,0x4f00
|
||||
INT 0x10
|
||||
CMP AX,0x004f
|
||||
JNE scrn320
|
||||
|
||||
; 检查VBE的版本
|
||||
|
||||
MOV AX,[ES:DI+4]
|
||||
CMP AX,0x0200
|
||||
JB scrn320 ; if (AX < 0x0200) goto scrn320
|
||||
|
||||
; 取得画面模式信息
|
||||
|
||||
MOV CX,VBEMODE
|
||||
MOV AX,0x4f01
|
||||
INT 0x10
|
||||
CMP AX,0x004f
|
||||
JNE scrn320
|
||||
|
||||
; 画面模式信息的确认
|
||||
CMP BYTE [ES:DI+0x19],8 ;颜色数必须为8
|
||||
JNE scrn320
|
||||
CMP BYTE [ES:DI+0x1b],4 ;颜色的指定方法必须为4(4是调色板模式)
|
||||
JNE scrn320
|
||||
MOV AX,[ES:DI+0x00] ;模式属性bit7不是1就不能加上0x4000
|
||||
AND AX,0x0080
|
||||
JZ scrn320 ; 模式属性的bit7是0,所以放弃
|
||||
|
||||
; 画面设置
|
||||
|
||||
MOV BX,VBEMODE+0x4000
|
||||
MOV AX,0x4f02
|
||||
INT 0x10
|
||||
MOV BYTE [VMODE],8 ; 屏幕的模式(参考C语言的引用)
|
||||
MOV AX,[ES:DI+0x12]
|
||||
MOV [SCRNX],AX
|
||||
MOV AX,[ES:DI+0x14]
|
||||
MOV [SCRNY],AX
|
||||
MOV EAX,[ES:DI+0x28] ;VRAM的地址
|
||||
MOV [VRAM],EAX
|
||||
JMP keystatus
|
||||
|
||||
scrn320:
|
||||
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 获取指示灯状态
|
||||
|
||||
keystatus:
|
||||
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能够访问1MB以上的内存空间,设定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为0(禁用分页)
|
||||
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 ; 可以读写的段(segment)32bit
|
||||
DW 0xffff,0x0000,0x9a28,0x0047 ; 可执行的文件的32bit寄存器(bootpack用)
|
||||
|
||||
DW 0
|
||||
GDTR0:
|
||||
DW 8*3-1
|
||||
DD GDT0
|
||||
|
||||
ALIGNB 16
|
||||
bootpack:
|
||||
24
25_day/beepdown.c
Normal file
24
25_day/beepdown.c
Normal file
@@ -0,0 +1,24 @@
|
||||
void api_end(void);
|
||||
int api_getkey(int mode);
|
||||
int api_alloctimer(void);
|
||||
void api_inittimer(int timer, int data);
|
||||
void api_settimer(int timer, int time);
|
||||
void api_beep(int tone);
|
||||
|
||||
void HariMain(void)
|
||||
{
|
||||
int i, timer;
|
||||
timer = api_alloctimer();
|
||||
api_inittimer(timer, 128);
|
||||
for (i = 20000000; i >= 20000; i -= i / 100) {
|
||||
/* 20KHz~20Hz,即人类可以听到的声音范围*/
|
||||
/* i以1%的速度递减*/
|
||||
api_beep(i);
|
||||
api_settimer(timer, 1); /* 0.01秒*/
|
||||
if (api_getkey(1) != 128) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
api_beep(0);
|
||||
api_end();
|
||||
}
|
||||
305
25_day/bootpack.c
Normal file
305
25_day/bootpack.c
Normal file
@@ -0,0 +1,305 @@
|
||||
/* bootpack */
|
||||
|
||||
#include "bootpack.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#define KEYCMD_LED 0xed
|
||||
|
||||
void keywin_off(struct SHEET *key_win);
|
||||
void keywin_on(struct SHEET *key_win);
|
||||
|
||||
void HariMain(void)
|
||||
{
|
||||
struct BOOTINFO *binfo = (struct BOOTINFO *) ADR_BOOTINFO;
|
||||
struct SHTCTL *shtctl;
|
||||
char s[40];
|
||||
struct FIFO32 fifo, keycmd;
|
||||
int fifobuf[128], keycmd_buf[32], *cons_fifo[2];
|
||||
int mx, my, i;
|
||||
unsigned int memtotal;
|
||||
struct MOUSE_DEC mdec;
|
||||
struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR;
|
||||
unsigned char *buf_back, buf_mouse[256], *buf_cons[2];
|
||||
struct SHEET *sht_back, *sht_mouse, *sht_cons[2];
|
||||
struct TASK *task_a, *task_cons[2], *task;
|
||||
static char keytable0[0x80] = {
|
||||
0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '^', 0x08, 0,
|
||||
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '@', '[', 0x0a, 0, 'A', 'S',
|
||||
'D', 'F', 'G', 'H', 'J', 'K', 'L', ';', ':', 0, 0, ']', 'Z', 'X', 'C', 'V',
|
||||
'B', 'N', 'M', ',', '.', '/', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, '7', '8', '9', '-', '4', '5', '6', '+', '1',
|
||||
'2', '3', '0', '.', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0x5c, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x5c, 0, 0
|
||||
};
|
||||
static char keytable1[0x80] = {
|
||||
0, 0, '!', 0x22, '#', '$', '%', '&', 0x27, '(', ')', '~', '=', '~', 0x08, 0,
|
||||
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '`', '{', 0x0a, 0, 'A', 'S',
|
||||
'D', 'F', 'G', 'H', 'J', 'K', 'L', '+', '*', 0, 0, '}', 'Z', 'X', 'C', 'V',
|
||||
'B', 'N', 'M', '<', '>', '?', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, '7', '8', '9', '-', '4', '5', '6', '+', '1',
|
||||
'2', '3', '0', '.', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, '_', 0, 0, 0, 0, 0, 0, 0, 0, 0, '|', 0, 0
|
||||
};
|
||||
int key_shift = 0, key_leds = (binfo->leds >> 4) & 7, keycmd_wait = -1;
|
||||
int j, x, y, mmx = -1, mmy = -1;
|
||||
struct SHEET *sht = 0, *key_win;
|
||||
|
||||
init_gdtidt();
|
||||
init_pic();
|
||||
io_sti(); /* IDT/PIC的初始化已经完成,于是开放CPU的中断 */
|
||||
fifo32_init(&fifo, 128, fifobuf, 0);
|
||||
init_pit();
|
||||
init_keyboard(&fifo, 256);
|
||||
enable_mouse(&fifo, 512, &mdec);
|
||||
io_out8(PIC0_IMR, 0xf8); /* 设定PIT和PIC1以及键盘为许可(11111000) */
|
||||
io_out8(PIC1_IMR, 0xef); /* 开放鼠标中断(11101111) */
|
||||
fifo32_init(&keycmd, 32, keycmd_buf, 0);
|
||||
|
||||
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);
|
||||
task_a = task_init(memman);
|
||||
fifo.task = task_a;
|
||||
task_run(task_a, 1, 2);
|
||||
*((int *) 0x0fe4) = (int) shtctl;
|
||||
|
||||
/* sht_back */
|
||||
sht_back = 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); /* 无透明色 */
|
||||
init_screen8(buf_back, binfo->scrnx, binfo->scrny);
|
||||
|
||||
/* sht_cons */
|
||||
for (i = 0; i < 2; i++) {
|
||||
sht_cons[i] = sheet_alloc(shtctl);
|
||||
buf_cons[i] = (unsigned char *) memman_alloc_4k(memman, 256 * 165);
|
||||
sheet_setbuf(sht_cons[i], buf_cons[i], 256, 165, -1); /*没有透明色*/
|
||||
make_window8(buf_cons[i], 256, 165, "console", 0);
|
||||
make_textbox8(sht_cons[i], 8, 28, 240, 128, COL8_000000);
|
||||
task_cons[i] = task_alloc();
|
||||
task_cons[i]->tss.esp = memman_alloc_4k(memman, 64 * 1024) + 64 * 1024 - 12;
|
||||
task_cons[i]->tss.eip = (int) &console_task;
|
||||
task_cons[i]->tss.es = 1 * 8;
|
||||
task_cons[i]->tss.cs = 2 * 8;
|
||||
task_cons[i]->tss.ss = 1 * 8;
|
||||
task_cons[i]->tss.ds = 1 * 8;
|
||||
task_cons[i]->tss.fs = 1 * 8;
|
||||
task_cons[i]->tss.gs = 1 * 8;
|
||||
*((int *) (task_cons[i]->tss.esp + 4)) = (int) sht_cons[i];
|
||||
*((int *) (task_cons[i]->tss.esp + 8)) = memtotal;
|
||||
task_run(task_cons[i], 2, 2); /* level=2, priority=2 */
|
||||
sht_cons[i]->task = task_cons[i];
|
||||
sht_cons[i]->flags |= 0x20; /*有光标*/
|
||||
cons_fifo[i] = (int *) memman_alloc_4k(memman, 128 * 4);
|
||||
fifo32_init(&task_cons[i]->fifo, 128, cons_fifo[i], task_cons[i]);
|
||||
}
|
||||
|
||||
/* sht_mouse */
|
||||
sht_mouse = sheet_alloc(shtctl);
|
||||
sheet_setbuf(sht_mouse, buf_mouse, 16, 16, 99);
|
||||
init_mouse_cursor8(buf_mouse, 99);
|
||||
mx = (binfo->scrnx - 16) / 2; /* 计算坐标使其位于画面中央 */
|
||||
my = (binfo->scrny - 28 - 16) / 2;
|
||||
|
||||
sheet_slide(sht_back, 0, 0);
|
||||
sheet_slide(sht_cons[1], 56, 6);
|
||||
sheet_slide(sht_cons[0], 8, 2);
|
||||
sheet_slide(sht_mouse, mx, my);
|
||||
sheet_updown(sht_back, 0);
|
||||
sheet_updown(sht_cons[1], 1);
|
||||
sheet_updown(sht_cons[0], 2);
|
||||
sheet_updown(sht_mouse, 3);
|
||||
key_win = sht_cons[0];
|
||||
keywin_on(key_win);
|
||||
|
||||
/*为了避免和键盘当前状态冲突,在一开始先进行设置*/
|
||||
fifo32_put(&keycmd, KEYCMD_LED);
|
||||
fifo32_put(&keycmd, key_leds);
|
||||
|
||||
for (;;) {
|
||||
if (fifo32_status(&keycmd) > 0 && keycmd_wait < 0) {
|
||||
/* 如果存在向键盘控制器发送的数据,则发送它 */
|
||||
keycmd_wait = fifo32_get(&keycmd);
|
||||
wait_KBC_sendready();
|
||||
io_out8(PORT_KEYDAT, keycmd_wait);
|
||||
}
|
||||
io_cli();
|
||||
if (fifo32_status(&fifo) == 0) {
|
||||
task_sleep(task_a);
|
||||
io_sti();
|
||||
} else {
|
||||
i = fifo32_get(&fifo);
|
||||
io_sti();
|
||||
if (key_win->flags == 0) { /*输入窗口被关闭*/
|
||||
key_win = shtctl->sheets[shtctl->top - 1];
|
||||
keywin_on(key_win);
|
||||
}
|
||||
if (256 <= i && i <= 511) { /* 键盘数据*/
|
||||
if (i < 0x80 + 256) { /*将按键编码转换为字符编码*/
|
||||
if (key_shift == 0) {
|
||||
s[0] = keytable0[i - 256];
|
||||
} else {
|
||||
s[0] = keytable1[i - 256];
|
||||
}
|
||||
} else {
|
||||
s[0] = 0;
|
||||
}
|
||||
if ('A' <= s[0] && s[0] <= 'Z') { /*当输入字符为英文字母时*/
|
||||
if (((key_leds & 4) == 0 && key_shift == 0) ||
|
||||
((key_leds & 4) != 0 && key_shift != 0)) {
|
||||
s[0] += 0x20; /*将大写字母转换为小写字母*/
|
||||
}
|
||||
}
|
||||
if (s[0] != 0) { /*一般字符、退格键、回车键*/
|
||||
fifo32_put(&key_win->task->fifo, s[0] + 256);
|
||||
}
|
||||
if (i == 256 + 0x0f) { /* Tab键 */
|
||||
keywin_off(key_win);
|
||||
j = key_win->height - 1;
|
||||
if (j == 0) {
|
||||
j = shtctl->top - 1;
|
||||
}
|
||||
key_win = shtctl->sheets[j];
|
||||
keywin_on(key_win);
|
||||
}
|
||||
if (i == 256 + 0x2a) { /*左Shift ON */
|
||||
key_shift |= 1;
|
||||
}
|
||||
if (i == 256 + 0x36) { /*右Shift ON */
|
||||
key_shift |= 2;
|
||||
}
|
||||
if (i == 256 + 0xaa) { /*左Shift OFF */
|
||||
key_shift &= ~1;
|
||||
}
|
||||
if (i == 256 + 0xb6) { /*右Shift OFF */
|
||||
key_shift &= ~2;
|
||||
}
|
||||
if (i == 256 + 0x3a) { /* CapsLock */
|
||||
key_leds ^= 4;
|
||||
fifo32_put(&keycmd, KEYCMD_LED);
|
||||
fifo32_put(&keycmd, key_leds);
|
||||
}
|
||||
if (i == 256 + 0x45) { /* NumLock */
|
||||
key_leds ^= 2;
|
||||
fifo32_put(&keycmd, KEYCMD_LED);
|
||||
fifo32_put(&keycmd, key_leds);
|
||||
}
|
||||
if (i == 256 + 0x46) { /* ScrollLock */
|
||||
key_leds ^= 1;
|
||||
fifo32_put(&keycmd, KEYCMD_LED);
|
||||
fifo32_put(&keycmd, key_leds);
|
||||
}
|
||||
if (i == 256 + 0x3b && key_shift != 0) {
|
||||
task = key_win->task;
|
||||
if (task != 0 && task->tss.ss0 != 0) { /* Shift+F1 */
|
||||
cons_putstr0(task->cons, "\nBreak(key) :\n");
|
||||
io_cli(); /*强制结束处理时禁止任务切换*/
|
||||
task->tss.eax = (int) &(task->tss.esp0);
|
||||
task->tss.eip = (int) asm_end_app;
|
||||
io_sti();
|
||||
}
|
||||
}
|
||||
if (i == 256 + 0x57) { /* F11 */
|
||||
sheet_updown(shtctl->sheets[1], shtctl->top - 1);
|
||||
}
|
||||
if (i == 256 + 0xfa) { /*键盘成功接收到数据*/
|
||||
keycmd_wait = -1;
|
||||
}
|
||||
if (i == 256 + 0xfe) { /*键盘没有成功接收到数据*/
|
||||
wait_KBC_sendready();
|
||||
io_out8(PORT_KEYDAT, keycmd_wait);
|
||||
}
|
||||
} else if (512 <= i && i <= 767) { /* 鼠标数据*/
|
||||
if (mouse_decode(&mdec, i - 512) != 0) {
|
||||
/* 已经收集了3字节的数据,移动光标 */
|
||||
mx += mdec.x;
|
||||
my += mdec.y;
|
||||
if (mx < 0) {
|
||||
mx = 0;
|
||||
}
|
||||
if (my < 0) {
|
||||
my = 0;
|
||||
}
|
||||
if (mx > binfo->scrnx - 1) {
|
||||
mx = binfo->scrnx - 1;
|
||||
}
|
||||
if (my > binfo->scrny - 1) {
|
||||
my = binfo->scrny - 1;
|
||||
}
|
||||
sheet_slide(sht_mouse, mx, my);/* 包含sheet_refresh含sheet_refresh */
|
||||
if ((mdec.btn & 0x01) != 0) { /* 按下左键 */
|
||||
if (mmx < 0) {
|
||||
/*如果处于通常模式*/
|
||||
/*按照从上到下的顺序寻找鼠标所指向的图层*/
|
||||
for (j = shtctl->top - 1; j > 0; j--) {
|
||||
sht = shtctl->sheets[j];
|
||||
x = mx - sht->vx0;
|
||||
y = my - sht->vy0;
|
||||
if (0 <= x && x < sht->bxsize && 0 <= y && y < sht->bysize) {
|
||||
if (sht->buf[y * sht->bxsize + x] != sht->col_inv) {
|
||||
sheet_updown(sht, shtctl->top - 1);
|
||||
if (sht != key_win) {
|
||||
keywin_off(key_win);
|
||||
key_win = sht;
|
||||
keywin_on(key_win);
|
||||
}
|
||||
if (3 <= x && x < sht->bxsize - 3 && 3 <= y && y < 21) {
|
||||
mmx = mx; /*进入窗口移动模式*/
|
||||
mmy = my;
|
||||
}
|
||||
if (sht->bxsize - 21 <= x && x < sht->bxsize - 5 && 5 <= y && y < 19) {
|
||||
/*点击“×”按钮*/
|
||||
if ((sht->flags & 0x10) != 0) { /*该窗口是否为应用程序窗口?*/
|
||||
task = sht->task;
|
||||
cons_putstr0(task->cons, "\nBreak(mouse) :\n");
|
||||
io_cli(); /*强制结束处理时禁止任务切换*/
|
||||
task->tss.eax = (int) &(task->tss.esp0);
|
||||
task->tss.eip = (int) asm_end_app;
|
||||
io_sti();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/*如果处于窗口移动模式*/
|
||||
x = mx - mmx; /*计算鼠标的移动距离*/
|
||||
y = my - mmy;
|
||||
sheet_slide(sht, sht->vx0 + x, sht->vy0 + y);
|
||||
mmx = mx; /*更新为移动后的坐标*/
|
||||
mmy = my;
|
||||
}
|
||||
} else {
|
||||
/*没有按下左键*/
|
||||
mmx = -1; /*返回通常模式*/
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void keywin_off(struct SHEET *key_win)
|
||||
{
|
||||
change_wtitle8(key_win, 0);
|
||||
if ((key_win->flags & 0x20) != 0) {
|
||||
fifo32_put(&key_win->task->fifo, 3); /*命令行窗口光标OFF */
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void keywin_on(struct SHEET *key_win)
|
||||
{
|
||||
change_wtitle8(key_win, 1);
|
||||
if ((key_win->flags & 0x20) != 0) {
|
||||
fifo32_put(&key_win->task->fifo, 2); /*命令行窗口光标ON */
|
||||
}
|
||||
return;
|
||||
}
|
||||
274
25_day/bootpack.h
Normal file
274
25_day/bootpack.h
Normal file
@@ -0,0 +1,274 @@
|
||||
/* asmhead.nas */
|
||||
struct BOOTINFO { /* 0x0ff0-0x0fff */
|
||||
char cyls; /* 启动区读磁盘读到此为止 */
|
||||
char leds; /* 启动时键盘的LED的状态 */
|
||||
char vmode; /* 显卡模式为多少位彩色 */
|
||||
char reserve;
|
||||
short scrnx, scrny; /* 画面分辨率 */
|
||||
char *vram;
|
||||
};
|
||||
#define ADR_BOOTINFO 0x00000ff0
|
||||
#define ADR_DISKIMG 0x00100000
|
||||
|
||||
/* 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 load_tr(int tr);
|
||||
void asm_inthandler0c(void);
|
||||
void asm_inthandler0d(void);
|
||||
void asm_inthandler20(void);
|
||||
void asm_inthandler21(void);
|
||||
void asm_inthandler2c(void);
|
||||
unsigned int memtest_sub(unsigned int start, unsigned int end);
|
||||
void farjmp(int eip, int cs);
|
||||
void farcall(int eip, int cs);
|
||||
void asm_hrb_api(void);
|
||||
void start_app(int eip, int cs, int esp, int ds, int *tss_esp0);
|
||||
void asm_end_app(void);
|
||||
|
||||
/* fifo.c */
|
||||
struct FIFO32 {
|
||||
int *buf;
|
||||
int p, q, size, free, flags;
|
||||
struct TASK *task;
|
||||
};
|
||||
void fifo32_init(struct FIFO32 *fifo, int size, int *buf, struct TASK *task);
|
||||
int fifo32_put(struct FIFO32 *fifo, int data);
|
||||
int fifo32_get(struct FIFO32 *fifo);
|
||||
int fifo32_status(struct FIFO32 *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_TSS32 0x0089
|
||||
#define AR_INTGATE32 0x008e
|
||||
|
||||
/* int.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
|
||||
|
||||
/* keyboard.c */
|
||||
void inthandler21(int *esp);
|
||||
void wait_KBC_sendready(void);
|
||||
void init_keyboard(struct FIFO32 *fifo, int data0);
|
||||
#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 FIFO32 *fifo, int data0, struct MOUSE_DEC *mdec);
|
||||
int mouse_decode(struct MOUSE_DEC *mdec, unsigned char dat);
|
||||
|
||||
/* memory.c */
|
||||
#define MEMMAN_FREES 4090 /* <20><><EFBFBD><EFBFBD>Ŗ<EFBFBD>32KB */
|
||||
#define MEMMAN_ADDR 0x003c0000
|
||||
struct FREEINFO { /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
||||
unsigned int addr, size;
|
||||
};
|
||||
struct MEMMAN { /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǘ<EFBFBD> */
|
||||
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 *ctl;
|
||||
struct TASK *task;
|
||||
};
|
||||
struct SHTCTL {
|
||||
unsigned char *vram, *map;
|
||||
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 SHEET *sht, int height);
|
||||
void sheet_refresh(struct SHEET *sht, int bx0, int by0, int bx1, int by1);
|
||||
void sheet_slide(struct SHEET *sht, int vx0, int vy0);
|
||||
void sheet_free(struct SHEET *sht);
|
||||
|
||||
/* timer.c */
|
||||
#define MAX_TIMER 500
|
||||
struct TIMER {
|
||||
struct TIMER *next;
|
||||
unsigned int timeout;
|
||||
char flags, flags2;
|
||||
struct FIFO32 *fifo;
|
||||
int data;
|
||||
};
|
||||
struct TIMERCTL {
|
||||
unsigned int count, next;
|
||||
struct TIMER *t0;
|
||||
struct TIMER timers0[MAX_TIMER];
|
||||
};
|
||||
extern struct TIMERCTL timerctl;
|
||||
void init_pit(void);
|
||||
struct TIMER *timer_alloc(void);
|
||||
void timer_free(struct TIMER *timer);
|
||||
void timer_init(struct TIMER *timer, struct FIFO32 *fifo, int data);
|
||||
void timer_settime(struct TIMER *timer, unsigned int timeout);
|
||||
void inthandler20(int *esp);
|
||||
int timer_cancel(struct TIMER *timer);
|
||||
void timer_cancelall(struct FIFO32 *fifo);
|
||||
|
||||
/* mtask.c */
|
||||
#define MAX_TASKS 1000 /*最大任务数量*/
|
||||
#define TASK_GDT0 3 /*定义从GDT的几号开始分配给TSS */
|
||||
#define MAX_TASKS_LV 100
|
||||
#define MAX_TASKLEVELS 10
|
||||
struct TSS32 {
|
||||
int backlink, esp0, ss0, esp1, ss1, esp2, ss2, cr3;
|
||||
int eip, eflags, eax, ecx, edx, ebx, esp, ebp, esi, edi;
|
||||
int es, cs, ss, ds, fs, gs;
|
||||
int ldtr, iomap;
|
||||
};
|
||||
struct TASK {
|
||||
int sel, flags; /* sel用来存放GDT的编号*/
|
||||
int level, priority; /* 优先级 */
|
||||
struct FIFO32 fifo;
|
||||
struct TSS32 tss;
|
||||
struct CONSOLE *cons;
|
||||
int ds_base;
|
||||
};
|
||||
struct TASKLEVEL {
|
||||
int running; /*正在运行的任务数量*/
|
||||
int now; /*这个变量用来记录当前正在运行的是哪个任务*/
|
||||
struct TASK *tasks[MAX_TASKS_LV];
|
||||
};
|
||||
struct TASKCTL {
|
||||
int now_lv; /*现在活动中的LEVEL */
|
||||
char lv_change; /*在下次任务切换时是否需要改变LEVEL */
|
||||
struct TASKLEVEL level[MAX_TASKLEVELS];
|
||||
struct TASK tasks0[MAX_TASKS];
|
||||
};
|
||||
extern struct TIMER *task_timer;
|
||||
struct TASK *task_now(void);
|
||||
struct TASK *task_init(struct MEMMAN *memman);
|
||||
struct TASK *task_alloc(void);
|
||||
void task_run(struct TASK *task, int level, int priority);
|
||||
void task_switch(void);
|
||||
void task_sleep(struct TASK *task);
|
||||
|
||||
/* window.c */
|
||||
void make_window8(unsigned char *buf, int xsize, int ysize, char *title, char act);
|
||||
void putfonts8_asc_sht(struct SHEET *sht, int x, int y, int c, int b, char *s, int l);
|
||||
void make_textbox8(struct SHEET *sht, int x0, int y0, int sx, int sy, int c);
|
||||
void make_wtitle8(unsigned char *buf, int xsize, char *title, char act);
|
||||
void change_wtitle8(struct SHEET *sht, char act);
|
||||
|
||||
/* console.c */
|
||||
struct CONSOLE {
|
||||
struct SHEET *sht;
|
||||
int cur_x, cur_y, cur_c;
|
||||
struct TIMER *timer;
|
||||
};
|
||||
void console_task(struct SHEET *sheet, int memtotal);
|
||||
void cons_putchar(struct CONSOLE *cons, int chr, char move);
|
||||
void cons_newline(struct CONSOLE *cons);
|
||||
void cons_putstr0(struct CONSOLE *cons, char *s);
|
||||
void cons_putstr1(struct CONSOLE *cons, char *s, int l);
|
||||
void cons_runcmd(char *cmdline, struct CONSOLE *cons, int *fat, int memtotal);
|
||||
void cmd_mem(struct CONSOLE *cons, int memtotal);
|
||||
void cmd_cls(struct CONSOLE *cons);
|
||||
void cmd_dir(struct CONSOLE *cons);
|
||||
void cmd_type(struct CONSOLE *cons, int *fat, char *cmdline);
|
||||
int cmd_app(struct CONSOLE *cons, int *fat, char *cmdline);
|
||||
int *hrb_api(int edi, int esi, int ebp, int esp, int ebx, int edx, int ecx, int eax);
|
||||
int *inthandler0d(int *esp);
|
||||
int *inthandler0c(int *esp);
|
||||
void hrb_api_linewin(struct SHEET *sht, int x0, int y0, int x1, int y1, int col);
|
||||
|
||||
/* file.c */
|
||||
struct FILEINFO {
|
||||
unsigned char name[8], ext[3], type;
|
||||
char reserve[10];
|
||||
unsigned short time, date, clustno;
|
||||
unsigned int size;
|
||||
};
|
||||
void file_readfat(int *fat, unsigned char *img);
|
||||
void file_loadfile(int clustno, int size, char *buf, int *fat, char *img);
|
||||
struct FILEINFO *file_search(char *name, struct FILEINFO *finfo, int max);
|
||||
|
||||
27
25_day/color.c
Normal file
27
25_day/color.c
Normal file
@@ -0,0 +1,27 @@
|
||||
int api_openwin(char *buf, int xsiz, int ysiz, int col_inv, char *title);
|
||||
void api_initmalloc(void);
|
||||
char *api_malloc(int size);
|
||||
void api_refreshwin(int win, int x0, int y0, int x1, int y1);
|
||||
void api_linewin(int win, int x0, int y0, int x1, int y1, int col);
|
||||
int api_getkey(int mode);
|
||||
void api_end(void);
|
||||
|
||||
void HariMain(void)
|
||||
{
|
||||
char *buf;
|
||||
int win, x, y, r, g, b;
|
||||
api_initmalloc();
|
||||
buf = api_malloc(144 * 164);
|
||||
win = api_openwin(buf, 144, 164, -1, "color");
|
||||
for (y = 0; y < 128; y++) {
|
||||
for (x = 0; x < 128; x++) {
|
||||
r = x * 2;
|
||||
g = y * 2;
|
||||
b = 0;
|
||||
buf[(x + 8) + (y + 28) * 144] = 16 + (r / 43) + (g / 43) * 6 + (b / 43) * 36;
|
||||
}
|
||||
}
|
||||
api_refreshwin(win, 8, 28, 136, 156);
|
||||
api_getkey(1); /*等待按下任意键*/
|
||||
api_end();
|
||||
}
|
||||
42
25_day/color2.c
Normal file
42
25_day/color2.c
Normal file
@@ -0,0 +1,42 @@
|
||||
int api_openwin(char *buf, int xsiz, int ysiz, int col_inv, char *title);
|
||||
void api_initmalloc(void);
|
||||
char *api_malloc(int size);
|
||||
void api_refreshwin(int win, int x0, int y0, int x1, int y1);
|
||||
void api_linewin(int win, int x0, int y0, int x1, int y1, int col);
|
||||
int api_getkey(int mode);
|
||||
void api_end(void);
|
||||
|
||||
unsigned char rgb2pal(int r, int g, int b, int x, int y);
|
||||
|
||||
void HariMain(void)
|
||||
{
|
||||
char *buf;
|
||||
int win, x, y;
|
||||
api_initmalloc();
|
||||
buf = api_malloc(144 * 164);
|
||||
win = api_openwin(buf, 144, 164, -1, "color2");
|
||||
for (y = 0; y < 128; y++) {
|
||||
for (x = 0; x < 128; x++) {
|
||||
buf[(x + 8) + (y + 28) * 144] = rgb2pal(x * 2, y * 2, 0, x, y);
|
||||
}
|
||||
}
|
||||
api_refreshwin(win, 8, 28, 136, 156);
|
||||
api_getkey(1); /*等待按下任意键*/
|
||||
api_end();
|
||||
}
|
||||
|
||||
unsigned char rgb2pal(int r, int g, int b, int x, int y)
|
||||
{
|
||||
static int table[4] = { 3, 1, 0, 2 };
|
||||
int i;
|
||||
x &= 1; /*判断是偶数还是奇数*/
|
||||
y &= 1;
|
||||
i = table[x + y * 2]; /*用来生成中间色的常量*/
|
||||
r = (r * 21) / 256; /* r为0~20*/
|
||||
g = (g * 21) / 256;
|
||||
b = (b * 21) / 256;
|
||||
r = (r + i) / 4; /* r为0~5*/
|
||||
g = (g + i) / 4;
|
||||
b = (b + i) / 4;
|
||||
return 16 + r + g * 6 + b * 36;
|
||||
}
|
||||
516
25_day/console.c
Normal file
516
25_day/console.c
Normal file
@@ -0,0 +1,516 @@
|
||||
/* 命令行窗口相关 */
|
||||
|
||||
#include "bootpack.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
void console_task(struct SHEET *sheet, int memtotal)
|
||||
{
|
||||
struct TASK *task = task_now();
|
||||
struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR;
|
||||
int i, *fat = (int *) memman_alloc_4k(memman, 4 * 2880);
|
||||
struct CONSOLE cons;
|
||||
char cmdline[30];
|
||||
cons.sht = sheet;
|
||||
cons.cur_x = 8;
|
||||
cons.cur_y = 28;
|
||||
cons.cur_c = -1;
|
||||
task->cons = &cons;
|
||||
|
||||
cons.timer = timer_alloc();
|
||||
timer_init(cons.timer, &task->fifo, 1);
|
||||
timer_settime(cons.timer, 50);
|
||||
file_readfat(fat, (unsigned char *) (ADR_DISKIMG + 0x000200));
|
||||
|
||||
/*显示提示符*/
|
||||
cons_putchar(&cons, '>', 1);
|
||||
|
||||
for (;;) {
|
||||
io_cli();
|
||||
if (fifo32_status(&task->fifo) == 0) {
|
||||
task_sleep(task);
|
||||
io_sti();
|
||||
} else {
|
||||
i = fifo32_get(&task->fifo);
|
||||
io_sti();
|
||||
if (i <= 1) { /*光标用定时器*/
|
||||
if (i != 0) {
|
||||
timer_init(cons.timer, &task->fifo, 0); /*下次置0 */
|
||||
if (cons.cur_c >= 0) {
|
||||
cons.cur_c = COL8_FFFFFF;
|
||||
}
|
||||
} else {
|
||||
timer_init(cons.timer, &task->fifo, 1); /*下次置1 */
|
||||
if (cons.cur_c >= 0) {
|
||||
cons.cur_c = COL8_000000;
|
||||
}
|
||||
}
|
||||
timer_settime(cons.timer, 50);
|
||||
}
|
||||
if (i == 2) { /*光标ON */
|
||||
cons.cur_c = COL8_FFFFFF;
|
||||
}
|
||||
if (i == 3) { /*光标OFF */
|
||||
boxfill8(sheet->buf, sheet->bxsize, COL8_000000, cons.cur_x, cons.cur_y, cons.cur_x + 7, cons.cur_y + 15);
|
||||
cons.cur_c = -1;
|
||||
}
|
||||
if (256 <= i && i <= 511) { /*键盘数据(通过任务A)*/
|
||||
if (i == 8 + 256) {
|
||||
/*退格键*/
|
||||
if (cons.cur_x > 16) {
|
||||
/*用空格擦除光标后将光标前移一位*/
|
||||
cons_putchar(&cons, ' ', 0);
|
||||
cons.cur_x -= 8;
|
||||
}
|
||||
} else if (i == 10 + 256) {
|
||||
/*回车键*/
|
||||
/*将光标用空格擦除后换行 */
|
||||
cons_putchar(&cons, ' ', 0);
|
||||
cmdline[cons.cur_x / 8 - 2] = 0;
|
||||
cons_newline(&cons);
|
||||
cons_runcmd(cmdline, &cons, fat, memtotal); /*运行命令*/
|
||||
/*显示提示符*/
|
||||
cons_putchar(&cons, '>', 1);
|
||||
} else {
|
||||
/*一般字符*/
|
||||
if (cons.cur_x < 240) {
|
||||
/*显示一个字符之后将光标后移一位*/
|
||||
cmdline[cons.cur_x / 8 - 2] = i - 256;
|
||||
cons_putchar(&cons, i - 256, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*重新显示光标*/
|
||||
if (cons.cur_c >= 0) {
|
||||
boxfill8(sheet->buf, sheet->bxsize, cons.cur_c, cons.cur_x, cons.cur_y, cons.cur_x + 7, cons.cur_y + 15);
|
||||
}
|
||||
sheet_refresh(sheet, cons.cur_x, cons.cur_y, cons.cur_x + 8, cons.cur_y + 16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cons_putchar(struct CONSOLE *cons, int chr, char move)
|
||||
{
|
||||
char s[2];
|
||||
s[0] = chr;
|
||||
s[1] = 0;
|
||||
if (s[0] == 0x09) { /*制表符*/
|
||||
for (;;) {
|
||||
putfonts8_asc_sht(cons->sht, cons->cur_x, cons->cur_y, COL8_FFFFFF, COL8_000000, " ", 1);
|
||||
cons->cur_x += 8;
|
||||
if (cons->cur_x == 8 + 240) {
|
||||
cons_newline(cons);
|
||||
}
|
||||
if (((cons->cur_x - 8) & 0x1f) == 0) {
|
||||
break; /*被32整除则break*/
|
||||
}
|
||||
}
|
||||
} else if (s[0] == 0x0a) { /*换行*/
|
||||
cons_newline(cons);
|
||||
} else if (s[0] == 0x0d) { /*回车*/
|
||||
/*先不做任何操作*/
|
||||
} else { /*一般字符*/
|
||||
putfonts8_asc_sht(cons->sht, cons->cur_x, cons->cur_y, COL8_FFFFFF, COL8_000000, s, 1);
|
||||
if (move != 0) {
|
||||
/* move为0时光标不后移*/
|
||||
cons->cur_x += 8;
|
||||
if (cons->cur_x == 8 + 240) {
|
||||
cons_newline(cons);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void cons_newline(struct CONSOLE *cons)
|
||||
{
|
||||
int x, y;
|
||||
struct SHEET *sheet = cons->sht;
|
||||
if (cons->cur_y < 28 + 112) {
|
||||
cons->cur_y += 16; /*到下一行*/
|
||||
} else {
|
||||
/*滚动*/
|
||||
for (y = 28; y < 28 + 112; y++) {
|
||||
for (x = 8; x < 8 + 240; x++) {
|
||||
sheet->buf[x + y * sheet->bxsize] = sheet->buf[x + (y + 16) * sheet->bxsize];
|
||||
}
|
||||
}
|
||||
for (y = 28 + 112; y < 28 + 128; y++) {
|
||||
for (x = 8; x < 8 + 240; x++) {
|
||||
sheet->buf[x + y * sheet->bxsize] = COL8_000000;
|
||||
}
|
||||
}
|
||||
sheet_refresh(sheet, 8, 28, 8 + 240, 28 + 128);
|
||||
}
|
||||
cons->cur_x = 8;
|
||||
return;
|
||||
}
|
||||
|
||||
void cons_putstr0(struct CONSOLE *cons, char *s)
|
||||
{
|
||||
for (; *s != 0; s++) {
|
||||
cons_putchar(cons, *s, 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void cons_putstr1(struct CONSOLE *cons, char *s, int l)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < l; i++) {
|
||||
cons_putchar(cons, s[i], 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void cons_runcmd(char *cmdline, struct CONSOLE *cons, int *fat, int memtotal)
|
||||
{
|
||||
if (strcmp(cmdline, "mem") == 0) {
|
||||
cmd_mem(cons, memtotal);
|
||||
} else if (strcmp(cmdline, "cls") == 0) {
|
||||
cmd_cls(cons);
|
||||
} else if (strcmp(cmdline, "dir") == 0 || strcmp(cmdline, "ls") == 0) {
|
||||
cmd_dir(cons);
|
||||
} else if (strncmp(cmdline, "type ", 5) == 0) {
|
||||
cmd_type(cons, fat, cmdline);
|
||||
} else if (cmdline[0] != 0) {
|
||||
if (cmd_app(cons, fat, cmdline) == 0) {
|
||||
/*不是命令,不是应用程序,也不是空行*/
|
||||
cons_putstr0(cons, "Bad command.\n\n");
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void cmd_mem(struct CONSOLE *cons, int memtotal)
|
||||
{
|
||||
struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR;
|
||||
char s[60];
|
||||
sprintf(s, "total %dMB\nfree %dKB\n\n", memtotal / (1024 * 1024), memman_total(memman) / 1024);
|
||||
cons_putstr0(cons, s);
|
||||
return;
|
||||
}
|
||||
|
||||
void cmd_cls(struct CONSOLE *cons)
|
||||
{
|
||||
int x, y;
|
||||
struct SHEET *sheet = cons->sht;
|
||||
for (y = 28; y < 28 + 128; y++) {
|
||||
for (x = 8; x < 8 + 240; x++) {
|
||||
sheet->buf[x + y * sheet->bxsize] = COL8_000000;
|
||||
}
|
||||
}
|
||||
sheet_refresh(sheet, 8, 28, 8 + 240, 28 + 128);
|
||||
cons->cur_y = 28;
|
||||
return;
|
||||
}
|
||||
|
||||
void cmd_dir(struct CONSOLE *cons)
|
||||
{
|
||||
struct FILEINFO *finfo = (struct FILEINFO *) (ADR_DISKIMG + 0x002600);
|
||||
int i, j;
|
||||
char s[30];
|
||||
for (i = 0; i < 224; i++) {
|
||||
if (finfo[i].name[0] == 0x00) {
|
||||
break;
|
||||
}
|
||||
if (finfo[i].name[0] != 0xe5) {
|
||||
if ((finfo[i].type & 0x18) == 0) {
|
||||
sprintf(s, "filename.ext %7d\n", finfo[i].size);
|
||||
for (j = 0; j < 8; j++) {
|
||||
s[j] = finfo[i].name[j];
|
||||
}
|
||||
s[ 9] = finfo[i].ext[0];
|
||||
s[10] = finfo[i].ext[1];
|
||||
s[11] = finfo[i].ext[2];
|
||||
cons_putstr0(cons, s);
|
||||
}
|
||||
}
|
||||
}
|
||||
cons_newline(cons);
|
||||
return;
|
||||
}
|
||||
|
||||
void cmd_type(struct CONSOLE *cons, int *fat, char *cmdline)
|
||||
{
|
||||
struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR;
|
||||
struct FILEINFO *finfo = file_search(cmdline + 5, (struct FILEINFO *) (ADR_DISKIMG + 0x002600), 224);
|
||||
char *p;
|
||||
if (finfo != 0) {
|
||||
/*找到文件的情况*/
|
||||
p = (char *) memman_alloc_4k(memman, finfo->size);
|
||||
file_loadfile(finfo->clustno, finfo->size, p, fat, (char *) (ADR_DISKIMG + 0x003e00));
|
||||
cons_putstr1(cons, p, finfo->size);
|
||||
memman_free_4k(memman, (int) p, finfo->size);
|
||||
} else {
|
||||
/*没有找到文件的情况*/
|
||||
cons_putstr0(cons, "File not found.\n");
|
||||
}
|
||||
cons_newline(cons);
|
||||
return;
|
||||
}
|
||||
|
||||
int cmd_app(struct CONSOLE *cons, int *fat, char *cmdline)
|
||||
{
|
||||
struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR;
|
||||
struct FILEINFO *finfo;
|
||||
struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *) ADR_GDT;
|
||||
char name[18], *p, *q;
|
||||
struct TASK *task = task_now();
|
||||
int i, segsiz, datsiz, esp, dathrb;
|
||||
struct SHTCTL *shtctl;
|
||||
struct SHEET *sht;
|
||||
|
||||
/*根据命令行生成文件名*/
|
||||
for (i = 0; i < 13; i++) {
|
||||
if (cmdline[i] <= ' ') {
|
||||
break;
|
||||
}
|
||||
name[i] = cmdline[i];
|
||||
}
|
||||
name[i] = 0; /*暂且将文件名的后面置为0*/
|
||||
|
||||
/*寻找文件 */
|
||||
finfo = file_search(name, (struct FILEINFO *) (ADR_DISKIMG + 0x002600), 224);
|
||||
if (finfo == 0 && name[i - 1] != '.') {
|
||||
/*由于找不到文件,故在文件名后面加上“.hrb”后重新寻找*/
|
||||
name[i ] = '.';
|
||||
name[i + 1] = 'H';
|
||||
name[i + 2] = 'R';
|
||||
name[i + 3] = 'B';
|
||||
name[i + 4] = 0;
|
||||
finfo = file_search(name, (struct FILEINFO *) (ADR_DISKIMG + 0x002600), 224);
|
||||
}
|
||||
|
||||
if (finfo != 0) {
|
||||
/*找到文件的情况*/
|
||||
p = (char *) memman_alloc_4k(memman, finfo->size);
|
||||
file_loadfile(finfo->clustno, finfo->size, p, fat, (char *) (ADR_DISKIMG + 0x003e00));
|
||||
if (finfo->size >= 36 && strncmp(p + 4, "Hari", 4) == 0 && *p == 0x00) {
|
||||
segsiz = *((int *) (p + 0x0000));
|
||||
esp = *((int *) (p + 0x000c));
|
||||
datsiz = *((int *) (p + 0x0010));
|
||||
dathrb = *((int *) (p + 0x0014));
|
||||
q = (char *) memman_alloc_4k(memman, segsiz);
|
||||
task->ds_base = (int) q;
|
||||
set_segmdesc(gdt + task->sel / 8 + 1000, finfo->size - 1, (int) p, AR_CODE32_ER + 0x60);
|
||||
set_segmdesc(gdt + task->sel / 8 + 2000, segsiz - 1, (int) q, AR_DATA32_RW + 0x60);
|
||||
for (i = 0; i < datsiz; i++) {
|
||||
q[esp + i] = p[dathrb + i];
|
||||
}
|
||||
start_app(0x1b, task->sel + 1000 * 8, esp, task->sel + 2000 * 8, &(task->tss.esp0));
|
||||
shtctl = (struct SHTCTL *) *((int *) 0x0fe4);
|
||||
for (i = 0; i < MAX_SHEETS; i++) {
|
||||
sht = &(shtctl->sheets0[i]);
|
||||
if ((sht->flags & 0x11) == 0x11 && sht->task == task) {
|
||||
/*找到被应用程序遗留的窗口*/
|
||||
sheet_free(sht); /*关闭*/
|
||||
}
|
||||
}
|
||||
timer_cancelall(&task->fifo);
|
||||
memman_free_4k(memman, (int) q, segsiz);
|
||||
} else {
|
||||
cons_putstr0(cons, ".hrb file format error.\n");
|
||||
}
|
||||
memman_free_4k(memman, (int) p, finfo->size);
|
||||
cons_newline(cons);
|
||||
return 1;
|
||||
}
|
||||
/*没有找到文件的情况*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
int *hrb_api(int edi, int esi, int ebp, int esp, int ebx, int edx, int ecx, int eax)
|
||||
{
|
||||
struct TASK *task = task_now();
|
||||
int ds_base = task->ds_base;
|
||||
struct CONSOLE *cons = task->cons;
|
||||
struct SHTCTL *shtctl = (struct SHTCTL *) *((int *) 0x0fe4);
|
||||
struct SHEET *sht;
|
||||
int *reg = &eax + 1; /* eax后面的地址*/
|
||||
/*强行改写通过PUSHAD保存的值*/
|
||||
/* reg[0] : EDI, reg[1] : ESI, reg[2] : EBP, reg[3] : ESP */
|
||||
/* reg[4] : EBX, reg[5] : EDX, reg[6] : ECX, reg[7] : EAX */
|
||||
int i;
|
||||
|
||||
if (edx == 1) {
|
||||
cons_putchar(cons, eax & 0xff, 1);
|
||||
} else if (edx == 2) {
|
||||
cons_putstr0(cons, (char *) ebx + ds_base);
|
||||
} else if (edx == 3) {
|
||||
cons_putstr1(cons, (char *) ebx + ds_base, ecx);
|
||||
} else if (edx == 4) {
|
||||
return &(task->tss.esp0);
|
||||
} else if (edx == 5) {
|
||||
sht = sheet_alloc(shtctl);
|
||||
sht->task = task;
|
||||
sht->flags |= 0x10;
|
||||
sheet_setbuf(sht, (char *) ebx + ds_base, esi, edi, eax);
|
||||
make_window8((char *) ebx + ds_base, esi, edi, (char *) ecx + ds_base, 0);
|
||||
sheet_slide(sht, (shtctl->xsize - esi) / 2, (shtctl->ysize - edi) / 2);
|
||||
sheet_updown(sht, shtctl->top); /*将窗口图层高度指定为当前鼠标所在图层的高度,鼠标移到上层*/
|
||||
reg[7] = (int) sht;
|
||||
} else if (edx == 6) {
|
||||
sht = (struct SHEET *) (ebx & 0xfffffffe);
|
||||
putfonts8_asc(sht->buf, sht->bxsize, esi, edi, eax, (char *) ebp + ds_base);
|
||||
if ((ebx & 1) == 0) {
|
||||
sheet_refresh(sht, esi, edi, esi + ecx * 8, edi + 16);
|
||||
}
|
||||
} else if (edx == 7) {
|
||||
sht = (struct SHEET *) (ebx & 0xfffffffe);
|
||||
boxfill8(sht->buf, sht->bxsize, ebp, eax, ecx, esi, edi);
|
||||
if ((ebx & 1) == 0) {
|
||||
sheet_refresh(sht, eax, ecx, esi + 1, edi + 1);
|
||||
}
|
||||
} else if (edx == 8) {
|
||||
memman_init((struct MEMMAN *) (ebx + ds_base));
|
||||
ecx &= 0xfffffff0; /*以16字节为单位*/
|
||||
memman_free((struct MEMMAN *) (ebx + ds_base), eax, ecx);
|
||||
} else if (edx == 9) {
|
||||
ecx = (ecx + 0x0f) & 0xfffffff0; /*以16字节为单位进位取整*/
|
||||
reg[7] = memman_alloc((struct MEMMAN *) (ebx + ds_base), ecx);
|
||||
} else if (edx == 10) {
|
||||
ecx = (ecx + 0x0f) & 0xfffffff0; /*以16字节为单位进位取整*/
|
||||
memman_free((struct MEMMAN *) (ebx + ds_base), eax, ecx);
|
||||
} else if (edx == 11) {
|
||||
sht = (struct SHEET *) (ebx & 0xfffffffe);
|
||||
sht->buf[sht->bxsize * edi + esi] = eax;
|
||||
if ((ebx & 1) == 0) {
|
||||
sheet_refresh(sht, esi, edi, esi + 1, edi + 1);
|
||||
}
|
||||
} else if (edx == 12) {
|
||||
sht = (struct SHEET *) ebx;
|
||||
sheet_refresh(sht, eax, ecx, esi, edi);
|
||||
} else if (edx == 13) {
|
||||
sht = (struct SHEET *) (ebx & 0xfffffffe);
|
||||
hrb_api_linewin(sht, eax, ecx, esi, edi, ebp);
|
||||
if ((ebx & 1) == 0) {
|
||||
sheet_refresh(sht, eax, ecx, esi + 1, edi + 1);
|
||||
}
|
||||
} else if (edx == 14) {
|
||||
sheet_free((struct SHEET *) ebx);
|
||||
} else if (edx == 15) {
|
||||
for (;;) {
|
||||
io_cli();
|
||||
if (fifo32_status(&task->fifo) == 0) {
|
||||
if (eax != 0) {
|
||||
task_sleep(task); /* FIFO为空,休眠并等待*/
|
||||
} else {
|
||||
io_sti();
|
||||
reg[7] = -1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
i = fifo32_get(&task->fifo);
|
||||
io_sti();
|
||||
if (i <= 1) { /*光标用定时器*/
|
||||
/*应用程序运行时不需要显示光标,因此总是将下次显示用的值置为1*/
|
||||
timer_init(cons->timer, &task->fifo, 1); /*下次置为1*/
|
||||
timer_settime(cons->timer, 50);
|
||||
}
|
||||
if (i == 2) { /*光标ON */
|
||||
cons->cur_c = COL8_FFFFFF;
|
||||
}
|
||||
if (i == 3) { /*光标OFF */
|
||||
cons->cur_c = -1;
|
||||
}
|
||||
if (i >= 256) { /*键盘数据(通过任务A)等*/
|
||||
reg[7] = i - 256;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} else if (edx == 16) {
|
||||
reg[7] = (int) timer_alloc();
|
||||
((struct TIMER *) reg[7])->flags2 = 1; /*允许自动取消*/
|
||||
} else if (edx == 17) {
|
||||
timer_init((struct TIMER *) ebx, &task->fifo, eax + 256);
|
||||
} else if (edx == 18) {
|
||||
timer_settime((struct TIMER *) ebx, eax);
|
||||
} else if (edx == 19) {
|
||||
timer_free((struct TIMER *) ebx);
|
||||
} else if (edx == 20) {
|
||||
if (eax == 0) {
|
||||
i = io_in8(0x61);
|
||||
io_out8(0x61, i & 0x0d);
|
||||
} else {
|
||||
i = 1193180000 / eax;
|
||||
io_out8(0x43, 0xb6);
|
||||
io_out8(0x42, i & 0xff);
|
||||
io_out8(0x42, i >> 8);
|
||||
i = io_in8(0x61);
|
||||
io_out8(0x61, (i | 0x03) & 0x0f);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int *inthandler0c(int *esp)
|
||||
{
|
||||
struct TASK *task = task_now();
|
||||
struct CONSOLE *cons = task->cons;
|
||||
char s[30];
|
||||
cons_putstr0(cons, "\nINT 0C :\n Stack Exception.\n");
|
||||
sprintf(s, "EIP = %08X\n", esp[11]);
|
||||
cons_putstr0(cons, s);
|
||||
return &(task->tss.esp0); /*强制结束程序*/
|
||||
}
|
||||
|
||||
int *inthandler0d(int *esp)
|
||||
{
|
||||
struct TASK *task = task_now();
|
||||
struct CONSOLE *cons = task->cons;
|
||||
char s[30];
|
||||
cons_putstr0(cons, "\nINT 0D :\n General Protected Exception.\n");
|
||||
sprintf(s, "EIP = %08X\n", esp[11]);
|
||||
cons_putstr0(cons, s);
|
||||
return &(task->tss.esp0); /*强制结束程序*/
|
||||
}
|
||||
|
||||
void hrb_api_linewin(struct SHEET *sht, int x0, int y0, int x1, int y1, int col)
|
||||
{
|
||||
int i, x, y, len, dx, dy;
|
||||
|
||||
dx = x1 - x0;
|
||||
dy = y1 - y0;
|
||||
x = x0 << 10;
|
||||
y = y0 << 10;
|
||||
if (dx < 0) {
|
||||
dx = - dx;
|
||||
}
|
||||
if (dy < 0) {
|
||||
dy = - dy;
|
||||
}
|
||||
if (dx >= dy) {
|
||||
len = dx + 1;
|
||||
if (x0 > x1) {
|
||||
dx = -1024;
|
||||
} else {
|
||||
dx = 1024;
|
||||
}
|
||||
if (y0 <= y1) {
|
||||
dy = ((y1 - y0 + 1) << 10) / len;
|
||||
} else {
|
||||
dy = ((y1 - y0 - 1) << 10) / len;
|
||||
}
|
||||
} else {
|
||||
len = dy + 1;
|
||||
if (y0 > y1) {
|
||||
dy = -1024;
|
||||
} else {
|
||||
dy = 1024;
|
||||
}
|
||||
if (x0 <= x1) {
|
||||
dx = ((x1 - x0 + 1) << 10) / len;
|
||||
} else {
|
||||
dx = ((x1 - x0 - 1) << 10) / len;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
sht->buf[(y >> 10) * sht->bxsize + (x >> 10)] = col;
|
||||
x += dx;
|
||||
y += dy;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
59
25_day/dsctbl.c
Normal file
59
25_day/dsctbl.c
Normal file
@@ -0,0 +1,59 @@
|
||||
/* 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 + 0x0c, (int) asm_inthandler0c, 2 * 8, AR_INTGATE32);
|
||||
set_gatedesc(idt + 0x0d, (int) asm_inthandler0d, 2 * 8, AR_INTGATE32);
|
||||
set_gatedesc(idt + 0x20, (int) asm_inthandler20, 2 * 8, AR_INTGATE32);
|
||||
set_gatedesc(idt + 0x21, (int) asm_inthandler21, 2 * 8, AR_INTGATE32);
|
||||
set_gatedesc(idt + 0x2c, (int) asm_inthandler2c, 2 * 8, AR_INTGATE32);
|
||||
set_gatedesc(idt + 0x40, (int) asm_hrb_api, 2 * 8, AR_INTGATE32 + 0x60);
|
||||
|
||||
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;
|
||||
}
|
||||
63
25_day/fifo.c
Normal file
63
25_day/fifo.c
Normal file
@@ -0,0 +1,63 @@
|
||||
/* FIFO */
|
||||
|
||||
#include "bootpack.h"
|
||||
|
||||
#define FLAGS_OVERRUN 0x0001
|
||||
|
||||
void fifo32_init(struct FIFO32 *fifo, int size, int *buf, struct TASK *task)
|
||||
/* FIFO缓冲区的初始化*/
|
||||
{
|
||||
fifo->size = size;
|
||||
fifo->buf = buf;
|
||||
fifo->free = size; /*空*/
|
||||
fifo->flags = 0;
|
||||
fifo->p = 0; /*写入位置*/
|
||||
fifo->q = 0; /*读取位置*/
|
||||
fifo->task = task; /*有数据写入时需要唤醒的任务*/
|
||||
return;
|
||||
}
|
||||
|
||||
int fifo32_put(struct FIFO32 *fifo, int 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--;
|
||||
if (fifo->task != 0) {
|
||||
if (fifo->task->flags != 2) { /*如果任务处于休眠状态*/
|
||||
task_run(fifo->task, -1, 0); /*将任务唤醒*/
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fifo32_get(struct FIFO32 *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 fifo32_status(struct FIFO32 *fifo)
|
||||
/*报告已经存储了多少数据*/
|
||||
{
|
||||
return fifo->size - fifo->free;
|
||||
}
|
||||
74
25_day/file.c
Normal file
74
25_day/file.c
Normal file
@@ -0,0 +1,74 @@
|
||||
/* 文件相关函数 */
|
||||
|
||||
#include "bootpack.h"
|
||||
|
||||
void file_readfat(int *fat, unsigned char *img)
|
||||
/*将磁盘映像中的FAT解压缩 */
|
||||
{
|
||||
int i, j = 0;
|
||||
for (i = 0; i < 2880; i += 2) {
|
||||
fat[i + 0] = (img[j + 0] | img[j + 1] << 8) & 0xfff;
|
||||
fat[i + 1] = (img[j + 1] >> 4 | img[j + 2] << 4) & 0xfff;
|
||||
j += 3;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void file_loadfile(int clustno, int size, char *buf, int *fat, char *img)
|
||||
{
|
||||
int i;
|
||||
for (;;) {
|
||||
if (size <= 512) {
|
||||
for (i = 0; i < size; i++) {
|
||||
buf[i] = img[clustno * 512 + i];
|
||||
}
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < 512; i++) {
|
||||
buf[i] = img[clustno * 512 + i];
|
||||
}
|
||||
size -= 512;
|
||||
buf += 512;
|
||||
clustno = fat[clustno];
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
struct FILEINFO *file_search(char *name, struct FILEINFO *finfo, int max)
|
||||
{
|
||||
int i, j;
|
||||
char s[12];
|
||||
for (j = 0; j < 11; j++) {
|
||||
s[j] = ' ';
|
||||
}
|
||||
j = 0;
|
||||
for (i = 0; name[i] != 0; i++) {
|
||||
if (j >= 11) { return 0; /*没有找到*/ }
|
||||
if (name[i] == '.' && j <= 8) {
|
||||
j = 8;
|
||||
} else {
|
||||
s[j] = name[i];
|
||||
if ('a' <= s[j] && s[j] <= 'z') {
|
||||
/*将小写字母转换为大写字母*/
|
||||
s[j] -= 0x20;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < max; ) {
|
||||
if (finfo->name[0] == 0x00) {
|
||||
break;
|
||||
}
|
||||
if ((finfo[i].type & 0x18) == 0) {
|
||||
for (j = 0; j < 11; j++) {
|
||||
if (finfo[i].name[j] != s[j]) {
|
||||
goto next;
|
||||
}
|
||||
}
|
||||
return finfo + i; /*找到文件*/
|
||||
}
|
||||
next:
|
||||
i++;
|
||||
}
|
||||
return 0; /*没有找到*/
|
||||
}
|
||||
167
25_day/graphic.c
Normal file
167
25_day/graphic.c
Normal file
@@ -0,0 +1,167 @@
|
||||
/* 关于绘图部分的处理 */
|
||||
|
||||
#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:暗灰 */
|
||||
};
|
||||
unsigned char table2[216 * 3];
|
||||
int r, g, b;
|
||||
set_palette(0, 15, table_rgb);
|
||||
for (b = 0; b < 6; b++) {
|
||||
for (g = 0; g < 6; g++) {
|
||||
for (r = 0; r < 6; r++) {
|
||||
table2[(r + g * 6 + b * 36) * 3 + 0] = r * 51;
|
||||
table2[(r + g * 6 + b * 36) * 3 + 1] = g * 51;
|
||||
table2[(r + g * 6 + b * 36) * 3 + 2] = b * 51;
|
||||
}
|
||||
}
|
||||
}
|
||||
set_palette(16, 231, table2);
|
||||
return;
|
||||
}
|
||||
|
||||
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
25_day/hankaku.txt
Normal file
4609
25_day/hankaku.txt
Normal file
File diff suppressed because it is too large
Load Diff
16
25_day/hello.nas
Normal file
16
25_day/hello.nas
Normal file
@@ -0,0 +1,16 @@
|
||||
[INSTRSET "i486p"]
|
||||
[BITS 32]
|
||||
MOV ECX,msg
|
||||
MOV EDX,1
|
||||
putloop:
|
||||
MOV AL,[CS:ECX]
|
||||
CMP AL,0
|
||||
JE fin
|
||||
INT 0x40
|
||||
ADD ECX,1
|
||||
JMP putloop
|
||||
fin:
|
||||
MOV EDX,4
|
||||
INT 0x40
|
||||
msg:
|
||||
DB "hello",0
|
||||
9
25_day/hello2.nas
Normal file
9
25_day/hello2.nas
Normal file
@@ -0,0 +1,9 @@
|
||||
[INSTRSET "i486p"]
|
||||
[BITS 32]
|
||||
MOV EDX,2
|
||||
MOV EBX,msg
|
||||
INT 0x40
|
||||
MOV EDX,4
|
||||
INT 0x40
|
||||
msg:
|
||||
DB "hello",0
|
||||
12
25_day/hello3.c
Normal file
12
25_day/hello3.c
Normal file
@@ -0,0 +1,12 @@
|
||||
void api_putchar(int c);
|
||||
void api_end(void);
|
||||
|
||||
void HariMain(void)
|
||||
{
|
||||
api_putchar('h');
|
||||
api_putchar('e');
|
||||
api_putchar('l');
|
||||
api_putchar('l');
|
||||
api_putchar('o');
|
||||
api_end();
|
||||
}
|
||||
8
25_day/hello4.c
Normal file
8
25_day/hello4.c
Normal file
@@ -0,0 +1,8 @@
|
||||
void api_putstr0(char *s);
|
||||
void api_end(void);
|
||||
|
||||
void HariMain(void)
|
||||
{
|
||||
api_putstr0("hello, world\n");
|
||||
api_end();
|
||||
}
|
||||
20
25_day/hello5.nas
Normal file
20
25_day/hello5.nas
Normal file
@@ -0,0 +1,20 @@
|
||||
[FORMAT "WCOFF"]
|
||||
[INSTRSET "i486p"]
|
||||
[BITS 32]
|
||||
[FILE "hello5.nas"]
|
||||
|
||||
GLOBAL _HariMain
|
||||
|
||||
[SECTION .text]
|
||||
|
||||
_HariMain:
|
||||
MOV EDX,2
|
||||
MOV EBX,msg
|
||||
INT 0x40
|
||||
MOV EDX,4
|
||||
INT 0x40
|
||||
|
||||
[SECTION .data]
|
||||
|
||||
msg:
|
||||
DB "hello, world", 0x0a, 0
|
||||
26
25_day/int.c
Normal file
26
25_day/int.c
Normal file
@@ -0,0 +1,26 @@
|
||||
/*初始化关系 */
|
||||
|
||||
#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;
|
||||
}
|
||||
109
25_day/ipl10.nas
Normal file
109
25_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
|
||||
44
25_day/keyboard.c
Normal file
44
25_day/keyboard.c
Normal file
@@ -0,0 +1,44 @@
|
||||
/* 键盘控制代码 */
|
||||
|
||||
#include "bootpack.h"
|
||||
|
||||
struct FIFO32 *keyfifo;
|
||||
int keydata0;
|
||||
|
||||
void inthandler21(int *esp)
|
||||
{
|
||||
int data;
|
||||
io_out8(PIC0_OCW2, 0x61); /* 把IRQ-01接收信号结束的信息通知给PIC */
|
||||
data = io_in8(PORT_KEYDAT);
|
||||
fifo32_put(keyfifo, data + keydata0);
|
||||
return;
|
||||
}
|
||||
|
||||
#define PORT_KEYSTA 0x0064
|
||||
#define KEYSTA_SEND_NOTREADY 0x02
|
||||
#define KEYCMD_WRITE_MODE 0x60
|
||||
#define KBC_MODE 0x47
|
||||
|
||||
void wait_KBC_sendready(void)
|
||||
{
|
||||
/* 等待键盘控制电路准备完毕 */
|
||||
for (;;) {
|
||||
if ((io_in8(PORT_KEYSTA) & KEYSTA_SEND_NOTREADY) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void init_keyboard(struct FIFO32 *fifo, int data0)
|
||||
{
|
||||
/* 将FIFO缓冲区的信息保存到全局变量里 */
|
||||
keyfifo = fifo;
|
||||
keydata0 = data0;
|
||||
/* 键盘控制器的初始化 */
|
||||
wait_KBC_sendready();
|
||||
io_out8(PORT_KEYCMD, KEYCMD_WRITE_MODE);
|
||||
wait_KBC_sendready();
|
||||
io_out8(PORT_KEYDAT, KBC_MODE);
|
||||
return;
|
||||
}
|
||||
29
25_day/lines.c
Normal file
29
25_day/lines.c
Normal file
@@ -0,0 +1,29 @@
|
||||
int api_openwin(char *buf, int xsiz, int ysiz, int col_inv, char *title);
|
||||
void api_initmalloc(void);
|
||||
char *api_malloc(int size);
|
||||
void api_refreshwin(int win, int x0, int y0, int x1, int y1);
|
||||
void api_linewin(int win, int x0, int y0, int x1, int y1, int col);
|
||||
void api_closewin(int win);
|
||||
int api_getkey(int mode);
|
||||
void api_end(void);
|
||||
|
||||
void HariMain(void)
|
||||
{
|
||||
char *buf;
|
||||
int win, i;
|
||||
api_initmalloc();
|
||||
buf = api_malloc(160 * 100);
|
||||
win = api_openwin(buf, 160, 100, -1, "lines");
|
||||
for (i = 0; i < 8; i++) {
|
||||
api_linewin(win + 1, 8, 26, 77, i * 9 + 26, i);
|
||||
api_linewin(win + 1, 88, 26, i * 9 + 88, 89, i);
|
||||
}
|
||||
api_refreshwin(win, 6, 26, 154, 90);
|
||||
for (;;) {
|
||||
if (api_getkey(1) == 0x0a) {
|
||||
break; /*按下回车键则break; */
|
||||
}
|
||||
}
|
||||
api_closewin(win);
|
||||
api_end();
|
||||
}
|
||||
1
25_day/make.bat
Normal file
1
25_day/make.bat
Normal file
@@ -0,0 +1 @@
|
||||
..\z_tools\make.exe %1 %2 %3 %4 %5 %6 %7 %8 %9
|
||||
162
25_day/memory.c
Normal file
162
25_day/memory.c
Normal file
@@ -0,0 +1,162 @@
|
||||
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>W */
|
||||
|
||||
#include "bootpack.h"
|
||||
|
||||
#define EFLAGS_AC_BIT 0x00040000
|
||||
#define CR0_CACHE_DISABLE 0x60000000
|
||||
|
||||
unsigned 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;
|
||||
}
|
||||
76
25_day/mouse.c
Normal file
76
25_day/mouse.c
Normal file
@@ -0,0 +1,76 @@
|
||||
/* 鼠标控制代码 */
|
||||
|
||||
#include "bootpack.h"
|
||||
|
||||
struct FIFO32 *mousefifo;
|
||||
int mousedata0;
|
||||
|
||||
void inthandler2c(int *esp)
|
||||
/* 来自PS/2鼠标的中断 */
|
||||
{
|
||||
int data;
|
||||
io_out8(PIC1_OCW2, 0x64); /* 把IRQ-12接收信号结束的信息通知给PIC1 */
|
||||
io_out8(PIC0_OCW2, 0x62); /* 把IRQ-02接收信号结束的信息通知给PIC0 */
|
||||
data = io_in8(PORT_KEYDAT);
|
||||
fifo32_put(mousefifo, data + mousedata0);
|
||||
return;
|
||||
}
|
||||
|
||||
#define KEYCMD_SENDTO_MOUSE 0xd4
|
||||
#define MOUSECMD_ENABLE 0xf4
|
||||
|
||||
void enable_mouse(struct FIFO32 *fifo, int data0, struct MOUSE_DEC *mdec)
|
||||
{
|
||||
/* 将FIFO缓冲区的信息保存到全局变量里 */
|
||||
mousefifo = fifo;
|
||||
mousedata0 = data0;
|
||||
/* 鼠标有效 */
|
||||
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) {
|
||||
/* 等待鼠标第一字节的阶段 */
|
||||
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;
|
||||
}
|
||||
202
25_day/mtask.c
Normal file
202
25_day/mtask.c
Normal file
@@ -0,0 +1,202 @@
|
||||
/* 多任务管理 */
|
||||
|
||||
#include "bootpack.h"
|
||||
|
||||
struct TASKCTL *taskctl;
|
||||
struct TIMER *task_timer;
|
||||
|
||||
struct TASK *task_now(void)
|
||||
{
|
||||
struct TASKLEVEL *tl = &taskctl->level[taskctl->now_lv];
|
||||
return tl->tasks[tl->now];
|
||||
}
|
||||
|
||||
void task_add(struct TASK *task)
|
||||
{
|
||||
struct TASKLEVEL *tl = &taskctl->level[task->level];
|
||||
tl->tasks[tl->running] = task;
|
||||
tl->running++;
|
||||
task->flags = 2; /*活动中*/
|
||||
return;
|
||||
}
|
||||
|
||||
void task_remove(struct TASK *task)
|
||||
{
|
||||
int i;
|
||||
struct TASKLEVEL *tl = &taskctl->level[task->level];
|
||||
|
||||
/*寻找task所在的位置*/
|
||||
for (i = 0; i < tl->running; i++) {
|
||||
if (tl->tasks[i] == task) {
|
||||
/*在这里 */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
tl->running--;
|
||||
if (i < tl->now) {
|
||||
tl->now--; /*需要移动成员,要相应地处理 */
|
||||
}
|
||||
if (tl->now >= tl->running) {
|
||||
/*如果now的值出现异常,则进行修正*/
|
||||
tl->now = 0;
|
||||
}
|
||||
task->flags = 1; /* 休眠中 */
|
||||
|
||||
/* 移动 */
|
||||
for (; i < tl->running; i++) {
|
||||
tl->tasks[i] = tl->tasks[i + 1];
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void task_switchsub(void)
|
||||
{
|
||||
int i;
|
||||
/*寻找最上层的LEVEL */
|
||||
for (i = 0; i < MAX_TASKLEVELS; i++) {
|
||||
if (taskctl->level[i].running > 0) {
|
||||
break; /*找到了*/
|
||||
}
|
||||
}
|
||||
taskctl->now_lv = i;
|
||||
taskctl->lv_change = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
void task_idle(void)
|
||||
{
|
||||
for (;;) {
|
||||
io_hlt();
|
||||
}
|
||||
}
|
||||
|
||||
struct TASK *task_init(struct MEMMAN *memman)
|
||||
{
|
||||
int i;
|
||||
struct TASK *task, *idle;
|
||||
struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *) ADR_GDT;
|
||||
|
||||
|
||||
taskctl = (struct TASKCTL *) memman_alloc_4k(memman, sizeof (struct TASKCTL));
|
||||
for (i = 0; i < MAX_TASKS; i++) {
|
||||
taskctl->tasks0[i].flags = 0;
|
||||
taskctl->tasks0[i].sel = (TASK_GDT0 + i) * 8;
|
||||
set_segmdesc(gdt + TASK_GDT0 + i, 103, (int) &taskctl->tasks0[i].tss, AR_TSS32);
|
||||
}
|
||||
for (i = 0; i < MAX_TASKLEVELS; i++) {
|
||||
taskctl->level[i].running = 0;
|
||||
taskctl->level[i].now = 0;
|
||||
}
|
||||
|
||||
task = task_alloc();
|
||||
task->flags = 2; /*活动中标志*/
|
||||
task->priority = 2; /* 0.02秒*/
|
||||
task->level = 0; /*最高LEVEL */
|
||||
task_add(task);
|
||||
task_switchsub(); /* LEVEL 设置*/
|
||||
load_tr(task->sel);
|
||||
task_timer = timer_alloc();
|
||||
timer_settime(task_timer, task->priority);
|
||||
|
||||
idle = task_alloc();
|
||||
idle->tss.esp = memman_alloc_4k(memman, 64 * 1024) + 64 * 1024;
|
||||
idle->tss.eip = (int) &task_idle;
|
||||
idle->tss.es = 1 * 8;
|
||||
idle->tss.cs = 2 * 8;
|
||||
idle->tss.ss = 1 * 8;
|
||||
idle->tss.ds = 1 * 8;
|
||||
idle->tss.fs = 1 * 8;
|
||||
idle->tss.gs = 1 * 8;
|
||||
task_run(idle, MAX_TASKLEVELS - 1, 1);
|
||||
|
||||
return task;
|
||||
}
|
||||
|
||||
struct TASK *task_alloc(void)
|
||||
{
|
||||
int i;
|
||||
struct TASK *task;
|
||||
for (i = 0; i < MAX_TASKS; i++) {
|
||||
if (taskctl->tasks0[i].flags == 0) {
|
||||
task = &taskctl->tasks0[i];
|
||||
task->flags = 1; /*正在使用的标志*/
|
||||
task->tss.eflags = 0x00000202; /* IF = 1; */
|
||||
task->tss.eax = 0; /*这里先置为0*/
|
||||
task->tss.ecx = 0;
|
||||
task->tss.edx = 0;
|
||||
task->tss.ebx = 0;
|
||||
task->tss.ebp = 0;
|
||||
task->tss.esi = 0;
|
||||
task->tss.edi = 0;
|
||||
task->tss.es = 0;
|
||||
task->tss.ds = 0;
|
||||
task->tss.fs = 0;
|
||||
task->tss.gs = 0;
|
||||
task->tss.ldtr = 0;
|
||||
task->tss.iomap = 0x40000000;
|
||||
task->tss.ss0 = 0;
|
||||
return task;
|
||||
}
|
||||
}
|
||||
return 0; /*全部正在使用*/
|
||||
}
|
||||
|
||||
void task_run(struct TASK *task, int level, int priority)
|
||||
{
|
||||
if (level < 0) {
|
||||
level = task->level; /*不改变LEVEL */
|
||||
}
|
||||
if (priority > 0) {
|
||||
task->priority = priority;
|
||||
}
|
||||
if (task->flags == 2 && task->level != level) {
|
||||
/*改变活动中的LEVEL */
|
||||
task_remove(task); /*这里执行之后flag的值会变为1,于是下面的if语句块也会被执行*/
|
||||
}
|
||||
if (task->flags != 2) {
|
||||
/*从休眠状态唤醒的情形*/
|
||||
task->level = level;
|
||||
task_add(task);
|
||||
}
|
||||
taskctl->lv_change = 1; /*下次任务切换时检查LEVEL */
|
||||
return;
|
||||
}
|
||||
|
||||
void task_sleep(struct TASK *task)
|
||||
{
|
||||
struct TASK *now_task;
|
||||
if (task->flags == 2) {
|
||||
/*如果处于活动状态*/
|
||||
now_task = task_now();
|
||||
task_remove(task); /*执行此语句的话flags将变为1 */
|
||||
if (task == now_task) {
|
||||
/*如果是让自己休眠,则需要进行任务切换*/
|
||||
task_switchsub();
|
||||
now_task = task_now(); /*在设定后获取当前任务的值*/
|
||||
farjmp(0, now_task->sel);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void task_switch(void)
|
||||
{
|
||||
struct TASKLEVEL *tl = &taskctl->level[taskctl->now_lv];
|
||||
struct TASK *new_task, *now_task = tl->tasks[tl->now];
|
||||
tl->now++;
|
||||
if (tl->now == tl->running) {
|
||||
tl->now = 0;
|
||||
}
|
||||
if (taskctl->lv_change != 0) {
|
||||
task_switchsub();
|
||||
tl = &taskctl->level[taskctl->now_lv];
|
||||
}
|
||||
new_task = tl->tasks[tl->now];
|
||||
timer_settime(task_timer, new_task->priority);
|
||||
if (new_task != now_task) {
|
||||
farjmp(0, new_task->sel);
|
||||
}
|
||||
return;
|
||||
}
|
||||
291
25_day/naskfunc.nas
Normal file
291
25_day/naskfunc.nas
Normal file
@@ -0,0 +1,291 @@
|
||||
; 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 _load_cr0, _store_cr0
|
||||
GLOBAL _load_tr
|
||||
GLOBAL _asm_inthandler20, _asm_inthandler21
|
||||
GLOBAL _asm_inthandler2c, _asm_inthandler0c
|
||||
GLOBAL _asm_inthandler0d, _asm_end_app
|
||||
GLOBAL _memtest_sub
|
||||
GLOBAL _farjmp, _farcall
|
||||
GLOBAL _asm_hrb_api, _start_app
|
||||
EXTERN _inthandler20, _inthandler21
|
||||
EXTERN _inthandler2c, _inthandler0d
|
||||
EXTERN _inthandler0c
|
||||
EXTERN _hrb_api
|
||||
|
||||
[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
|
||||
|
||||
_load_cr0: ; int load_cr0(void);
|
||||
MOV EAX,CR0
|
||||
RET
|
||||
|
||||
_store_cr0: ; void store_cr0(int cr0);
|
||||
MOV EAX,[ESP+4]
|
||||
MOV CR0,EAX
|
||||
RET
|
||||
|
||||
_load_tr: ; void load_tr(int tr);
|
||||
LTR [ESP+4] ; tr
|
||||
RET
|
||||
|
||||
_asm_inthandler20:
|
||||
PUSH ES
|
||||
PUSH DS
|
||||
PUSHAD
|
||||
MOV EAX,ESP
|
||||
PUSH EAX
|
||||
MOV AX,SS
|
||||
MOV DS,AX
|
||||
MOV ES,AX
|
||||
CALL _inthandler20
|
||||
POP EAX
|
||||
POPAD
|
||||
POP DS
|
||||
POP ES
|
||||
IRETD
|
||||
|
||||
_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_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
|
||||
|
||||
_asm_inthandler0c:
|
||||
STI
|
||||
PUSH ES
|
||||
PUSH DS
|
||||
PUSHAD
|
||||
MOV EAX,ESP
|
||||
PUSH EAX
|
||||
MOV AX,SS
|
||||
MOV DS,AX
|
||||
MOV ES,AX
|
||||
CALL _inthandler0c
|
||||
CMP EAX,0
|
||||
JNE _asm_end_app
|
||||
POP EAX
|
||||
POPAD
|
||||
POP DS
|
||||
POP ES
|
||||
ADD ESP,4 ; 在INT 0x0c中也需要这句
|
||||
IRETD
|
||||
|
||||
_asm_inthandler0d:
|
||||
STI
|
||||
PUSH ES
|
||||
PUSH DS
|
||||
PUSHAD
|
||||
MOV EAX,ESP
|
||||
PUSH EAX
|
||||
MOV AX,SS
|
||||
MOV DS,AX
|
||||
MOV ES,AX
|
||||
CALL _inthandler0d
|
||||
CMP EAX,0
|
||||
JNE _asm_end_app
|
||||
POP EAX
|
||||
POPAD
|
||||
POP DS
|
||||
POP ES
|
||||
ADD ESP,4 ; INT 0x0d需要这句
|
||||
IRETD
|
||||
|
||||
_memtest_sub: ; unsigned int memtest_sub(unsigned int start, unsigned int end)
|
||||
PUSH EDI ; (由于还要使用EBX, ESI, EDI)
|
||||
PUSH ESI
|
||||
PUSH EBX
|
||||
MOV ESI,0xaa55aa55 ; pat0 = 0xaa55aa55;
|
||||
MOV EDI,0x55aa55aa ; pat1 = 0x55aa55aa;
|
||||
MOV EAX,[ESP+12+4] ; i = start;
|
||||
mts_loop:
|
||||
MOV EBX,EAX
|
||||
ADD 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_fin
|
||||
XOR DWORD [EBX],0xffffffff ; *p ^= 0xffffffff;
|
||||
CMP ESI,[EBX] ; if (*p != pat0) goto fin;
|
||||
JNE mts_fin
|
||||
MOV [EBX],EDX ; *p = old;
|
||||
ADD EAX,0x1000 ; i += 0x1000;
|
||||
CMP EAX,[ESP+12+8] ; if (i <= end) goto mts_loop;
|
||||
JBE mts_loop
|
||||
POP EBX
|
||||
POP ESI
|
||||
POP EDI
|
||||
RET
|
||||
mts_fin:
|
||||
MOV [EBX],EDX ; *p = old;
|
||||
POP EBX
|
||||
POP ESI
|
||||
POP EDI
|
||||
RET
|
||||
|
||||
_farjmp: ; void farjmp(int eip, int cs);
|
||||
JMP FAR [ESP+4] ; eip, cs
|
||||
RET
|
||||
|
||||
_farcall: ; void farcall(int eip, int cs);
|
||||
CALL FAR [ESP+4] ; eip, cs
|
||||
RET
|
||||
|
||||
_asm_hrb_api:
|
||||
STI
|
||||
PUSH DS
|
||||
PUSH ES
|
||||
PUSHAD ; 用于保存的PUSH
|
||||
PUSHAD ; 用于向hrb_api传值的PUSH
|
||||
MOV AX,SS
|
||||
MOV DS,AX ; 将操作系统用段地址存入DS和ES
|
||||
MOV ES,AX
|
||||
CALL _hrb_api
|
||||
CMP EAX,0 ; 当EAX不为0时程序结束
|
||||
JNE _asm_end_app
|
||||
ADD ESP,32
|
||||
POPAD
|
||||
POP ES
|
||||
POP DS
|
||||
IRETD
|
||||
_asm_end_app:
|
||||
; EAX为tss.esp0的地址
|
||||
MOV ESP,[EAX]
|
||||
MOV DWORD [EAX+4],0
|
||||
POPAD
|
||||
RET ; 返回cmd_app
|
||||
|
||||
_start_app: ; void start_app(int eip, int cs, int esp, int ds, int *tss_esp0);
|
||||
PUSHAD ; 将32位寄存器的值全部保存起来
|
||||
MOV EAX,[ESP+36] ; 应用程序用EIP
|
||||
MOV ECX,[ESP+40] ; 应用程序用CS
|
||||
MOV EDX,[ESP+44] ; 应用程序用ESP
|
||||
MOV EBX,[ESP+48] ; 应用程序用DS/SS
|
||||
MOV EBP,[ESP+52] ; tss.esp0的地址
|
||||
MOV [EBP ],ESP ; 保存操作系统用ESP
|
||||
MOV [EBP+4],SS ; 保存操作系统用SS
|
||||
MOV ES,BX
|
||||
MOV DS,BX
|
||||
MOV FS,BX
|
||||
MOV GS,BX
|
||||
; 下面调整栈,以免用RETF跳转到应用程序
|
||||
OR ECX,3 ; 将应用程序用段号和3进行OR运算
|
||||
OR EBX,3 ; 将应用程序用段号和3进行OR运算
|
||||
PUSH EBX ; 应用程序的SS
|
||||
PUSH EDX ; 应用程序的ESP
|
||||
PUSH ECX ; 应用程序的CS
|
||||
PUSH EAX ; 应用程序的EIP
|
||||
RETF
|
||||
; 应用程序结束后不会回到这里
|
||||
42
25_day/noodle.c
Normal file
42
25_day/noodle.c
Normal file
@@ -0,0 +1,42 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int api_openwin(char *buf, int xsiz, int ysiz, int col_inv, char *title);
|
||||
void api_putstrwin(int win, int x, int y, int col, int len, char *str);
|
||||
void api_boxfilwin(int win, int x0, int y0, int x1, int y1, int col);
|
||||
void api_initmalloc(void);
|
||||
char *api_malloc(int size);
|
||||
int api_getkey(int mode);
|
||||
int api_alloctimer(void);
|
||||
void api_inittimer(int timer, int data);
|
||||
void api_settimer(int timer, int time);
|
||||
void api_end(void);
|
||||
|
||||
void HariMain(void)
|
||||
{
|
||||
char *buf, s[12];
|
||||
int win, timer, sec = 0, min = 0, hou = 0;
|
||||
api_initmalloc();
|
||||
buf = api_malloc(150 * 50);
|
||||
win = api_openwin(buf, 150, 50, -1, "noodle");
|
||||
timer = api_alloctimer();
|
||||
api_inittimer(timer, 128);
|
||||
for (;;) {
|
||||
sprintf(s, "%5d:%02d:%02d", hou, min, sec);
|
||||
api_boxfilwin(win, 28, 27, 115, 41, 7);/*白色*/
|
||||
api_putstrwin(win, 28, 27, 0, 11, s); /*黑色*/
|
||||
api_settimer(timer, 100); /* 1秒 */
|
||||
if (api_getkey(1) != 128) {
|
||||
break;
|
||||
}
|
||||
sec++;
|
||||
if (sec == 60) {
|
||||
sec = 0;
|
||||
min++;
|
||||
if (min == 60) {
|
||||
min = 0;
|
||||
hou++;
|
||||
}
|
||||
}
|
||||
}
|
||||
api_end();
|
||||
}
|
||||
217
25_day/sheet.c
Normal file
217
25_day/sheet.c
Normal file
@@ -0,0 +1,217 @@
|
||||
/* sheet */
|
||||
|
||||
#include "bootpack.h"
|
||||
|
||||
#define SHEET_USE 1
|
||||
|
||||
struct 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->map = (unsigned char *) memman_alloc_4k(memman, xsize * ysize);
|
||||
if (ctl->map == 0) {
|
||||
memman_free_4k(memman, (int) ctl, sizeof (struct SHTCTL));
|
||||
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; /* 标记为未使用 */
|
||||
ctl->sheets0[i].ctl = ctl; /* 记录所属*/
|
||||
}
|
||||
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; /* 隐藏 */
|
||||
sht->task = 0; /*不使用自动关闭功能*/
|
||||
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_refreshmap(struct SHTCTL *ctl, int vx0, int vy0, int vx1, int vy1, int h0)
|
||||
{
|
||||
int h, bx, by, vx, vy, bx0, by0, bx1, by1;
|
||||
unsigned char *buf, sid, *map = ctl->map;
|
||||
struct SHEET *sht;
|
||||
if (vx0 < 0) { vx0 = 0; }
|
||||
if (vy0 < 0) { vy0 = 0; }
|
||||
if (vx1 > ctl->xsize) { vx1 = ctl->xsize; }
|
||||
if (vy1 > ctl->ysize) { vy1 = ctl->ysize; }
|
||||
for (h = h0; h <= ctl->top; h++) {
|
||||
sht = ctl->sheets[h];
|
||||
sid = sht - ctl->sheets0; /* 将进行了减法计算的地址作为图层号码使用 */
|
||||
buf = sht->buf;
|
||||
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;
|
||||
if (buf[by * sht->bxsize + bx] != sht->col_inv) {
|
||||
map[vy * ctl->xsize + vx] = sid;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void sheet_refreshsub(struct SHTCTL *ctl, int vx0, int vy0, int vx1, int vy1, int h0, int h1)
|
||||
{
|
||||
int h, bx, by, vx, vy, bx0, by0, bx1, by1;
|
||||
unsigned char *buf, *vram = ctl->vram, *map = ctl->map, sid;
|
||||
struct SHEET *sht;
|
||||
|
||||
/* 如果refresh的范围超出了画面则修正 */
|
||||
if (vx0 < 0) { vx0 = 0; }
|
||||
if (vy0 < 0) { vy0 = 0; }
|
||||
if (vx1 > ctl->xsize) { vx1 = ctl->xsize; }
|
||||
if (vy1 > ctl->ysize) { vy1 = ctl->ysize; }
|
||||
for (h = h0; h <= h1; h++) {
|
||||
sht = ctl->sheets[h];
|
||||
buf = sht->buf;
|
||||
sid = sht - ctl->sheets0;
|
||||
|
||||
/* 使用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;
|
||||
if (map[vy * ctl->xsize + vx] == sid) {
|
||||
vram[vy * ctl->xsize + vx] = buf[by * sht->bxsize + bx];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void sheet_updown(struct SHEET *sht, int height)
|
||||
{
|
||||
struct SHTCTL *ctl = sht->ctl;
|
||||
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;
|
||||
sheet_refreshmap(ctl, sht->vx0, sht->vy0, sht->vx0 + sht->bxsize, sht->vy0 + sht->bysize, height + 1);
|
||||
sheet_refreshsub(ctl, sht->vx0, sht->vy0, sht->vx0 + sht->bxsize, sht->vy0 + sht->bysize, height + 1, old);
|
||||
} 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_refreshmap(ctl, sht->vx0, sht->vy0, sht->vx0 + sht->bxsize, sht->vy0 + sht->bysize, 0);
|
||||
sheet_refreshsub(ctl, sht->vx0, sht->vy0, sht->vx0 + sht->bxsize, sht->vy0 + sht->bysize, 0, old - 1);
|
||||
}
|
||||
} 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_refreshmap(ctl, sht->vx0, sht->vy0, sht->vx0 + sht->bxsize, sht->vy0 + sht->bysize, height);
|
||||
sheet_refreshsub(ctl, sht->vx0, sht->vy0, sht->vx0 + sht->bxsize, sht->vy0 + sht->bysize, height, height); /* 按新图层信息重新绘制画面 */
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void sheet_refresh(struct SHEET *sht, int bx0, int by0, int bx1, int by1)
|
||||
{
|
||||
if (sht->height >= 0) { /* 如果正在显示,则按新图层的信息刷新画面*/
|
||||
sheet_refreshsub(sht->ctl, sht->vx0 + bx0, sht->vy0 + by0, sht->vx0 + bx1, sht->vy0 + by1, sht->height, sht->height);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void sheet_slide(struct SHEET *sht, int vx0, int vy0)
|
||||
{
|
||||
struct SHTCTL *ctl = sht->ctl;
|
||||
int old_vx0 = sht->vx0, old_vy0 = sht->vy0;
|
||||
sht->vx0 = vx0;
|
||||
sht->vy0 = vy0;
|
||||
if (sht->height >= 0) { /* 如果正在显示,则按新图层的信息刷新画面 */
|
||||
sheet_refreshmap(ctl, old_vx0, old_vy0, old_vx0 + sht->bxsize, old_vy0 + sht->bysize, 0);
|
||||
sheet_refreshmap(ctl, vx0, vy0, vx0 + sht->bxsize, vy0 + sht->bysize, sht->height);
|
||||
sheet_refreshsub(ctl, old_vx0, old_vy0, old_vx0 + sht->bxsize, old_vy0 + sht->bysize, 0, sht->height - 1);
|
||||
sheet_refreshsub(ctl, vx0, vy0, vx0 + sht->bxsize, vy0 + sht->bysize, sht->height, sht->height);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void sheet_free(struct SHEET *sht)
|
||||
{
|
||||
if (sht->height >= 0) {
|
||||
sheet_updown(sht, -1); /* 如果处于显示状态,则先设定为隐藏 */
|
||||
}
|
||||
sht->flags = 0; /* "未使用"标志 */
|
||||
return;
|
||||
}
|
||||
18
25_day/star1.c
Normal file
18
25_day/star1.c
Normal file
@@ -0,0 +1,18 @@
|
||||
int api_openwin(char *buf, int xsiz, int ysiz, int col_inv, char *title);
|
||||
void api_boxfilwin(int win, int x0, int y0, int x1, int y1, int col);
|
||||
void api_initmalloc(void);
|
||||
char *api_malloc(int size);
|
||||
void api_point(int win, int x, int y, int col);
|
||||
void api_end(void);
|
||||
|
||||
void HariMain(void)
|
||||
{
|
||||
char *buf;
|
||||
int win;
|
||||
api_initmalloc();
|
||||
buf = api_malloc(150 * 100);
|
||||
win = api_openwin(buf, 150, 100, -1, "star1");
|
||||
api_boxfilwin(win, 6, 26, 143, 93, 0);/*黑色*/
|
||||
api_point(win, 75, 59, 3);/*黄色*/
|
||||
api_end();
|
||||
}
|
||||
24
25_day/stars.c
Normal file
24
25_day/stars.c
Normal file
@@ -0,0 +1,24 @@
|
||||
int api_openwin(char *buf, int xsiz, int ysiz, int col_inv, char *title);
|
||||
void api_boxfilwin(int win, int x0, int y0, int x1, int y1, int col);
|
||||
void api_initmalloc(void);
|
||||
char *api_malloc(int size);
|
||||
void api_point(int win, int x, int y, int col);
|
||||
void api_end(void);
|
||||
|
||||
int rand(void); /*产生0~32767之间的随机数*/
|
||||
|
||||
void HariMain(void)
|
||||
{
|
||||
char *buf;
|
||||
int win, i, x, y;
|
||||
api_initmalloc();
|
||||
buf = api_malloc(150 * 100);
|
||||
win = api_openwin(buf, 150, 100, -1, "stars");
|
||||
api_boxfilwin(win, 6, 26, 143, 93, 0);/*黑色*/
|
||||
for (i = 0; i < 50; i++) {
|
||||
x = (rand() % 137) + 6;
|
||||
y = (rand() % 67) + 26;
|
||||
api_point(win, x, y, 3);/*黄色*/
|
||||
}
|
||||
api_end();
|
||||
}
|
||||
26
25_day/stars2.c
Normal file
26
25_day/stars2.c
Normal file
@@ -0,0 +1,26 @@
|
||||
int api_openwin(char *buf, int xsiz, int ysiz, int col_inv, char *title);
|
||||
void api_boxfilwin(int win, int x0, int y0, int x1, int y1, int col);
|
||||
void api_initmalloc(void);
|
||||
char *api_malloc(int size);
|
||||
void api_point(int win, int x, int y, int col);
|
||||
void api_refreshwin(int win, int x0, int y0, int x1, int y1);
|
||||
void api_end(void);
|
||||
|
||||
int rand(void); /*产生0~32767的随机数*/
|
||||
|
||||
void HariMain(void)
|
||||
{
|
||||
char *buf;
|
||||
int win, i, x, y;
|
||||
api_initmalloc();
|
||||
buf = api_malloc(150 * 100);
|
||||
win = api_openwin(buf, 150, 100, -1, "stars2");
|
||||
api_boxfilwin(win + 1, 6, 26, 143, 93, 0);/*黑色*/
|
||||
for (i = 0; i < 50; i++) {
|
||||
x = (rand() % 137) + 6;
|
||||
y = (rand() % 67) + 26;
|
||||
api_point(win + 1, x, y, 3);/*黄色*/
|
||||
}
|
||||
api_refreshwin(win, 6, 26, 144, 94);
|
||||
api_end();
|
||||
}
|
||||
169
25_day/timer.c
Normal file
169
25_day/timer.c
Normal file
@@ -0,0 +1,169 @@
|
||||
/* 定时器 */
|
||||
|
||||
#include "bootpack.h"
|
||||
|
||||
#define PIT_CTRL 0x0043
|
||||
#define PIT_CNT0 0x0040
|
||||
|
||||
struct TIMERCTL timerctl;
|
||||
|
||||
#define TIMER_FLAGS_ALLOC 1 /* 已配置状态 */
|
||||
#define TIMER_FLAGS_USING 2 /* 定时器运行中 */
|
||||
|
||||
void init_pit(void)
|
||||
{
|
||||
int i;
|
||||
struct TIMER *t;
|
||||
io_out8(PIT_CTRL, 0x34);
|
||||
io_out8(PIT_CNT0, 0x9c);
|
||||
io_out8(PIT_CNT0, 0x2e);
|
||||
timerctl.count = 0;
|
||||
for (i = 0; i < MAX_TIMER; i++) {
|
||||
timerctl.timers0[i].flags = 0; /* 没有使用 */
|
||||
}
|
||||
t = timer_alloc(); /* 取得一个 */
|
||||
t->timeout = 0xffffffff;
|
||||
t->flags = TIMER_FLAGS_USING;
|
||||
t->next = 0; /* 末尾 */
|
||||
timerctl.t0 = t; /* 因为现在只有哨兵,所以他就在最前面*/
|
||||
timerctl.next = 0xffffffff; /* 因为只有哨兵,所以下一个超时时刻就是哨兵的时刻 */
|
||||
return;
|
||||
}
|
||||
|
||||
struct TIMER *timer_alloc(void)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < MAX_TIMER; i++) {
|
||||
if (timerctl.timers0[i].flags == 0) {
|
||||
timerctl.timers0[i].flags = TIMER_FLAGS_ALLOC;
|
||||
timerctl.timers0[i].flags2 = 0;
|
||||
return &timerctl.timers0[i];
|
||||
}
|
||||
}
|
||||
return 0; /* 没找到 */
|
||||
}
|
||||
|
||||
void timer_free(struct TIMER *timer)
|
||||
{
|
||||
timer->flags = 0; /* 未使用 */
|
||||
return;
|
||||
}
|
||||
|
||||
void timer_init(struct TIMER *timer, struct FIFO32 *fifo, int data)
|
||||
{
|
||||
timer->fifo = fifo;
|
||||
timer->data = data;
|
||||
return;
|
||||
}
|
||||
|
||||
void timer_settime(struct TIMER *timer, unsigned int timeout)
|
||||
{
|
||||
int e;
|
||||
struct TIMER *t, *s;
|
||||
timer->timeout = timeout + timerctl.count;
|
||||
timer->flags = TIMER_FLAGS_USING;
|
||||
e = io_load_eflags();
|
||||
io_cli();
|
||||
t = timerctl.t0;
|
||||
if (timer->timeout <= t->timeout) {
|
||||
/* 插入最前面的情况 */
|
||||
timerctl.t0 = timer;
|
||||
timer->next = t; /* 下面是设定t */
|
||||
timerctl.next = timer->timeout;
|
||||
io_store_eflags(e);
|
||||
return;
|
||||
}
|
||||
for (;;) {
|
||||
s = t;
|
||||
t = t->next;
|
||||
if (timer->timeout <= t->timeout) {
|
||||
/* 插入s和t之间的情况 */
|
||||
s->next = timer; /* s下一个是timer */
|
||||
timer->next = t; /* timer的下一个是t */
|
||||
io_store_eflags(e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void inthandler20(int *esp)
|
||||
{
|
||||
struct TIMER *timer;
|
||||
char ts = 0;
|
||||
io_out8(PIC0_OCW2, 0x60); /* 把IRQ-00接收信号结束的信息通知给PIC */
|
||||
timerctl.count++;
|
||||
if (timerctl.next > timerctl.count) {
|
||||
return;
|
||||
}
|
||||
timer = timerctl.t0; /* 首先把最前面的地址赋给timer */
|
||||
for (;;) {
|
||||
/* 因为timers的定时器都处于运行状态,所以不确认flags */
|
||||
if (timer->timeout > timerctl.count) {
|
||||
break;
|
||||
}
|
||||
/* 超时 */
|
||||
timer->flags = TIMER_FLAGS_ALLOC;
|
||||
if (timer != task_timer) {
|
||||
fifo32_put(timer->fifo, timer->data);
|
||||
} else {
|
||||
ts = 1; /* mt_timer超时*/
|
||||
}
|
||||
timer = timer->next; /* 将下一个定时器的地址赋给timer*/
|
||||
}
|
||||
timerctl.t0 = timer;
|
||||
timerctl.next = timer->timeout;
|
||||
if (ts != 0) {
|
||||
task_switch();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int timer_cancel(struct TIMER *timer)
|
||||
{
|
||||
int e;
|
||||
struct TIMER *t;
|
||||
e = io_load_eflags();
|
||||
io_cli(); /*在设置过程中禁止改变定时器状态*/
|
||||
if (timer->flags == TIMER_FLAGS_USING) { /*是否需要取消?*/
|
||||
if (timer == timerctl.t0) {
|
||||
/*第一个定时器的取消处理*/
|
||||
t = timer->next;
|
||||
timerctl.t0 = t;
|
||||
timerctl.next = t->timeout;
|
||||
} else {
|
||||
/*非第一个定时器的取消处理*/
|
||||
/*找到timer前一个定时器*/
|
||||
t = timerctl.t0;
|
||||
for (;;) {
|
||||
if (t->next == timer) {
|
||||
break;
|
||||
}
|
||||
t = t->next;
|
||||
}
|
||||
t->next = timer->next;
|
||||
/*将之前“timer的下一个”指向“timer的下一个”*/
|
||||
}
|
||||
timer->flags = TIMER_FLAGS_ALLOC;
|
||||
io_store_eflags(e);
|
||||
return 1; /*取消处理成功*/
|
||||
}
|
||||
io_store_eflags(e);
|
||||
return 0; /*不需要取消处理*/
|
||||
}
|
||||
|
||||
void timer_cancelall(struct FIFO32 *fifo)
|
||||
{
|
||||
int e, i;
|
||||
struct TIMER *t;
|
||||
e = io_load_eflags();
|
||||
io_cli(); /*在设置过程中禁止改变定时器状态*/
|
||||
for (i = 0; i < MAX_TIMER; i++) {
|
||||
t = &timerctl.timers0[i];
|
||||
if (t->flags != 0 && t->flags2 != 0 && t->fifo == fifo) {
|
||||
timer_cancel(t);
|
||||
timer_free(t);
|
||||
}
|
||||
}
|
||||
io_store_eflags(e);
|
||||
return;
|
||||
}
|
||||
35
25_day/walk.c
Normal file
35
25_day/walk.c
Normal file
@@ -0,0 +1,35 @@
|
||||
int api_openwin(char *buf, int xsiz, int ysiz, int col_inv, char *title);
|
||||
void api_putstrwin(int win, int x, int y, int col, int len, char *str);
|
||||
void api_boxfilwin(int win, int x0, int y0, int x1, int y1, int col);
|
||||
void api_initmalloc(void);
|
||||
char *api_malloc(int size);
|
||||
void api_refreshwin(int win, int x0, int y0, int x1, int y1);
|
||||
void api_linewin(int win, int x0, int y0, int x1, int y1, int col);
|
||||
void api_closewin(int win);
|
||||
int api_getkey(int mode);
|
||||
void api_end(void);
|
||||
|
||||
void HariMain(void)
|
||||
{
|
||||
char *buf;
|
||||
int win, i, x, y;
|
||||
api_initmalloc();
|
||||
buf = api_malloc(160 * 100);
|
||||
win = api_openwin(buf, 160, 100, -1, "walk");
|
||||
api_boxfilwin(win, 4, 24, 155, 95, 0);/*黑色*/
|
||||
x = 76;
|
||||
y = 56;
|
||||
api_putstrwin(win, x, y, 3, 1, "*");/*黄色*/
|
||||
for (;;) {
|
||||
i = api_getkey(1);
|
||||
api_putstrwin(win, x, y, 0 , 1, "*"); /*用黑色擦除*/
|
||||
if (i == '4' && x > 4) { x -= 8; }
|
||||
if (i == '6' && x < 148) { x += 8; }
|
||||
if (i == '8' && y > 24) { y -= 8; }
|
||||
if (i == '2' && y < 80) { y += 8; }
|
||||
if (i == 0x0a) { break; } /*按回车键结束*/
|
||||
api_putstrwin(win, x, y, 3 , 1, "*");/*黄色*/
|
||||
}
|
||||
api_closewin(win);
|
||||
api_end();
|
||||
}
|
||||
118
25_day/window.c
Normal file
118
25_day/window.c
Normal file
@@ -0,0 +1,118 @@
|
||||
/* 窗口相关函数 */
|
||||
|
||||
#include "bootpack.h"
|
||||
|
||||
void make_window8(unsigned char *buf, int xsize, int ysize, char *title, char act)
|
||||
{
|
||||
boxfill8(buf, xsize, COL8_C6C6C6, 0, 0, xsize - 1, 0 );
|
||||
boxfill8(buf, xsize, COL8_FFFFFF, 1, 1, xsize - 2, 1 );
|
||||
boxfill8(buf, xsize, COL8_C6C6C6, 0, 0, 0, ysize - 1);
|
||||
boxfill8(buf, xsize, COL8_FFFFFF, 1, 1, 1, ysize - 2);
|
||||
boxfill8(buf, xsize, COL8_848484, xsize - 2, 1, xsize - 2, ysize - 2);
|
||||
boxfill8(buf, xsize, COL8_000000, xsize - 1, 0, xsize - 1, ysize - 1);
|
||||
boxfill8(buf, xsize, COL8_C6C6C6, 2, 2, xsize - 3, ysize - 3);
|
||||
boxfill8(buf, xsize, COL8_848484, 1, ysize - 2, xsize - 2, ysize - 2);
|
||||
boxfill8(buf, xsize, COL8_000000, 0, ysize - 1, xsize - 1, ysize - 1);
|
||||
make_wtitle8(buf, xsize, title, act);
|
||||
return;
|
||||
}
|
||||
|
||||
void make_wtitle8(unsigned char *buf, int xsize, char *title, char act)
|
||||
{
|
||||
static char closebtn[14][16] = {
|
||||
"OOOOOOOOOOOOOOO@",
|
||||
"OQQQQQQQQQQQQQ$@",
|
||||
"OQQQQQQQQQQQQQ$@",
|
||||
"OQQQ@@QQQQ@@QQ$@",
|
||||
"OQQQQ@@QQ@@QQQ$@",
|
||||
"OQQQQQ@@@@QQQQ$@",
|
||||
"OQQQQQQ@@QQQQQ$@",
|
||||
"OQQQQQ@@@@QQQQ$@",
|
||||
"OQQQQ@@QQ@@QQQ$@",
|
||||
"OQQQ@@QQQQ@@QQ$@",
|
||||
"OQQQQQQQQQQQQQ$@",
|
||||
"OQQQQQQQQQQQQQ$@",
|
||||
"O$$$$$$$$$$$$$$@",
|
||||
"@@@@@@@@@@@@@@@@"
|
||||
};
|
||||
int x, y;
|
||||
char c, tc, tbc;
|
||||
if (act != 0) {
|
||||
tc = COL8_FFFFFF;
|
||||
tbc = COL8_000084;
|
||||
} else {
|
||||
tc = COL8_C6C6C6;
|
||||
tbc = COL8_848484;
|
||||
}
|
||||
boxfill8(buf, xsize, tbc, 3, 3, xsize - 4, 20);
|
||||
putfonts8_asc(buf, xsize, 24, 4, tc, title);
|
||||
for (y = 0; y < 14; y++) {
|
||||
for (x = 0; x < 16; x++) {
|
||||
c = closebtn[y][x];
|
||||
if (c == '@') {
|
||||
c = COL8_000000;
|
||||
} else if (c == '$') {
|
||||
c = COL8_848484;
|
||||
} else if (c == 'Q') {
|
||||
c = COL8_C6C6C6;
|
||||
} else {
|
||||
c = COL8_FFFFFF;
|
||||
}
|
||||
buf[(5 + y) * xsize + (xsize - 21 + x)] = c;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void putfonts8_asc_sht(struct SHEET *sht, int x, int y, int c, int b, char *s, int l)
|
||||
{
|
||||
boxfill8(sht->buf, sht->bxsize, b, x, y, x + l * 8 - 1, y + 15);
|
||||
putfonts8_asc(sht->buf, sht->bxsize, x, y, c, s);
|
||||
sheet_refresh(sht, x, y, x + l * 8, y + 16);
|
||||
return;
|
||||
}
|
||||
|
||||
void make_textbox8(struct SHEET *sht, int x0, int y0, int sx, int sy, int c)
|
||||
{
|
||||
int x1 = x0 + sx, y1 = y0 + sy;
|
||||
boxfill8(sht->buf, sht->bxsize, COL8_848484, x0 - 2, y0 - 3, x1 + 1, y0 - 3);
|
||||
boxfill8(sht->buf, sht->bxsize, COL8_848484, x0 - 3, y0 - 3, x0 - 3, y1 + 1);
|
||||
boxfill8(sht->buf, sht->bxsize, COL8_FFFFFF, x0 - 3, y1 + 2, x1 + 1, y1 + 2);
|
||||
boxfill8(sht->buf, sht->bxsize, COL8_FFFFFF, x1 + 2, y0 - 3, x1 + 2, y1 + 2);
|
||||
boxfill8(sht->buf, sht->bxsize, COL8_000000, x0 - 1, y0 - 2, x1 + 0, y0 - 2);
|
||||
boxfill8(sht->buf, sht->bxsize, COL8_000000, x0 - 2, y0 - 2, x0 - 2, y1 + 0);
|
||||
boxfill8(sht->buf, sht->bxsize, COL8_C6C6C6, x0 - 2, y1 + 1, x1 + 0, y1 + 1);
|
||||
boxfill8(sht->buf, sht->bxsize, COL8_C6C6C6, x1 + 1, y0 - 2, x1 + 1, y1 + 1);
|
||||
boxfill8(sht->buf, sht->bxsize, c, x0 - 1, y0 - 1, x1 + 0, y1 + 0);
|
||||
return;
|
||||
}
|
||||
|
||||
void change_wtitle8(struct SHEET *sht, char act)
|
||||
{
|
||||
int x, y, xsize = sht->bxsize;
|
||||
char c, tc_new, tbc_new, tc_old, tbc_old, *buf = sht->buf;
|
||||
if (act != 0) {
|
||||
tc_new = COL8_FFFFFF;
|
||||
tbc_new = COL8_000084;
|
||||
tc_old = COL8_C6C6C6;
|
||||
tbc_old = COL8_848484;
|
||||
} else {
|
||||
tc_new = COL8_C6C6C6;
|
||||
tbc_new = COL8_848484;
|
||||
tc_old = COL8_FFFFFF;
|
||||
tbc_old = COL8_000084;
|
||||
}
|
||||
for (y = 3; y <= 20; y++) {
|
||||
for (x = 3; x <= xsize - 4; x++) {
|
||||
c = buf[y * xsize + x];
|
||||
if (c == tc_old && x <= xsize - 22) {
|
||||
c = tc_new;
|
||||
} else if (c == tbc_old) {
|
||||
c = tbc_new;
|
||||
}
|
||||
buf[y * xsize + x] = c;
|
||||
}
|
||||
}
|
||||
sheet_refresh(sht, 3, 3, xsize, 21);
|
||||
return;
|
||||
}
|
||||
11
25_day/winhelo.c
Normal file
11
25_day/winhelo.c
Normal file
@@ -0,0 +1,11 @@
|
||||
int api_openwin(char *buf, int xsiz, int ysiz, int col_inv, char *title);
|
||||
void api_end(void);
|
||||
|
||||
char buf[150 * 50];
|
||||
|
||||
void HariMain(void)
|
||||
{
|
||||
int win;
|
||||
win = api_openwin(buf, 150, 50, -1, "hello");
|
||||
api_end();
|
||||
}
|
||||
15
25_day/winhelo2.c
Normal file
15
25_day/winhelo2.c
Normal file
@@ -0,0 +1,15 @@
|
||||
int api_openwin(char *buf, int xsiz, int ysiz, int col_inv, char *title);
|
||||
void api_putstrwin(int win, int x, int y, int col, int len, char *str);
|
||||
void api_boxfilwin(int win, int x0, int y0, int x1, int y1, int col);
|
||||
void api_end(void);
|
||||
|
||||
char buf[150 * 50];
|
||||
|
||||
void HariMain(void)
|
||||
{
|
||||
int win;
|
||||
win = api_openwin(buf, 150, 50, -1, "hello");
|
||||
api_boxfilwin(win, 8, 36, 141, 43, 3); /*黄色*/
|
||||
api_putstrwin(win, 28, 28, 0 /*黑色*/, 12, "hello, world");
|
||||
api_end();
|
||||
}
|
||||
19
25_day/winhelo3.c
Normal file
19
25_day/winhelo3.c
Normal file
@@ -0,0 +1,19 @@
|
||||
int api_openwin(char *buf, int xsiz, int ysiz, int col_inv, char *title);
|
||||
void api_putstrwin(int win, int x, int y, int col, int len, char *str);
|
||||
void api_boxfilwin(int win, int x0, int y0, int x1, int y1, int col);
|
||||
void api_initmalloc(void);
|
||||
char *api_malloc(int size);
|
||||
void api_end(void);
|
||||
|
||||
void HariMain(void)
|
||||
{
|
||||
char *buf;
|
||||
int win;
|
||||
|
||||
api_initmalloc();
|
||||
buf = api_malloc(150 * 50);
|
||||
win = api_openwin(buf, 150, 50, -1, "hello");
|
||||
api_boxfilwin(win, 8, 36, 141, 43, 6); /*浅蓝色*/
|
||||
api_putstrwin(win, 28, 28, 0 , 12, "hello, world");/*黑色*/
|
||||
api_end();
|
||||
}
|
||||
1
26_day/!cons_9x.bat
Normal file
1
26_day/!cons_9x.bat
Normal file
@@ -0,0 +1 @@
|
||||
command
|
||||
1
26_day/!cons_nt.bat
Normal file
1
26_day/!cons_nt.bat
Normal file
@@ -0,0 +1 @@
|
||||
cmd.exe
|
||||
232
26_day/Makefile
Normal file
232
26_day/Makefile
Normal file
@@ -0,0 +1,232 @@
|
||||
OBJS_BOOTPACK = bootpack.obj naskfunc.obj hankaku.obj graphic.obj dsctbl.obj \
|
||||
int.obj fifo.obj keyboard.obj mouse.obj memory.obj sheet.obj timer.obj \
|
||||
mtask.obj window.obj console.obj file.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
|
||||
|
||||
hello.hrb : hello.nas Makefile
|
||||
$(NASK) hello.nas hello.hrb hello.lst
|
||||
|
||||
hello2.hrb : hello2.nas Makefile
|
||||
$(NASK) hello2.nas hello2.hrb hello2.lst
|
||||
|
||||
a.bim : a.obj a_nask.obj Makefile
|
||||
$(OBJ2BIM) @$(RULEFILE) out:a.bim map:a.map a.obj a_nask.obj
|
||||
|
||||
a.hrb : a.bim Makefile
|
||||
$(BIM2HRB) a.bim a.hrb 0
|
||||
|
||||
hello3.bim : hello3.obj a_nask.obj Makefile
|
||||
$(OBJ2BIM) @$(RULEFILE) out:hello3.bim map:hello3.map hello3.obj a_nask.obj
|
||||
|
||||
hello3.hrb : hello3.bim Makefile
|
||||
$(BIM2HRB) hello3.bim hello3.hrb 0
|
||||
|
||||
hello4.bim : hello4.obj a_nask.obj Makefile
|
||||
$(OBJ2BIM) @$(RULEFILE) out:hello4.bim stack:1k map:hello4.map \
|
||||
hello4.obj a_nask.obj
|
||||
|
||||
hello4.hrb : hello4.bim Makefile
|
||||
$(BIM2HRB) hello4.bim hello4.hrb 0
|
||||
|
||||
hello5.bim : hello5.obj Makefile
|
||||
$(OBJ2BIM) @$(RULEFILE) out:hello5.bim stack:1k map:hello5.map hello5.obj
|
||||
|
||||
hello5.hrb : hello5.bim Makefile
|
||||
$(BIM2HRB) hello5.bim hello5.hrb 0
|
||||
|
||||
winhelo.bim : winhelo.obj a_nask.obj Makefile
|
||||
$(OBJ2BIM) @$(RULEFILE) out:winhelo.bim stack:1k map:winhelo.map \
|
||||
winhelo.obj a_nask.obj
|
||||
|
||||
winhelo.hrb : winhelo.bim Makefile
|
||||
$(BIM2HRB) winhelo.bim winhelo.hrb 0
|
||||
|
||||
winhelo2.bim : winhelo2.obj a_nask.obj Makefile
|
||||
$(OBJ2BIM) @$(RULEFILE) out:winhelo2.bim stack:1k map:winhelo2.map \
|
||||
winhelo2.obj a_nask.obj
|
||||
|
||||
winhelo2.hrb : winhelo2.bim Makefile
|
||||
$(BIM2HRB) winhelo2.bim winhelo2.hrb 0
|
||||
|
||||
winhelo3.bim : winhelo3.obj a_nask.obj Makefile
|
||||
$(OBJ2BIM) @$(RULEFILE) out:winhelo3.bim stack:1k map:winhelo3.map \
|
||||
winhelo3.obj a_nask.obj
|
||||
|
||||
winhelo3.hrb : winhelo3.bim Makefile
|
||||
$(BIM2HRB) winhelo3.bim winhelo3.hrb 40k
|
||||
|
||||
star1.bim : star1.obj a_nask.obj Makefile
|
||||
$(OBJ2BIM) @$(RULEFILE) out:star1.bim stack:1k map:star1.map \
|
||||
star1.obj a_nask.obj
|
||||
|
||||
star1.hrb : star1.bim Makefile
|
||||
$(BIM2HRB) star1.bim star1.hrb 47k
|
||||
|
||||
stars.bim : stars.obj a_nask.obj Makefile
|
||||
$(OBJ2BIM) @$(RULEFILE) out:stars.bim stack:1k map:stars.map \
|
||||
stars.obj a_nask.obj
|
||||
|
||||
stars.hrb : stars.bim Makefile
|
||||
$(BIM2HRB) stars.bim stars.hrb 47k
|
||||
|
||||
stars2.bim : stars2.obj a_nask.obj Makefile
|
||||
$(OBJ2BIM) @$(RULEFILE) out:stars2.bim stack:1k map:stars2.map \
|
||||
stars2.obj a_nask.obj
|
||||
|
||||
stars2.hrb : stars2.bim Makefile
|
||||
$(BIM2HRB) stars2.bim stars2.hrb 47k
|
||||
|
||||
lines.bim : lines.obj a_nask.obj Makefile
|
||||
$(OBJ2BIM) @$(RULEFILE) out:lines.bim stack:1k map:lines.map \
|
||||
lines.obj a_nask.obj
|
||||
|
||||
lines.hrb : lines.bim Makefile
|
||||
$(BIM2HRB) lines.bim lines.hrb 48k
|
||||
|
||||
walk.bim : walk.obj a_nask.obj Makefile
|
||||
$(OBJ2BIM) @$(RULEFILE) out:walk.bim stack:1k map:walk.map \
|
||||
walk.obj a_nask.obj
|
||||
|
||||
walk.hrb : walk.bim Makefile
|
||||
$(BIM2HRB) walk.bim walk.hrb 48k
|
||||
|
||||
noodle.bim : noodle.obj a_nask.obj Makefile
|
||||
$(OBJ2BIM) @$(RULEFILE) out:noodle.bim stack:1k map:noodle.map \
|
||||
noodle.obj a_nask.obj
|
||||
|
||||
noodle.hrb : noodle.bim Makefile
|
||||
$(BIM2HRB) noodle.bim noodle.hrb 40k
|
||||
|
||||
beepdown.bim : beepdown.obj a_nask.obj Makefile
|
||||
$(OBJ2BIM) @$(RULEFILE) out:beepdown.bim stack:1k map:beepdown.map \
|
||||
beepdown.obj a_nask.obj
|
||||
|
||||
beepdown.hrb : beepdown.bim Makefile
|
||||
$(BIM2HRB) beepdown.bim beepdown.hrb 40k
|
||||
|
||||
color.bim : color.obj a_nask.obj Makefile
|
||||
$(OBJ2BIM) @$(RULEFILE) out:color.bim stack:1k map:color.map \
|
||||
color.obj a_nask.obj
|
||||
|
||||
color.hrb : color.bim Makefile
|
||||
$(BIM2HRB) color.bim color.hrb 56k
|
||||
|
||||
color2.bim : color2.obj a_nask.obj Makefile
|
||||
$(OBJ2BIM) @$(RULEFILE) out:color2.bim stack:1k map:color2.map \
|
||||
color2.obj a_nask.obj
|
||||
|
||||
color2.hrb : color2.bim Makefile
|
||||
$(BIM2HRB) color2.bim color2.hrb 56k
|
||||
|
||||
haribote.img : ipl10.bin haribote.sys Makefile \
|
||||
hello.hrb hello2.hrb a.hrb hello3.hrb hello4.hrb hello5.hrb \
|
||||
winhelo.hrb winhelo2.hrb winhelo3.hrb star1.hrb stars.hrb stars2.hrb \
|
||||
lines.hrb walk.hrb noodle.hrb beepdown.hrb color.hrb color2.hrb
|
||||
$(EDIMG) imgin:../z_tools/fdimg0at.tek \
|
||||
wbinimg src:ipl10.bin len:512 from:0 to:0 \
|
||||
copy from:haribote.sys to:@: \
|
||||
copy from:ipl10.nas to:@: \
|
||||
copy from:make.bat to:@: \
|
||||
copy from:hello.hrb to:@: \
|
||||
copy from:hello2.hrb to:@: \
|
||||
copy from:a.hrb to:@: \
|
||||
copy from:hello3.hrb to:@: \
|
||||
copy from:hello4.hrb to:@: \
|
||||
copy from:hello5.hrb to:@: \
|
||||
copy from:winhelo.hrb to:@: \
|
||||
copy from:winhelo2.hrb to:@: \
|
||||
copy from:winhelo3.hrb to:@: \
|
||||
copy from:star1.hrb to:@: \
|
||||
copy from:stars.hrb to:@: \
|
||||
copy from:stars2.hrb to:@: \
|
||||
copy from:lines.hrb to:@: \
|
||||
copy from:walk.hrb to:@: \
|
||||
copy from:noodle.hrb to:@: \
|
||||
copy from:beepdown.hrb to:@: \
|
||||
copy from:color.hrb to:@: \
|
||||
copy from:color2.hrb 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.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
|
||||
8
26_day/a.c
Normal file
8
26_day/a.c
Normal file
@@ -0,0 +1,8 @@
|
||||
void api_putchar(int c);
|
||||
void api_end(void);
|
||||
|
||||
void HariMain(void)
|
||||
{
|
||||
api_putchar('A');
|
||||
api_end();
|
||||
}
|
||||
230
26_day/a_nask.nas
Normal file
230
26_day/a_nask.nas
Normal file
@@ -0,0 +1,230 @@
|
||||
[FORMAT "WCOFF"] ; 生成对象文件的模式
|
||||
[INSTRSET "i486p"] ; 表示使用486兼容指令集
|
||||
[BITS 32] ; 生成32位模式机器语言
|
||||
[FILE "a_nask.nas"] ; 源文件名信息
|
||||
|
||||
GLOBAL _api_putchar
|
||||
GLOBAL _api_putstr0
|
||||
GLOBAL _api_end
|
||||
GLOBAL _api_openwin
|
||||
GLOBAL _api_putstrwin
|
||||
GLOBAL _api_boxfilwin
|
||||
GLOBAL _api_initmalloc
|
||||
GLOBAL _api_malloc
|
||||
GLOBAL _api_free
|
||||
GLOBAL _api_point
|
||||
GLOBAL _api_refreshwin
|
||||
GLOBAL _api_linewin
|
||||
GLOBAL _api_closewin
|
||||
GLOBAL _api_getkey
|
||||
GLOBAL _api_alloctimer
|
||||
GLOBAL _api_inittimer
|
||||
GLOBAL _api_settimer
|
||||
GLOBAL _api_freetimer
|
||||
GLOBAL _api_beep
|
||||
|
||||
[SECTION .text]
|
||||
|
||||
_api_putchar: ; void api_putchar(int c);
|
||||
MOV EDX,1
|
||||
MOV AL,[ESP+4] ; c
|
||||
INT 0x40
|
||||
RET
|
||||
|
||||
_api_putstr0: ; void api_putstr0(char *s);
|
||||
PUSH EBX
|
||||
MOV EDX,2
|
||||
MOV EBX,[ESP+8] ; s
|
||||
INT 0x40
|
||||
POP EBX
|
||||
RET
|
||||
|
||||
_api_end: ; void api_end(void);
|
||||
MOV EDX,4
|
||||
INT 0x40
|
||||
|
||||
_api_openwin: ; int api_openwin(char *buf, int xsiz, int ysiz, int col_inv, char *title);
|
||||
PUSH EDI
|
||||
PUSH ESI
|
||||
PUSH EBX
|
||||
MOV EDX,5
|
||||
MOV EBX,[ESP+16] ; buf
|
||||
MOV ESI,[ESP+20] ; xsiz
|
||||
MOV EDI,[ESP+24] ; ysiz
|
||||
MOV EAX,[ESP+28] ; col_inv
|
||||
MOV ECX,[ESP+32] ; title
|
||||
INT 0x40
|
||||
POP EBX
|
||||
POP ESI
|
||||
POP EDI
|
||||
RET
|
||||
|
||||
_api_putstrwin: ; void api_putstrwin(int win, int x, int y, int col, int len, char *str);
|
||||
PUSH EDI
|
||||
PUSH ESI
|
||||
PUSH EBP
|
||||
PUSH EBX
|
||||
MOV EDX,6
|
||||
MOV EBX,[ESP+20] ; win
|
||||
MOV ESI,[ESP+24] ; x
|
||||
MOV EDI,[ESP+28] ; y
|
||||
MOV EAX,[ESP+32] ; col
|
||||
MOV ECX,[ESP+36] ; len
|
||||
MOV EBP,[ESP+40] ; str
|
||||
INT 0x40
|
||||
POP EBX
|
||||
POP EBP
|
||||
POP ESI
|
||||
POP EDI
|
||||
RET
|
||||
|
||||
_api_boxfilwin: ; void api_boxfilwin(int win, int x0, int y0, int x1, int y1, int col);
|
||||
PUSH EDI
|
||||
PUSH ESI
|
||||
PUSH EBP
|
||||
PUSH EBX
|
||||
MOV EDX,7
|
||||
MOV EBX,[ESP+20] ; win
|
||||
MOV EAX,[ESP+24] ; x0
|
||||
MOV ECX,[ESP+28] ; y0
|
||||
MOV ESI,[ESP+32] ; x1
|
||||
MOV EDI,[ESP+36] ; y1
|
||||
MOV EBP,[ESP+40] ; col
|
||||
INT 0x40
|
||||
POP EBX
|
||||
POP EBP
|
||||
POP ESI
|
||||
POP EDI
|
||||
RET
|
||||
|
||||
_api_initmalloc: ; void api_initmalloc(void);
|
||||
PUSH EBX
|
||||
MOV EDX,8
|
||||
MOV EBX,[CS:0x0020] ; malloc内存空间的地址
|
||||
MOV EAX,EBX
|
||||
ADD EAX,32*1024 ; 加上32KB
|
||||
MOV ECX,[CS:0x0000] ; 数据段的大小
|
||||
SUB ECX,EAX
|
||||
INT 0x40
|
||||
POP EBX
|
||||
RET
|
||||
|
||||
_api_malloc: ; char *api_malloc(int size);
|
||||
PUSH EBX
|
||||
MOV EDX,9
|
||||
MOV EBX,[CS:0x0020]
|
||||
MOV ECX,[ESP+8] ; size
|
||||
INT 0x40
|
||||
POP EBX
|
||||
RET
|
||||
|
||||
_api_free: ; void api_free(char *addr, int size);
|
||||
PUSH EBX
|
||||
MOV EDX,10
|
||||
MOV EBX,[CS:0x0020]
|
||||
MOV EAX,[ESP+ 8] ; addr
|
||||
MOV ECX,[ESP+12] ; size
|
||||
INT 0x40
|
||||
POP EBX
|
||||
RET
|
||||
|
||||
_api_point: ; void api_point(int win, int x, int y, int col);
|
||||
PUSH EDI
|
||||
PUSH ESI
|
||||
PUSH EBX
|
||||
MOV EDX,11
|
||||
MOV EBX,[ESP+16] ; win
|
||||
MOV ESI,[ESP+20] ; x
|
||||
MOV EDI,[ESP+24] ; y
|
||||
MOV EAX,[ESP+28] ; col
|
||||
INT 0x40
|
||||
POP EBX
|
||||
POP ESI
|
||||
POP EDI
|
||||
RET
|
||||
|
||||
_api_refreshwin: ; void api_refreshwin(int win, int x0, int y0, int x1, int y1);
|
||||
PUSH EDI
|
||||
PUSH ESI
|
||||
PUSH EBX
|
||||
MOV EDX,12
|
||||
MOV EBX,[ESP+16] ; win
|
||||
MOV EAX,[ESP+20] ; x0
|
||||
MOV ECX,[ESP+24] ; y0
|
||||
MOV ESI,[ESP+28] ; x1
|
||||
MOV EDI,[ESP+32] ; y1
|
||||
INT 0x40
|
||||
POP EBX
|
||||
POP ESI
|
||||
POP EDI
|
||||
RET
|
||||
|
||||
_api_linewin: ; void api_linewin(int win, int x0, int y0, int x1, int y1, int col);
|
||||
PUSH EDI
|
||||
PUSH ESI
|
||||
PUSH EBP
|
||||
PUSH EBX
|
||||
MOV EDX,13
|
||||
MOV EBX,[ESP+20] ; win
|
||||
MOV EAX,[ESP+24] ; x0
|
||||
MOV ECX,[ESP+28] ; y0
|
||||
MOV ESI,[ESP+32] ; x1
|
||||
MOV EDI,[ESP+36] ; y1
|
||||
MOV EBP,[ESP+40] ; col
|
||||
INT 0x40
|
||||
POP EBX
|
||||
POP EBP
|
||||
POP ESI
|
||||
POP EDI
|
||||
RET
|
||||
|
||||
_api_closewin: ; void api_closewin(int win);
|
||||
PUSH EBX
|
||||
MOV EDX,14
|
||||
MOV EBX,[ESP+8] ; win
|
||||
INT 0x40
|
||||
POP EBX
|
||||
RET
|
||||
|
||||
_api_getkey: ; int api_getkey(int mode);
|
||||
MOV EDX,15
|
||||
MOV EAX,[ESP+4] ; mode
|
||||
INT 0x40
|
||||
RET
|
||||
|
||||
_api_alloctimer: ; int api_alloctimer(void);
|
||||
MOV EDX,16
|
||||
INT 0x40
|
||||
RET
|
||||
|
||||
_api_inittimer: ; void api_inittimer(int timer, int data);
|
||||
PUSH EBX
|
||||
MOV EDX,17
|
||||
MOV EBX,[ESP+ 8] ; timer
|
||||
MOV EAX,[ESP+12] ; data
|
||||
INT 0x40
|
||||
POP EBX
|
||||
RET
|
||||
|
||||
_api_settimer: ; void api_settimer(int timer, int time);
|
||||
PUSH EBX
|
||||
MOV EDX,18
|
||||
MOV EBX,[ESP+ 8] ; timer
|
||||
MOV EAX,[ESP+12] ; time
|
||||
INT 0x40
|
||||
POP EBX
|
||||
RET
|
||||
|
||||
_api_freetimer: ; void api_freetimer(int timer);
|
||||
PUSH EBX
|
||||
MOV EDX,19
|
||||
MOV EBX,[ESP+ 8] ; timer
|
||||
INT 0x40
|
||||
POP EBX
|
||||
RET
|
||||
|
||||
_api_beep: ; void api_beep(int tone);
|
||||
MOV EDX,20
|
||||
MOV EAX,[ESP+4] ; tone
|
||||
INT 0x40
|
||||
RET
|
||||
202
26_day/asmhead.nas
Normal file
202
26_day/asmhead.nas
Normal file
@@ -0,0 +1,202 @@
|
||||
; haribote-os boot asm
|
||||
; TAB=4
|
||||
|
||||
[INSTRSET "i486p"]
|
||||
|
||||
VBEMODE EQU 0x105 ; 1024 x 768 x 8bit 彩色
|
||||
; 显示模式
|
||||
; 0x100 : 640 x 400 x 8bit 彩色
|
||||
; 0x101 : 640 x 480 x 8bit 彩色
|
||||
; 0x103 : 800 x 600 x 8bit 彩色
|
||||
; 0x105 : 1024 x 768 x 8bit 彩色
|
||||
; 0x107 : 1280 x 1024 x 8bit 彩色
|
||||
|
||||
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 ; 这个的程序要被装载的内存地址
|
||||
|
||||
; 确认VBE是否存在
|
||||
|
||||
MOV AX,0x9000
|
||||
MOV ES,AX
|
||||
MOV DI,0
|
||||
MOV AX,0x4f00
|
||||
INT 0x10
|
||||
CMP AX,0x004f
|
||||
JNE scrn320
|
||||
|
||||
; 检查VBE的版本
|
||||
|
||||
MOV AX,[ES:DI+4]
|
||||
CMP AX,0x0200
|
||||
JB scrn320 ; if (AX < 0x0200) goto scrn320
|
||||
|
||||
; 取得画面模式信息
|
||||
|
||||
MOV CX,VBEMODE
|
||||
MOV AX,0x4f01
|
||||
INT 0x10
|
||||
CMP AX,0x004f
|
||||
JNE scrn320
|
||||
|
||||
; 画面模式信息的确认
|
||||
CMP BYTE [ES:DI+0x19],8 ;颜色数必须为8
|
||||
JNE scrn320
|
||||
CMP BYTE [ES:DI+0x1b],4 ;颜色的指定方法必须为4(4是调色板模式)
|
||||
JNE scrn320
|
||||
MOV AX,[ES:DI+0x00] ;模式属性bit7不是1就不能加上0x4000
|
||||
AND AX,0x0080
|
||||
JZ scrn320 ; 模式属性的bit7是0,所以放弃
|
||||
|
||||
; 画面设置
|
||||
|
||||
MOV BX,VBEMODE+0x4000
|
||||
MOV AX,0x4f02
|
||||
INT 0x10
|
||||
MOV BYTE [VMODE],8 ; 屏幕的模式(参考C语言的引用)
|
||||
MOV AX,[ES:DI+0x12]
|
||||
MOV [SCRNX],AX
|
||||
MOV AX,[ES:DI+0x14]
|
||||
MOV [SCRNY],AX
|
||||
MOV EAX,[ES:DI+0x28] ;VRAM的地址
|
||||
MOV [VRAM],EAX
|
||||
JMP keystatus
|
||||
|
||||
scrn320:
|
||||
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 获取指示灯状态
|
||||
|
||||
keystatus:
|
||||
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能够访问1MB以上的内存空间,设定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为0(禁用分页)
|
||||
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 ; 可以读写的段(segment)32bit
|
||||
DW 0xffff,0x0000,0x9a28,0x0047 ; 可执行的文件的32bit寄存器(bootpack用)
|
||||
|
||||
DW 0
|
||||
GDTR0:
|
||||
DW 8*3-1
|
||||
DD GDT0
|
||||
|
||||
ALIGNB 16
|
||||
bootpack:
|
||||
24
26_day/beepdown.c
Normal file
24
26_day/beepdown.c
Normal file
@@ -0,0 +1,24 @@
|
||||
void api_end(void);
|
||||
int api_getkey(int mode);
|
||||
int api_alloctimer(void);
|
||||
void api_inittimer(int timer, int data);
|
||||
void api_settimer(int timer, int time);
|
||||
void api_beep(int tone);
|
||||
|
||||
void HariMain(void)
|
||||
{
|
||||
int i, timer;
|
||||
timer = api_alloctimer();
|
||||
api_inittimer(timer, 128);
|
||||
for (i = 20000000; i >= 20000; i -= i / 100) {
|
||||
/* 20KHz~20Hz,即人类可以听到的声音范围*/
|
||||
/* i以1%的速度递减*/
|
||||
api_beep(i);
|
||||
api_settimer(timer, 1); /* 0.01秒*/
|
||||
if (api_getkey(1) != 128) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
api_beep(0);
|
||||
api_end();
|
||||
}
|
||||
377
26_day/bootpack.c
Normal file
377
26_day/bootpack.c
Normal file
@@ -0,0 +1,377 @@
|
||||
/* bootpack */
|
||||
|
||||
#include "bootpack.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#define KEYCMD_LED 0xed
|
||||
|
||||
void keywin_off(struct SHEET *key_win);
|
||||
void keywin_on(struct SHEET *key_win);
|
||||
void close_console(struct SHEET *sht);
|
||||
void close_constask(struct TASK *task);
|
||||
|
||||
void HariMain(void)
|
||||
{
|
||||
struct BOOTINFO *binfo = (struct BOOTINFO *) ADR_BOOTINFO;
|
||||
struct SHTCTL *shtctl;
|
||||
char s[40];
|
||||
struct FIFO32 fifo, keycmd;
|
||||
int fifobuf[128], keycmd_buf[32];
|
||||
int mx, my, i, new_mx = -1, new_my = 0, new_wx = 0x7fffffff, new_wy = 0;
|
||||
unsigned int memtotal;
|
||||
struct MOUSE_DEC mdec;
|
||||
struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR;
|
||||
unsigned char *buf_back, buf_mouse[256];
|
||||
struct SHEET *sht_back, *sht_mouse;
|
||||
struct TASK *task_a, *task;
|
||||
static char keytable0[0x80] = {
|
||||
0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '^', 0x08, 0,
|
||||
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '@', '[', 0x0a, 0, 'A', 'S',
|
||||
'D', 'F', 'G', 'H', 'J', 'K', 'L', ';', ':', 0, 0, ']', 'Z', 'X', 'C', 'V',
|
||||
'B', 'N', 'M', ',', '.', '/', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, '7', '8', '9', '-', '4', '5', '6', '+', '1',
|
||||
'2', '3', '0', '.', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0x5c, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x5c, 0, 0
|
||||
};
|
||||
static char keytable1[0x80] = {
|
||||
0, 0, '!', 0x22, '#', '$', '%', '&', 0x27, '(', ')', '~', '=', '~', 0x08, 0,
|
||||
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '`', '{', 0x0a, 0, 'A', 'S',
|
||||
'D', 'F', 'G', 'H', 'J', 'K', 'L', '+', '*', 0, 0, '}', 'Z', 'X', 'C', 'V',
|
||||
'B', 'N', 'M', '<', '>', '?', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, '7', '8', '9', '-', '4', '5', '6', '+', '1',
|
||||
'2', '3', '0', '.', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, '_', 0, 0, 0, 0, 0, 0, 0, 0, 0, '|', 0, 0
|
||||
};
|
||||
int key_shift = 0, key_leds = (binfo->leds >> 4) & 7, keycmd_wait = -1;
|
||||
int j, x, y, mmx = -1, mmy = -1, mmx2 = 0;
|
||||
struct SHEET *sht = 0, *key_win;
|
||||
|
||||
init_gdtidt();
|
||||
init_pic();
|
||||
io_sti(); /* IDT/PIC的初始化已经完成,于是开放CPU的中断 */
|
||||
fifo32_init(&fifo, 128, fifobuf, 0);
|
||||
*((int *) 0x0fec) = (int) &fifo;
|
||||
init_pit();
|
||||
init_keyboard(&fifo, 256);
|
||||
enable_mouse(&fifo, 512, &mdec);
|
||||
io_out8(PIC0_IMR, 0xf8); /* 设定PIT和PIC1以及键盘为许可(11111000) */
|
||||
io_out8(PIC1_IMR, 0xef); /* 开放鼠标中断(11101111) */
|
||||
fifo32_init(&keycmd, 32, keycmd_buf, 0);
|
||||
|
||||
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);
|
||||
task_a = task_init(memman);
|
||||
fifo.task = task_a;
|
||||
task_run(task_a, 1, 2);
|
||||
*((int *) 0x0fe4) = (int) shtctl;
|
||||
|
||||
/* sht_back */
|
||||
sht_back = 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); /* 无透明色 */
|
||||
init_screen8(buf_back, binfo->scrnx, binfo->scrny);
|
||||
|
||||
/* sht_cons */
|
||||
key_win = open_console(shtctl, memtotal);
|
||||
|
||||
/* sht_mouse */
|
||||
sht_mouse = sheet_alloc(shtctl);
|
||||
sheet_setbuf(sht_mouse, buf_mouse, 16, 16, 99);
|
||||
init_mouse_cursor8(buf_mouse, 99);
|
||||
mx = (binfo->scrnx - 16) / 2; /* 计算坐标使其位于画面中央 */
|
||||
my = (binfo->scrny - 28 - 16) / 2;
|
||||
|
||||
sheet_slide(sht_back, 0, 0);
|
||||
sheet_slide(key_win, 32, 4);
|
||||
sheet_slide(sht_mouse, mx, my);
|
||||
sheet_updown(sht_back, 0);
|
||||
sheet_updown(key_win, 1);
|
||||
sheet_updown(sht_mouse, 2);
|
||||
keywin_on(key_win);
|
||||
|
||||
/*为了避免和键盘当前状态冲突,在一开始先进行设置*/
|
||||
fifo32_put(&keycmd, KEYCMD_LED);
|
||||
fifo32_put(&keycmd, key_leds);
|
||||
|
||||
for (;;) {
|
||||
if (fifo32_status(&keycmd) > 0 && keycmd_wait < 0) {
|
||||
/* 如果存在向键盘控制器发送的数据,则发送它 */
|
||||
keycmd_wait = fifo32_get(&keycmd);
|
||||
wait_KBC_sendready();
|
||||
io_out8(PORT_KEYDAT, keycmd_wait);
|
||||
}
|
||||
io_cli();
|
||||
if (fifo32_status(&fifo) == 0) {
|
||||
/* FIFO为空,当存在搁置的绘图操作时立即执行*/
|
||||
if (new_mx >= 0) {
|
||||
io_sti();
|
||||
sheet_slide(sht_mouse, new_mx, new_my);
|
||||
new_mx = -1;
|
||||
} else if (new_wx != 0x7fffffff) {
|
||||
io_sti();
|
||||
sheet_slide(sht, new_wx, new_wy);
|
||||
new_wx = 0x7fffffff;
|
||||
} else {
|
||||
task_sleep(task_a);
|
||||
io_sti();
|
||||
}
|
||||
} else {
|
||||
i = fifo32_get(&fifo);
|
||||
io_sti();
|
||||
if (key_win != 0 && key_win->flags == 0) { /*窗口被关闭*/
|
||||
if (shtctl->top == 1) { /*当画面上只剩鼠标和背景时*/
|
||||
key_win = 0;
|
||||
} else {
|
||||
key_win = shtctl->sheets[shtctl->top - 1];
|
||||
keywin_on(key_win);
|
||||
}
|
||||
}
|
||||
if (256 <= i && i <= 511) { /* 键盘数据*/
|
||||
if (i < 0x80 + 256) { /*将按键编码转换为字符编码*/
|
||||
if (key_shift == 0) {
|
||||
s[0] = keytable0[i - 256];
|
||||
} else {
|
||||
s[0] = keytable1[i - 256];
|
||||
}
|
||||
} else {
|
||||
s[0] = 0;
|
||||
}
|
||||
if ('A' <= s[0] && s[0] <= 'Z') { /*当输入字符为英文字母时*/
|
||||
if (((key_leds & 4) == 0 && key_shift == 0) ||
|
||||
((key_leds & 4) != 0 && key_shift != 0)) {
|
||||
s[0] += 0x20; /*将大写字母转换为小写字母*/
|
||||
}
|
||||
}
|
||||
if (s[0] != 0 && key_win != 0) { /*一般字符、退格键、回车键*/
|
||||
fifo32_put(&key_win->task->fifo, s[0] + 256);
|
||||
}
|
||||
if (i == 256 + 0x0f && key_win != 0) { /* Tab键 */
|
||||
keywin_off(key_win);
|
||||
j = key_win->height - 1;
|
||||
if (j == 0) {
|
||||
j = shtctl->top - 1;
|
||||
}
|
||||
key_win = shtctl->sheets[j];
|
||||
keywin_on(key_win);
|
||||
}
|
||||
if (i == 256 + 0x2a) { /*左Shift ON */
|
||||
key_shift |= 1;
|
||||
}
|
||||
if (i == 256 + 0x36) { /*右Shift ON */
|
||||
key_shift |= 2;
|
||||
}
|
||||
if (i == 256 + 0xaa) { /*左Shift OFF */
|
||||
key_shift &= ~1;
|
||||
}
|
||||
if (i == 256 + 0xb6) { /*右Shift OFF */
|
||||
key_shift &= ~2;
|
||||
}
|
||||
if (i == 256 + 0x3a) { /* CapsLock */
|
||||
key_leds ^= 4;
|
||||
fifo32_put(&keycmd, KEYCMD_LED);
|
||||
fifo32_put(&keycmd, key_leds);
|
||||
}
|
||||
if (i == 256 + 0x45) { /* NumLock */
|
||||
key_leds ^= 2;
|
||||
fifo32_put(&keycmd, KEYCMD_LED);
|
||||
fifo32_put(&keycmd, key_leds);
|
||||
}
|
||||
if (i == 256 + 0x46) { /* ScrollLock */
|
||||
key_leds ^= 1;
|
||||
fifo32_put(&keycmd, KEYCMD_LED);
|
||||
fifo32_put(&keycmd, key_leds);
|
||||
}
|
||||
if (i == 256 + 0x3b && key_shift != 0 && key_win != 0) { /* Shift+F1 */
|
||||
task = key_win->task;
|
||||
if (task != 0 && task->tss.ss0 != 0) {
|
||||
cons_putstr0(task->cons, "\nBreak(key) :\n");
|
||||
io_cli(); /*强制结束处理时禁止任务切换*/
|
||||
task->tss.eax = (int) &(task->tss.esp0);
|
||||
task->tss.eip = (int) asm_end_app;
|
||||
io_sti();
|
||||
}
|
||||
}
|
||||
if (i == 256 + 0x3c && key_shift != 0) { /* Shift+F2 */
|
||||
if (key_win != 0) {
|
||||
keywin_off(key_win);
|
||||
}
|
||||
key_win = open_console(shtctl, memtotal);
|
||||
sheet_slide(key_win, 32, 4);
|
||||
sheet_updown(key_win, shtctl->top);
|
||||
keywin_on(key_win);
|
||||
}
|
||||
if (i == 256 + 0x57) { /* F11 */
|
||||
sheet_updown(shtctl->sheets[1], shtctl->top - 1);
|
||||
}
|
||||
if (i == 256 + 0xfa) { /*键盘成功接收到数据*/
|
||||
keycmd_wait = -1;
|
||||
}
|
||||
if (i == 256 + 0xfe) { /*键盘没有成功接收到数据*/
|
||||
wait_KBC_sendready();
|
||||
io_out8(PORT_KEYDAT, keycmd_wait);
|
||||
}
|
||||
} else if (512 <= i && i <= 767) { /* 鼠标数据*/
|
||||
if (mouse_decode(&mdec, i - 512) != 0) {
|
||||
/* 已经收集了3字节的数据,移动光标 */
|
||||
mx += mdec.x;
|
||||
my += mdec.y;
|
||||
if (mx < 0) {
|
||||
mx = 0;
|
||||
}
|
||||
if (my < 0) {
|
||||
my = 0;
|
||||
}
|
||||
if (mx > binfo->scrnx - 1) {
|
||||
mx = binfo->scrnx - 1;
|
||||
}
|
||||
if (my > binfo->scrny - 1) {
|
||||
my = binfo->scrny - 1;
|
||||
}
|
||||
new_mx = mx;
|
||||
new_my = my;
|
||||
if ((mdec.btn & 0x01) != 0) { /* 按下左键 */
|
||||
if (mmx < 0) {
|
||||
/*如果处于通常模式*/
|
||||
/*按照从上到下的顺序寻找鼠标所指向的图层*/
|
||||
for (j = shtctl->top - 1; j > 0; j--) {
|
||||
sht = shtctl->sheets[j];
|
||||
x = mx - sht->vx0;
|
||||
y = my - sht->vy0;
|
||||
if (0 <= x && x < sht->bxsize && 0 <= y && y < sht->bysize) {
|
||||
if (sht->buf[y * sht->bxsize + x] != sht->col_inv) {
|
||||
sheet_updown(sht, shtctl->top - 1);
|
||||
if (sht != key_win) {
|
||||
keywin_off(key_win);
|
||||
key_win = sht;
|
||||
keywin_on(key_win);
|
||||
}
|
||||
if (3 <= x && x < sht->bxsize - 3 && 3 <= y && y < 21) {
|
||||
mmx = mx; /*进入窗口移动模式*/
|
||||
mmy = my;
|
||||
mmx2 = sht->vx0;
|
||||
new_wy = sht->vy0;
|
||||
}
|
||||
if (sht->bxsize - 21 <= x && x < sht->bxsize - 5 && 5 <= y && y < 19) {
|
||||
/*点击“×”按钮*/
|
||||
if ((sht->flags & 0x10) != 0) { /*该窗口是否为应用程序窗口?*/
|
||||
task = sht->task;
|
||||
cons_putstr0(task->cons, "\nBreak(mouse) :\n");
|
||||
io_cli(); /*强制结束处理时禁止任务切换*/
|
||||
task->tss.eax = (int) &(task->tss.esp0);
|
||||
task->tss.eip = (int) asm_end_app;
|
||||
io_sti();
|
||||
} else { /*命令行窗口*/
|
||||
task = sht->task;
|
||||
io_cli();
|
||||
fifo32_put(&task->fifo, 4);
|
||||
io_sti();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/*如果处于窗口移动模式*/
|
||||
x = mx - mmx; /*计算鼠标指针移动量*/
|
||||
y = my - mmy;
|
||||
new_wx = (mmx2 + x + 2) & ~3;
|
||||
new_wy = new_wy + y;
|
||||
mmy = my;
|
||||
}
|
||||
} else {
|
||||
/*没有按下左键*/
|
||||
mmx = -1; /*切换到一般模式*/
|
||||
if (new_wx != 0x7fffffff) {
|
||||
sheet_slide(sht, new_wx, new_wy); /*固定图层位置*/
|
||||
new_wx = 0x7fffffff;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (768 <= i && i <= 1023) { /*命令行窗口关闭处理*/
|
||||
close_console(shtctl->sheets0 + (i - 768));
|
||||
} else if (1024 <= i && i <= 2023) {
|
||||
close_constask(taskctl->tasks0 + (i - 1024));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void keywin_off(struct SHEET *key_win)
|
||||
{
|
||||
change_wtitle8(key_win, 0);
|
||||
if ((key_win->flags & 0x20) != 0) {
|
||||
fifo32_put(&key_win->task->fifo, 3); /*命令行窗口光标OFF */
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void keywin_on(struct SHEET *key_win)
|
||||
{
|
||||
change_wtitle8(key_win, 1);
|
||||
if ((key_win->flags & 0x20) != 0) {
|
||||
fifo32_put(&key_win->task->fifo, 2); /*命令行窗口光标ON */
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
struct TASK *open_constask(struct SHEET *sht, unsigned int memtotal)
|
||||
{
|
||||
struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR;
|
||||
struct TASK *task = task_alloc();
|
||||
int *cons_fifo = (int *) memman_alloc_4k(memman, 128 * 4);
|
||||
task->cons_stack = memman_alloc_4k(memman, 64 * 1024);
|
||||
task->tss.esp = task->cons_stack + 64 * 1024 - 12;
|
||||
task->tss.eip = (int) &console_task;
|
||||
task->tss.es = 1 * 8;
|
||||
task->tss.cs = 2 * 8;
|
||||
task->tss.ss = 1 * 8;
|
||||
task->tss.ds = 1 * 8;
|
||||
task->tss.fs = 1 * 8;
|
||||
task->tss.gs = 1 * 8;
|
||||
*((int *) (task->tss.esp + 4)) = (int) sht;
|
||||
*((int *) (task->tss.esp + 8)) = memtotal;
|
||||
task_run(task, 2, 2); /* level=2, priority=2 */
|
||||
fifo32_init(&task->fifo, 128, cons_fifo, task);
|
||||
return task;
|
||||
}
|
||||
|
||||
struct SHEET *open_console(struct SHTCTL *shtctl, unsigned int memtotal)
|
||||
{
|
||||
struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR;
|
||||
struct SHEET *sht = sheet_alloc(shtctl);
|
||||
unsigned char *buf = (unsigned char *) memman_alloc_4k(memman, 256 * 165);
|
||||
sheet_setbuf(sht, buf, 256, 165, -1); /*无透明色*/
|
||||
make_window8(buf, 256, 165, "console", 0);
|
||||
make_textbox8(sht, 8, 28, 240, 128, COL8_000000);
|
||||
sht->task = open_constask(sht, memtotal);
|
||||
sht->flags |= 0x20; /*有光标*/
|
||||
return sht;
|
||||
}
|
||||
|
||||
void close_constask(struct TASK *task)
|
||||
{
|
||||
struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR;
|
||||
task_sleep(task);
|
||||
memman_free_4k(memman, task->cons_stack, 64 * 1024);
|
||||
memman_free_4k(memman, (int) task->fifo.buf, 128 * 4);
|
||||
task->flags = 0; /*用来替代task_free(task); */
|
||||
return;
|
||||
}
|
||||
|
||||
void close_console(struct SHEET *sht)
|
||||
{
|
||||
struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR;
|
||||
struct TASK *task = sht->task;
|
||||
memman_free_4k(memman, (int) sht->buf, 256 * 165);
|
||||
sheet_free(sht);
|
||||
close_constask(task);
|
||||
return;
|
||||
}
|
||||
281
26_day/bootpack.h
Normal file
281
26_day/bootpack.h
Normal file
@@ -0,0 +1,281 @@
|
||||
/* asmhead.nas */
|
||||
struct BOOTINFO { /* 0x0ff0-0x0fff */
|
||||
char cyls; /* 启动区读磁盘读到此为止 */
|
||||
char leds; /* 启动时键盘的LED的状态 */
|
||||
char vmode; /* 显卡模式为多少位彩色 */
|
||||
char reserve;
|
||||
short scrnx, scrny; /* 画面分辨率 */
|
||||
char *vram;
|
||||
};
|
||||
#define ADR_BOOTINFO 0x00000ff0
|
||||
#define ADR_DISKIMG 0x00100000
|
||||
|
||||
/* 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 load_tr(int tr);
|
||||
void asm_inthandler0c(void);
|
||||
void asm_inthandler0d(void);
|
||||
void asm_inthandler20(void);
|
||||
void asm_inthandler21(void);
|
||||
void asm_inthandler2c(void);
|
||||
unsigned int memtest_sub(unsigned int start, unsigned int end);
|
||||
void farjmp(int eip, int cs);
|
||||
void farcall(int eip, int cs);
|
||||
void asm_hrb_api(void);
|
||||
void start_app(int eip, int cs, int esp, int ds, int *tss_esp0);
|
||||
void asm_end_app(void);
|
||||
|
||||
/* fifo.c */
|
||||
struct FIFO32 {
|
||||
int *buf;
|
||||
int p, q, size, free, flags;
|
||||
struct TASK *task;
|
||||
};
|
||||
void fifo32_init(struct FIFO32 *fifo, int size, int *buf, struct TASK *task);
|
||||
int fifo32_put(struct FIFO32 *fifo, int data);
|
||||
int fifo32_get(struct FIFO32 *fifo);
|
||||
int fifo32_status(struct FIFO32 *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_TSS32 0x0089
|
||||
#define AR_INTGATE32 0x008e
|
||||
|
||||
/* int.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
|
||||
|
||||
/* keyboard.c */
|
||||
void inthandler21(int *esp);
|
||||
void wait_KBC_sendready(void);
|
||||
void init_keyboard(struct FIFO32 *fifo, int data0);
|
||||
#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 FIFO32 *fifo, int data0, struct MOUSE_DEC *mdec);
|
||||
int mouse_decode(struct MOUSE_DEC *mdec, unsigned char dat);
|
||||
|
||||
/* memory.c */
|
||||
#define MEMMAN_FREES 4090 /* <20><><EFBFBD><EFBFBD>Ŗ<EFBFBD>32KB */
|
||||
#define MEMMAN_ADDR 0x003c0000
|
||||
struct FREEINFO { /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
||||
unsigned int addr, size;
|
||||
};
|
||||
struct MEMMAN { /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǘ<EFBFBD> */
|
||||
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 *ctl;
|
||||
struct TASK *task;
|
||||
};
|
||||
struct SHTCTL {
|
||||
unsigned char *vram, *map;
|
||||
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 SHEET *sht, int height);
|
||||
void sheet_refresh(struct SHEET *sht, int bx0, int by0, int bx1, int by1);
|
||||
void sheet_slide(struct SHEET *sht, int vx0, int vy0);
|
||||
void sheet_free(struct SHEET *sht);
|
||||
|
||||
/* timer.c */
|
||||
#define MAX_TIMER 500
|
||||
struct TIMER {
|
||||
struct TIMER *next;
|
||||
unsigned int timeout;
|
||||
char flags, flags2;
|
||||
struct FIFO32 *fifo;
|
||||
int data;
|
||||
};
|
||||
struct TIMERCTL {
|
||||
unsigned int count, next;
|
||||
struct TIMER *t0;
|
||||
struct TIMER timers0[MAX_TIMER];
|
||||
};
|
||||
extern struct TIMERCTL timerctl;
|
||||
void init_pit(void);
|
||||
struct TIMER *timer_alloc(void);
|
||||
void timer_free(struct TIMER *timer);
|
||||
void timer_init(struct TIMER *timer, struct FIFO32 *fifo, int data);
|
||||
void timer_settime(struct TIMER *timer, unsigned int timeout);
|
||||
void inthandler20(int *esp);
|
||||
int timer_cancel(struct TIMER *timer);
|
||||
void timer_cancelall(struct FIFO32 *fifo);
|
||||
|
||||
/* mtask.c */
|
||||
#define MAX_TASKS 1000 /*最大任务数量*/
|
||||
#define TASK_GDT0 3 /*定义从GDT的几号开始分配给TSS */
|
||||
#define MAX_TASKS_LV 100
|
||||
#define MAX_TASKLEVELS 10
|
||||
struct TSS32 {
|
||||
int backlink, esp0, ss0, esp1, ss1, esp2, ss2, cr3;
|
||||
int eip, eflags, eax, ecx, edx, ebx, esp, ebp, esi, edi;
|
||||
int es, cs, ss, ds, fs, gs;
|
||||
int ldtr, iomap;
|
||||
};
|
||||
struct TASK {
|
||||
int sel, flags; /* sel用来存放GDT的编号*/
|
||||
int level, priority; /* 优先级 */
|
||||
struct FIFO32 fifo;
|
||||
struct TSS32 tss;
|
||||
struct CONSOLE *cons;
|
||||
int ds_base, cons_stack;
|
||||
};
|
||||
struct TASKLEVEL {
|
||||
int running; /*正在运行的任务数量*/
|
||||
int now; /*这个变量用来记录当前正在运行的是哪个任务*/
|
||||
struct TASK *tasks[MAX_TASKS_LV];
|
||||
};
|
||||
struct TASKCTL {
|
||||
int now_lv; /*现在活动中的LEVEL */
|
||||
char lv_change; /*在下次任务切换时是否需要改变LEVEL */
|
||||
struct TASKLEVEL level[MAX_TASKLEVELS];
|
||||
struct TASK tasks0[MAX_TASKS];
|
||||
};
|
||||
extern struct TASKCTL *taskctl;
|
||||
extern struct TIMER *task_timer;
|
||||
struct TASK *task_now(void);
|
||||
struct TASK *task_init(struct MEMMAN *memman);
|
||||
struct TASK *task_alloc(void);
|
||||
void task_run(struct TASK *task, int level, int priority);
|
||||
void task_switch(void);
|
||||
void task_sleep(struct TASK *task);
|
||||
|
||||
/* window.c */
|
||||
void make_window8(unsigned char *buf, int xsize, int ysize, char *title, char act);
|
||||
void putfonts8_asc_sht(struct SHEET *sht, int x, int y, int c, int b, char *s, int l);
|
||||
void make_textbox8(struct SHEET *sht, int x0, int y0, int sx, int sy, int c);
|
||||
void make_wtitle8(unsigned char *buf, int xsize, char *title, char act);
|
||||
void change_wtitle8(struct SHEET *sht, char act);
|
||||
|
||||
/* console.c */
|
||||
struct CONSOLE {
|
||||
struct SHEET *sht;
|
||||
int cur_x, cur_y, cur_c;
|
||||
struct TIMER *timer;
|
||||
};
|
||||
void console_task(struct SHEET *sheet, int memtotal);
|
||||
void cons_putchar(struct CONSOLE *cons, int chr, char move);
|
||||
void cons_newline(struct CONSOLE *cons);
|
||||
void cons_putstr0(struct CONSOLE *cons, char *s);
|
||||
void cons_putstr1(struct CONSOLE *cons, char *s, int l);
|
||||
void cons_runcmd(char *cmdline, struct CONSOLE *cons, int *fat, int memtotal);
|
||||
void cmd_mem(struct CONSOLE *cons, int memtotal);
|
||||
void cmd_cls(struct CONSOLE *cons);
|
||||
void cmd_dir(struct CONSOLE *cons);
|
||||
void cmd_type(struct CONSOLE *cons, int *fat, char *cmdline);
|
||||
void cmd_exit(struct CONSOLE *cons, int *fat);
|
||||
void cmd_start(struct CONSOLE *cons, char *cmdline, int memtotal);
|
||||
void cmd_ncst(struct CONSOLE *cons, char *cmdline, int memtotal);
|
||||
int cmd_app(struct CONSOLE *cons, int *fat, char *cmdline);
|
||||
int *hrb_api(int edi, int esi, int ebp, int esp, int ebx, int edx, int ecx, int eax);
|
||||
int *inthandler0d(int *esp);
|
||||
int *inthandler0c(int *esp);
|
||||
void hrb_api_linewin(struct SHEET *sht, int x0, int y0, int x1, int y1, int col);
|
||||
|
||||
/* file.c */
|
||||
struct FILEINFO {
|
||||
unsigned char name[8], ext[3], type;
|
||||
char reserve[10];
|
||||
unsigned short time, date, clustno;
|
||||
unsigned int size;
|
||||
};
|
||||
void file_readfat(int *fat, unsigned char *img);
|
||||
void file_loadfile(int clustno, int size, char *buf, int *fat, char *img);
|
||||
struct FILEINFO *file_search(char *name, struct FILEINFO *finfo, int max);
|
||||
|
||||
/* bootpack.c */
|
||||
struct TASK *open_constask(struct SHEET *sht, unsigned int memtotal);
|
||||
struct SHEET *open_console(struct SHTCTL *shtctl, unsigned int memtotal);
|
||||
27
26_day/color.c
Normal file
27
26_day/color.c
Normal file
@@ -0,0 +1,27 @@
|
||||
int api_openwin(char *buf, int xsiz, int ysiz, int col_inv, char *title);
|
||||
void api_initmalloc(void);
|
||||
char *api_malloc(int size);
|
||||
void api_refreshwin(int win, int x0, int y0, int x1, int y1);
|
||||
void api_linewin(int win, int x0, int y0, int x1, int y1, int col);
|
||||
int api_getkey(int mode);
|
||||
void api_end(void);
|
||||
|
||||
void HariMain(void)
|
||||
{
|
||||
char *buf;
|
||||
int win, x, y, r, g, b;
|
||||
api_initmalloc();
|
||||
buf = api_malloc(144 * 164);
|
||||
win = api_openwin(buf, 144, 164, -1, "color");
|
||||
for (y = 0; y < 128; y++) {
|
||||
for (x = 0; x < 128; x++) {
|
||||
r = x * 2;
|
||||
g = y * 2;
|
||||
b = 0;
|
||||
buf[(x + 8) + (y + 28) * 144] = 16 + (r / 43) + (g / 43) * 6 + (b / 43) * 36;
|
||||
}
|
||||
}
|
||||
api_refreshwin(win, 8, 28, 136, 156);
|
||||
api_getkey(1); /*等待按下任意键*/
|
||||
api_end();
|
||||
}
|
||||
42
26_day/color2.c
Normal file
42
26_day/color2.c
Normal file
@@ -0,0 +1,42 @@
|
||||
int api_openwin(char *buf, int xsiz, int ysiz, int col_inv, char *title);
|
||||
void api_initmalloc(void);
|
||||
char *api_malloc(int size);
|
||||
void api_refreshwin(int win, int x0, int y0, int x1, int y1);
|
||||
void api_linewin(int win, int x0, int y0, int x1, int y1, int col);
|
||||
int api_getkey(int mode);
|
||||
void api_end(void);
|
||||
|
||||
unsigned char rgb2pal(int r, int g, int b, int x, int y);
|
||||
|
||||
void HariMain(void)
|
||||
{
|
||||
char *buf;
|
||||
int win, x, y;
|
||||
api_initmalloc();
|
||||
buf = api_malloc(144 * 164);
|
||||
win = api_openwin(buf, 144, 164, -1, "color2");
|
||||
for (y = 0; y < 128; y++) {
|
||||
for (x = 0; x < 128; x++) {
|
||||
buf[(x + 8) + (y + 28) * 144] = rgb2pal(x * 2, y * 2, 0, x, y);
|
||||
}
|
||||
}
|
||||
api_refreshwin(win, 8, 28, 136, 156);
|
||||
api_getkey(1); /*等待按下任意键*/
|
||||
api_end();
|
||||
}
|
||||
|
||||
unsigned char rgb2pal(int r, int g, int b, int x, int y)
|
||||
{
|
||||
static int table[4] = { 3, 1, 0, 2 };
|
||||
int i;
|
||||
x &= 1; /*判断是偶数还是奇数*/
|
||||
y &= 1;
|
||||
i = table[x + y * 2]; /*用来生成中间色的常量*/
|
||||
r = (r * 21) / 256; /* r为0~20*/
|
||||
g = (g * 21) / 256;
|
||||
b = (b * 21) / 256;
|
||||
r = (r + i) / 4; /* r为0~5*/
|
||||
g = (g + i) / 4;
|
||||
b = (b + i) / 4;
|
||||
return 16 + r + g * 6 + b * 36;
|
||||
}
|
||||
592
26_day/console.c
Normal file
592
26_day/console.c
Normal file
@@ -0,0 +1,592 @@
|
||||
/* 命令行窗口相关 */
|
||||
|
||||
#include "bootpack.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
void console_task(struct SHEET *sheet, int memtotal)
|
||||
{
|
||||
struct TASK *task = task_now();
|
||||
struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR;
|
||||
int i, *fat = (int *) memman_alloc_4k(memman, 4 * 2880);
|
||||
struct CONSOLE cons;
|
||||
char cmdline[30];
|
||||
cons.sht = sheet;
|
||||
cons.cur_x = 8;
|
||||
cons.cur_y = 28;
|
||||
cons.cur_c = -1;
|
||||
task->cons = &cons;
|
||||
|
||||
if (sheet != 0) {
|
||||
cons.timer = timer_alloc();
|
||||
timer_init(cons.timer, &task->fifo, 1);
|
||||
timer_settime(cons.timer, 50);
|
||||
}
|
||||
file_readfat(fat, (unsigned char *) (ADR_DISKIMG + 0x000200));
|
||||
|
||||
/*显示提示符*/
|
||||
cons_putchar(&cons, '>', 1);
|
||||
|
||||
for (;;) {
|
||||
io_cli();
|
||||
if (fifo32_status(&task->fifo) == 0) {
|
||||
task_sleep(task);
|
||||
io_sti();
|
||||
} else {
|
||||
i = fifo32_get(&task->fifo);
|
||||
io_sti();
|
||||
if (i <= 1) { /*光标用定时器*/
|
||||
if (i != 0) {
|
||||
timer_init(cons.timer, &task->fifo, 0); /*下次置0 */
|
||||
if (cons.cur_c >= 0) {
|
||||
cons.cur_c = COL8_FFFFFF;
|
||||
}
|
||||
} else {
|
||||
timer_init(cons.timer, &task->fifo, 1); /*下次置1 */
|
||||
if (cons.cur_c >= 0) {
|
||||
cons.cur_c = COL8_000000;
|
||||
}
|
||||
}
|
||||
timer_settime(cons.timer, 50);
|
||||
}
|
||||
if (i == 2) { /*光标ON */
|
||||
cons.cur_c = COL8_FFFFFF;
|
||||
}
|
||||
if (i == 3) { /*光标OFF */
|
||||
boxfill8(sheet->buf, sheet->bxsize, COL8_000000, cons.cur_x, cons.cur_y, cons.cur_x + 7, cons.cur_y + 15);
|
||||
cons.cur_c = -1;
|
||||
}
|
||||
if (i == 4) { /*点击命令行窗口的“×”按钮*/
|
||||
cmd_exit(&cons, fat);
|
||||
}
|
||||
if (256 <= i && i <= 511) { /*键盘数据(通过任务A)*/
|
||||
if (i == 8 + 256) {
|
||||
/*退格键*/
|
||||
if (cons.cur_x > 16) {
|
||||
/*用空格擦除光标后将光标前移一位*/
|
||||
cons_putchar(&cons, ' ', 0);
|
||||
cons.cur_x -= 8;
|
||||
}
|
||||
} else if (i == 10 + 256) {
|
||||
/*回车键*/
|
||||
/*将光标用空格擦除后换行 */
|
||||
cons_putchar(&cons, ' ', 0);
|
||||
cmdline[cons.cur_x / 8 - 2] = 0;
|
||||
cons_newline(&cons);
|
||||
cons_runcmd(cmdline, &cons, fat, memtotal); /*运行命令*/
|
||||
if (sheet == 0) {
|
||||
cmd_exit(&cons, fat);
|
||||
}
|
||||
/*显示提示符*/
|
||||
cons_putchar(&cons, '>', 1);
|
||||
} else {
|
||||
/*一般字符*/
|
||||
if (cons.cur_x < 240) {
|
||||
/*显示一个字符之后将光标后移一位*/
|
||||
cmdline[cons.cur_x / 8 - 2] = i - 256;
|
||||
cons_putchar(&cons, i - 256, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*重新显示光标*/
|
||||
if (sheet != 0) {
|
||||
if (cons.cur_c >= 0) {
|
||||
boxfill8(sheet->buf, sheet->bxsize, cons.cur_c, cons.cur_x, cons.cur_y, cons.cur_x + 7, cons.cur_y + 15);
|
||||
}
|
||||
sheet_refresh(sheet, cons.cur_x, cons.cur_y, cons.cur_x + 8, cons.cur_y + 16);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cons_putchar(struct CONSOLE *cons, int chr, char move)
|
||||
{
|
||||
char s[2];
|
||||
s[0] = chr;
|
||||
s[1] = 0;
|
||||
if (s[0] == 0x09) { /*制表符*/
|
||||
for (;;) {
|
||||
if (cons->sht != 0) {
|
||||
putfonts8_asc_sht(cons->sht, cons->cur_x, cons->cur_y, COL8_FFFFFF, COL8_000000, " ", 1);
|
||||
cons->cur_x += 8;
|
||||
}
|
||||
if (cons->cur_x == 8 + 240) {
|
||||
cons_newline(cons);
|
||||
}
|
||||
if (((cons->cur_x - 8) & 0x1f) == 0) {
|
||||
break; /*被32整除则break*/
|
||||
}
|
||||
}
|
||||
} else if (s[0] == 0x0a) { /*换行*/
|
||||
cons_newline(cons);
|
||||
} else if (s[0] == 0x0d) { /*回车*/
|
||||
/*先不做任何操作*/
|
||||
} else { /*一般字符*/
|
||||
if (cons->sht != 0) {
|
||||
putfonts8_asc_sht(cons->sht, cons->cur_x, cons->cur_y, COL8_FFFFFF, COL8_000000, s, 1);
|
||||
}
|
||||
if (move != 0) {
|
||||
/* move为0时光标不后移*/
|
||||
cons->cur_x += 8;
|
||||
if (cons->cur_x == 8 + 240) {
|
||||
cons_newline(cons);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void cons_newline(struct CONSOLE *cons)
|
||||
{
|
||||
int x, y;
|
||||
struct SHEET *sheet = cons->sht;
|
||||
if (cons->cur_y < 28 + 112) {
|
||||
cons->cur_y += 16; /*到下一行*/
|
||||
} else {
|
||||
/*滚动*/
|
||||
if (sheet != 0) {
|
||||
for (y = 28; y < 28 + 112; y++) {
|
||||
for (x = 8; x < 8 + 240; x++) {
|
||||
sheet->buf[x + y * sheet->bxsize] = sheet->buf[x + (y + 16) * sheet->bxsize];
|
||||
}
|
||||
}
|
||||
for (y = 28 + 112; y < 28 + 128; y++) {
|
||||
for (x = 8; x < 8 + 240; x++) {
|
||||
sheet->buf[x + y * sheet->bxsize] = COL8_000000;
|
||||
}
|
||||
}
|
||||
sheet_refresh(sheet, 8, 28, 8 + 240, 28 + 128);
|
||||
}
|
||||
}
|
||||
cons->cur_x = 8;
|
||||
return;
|
||||
}
|
||||
|
||||
void cons_putstr0(struct CONSOLE *cons, char *s)
|
||||
{
|
||||
for (; *s != 0; s++) {
|
||||
cons_putchar(cons, *s, 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void cons_putstr1(struct CONSOLE *cons, char *s, int l)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < l; i++) {
|
||||
cons_putchar(cons, s[i], 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void cons_runcmd(char *cmdline, struct CONSOLE *cons, int *fat, int memtotal)
|
||||
{
|
||||
if (strcmp(cmdline, "mem") == 0 && cons->sht != 0) {
|
||||
cmd_mem(cons, memtotal);
|
||||
} else if (strcmp(cmdline, "cls") == 0 && cons->sht != 0) {
|
||||
cmd_cls(cons);
|
||||
} else if ((strcmp(cmdline, "dir") == 0 || strcmp(cmdline, "ls") == 0) && cons->sht != 0) {
|
||||
cmd_dir(cons);
|
||||
} else if (strncmp(cmdline, "type ", 5) == 0 && cons->sht != 0) {
|
||||
cmd_type(cons, fat, cmdline);
|
||||
} else if (strcmp(cmdline, "exit") == 0) {
|
||||
cmd_exit(cons, fat);
|
||||
} else if (strncmp(cmdline, "start ", 6) == 0) {
|
||||
cmd_start(cons, cmdline, memtotal);
|
||||
} else if (strncmp(cmdline, "ncst ", 5) == 0) {
|
||||
cmd_ncst(cons, cmdline, memtotal);
|
||||
}else if (cmdline[0] != 0) {
|
||||
if (cmd_app(cons, fat, cmdline) == 0) {
|
||||
/*不是命令,不是应用程序,也不是空行*/
|
||||
cons_putstr0(cons, "Bad command.\n\n");
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void cmd_mem(struct CONSOLE *cons, int memtotal)
|
||||
{
|
||||
struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR;
|
||||
char s[60];
|
||||
sprintf(s, "total %dMB\nfree %dKB\n\n", memtotal / (1024 * 1024), memman_total(memman) / 1024);
|
||||
cons_putstr0(cons, s);
|
||||
return;
|
||||
}
|
||||
|
||||
void cmd_cls(struct CONSOLE *cons)
|
||||
{
|
||||
int x, y;
|
||||
struct SHEET *sheet = cons->sht;
|
||||
for (y = 28; y < 28 + 128; y++) {
|
||||
for (x = 8; x < 8 + 240; x++) {
|
||||
sheet->buf[x + y * sheet->bxsize] = COL8_000000;
|
||||
}
|
||||
}
|
||||
sheet_refresh(sheet, 8, 28, 8 + 240, 28 + 128);
|
||||
cons->cur_y = 28;
|
||||
return;
|
||||
}
|
||||
|
||||
void cmd_dir(struct CONSOLE *cons)
|
||||
{
|
||||
struct FILEINFO *finfo = (struct FILEINFO *) (ADR_DISKIMG + 0x002600);
|
||||
int i, j;
|
||||
char s[30];
|
||||
for (i = 0; i < 224; i++) {
|
||||
if (finfo[i].name[0] == 0x00) {
|
||||
break;
|
||||
}
|
||||
if (finfo[i].name[0] != 0xe5) {
|
||||
if ((finfo[i].type & 0x18) == 0) {
|
||||
sprintf(s, "filename.ext %7d\n", finfo[i].size);
|
||||
for (j = 0; j < 8; j++) {
|
||||
s[j] = finfo[i].name[j];
|
||||
}
|
||||
s[ 9] = finfo[i].ext[0];
|
||||
s[10] = finfo[i].ext[1];
|
||||
s[11] = finfo[i].ext[2];
|
||||
cons_putstr0(cons, s);
|
||||
}
|
||||
}
|
||||
}
|
||||
cons_newline(cons);
|
||||
return;
|
||||
}
|
||||
|
||||
void cmd_type(struct CONSOLE *cons, int *fat, char *cmdline)
|
||||
{
|
||||
struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR;
|
||||
struct FILEINFO *finfo = file_search(cmdline + 5, (struct FILEINFO *) (ADR_DISKIMG + 0x002600), 224);
|
||||
char *p;
|
||||
if (finfo != 0) {
|
||||
/*找到文件的情况*/
|
||||
p = (char *) memman_alloc_4k(memman, finfo->size);
|
||||
file_loadfile(finfo->clustno, finfo->size, p, fat, (char *) (ADR_DISKIMG + 0x003e00));
|
||||
cons_putstr1(cons, p, finfo->size);
|
||||
memman_free_4k(memman, (int) p, finfo->size);
|
||||
} else {
|
||||
/*没有找到文件的情况*/
|
||||
cons_putstr0(cons, "File not found.\n");
|
||||
}
|
||||
cons_newline(cons);
|
||||
return;
|
||||
}
|
||||
|
||||
void cmd_exit(struct CONSOLE *cons, int *fat)
|
||||
{
|
||||
struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR;
|
||||
struct TASK *task = task_now();
|
||||
struct SHTCTL *shtctl = (struct SHTCTL *) *((int *) 0x0fe4);
|
||||
struct FIFO32 *fifo = (struct FIFO32 *) *((int *) 0x0fec);
|
||||
if (cons->sht != 0) {
|
||||
timer_cancel(cons->timer);
|
||||
}
|
||||
memman_free_4k(memman, (int) fat, 4 * 2880);
|
||||
io_cli();
|
||||
if (cons->sht != 0) {
|
||||
fifo32_put(fifo, cons->sht - shtctl->sheets0 + 768); /* 768〜1023 */
|
||||
} else {
|
||||
fifo32_put(fifo, task - taskctl->tasks0 + 1024); /*1024~2023*/
|
||||
}
|
||||
io_sti();
|
||||
for (;;) {
|
||||
task_sleep(task);
|
||||
}
|
||||
}
|
||||
|
||||
void cmd_start(struct CONSOLE *cons, char *cmdline, int memtotal)
|
||||
{
|
||||
struct SHTCTL *shtctl = (struct SHTCTL *) *((int *) 0x0fe4);
|
||||
struct SHEET *sht = open_console(shtctl, memtotal);
|
||||
struct FIFO32 *fifo = &sht->task->fifo;
|
||||
int i;
|
||||
sheet_slide(sht, 32, 4);
|
||||
sheet_updown(sht, shtctl->top);
|
||||
/*将命令行输入的字符串逐字复制到新的命令行窗口中*/
|
||||
for (i = 6; cmdline[i] != 0; i++) {
|
||||
fifo32_put(fifo, cmdline[i] + 256);
|
||||
}
|
||||
fifo32_put(fifo, 10 + 256); /*回车键*/
|
||||
cons_newline(cons);
|
||||
return;
|
||||
}
|
||||
|
||||
void cmd_ncst(struct CONSOLE *cons, char *cmdline, int memtotal)
|
||||
{
|
||||
struct TASK *task = open_constask(0, memtotal);
|
||||
struct FIFO32 *fifo = &task->fifo;
|
||||
int i;
|
||||
|
||||
/*将命令行输入的字符串逐字复制到新的命令行窗口中*/
|
||||
for (i = 5; cmdline[i] != 0; i++) {
|
||||
fifo32_put(fifo, cmdline[i] + 256);
|
||||
}
|
||||
fifo32_put(fifo, 10 + 256); /*回车键*/
|
||||
cons_newline(cons);
|
||||
return;
|
||||
}
|
||||
|
||||
int cmd_app(struct CONSOLE *cons, int *fat, char *cmdline)
|
||||
{
|
||||
struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR;
|
||||
struct FILEINFO *finfo;
|
||||
struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *) ADR_GDT;
|
||||
char name[18], *p, *q;
|
||||
struct TASK *task = task_now();
|
||||
int i, segsiz, datsiz, esp, dathrb;
|
||||
struct SHTCTL *shtctl;
|
||||
struct SHEET *sht;
|
||||
|
||||
/*根据命令行生成文件名*/
|
||||
for (i = 0; i < 13; i++) {
|
||||
if (cmdline[i] <= ' ') {
|
||||
break;
|
||||
}
|
||||
name[i] = cmdline[i];
|
||||
}
|
||||
name[i] = 0; /*暂且将文件名的后面置为0*/
|
||||
|
||||
/*寻找文件 */
|
||||
finfo = file_search(name, (struct FILEINFO *) (ADR_DISKIMG + 0x002600), 224);
|
||||
if (finfo == 0 && name[i - 1] != '.') {
|
||||
/*由于找不到文件,故在文件名后面加上“.hrb”后重新寻找*/
|
||||
name[i ] = '.';
|
||||
name[i + 1] = 'H';
|
||||
name[i + 2] = 'R';
|
||||
name[i + 3] = 'B';
|
||||
name[i + 4] = 0;
|
||||
finfo = file_search(name, (struct FILEINFO *) (ADR_DISKIMG + 0x002600), 224);
|
||||
}
|
||||
|
||||
if (finfo != 0) {
|
||||
/*找到文件的情况*/
|
||||
p = (char *) memman_alloc_4k(memman, finfo->size);
|
||||
file_loadfile(finfo->clustno, finfo->size, p, fat, (char *) (ADR_DISKIMG + 0x003e00));
|
||||
if (finfo->size >= 36 && strncmp(p + 4, "Hari", 4) == 0 && *p == 0x00) {
|
||||
segsiz = *((int *) (p + 0x0000));
|
||||
esp = *((int *) (p + 0x000c));
|
||||
datsiz = *((int *) (p + 0x0010));
|
||||
dathrb = *((int *) (p + 0x0014));
|
||||
q = (char *) memman_alloc_4k(memman, segsiz);
|
||||
task->ds_base = (int) q;
|
||||
set_segmdesc(gdt + task->sel / 8 + 1000, finfo->size - 1, (int) p, AR_CODE32_ER + 0x60);
|
||||
set_segmdesc(gdt + task->sel / 8 + 2000, segsiz - 1, (int) q, AR_DATA32_RW + 0x60);
|
||||
for (i = 0; i < datsiz; i++) {
|
||||
q[esp + i] = p[dathrb + i];
|
||||
}
|
||||
start_app(0x1b, task->sel + 1000 * 8, esp, task->sel + 2000 * 8, &(task->tss.esp0));
|
||||
shtctl = (struct SHTCTL *) *((int *) 0x0fe4);
|
||||
for (i = 0; i < MAX_SHEETS; i++) {
|
||||
sht = &(shtctl->sheets0[i]);
|
||||
if ((sht->flags & 0x11) == 0x11 && sht->task == task) {
|
||||
/*找到被应用程序遗留的窗口*/
|
||||
sheet_free(sht); /*关闭*/
|
||||
}
|
||||
}
|
||||
timer_cancelall(&task->fifo);
|
||||
memman_free_4k(memman, (int) q, segsiz);
|
||||
} else {
|
||||
cons_putstr0(cons, ".hrb file format error.\n");
|
||||
}
|
||||
memman_free_4k(memman, (int) p, finfo->size);
|
||||
cons_newline(cons);
|
||||
return 1;
|
||||
}
|
||||
/*没有找到文件的情况*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
int *hrb_api(int edi, int esi, int ebp, int esp, int ebx, int edx, int ecx, int eax)
|
||||
{
|
||||
struct TASK *task = task_now();
|
||||
int ds_base = task->ds_base;
|
||||
struct CONSOLE *cons = task->cons;
|
||||
struct SHTCTL *shtctl = (struct SHTCTL *) *((int *) 0x0fe4);
|
||||
struct SHEET *sht;
|
||||
int *reg = &eax + 1; /* eax后面的地址*/
|
||||
/*强行改写通过PUSHAD保存的值*/
|
||||
/* reg[0] : EDI, reg[1] : ESI, reg[2] : EBP, reg[3] : ESP */
|
||||
/* reg[4] : EBX, reg[5] : EDX, reg[6] : ECX, reg[7] : EAX */
|
||||
int i;
|
||||
|
||||
if (edx == 1) {
|
||||
cons_putchar(cons, eax & 0xff, 1);
|
||||
} else if (edx == 2) {
|
||||
cons_putstr0(cons, (char *) ebx + ds_base);
|
||||
} else if (edx == 3) {
|
||||
cons_putstr1(cons, (char *) ebx + ds_base, ecx);
|
||||
} else if (edx == 4) {
|
||||
return &(task->tss.esp0);
|
||||
} else if (edx == 5) {
|
||||
sht = sheet_alloc(shtctl);
|
||||
sht->task = task;
|
||||
sht->flags |= 0x10;
|
||||
sheet_setbuf(sht, (char *) ebx + ds_base, esi, edi, eax);
|
||||
make_window8((char *) ebx + ds_base, esi, edi, (char *) ecx + ds_base, 0);
|
||||
sheet_slide(sht, ((shtctl->xsize - esi) / 2) & ~3, (shtctl->ysize - edi) / 2);
|
||||
sheet_updown(sht, shtctl->top); /*将窗口图层高度指定为当前鼠标所在图层的高度,鼠标移到上层*/
|
||||
reg[7] = (int) sht;
|
||||
} else if (edx == 6) {
|
||||
sht = (struct SHEET *) (ebx & 0xfffffffe);
|
||||
putfonts8_asc(sht->buf, sht->bxsize, esi, edi, eax, (char *) ebp + ds_base);
|
||||
if ((ebx & 1) == 0) {
|
||||
sheet_refresh(sht, esi, edi, esi + ecx * 8, edi + 16);
|
||||
}
|
||||
} else if (edx == 7) {
|
||||
sht = (struct SHEET *) (ebx & 0xfffffffe);
|
||||
boxfill8(sht->buf, sht->bxsize, ebp, eax, ecx, esi, edi);
|
||||
if ((ebx & 1) == 0) {
|
||||
sheet_refresh(sht, eax, ecx, esi + 1, edi + 1);
|
||||
}
|
||||
} else if (edx == 8) {
|
||||
memman_init((struct MEMMAN *) (ebx + ds_base));
|
||||
ecx &= 0xfffffff0; /*以16字节为单位*/
|
||||
memman_free((struct MEMMAN *) (ebx + ds_base), eax, ecx);
|
||||
} else if (edx == 9) {
|
||||
ecx = (ecx + 0x0f) & 0xfffffff0; /*以16字节为单位进位取整*/
|
||||
reg[7] = memman_alloc((struct MEMMAN *) (ebx + ds_base), ecx);
|
||||
} else if (edx == 10) {
|
||||
ecx = (ecx + 0x0f) & 0xfffffff0; /*以16字节为单位进位取整*/
|
||||
memman_free((struct MEMMAN *) (ebx + ds_base), eax, ecx);
|
||||
} else if (edx == 11) {
|
||||
sht = (struct SHEET *) (ebx & 0xfffffffe);
|
||||
sht->buf[sht->bxsize * edi + esi] = eax;
|
||||
if ((ebx & 1) == 0) {
|
||||
sheet_refresh(sht, esi, edi, esi + 1, edi + 1);
|
||||
}
|
||||
} else if (edx == 12) {
|
||||
sht = (struct SHEET *) ebx;
|
||||
sheet_refresh(sht, eax, ecx, esi, edi);
|
||||
} else if (edx == 13) {
|
||||
sht = (struct SHEET *) (ebx & 0xfffffffe);
|
||||
hrb_api_linewin(sht, eax, ecx, esi, edi, ebp);
|
||||
if ((ebx & 1) == 0) {
|
||||
sheet_refresh(sht, eax, ecx, esi + 1, edi + 1);
|
||||
}
|
||||
} else if (edx == 14) {
|
||||
sheet_free((struct SHEET *) ebx);
|
||||
} else if (edx == 15) {
|
||||
for (;;) {
|
||||
io_cli();
|
||||
if (fifo32_status(&task->fifo) == 0) {
|
||||
if (eax != 0) {
|
||||
task_sleep(task); /* FIFO为空,休眠并等待*/
|
||||
} else {
|
||||
io_sti();
|
||||
reg[7] = -1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
i = fifo32_get(&task->fifo);
|
||||
io_sti();
|
||||
if (i <= 1) { /*光标用定时器*/
|
||||
/*应用程序运行时不需要显示光标,因此总是将下次显示用的值置为1*/
|
||||
timer_init(cons->timer, &task->fifo, 1); /*下次置为1*/
|
||||
timer_settime(cons->timer, 50);
|
||||
}
|
||||
if (i == 2) { /*光标ON */
|
||||
cons->cur_c = COL8_FFFFFF;
|
||||
}
|
||||
if (i == 3) { /*光标OFF */
|
||||
cons->cur_c = -1;
|
||||
}
|
||||
if (i >= 256) { /*键盘数据(通过任务A)等*/
|
||||
reg[7] = i - 256;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} else if (edx == 16) {
|
||||
reg[7] = (int) timer_alloc();
|
||||
((struct TIMER *) reg[7])->flags2 = 1; /*允许自动取消*/
|
||||
} else if (edx == 17) {
|
||||
timer_init((struct TIMER *) ebx, &task->fifo, eax + 256);
|
||||
} else if (edx == 18) {
|
||||
timer_settime((struct TIMER *) ebx, eax);
|
||||
} else if (edx == 19) {
|
||||
timer_free((struct TIMER *) ebx);
|
||||
} else if (edx == 20) {
|
||||
if (eax == 0) {
|
||||
i = io_in8(0x61);
|
||||
io_out8(0x61, i & 0x0d);
|
||||
} else {
|
||||
i = 1193180000 / eax;
|
||||
io_out8(0x43, 0xb6);
|
||||
io_out8(0x42, i & 0xff);
|
||||
io_out8(0x42, i >> 8);
|
||||
i = io_in8(0x61);
|
||||
io_out8(0x61, (i | 0x03) & 0x0f);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int *inthandler0c(int *esp)
|
||||
{
|
||||
struct TASK *task = task_now();
|
||||
struct CONSOLE *cons = task->cons;
|
||||
char s[30];
|
||||
cons_putstr0(cons, "\nINT 0C :\n Stack Exception.\n");
|
||||
sprintf(s, "EIP = %08X\n", esp[11]);
|
||||
cons_putstr0(cons, s);
|
||||
return &(task->tss.esp0); /*强制结束程序*/
|
||||
}
|
||||
|
||||
int *inthandler0d(int *esp)
|
||||
{
|
||||
struct TASK *task = task_now();
|
||||
struct CONSOLE *cons = task->cons;
|
||||
char s[30];
|
||||
cons_putstr0(cons, "\nINT 0D :\n General Protected Exception.\n");
|
||||
sprintf(s, "EIP = %08X\n", esp[11]);
|
||||
cons_putstr0(cons, s);
|
||||
return &(task->tss.esp0); /*强制结束程序*/
|
||||
}
|
||||
|
||||
void hrb_api_linewin(struct SHEET *sht, int x0, int y0, int x1, int y1, int col)
|
||||
{
|
||||
int i, x, y, len, dx, dy;
|
||||
|
||||
dx = x1 - x0;
|
||||
dy = y1 - y0;
|
||||
x = x0 << 10;
|
||||
y = y0 << 10;
|
||||
if (dx < 0) {
|
||||
dx = - dx;
|
||||
}
|
||||
if (dy < 0) {
|
||||
dy = - dy;
|
||||
}
|
||||
if (dx >= dy) {
|
||||
len = dx + 1;
|
||||
if (x0 > x1) {
|
||||
dx = -1024;
|
||||
} else {
|
||||
dx = 1024;
|
||||
}
|
||||
if (y0 <= y1) {
|
||||
dy = ((y1 - y0 + 1) << 10) / len;
|
||||
} else {
|
||||
dy = ((y1 - y0 - 1) << 10) / len;
|
||||
}
|
||||
} else {
|
||||
len = dy + 1;
|
||||
if (y0 > y1) {
|
||||
dy = -1024;
|
||||
} else {
|
||||
dy = 1024;
|
||||
}
|
||||
if (x0 <= x1) {
|
||||
dx = ((x1 - x0 + 1) << 10) / len;
|
||||
} else {
|
||||
dx = ((x1 - x0 - 1) << 10) / len;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
sht->buf[(y >> 10) * sht->bxsize + (x >> 10)] = col;
|
||||
x += dx;
|
||||
y += dy;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
59
26_day/dsctbl.c
Normal file
59
26_day/dsctbl.c
Normal file
@@ -0,0 +1,59 @@
|
||||
/* 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 + 0x0c, (int) asm_inthandler0c, 2 * 8, AR_INTGATE32);
|
||||
set_gatedesc(idt + 0x0d, (int) asm_inthandler0d, 2 * 8, AR_INTGATE32);
|
||||
set_gatedesc(idt + 0x20, (int) asm_inthandler20, 2 * 8, AR_INTGATE32);
|
||||
set_gatedesc(idt + 0x21, (int) asm_inthandler21, 2 * 8, AR_INTGATE32);
|
||||
set_gatedesc(idt + 0x2c, (int) asm_inthandler2c, 2 * 8, AR_INTGATE32);
|
||||
set_gatedesc(idt + 0x40, (int) asm_hrb_api, 2 * 8, AR_INTGATE32 + 0x60);
|
||||
|
||||
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;
|
||||
}
|
||||
63
26_day/fifo.c
Normal file
63
26_day/fifo.c
Normal file
@@ -0,0 +1,63 @@
|
||||
/* FIFO */
|
||||
|
||||
#include "bootpack.h"
|
||||
|
||||
#define FLAGS_OVERRUN 0x0001
|
||||
|
||||
void fifo32_init(struct FIFO32 *fifo, int size, int *buf, struct TASK *task)
|
||||
/* FIFO缓冲区的初始化*/
|
||||
{
|
||||
fifo->size = size;
|
||||
fifo->buf = buf;
|
||||
fifo->free = size; /*空*/
|
||||
fifo->flags = 0;
|
||||
fifo->p = 0; /*写入位置*/
|
||||
fifo->q = 0; /*读取位置*/
|
||||
fifo->task = task; /*有数据写入时需要唤醒的任务*/
|
||||
return;
|
||||
}
|
||||
|
||||
int fifo32_put(struct FIFO32 *fifo, int 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--;
|
||||
if (fifo->task != 0) {
|
||||
if (fifo->task->flags != 2) { /*如果任务处于休眠状态*/
|
||||
task_run(fifo->task, -1, 0); /*将任务唤醒*/
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fifo32_get(struct FIFO32 *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 fifo32_status(struct FIFO32 *fifo)
|
||||
/*报告已经存储了多少数据*/
|
||||
{
|
||||
return fifo->size - fifo->free;
|
||||
}
|
||||
74
26_day/file.c
Normal file
74
26_day/file.c
Normal file
@@ -0,0 +1,74 @@
|
||||
/* 文件相关函数 */
|
||||
|
||||
#include "bootpack.h"
|
||||
|
||||
void file_readfat(int *fat, unsigned char *img)
|
||||
/*将磁盘映像中的FAT解压缩 */
|
||||
{
|
||||
int i, j = 0;
|
||||
for (i = 0; i < 2880; i += 2) {
|
||||
fat[i + 0] = (img[j + 0] | img[j + 1] << 8) & 0xfff;
|
||||
fat[i + 1] = (img[j + 1] >> 4 | img[j + 2] << 4) & 0xfff;
|
||||
j += 3;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void file_loadfile(int clustno, int size, char *buf, int *fat, char *img)
|
||||
{
|
||||
int i;
|
||||
for (;;) {
|
||||
if (size <= 512) {
|
||||
for (i = 0; i < size; i++) {
|
||||
buf[i] = img[clustno * 512 + i];
|
||||
}
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < 512; i++) {
|
||||
buf[i] = img[clustno * 512 + i];
|
||||
}
|
||||
size -= 512;
|
||||
buf += 512;
|
||||
clustno = fat[clustno];
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
struct FILEINFO *file_search(char *name, struct FILEINFO *finfo, int max)
|
||||
{
|
||||
int i, j;
|
||||
char s[12];
|
||||
for (j = 0; j < 11; j++) {
|
||||
s[j] = ' ';
|
||||
}
|
||||
j = 0;
|
||||
for (i = 0; name[i] != 0; i++) {
|
||||
if (j >= 11) { return 0; /*没有找到*/ }
|
||||
if (name[i] == '.' && j <= 8) {
|
||||
j = 8;
|
||||
} else {
|
||||
s[j] = name[i];
|
||||
if ('a' <= s[j] && s[j] <= 'z') {
|
||||
/*将小写字母转换为大写字母*/
|
||||
s[j] -= 0x20;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < max; ) {
|
||||
if (finfo->name[0] == 0x00) {
|
||||
break;
|
||||
}
|
||||
if ((finfo[i].type & 0x18) == 0) {
|
||||
for (j = 0; j < 11; j++) {
|
||||
if (finfo[i].name[j] != s[j]) {
|
||||
goto next;
|
||||
}
|
||||
}
|
||||
return finfo + i; /*找到文件*/
|
||||
}
|
||||
next:
|
||||
i++;
|
||||
}
|
||||
return 0; /*没有找到*/
|
||||
}
|
||||
167
26_day/graphic.c
Normal file
167
26_day/graphic.c
Normal file
@@ -0,0 +1,167 @@
|
||||
/* 关于绘图部分的处理 */
|
||||
|
||||
#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:暗灰 */
|
||||
};
|
||||
unsigned char table2[216 * 3];
|
||||
int r, g, b;
|
||||
set_palette(0, 15, table_rgb);
|
||||
for (b = 0; b < 6; b++) {
|
||||
for (g = 0; g < 6; g++) {
|
||||
for (r = 0; r < 6; r++) {
|
||||
table2[(r + g * 6 + b * 36) * 3 + 0] = r * 51;
|
||||
table2[(r + g * 6 + b * 36) * 3 + 1] = g * 51;
|
||||
table2[(r + g * 6 + b * 36) * 3 + 2] = b * 51;
|
||||
}
|
||||
}
|
||||
}
|
||||
set_palette(16, 231, table2);
|
||||
return;
|
||||
}
|
||||
|
||||
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
26_day/hankaku.txt
Normal file
4609
26_day/hankaku.txt
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user