The two are not related in any way: that's GPL3 licensed, mine is MIT. That's a .c source, mine is a single header library. And the API is totally different too (pcm_open, pcm_set, pcm_hw_params_setup, pcm_write, versus alsa_open and alsa_write). That supports recording, mine does not. That does not support async playback, mine does.
> The fact that the subscription agreement does not allow this is exactly what we're discussing here.
There's nothing to discuss. What Red Hat is trying to do IS ILLEGAL and GPL explicitly grants the right to all their subscribers to gave RH the finger.
From GPL Section 8
"If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term."
It is obvious that the "subscription agreement which denies the right to redistribute" is a "further restriction" that GPL legally allows users to simply ignore.
Also Red Hat violating GPL is unquestionably clear from the Preamble:
"To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others."
RH asking users to surrender their rights and revoking any subscription for redistributing is clearly violating its responsibilities as demanded by the GPL.
It's even better because not only can you ignore RHEL's infringing terms, but RHEL's license to use GPL code has been terminated.
You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and *will automatically terminate your rights under this License*. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.
As I wrote, I created a bytecode which fits the compiler's code generator the most. This keeps the entire code base small, the bytecode VM simple and compilation fast. This is a self-contained solution, the compiler as well as the execution environment is part of the emulator; therefore it has to be compatible with itself only, which opens up solutions for simplicity and effectiveness.
Using real world RISC-V instructions would have introduced a lot of complexity without any real benefit. It's not that you can run the MEG-4 scripts without the API library and emulation environment anyway, so at the end of the day the actual instruction encoding doesn't matter.
BTW, if I were to use an existing instruction encoding, I probably would have chosen WebAssembly instead, because it is a lot easier to generate and lot easier to process than a real CPU's instruction set. There are many wasm VM libraries with nice licensing and easy to integrate interface and virtually no dependencies like https://github.com/kanaka/wac for example. But again, implementing wasm's poorly engineered container format and one of its incompatible ABI would just add complexity and have no real benefit.
All that being said, one could implement a new bytecode format in MEG-4 easily if they really want to. It already supports multiple instruction sets (Lua being a working PoC).
> Is there a table of contents for the manual? I’m on my phone and I only see next/previous buttons, and that’s very tedious.
On desktop, should be on the left (like readthedocs). On mobile there should be a hamburger icon. I'll look into it (the MarkDown to HTML converter is my project too, https://gitlab.com/bztsrc/gendoc so you are right to blame me if this isn't working)
Most of it is standard (like "jmp", "jz", "jnz", "call", "ret" etc.), and for the rest I've used AT&T style type-in-suffix syntax, like "mulf" (float multiplication), "ldb" (load byte), "stw" (store word) etc. It's a RISC, about 60 instructions only, so it's pretty straightforward and easy to learn I believe.
> Was it inspired by something (6502)?
Not really. I invented the instruction set as I wrote the C compiler and the optimizer. My goal was to come up with a bytecode that plays nicely with the code generator and can be processed in the VM easily and efficiently.
Full disclosure, I've used 6502 (back in the C64 era, haven't touched it for a while). On the other hand I use x86 and AArch64 Assembly regularly and I also have a fair knowledge on VM bytecode (like Lua, Java, WASM) too, so these might have unintentionally affected some of my decisions. But I don't think any of these as direct inspiration.
> I assumed you were relying on an existing compiler.
Fair assumption, actually I was. Originally I wanted to port Bellard's TCC, but run into roadblocks: no real architecture abstraction layer as it generates machine code directly, so hard to port to a new CPU. Also it would be nearly impossible to add new languages like BASIC to that compiler.
> Very impressive!
Thank you very much, but I'm not so sure. C89 is a very simple language (the best ever in terms of provided expressivity and required compiler complexity IMHO).
TL;DR Problem only starts when you try to generate efficient code for an actual real hardware (which part I elegantly avoided entirely by designing the CPU myself), and when you start adding features from the later, increasingly more insane standards (C99, C11 etc.). K&R were geniuses, most of the restrictions they designed and were put in the basic ANSI C89 language makes it extremely easy to implement a C compiler.
And a little rant about integrating a 3rd party compiler, if you don't mind: it was much harder to integrate Lua. That's because Lua is a security nightmare, poorly documented and does not work the way as the doc says. For example:
- Lua might call abort() on your host application (seriously, not joking! And "lua_pcall" dares to throw an "isn't protected" error, resulting in calling that abort. I had to come up with an ugly continuity function and "lua_resume" workaround);
- lack of parameter verification, calling functions like "lua_getinfo" might segfault without any apparent reason;
- unless patched, execution of user provided strings as system commands is allowed;
- unless patched, provides full file system access outside of the sandboxed environment;
- ...and I still couldn't figure out how to get the faulting source line from an error event (which one might think to be obvious and trivial, but it really isn't).
So yeah, integrating Lua definitely took longer than implementing my own compiler :-)
> For Lua and file system access, is that only with the standard library? If not, that would be very surprising!
If by standard library you mean Lua's io package in baselib, then the answer is yes. For example, "dofile" or "loadfile" functions will work no matter baselib is removed or not.
In a nutshell, I've removed package, coroutine, io, os modules from baselib and all functions calling fopen or fread/fwrite (like "loadfile") and replaced these with the MEG-4 API. This way you have the same functions in Lua as in C. All the rest left untouched; eg. table, string, utf8, math, etc. modules are still available as usual.
You're welcome! Spread the word if you like it ;-)
My hope is to build a nice and friendly community around it in time. Testing results, translations, contributions, PRs, more floppies are always appreciated!
- I've added transparent PCM resampling, so it's ca. 400 SLoC now. The API hasn't changed, and the feature can be turned off with a define.
- Bad project name, I've just found out that there's already another project by this name: https://github.com/psqli/nanoalsa
The two are not related in any way: that's GPL3 licensed, mine is MIT. That's a .c source, mine is a single header library. And the API is totally different too (pcm_open, pcm_set, pcm_hw_params_setup, pcm_write, versus alsa_open and alsa_write). That supports recording, mine does not. That does not support async playback, mine does.