//See Install Documentation.
//Study the account examples: Config Strs, Update Funs

#include "BootHD"

#help_index "Install"

#define KERNEL_BIN_C    "Kernel.BIN.C"


U0 CompComp()
{
        if (Comp("/Compiler/Compiler", "Compiler",, ':'))
                throw;
}

U0 MakeAll()
{
        CompComp;
        if (Comp("/Kernel/Kernel", "Kernel",, ':'))
                throw;
}

public U0 BootHDIns(U8 drv_let=0)
{//MakeAll and install new boot-loader.
        CDrive          *drive;
        CFAT32Boot       br;
        CDirEntry        de;
        I64                      i;

        try
        {
                if (!Drive(drv_let))
                        throw;

                drive = Fs->cur_dv;
                MakeAll;

                switch (Letter2BlkDevType(drive->drv_let))
                {
                        case BDT_RAM:
                        case BDT_ATA:
                                Move("/Kernel/Kernel.BIN", "/" KERNEL_BIN_C);

                                if (!FileFind("/" KERNEL_BIN_C, &de, FUF_JUST_FILES))
                                        "No Kernel.BIN.C\n";
                                else
                                {
                                        Free(de.full_name);
                                        "Modifying partition boot record.\n";
                                        BlkRead(drive, &br, drive->drv_offset, 1);

                                        br.jump_and_nop[0] = OC_JMP_REL8;
                                        br.jump_and_nop[1] = offset(CFAT32Boot.code) - 2;

#assert offset(CFAT32Boot.code) >= offset(CRedSeaBoot.code)

                                        br.jump_and_nop[2] = OC_NOP;
                                        *BHD_BLK_COUNT(U16 *) = (de.size + BLK_SIZE - 1) >> BLK_SIZE_BITS;
                                        *BHD_DAP_BLK(I64 *) = Clus2Blk(drive, de.clus);

                                        for (i = 0; i < BHD_END - BHD_CODE; i++)
                                                br.code[i] = BHD_CODE(U8 *)[i];

#assert sizeof(CFAT32Boot.code) >= BHD_END - BHD_CODE

                                        for (; i < sizeof(CFAT32Boot.code); i++)
                                                br.code[i] = 0;

                                        BlkWrite(drive, &br, drive->drv_offset, 1);
                                }
                                break;

                        default:
                                throw;
                }
        }
        catch
        {
                PutExcept;
                Beep;
        }
}