Some optimizations
This commit is contained in:
@@ -1,18 +1,19 @@
|
|||||||
/* Build with: cc -Os -o nrj nrj.c */
|
/*
|
||||||
|
* NRJ (NOR and Reference Jump) OISC ANSI C emulator by Luxferre
|
||||||
|
* Public domain
|
||||||
|
* Build with: cc -Os -o nrj nrj.c
|
||||||
|
*/
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
#ifndef NRJBITS
|
|
||||||
#define NRJBITS 16
|
|
||||||
#endif
|
|
||||||
#ifndef NRJWORD
|
#ifndef NRJWORD
|
||||||
#define NRJWORD unsigned short
|
#define NRJWORD unsigned short
|
||||||
#endif
|
#endif
|
||||||
#define NRJSIZE (1 << NRJBITS)
|
#define NRJWSIZE (sizeof(NRJWORD))
|
||||||
|
#define NRJSIZE (1 << NRJWSIZE)
|
||||||
#define MAXADDR ((NRJWORD) (NRJSIZE - 1))
|
#define MAXADDR ((NRJWORD) (NRJSIZE - 1))
|
||||||
#define NRJWSIZE sizeof(NRJWORD)
|
|
||||||
|
|
||||||
int kbhit() {
|
int kbhit() {
|
||||||
struct timeval tv = { 0L, 0L };
|
struct timeval tv = { 0L, 0L };
|
||||||
@@ -22,26 +23,18 @@ int kbhit() {
|
|||||||
return select(1, &fds, NULL, NULL, &tv) > 0;
|
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;
|
struct termios tty_opts_backup, tty_opts_raw;
|
||||||
void restore_term() {
|
void restore_term() {
|
||||||
tcsetattr(STDIN_FILENO, TCSANOW, &tty_opts_backup);
|
tcsetattr(STDIN_FILENO, TCSANOW, &tty_opts_backup);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nrj_in(NRJWORD *ctxid, NRJWORD *val) {
|
void nrj_in(NRJWORD *ctxid, NRJWORD *val) {
|
||||||
int x;
|
unsigned char c;
|
||||||
if(*ctxid == (NRJWORD) 0) { /* for now, only emulate standard context id */
|
if(*ctxid == (NRJWORD) 0) { /* for now, only emulate standard context id */
|
||||||
*val = (NRJWORD) 0;
|
*val = (NRJWORD) 0;
|
||||||
if(kbhit()) {
|
if(kbhit()) {
|
||||||
x = getch();
|
if(read(0, &c, 1) > -1)
|
||||||
if(x > -1)
|
*val = (NRJWORD) c;
|
||||||
*val = (NRJWORD) x;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -51,26 +44,7 @@ void nrj_out(NRJWORD *ctxid, NRJWORD *val) {
|
|||||||
putchar((unsigned char) *val);
|
putchar((unsigned char) *val);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nrj_load(NRJWORD* m, char *fname) {
|
void nrj_run(NRJWORD *mem, NRJWORD pc) { /* 0 - input, 1 - output, 2 - I/O context, 3 - program start */
|
||||||
FILE *prog = fopen(fname, "rb");
|
|
||||||
if(prog) {
|
|
||||||
fseek(prog, 0, SEEK_END);
|
|
||||||
int flen = ftell(prog);
|
|
||||||
fseek(prog, 0, SEEK_SET);
|
|
||||||
fread(m, NRJWSIZE, (flen/NRJWSIZE) & MAXADDR, 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 mem[NRJSIZE], pc = (NRJWORD) 3; /* 0 - input, 1 - output, 2 - I/O context, 3 - program start */
|
|
||||||
nrj_load(mem, program);
|
|
||||||
while(pc != MAXADDR) {
|
while(pc != MAXADDR) {
|
||||||
if(mem[0]) nrj_in(&mem[2], &mem[mem[0]]);
|
if(mem[0]) nrj_in(&mem[2], &mem[mem[0]]);
|
||||||
mem[mem[pc]] = (~(mem[mem[pc]] | mem[mem[pc+1]])) & MAXADDR;
|
mem[mem[pc]] = (~(mem[mem[pc]] | mem[mem[pc+1]])) & MAXADDR;
|
||||||
@@ -84,11 +58,29 @@ void nrj_run(char *program) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
tcgetattr(STDIN_FILENO, &tty_opts_backup);
|
if(argc > 1) {
|
||||||
atexit(&restore_term);
|
NRJWORD mem[NRJSIZE];
|
||||||
if(argc > 1)
|
FILE *prog = fopen(argv[1], "rb");
|
||||||
nrj_run(argv[1]);
|
if(prog) {
|
||||||
else {
|
/* load the program */
|
||||||
|
fseek(prog, 0, SEEK_END);
|
||||||
|
int flen = ftell(prog);
|
||||||
|
fseek(prog, 0, SEEK_SET);
|
||||||
|
fread(mem, NRJWSIZE, (flen/NRJWSIZE) & MAXADDR, prog);
|
||||||
|
fclose(prog);
|
||||||
|
/* prepare the terminal */
|
||||||
|
tcgetattr(STDIN_FILENO, &tty_opts_backup);
|
||||||
|
atexit(&restore_term);
|
||||||
|
cfmakeraw(&tty_opts_raw);
|
||||||
|
tcsetattr(STDIN_FILENO, TCSANOW, &tty_opts_raw);
|
||||||
|
/* start the engine */
|
||||||
|
nrj_run(mem, 3);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("NRJ16: could not open the input file %s\r\n", argv[1]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
puts("NRJ16: no binary specified\r");
|
puts("NRJ16: no binary specified\r");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user