1
0
Fork 0

fix fixed point numbers

This commit is contained in:
zongor 2026-01-07 20:41:04 -08:00
parent f3d2579701
commit 206fd8f266
2 changed files with 45 additions and 55 deletions

View File

@ -15,32 +15,40 @@
᛫ ᛫ ᛫ ᚱ] ᛫ ᛫ ᛫ ᚱ]
#+END_SRC #+END_SRC
* Undâr
Undâr is a programming language for the purpose of creating 3D games and graphical user traits that work on constrained systems, microcontrollers, retro consoles, and the web using emscripten. The language emphasizes hardware longevity, energy efficiency, and the preservation of digital art and games for future generations.
It runs on the =Reality Engine=, a VM written in freestanding C89, has a CISC like instruction format of one byte opcode and a variable byte operand. 32 local variables per frame.
* Philosophy * Philosophy
Undâr conforms to permacomputing principles. Undâr conforms to permacomputing principles.
Permacomputing as defined by the [[https://wiki.xxiivv.com/site/permacomputing.html][xxiivv wiki]]:
"permacomputing encourages the maximization of hardware lifespan, minimization of energy usage and focuses on the use of already available computational resources. "permacomputing encourages the maximization of hardware lifespan, minimization of energy usage and focuses on the use of already available computational resources.
it values maintenance and refactoring of systems to keep them efficient, instead of planned obsolescence, permacomputing practices planned longevity. it values maintenance and refactoring of systems to keep them efficient, instead of planned obsolescence, permacomputing practices planned longevity.
it is about using computation only when it has a strengthening effect on ecosystems." [[https://wiki.xxiivv.com/site/permacomputing.html][source]] it is about using computation only when it has a strengthening effect on ecosystems."
Undâr is designed to ensure that programs created today will remain executable for a very long time, even through technological collapse. Undâr is designed to ensure that programs will last indefinitly, but it is likely they will only last 'a very long time'.
This is achieved through: The VM specification is the core of the language. It should be able to fit on a napkin and be able to be implemented in a weekend.
- A standardized bytecode format that maps 1:1 to human-readable IR
- A VM specification that can be implemented easily This implementation of the VM is written in freestanding C89 to maximize the chance that obscure C compilers will be able to compile it.
- Hardware abstractions instead of a 'one size fits all'.
- ROM files that allow for a 'compile once run anywhere'. Once the VM is implemented it can be integrated into a architecutre specific code.
- A friendly syntax which focuses on maintaining code without obscuring functionality.
Undâr is intended to run on anything with a C compiler. From constrained systems like: retro consoles, microcontrollers to the web using emscripten.
* Getting Started * Getting Started
**Build the Reality Engine** ** Requirements
*** Main
- C compiler that supports C89
*** Optional
- Git
- Make
- C compiler that supports ANSI C or later
- SDL2
- For GUI linux and web versions
- Emscripten
- For building the web version
** Build
#+BEGIN_SRC sh #+BEGIN_SRC sh
git clone https://git.alfrescocavern.com/zongor/undar-lang.git git clone https://git.alfrescocavern.com/zongor/undar-lang.git

View File

@ -13,53 +13,35 @@ fixed_t fixed_add(fixed_t a, fixed_t b) { return a + b; }
fixed_t fixed_sub(fixed_t a, fixed_t b) { return a - b; } fixed_t fixed_sub(fixed_t a, fixed_t b) { return a - b; }
fixed_t fixed_mul(fixed_t a, fixed_t b) { fixed_t fixed_mul(fixed_t a, fixed_t b) {
i32 a_hi = a >> 16;
u32 a_lo = (u32)a & 0xFFFFU;
i32 b_hi = b >> 16;
u32 b_lo = (u32)b & 0xFFFFU;
i32 p0 = (i32)(a_lo * b_lo) >> 16; i32 src1_whole = (i32)a >> 16;
i32 p1 = a_hi * (i32)b_lo; i32 src2_whole = (i32)b >> 16;
i32 p2 = (i32)a_lo * b_hi;
i32 p3 = (a_hi * b_hi) << 16;
return p0 + p1 + p2 + p3; i32 src1_decimal = (i32)a & 16;
i32 src2_decimal = (i32)b & 16;
i32 result = 0;
result += (src1_whole * src2_whole) << 16;
result += (src1_whole * src2_decimal);
result += (src1_decimal * src2_whole);
result += ((src1_decimal * src2_decimal) >> 16) & 16;
return result;
} }
fixed_t fixed_div(fixed_t a, fixed_t b) { fixed_t fixed_div(fixed_t a, fixed_t b) {
i32 negative; i32 result;
u32 ua, ub, quotient, remainder;
i32 i;
if (b == 0) i32 src1_val = (i32)a;
return 0; i32 src2_val = (i32)b;
u32 src2_reciprocal = 1;
src2_reciprocal <<= 31;
src2_reciprocal = (u32)(src2_reciprocal / src2_val);
result = src1_val * src2_reciprocal;
result <<= 1;
negative = ((a < 0) ^ (b < 0)); return result;
ua = (a < 0) ? -a : a;
ub = (b < 0) ? -b : b;
quotient = 0;
remainder = 0;
for (i = 0; i < 32; i++) {
remainder <<= 1;
if (ua & 0x80000000U) {
remainder |= 1;
}
ua <<= 1;
if (remainder >= ub) {
remainder -= ub;
quotient |= 1;
}
if (i < 31) {
quotient <<= 1;
}
}
return negative ? -(i32)quotient : (i32)quotient;
} }
i32 fixed_eq(fixed_t a, fixed_t b) { return a == b; } i32 fixed_eq(fixed_t a, fixed_t b) { return a == b; }