OSDN Git Service

first commit
[winexe-harib/winexe-harib.git] / haribote / asmhead.asm
1 ; haribote-os boot asm
2 ; TAB=4
3
4
5 VBEMODE EQU 0x118                       ; 1024 x 768 x 24bitカラー
6 BITPERPIXEL EQU 24
7 MEMORYMODEL EQU 6 ; 4ならインデックスカラー 6ならダイレクトカラー
8 ; (画面モード一覧)
9 ;       0x100 :  640 x  400 x 8bitカラー
10 ;       0x101 :  640 x  480 x 8bitカラー
11 ;       0x103 :  800 x  600 x 8bitカラー
12 ;       0x105 : 1024 x  768 x 8bitカラー
13 ;       0x107 : 1280 x 1024 x 8bitカラー
14 ;       0x118 : 1024 x 768 x 24bitカラー
15
16
17 BOOTPACK_CODE EQU 0x00280000            ; bootpackのロード先
18
19 ;DSKCAC EQU             0x00100000              ; ディスクキャッシュの場所
20 ;DSKCAC0        EQU             0x00008000              ; ディスクキャッシュの場所(リアルモード)
21
22 SYSPAGEDIR EQU 0x00100000
23
24 ; BOOT_INFO関係
25 BOOTDRIVE       EQU             0x0ff0                  ; ブートセクタが設定する
26 LEDS    EQU             0x0ff1
27 VMODE   EQU             0x0ff2                  ; 色数に関する情報。何ビットカラーか?
28 SCRNX   EQU             0x0ff4                  ; 解像度のX
29 SCRNY   EQU             0x0ff6                  ; 解像度のY
30 VRAM    EQU             0x0ff8                  ; グラフィックバッファの開始番地
31
32                 ORG             0xc200                  ; このプログラムがどこに読み込まれるのか
33
34 ;ブートデバイスを保存
35                 mov [BOOTDRIVE], dl
36 ; VBE存在確認
37
38                 MOV             AX,0x9000
39                 MOV             ES,AX
40                 MOV             DI,0
41                 MOV             AX,0x4f00
42                 INT             0x10
43                 CMP             AX,0x004f
44                 JNE             scrn320
45
46 ; VBEのバージョンチェック
47
48                 MOV             AX,[ES:DI+4]
49                 CMP             AX,0x0200
50                 JB              scrn320                 ; if (AX < 0x0200) goto scrn320
51
52 ; 画面モード情報を得る
53
54                 MOV             CX,VBEMODE
55                 MOV             AX,0x4f01
56                 INT             0x10
57                 CMP             AX,0x004f
58                 JNE             scrn320
59
60 ; 画面モード情報の確認
61
62                 CMP             BYTE [ES:DI+0x19],BITPERPIXEL
63                 JNE             scrn320
64                 CMP             BYTE [ES:DI+0x1b],MEMORYMODEL
65                 JNE             scrn320
66                 MOV             AX,[ES:DI+0x00]
67                 AND             AX,0x0080
68                 JZ              scrn320                 ; モード属性のbit7が0だったのであきらめる
69
70 ; 画面モードの切り替え
71
72                 MOV             BX,VBEMODE | 0x4000
73                 MOV             AX,0x4f02
74                 INT             0x10
75                 MOV             BYTE [VMODE],BITPERPIXEL        ; 画面モードをメモする(C言語が参照する)
76                 MOV             AX,[ES:DI+0x12]
77                 MOV             [SCRNX],AX
78                 MOV             AX,[ES:DI+0x14]
79                 MOV             [SCRNY],AX
80                 MOV             EAX,[ES:DI+0x28]
81                 MOV             [VRAM],EAX
82                 JMP             keystatus
83
84 scrn320:
85                 MOV             AL,0x13                 ; VGAグラフィックス、320x200x8bitカラー
86                 MOV             AH,0x00
87                 INT             0x10
88                 MOV             BYTE [VMODE],8  ; 画面モードをメモする(C言語が参照する)
89                 MOV             WORD [SCRNX],320
90                 MOV             WORD [SCRNY],200
91                 MOV             DWORD [VRAM],0x000a0000
92
93 ; キーボードのLED状態をBIOSに教えてもらう
94
95 keystatus:
96                 MOV             AH,0x02
97                 INT             0x16                    ; keyboard BIOS
98                 MOV             [LEDS],AL
99
100 ; PICが一切の割り込みを受け付けないようにする
101 ;       AT互換機の仕様では、PICの初期化をするなら、
102 ;       こいつをCLI前にやっておかないと、たまにハングアップする
103 ;       PICの初期化はあとでやる
104
105                 MOV             AL,0xff
106                 OUT             0x21,AL
107                 NOP                                             ; OUT命令を連続させるとうまくいかない機種があるらしいので
108                 OUT             0xa1,AL
109
110                 CLI                                             ; さらにCPUレベルでも割り込み禁止
111
112 ; CPUから1MB以上のメモリにアクセスできるように、A20GATEを設定
113
114                 CALL    waitkbdout
115                 MOV             AL,0xd1
116                 OUT             0x64,AL
117                 CALL    waitkbdout
118                 MOV             AL,0xdf                 ; enable A20
119                 OUT             0x60,AL
120                 CALL    waitkbdout
121                 
122 ;[INSTRSET "i486p"]                             ; 486の命令まで使いたいという記述
123
124 ; プロテクトモード移行
125 ; page size = 4mb or 4kb (混在)  pys addr size = 32 bit
126
127                 LGDT    [GDTR0]                 ; 暫定GDTを設定
128                 MOV             EAX,CR0
129                 ;or eax, 1 << 0x1f ; paging flag
130                 ;AND            EAX,0x7fffffff  ; bit31を0にする(ページング禁止のため)
131                 OR              EAX,0x00000001  ; bit0を1にする(プロテクトモード移行のため)
132                 MOV             CR0,EAX
133                 JMP     pipelineflush
134 pipelineflush:
135 ;ページディレクトリ等の設定
136
137                 xor eax, eax
138                 mov ecx, 0
139                 
140                 align 16
141 pagedirloop:
142                 mov eax, ecx
143                 shl eax, 22
144                 or eax, ((1 << 8)|(1 << 7)|(1 << 1)|1)
145                 mov [SYSPAGEDIR + 4 * ecx], eax
146                 
147                 inc ecx
148                 cmp ecx, 0x400
149                 jb pagedirloop
150
151
152 ;ページングの設定
153                 mov eax, cr3
154                 or eax, SYSPAGEDIR
155                 mov cr3, eax
156                 
157                 mov eax, cr4
158                 and eax, ~(1 << 5) ;  physical addr ext(pae) を無効に
159                 or eax, 1 << 4; enable paging size ext(pse)
160                 mov cr4, eax
161                 
162                 ;TLB無効化?
163                 mov eax, cr3
164                 mov cr3, eax
165                 
166                 MOV             EAX,CR0
167                 or eax, 1 << 0x1f ; paging flag
168                 MOV             CR0,EAX
169                 JMP     pipelineflush2
170 pipelineflush2:
171                 
172                 MOV             AX,1*8                  ;  読み書き可能セグメント32bit
173                 MOV             DS,AX
174                 MOV             ES,AX
175                 MOV             FS,AX
176                 MOV             GS,AX
177                 MOV             SS,AX
178
179
180 ; ついでにディスクデータも本来の位置へ転送
181
182 ; まずはブートセクタから
183
184                 ;MOV            ESI,0x7c00              ; 転送元
185                 ;MOV            EDI,DSKCAC              ; 転送先
186                 ;MOV            ECX,512/4
187                 ;CALL   memcpy
188
189 ; asmheadでしなければいけないことは全部し終わったので、
190 ;       あとはbootpackに任せる
191
192 ; bootpackの起動
193
194                 MOV     EBX, bootpack
195                 MOV     ECX, [EBX+0x3C]   ; lfanew
196                 add ebx, ecx          ; nt header 32
197                 mov  ax, [ebx + 6]    ; number of section
198                 mov ebp, [ebx + 0x28] ; entry point
199                 add ebp, BOOTPACK_CODE
200                 add ebx, 0xf8          ; section header
201 readsection:
202                 mov edi, [ebx + 0x0C] ; virtual addr
203                 mov ecx, [ebx + 0x10] ; size of raw data
204                 mov esi, [ebx + 0x14] ; pointer to raw data
205                 add edi, BOOTPACK_CODE ; このセクションのコピー先
206                 add esi, bootpack      ; コピー元
207                 cld
208                 
209                 a32 rep movsb
210                 ;db 0xf3
211                 ;db 0x67
212                 ;db 0xa4
213                 ;rep dword movsb ; f3 a4
214                 
215                 
216                 add ebx, 0x28 ; section header size
217                 dec ax
218                 jnz readsection
219                 
220
221                 MOV     ESP, 0x00380000 ; スタック初期値
222
223                 push dword 2*8
224                 push ebp
225                 
226                 ;sti
227                 
228                 
229                 o32 retf 
230                 ; call eipload
231 ; eipload:
232                 ; pop ax
233                 ; movzx eax, ax
234                 ; mov [eax+0x15], ebp
235                 ; mov dword [eax+0x19], 2*8
236
237                 ; jmp dword 0:0
238                 ; db 0,0
239
240 waitkbdout:
241                 IN               AL,0x64
242                 AND              AL,0x02
243                 IN               AL,0x60                ; から読み(受信バッファが悪さをしないように)
244                 JNZ             waitkbdout              ; ANDの結果が0でなければwaitkbdoutへ
245                 RET
246
247 memcpy:
248                 push eax
249 memcpy_loop:
250                 MOV             EAX,[ESI]
251                 ADD             ESI,4
252                 MOV             [EDI],EAX
253                 ADD             EDI,4
254                 SUB             ECX,1
255                 JNZ             memcpy_loop                     ; 引き算した結果が0でなければmemcpyへ
256                 pop eax
257                 RET
258 ; memcpyはアドレスサイズプリフィクスを入れ忘れなければ、ストリング命令でも書ける
259
260
261                 ALIGNB  16
262 GDT0:
263                 RESB    8                               ; ヌルセレクタ
264                 db 0xff,0xff,0x00,0x00,0x00,0x92,0xcf,0x00      ; 読み書き可能セグメント32bit
265                 ;db 0xff,0xff,0x00,0x00,0x28,0x9a,0x4f,0x00     ; 実行可能セグメント32bit(bootpack用)
266                 db 0xff,0xff,0x00,0x00,0x00,0x9a,0xcf,0x00      ; 実行可能セグメント32bit(bootpack用)
267
268                 DW              0
269 GDTR0:
270                 DW              8*3-1
271                 DD              GDT0
272
273                 ALIGNB  16
274 bootpack: