aha
This commit is contained in:
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user