From febac10ebfb5dd7af2ecf60d4f23f95e3c301877 Mon Sep 17 00:00:00 2001 From: Yourtion Date: Fri, 20 May 2016 14:49:26 +0800 Subject: [PATCH] =?UTF-8?q?IPL=E7=9A=84=E6=94=B9=E8=89=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 30_day/Makefile | 4 +- 30_day/app_make.txt | 4 +- 30_day/haribote/Makefile | 8 +- 30_day/haribote/ipl10.nas | 152 ++++++++++++++++++++++++++++++++++++++ 30_day/invader/invader.c | 16 +++- 5 files changed, 174 insertions(+), 10 deletions(-) create mode 100644 30_day/haribote/ipl10.nas diff --git a/30_day/Makefile b/30_day/Makefile index d54fa0c..a5cdf58 100644 --- a/30_day/Makefile +++ b/30_day/Makefile @@ -14,7 +14,7 @@ default : #文件生成规则 -haribote.img : haribote/ipl20.bin haribote/haribote.sys Makefile \ +haribote.img : haribote/ipl10.bin haribote/haribote.sys Makefile \ a/a.hrb hello3/hello3.hrb hello4/hello4.hrb hello5/hello5.hrb \ winhelo/winhelo.hrb winhelo2/winhelo2.hrb winhelo3/winhelo3.hrb \ star1/star1.hrb stars/stars.hrb stars2/stars2.hrb \ @@ -25,7 +25,7 @@ haribote.img : haribote/ipl20.bin haribote/haribote.sys Makefile \ notrec/notrec.hrb bball/bball.hrb invader/invader.hrb \ calc/calc.hrb tview/tview.hrb mmlplay/mmlplay.hrb gview/gview.hrb $(EDIMG) imgin:../z_tools/fdimg0at.tek \ - wbinimg src:haribote/ipl20.bin len:512 from:0 to:0 \ + wbinimg src:haribote/ipl10.bin len:512 from:0 to:0 \ copy from:haribote/haribote.sys to:@: \ copy from:haribote/jp.nas to:@: \ copy from:make.bat to:@: \ diff --git a/30_day/app_make.txt b/30_day/app_make.txt index b1e4436..f0c66f3 100644 --- a/30_day/app_make.txt +++ b/30_day/app_make.txt @@ -35,10 +35,10 @@ $(STDAPP).bim : $(APP).obj $(STDLIBPATH)stdlib.lib Makefile ../app_make.txt $(OBJ2BIM) @$(RULEFILE) out:$(APP).bim map:$(APP).map stack:$(STACK) \ $(APP).obj $(STDLIBPATH)stdlib.lib -haribote.img : ../haribote/ipl20.bin ../haribote/haribote.sys $(APP).hrb \ +haribote.img : ../haribote/ipl10.bin ../haribote/haribote.sys $(APP).hrb \ Makefile ../app_make.txt $(EDIMG) imgin:../../z_tools/fdimg0at.tek \ - wbinimg src:../haribote/ipl20.bin len:512 from:0 to:0 \ + wbinimg src:../haribote/ipl10.bin len:512 from:0 to:0 \ copy from:../haribote/haribote.sys to:@: \ copy from:$(APP).hrb to:@: \ copy from:../nihongo/nihongo.fnt to:@: \ diff --git a/30_day/haribote/Makefile b/30_day/haribote/Makefile index 6844a71..cb530a1 100644 --- a/30_day/haribote/Makefile +++ b/30_day/haribote/Makefile @@ -23,13 +23,13 @@ DEL = del #默认动作 default : - $(MAKE) ipl20.bin + $(MAKE) ipl10.bin $(MAKE) haribote.sys # 镜像文件生成 -ipl20.bin : ipl20.nas Makefile - $(NASK) ipl20.nas ipl20.bin ipl20.lst +ipl10.bin : ipl10.nas Makefile + $(NASK) ipl10.nas ipl10.bin ipl10.lst asmhead.bin : asmhead.nas Makefile $(NASK) asmhead.nas asmhead.bin asmhead.lst @@ -75,5 +75,5 @@ clean : src_only : $(MAKE) clean - -$(DEL) ipl20.bin + -$(DEL) ipl10.bin -$(DEL) haribote.sys diff --git a/30_day/haribote/ipl10.nas b/30_day/haribote/ipl10.nas new file mode 100644 index 0000000..134d0c2 --- /dev/null +++ b/30_day/haribote/ipl10.nas @@ -0,0 +1,152 @@ +; 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 + MOV BX,18*2*CYLS-1 ; 要读取的合计扇区数 + CALL readfast ; 告诉读取 + +; 读取完毕,跳转到haribote.sys执行! + MOV [0x0ff0],CH ; 记录IPL实际读取了多少内容 + JMP 0xc200 + +error: + MOV AX,0 + MOV ES,AX + 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 + +readfast: ; 使用AL尽量一次性读取数据 从此开始 +; ES:读取地址, CH:柱面, DH:磁头, CL:扇区, BX:读取扇区数 + + MOV AX,ES ; < 通过ES计算AL的最大值 > + SHL AX,3 ; 将AX除以32,将结果存入AH(SHL是左移位指令) + AND AH,0x7f ; AH是AH除以128所得的余数(512*128=64K) + MOV AL,128 ; AL = 128 - AH; AH是AH除以128所得的余数(512*128=64K) + SUB AL,AH + + MOV AH,BL ; < 通过BX计算AL的最大值并存入AH > + CMP BH,0 ; if (BH != 0) { AH = 18; } + JE .skip1 + MOV AH,18 +.skip1: + CMP AL,AH ; if (AL > AH) { AL = AH; } + JBE .skip2 + MOV AL,AH +.skip2: + + MOV AH,19 ; < 通过CL计算AL的最大值并存入AH > + SUB AH,CL ; AH = 19 - CL; + CMP AL,AH ; if (AL > AH) { AL = AH; } + JBE .skip3 + MOV AL,AH +.skip3: + + PUSH BX + MOV SI,0 ; 计算失败次数的寄存器 +retry: + MOV AH,0x02 ; AH=0x02 : 读取磁盘 + MOV BX,0 + MOV DL,0x00 ; A盘 + PUSH ES + PUSH DX + PUSH CX + PUSH AX + INT 0x13 ; 调用磁盘BIOS + JNC next ; 没有出错的话则跳转至next + ADD SI,1 ; 将SI加1 + CMP SI,5 ; 将SI与5比较 + JAE error ; SI >= 5则跳转至error + MOV AH,0x00 + MOV DL,0x00 ; A盘 + INT 0x13 ; 驱动器重置 + POP AX + POP CX + POP DX + POP ES + JMP retry +next: + POP AX + POP CX + POP DX + POP BX ; 将ES的内容存入BX + SHR BX,5 ; 将BX由16字节为单位转换为512字节为单位 + MOV AH,0 + ADD BX,AX ; BX += AL; + SHL BX,5 ; 将BX由512字节为单位转换为16字节为单位 + MOV ES,BX ; 相当于EX += AL * 0x20; + POP BX + SUB BX,AX + JZ .ret + ADD CL,AL ; 将CL加上AL + CMP CL,18 ; 将CL与18比较 + JBE readfast ; CL <= 18则跳转至readfast + MOV CL,1 + ADD DH,1 + CMP DH,2 + JB readfast ; DH < 2则跳转至readfast + MOV DH,0 + ADD CH,1 + JMP readfast +.ret: + RET + + RESB 0x7dfe-$ ; 到0x7dfe为止用0x00填充的指令 + + DB 0x55, 0xaa diff --git a/30_day/invader/invader.c b/30_day/invader/invader.c index d26d3b1..f045093 100644 --- a/30_day/invader/invader.c +++ b/30_day/invader/invader.c @@ -1,9 +1,9 @@ -#include /* sprintf */ #include /* strlen */ #include "apilib.h" void putstr(int win, char *winbuf, int x, int y, int col, unsigned char *s); void wait(int i, int timer, char *keyflag); +void setdec8(char *s, int i); static unsigned char charset[16 * 8] = { @@ -171,7 +171,7 @@ next_group: /* hit ! */ score += point; point++; - sprintf(s, "%08d", score); + setdec8(s, score); putstr(win, winbuf, 10, 0, 7, s); if (high < score) { high = score; @@ -279,3 +279,15 @@ void wait(int i, int timer, char *keyflag) } return; } + +void setdec8(char *s, int i) +/*将i用十进制表示并存入s*/ +{ + int j; + for (j = 7; j >= 0; j--) { + s[j] = '0' + i % 10; + i /= 10; + } + s[8] = 0; + return; +}