Directory Structure

/Home All your user data should be placed in here to ease backing-up your data.  When you install an application it will 
create a subdirectory of your /Home directory for storage.

/Apps Applications are placed in subdirectories of /Apps.  Applications should have a file called Install.ZC which will 
install the app, possibly making files or directories in /Home.  The file, Load.ZC will load the application into mem.  The 
file, Run.ZC, will usually load and execute the app.    To add an app to your PersonalMenu, use <CTRL-l>, insert a macro with 
the PopUp option checked and invoke the Run.ZC file.

/Demo Here you can find lots of sample code to do various things.

/Doc Here you can find documentation.

/Kernel The core of the operating system is found here.  Since privilege levels are not used, calling it a kernel is 
deceptive.  It is AOT compiled by BootHDIns().  It is loaded by the boot loader and must fit in 640K.

/Compiler The compiler module src code is found here.  The compiler is AOT compiled to produce a binary file which is loaded 
at boot.  It, too, is AOT compiled by BootHDIns().

/System The non-kernel part of the operating system is found here.  It is JIT compiled during boot.  The System Task is the 
most important task. It never dies.

/Boot Boot files go here.  Stage 2 of the ZealOS hard drive master boot loader, the old hard drive master boot record which is 
just block#0, and the HDD & CD/DVD Kernel.ZXE file go here.



                                                        ::/Home Files

The home dir is specified with '~'.  The home dir is ::/Home unless you change it with HomeSet() or compile the kernel with a 
config option.  An empty /Home dir should be valid because it will get default files from the root dir.

~/PersonalMenu.DD a menu viewed with the <CTRL-m> key or by clicking "MENU" in the upper left border area of a window.

~/PersonalNotes.DD a personal note file viewed with the <CTRL-SHIFT-M> key.

~/MakeHome.ZC a file compiled by the System Task during StartOS.

~/Home* Copy Home* files from the root into ~ and customize them.  These files are invoked when the System Task starts-up.

~/Once.ZC a file invoked at the start-up of the first user. Customize this!

~/Registry.ZC can be edited by hand or deleted to reset to defaults.  Takes affect next boot.



                                                     Application Policies

* Place applications in their own /Apps subdirectory.

* Make a file called Load.ZC to load the application.

* Make a file called Run.ZC to load and run the application, preferable by #includeing the Load.ZC file.

* Place user data in a subdirectory of /Home, preferably naming the subdirectory the same as the /Apps subdirectory.    Or, 
place data in the Registry.ZC file.  See ::/Demo/RegistryDemo.ZC.

* If the app needs files in the /Home directory, make an /Apps file called Install.ZC or Install.IN to create the /Home 
subdirectory.

 

                                                    Programming Guidelines

* Virtual mem/Paging is not used -- it is identity mapped in x86_64 mode.  The stack does not grow, so alloc enough when the 
task (process) is Spawned and use the heap for most things. (The heap refers to MAlloc() and Free().)

* You can Free(NULL).

* See Naming Convention and Abbreviations.

* There are two modes of compiling, AOT Compile Mode and JIT Compile Mode.  Compilation is done in both -- neither is 
"interpreted".  Use JIT Mode.

* ZealC

* Use I64 instead of smaller int sizes because the compiler converts everything to 64-bit.  Don't use unsigned unless it 
actually breaks.  A policy of signed keeps it simple so you don't have to agonize over choices.

     U32 DistDist(U16 x1, U16 y1, U16 x2, U16 y2)
     {//This requires zero-extend when fetching args.
        return SqrI64(x1 - x2) + SqrI64(y1 - y2);
     }
     
     I64 DistDist(I64 x1, I64 y1, I64 x2, I64 y2)
     {
        return SqrI64(x1 - x2) + SqrI64(y1 - y2);
     }

* In-order, short circuit logic is assumed.

* Avoid boolean expression assignments.  Boolean assignments don't have short circuit logic and are not compiled efficiently.  
The Bool type is just an alias for a 1 byte signed int -- nothing forces it to 1 or 0.  There is a ToBool() function that will 
for to 1 ot 0, however.

* Global variables in AOT ZXE modules are initialized to zero.  They occupy space in ZXE files.

* Bracketing code with PUSHFD CLI and POPFD will protect against simultaneous accesses from tasks on one core.  To protect 
against multiple cores, you need a locked semaphore.  Semaphores might need to be in their own cache line.  Lock bits are used 
in a lot of places not aligned.

* SysDebug() and IsSysDebug() are really handy when working on the compiler or kernel.  It's just a bit you can set and test.

* U0 * is not used because the size is zero for pointer arithmetic.

* Do not use #if or #ifdef



                                                       Hash Sym Tables

* See ::/System/Hash.ZC for examples of how the hash tables are set-up.  Basically, symbols are placed into hash tables and 
child process hash tables are chained to parents.   This provides scopes for variables and functions.

* sys_task->hash_table holds the ZealC symbols loaded in on start-up.

* Fs->hash_table holds user ZealC symbols and if a symbol is not found, it checks parents.  When a duplicate symbol is added 
to the table, it overshadows the prev symbol.  When developing software, typically you include the file at the cmd prompt, 
make changes and reinclude it.  Old symbols are overshadowed but they are still there.  Periodically, kill the TASK and start 
fresh when mem is low.  If you wish your applications to free themselves instead of staying in mem, spawn or PopUp() a task to 
run the application and kill it when it's done.

* To display the contents of a hash table, use the HashTableDump() routine or the varients.  HashDepthRep() gives a histogram   
of how long the chains are, in case you wish to make hash table sizes bigger.



                                                      Assembly Language

See ::/Doc/Asm.DD.

* FS must always point to the cur CTask.

* GS must always point to the cur CCPU.

* Don't change the segment registers unless interrupts are off. It's hard to do, anyway.    SET_FS_BASE and SET_GS_BASE.

* When interacting with ZealC compiled code, preserve RBP, RSI, RDI, R10-R15 because the compiler uses these for register 
variables.  You are free to clobber RAX, RBX, RCX, RDX, R8 and R9.  See Compiler Reg Masks, PUSH_C_REGS and POP_C_REGS

* It is recommended to use the standard stack frame for functions because Caller() is used to display the call stack, such as 
for the wallpaper.
                PUSH        RBP
                MOV         RBP, RSP
                SUB         RSP, nnnn
...
                LEAVE
                RET

* The args are removed from the stack with RET1 statements.

                RET1        16      //remove two args

* No args are passed in registers.

* RAX holds function return values, of course.