#include "sux.h"
char *key = NULL;
uint8_t key_idx = 0;
uint8_t iscol;
uint8_t idx = 3;
uint8_t bcd[4];
static inline char *get_keyseq(int keycode) {
switch (keycode) {
case KEY_BACKSPACE: return "\b";
case KEY_UP : return "\x1B[A";
case KEY_DOWN : return "\x1B[B";
case KEY_RIGHT : return "\x1B[C";
case KEY_LEFT : return "\x1B[D";
case KEY_F( 1) : return "\x1BOP";
case KEY_F( 2) : return "\x1BOQ";
case KEY_F( 3) : return "\x1BOR";
case KEY_F( 4) : return "\x1BOS";
case KEY_F( 5) : return "\x1B[15~";
case KEY_F( 6) : return "\x1B[17~";
case KEY_F( 7) : return "\x1B[18~";
case KEY_F( 8) : return "\x1B[19~";
case KEY_F( 9) : return "\x1B[20~";
case KEY_F(10) : return "\x1B[21~";
case KEY_F(11) : return "\x1B[23~";
case KEY_F(12) : return "\x1B[24~";
default : return NULL;
}
}
int get_key(WINDOW *scr) {
int x, y;
int c;
int keycode = 0;
curs_set(1);
if ((key == NULL) || (key && key[key_idx] == '\0') || !kbd_rdy) {
c = wgetch(scr);
if (c == 19) {
if (kbd_rdy) {
c = wgetch(scr);
}
step = 1;
} else if (c == 0x11) {
end = 1;
}
if (kbd_rdy) {
key_idx = 0;
key = get_keyseq(c);
}
keycode = c;
}
if (kbd_rdy) {
c = (key != NULL) ? key[key_idx++] : c;
}
if (step) {
if (keycode != 19 && keycode != 18 && keycode != 0x11 && !isalnum(keycode)) {
switch (keycode) {
case KEY_F(1):
endwin();
puts("Starting asmmon()");
asmmon("stdin");
puts("Reinitializing screen.");
init_scr();
wrefresh(scr);
break;
}
#if debug && !bench
getyx(scr, y, x);
wmove(scr, getmaxy(scr)-1, 0);
wclrtoeol(scr);
wprintw(scr, "keycode: %i", keycode);
wmove(scr, y, x);
#endif
}
}
if (kbd_rdy) {
switch (c) {
case ERR:
addr[CTRL_ADDR] = 0;
break;
case '\0': break;
default:
if (kbd_rdy && c < 0x100) {
addr[CTRL_ADDR] = 1;
#if debug && !bench
wmove(scr, getmaxy(scr)-1, 0);
wclrtoeol(scr);
wprintw(scr, "c: %i ", c);
wprintw(scr, "key: ");
for (int i = 0; key && key[i] != '\0'; i++) {
wprintw(scr, "$%02X%s", key[i], (key[i+1] != '\0') ? ", " : "");
}
wmove(scr, y, x);
#endif
}
break;
}
} else {
if (step) {
step = !(c == 18);
}
}
addr[STEP_ADDR] = step;
curs_set(0);
return c;
}
void io(uint64_t address, uint8_t rw) {
int x, y;
uint16_t scr_col = 0;
switch (address) {
case STEP_ADDR: step = (!rw) ? addr[STEP_ADDR] : step; break;
case CTRL_ADDR:
if (!rw) {
break;
}
kbd_rdy = 1;
wrefresh(scr);
addr[RX_ADDR] = get_key(scr);
kbd_rdy = 0;
break;
case TX_ADDR:
if (rw) {
break;
}
getyx(scr, y, x);
#if debug
if (!subdbg) {
scr_col = (addr[TX_ADDR] != 0x0C && addr[TX_ADDR] != '\n' && scr_col < 160) ? (addr[1] << 1)-2 : 0;
wmove(scr, 28, scr_col);
}
#endif
if (esc) {
#if debug
if (!subdbg && addr[RX_ADDR] == '\n') {
wclrtoeol(scr);
}
#endif
switch (addr[TX_ADDR]) {
case 'A':
if (y > 0)
y--;
#if !debug
wmove(scr, y, x);
#endif
esc = 0;
break;
case 'B':
if (y < getmaxy(scr))
y++;
#if !debug
wmove(scr, y, x);
#endif
esc = 0;
break;
case 'C':
if (x < getmaxx(scr))
x++;
#if !debug
wmove(scr, y, x);
#endif
esc = 0;
break;
case 'D':
if (x > 0)
x--;
#if !debug
wmove(scr, y, x);
#endif
esc = 0;
break;
case 'H':
if (!bcd[2] && !bcd[3]) {
y = 0;
} else {
y = ((bcd[3]*10) + bcd[2]);
}
if (!bcd[0] && !bcd[1]) {
x = 0;
} else {
x = ((bcd[1]*10) + bcd[0]);
}
#if !debug
wmove(scr, y, x);
#else
mvwprintw(scr, 31, 0, "bcd[3-2]: {%u, %u}, bcd[1-0]: {%u, %u}", bcd[3], bcd[2], bcd[1], bcd[0]);
#endif
idx = 3;
bcd[0] = 0;
bcd[1] = 0;
bcd[2] = 0;
bcd[3] = 0;
esc = 0;
break;
case 'S':
#if !debug
wscrl(scr, -1);
#else
#endif
esc = 0;
break;
case 'T':
#if !debug
wscrl(scr, 1);
#else
#endif
esc = 0;
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
bcd[idx--] = (addr[address] - '0');
break;
default:
iscol = (addr[address] == ';');
break;
}
} else {
switch (addr[TX_ADDR]) {
case 0xC:
x=0,y=0;
#if !debug
wclear(scr);
wmove(scr, y, x);
#endif
break;
case CURSES_BACKSPACE:
case '\b':
if (x > 0) {
x--;
#if !debug
wmove(scr, y, x);
#endif
}
#if !debug
wdelch(scr);
#else
if (!subdbg) {
scr_col++;
wmove(scr, 28, scr_col--);
wdelch(scr);
wmove(scr, 28, scr_col);
wdelch(scr);
}
#endif
break;
case '\033': esc = 1; break;
case '\n':
x = 0;
y+=1;
#if !debug
wmove(scr, y, x);
#endif
break;
default:
#if !debug
waddch(scr, addr[address]);
#else
if (!subdbg && scr_col < 160) {
if (addr[address] != ' ') {
wprintw(scr, "%02X", addr[address]);
} else {
wprintw(scr, " ");
}
}
#endif
x+=1;
break;
}
}
break;
}
}