#help_index "Info;Memory/Info;Cmd Line (Typically)"

I64 TSSSize(CTSS *tss)
{
        return MSize2(tss) + MSize2(tss->st0) + MSize2(tss->st1) + MSize2(tss->st2);
}

I64 PenBrushesSize()
{
        I64 res = 0, i;

        for (i = 0; i < GR_PEN_BRUSHES_NUM; i++)
                res += DCSize(gr.pen_brushes[i]) + DCSize(gr.collision_pen_brushes[i]) + 
                           DCSize(gr.even_pen_brushes[i]) + DCSize(gr.odd_pen_brushes[i]);

        return res;
}

I64 ScreenZoomTablesSize()
{
        I64 res = 0, i;

        for (i = 1; i <= GR_SCREEN_ZOOM_MAX;i++)
                res += MSize2(gr.screen_zoom_tables[i]);

        return res;
}

I64 TaskStackSize(CTask *task)
{
        CTaskStack      *tmps = task->stack;
        I64                      res = 0;

        while (tmps)
        {
                res += MSize2(tmps);
                tmps = tmps->next_stack;
        }

        return res;
}

I64 TaskQueueSize(CTask *task)
{
        CJob *tmpc,*tmpc1;
        I64   res = 0;

        PUSHFD
        CLI
        while (LBts(&task->server_ctrl.flags, JOBCf_LOCKED))
                PAUSE

        tmpc1 = &task->server_ctrl.next_waiting;
        tmpc = tmpc1->next;
        while (tmpc != tmpc1)
        {
                res += MSize2(tmpc) + MSize2(tmpc->aux_str);
                tmpc = tmpc->next;
        }

        tmpc1 = &task->server_ctrl.next_done;
        tmpc = tmpc1->next;
        while (tmpc != tmpc1)
        {
                res += MSize2(tmpc) + MSize2(tmpc->aux_str);
                tmpc = tmpc->next;
        }

        LBtr(&task->server_ctrl.flags, JOBCf_LOCKED);
        POPFD
        return res;
}

I64 BlkDevsSize()
{
        I64              i, j, res = MSize2(blkdev.blkdevs);
        CBlkDev *bd;

        for (i = 0; i < BLKDEVS_NUM; i++)
        {
                bd = &blkdev.blkdevs[i];
                if (bd->bd_signature == BD_SIGNATURE_VAL)
                {
                        j = (bd->max_blk + 1) << BLK_SIZE_BITS;
                        if (bd->type == BDT_RAM)
                                "RAMDisk %C\t:%010X/%010X\n", bd->first_drive_let, j - DriveUnused(bd->first_drive_let), j;
                        res += MSize2(bd->dev_id_record);
                }
        }

        return res;
}

I64 DrivesSize()
{
        I64 i, res = MSize2(blkdev.drvs);

        for (i = 0; i < DRIVES_NUM; i++)
                res += MSize2(blkdev.drvs[i].cur_fat_blk) + MSize2(blkdev.drvs[i].fis);

        return res;
}

Bool MemRepTask(CTask *task,Bool override_validate=FALSE)
{
        I64                      i, j, k, m, n;
        CDoc            *pdoc, *ddoc, *bdoc;
        CCompCtrl       *cc;
        CMathODE        *o;
        CCPU            *c;
        CTask           *task1;

        if (!override_validate && !TaskValidate(task))
                return FALSE;
        if (task == Fs)
                task->rsp = RSPGet;
        "$BLACK$%-27t$Q#%08X$FG$\n",  task->task_title,task;
        "$ID,2$Heap\t:%010X/%010X\n", TaskMemUsed(task, override_validate), TaskMemAlloced(task,override_validate);

        i = UnusedStack(task);
        j = TaskStackSize(task);
        if (0 <= i <= task->stack->stack_size)
                "Stack\t\t:%010X/%010X\n",j - i, j;
        else
                "Stack\t\t:$RED$$BK,1$Overflow$BK,0$$FG$/%010X\n", j;

        "HashTable\t:%010X\n",  HashTableSize2(task->hash_table);
        "FPU\t\t\t:%010X\n",    MSize2(task->fpu_mmx);
        "DirCur\t\t:%010X\n",   MSize2(task->cur_dir);

        if (pdoc = DocPut(task))
                "PutDoc\t\t:%010X\n",   DocSize(pdoc);
        if ((ddoc = DocDisplay(task)) && pdoc != ddoc)
                "DisplayDoc\t:%010X\n", DocSize(ddoc);
        if (bdoc = DocBorder(task))
                "BorderDoc\t:%010X\n",  DocSize(bdoc);

        cc = task->next_cc;
        while (cc != &task->next_cc)
        {
                "CompCtrl\t:%010X\n", CompCtrlSize(cc);
                cc = cc->next;
        }

        o = task->next_ode;
        while (o != &task->next_ode)
        {
                "CMathODE\t:%010X\n", ODESize(o);
                o = o->next;
        }

        if (task == sys_winmgr_task)
        {
                "gr.pen_brushes\t:%010X\n",                     PenBrushesSize;
                "gr.screen_zoom_tbles\t:%010X\n",       ScreenZoomTablesSize;
                "screencast.dc\t:%010X\n",                      DCSize(screencast.dc);
                "screencast.dc2_alias\t:%010X\n",       DCSize(screencast.dc2_alias);
        }
        else if (task == sys_task)
        {
                j = 0;
                k = 0;
                m = 0;
                n = 0;
                for (i = 0; i < mp_count; i++)
                {
                        c = &cpu_structs[i];
                        k += TSSSize(c->tss);
                        task1 = c->executive_task;
                        do
                        {
                                if (task1 != sys_task) {//system task located in Kernel mem
                                        j += MSize2(task1);
                                        m += MSize2(task1->code_heap);
                                        if (task1->data_heap != task1->code_heap)
                                                m += MSize2(task1->code_heap);
                                }
                                n += TaskQueueSize(task1);
                                task1 = task1->next_task;
                        }
                        while (task1 != c->executive_task);

                        task1 = c->idle_task;
                        j += MSize2(task1);
                        m += MSize2(task1->code_heap);
                        if (task1->data_heap != task1->code_heap)
                                m += MSize2(task1->code_heap);
                }
                "TaskStructs\t:%010X\n",                j;
                "TSSes\t\t:%010X\n",                    k;
                "HeapCtrls\t:%010X\n",                  m;
                if (n)
                        "TaskQueues\t:%010X\n",         n;
                "BlkDevs\t\t:%010X\n",                  BlkDevsSize;
                "Drives\t\t:%010X\n",                   DrivesSize;
                if (blkdev.cache_base)
                        "DiskCache\t:%010X\n",          MSize2(blkdev.cache_base)+MSize2(blkdev.cache_hash_table)+ MSize2(blkdev.cache_ctrl);
                "Clip\t\t:%010X\n",                             DocSize(sys_clip_doc);
                "AutoComplete:%010X\n",                 CallExtStr("AutoCompleteSize");
                "text.font\t\t:%010X\n",                MSize2(text.font);
                "text.raw_screen\t:%010X\n",    MSize2(text.raw_screen);
                "gr.to_8_bits\t:%010X\n",               MSize2(gr.to_8_bits);
                "gr.to_8_colors\t:%010X\n",             MSize2(gr.to_8_colors);
                "gr.text_base\t:%010X\n",               MSize2(gr.text_base);
                "gr.screen_cache\t:%010X\n",    MSize2(gr.screen_cache);
                "gr.win_z_buf\t:%010X\n",               MSize2(gr.win_z_buf)+ MSize2(gr.win_uncovered_bitmap);
                "gr.dc\t\t\t:%010X\n",                  DCSize(gr.dc);
                "gr.dc1\t\t\t:%010X\n",                 DCSize(gr.dc1);
                "gr.dc2\t\t\t:%010X\n",                 DCSize(gr.dc2);
                "gr.dc_cache\t\t:%010X\n",              DCSize(gr.dc_cache);
                "gr.screen_image\t:%010X\n",    DCSize(gr.screen_image);
                "gr.zoomed_dc\t:%010X\n",               DCSize(gr.zoomed_dc);
        }
        "$ID,-2$";

        return TRUE;
}

public U0 MemRep()
{//Memory usage report.
        I64                      i;
        CTask           *task;
        CCPU            *c;
        CBinFile        *bfh = mem_boot_base - sizeof(CBinFile);

        bfh(I64) += bfh->file_size - 1;

        "$BLACK$Low Memory\t:00100000$FG$\n$ID,2$";
        "Kernel\t:%08X-%08X\n", mem_boot_base - sizeof(CBinFile), bfh;

        "$ID,-2$$BLACK$High Memory\t:00100000-%08X$FG$\n", mem_heap_limit;
        "SYS_FIXED_AREA\t:%08X-%08X\n", SYS_FIXED_AREA, SYS_FIXED_AREA + sizeof(CSysFixedArea) - 1;

    "VBE framebuffer\t:%08X-%08X\n", text.fb_alias, text.fb_alias(U8 *) + text.buffer_size - 1;
        if (sys_data_bp)
    {
                "$BLACK$Code Heap\t:%010X/%010X$FG$\n", sys_code_bp->used_u8s, sys_code_bp->alloced_u8s;
                "$BLACK$Data Heap\t:%010X/%010X$FG$\n", sys_data_bp->used_u8s, sys_data_bp->alloced_u8s;
        }
        else
                "$BLACK$Code/Data Heap\t:%08X/%08X$FG$\n", sys_code_bp->used_u8s, sys_code_bp->alloced_u8s;

        for (i = 0; i < mp_count; i++)
        {
                c = &cpu_structs[i];
                "$PURPLE$CPU%d$FG$\n$ID,2$", i;
                task = c->executive_task;
                do
                {
                        if (!MemRepTask(task))
                                break;
                        task = task->next_task;
                }
                while (task != c->executive_task);

                MemRepTask(c->idle_task, TRUE);
                "$ID,-2$";
        }
}