とりあえず読み込んでいるようだ
お気楽に、とりあえず、1セクタ分の読み込み機能を実装。
エラー処理やキャンセル処理などは含めていないので、
ちょっと入力を間違えたりしたら大変な事になるような代物。(苦笑)
こういう細かい部分は、自分的には苦手な分野なので、
余裕がある時に、ゆっくり見直す、という事にしておいて、スルー。
ざっくりと、中身を晒してみると...
; レジスタ退避 PUSHA PUSH ES ; 変数領域確保 ; [BP-0A] セクタ (WORD) ; [BP-08] トラック (WORD) ; [BP-06] ドライブ (BYTE) ; [BP-05] ヘッド (BYTE) ; [BP-04] オフセット ; [BP-02] セグメント ; [BP+00] リターンアドレス PUSH BP MOV BP, SP SUB SP, 0x0A
BIOSコールを行うので、全汎用レジスタとESレジスタを退避。
変数領域は、とりあえず、コメントの通り確保。
ヘッド・ドライブは、WORDで扱うと、上位にヘッド、下位にドライブ、となる。
; セクタ単位読み込みコマンド MOV SI, readmsg CALL puts
"SECTOR READ"とか表示する。
; セグメントアドレス入力 MOV SI, segmsg CALL puts MOV CX, 4 CALL gethex MOV [BP-0x02], AX ; セグメント←入力値 ; オフセットアドレス入力 MOV SI, offmsg CALL puts MOV CX, 4 CALL gethex MOV [BP-0x04], AX ; オフセット←入力値 ; ドライブ MOV SI, driveqmsg CALL puts MOV CX, 2 CALL gethex MOV [BP-0x06], AL ; ドライブ←入力値 ; トラック MOV SI, trackqmsg CALL puts MOV CX, 4 CALL gethex MOV [BP-0x08], AX ; トラック←入力値 ; ヘッド MOV SI, headqmsg CALL puts MOV CX, 2 CALL gethex MOV [BP-0x05], AL ; ヘッド←入力値 ; セクタ MOV SI, sectorqmsg CALL puts MOV CX, 2 CALL gethex MOV [BP-0x0A], AX ; セクタ←入力値
各パラメータを入力する。
本当は、それぞれの範囲チェックが必要だと思うけれど、
ドライブ毎に有効な範囲が変わったりするので、自己責任で使って頂く。(爆)
; BIOSサービス呼び出し MOV AX, 0x0201 ; とりあえず1セクタ分 MOV BX, [BP-0x04] ; オフセット MOV CX, [BP-0x08] ; トラック XCHG CH, CL ; CLレジスタとCHレジスタの内容を入れ替える SHL CL, 6 ; CLレジスタの内容を左に6bitシフト MOV DL, [BP-0x0A] ; セクタ AND DL, 0x3F ; 上位2bitをマスク OR CL, DL ; トラック(上位2bit) | セクタ(下位6bit) MOV DX, [BP-0x06] ; ヘッド・ドライブ MOV ES, [BP-0x02] ; セグメント INT 0x13 ; BIOSコール(ディスクサービス)
INT 13h AH=02h ディスク読み込みサービス
ALは、読み込みセクタ数だけど、とりあえず、1セクタ分固定。(おぃおぃ)
BXは、読み込み先アドレスのオフセット。
CXは、ちょっと面倒なんだけど、シリンダ(トラック)10bit分とセクタ6bit分を同居させる。
シリンダ下位8bitは、そのまま、CHレジスタへ格納。
シリンダ上位2bit分とセクタ6bit分は、CCSSSSSSってな感じで、CLレジスタへ格納。
途中の処理では、まだ未使用のDLレジスタを流用して、演算してる。
もうちょっと、エレガントにならんかな?とか思うんだけど、まずは、動かす。
ヘッド・ドライブは、それぞれ、DH,DLレジスタへ格納。
ESは、読み込み先アドレスのセグメント。
どうでも良い話かもしれないが、16進数表記を、13hと0x13と、混在させるのは、ちょっと気持ちが悪い。
が、どちらか一方に統一しようとするのも、実は、なかなか難しい。
きっと、それなりに固い決意で臨めば、それほど難しい話でもないのかもしれないが、
あちこち調べていると、どちらの表記にも、それなりのこだわりがあるようで...
まぁ、きっと、アセンブラ的には、XXh のような気もするけど、
C的な 0xXX も、今や、それなりに、業界標準的な表記で、
どちらかと言えば、0xXX の方が、個人的にも優勢なわけなんだけれど、
それでも、割り込みに関しては、INT 13h、と刷り込まれている部分がある。
本当に、どうでも良い話だな... 苦笑
cmd_read_end: ; 領域開放 MOV SP, BP POP BP POP ES POPA RET
後片付け。
ダンプコマンドで確認してみたところ、ちゃんと読み込んでいるように見える。
ただ、今のところ、QEMU上で、FDベースでの確認のみ。
実機では、FDドライブ未搭載だし、そもそも、CDブートだし。
早いところ、壊しても問題ないHDDを探さないと。
ちなみに、現時点で、無駄なコードも含め、ROSe本体は、5FC(1532)バイト。
1stloaderでは、一応、4KiB(8セクタ分)ロードしているんだけど、まだ半分も使っていないんだなぁ...
1セグメント64KiB(65536バイト)って、今の感覚だと、やっぱり大きい気がする。
まぁ、大した事をやっているわけじゃないので、小さくて当たり前なんだけれど、
ちまたでは、100万行のソースとか、ありふれているような時代だから、
なんだか、ちょっと、時代錯誤的な事をやっているような気分にはなる。(^^;;;
きっと、昔は、みんな、こんな感じだったんじゃないかなぁ?とか思ったりもする。