├── BUILDS ├── LICENSE ├── README.md ├── TODO ├── buildutils.sh ├── compiler ├── addressof.bas ├── arrays.bas ├── cmp.bas ├── div.bas ├── example.bas ├── float.bas ├── func.bas ├── getc.bas ├── hello.bas ├── if.bas ├── include.hb ├── input.bas ├── nativelib.bas ├── preproc.bas ├── readme.txt ├── recur.bas ├── string.bas ├── struct.bas ├── t++.c ├── tbc.c ├── test_func_lib.bas └── while.bas ├── disasm ├── build.sh ├── cgen.c ├── readme.txt ├── readrex.c ├── rexdump.c └── rexpack.c ├── docs ├── Building.html ├── CPU.html ├── ConfigureScript.html ├── DynamicLinking.html ├── ExceptionHandling.html ├── Format.html ├── Memory.html ├── Multithreading.html ├── NativeLinking.html ├── Opcodes.html ├── Porting.html ├── REX.html ├── REXCall.html ├── Syscalls.html ├── T++.html ├── data │ ├── CREDITS.txt │ ├── background.jpg │ └── logo.png ├── libR3X.html └── notes.txt ├── fasm ├── examples │ ├── elfexe │ │ ├── dynamic │ │ │ ├── elf.inc │ │ │ ├── hello │ │ │ ├── hello.asm │ │ │ ├── hello64 │ │ │ ├── hello64.asm │ │ │ ├── import32.inc │ │ │ ├── import64.inc │ │ │ └── proc32.inc │ │ ├── hello │ │ ├── hello.asm │ │ ├── hello64 │ │ └── hello64.asm │ ├── elfobj │ │ ├── msgdemo.asm │ │ ├── msgdemo.o │ │ ├── writemsg.asm │ │ └── writemsg.o │ └── libcdemo │ │ ├── ccall.inc │ │ ├── libcdemo.asm │ │ └── libcdemo.o ├── fasm.txt ├── license.txt ├── source │ ├── DOS │ │ ├── fasm.asm │ │ ├── modes.inc │ │ └── system.inc │ ├── Linux │ │ ├── fasm.asm │ │ └── system.inc │ ├── Win32 │ │ ├── fasm.asm │ │ └── system.inc │ ├── assemble.inc │ ├── avx.inc │ ├── errors.inc │ ├── exprcalc.inc │ ├── exprpars.inc │ ├── formats.inc │ ├── libc │ │ ├── fasm.asm │ │ └── system.inc │ ├── messages.inc │ ├── parser.inc │ ├── preproce.inc │ ├── symbdump.inc │ ├── tables.inc │ ├── variable.inc │ ├── version.inc │ └── x86_64.inc ├── tools │ ├── dos │ │ ├── listing.asm │ │ ├── loader.inc │ │ ├── prepsrc.asm │ │ ├── symbols.asm │ │ └── system.inc │ ├── libc │ │ ├── ccall.inc │ │ ├── listing.asm │ │ ├── prepsrc.asm │ │ ├── symbols.asm │ │ └── system.inc │ ├── listing.inc │ ├── prepsrc.inc │ ├── readme.txt │ ├── symbols.inc │ └── win32 │ │ ├── listing.asm │ │ ├── prepsrc.asm │ │ ├── symbols.asm │ │ └── system.inc └── whatsnew.txt ├── llvm └── lib │ └── Target │ ├── R3X │ └── R3XTargetMachine.cpp │ └── llvm.txt ├── server ├── build.sh ├── readme.txt └── server.c └── src ├── 128x128.png ├── bios.c ├── build.sh ├── cpu.c ├── disassemble.c ├── dispatcher.c ├── dynamic.c ├── exception.c ├── font.c ├── format.c ├── garbagecollector.c ├── graphics.c ├── include ├── big_endian.h ├── nt_malloc.h ├── r3x_bios.h ├── r3x_checksum_generator.h ├── r3x_cpu.h ├── r3x_disassemble.h ├── r3x_dispatcher.h ├── r3x_dynamic.h ├── r3x_exception.h ├── r3x_format.h ├── r3x_garbage_collector.h ├── r3x_graphics.h ├── r3x_memory.h ├── r3x_native.h ├── r3x_object.h ├── r3x_opcode_table.h ├── r3x_opcodes.h ├── r3x_pack.h ├── r3x_script.h ├── r3x_stack.h ├── r3x_stacktrace.h ├── r3x_stream.h ├── r3x_version.h ├── system.h └── win32 │ ├── dbghelp.h │ └── dlfcn.h ├── lib ├── gl │ ├── gl.bas │ ├── rxgl.c │ └── rxgl.h ├── include │ ├── nt_malloc.h │ └── virtual-machine.h ├── ntmalloc │ └── nt_malloc.c ├── rstdlib │ ├── include │ │ └── rstdlib.h │ ├── ircbot.bas │ ├── readme.txt │ ├── rmath.c │ ├── rsocket.c │ ├── rstdlib.c │ └── stdlibtest.bas └── rxvmlib │ └── rxvmlib.c ├── main.c ├── memory.c ├── native.c ├── object.c ├── packageloader.c ├── programs ├── args.il ├── asshole.il ├── bios.il ├── dynamiclib.il ├── example.il ├── exception.il ├── hello.il ├── jmp.il ├── libR3X │ ├── corelib.pkg │ ├── dynR3X.pkg │ ├── libR3X.pkg │ ├── r3x_asm.pkg │ └── simplelib.pkg ├── math.il ├── mylib.c ├── nativelib.il ├── overflow.il ├── perf.il ├── r3x_ex.il ├── rfc.il ├── simplelib.il ├── stack.il ├── stream.il ├── symbols.exe └── symbols.il ├── rfc.c ├── script.c ├── stack.c ├── stream.c └── win32 └── dlfcn.c /BUILDS: -------------------------------------------------------------------------------- 1 | Builds with the following compilers: 2 | gcc 4.8.1 3 | gcc 4.8.2 4 | gcc 4.9.0 5 | gcc 4.9.1 6 | gcc 5.1.0 7 | clang 3.5 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 Benderx2, 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of R3X nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | NOTE: 30 | 31 | The files src/win32/dlfcn.c and src/include/win32/dlfcn.h have been taken from 32 | github.com/dlfcn-win32/dlfcn-win32 33 | 34 | The file src/inclue/win32/dbghelp.h has been taken from mingw64's headers. 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | R3X Virtual Machine 2 | === 3 | A virtual machine which functions as a portable runtime for applications.
4 | Please see: http://benderx2.github.io/R3X/ for more information
5 | ![Alt tag](http://benderx2.github.io/R3X/tmp/rx_opengl_2016-03-04%2017:35:45.png "R3X program using rxgl library on Linux64") 6 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | TODO: Stuff that needs to be done 2 | HI = High priority, ME = Medium, LO = Low. 3 | [HI] 1. Remove shitty build.sh and use a proper build system. 4 | [LO] 2. Remove useless comments 5 | [ME] 3. Don't USE redundant typecasts 6 | [ME] 4. Proper whitespacing 7 | [X] 5. Remove 'r3x_' prefix from source files -- Fixed 8 | [X] 6. Make typecasting mechanism local. -- Fixed 9 | [HI] 7. Print errors to stderr not to stdout. 10 | [HI] 8. 'fopen' returns null on not just file ceasing to exist. Add a proper message 11 | [ME] 9. Stop using different case styles, use either normal_case, CamelCase, or cameCase. 12 | [X] 10. Use something like a debug macro, to fix nt_malloc_init -- Fixed 13 | [LO] 11. Stop using swear words. 14 | [X] 12. Stop using multiple printfs --- Fixed 15 | [ME] 13. Fix identation 16 | [HI] 14. Remove useless 'else' statements 17 | [LO] 15. Remove offensive error messages (Keep it down) 18 | [HI] 16. Use a standard header for endianess (), remove big_endian.h 19 | [Too high to describe] 17. Write standard-compliant code. 20 | [X] 18. Rewrite include guards, to not use reserved prefixes. -- Fixed 21 | [HI] 19. Rewrite big_endian.h to use 22 | [HI] 20. Remove all references to R3X_BIG_ENDIAN, and use a common function to read a 32-bit integer from memory. 23 | [ME] 21. Show message for big endian machines too. Use a common function to read as above. -- Partially Fixed 24 | [HI] 22. Remove the little malloc wrapper. It's problematic. 25 | [ME] 23. Remove /fasm/ directory and use git's submodule system to link it to fasm's repository. 26 | [HI] 24. Use strdup() instead of manually using malloc to create duplicate of strings 27 | [ME] 25. Remove useless binaries from /src/ directory. 28 | [ME] 26. Use the current directory, (and not the executable directory) for devenv. 29 | [HI] 27. Don't use strncmp for comparision, since it works without error on things like ("helpppppppp" instead of showing an error message) 30 | [HI] 28. Update "r3x_version.h" to simply have 1 name for all architectures, use standard functions to detect system rather than manually specifying it. 31 | [Too high to describe] 29. Improve code overall, try to make it more readable, at the same time run with decent performance. 32 | [X] 30. Exit on not receiving arguments --> Fixed. 33 | [HI] 31. Use size_t instead of 'int' while comparing return values from strlen. 34 | [X] 32. Add license headers in each file. Maybe remove the license in "help" option too. -- Fixed 35 | [X] 33. Add a stack overflow check. --Fixed 36 | Thanks to guys at #osdev for these suggestions! 37 | Want to report something? Head to the issues section. 38 | -------------------------------------------------------------------------------- /buildutils.sh: -------------------------------------------------------------------------------- 1 | # Build utilites for R3X 2 | export CC=gcc 3 | cd disasm 4 | ./build.sh 5 | mv ./readrex $PREFIX 6 | mv ./rexdump $PREFIX 7 | mv ./cgen $PREFIX 8 | cd .. 9 | cd compiler 10 | $CC -std=gnu99 -g tbc.c -o tbc 11 | $CC -std=gnu99 t++.c -o t++ -D RX_PREFIX="\"$PREFIX\"" 12 | mv ./tbc $PREFIX 13 | mv ./t++ $PREFIX 14 | cd ../src 15 | cd programs 16 | cp -r ./libR3X/ $PREFIX 17 | cd .. 18 | cd .. 19 | cd $PREFIX 20 | mkdir -p include 21 | cp -r ../src/lib/rstdlib/include/rstdlib.h ./include/ 22 | export STDLIB_R3X="$PREFIX/include" 23 | -------------------------------------------------------------------------------- /compiler/addressof.bas: -------------------------------------------------------------------------------- 1 | function x(0) 2 | print "hello, world from x!" 3 | return 0 4 | endf 5 | function y(2) 6 | let FirstArgument = $1 7 | let SecondArgument = $2 8 | print "first arg: "; FirstArgument 9 | print "second arg: "; SecondArgument 10 | return 5 11 | endf 12 | function main(0) 13 | let a = addressof(@x) 14 | let q = addressof(a) 15 | /* Call address a with 0 arguments */ 16 | @raw_call(a, 0) 17 | let a = addressof(@y) 18 | /* Call address a with 3 arguments */ 19 | let c = @raw_call(a, 2, 15, 27+22) 20 | print "return value from y ="; c 21 | end 22 | endf 23 | -------------------------------------------------------------------------------- /compiler/arrays.bas: -------------------------------------------------------------------------------- 1 | function main(0) 2 | print "Array stuff00" 3 | goto mylabel 4 | :mylabel 5 | // Allocate 4 bytes for S. 6 | let buffer = alloc(4) 7 | let B=100 8 | // int32_ptr = 32-bit array access, int16_ptr = 16-bit array access, int8_ptr = 8-bit array access 9 | // 122233 = Decimal 0xFFF2FFF = Hex, 0b10101111 = Binary, 0o23339 = Octal 10 | let int32_ptr(buffer) = 1098143098+0xFF 11 | let X = int16_ptr(buffer) 12 | print "(uint16_t)S[0] and (uint32_t)S[0] = "; X, int32_ptr(buffer) 13 | let mystr = "Hello, World!" 14 | let int8_ptr(mystr+13) = 0 15 | print $mystr 16 | let firstvariable = int8_ptr(mystr) 17 | print "first char: "; firstvariable 18 | let S = 0 19 | end 20 | endf 21 | -------------------------------------------------------------------------------- /compiler/cmp.bas: -------------------------------------------------------------------------------- 1 | function main(0) 2 | let a = (5 <= 8) && (5 := 6) 3 | print "Checking if 5 is less than 8 and 5 is equal to 6 lol. (Should be 0): " ; a 4 | let qvar = 1 5 | let ivar = 3 6 | if((qvar := 1) && (ivar != 2)) goto we_are_cool 7 | end 8 | :we_are_cool 9 | print "we are cool!" 10 | end 11 | endf 12 | -------------------------------------------------------------------------------- /compiler/div.bas: -------------------------------------------------------------------------------- 1 | function main(0) 2 | print "Testing Division and bitwise" 3 | goto mylabel 4 | print "Testing division" 5 | :mylabel 6 | let X = 21 7 | let Y = 5 8 | let Z = X / Y 9 | let R = X%Y 10 | print "Mod: "; R 11 | print "Div: "; Z 12 | let A = 50 & 2 13 | let Q = left_shift(50, 2) 14 | let C = not(Q) 15 | print "Or: "; A 16 | print "Q, C = "; Q, C 17 | input Y 18 | print "Y = "; Y 19 | print Y 20 | asm "push 0" 21 | asm "exit" 22 | endf 23 | -------------------------------------------------------------------------------- /compiler/example.bas: -------------------------------------------------------------------------------- 1 | function main(0) 2 | // Fibonacci generator 3 | let I = 1 4 | let X = 1 5 | let Y = 0 6 | while I <= 10 7 | print "FIB: "; I, X 8 | 9 | let Z = X 10 | let X = X + Y 11 | let Y = Z 12 | 13 | let I = I + 1 14 | 15 | endw 16 | asm ".data \{ mystr : db 'Thank You!', 0 \}" 17 | asm "push mystr" 18 | asm "syscall SYSCALL_PUTS" 19 | end 20 | endf 21 | -------------------------------------------------------------------------------- /compiler/float.bas: -------------------------------------------------------------------------------- 1 | function main(0) 2 | print "floating point test" 3 | // sorry bros and sis, due to this typelessness, you just fkn use different operators. 4 | let A = mul_f(11.5, add_f(30.567, 23.01)) 5 | // round off and convert to int32. 6 | let rounded_a = conv_i(A) 7 | // can convert the rounded value back too. tho the mantissa will be lost. 8 | let rounded_a_as_float = conv_f(rounded_a) 9 | // use '%' prefix for print float stuff 10 | print "result of adding 30.567, 23.01 and the multiplying with 11.5 and rounding it off as int32 "; %A, rounded_a 11 | end 12 | endf 13 | -------------------------------------------------------------------------------- /compiler/func.bas: -------------------------------------------------------------------------------- 1 | /* this is a global variable */ 2 | global myglobal 3 | function x(3) 4 | let i = add_f(add_f(2.4, mul_f(3.5, 4.6)), 5.6) 5 | print "float i = "; %i 6 | print "I'm a function take takes 3 args" 7 | let a = $1 8 | print "the number got in the first arg is: "; a 9 | /* NOTE: $2 + 15 is something different than the below 10 | $2 + 15 means load the 17th argument! This is largely different 11 | from load the 2nd argument and add 15! */ 12 | let b = $2 13 | let b = b + 15 14 | print "the number got in the second arg + 15 is :"; b 15 | let f = 5 16 | print "f in this scope is: "; f 17 | let a = $3 18 | return a 19 | endf 20 | function add2numbers(2) 21 | let a = $1 22 | let b = $2 23 | return a + b 24 | endf 25 | function subtract2numbers(2) 26 | let a = $1 27 | let b = $2 28 | return a - b 29 | endf 30 | function misc(0) 31 | let f = 0 32 | print "value of global variable"; myglobal 33 | print "f in this scope is"; f 34 | /* Dont FORGET TO RETURN! else cause undefined behaviour lol */ 35 | return 0 36 | endf 37 | function main(0) 38 | let myglobal = 5 39 | let xxx = 0 40 | let y_z = 0 41 | let f = 1 42 | @misc() 43 | let c = 24 44 | let retval = @x(100, 200, c * 5 + 2) 45 | print "return value: "; retval 46 | if (retval := c*5+2) goto correct 47 | print "lol, this failed." 48 | end 49 | :correct 50 | print "lol it's right" 51 | print "f in this scope is: "; f 52 | print "adding 2 numbers: 57 and 90+5" 53 | let result = @add2numbers(57, (90+5)) 54 | print "result = "; result 55 | print "subtracting 2 numbers: 30 and 10" 56 | let result = @subtract2numbers(30, 10) 57 | print "result = "; result 58 | end 59 | endf 60 | -------------------------------------------------------------------------------- /compiler/getc.bas: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | function main(0) 4 | print "press a key and this program will react. press Q and it will quit" 5 | let a = 0 6 | :check_key 7 | let a = @r_getc() 8 | if(a := 0) goto check_key 9 | if((a := 'Q') || (a := 'q')) asm "exit" 10 | print "you pressed key no.:"; a 11 | goto check_key 12 | endf 13 | -------------------------------------------------------------------------------- /compiler/hello.bas: -------------------------------------------------------------------------------- 1 | /* Compile as: t++ -s hello.bas -o hello.exe */ 2 | extern (test_func, "test_func.ro", 0) 3 | function main(0) 4 | @test_func() 5 | print "Hello World!" 6 | let a = 5 7 | if ( a := 5 ) print "a is 5!" 8 | print "press any key to continue!" 9 | end 10 | endf 11 | -------------------------------------------------------------------------------- /compiler/if.bas: -------------------------------------------------------------------------------- 1 | function main(0) 2 | print "If stuff" 3 | // Allocate 256 bytes for buffer 4 | let buffer = alloc(256) 5 | let int16_ptr(buffer) := 0xFF44 6 | if (int8_ptr(buffer) := 0x44) goto yes 7 | print "Uh, error!" 8 | end 9 | :yes 10 | print "Yay, little endian!" 11 | end 12 | endf 13 | -------------------------------------------------------------------------------- /compiler/include.hb: -------------------------------------------------------------------------------- 1 | #define ADD_X_Y(x, y) (x + y) 2 | -------------------------------------------------------------------------------- /compiler/input.bas: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | function main(0) 4 | print "Hello, World!" 5 | print "Welcome to my First Program" 6 | print "Type something: (11 characters):" 7 | let string = alloc(12) 8 | input string, 12 9 | print "You typed: "; $string 10 | end 11 | endf 12 | -------------------------------------------------------------------------------- /compiler/nativelib.bas: -------------------------------------------------------------------------------- 1 | native(myfunc, "./mylib.so", 1) 2 | 3 | function main(0) 4 | print "calling function from mylib.so" 5 | let asshole = @myfunc("Hello, This is the string from the main function!") 6 | print "i got (hopefully that evil number):"; asshole 7 | let myshit = 6 + 322 + 1139 8 | let stuff = myshit * 6 9 | print "stuff: "; stuff 10 | end 11 | endf 12 | -------------------------------------------------------------------------------- /compiler/preproc.bas: -------------------------------------------------------------------------------- 1 | #include "include.hb" 2 | function main(0) 3 | print "I'm a preprocessor test!" 4 | let resultofexpr = ADD_X_Y(20, 50) 5 | end 6 | endf 7 | -------------------------------------------------------------------------------- /compiler/readme.txt: -------------------------------------------------------------------------------- 1 | See docs/BASIC.html 2 | -------------------------------------------------------------------------------- /compiler/recur.bas: -------------------------------------------------------------------------------- 1 | function factorial(1) 2 | let number = $1 3 | if (number <= 1) goto func_return 4 | return number*@factorial(number-1) 5 | :func_return 6 | return 1 7 | endf 8 | 9 | function main(0) 10 | let fact = @factorial(9) 11 | print "factorial of 9: "; fact 12 | end 13 | endf 14 | -------------------------------------------------------------------------------- /compiler/string.bas: -------------------------------------------------------------------------------- 1 | function strlen(1) 2 | let i = 0 3 | let s = $1 4 | while (int8_ptr(s+i) != 0) 5 | let i = i+1 6 | endw 7 | return i 8 | endf 9 | function strcpy(2) 10 | let Source = $1 11 | let Destination = $2 12 | let i = 0 13 | while(1) 14 | print "lulz" 15 | if(int8_ptr(Source+i) := 0) goto finish 16 | let int8_ptr(Destination+i) = int8_ptr(Source+i) 17 | let i = i + 1 18 | endw 19 | :finish 20 | return 0 21 | endf 22 | function strcmp(2) 23 | let str01 = $1 24 | let str02 = $2 25 | let i = 0 26 | if (@strlen(str01) != @strlen(str02)) return 1 27 | while(i <= @strlen(str01)) 28 | let a = int8_ptr(str01+i) 29 | let b = int8_ptr(str02+i) 30 | print a 31 | print b 32 | if ((int8_ptr(str01+i)) != (int8_ptr(str02+i))) return 1 33 | let i = i + 1 34 | endw 35 | return 0 36 | endf 37 | function main(0) 38 | let strlen_ = @strlen("hello") 39 | print strlen_ 40 | let is_equal_or_not = @strcmp("hello", "hello") 41 | if (is_equal_or_not := 0) goto yay 42 | print "string doesnt work"; is_equal_or_not 43 | end 44 | :yay 45 | print "string works" 46 | let x = @strlen("hello") 47 | let x = alloc(7) 48 | @strcpy("hello", x) 49 | print "strcpy: "; x 50 | print $x 51 | end 52 | endf 53 | -------------------------------------------------------------------------------- /compiler/struct.bas: -------------------------------------------------------------------------------- 1 | #define exec_load_addr 0x100000 2 | struct mystruct(1) 3 | int32 header 4 | ends 5 | struct mystruct02(3) 6 | int8 member1 7 | int16 member2 8 | int32 member3 9 | ends 10 | function main(0) 11 | let myvar = alloc(sizeof(mystruct02)) 12 | let [struct mystruct02]myvar.member1 = 0x34 13 | let [struct mystruct02]myvar.member2 = 32768 14 | let [struct mystruct02]myvar.member3 = 0xDEADBEEF 15 | if ([struct mystruct](exec_load_addr).header := 0xBA5EBA11) goto success 16 | print "not loaded using compliant header" 17 | end 18 | :success 19 | print "compliant header detected!" 20 | print "size of mystruct02: "; sizeof(mystruct02) 21 | print "member 1 ="; [struct mystruct02]myvar.member1 22 | print "member 2 ="; [struct mystruct02]myvar.member2 23 | print "member 3 ="; [struct mystruct02]myvar.member3 24 | end 25 | endf 26 | -------------------------------------------------------------------------------- /compiler/test_func_lib.bas: -------------------------------------------------------------------------------- 1 | /* Compile as: t++ -s test_func_lib.bas -o test_func.ro -d */ 2 | function addnumbers(2) 3 | let A = $1 4 | let B = $2 5 | let C = A+B 6 | return C 7 | endf 8 | function test_func(0) 9 | print "hello, world from ro!" 10 | let num = @addnumbers(58,62) 11 | print "result: "; num 12 | return 0 13 | endf 14 | -------------------------------------------------------------------------------- /compiler/while.bas: -------------------------------------------------------------------------------- 1 | function main(0) 2 | let X = 0x0 3 | while (X <= 5) 4 | print "Doing a while loop till 5 "; X 5 | let X = X+1 6 | endw 7 | end 8 | endf 9 | -------------------------------------------------------------------------------- /disasm/build.sh: -------------------------------------------------------------------------------- 1 | export CC='gcc' 2 | export CFLAGS='-Wall -Wextra -std=gnu99 -I../src/include' 3 | $CC $CFLAGS rexdump.c -o rexdump 4 | $CC $CFLAGS readrex.c -o readrex 5 | $CC $CFLAGS cgen.c -o cgen 6 | -------------------------------------------------------------------------------- /disasm/cgen.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "../src/include/r3x_format.h" 6 | #include "../src/include/r3x_checksum_generator.h" 7 | char* ExecutableName = NULL; 8 | 9 | void ParseArguments(int argc, char* argv[]); 10 | 11 | int main(int argc, char* argv[]) { 12 | ParseArguments(argc, argv); 13 | if(ExecutableName==NULL) { 14 | printf("Pass -h option for help\n"); 15 | exit(0); 16 | } 17 | FILE* InputFile = fopen(ExecutableName, "r+b"); 18 | if(InputFile == NULL) { 19 | fprintf(stderr, "cgen: cannot open: %s\n", ExecutableName); 20 | exit(0); 21 | } 22 | fseek(InputFile, 0L, SEEK_END); 23 | unsigned int FileSize = ftell(InputFile); 24 | fseek(InputFile, 0L, SEEK_SET); 25 | uint8_t* FileBuf = malloc(FileSize+1); 26 | if(fread(FileBuf, sizeof(uint8_t), FileSize, InputFile)!=FileSize){ 27 | fprintf(stderr, "cgen: unable to read %u bytes from file: %s\n", FileSize, ExecutableName); 28 | exit(0); 29 | } 30 | r3x_header_t* Header = (r3x_header_t*)&FileBuf[0]; 31 | if(Header->checksum != 0) { 32 | fprintf(stderr, "Error: Checksum already exists\n"); 33 | exit(0); 34 | } 35 | fseek(InputFile, offsetof(r3x_header_t, checksum), SEEK_SET); 36 | uint32_t CRC32Checksum = GenerateChecksumCRC32(FileBuf, FileSize); 37 | fwrite(&CRC32Checksum, sizeof(uint32_t), 1, InputFile); 38 | printf("Generated checksum: %u\n", CRC32Checksum); 39 | printf("Checksum written to file\n"); 40 | return 0; 41 | } 42 | void ParseArguments(int argc, char* argv[]) { 43 | int i = 0; 44 | for(i = 0; i < argc; i++) { 45 | if(!strcmp(argv[i], "-exe")) { 46 | if(i+1 < argc) { 47 | ExecutableName = argv[i+1]; 48 | } else { 49 | printf("-exe option: Executable not specified\n"); 50 | } 51 | } else if(!strcmp(argv[i], "-h")) { 52 | printf("cgen - Checksum generator for R3X programs.\n"); 53 | printf("Generates a CRC32 checksum for an R3X executable\n"); 54 | printf("Usage: cgen -exe \n"); 55 | exit(0); 56 | } 57 | } 58 | } -------------------------------------------------------------------------------- /disasm/readme.txt: -------------------------------------------------------------------------------- 1 | This folder contains a couple of tools for the R3X Virtual Machine. 2 | There are three files in this directory: 3 | readrex.c - Useful for reading and parsing headers of shared libraries/executables 4 | rexdump.c - Useful for disassembling executables (shared libraries not currently supported) 5 | cgen.c - Generates a checksum of the executable, the checksum generated uses crc32 and hence is not cryptographically 6 | secure. 7 | Pass the '-h' option to the program for help. 8 | -------------------------------------------------------------------------------- /disasm/rexpack.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Benderx2/R3X/f45118d3d9b5c462dc45121742d6e514b1bfe3ed/disasm/rexpack.c -------------------------------------------------------------------------------- /docs/Building.html: -------------------------------------------------------------------------------- 1 | ```html 2 | 3 |
4 | 5 |
6 | 12 | 13 |

REX Virtual Machine Documentation

14 |

Building and running the Virtual Machine

15 | REX uses a bash script ("src/build.sh"), to configure and compile itself.
16 | In order to build it properly on your system, follow the instructions below:
17 | 1. Please ensure you've a bash (or compatible) shell for your host system.
18 | 2. Install the GNU C compiler. (For ARM the compiler is the arm-linux-gnueabi suite)
19 | 3. Next install the required libraries: libSDL, libSDL_ttf, and OpenGL for the target
20 | 4. With the 0.71b build script, you can simply build using
21 |
22 | ./build.sh arch=<archname> usegl=yes/no usedynamic=yes/no useoptimize=yes/no
23 | 
24 | Here is the description of what you may need to modify in the build script for non-developmental purposes
25 |
export TARGET="ARCHNAME"

26 | Replace "ARCHNAME" with the name of your target architecture
27 | Current options are:
28 | x86_32 - 32-bit x86 Linux
29 | x86_64 - 64-bit x86 Linux
30 | aarch64 - 64-bit ARM (little endian) Linux
31 | aarch64-big - 64-bit ARM (big endian) Linux
32 | ppc - 32/64-bit PPC Linux (Depending upon toolchain)
33 |
export USEGL="yes"
34 | Set to empty ("") if you don't want to use graphical features of REX (note: This currently has bugs, especially with multithreading, which need to be fixed)
35 |
export USEDYNAMIC="yes"
36 | Set to empty ("") if you don't want to use dynamic linking with native libraries for REX.
37 |
export USEOPTIMIZE="yes"
38 | Set to empty ("") if you don't want to use internal untested optimizations. (Required pthread support)
39 |
export OFLAGS="-O2"
40 | Optimization flags, set to -O0 for no optimization, -O3 for better optimization
41 |
export DFLAGS="-g"
42 | Set to empty ("") if you don't want debugging information in the binary
43 | 5. From the command line, run build.sh (with executable permissions)
44 | 6. The binary must be in /bin64, /bin32, /binAARCH64, depending upon target
45 | 7. "cd" to the directory, and run with: ./rxvm.out -exe [name of exe]
46 | You can also use the "-f" option to specify frequency in Kilohertz (KHz) like this: -f 1.5 47 |

Options

48 | There are a few options that can be used while invoking the VM, here is a list of them:
49 |
-exe [exename]
50 | Specifies the executable file to be used
51 |
-stack [stack size]
52 | Specifies the number of 32-bit integers that the stack is allowed to hold
53 |
-h, --help
54 | Displays licensing information and help
55 |
-f [frequency]
56 | Specifies what frequency to use in Kilohertz. The CPU runs in real time if no frequency is given. (ONLY IF COMPILED WITH -D R_DEBUG)
57 |
-s
58 | Runs the VM in client mode. NOTE: Should only be used by servers while invoking the VM.
59 |
-w
60 | Specify width of screen while using VM. Should be divisible by 16. (Works only if compiled with REX_GRAPHICS)
61 |
-h
62 | Specify height of screen while using VM. Should be divisible by 16. (Works only if compiled with REX_GRAPHICS)
63 |
-fo
64 | Specifiy a bitmap font in PNG format.
65 |
-fh
66 | Specify font height
67 |
-fw
68 | Specify font width
69 |
-fs
70 | Specify font scale [Floating Point Number]
71 |
-args "arguments"
72 | Specify program arguments
73 |
-rs scriptname
74 | Specify R3X configure script. (NOTE: The command line options will be overwritten by the scripts' ones')
75 |
76 | 77 | ``` 78 | -------------------------------------------------------------------------------- /docs/ConfigureScript.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 |
5 | 11 | 12 |

REX Virtual Machine Documentation

13 |

REX Configure Script

14 | 15 | Other than passing arguments to the VM through the command line, one can also pass a "configure" script using the -rs
16 | option.
17 | 18 |

Basic Syntax

19 | All configure types must follow this basic syntax: 20 |
21 | command: [value]
22 | 
23 | 24 |

List of commands

25 |
executable: "[exename]"
26 | Specify executable name. 27 |
args: "[args]"
28 | Specify arguments 29 |
font_file: "[font name]"
30 | Specify font file name (Must be a PNG-Bitmap font: 128x128, 256x256, 512x512) 31 |
font_height: [integer value]
32 | Specify font height 33 |
font_width: [integer value]
34 | Specify font width 35 |
font_scale: [float value]
36 | Specify font scale 37 |
screen_width: [integer value]
38 | Specify screen width (in pixels) 39 |
screen_height: [integer value]
40 | Specify screen height (in pixels) 41 |
stack: [integer value]
42 | Specify max stack size 43 |
end: 
44 | End of Script 45 | 46 |

An example script

47 | Below is an example of running args.exe with the appropriate options: 48 |
49 | executable: "args.exe"
50 | font_height: 16
51 | font_width: 16
52 | font_scale: 1.0f
53 | args: "hello, world!"
54 | end:
55 | 
56 | (NOTE: The "end:" is not needed, but is recommended.) 57 | 58 | You can also use enviroment variables in strings, for example executable: "$EXEC_FILE_NAME" will set the executable to the enviroment variable
59 | pointed by "EXEC_FILE_NAME". 60 | -------------------------------------------------------------------------------- /docs/DynamicLinking.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 |
5 | 11 | 12 |

REX Virtual Machine Documentation

13 |

Dynamic Linking

14 |
15 | 

Using the REX dynamic linker

16 |

REX Object format (*.ro)

17 | The REX Object format is used by REX shared libraries to export functions to a REX executable 18 | The header is defined in src/r3x_dynamic.h:11< 19 | 30 | TODO: Add description. 31 |

Your first dynamic library

32 | Writing a dynamic library is easy, here's an example: 33 | 34 | include 'libR3X/dynR3X.inc' 35 | .text { 36 | function test_func 37 | ; Dynamically loaded libraries must 38 | ; be relocatable that is, position independent. 39 | loadr R1, str01 40 | ; Load address of library is in R20 41 | addrr R1, R20 42 | pushr R1 43 | syscall SYSCALL_PUTS 44 | pop 45 | loadr R0, word_data 46 | addrr R0, R20 47 | lodsw 48 | pushr R1 49 | syscall SYSCALL_PUTI 50 | pop 51 | push 0xA 52 | syscall SYSCALL_PUTCH 53 | pop 54 | ; Return back! 55 | ret 56 | endfunction test_func 57 | .data { 58 | str01: db 'Hello from dynamic library! I can read stuff from addresses! word_data=', 0 59 | word_data: dw 65532 60 | dd 0xFFF3FFFF 61 | } 62 | end 63 | 64 | Your code must be position-independent as shown above! As you see, R20 is the "physical" address where your
65 | library is loaded, you should add R20 to all internal address references before doing a load/store operation,
66 | as shown above.
67 |

OPTION 1: Manually load the library and execute it:

68 |

Loading a dynamic library

69 | Loading a dynamic library is simple, simply do: 70 | pushstring "lib.ro" 71 | syscall SYSCALL_LOADDYNAMIC 72 | 73 | The library's handle will be pushed to stack. Make SURE to store it! Since this will be used to call functions. 74 |

The calldynamic instruction

75 | The calldynamic instruction is used to call a function from a library. Use it like this: 76 | 77 | push [library handle] -- Handle that you got from the above syscall 78 | pushstring [function name] -- "test_func" for the above example. 79 | calldynamic 80 |
81 | 82 |

OPTION 2: Use the import functionality

83 | Another way to do it is like this: 84 |
85 | extern test_func, "lib.ro"
86 | 
87 | ...
88 | 	externcall test_func
89 | ...
90 | 
91 | The library will be loaded automatically by the VM, and you won't have to store and do crazy things manually!
92 | -------------------------------------------------------------------------------- /docs/ExceptionHandling.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 |
5 | 11 | 12 |

REX Virtual Machine Documentation

13 |

Exception Handling

14 | Exception Handling in the REX architecture is in it's very early stages, however
15 | it is fully functional.
16 |

Kinds of exceptions

17 | As of now, there are 3 types of exceptions that can be handled, they are given below
18 | INVALID_ACCESS - Invalid Memory Access
19 | INVALID_OPCODE - Invalid Instruction
20 | INVALID_ARITH - Invalid arithmetic operation (usually a divide by 0)
21 | R_EXCEP - Program defined exception
22 |

Handling Exceptions

23 | Exceptions can be handled by assigning them with specific handlers, using the "catch" instruction.
24 | Example Usage:
25 |
26 | push handler_address
27 | push R_EXCEP/INVALID_ACCESS/INVALID_OPCODE --- Exception ID
28 | catch
29 | popn 2 ; Optional but recommended
30 | 
31 |

Throwing custom exceptions

32 | The INVALID_ACCESS/INVALID_OPCODE exceptions are caused when a program does an invalid memory access or
33 | executes an unknown instruction. But there are a third type of exception as shown above: "R_EXCEP"
34 | The 'throw' instruction is used to intentionally cause an exception. Example usage show below:
35 |
36 | push error_code
37 | push R_EXCEP
38 | throw
39 | 
40 | One advice would be to 'pop' out the exception ID at the start of the handler, which would make the error_code at the top of stack.
41 | An example is shown in src/programs/exception.asm 42 |

The 'handle' instruction

43 | The 'handle' instruction informs the CPU that the exception has been handled successfully. When an exception is thrown, the CPU
44 | sets the Exception Flag (EXF) to true. This means that any exception that is caused when the exception flag is set to true, would
45 | make the VM shutdown. This helps when the exception handlers themselves are bogus.
46 | Before resuming execution, the exception handler, must execute the 'handle' instruction, which sets the exception flag to false.
47 | If you fail to do this, the VM would simply shutdown with a "bad handler" message, if another exception is caused
48 | 49 |

Stack Overflow

50 | When a program causes a stack overflow exception, the virtual machine will simply return control to the debugger, giving a message
51 | telling the user that the stack has exceeded it's limit. The size of the stack can be specified using the "-stack" option. Please 52 | see the "Building and Running" section about this option. The default stack size of assumed to be 262144 32-bit integers
53 |
54 | 55 | -------------------------------------------------------------------------------- /docs/Memory.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 |
5 | 11 | 12 |

REX Virtual Machine Documentation

13 |

Memory

14 |

Introduction

15 |
16 | When it comes to virtual machines, memory is the first thing that needs to be take care of. Under the REX architecture, 
17 | memory can be accessed using several instructions. More information found on the "CPU Instructions" page.
18 | 
19 | Since REX is currently a primitive CPU there is no support for virtual memory, and hence all addresses
20 | accessed by the CPU are physical. It would be useful to note however, that the CPU does provide protection against
21 | malicious programs which attempt to access memory outside the allocated region.
22 | 
23 |

Stack

24 |
25 | At the core of the REX architecture, lies the stack, a memory region containing data, pushed onto by the program.
26 | The stack is the single unit being responsible for storing data required for arithmetic operations, 
27 | system calls, memory operations and so on. Since REX is a more of a stack-based machine (but it does have registers), the
28 | stack is a very important aspect of the CPU, and hence direct access to the stack is prohibited. The stack does not
29 | lie within the application memory. Access to the stack can be done using several instructions: push, pop, pushr, popr, loads etc.
30 | Please see the "CPU Instructions" page about what instructions are used to access the stack.
31 | 
32 | The REX CPU uses a totally different stack for return addresses, this ensures that the return address is not corrupted
33 | throughout simple operations which forget to pop out values. Please do note that it is a bad pratice to not pop out used 
34 | data after use on the stack, and it wastes memory.
35 | 
36 |

Memory Security

37 |
38 | The R3X architecture uses a system of memory "blocks", each block has a total length of 4096 bytes and has an attribute.
39 | The blocks can have one of the following attributes:
40 | 1. RX_EXEC
41 | R3X Execute: This block is executable, it cannot be modified or be read from.
42 | 2. RX_RW
43 | R3X Readable/Writeable: This block is readable/writeable but not executable.
44 | 3. RX_RONLY
45 | R3X Read-Only: This block is read-only, not executable.
46 | 4. RX_NOEXIST:
47 | R3X Non-Existent: Even though this block exists, it has been kept hidden from program. It is unreadable, unwriteable, and unexecutable
48 | The program's sections are required to be 4096-byte aligned, the VM maps the first 4096 bytes of memory and the program's text section as executable,
49 | while the data, symbol, and bss sections are marked as read-write.
50 | SYSCALL_ALLOC returns a page with attributes RX_RW.
51 | When a dynamic library is loaded, it's text sections are marked as RX_EXEC, and the rest as RX_RW.
52 | Writing to an non-writable section will cause a CPU_INVALID_ACCESS, while executing code in an non-executable will cause an immediate shutdown.
53 |
54 |

Reserved Memory

55 |
56 | The REX architecture reserves all memory under the program load point, and access memory below is considered undefined behaviour. The program load point is implementation defined, however all implementations are required to define
57 | the constant R3_LOAD_POINT as the load address.
58 | 
59 | Also, the first 512-bytes are reserved globally, regardless of the implementation, the first 512-bytes MUST be reserved
60 | for the system BIOS.
61 | 
62 | 
63 | 


--------------------------------------------------------------------------------
/docs/Multithreading.html:
--------------------------------------------------------------------------------
 1 | 
 2 | 
3 | 4 |
5 | 11 | 12 |

REX Virtual Machine Documentation

13 |

Multithreading

14 | The REX CPU supports multithreading through the CPU Dispatcher which dispatches jobs to the CPU's Root Domain.
15 | The CPU's root domain is made up of sub-domains which contain threading information
16 | To dispatch a job to a sub-domain, simply do: (libR3X):
17 |
System.DispatchJob job
18 | ...
19 | job:
20 | 	loadr R0, value
21 | 	code here...
22 | 
23 | 
24 | To exit from a job, use System.Quit, (note that the exit instruction works differently for the "main" domain and other domains, when the main
25 | domain exits all sub-domains are closed, but when a sub-domain exits, no modification is done to the other domains
26 | Planned support for pausing, and exitting tasks from the main domain..
27 | -------------------------------------------------------------------------------- /docs/NativeLinking.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 |
5 | 11 | 12 |

REX Virtual Machine Documentation

13 |

Native Linking

14 | REX programs are written in byte code, but can also use native code if required, through shared objects.
15 | This is known as native linking.
16 | The disadvantage of native linking is that the library needs to be rewritten/recompiled for a new platform.
17 | Please note that native linking is an experimental feature, and can be subject to changes in future
18 |

Writing a shared library

19 | First, get a copy of "virtual-machine.h" and "stack.o" located in src/programs/rex.
20 | Then compile r3x_stack.c to an object file.
21 | Then write your library like this:
22 |
23 | #include "rex/virtual-machine.h"
24 | r3x_cpu_t* CPUptr = NULL;
25 | void Start(r3x_cpu_t* CPU) {
26 | 	CPUptr = CPU;
27 | }
28 | /* 2 arugments for myfunc */
29 | #define MY_FUNC_TOTAL_ARGS 2
30 | uint32_t myfunc(void) {
31 | 	argument1 = GetArgument(0, 1, MY_FUNC_TOTAL_ARGS); // Get 1st argument
32 | 	argument2 = GetArgument(0, 2, MY_FUNC_TOTAL_ARGS); // Get 2nd argument
33 | 	return argument1+argument2; // Return
34 | }
35 | ...
36 | 
37 | Having a start function is mandatory, this will save your CPU pointer which the VM passes, now you can
38 | use this pointer to do operations on the CPU when your function is called.
39 | Compile the library using:
40 |
41 | gcc -c -Wall -Werror -fpic mylib.c -o mylib.o
42 | gcc -shared -o mylib.so mylib.o stack.o [The object file given in src/programs/rex/] -lc -lm
43 | 
44 | Then in your program, load the library like this:
45 |
46 | pushstring "mylib.so"
47 | loadlib
48 | 
49 | Execute functions, like this:
50 |
51 | pushstring "mylib.so"
52 | pushstring "myfunction"
53 | libexec
54 | 
55 | Or if you use T++, then refer to that page.
56 | An example is given in /src/programs/mylib.c and /src/programs/nativelib.il
57 | (Note that on Windows systems the extension is usually .DLL.)
58 |
59 | -------------------------------------------------------------------------------- /docs/REX.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 |
5 | 11 | 12 |

REX Virtual Machine Documentation

13 |

Preface

14 | The sole purpose of this documentation is to give a programmer an idea of how
15 | the REX architecture performs and functions and it's respective goals.
16 | It is also meant to give an overview of the technical aspects of the archi-
17 | -tecture.
18 |

Note: All bit representations in this document are in little-endian format.

19 |

Note2: This document is spefically written for R3X Virtual Machine 0.4.6b BASICPie

20 |
21 | Building and Running
22 | CPU 
23 | T++
24 | libR3X
25 | Memory 
26 | Format 
27 | Syscalls 
28 | Multithreading
29 | Native Linking
30 | Dynamic Linking
31 | Exception Handling
32 | Opcode Table
33 | Porting Guide
34 | Calling Convention
35 | Configure Scripts
36 | 


--------------------------------------------------------------------------------
/docs/REXCall.html:
--------------------------------------------------------------------------------
 1 | 
 2 | 
3 | 4 |
5 | 11 | 12 |

REX Virtual Machine Documentation

13 |

REX Calling Convention

14 | The REX Calling convention is the standard convention by which REX programs are supposed to communicate
15 | to external / internal methods.
16 | 17 | For arguments the convention uses the data stack of a domain, the arguments are to be push in ascending order,
18 | that is, the first argument is pushed first, the second is pushed second, and so on.
19 | 20 | For this mechanism to work properly, the caller MUST know the total number of arguments to be given to the method.
21 | 22 | Next, the caller must increment the stack pointer by 4, by pushing 4 registers to the data stack. They can be any 4 out of the 20 registers provided
23 | This is used to preserve registers during the call.
24 | 25 | The return value from the function is stored in R7.
26 | An example is given below (in assembly):
27 |
28 | 	push 1
29 | 	push 2
30 | 	push 3
31 | 	; Push 4 items to stack.
32 | 	; They can be regs as well, if you want to save their values
33 | 	push 0
34 | 	push 0
35 | 	push 0
36 | 	push 0
37 | 	
38 | 	call add3numbers
39 | 	
40 | 	popn 4
41 | 	; Pop out the number of args on stack
42 | 	popn 3
43 | 	...
44 | function add3numbers
45 | 	; load first argument from stack
46 | 	loadr R8, 4+3
47 | 	loadsr R8
48 | 	loadr R7, R8
49 | 	; Load second argument from stack
50 | 	loadr R8, 4+2
51 | 	loadsr R8
52 | 	addrr R7, R8
53 | 	; Load third argument from stack
54 | 	loadr R8, 4+1
55 | 	loadsr R8
56 | 	addr R7, R8
57 | 	; Return
58 | 	ret
59 | 	...
60 | 
61 | -------------------------------------------------------------------------------- /docs/Syscalls.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 |
5 | 11 | 12 |

REX Virtual Machine Documentation

13 |

Syscalls

14 | The syscall instruction is provided by the CPU, however what it means is totally implementation defined.
15 | Due to this, REX programs will have huge problems while running on different implementations, to solve this problem
16 | the standard defines certain system calls which need to be present in every implementation.
17 | The following system calls are to be defined in every implementation which conforms to the REX standard.
18 | SYSCALL_PUTCH - Print an 8-bit ASCII character pushed to stack to stdout or any other graphics device assumed to be stdout
19 | SYSCALL_PUTS - Print an unformatted string to program's stdout or any other graphics device which is assumed to be stdout.
20 | SYSCALL_PUTI/SYSCALL_PUTF - Print an integer/float pushed to stack to stdout or any other graphics device assumed to be stdout
21 | SYSCALL_GETC - Get a character from stdin or an input device assumed to be stdin.
22 | SYSCALL_ATOI - Convert string which is pointed by the last value pushed to stack, and push the converted value to stack.
23 | SYSCALL_ALLOC - Allocate one page. The size of one segment is implementation defined. All implementations are required to define a constant "R3_SEGMENT_SIZE"
24 | SYSCALL_DISPATCH - Dispatch a background job, whose instruction pointer is pushed to stack.
25 | SYSCALL_LOADDYANMIC - Load a dynamic library and push it's handle.
26 | SYSCALL_OPENSTREAM - Opens a stream, whose name is pushed to stack, and then pushes the file handle to stack.
27 | SYSCALL_SEEKSTREAM - Sets pointer in stream. The arguments are in the following order:
28 |
29 | push [handle]
30 | push [offset]
31 | push [origin] - SEEK_SET (Beginning of file), SEEK_CUR (Current position), SEEK_END (EOF)

32 | SYSCALL_READSTREAM/SYSCALL_WRITESTREAM - Reads/Writes to/from stream. The arguments are in the following order
33 |
push [handle]
34 | push [buffer address]
35 | push [size]
36 | SYSCALL_TELLSTREAM - Pushes current pointer of a stream whose handle is pushed to stack
37 | SYSCALL_CLOSESTREAM - Closes an open stream whose handle is pushed to stack
38 |

Non standard syscalls

39 | SYSCALL_GETCPUCLOCK - Returns current CPU time (pushes to stack).
40 | SYSCALL_GETCLOCKSPERSEC - Return how many CPU clocks are equivalent to 1 second (pushes to stack)
41 | SYSCALL_GETARGS - Return address of the string which contains program arguments.
42 |
43 | 44 | -------------------------------------------------------------------------------- /docs/data/CREDITS.txt: -------------------------------------------------------------------------------- 1 | I do not own the "background.jpg" file located in the current directory. 2 | Source: http://www.elegantthemes.com/blog/freebie-of-the-week/20-free-background-images-for-wordpress 3 | As of Thursday 25th December 2014, the page says: 4 | "......These images are released as Open Source under the GPL (GNU General Public License) 2.0......" 5 | Please find a copy of the GPLv2 here: www.gnu.org/licenses/gpl-2.0.html 6 | 7 | "logo.png" file created using cooltext.com. 8 | -------------------------------------------------------------------------------- /docs/data/background.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Benderx2/R3X/f45118d3d9b5c462dc45121742d6e514b1bfe3ed/docs/data/background.jpg -------------------------------------------------------------------------------- /docs/data/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Benderx2/R3X/f45118d3d9b5c462dc45121742d6e514b1bfe3ed/docs/data/logo.png -------------------------------------------------------------------------------- /docs/libR3X.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 |
5 | 11 | 12 |

REX Virtual Machine Documentation

13 |

libR3X - REX Standard Library

14 | libR3X is a library provided by the offical REX CPU implementation, it contains useful macro instructions and defines that can used by the
15 | program.
16 | The current implementation provides the following functions:
17 |
18 | Console.Write "String" - Writes an unformatted string to stdout or graphics device assumed to be stdout.
19 | Console.NewLine - Writes a newline character to stdout or graphics device assumed to be stdout.
20 | Console.WriteFloat - Writes an IEEE754 floating point number pushed on stack to stdout or graphics device assumed to be stdout.
21 | Console.WriteInt - Writes a 32-bit integer pushed on stack to stdout or graphics device assumed to be stdout.
22 | Console.WritePointer addr - Write an unformatted string pointer by "addr", to stdout or graphics device assumed to be stdout.
23 | Console.WaitKey - Waits for keypress and returns.
24 | Console.GetInput size, addr - Get input from console into string pointed by "addr", with size "size".
25 | Memcpy dest, src, len - Copies a chunk of memory.
26 | MemcpyR - Copies a chunck of memory but uses registers. R0 = dest, R1 = src, R2 = len
27 | System.AllocatePage - Allocate 1 segment of memory.
28 | System.Quit status - Quit with Status.
29 | Stack.Push, Stack,Pop, Stack.PushRegister, Stack.PopRegister - Class based push, pop, pushr and popr functions.
30 | StoreInt addr, int | StoreByte addr, byte Stores an 8/32-bit value in "int" to address pointed by "addr"
31 | System.DispatchJob jobaddr - Dispatch a job with IP of "jobaddr" 
32 | 

Constans

33 | libR3X also defines a few constants that the programs can use
34 | SEEK_SET, SEEK_CUR, SEEK_END: Values to be passed to "syscall SYSCALL_SEEKSTREAM" 35 | R_FALSE, R_TRUE: Boolean values. 36 | M_PI, M_E: e and pi constants. 37 |
38 |
39 | 40 | -------------------------------------------------------------------------------- /docs/notes.txt: -------------------------------------------------------------------------------- 1 | notes: random notes written by me for reference 2 | 3 | 4 | 1. garbage collection: 5 | 6 | i'd like to implement garbage collection as soon as possible, but it's kinda challenging, 7 | because of the design of the virtual machine. firstly, the vm is very simple when it comes 8 | to the instruction set, everything on the stack is just an integer, there are no types or whatever. 9 | 10 | but it would still be possible, if somehow i could update the vm about the state of variables etc. 11 | 12 | the plan would roughly be like: 13 | 14 | --> allocate variable 15 | --> call a specific "function" called gc_add 16 | --> gc_add will add the variable and the pointer to the list 17 | --> 18 | -------------------------------------------------------------------------------- /fasm/examples/elfexe/dynamic/elf.inc: -------------------------------------------------------------------------------- 1 | 2 | macro Elf32_Sym name,value,size,bind,type,other,shndx 3 | { 4 | dd name+0 5 | dd value+0 6 | dd size+0 7 | db (bind+0) shl 4 + (type+0) 8 | db other+0 9 | dw shndx+0 10 | } 11 | 12 | virtual at 0 13 | Elf32_Sym 14 | sizeof.Elf32_Sym = $ 15 | end virtual 16 | 17 | macro Elf32_Rel offset,symbol,type 18 | { 19 | dd offset+0 20 | dd (symbol+0) shl 8 + (type+0) 21 | } 22 | 23 | virtual at 0 24 | Elf32_Rel 25 | sizeof.Elf32_Rel = $ 26 | end virtual 27 | 28 | macro Elf32_Rela offset,symbol,type,addend 29 | { 30 | dd offset+0 31 | dd (symbol+0) shl 8 + (type+0) 32 | dd addend+0 33 | } 34 | 35 | virtual at 0 36 | Elf32_Rela 37 | sizeof.Elf32_Rela = $ 38 | end virtual 39 | 40 | macro Elf64_Sym name,value,size,bind,type,other,shndx 41 | { 42 | dd name+0 43 | db (bind+0) shl 4 + (type+0) 44 | db other+0 45 | dw shndx+0 46 | dq value+0 47 | dq size+0 48 | } 49 | 50 | virtual at 0 51 | Elf64_Sym 52 | sizeof.Elf64_Sym = $ 53 | end virtual 54 | 55 | macro Elf64_Rel offset,symbol,type 56 | { 57 | dq offset+0 58 | dq (symbol+0) shl 32 + (type+0) 59 | } 60 | 61 | virtual at 0 62 | Elf64_Rel 63 | sizeof.Elf64_Rel = $ 64 | end virtual 65 | 66 | macro Elf64_Rela offset,symbol,type,addend 67 | { 68 | dq offset+0 69 | dq (symbol+0) shl 32 + (type+0) 70 | dq addend+0 71 | } 72 | 73 | virtual at 0 74 | Elf64_Rela 75 | sizeof.Elf64_Rela = $ 76 | end virtual 77 | 78 | DT_NULL = 0 79 | DT_NEEDED = 1 80 | DT_HASH = 4 81 | DT_STRTAB = 5 82 | DT_SYMTAB = 6 83 | DT_RELA = 7 84 | DT_RELASZ = 8 85 | DT_RELAENT = 9 86 | DT_STRSZ = 10 87 | DT_SYMENT = 11 88 | DT_REL = 17 89 | DT_RELSZ = 18 90 | DT_RELENT = 19 91 | 92 | STB_LOCAL = 0 93 | STB_GLOBAL = 1 94 | STB_WEAK = 2 95 | 96 | STT_NOTYPE = 0 97 | STT_OBJECT = 1 98 | STT_FUNC = 2 99 | STT_SECTION = 3 100 | STT_FILE = 4 101 | 102 | R_386_NONE = 0 103 | R_386_32 = 1 104 | R_386_PC32 = 2 105 | R_386_GOT32 = 3 106 | R_386_PLT32 = 4 107 | R_386_COPY = 5 108 | R_386_GLOB_DAT = 6 109 | R_386_JMP_SLOT = 7 110 | R_386_RELATIVE = 8 111 | R_386_GOTOFF = 9 112 | R_386_GOTPC = 10 113 | 114 | R_X86_64_NONE = 0 115 | R_X86_64_64 = 1 116 | R_X86_64_PC32 = 2 117 | R_X86_64_GOT32 = 3 118 | R_X86_64_PLT32 = 4 119 | R_X86_64_COPY = 5 120 | R_X86_64_GLOB_DAT = 6 121 | R_X86_64_JUMP_SLOT = 7 122 | R_X86_64_RELATIVE = 8 123 | R_X86_64_GOTPCREL = 9 124 | R_X86_64_32 = 10 125 | R_X86_64_32S = 11 126 | R_X86_64_16 = 12 127 | R_X86_64_PC16 = 13 128 | R_X86_64_8 = 14 129 | R_X86_64_PC8 = 15 130 | R_X86_64_DPTMOD64 = 16 131 | R_X86_64_DTPOFF64 = 17 132 | R_X86_64_TPOFF64 = 18 133 | R_X86_64_TLSGD = 19 134 | R_X86_64_TLSLD = 20 135 | R_X86_64_DTPOFF32 = 21 136 | R_X86_64_GOTTPOFF = 22 137 | R_X86_64_TPOFF32 = 23 138 | R_X86_64_PC64 = 24 139 | R_X86_64_GOTOFF64 = 25 140 | R_X86_64_GOTPC32 = 26 141 | -------------------------------------------------------------------------------- /fasm/examples/elfexe/dynamic/hello: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Benderx2/R3X/f45118d3d9b5c462dc45121742d6e514b1bfe3ed/fasm/examples/elfexe/dynamic/hello -------------------------------------------------------------------------------- /fasm/examples/elfexe/dynamic/hello.asm: -------------------------------------------------------------------------------- 1 | 2 | format ELF executable 3 3 | entry start 4 | 5 | include 'import32.inc' 6 | include 'proc32.inc' 7 | 8 | interpreter '/lib/ld-linux.so.2' 9 | needed 'libc.so.6' 10 | import printf,exit 11 | 12 | segment readable executable 13 | 14 | start: 15 | cinvoke printf,msg 16 | cinvoke exit 17 | 18 | segment readable writeable 19 | 20 | msg db 'Hello world!',0xA,0 21 | -------------------------------------------------------------------------------- /fasm/examples/elfexe/dynamic/hello64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Benderx2/R3X/f45118d3d9b5c462dc45121742d6e514b1bfe3ed/fasm/examples/elfexe/dynamic/hello64 -------------------------------------------------------------------------------- /fasm/examples/elfexe/dynamic/hello64.asm: -------------------------------------------------------------------------------- 1 | 2 | format ELF64 executable 3 3 | entry start 4 | 5 | include 'import64.inc' 6 | 7 | interpreter '/lib64/ld-linux-x86-64.so.2' 8 | needed 'libc.so.6' 9 | import printf,exit 10 | 11 | segment readable executable 12 | 13 | start: 14 | 15 | lea rdi,[msg] 16 | xor eax,eax 17 | call [printf] 18 | 19 | call [exit] 20 | 21 | segment readable writeable 22 | 23 | msg db 'Hello world!',0xA,0 24 | -------------------------------------------------------------------------------- /fasm/examples/elfexe/dynamic/import32.inc: -------------------------------------------------------------------------------- 1 | 2 | include 'elf.inc' 3 | 4 | macro interpreter [library] 5 | { 6 | segment interpreter readable 7 | db library,0 8 | } 9 | 10 | macro needed [library] 11 | { 12 | local str 13 | match needed,needed@dynamic \{ define needed@dynamic needed,str:library \} 14 | match ,needed@dynamic \{ define needed@dynamic str:library \} 15 | } 16 | define needed@dynamic 17 | 18 | macro import [name] 19 | { 20 | common 21 | local strtab,strsz,symtab,rel,relsz,hash 22 | segment dynamic readable 23 | match needed,needed@dynamic 24 | \{ irp item,needed \\{ match str:library,item \\\{ dd DT_NEEDED,str-strtab \\\} \\} \} 25 | dd DT_STRTAB,strtab 26 | dd DT_STRSZ,strsz 27 | dd DT_SYMTAB,symtab 28 | dd DT_SYMENT,sizeof.Elf32_Sym 29 | dd DT_REL,rel 30 | dd DT_RELSZ,relsz 31 | dd DT_RELENT,sizeof.Elf32_Rel 32 | dd DT_HASH,hash 33 | dd DT_NULL,0 34 | segment readable writeable 35 | symtab: Elf32_Sym 36 | forward 37 | local fstr 38 | Elf32_Sym fstr-strtab,0,0,STB_GLOBAL,STT_FUNC,0,0 39 | common 40 | rel: 41 | local counter 42 | counter = 1 43 | forward 44 | Elf32_Rel name,counter,R_386_32 45 | counter = counter+1 46 | common 47 | relsz = $-rel 48 | hash: 49 | dd 1,counter 50 | dd 0 51 | repeat counter 52 | if %=counter 53 | dd 0 54 | else 55 | dd % 56 | end if 57 | end repeat 58 | strtab db 0 59 | forward 60 | fstr db `name,0 61 | common 62 | match needed,needed@dynamic 63 | \{ irp item,needed \\{ match str:library,item \\\{ str db library,0 \\\} \\} \} 64 | strsz = $-strtab 65 | forward 66 | name dd 0 67 | } 68 | -------------------------------------------------------------------------------- /fasm/examples/elfexe/dynamic/import64.inc: -------------------------------------------------------------------------------- 1 | 2 | include 'elf.inc' 3 | 4 | macro interpreter [library] 5 | { 6 | segment interpreter readable 7 | db library,0 8 | } 9 | 10 | macro needed [library] 11 | { 12 | local str 13 | match needed,needed@dynamic \{ define needed@dynamic needed,str:library \} 14 | match ,needed@dynamic \{ define needed@dynamic str:library \} 15 | } 16 | define needed@dynamic 17 | 18 | macro import [name] 19 | { 20 | common 21 | local strtab,strsz,symtab,rel,relsz,hash 22 | segment dynamic readable 23 | match needed,needed@dynamic 24 | \{ irp item,needed \\{ match str:library,item \\\{ dq DT_NEEDED,str-strtab \\\} \\} \} 25 | dq DT_STRTAB,strtab 26 | dq DT_STRSZ,strsz 27 | dq DT_SYMTAB,symtab 28 | dq DT_SYMENT,sizeof.Elf64_Sym 29 | dq DT_RELA,rela 30 | dq DT_RELASZ,relasz 31 | dq DT_RELAENT,sizeof.Elf64_Rela 32 | dq DT_HASH,hash 33 | dq DT_NULL,0 34 | segment readable writeable 35 | symtab: Elf64_Sym 36 | forward 37 | local fstr 38 | Elf64_Sym fstr-strtab,0,0,STB_GLOBAL,STT_FUNC,0,0 39 | common 40 | rela: 41 | local counter 42 | counter = 1 43 | forward 44 | Elf64_Rela name,counter,R_X86_64_64 45 | counter = counter+1 46 | common 47 | relasz = $-rela 48 | hash: 49 | dd 1,counter 50 | dd 0 51 | repeat counter 52 | if %=counter 53 | dd 0 54 | else 55 | dd % 56 | end if 57 | end repeat 58 | strtab db 0 59 | forward 60 | fstr db `name,0 61 | common 62 | match needed,needed@dynamic 63 | \{ irp item,needed \\{ match str:library,item \\\{ str db library,0 \\\} \\} \} 64 | strsz = $-strtab 65 | forward 66 | name dq 0 67 | } 68 | -------------------------------------------------------------------------------- /fasm/examples/elfexe/hello: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Benderx2/R3X/f45118d3d9b5c462dc45121742d6e514b1bfe3ed/fasm/examples/elfexe/hello -------------------------------------------------------------------------------- /fasm/examples/elfexe/hello.asm: -------------------------------------------------------------------------------- 1 | 2 | ; fasm demonstration of writing simple ELF executable 3 | 4 | format ELF executable 3 5 | entry start 6 | 7 | segment readable executable 8 | 9 | start: 10 | 11 | mov eax,4 12 | mov ebx,1 13 | mov ecx,msg 14 | mov edx,msg_size 15 | int 0x80 16 | 17 | mov eax,1 18 | xor ebx,ebx 19 | int 0x80 20 | 21 | segment readable writeable 22 | 23 | msg db 'Hello world!',0xA 24 | msg_size = $-msg 25 | -------------------------------------------------------------------------------- /fasm/examples/elfexe/hello64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Benderx2/R3X/f45118d3d9b5c462dc45121742d6e514b1bfe3ed/fasm/examples/elfexe/hello64 -------------------------------------------------------------------------------- /fasm/examples/elfexe/hello64.asm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Benderx2/R3X/f45118d3d9b5c462dc45121742d6e514b1bfe3ed/fasm/examples/elfexe/hello64.asm -------------------------------------------------------------------------------- /fasm/examples/elfobj/msgdemo.asm: -------------------------------------------------------------------------------- 1 | 2 | ; fasm demonstration of assembling object files 3 | 4 | ; compile the program using commands like: 5 | ; fasm msgdemo.asm msgdemo.o 6 | ; fasm writemsg.asm writemsg.o 7 | ; ld msgdemo.o writemsg.o -o msgdemo 8 | 9 | format ELF 10 | 11 | section '.text' executable 12 | 13 | public _start 14 | _start: 15 | 16 | extrn writemsg 17 | 18 | mov esi,msg 19 | call writemsg 20 | 21 | mov eax,1 22 | xor ebx,ebx 23 | int 0x80 24 | 25 | section '.data' writeable 26 | 27 | msg db "Elves are coming!",0xA,0 28 | -------------------------------------------------------------------------------- /fasm/examples/elfobj/msgdemo.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Benderx2/R3X/f45118d3d9b5c462dc45121742d6e514b1bfe3ed/fasm/examples/elfobj/msgdemo.o -------------------------------------------------------------------------------- /fasm/examples/elfobj/writemsg.asm: -------------------------------------------------------------------------------- 1 | 2 | format ELF 3 | 4 | section '.text' executable 5 | 6 | public writemsg 7 | 8 | writemsg: 9 | mov ecx,esi 10 | find_end: 11 | lodsb 12 | or al,al 13 | jnz find_end 14 | mov edx,esi 15 | sub edx,ecx 16 | mov eax,4 17 | mov ebx,1 18 | int 0x80 19 | ret 20 | -------------------------------------------------------------------------------- /fasm/examples/elfobj/writemsg.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Benderx2/R3X/f45118d3d9b5c462dc45121742d6e514b1bfe3ed/fasm/examples/elfobj/writemsg.o -------------------------------------------------------------------------------- /fasm/examples/libcdemo/ccall.inc: -------------------------------------------------------------------------------- 1 | 2 | macro ccall proc,[arg] 3 | { common 4 | local size 5 | size = 0 6 | mov ebp,esp 7 | if ~ arg eq 8 | forward 9 | size = size + 4 10 | common 11 | sub esp,size 12 | end if 13 | and esp,-16 14 | if ~ arg eq 15 | add esp,size 16 | reverse 17 | pushd arg 18 | common 19 | end if 20 | call proc 21 | mov esp,ebp } 22 | 23 | -------------------------------------------------------------------------------- /fasm/examples/libcdemo/libcdemo.asm: -------------------------------------------------------------------------------- 1 | 2 | ; fasm example of using the C library in Unix systems 3 | 4 | ; compile the source with commands like: 5 | ; fasm libcdemo.asm libcdemo.o 6 | ; gcc libcdemo.o -o libcdemo 7 | ; strip libcdemo 8 | 9 | format ELF 10 | 11 | include 'ccall.inc' 12 | 13 | section '.text' executable 14 | 15 | public main 16 | extrn printf 17 | extrn getpid 18 | 19 | main: 20 | call getpid 21 | ccall printf, msg,eax 22 | ret 23 | 24 | section '.data' writeable 25 | 26 | msg db "Current process ID is %d.",0xA,0 27 | -------------------------------------------------------------------------------- /fasm/examples/libcdemo/libcdemo.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Benderx2/R3X/f45118d3d9b5c462dc45121742d6e514b1bfe3ed/fasm/examples/libcdemo/libcdemo.o -------------------------------------------------------------------------------- /fasm/license.txt: -------------------------------------------------------------------------------- 1 | 2 | flat assembler version 1.71 3 | Copyright (c) 1999-2013, Tomasz Grysztar. 4 | All rights reserved. 5 | 6 | This program is free for commercial and non-commercial use as long as 7 | the following conditions are adhered to. 8 | 9 | Copyright remains Tomasz Grysztar, and as such any Copyright notices 10 | in the code are not to be removed. 11 | 12 | Redistribution and use in source and binary forms, with or without 13 | modification, are permitted provided that the following conditions are 14 | met: 15 | 16 | 1. Redistributions of source code must retain the above copyright notice, 17 | this list of conditions and the following disclaimer. 18 | 2. Redistributions in binary form must reproduce the above copyright 19 | notice, this list of conditions and the following disclaimer in the 20 | documentation and/or other materials provided with the distribution. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 24 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 25 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR 26 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 27 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 28 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 29 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 30 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 31 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | The licence and distribution terms for any publically available 35 | version or derivative of this code cannot be changed. i.e. this code 36 | cannot simply be copied and put under another distribution licence 37 | (including the GNU Public Licence). 38 | -------------------------------------------------------------------------------- /fasm/source/messages.inc: -------------------------------------------------------------------------------- 1 | 2 | ; flat assembler core 3 | ; Copyright (c) 1999-2014, Tomasz Grysztar. 4 | ; All rights reserved. 5 | 6 | _out_of_memory db 'out of memory',0 7 | _stack_overflow db 'out of stack space',0 8 | _main_file_not_found db 'source file not found',0 9 | _unexpected_end_of_file db 'unexpected end of file',0 10 | _code_cannot_be_generated db 'code cannot be generated',0 11 | _format_limitations_exceeded db 'format limitations exceeded',0 12 | _invalid_definition db 'invalid definition provided',0 13 | _write_failed db 'write failed',0 14 | _file_not_found db 'file not found',0 15 | _error_reading_file db 'error reading file',0 16 | _invalid_file_format db 'invalid file format',0 17 | _invalid_macro_arguments db 'invalid macro arguments',0 18 | _incomplete_macro db 'incomplete macro',0 19 | _unexpected_characters db 'unexpected characters',0 20 | _invalid_argument db 'invalid argument',0 21 | _illegal_instruction db 'illegal instruction',0 22 | _invalid_operand db 'invalid operand',0 23 | _invalid_operand_size db 'invalid size of operand',0 24 | _operand_size_not_specified db 'operand size not specified',0 25 | _operand_sizes_do_not_match db 'operand sizes do not match',0 26 | _invalid_address_size db 'invalid size of address value',0 27 | _address_sizes_do_not_agree db 'address sizes do not agree',0 28 | _disallowed_combination_of_registers db 'disallowed combination of registers',0 29 | _long_immediate_not_encodable db 'not encodable with long immediate',0 30 | _relative_jump_out_of_range db 'relative jump out of range',0 31 | _invalid_expression db 'invalid expression',0 32 | _invalid_address db 'invalid address',0 33 | _invalid_value db 'invalid value',0 34 | _value_out_of_range db 'value out of range',0 35 | _undefined_symbol db 'undefined symbol',0 36 | _symbol_out_of_scope_1 db 'symbol',0 37 | _symbol_out_of_scope_2 db 'out of scope',0 38 | _invalid_use_of_symbol db 'invalid use of symbol',0 39 | _name_too_long db 'name too long',0 40 | _invalid_name db 'invalid name',0 41 | _reserved_word_used_as_symbol db 'reserved word used as symbol',0 42 | _symbol_already_defined db 'symbol already defined',0 43 | _missing_end_quote db 'missing end quote',0 44 | _missing_end_directive db 'missing end directive',0 45 | _unexpected_instruction db 'unexpected instruction',0 46 | _extra_characters_on_line db 'extra characters on line',0 47 | _section_not_aligned_enough db 'section is not aligned enough',0 48 | _setting_already_specified db 'setting already specified',0 49 | _data_already_defined db 'data already defined',0 50 | _too_many_repeats db 'too many repeats',0 51 | _invoked_error db 'error directive encountered in source file',0 52 | _assertion_failed db 'assertion failed',0 53 | -------------------------------------------------------------------------------- /fasm/source/variable.inc: -------------------------------------------------------------------------------- 1 | 2 | ; flat assembler core variables 3 | ; Copyright (c) 1999-2014, Tomasz Grysztar. 4 | ; All rights reserved. 5 | 6 | ; Variables which have to be set up by interface: 7 | 8 | memory_start dd ? 9 | memory_end dd ? 10 | 11 | additional_memory dd ? 12 | additional_memory_end dd ? 13 | 14 | stack_limit dd ? 15 | 16 | input_file dd ? 17 | output_file dd ? 18 | symbols_file dd ? 19 | 20 | passes_limit dw ? 21 | 22 | ; Internal core variables: 23 | 24 | current_pass dw ? 25 | 26 | include_paths dd ? 27 | free_additional_memory dd ? 28 | source_start dd ? 29 | code_start dd ? 30 | code_size dd ? 31 | real_code_size dd ? 32 | written_size dd ? 33 | headers_size dd ? 34 | 35 | current_line dd ? 36 | macro_line dd ? 37 | macro_block dd ? 38 | macro_block_line dd ? 39 | macro_block_line_number dd ? 40 | macro_symbols dd ? 41 | struc_name dd ? 42 | struc_label dd ? 43 | instant_macro_start dd ? 44 | parameters_end dd ? 45 | locals_counter rb 8 46 | current_locals_prefix dd ? 47 | anonymous_reverse dd ? 48 | anonymous_forward dd ? 49 | labels_list dd ? 50 | label_hash dd ? 51 | label_leaf dd ? 52 | hash_tree dd ? 53 | addressing_space dd ? 54 | undefined_data_start dd ? 55 | undefined_data_end dd ? 56 | counter dd ? 57 | counter_limit dd ? 58 | error_info dd ? 59 | error_line dd ? 60 | error dd ? 61 | tagged_blocks dd ? 62 | structures_buffer dd ? 63 | number_start dd ? 64 | current_offset dd ? 65 | value dq ? 66 | fp_value rd 8 67 | adjustment dq ? 68 | symbol_identifier dd ? 69 | address_symbol dd ? 70 | address_high dd ? 71 | format_flags dd ? 72 | resolver_flags dd ? 73 | symbols_stream dd ? 74 | number_of_relocations dd ? 75 | number_of_sections dd ? 76 | stub_size dd ? 77 | stub_file dd ? 78 | current_section dd ? 79 | machine dw ? 80 | subsystem dw ? 81 | subsystem_version dd ? 82 | image_base dd ? 83 | image_base_high dd ? 84 | resource_data dd ? 85 | resource_size dd ? 86 | actual_fixups_size dd ? 87 | reserved_fixups dd ? 88 | reserved_fixups_size dd ? 89 | last_fixup_base dd ? 90 | last_fixup_header dd ? 91 | parenthesis_stack dd ? 92 | blocks_stack dd ? 93 | parsed_lines dd ? 94 | logical_value_parentheses dd ? 95 | file_extension dd ? 96 | 97 | operand_size db ? 98 | size_override db ? 99 | operand_prefix db ? 100 | opcode_prefix db ? 101 | rex_prefix db ? 102 | vex_required db ? 103 | vex_register db ? 104 | immediate_size db ? 105 | 106 | base_code db ? 107 | extended_code db ? 108 | supplemental_code db ? 109 | postbyte_register db ? 110 | segment_register db ? 111 | xop_opcode_map db ? 112 | 113 | mmx_size db ? 114 | jump_type db ? 115 | push_size db ? 116 | value_size db ? 117 | address_size db ? 118 | label_size db ? 119 | size_declared db ? 120 | 121 | value_undefined db ? 122 | value_constant db ? 123 | value_type db ? 124 | value_sign db ? 125 | fp_sign db ? 126 | fp_format db ? 127 | address_sign db ? 128 | compare_type db ? 129 | logical_value_wrapping db ? 130 | next_pass_needed db ? 131 | output_format db ? 132 | code_type db ? 133 | adjustment_sign db ? 134 | 135 | macro_status db ? 136 | default_argument_value db ? 137 | prefixed_instruction db ? 138 | formatter_symbols_allowed db ? 139 | free_address_range db ? 140 | 141 | 142 | characters rb 100h 143 | converted rb 100h 144 | message rb 200h 145 | -------------------------------------------------------------------------------- /fasm/source/version.inc: -------------------------------------------------------------------------------- 1 | 2 | ; flat assembler version 1.71 3 | ; Copyright (c) 1999-2014, Tomasz Grysztar. 4 | ; All rights reserved. 5 | ; 6 | ; This programs is free for commercial and non-commercial use as long as 7 | ; the following conditions are adhered to. 8 | ; 9 | ; Redistribution and use in source and binary forms, with or without 10 | ; modification, are permitted provided that the following conditions are 11 | ; met: 12 | ; 13 | ; 1. Redistributions of source code must retain the above copyright notice, 14 | ; this list of conditions and the following disclaimer. 15 | ; 2. Redistributions in binary form must reproduce the above copyright 16 | ; notice, this list of conditions and the following disclaimer in the 17 | ; documentation and/or other materials provided with the distribution. 18 | ; 19 | ; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | ; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 | ; TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 22 | ; PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR 23 | ; CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24 | ; EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 | ; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26 | ; PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 27 | ; LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28 | ; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 | ; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | ; 31 | ; The licence and distribution terms for any publically available 32 | ; version or derivative of this code cannot be changed. i.e. this code 33 | ; cannot simply be copied and put under another distribution licence 34 | ; (including the GNU Public Licence). 35 | 36 | VERSION_STRING equ "1.71.22" 37 | 38 | VERSION_MAJOR = 1 39 | VERSION_MINOR = 71 40 | -------------------------------------------------------------------------------- /fasm/tools/dos/loader.inc: -------------------------------------------------------------------------------- 1 | 2 | segment loader use16 3 | 4 | init: 5 | 6 | mov ax,1687h 7 | int 2Fh 8 | or ax,ax ; DPMI installed? 9 | jnz short no_dpmi 10 | test bl,1 ; 32-bit programs supported? 11 | jz short no_dpmi 12 | mov word [cs:mode_switch],di 13 | mov word [cs:mode_switch+2],es 14 | mov bx,si ; allocate memory for DPMI data 15 | mov ah,48h 16 | int 21h 17 | jnc init_protected_mode 18 | init_failed: 19 | call init_error 20 | db 'error: DPMI initialization failed.',0Dh,0Ah,0 21 | no_dpmi: 22 | call init_error 23 | db 'error: 32-bit DPMI services are not available.',0Dh,0Ah,0 24 | init_error: 25 | pop si 26 | push cs 27 | pop ds 28 | display_error: 29 | lodsb 30 | test al,al 31 | jz short error_finish 32 | mov dl,al 33 | mov ah,2 34 | int 21h 35 | jmp short display_error 36 | error_finish: 37 | mov ax,4CFFh 38 | int 21h 39 | init_protected_mode: 40 | mov es,ax 41 | mov ds,[ds:2Ch] 42 | mov ax,1 43 | call far [cs:mode_switch] ; switch to protected mode 44 | jc init_failed 45 | mov cx,1 46 | xor ax,ax 47 | int 31h ; allocate descriptor for code 48 | jc init_failed 49 | mov si,ax 50 | xor ax,ax 51 | int 31h ; allocate descriptor for data 52 | jc init_failed 53 | mov di,ax 54 | mov dx,cs 55 | lar cx,dx 56 | shr cx,8 57 | or cx,0C000h 58 | mov bx,si 59 | mov ax,9 60 | int 31h ; set code descriptor access rights 61 | jc init_failed 62 | mov dx,ds 63 | lar cx,dx 64 | shr cx,8 65 | or cx,0C000h 66 | mov bx,di 67 | int 31h ; set data descriptor access rights 68 | jc init_failed 69 | mov ecx,main 70 | shl ecx,4 71 | mov dx,cx 72 | shr ecx,16 73 | mov ax,7 74 | int 31h ; set data descriptor base address 75 | jc init_failed 76 | mov bx,si 77 | int 31h ; set code descriptor base address 78 | jc init_failed 79 | mov cx,0FFFFh 80 | mov dx,0FFFFh 81 | mov ax,8 ; set segment limit to 4 GB 82 | int 31h 83 | jc init_failed 84 | mov bx,di 85 | int 31h 86 | jc init_failed 87 | mov ax,ds 88 | mov ds,di 89 | mov [psp_selector],es 90 | mov [environment_selector],ax 91 | cli 92 | mov ss,di 93 | mov esp,stack_top 94 | sti 95 | mov es,di 96 | xor eax,eax 97 | mov [memory_handles_count],eax 98 | push si 99 | push start 100 | retf 101 | 102 | mode_switch dd ? 103 | -------------------------------------------------------------------------------- /fasm/tools/dos/prepsrc.asm: -------------------------------------------------------------------------------- 1 | 2 | format MZ 3 | heap 0 4 | stack 8000h 5 | entry loader:init 6 | 7 | include 'loader.inc' 8 | 9 | segment main use32 10 | 11 | start: 12 | 13 | call get_params 14 | jnc make_dump 15 | 16 | mov esi,_usage 17 | call display_string 18 | mov ax,4C02h 19 | int 21h 20 | 21 | make_dump: 22 | call preprocessed_source 23 | mov ax,4C00h 24 | int 21h 25 | 26 | error: 27 | mov esi,_error_prefix 28 | call display_string 29 | pop esi 30 | call display_string 31 | mov esi,_error_suffix 32 | call display_string 33 | mov ax,4C00h 34 | int 21h 35 | 36 | get_params: 37 | push ds 38 | mov ds,[psp_selector] 39 | mov esi,81h 40 | mov edi,params 41 | find_param: 42 | lodsb 43 | cmp al,20h 44 | je find_param 45 | cmp al,0Dh 46 | je all_params 47 | or al,al 48 | jz all_params 49 | cmp [es:input_file],0 50 | jne get_output_file 51 | mov [es:input_file],edi 52 | jmp process_param 53 | get_output_file: 54 | cmp [es:output_file],0 55 | jne bad_params 56 | mov [es:output_file],edi 57 | process_param: 58 | cmp al,22h 59 | je string_param 60 | copy_param: 61 | stosb 62 | lodsb 63 | cmp al,20h 64 | je param_end 65 | cmp al,0Dh 66 | je param_end 67 | or al,al 68 | jz param_end 69 | jmp copy_param 70 | string_param: 71 | lodsb 72 | cmp al,22h 73 | je string_param_end 74 | cmp al,0Dh 75 | je param_end 76 | or al,al 77 | jz param_end 78 | stosb 79 | jmp string_param 80 | bad_params_value: 81 | stc 82 | ret 83 | param_end: 84 | dec esi 85 | string_param_end: 86 | xor al,al 87 | stosb 88 | jmp find_param 89 | all_params: 90 | xor al,al 91 | stosb 92 | pop ds 93 | cmp [input_file],0 94 | je bad_params 95 | cmp [output_file],0 96 | je bad_params 97 | clc 98 | ret 99 | bad_params: 100 | stc 101 | ret 102 | 103 | include 'system.inc' 104 | 105 | include '..\prepsrc.inc' 106 | 107 | _usage db 'preprocessed source dumper for flat assembler',0Dh,0Ah 108 | db 'usage: prepsrc ',0Dh,0Ah 109 | db 0 110 | _error_prefix db 'error: ',0 111 | _error_suffix db '.',0Dh,0Ah,0 112 | 113 | input_file dd 0 114 | output_file dd 0 115 | 116 | psp_selector dw ? 117 | environment_selector dw ? 118 | 119 | memory_handles_count dd ? 120 | memory_handles rd 400h 121 | 122 | params rb 1000h 123 | 124 | segment buffer_segment 125 | 126 | buffer = (buffer_segment-main) shl 4 127 | 128 | db 1000h dup ? 129 | 130 | segment stack_segment 131 | 132 | stack_bottom = (stack_segment-main) shl 4 133 | 134 | db 4000h dup ? 135 | 136 | stack_top = stack_bottom + $ 137 | -------------------------------------------------------------------------------- /fasm/tools/dos/symbols.asm: -------------------------------------------------------------------------------- 1 | 2 | format MZ 3 | heap 0 4 | stack 8000h 5 | entry loader:init 6 | 7 | include 'loader.inc' 8 | 9 | segment main use32 10 | 11 | start: 12 | 13 | call get_params 14 | jnc make_dump 15 | 16 | mov esi,_usage 17 | call display_string 18 | mov ax,4C02h 19 | int 21h 20 | 21 | make_dump: 22 | call symbols 23 | mov ax,4C00h 24 | int 21h 25 | 26 | error: 27 | mov esi,_error_prefix 28 | call display_string 29 | pop esi 30 | call display_string 31 | mov esi,_error_suffix 32 | call display_string 33 | mov ax,4C00h 34 | int 21h 35 | 36 | get_params: 37 | push ds 38 | mov ds,[psp_selector] 39 | mov esi,81h 40 | mov edi,params 41 | find_param: 42 | lodsb 43 | cmp al,20h 44 | je find_param 45 | cmp al,0Dh 46 | je all_params 47 | or al,al 48 | jz all_params 49 | cmp [es:input_file],0 50 | jne get_output_file 51 | mov [es:input_file],edi 52 | jmp process_param 53 | get_output_file: 54 | cmp [es:output_file],0 55 | jne bad_params 56 | mov [es:output_file],edi 57 | process_param: 58 | cmp al,22h 59 | je string_param 60 | copy_param: 61 | stosb 62 | lodsb 63 | cmp al,20h 64 | je param_end 65 | cmp al,0Dh 66 | je param_end 67 | or al,al 68 | jz param_end 69 | jmp copy_param 70 | string_param: 71 | lodsb 72 | cmp al,22h 73 | je string_param_end 74 | cmp al,0Dh 75 | je param_end 76 | or al,al 77 | jz param_end 78 | stosb 79 | jmp string_param 80 | bad_params_value: 81 | stc 82 | ret 83 | param_end: 84 | dec esi 85 | string_param_end: 86 | xor al,al 87 | stosb 88 | jmp find_param 89 | all_params: 90 | xor al,al 91 | stosb 92 | pop ds 93 | cmp [input_file],0 94 | je bad_params 95 | cmp [output_file],0 96 | je bad_params 97 | clc 98 | ret 99 | bad_params: 100 | stc 101 | ret 102 | 103 | include 'system.inc' 104 | 105 | include '..\symbols.inc' 106 | 107 | _usage db 'symbols dumper for flat assembler',0Dh,0Ah 108 | db 'usage: symbols ',0Dh,0Ah 109 | db 0 110 | _error_prefix db 'error: ',0 111 | _error_suffix db '.',0Dh,0Ah,0 112 | 113 | input_file dd 0 114 | output_file dd 0 115 | 116 | input dd ? 117 | output_buffer dd ? 118 | output_handle dd ? 119 | 120 | psp_selector dw ? 121 | environment_selector dw ? 122 | 123 | memory_handles_count dd ? 124 | memory_handles rd 400h 125 | 126 | params rb 1000h 127 | 128 | segment buffer_segment 129 | 130 | buffer = (buffer_segment-main) shl 4 131 | 132 | db 1000h dup ? 133 | 134 | segment stack_segment 135 | 136 | stack_bottom = (stack_segment-main) shl 4 137 | 138 | db 4000h dup ? 139 | 140 | stack_top = stack_bottom + $ 141 | -------------------------------------------------------------------------------- /fasm/tools/dos/system.inc: -------------------------------------------------------------------------------- 1 | 2 | display_string: 3 | lods byte [esi] 4 | or al,al 5 | jz string_end 6 | mov dl,al 7 | mov ah,2 8 | int 21h 9 | jmp display_string 10 | string_end: 11 | ret 12 | alloc: 13 | push ebx esi edi 14 | mov cx,ax 15 | shr eax,16 16 | mov bx,ax 17 | mov ax,501h 18 | int 31h 19 | jc dpmi_allocation_failed 20 | mov ax,bx 21 | shl eax,16 22 | mov ax,cx 23 | mov edx,main 24 | shl edx,4 25 | sub eax,edx 26 | mov bx,si 27 | shl ebx,16 28 | mov bx,di 29 | mov ecx,[memory_handles_count] 30 | inc [memory_handles_count] 31 | shl ecx,3 32 | add ecx,memory_handles 33 | mov [ecx],eax 34 | mov [ecx+4],ebx 35 | pop edi esi ebx 36 | clc 37 | ret 38 | dpmi_allocation_failed: 39 | pop edi esi ebx 40 | stc 41 | ret 42 | free: 43 | push ebx esi edi 44 | mov esi,memory_handles 45 | mov ecx,[memory_handles_count] 46 | find_memory_handle: 47 | cmp eax,[esi] 48 | je memory_handle_found 49 | add esi,8 50 | loop find_memory_handle 51 | pop edi esi 52 | ret 53 | memory_handle_found: 54 | mov ebx,[esi+4] 55 | dec [memory_handles_count] 56 | dec ecx 57 | jz free_memory 58 | remove_memory_handle: 59 | mov edx,[esi+8] 60 | mov edi,[esi+8+4] 61 | mov [esi],edx 62 | mov [esi+4],edi 63 | add esi,8 64 | loop remove_memory_handle 65 | free_memory: 66 | mov esi,ebx 67 | shr esi,16 68 | mov di,bx 69 | mov ax,502h 70 | int 31h 71 | pop edi esi ebx 72 | ret 73 | open: 74 | push esi edi ebp 75 | call adapt_path 76 | mov ax,716Ch 77 | mov bx,100000b 78 | mov dx,1 79 | xor cx,cx 80 | xor si,si 81 | call dos_int 82 | jnc open_done 83 | cmp ax,7100h 84 | je old_open 85 | stc 86 | jmp open_done 87 | old_open: 88 | mov ax,3D00h 89 | xor dx,dx 90 | call dos_int 91 | open_done: 92 | mov bx,ax 93 | pop ebp edi esi 94 | ret 95 | adapt_path: 96 | mov esi,edx 97 | mov edi,buffer 98 | copy_path: 99 | lodsb 100 | cmp al,'/' 101 | jne path_char_ok 102 | mov al,'\' 103 | path_char_ok: 104 | stosb 105 | or al,al 106 | jnz copy_path 107 | ret 108 | dos_int: 109 | push 0 0 0 110 | pushw buffer_segment buffer_segment 111 | stc 112 | pushfw 113 | push eax 114 | push ecx 115 | push edx 116 | push ebx 117 | push 0 118 | push ebp 119 | push esi 120 | push edi 121 | mov ax,300h 122 | mov bx,21h 123 | xor cx,cx 124 | mov edi,esp 125 | push es ss 126 | pop es 127 | int 31h 128 | pop es 129 | mov edi,[esp] 130 | mov esi,[esp+4] 131 | mov ebp,[esp+8] 132 | mov ebx,[esp+10h] 133 | mov edx,[esp+14h] 134 | mov ecx,[esp+18h] 135 | mov ah,[esp+20h] 136 | add esp,32h 137 | sahf 138 | mov eax,[esp-32h+1Ch] 139 | ret 140 | create: 141 | push esi edi ebp 142 | call adapt_path 143 | mov ax,716Ch 144 | mov bx,100001b 145 | mov dx,10010b 146 | xor cx,cx 147 | xor si,si 148 | xor di,di 149 | call dos_int 150 | jnc create_done 151 | cmp ax,7100h 152 | je old_create 153 | stc 154 | jmp create_done 155 | old_create: 156 | mov ah,3Ch 157 | xor cx,cx 158 | xor dx,dx 159 | call dos_int 160 | create_done: 161 | mov bx,ax 162 | pop ebp edi esi 163 | ret 164 | write: 165 | push edx esi edi ebp 166 | mov ebp,ecx 167 | mov esi,edx 168 | write_loop: 169 | mov ecx,1000h 170 | sub ebp,1000h 171 | jnc do_write 172 | add ebp,1000h 173 | mov ecx,ebp 174 | xor ebp,ebp 175 | do_write: 176 | push ecx 177 | mov edi,buffer 178 | shr ecx,2 179 | rep movsd 180 | mov ecx,[esp] 181 | and ecx,11b 182 | rep movsb 183 | pop ecx 184 | mov ah,40h 185 | xor dx,dx 186 | call dos_int 187 | or ebp,ebp 188 | jnz write_loop 189 | pop ebp edi esi edx 190 | ret 191 | read: 192 | push edx esi edi ebp 193 | mov ebp,ecx 194 | mov edi,edx 195 | read_loop: 196 | mov ecx,1000h 197 | sub ebp,1000h 198 | jnc do_read 199 | add ebp,1000h 200 | mov ecx,ebp 201 | xor ebp,ebp 202 | do_read: 203 | push ecx 204 | mov ah,3Fh 205 | xor dx,dx 206 | call dos_int 207 | cmp ax,cx 208 | jne eof 209 | mov esi,buffer 210 | mov ecx,[esp] 211 | shr ecx,2 212 | rep movsd 213 | pop ecx 214 | and ecx,11b 215 | rep movsb 216 | or ebp,ebp 217 | jnz read_loop 218 | read_done: 219 | pop ebp edi esi edx 220 | ret 221 | eof: 222 | pop ecx 223 | stc 224 | jmp read_done 225 | close: 226 | mov ah,3Eh 227 | int 21h 228 | ret 229 | lseek: 230 | mov ah,42h 231 | mov ecx,edx 232 | shr ecx,16 233 | int 21h 234 | pushf 235 | shl edx,16 236 | popf 237 | mov dx,ax 238 | mov eax,edx 239 | ret 240 | -------------------------------------------------------------------------------- /fasm/tools/libc/ccall.inc: -------------------------------------------------------------------------------- 1 | 2 | macro ccall proc,[arg] 3 | { common 4 | push ebp 5 | mov ebp,esp 6 | local size 7 | size = 0 8 | if ~ arg eq 9 | forward 10 | size = size + 4 11 | common 12 | sub esp,size 13 | end if 14 | and esp,-16 15 | if ~ arg eq 16 | add esp,size 17 | reverse 18 | pushd arg 19 | common 20 | end if 21 | call proc 22 | leave } 23 | 24 | -------------------------------------------------------------------------------- /fasm/tools/libc/listing.asm: -------------------------------------------------------------------------------- 1 | 2 | format ELF 3 | public main 4 | 5 | include 'ccall.inc' 6 | 7 | section '.text' executable align 16 8 | 9 | main: 10 | mov ecx,[esp+4] 11 | mov [argc],ecx 12 | mov ebx,[esp+8] 13 | mov [argv],ebx 14 | 15 | mov [display_handle],1 16 | 17 | call get_params 18 | jnc make_listing 19 | 20 | mov esi,_usage 21 | call display_string 22 | ccall exit,2 23 | 24 | make_listing: 25 | call listing 26 | ccall exit,0 27 | 28 | error: 29 | mov [display_handle],2 30 | mov esi,_error_prefix 31 | call display_string 32 | pop esi 33 | call display_string 34 | mov esi,_error_suffix 35 | call display_string 36 | ccall exit,0 37 | 38 | get_params: 39 | mov ecx,[argc] 40 | mov ebx,[argv] 41 | add ebx,4 42 | dec ecx 43 | jz bad_params 44 | get_param: 45 | mov esi,[ebx] 46 | mov al,[esi] 47 | cmp al,'-' 48 | je option_param 49 | cmp [input_file],0 50 | jne get_output_file 51 | mov [input_file],esi 52 | jmp next_param 53 | get_output_file: 54 | cmp [output_file],0 55 | jne bad_params 56 | mov [output_file],esi 57 | jmp next_param 58 | option_param: 59 | inc esi 60 | lodsb 61 | cmp al,'a' 62 | je addresses_option 63 | cmp al,'A' 64 | je addresses_option 65 | cmp al,'b' 66 | je bytes_per_line_option 67 | cmp al,'B' 68 | je bytes_per_line_option 69 | bad_params: 70 | stc 71 | ret 72 | addresses_option: 73 | cmp byte [esi],0 74 | jne bad_params 75 | mov [show_addresses],1 76 | jmp next_param 77 | bytes_per_line_option: 78 | cmp byte [esi],0 79 | jne get_bytes_per_line_setting 80 | dec ecx 81 | jz bad_params 82 | add ebx,4 83 | mov esi,[ebx] 84 | get_bytes_per_line_setting: 85 | call get_option_value 86 | or edx,edx 87 | jz bad_params 88 | cmp edx,1000 89 | ja bad_params 90 | mov [code_bytes_per_line],edx 91 | next_param: 92 | add ebx,4 93 | dec ecx 94 | jnz get_param 95 | cmp [input_file],0 96 | je bad_params 97 | cmp [output_file],0 98 | je bad_params 99 | clc 100 | ret 101 | get_option_value: 102 | xor eax,eax 103 | mov edx,eax 104 | get_option_digit: 105 | lodsb 106 | cmp al,20h 107 | je option_value_ok 108 | cmp al,0Dh 109 | je option_value_ok 110 | or al,al 111 | jz option_value_ok 112 | sub al,30h 113 | jc invalid_option_value 114 | cmp al,9 115 | ja invalid_option_value 116 | imul edx,10 117 | jo invalid_option_value 118 | add edx,eax 119 | jc invalid_option_value 120 | jmp get_option_digit 121 | option_value_ok: 122 | dec esi 123 | clc 124 | ret 125 | invalid_option_value: 126 | stc 127 | ret 128 | 129 | include 'system.inc' 130 | 131 | include '..\listing.inc' 132 | 133 | section '.data' writeable align 4 134 | 135 | input_file dd 0 136 | output_file dd 0 137 | code_bytes_per_line dd 16 138 | show_addresses db 0 139 | 140 | line_break db 0Dh,0Ah 141 | 142 | _usage db 'listing generator for flat assembler',0Dh,0Ah 143 | db 'usage: listing ',0Dh,0Ah 144 | db 'optional settings:',0Dh,0Ah 145 | db ' -a show target addresses for assembled code',0Dh,0Ah 146 | db ' -b set the amount of bytes listed per line',0Dh,0Ah 147 | db 0 148 | _error_prefix db 'error: ',0 149 | _error_suffix db '.',0Dh,0Ah,0 150 | 151 | section '.bss' writeable align 4 152 | 153 | argc dd ? 154 | argv dd ? 155 | 156 | input dd ? 157 | assembled_code dd ? 158 | assembled_code_length dd ? 159 | code_end dd ? 160 | code_offset dd ? 161 | code_length dd ? 162 | output_handle dd ? 163 | output_buffer dd ? 164 | current_source_file dd ? 165 | current_source_line dd ? 166 | source dd ? 167 | source_length dd ? 168 | maximum_address_length dd ? 169 | address_start dd ? 170 | last_listed_address dd ? 171 | 172 | display_handle dd ? 173 | character db ? 174 | 175 | params rb 1000h 176 | characters rb 100h 177 | buffer rb 1000h 178 | -------------------------------------------------------------------------------- /fasm/tools/libc/prepsrc.asm: -------------------------------------------------------------------------------- 1 | 2 | format ELF 3 | public main 4 | 5 | include 'ccall.inc' 6 | 7 | section '.text' executable align 16 8 | 9 | main: 10 | mov ecx,[esp+4] 11 | mov [argc],ecx 12 | mov ebx,[esp+8] 13 | mov [argv],ebx 14 | 15 | mov [display_handle],1 16 | 17 | call get_params 18 | jnc make_dump 19 | 20 | mov esi,_usage 21 | call display_string 22 | ccall exit,2 23 | 24 | make_dump: 25 | call preprocessed_source 26 | ccall exit,0 27 | 28 | error: 29 | mov [display_handle],2 30 | mov esi,_error_prefix 31 | call display_string 32 | pop esi 33 | call display_string 34 | mov esi,_error_suffix 35 | call display_string 36 | ccall exit,0 37 | 38 | get_params: 39 | mov ecx,[argc] 40 | mov ebx,[argv] 41 | add ebx,4 42 | dec ecx 43 | jz bad_params 44 | get_param: 45 | mov esi,[ebx] 46 | mov al,[esi] 47 | cmp [input_file],0 48 | jne get_output_file 49 | mov [input_file],esi 50 | jmp next_param 51 | get_output_file: 52 | cmp [output_file],0 53 | jne bad_params 54 | mov [output_file],esi 55 | jmp next_param 56 | bad_params: 57 | stc 58 | ret 59 | next_param: 60 | add ebx,4 61 | dec ecx 62 | jnz get_param 63 | cmp [input_file],0 64 | je bad_params 65 | cmp [output_file],0 66 | je bad_params 67 | clc 68 | ret 69 | 70 | include 'system.inc' 71 | 72 | include '..\prepsrc.inc' 73 | 74 | section '.data' writeable align 4 75 | 76 | input_file dd 0 77 | output_file dd 0 78 | 79 | _usage db 'preprocessed source dumper for flat assembler',0Dh,0Ah 80 | db 'usage: prepsrc ',0Dh,0Ah 81 | db 0 82 | _error_prefix db 'error: ',0 83 | _error_suffix db '.',0Dh,0Ah,0 84 | 85 | section '.bss' writeable align 4 86 | 87 | argc dd ? 88 | argv dd ? 89 | 90 | display_handle dd ? 91 | character db ? 92 | 93 | params rb 1000h 94 | buffer rb 1000h 95 | -------------------------------------------------------------------------------- /fasm/tools/libc/symbols.asm: -------------------------------------------------------------------------------- 1 | 2 | format ELF 3 | public main 4 | 5 | include 'ccall.inc' 6 | 7 | section '.text' executable align 16 8 | 9 | main: 10 | mov ecx,[esp+4] 11 | mov [argc],ecx 12 | mov ebx,[esp+8] 13 | mov [argv],ebx 14 | 15 | mov [display_handle],1 16 | 17 | call get_params 18 | jnc make_dump 19 | 20 | mov esi,_usage 21 | call display_string 22 | ccall exit,2 23 | 24 | make_dump: 25 | call symbols 26 | ccall exit,0 27 | 28 | error: 29 | mov [display_handle],2 30 | mov esi,_error_prefix 31 | call display_string 32 | pop esi 33 | call display_string 34 | mov esi,_error_suffix 35 | call display_string 36 | ccall exit,0 37 | 38 | get_params: 39 | mov ecx,[argc] 40 | mov ebx,[argv] 41 | add ebx,4 42 | dec ecx 43 | jz bad_params 44 | get_param: 45 | mov esi,[ebx] 46 | mov al,[esi] 47 | cmp [input_file],0 48 | jne get_output_file 49 | mov [input_file],esi 50 | jmp next_param 51 | get_output_file: 52 | cmp [output_file],0 53 | jne bad_params 54 | mov [output_file],esi 55 | jmp next_param 56 | bad_params: 57 | stc 58 | ret 59 | next_param: 60 | add ebx,4 61 | dec ecx 62 | jnz get_param 63 | cmp [input_file],0 64 | je bad_params 65 | cmp [output_file],0 66 | je bad_params 67 | clc 68 | ret 69 | 70 | include 'system.inc' 71 | 72 | include '..\symbols.inc' 73 | 74 | section '.data' writeable align 4 75 | 76 | input_file dd 0 77 | output_file dd 0 78 | 79 | _usage db 'symbols dumper for flat assembler',0Dh,0Ah 80 | db 'usage: symbols ',0Dh,0Ah 81 | db 0 82 | _error_prefix db 'error: ',0 83 | _error_suffix db '.',0Dh,0Ah,0 84 | 85 | section '.bss' writeable align 4 86 | 87 | input dd ? 88 | output_buffer dd ? 89 | output_handle dd ? 90 | 91 | argc dd ? 92 | argv dd ? 93 | 94 | display_handle dd ? 95 | character db ? 96 | 97 | params rb 1000h 98 | buffer rb 1000h 99 | -------------------------------------------------------------------------------- /fasm/tools/libc/system.inc: -------------------------------------------------------------------------------- 1 | 2 | extrn malloc 3 | extrn getenv 4 | extrn fopen 5 | extrn fclose 6 | extrn fread 7 | extrn fwrite 8 | extrn fseek 9 | extrn ftell 10 | extrn time 11 | extrn exit 12 | extrn 'free' as libc_free 13 | extrn 'write' as libc_write 14 | 15 | alloc: 16 | ccall malloc,eax 17 | test eax,eax 18 | jz allocation_failed 19 | clc 20 | ret 21 | allocation_failed: 22 | stc 23 | ret 24 | free: 25 | ccall libc_free,eax 26 | ret 27 | display_string: 28 | lodsb 29 | or al,al 30 | jz string_displayed 31 | mov dl,al 32 | call display_character 33 | jmp display_string 34 | string_displayed: 35 | ret 36 | display_character: 37 | mov [character],dl 38 | ccall libc_write,[display_handle],character,1 39 | ret 40 | open: 41 | push esi edi ebp 42 | call adapt_path 43 | ccall fopen,buffer,open_mode 44 | pop ebp edi esi 45 | or eax,eax 46 | jz file_error 47 | mov ebx,eax 48 | clc 49 | ret 50 | adapt_path: 51 | mov esi,edx 52 | mov edi,buffer 53 | copy_path: 54 | lods byte [esi] 55 | cmp al,'\' 56 | jne path_char_ok 57 | mov al,'/' 58 | path_char_ok: 59 | stos byte [edi] 60 | or al,al 61 | jnz copy_path 62 | cmp edi,buffer+1000h 63 | ja not_enough_memory 64 | ret 65 | create: 66 | push esi edi ebp 67 | call adapt_path 68 | ccall fopen,buffer,create_mode 69 | pop ebp edi esi 70 | or eax,eax 71 | jz file_error 72 | mov ebx,eax 73 | clc 74 | ret 75 | close: 76 | ccall fclose,ebx 77 | ret 78 | read: 79 | push ebx ecx edx esi edi 80 | ccall fread,edx,1,ecx,ebx 81 | pop edi esi edx ecx ebx 82 | cmp eax,ecx 83 | jne file_error 84 | clc 85 | ret 86 | file_error: 87 | stc 88 | ret 89 | write: 90 | push ebx ecx edx esi edi 91 | ccall fwrite,edx,1,ecx,ebx 92 | pop edi esi edx ecx ebx 93 | cmp eax,ecx 94 | jne file_error 95 | clc 96 | ret 97 | lseek: 98 | push ebx 99 | movzx eax,al 100 | ccall fseek,ebx,edx,eax 101 | mov ebx,[esp] 102 | ccall ftell,ebx 103 | pop ebx 104 | ret 105 | 106 | open_mode db 'r',0 107 | create_mode db 'w',0 108 | -------------------------------------------------------------------------------- /fasm/tools/prepsrc.inc: -------------------------------------------------------------------------------- 1 | 2 | preprocessed_source: 3 | mov edx,[input_file] 4 | call open 5 | jc input_not_found 6 | mov al,2 7 | xor edx,edx 8 | call lseek 9 | cmp eax,30h 10 | jb invalid_input 11 | push eax 12 | call alloc 13 | jc not_enough_memory 14 | push eax 15 | xor al,al 16 | xor edx,edx 17 | call lseek 18 | mov ecx,[esp+4] 19 | mov edx,[esp] 20 | call read 21 | jc reading_error 22 | pop eax ecx 23 | cmp dword [eax],1A736166h 24 | jne invalid_input 25 | mov esi,[eax+32] 26 | add esi,eax 27 | mov ebp,[eax+36] 28 | add ebp,esi 29 | mov edi,eax 30 | push eax 31 | preprocessed_to_text: 32 | cmp esi,ebp 33 | jae conversion_done 34 | add esi,16 35 | xor dl,dl 36 | convert_preprocessed_line: 37 | lodsb 38 | cmp al,1Ah 39 | je copy_symbol 40 | cmp al,22h 41 | je copy_symbol 42 | cmp al,3Bh 43 | je preprocessor_symbols 44 | or al,al 45 | jz line_converted 46 | stosb 47 | xor dl,dl 48 | jmp convert_preprocessed_line 49 | copy_symbol: 50 | or dl,dl 51 | jz space_ok 52 | mov byte [edi],20h 53 | inc edi 54 | space_ok: 55 | cmp al,22h 56 | je quoted 57 | lodsb 58 | movzx ecx,al 59 | rep movsb 60 | or dl,-1 61 | jmp convert_preprocessed_line 62 | quoted: 63 | mov al,27h 64 | stosb 65 | lodsd 66 | mov ecx,eax 67 | jecxz quoted_copied 68 | copy_quoted: 69 | lodsb 70 | stosb 71 | cmp al,27h 72 | jne quote_ok 73 | stosb 74 | quote_ok: 75 | loop copy_quoted 76 | quoted_copied: 77 | mov al,27h 78 | stosb 79 | or dl,-1 80 | jmp convert_preprocessed_line 81 | preprocessor_symbols: 82 | mov al,3Bh 83 | stosb 84 | jmp copy_symbol 85 | line_converted: 86 | mov ax,0A0Dh 87 | stosw 88 | jmp preprocessed_to_text 89 | conversion_done: 90 | mov edx,[output_file] 91 | call create 92 | jc writing_error 93 | pop edx 94 | mov ecx,edi 95 | sub ecx,edx 96 | call write 97 | jc writing_error 98 | call close 99 | ret 100 | 101 | not_enough_memory: 102 | call error 103 | db 'not enough memory to load the required data',0 104 | input_not_found: 105 | call error 106 | db 'the input file was not found',0 107 | reading_error: 108 | call error 109 | db 'some error occured while trying to read file',0 110 | writing_error: 111 | call error 112 | db 'some error occured while trying to write file',0 113 | invalid_input: 114 | call error 115 | db 'input file is not a recognized assembly information format',0 116 | -------------------------------------------------------------------------------- /fasm/tools/readme.txt: -------------------------------------------------------------------------------- 1 | 2 | This directory contains some tools, which extract various types of information 3 | from the symbolic information file generated by flat assembler, and present 4 | them in a human-readable form. 5 | 6 | The listing tool creates a listing of assembled code - this tool needs to be 7 | executed in the exact configuration, in which the assembly was taking place. 8 | All the source files and the output file aswell must not have been moved or 9 | modified - if any of them was altered before generating the listing, it is 10 | going to contain garbage instead of useful information. For example, if you 11 | assembled the file with the command like: 12 | 13 | fasm example.asm example.exe -s example.fas 14 | 15 | you should generate listing by immediately running this command from the same 16 | directory: 17 | 18 | listing example.fas example.lst 19 | 20 | In addition, the "-a" switch is recommended to use in the case of executable 21 | formats, as it allows to get the run-time addresses for all the assembled code 22 | and data. 23 | 24 | The preprocessed source and symbols dump tools are simpler ones - they only 25 | need the symbolic information file as input and generate proper output text 26 | regardless of the availability of other files. 27 | -------------------------------------------------------------------------------- /fasm/tools/win32/prepsrc.asm: -------------------------------------------------------------------------------- 1 | 2 | format PE console 4.0 3 | entry start 4 | 5 | include 'win32a.inc' 6 | 7 | section '.data' data readable writeable 8 | 9 | _usage db 'preprocessed source dumper for flat assembler',0Dh,0Ah 10 | db 'usage: prepsrc ',0Dh,0Ah 11 | db 0 12 | _error_prefix db 'error: ',0 13 | _error_suffix db '.',0Dh,0Ah,0 14 | 15 | input_file dd 0 16 | output_file dd 0 17 | 18 | display_handle dd ? 19 | bytes_count dd ? 20 | 21 | params rb 1000h 22 | 23 | section '.text' code readable executable 24 | 25 | start: 26 | 27 | mov [display_handle],STD_OUTPUT_HANDLE 28 | 29 | call get_params 30 | jnc make_dump 31 | 32 | mov esi,_usage 33 | call display_string 34 | invoke ExitProcess,2 35 | 36 | make_dump: 37 | call preprocessed_source 38 | invoke ExitProcess,0 39 | 40 | error: 41 | mov [display_handle],STD_ERROR_HANDLE 42 | mov esi,_error_prefix 43 | call display_string 44 | pop esi 45 | call display_string 46 | mov esi,_error_suffix 47 | call display_string 48 | invoke ExitProcess,1 49 | 50 | get_params: 51 | invoke GetCommandLine 52 | mov esi,eax 53 | mov edi,params 54 | find_command_start: 55 | lodsb 56 | cmp al,20h 57 | je find_command_start 58 | cmp al,22h 59 | je skip_quoted_name 60 | skip_name: 61 | lodsb 62 | cmp al,20h 63 | je find_param 64 | or al,al 65 | jz all_params 66 | jmp skip_name 67 | skip_quoted_name: 68 | lodsb 69 | cmp al,22h 70 | je find_param 71 | or al,al 72 | jz all_params 73 | jmp skip_quoted_name 74 | find_param: 75 | lodsb 76 | cmp al,20h 77 | je find_param 78 | cmp al,0Dh 79 | je all_params 80 | or al,al 81 | jz all_params 82 | cmp [input_file],0 83 | jne get_output_file 84 | mov [input_file],edi 85 | jmp process_param 86 | get_output_file: 87 | cmp [output_file],0 88 | jne bad_params 89 | mov [output_file],edi 90 | process_param: 91 | cmp al,22h 92 | je string_param 93 | copy_param: 94 | stosb 95 | lodsb 96 | cmp al,20h 97 | je param_end 98 | cmp al,0Dh 99 | je param_end 100 | or al,al 101 | jz param_end 102 | jmp copy_param 103 | string_param: 104 | lodsb 105 | cmp al,22h 106 | je string_param_end 107 | cmp al,0Dh 108 | je param_end 109 | or al,al 110 | jz param_end 111 | stosb 112 | jmp string_param 113 | bad_params: 114 | stc 115 | ret 116 | param_end: 117 | dec esi 118 | string_param_end: 119 | xor al,al 120 | stosb 121 | jmp find_param 122 | all_params: 123 | cmp [input_file],0 124 | je bad_params 125 | cmp [output_file],0 126 | je bad_params 127 | clc 128 | ret 129 | 130 | include 'system.inc' 131 | 132 | include '..\prepsrc.inc' 133 | 134 | section '.idata' import data readable writeable 135 | 136 | library kernel32,'KERNEL32.DLL' 137 | 138 | include 'api\kernel32.inc' 139 | -------------------------------------------------------------------------------- /fasm/tools/win32/symbols.asm: -------------------------------------------------------------------------------- 1 | 2 | format PE console 4.0 3 | entry start 4 | 5 | include 'win32a.inc' 6 | 7 | section '.data' data readable writeable 8 | 9 | _usage db 'symbols dumper for flat assembler',0Dh,0Ah 10 | db 'usage: symbols ',0Dh,0Ah 11 | db 0 12 | _error_prefix db 'error: ',0 13 | _error_suffix db '.',0Dh,0Ah,0 14 | 15 | input_file dd 0 16 | output_file dd 0 17 | 18 | input dd ? 19 | output_buffer dd ? 20 | output_handle dd ? 21 | 22 | display_handle dd ? 23 | bytes_count dd ? 24 | 25 | params rb 1000h 26 | 27 | section '.text' code readable executable 28 | 29 | start: 30 | 31 | mov [display_handle],STD_OUTPUT_HANDLE 32 | 33 | call get_params 34 | jnc make_dump 35 | 36 | mov esi,_usage 37 | call display_string 38 | invoke ExitProcess,2 39 | 40 | make_dump: 41 | call symbols 42 | invoke ExitProcess,0 43 | 44 | error: 45 | mov [display_handle],STD_ERROR_HANDLE 46 | mov esi,_error_prefix 47 | call display_string 48 | pop esi 49 | call display_string 50 | mov esi,_error_suffix 51 | call display_string 52 | invoke ExitProcess,1 53 | 54 | get_params: 55 | invoke GetCommandLine 56 | mov esi,eax 57 | mov edi,params 58 | find_command_start: 59 | lodsb 60 | cmp al,20h 61 | je find_command_start 62 | cmp al,22h 63 | je skip_quoted_name 64 | skip_name: 65 | lodsb 66 | cmp al,20h 67 | je find_param 68 | or al,al 69 | jz all_params 70 | jmp skip_name 71 | skip_quoted_name: 72 | lodsb 73 | cmp al,22h 74 | je find_param 75 | or al,al 76 | jz all_params 77 | jmp skip_quoted_name 78 | find_param: 79 | lodsb 80 | cmp al,20h 81 | je find_param 82 | cmp al,0Dh 83 | je all_params 84 | or al,al 85 | jz all_params 86 | cmp [input_file],0 87 | jne get_output_file 88 | mov [input_file],edi 89 | jmp process_param 90 | get_output_file: 91 | cmp [output_file],0 92 | jne bad_params 93 | mov [output_file],edi 94 | process_param: 95 | cmp al,22h 96 | je string_param 97 | copy_param: 98 | stosb 99 | lodsb 100 | cmp al,20h 101 | je param_end 102 | cmp al,0Dh 103 | je param_end 104 | or al,al 105 | jz param_end 106 | jmp copy_param 107 | string_param: 108 | lodsb 109 | cmp al,22h 110 | je string_param_end 111 | cmp al,0Dh 112 | je param_end 113 | or al,al 114 | jz param_end 115 | stosb 116 | jmp string_param 117 | bad_params: 118 | stc 119 | ret 120 | param_end: 121 | dec esi 122 | string_param_end: 123 | xor al,al 124 | stosb 125 | jmp find_param 126 | all_params: 127 | cmp [input_file],0 128 | je bad_params 129 | cmp [output_file],0 130 | je bad_params 131 | clc 132 | ret 133 | 134 | include 'system.inc' 135 | 136 | include '..\symbols.inc' 137 | 138 | section '.idata' import data readable writeable 139 | 140 | library kernel32,'KERNEL32.DLL' 141 | 142 | include 'api\kernel32.inc' 143 | -------------------------------------------------------------------------------- /fasm/tools/win32/system.inc: -------------------------------------------------------------------------------- 1 | 2 | display_string: 3 | invoke GetStdHandle,[display_handle] 4 | mov edx,eax 5 | mov edi,esi 6 | or ecx,-1 7 | xor al,al 8 | repne scasb 9 | neg ecx 10 | sub ecx,2 11 | invoke WriteFile,edx,esi,ecx,bytes_count,0 12 | retn 13 | alloc: 14 | invoke VirtualAlloc,0,eax,MEM_COMMIT,PAGE_READWRITE 15 | or eax,eax 16 | jz allocation_error 17 | clc 18 | retn 19 | allocation_error: 20 | stc 21 | retn 22 | free: 23 | invoke VirtualFree,eax,0,MEM_RELEASE 24 | retn 25 | open: 26 | invoke CreateFile,edx,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,0,0 27 | cmp eax,-1 28 | je file_error 29 | mov ebx,eax 30 | clc 31 | retn 32 | file_error: 33 | stc 34 | retn 35 | create: 36 | invoke CreateFile,edx,GENERIC_WRITE,0,0,CREATE_ALWAYS,0,0 37 | cmp eax,-1 38 | je file_error 39 | mov ebx,eax 40 | clc 41 | retn 42 | write: 43 | invoke WriteFile,ebx,edx,ecx,bytes_count,0 44 | or eax,eax 45 | jz file_error 46 | clc 47 | retn 48 | read: 49 | push ecx 50 | invoke ReadFile,ebx,edx,ecx,bytes_count,0 51 | pop edx 52 | or eax,eax 53 | jz file_error 54 | cmp edx,[bytes_count] 55 | jne file_error 56 | clc 57 | retn 58 | close: 59 | invoke CloseHandle,ebx 60 | retn 61 | lseek: 62 | movzx eax,al 63 | invoke SetFilePointer,ebx,edx,0,eax 64 | cmp eax,-1 65 | je file_error 66 | retn 67 | -------------------------------------------------------------------------------- /llvm/lib/Target/R3X/R3XTargetMachine.cpp: -------------------------------------------------------------------------------- 1 | #include "R3XTargetMachine.h" 2 | #include "R3XTargetMachineObjectFile.h" 3 | #include "R3X.h" 4 | #include "llvm/CodeGen/Passes.h" 5 | #include "llvm/PassManager.h" 6 | #include "llvm/Support/TargetRegistry.h" 7 | using namespace llvm; 8 | 9 | extern "C" void LLVMInitializeR3XTarget() { 10 | // Register the target. 11 | RegisterTargetMachine X(R3XTarget); 12 | } 13 | 14 | /// Create an R3X sub-machine class 15 | /// 16 | R3XTargetMachine::R3XTargetMachine(const Target &T, StringRef TT, 17 | StringRef CPU, StringRef FS, 18 | const TargetOptions &Options, 19 | Reloc::Model RM, CodeModel::Model CM, 20 | CodeGenOpt::Level OL, 21 | bool is64bit) 22 | : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL), 23 | TLOF(make_unique()), 24 | Subtarget(TT, CPU, FS, *this, is64bit) { 25 | initAsmInfo(); 26 | } 27 | 28 | R3XTargetMachine::~R3XTargetMachine() {} 29 | 30 | namespace { 31 | /// Sparc Code Generator Pass Configuration Options. 32 | class R3XPassConfig : public TargetPassConfig { 33 | public: 34 | SparcPassConfig(R3XTargetMachine *TM, PassManagerBase &PM) 35 | : TargetPassConfig(TM, PM) {} 36 | 37 | R3XTargetMachine &getR3XTargetMachine() const { 38 | return getTM(); 39 | } 40 | 41 | void addIRPasses() override; 42 | bool addInstSelector() override; 43 | void addPreEmitPass() override; 44 | }; 45 | } // namespace 46 | 47 | TargetPassConfig *R3XTargetMachine::createPassConfig(PassManagerBase &PM) { 48 | return new R3XPassConfig(this, PM); 49 | } 50 | 51 | void R3XPassConfig::addIRPasses() { 52 | addPass(createAtomicExpandPass(&getR3XTargetMachine())); 53 | 54 | TargetPassConfig::addIRPasses(); 55 | } 56 | 57 | bool R3XPassConfig::addInstSelector() { 58 | addPass(createR3XISelDag(getR3XTargetMachine())); 59 | return false; 60 | } 61 | 62 | void R3XPassConfig::addPreEmitPass(){ 63 | addPass(createR3XDelaySlotFillerPass(getR3XTargetMachine())); 64 | } 65 | 66 | void R3XTargetMachine::anchor() { } 67 | 68 | R3XTargetMachine::R3XTargetMachine(const Target &T, 69 | StringRef TT, StringRef CPU, 70 | StringRef FS, 71 | const TargetOptions &Options, 72 | Reloc::Model RM, 73 | CodeModel::Model CM, 74 | CodeGenOpt::Level OL) 75 | : R3XTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) { 76 | } 77 | 78 | void R3XTargetMachine::anchor() { } 79 | 80 | R3XTargetMachine::R3XTargetMachine(const Target &T, 81 | StringRef TT, StringRef CPU, 82 | StringRef FS, 83 | const TargetOptions &Options, 84 | Reloc::Model RM, 85 | CodeModel::Model CM, 86 | CodeGenOpt::Level OL) 87 | : R3XTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) { 88 | } -------------------------------------------------------------------------------- /llvm/lib/Target/llvm.txt: -------------------------------------------------------------------------------- 1 | This directory contains the target specifications for LLVM. 2 | It's currently under progress, bother to checkout later! -------------------------------------------------------------------------------- /server/build.sh: -------------------------------------------------------------------------------- 1 | export CC="gcc" 2 | export CFLAGS="-g -Wall -Wextra -std=gnu99" 3 | $CC $CFLAGS server.c -o server 4 | -------------------------------------------------------------------------------- /server/readme.txt: -------------------------------------------------------------------------------- 1 | This folder contains a small application which functions as a simple server for the R3X VM. 2 | Compile for Linux using 'build.sh'. Then move it to your bin directory, from there do './server'. 3 | You will see a prompt like this: 4 | [/directory/]$: 5 | To run an application, just type: 6 | run 7 | After the application starts you will see that the prompt disappeared. To recover, switch 8 | to your terminal and just press ENTER. 9 | You can run as many applications as you want by repeating the steps above. 10 | The client VMs process ID would be on it's window header, and would also be printed 11 | by the server app when you execute it. 12 | There are a few things you can mess with: 13 | kill - Kill a client 14 | pause - Pause a client 15 | cont - continue a client after pause 16 | status - make the client print VM status. 17 | quit - Quits the server and all clients -------------------------------------------------------------------------------- /src/128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Benderx2/R3X/f45118d3d9b5c462dc45121742d6e514b1bfe3ed/src/128x128.png -------------------------------------------------------------------------------- /src/bios.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 Benderx2, 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | * Neither the name of R3X nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #include 31 | #include 32 | extern char* ApplicationPath; 33 | void r3x_load_bios(r3x_cpu_t* CPU) { 34 | // Load the bios, not really sure whatthefuck should i reallyfucking write here. 35 | char* BIOSPath = nt_concat(ApplicationPath, "/bios/bios.bin"); 36 | FILE* biosfile = fopen(BIOSPath, "r"); 37 | if(biosfile == NULL) { perror("Unable to read BIOS image /bios/bios.bin"); nt_freeall(); exit(1); } 38 | else { 39 | // read 512 bytes 40 | fseek(biosfile, 0L, SEEK_END); 41 | unsigned int totalsize = ftell(biosfile); 42 | fseek(biosfile, 0L, SEEK_SET); 43 | assert(CPU->Memory); 44 | unsigned int sizeread = fread(&CPU->Memory[0], sizeof(uint8_t), totalsize, biosfile); 45 | if(sizeread != REX_BIOS_SIZE) { 46 | printf("What the fuck is this thing?\nIt's supposed to a BIOS for fucks sake.\nOr something wrong with fread?\nExpected size : %u, but read %u\n", REX_BIOS_SIZE, sizeread); 47 | exit(1); 48 | 49 | } 50 | fclose(biosfile); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/garbagecollector.c: -------------------------------------------------------------------------------- 1 | #include 2 | /** 3 | * Initialize Garbage Collector, and return a GC_VARIABLE_LIST* which can be used later. 4 | **/ 5 | GC_VARIABLE_LIST* InitializeGC(r3x_cpu_t* CPU) { 6 | (void)CPU; 7 | return NULL; 8 | } 9 | -------------------------------------------------------------------------------- /src/include/big_endian.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 Benderx2, 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | * Neither the name of R3X nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #ifndef BIG_ENDIAN_H 31 | #define BIG_ENDIAN_H 32 | #include 33 | #ifdef R3X_BIG_ENDIAN 34 | // Swaps an integer 35 | static inline uint32_t BIG_ENDIAN_INT (uint32_t i) { 36 | #ifdef __GNUC__ 37 | // Use GNUs builtin 38 | return (uint32_t)__builtin_bswap32(i); 39 | #else 40 | uint32_t convswap = (i & 0xFFFF) << 16 | (i & 0xFFFF0000) >> 16; 41 | convswap = (convswap & 0x00FF00FF) << 8 | (convswap & 0xFF00FF00) >> 8; 42 | return convswap; 43 | #endif 44 | } 45 | static inline uint16_t BIG_ENDIAN_INT16 (uint16_t i){ 46 | #ifdef __GNUC__ 47 | return (uint16_t)__builtin_bswap16(i); 48 | #else 49 | return (uint16_t)((i>>8) | (i<<8)); 50 | #endif 51 | } 52 | #else 53 | #define BIG_ENDIAN_INT(x) (x) 54 | #define BIG_ENDIAN_INT16(x) (x) 55 | #endif 56 | #endif 57 | -------------------------------------------------------------------------------- /src/include/nt_malloc.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 Benderx2, 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | * Neither the name of R3X nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #ifndef NT_MALLOC_H 31 | #define NT_MALLOC_H 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | extern bool isAllFreed; 38 | int nt_malloc_init(bool); 39 | void* nt_calloc(unsigned int, size_t); 40 | void* nt_realloc(void*, size_t); 41 | void* nt_malloc(size_t); 42 | int nt_free(void*); 43 | void nt_freeall(void); 44 | void nt_atexit(void); 45 | char* nt_concat(char *s1, char *s2); 46 | #endif 47 | -------------------------------------------------------------------------------- /src/include/r3x_bios.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 Benderx2, 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | * Neither the name of R3X nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #ifndef R3X_BIOS_H 31 | #define R3X_BIOS_H 32 | #include 33 | #include 34 | #define REX_BIOS_SIZE 512 35 | void r3x_load_bios(r3x_cpu_t* CPU); 36 | #endif 37 | -------------------------------------------------------------------------------- /src/include/r3x_checksum_generator.h: -------------------------------------------------------------------------------- 1 | /** NOTE: This checksum is *not* crypto-sec since it uses CRC32. 2 | * It's only designed to protect against accidental tampering with an executable **/ 3 | #ifndef R3X_CHECKSUM_GEN_H 4 | #define R3X_CHECKSUM_GEN_H 5 | #include 6 | 7 | static inline uint32_t GenerateChecksumCRC32(uint8_t* Buffer, unsigned int size); 8 | 9 | static inline uint32_t GenerateChecksumCRC32(uint8_t* Buffer, unsigned int size) { 10 | unsigned int i; 11 | signed int j; 12 | unsigned int byte, mask; 13 | uint32_t crc; 14 | i = 0; 15 | crc = 0xFFFFFFFF; 16 | while (i <= size) { 17 | byte = Buffer[i]; 18 | crc = crc ^ byte; 19 | for (j = 7; j >= 0; j--) { 20 | mask = -(crc & 1); 21 | crc = (crc >> 1) ^ (0xEDB88320 & mask); 22 | } 23 | i = i + 1; 24 | } 25 | return ~crc; 26 | } 27 | #endif -------------------------------------------------------------------------------- /src/include/r3x_cpu.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 Benderx2, 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | * Neither the name of R3X nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #ifndef R3X_CPU_H 31 | #define R3X_CPU_H 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #define EFLAG_BIT 0 39 | #define GFLAG_BIT 1 40 | #define LFLAG_BIT 2 41 | #define ZFLAG_BIT 3 42 | #define EXFLAG_BIT 4 43 | #define R3X_FALSE 0 44 | #define BIOS_START 0 45 | #define CPU_INVALID_OPCODE_SIGNAL -1 46 | #define CPU_EXIT_SIGNAL -2 47 | #define CPU_INCREMENT_SINGLE 1 48 | #define CPU_INCREMENT_DOUBLE 2 49 | #define CPU_INCREMENT_WITH_32_OP 5 50 | #define CPU_INCREMENT_WITH_32_OP_2 9 51 | #define CPU_INCREMENT_WITH_32_OP_3 13 52 | #define CPU_INCREMENT_WITH_64_OP 9 53 | #define CPU_EXCEPTION_INVALIDACCESS 0 54 | #define CPU_EXCEPTION_INVALIDOPCODE 1 55 | #define CPU_EXCEPTION_EXCEPTION 2 56 | #define CPU_EXCEPTION_ARITHMETIC 3 57 | #define CPU_BREAK_POINT 4 58 | #define R_LOCK 0 59 | #define R_SHUTDOWN 1 60 | #define R_KEYPRESS 2 61 | #define R_TIMER 3 62 | #define MAX_NUMBER_OF_REGISTERS 21 63 | #define TOTAL_EXCEPTIONS 3 64 | #define BP_REG 21 65 | typedef struct r3x_job { 66 | uint32_t InstructionPointer; 67 | vstack_t* Stack; 68 | vstack_t* CallStack; 69 | uint32_t Regs[MAX_NUMBER_OF_REGISTERS+1]; 70 | uint32_t ExceptionHandlers[4]; 71 | bool EqualFlag; 72 | bool GreaterFlag; 73 | bool LesserFlag; 74 | bool ZeroFlag; 75 | bool ExceptionFlag; 76 | int CycleUpdate; 77 | int JobID; 78 | bool ismain; 79 | bool paused; 80 | bool Alive; 81 | } r3x_job_t; 82 | typedef struct r3x_global_domain { 83 | r3x_job_t** Jobs; 84 | unsigned int CurrentJobID; 85 | unsigned int NumberOfActiveJobs; 86 | unsigned int TotalNumberOfJobs; 87 | } r3x_global_domain_t; 88 | typedef struct r3x_cpu { 89 | uint8_t* Memory; 90 | // Not global -- Thread dependent 91 | vstack_t* Stack; 92 | vstack_t* CallStack; 93 | unsigned int InstructionPointer; 94 | int ErrorCode; 95 | bool EqualFlag; 96 | bool GreaterFlag; 97 | bool LesserFlag; 98 | bool ZeroFlag; 99 | bool ExceptionFlag; 100 | uint32_t FLAGS; 101 | uint64_t Regs[MAX_NUMBER_OF_REGISTERS+1]; 102 | uint32_t ExceptionHandlers[4]; 103 | // Global -- Thread Independent. 104 | r3x_memory_blocks* CPUMemoryBlocks; 105 | double CPUClock; 106 | uint32_t ISR_handlers[256]; 107 | unsigned int CurrentInstruction; 108 | unsigned int MemorySize; 109 | unsigned int HeapAddr; 110 | bool use_frequency; 111 | double CPUFrequency; 112 | r3x_global_domain_t* RootDomain; 113 | Graphics_t* Graphics; 114 | ObjectList_t* ObjectList; 115 | } r3x_cpu_t; 116 | #include 117 | extern r3x_cpu_t* r3_cpu; 118 | 119 | void handle_cpu_exception(r3x_cpu_t*, unsigned int); 120 | 121 | int r3x_cpu_loop(r3x_cpu_t* CPU, r3x_header_t* header, char* Arguments); 122 | 123 | uint64_t rfc_emulate_instruction(r3x_cpu_t* CPU); 124 | #endif 125 | -------------------------------------------------------------------------------- /src/include/r3x_disassemble.h: -------------------------------------------------------------------------------- 1 | #ifndef R3X_DISASSEMBLE_H 2 | #define R3X_DISASSEMBLE_H 3 | #include 4 | #include 5 | #include 6 | #ifdef R3X_BIG_ENDIAN 7 | #define BYTE_SWAP(x) BIG_ENDIAN_INT(x) 8 | #else 9 | #define BYTE_SWAP(x) (x) 10 | #endif 11 | void disassemble(uint8_t* input, unsigned int size, FILE* output, char* sectionheader, uint32_t memaddr); 12 | #endif 13 | -------------------------------------------------------------------------------- /src/include/r3x_dispatcher.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 Benderx2, 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | * Neither the name of R3X nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #ifndef R3X_DISPATCHER_H 31 | #define R3X_DISPATCHER_H 32 | #include 33 | #include 34 | #include 35 | r3x_global_domain_t* r3x_init_domain(void); 36 | unsigned int r3x_dispatch_job(unsigned int InstructionPointer, int CycleUpdate, r3x_global_domain_t* Domain, bool ismain); 37 | int r3x_load_job_state(r3x_cpu_t* CPU, r3x_global_domain_t* Domain, unsigned int); 38 | void r3x_save_job_state(r3x_cpu_t* CPU, r3x_global_domain_t* Domain, unsigned int); 39 | void r3x_exit_job(r3x_global_domain_t* Domain, int JobID); 40 | #endif 41 | -------------------------------------------------------------------------------- /src/include/r3x_dynamic.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 Benderx2, 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | * Neither the name of R3X nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #ifndef R3X_DYNAMIC_H 31 | #define R3X_DYNAMIC_H 32 | #include 33 | #include 34 | #include 35 | #include 36 | #define REX_DYNAMIC_HEADER_VAL 0xDEADBEEF 37 | typedef struct REX_DYNAMIC_HEADER { 38 | uint32_t header; 39 | uint32_t minor; 40 | uint32_t major; 41 | uint32_t text_section; 42 | uint32_t text_size; 43 | uint32_t export_section; 44 | uint32_t export_size; 45 | uint32_t data_section; 46 | uint32_t data_size; 47 | uint32_t bss_section; 48 | uint32_t bss_size; 49 | uint32_t nameaddr; 50 | uint32_t publisheraddr; 51 | } r3x_dynamic_header_t; 52 | typedef struct export_struct { 53 | uint32_t function_id; 54 | uint32_t instruction_pointer; 55 | } export_struct; 56 | typedef struct function_call_struct { 57 | char* Name; 58 | uint32_t libid; 59 | uint32_t function_count; 60 | uint32_t loadaddr; 61 | uint32_t export_sec; 62 | export_struct* functions; 63 | } libimport_struct; 64 | 65 | int load_lib_manager(void); 66 | 67 | void load_dependencies(r3x_cpu_t* CPU); 68 | 69 | int load_dynamic_library(char* name, r3x_cpu_t* CPU); 70 | 71 | uint32_t dynamic_call(r3x_cpu_t* CPU, unsigned int libhandle, char* functionhandle); 72 | 73 | uint32_t return_dynamic_load_addr(unsigned int libhandle); 74 | #endif 75 | -------------------------------------------------------------------------------- /src/include/r3x_exception.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 Benderx2, 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | * Neither the name of R3X nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #ifndef R3X_EXCEPTION_H 31 | #define R3X_EXCEPTION_H 32 | #include 33 | #include 34 | void REX_EXCEPTION_HANDLER(int); 35 | void SIGUSR1_handler(int); 36 | #endif 37 | -------------------------------------------------------------------------------- /src/include/r3x_format.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 Benderx2, 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | * Neither the name of R3X nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #ifndef R3X_FORMAT_H 31 | #define R3X_FORMAT_H 32 | #include 33 | #define R3X_HEADER_2033 0xBA5EBA11 34 | typedef struct r3x_header { 35 | uint32_t header_id; 36 | uint32_t program_header; 37 | uint16_t minor; 38 | uint16_t major; 39 | uint32_t r3x_init; 40 | uint32_t r3x_text_size; 41 | uint32_t r3x_data; 42 | uint32_t r3x_data_size; 43 | uint32_t r3x_symbols; 44 | uint32_t r3x_symbolsize; 45 | uint32_t r3x_bss; 46 | uint32_t r3x_bss_size; 47 | uint32_t stack_size; 48 | uint32_t total_size; 49 | uint32_t nameaddr; 50 | uint32_t pulibsheraddr; 51 | uint32_t checksum; 52 | uint32_t r3x_imports; 53 | uint32_t r3x_importsize; 54 | } r3x_header_t; 55 | typedef struct r3x_symbol { 56 | uint32_t SymbolName; 57 | uint32_t SymbolStart; 58 | uint32_t SymbolEnd; 59 | } r3x_symbol_t; 60 | typedef struct { 61 | uint32_t LibName; 62 | uint32_t SymbolName; 63 | uint32_t CallerAddr; 64 | uint32_t LibLoadAddr; 65 | } r3x_import_t; 66 | #define PROG_EXEC_POINT 0x100000// under 1 MB = System reserved. 67 | uint8_t* r3x_load_executable(char* name, r3x_header_t* header); 68 | void read_symbol_table(r3x_header_t* header, uint8_t* Memory, uint32_t size, uint32_t IP); 69 | #endif 70 | -------------------------------------------------------------------------------- /src/include/r3x_garbage_collector.h: -------------------------------------------------------------------------------- 1 | #ifndef __R3X_GARBAGE_COLLECTOR_H 2 | #define __R3X_GARBAGE_COLLECTOR_H 3 | #include 4 | #include 5 | typedef enum { 6 | RX_GC_ALIVE, 7 | RX_GC_DEAD, 8 | } RX_GC_STATUS; 9 | typedef struct { 10 | uint32_t** Addresses; 11 | unsigned int TotalReferences; 12 | } GC_VARIABLE_REFERENCE; 13 | typedef struct { 14 | r3x_cpu_t* CPU; 15 | GC_VARIABLE_REFERENCE* Variables; 16 | unsigned int TotalObjects; 17 | } GC_VARIABLE_LIST; 18 | 19 | GC_VARIABLE_LIST* InitializeGC(r3x_cpu_t* CPU); 20 | 21 | unsigned int GCCreateVariableInstance(GC_VARIABLE_LIST* List, uint32_t Address, uint32_t Value); 22 | 23 | void GCAddReference(GC_VARIABLE_LIST* List, unsigned int ObjectID, uint32_t Address); 24 | 25 | void GCMark(GC_VARIABLE_LIST*); 26 | 27 | void GCCollect(GC_VARIABLE_LIST*); 28 | #endif 29 | -------------------------------------------------------------------------------- /src/include/r3x_graphics.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 Benderx2, 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | * Neither the name of R3X nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #ifndef R3X_GRAPHICS_H 31 | #define R3X_GRAPHICS_H 32 | #include 33 | #ifdef REX_GRAPHICS 34 | #include 35 | #include 36 | #include 37 | #include 38 | #endif 39 | typedef struct { 40 | #ifdef REX_GRAPHICS 41 | GLuint display_list; 42 | GLuint mat_list; 43 | GLuint texture; 44 | #else 45 | unsigned int display_list; 46 | unsigned int mat_list; 47 | unsigned int texture; 48 | #endif 49 | int box_w; int box_h; 50 | int w[256]; 51 | } font_t; 52 | typedef struct { 53 | #ifdef REX_GRAPHICS 54 | SDL_Surface* Screen; 55 | #else 56 | void* Screen; 57 | #endif 58 | uint8_t* TextBuf; 59 | int TextOffset; 60 | int FontHeight; 61 | int FontWidth; 62 | float FontScale; 63 | int CharMaxW; 64 | int CharMaxH; 65 | #ifdef REX_GRAPHICS 66 | const SDL_VideoInfo* VideoInfo; 67 | #else 68 | void* VideoInfo; 69 | #endif 70 | font_t* font; 71 | FILE* Console; 72 | int Height; 73 | int Width; 74 | int Depth; 75 | // Used for graphix 76 | int ScreenX; 77 | int ScreenY; 78 | int SDLFlags; 79 | } Graphics_t; 80 | typedef struct { 81 | unsigned int x; 82 | unsigned int y; 83 | } Graphics_Cursor_t; 84 | font_t* loadfont(char* s); 85 | bool text3D( font_t * f, const char* txt, ...); 86 | bool text( int x, int y, float scale, font_t * f, char* txt); 87 | bool vm_puts(font_t* font, char* txt, Graphics_t* Graphics); 88 | Graphics_t* InitGraphics(void); 89 | void GLUpdate(void); 90 | void vm_putc(char a, Graphics_t* Graphics); 91 | bool gl_text_update(Graphics_t* Graphics); 92 | bool freefont(font_t * f); 93 | void GL_ClearScreen(void); 94 | extern double DefaultRGBA_r, DefaultRGBA_g, DefaultRGBA_b, DefaultRGBA_a; 95 | extern unsigned int FontHeight, FontWidth; extern char* FontFileName; 96 | extern double FontScale; 97 | #endif 98 | -------------------------------------------------------------------------------- /src/include/r3x_memory.h: -------------------------------------------------------------------------------- 1 | #ifndef REX_MEMORY_H 2 | #define REX_MEMORY_H 3 | #include 4 | #define SEGMENT_SIZE (4*1024) 5 | typedef enum { 6 | //! Doesn't exist. 7 | RX_NOEXIST, 8 | //! Execute? 9 | RX_EXEC, 10 | //! Read Only? 11 | RX_RONLY, 12 | //! Readable/Writeable 13 | RX_RW 14 | } RX_MM_TYPE; 15 | typedef struct { 16 | RX_MM_TYPE Type; 17 | uint32_t MemorySegment; 18 | } r3x_mem_block; 19 | typedef struct { 20 | r3x_mem_block* MemoryBlocks; 21 | uint32_t NumberOfBlocks; 22 | } r3x_memory_blocks; 23 | r3x_memory_blocks* BuildMemoryBlock(unsigned int); 24 | r3x_memory_blocks* RebuildMemoryBlock(r3x_memory_blocks*, unsigned int); 25 | int MemoryMap(r3x_memory_blocks*, RX_MM_TYPE, unsigned int, unsigned int); 26 | int MemoryUnmap(r3x_memory_blocks*, unsigned int, unsigned int); 27 | r3x_mem_block* ReturnMemorySegment(r3x_memory_blocks*, unsigned int); 28 | static inline RX_MM_TYPE GetBlockTypefromAddress(r3x_memory_blocks* MemBlock, unsigned int Addr) { 29 | unsigned int PageIndex = ((((Addr & 0xFFFFF000)) / SEGMENT_SIZE)); 30 | if(PageIndex > MemBlock->NumberOfBlocks){ 31 | return RX_NOEXIST; 32 | } 33 | return MemBlock->MemoryBlocks[PageIndex].Type; 34 | } 35 | int DumpMemoryMap(r3x_memory_blocks* MemBlock); 36 | #endif 37 | -------------------------------------------------------------------------------- /src/include/r3x_native.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 Benderx2, 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | * Neither the name of R3X nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #ifndef R3X_NATIVE_H 31 | #define R3X_NATIVE_H 32 | #include 33 | #include 34 | typedef struct native_handle { 35 | char* soname; 36 | void* handle; 37 | struct native_handle* next; 38 | } native_handle_t; 39 | void* load_native_library(char* name, r3x_cpu_t* CPU); 40 | int native_call(char* name, void* handle); 41 | void* returnhandle(char* soname); 42 | #endif 43 | -------------------------------------------------------------------------------- /src/include/r3x_object.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 Benderx2, 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | * Neither the name of R3X nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #ifndef R3X_OBJECT_H 31 | #define R3X_OBJECT_H 32 | #include 33 | #include 34 | typedef enum ObjectType { 35 | R3X_OBJECT_INT, 36 | R3X_OBJECT_STRING, 37 | R3X_OBJECT_POINTER, 38 | R3X_OBJECT_STACK, 39 | R3X_OBJECT_BUFFER 40 | } ObjectType; 41 | typedef struct object { 42 | /** What the object is **/ 43 | ObjectType Type; 44 | /** The value, for a int it's a a normal integer, for string it's a char*, for pointer it's a void*, for stack it's a stack_t* and for buffer it's a buffer_t* **/ 45 | int Value; 46 | /** Object Identification Number, use by GC and CPU to keep track of objects and access them.. */ 47 | int ObjectID; 48 | } object_t; 49 | typedef struct ObjectList { 50 | int* Objects; 51 | unsigned int NumberOfObjects; 52 | unsigned int Index; 53 | } ObjectList_t; 54 | object_t* pushObj(vstack_t* stack, ObjectList_t* List, ObjectType Type); 55 | void popObj(vstack_t* stack, ObjectList_t* List); 56 | object_t* accessObj(ObjectList_t* List, unsigned int Index); 57 | #endif 58 | -------------------------------------------------------------------------------- /src/include/r3x_opcode_table.h: -------------------------------------------------------------------------------- 1 | #ifndef __R3X_OPCODE_TABLE_H 2 | #define __R3X_OPCODE_TABLE_H 3 | #ifdef REX_OPTIMIZE 4 | #include 5 | static void* DispatchTable[] = { 6 | [R3X_SLEEP] = &&INTERP_SLEEP, 7 | [R3X_PUSH] = &&INTERP_PUSH, 8 | [R3X_POP] = &&INTERP_POP, 9 | [R3X_ADD] = &&INTERP_ADD, 10 | [R3X_SUB] = &&INTERP_SUB, 11 | [R3X_MUL] = &&INTERP_MUL, 12 | [R3X_DIV] = &&INTERP_DIV, 13 | [R3X_FADD] = &&INTERP_FADD, 14 | [R3X_FSUB] = &&INTERP_FSUB, 15 | [R3X_FMUL] = &&INTERP_FMUL, 16 | [R3X_FDIV] = &&INTERP_FDIV, 17 | [R3X_CMP] = &&INTERP_CMP, 18 | [R3X_JE] = &&INTERP_JE, 19 | [R3X_JL] = &&INTERP_JL, 20 | [R3X_JG] = &&INTERP_JG, 21 | [R3X_JZ] = &&INTERP_JZ, 22 | [R3X_JMP] = &&INTERP_JMP, 23 | [R3X_AND] = &&INTERP_AND, 24 | [R3X_OR] = &&INTERP_OR, 25 | [R3X_XOR] = &&INTERP_XOR, 26 | [R3X_DUP] = &&INTERP_DUP, 27 | [R3X_LOADS] = &&INTERP_LOADS, 28 | [R3X_LOAD] = &&INTERP_LOAD, 29 | [R3X_STORE] = &&INTERP_STORE, 30 | // 0x1A Reserved 31 | [R3X_EXIT] = &&INTERP_EXIT, 32 | [R3X_SYSCALL] = &&INTERP_SYSCALL, 33 | [R3X_LOADLIB] = &&INTERP_LOADLIB, 34 | [R3X_LIBEXEC] = &&INTERP_LIBEXEC, 35 | [R3X_CALL] = &&INTERP_CALL, 36 | [R3X_RET] = &&INTERP_RET, 37 | [R3X_PUSHA] = &&INTERP_PUSHA, 38 | [R3X_POPA] = &&INTERP_POPA, 39 | [R3X_MEMCPY] = &&INTERP_MEMCPY, 40 | [R3X_LODSB] = &&INTERP_LODSB, 41 | [R3X_LODSW] = &&INTERP_LODSW, 42 | [R3X_LODSD] = &&INTERP_LODSD, 43 | [R3X_STOSB] = &&INTERP_STOSB, 44 | [R3X_STOSD] = &&INTERP_STOSD, 45 | [R3X_STOSW] = &&INTERP_STOSW, 46 | [R3X_CMPSB] = &&INTERP_CMPSB, 47 | [R3X_CMPSW] = &&INTERP_CMPSW, 48 | [R3X_CMPSD] = &&INTERP_CMPSD, 49 | [R3X_LOADR] = &&INTERP_LOADR, 50 | [R3X_PUSHR] = &&INTERP_PUSHR, 51 | [R3X_POPR] = &&INTERP_POPR, 52 | [R3X_INCR] = &&INTERP_INCR, 53 | [R3X_DECR] = &&INTERP_DECR, 54 | [R3X_INT] = &&INTERP_INT, 55 | [R3X_LOADI] = &&INTERP_LOADI, 56 | [R3X_NOT] = &&INTERP_NOT, 57 | [R3X_NEG] = &&INTERP_NEG, 58 | [R3X_PUSHAR] = &&INTERP_PUSHAR, 59 | [R3X_POPAR] = &&INTERP_POPAR, 60 | [R3X_SHR] = &&INTERP_SHR, 61 | [R3X_SHL] = &&INTERP_SHL, 62 | [R3X_ROR] = &&INTERP_ROR, 63 | [R3X_ROL] = &&INTERP_ROL, 64 | [R3X_CALLDYNAMIC] = &&INTERP_CALLDYNAMIC, 65 | [R3X_FSIN] = &&INTERP_FSIN, 66 | [R3X_FCOS] = &&INTERP_FCOS, 67 | [R3X_FTAN] = &&INTERP_FTAN, 68 | [R3X_ASIN] = &&INTERP_ASIN, 69 | [R3X_ACOS] = &&INTERP_ACOS, 70 | [R3X_ATAN] = &&INTERP_ATAN, 71 | [R3X_FPOW] = &&INTERP_FPOW, 72 | [R3X_MOD] = &&INTERP_MOD, 73 | [R3X_FMOD] = &&INTERP_FMOD, 74 | [R3X_RCONV] = &&INTERP_RCONV, 75 | [R3X_ACONV] = &&INTERP_ACONV, 76 | [R3X_CMPS] = &&INTERP_CMPS, 77 | [R3X_POPN] = &&INTERP_POPN, 78 | [R3X_PUSHF] = &&INTERP_PUSHF, 79 | [R3X_POPF] = &&INTERP_POPF, 80 | [R3X_TERN] = &&INTERP_TERN, 81 | [R3X_CATCH] = &&INTERP_CATCH, 82 | [R3X_THROW] = &&INTERP_THROW, 83 | [R3X_HANDLE] = &&INTERP_HANDLE, 84 | [R3X_STORES] = &&INTERP_STORES, 85 | [R3X_LOADSR] = &&INTERP_LOADSR, 86 | [R3X_STORESR] = &&INTERP_STORESR, 87 | [R3X_SETE] = &&INTERP_SETE, 88 | [R3X_SETNE] = &&INTERP_SETNE, 89 | [R3X_SETG] = &&INTERP_SETG, 90 | [R3X_SETL] = &&INTERP_SETL, 91 | [R3X_FSINH] = &&INTERP_FSINH, 92 | [R3X_FCOSH] = &&INTERP_FCOSH, 93 | [R3X_FTANH] = &&INTERP_FTANH, 94 | [R3X_FABS] = &&INTERP_FABS, 95 | [R3X_FLOOR] = &&INTERP_FLOOR, 96 | [R3X_CEIL] = &&INTERP_CEIL, 97 | [R3X_ASINH] = &&INTERP_ASINH, 98 | [R3X_ACOSH] = &&INTERP_ACOSH, 99 | [R3X_ATANH] = &&INTERP_ATANH, 100 | [R3X_FCONV] = &&INTERP_FCONV, 101 | [R3X_ICONV] = &&INTERP_ICONV, 102 | [R3X_FSQRT] = &&INTERP_FSQRT, 103 | [R3X_JMPL] = &&INTERP_JMPL, 104 | [R3X_JEL] = &&INTERP_JEL, 105 | [R3X_JGL] = &&INTERP_JGL, 106 | [R3X_JLL] = &&INTERP_JLL, 107 | [R3X_JZL] = &&INTERP_JZL, 108 | [R3X_PUSHIP] = &&INTERP_PUSHIP, 109 | /**[ R3X_REX64_INST01 **/ 110 | /**R3X_REX64_INS02**/ 111 | [R3X_ARS] = &&INTERP_ARS, 112 | [R3X_BREAK] = &&INTERP_BREAK, 113 | [R3X_CALLL] = &&INTERP_CALLL, 114 | [RFC_PREFIX] = &&INTERP_RFC, 115 | [R3X_LOR] = &&INTERP_LOR, 116 | [R3X_LAND] = &&INTERP_LAND 117 | }; 118 | #endif 119 | #endif 120 | -------------------------------------------------------------------------------- /src/include/r3x_pack.h: -------------------------------------------------------------------------------- 1 | #include 2 | #ifndef R3X_PACK_H 3 | #define R3X_PACK_H 4 | #define R3X_PACKAGE_HEADER 0xC002B00B 5 | typedef struct { 6 | uint32_t PackageHeader; 7 | uint32_t EXEName; 8 | uint32_t EXEFilePointer; 9 | uint32_t EXESize; 10 | uint32_t ObjFileListPointer; 11 | uint32_t NativeObjectFileListPointer; 12 | uint16_t ArchiveVersionMajor; 13 | uint16_t ArchiveVersionMinor; 14 | uint32_t Checksum; 15 | } r3x_package_header; 16 | 17 | typedef struct { 18 | uint32_t ObjectName; //! Recasted to CHAR* 19 | uint32_t ObjectFilePointer; 20 | uint32_t ObjectFileSize; 21 | } r3x_package_object_list; 22 | 23 | typedef struct { 24 | FILE* package_file; 25 | char** ObjectFiles; 26 | char** NativeFiles; 27 | } package_info; 28 | #endif 29 | -------------------------------------------------------------------------------- /src/include/r3x_script.h: -------------------------------------------------------------------------------- 1 | #ifndef R3X_SCRIPT_H 2 | #define R3X_SCRIPT_H 3 | #include 4 | 5 | typedef struct { 6 | char* ExeName; 7 | char* FontName; 8 | char* Args; 9 | uint64_t StackSize; 10 | float Frequency; 11 | float FontScale; 12 | unsigned int ScreenWidth; 13 | unsigned int ScreenHeight; 14 | unsigned int FontHeight; 15 | unsigned int FontWidth; 16 | } ScriptState; 17 | 18 | void parse_script(char*, ScriptState*); 19 | #endif 20 | -------------------------------------------------------------------------------- /src/include/r3x_stack.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 Benderx2, 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | * Neither the name of R3X nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #ifndef R3X_VSTACK_H 31 | #define R3X_VSTACK_H 32 | #include 33 | #define STACK_UFLOW_ERR -1 34 | #define DEFAULT_STACK_SIZE 16 * sizeof(int64_t) 35 | #define DEFAULT_MAX_STACK_SIZE 262144 36 | typedef struct __stack { 37 | int64_t* content; 38 | unsigned int top_of_stack; 39 | unsigned int stack_count; 40 | unsigned int max_stack; 41 | } vstack_t; 42 | typedef struct __stack_construct { 43 | vstack_t* (*Create)(void); 44 | int(*Push)(vstack_t*, int64_t); 45 | int64_t(*Pop)(vstack_t*); 46 | int(*Duplicate)(vstack_t*); 47 | int64_t(*GetItem)(vstack_t*, unsigned int); 48 | int(*SetItem)(vstack_t*, unsigned int, int64_t); 49 | void(*DestroyStack)(vstack_t*); 50 | } stack_construct; 51 | extern stack_construct Stack; 52 | void init_stack_construct(void); 53 | #endif 54 | -------------------------------------------------------------------------------- /src/include/r3x_stacktrace.h: -------------------------------------------------------------------------------- 1 | #ifndef R3X_STACK_TRACE_H 2 | #define R3X_STACK_TRACE_H 3 | #include 4 | #ifdef R_DEBUG 5 | static inline void print_backtrace(void); 6 | static inline void print_backtrace(void) { 7 | #ifndef _WIN32 8 | //! assume posix. 9 | void * buffer[512]; 10 | const int calls = backtrace(buffer, 11 | sizeof(buffer) / sizeof(void *)); 12 | backtrace_symbols_fd(buffer, calls, 1); 13 | #else 14 | //! do extra stuff for win32 15 | void* stack[100]; 16 | unsigned short frames; 17 | SYMBOL_INFO* symbol; 18 | HANDLE process; 19 | process = GetCurrentProcess(); 20 | SymInitialize(process, NULL, TRUE); 21 | frames = CaptureStackBackTrace(0, 100, stack, NULL); 22 | symbol = (SYMBOL_INFO *)calloc( sizeof(SYMBOL_INFO) + 256 * sizeof(char), 1); 23 | symbol->MaxNameLen = 255; 24 | symbol->SizeOfStruct = sizeof(SYMBOL_INFO); 25 | for(unsigned int i = 0; i < frames; i++) { 26 | SymFromAddr(process, (uint64_t)(stack[i]), 0, symbol); 27 | printf("%i: %s - 0x%0X\n", frames - i - 1, symbol->Name, symbol->Address); 28 | } 29 | free(symbol); 30 | #endif 31 | } 32 | #endif 33 | #endif -------------------------------------------------------------------------------- /src/include/r3x_stream.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 Benderx2, 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | * Neither the name of R3X nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #ifndef R3X_STREAM_H 31 | #define R3X_STREAM_H 32 | #include 33 | #include 34 | void init_stream_manager(void); 35 | unsigned int stream_open(char* name); 36 | void stream_close(unsigned int handle); 37 | void stream_seek(unsigned int handle, long int off, int origin); 38 | unsigned int stream_tell(unsigned int handle); 39 | unsigned int stream_read(void* ptr, unsigned int handle, size_t count); 40 | unsigned int stream_write(void* ptr, unsigned int handle, size_t count); 41 | #endif 42 | -------------------------------------------------------------------------------- /src/include/r3x_version.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 Benderx2, 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | * Neither the name of R3X nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #ifndef R3X_VERSION_H 31 | #define R3X_VERSION_H 32 | #ifdef LINUX_ARCH_X8664 33 | #define R3X_SYSTEM_VERSION "R3X Virtual Machine 0.4.8b Aura, compiled for: Linux64" 34 | #endif 35 | #ifdef LINUX_ARCH_X8632 36 | #define R3X_SYSTEM_VERSION "R3X Virtual Machine 0.4.8b Aura, compiled for: Linux32" 37 | #endif 38 | #ifdef LINUX_ARCH_ARM64 39 | #define R3X_SYSTEM_VERSION "R3X Virtual Machine 0.4.8b Aura, compiled for: LinuxARM64" 40 | #endif 41 | #ifdef LINUX_ARCH_PPC 42 | #define R3X_SYSTEM_VERSION "R3X Virtual Machine 0.4.8b Aura, compiled for: LinuxPPC" 43 | #endif 44 | #ifdef WIN_ARCH_X8632 45 | #define R3X_SYSTEM_VERSION "R3X Virtual Machine 0.4.8b Aura, compiled for: Windows32" 46 | #endif 47 | #ifdef WIN_ARCH_X8664 48 | #define R3X_SYSTEM_VERSION "R3X Virtual Machine 0.4.8b Aura, compiled for: Windows64" 49 | #endif 50 | #endif 51 | -------------------------------------------------------------------------------- /src/include/system.h: -------------------------------------------------------------------------------- 1 | #ifndef R_SYSTEM_HEADER 2 | #define R_SYSTEM_HEADER 3 | 4 | //! Just something experimental 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #ifndef _WIN32 16 | #include 17 | #else 18 | #include 19 | #include 20 | #endif 21 | #include 22 | #include 23 | #ifdef REX_DYNAMIC 24 | #ifndef _WIN32 25 | #include 26 | #else 27 | #include 28 | #endif 29 | #endif 30 | #ifdef R_DEBUG 31 | #ifndef _WIN32 32 | #include 33 | #else 34 | #include 35 | #endif 36 | #endif 37 | #ifndef PRIu64 38 | #warning "PRIu64 undefined, defining built-in!" 39 | #define PRIu64 "llu" 40 | #endif 41 | typedef bool Boolean; 42 | //! System specific description of file descriptor and stuff 43 | typedef FILE* File; 44 | typedef void* Pointer; 45 | typedef const void* CPointer; 46 | typedef size_t Size; 47 | typedef unsigned int Uint; 48 | #ifndef _WIN32 49 | typedef pid_t ProcessID; 50 | #else 51 | typedef int ProcessID; 52 | #endif 53 | typedef int Exception; 54 | typedef struct { 55 | //! Write formatted output to console 56 | int (*WriteLine)(const char*, ...); 57 | //! Read 'raw' input from console, with a specified length 58 | char* (*ReadLine)(char*, Uint); 59 | //! Console specific newline character, could be a LF, could be 60 | //! a CR+LF, could be anything 61 | unsigned char NewLine; 62 | } REX_CONSOLE; 63 | typedef struct { 64 | //! System specific IO access functions 65 | File (*Open)(const char*, const char*); 66 | int (*Close)(File); 67 | Size (*Read)(Pointer, Size, Size, File); 68 | Size (*Write)(CPointer, Size, Size, File); 69 | //! Write in printf format 70 | int (*WriteLine)(File, const char*, ...); 71 | } REX_IO; 72 | typedef struct { 73 | Exception InvalidMemoryAccessException; 74 | Exception FloatingPointException; 75 | Exception ProgramInterruption; 76 | Exception ProgramExitException; 77 | Exception ProgramAlaramException; 78 | Exception UserException; 79 | void (*RegisterException)(int, void(*)(int)); 80 | } REX_EXCEPTIONS; 81 | typedef struct { 82 | char* SystemName; 83 | char* SystemVersion; 84 | char* EnviromentVariables; 85 | void (*GetApplicationPath)(char*, Uint); 86 | ProcessID (*GetProcessID)(void); 87 | } REX_SYSINFO; 88 | typedef struct { 89 | REX_CONSOLE Console; 90 | REX_IO IO; 91 | REX_EXCEPTIONS Exceptions; 92 | REX_SYSINFO SystemInfo; 93 | Pointer (*AllocateMemory)(Size); 94 | Pointer (*FreeMemory)(Size); 95 | } REX_SYSTEM_STRUCT; 96 | //! Declare global struct 97 | extern REX_SYSTEM_STRUCT System; 98 | void InitializeREXSubsystem(Boolean DebugFlags); 99 | #endif 100 | -------------------------------------------------------------------------------- /src/include/win32/dlfcn.h: -------------------------------------------------------------------------------- 1 | /* 2 | * dlfcn-win32 3 | * Copyright (c) 2007 Ramiro Polla 4 | * 5 | * dlfcn-win32 is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * dlfcn-win32 is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with dlfcn-win32; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | #ifndef WIN32_DLFCN_H 20 | #define WIN32_DLFCN_H 21 | #include 22 | #include 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | /* POSIX says these are implementation-defined. 29 | * To simplify use with Windows API, we treat them the same way. 30 | */ 31 | 32 | #define RTLD_LAZY 0 33 | #define RTLD_NOW 0 34 | 35 | #define RTLD_GLOBAL (1 << 1) 36 | #define RTLD_LOCAL (1 << 2) 37 | 38 | /* These two were added in The Open Group Base Specifications Issue 6. 39 | * Note: All other RTLD_* flags in any dlfcn.h are not standard compliant. 40 | */ 41 | 42 | #define RTLD_DEFAULT 0 43 | #define RTLD_NEXT 0 44 | 45 | void *dlopen ( const char *file, int mode ); 46 | int dlclose( void *handle ); 47 | void *dlsym ( void *handle, const char *name ); 48 | char *dlerror( void ); 49 | 50 | #ifdef __cplusplus 51 | } 52 | #endif 53 | #endif -------------------------------------------------------------------------------- /src/lib/gl/gl.bas: -------------------------------------------------------------------------------- 1 | #include 2 | #include "rxgl.h" 3 | 4 | /* gl example for r3x */ 5 | function main(0) 6 | print "clearing screen" 7 | // gl clear color with white. 8 | @r_glClearColor(1.0, 1.0, 1.0, 1.0) 9 | // clear color and depth buffers 10 | @r_glClear(GL_COLOR_BUFFER_BIT) 11 | @r_glClear(GL_DEPTH_BUFFER_BIT) 12 | // draw 4 triangles 13 | @r_glBegin(GL_TRIANGLES) 14 | @r_glColor3f(0.8, 0, 0) 15 | @r_glVertex3f(0, 0, 0) 16 | @r_glVertex3f(1.0, 0, 0) 17 | @r_glVertex3f(0, 1.0, 0) 18 | @r_glEnd() 19 | 20 | @r_glBegin(GL_TRIANGLES) 21 | @r_glColor3f(0.8, 0.8, 0) 22 | @r_glVertex3f(0, 0, 0) 23 | @r_glVertex3f(sub_f(0, 1.0), 0, 0) 24 | @r_glVertex3f(0, sub_f(0, 1.0), 0) 25 | @r_glEnd() 26 | 27 | @r_glBegin(GL_TRIANGLES) 28 | @r_glColor3f(0, 0, 0.8) 29 | @r_glVertex3f(0, 0, 0) 30 | @r_glVertex3f(sub_f(0, 1.0), 0, 0) 31 | @r_glVertex3f(0, 1.0, 0) 32 | @r_glEnd() 33 | 34 | @r_glBegin(GL_TRIANGLES) 35 | @r_glColor3f(0, 0.8, 0) 36 | @r_glVertex3f(0, 0, 0) 37 | @r_glVertex3f(1.0, 0 , 0) 38 | @r_glVertex3f(0, sub_f(0, 1.0), 0) 39 | @r_glEnd() 40 | // call vm specific function to swap buffers 41 | asm "syscall SYSCALL_GLUPDATE" 42 | // jump into debugger 43 | asm "break" 44 | print "program execution complete" 45 | end 46 | endf 47 | -------------------------------------------------------------------------------- /src/lib/gl/rxgl.h: -------------------------------------------------------------------------------- 1 | #ifndef __RXGL_H 2 | #define __RXGL_H 3 | /* 4 | * This is not a C/C++ header! 5 | * It is to be used with R3X applications 6 | * that are written in T++. 7 | */ 8 | #define GL_POINTS 0 9 | #define GL_LINES 1 10 | #define GL_LINE_STRIP 2 11 | #define GL_LINE_LOOP 3 12 | #define GL_TRIANGLES 4 13 | #define GL_QUADS 5 14 | #define GL_QUAD_STRIP 6 15 | #define GL_POLYGON 7 16 | 17 | #define GL_FRONT 0 18 | #define GL_BACK 1 19 | #define GL_FRONT_AND_BACK 2 20 | 21 | #define GL_ALPHA_TEST 0 22 | #define GL_AUTO_NORMAL 1 23 | #define GL_BLEND 2 24 | #define GL_CULL_FACE 3 25 | #define GL_DEPTH_TEST 4 26 | #define GL_DITHER 5 27 | #define GL_FOG 6 28 | #define GL_LIGHTING 7 29 | #define GL_LINE_SMOOTH 8 30 | #define GL_SCISSOR_TEST 9 31 | #define GL_STENCIL_TEST 10 32 | 33 | #define GL_COLOR_BUFFER_BIT 0 34 | #define GL_DEPTH_BUFFER_BIT 1 35 | #define GL_ACCUM_BUFFER_BIT 2 36 | #define GL_STENCIL_BUFFER_BIT 3 37 | 38 | #define GL_MODELVIEW 0 39 | #define GL_PROJECTION 1 40 | #define GL_TEXTURE 2 41 | 42 | #define GL_TEXTURE_2D 0 43 | 44 | #define GL_COLOR_INDEX 0 45 | #define GL_RED 1 46 | #define GL_GREEN 2 47 | #define GL_BLUE 3 48 | #define GL_ALPHA 4 49 | #define GL_RGB 5 50 | #define GL_BGR 6 51 | #define GL_RGBA 7 52 | #define GL_BGRA 8 53 | #define GL_LUMINANCE 9 54 | #define GL_LUMINANCE_ALPHA 10 55 | 56 | #define GL_UNSIGNED_BYTE 0 57 | #define GL_BYTE 1 58 | #define GL_UNSIGNED_SHORT 2 59 | #define GL_SHORT 3 60 | #define GL_UNSIGNED_INT 4 61 | #define GL_INT 5 62 | #define GL_FLOAT 6 63 | 64 | // Declare native GL functions 65 | native(r_glBegin, "rxgl.so", 1) 66 | native(r_glClear, "rxgl.so", 1) 67 | native(r_glClearColor, "rxgl.so", 4) 68 | native(r_glColor4f, "rxgl.so", 4) 69 | native(r_glColor3f, "rxgl.so", 3) 70 | native(r_glEnd, "rxgl.so", 0) 71 | native(r_glFrustum, "rxgl.so", 6) 72 | native(r_glLoadIdentity, "rxgl.so", 0) 73 | native(r_glMatrixMode, "rxgl.so", 1) 74 | native(r_glRotated, "rxgl.so", 4) 75 | native(r_glRotatef, "rxgl.so", 4) 76 | native(r_glScalef, "rxgl.so", 3) 77 | native(r_glScaled, "rxgl.so", 3) 78 | native(r_glScissor, "rxgl.so", 4) 79 | native(r_glTexCoord2f, "rxgl.so", 2) 80 | native(r_glTexCoord3f, "rxgl.so", 3) 81 | native(r_glTexCoord4f, "rxgl.so", 4) 82 | native(r_glTexImage2D, "rxgl.so", 9) 83 | native(r_glTexSubImage2D, "rxgl.so", 9) 84 | native(r_glTranslatef, "rxgl.so", 3) 85 | native(r_glTranslated, "rxgl.so", 3) 86 | native(r_glVertex2f, "rxgl.so", 2) 87 | native(r_glVertex3f, "rxgl.so", 3) 88 | native(r_glVertex4f, "rxgl.so", 4) 89 | native(r_glViewport, "rxgl.so", 4) 90 | 91 | #endif 92 | -------------------------------------------------------------------------------- /src/lib/include/nt_malloc.h: -------------------------------------------------------------------------------- 1 | #ifndef __NT_MALLOC_H 2 | #define __NT_MALLOC_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | extern bool isAllFreed; 9 | int nt_malloc_init(bool); 10 | void* nt_calloc(unsigned int, size_t); 11 | void* nt_realloc(void*, size_t); 12 | void* nt_malloc(size_t); 13 | int nt_free(void*); 14 | void nt_freeall(void); 15 | void nt_atexit(void); 16 | char* nt_concat(char *s1, char *s2); 17 | #endif 18 | -------------------------------------------------------------------------------- /src/lib/include/virtual-machine.h: -------------------------------------------------------------------------------- 1 | #ifndef REX_VIRTUAL_MACHINE_H 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #ifdef REX_GRAPHICS 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #endif 17 | #ifndef _WIN32 18 | #include 19 | #else 20 | #include 21 | #endif 22 | #include 23 | #include 24 | #define CPU_INVALID_OPCODE_SIGNAL -1 25 | #define CPU_EXIT_SIGNAL -2 26 | #define CPU_INCREMENT_SINGLE 1 27 | #define CPU_INCREMENT_DOUBLE 2 28 | #define CPU_INCREMENT_WITH_32_OP 5 29 | #define CPU_INCREMENT_WITH_32_OP_2 9 30 | #define CPU_INCREMENT_WITH_32_OP_3 13 31 | #define CPU_EXCEPTION_INVALIDACCESS 0 32 | #define CPU_EXCEPTION_INVALIDOPCODE 1 33 | #define CPU_EXCEPTION_EXCEPTION 2 34 | #define CPU_EXCEPTION_ARITHMETIC 3 35 | #define MAX_NUMBER_OF_REGISTERS 20 36 | #define TOTAL_EXCEPTIONS 3 37 | #define R_LOCK 0 38 | #define R_SHUTDOWN 1 39 | #define R_KEYPRESS 2 40 | #define R_TIMER 3 41 | #define STACK_UFLOW_ERR -1 42 | #define DEFAULT_STACK_SIZE 16 * sizeof(int32_t) 43 | #define DEFAULT_MAX_STACK_SIZE 262144 44 | #define TOTAL_NUMBER_OF_ITEMS_BEFORE_ARGS 7 45 | typedef struct __stack { 46 | int32_t* content; 47 | unsigned int top_of_stack; 48 | unsigned int stack_count; 49 | unsigned int max_stack; 50 | } vstack_t; 51 | typedef struct __stack_construct { 52 | vstack_t* (*Create)(void); 53 | int32_t(*Push)(vstack_t*, int32_t); 54 | int32_t(*Pop)(vstack_t*); 55 | int32_t(*Duplicate)(vstack_t*); 56 | int32_t(*GetItem)(vstack_t*, unsigned int); 57 | int(*SetItem)(vstack_t*, unsigned int, int32_t); 58 | void(*DestroyStack)(vstack_t*); 59 | } stack_construct; 60 | typedef struct r3x_job { 61 | uint32_t InstructionPointer; 62 | vstack_t* Stack; 63 | vstack_t* CallStack; 64 | vstack_t* FreeAddressStack; 65 | uint32_t Regs[22]; 66 | uint32_t ExceptionHandlers[4]; 67 | bool EqualFlag; 68 | bool GreaterFlag; 69 | bool LesserFlag; 70 | bool ZeroFlag; 71 | bool ExceptionFlag; 72 | int CycleUpdate; 73 | int JobID; 74 | bool ismain; 75 | bool paused; 76 | } r3x_job_t; 77 | typedef struct r3x_global_domain { 78 | r3x_job_t** Jobs; 79 | unsigned int CurrentJobID; 80 | unsigned int NumberOfActiveJobs; 81 | unsigned int TotalNumberOfJobs; 82 | } r3x_global_domain_t; 83 | typedef struct { 84 | void* MemoryBlocks; 85 | } r3x_memory_blocks; 86 | typedef struct r3x_cpu { 87 | // super global : memory 88 | uint8_t* Memory; 89 | // Not global -- Thread dependent 90 | vstack_t* Stack; 91 | vstack_t* CallStack; 92 | unsigned int InstructionPointer; 93 | int ErrorCode; 94 | bool EqualFlag; 95 | bool GreaterFlag; 96 | bool LesserFlag; 97 | bool ZeroFlag; 98 | bool ExceptionFlag; 99 | uint32_t FLAGS; 100 | uint64_t Regs[MAX_NUMBER_OF_REGISTERS+1]; 101 | uint32_t ExceptionHandlers[4]; 102 | // Global -- Thread Independent. 103 | r3x_memory_blocks* CPUMemoryBlocks; 104 | double CPUClock; 105 | uint32_t ISR_handlers[256]; 106 | unsigned int CurrentInstruction; 107 | unsigned int MemorySize; 108 | unsigned int HeapAddr; 109 | bool use_frequency; 110 | double CPUFrequency; 111 | r3x_global_domain_t* RootDomain; 112 | void* Graphics; 113 | void* ObjectList; 114 | } r3x_cpu_t; 115 | extern stack_construct Stack; 116 | static inline uint32_t GetArgument(r3x_cpu_t* CPU, uint32_t arg_num, uint32_t total_no_of_args) { 117 | if(arg_num == 0) { 118 | printf("Fatal error! Trying to grab argument 0. Arguments are NOT 0-indexed.\n"); 119 | return 0xFFFFFFFF; 120 | } 121 | return Stack.GetItem(CPU->Stack, (CPU->Stack->top_of_stack-TOTAL_NUMBER_OF_ITEMS_BEFORE_ARGS)-(total_no_of_args)+arg_num); 122 | } 123 | static inline void* GetLinearAddress(r3x_cpu_t* CPU, uint32_t addr) { 124 | if(addr == 0) { return (void*)NULL; } 125 | return (void*)((uintptr_t)CPU->Memory + (uintptr_t)addr); 126 | } 127 | #endif 128 | -------------------------------------------------------------------------------- /src/lib/rstdlib/include/rstdlib.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Standard include file for t++ programs 3 | */ 4 | 5 | #ifndef __RSTDLIB_H 6 | #define __RSTDLIB_H 7 | 8 | #define true 1 9 | #define false 0 10 | #define NULL 0 11 | /* standard library functions defined in rstdlib.so */ 12 | /* note: the vm has a special case for "rstdlib" */ 13 | 14 | native(r_strlen, "rstdlib", 1) 15 | native(r_strcmp, "rstdlib", 2) 16 | native(r_strcpy, "rstdlib", 2) 17 | native(r_strcat, "rstdlib", 2) 18 | native(r_memset, "rstdlib", 3) 19 | native(r_memcpy, "rstdlib", 3) 20 | native(r_fopen, "rstdlib", 2) 21 | native(r_fclose, "rstdlib", 1) 22 | native(r_fread, "rstdlib", 3) 23 | native(r_fwrite, "rstdlib", 3) 24 | native(r_fflush, "rstdlib", 1) 25 | native(r_getenv, "rstdlib", 2) 26 | native(r_setenv, "rstdlib", 3) 27 | native(r_getapiversion, "rstdlib", 0) 28 | native(r_exitlib, "rstdlib", 0) 29 | 30 | /* math functions */ 31 | 32 | native(r_sin, "rstdlib", 1) 33 | native(r_cos, "rstdlib", 1) 34 | native(r_tan, "rstdlib", 1) 35 | native(r_sec, "rstdlib", 1) 36 | native(r_cosec, "rstdlib", 1) 37 | native(r_cot, "rstdlib", 1) 38 | native(r_sinh, "rstdlib", 1) 39 | native(r_cosh, "rstdlib", 1) 40 | native(r_tanh, "rstdlib", 1) 41 | native(r_sech, "rstdlib", 1) 42 | native(r_cosech, "rstdlib", 1) 43 | native(r_coth, "rstdlib", 1) 44 | native(r_asin, "rstdlib", 1) 45 | native(r_acos, "rstdlib", 1) 46 | native(r_atan, "rstdlib", 1) 47 | native(r_asec, "rstdlib", 1) 48 | native(r_acosec, "rstdlib", 1) 49 | native(r_acot, "rstdlib", 1) 50 | native(r_asinh, "rstdlib", 1) 51 | native(r_acosh, "rstdlib", 1) 52 | native(r_atanh, "rstdlib", 1) 53 | native(r_asech, "rstdlib", 1) 54 | native(r_acosech, "rstdlib", 1) 55 | native(r_acoth, "rstdlib", 1) 56 | native(r_exp, "rstdlib", 1) 57 | native(r_log, "rstdlib", 1) 58 | native(r_log10, "rstdlib", 1) 59 | native(r_pow, "rstdlib", 2) 60 | native(r_fabs, "rstdlib", 1) 61 | native(r_floor, "rstdlib", 1) 62 | native(r_ceil, "rstdlib", 1) 63 | native(r_fmod, "rstdlib", 2) 64 | 65 | /* socket functions */ 66 | native(r_connect, "rstdlib", 2) 67 | native(r_send, "rstdlib", 2) 68 | native(r_receive, "rstdlib", 3) 69 | native(r_receive_no_wait, "rstdlib", 3) 70 | 71 | /* Keyboard functions */ 72 | // Get character from keyboard - 0 if no character is pressed. 73 | function r_getc(0) 74 | asm "syscall SYSCALL_GETC" 75 | asm "popr R7" 76 | asm "ret" 77 | endf 78 | 79 | #endif 80 | -------------------------------------------------------------------------------- /src/lib/rstdlib/ircbot.bas: -------------------------------------------------------------------------------- 1 | #include 2 | #define HOST_READ_MAXLINE 512 3 | function main(0) 4 | let buf = alloc(HOST_READ_MAXLINE+1) 5 | print "irc bot: sending stuff to ##ingsoc @ irc.freenode.net" 6 | let sockfd = @r_connect("irc.freenode.net", 6667) 7 | print "socket: "; sockfd 8 | @r_send(sockfd, "NICK rxvm_bot") 9 | @r_send(sockfd, "USER rxvm_bot 0 0 : rxvm_bot") 10 | @r_send(sockfd, "JOIN ##ingsoc") 11 | @r_send(sockfd, "PRIVMSG ##ingsoc bender|:testing.host_connect......") 12 | /* Todo: get proper vm version than using fixed ones, but fuck off */ 13 | @r_send(sockfd, "PRIVMSG ##ingsoc Running.on.VM.Version:.0.4.7b") 14 | @r_send(sockfd, "PRIVMSG ##ingsoc Bye.Bye!") 15 | print "sent the stuff, now receiving, press a key to quit" 16 | let a = 0 17 | while (a := 0) 18 | @r_receive(sockfd, HOST_READ_MAXLINE, buf) 19 | print "->"; $buf 20 | endw 21 | @r_send(sockfd, "QUIT") 22 | end 23 | endf 24 | -------------------------------------------------------------------------------- /src/lib/rstdlib/readme.txt: -------------------------------------------------------------------------------- 1 | this file contains the rstdlib implementation for r3x and examples in t++. 2 | using the standard library is very easy, during the build process, the build script compiles it 3 | and copies it to the vm's directory. 4 | 5 | the buildutils.sh will compile the compiler, and then copy the header to compiler directory/include and will 6 | export STDLIB_R3X as that. this will only work for one session though. 7 | 8 | to make it permanent, edit your .bashrc or similar, and add this: 9 | 10 | export STDLIB_R3X="$PREFIX/include" # $PREFIX is where you have your compiler. 11 | STRING FUNCTIONS: 12 | 13 | @r_strlen(string) -> return length of string 14 | 15 | @r_strcmp(str1, str2) -> compare 2 strings, returns 0 (true) if they are equal. 16 | 17 | @r_strcpy(dest, src) -> Copy string src into string dest. 18 | 19 | @r_strcat(dest, src) -> concatenate two strings, (note dest should have required buffer size) 20 | 21 | MEMORY ACCESS FUNCTIONS 22 | 23 | @r_memset(buffer, char, size) -> set all bytes in buffer of size to char. 24 | 25 | @r_memcpy(dest, src, length) -> copy src to dest of length "length". 26 | 27 | FILE I/O FUNCTIONS 28 | 29 | @r_fopen(filename, mode) -> open file with name "filename" and mode. returns file descriptor (filefd) 30 | 31 | @r_fclose(filefd) -> close a file 32 | 33 | @r_fread(filefd, length, buffer) -> read from filfd into buffer of length "length". return the amount of bytes 34 | read 35 | 36 | @r_fwrite(filefd, length, buffer) -> write to filefd of length "length" from buffer. return the amount of bytes 37 | written 38 | 39 | @r_fflush(filefd) -> flush filefd. 40 | 41 | ENVIRONMENT FUNCTIONS 42 | 43 | @r_getenv(envname, buf) -> copy value of environment variable "envname" to buf. buffer should be allocated previously. 44 | in order to find the required size of buffer, use the function with null as buf, it will return the amount of bytes 45 | required for envname. 46 | 47 | @r_setenv(envname, envval, overwrite) -> set environment variable "envname" to "envval", with "overwrite" properties 48 | 49 | MATH FUNCTIONS 50 | 51 | @r_sin/r_cos/r_tan/r_sec/r_cosec/r_cot(float) -> return sine/cos/tan/sec/cosec/cot in [radians] 52 | @r_sinh/r_cosh/r_tanh/r_sech/r_cosech/r_coth(float) -> return value of hyperbolic trig functions [in radians] 53 | @r_asin/r_acos/r_atan/r_asec/r_acosec/r_acot(float) -> return value of inverse trig functions in radians 54 | @r_asinh/r_acosh/r_atanh/r_asech/r_acoseh/r_coth(float) -> do i need to explain this 55 | 56 | @r_exp(float) -> return e^float 57 | 58 | @r_log(float) -> return log base e of float 59 | @r_log10(float) -> return log base 10 of float 60 | 61 | @r_pow(base, exp) -> return base^exp 62 | @r_ceil(float) -> return ceil of float 63 | @r_floor(float) -> return floor of float 64 | @r_fmod(dividend, divisor) -> return remainder of dividend/divisor 65 | 66 | SOCKET FUNCTIONS: 67 | 68 | @r_connect(server_name, port) -> Connects to the server with the specified port and returns the socket descriptor. 69 | 70 | @r_send(sockfd, string) -> sends a null terminated "string" to sockfd with a newline '\n' 71 | 72 | @r_receive(sockfd, length, buffer) -> Reads from socket sockfd, to buffer with specified length. This function will 73 | !WAIT! until data is received. returns the number of bytes read. 74 | 75 | @r_receive_no_wait(sockfd, length, buffer) -> Reads from socket sockfd, to buffer with specified length. This function does not wait for data to be received. if there is no data received, it returns 0, else it returns the 76 | number of bytes read. 77 | -------------------------------------------------------------------------------- /src/lib/rstdlib/rsocket.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | extern r3x_cpu_t* CPU; 10 | 11 | int get_ip_from_hostname(char * hostname, char* ip); 12 | 13 | uint32_t r_connect(/*char *server, unsigned int port*/) { 14 | char* server_name = GetLinearAddress(CPU, GetArgument(CPU, 1,2)); 15 | char* server = malloc(80); 16 | get_ip_from_hostname(server_name, server); 17 | printf("Server Name: %s\n", server_name); 18 | unsigned int port = GetArgument(CPU, 2,2); 19 | printf("Connecting to server and port: %s, %u\n", server, port); 20 | int sockfd; 21 | struct sockaddr_in servaddr; 22 | bzero(&servaddr, sizeof(servaddr)); 23 | servaddr.sin_family = AF_INET; 24 | servaddr.sin_port = htons(port); 25 | 26 | if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { 27 | printf("host_connect FAILED\n"); 28 | return (uint32_t)-1; 29 | } 30 | 31 | if (inet_pton(AF_INET, server, &servaddr.sin_addr) <= 0) { 32 | printf("host_connect FAILED\n"); 33 | return (uint32_t)-1; 34 | } 35 | if (connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0 ) { 36 | printf("host_connect FAILED\n"); 37 | return (uint32_t)-1; 38 | } 39 | return sockfd; 40 | } 41 | uint32_t r_send(void) { 42 | int sockfd = (int)GetArgument(CPU,1,2); 43 | char* arg2 = (char*)GetLinearAddress(CPU, GetArgument(CPU,2,2)); 44 | char* out = malloc(strlen(arg2+2)); 45 | memset(out, 0, strlen(arg2+2)); 46 | strcpy(out, arg2); 47 | strcat(out, "\n"); 48 | //printf("Sending message: %s to socket: %d\n", out, sockfd); 49 | int retval = (uint32_t)send(sockfd, out, strlen(out), 0); 50 | return retval; 51 | } 52 | uint32_t r_receive(void) { 53 | int sockfd = (int)GetArgument(CPU, 1,3); 54 | unsigned int length = (unsigned int)GetArgument(CPU, 2,3); 55 | char* buf = GetLinearAddress(CPU, GetArgument(CPU, 3,3)); 56 | memset(buf, 0, length); 57 | int n = 0; 58 | while(n == 0) { 59 | n = read(sockfd, buf, length); 60 | } 61 | return n; 62 | } 63 | uint32_t r_receive_no_wait(void) { 64 | int sockfd = (int)GetArgument(CPU, 1,3); 65 | unsigned int length = (unsigned int)GetArgument(CPU, 2,3); 66 | char* buf = GetLinearAddress(CPU, GetArgument(CPU, 3,3)); 67 | memset(buf, 0, length); 68 | int n = read(sockfd, buf, length); 69 | return n; 70 | } 71 | int get_ip_from_hostname(char* hostname, char* ip) 72 | { 73 | struct hostent *host_entry; 74 | struct in_addr **address_list; 75 | int i; 76 | if ((host_entry = gethostbyname(hostname)) == NULL) { 77 | herror("gethostbyname"); 78 | return 1; 79 | } 80 | address_list = (struct in_addr **)host_entry->h_addr_list; 81 | for(i = 0; address_list[i] != NULL; i++) 82 | { 83 | strcpy(ip, inet_ntoa(*address_list[i])); 84 | return 0; 85 | } 86 | return 1; 87 | } 88 | -------------------------------------------------------------------------------- /src/lib/rstdlib/stdlibtest.bas: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | function main(0) 4 | print "calling sin" 5 | let x = @r_sin(30.0) 6 | print "sin 30 = "; %x 7 | print "opening a file" 8 | let filefd = @r_fopen("./file.txt", "w+b") 9 | print "writing hello world to file" 10 | let retval = @r_fwrite(filefd, @r_strlen("Hello World!"), "Hello World!") 11 | @r_fflush(filefd) 12 | @r_fclose(filefd) 13 | print "returned: "; retval 14 | end 15 | endf 16 | -------------------------------------------------------------------------------- /src/native.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 Benderx2, 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | * Neither the name of R3X nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #ifdef REX_DYNAMIC 31 | #include 32 | #include 33 | extern char* ApplicationPath; 34 | native_handle_t* head; 35 | native_handle_t* tail; 36 | int number_of_handles; 37 | extern r3x_cpu_t* r3_cpu; 38 | void* load_native_library(char* name, r3x_cpu_t* CPU) 39 | { 40 | void *handle; 41 | if(!strcmp(name, "rstdlib")) { 42 | char* tempstr = nt_malloc(strlen(ApplicationPath)+strlen("/rstdlib.so")+1); 43 | strcpy(tempstr, ApplicationPath); 44 | strcat(tempstr, "/rstdlib.so"); 45 | handle = dlopen(tempstr, RTLD_LAZY); 46 | nt_free(tempstr); 47 | } else { 48 | handle = dlopen(name, RTLD_LAZY); 49 | } 50 | if(!handle){ 51 | // Try opening it from the VM directory. 52 | char* tempstr = nt_malloc(strlen(ApplicationPath)+strlen(name)+3); 53 | strcpy(tempstr, ApplicationPath); 54 | tempstr[strlen(tempstr)] = '/'; 55 | tempstr[strlen(tempstr)+1] = 0; 56 | strcat(tempstr, name); 57 | printf("[Alert]Library %s not found in Application directory. Trying to load from %s\n", name, tempstr); 58 | handle = dlopen(tempstr, RTLD_LAZY); 59 | } 60 | if(!handle) { 61 | printf("\nFATAL: Unable to load shared object: %s\n", name); 62 | exit(0); 63 | } 64 | 65 | native_handle_t* newhandle = nt_malloc(sizeof(native_handle_t)); 66 | newhandle->soname = strdup(name); 67 | newhandle->handle = handle; 68 | newhandle->next = NULL; 69 | void (*Start)(r3x_cpu_t*); 70 | *(void**)(&Start) = dlsym(handle, "Start"); 71 | if(Start == NULL) 72 | { 73 | printf("ERROR: Start function not found in native library! Exitting..\n"); 74 | exit(0); 75 | } 76 | else { 77 | (*Start)(CPU); 78 | } 79 | if(number_of_handles == 0) 80 | { 81 | head = newhandle; 82 | tail = newhandle; 83 | } 84 | else { 85 | tail->next = newhandle; 86 | tail = newhandle; 87 | } 88 | number_of_handles++; 89 | return handle; 90 | } 91 | void* returnhandle(char* soname) 92 | { 93 | native_handle_t* current_handle = head; 94 | for(int i = 0; i <= number_of_handles; i++) 95 | { 96 | if(current_handle->soname != NULL) { 97 | if(!strcmp(current_handle->soname, soname)){ 98 | return current_handle->handle; 99 | } 100 | else { 101 | if(current_handle->next == NULL) 102 | { 103 | return NULL; 104 | } 105 | current_handle = (struct native_handle*)current_handle->next; 106 | } 107 | } 108 | } 109 | return NULL; 110 | } 111 | int native_call(char* name, void* handle) 112 | { 113 | // Clear existing errors. 114 | dlerror(); 115 | int (*function)(void); 116 | *(void**)(&function) = dlsym(handle, name); 117 | if(function == NULL) 118 | { 119 | printf("ERROR: Requested function not found! Name: %s\n", name); 120 | exit(EXIT_FAILURE); 121 | } 122 | return (*function)(); 123 | } 124 | #endif 125 | -------------------------------------------------------------------------------- /src/object.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 Benderx2, 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | * Neither the name of R3X nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #include 31 | #include 32 | object_t* pushObj(vstack_t* stack, ObjectList_t* List, ObjectType Type) 33 | { 34 | // Create an object and store it in a list... 35 | if(List->NumberOfObjects == 0){ 36 | List->Objects = nt_malloc(16 * sizeof(int)); // 16 default size... 37 | List->Index = 0; 38 | } 39 | else if(List->Index >= List->NumberOfObjects){ 40 | // Allocate twice as objects as the previous buffer and null out 41 | int* new_buf = nt_malloc(List->NumberOfObjects * 2 * sizeof(int)); 42 | memset(new_buf, 0, List->NumberOfObjects * 2 * sizeof(int)); 43 | // Copy from the original to the new one and free the original 44 | memcpy(new_buf, List->Objects, List->NumberOfObjects * sizeof(int)); 45 | nt_free(List->Objects); 46 | // Set the buffer and size accordingly 47 | List->Objects = new_buf; 48 | List->NumberOfObjects = List->NumberOfObjects * 2; 49 | } 50 | // Allocate new object and put it to the list. 51 | object_t* new_obj = nt_malloc(sizeof(object_t)); 52 | new_obj->Type = Type; 53 | new_obj->Value = 0; 54 | new_obj->ObjectID = List->Index; 55 | List->Objects[List->Index] = (intptr_t)new_obj; 56 | // Increment Index 57 | List->Index++; 58 | // Push to stack and return... 59 | Stack.Push(stack, new_obj->ObjectID); 60 | return new_obj; 61 | } 62 | void popObj(vstack_t* stack, ObjectList_t* List) 63 | { 64 | Stack.Pop(stack); // Pop out the object ID 65 | List->Objects[List->Index-1] = 0; 66 | } 67 | object_t* accessObj(ObjectList_t* List, unsigned int Index) 68 | { 69 | if(Index >= List->Index){ 70 | return NULL; // Return NULL if invalid Index.. 71 | } else { 72 | return (object_t*)((intptr_t)(List->Objects[Index])); // Since List->Objects contains a pointer stored as integer, hence typecast... 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/packageloader.c: -------------------------------------------------------------------------------- 1 | /* Package loader for R3X VM */ 2 | 3 | #include 4 | #include 5 | package_info* load_package(char* package_name); 6 | 7 | package_info* load_package(char* package_name) { 8 | (void)package_name; 9 | return NULL; 10 | /*package_info* pack_info = malloc(sizeof(package_info)); 11 | package_info->package_file = fopen(package_file, "r"); 12 | if(package_info->package_file == NULL) { 13 | return NULL; 14 | } 15 | void* temp = malloc(sizeof(r3x_package_header)); 16 | fread(temp, sizeof(r3x_package_header), uint8_t, package_info->package_file); 17 | r3x_package_header* myheader = &temp; 18 | if(myheader->PackageHeader != R3X_PACKAGE_HEADER) { 19 | return NULL; 20 | }*/ 21 | } 22 | -------------------------------------------------------------------------------- /src/programs/args.il: -------------------------------------------------------------------------------- 1 | include 'libR3X/libR3X.pkg' 2 | .text { 3 | function main 4 | Console.Write 'Run with: rxvm -exe ./args.exe -args "myarguments"' 5 | Console.NewLine 6 | Console.Write "Arugments Passed: " 7 | syscall SYSCALL_GETARGS 8 | syscall SYSCALL_PUTS 9 | Console.WaitKey 10 | System.Quit 0 11 | endfunction main 12 | } 13 | end 14 | -------------------------------------------------------------------------------- /src/programs/asshole.il: -------------------------------------------------------------------------------- 1 | include 'libR3X/libR3X.pkg' 2 | .text { 3 | function main 4 | Console.Write "I'm an asshole program!" 5 | Console.NewLine 6 | Console.Write "I'm going to write to executable memory!" 7 | Console.NewLine 8 | loadr R0, _lel 9 | stosd ; BOOBS. er. I mean BOOM 10 | _lel: 11 | dd 0 12 | endfunction main 13 | } 14 | end 15 | -------------------------------------------------------------------------------- /src/programs/bios.il: -------------------------------------------------------------------------------- 1 | ; R3X System BIOS 2 | ; Configures initial system information 3 | ; The BIOS has no format, so just directly include the header.. 4 | include 'libR3X/r3x_asm.pkg' 5 | define MACHINE_VER 0x36B 6 | define BIOS_VER 007 7 | define IS_UNIX 1 8 | init: 9 | ; Initialize all registers to 0 10 | loadr R1, 0 11 | loadr R2, 0 12 | loadr R3, 0 13 | loadr R4, 0 14 | loadr R5, 0 15 | loadr R6, 0 16 | loadr R7, 0 17 | loadr R8, 0 18 | loadr R9, 0 19 | loadr R10, 0 20 | loadr R11, 0 21 | loadr R12, 0 22 | loadr R13, 0 23 | loadr R14, 0 24 | loadr R15, 0 25 | loadr R16, 0 26 | loadr R17, 0 27 | loadr R18, 0 28 | loadr R19, 0 29 | loadr R20, 0 30 | ; Print System Information 31 | push BIOS_STRING 32 | syscall SYSCALL_PUTS 33 | pop 34 | push CPU_STRING 35 | syscall SYSCALL_PUTS 36 | pop 37 | ; Load Interrupts and jump to 1MB 38 | loadi 0x20, get_system_information 39 | ; Run the program 40 | pushar R0 41 | ret 42 | get_system_information: 43 | push MACHINE_VER 44 | push BIOS_VER 45 | push IS_UNIX 46 | ret 47 | CPU_STRING: db "R3X CPU, Based upon FVM Technology. (C) Benderx2", 0x0A, 0 48 | BIOS_STRING: db "R3X BIOS 0.4.8b Aura", 0x0A, 0 49 | is_exec: dd 0 50 | _END: 51 | times 512 - _END db 0 52 | _MEM_AFTR: 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /src/programs/dynamiclib.il: -------------------------------------------------------------------------------- 1 | include 'libR3X/libR3X.pkg' 2 | extern test_func, "simplelib.ro" 3 | 4 | .text { 5 | function main 6 | externcall test_func 7 | Console.WaitKey 8 | exit 9 | endfunction main 10 | } 11 | end 12 | -------------------------------------------------------------------------------- /src/programs/example.il: -------------------------------------------------------------------------------- 1 | 2 | include 'libR3X/libR3X.pkg' 3 | .text { 4 | dd 0x56081124 5 | dd 0x12345678 6 | dd 0x12335850 7 | dd 0xFFFF3FFF 8 | dd 0x23FF0FFF 9 | dd 0x13370000 10 | dd 0x66600000 11 | dd 0xEF7E0016 12 | } 13 | 14 | .text { 15 | 16 | 17 | ; debug line 1 18 | function main 19 | 20 | ; debug line 2 21 | loadr R1, s0 22 | call print_s 23 | call print_n 24 | 25 | ; debug line 3 26 | 27 | ; debug line 4 28 | loadr R1, 256 29 | pushr R0 30 | pushr R1 31 | call alloc_n 32 | loadr R0, vmain.buffer 33 | stosd 34 | popr R1 35 | popr R0 36 | 37 | ; debug line 5 38 | loadrm dword, R1, vmain.buffer 39 | loadrr R5, R1 40 | loadr R1, 65348 41 | pushr R0 42 | loadrr R0, R5 43 | stosw 44 | popr R0 45 | 46 | ; debug line 6 47 | loadrm dword, R1, vmain.buffer 48 | pushr R0 49 | loadrr R0, R1 50 | lodsb 51 | popr R0 52 | loadrr R4, R1 53 | loadr R1, 68 54 | cmpr R4, R1 55 | jne i6 56 | jmp main.lyes 57 | i6: 58 | 59 | ; debug line 7 60 | loadr R1, s1 61 | call print_s 62 | call print_n 63 | 64 | ; debug line 8 65 | jmp _exit 66 | 67 | ; debug line 9 68 | main.lyes: 69 | loadr R1, s2 70 | call print_s 71 | call print_n 72 | 73 | ; debug line 10 74 | jmp _exit 75 | 76 | ; debug line 11 77 | endfunction main 78 | 79 | ; exit to operating system 80 | 81 | _exit: 82 | Console.WaitKey 83 | System.Quit 0 84 | 85 | ; print_i excluded 86 | 87 | ; print string to terminal 88 | print_s: 89 | pushr R1 90 | syscall SYSCALL_PUTS 91 | popr R1 92 | ret 93 | 94 | ; print_t excluded 95 | 96 | ; print a newline to the terminal 97 | print_n: 98 | push 0x0A 99 | syscall SYSCALL_PUTCH 100 | pop 101 | ret 102 | 103 | ; input_i excluded 104 | ; Allocate n bytes of memory 105 | alloc_n: 106 | pushr R1 107 | syscall SYSCALL_ALLOC 108 | popr R1 109 | pop 110 | ret 111 | ; Output an IEEE-754 floating point number to stdout 112 | print_f: 113 | pushr R1 114 | syscall SYSCALL_PUTF 115 | popr R1 116 | ret 117 | ; Free an allocated region 118 | free: 119 | pushr R1 120 | syscall SYSCALL_FREE 121 | pop 122 | ret 123 | 124 | } 125 | .bss { 126 | 127 | vmain.buffer: rd 1 128 | } 129 | .data { 130 | 131 | s0: db "If stuff", 0 132 | s1: db "Uh, error!", 0 133 | s2: db "Yay, little endian!", 0 134 | } 135 | end 136 | ; Task Completed -- Assemble with FASM 137 | -------------------------------------------------------------------------------- /src/programs/exception.il: -------------------------------------------------------------------------------- 1 | include 'libR3X/libR3X.pkg' 2 | .text { 3 | function main 4 | ; This example shows exception handling 5 | push _zero_handler 6 | push INVALID_ARITH 7 | catch 8 | popn 2 9 | push _invalidexception_handler 10 | push INVALID_ACCESS 11 | catch 12 | popn 2 13 | push _invalid_opcode_handler 14 | push INVALID_OPCODE 15 | catch 16 | popn 2 17 | push _exception_handler 18 | push R_EXCEP 19 | catch 20 | popn 2 21 | ; Divide by 0 22 | push 27 23 | push 0 24 | div ; BOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOB5 25 | _doinvalid_access: 26 | ; Do an invalid access! 27 | loadr R0, 0xFFFFFFF 28 | lodsw ; BOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOM -- Not again :) 29 | _doinvalid_opcode_exception: 30 | db 0xFF 31 | _dorandom_exception: 32 | push 15 ; Push random error code 33 | push R_EXCEP 34 | throw 35 | exit ; This will never be called lol 36 | _invalidexception_handler: 37 | push INVAEXCEPTION_STRING 38 | syscall SYSCALL_PUTS 39 | pop 40 | handle 41 | jmp _doinvalid_opcode_exception 42 | _invalid_opcode_handler: 43 | push INVOEXCEPTION_STRING 44 | syscall SYSCALL_PUTS 45 | pop 46 | handle 47 | jmp _dorandom_exception 48 | _zero_handler: 49 | push ZEROEXCEPTION_STRING 50 | syscall SYSCALL_PUTS 51 | pop 52 | handle 53 | jmp _doinvalid_access 54 | _exception_handler: 55 | pop ; Pop out exception code 56 | push GLOBAL_EXCEPTION_STRING 57 | syscall SYSCALL_PUTS 58 | pop 59 | ; The program pushed the error code remember? 60 | syscall SYSCALL_PUTI 61 | Console.WaitKey 62 | handle 63 | System.Quit 0 64 | endfunction main 65 | } 66 | .data { 67 | INVAEXCEPTION_STRING: db 'Invalid Memory Access. Exception Detected! Causing another one.. ;).', 0x0A, 0 68 | INVOEXCEPTION_STRING: db 'Invalid Opcode! Causing Another one... lol', 0x0A, 0 69 | ZEROEXCEPTION_STRING: db "Hey, dividing by 0? Not allowed here honey", 0x0A, 0 70 | GLOBAL_EXCEPTION_STRING: db "Well, the program threw an exception on it's own.", 0x0A, "So well, fuck it. I'm closing", 0x0A, "And here's the error code: ", 0 71 | } 72 | end 73 | -------------------------------------------------------------------------------- /src/programs/hello.il: -------------------------------------------------------------------------------- 1 | include 'libR3X/libR3X.pkg' 2 | .text { 3 | function main 4 | pushstring "Hello, World!" 5 | syscall SYSCALL_PUTS 6 | push 0 7 | exit 8 | endfunction main 9 | } 10 | end 11 | -------------------------------------------------------------------------------- /src/programs/jmp.il: -------------------------------------------------------------------------------- 1 | include 'libR3X/libR3X.pkg' 2 | .text { 3 | function main 4 | Console.Write "Current IP: " 5 | jmp current_ip 6 | current_ip: 7 | ; Address of "current_ip" is pushed to stack 8 | puship 9 | syscall SYSCALL_PUTI 10 | pop 11 | ; Jump 269 bytes after "rel_jump". NOTE: This jump is position independent. 12 | calll rel_jump 13 | System.Quit 0 14 | times 269 db 0x1F ; Exit opcode. 15 | finally_exit: 16 | Console.Write "Exitting!" 17 | Console.WaitKey 18 | exit 19 | rel_jump: 20 | Console.Write "Relative Jump!" 21 | jmpl finally_exit 22 | endfunction main 23 | } 24 | end 25 | -------------------------------------------------------------------------------- /src/programs/libR3X/corelib.pkg: -------------------------------------------------------------------------------- 1 | ; Corelib package for R3X systems 2 | struc corelib.int value { 3 | jmp .______end 4 | .num: dd value+0 5 | .print: 6 | pushr R0 7 | pushr R1 8 | loadr R0, .num 9 | lodsd 10 | pushr R1 11 | syscall SYSCALL_PUTI 12 | pop 13 | popr R1 14 | popr R0 15 | ret 16 | .______end: 17 | } 18 | struc corelib.string string { 19 | jmp .______end 20 | .data: db string, 0 21 | .toint32: 22 | push .data 23 | syscall SYSCALL_ATOI 24 | popr R1 25 | pop 26 | ret 27 | .______end: 28 | } 29 | -------------------------------------------------------------------------------- /src/programs/libR3X/dynR3X.pkg: -------------------------------------------------------------------------------- 1 | include 'r3x_asm.pkg' 2 | format binary as 'ro' 3 | org 0 4 | _begin: 5 | dd 0xDEADBEEF 6 | dd 0 7 | dd 0 8 | dd _text 9 | dd _end_text - _text 10 | dd _export 11 | dd _end_export - _export 12 | dd _data 13 | dd _end_data - _data 14 | dd _bss 15 | dd _end_bss - _bss 16 | dd _name_addr 17 | dd _pub_addr 18 | _name_addr: db 'Default Shared Library', 0 19 | _pub_addr: db 'No publisher', 0 20 | _end_begin: 21 | times 4096-(_end_begin - _begin) db 0 22 | macro DECLARE_SECTION name { 23 | local m,c 24 | c equ 0 25 | macro .#name [a] \{ 26 | \common 27 | rept 1 x:c+1 \\{ c equ x 28 | macro m\\#x a \\} 29 | \} 30 | macro STORE_SECTION_#name \{ 31 | rept c x \\{ m\\#x \\} 32 | \} 33 | } 34 | macro declare_bss_entry entry_name { 35 | local symnameaddr 36 | .data \{ 37 | symnameaddr: 38 | db 'BSS Entry (4-bytes): ' 39 | db `entry_name#, 0 40 | \} 41 | .bss \{ 42 | #entry_name: 43 | rd 1 44 | entry_name#_end_bss: 45 | \} 46 | } 47 | DECLARE_SECTION text 48 | DECLARE_SECTION data 49 | DECLARE_SECTION bss 50 | DECLARE_SECTION export 51 | macro end { 52 | align 4096 53 | _text: 54 | align 1 55 | STORE_SECTION_text 56 | align 4096 57 | _end_text: 58 | align 4096 59 | _data: 60 | STORE_SECTION_data 61 | _end_data: 62 | _export: 63 | STORE_SECTION_export 64 | _end_export: 65 | _bss: 66 | STORE_SECTION_bss 67 | align 4096 68 | _end_bss: 69 | } 70 | macro pushstring string { 71 | local addm 72 | pushar R1 73 | loadr R1, addm 74 | addrr R1, R20 75 | pushr R1 76 | popar R1 77 | .data \{ addm: db string, 0 \} 78 | } 79 | macro loadrm size, reg1, memaddr { 80 | if reg1 eq R0 81 | else 82 | pushr R0 83 | end if 84 | if reg1 eq R1 85 | else 86 | pushr R1 87 | end if 88 | loadr R0, memaddr 89 | if size eq byte 90 | lodsb 91 | else if size eq word 92 | lodsw 93 | else if size eq dword 94 | lodsd 95 | else 96 | display 'Unknown size operand for loadrm' 97 | err 98 | end if 99 | loadrr reg1, R1 100 | if reg1 eq R0 101 | else 102 | popr R0 103 | end if 104 | if reg1 eq R1 105 | else 106 | popr R1 107 | end if 108 | } 109 | macro function name { 110 | #name: 111 | local symbol_name 112 | .data \{ 113 | symbol_name: db `name#, 0 114 | \} 115 | .export \{ 116 | dd symbol_name 117 | dd name# 118 | \} 119 | } 120 | macro function name { 121 | #name: 122 | local symbol_name 123 | .data \{ 124 | symbol_name: db `name#, 0 125 | \} 126 | .export \{ 127 | dd symbol_name 128 | dd name# 129 | \} 130 | } 131 | macro endfunction name { 132 | name#_end: 133 | } 134 | macro extern name, lib { 135 | pushr R1 136 | pushr R0 137 | pushstring lib 138 | syscall SYSCALL_LOADDYNAMIC 139 | popr R1 140 | pop 141 | loadr R0, name#_import_sym 142 | addrr R0, R20 143 | stosd 144 | popr R0 145 | popr R1 146 | .data \{ 147 | name#_import_sym: 148 | ; lib id 149 | .libid: 150 | dd 0 151 | .nameaddr: 152 | db `name#, 0 153 | .libaddr: 154 | db lib, 0 155 | \} 156 | } 157 | macro externcall name { 158 | pushr R0 159 | pushr R1 160 | ; Push lib handle 161 | loadr R0, name#_import_sym 162 | addrr R0, R20 163 | lodsd 164 | pushr R1 165 | loadr R0, name#_import_sym.nameaddr 166 | addrr R0, R20 167 | pushr R0 168 | calldynamic 169 | popn 2 170 | popr R1 171 | popr R0 172 | } 173 | -------------------------------------------------------------------------------- /src/programs/libR3X/simplelib.pkg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/programs/math.il: -------------------------------------------------------------------------------- 1 | include 'libR3X/libR3X.pkg' 2 | .text { 3 | function main 4 | Console.Write "Hello, this example will showcase R3X's math functions" 5 | Console.NewLine 6 | Console.Write "Sine, Cosine, and tangent of 30 DEG: " 7 | push 30.0f 8 | rconv 9 | fsin 10 | syscall SYSCALL_PUTF 11 | pop 12 | fcos 13 | syscall SYSCALL_PUTF 14 | pop 15 | ftan 16 | syscall SYSCALL_PUTF 17 | pop 18 | pop 19 | Console.NewLine 20 | Console.Write "Inverse sine, cosine and tangent of 30 DEG: " 21 | asin 22 | syscall SYSCALL_PUTF 23 | pop 24 | acos 25 | syscall SYSCALL_PUTF 26 | pop 27 | atan 28 | syscall SYSCALL_PUTF 29 | pop 30 | pop 31 | Console.NewLine 32 | Console.Write "Square root of 56: " 33 | push 56.0f 34 | push 0.5f 35 | fpow 36 | syscall SYSCALL_PUTF 37 | Console.NewLine 38 | Console.Write "Doing a modulo operation. N=27.6, D=4.5: " 39 | push 27.6 40 | push 4.5 41 | fmod 42 | syscall SYSCALL_PUTF 43 | popn 3 44 | Console.NewLine 45 | Console.Write "Finding sinh, cosh, tanh, asinh, acosh, atanh of 30 DEG: " 46 | push 30.0f 47 | rconv 48 | fsinh 49 | syscall SYSCALL_PUTF 50 | pop 51 | fcosh 52 | syscall SYSCALL_PUTF 53 | pop 54 | ftanh 55 | syscall SYSCALL_PUTF 56 | pop 57 | asinh 58 | syscall SYSCALL_PUTF 59 | pop 60 | acosh 61 | syscall SYSCALL_PUTF 62 | pop 63 | atanh 64 | syscall SYSCALL_PUTF 65 | pop 66 | Console.NewLine 67 | Console.Write "Doing a floor/ceil operation on 30.5555: " 68 | push 30.5555f 69 | floor 70 | syscall SYSCALL_PUTF 71 | pop 72 | ceil 73 | syscall SYSCALL_PUTF 74 | pop 75 | Console.NewLine 76 | Console.Write "Converting 30.567 to a 32-bit integer: " 77 | push 30.567 78 | iconv 79 | syscall SYSCALL_PUTI 80 | Console.WaitKey 81 | ; VM clears the stack... 82 | System.Quit 0 83 | endfunction main 84 | } 85 | end 86 | -------------------------------------------------------------------------------- /src/programs/mylib.c: -------------------------------------------------------------------------------- 1 | #include "virtual-machine.h" 2 | r3x_cpu_t* MyCPU; 3 | void Start(r3x_cpu_t* CPU) { 4 | MyCPU = CPU; 5 | return; 6 | } 7 | uint32_t myfunc(void) { 8 | printf("getting argument 1 (STRING): %s\n", (char*)GetLinearAddress(MyCPU, GetArgument(MyCPU, 1,1))); 9 | printf("returning 666\n"); 10 | return 666; 11 | } 12 | -------------------------------------------------------------------------------- /src/programs/nativelib.il: -------------------------------------------------------------------------------- 1 | include 'libR3X/libR3X.pkg' 2 | .text { 3 | function main 4 | pushstring "./mylib.so" 5 | loadlib 6 | Console.Write "Loaded mylib.so" 7 | Console.NewLine 8 | pushstring "Hello World!" 9 | push 0 10 | push 0 11 | push 0 12 | push 0 13 | pushstring "./mylib.so" 14 | pushstring "myfunc" 15 | libexec 16 | Console.Write "Function returned: " 17 | syscall SYSCALL_PUTI 18 | Console.WaitKey 19 | exit 20 | endfunction main 21 | } 22 | end 23 | -------------------------------------------------------------------------------- /src/programs/overflow.il: -------------------------------------------------------------------------------- 1 | include 'libR3X/libR3X.pkg' 2 | .text { 3 | function main 4 | _loop: 5 | push 0 6 | jmp _loop 7 | endfunction main 8 | } 9 | end 10 | -------------------------------------------------------------------------------- /src/programs/perf.il: -------------------------------------------------------------------------------- 1 | ; Simple performance test 2 | include 'libR3X/libR3X.pkg' 3 | .text { 4 | function main 5 | syscall SYSCALL_GETCLOCK 6 | popr R1 7 | loadr R0, save_float 8 | stosd 9 | ; Load R7 with 1 10 | loadr R7, 1 11 | .do_perf_test: 12 | ; Push R7 13 | pushr R7 14 | fsqrt 15 | ; Increment R7 16 | incr R7 17 | ; Is R7 == 10000000 18 | pushr R7 19 | push 100000000 20 | cmp 21 | popn 4 22 | je .done 23 | jmp .do_perf_test 24 | .done: 25 | syscall SYSCALL_GETCLOCK 26 | popr R1 27 | pushr R1 28 | syscall SYSCALL_GETCLOCKSPERSEC 29 | fdiv 30 | popr R1 31 | popn 2 32 | push desc 33 | syscall SYSCALL_PUTS 34 | pushr R1 35 | syscall SYSCALL_PUTF 36 | Console.WaitKey 37 | push 0 38 | exit 39 | endfunction main 40 | } 41 | .data { 42 | save_float: dd 0 43 | desc: db 'Found the square root of numbers 1-10000000 in (seconds) : ', 0 44 | } 45 | end 46 | -------------------------------------------------------------------------------- /src/programs/r3x_ex.il: -------------------------------------------------------------------------------- 1 | include 'libR3X/libR3X.pkg' 2 | import 'libR3X/corelib.pkg' 3 | .text { 4 | function main 5 | Console.Write "Allocating Page, page address: " 6 | System.AllocatePage 7 | Console.WriteInt 8 | Console.NewLine 9 | Console.Write "Calling Dynamic Library (simplelib.ro)" 10 | Console.NewLine 11 | pushr R0 12 | pushr R1 13 | ; Load lib. 14 | call loadsimplelib 15 | ; run lib 16 | call callsimplelib 17 | Console.Write "Hello, World!" 18 | Console.NewLine 19 | Console.Write "This is the beta preview of R3X (read : REX) virtual machine" 20 | Console.NewLine 21 | Console.Write "Feel free to visit https://www.github.com/Benderx2/R3X for more information!" 22 | Console.NewLine 23 | Console.Write "Dispatching a counting job..." 24 | System.DispatchJob randomjob 25 | Console.NewLine 26 | Console.Write "Wait as long as you want... then press a key" 27 | Console.NewLine 28 | Console.WaitKey 29 | Console.Write "Counted " 30 | loadr R0, result 31 | lodsd 32 | pushr R1 33 | Console.WriteInt 34 | Console.WaitKey 35 | System.Quit 0 36 | endfunction main 37 | function randomjob 38 | loadr R20, 678910 39 | ; Note: This thread has it's own registers, stack, and call stack! 40 | loadr R0, result 41 | loadr R1, 0 42 | .loop1: 43 | incr R1 44 | stosd 45 | ; A system.quit here will close ONLY this thread, while a system.quit in our init function will close all jobs. 46 | jmp .loop1; 47 | endfunction randomjob 48 | 49 | function loadsimplelib 50 | ; We first load the library and then store it's ID, returned by SYSCALL_LOADDYNAMIC 51 | push libname 52 | syscall SYSCALL_LOADDYNAMIC 53 | popr R1 54 | loadr R0, simplelibid 55 | stosd 56 | pop 57 | popr R1 58 | popr R0 59 | ret 60 | endfunction loadsimplelib 61 | 62 | function callsimplelib 63 | ; Now we load the ID, push it, and then push the function name, and use the calldynamic instruction 64 | ; to call the function in simplelib.il. 65 | pushr R0 66 | pushr R1 67 | loadr R0, simplelibid 68 | lodsd 69 | pushr R1 70 | pushstring "test_func" 71 | calldynamic 72 | pop 73 | pop 74 | popr R1 75 | popr R0 76 | ret 77 | endfunction callsimplelib 78 | } 79 | .data { 80 | libname: db "simplelib.ro", 0 81 | } 82 | .bss { 83 | string: times 256 rb 0 84 | simplelibid: rd 0 85 | result: rd 0 86 | } 87 | end 88 | -------------------------------------------------------------------------------- /src/programs/rfc.il: -------------------------------------------------------------------------------- 1 | include 'libR3X/libR3X.pkg' 2 | .text { 3 | function main 4 | loadr64 R0, 0xFFFFFFFFFFFFFFFE 5 | addr R0, 1 6 | pushr R0 7 | syscall SYSCALL_PUTI 8 | pop 9 | Console.WaitKey 10 | exit 11 | endfunction main 12 | } 13 | end 14 | -------------------------------------------------------------------------------- /src/programs/simplelib.il: -------------------------------------------------------------------------------- 1 | include 'libR3X/dynR3X.pkg' 2 | ; NOTE: CODE MUST BE RELOCATABLE! 3 | ; USE RELOCATABLE BRANCH INSTRUCTIONS! 4 | ; jmpl, jzl, jll, jel, jgl, and calll. (an 'l' suffix) 5 | ; Also, add the value of R20 (which is guarenteed to be the load address of the library) 6 | ; before addressing local addresses. 7 | .text { 8 | function test_func 9 | ; Dynamically loaded libraries must 10 | ; be relocatable that is, position independent. 11 | loadr R1, str01 12 | ; Load address of library is in R20 13 | addrr R1, R20 14 | pushr R1 15 | syscall SYSCALL_PUTS 16 | pop 17 | loadr R0, word_data 18 | addrr R0, R20 19 | lodsw 20 | pushr R1 21 | syscall SYSCALL_PUTI 22 | pop 23 | push 0xA 24 | syscall SYSCALL_PUTCH 25 | pop 26 | ret 27 | endfunction test_func 28 | } 29 | .data { 30 | str01: db 'Hello from dynamic library! I can read stuff from addresses! word_data=', 0 31 | word_data: dw 212 32 | dd 0xFFF3FFFF 33 | } 34 | end 35 | -------------------------------------------------------------------------------- /src/programs/stack.il: -------------------------------------------------------------------------------- 1 | ; This example showcases how to use the stack in r3x VM. 2 | ; Since the stack is not modifiable directly by the program, 3 | ; it is supposed to use a set of instructions to change it. 4 | ; This example will showcase the following instructions: 5 | ; push 6 | ; pushr 7 | ; pop 8 | ; popr 9 | ; popn 10 | ; loads 11 | ; stores 12 | ; loadsr 13 | ; storesr 14 | ; You should expect the following output 15 | ; 35 65 35 12345 5 49 12 100 16 | include 'libR3X/libR3X.pkg' 17 | .text { 18 | function main 19 | ; The push instruction pushes an integer (which could be anything pointer, number, pointer to structure..) 20 | push 35 21 | ; Let's print what we just pushed! 22 | syscall SYSCALL_PUTI 23 | ; Let's load a register with immediate 24 | loadr R8, 65 25 | ; Let's push the value of the register 26 | pushr R8 ; 65 will be pushed to stack! 27 | ; Let's print it. 28 | syscall SYSCALL_PUTI 29 | ; Let's clean up the stack, that is remove the stuff we just pushed 30 | pop ; Removes 65 from stack 31 | ; Since 65 is removed, what remains is 35 on stack, let's pop it into R8 32 | popr R8 33 | ; Let's push R8 and see what value it contains 34 | pushr R8 35 | syscall SYSCALL_PUTI 36 | pop ; Pop out and destroy value 37 | ; Let push 6 things to stack 38 | push 12345 39 | push 1 40 | push 2 41 | push 3 42 | push 4 43 | push 5 44 | ; Let's pop off 5 of em 45 | popn 5 46 | ; The number left on stack would be 12345 47 | ; Let's print it! 48 | syscall SYSCALL_PUTI 49 | ; Pop it off 50 | pop 51 | ; Let's load something from stack offset 52 | push 5 53 | push 7 54 | push 9 55 | ; What if we wanted to push the value we pushed 3rd last? 56 | loads 3 ; Pushes 5, remember we pushed 5 3rd last? 57 | syscall SYSCALL_PUTI 58 | popn 4 ; Pop off 4 things pushed to stack 59 | ; Let's store something to stack 60 | push 7 61 | push 3 62 | push 12 63 | ; What if we wanted to change the '7' to '49' we pushed to stack? 64 | push 49 65 | stores 4 ; Remember, position of 7 changed when we pushed 49 to stack by 1. 66 | popn 3 ; Pop off the last 3 elements of stack, which makes 49 on top 67 | ; Let's print it! 68 | syscall SYSCALL_PUTI 69 | ; Let's use storesr and loadsr, they are same as loads/stores but they use registers instead of immediates 70 | push 15 71 | push 12 72 | ; Change 15 to 12 73 | loadr R15, 2 ; Load 15's stack offset 74 | storesr R15 75 | pop 76 | ; Now 12 is on top of stack since we changed 15 to 12 77 | ; Print it! 78 | syscall SYSCALL_PUTI 79 | pop 80 | push 100 81 | push 150 82 | push 200 83 | ; Let's load 100 from stack, through loadsr. 84 | loadr R15, 3 ; Load 100's stack offset 85 | loadsr R15 86 | ; Now 100 is pushed to stack 87 | syscall SYSCALL_PUTI 88 | popn 4 ; Clean up stack 89 | ; Let's wait for user input 90 | Console.WaitKey 91 | ; And exit! 92 | System.Quit 0 93 | endfunction main 94 | } 95 | ; REMEMBER TO PUT THIS AT THE END OF EVERY MAIN MODULE! 96 | end 97 | -------------------------------------------------------------------------------- /src/programs/stream.il: -------------------------------------------------------------------------------- 1 | include 'libR3X/libR3X.pkg' 2 | .text { 3 | function main 4 | pushstring "./myfile.txt" 5 | syscall SYSCALL_OPENSTREAM 6 | push mybuf 7 | push 255 8 | syscall SYSCALL_READSTREAM 9 | pop 10 | pop 11 | pop 12 | syscall SYSCALL_CLOSESTREAM 13 | Console.Write "Read 255 bytes of ./myfile.txt: (Press a key to quit)" 14 | Console.NewLine 15 | Console.WritePointer mybuf 16 | Console.WaitKey 17 | exit 18 | endfunction main 19 | } 20 | .data { 21 | mybuf: times 256 db 0 22 | } 23 | end 24 | -------------------------------------------------------------------------------- /src/programs/symbols.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Benderx2/R3X/f45118d3d9b5c462dc45121742d6e514b1bfe3ed/src/programs/symbols.exe -------------------------------------------------------------------------------- /src/programs/symbols.il: -------------------------------------------------------------------------------- 1 | include 'libR3X/libR3X.pkg' 2 | .text { 3 | function main 4 | System.Quit 0 5 | endfunction main 6 | 7 | function itoa 8 | dd 0 9 | endfunction itoa 10 | 11 | function atoi 12 | dd 0 13 | endfunction atoi 14 | 15 | function puts 16 | dd 0 17 | endfunction puts 18 | } 19 | end 20 | -------------------------------------------------------------------------------- /src/rfc.c: -------------------------------------------------------------------------------- 1 | /** 2 | * This file contains the interpreter for the RFC (REX Fast computing) extension. 3 | * Executed when an RFC Prefix (0x8C) is encountered. 4 | **/ 5 | #include 6 | #include 7 | #include 8 | 9 | static inline uint64_t read_64bit_int_from_instruction_pointer(r3x_cpu_t* CPU); 10 | 11 | uint64_t rfc_emulate_instruction(r3x_cpu_t* CPU) { 12 | switch(CPU->Memory[CPU->InstructionPointer]) { 13 | case RFC_LOADR64: 14 | CPU->InstructionPointer++; 15 | if(CPU->Memory[CPU->InstructionPointer] > MAX_NUMBER_OF_REGISTERS) { 16 | handle_cpu_exception(CPU, CPU_EXCEPTION_INVALIDOPCODE); 17 | break; 18 | } else { 19 | CPU->Regs[CPU->Memory[CPU->InstructionPointer]] = read_64bit_int_from_instruction_pointer(CPU); 20 | CPU->InstructionPointer += CPU_INCREMENT_WITH_64_OP; 21 | } 22 | break; 23 | case RFC_PUSH64: 24 | Stack.Push(CPU->Stack, read_64bit_int_from_instruction_pointer(CPU)); 25 | CPU->InstructionPointer += CPU_INCREMENT_WITH_64_OP; 26 | break; 27 | default: 28 | handle_cpu_exception(CPU, CPU_EXCEPTION_INVALIDOPCODE); 29 | break; 30 | } 31 | return 0; 32 | } 33 | static inline uint64_t read_64bit_int_from_instruction_pointer(r3x_cpu_t* CPU) { 34 | return BIG_ENDIAN_INT(*((uint64_t*)(&CPU->Memory[CPU->InstructionPointer+1]))); 35 | } 36 | -------------------------------------------------------------------------------- /src/stream.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 Benderx2, 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | * Neither the name of R3X nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | /** R3X Stream manager **/ 31 | #include 32 | FILE** streams = NULL; 33 | unsigned int number_of_total_streams = 16; 34 | unsigned int used_streams = 0; 35 | void init_stream_manager(void) { 36 | streams = nt_malloc(sizeof(FILE*)*number_of_total_streams); 37 | } 38 | unsigned int stream_open(char* name) { 39 | if(used_streams >= number_of_total_streams) { 40 | streams = nt_realloc(streams, sizeof(FILE*)*(number_of_total_streams+16)); 41 | number_of_total_streams += 16; 42 | } 43 | for(unsigned int i = 0; i < number_of_total_streams; i++) 44 | { 45 | if(streams[i] == NULL) { 46 | streams[i] = fopen(name, "r+b"); 47 | if(streams[i] == NULL) { 48 | printf("Unable to open stream... %s\n", name); 49 | return 0xFFFFFFFF; 50 | } 51 | else { 52 | printf("Opened stream for writing, handle: %u, name: %s\n", i, name); 53 | used_streams++; 54 | return i; 55 | } 56 | } 57 | } 58 | printf("Unable to find free stream! Please report this bug!\n"); 59 | exit(EXIT_FAILURE); 60 | } 61 | void stream_close(unsigned int handle) { 62 | if(handle >= number_of_total_streams) { 63 | return; 64 | } else { 65 | if(streams[handle] != NULL) { 66 | fclose(streams[handle]); 67 | streams[handle] = NULL; 68 | used_streams--; 69 | } 70 | } 71 | } 72 | void stream_seek(unsigned int handle, long int off, int origin) { 73 | if(handle >= number_of_total_streams) { 74 | return; 75 | } else { 76 | if(streams[handle] != NULL) { 77 | switch(origin) { 78 | case 0: 79 | fseek(streams[handle], off, SEEK_SET); 80 | case 1: 81 | fseek(streams[handle], off, SEEK_CUR); 82 | case 2: 83 | fseek(streams[handle], off, SEEK_END); 84 | default: 85 | return; 86 | } 87 | } 88 | } 89 | } 90 | unsigned int stream_tell(unsigned int handle) { 91 | if(handle >= number_of_total_streams) { 92 | return 0xFFFFFFFF; 93 | } else { 94 | if(streams[handle] != NULL) { 95 | return (unsigned int)ftell(streams[handle]); 96 | } 97 | } 98 | return 0xFFFFFFFF; 99 | } 100 | unsigned int stream_read(void* ptr, unsigned int handle, size_t count) { 101 | if(handle >= number_of_total_streams) { 102 | return 0xFFFFFFFF; 103 | } else { 104 | if(streams[handle] != NULL){ 105 | return fread(ptr, sizeof(uint8_t), count, streams[handle]); 106 | } 107 | } 108 | return 0xFFFFFFFF; 109 | } 110 | unsigned int stream_write(void* ptr, unsigned int handle, size_t count) { 111 | if(handle >= number_of_total_streams) { 112 | return 0xFFFFFFFF; 113 | } else { 114 | if(streams[handle] != NULL){ 115 | return fwrite((const void*)ptr, sizeof(uint8_t), count, streams[handle]); 116 | } 117 | } 118 | return 0xFFFFFFFF; 119 | } 120 | --------------------------------------------------------------------------------