Skip to content

Commit

Permalink
Add day 04 code
Browse files Browse the repository at this point in the history
  • Loading branch information
yourtion committed Sep 10, 2014
1 parent 9958565 commit a13dc8e
Show file tree
Hide file tree
Showing 8 changed files with 375 additions and 0 deletions.
1 change: 1 addition & 0 deletions 04_day/!cons_9x.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
command
1 change: 1 addition & 0 deletions 04_day/!cons_nt.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
cmd.exe
85 changes: 85 additions & 0 deletions 04_day/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
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
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

bootpack.gas : bootpack.c Makefile
$(CC1) -o bootpack.gas bootpack.c

bootpack.nas : bootpack.gas Makefile
$(GAS2NASK) bootpack.gas bootpack.nas

bootpack.obj : bootpack.nas Makefile
$(NASK) bootpack.nas bootpack.obj bootpack.lst

naskfunc.obj : naskfunc.nas Makefile
$(NASK) naskfunc.nas naskfunc.obj naskfunc.lst

bootpack.bim : bootpack.obj naskfunc.obj Makefile
$(OBJ2BIM) @$(RULEFILE) out:bootpack.bim stack:3136k map:bootpack.map \
bootpack.obj naskfunc.obj
# 3MB+64KB=3136KB

bootpack.hrb : bootpack.bim Makefile
$(BIM2HRB) bootpack.bim bootpack.hrb 0

haribote.sys : asmhead.bin bootpack.hrb Makefile
copy /B asmhead.bin+bootpack.hrb haribote.sys

haribote.img : ipl10.bin haribote.sys Makefile
$(EDIMG) imgin:../z_tools/fdimg0at.tek \
wbinimg src:ipl10.bin len:512 from:0 to:0 \
copy from:haribote.sys to:@: \
imgout:haribote.img

# コマンド

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) *.gas
-$(DEL) *.obj
-$(DEL) bootpack.nas
-$(DEL) bootpack.map
-$(DEL) bootpack.bim
-$(DEL) bootpack.hrb
-$(DEL) haribote.sys

src_only :
$(MAKE) clean
-$(DEL) haribote.img
146 changes: 146 additions & 0 deletions 04_day/asmhead.nas
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
; haribote-os boot asm
; TAB=4

BOTPAK EQU 0x00280000 ; bootpackのロード先
DSKCAC EQU 0x00100000 ; ディスクキャッシュの場所
DSKCAC0 EQU 0x00008000 ; ディスクキャッシュの場所(リアルモード)

; BOOT_INFO関係
CYLS EQU 0x0ff0 ; ブートセクタが設定する
LEDS EQU 0x0ff1
VMODE EQU 0x0ff2 ; 色数に関する情報。何ビットカラーか?
SCRNX EQU 0x0ff4 ; 解像度のX
SCRNY EQU 0x0ff6 ; 解像度のY
VRAM EQU 0x0ff8 ; グラフィックバッファの開始番地

ORG 0xc200 ; このプログラムがどこに読み込まれるのか

; 画面モードを設定

MOV AL,0x13 ; VGAグラフィックス、320x200x8bitカラー
MOV AH,0x00
INT 0x10
MOV BYTE [VMODE],8 ; 画面モードをメモする(C言語が参照する)
MOV WORD [SCRNX],320
MOV WORD [SCRNY],200
MOV DWORD [VRAM],0x000a0000

; キーボードのLED状態をBIOSに教えてもらう

MOV AH,0x02
INT 0x16 ; keyboard BIOS
MOV [LEDS],AL

; PICが一切の割り込みを受け付けないようにする
; AT互換機の仕様では、PICの初期化をするなら、
; こいつをCLI前にやっておかないと、たまにハングアップする
; PICの初期化はあとでやる

MOV AL,0xff
OUT 0x21,AL
NOP ; OUT命令を連続させるとうまくいかない機種があるらしいので
OUT 0xa1,AL

CLI ; さらにCPUレベルでも割り込み禁止

; CPUから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 ; 読み書き可能セグメント32bit
DW 0xffff,0x0000,0x9a28,0x0047 ; 実行可能セグメント32bit(bootpack用)

DW 0
GDTR0:
DW 8*3-1
DD GDT0

ALIGNB 16
bootpack:
15 changes: 15 additions & 0 deletions 04_day/bootpack.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
void io_hlt(void);
void write_mem8(int addr, int data);

void HariMain(void)
{
int i; /* 変数宣言。iという変数は、32ビットの整数型 */

for (i = 0xa0000; i <= 0xaffff; i++) {
write_mem8(i, 15); /* MOV BYTE [i],15 */
}

for (;;) {
io_hlt();
}
}
105 changes: 105 additions & 0 deletions 04_day/ipl10.nas
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
; haribote-ipl
; TAB=4

CYLS EQU 10 ; どこまで読み込むか

ORG 0x7c00 ; このプログラムがどこに読み込まれるのか

; 以下は標準的なFAT12フォーマットフロッピーディスクのための記述

JMP entry
DB 0x90
DB "HARIBOTE" ; ブートセクタの名前を自由に書いてよい(8バイト)
DW 512 ; 1セクタの大きさ(512にしなければいけない)
DB 1 ; クラスタの大きさ(1セクタにしなければいけない)
DW 1 ; FATがどこから始まるか(普通は1セクタ目からにする)
DB 2 ; FATの個数(2にしなければいけない)
DW 224 ; ルートディレクトリ領域の大きさ(普通は224エントリにする)
DW 2880 ; このドライブの大きさ(2880セクタにしなければいけない)
DB 0xf0 ; メディアのタイプ(0xf0にしなければいけない)
DW 9 ; FAT領域の長さ(9セクタにしなければいけない)
DW 18 ; 1トラックにいくつのセクタがあるか(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 ; エラーがおきなければ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 ; ドライブのリセット
JMP retry
next:
MOV AX,ES ; アドレスを0x200進める
ADD AX,0x0020
MOV ES,AX ; ADD ES,0x020 という命令がないのでこうしている
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 ; 改行を2つ
DB "load error"
DB 0x0a ; 改行
DB 0

RESB 0x7dfe-$ ; 0x7dfeまでを0x00で埋める命令

DB 0x55, 0xaa
1 change: 1 addition & 0 deletions 04_day/make.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
..\z_tools\make.exe %1 %2 %3 %4 %5 %6 %7 %8 %9
21 changes: 21 additions & 0 deletions 04_day/naskfunc.nas
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
; naskfunc
; TAB=4

[FORMAT "WCOFF"] ; オブジェクトファイルを作るモード
[INSTRSET "i486p"] ; 486の命令まで使いたいという記述
[BITS 32] ; 32ビットモード用の機械語を作らせる
[FILE "naskfunc.nas"] ; ソースファイル名情報

GLOBAL _io_hlt,_write_mem8

[SECTION .text]

_io_hlt: ; void io_hlt(void);
HLT
RET

_write_mem8: ; void write_mem8(int addr, int data);
MOV ECX,[ESP+4] ; [ESP+4]にaddrが入っているのでそれをECXに読み込む
MOV AL,[ESP+8] ; [ESP+8]にdataが入っているのでそれをALに読み込む
MOV [ECX],AL
RET

0 comments on commit a13dc8e

Please sign in to comment.