From 0b81224b6ab8cd6da45039525962c6490ed2df56 Mon Sep 17 00:00:00 2001 From: mrb0nk500 Date: Sat, 14 Dec 2019 23:58:01 -0500 Subject: We now have keyboard support!!! I also added the WAI instruction, which puts the thread that executed it, into a catatonic stat, where it can't do anything, until an interrupt occurs. I will be starting work on GFsuX next. I also might start work on SuBAsm, the Sux Bootstrapping Assembler. --- sux.c | 207 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 181 insertions(+), 26 deletions(-) (limited to 'sux.c') diff --git a/sux.c b/sux.c index 452c8fa..21ac0ca 100644 --- a/sux.c +++ b/sux.c @@ -1,24 +1,38 @@ #include "opcode.h" #include +#include #include #include #define bench 0 #define debug 0 #define IO 1 +#define en_nc 1 #if bench #include #endif #define THREADS 1 #define BENCH_INST 100000000*THREADS -#define DATA_ADDR 0xC001 +#define CTRL_ADDR 0xC000 +#define TX_ADDR 0xC001 +#define RX_ADDR 0xC002 +#define CURSES_BACKSPACE 0x7F + uint64_t clk[THREADS]; /* Per Thread Clock cycles. */ uint64_t tclk; /* Total Clock cycles. */ uint64_t inst[THREADS]; uint64_t inss; uint8_t threads_done = 0; +uint8_t kbd_rdy = 0; +uint8_t wai = 0; +uint8_t irq = 0; +#if en_nc +WINDOW *scr; +#endif pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; +pthread_mutex_t main_mutex = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t cond = PTHREAD_COND_INITIALIZER; +pthread_cond_t main_cond = PTHREAD_COND_INITIALIZER; struct suxthr { struct sux sx; uint8_t th; @@ -44,10 +58,36 @@ void *run(void *args) { char *s = malloc(2048); uint8_t lines = (6*thread)+2; uint16_t tv = 0xFF50; /* Starting address of the Thread Vectors. */ + int x = 0, y = 0; #if bench gettimeofday(&str[thread], 0); #endif while (!end) { + #if en_nc + if (wai) { + for (int8_t i = 56; i >= 0; i-=8) { + if (i) + addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread]-1 >> i; + else + addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread]-1 & 0xFF; + cpu->sp[thread]--; + } + addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->ps >> 8*thread; + cpu->sp[thread]--; + cpu->i[thread] = 1; + (cpu->i[thread]) ? (cpu->ps |= (I << 8*thread)) : (cpu->ps &= ~(I << 8*thread)); + cpu->pc[thread] = (uint64_t)addr[0xFFA0] + | (uint64_t)addr[0xFFA1] << 8 + | (uint64_t)addr[0xFFA2] << 16 + | (uint64_t)addr[0xFFA3] << 24 + | (uint64_t)addr[0xFFA4] << 32 + | (uint64_t)addr[0xFFA5] << 40 + | (uint64_t)addr[0xFFA6] << 48 + | (uint64_t)addr[0xFFA7] << 56; + wai = 0; + kbd_rdy &= (uint8_t)~(1 << thread); + } + #endif prefix = addr[cpu->pc[thread]]; if ((prefix & 0x07) == 0x07) cpu->pc[thread]++; @@ -56,16 +96,21 @@ void *run(void *args) { opcode = addr[cpu->pc[thread]]; #if debug && !bench - sprintf(s, "\033[%uH" + /*sprintf(s, "\033[%uH" "pc: 0x%08llx, a: 0x%016llx, x: 0x%016llx, y: 0x%016llx" ", sp: 0x%04lx, ps: 0x%016llx, prefix: 0x%02x, opcode: 0x%02x, thread: %u, inst: %s \r" , lines , cpu->pc[thread], cpu->a[thread], cpu->x[thread], cpu->y[thread] , cpu->sp[thread], cpu->ps, prefix, opcode, thread, opname[opcode]); - fwrite(s, sizeof(char), strlen(s), stdout); + fwrite(s, sizeof(char), strlen(s), stdout);*/ + mvwprintw(scr, lines, 0, "pc: 0x%08llx, a: 0x%016llx, x: 0x%016llx, y: 0x%016llx" + ", sp: 0x%04lx, ps: 0x%016llx, prefix: 0x%02x, opcode: 0x%02x, thread: %u, inst: %s \r" + , cpu->pc[thread], cpu->a[thread], cpu->x[thread], cpu->y[thread] + , cpu->sp[thread], cpu->ps, prefix, opcode, thread, opname[opcode]); + wrefresh(scr); lines++; - if (lines > 6*(thread+1)) - lines = (6*thread)+2; + if (lines > 24*(thread+1)) + lines = (24*thread)+2; #endif uint8_t rs = (prefix & 0x30) >> 4; @@ -716,14 +761,38 @@ void *run(void *args) { value = cpu->y[thread]; if (opcode == STX || opcode == 0x7E || opcode == 0x9E) value = cpu->x[thread]; - addr[address] = value & 0xFF; #if IO - if (address == DATA_ADDR) { + if (address == TX_ADDR) { + /*if (addr[address] == '\r') { + waddch(context->screen, '\n'); + }*/ + #if en_nc + if (addr[address] == CURSES_BACKSPACE || addr[address] == '\b') { + if (x > 0) { + x--; + wmove(scr, y, x); + } + wdelch(scr); + wrefresh(scr); + } else { + wmove(scr, y, x); + waddch(scr, addr[address]); + wrefresh(scr); + if (addr[address] == '\n') { + x = 0; + y+=1; + } else { + x+=1; + } + /*putchar(addr[address]);*/ + } + #else if (addr[address] == '\b') putchar('\b'); else putchar(addr[address]); + #endif } #endif if (regsize >= 2) @@ -1207,7 +1276,7 @@ void *run(void *args) { if ((value >> i) & 1) cpu->pc[i+1] = cpu->pc[0]+(i+1); break; - case RTI: /* ReTurn from Interupt routine. */ + case RTI: /* ReTurn from Interrupt routine. */ cpu->sp[thread]++; cpu->ps = addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << 8*thread; for (uint8_t i = 0; i < 64; i+=8) { @@ -1365,12 +1434,7 @@ void *run(void *args) { addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->ps >> 8*thread; cpu->sp[thread]--; cpu->i[thread] = 1; - (cpu->c[thread]) ? (cpu->ps |= (C << 8*thread)) : (cpu->ps &= ~(C << 8*thread)); - (cpu->z[thread]) ? (cpu->ps |= (Z << 8*thread)) : (cpu->ps &= ~(Z << 8*thread)); (cpu->i[thread]) ? (cpu->ps |= (I << 8*thread)) : (cpu->ps &= ~(I << 8*thread)); - (cpu->s[thread]) ? (cpu->ps |= (S << 8*thread)) : (cpu->ps &= ~(S << 8*thread)); - (cpu->v[thread]) ? (cpu->ps |= (V << 8*thread)) : (cpu->ps &= ~(V << 8*thread)); - (cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread)); cpu->pc[thread] = (uint64_t)addr[0xFFE0] | (uint64_t)addr[0xFFE1] << 8 | (uint64_t)addr[0xFFE2] << 16 @@ -1380,6 +1444,15 @@ void *run(void *args) { | (uint64_t)addr[0xFFE6] << 48 | (uint64_t)addr[0xFFE7] << 56; break; + case WAI: /* WAit for Interrupt. */ + wai = 1; + pthread_mutex_lock(&main_mutex); + pthread_cond_signal(&main_cond); + pthread_mutex_unlock(&main_mutex); + pthread_mutex_lock(&mutex); + pthread_cond_wait(&cond, &mutex); + pthread_mutex_unlock(&mutex); + break; default: if(opcode != BRK) { /*printf("Cool, you inputed a non existent opcode, which means\n" @@ -1390,9 +1463,11 @@ void *run(void *args) { } ins++; #if debug && !bench - sprintf(s, "\033[%uHInstructions executed: %llu, Clock cycles: %llu\n", (6*thread)+1, ins, iclk); + /*sprintf(s, "\033[%uHInstructions executed: %llu, Clock cycles: %llu\n", (6*thread)+1, ins, iclk); fwrite(s, sizeof(char), strlen(s), stdout); - fflush(stdout); + fflush(stdout);*/ + mvwprintw(scr, (24*thread)+1, 0, "Instructions executed: %llu, Clock cycles: %llu\r", ins, iclk); + wrefresh(scr); #endif #if bench if (ins >= BENCH_INST) { @@ -1401,7 +1476,7 @@ void *run(void *args) { threads_done++; inst[thread] = ins; clk[thread] = iclk; - pthread_cond_signal(&cond); + pthread_cond_signal(&main_cond); pthread_mutex_unlock(&mutex); gettimeofday(&en[thread], 0); } @@ -1418,8 +1493,33 @@ int main(int argc, char **argv) { inss = 0; int v = 0; - if (asmmon() == 2) - return 0; + if (argc != 2) { + if (asmmon("stdin") == 2) + return 0; + } else { + if (asmmon(argv[1]) == 2) + return 0; + } + sprintf(tmp, "\033[2J\033[H"); + fwrite(tmp, sizeof(char), strlen(tmp), stdout); + fflush(stdout); + #if en_nc + if(!scr) + scr = initscr(); + nodelay(stdscr, 0); + crmode(); + noecho(); + nl(); + curs_set(0); + werase(scr); + scrollok(scr, 1); + wrefresh(scr); + start_color(); + use_default_colors(); + init_pair(1, COLOR_WHITE, -1); + attron(COLOR_PAIR(1) | A_BOLD); + wmove(scr, 0, 0); + #endif for (int i = 0; i < THREADS; i++) { thr[i].sx.sp[i] = 0xFFFF; thr[i].sx.stk_st[i] = i+1; @@ -1450,25 +1550,80 @@ int main(int argc, char **argv) { } thr[i].th = i; } + pthread_t therads[THREADS]; + int result; for (int i = 0; i < THREADS; i++) { inst[i] = 0; } - pthread_t therads[THREADS]; - int result; - sprintf(tmp, "\033[2J\033[H"); - fwrite(tmp, sizeof(char), strlen(tmp), stdout); - fflush(stdout); for (int i = 0; i < THREADS; i++) { result = pthread_create(&therads[i], NULL, run, &thr[i]); assert(!result); } - pthread_mutex_lock(&mutex); + int c = 0; while (threads_done < THREADS) { - pthread_cond_wait(&cond, &mutex); + int x, y, i = 0; + #if !bench + if ((c != EOF && c !=-1)) { + pthread_mutex_lock(&main_mutex); + pthread_cond_wait(&main_cond, &main_mutex); + pthread_mutex_unlock(&main_mutex); + c = 0; + } + #if en_nc + getyx(scr, y, x); + attroff(A_REVERSE); + attron(A_BLINK); + wprintw(scr, "_"); + attroff(A_BLINK); + wmove(scr, y, x); + wrefresh(scr); + + c = wgetch(scr); + + /*wmove(scr, 0, getmaxx(scr) - 1); + attron(A_REVERSE); + wprintw(scr, "!"); + attroff(A_REVERSE); + wmove(scr, y, x); + wrefresh(scr);*/ + switch (c) { + case ERR: + kbd_rdy = 0; + wmove(scr, getmaxy(scr)-1, 0); + wprintw(scr, "c: %i, x: %i, y: %i, i: %i.", c, x, y, i++); + wmove(scr, y, x); + wrefresh(scr); + break; + default: + addr[RX_ADDR] = (uint8_t)c; + kbd_rdy = 1 << 0; + pthread_mutex_lock(&mutex); + pthread_cond_broadcast(&cond); + pthread_mutex_unlock(&mutex); + break; + } + #else + c = getchar(); + if (c != EOF) { + sprintf(tmp, "\033[24Hc: %i\r", c); + fwrite(tmp, sizeof(char), strlen(tmp), stdout); + fflush(stdout); + kbd_rdy = 1 << 0; + pthread_mutex_lock(&mutex); + pthread_cond_signal(&cond); + pthread_mutex_unlock(&mutex); + } + #endif + #else + + #endif } - pthread_mutex_unlock(&mutex); #if bench if (threads_done == THREADS) { + #if en_nc + scr = NULL; + endwin(); + #endif double tm_sec, tm_usec, tm[THREADS], ttm; double clkspd; double mhz; -- cgit v1.2.3-13-gbd6f