86系のPCをブートさせて遊んでみよう、というお話の7回目になります。テキストは『OSを書く:初歩から一歩ずつ』です。
環境はAMD64+Windows10+VMware Workstation 17 Player+Debian 12.4です。
テキストの練習問題もこれで最後です。
頑張りましゅっ(噛んだ)
6. BIOSからキー押下情報を取り込む。
キーボードからの入力を得ることができれば、いろんな事が出来そうです。
期待が膨らみます。
使うBIOSコールは0x16。設定値は無し。キーが押されるとahとalに値が入って戻ってくるみたいです。ソースはこんな感じ?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | ; boot.asm ; mov ax, 0x07c0 mov ds, ax mov ah, 0x0 mov al, 0x3 int 0x10 mov ah, 0x00 int 0x16 mov cx, ax mov ch, 0x00 mov bx, 10 loop: mov dx, 0 mov ax, cx div bx mov cx, ax mov ah, 0x0e mov al, dl add al, 0x30 int 0x10 cmp cx, 0 jne loop jmp hang [text] ; end of proccess ; hang: jmp hang times 510-($-$$) db 0 db 0x55 db 0xAA |
PlayWithBoot.6.1
実行すると、こんな感じ。
これはエンターを押した場合のalの値ですね。
なんだか簡単に終わってしまった?
一応、練習問題はこれで終わりですけど、これだけだと寂しいので、少し遊んでみましょう。
おまけ
せっかくなので練習問題の1から6まで、一つにまとめてみました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 | ; boot.asm ; mov ax, 0x07c0 mov ds, ax mov ah, 0x0 mov al, 0x3 int 0x10 ; practice 1 (print other) mov ax, p1_title call print_str mov al, 1 mov ah, 0x0e add al, 0x30 int 0x10 mov ax, crlf call print_str call print_str ; practice 2 (add 2 num) mov ax, p2_title call print_str mov ax, p2_msg call print_str mov bh, 1 mov bl, 3 add bl, bh mov ah, 0x0e mov al, bl add al, 0x30 int 0x10 mov ax, crlf call print_str call print_str ; practice 3 (add 1 to 100 and print it) mov ax, p3_title call print_str mov bx, 0 mov ax, 0 add_loop: add ax, bx add bx, 1 cmp bx, 100 jle add_loop mov bx, ax print_loop: mov dx, 0 mov ax, bx mov bx, 10 div bx mov bx, ax mov ah, 0x0e mov al, dl add al, 0x30 int 0x10 cmp bx, 0 jne print_loop mov ax, crlf call print_str call print_str ; practice 4 (print valu in address) mov ax, p4_title call print_str mov ax, 0x0000 mov bx, _test mov byte al, [bx] mov bx, ax p4_loop: mov dx, 0 mov ax, bx mov bx, 10 div bx ;mov cx, dx mov bx, ax mov ah, 0x0e mov al, dl add al, 0x30 int 0x10 cmp bx, 0 jne p4_loop mov ax, crlf call print_str call print_str ; practice 5 (read disk) mov ax, p5_title call print_str mov ax, 0x07c0 mov es, ax mov bx, 512 mov ah, 0x02 ; Read Sectors From Drive mov dl, 0x80 ; Drive mov al, 0x01 ; Sectors To Read Count ; mov ch, 0x00 ; Cylinder mov cl, 0x02 ; Sector(starts from 1, not 0) ; set 2. becouse not need MBR mov dh, 0x00 ; Head int 0x13 ; Execute disk read mov ax, 512 call print_str mov ax, crlf call print_str call print_str ; practice 6 (key read) mov ax, p6_title call print_str mov ax, p6_msg call print_str mov ah, 0x00 int 0x16 mov bx, ax mov bh, 0 p6_loop: mov dx, 0 mov ax, bx mov bx, 10 div bx mov bx, ax mov ah, 0x0e mov al, dl add al, 0x30 int 0x10 cmp bx, 0 jne p6_loop jmp hang ; end of proccess ; hang: jmp hang p1_title: db 'practice 1 (print other)', 0x0a, 0x0d, 0x0a, 0x0d, 0x00 p2_title: db 'practice 2 (add 2 num)', 0x0a, 0x0d, 0x0a, 0x0d, 0x00 p2_msg: db '1 + 3 : ', 0x00 p3_title: db 'practice 3 (add 1 to 100 and print it)', 0x0a, 0x0d, 0x0a, 0x0d, 0x00 p4_title: db 'practice 4 (print valu in address)', 0x0a, 0x0d, 0x0a, 0x0d, 0x00 p5_title: db 'practice 5 (read disk)', 0x0a, 0x0d, 0x0a, 0x0d, 0x00 p6_title: db 'practice 6 (key read)', 0x0a, 0x0d, 0x0a, 0x0d, 0x00 p6_msg: db 'ascii code : ', 0x00 crlf: db '', 0x0a, 0x0d, 0x00 _test: db 0x15, 0x00 print_str: push ax push si mov si, ax mov ah, 0x0E loop: lodsb or al, al jz loop_end int 0x10 jmp loop loop_end: pop si pop ax ret times 510-($-$$) db 0 db 0x55 db 0xAA top_of_2nd_sector: db 'Hello Sector No.1', 0x0d, 0x0a, 0x00 times 1024-($-$$) db 0 |
PlayWithBoot.6.2
実行すると、こんな感じです。
これで一通りやり切しました。
他にもやりようはあるし、数値の表示を左からきちんと表示するとか、手を加えられるところも沢山あると思います。
そのあたり、気になった部分はそれそれ直してみていただければと。
一連のソースですが、githubに上げてみました。素の設定なので公開されている筈です。よろしければ覗いてやってください。
https://github.com/cbwb-inc/software/PlayWithBoot
かなり時間がかかってしまいましたが、『ブートで遊ぼっ!』これにて終了です。
物凄く楽しかった♪
《2024/5/9 12:30:24》