commit 570646b8dd5c5d4834d1c4014fe1fd98dd1b3479
Author: Luxferre <lux@ferre>
Date: Fri, 19 Aug 2022 21:55:12 +0300
aha
Diffstat:
A | nrj.c | | | 100 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
1 file changed, 100 insertions(+), 0 deletions(-)
diff --git a/nrj.c b/nrj.c
@@ -0,0 +1,100 @@
+/* Build with: cc -Os -o nrj nrj.c */
+#include <stdlib.h>
+#include <stdio.h>
+#include <termios.h>
+#include <unistd.h>
+#include <sys/select.h>
+#ifndef NRJBITS
+#define NRJBITS 16
+#endif
+#ifndef NRJWORD
+#define NRJWORD unsigned short
+#endif
+#define NRJSIZE (1 << NRJBITS)
+#define NRJWSIZE sizeof(NRJWORD)
+
+int kbhit() {
+ struct timeval tv = { 0L, 0L };
+ fd_set fds;
+ FD_ZERO(&fds);
+ FD_SET(0, &fds);
+ return select(1, &fds, NULL, NULL, &tv) > 0;
+}
+
+int getch() {
+ int r;
+ unsigned char c;
+ if((r = read(0, &c, 1)) < 0) return r;
+ else return c;
+}
+
+struct termios tty_opts_backup, tty_opts_raw;
+void restore_term() {
+ tcsetattr(STDIN_FILENO, TCSANOW, &tty_opts_backup);
+}
+
+void nrj_in(NRJWORD *ctxid, NRJWORD *val) {
+ int x;
+ if(*ctxid == (NRJWORD) 0) { /* for now, only emulate standard context id */
+ *val = (NRJWORD) 0;
+ if(kbhit()) {
+ x = getch();
+ if(x > -1)
+ *val = (NRJWORD) x;
+ }
+ }
+}
+
+void nrj_out(NRJWORD *ctxid, NRJWORD *val) {
+ if(*ctxid == (NRJWORD) 0) /* for now, only emulate standard context id */
+ putchar((unsigned char) *val);
+}
+
+void nrj_load(NRJWORD* m, NRJWORD offset, char *fname) {
+ FILE *prog = fopen(fname, "rb");
+ if(prog) {
+ fseek(prog, 0, SEEK_END);
+ int flen = ftell(prog);
+ fseek(prog, 0, SEEK_SET);
+ fread(m+offset, NRJWSIZE, flen/NRJWSIZE, prog);
+ fclose(prog);
+ cfmakeraw(&tty_opts_raw);
+ tcsetattr(STDIN_FILENO, TCSANOW, &tty_opts_raw);
+ }
+ else {
+ printf("NRJ16: could not open the input file %s\r\n", fname);
+ exit(1);
+ }
+}
+
+void nrj_run(char *program) {
+ NRJWORD maxaddr = (NRJWORD) (NRJSIZE - 1), mem[NRJSIZE], a, b, c;
+ mem[0] = (NRJWORD) 4;
+ mem[1] = mem[2] = mem[3] = (NRJWORD) 0;
+ nrj_load(mem, mem[0], program);
+ while(mem[0] != maxaddr) {
+ if(mem[1]) nrj_in(&mem[3], &mem[mem[1]]);
+ a = mem[0]++;
+ b = mem[0]++;
+ c = mem[0]++;
+ mem[a] = (~(mem[a] | mem[b])) & maxaddr;
+ mem[0] = (mem[0] + mem[c]) & maxaddr;
+ mem[1] = (NRJWORD) 0;
+ if(mem[2]) {
+ nrj_out(&mem[3], &mem[mem[2]]);
+ mem[2] = (NRJWORD) 0;
+ }
+ }
+}
+
+int main(int argc, char* argv[]) {
+ tcgetattr(STDIN_FILENO, &tty_opts_backup);
+ atexit(&restore_term);
+ if(argc > 1)
+ nrj_run(argv[1]);
+ else {
+ puts("NRJ16: no binary specified\r");
+ return 1;
+ }
+ return 0;
+}