From a9860417f53216a2f3b0b490afec46ab5db70181 Mon Sep 17 00:00:00 2001 From: mrb0nk500 Date: Wed, 12 Aug 2020 12:37:54 -0400 Subject: - Refactored the escape sequence parsing, and handling. It now uses a struct to store the escape sequence. Before it handles the escape sequence, it parses it, which includes things like getting any arguments that are supplied, and getting the mode type. - Moved the code that handles control codes to a separate function. The reason for doing this was because I wanted to make the escape sequence handling faster, but also make the code more readable at the same time. I got the idea to do this from st, a terminal emulator created by the suckless.org project. --- disasm.c | 1 + io.c | 328 +++++++++++++++++++++++------------------ programs/sub-suite/subeditor.s | 5 +- sux.c | 5 +- sux.h | 2 +- 5 files changed, 193 insertions(+), 148 deletions(-) diff --git a/disasm.c b/disasm.c index 8997baf..57cef04 100644 --- a/disasm.c +++ b/disasm.c @@ -146,6 +146,7 @@ void disasm(struct sux *cpu, uint64_t *operands, uint8_t lines, uint8_t opcode, wprintw(scr, "TX_ADDR: $%02X, RX_ADDR: $%02X", addr[TX_ADDR], addr[RX_ADDR]); } wmove(scr, 29, 0); + wclrtoeol(scr); wprintw(scr, "address: $%04"PRIX64, address); if (subdbg) { uint8_t ln = 33; diff --git a/io.c b/io.c index ef491f5..37116df 100644 --- a/io.c +++ b/io.c @@ -1,11 +1,25 @@ #include "sux.h" +#define BETWEEN(x, a, b) ((a) <= (x) && (x) <= (b)) +#define DEFAULT(a, b) (a) = (a) ? (a) : (b) + char *key = NULL; uint8_t key_idx = 0; -uint8_t iscol; -uint8_t idx = 3; -uint8_t bcd[4]; +uint8_t esc = 0; +uint8_t iscsi = 0; + +typedef struct escape escape; + +struct escape { + char buf[128]; /* Buffer. */ + size_t len; /* Buffer length. */ + int arg[16]; /* Arguments. */ + int narg; /* Number of arguments. */ + char mode[2]; /* Mode type. */ +}; + +escape escseq; static inline char *get_keyseq(int keycode) { switch (keycode) { @@ -115,9 +129,165 @@ int get_key(WINDOW *scr) { return c; } +void parse_esc() { + char *str = escseq.buf, *nstr; + long int value; + escseq.narg = 0; -void io(uint64_t address, uint8_t rw) { + escseq.buf[escseq.len] = '\0'; + for (;str < escseq.buf + escseq.len; str++) { + nstr = NULL; + value = strtol(str, &nstr, 10); + if (nstr == str) { + value = 0; + } + if (value == LONG_MAX || value == LONG_MIN) { + value = -1; + } + escseq.arg[escseq.narg++] = value; + str = nstr; + if (*str != ';' || escseq.narg == 16) { + break; + } + } + escseq.mode[0] = *str++; + escseq.mode[1] = (str < (escseq.buf + escseq.len)) ? *str : '\0'; +} + +void handle_esc() { int x, y; + getyx(scr, y, x); + switch (escseq.mode[0]) { + case 'A': + DEFAULT(escseq.arg[0], 1); + if (y-escseq.arg[0] >= 0) { + y -= escseq.arg[0]; + #if !debug + wmove(scr, y, x); + #endif + } + break; + case 'B': + case 'e': + DEFAULT(escseq.arg[0], 1); + if (y+escseq.arg[0] <= getmaxy(scr)) { + y += escseq.arg[0]; + #if !debug + wmove(scr, y, x); + #endif + } + break; + case 'C': + case 'a': + DEFAULT(escseq.arg[0], 1); + if (x+escseq.arg[0] <= getmaxx(scr)) { + x += escseq.arg[0]; + #if !debug + wmove(scr, y, x); + #endif + } + break; + case 'D': + DEFAULT(escseq.arg[0], 1); + if (x-escseq.arg[0] >= 0) { + x -= escseq.arg[0]; + #if !debug + wmove(scr, y, x); + #endif + } + break; + case 'H': + case 'f': + DEFAULT(escseq.arg[0], 1); + DEFAULT(escseq.arg[1], 1); + #if !debug + wmove(scr, escseq.arg[0]-1, escseq.arg[1]-1); + #else + wmove(scr, 31, 0); + wclrtoeol(scr); + wprintw(scr, "escseq.arg[0]: %i, escseq.arg[1]: %i", escseq.arg[0], escseq.arg[1]); + #endif + break; + case 'S': + DEFAULT(escseq.arg[0], 1); + #if !debug + wscrl(scr, -escseq.arg[0]); + #else + #endif + break; + case 'T': + DEFAULT(escseq.arg[0], 1); + #if !debug + wscrl(scr, escseq.arg[0]); + #else + #endif + break; + } +} + +void reset_esc() { + memset(&escseq, 0, sizeof(escseq)); +} + +void handle_ctrlcode(int c) { + int x, y; + getyx(scr, y, x); + switch (c) { + 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': reset_esc(); esc = 1; break; + case '\n': + x = 0; + y+=1; + #if !debug + wmove(scr, y, x); + #endif + break; + default: + #if !debug + /*wmove(scr, y, x);*/ + waddch(scr, c); + #else + if (!subdbg && scr_col < 160) { + if (c != ' ') { + wprintw(scr, "%02X", c); + } else { + wprintw(scr, " "); + } + } + #endif + x+=1; + break; + } +} + + +void io(uint64_t address, uint8_t rw) { uint16_t scr_col = 0; /*step |= (!rw) ? (cpu->pc[thread] == CTRL_ADDR) : step;*/ switch (address) { @@ -135,7 +305,6 @@ void io(uint64_t address, uint8_t rw) { 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; @@ -148,146 +317,21 @@ void io(uint64_t address, uint8_t rw) { 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 + int c = addr[TX_ADDR]; + if (iscsi) { + escseq.buf[escseq.len++] = c; + if (BETWEEN(c, 0x40, 0x7E) || escseq.len >= sizeof(escseq.buf)-1) { 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, "x: %i, y: %i ", x, y);*/ - 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; + iscsi = 0; + parse_esc(); + handle_esc(); + } } - } 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 - /*wmove(scr, y, x);*/ - 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; + if (c == '[') { + iscsi = 1; } + } else { + handle_ctrlcode(addr[TX_ADDR]); } break; } diff --git a/programs/sub-suite/subeditor.s b/programs/sub-suite/subeditor.s index fb3f3c4..476f1cf 100644 --- a/programs/sub-suite/subeditor.s +++ b/programs/sub-suite/subeditor.s @@ -957,6 +957,8 @@ update_pos: lda #'[' ; Print '[' sta scr ; to the screen, and start the escape sequence. jsr getrow ; Start printing the row number to the screen. + lda #';' ; Print ';' + sta scr ; to the screen. jsr getcol ; Start printing the column number to the screen. lda #'H' ; Print 'H' sta scr ; to the screen. @@ -967,10 +969,9 @@ getrow: lda scr_row ; Get the cursor's y coordinate. bra bcd ; Convert it to BCD. getcol: - lda #';' ; Print ';' - sta scr ; to the screen. lda scr_col ; Get the cursor's x coordinate. bcd: + inc ; Add one to A. div #10 ; Divide A by 10. ora #'0' ; Convert it to ascii, and sta scr ; print to the screen. diff --git a/sux.c b/sux.c index 3082632..d26118d 100644 --- a/sux.c +++ b/sux.c @@ -27,7 +27,6 @@ pthread_cond_t main_cond = PTHREAD_COND_INITIALIZER; uint8_t threads_done = 0; uint8_t step = 0; -uint8_t esc = 0; uint8_t *addr; @@ -621,12 +620,12 @@ int main(int argc, char **argv) { pthread_mutex_lock(&main_mutex); pthread_cond_wait(&main_cond, &main_mutex); pthread_mutex_unlock(&main_mutex); - #if keypoll + /*#if keypoll pthread_mutex_lock(&mutex); #endif #if keypoll pthread_mutex_unlock(&mutex); - #endif + #endif*/ #else pthread_mutex_lock(&main_mutex); pthread_cond_wait(&main_cond, &main_mutex); diff --git a/sux.h b/sux.h index 75337c9..b729550 100644 --- a/sux.h +++ b/sux.h @@ -2,6 +2,7 @@ #include #include #include +#include #if bench #include @@ -27,7 +28,6 @@ extern uint8_t subdbg; static const uint64_t mem_size = 0x04000000; /* Size of address space. */ extern uint8_t step; -extern uint8_t esc; extern uint8_t end; #define setflag(flag, bit) ((flag)) ? (cpu->ps.u8[thread] |= bit) : (cpu->ps.u8[thread] &= ~bit) -- cgit v1.2.3-13-gbd6f