+ mov dword ptr ds:[CurrentDir+dir_clust], eax
+ xor eax, eax
+ xchg eax, dword ptr ds:[si+file_sector]
+ mov dword ptr ds:[CurrentDir+dir_lba], eax
+
+ // Look for the "SETUPLDR.SYS" file.
+ mov di, offset setupldr_sys
+ call searchdir
+ jnz .setupldr_found
+
+ // The SETUPLDR file was not found, so bail out with an error message.
+ mov si, offset no_setupldr_msg
+ call writemsg
+ jmp kaboom
+
+.setupldr_found:
+ // Calculate the rounded up number of 2K sectors that need to be read.
+ mov ecx, eax
+ shr ecx, SECTOR_SHIFT
+ test eax, HEX(7FF)
+ jz .load_setupldr
+ inc ecx
+
+.load_setupldr:
+ // Load the entire SETUPLDR.SYS (parameter CX = FFFFh) to its designated base address FREELDR_BASE.
+ // Using a high segment address with offset 0 instead of segment 0 with offset FREELDR_BASE apparently increases compatibility with some BIOSes.
+ mov bx, FREELDR_BASE / 16
+ mov es, bx
+ xor ebx, ebx
+ mov cx, HEX(FFFF)
+ call getfssec
+
+ // Fetch our stored drive number to DL and set the boot partition to 0 in DH.
+ mov dl, byte ptr ds:[DriveNumber]
+ mov dh, 0
+
+ // Transfer execution to the bootloader.
+ ljmp16 0, FREELDR_BASE
+
+
+/* FUNCTIONS *****************************************************************/
+
+///////////////////////////////////////////////////////////////////////////////
+// Start of BrokenAwardHack --- 10-nov-2002 Knut_Petersen@t-online.de
+///////////////////////////////////////////////////////////////////////////////
+//
+// There is a problem with certain versions of the AWARD BIOS ...
+// the boot sector will be loaded and executed correctly, but, because the
+// int 13 vector points to the wrong code in the BIOS, every attempt to
+// load the spec packet will fail. We scan for the equivalent of
+//
+// mov ax,0201h
+// mov bx,7c00h
+// mov cx,0006h
+// mov dx,0180h
+// pushf
+// call <direct far>
+//
+// and use <direct far> as the new vector for int 13. The code above is
+// used to load the boot code into ram, and there should be no reason
+// for anybody to change it now or in the future. There are no opcodes
+// that use encodings relativ to IP, so scanning is easy. If we find the
+// code above in the BIOS code we can be pretty sure to run on a machine
+// with an broken AWARD BIOS ...
+//
+///////////////////////////////////////////////////////////////////////////////
+award_oldint13:
+ .long 0
+award_string:
+ .byte HEX(0b8),1,2,HEX(0bb),0,HEX(7c),HEX(0b9),6,0,HEX(0ba),HEX(80),1,HEX(09c),HEX(09a)
+
+award_hack:
+ mov si, offset spec_err_msg // Moved to this place from
+ call writemsg // spec_query_failed
+
+ mov eax, dword ptr ds:[HEX(13)*4]
+ mov dword ptr ds:[award_oldint13], eax
+
+ push es
+ mov ax, HEX(F000) // ES = BIOS Seg
+ mov es, ax
+ cld
+ xor di, di // start at ES:DI = f000:0
+award_loop:
+ push di // save DI
+ mov si, offset award_string // scan for award_string
+ mov cx, 7 // length of award_string = 7dw
+ repz cmpsw // compare
+ pop di // restore DI
+ jcxz award_found // jmp if found
+ inc di // not found, inc di
+ jno award_loop
+
+award_failed:
+ pop es // No, not this way :-((
+award_fail2:
+ mov eax, dword ptr ds:[award_oldint13] // restore the original int
+ or eax, eax // 13 vector if there is one
+ jz spec_query_failed // and try other workarounds
+ mov dword ptr ds:[HEX(13)*4], eax
+ jmp spec_query_failed
+
+award_found:
+ mov eax, dword ptr es:[di+HEX(0e)] // load possible int 13 addr
+ pop es // restore ES
+
+ cmp eax, dword ptr ds:[award_oldint13] // give up if this is the
+ jz award_failed // active int 13 vector,
+ mov dword ptr ds:[HEX(13)*4], eax // otherwise change 0:13h*4
+
+ mov ax, HEX(4B01) // try to read the spec packet
+ mov dl, byte ptr ds:[DriveNumber] // now ... it should not fail
+ mov si, offset spec_packet // any longer
+ int HEX(13)
+ jc award_fail2
+
+ jmp found_drive // and leave error recovery code
+///////////////////////////////////////////////////////////////////////////////
+// End of BrokenAwardHack ---- 10-nov-2002 Knut_Petersen@t-online.de
+///////////////////////////////////////////////////////////////////////////////
+