From a76977af62010a392c16010c367185e61e856ffe Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Wed, 30 Oct 2019 20:04:56 +0100 Subject: mv to docs --- docs/j1eforth/j1.c | 162 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 docs/j1eforth/j1.c (limited to 'docs/j1eforth/j1.c') diff --git a/docs/j1eforth/j1.c b/docs/j1eforth/j1.c new file mode 100644 index 0000000..926adb5 --- /dev/null +++ b/docs/j1eforth/j1.c @@ -0,0 +1,162 @@ +#include +#include +#include +#include +#include +#if defined(unix) || defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)) +#include +#include +int getch(void) { /* reads from keypress, doesn't echo */ + struct termios oldattr, newattr; + int ch; + tcgetattr( STDIN_FILENO, &oldattr ); + newattr = oldattr; + // newattr.c_iflag &= ~( ICRNL ); + newattr.c_lflag &= ~( ICANON | ECHO ); + tcsetattr( STDIN_FILENO, TCSANOW, &newattr ); + ch = getchar(); + tcsetattr( STDIN_FILENO, TCSANOW, &oldattr ); + // printf("%d\n", ch); + if(ch==0x1b) exit(0); + return ch==127 ? 8 : ch; +} +int putch(int c) { /* output character to sstdout & flush */ + int res=putchar(c); + fflush(stdout); + return res; +} +#endif +int len = 0; +static unsigned short t; +static unsigned short s; +static unsigned short d[0x20]; /* data stack */ +static unsigned short r[0x20]; /* return stack */ +static unsigned short pc; /* program counter, counts cells */ +static unsigned char dsp, rsp; /* point to top entry */ +static unsigned short* memory; /* ram */ +static int sx[4] = { 0, 1, -2, -1 }; /* 2-bit sign extension */ + +static void push(int v) // push v on the data stack +{ + dsp = 0x1f & (dsp + 1); + d[dsp] = t; + t = v; +} + +static int pop(void) // pop value from the data stack and return it +{ + int v = t; + t = d[dsp]; + dsp = 0x1f & (dsp - 1); + return v; +} + +static void execute(int entrypoint) +{ + int i = 0; + int j = 0; + int _pc, _t; + int insn = 0x4000 | entrypoint; // first insn: "call entrypoint" + do { + _pc = pc + 1; + if (insn & 0x8000) { // literal + push(insn & 0x7fff); + } else { + int target = insn & 0x1fff; + switch (insn >> 13) { + case 0: // jump + _pc = target; + break; + case 1: // conditional jump + if (pop() == 0) + _pc = target; + break; + case 2: // call + rsp = 31 & (rsp + 1); + r[rsp] = _pc << 1; + _pc = target; + break; + case 3: // alu + if (insn & 0x1000) {/* r->pc */ + _pc = r[rsp] >> 1; + } + s = d[dsp]; + switch ((insn >> 8) & 0xf) { + case 0: _t = t; break; /* noop */ + case 1: _t = s; break; /* copy */ + case 2: _t = t+s; break; /* + */ + case 3: _t = t&s; break; /* and */ + case 4: _t = t|s; break; /* or */ + case 5: _t = t^s; break; /* xor */ + case 6: _t = ~t; break; /* invert */ + case 7: _t = -(t==s); break; /* = */ + case 8: _t = -((signed short)s < (signed short)t); break; /* < */ + case 9: _t = s>>t; break; /* rshift */ + case 0xa: _t = t-1; break; /* 1- */ + case 0xb: _t = r[rsp]; break; /* r@ */ + case 0xc: switch (t) { + case 0x7001: _t = 1; break; + case 0x7000: _t = getch(); break; + default: _t = memory[t>>1]; break; + } + break; /* @ */ + case 0xd: _t = s<> 2) & 3]); /* rstack+- */ + if (insn & 0x80) /* t->s */ + d[dsp] = t; + if (insn & 0x40) /* t->r */ + r[rsp] = t; + if (insn & 0x20) /* s->[t] */ + switch (t) { + case 0x7002: rsp = 0; break; + case 0x7000: putch(s); break; + default: memory[t>>1]=s; break; /* ! */ + } + t = _t; + break; + } + } + pc = _pc; + insn = memory[pc]; +#if DEBUG + printf("%d: pc: %0.4x; sp: %0.4x\n", i, pc, t); + printf("\td:"); + for (j = 0; j < dsp; j++) { + printf(" %0.4x", d[j]); + } + printf("\n\tr:"); + for (j = 0; j < rsp; j++) { + printf(" %0.4x", r[j]); + } + printf("\n"); +#endif + i++; + } while (1); +} +/* end of cpu */ + +/* start of i/o demo */ + + +int main(int argc , char *argv[]) +{ + unsigned short m[0x4000]; /* 32kb or RAM */ + FILE *f = fopen("j1.bin", "rb"); + fread(m, 0x2000, sizeof(m[0]), f); /* 0kb - 16kb data and code */ + fclose(f); + if (argc>1) { // program name is counted as one + struct stat st; + f = fopen(argv[1], "r"); + stat(argv[1], &st); + (&m[0x2000])[0] = st.st_size; /* 16kb - 32kb memory mapped i/o */ + fread(&m[0x2001], 0x2000, sizeof(m[0]), f); + fclose(f); + } + memory = m; + execute(0x00); + return 0; +} -- cgit v1.2.3