1 1 ; haribote-os boot asm
5 5 VBEMODE EQU 0x118 ; 1024 x 768 x 24bitカラー
7 7 MEMORYMODEL EQU 6 ; 4ならインデックスカラー 6ならダイレクトカラー
9 9 ; 0x100 : 640 x 400 x 8bitカラー
10 10 ; 0x101 : 640 x 480 x 8bitカラー
11 11 ; 0x103 : 800 x 600 x 8bitカラー
12 12 ; 0x105 : 1024 x 768 x 8bitカラー
13 13 ; 0x107 : 1280 x 1024 x 8bitカラー
14 14 ; 0x118 : 1024 x 768 x 24bitカラー
17 17 BOOTPACK_CODE EQU 0x00280000 ; bootpackのロード先
19 19 ;DSKCAC EQU 0x00100000 ; ディスクキャッシュの場所
20 20 ;DSKCAC0 EQU 0x00008000 ; ディスクキャッシュの場所(リアルモード)
22 22 SYSPAGEDIR EQU 0x00100000
25 25 BOOTDRIVE EQU 0x0ff0 ; ブートセクタが設定する
27 27 VMODE EQU 0x0ff2 ; 色数に関する情報。何ビットカラーか?
28 28 SCRNX EQU 0x0ff4 ; 解像度のX
29 29 SCRNY EQU 0x0ff6 ; 解像度のY
30 30 VRAM EQU 0x0ff8 ; グラフィックバッファの開始番地
32 32 ORG 0xc200 ; このプログラムがどこに読み込まれるのか
35 35 00000000 8816F00F mov [BOOTDRIVE], dl
38 38 00000004 B80090 MOV AX,0x9000
39 39 00000007 8EC0 MOV ES,AX
40 40 00000009 BF0000 MOV DI,0
41 41 0000000C B8004F MOV AX,0x4f00
42 42 0000000F CD10 INT 0x10
43 43 00000011 3D4F00 CMP AX,0x004f
44 44 00000014 7553 JNE scrn320
48 48 00000016 268B4504 MOV AX,[ES:DI+4]
49 49 0000001A 3D0002 CMP AX,0x0200
50 50 0000001D 724A JB scrn320 ; if (AX < 0x0200) goto scrn320
54 54 0000001F B91801 MOV CX,VBEMODE
55 55 00000022 B8014F MOV AX,0x4f01
56 56 00000025 CD10 INT 0x10
57 57 00000027 3D4F00 CMP AX,0x004f
58 58 0000002A 753D JNE scrn320
62 62 0000002C 26807D1918 CMP BYTE [ES:DI+0x19],BITPERPIXEL
63 63 00000031 7536 JNE scrn320
64 64 00000033 26807D1B06 CMP BYTE [ES:DI+0x1b],MEMORYMODEL
65 65 00000038 752F JNE scrn320
66 66 0000003A 268B05 MOV AX,[ES:DI+0x00]
67 67 0000003D 258000 AND AX,0x0080
68 68 00000040 7427 JZ scrn320 ; モード属性のbit7が0だったのであきらめる
72 72 00000042 BB1841 MOV BX,VBEMODE | 0x4000
73 73 00000045 B8024F MOV AX,0x4f02
74 74 00000048 CD10 INT 0x10
75 75 0000004A C606F20F18 MOV BYTE [VMODE],BITPERPIXEL ; 画面モードをメモする(C言語が参照する)
76 76 0000004F 268B4512 MOV AX,[ES:DI+0x12]
77 77 00000053 A3F40F MOV [SCRNX],AX
78 78 00000056 268B4514 MOV AX,[ES:DI+0x14]
79 79 0000005A A3F60F MOV [SCRNY],AX
80 80 0000005D 26668B4528 MOV EAX,[ES:DI+0x28]
81 81 00000062 66A3F80F MOV [VRAM],EAX
82 82 00000066 E92000 JMP keystatus
85 85 00000069 B013 MOV AL,0x13 ; VGAグラフィックス、320x200x8bitカラー
86 86 0000006B B400 MOV AH,0x00
87 87 0000006D CD10 INT 0x10
88 88 0000006F C606F20F08 MOV BYTE [VMODE],8 ; 画面モードをメモする(C言語が参照する)
89 89 00000074 C706F40F4001 MOV WORD [SCRNX],320
90 90 0000007A C706F60FC800 MOV WORD [SCRNY],200
91 91 00000080 66C706F80F00000A00 MOV DWORD [VRAM],0x000a0000
93 93 ; キーボードのLED状態をBIOSに教えてもらう
96 96 00000089 B402 MOV AH,0x02
97 97 0000008B CD16 INT 0x16 ; keyboard BIOS
98 98 0000008D A2F10F MOV [LEDS],AL
100 100 ; PICが一切の割り込みを受け付けないようにする
101 101 ; AT互換機の仕様では、PICの初期化をするなら、
102 102 ; こいつをCLI前にやっておかないと、たまにハングアップする
105 105 00000090 B0FF MOV AL,0xff
106 106 00000092 E621 OUT 0x21,AL
107 107 00000094 90 NOP ; OUT命令を連続させるとうまくいかない機種があるらしいので
108 108 00000095 E6A1 OUT 0xa1,AL
110 110 00000097 FA CLI ; さらにCPUレベルでも割り込み禁止
112 112 ; CPUから1MB以上のメモリにアクセスできるように、A20GATEを設定
114 114 00000098 E8F600 CALL waitkbdout
115 115 0000009B B0D1 MOV AL,0xd1
116 116 0000009D E664 OUT 0x64,AL
117 117 0000009F E8EF00 CALL waitkbdout
118 118 000000A2 B0DF MOV AL,0xdf ; enable A20
119 119 000000A4 E660 OUT 0x60,AL
120 120 000000A6 E8E800 CALL waitkbdout
122 122 ;[INSTRSET "i486p"] ; 486の命令まで使いたいという記述
125 125 ; page size = 4mb or 4kb (混在) pys addr size = 32 bit
127 127 000000A9 0F0116[DA01] LGDT [GDTR0] ; 暫定GDTを設定
128 128 000000AE 0F20C0 MOV EAX,CR0
129 129 ;or eax, 1 << 0x1f ; paging flag
130 130 ;AND EAX,0x7fffffff ; bit31を0にする(ページング禁止のため)
131 131 000000B1 660D01000000 OR EAX,0x00000001 ; bit0を1にする(プロテクトモード移行のため)
132 132 000000B7 0F22C0 MOV CR0,EAX
133 133 000000BA E90000 JMP pipelineflush
137 137 000000BD 6631C0 xor eax, eax
138 138 000000C0 66B900000000 mov ecx, 0
140 140 000000C6 90<rept> align 16
142 142 000000D0 6689C8 mov eax, ecx
143 143 000000D3 66C1E016 shl eax, 22
144 144 000000D7 660D83010000 or eax, ((1 << 8)|(1 << 7)|(1 << 1)|1)
145 145 000000DD 676689048D00001000 mov [SYSPAGEDIR + 4 * ecx], eax
147 147 000000E6 6641 inc ecx
148 148 000000E8 6681F900040000 cmp ecx, 0x400
149 149 000000EF 72DF jb pagedirloop
153 153 000000F1 0F20D8 mov eax, cr3
154 154 000000F4 660D00001000 or eax, SYSPAGEDIR
155 155 000000FA 0F22D8 mov cr3, eax
157 157 000000FD 0F20E0 mov eax, cr4
158 158 00000100 6625DFFFFFFF and eax, ~(1 << 5) ; physical addr ext(pae) を無効に
159 159 00000106 660D10000000 or eax, 1 << 4; enable paging size ext(pse)
160 160 0000010C 0F22E0 mov cr4, eax
163 163 0000010F 0F20D8 mov eax, cr3
164 164 00000112 0F22D8 mov cr3, eax
166 166 00000115 0F20C0 MOV EAX,CR0
167 167 00000118 660D00000080 or eax, 1 << 0x1f ; paging flag
168 168 0000011E 0F22C0 MOV CR0,EAX
169 169 00000121 E90000 JMP pipelineflush2
172 172 00000124 B80800 MOV AX,1*8 ; 読み書き可能セグメント32bit
173 173 00000127 8ED8 MOV DS,AX
174 174 00000129 8EC0 MOV ES,AX
175 175 0000012B 8EE0 MOV FS,AX
176 176 0000012D 8EE8 MOV GS,AX
177 177 0000012F 8ED0 MOV SS,AX
180 180 ; ついでにディスクデータも本来の位置へ転送
184 184 ;MOV ESI,0x7c00 ; 転送元
185 185 ;MOV EDI,DSKCAC ; 転送先
189 189 ; asmheadでしなければいけないことは全部し終わったので、
190 190 ; あとはbootpackに任せる
194 194 00000131 66BB[E0010000] MOV EBX, bootpack
195 195 00000137 67668B4B3C MOV ECX, [EBX+0x3C] ; lfanew
196 196 0000013C 6601CB add ebx, ecx ; nt header 32
197 197 0000013F 678B4306 mov ax, [ebx + 6] ; number of section
198 198 00000143 67668B6B28 mov ebp, [ebx + 0x28] ; entry point
199 199 00000148 6681C500002800 add ebp, BOOTPACK_CODE
200 200 0000014F 6681C3F8000000 add ebx, 0xf8 ; section header
202 202 00000156 67668B7B0C mov edi, [ebx + 0x0C] ; virtual addr
203 203 0000015B 67668B4B10 mov ecx, [ebx + 0x10] ; size of raw data
204 204 00000160 67668B7314 mov esi, [ebx + 0x14] ; pointer to raw data
205 205 00000165 6681C700002800 add edi, BOOTPACK_CODE ; このセクションのコピー先
206 206 0000016C 6681C6[E0010000] add esi, bootpack ; コピー元
209 209 00000174 F367A4 a32 rep movsb
213 213 ;rep dword movsb ; f3 a4
216 216 00000177 6681C328000000 add ebx, 0x28 ; section header size
217 217 0000017E 48 dec ax
218 218 0000017F 75D5 jnz readsection
221 221 00000181 66BC00003800 MOV ESP, 0x00380000 ; スタック初期値
223 223 00000187 666810000000 push dword 2*8
224 224 0000018D 6655 push ebp
229 229 0000018F 66CB o32 retf
234 234 ; mov [eax+0x15], ebp
235 235 ; mov dword [eax+0x19], 2*8
241 241 00000191 E464 IN AL,0x64
242 242 00000193 2402 AND AL,0x02
243 243 00000195 E460 IN AL,0x60 ; から読み(受信バッファが悪さをしないように)
244 244 00000197 75F8 JNZ waitkbdout ; ANDの結果が0でなければwaitkbdoutへ
248 248 0000019A 6650 push eax
250 250 0000019C 67668B06 MOV EAX,[ESI]
251 251 000001A0 6681C604000000 ADD ESI,4
252 252 000001A7 67668907 MOV [EDI],EAX
253 253 000001AB 6681C704000000 ADD EDI,4
254 254 000001B2 6681E901000000 SUB ECX,1
255 255 000001B9 75E1 JNZ memcpy_loop ; 引き算した結果が0でなければmemcpyへ
256 256 000001BB 6658 pop eax
258 258 ; memcpyはアドレスサイズプリフィクスを入れ忘れなければ、ストリング命令でも書ける
261 261 000001BE <res 00000002> ALIGNB 16
262 262 ****************** warning: uninitialized space declared in .text section: zeroing
264 264 000001C0 <res 00000008> RESB 8 ; ヌルセレクタ
265 265 ****************** warning: uninitialized space declared in .text section: zeroing
266 266 000001C8 FFFF00000092CF00 db 0xff,0xff,0x00,0x00,0x00,0x92,0xcf,0x00 ; 読み書き可能セグメント32bit
267 267 ;db 0xff,0xff,0x00,0x00,0x28,0x9a,0x4f,0x00 ; 実行可能セグメント32bit(bootpack用)
268 268 000001D0 FFFF0000009ACF00 db 0xff,0xff,0x00,0x00,0x00,0x9a,0xcf,0x00 ; 実行可能セグメント32bit(bootpack用)
270 270 000001D8 0000 DW 0
272 272 000001DA 1700 DW 8*3-1
273 273 000001DC [C0010000] DD GDT0