86系のPCをブートさせて遊んでみよう、というお話の7回目になります。テキストは『OSを書く:初歩から一歩ずつ』です。
環境はAMD64+Windows10+VMware Workstation 17 Player+Debian 12.4です。
テキストの練習問題もこれで最後です。
頑張りましゅっ(噛んだ)
6. BIOSからキー押下情報を取り込む。
キーボードからの入力を得ることができれば、いろんな事が出来そうです。
期待が膨らみます。
使うBIOSコールは0x16。設定値は無し。キーが押されるとahとalに値が入って戻ってくるみたいです。ソースはこんな感じ?
; 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まで、一つにまとめてみました。
; 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》