Files
nrj-oisc/nrj.c
T

97 lines
2.2 KiB
C
Raw Normal View History

2022-08-19 21:55:12 +03:00
/* 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)
2022-08-22 08:20:51 +03:00
#define MAXADDR ((NRJWORD) (NRJSIZE - 1))
2022-08-19 21:55:12 +03:00
#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);
}
2022-08-22 08:20:51 +03:00
void nrj_load(NRJWORD* m, char *fname) {
2022-08-19 21:55:12 +03:00
FILE *prog = fopen(fname, "rb");
if(prog) {
fseek(prog, 0, SEEK_END);
int flen = ftell(prog);
fseek(prog, 0, SEEK_SET);
2022-08-22 08:20:51 +03:00
fread(m, NRJWSIZE, (flen/NRJWSIZE) & MAXADDR, prog);
2022-08-19 21:55:12 +03:00
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) {
2022-08-22 08:20:51 +03:00
NRJWORD mem[NRJSIZE], pc = (NRJWORD) 3; /* 0 - input, 1 - output, 2 - I/O context, 3 - program start */
nrj_load(mem, program);
while(pc != MAXADDR) {
2022-08-21 20:10:03 +03:00
if(mem[0]) nrj_in(&mem[2], &mem[mem[0]]);
2022-08-22 08:20:51 +03:00
mem[mem[pc]] = (~(mem[mem[pc]] | mem[mem[pc+1]])) & MAXADDR;
2022-08-21 20:10:03 +03:00
pc = mem[mem[pc+2]];
mem[0] = (NRJWORD) 0;
if(mem[1]) {
nrj_out(&mem[2], &mem[mem[1]]);
mem[1] = (NRJWORD) 0;
2022-08-19 21:55:12 +03:00
}
}
}
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;
}