// OS名長さ
-OS_NAME_LENGTH = osNameTail - osName - 1
+// OS_NAME_LENGTH = osNameTail - osName - 1
// ファイル名長さ
#OS_DIR_NAME_LENGTH = osDirNameTail - osDirName - 1
#KERNEL_DIR_NAME_LENGTH = kernelDirNameTail - kernelDirName - 1
#KERNEL_IMAGE_NAME_LENGTH = kernelImageNameTail - kernelImageName - 1
-KERNEL_IMAGE_PATH_LENGTH = kernelImagePathTail - kernelImagePath
+// KERNEL_IMAGE_PATH_LENGTH = kernelImagePathTail - kernelImagePath
.code16
* 2 バッファのオフセット
* 2 バッファのセグメントセレクタ
* 8 LBA
- */
+ *
exDiscReadData:
structSize: .word 0
readSectors: .word 0
lbaLow: .long 0
lbaHigh: .long 0
exDiscReadDataTail:
-
-/* ■ data セクション ■ */
+*/
+/* ■ data セクション ■ *
.section .data
// OS名
osName: .string OS_NAME
volumeIdSegOfs:
.word PVD_VOLUME_IDENTIFIER
.word ISO_FS_WORK_SEGMENT
+*/
+
/* ■ text セクション ■ */
.section .text
/**
- * ディスク読み取り
- * @return FLAGS.CF 0: 1:
+ * CDからデータ取得
+ * @return FLAGS.CF 0:成功 1:失敗
*/
.global readDataFromCD
readDataFromCD:
- // 初期化
- call init
- // ディスク検索
- call searchDisc
- jc readDataFromCD_error
-
- // パステーブル読み込み
- call readPathTable
- jc readDataFromCD_error
-
- // カーネルファイルを読み込む。
- call readKernelImage
- jc readDataFromCD_error
-
-
- // TODO ファイルシステムを読み込む。
-
-
- // TODO デバイスマネージャを読み込む。
-
-
- // TODO CDドライバを読み込む。
-
-
-readDataFromCD_return:
- ret
-readDataFromCD_error:
- stc // キャリーフラグをセットして、異常終了を通知
- jmp readDataFromCD_return
-
-
-/**
- * 拡張INT13H初期化
- * @global 拡張ディスクリード用データ
- */
-init:
- // 拡張ディスクリード用データ初期化
- movw $(exDiscReadDataTail - exDiscReadData), structSize
- ret
-
-
-/**
- * ディスク検索
- * このOSのディスクを探します。
- * 検索のために、PVDを読み取ります。
- *
- * @global memory0x00060000 PVDデータ
- * @return EFLAGS.CF 0:エラーなし 1:エラーあり
- * @return dl ディスク番号
- */
-searchDisc:
pushw %ax
- pushw %cx
- pushw %dx
+ pushw %bx
pushw %si
pushw %di
- pushw %ds
- pushw %es
-
- // ディスク番号0x80 〜 0xffからPVDを読み取り、
- // このOSのディスクかどうかを調べる
- movb $0x7f, %dl
-searchDisc_checkLoop:
- incb %dl
- // 全てのディスクを読み取っても見つからない場合はエラー。
- jz searchDisc_error
- call exDiscCheck
- jc searchDisc_checkLoop // 拡張int13に対応していなければ次へ。
-
- // PVD 読み取り
- call readPVD
- jc searchDisc_checkLoop // エラーが発生していたら、次へ。
-
- // ボリューム識別子を比較してこのOSのディスクか確認する
- // ds:si と es:di を比較
- movw $OS_NAME_LENGTH, %cx // 比較する長さを指定
- ldsw osNameSegOfs, %si
- lesw volumeIdSegOfs, %di
- repe cmpsb // ボリューム識別子を比較
- // ZFがfalse == 一致していない 場合は、次のディスクからPVDを読み取る
- jnz searchDisc_checkLoop
- // 文字列を全て比較していなければ、次のディスクからPVDを読み取る
- cmpw $0, %cx
- jne searchDisc_checkLoop
- clc // キャリーフラグをクリアして、正常終了を通知
-searchDisc_return:
- popw %es
- popw %ds
- popw %di
- popw %si
- popw %dx
- popw %cx
- popw %ax
- ret
-searchDisc_error:
- stc // キャリーフラグをセットして、異常終了を通知
- jmp searchDisc_return
-
-
-/**
- * 拡張INT13Hの存在確認
- *
- * @param dl ドライブ番号
- * @return FLAGS.CF 0:対応 1:非対応
- */
-exDiscCheck:
- pushw %ax
- pushw %bx
- pushw %cx
- movb $0x41, %ah
- movw $0x55aa, %bx
- int $0x13
- jc exDiscCheck_error
- cmpw $0xaa55, %bx
- jne exDiscCheck_error
- andb $0x01, %cl
- jz exDiscCheck_error
- clc // キャリーフラグをクリアして、正常終了を通知
-exDiscCheck_return:
- popw %cx
- popw %bx
- popw %ax
- ret
-exDiscCheck_error:
- stc // キャリーフラグをセットして、異常終了を通知
- jmp exDiscCheck_return
+ // カーネル、FS、DM、etc..読み込み
+ movw $0x1000, %ax
+ movw %ax, %es
+ movw $0, %bx
+ movw $1, %ax
+ movw $10, %si
+ movw $0, %di
+ call readData
-/**
- * 拡張ディスクリード
- *
- * @param dl ドライブ番号
- * @global 拡張ディスクリード用データ
- * @return FLAGS.CF 0:エラーなし 1:エラーあり
- */
-exDiscRead:
- pushw %ax
- pushw %si
- movw $exDiscReadData, %si
- movw $0x4200, %ax
- int $0x13
+readDataFromCD_return:
+ popw %di
popw %si
+ popw %bx
popw %ax
ret
-/**
- * PVD読み取り
- * PVDをディスクから読み取り、メモリに展開します。
- *
- * @param dl ドライブ番号
- * @return FLAGS.CF 0:エラーなし 1:エラーあり
- */
-readPVD:
- movw $ISO_FS_WORK_SEGMENT, bufSegment
- movw $PVD_BUF_OFFSET, bufOffset
- movw $1, readSectors
- movl $LBA_PVD, lbaLow
- call exDiscRead
- ret
/**
- * ã\83\91ã\82¹ã\83\86ã\83¼ã\83\96ã\83«読み取り
- * パステーブルをディスクから読み取り、メモリに展開します。
- *
- * @param dl ドライブ番号
- * @global PVD(パステーブル情報)
- * @return FLAGS.CF 0:エラーなし 1:エラーあり
+ * ã\83\87ã\83¼ã\82¿読み取り
+ * @param ax LBA(512Byte単位)0ベース
+ * @param si 読み取りセクタ数(512Byte単位)
+ * @param di ドライブ番号
+ * @param es:bx 読み取りデータ格納バッファ
+ * @return FLAGS.CF 0:成功 1:失敗
*/
-readPathTable:
- pushl %eax
- pushl %ebx
- pushw %ds
- // パステーブルサイズ読み取り
- movw $ISO_FS_WORK_SEGMENT, %ax
- movw %ax, %ds
- movl PVD_PATH_TABLE_SIZE, %eax
- // バイトサイズをブロックサイズに変換
- byteToBlock %eax
-
- // パステーブル読み取り
- movl PVD_PATH_TABLE_BASE, %ebx
-
- // 拡張リード用データ構築
- movw $ISO_FS_WORK_SEGMENT, bufSegment
- movw $PT_BUF_OFFSET, bufOffset
- movw %ax, readSectors
- movl %ebx, lbaLow
- call exDiscRead
-
- popw %ds
- popl %ebx
- popl %eax
- ret
-
-
-/**
- * パステーブルレコード取得
- *
- * @param es:di ファイルパスの先頭アドレス (例:"/TryOS/Kernel/TryKernel.img")
- * @param cx ファイルパスの文字列長
- * @return FLAGS.CF 0:エラーなし 1:エラーあり
- * @return (成功時)es:bx 該当パステーブルレコードの先頭アドレス
- */
-getPathRecord:
- pushw %ax
+readData:
pushw %cx
pushw %dx
- pushw %si
- pushw %ds
- // セグメントセレクタをセット
- movw $ISO_FS_WORK_SEGMENT, %ax
- movw %ax, %ds
+ #論理セクタをCHSに変換
+ xorw %dx, %dx
+ movw $18, %cx
+ divw %cx // 論理セクタ(ax) / 18 = シリンダ * 2 (ax) 余りセクタ(dx)
+ movb %dl, %cl // セクタ
+ movw %di, %dx // ドライブ(下位8ビットのみ)
+ movb %al, %ch // シリンダ
+ shrb %ch // シリンダ
+ movb %al, %dh // ヘッド
+ andb $1, %dh // ヘッド
- // cx初期化
- //(cxはファイルパス全体の長さと
- // それぞれのディレクトリ名の長さとして使っているため、
- // 少し複雑になっています。)
- pushw %cx
- xorw %cx, %cx
-
- movw $PT_BUF_OFFSET, %bx // 読み取り位置
- xorb %dl, %dl
-
-
-// 次のエントリへ
-getPathRecord_nextDown:
- incb %dl // 親ディレクトリ番号
+readData_readLoop:
- // ▼ファイルパスの操作
- movw %cx, %ax // 前のディレクトリ名の長さ
- incw %ax // '/'分増やす
- // 前のディレクトリ名の長さ分diを進め、cxを減らす。
- popw %cx // 前のディレクトリ名の先頭からパスの終わりまでのサイズ
- addw %ax, %di // 現在のディレクトリ名の先頭アドレス
- subw %ax, %cx // 現在のディレクトリ名の先頭からパスの終わりまでのサイズ
+ incb %cl // セクタをインクリメント(1ベースのため、これで良い。)
+ movw $0x0201, %ax // ah:読み取りモード, al:セクタ数
- // 現在のディレクトリ名の長さを取得する。
- pushw %di
- pushw %cx
- movb $'/', %al
- repne scasb
- movw %cx, %ax
- popw %cx
- popw %di
- // 終端までいったら終わり
- jnz getPathRecord_success // ZF = scasbの結果
- pushw %ax // ディレクトリの先頭からパスの終わりまでのサイズ
- // ディレクトリ名のサイズをcxへ。
- subw %ax, %cx
- decw %cx // '/'分引く
- // ▲ファイルパスの操作
-
-// ディレクトリ検索
-getPathRecord_findDirectory:
- // ▼パステーブルの操作
- // 次のエントリへ。
- addw (%bx), %bx // ディレクトリ名分足す。
- addw $9, %bx // パステーブルの固定長分足す。(1+1+4+2+1=9)
- andw $0xfffe, %bx // 偶数にする
- // ディレクトリ名の長さが0なら終了と判断。
- movw (%bx), %ax
- orw %ax, %ax
- jz getPathRecord_error
- // ディレクトリ名の長さが一致しなければ次へ
- cmpw %ax, %cx
- jne getPathRecord_findDirectory
- // エントリ情報の取得
- cmpb 6(%bx), %dl
- jb getPathRecord_findDirectory // 6(%bx) > %dl 自番号が親より小さければ次へ
- ja getPathRecord_error // 6(%bx) < %dl 自番号より親番号が大きい場合は異常
- movw %bx, %si
- addw $8, %si // ディレクトリ名の先頭位置
- // ▲パステーブルの操作
-
- // 親番号一致
- // ディレクトリ名がstrと一致したら次の階層へ
- pushw %di
- pushw %cx
- repe cmpsb
- popw %cx
- popw %di
- // 一致したら次の階層へ
- jz getPathRecord_nextDown // ZF = cmpsbの結果
- // 一致しなければ次のエントリへ
- jmp getPathRecord_findDirectory
+ // 読み取り
+ int $0x13
+ jc readData_return // 異常終了
+ // 指定のセクタ数読み取ったら終了
+ decw %si
+ jz readData_success
-getPathRecord_success:
- movw %ds, %ax
+ // バッファアドレスを進める
+ movw %es, %ax
+ addw $0x20, %ax
movw %ax, %es
- clc // キャリーフラグをクリアして、正常終了を通知
-getPathRecord_return:
- popw %ds
- popw %si
- popw %dx
- popw %cx
- popw %ax
- ret
-getPathRecord_error:
- stc // キャリーフラグをセットして、異常終了を通知
- jmp getPathRecord_return
-
-
-/*
- * ファイル読み取り
- *
- * @param dl ドライブ番号
- * @param ディレクトリレコードのLBA
- * @param ファイル名の先頭アドレス
- */
-readFile:
-
-TODO ここから。
- call exDiscRead
-
-readFile_success:
- clc // キャリーフラグをクリアして、正常終了を通知
-readFile_return:
- ret
-readFile_error:
- stc // キャリーフラグをセットして、異常終了を通知
- jmp readFile_return
-
-
-/**
- * カーネルイメージ読み取り
- *
- * @param dl ドライブ番号
- */
-readKernelImage:
- pushw %cx
- pushw %di
- movw $kernelImagePath, %di
- movw $KERNEL_IMAGE_PATH_LENGTH, %cx
- call getPathRecord
- jc readKernelImage_error
+ // 18セクタ(1シリンダ)読んでいなければもう一度
+ cmpb $18, %cl
+ jb readData_readLoop
- readFile
+ // セクタ番号とシリンダ番号とヘッド番号の設定
+ xorb %cl, %cl // セクタ番号リセット
+ addb %dh, %ch // シリンダ番号を加算(表なら+0, 裏なら+1)
+ xorb $1, %dh // ヘッド番号を反転
+ // もう一回。
+ jmp readData_readLoop
- jmp halt
+readData_success:
+ clc // 正常終了
-readKernelImage_success:
- clc // キャリーフラグをクリアして、正常終了を通知
-readKernelImage_return:
- popw %di
+readData_return:
+ popw %dx
popw %cx
ret
-readKernelImage_error:
- stc // キャリーフラグをセットして、異常終了を通知
- jmp readKernelImage_return
-/*
-
- // Eint13でデータ読み込み(ISO 9660を読む)
- // TODO
-
- // プロテクトモードに移行
- call SwitchProtectMode
-
- // 1MiBラインにデータを移動
- // TODO
-
- // リアルモードに移行
- call SwitchRealMode
-
-*/