U0 SysGlobalsInit()
{
    I64             i, j;
    CRAXRBXRCXRDX   regs;

    CPUId(0x1, &regs);
    sys_cache_line_width = regs.rbx.u8[1] * 8;

    sys_focus_task = Fs;
    QueueInit(&sys_macro_head);

    blkdev.default_iso_filename     = SysStrNew(DEFAULT_ISO_FILENAME);
    blkdev.default_iso_c_filename   = SysStrNew(DEFAULT_ISO_C_FILENAME);
    blkdev.tmp_filename             = SysStrNew("~/Tmp.DD");
    blkdev.dvd_boot_is_good         = TRUE;

    #exe
    {
        if (!kernel_config->mount_ide_auto_hd_let)
            kernel_config->mount_ide_auto_hd_let = 'C';

        if (!kernel_config->mount_ide_auto_cd_let)
            kernel_config->mount_ide_auto_cd_let = 'T';

        StreamPrint("blkdev.first_hd_drive_let  = %d;", kernel_config->mount_ide_auto_hd_let);
        StreamPrint("blkdev.first_dvd_drive_let = %d;", kernel_config->mount_ide_auto_cd_let);
    }

    DebugMode(ON);

    rev_bits_table = CAlloc(256);

    for (i = 0; i < 256; i++)
        for (j = 0; j < 8; j++) 
            if (Bt(&i, 7 - j))
                Bts(rev_bits_table + i, j);

    ext = CAlloc(EXT_EXTS_NUM * sizeof(U8 *));
    fp_getstr2 = &SysGetStr2;
    KeyDevInit;

    #exe
    {
        StreamPrint("blkdev.boot_drive_let = '%C';", kernel_config->boot_drive_let);

        StreamPrint("#exe{ Option(OPTf_WARN_PAREN, OFF); }");

        StreamPrint("DiskCacheInit(%s);", kernel_config->disk_cache_size_exp);

        StreamPrint("#exe{ Option(OPTf_WARN_PAREN, ON); }");
    };

    pow10_I64 = CAlloc(sizeof(F64) * (308 + 308 + 1));
    for (i = -308; i < 309; i++)
        pow10_I64[i + 309] = Pow10(i);

    QueueInit(&screencast.sound_head);
    screencast.t0_now   = Now;
    screencast.t0_tS    = tS;
    screencast.ona = screencast.sound_head.ona = 0;

    ProgressBarsReset;

    QueueInit(&dev.pci_head);
    dev.mem64_ptr = mem_mapped_space;

    debug.fun_seg_cache  = CAlloc(FUN_SEG_CACHE_SIZE * sizeof(CFunSegCache));
    debug.int_fault_code = IntFaultHandlersNew;
}

U0 SysGrInit()
{
    I64 i;

    text.font = sys_font_std;

    text.aux_font = sys_font_aux;

    //patch some chars
    text.aux_font[10]   = text.font[10]; //"Return" symbol 
    text.aux_font[255]  = text.font[255]; //Block symbol .

    for (i = '.'; i < '.'; i++)
        text.aux_font[i] = text.font[i];

    text.aux_font['.'] = text.font['.'];
    
    text.border_chars[2] (I64) = '........';
    text.border_chars[10](U32) = '....';

    text.cols = sys_framebuffer_width  / FONT_WIDTH;
    text.rows = sys_framebuffer_height / FONT_HEIGHT;

    text.screen_size    = sys_framebuffer_width * sys_framebuffer_height;
    text.buffer_size    = text.screen_size * 4; //buffer for 32-bit, but only 16 colors now.
    text.raw_screen     = CAlloc(text.buffer_size);
    text.fb_alias       = sys_framebuffer_addr;

    MemSetU32(text.fb_alias, BLACK32, text.screen_size);
}

U0 TimerInit()
{//See ::/Doc/PIT.DD.
    OutU8(PIT_CMD, PIT_CMDF_CHANNEL0 | PIT_CMDF_OPMODE_RATE_GEN | PIT_CMDF_ACCESS_WORD);
    OutU8(PIT_0, SYS_TIMER0_PERIOD);
    OutU8(PIT_0, SYS_TIMER0_PERIOD >> 8);
}

U0 Reboot(Bool format_ramdisks=FALSE)
{//Hardware reset.
    if (format_ramdisks)
    {
        if (DriveIsWritable('A'))
            Format('A',, FALSE, FSt_REDSEA);
        if (DriveIsWritable('B'))
            Format('B',, FALSE, FSt_REDSEA);
    }
    CLI
    if (mp_count > 1)
        MPHalt;
    *0x472(U16 *) = 0;
    OutU8(0x70, 0x8F);
    OutU8(0x71, 0x00);
    OutU8(0x70, 0x00);
    OutU8(0x92, InU8(0x92) | 1);
    SysHlt;
}

U0 KMain()
{//Continued from KStart64.ZC
    CBlkDev *bd;

    OutU8(PCSPKR, InU8(PCSPKR) & ~3); //Sound;
    sys_task = Fs;
    BlkPoolsInit;
    SysGlobalsInit;
    Mem32DevInit;
    UncachedAliasAlloc;
    LoadKernel;
    SysGrInit;
    StrCopy(Fs->task_name, "System Task CPU00");
    StrCopy(Fs->task_title, Fs->task_name);
    Fs->title_src = TTS_TASK_NAME;
    Fs->win_right = text.cols - 2;
    Fs->win_top++;
    TaskDerivedValsUpdate;

    SysDefinesLoad;
    Core0Init;
    IntInit1;

    //Before this point use Sound() and Busy()
    //to debug.  After this point, use RawPrint()
    LBts(&sys_run_level, RLf_RAW);
    "\nZealOS V%0.2f\t%D %T\n", sys_os_version, sys_compile_time, sys_compile_time;
    "_________________________________\n\n";

    "TimerInit;\n";
    TimerInit;

    if (MemBIOSTotal < ToI64 (0.95 * MEM_MIN_MEG * 0x100000) )
        RawPrint(4000, "!!! Requires 256Meg of RAM Memory !!!");

    "IntPICInit;\n";
    IntPICInit;
    RFlagsSet(RFLAGG_NORMAL);
    Busy(2000);
    "IntInit2;\n";
    IntInit2;
    LBts(&sys_run_level, RLf_INTERRUPTS);

    "TimeCal;\n";
    TimeCal;

    "BlkDevsInitAll;\n";
    BlkDevsInitAll;
    "\nDiskChange(':');\n";
    DiskChange(':');

    #exe
    {
        StreamPrint("HomeSet(\"%s\");\n"
                    "blkdev.ins_port = %d;",
                    kernel_config->home_dir,
                    blkdev.ins_port);
    }

    Gs->idle_task->cur_dv = blkdev.let_to_drive[*blkdev.home_dir - 'A'];
    DriveRep;
    if (blkdev.dvd_boot_is_good)
    {
        bd = Letter2BlkDev(':');
        if (bd->type == BDT_ATAPI)
            blkdev.ins_port = bd->port_num;
    }
    LBts(&sys_run_level, RLf_BLKDEV);

    #exe
    {
        if (!kernel_config->opts[CONFIG_NO_MP])
            StreamPrint("\"\\nCore0StartMP;\\n\\n\";"
                        "Core0StartMP;"
                        "LBts(&sys_run_level, RLf_MP);");
    };

    "KbdMouseInit;\n";
    KbdMouseInit;
    "MouseInit;\n";
    MouseInit;
    "KbdInit;\n";
    KbdInit;
    "Spawn(&MouseHardDriverInstall);\n\n";
    Spawn(&MouseHardDriverInstall);
    "Spawn(&MouseRawWatcher,, \"MouseRawWatcher\");\n";
    Spawn(&MouseRawWatcher,, "MouseRawWatcher");

    "Load(\"Compiler\");\n";
    Cd("/Compiler");
    Load("Compiler", LDF_SILENT);
    LBts(&sys_run_level, RLf_COMPILER);

    DebugMode(OFF);
    counts.time_stamp_freq_initial = TimeCal;
    Cd("/");
    try
        ExeFile("StartOS"); //Continues /StartOS.ZC
    catch
    {
        Raw(ON);
        Silent(OFF);
        GetOutOfDollar;
        PutExcept;
        Debug;
    }

    LBts(&sys_run_level, RLf_SYSTEM_SERVER);
    ServerTaskCont; //Never to return
}

asm
{

    ALIGN   16, OC_NOP
SYS_KERNEL_END::
#exe {
    if (kernel_config->opts[CONFIG_DEBUG_DISTRO])
        StreamPrint("DU8 0x%X - (SYS_KERNEL_END-SYS_KERNEL + BOOT_RAM_BASE + sizeof(CZXE)) DUP (0);"
                    "BINLOAD \"%s\";",
                    kernel_config->debug_distro_start, kernel_config->debug_distro_file);
};

}