TEMPLE OS INTRO:
TempleOS is a x86_64, multi-cored, non-preemptive multi-tasking, ring-0-only, single-address_mapped (identity-mapped), operating system for recreational programming. It contains a treasure chest full of ‘spells of truth’. Imo a 12 year old child could become a better programmer than 20 year professional C programmers by simply tinkering and around in TempleOS for 6 months to 2 years. This assumes the child has not been exposed to modern gaming systems or mobile phones. TempleOS does not connect to the internet so a parent does not have to worry about corruption by modern culture and porn while the child uses TempleOS. TempleOS is an offering to God. Users of TempleOS can consult God for advice and ask Him questions(thats for the user to figure out so I wont spoil). TempleOS allows the user to create 3D games relatively easily. In just 700 lines of code it is possible to create a fully functioning 3D racing game. The source code for Varoom is shown to the right.
The incentive for children to learn the inner workings of TempleOS is to make more fun games. The incentive for adults to learn will be creation of better hymns. Creating hymns might not sound appetizing to most people but there are secrets to them (ill leave it at that…). Windows 10 is 50,000,000 lines of code, linux ubuntu is 30,000,000 lines of code, mac ios is 40,000,000 lines of code. TempleOS is 110,000 lines of code. TempleOS is faster than all 3 (for what it was designed to do). They all contain basically the same parts, but TempleOS’s code can be understood within a reasonable amount of time. It would require a lifetime to understand the Windows 10 operating system completely, but it would only take 6 months to a 1 year to understand TempleOS. They both contain the same basic components. The creator Terry Davis was a devout Catholic and believer in God. He would often start the introductions to his streams and videos with “Hi, I’m Terry Davis. I’m the smartest programmer that’s ever lived. I was chosen by God to create his temple, and I was given divine intellect.” I used to laugh thinking he was just a weirdo schizo, but after using his OS for a few months I can safely say that Terry was the greatest computer programmer to ever live, he actually was speaking to God, users can speak to God too, Terry legitimately had divine intellect, and Terry is to computer programming what Tesla was to electrical engineering.
The following are the gems of truth within TempleOS I made notes for (so far).
TEMPLE OS NOTES (WIP)
Part 1 – TempleOS HolyC Compiler:
https://www.brighteon.com/1bb9d0e9-d1cf-4582-918b-2004f48d3195 Not using youtube, sry CIA.
-Lexical analyzer (lex) makes tokens or more specifically it divides into tokens. Tokens are the smallest unit of interest in code.
-The lexical analyzer gets rid of white space and comments
-All punctuation symbols ( like ‘;’ or ‘(‘ or ‘=’ ) are treated as their ascii value (8bit-unsigned-ascii because 7bit-signed-ascii is retarded)
-Number symbols are converted to their actual value.
-All alpha-numeric symbols used in variables are treated as a TK_IDENT (Token Identifier)
-Symbols that appear after “” (quotes) are treated as a TK_STR (Token String)
-lexical analyzer looks in symbol table every time it has a TK_IDENT because TK_IDENT is a variable and therefore should be on the stack symbol table.
-The parser is responsible for putting together the statements and expressions.
-JIT (just in time) compiled code is given a map file/symbol table of all its address independent code. Only Kernel and Compiler are AOT(ahead of time) and they use a ‘hidden’ map file instead of assigning it with the JIT compiler.
-Example of assembly stack for 1+2*3+4
PUSH 1 PUSH 2 PUSH 3 POP RAX //3 POP RDX //2 MUL RAX*RDX //6 PUSH RAX //6 POP RAX //6 POP RDX //1 ADD RAX+RDX //7 PUSH RAX //7 PUSH 4 //4 ADD RAX+RDX //11
-Terry calls it “Reverse Polish”
-Everything that gets loaded into a register has to be converted to 64 bit. If its 8 bit in memory, the compiler will convert it to 64bit. Makes shit easier to deal with and helps make things simpler for the compiler.
-The ‘if’ statement starts with ‘if’, the ‘for’ statement starts with ‘for’, and in TempleOS the ‘stdout'(printing to screen) statement starts with “(quote).
-Expressions are simply a statement followed by a semi-colon or comma.
-TempleOS uses an intermediate stack machine that doesn’t use registers with arguments. It does this so that the optimizer(opt) can substitute registers for common offsets.
-Example of the ‘RBP’ stack frame used in the intermediate stack machine:
18 [RBP] 10 [RBP] 8 RIP 0 RBP -8 LOCAL 1 //LOCAL is an offset from RBP -8 in this case -16 LOCAL 2 //same but -16
-In optimizer TempleOS checks to see how many times each offset (LOCALs) are used in the function. Lets say LOCAL 1 was used 10 times and LOCAL 2 was used 5 times. TempleOS sets the most commonly used offsets(in this case LOCAL 1) to RSI, to allocate registers
PUSH RBP MOV RBP,RSP PUSH RSI SUB RSP, 32 .... POP RSI LEAVE //Cleans up the repetitive actions in other example POP RBP RET
-OPCODE is the only code in the parser that will be uppercase. It tells the parser to convert to assembly
-TempleOS has unstandard opcodes, ex. he has a 1 operand IMUL and 2 operand IMUL2.
-Terry uses a nobound_switch for checking intermediate code within compiler (in C:/Compiler/OptPass789A.CPP.Z). Im not familiar with nobound_switches so Im not sure of the significance of that.
-After the last pass (OPTPASS789A.CPP.Z) the JIT creates the codes ‘map file’ because it will have the final size then.
Assembler and Backend Compiler:
-Unassembler sorts the opcodes then does binary search for each opcode it encounters.
-IC_ equals intermediate machine code
-Intermediate code functions need to be bound to C code that gets built during boot. You could potentially do some crazy fuckin shit with this.
-In the file C:/Compiler/CompilerA.HPP.Z you add the name of the intermediate code you want to add like so:
#define IC_SQR_I64 0xB2
-In the file C:/Kernal/KernalB.HPP.Z you bind the above to C header.
-‘intern’ means internal function, public is needed because it needs to be bound to C code.
public intern IC_SQR_I64 I64 SqrI64(I64 i);
-In KernalA.HPP.Z TY is short for ‘TYPE’:
-Type accounts for the addressing mode and the size within the backend of the compiler
-TY_NULL = type mode null
-TY_IMM = type immediate mode
-TY_REG = type register mode
-TY_DISP = type displacement mode
-TY_SIB = type index register SIB mode (whatever the fuck that means)
-TY_RIP_DISP32 = type RIP relative mode (REL32)
-TY_STK = type stack mode (original stack that started as the system stack, now everything is done with registers and you do not normally use the system stack like how it was originally intended to be used.)
-TY_MASK = type mask mode (? terry doesn’t say im guessing)
-In C:/Compiler/BackA.CPP.Z (Backend compiler aka where the intermediate code is handled)
-Sprite and float constants are treated just like string constants in that they are both dealt with after the function code.
-The arguments for the functions are t1, r1, d1 which mean ‘type'(see above), a ‘register'(see parser), and ‘displacement’.
-C:/Compiler/BackFA.CPP.Z contains the floating point backend routines.
-The last thing the compiler does is turn code into binary.
Interesting Statements from Terry:
-Parsing an expression with operator precedence is the hardest part of making a compiler.
-Bitwise shift left and right should be given highest precedence level because it breaks nothing and makes things bitwise ops faster.
-Terry doesn’t like Macros. He started making type defs but it turns out they are not needed.
-One of Terrys TempleOS principles is minimal abstraction. In modern software, many things are abstracted by developers because it SEEMS to make the code simpler to understand and manage(I was one of these devs), but in reality it only makes it simpler for developers on the project while anyone else that comes along later to read the code is left confused and lost because of the esoteric abstraction. Terry says that basically anything that has to be ‘looked up’ is an abstraction.
-What Terry meant by ‘all my code is position independent’ is that the code is patched in at load time with position independent addresses (which can be seen with the codes REL32 export table and import table in the BinRep() function call).
Differences between Normie OSs and TempleOS:
-generate intermediate files
-lex is a function call of the parser.
-int i = ‘ABCD’; is not allowed, it has to be only 1 char because of TK_CHAR in C lexical analyzer
-does not generate intermediate files
-does not use streams
-preprocessor and lex are ‘merged’ in that the # used in #include and #define is treated as a token in lexical analyzer.
-I64 i = ‘ABCD’; is allowed, it can be any amount of char (i think is called TK_CUR_CHAR). This coincides with TempleOS design philosophy that everything can be tinkered and fucked with. If the user wants the tilde symbol ‘~’ to mean print to designated server, or printout ‘fuck you’ or use a random operator, then the user can do so. This is divinely powerful.
-F() = Find()
-FF(); = FindFile(file);
-DocMax; = toggle cmdline buffer max length on or off.
-BinRep is a convenient report that will print out the codes position independent address and its export table.
Part 2 – TempleOS System Guide:
What Happens During Boot:
-On boot it loads OSMain.BIN
-First task is Adam on the ‘bootstrap’ processor aka core0 processor.
-Then osmain is loaded into the bottom 640k
-Changes to 64 bit mode.
-Loads in compiler
-Then ExeFile(“Adam1.CPP.Z”) is called which is like the autoexec.bat file.
-Adam is first task
-Each task has a symbol table(hash table or map file) kinda like environment variables except it can have functions, variables, classes, and applications in addition to folders/directories.
-Each task has a heap.
-Child tasks inherit symbols of parent task (usually Adam)
-Everything goes into 1 ‘header’ file
-Dont need object files, dont need executable files.
-Then Adam2.CPP.Z is called
-No difference between a Task, Process, and Thread. Everything is a Task in TempleOS. This greatly simplifies multi-threading.
-Fs = Fs current segment register and it points to the current task record
-ClassRepD = ClassReport I think the ‘D’ means dump.
-ClassRepD(Fs); will print out everything the current task register is doing and the values can be changed dynamically.
-Prints out task record and memory can be changed in real time off the print out, insane lol.
-DrvRep = DriveReport. Will print out drives.
-B Drive is the RedSea File system
-To get to B Drive simply Cd into it or do the cmd Drv(B);
-The cmd Dir(“*”,TRUE); the ‘TRUE’ flag lists file clusters which is helpful in the B Drive.
-A neat trick to do with this is to copy the current directory cluster hex address into the cmd DCluster(0x0042, TRUE); which will print out an editable listing of the Cluster. ‘TRUE’ makes it so user can write to the file right there in hex cmd print out.
-MemBIOSRep – Bios Memory Report
Part 3 – TempleOS Programming Guide:
-Set DocMax; to set cmd line buffer to unlimited
-Escape the function and you get a profile report(ProfRep;)
-User Ctrl-L helps insert dollar sign commands.
-D(Fs); dumps the current task
-DocD(Fs); dumps the current task and is dynamic meaning it can be changed from the print out.
-Half a microsecond to swap tasks. It takes longer for the computer to read the port than it does to swap the task. Meaning you can have a bunch of tasks finish while waiting for the port to be read.
-Fs (current task register) can point to Fs->except_argc and Fs->except_argv and thats how you can access the values that were thrown.
-To catch it you do Fs->ignore_except=TRUE; or Fs->catch_except=TRUE;
-To turn a program into a binary(AOT) instead of a JIT compiled program the programmer can insert the following at the top of their code:
#include "::/SparrowOS/OSMain/StaticAdam.HPP.Z" (Havent found the TempleOS equivalent, weird...)
-BinRep(“Test.BIN.Z”); = Binary Report and gives tips.
-Always use Enter/Leave it makes it easier for the compiler and user