mirror of
https://github.com/yourtion/30dayMakeOS.git
synced 2026-02-03 01:53:24 +08:00
Add 24 day code
This commit is contained in:
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
|
||||
212
24_day/Makefile
Normal file
212
24_day/Makefile
Normal file
@@ -0,0 +1,212 @@
|
||||
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
|
||||
|
||||
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
|
||||
$(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:@: \
|
||||
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();
|
||||
}
|
||||
188
24_day/a_nask.nas
Normal file
188
24_day/a_nask.nas
Normal file
@@ -0,0 +1,188 @@
|
||||
[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
|
||||
|
||||
[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
|
||||
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:
|
||||
290
24_day/bootpack.c
Normal file
290
24_day/bootpack.c
Normal file
@@ -0,0 +1,290 @@
|
||||
/* bootpack */
|
||||
|
||||
#include "bootpack.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#define KEYCMD_LED 0xed
|
||||
|
||||
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_to = 0, key_shift = 0, key_leds = (binfo->leds >> 4) & 7, keycmd_wait = -1;
|
||||
struct CONSOLE *cons;
|
||||
|
||||
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);
|
||||
|
||||
/*为了避免和键盘当前状态冲突,在一开始先进行设置*/
|
||||
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 (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_to == 0) { /*发送给任务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(&task_cons->fifo, s[0] + 256);
|
||||
}
|
||||
}
|
||||
if (i == 256 + 0x0e) { /* 退格键 */
|
||||
if (key_to == 0) { /*发送给任务A */
|
||||
if (cursor_x > 8) {
|
||||
/*用空白擦除光标后将光标前移一位*/
|
||||
putfonts8_asc_sht(sht_win, cursor_x, 28, COL8_000000, COL8_FFFFFF, " ", 1);
|
||||
cursor_x -= 8;
|
||||
}
|
||||
} else { /*发送给命令行窗口*/
|
||||
fifo32_put(&task_cons->fifo, 8 + 256);
|
||||
}
|
||||
}
|
||||
if (i == 256 + 0x1c) { /*回车键*/
|
||||
if (key_to != 0) { /*发送至命令行窗口*/
|
||||
fifo32_put(&task_cons->fifo, 10 + 256);
|
||||
}
|
||||
}
|
||||
if (i == 256 + 0x0f) { /* Tab */
|
||||
if (key_to == 0) {
|
||||
key_to = 1;
|
||||
make_wtitle8(buf_win, sht_win->bxsize, "task_a", 0);
|
||||
make_wtitle8(buf_cons, sht_cons->bxsize, "console", 1);
|
||||
cursor_c = -1; /* 不显示光标 */
|
||||
boxfill8(sht_win->buf, sht_win->bxsize, COL8_FFFFFF, cursor_x, 28, cursor_x + 7, 43);
|
||||
fifo32_put(&task_cons->fifo, 2); /*命令行窗口光标ON */
|
||||
} else {
|
||||
key_to = 0;
|
||||
make_wtitle8(buf_win, sht_win->bxsize, "task_a", 1);
|
||||
make_wtitle8(buf_cons, sht_cons->bxsize, "console", 0);
|
||||
cursor_c = COL8_000000;
|
||||
fifo32_put(&task_cons->fifo, 3); /*命令行窗口光标OFF */
|
||||
}
|
||||
sheet_refresh(sht_win, 0, 0, sht_win->bxsize, 21);
|
||||
sheet_refresh(sht_cons, 0, 0, sht_cons->bxsize, 21);
|
||||
}
|
||||
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 + 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) { /* 按下左键、移动sht_win */
|
||||
sheet_slide(sht_win, mx - 80, my - 8);
|
||||
}
|
||||
}
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
267
24_day/bootpack.h
Normal file
267
24_day/bootpack.h
Normal file
@@ -0,0 +1,267 @@
|
||||
/* 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, flags;
|
||||
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);
|
||||
|
||||
/* 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);
|
||||
|
||||
/* 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');
|
||||
}
|
||||
}
|
||||
494
24_day/console.c
Normal file
494
24_day/console.c
Normal file
@@ -0,0 +1,494 @@
|
||||
/* 命令行窗口相关 */
|
||||
|
||||
#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 != 0 && sht->task == task) {
|
||||
/*找到被应用程序遗留的窗口*/
|
||||
sheet_free(sht); /*关闭*/
|
||||
}
|
||||
}
|
||||
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;
|
||||
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 (256 <= i && i <= 511) { /*键盘数据(通过任务A)*/
|
||||
reg[7] = i - 256;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
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
|
||||
; 应用程序结束后不会回到这里
|
||||
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();
|
||||
}
|
||||
118
24_day/timer.c
Normal file
118
24_day/timer.c
Normal file
@@ -0,0 +1,118 @@
|
||||
/* 定时器 */
|
||||
|
||||
#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;
|
||||
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;
|
||||
}
|
||||
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();
|
||||
}
|
||||
88
24_day/window.c
Normal file
88
24_day/window.c
Normal file
@@ -0,0 +1,88 @@
|
||||
/* 窗口相关函数 */
|
||||
|
||||
#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;
|
||||
}
|
||||
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();
|
||||
}
|
||||
Reference in New Issue
Block a user