+++ /dev/null
-// fathelp.S\r
-// FAT12/16 Boot Sector Helper Code\r
-// Copyright (c) 1998, 2001, 2002, 2003 Brian Palmer\r
-\r
-//#include <asm.inc>\r
-\r
-//org 8000h\r
-\r
-//.text\r
-\r
-#define BootSectorStackTop HEX(7bf2)\r
-#define DataAreaStartHigh 2\r
-#define DataAreaStartLow 4\r
-#define BiosCHSDriveSizeHigh 6\r
-#define BiosCHSDriveSizeLow 8\r
-#define BiosCHSDriveSize 8\r
-#define ReadSectorsOffset 10\r
-#define ReadClusterOffset 12\r
-#define PutCharsOffset 14\r
-\r
-#define OEMName 3\r
-#define BytesPerSector 11\r
-#define SectsPerCluster 13\r
-#define ReservedSectors 14\r
-#define NumberOfFats 16\r
-#define MaxRootEntries 17\r
-#define TotalSectors 19\r
-#define MediaDescriptor 21\r
-#define SectorsPerFat 22\r
-#define SectorsPerTrack 24\r
-#define NumberOfHeads 26\r
-#define HiddenSectors 28\r
-#define TotalSectorsBig 32\r
-#define BootDrive 36\r
-#define Reserved 37\r
-#define ExtendSig 38\r
-#define SerialNumber 39\r
-#define VolumeLabel 43\r
-#define FileSystem 54\r
-\r
-#define BootPartition HEX(7dfd)\r
-\r
-\r
-// This code will be stored in the first 512 bytes\r
-// of freeldr.sys. The first 3 bytes will be a jmp\r
-// instruction to skip past the FAT helper code\r
-// that is stored in the rest of the 512 bytes.\r
-//\r
-\r
-PUBLIC start\r
-start:\r
- // This code is loaded at 0000:F800 so we have to\r
- // encode a jmp instruction to jump to 0000:FA00\r
- .byte HEX(e9), HEX(fd), HEX(01)\r
-\r
-// Now starts the extra boot code that we will store\r
-// in the first 512 bytes of freeldr.sys. This code\r
-// allows the FAT12/16 bootsector to navigate the\r
-// FAT table so that we can still load freeldr.sys\r
-// even if it is fragmented.\r
-\r
-\r
-FatHelperEntryPoint:\r
- /* First save AX - the start cluster of freeldr.sys */\r
- push ax\r
-\r
- /* Display "Loading FreeLoader..." message */\r
- mov si, offset msgLoading\r
- call word ptr [bp-PutCharsOffset]\r
-\r
- call ReadFatIntoMemory\r
-\r
- /* Restore AX (start cluster) */\r
- pop ax\r
-\r
- // AX has start cluster of freeldr.sys\r
- mov bx, FREELDR_BASE / 16\r
- mov es,bx\r
-\r
-LoadFile:\r
- push ax\r
- call IsFat12\r
- pop ax\r
- jnc LoadFile2\r
- cmp ax, HEX(0ff8) // Check to see if this is the last cluster in the chain\r
- jmp LoadFile3\r
-\r
-LoadFile2:\r
- cmp ax, HEX(0fff8)\r
-LoadFile3:\r
- jae LoadFile_Done // If so continue, if not then read then next one\r
- push ax\r
- xor bx,bx // Load ROSLDR starting at 0000:8000h\r
- push es\r
- call word ptr [bp-ReadClusterOffset]\r
- pop es\r
-\r
- xor bx,bx\r
- mov bl, [bp+SectsPerCluster]\r
- shl bx,5 // BX = BX * 512 / 16\r
- mov ax,es // Increment the load address by\r
- add ax,bx // The size of a cluster\r
- mov es,ax\r
-\r
- call IsFat12\r
- pop ax\r
- push es\r
- jnc LoadFile4\r
- call GetFatEntry12 // Get the next entry\r
- jmp LoadFile5\r
-LoadFile4:\r
- call GetFatEntry16\r
-LoadFile5:\r
- pop es\r
-\r
- jmp LoadFile // Load the next cluster (if any)\r
-\r
-LoadFile_Done:\r
- mov dl, byte ptr [bp+BootDrive] // Load the boot drive into DL\r
- mov dh, byte ptr ds:[BootPartition] // Load the boot partition into DH\r
-\r
- /* continue where other bootsectors start */\r
- jmp start\r
-\r
-\r
-// Reads the entire FAT into memory at 7000:0000\r
-ReadFatIntoMemory:\r
- mov ax, [bp+HiddenSectors]\r
- mov dx, [bp+HiddenSectors+2]\r
- add ax, [bp+ReservedSectors]\r
- adc dx, 0\r
- mov cx, [bp+SectorsPerFat]\r
- mov bx, HEX(7000)\r
- mov es,bx\r
- xor bx,bx\r
- call word ptr [bp-ReadSectorsOffset]\r
- ret\r
-\r
-\r
-// Returns the FAT entry for a given cluster number for 16-bit FAT\r
-// On entry AX has cluster number\r
-// On return AX has FAT entry for that cluster\r
-GetFatEntry16:\r
- mov cx,2 // AX = AX * 2 (since FAT16 entries are 2 bytes)\r
- mul cx\r
- shl dx,12\r
-\r
- mov bx, HEX(7000)\r
- add bx,dx\r
- mov es,bx\r
- mov bx,ax // Restore FAT entry offset\r
- mov ax, es:[bx] // Get FAT entry\r
-\r
- ret\r
-\r
-\r
-// Returns the FAT entry for a given cluster number for 12-bit FAT\r
-// On entry AX has cluster number\r
-// On return AX has FAT entry for that cluster\r
-GetFatEntry12:\r
- push ax\r
- mov cx,ax\r
- shr ax,1\r
- add ax,cx // AX = AX * 1.5 (AX = AX + (AX / 2)) (since FAT12 entries are 12 bits)\r
-\r
- mov bx, HEX(7000)\r
- mov es,bx\r
- mov bx,ax // Put FAT entry offset into BX\r
- mov ax, es:[bx] // Get FAT entry\r
- pop cx // Get cluster number from stack\r
- and cx,1\r
- jz UseLow12Bits\r
- and ax, HEX(0fff0)\r
- shr ax,4\r
- jmp GetFatEntry12_Done\r
-\r
-UseLow12Bits:\r
- and ax, HEX(0fff)\r
-\r
-GetFatEntry12_Done:\r
-\r
- ret\r
-\r
-\r
-// Returns CF = 1 if this is a FAT12 file system\r
-// Otherwise CF = 0 for FAT16\r
-IsFat12:\r
-\r
- mov ebx, dword ptr [bp-DataAreaStartLow]\r
- // EBX now has the number of the starting sector of the data area\r
- // starting from the beginning of the disk, so subtrace hidden sectors\r
- sub ebx, dword ptr [bp+HiddenSectors]\r
-\r
-\r
- xor eax,eax\r
- mov ax, word ptr [bp+TotalSectors]\r
- cmp ax, 0\r
- jnz IsFat12_2\r
- mov eax, dword ptr [bp+TotalSectorsBig]\r
-\r
- // EAX now contains the number of sectors on the volume\r
-\r
-IsFat12_2:\r
- sub eax,ebx // Subtract data area start sector\r
- xor edx,edx // from total sectors of volume\r
-\r
- // EDX:EAX now contains the number of data sectors on the volume\r
- movzx ebx, byte ptr [bp+SectsPerCluster]\r
- div ebx\r
- // EAX now has the number of clusters on the volume\r
- stc\r
- cmp eax,4085\r
- jb IsFat12_Done\r
- clc\r
-\r
-IsFat12_Done:\r
- ret\r
-\r
-\r
-msgLoading:\r
- .ascii "Loading FreeLoader...", CR, LF, NUL\r
-\r
- .org 510 // Pad to 510 bytes\r
- .word HEX(0aa55) // BootSector signature\r
-\r