1 ; **************************************************************************** 2 ; TRDOS386.ASM (TRDOS 386 Kernel) - v2.0.0 - fat32_bs.s - FAT32 BOOT SECTOR 3 ; ---------------------------------------------------------------------------- 4 ; Last Update: 16/12/2017 5 ; ---------------------------------------------------------------------------- 6 ; Beginning: 13/12/2017 7 ; ---------------------------------------------------------------------------- 8 ; Assembler: NASM version 2.11 9 ; ---------------------------------------------------------------------------- 10 ; ((nasm fats32_bs.s - l fat32_bs.lst -o FAT32_BS.BIN)) 11 ; ---------------------------------------------------------------------------- 12 ; Turkish Rational DOS 13 ; Operating System Project v2.0 by ERDOGAN TAN (Beginning: 04/01/2016) 14 ; 15 ; This boot sector code occupies 2 sectors.. as below: 16 ; * Boot Sector 1: 17 ; The 1st 512 bytes of this boot code will be on sector 0 (of the partition). 18 ; * Boot Sector 2: 19 ; Remain bytes of this boot code will be sector 2 (just after FSINFO sector) 20 ; of the (FAT32) partition. 21 ; 22 ; NOTE: This code has some tricks and TRDOS 386 specific modifications 23 ; which are not a part of original Microsoft Windows (XP) FAT32 BS code. 24 ; (Purpose of TRDOS 386 specific modifications and tricks is 25 ; to load 'TRDOS386.SYS' kernel file as easy and as correct, 26 ; without affecting FAT32 FS recognization for other operating systems.) 27 ; 28 ; Note: Modifications (on WINDOWS 98 FAT32 boot sector code) 29 ; are based on WINDOWS XP FAT32 boot sector(s) code (2 sectors), 30 ; which is disassembled by Erdogan Tan (12/12/2017) 31 ; by using BINFILEHEX (Erdogan Tan) & IDA PRO FREE (Hex-Rays SA) 32 ; programs. 33 ; 34 ; Derived from Microsoft WINDOWS 98 FAT 32 boot sector code 35 ; which is edited/disassembled by Erdogan Tan (04/10/2003). 36 ; 37 ; Derived from 'trfdbs.s' TRDOS 386 FAT12 (3.5") floppy disk boot sector 38 ; source code by Erdogan Tan (06/07/2017). 39 ; **************************************************************************** 40 ; incbin "FAT32_BS.BIN" (in 'hdimage.s' & 'hdformat.s') 41 42 rts_segment equ 1000h 43 44 [BITS 16] 45 [ORG 7C00h] 46 BS_jmpBoot: 47 00000000 EB58 jmp short loc_5A ; jmp short start 48 BS_jmpBoot_nop: 49 00000002 90 nop 50 51 ; BootSector Identification (Data) Block 52 BS_OEMName: 53 00000003 4D5357494E342E31 db 'MSWIN4.1' ; bp+3 54 0000000B 0002 BPB_BytesPerSec: dw 512 ; bp+11 55 0000000D 08 BPB_SecPerClus: db 8 ; bp+13 56 0000000E 2000 BPB_RsvdSecCnt: dw 32 ; bp+14 57 00000010 02 BPB_NumFATs: db 2 ; bp+16 58 00000011 0000 BPB_RootEntCnt: dw 0 ; bp+17 59 00000013 0000 BPB_TotSec16: dw 0 ; bp+19 60 00000015 F8 BPB_Media: db 0F8h ; bp+21 61 00000016 0000 BPB_FATSz16: dw 0 ; bp+22 62 00000018 3F00 BPB_SecPerTrk: dw 63 ; bp+24 63 0000001A FF00 BPB_NumHeads: dw 255 ; bp+26 64 0000001C 01000000 BPB_HiddSec: dd 1 ; bp+28 65 00000020 00000000 BPB_TotSec32: dd 0 ; bp+32 66 00000024 00000000 BPB_FATSz32: dd 0 ; bp+36 67 00000028 0000 BPB_ExtFlags: dw 0 ; bp+40 68 0000002A 0000 BPB_FSVer: dw 0 ; bp+42 69 0000002C 02000000 BPB_RootClus: dd 2 ; bp+44 70 00000030 0100 BPB_FSInfo: dw 1 ; bp+48 71 00000032 0600 BPB_BkBootSec: dw 6 ; bp+50 72 00000034 00 BPB_Reserved: times 12 db 0 ; bp+52 73 00000040 80 BS_DrvNum: db 80h ; bp+64 74 00000041 00 BS_Reserved1: db 0 ; bp+65 75 00000042 29 BS_BootSig: db 29h ; bp+66 76 00000043 00000000 BS_VolID: dd 0 ; bp+67 77 00000047 5452444F5333383620- BS_VolLab: db 'TRDOS386 ' ; bp+71 77 00000050 2020 78 00000052 4641543332202020 BS_FilSysType: db 'FAT32 ' ; bp+82 79 80 start: 81 loc_5A: 82 0000005A 09C0 OR AX, AX ; db 09h, C0h (db 0Bh, C0h) 83 ; TRDOS 386 (FAT32 BS) LBA check trick!! 84 85 ; ((WINDOWS XP FAT 32 boot sector code checks Masterboot 86 ; partition table for partition type, if it is 0Ch 87 ; -FAT32 LBA-, the boot code changes 90h at BS offset 2 88 ; to 0Eh. Then a 0Eh at this addr is used as identifier, 89 ; for reading disk sector by using INT 13h -LBA read- 90 ; extension.)) 91 92 0000005C 3DA101 cmp ax, 417 ; If AX=417, the masterboot sector 93 ; has a SINGLIX FS (& TRDOS 386) 94 ; masterboot code; and... 95 ; DX=ES=SS=0, BP=7C00h 96 ; SP=7C00h ... masterboot sector has 97 ; been loaded at 0:600h, it has 98 ; CHS parameters at offset 600h+420. 99 ; (There is a 01A1h in offset 600h+417) 100 101 0000005F 740F je short bs_01 ; no need to following assignments ! 102 103 00000061 31C0 xor ax, ax 104 00000063 8ED8 mov ds, ax 105 00000065 8EC0 mov es, ax 106 00000067 BD007C mov bp, 7C00h 107 0000006A FA cli 108 0000006B 8ED0 mov ss, ax 109 0000006D 89EC mov sp, bp 110 0000006F FB sti 111 bs_01: 112 ; Check Bytes/Sector value 113 ; It must be 512 !? (at least, for TRDOS386) 114 00000070 817E0B0002 cmp word [bp+0Bh], 512 ; [BPB_BytesPerSec] 115 00000075 757A jne short invalid_system_disk 116 117 ; Following validation checks (*!*) 118 ; are done according to 119 ; Microsoft Extensible Firmware Initiative 120 ; FAT32 File System Specification, 121 ; Version 1.03 (2000). 122 123 ; [BPB_FATSz16] must be 0 (!*!) ; [bp+16h] 124 00000077 6631C0 xor eax, eax ; 0 125 ;cmp [BPB_FATSz16], ax ; 0 ; sectors/fat for FAT16 126 0000007A 394616 cmp [bp+16h], ax 127 0000007D 7572 jnz short invalid_system_disk 128 129 ; [BPB_FSVer] must be 0 for current FAT32 version (!*!) 130 ;cmp [BPB_FSVer], ax ; 0 ; [bp+2Ah], FAT32 version 131 0000007F 39462A cmp [bp+2Ah], ax 132 00000082 756D jnz short invalid_system_disk 133 134 ; overwrite hd drive number ! 135 ;mov [BS_DrvNum], dl ; drive number from INT 19h 136 00000084 885640 mov [bp+40h], dl 137 138 ; reset FAT32 FS reading pointers and set SP to 7BF4h 139 ;xor ecx, ecx ; * 140 00000087 6629C9 sub ecx, ecx ; * 141 0000008A 6651 push ecx ; [bp-4] = 0 ; CHS limit (8.4GB) 142 0000008C 6651 push ecx ; [bp-8] = 0 ; Address of Cluster 2 143 0000008E 6649 dec ecx ; 0FFFFFFFFh 144 ;mov [loc_5A+1], cl ; 0FFh 145 00000090 884E5B mov [bp+5Bh], cl 146 00000093 6651 push ecx ; [bp-12] = -1 ; FAT sector in FAT buffer 147 00000095 6641 inc ecx ; 0 148 149 ; SP = 7BF4h 150 151 ; check for ROMBIOS INT 13h extensions 152 00000097 B441 mov ah, 41h 153 ;mov bx, 55AAh 154 00000099 66BBAA550000 mov ebx, 55AAh 155 ;mov dl, [BS_DrvNum] 156 ;mov dl, [bp+40h] 157 0000009F CD13 int 13h 158 000000A1 720F jc short bs_02 159 000000A3 81FB55AA cmp bx, 0AA55h 160 000000A7 7509 jne short bs_02 161 000000A9 F6C101 test cl, 1 162 000000AC 7404 jz short bs_02 163 164 ; ROMBIOS INT 13h extentions are present... 165 166 ;mov byte [loc_5A], 0Ch ; 'LBA mode is available' 167 000000AE C6465A0C mov byte [bp+5Ah], 0Ch 168 bs_02: 169 ; ..CHS limit setup.. 170 171 ; Get drive parameters (CHS parameters) 172 ;mov dl, [BS_DrvNum] 173 ;mov dl, [bp+40h] 174 000000B2 B408 mov ah, 08h 175 000000B4 CD13 int 13h 176 000000B6 7245 jc short disk_io_error 177 178 ; CX = maximum value for cylinder and sector 179 ; DH = maximum value for head 180 ; DL = number of harddisks on first controller 181 ; ES:DI = address of hard disk parameters table 182 ; (Bits 6&7 of CL is high 2 bits of 10 bit clinder value 183 ; which is low 8 bits are in CH.) 184 185 000000B8 1E push ds 186 000000B9 07 pop es 187 188 ; convert CHS values to CHS limit (as LBA) 189 000000BA 660FB6C6 movzx eax, dh 190 000000BE 40 inc ax 191 ;movzx edx, cl 192 000000BF 88CA mov dl, cl 193 ;and dl, 3Fh 194 000000C1 83E23F and dx, 3Fh 195 000000C4 F7E2 mul dx 196 000000C6 86CD xchg cl, ch 197 000000C8 C0ED06 shr ch, 6 198 000000CB 41 inc cx 199 ;movzx ecx, cx ; * 200 000000CC 66F7E1 mul ecx 201 000000CF 668946FC mov [bp-4], eax ; dword [7BFCh] ; CHS limit 202 203 ; Load the second half (remain bytes) of this boot code 204 ; at 7E00h. 205 206 ; EDX = 0 207 000000D3 6689F0 mov eax, esi 208 000000D6 6683C002 add eax, 2 ; Second half of boot code is in BS 2 209 000000DA 66BB007E0000 mov ebx, 7E00h 210 000000E0 B90100 mov cx, 1 211 000000E3 E83400 call disk_read 212 000000E6 7215 jc short disk_io_error 213 214 ; Boot sector 2 validation check 215 000000E8 BEA101 mov si, 417 216 000000EB 3930 cmp [bx+si], si ; [7E00h+417] = 417 217 000000ED 0F841101 je check_root_dir_entries 218 219 invalid_system_disk: 220 000000F1 BE[9101] mov si, Inv_disk_Msg 221 000000F4 E81400 call print_msg 222 getchar_reboot: 223 ; Wait for a keystroke just before reboot 224 000000F7 30E4 xor ah, ah 225 000000F9 CD16 int 16h 226 227 000000FB CD19 int 19h ; disk boot 228 ; causes reboot of disk system 229 disk_io_error: 230 000000FD BE[8001] mov si, Diskio_err_Msg 231 00000100 E80800 call print_msg 232 ;replace_disk: 233 ; mov si, Replace_Msg 234 replace_disk: 235 00000103 BE[A601] mov si, Disk_err_replace_Msg 236 00000106 E80200 call print_msg 237 00000109 EBEC jmp getchar_reboot 238 239 print_msg: 240 ; DS:SI = Error message address (ASCIIZ string) 241 0000010B B40E mov ah, 0Eh 242 0000010D BB0700 mov bx, 7 243 bs_03: 244 00000110 AC lodsb 245 00000111 84C0 test al, al 246 00000113 7404 jz short bs_04 247 00000115 CD10 int 10h ; - VIDEO - WRITE CHARACTER AND ADVANCE CURSOR (TTY WRITE) 248 ; AL = character, BH = display page (alpha modes) 249 ; BL = foreground color (graphics modes) 250 00000117 EBF7 jmp short bs_03 251 bs_04: 252 00000119 C3 retn 253 254 disk_read: 255 ;mov byte [bp+retry_count-7C00h], 4 256 0000011A B204 mov dl, 4 ; retry count 257 disk_read_0: 258 0000011C 6660 pushad 259 260 ; Jump to lba_read if sector addr overs CHS limit 261 0000011E 663B46FC cmp eax, [bp-4] ; CHS limit ([7BFCh]) 262 00000122 7220 jb short chs_read 263 ; Disk I/O error if Int 13h LBA read func is not usable 264 ; byte [loc_5A+1] = LBA read mode availability sign 265 ;cmp byte [loc_5A], 0Ch ; FAT32 LBA availability 266 00000124 807E5A0C cmp byte [bp+5Ah], 0Ch 267 00000128 7502 jne short lba_read ; LBA mode is usable/available 268 0000012A F9 stc ; cf = 1 269 0000012B C3 retn 270 lba_read: 271 ;pushad 272 273 ;mov di, sp 274 275 0000012C 666A00 push dword 0 276 0000012F 6650 push eax 277 00000131 06 push es 278 00000132 53 push bx 279 00000133 6A01 push byte 1 280 00000135 6A10 push byte 16 ; 10h 281 00000137 B442 mov ah, 42h 282 ;mov dl, [BS_DrvNum] 283 00000139 8A5640 mov dl, [bp+40h] 284 0000013C 89E6 mov si, sp 285 0000013E CD13 int 13h 286 287 ;pop eax 288 ;pop eax 289 ;pop eax 290 ;pop eax 291 ;mov sp, di 292 293 00000140 61 popa 294 00000141 61 popa 295 00000142 EB2A jmp short disk_read_1 296 chs_read: 297 ;pushad 298 299 ; Convert LBA to CHS 300 00000144 6631D2 xor edx, edx 301 ;movzx ecx, word [BPB_SecPerTrk] ; [bp+18h] 302 ; sectors per track (17 or 63) 303 00000147 660FB74E18 movzx ecx, word [bp+18h] 304 0000014C 66F7F1 div ecx 305 0000014F FEC2 inc dl ; sector number (1 based) 306 00000151 88D1 mov cl, dl 307 00000153 6689C2 mov edx, eax ; (heads * cylinder) + head number 308 00000156 66C1EA10 shr edx, 16 ; high word in DX, low word in AX 309 ;div word [BPB_NumHeads] ; [bp+1Ah] 310 ; number of heads (2 to 255) 311 0000015A F7761A div word [bp+1Ah] 312 ; AX = cylinder (0 to 1023) 313 ; DX = head number (in DL) 314 0000015D 88D6 mov dh, dl ; head number in DH 315 ;mov dl, [BS_DrvNum] ; [bp+40h] ; Drive number (80h) 316 0000015F 8A5640 mov dl, [bp+40h] 317 00000162 88C5 mov ch, al ; Low 8 bits of cylinder number (0 to 7) 318 00000164 C0E406 shl ah, 6 ; High 2 bits of cylinder is in bit 7&8 319 00000167 08E1 or cl, ah ; High two bits of CL is cylinder bits 8&9 320 00000169 B80102 mov ax, 201h ; Read 1 sector 321 0000016C CD13 int 13h 322 disk_read_1: 323 0000016E 6661 popad 324 00000170 7305 jnc short disk_read_2 325 ; cf = 1 326 ;dec byte [retry_count] 327 ;dec byte [bp+retry_count-7C00h] 328 00000172 FECA dec dl ; Retry count 329 00000174 75A6 jnz short disk_read_0 ; Retry 330 ; cf = 1 331 00000176 C3 retn 332 disk_read_2: 333 ;add bx, [bp+0Bh] ; [BPB_BytesPerSec] ; 512 334 ;add bx, 512 335 00000177 80C702 add bh, 2 336 0000017A 6640 inc eax 337 0000017C 49 dec cx 338 0000017D 759B jnz short disk_read 339 disk_read_retn: 340 0000017F C3 retn 341 342 Diskio_err_Msg: 343 00000180 0D0A db 0Dh, 0Ah 344 00000182 4469736B20492F4F20- db 'Disk I/O error' 344 0000018B 6572726F72 345 ;db '!' 346 00000190 00 db 0 347 Inv_disk_Msg: 348 00000191 0D0A db 0Dh, 0Ah 349 00000193 496E76616C69642073- db 'Invalid system disk' 349 0000019C 797374656D20646973- 349 000001A5 6B 350 Disk_err_replace_Msg: 351 000001A6 21 db '!' 352 Replace_Msg: 353 000001A7 0D0A db 0Dh, 0Ah 354 000001A9 5265706C6163652074- db 'Replace the disk and press any key to reboot.' 354 000001B2 6865206469736B2061- 354 000001BB 6E6420707265737320- 354 000001C4 616E79206B65792074- 354 000001CD 6F207265626F6F742E 355 000001D6 0D0A00 db 0Dh, 0Ah,0 356 357 000001D9 76312E30 db 'v1.0' 358 000001DD 00 db 0 359 360 000001DE 31362F31322F323031- db '16/12/2017' 360 000001E7 37 361 000001E8 00 db 0 362 363 000001E9 00 times (508+rtsfilename-bsReserved1) - ($ - $$) db 0 364 365 rtsfilename: 366 000001F0 5452444F5333383653- db 'TRDOS386SYS' 366 000001F9 5953 367 000001FB 00 db 0 368 bsReserved1: 369 000001FC 5452 next_segment: db 'TR' ; 'Turkish Rational DOS' feature identifier. 370 ; (Also 'next segment' pointer which 371 ; will be used by kernel loading 372 ; subroutine. Initial value will be 373 ; set to 'rts_segment', it is 1000h 374 ; for current TRDOS 386 kernel.) 375 ; <<14-12-2017, TRDOS 386 v2.0.0>> 376 377 bootsignature1: 378 000001FE 55AA db 55h, 0AAh 379 380 bsReserved2: 381 00000200 5254 db 'RT' ; 'Turkish Rational DOS' feature identifier 382 383 check_root_dir_entries: 384 ; load root directory and check directory entries 385 ; EAX = 0 386 387 ; calculate total size of FAT area 388 ;movzx eax, byte [BPB_NumFATs] 389 ;mov al, [BPB_NumFATs] ; [bp+10h] ; number of FATs 390 00000202 8A4610 mov al, [bp+10h] 391 ;mov ecx, [BPB_FATSz32] ; [bp+24h] ; sectors per FAT 392 00000205 668B4E24 mov ecx, [bp+24h] 393 00000209 66F7E1 mul ecx 394 395 ; add hidden sectors 396 ;add eax, [BPB_HiddSec] ; [bp+1Ch] 397 0000020C 6603461C add eax, [bp+1Ch] 398 399 ; add reserved sectors 400 ;movzx edx, [BPB_RsvdSecCnt] ; [bp+0Eh] 401 ;mov dx, [BPB_RsvdSecCnt] 402 00000210 8B560E mov dx, [bp+0Eh] 403 00000213 6601D0 add eax, edx 404 405 ; Save address of cluster 2 into 7BF8h 406 00000216 668946F8 mov [bp-8], eax ; EAX = Data Area (Cluster 2) 407 ; (Data) Start Addres in 7BF8h 408 409 ; Reset FAT sector address pointer (7BF4h) 410 ; which points to FAT sectors in the FAT buffer 411 ; (8000h) 412 ; 413 ;mov dword [bp-12], 0FFFFFFFFh ; invalid address 414 ; (for now) 415 416 ; Check Root Directory Start Cluster is valid or not. 417 ;mov eax, [BPB_RootClus] ; [bp+2Ch] 418 0000021A 668B462C mov eax, [bp+2Ch] 419 420 load_root_dir_sector: 421 ; EAX = Cluster Number 422 423 ; Cluster number must not be less than 2 424 0000021E 6683F802 cmp eax, 2 ; Is it Cluster 2? 425 00000222 0F82CBFE jb invalid_system_disk ; error if less than 2 426 427 ; Is it End Of Cluster Chain marker or something above? 428 00000226 663DF8FFFF0F cmp eax, 0FFFFFF8h ; clust 2 to 0FFFFFF7h is valid 429 0000022C 0F83C1FE jnb invalid_system_disk ; invalid cluster num 430 ; or end of cluster chain 431 00000230 6650 push eax 432 00000232 6683E802 sub eax, 2 ; 0 based cluster number 433 ;movzx ebx, byte [BPB_SecPerClus] ; [bp+0Dh] 434 00000236 660FB65E0D movzx ebx, byte [bp+0Dh] 435 0000023B 89DE mov si, bx ; save sector per cluster in SI 436 0000023D 66F7E3 mul ebx 437 ; EAX = relative sector of the 1st part of root dir 438 00000240 660346F8 add eax, [bp-8] ; add 'start address of data area' 439 ; (in 7BF8h) to relative address 440 bs_05: 441 00000244 BB0082 mov bx, 8200h ; Root directory buffer (1 sector) 442 00000247 89DF mov di, bx 443 00000249 B90100 mov cx, 1 444 0000024C E8CBFE call disk_read 445 0000024F 0F82AAFE jc disk_io_error 446 447 ; BX = 8400h 448 449 search_startup_file: 450 ; check/compare root dir entry for/with kernel file 451 00000253 382D cmp [di], ch ; 0 452 00000255 0F8498FE je invalid_system_disk ; kernel not found! 453 00000259 B10B mov cl, 11 ; 0Bh 454 ; SI = count down value from 'sectors per cluster' 455 0000025B 56 push si ; SPC to 1 456 0000025C BE[F001] mov si, rtsfilename ; Run Time System file name 457 ; or Kernel file name 458 ; (or Startup file name) 459 ; (or Standalone file name) 460 ; in MSDOS directory entry 461 ; format. ('TRDOS386SYS') 462 ; It is 'TRDOS386.SYS' 463 ; for TRDOS 386 OS. 464 0000025F F3A6 repe cmpsb ; compare dir entry and kernel's name 465 00000261 5E pop si 466 00000262 7478 jz load_startup_file ; kernel is there! 467 00000264 01CF add di, cx 468 00000266 83C715 add di, 21 ; 15h (11+21=32) 469 00000269 39DF cmp di, bx ; 8400h 470 0000026B 72E6 jb short search_startup_file ; chk next entry 471 ; Sector Per Cluster countdown 472 0000026D 4E dec si 473 0000026E 75D4 jnz short bs_05 ; next sector in same cluster 474 00000270 6658 pop eax 475 00000272 E80600 call get_next_cluster 476 00000275 0F8284FE jc disk_io_error 477 ;; EAX = 32 bit cluster number (32 bit FAT entry) 478 ;and eax, 0FFFFFFFh ; 28 bit cluster number 479 00000279 EBA3 jmp short load_root_dir_sector 480 481 get_next_cluster: ; get next (FAT32) directory/file cluster 482 ; EAX = current cluster number (28 bit, zero based) 483 0000027B 66C1E002 shl eax, 2 ; 32 bit FAT entry offset 484 0000027F E80D00 call get_fat32_entry 485 00000282 720A jc short bs_06 ; Disk read error! 486 00000284 26668B01 mov eax, [es:bx+di] ; 32 bit clust entry number 487 00000288 6625FFFFFF0F and eax, 0FFFFFFFh ; 28 bit cluster number 488 ;cmp eax, 0FFFFFF8h 489 ;cmc 490 bs_06: 491 0000028E C3 retn 492 493 get_fat32_entry: 494 ; EAX = 32 bit FAT entry (dword) offset 495 0000028F BF0080 mov di, 8000h ; FAT (sector) buffer 496 ;movzx ecx, word [BPB_BytesPerSec] ; [bp+11] 497 ;mov cx, [BPB_BytesPerSec] 498 ;mov cx, [bp+0Bh] 499 00000292 B90002 mov cx, 512 500 ;xor edx, edx 501 00000295 31D2 xor dx, dx 502 00000297 66F7F1 div ecx 503 ; EAX = FAT sector number (relative) 504 ; Check FAT sector number if it is already 505 ; in FAT buffer at 8000h. 506 ; Current FAT sector is in 7BF4h. 507 ; (Note: initial FAT sector value in 7BF4h is 508 ; 0FFFFFFFFh which means the buff 509 ; is not loaded yet..) 510 0000029A 663B46F4 cmp eax, [bp-0Ch] ; [7BF4h] 511 0000029E 7434 je short bs_08 ; same sector in FAT buffer 512 000002A0 668946F4 mov [bp-0Ch], eax ; save FAT sector number 513 ; Calculate physcial (LBA) address of FAT sector 514 ; by adding hidden (partition's start sector) 515 ; and reserved sectors (between BS and FAT). 516 ;add eax, [BPB_HiddSec] ; [bp+1Ch] 517 000002A4 6603461C add eax, [bp+1Ch] 518 ;movzx ecx, word [BPB_RsvdSecCnt] ; [bp+0Eh] 519 ;mov cx, [BPB_RsvdSecCnt] ; = 32 (typically) 520 000002A8 8B4E0E mov cx, [bp+0Eh] 521 000002AB 6601C8 add eax, ecx ; LBA of the FAT sector 522 ; Check FAT mirroring flag.. 523 ; bits 0 to 3 are used for active FAT number 524 ; If bit 7 is 1, only one (active) FAT copy 525 ; is updated (written without mirroring). 526 ; (Default active FAT is 0 and default option 527 ; is to mirror the active FAT -at runtime- into 528 ; all FAT copies -generally 2 FATs-. 529 ;movzx ebx, word [BPB_ExtFlags] ; [bp+28h] 530 ;mov bx, [BPB_ExtFlags] 531 000002AE 8B5E28 mov bx, [bp+28h] 532 000002B1 83E30F and bx, 0Fh 533 000002B4 7414 jz short bs_07 ; FAT number 0 is active 534 ; (as default) 535 ; compare active FAT number with number of FATs 536 ;cmp bl, [BPB_NumFATs] ; [bp+10h] 537 000002B6 3A5E10 cmp bl, [bp+10h] 538 000002B9 731C jnb short bs_09 ; invalid parameter! 539 000002BB 52 push dx 540 000002BC 6689C1 mov ecx, eax 541 ; multiply zero based FAT number with FAT size 542 ;mov eax, [BPB_FATSz32] ; [bp+24h] 543 000002BF 668B4624 mov eax, [bp+24h] 544 000002C3 66F7E3 mul ebx 545 000002C6 6601C8 add eax, ecx ; start of active FAT copy 546 000002C9 5A pop dx 547 bs_07: 548 000002CA 52 push dx 549 000002CB 89FB mov bx, di 550 000002CD B90100 mov cx, 1 551 000002D0 E847FE call disk_read 552 ; If cf = 1 -> Disk I/O err, not invalid sys disk! 553 000002D3 5A pop dx 554 bs_08: 555 000002D4 89D3 mov bx, dx 556 000002D6 C3 retn 557 bs_09: 558 ; Invalid boot sector parameter/data 559 ;add sp, 4 560 000002D7 58 pop ax ; return to 'get_next_cluster' 561 000002D8 58 pop ax ; return to 'search_startup_file' 562 000002D9 E915FE jmp invalid_system_disk 563 564 load_startup_file: 565 ; DI = directory entry offset 9 (of 32 bytes) 566 000002DC 83C404 add sp, 4 ; pop eax 567 ; High word of First Cluster 568 000002DF 8B7509 mov si, [di+9] ; [di+DIR_FstClusHI-11] 569 ; Low word of First Cluster 570 000002E2 8B7D0F mov di, [di+0Fh] ; [di+DIR_FstClusLO-11] 571 000002E5 89F0 mov ax, si 572 000002E7 66C1E010 shl eax, 10h ; * 65536 573 000002EB 89F8 mov ax, di 574 ; Valid cluster number must not be less than 2 575 ; and it (a first cluster value in directoy entry) 576 ; must not be greater than 0FFFFFFF7h. 577 000002ED 6683F802 cmp eax, 2 578 000002F1 0F82FCFD jb invalid_system_disk 579 000002F5 663DF8FFFF0F cmp eax, 0FFFFFF8h 580 000002FB 0F83F2FD jnb invalid_system_disk 581 582 000002FF 6689C1 mov ecx, eax ; save first cluster number 583 584 ; Load RTS (Kernel) file 585 00000302 BE[7003] mov si, Loading_Msg 586 00000305 E803FE call print_msg 587 588 00000308 6689C8 mov eax, ecx ; restore first cluster number 589 590 0000030B BB0010 mov bx, rts_segment ; 1000h 591 ;mov [next_segment], bx 592 0000030E 899E[FC85] mov [bp+next_segment-7C00h], bx 593 bs_10: 594 00000312 6650 push eax ; 28 bit cluster num, starts from 2 595 00000314 6683E802 sub eax, 2 ; now, cluster num starts from 0 596 ;movzx ecx, byte [BPB_SecPerClus] ; [bp+0Dh] 597 00000318 660FB64E0D movzx ecx, byte [bp+0Dh] 598 0000031D 66F7E1 mul ecx 599 ; eax = sector offset (from start of data area) 600 00000320 660346F8 add eax, [bp-8] ; add data area (start) addr 601 ;mov bx, [next_segment] ; 1000h + 602 00000324 8B9E[FC85] mov bx, [bp+next_segment-7C00h] 603 00000328 06 push es 604 00000329 8EC3 mov es, bx ; segment = 1000h + 605 0000032B 31DB xor bx, bx ; offset = 0 606 ; CL = num of sectors to read (= sectors/cluster) 607 0000032D E8EAFD call disk_read 608 00000330 07 pop es 609 00000331 6658 pop eax 610 00000333 C1EB04 shr bx, 4 ; from byte count to paragraph count 611 ;add [next_segment], bx ; next segment 612 00000336 019E[FC85] add [bp+next_segment-7C00h], bx 613 0000033A E83EFF call get_next_cluster 614 ;jc short diskio_error 615 0000033D 7212 jc short trdos_loading_error 616 0000033F 663DF8FFFF0F cmp eax, 0FFFFFF8h 617 00000345 734D jnb short bs_11 618 619 00000347 6683F802 cmp eax, 2 620 0000034B 0F82A2FD jb invalid_system_disk 621 0000034F EBC1 jmp short bs_10 622 623 trdos_loading_error: 624 00000351 BE[5A03] mov si, Load_err_Msg 625 00000354 E8B4FD call print_msg 626 00000357 E9A9FD jmp replace_disk 627 628 Load_err_Msg: 629 0000035A 0D0A db 0Dh, 0Ah 630 0000035C 5452444F53204C6F61- db 'TRDOS Loading Error' 630 00000365 64696E67204572726F- 630 0000036E 72 631 ;db '!' 632 0000036F 00 db 0 633 634 00000370 0D0A Loading_Msg: db 0Dh, 0Ah 635 00000372 4C6F6164696E67204B- db "Loading Kernel TRDOS386.SYS ..." 635 0000037B 65726E656C20545244- 635 00000384 4F533338362E535953- 635 0000038D 202E2E2E 636 00000391 0D0A00 db 0Dh, 0Ah, 0 637 638 ; End Of File 639 bs_11: 640 ; Set TRDOS 386 kernel specific parameters (& signs) 641 ; and 642 ; Launch TRDOS 386 Kernel (Startup/RTS file) 643 644 ;mov ax, [next_segment] ; 16 paragraphs after the 645 ; start of the last segment 646 ; of the kernel file loading 647 ; space. 648 ; So, (top of) stack will have 649 ; 256 bytes or more distance 650 ; from the last byte 651 ; of the kernel file. 652 ; (This will be enough for 653 ; TRDOS 386 kernel before 654 ; entering protected mode.) 655 00000394 8B86[FC85] mov ax, [bp+next_segment-7C00h] 656 00000398 FA cli 657 00000399 8ED0 mov ss, ax 658 0000039B BCFEFF mov sp, 0FFFEh 659 0000039E FB sti 660 661 ;xor edx, edx 662 663 0000039F 66B8A1010000 mov eax, 417 ; TRDOS boot sector sign for TRDOS386.SYS 664 665 ;mov dl, [BS_DrvNum] 666 000003A5 8A5640 mov dl, [bp+40h] 667 000003A8 BB0010 mov bx, rts_segment ; 1000h 668 000003AB 8EDB mov ds, bx 669 000003AD 8EC3 mov es, bx 670 ;mov fs, bx 671 ;mov gs, bx 672 673 ;xor ebx, ebx 674 ;xor ecx, ecx 675 ;xor esi, esi 676 ;xor edi, edi 677 ;xor ebp, ebp 678 679 000003AF 31DB xor bx, bx 680 000003B1 26FF27 jmp [es:bx] ; 1000h:0000h 681 682 000003B4 00 times 1020 - ($ - $$) db 0 683 bsReserved3: 684 000003FC 5452 db 'TR' ; 'Turkish Rational DOS' feature identifier 685 bootsignature2: 686 000003FE 55AA db 55h, 0AAh