     1                                  ; ****************************************************************************
     2                                  ; TRDOS386.ASM (TRDOS 386 Kernel) - v2.0.7 - fat32_bs.s - FAT32 BOOT SECTOR
     3                                  ; ----------------------------------------------------------------------------
     4                                  ; Last Update: 27/04/2024 (Previous: 31/01/2018)
     5                                  ; ----------------------------------------------------------------------------
     6                                  ; Beginning: 13/12/2017
     7                                  ; ----------------------------------------------------------------------------
     8                                  ; Assembler: NASM version 2.11  
     9                                  ; ----------------------------------------------------------------------------
    10                                  ;	    ((nasm fat32_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<rep Ch>              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 0000005C BD007C                  		mov	bp, 7C00h
    86                                  
    87                                  		; ((WINDOWS XP FAT 32 boot sector code checks Masterboot
    88                                  		; partition table for partition type, if it is 0Ch 
    89                                  		; -FAT32 LBA-, the boot code changes 90h at BS offset 2
    90                                  		; to 0Eh. Then a 0Eh at this addr is used as identifier, 
    91                                  		; for reading disk sector by using INT 13h -LBA read- 
    92                                  		; extension.))  
    93                                  
    94 0000005F 3DA101                  		cmp	ax, 417  ; If AX=417, the masterboot sector
    95                                  				 ; has a SINGLIX FS (& TRDOS 386)
    96                                  				 ; masterboot code; and...  
    97                                  				 ; DX=ES=SS=0, BP=7C00h
    98                                  				 ; SP=7C00h ... masterboot sector has
    99                                  				 ; been loaded at 0:600h, it has
   100                                  				 ; CHS parameters at offset 600h+420.
   101                                  				 ; (There is a 01A1h in offset 600h+417)
   102                                  	
   103 00000062 740F                    		je	short bs_01 ; no need to following assignments !
   104                                  
   105 00000064 31C0                    		xor	ax, ax
   106 00000066 8ED8                    		mov	ds, ax
   107 00000068 8EC0                    		mov	es, ax
   108 0000006A FA                      		cli
   109 0000006B 8ED0                    		mov	ss, ax
   110 0000006D 89EC                    		mov	sp, bp
   111 0000006F FB                      		sti
   112 00000070 8A5640                  		mov	dl, [bp+40h] ; [BS_DrvNum]
   113                                  bs_01:
   114 00000073 8936[FC01]              		mov	[bsReserved1], si ; Partition entry address..
   115                                  		; 24/12/2017		  ; (from Singlix FS MBR)
   116                                  					  ; (7BEh,7CEh,7DEh,7EEh) 
   117                                  
   118                                  		; Check Bytes/Sector value
   119                                  		; It must be 512 !? (at least, for TRDOS386) 
   120 00000077 817E0B0002              		cmp	word [bp+0Bh], 512 ; [BPB_BytesPerSec]
   121 0000007C 7578                    		jne	short invalid_system_disk
   122                                  
   123                                  		; Following validation checks (*!*)
   124                                  		; are done according to 
   125                                  		; 	Microsoft Extensible Firmware Initiative
   126                                  		;	FAT32 File System Specification, 
   127                                  		;				Version 1.03 (2000).
   128                                  		
   129                                                  ; [BPB_FATSz16] must be 0 (!*!) ; [bp+16h]
   130 0000007E 6629C9                  		sub	ecx, ecx ; 0 ; *
   131                                                  ;cmp	[BPB_FATSz16], cx ; 0	; sectors/fat for FAT16
   132 00000081 394E16                                  cmp	[bp+16h], cx
   133 00000084 7570                    		jne	short invalid_system_disk
   134                                  
   135                                  		; [BPB_FSVer] must be 0 for current FAT32 version (!*!)
   136                                  		;cmp	[BPB_FSVer], cx   ; 0 	; [bp+2Ah], FAT32 version
   137 00000086 394E2A                  		cmp	[bp+2Ah], cx
   138 00000089 756B                    		jne	short invalid_system_disk
   139                                  
   140                                  		;mov	dh, [bp+5Ah]    ; 0Ch (FAT32 LBA) or 0Bh (FAT32 CHS)
   141                                  			; NOTE: 09h at bp+5Ah (at loc_5A) will be overwritten 
   142                                  			; by TRDOS 386 disk format program.
   143                                  			; (0BC0h -or AX,AX- is written for FAT32 CHS partition, 
   144                                  			; 0C00h -or AL,0- is written for FAT32 LBA partition.)
   145                                  
   146                                  		; overwrite hd drive number !
   147                                                  ;mov	[BS_DrvNum], dl		; drive number from INT 19h
   148 0000008B 885640                  		mov	[bp+40h], dl
   149                                  		;mov	[bp+41h], dh	; [BS_Reserved1] = Partition ID !!!
   150                                  		;mov	[bp+40h], dx	
   151                                  
   152                                  		; reset FAT32 FS reading pointers and set SP to 7BF4h
   153                                  		;xor	ecx, ecx ; *
   154                                  		;sub	ecx, ecx ; *
   155 0000008E 6651                    		push	ecx 	; [bp-4] = 0   ; CHS limit (8.4GB)
   156 00000090 6651                    		push	ecx	; [bp-8] = 0   ; Address of Cluster 2
   157 00000092 6649                    		dec	ecx 	; 0FFFFFFFFh
   158 00000094 6651                    		push	ecx	; [bp-12] = -1	; FAT sector in FAT buffer
   159 00000096 6641                    		inc	ecx	; 0
   160                                  
   161                                  		; SP = 7BF4h
   162                                  
   163                                  		; check for ROMBIOS INT 13h extensions
   164 00000098 B441                    		mov	ah, 41h
   165                                  		;mov	ebx, 55AAh  
   166 0000009A BBAA55                  		mov	bx, 55AAh
   167                                  		;mov	dl, [BS_DrvNum]
   168                                  		;mov	dl, [bp+40h]
   169 0000009D CD13                    		int	13h
   170 0000009F 721A                    		jc	short bs_02
   171 000000A1 81FB55AA                		cmp	bx, 0AA55h
   172 000000A5 7514                    		jne	short bs_02
   173 000000A7 F6C101                  		test	cl, 1
   174 000000AA 740F                    		jz	short bs_02
   175                                  
   176                                  		; ROMBIOS INT 13h extentions are present...
   177                                  
   178 000000AC B8424A                  		mov	ax, 4A42h
   179                                  		;mov	[BS_jmpBoot+2], al ; 42h ; 'LBA mode is available'
   180 000000AF 884602                  		mov	[bp+2], al ; 42h
   181                                  		;cmp	dh, 0Ch ; is this BS of a FAT32 LBA partition? 
   182 000000B2 807E5A0C                		cmp	byte [bp+5Ah], 0Ch
   183 000000B6 7503                    		jne	short bs_02 ; no..
   184                                  		; yes, put sign for disk read subroutine (for LBA read) 
   185                                  		;mov	[loc_5A], ax
   186 000000B8 89465A                  		mov	[bp+5Ah], ax ; INC DX (FAT32 LBA read), DEC DX
   187                                  bs_02:
   188                                  		; ..CHS limit setup..
   189                                  
   190                                  		; Get drive parameters (CHS parameters)
   191                                  		;mov	dl, [BS_DrvNum]
   192                                  		;mov	dl, [bp+40h]
   193 000000BB B408                    		mov	ah, 08h
   194 000000BD CD13                    		int	13h
   195 000000BF 7241                    		jc	short disk_io_error
   196                                  
   197                                  		; CX = maximum value for cylinder and sector
   198                                  		; DH = maximum value for head
   199                                  		; DL = number of harddisks on first controller 			
   200                                  		; ES:DI = address of hard disk parameters table
   201                                  		; (Bits 6&7 of CL is high 2 bits of 10 bit clinder value
   202                                  		; which is low 8 bits are in CH.)
   203                                  
   204 000000C1 1E                      		push	ds
   205 000000C2 07                      		pop	es
   206                                  
   207                                  		; convert CHS values to CHS limit (as LBA)
   208 000000C3 660FB6C6                		movzx	eax, dh
   209 000000C7 40                      		inc	ax
   210                                  		;movzx	edx, cl
   211 000000C8 88CA                    		mov	dl, cl
   212                                  		;and	dl, 3Fh
   213 000000CA 83E23F                  		and	dx, 3Fh
   214 000000CD F7E2                    		mul	dx
   215 000000CF C0E906                  		shr	cl, 6
   216 000000D2 86CD                    		xchg	cl, ch
   217 000000D4 41                      		inc	cx
   218                                  		;movzx	ecx, cx ; *
   219 000000D5 66F7E1                  		mul	ecx
   220 000000D8 668946FC                		mov	[bp-4], eax ; dword [7BFCh] ; CHS limit
   221                                  
   222                                  		; Load the second half (remain bytes) of this boot code
   223                                  		; at 7E00h.
   224                                  
   225 000000DC 668B461C                		mov	eax, [bp+1Ch] ; [BPB_HiddSec]
   226 000000E0 6683C002                		add	eax, 2 ; Second half of boot code is in BS 2
   227                                  		;mov	ebx, 7E00h
   228 000000E4 BB007E                  		mov	bx, 7E00h
   229                                  		;mov	cx, 1
   230                                  		;call	disk_read
   231 000000E7 E83100                  		call	read_sector ; 25/12/2017 (Read 1 sector)
   232 000000EA 7216                    		jc	short disk_io_error
   233                                  
   234                                  		; Boot sector 2 validation check 
   235 000000EC 813EA17FA101            		cmp	word [7FA1h], 417 ; The magic word !
   236 000000F2 0F840C01                		je	check_root_dir_entries
   237                                  
   238                                  invalid_system_disk:
   239 000000F6 BE[A001]                		mov	si, Inv_disk_Msg
   240                                  getchar_reboot:		; 27/04/2024
   241 000000F9 E81100                  		call	print_msg
   242                                  ;getchar_reboot:
   243                                  		; Wait for a keystroke just before reboot
   244 000000FC 30E4                    		xor	ah, ah
   245 000000FE CD16                    		int	16h
   246                                  		
   247 00000100 CD19                    		int	19h	; disk boot	
   248                                  				; causes reboot of disk system
   249                                  disk_io_error:
   250 00000102 BE[8F01]                		mov	si, Diskio_err_Msg
   251 00000105 E80500                  		call	print_msg
   252                                  ;replace_disk:		
   253                                  ;		mov	si, Replace_Msg	
   254                                  replace_disk:	
   255 00000108 BE[B501]                		mov	si, Disk_err_replace_Msg
   256                                  		;call	print_msg
   257                                  		;jmp	getchar_reboot
   258                                  		; 27/04/2024
   259 0000010B EBEC                    		jmp	short getchar_reboot
   260                                  
   261                                  print_msg:
   262                                  		; DS:SI = Error message address (ASCIIZ string)	
   263 0000010D B40E                    		mov	ah, 0Eh
   264 0000010F BB0700                  		mov	bx, 7
   265                                  bs_03:
   266 00000112 AC                      		lodsb
   267 00000113 84C0                    		test	al, al
   268 00000115 741E                    		jz	short bs_04
   269 00000117 CD10                    		int	10h
   270 00000119 EBF7                    		jmp	short bs_03
   271                                  ;bs_04:
   272                                  		;retn
   273                                  
   274                                  read_sector:	; 25/12/2017 (Read 1 sector)
   275 0000011B B90100                  		mov	cx, 1
   276                                  disk_read:
   277                                  		;mov	byte [bp+retry_count-7C00h], 4
   278 0000011E B204                    		mov	dl, 4 ; retry count
   279                                  disk_read_0:
   280 00000120 6660                    		pushad
   281                                  		;cmp	byte [loc_5A], 42h ; FAT32 LBA availability
   282 00000122 B242                    		mov	dl, 42h
   283 00000124 38565A                  		cmp	[bp+5Ah], dl ; 42h ; FAT32 LBA partition & LBA ready
   284 00000127 740D                    		je	short lba_read
   285                                  		; Jump to lba_read if sector addr overs CHS limit
   286 00000129 663B46FC                		cmp	eax, [bp-4] ; CHS limit ([7BFCh])
   287 0000012D 721E                    		jb	short chs_read
   288                                  		; Disk I/O error if Int 13h LBA read func is not usable
   289                                  		; byte [BS_jmpBoot+2] = 'LBA read function is ready' sign 
   290                                  		;cmp	byte [[BS_jmpBoot+2], 42h ; FAT32 LBA availability
   291                                  		;cmp	byte [bp+2], 42h
   292 0000012F 385602                  		cmp	[bp+2], dl ; 42h ; is LBA mode ready ? 
   293 00000132 7402                    		je	short lba_read ; LBA mode is usable/available
   294 00000134 F9                      		stc ; cf = 1
   295                                  		; 27/04/2024
   296                                  bs_04:
   297 00000135 C3                      		retn
   298                                  
   299                                  lba_read:
   300                                  		;pushad
   301                                  
   302                                  		;mov	di, sp
   303                                  		
   304 00000136 666A00                  		push	dword 0
   305 00000139 6650                    		push	eax
   306 0000013B 06                      		push	es
   307 0000013C 53                      		push	bx
   308 0000013D 6A01                    		push 	byte 1
   309 0000013F 6A10                    		push	byte 16 ; 10h
   310                                  		;mov	ah, 42h
   311 00000141 88D4                    		mov	ah, dl ; 42h
   312                                  		;mov	dl, [BS_DrvNum]
   313 00000143 8A5640                  		mov	dl, [bp+40h]
   314 00000146 89E6                    		mov	si, sp
   315 00000148 CD13                    		int	13h
   316                                  
   317                                  		;pop	eax
   318                                  		;pop	eax
   319                                  		;pop	eax
   320                                  		;pop	eax
   321                                  		;mov	sp, di
   322                                  		
   323 0000014A 61                      		popa
   324 0000014B EB2A                    		jmp	short disk_read_1
   325                                  chs_read:	
   326                                  		;pushad
   327                                  
   328                                  		; Convert LBA to CHS
   329 0000014D 6631D2                  		xor	edx, edx
   330                                  		;movzx	ecx, word [BPB_SecPerTrk] ; [bp+18h]
   331                                  				; sectors per track (17 or 63)
   332 00000150 660FB74E18              		movzx	ecx, word [bp+18h]
   333 00000155 66F7F1                  		div	ecx
   334 00000158 FEC2                    		inc	dl	; sector number (1 based)
   335 0000015A 88D1                    		mov	cl, dl
   336 0000015C 6689C2                  		mov	edx, eax ; (heads * cylinder) + head number
   337 0000015F 66C1EA10                		shr	edx, 16	 ; high word in DX, low word in AX	
   338                                  		;div	word [BPB_NumHeads] ; [bp+1Ah]
   339                                  				 ; number of heads (2 to 255)
   340 00000163 F7761A                  		div	word [bp+1Ah]
   341                                  		; AX = cylinder (0 to 1023)
   342                                  		; DX = head number (in DL)
   343 00000166 88D6                    		mov	dh, dl	 ; head number in DH
   344                                  		;mov	dl, [BS_DrvNum] ; [bp+40h] ; Drive number (80h)
   345 00000168 8A5640                  		mov	dl, [bp+40h]
   346 0000016B 88C5                    		mov	ch, al ; Low 8 bits of cylinder number (0 to 7)
   347 0000016D C0E406                  		shl	ah, 6  ; High 2 bits of cylinder is in bit 7&8	
   348 00000170 08E1                    		or	cl, ah ; High two bits of CL is cylinder bits 8&9 
   349 00000172 B80102                  		mov	ax, 201h ; Read 1 sector
   350 00000175 CD13                    		int	13h
   351                                  disk_read_1:
   352 00000177 6661                    		popad
   353 00000179 7305                    		jnc	short disk_read_2
   354                                  		; cf = 1
   355                                  		;dec	byte [retry_count]
   356                                  		;dec	byte [bp+retry_count-7C00h]
   357 0000017B FECA                    		dec	dl ; Retry count
   358 0000017D 75A1                    		jnz	short disk_read_0 ; Retry
   359                                  		; cf = 1		
   360 0000017F C3                      		retn
   361                                  disk_read_2:
   362                                  		;add	bx, [bp+0Bh] ; [BPB_BytesPerSec] ; 512
   363                                  		;add	bx, 512
   364 00000180 80C702                  		add	bh, 2 ; **
   365 00000183 6640                    		inc	eax
   366 00000185 49                      		dec	cx
   367 00000186 7596                    		jnz	short disk_read
   368                                  		;clc 	; ** (128 sectors/cluster!?)
   369 00000188 C3                      		retn
   370                                  
   371                                  		; 27/04/2024
   372                                  		; Filler
   373 00000189 00000000                		dd	0
   374                                  
   375                                  		; Filler
   376 0000018D 07                      		db	07h
   377 0000018E 14                      		db	14h
   378                                  
   379                                  Diskio_err_Msg:
   380 0000018F 0D0A                    		db	0Dh, 0Ah
   381 00000191 4469736B20492F4F20-     		db	'Disk I/O error'
   381 0000019A 6572726F72         
   382                                  		;db	'!'
   383 0000019F 00                      		db	0
   384                                  Inv_disk_Msg:   
   385 000001A0 0D0A                    		db	0Dh, 0Ah
   386 000001A2 496E76616C69642073-     		db	'Invalid system disk'
   386 000001AB 797374656D20646973-
   386 000001B4 6B                 
   387                                  Disk_err_replace_Msg:
   388 000001B5 21                      		db	'!'
   389                                  Replace_Msg:    
   390 000001B6 0D0A                    		db	0Dh, 0Ah
   391 000001B8 5265706C6163652074-     		db	'Replace the disk and press any key to reboot.'
   391 000001C1 6865206469736B2061-
   391 000001CA 6E6420707265737320-
   391 000001D3 616E79206B65792074-
   391 000001DC 6F207265626F6F742E 
   392 000001E5 0D0A00                  		db	0Dh, 0Ah, 0
   393                                  
   394                                  		; Boot sector code writing date (by Erdogan Tan)
   395                                  		;db	31
   396                                  		;db	01
   397                                  		;dw	2018
   398 000001E8 1B                      		db	27
   399 000001E9 04                      		db	04
   400 000001EA E807                    		dw	2024
   401                                  
   402                                  		; TRDOS 386 FAT32 boot sector code version
   403                                  		;db	'v1.0'
   404                                  		; 27/04/2024
   405 000001EC 76322E30                		db	'v2.0'
   406                                  		
   407                                  		times	(508+rtsfilename-bsReserved1) - ($ - $$) db 0
   408                                  rtsfilename:
   409 000001F0 5452444F5333383653-                     db      'TRDOS386SYS'
   409 000001F9 5953               
   410 000001FB 00                                      db      0
   411                                  bsReserved1:
   412 000001FC 5452                    		db	'TR'  ; 'Turkish Rational DOS' feature identifier.
   413                                  bootsignature1:
   414 000001FE 55AA                    		db	55h, 0AAh
   415                                  
   416                                  bsReserved2:
   417 00000200 5254                    		db	'RT'  ; 'Turkish Rational DOS' feature identifier
   418                                  
   419                                  check_root_dir_entries: 
   420                                  		; load root directory and check directory entries 
   421                                  				
   422                                  		; calculate total size of FAT area
   423                                                  ;movzx	ecx, byte [BPB_NumFATs] ; [bp+10h] ; number of FATs
   424 00000202 8A4E10                    		mov	cl, [bp+10h]
   425                                  		;mov	eax, [BPB_FATSz32] ; [bp+24h] ; sectors per FAT
   426 00000205 668B4624                                mov	eax, [bp+24h]
   427 00000209 66F7E1                  		mul     ecx
   428                                                               
   429                                  		; add hidden sectors
   430                                  		;add	eax, [BPB_HiddSec] ; [bp+1Ch]
   431 0000020C 6603461C                		add	eax, [bp+1Ch]
   432                                  
   433                                  		; add reserved sectors
   434                                                  ;movzx	edx, [BPB_RsvdSecCnt] ; [bp+0Eh]
   435                                                  ;mov	dx, [BPB_RsvdSecCnt]
   436 00000210 8B560E                  		mov	dx, [bp+0Eh]
   437 00000213 6601D0                  		add	eax, edx
   438                                  
   439                                  		; Save address of cluster 2 into 7BF8h 
   440 00000216 668946F8                		mov     [bp-8], eax	; EAX = Data Area (Cluster 2)
   441                                                                          ; (Data) Start Address in 7BF8h
   442                                  
   443                                  		; Reset FAT sector address pointer (7BF4h) 
   444                                  		; 	which points to FAT sectors in the FAT buffer
   445                                  		;	(8000h) 
   446                                  		;	
   447                                  		;mov	dword [bp-12], 0FFFFFFFFh ; invalid address 
   448                                  						 ; (for now)
   449                                  
   450                                  		; Check Root Directory Start Cluster is valid or not.
   451                                  		;mov	eax, [BPB_RootClus] ; [bp+2Ch]
   452 0000021A 668B462C                		mov	eax, [bp+2Ch]
   453                                  
   454                                  load_root_dir_sector:
   455                                  		; EAX = Cluster Number
   456                                  
   457                                  		; Cluster number must not be less than 2
   458 0000021E 6683F802                		cmp	eax, 2			  ; Is it Cluster 2?
   459 00000222 0F82D0FE                		jb	invalid_system_disk ; error if less than 2
   460                                  
   461                                                 	; Is it End Of Cluster Chain marker or something above?
   462                                                  ;cmp	eax, 0FFFFFF8h  ; clust 2 to 0FFFFFF7h is valid
   463                                                  ;jnb	invalid_system_disk ; invalid cluster num
   464                                  					      ; or end of cluster chain			
   465                                  		; 23/12/2017
   466                                  		; Note: Bad Cluster number is 0FFFFFF7h !		
   467                                  		; (According to MS FAT32 Specification, 2000, page 18)
   468                                  		; "It is not possible for the bad cluster mark to be
   469                                  		; an allocatable cluster number on FAT12 and FAT16 volumes, 
   470                                  		; but it is feasible for 0x0FFFFFF7 to be an allocatable 
   471                                  		; cluster number on FAT32 volumes.
   472                                  		; To avoid possible confusion by disk utilities, 
   473                                  		; no FAT32 volume should ever be configured such that 
   474                                  		; 0x0FFFFFF7 is an allocatable cluster number."
   475                                  		
   476                                                 	; Is it End Of Cluster Chain marker or something above?
   477 00000226 663DF7FFFF0F                            cmp	eax, 0FFFFFF7h  ; clust 2 to 0FFFFFF6h is valid
   478 0000022C 0F83C6FE                                jnb	invalid_system_disk   ; invalid cluster num
   479                                  					      ; or end of cluster chain	
   480 00000230 6650                    		push	eax
   481 00000232 6683E802                		sub	eax, 2	; 0 based cluster number
   482                                  		;movzx	ebx, byte [BPB_SecPerClus] ; [bp+13]
   483 00000236 660FB65E0D              		movzx	ebx, byte [bp+0Dh]
   484 0000023B 89DE                    		mov	si, bx	; save sector per cluster in SI
   485 0000023D 66F7E3                  		mul	ebx
   486                                  		; EAX = relative sector of the 1st part of root dir 
   487 00000240 660346F8                		add	eax, [bp-8] ; add 'start address of data area'
   488                                  				    ; (in 7BF8h) to relative address
   489                                  bs_05:
   490 00000244 BB0082                  		mov	bx, 8200h  ; Root directory buffer (1 sector)		
   491 00000247 89DF                    		mov	di, bx
   492                                  		;mov	cx, 1
   493                                  		;call	disk_read
   494 00000249 E8CFFE                  		call	read_sector ; 25/12/2017 (Read 1 sector)
   495 0000024C 0F82B2FE                		jc	disk_io_error
   496                                  
   497                                  		; BX = 8400h
   498                                  
   499                                  search_startup_file: 
   500                                  		; check/compare root dir entry for/with kernel file
   501 00000250 382D                    		cmp	[di], ch ; 0
   502 00000252 0F84A0FE                		je	invalid_system_disk ; kernel not found!
   503 00000256 B10B                    		mov	cl, 11 ; 0Bh
   504                                  		; SI = count down value from 'sectors per cluster'
   505 00000258 56                      		push	si ; SPC to 1
   506 00000259 BE[F001]                		mov	si, rtsfilename ; Run Time System file name
   507                                  					; or Kernel file name
   508                                  					; (or Startup file name)
   509                                  					; (or Standalone file name)
   510                                  					; in MSDOS directory entry
   511                                  					; format. ('TRDOS386SYS')
   512                                  					; It is 'TRDOS386.SYS'
   513                                  					; for TRDOS 386 OS.
   514 0000025C F3A6                    		repe	cmpsb ; compare dir entry and kernel's name
   515 0000025E 5E                      		pop	si
   516 0000025F 7475                    		jz	load_startup_file ; kernel is there!
   517 00000261 01CF                    		add	di, cx
   518 00000263 83C715                  		add	di, 21 ; 15h (11+21=32)
   519 00000266 39DF                    		cmp	di, bx ; 8400h
   520 00000268 72E6                    		jb	short search_startup_file ; chk next entry
   521                                  		; Sector Per Cluster countdown
   522 0000026A 4E                      		dec	si 
   523 0000026B 75D7                    		jnz	short bs_05 ; next sector in same cluster
   524 0000026D 6658                    		pop	eax
   525 0000026F E80600                  		call	get_next_cluster
   526 00000272 0F828CFE                		jc	disk_io_error
   527                                  		;; EAX = 32 bit cluster number (32 bit FAT entry)
   528                                  		;and	eax, 0FFFFFFFh ; 28 bit cluster number
   529 00000276 EBA6                    		jmp	short load_root_dir_sector
   530                                  
   531                                  get_next_cluster:	; get next (FAT32) directory/file cluster
   532                                  		; EAX = current cluster number (28 bit, zero based)
   533 00000278 66C1E002                		shl	eax, 2 ; 32 bit FAT entry offset
   534 0000027C E80D00                  		call	get_fat32_entry
   535 0000027F 720A                    		jc	short bs_06 ; Disk read error!
   536 00000281 26668B01                		mov	eax, [es:bx+di]	; 32 bit clust entry number
   537 00000285 6625FFFFFF0F            		and	eax, 0FFFFFFFh	; 28 bit cluster number
   538                                  		;cmp	eax, 0FFFFFF8h
   539                                  		;cmp	eax, 0FFFFFF7h  ; 23/12/2017
   540                                  		;cmc
   541                                  bs_06:
   542 0000028B C3                      		retn
   543                                  
   544                                  get_fat32_entry:
   545                                  		; EAX = 32 bit FAT entry (dword) offset
   546 0000028C BF0080                  		mov	di, 8000h ; FAT (sector) buffer
   547                                  		;movzx	ecx, word [BPB_BytesPerSec] ; [bp+11]
   548                                  		;mov	cx, [BPB_BytesPerSec]
   549                                  		;mov	cx, [bp+0Bh]
   550 0000028F B90002                  		mov	cx, 512
   551                                  		;xor	edx, edx
   552 00000292 31D2                    		xor	dx, dx
   553 00000294 66F7F1                  		div	ecx
   554                                  		; EAX = FAT sector number (relative)
   555                                  		; Check FAT sector number if it is already
   556                                  		; in FAT buffer at 8000h.
   557                                  		; Current FAT sector is in 7BF4h. 
   558                                  		; (Note: initial FAT sector value in 7BF4h is
   559                                  		;	 0FFFFFFFFh which means the buff 
   560                                  		;	 is not loaded yet..)
   561 00000297 663B46F4                		cmp	eax, [bp-0Ch] ; [7BF4h]
   562 0000029B 7431                    		je	short bs_08 ; same sector in FAT buffer
   563 0000029D 668946F4                		mov	[bp-0Ch], eax ; save FAT sector number
   564                                  		; Calculate absolute (LBA) address of FAT sector
   565                                  		; by adding hidden (partition's start sector)
   566                                  		; and reserved sectors (between BS and FAT).
   567                                  		;add	eax, [BPB_HiddSec] ; [bp+1Ch]
   568 000002A1 6603461C                		add	eax, [bp+1Ch]
   569                                  		;movzx	ecx, word [BPB_RsvdSecCnt] ; [bp+0Eh]
   570                                  		;mov	cx, [BPB_RsvdSecCnt] ; = 32 (typically)
   571 000002A5 8B4E0E                  		mov	cx, [bp+0Eh]
   572 000002A8 6601C8                  		add	eax, ecx ; LBA of the FAT sector
   573                                  		; Check FAT mirroring flag..
   574                                  		;	bits 0 to 3 are used for active FAT number 
   575                                  		;	If bit 7 is 1, only one (active) FAT copy
   576                                  		;	is updated (written without mirroring). 
   577                                  		;  (Default active FAT is 0 and default option
   578                                  		;   is to mirror the active FAT -at runtime- into
   579                                  		;	all FAT copies -generally 2 FATs-. 	
   580                                  		;movzx	ebx, word [BPB_ExtFlags] ; [bp+28h]
   581                                  		;mov	bx, [BPB_ExtFlags]
   582 000002AB 8B5E28                  		mov	bx, [bp+28h]
   583 000002AE 83E30F                  		and	bx, 0Fh
   584 000002B1 7414                    		jz	short bs_07	; FAT number 0 is active
   585                                  					; (as default)
   586                                  		; compare active FAT number with number of FATs	
   587                                  		;cmp	bl, [BPB_NumFATs] ; [bp+10h]
   588 000002B3 3A5E10                  		cmp	bl, [bp+10h]
   589 000002B6 7319                    		jnb	short bs_09 ; invalid parameter!
   590 000002B8 52                      		push	dx
   591 000002B9 6689C1                  		mov	ecx, eax
   592                                  		; multiply zero based FAT number with FAT size
   593                                  		;mov	eax, [BPB_FATSz32] ; [bp+24h]
   594 000002BC 668B4624                		mov	eax, [bp+24h]
   595 000002C0 66F7E3                  		mul	ebx
   596 000002C3 6601C8                  		add	eax, ecx   ; start of active FAT copy
   597 000002C6 5A                      		pop	dx
   598                                  bs_07:
   599 000002C7 52                      		push	dx
   600 000002C8 89FB                    		mov	bx, di
   601                                  		;mov	cx, 1
   602                                  		;call	disk_read
   603 000002CA E84EFE                  		call	read_sector ; 25/12/2017 (Read 1 sector)
   604                                  		; If cf = 1 -> Disk I/O err, not invalid sys disk!
   605 000002CD 5A                      		pop	dx
   606                                  bs_08:
   607 000002CE 89D3                    		mov	bx, dx
   608 000002D0 C3                      		retn
   609                                  bs_09:
   610                                  		; Invalid boot sector parameter/data
   611                                  		;add	sp, 4
   612 000002D1 58                      		pop	ax ; return to 'get_next_cluster'
   613 000002D2 58                      		pop	ax ; return to 'search_startup_file'
   614 000002D3 E920FE                  		jmp	invalid_system_disk
   615                                  
   616                                  load_startup_file:
   617                                  		; DI = directory entry offset 9 (of 32 bytes)
   618 000002D6 83C404                  		add	sp, 4 ; pop eax
   619                                  		; High word of First Cluster
   620 000002D9 8B4509                  		mov	ax, [di+9] ; [di+DIR_FstClusHI-11]
   621                                  		; Low word of First Cluster
   622 000002DC 8B550F                  		mov	dx, [di+0Fh] ; [di+DIR_FstClusLO-11]
   623 000002DF 66C1E010                		shl	eax, 16
   624 000002E3 89D0                    		mov	ax, dx
   625                                  		; Valid cluster number must not be less than 2
   626                                  		; and it (a first cluster value in directory entry)
   627                                  		; must not be greater than 0FFFFFF6h. 
   628 000002E5 6683F802                		cmp	eax, 2
   629 000002E9 0F8209FE                		jb	invalid_system_disk
   630                                  		;cmp	eax, 0FFFFFF8h
   631 000002ED 663DF7FFFF0F            		cmp	eax, 0FFFFFF7h ; 23/12/2017
   632 000002F3 0F83FFFD                		jnb	invalid_system_disk
   633                                  
   634 000002F7 6689C1                  		mov	ecx, eax ; save first cluster number
   635                                  
   636                                  		; Load  RTS (Kernel) file
   637 000002FA BE[4F03]                                mov     si, Loading_Msg
   638 000002FD E80DFE                                  call    print_msg
   639                                                  
   640 00000300 6689C8                  		mov	eax, ecx ; restore first cluster number
   641                                  		
   642                                  		;mov	bx, rts_segment ; 1000h
   643                                  		;mov	[next_segment], bx
   644                                  bs_10:
   645 00000303 6650                    		push	eax ; 28 bit cluster num, starts from 2
   646 00000305 6683E802                		sub	eax, 2 ; now, cluster num starts from 0 
   647                                  		;movzx	ecx, byte [BPB_SecPerClus] ; [bp+0Dh]
   648 00000309 660FB64E0D              		movzx	ecx, byte [bp+0Dh]
   649 0000030E 66F7E1                  		mul	ecx
   650                                  		; eax = sector offset (from start of data area)
   651 00000311 660346F8                		add	eax, [bp-8] ; add data area (start) addr
   652 00000315 8B1E[4703]              		mov	bx, [next_segment]
   653 00000319 06                      		push	es
   654 0000031A 8EC3                    		mov	es, bx ; segment = 1000h +
   655 0000031C 31DB                    		xor	bx, bx ; offset = 0 
   656                                  		; CX = num of sectors to read (= sectors/cluster)
   657 0000031E E8FDFD                  		call	disk_read
   658 00000321 07                      		pop	es
   659 00000322 6658                    		pop	eax
   660 00000324 C1EB04                  		shr	bx, 4 ; from byte count to paragraph count
   661 00000327 011E[4703]              		add	[next_segment], bx
   662 0000032B E84AFF                  		call	get_next_cluster
   663                                  		;jc	short diskio_error
   664 0000032E 720E                    		jc	short trdos_loading_error
   665                                  		;cmp	eax, 0FFFFFF8h
   666 00000330 663DF7FFFF0F            		cmp	eax, 0FFFFFF7h ; 23/12/2017
   667 00000336 7351                    		jnb	short bs_11 ; Startup file has been loaded.
   668                                  
   669 00000338 6683F802                		cmp	eax, 2
   670                                  		;jb	invalid_system_disk 
   671                                  		;jmp	short bs_10 ; load next clust of the file
   672 0000033C 73C5                    		jnb	short bs_10
   673                                  
   674                                  trdos_loading_error:
   675 0000033E BE[7303]                		mov	si, Load_err_Msg
   676 00000341 E8C9FD                  		call	print_msg
   677 00000344 E9C1FD                  		jmp	replace_disk
   678                                  next_segment:
   679 00000347 0010                    		dw	rts_segment
   680                                  
   681 00000349 54522D444F53            		db	'TR-DOS' ; Filler
   682                                  		
   683 0000034F 0D0A                    Loading_Msg:    db	0Dh, 0Ah
   684 00000351 4C6F6164696E67204B-     		db	'Loading Kernel TRDOS386.SYS ...'
   684 0000035A 65726E656C20545244-
   684 00000363 4F533338362E535953-
   684 0000036C 202E2E2E           
   685 00000370 0D0A00                                  db 	0Dh, 0Ah, 0
   686                                  Load_err_Msg:
   687 00000373 0D0A                    		db	0Dh, 0Ah
   688 00000375 5452444F53204C6F61-     		db	'TRDOS Loading Error'
   688 0000037E 64696E67204572726F-
   688 00000387 72                 
   689                                  		;db	'!'
   690 00000388 00                      		db	0
   691                                  
   692                                  bs_11:
   693                                  		; Set TRDOS 386 kernel specific parameters (& signs)
   694                                  		; and
   695                                  		; Launch TRDOS 386 Kernel (Startup/RTS file)
   696                                  
   697                                  		;mov	dl, [BS_DrvNum]
   698 00000389 8B5640                                  mov	dx, [bp+40h] ; DL = Drive number, DH = 0 
   699 0000038C FEC6                    		inc	dh  ; TRDOS 386 FAT32 BS major version = 1
   700                                     		
   701 0000038E A1[4703]                		mov	ax, [next_segment] ; 16 paragraphs after the
   702                                  					  ; start of the last segment
   703                                  					  ; of the kernel file loading
   704                                  					  ; space.
   705                                  					  ; So, (top of) stack will have
   706                                  					  ; 256 bytes or more distance
   707                                  					  ; from the last byte
   708                                  					  ; of the kernel file.	 							
   709                                  					  ; (This will be enough for
   710                                  					  ; TRDOS 386 kernel before 
   711                                  					  ; entering protected mode.)
   712 00000391 FA                      		cli
   713 00000392 8ED0                    		mov	ss, ax
   714 00000394 BCFEFF                  		mov	sp, 0FFFEh			
   715 00000397 FB                      		sti
   716                                  
   717 00000398 BB0010                  		mov     bx, rts_segment ; 1000h
   718 0000039B 8EDB                                    mov     ds, bx
   719 0000039D 8EC3                                    mov     es, bx
   720                                  		;mov	fs, bx
   721                                  		;mov	gs, bx 
   722                                  
   723                                  		;xor	ebx, ebx
   724                                  		;xor	ecx, ecx
   725                                  		;xor	edx, edx
   726                                  		;xor	esi, esi
   727                                  		;xor	edi, edi
   728                                  		;xor	ebp, ebp
   729                                  
   730                                  		; bp = 7C00h
   731                                  
   732                                  		; NOTE: Offset 417 in boot sector 2 (the 2nd half of VBR)
   733                                  		; is also FAT32 boot record validation check address and 
   734                                  		; boot sector 2 must have 417 here for boot sector 1 code
   735                                  		; (the 1st half of volume boot record).
   736                                  		; ((So, 'mov eax, 417' has double meaning here.))
   737                                  loc_39F:                
   738 0000039F 66B8A1010000                            mov     eax, 417 ; TRDOS boot sector sign for TRDOS386.SYS
   739                                  
   740 000003A5 EA00000010              		jmp	rts_segment:0
   741                                  
   742 000003AA 00<rep 52h>             		times	1020 - ($ - $$) db 0
   743                                  bsReserved3:
   744 000003FC 5452                    		db	'TR'	; 'Turkish Rational DOS' feature identifier
   745                                  bootsignature2:
   746 000003FE 55AA                    		db	55h, 0AAh
