DOS2解析

  データセグメント編    カーネルパッチ編

FAT16のカーネルパッチはこんな風になっています。 アドレスはSTのものですが、アドレスが14hずれている別バージョンがあります。 GTならこのアドレス+1Ehです。 FAT16パッチver 0.03 ;----------------------------- ;FAT読みだし (CALL 2D86h) ;設定  DEにクラスタ番号 ;戻り値 DEに次のクラスタ番号   ;FATRED   PUSH AF CALL CHKDRV JR Z,Z0018 ;FAT16ドライブ POP AF CALL 02D86h ;FAT12ドライブ BIT 7,D RET  Z0018: POP AF CALL FATADR ;FATアドレスを得る JR Z,Z0019 Z0020: XOR A LD (0BBEAh),A LD A,0F2h LD DE,0FFFFh CALL 0368Eh ;エラー処理ルーチン? JR Z,Z0020 JR Z0021 Z0019: PUSH HL LD A,(DE) ;DE = FATアドレス LD L,A INC DE LD A,(DE) LD H,A EX DE,HL ;DE=next cluster LD HL,0FFF7h ;HL=wrong cluster OR A SBC HL,DE POP HL JR NC,Z1021 Z0021: LD DE,0FFFFh OR D ;Z=0 SCF ;Cy=1 RET Z1021: XOR A ;Cy=0 Z=1 RET  ;----------------------------------------------------------- ;クラスタ番号からFATのセクタ番号を求め、Disk Bufferに読み込む ;クラスタ番号からFATのアドレスを得る ;設定  DEにクラスタ番号 ;    HLにデータセグメント内のDPBアドレス ;戻り値 DEにFATアドレス   FATADR: PUSH IX PUSH BC PUSH HL PUSH HL POP IX RES 0,(IY+29h) LD L,(IX+16h) LD H,(IX+17h) XOR A SBC HL,DE JR C,FATAD_ ;エラー LD H,D ;DE=クラスタ番号 LD L,E ADD HL,HL PUSH HL LD E,D LD D,0 LD L,(IX+0Ch) ;FATの先頭のセクタ番号 LD H,(IX+0Dh) ADD HL,DE ;HL = FATのセクタ番号 EX DE,HL CALL BUF_1 ;FATのセクタをBufferに読み込む LD BC,0Bh ADD HL,BC ;HL = Bufferのアドレス POP BC LD A,B AND 01h LD B,A ADD HL,BC ;HL = そのクラスタのFATアドレス EX DE,HL CP A ;Z=1 right FATAD_: POP HL POP BC POP IX RET ;----------------------------------------------------------- ;FAT書き込み     FATWRT: CALL CHKDRV JR Z,FATWR2 ;16bit FAT LD A,B CP 10h JP 2DDAh ;12bit FAT   FATWR2: CALL FATADR ;FATアドレスを得る JR Z,FATWR3 LD A,0FFh LD (0BBEAh),A FATWR4: LD A,0F2h LD DE,0FFFFh CALL 368Eh JR Z,FATWR4 JP 2E35h ;Error FATWR3: PUSH HL LD A,C LD (DE),A ;FAT書き込み INC DE LD A,B LD (DE),A JP 2E0Fh ;------------------------------------------------------------ ;ルートかサブか クラスタ番号のチェック CLST_1: LD D,(HL) ;1534h JR CHECK CLST_2: SET 3,(IY+20h) ;158Bh JR CHECK CLST_3: LD DE,(0BBE6h) ;1C0Dh JR CHECK CLST_4: LD DE,(0BBE8h) ;1C53h JR CHECK CLST_9: LD DE,(0BBE4h) ;1CB1h JR CHECK CLST_8: POP AF ;1B87h POP DE JR CLS_ CLST_5: POP AF ;2F6Fh PUSH BC CLS_: PUSH AF JR CHECK CLST_6: LD DE,(0BBA3h) ;2F9Bh CHECK: LD A,D INC A JR Z,CSTMSB XOR A RET ;z=1 サブディレクトリ CSTMSB: DEC A RET ;z=0 ルートディレクトリ CLST_7: JR NZ,CHECK ;300Dh INC SP INC SP RET ;--------------------------------- CLUST: LD HL,(0B9FAh) ;FCB+20h DPB address CALL CHKDRV RET Z ;FAT16 LD A,(IX+2Ah) JP 39D6h CLUST2: LD HL,(0B9FAh) CALL CHKDRV RET Z ;FAT16 LD A,(IX+1Dh) JP 3CDFh ;------------------------------- ;ドライブチェック ;z=1 FAT16 drive  z=0 FAT12 drive   CHKDRV: PUSH HL PUSH DE LD DE,0008h ADD HL,DE LD A,(HL) LD HL,(DRIVE) CP L JR Z,CHKD_1 CP H CHKD_1: POP DE POP HL RET ;------------------------------------------------------------ ;クラスタ番号をセクタ番号に換算 ;設定:  DE=クラスタ番号 ;戻り値: DE=セクタ番号   GETSEC: LD C,A CALL CHKDRV LD A,C LD BC,000Bh JP NZ,2DBBh   ADD HL,BC LD B,(HL) ;B=クラスタシフト EX DE,HL DEC HL ;クラスタ - 2 DEC HL LD C,A XOR A JR Z0022 Z0023: ADD HL,HL ;セクタ番号bit 0-15 ADC A,A ;セクタ番号bit16-23 Z0022: DJNZ Z0023 LD B,A ;bit16-23 LD A,C ADD A,L LD L,A EX DE,HL ;BDE=セクタ番号 LD A,B LD BC,0009h ADD HL,BC ;DPB+14h データ領域の先頭セクタ LD C,(HL) INC HL LD H,(HL) LD L,C ADD HL,DE JR NC,Z0024 INC A Z0024: EX DE,HL ;BDE=sector number LD (BIT16),A ;bit16-23を保存する OR A POP BC POP HL RET ;---------------------------------------------------------- ;BBB4hのセクタ番号をINC NUM_1: LD (0BBB4h),HL RET NC SECINC: LD A,(BIT16) INC A LD (BIT16),A RET NUM_2: INC (IY+35h) RET NZ JR SECINC ;----------------------------------------------- ;Disk bufferにセクタリード BUF_1: XOR A ;0C22h,2E26h,2E63h,2E80h,2EDCh LD (DSKEX),A ;セクタ番号のbit16-23 JP 2B6Ah   BUF_5: XOR A ;2FBEh LD (BIT16),A LD B,L DEC B DEC DE RET   BUF_4: LD A,(0BBE9h) ;1CFEh Sub? or Root dir? INC A JR Z,BUF_3 LD A,(SUBSEC) JR BUF_   BUF_2: LD A,(BIT16) ;1B34h,26C1h,2FDFh JR BUF_ BUF_3: XOR A ;2ED7h,2F02h BUF_: LD (DSKEX),A JP 2B78h   ;-------------------------------------------------------------- ;ディスクアクセスのためにセクタ番号セットを24ビットでセット RAMRED: PUSH AF ;25CDh LD A,(BIT16) LD (RW_16),A ;セクタ換算したときのbit16-23 LD DE,(0BBB4h) ;セクタ換算したときのbit0-15 POP AF RET     ;------------------------------------------------------------ ;セクタ番号のbit16-23をセット(Disk bufferにリード・ライト) REDBUF: PUSH AF ;2BF8h LD A,(DSKEX) JR REDB_1 WRTBUF: PUSH AF ;2D54h LD A,(IX+0FDh) ;Disk bufferに保存したbit16-23 REDB_1: LD (RW_16),A ;Cにセットするために POP AF JP 0324Fh   ;Disk-romの4010hへ ;--------------------------------- ;Not a dos disk 対策 DSKROM: CP 06h ;34DCh JP NC,3525h ;エラー PUSH AF XOR A ;ブートセクタ、FATを読むためbit16-23=0にする LD (RW_16),A POP AF JP 034E0h   ;-------------------------------------   DRIVE: DB 0,0 ;FAT16 DRIVE BIT16: DB 0 ;ファイルアクセス用 bit16-23 DSKEX: DB 0 ;ディスクバッファ用 bit16-23 SUBSEC: DB 0 ;サブディレクトリ用 bit16-23 RW_16: DB 0 ;call 4010h時のbit16-23 FSTDAT: DS 6 ;ドライブ登録テーブル保存用 SECDAT: DS 6 ;   〃     ;------------------------------------------------------------ ;0FA00h - ;Disk bufferに読み込むセクタのbit16-23を保存する SECNUM: LD A,(DRIVE) ;2BBDh CP C ;C=ドライブ番号 JR Z,SECN_2 LD A,(DRIVE+1) CP C LD A,0 ;FAT12 JR NZ,SECN_1 SECN_2: LD A,(DSKEX) SECN_1: LD C,(IX+11h) LD (HL),C RET ;----------------------------------------------- ;Disk bufferにリード済みかどうか、セクタ番号調べ CMPSEC: ;2C33h INC HL LD A,(HL) SUB D RET NZ ;Z=0 セクタ番号が違う LD A,(DRIVE) CP C JR Z,CMPSE_ LD A,(DRIVE+1) CP C JR Z,CMPSE_ XOR A ;FAT12 drive Disk bufferにリード済み RET CMPSE_: LD A,(DSKEX) ;FAT16 drive COMPAR: INC HL INC HL INC HL CP (HL) ;bit16-23の比較 RET   ;------------------------------------------------------ ;FAT12 driveならメディアID、FAT16 driveならセクタ番号のbit16-23を ;Cレジスタにセットする   SETNUM: PUSH AF ;3540h PUSH HL LD HL,(DRIVE) LD A,(IX+08h) CP L JR Z,SNUM_1 CP H SNUM_1: POP HL JR NZ,MEDIA LD A,(RW_16) ;bit16-23 セット LD C,A POP AF RET MEDIA: LD C,(IX+1Dh) ;Media ID セット POP AF RET ;------------------------------------------------------- ;クラスタ総数の計算 TALCLS: LD A,L OR H JR Z,WINFMT ;ブートセクタの+13h,14hが0ならFAT16フォーマット SBC HL,DE JP 346Fh ;FAT12   WINFMT: LD L,(IX+20h) ;総セクタ数 LD H,(IX+21h) LD A,(IX+22h) OR A SBC HL,DE SBC A,0 WINFM_: DEC C JP Z,3478h SRL A RR H RR L JR WINFM_   ;----------------------------- ;ファイルアクセス時のDisk buffer処理(bufferのフラッシュとか) DSKBUF: SBC HL,BC ;2649h PUSH AF PUSH DE DEC DE DEC DE DEC DE EX DE,HL LD A,(HL) LD HL,(DRIVE) CP L JR Z,DSKB_1 CP H DSKB_1: EX DE,HL POP DE JR Z,CALUC POP AF POP BC JP 264Ch ;FAT12 drive CALUC: POP AF PUSH DE INC DE INC DE INC DE LD A,(DE) LD BC,(BIT16) SBC A,C POP DE POP BC INC A JP NZ,2665h LD A,L ADD A,B JR NC,PAT_40 LD A,0 ADC A,H PAT_40: JP 2642h   ;------------------------------------- GETSUB: CALL 2DB6h ;1CC4h LD A,(BIT16) LD (SUBSEC),A ;Sub dirのセクタ番号bit16-23 RET   SUB_16: INC E ;1CA5h JR NC,SUB_ INC D JR NC,SUB_ LD A,(SUBSEC) INC A LD (SUBSEC),A SUB_: LD A,(0BBE1h) RET ;-------------------------------------- ;セクタ直アクセスのときは、bit16-23を00hに固定 SECABS: XOR A ;2588h LD (BIT16),A JP 2599h
DOS2解析データセグメント編 トップページに戻る