ブートで遊ぼっ!(7)

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》

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です