diff options
-rw-r--r-- | asmmon.c | 17 | ||||
-rw-r--r-- | disasm.c | 46 | ||||
-rw-r--r-- | lexer.c | 4 | ||||
-rw-r--r-- | programs/lexer.s | 231 | ||||
-rw-r--r-- | programs/sub-suite/lexer.s | 413 | ||||
-rw-r--r-- | programs/sub-suite/subasm.s (renamed from programs/subasm.s) | 7 | ||||
-rw-r--r-- | programs/sub-suite/subeditor.s (renamed from programs/subeditor.s) | 0 | ||||
-rw-r--r-- | programs/sub-suite/utils.s (renamed from programs/utils.s) | 1 | ||||
-rw-r--r-- | sux.c | 2 |
9 files changed, 461 insertions, 260 deletions
@@ -127,8 +127,7 @@ void list(uint16_t start, uint16_t end, uint8_t all, uint8_t ln, uint8_t addr, u char ch[6]; do { - token *tok = s->tok; - token *t; + token *t = s->tok; uint8_t am = 0xFF; uint8_t rs = 0xFF; if (dbg) { @@ -151,8 +150,7 @@ void list(uint16_t start, uint16_t end, uint8_t all, uint8_t ln, uint8_t addr, u tabs--; } } - for (; tok && tok->id != TOK_COMMENT && tok >= t; tok = tok->next) { - t = tok; + while (t && t->id != TOK_COMMENT) { switch (t->id) { case TOK_DIR : printf(".%s ", dir_t[t->type] ); break; case TOK_OPCODE: @@ -163,8 +161,8 @@ void list(uint16_t start, uint16_t end, uint8_t all, uint8_t ln, uint8_t addr, u j = 0; printf("%s", mne_lower); am = t->type; - t = t->next; - if (t && t->id == TOK_RS) { + if (t->next && t->next->id == TOK_RS) { + t = t->next; rs = t->type; printf("%s", rs_t[t->type]); } @@ -217,8 +215,10 @@ void list(uint16_t start, uint16_t end, uint8_t all, uint8_t ln, uint8_t addr, u default : ch[j++] = t->byte; break; case '\n': ch[j++] = '\\'; ch[j++] = 'n' ; break; case '\r': ch[j++] = '\\'; ch[j++] = 'r' ; break; + case '\t': ch[j++] = '\\'; ch[j++] = 't' ; break; case '\b': ch[j++] = '\\'; ch[j++] = 'b' ; break; case '\\': ch[j++] = '\\'; ch[j++] = '\\'; break; + case '\0': ch[j++] = '\\'; ch[j++] = '0'; break; case '\'': ch[j++] = '\\'; ch[j++] = '\''; break; case '\"': ch[j++] = '\\'; ch[j++] = '\"'; break; } @@ -245,6 +245,7 @@ void list(uint16_t start, uint16_t end, uint8_t all, uint8_t ln, uint8_t addr, u } break; } + t = t->next; } if (am != 0xFF) { if (fall) { @@ -285,8 +286,8 @@ void list(uint16_t start, uint16_t end, uint8_t all, uint8_t ln, uint8_t addr, u tabs--; } } - if (tok && tok->id == TOK_COMMENT) { - printf(";%s", (tok->str) ? tok->str : ""); + if (t && t->id == TOK_COMMENT) { + printf(";%s", (t->str) ? t->str : ""); } puts(""); s = s->next; @@ -74,7 +74,7 @@ void disasm(struct sux *cpu, uint64_t *operands, uint8_t lines, uint8_t opcode, uint8_t iscursor = 0; union reg ptr; uint32_t adr; - wmove(scr, 30, 0); + /*wmove(scr, 30, 0); wclrtoeol(scr); adr = 0x25; ptr.u8[0] = addr[adr+0]; ptr.u8[1] = addr[adr+1]; @@ -99,7 +99,7 @@ void disasm(struct sux *cpu, uint64_t *operands, uint8_t lines, uint8_t opcode, ptr.u8[2] = addr[adr+2]; ptr.u8[3] = addr[adr+3]; ptr.u8[4] = addr[adr+4]; ptr.u8[5] = addr[adr+5]; ptr.u8[6] = addr[adr+6]; ptr.u8[7] = addr[adr+7]; - wprintw(scr, ", idx0: $%04"PRIX64, ptr.u64); + wprintw(scr, ", idx0: $%04"PRIX64, ptr.u64);*/ if (address == CTRL_ADDR || addr[STEP_ADDR]) { mvwprintw(scr, 29, 0, "address: $%04"PRIX64", scr_row: %02u, scr_col: %02u, scr_str: %02u, scr_end: %02u\r", address, addr[0], addr[1], addr[0x22], addr[0x23]); adr = 0x30000; @@ -108,13 +108,15 @@ void disasm(struct sux *cpu, uint64_t *operands, uint8_t lines, uint8_t opcode, for (uint8_t i = 0; i < 16; i++) { wprintw(scr, "%02X", addr[adr+i]); } - mvwprintw(scr, ln++, 0, "buffer:\r"); + mvwprintw(scr, ln++, 0, "buffer: "); wmove(scr, ln++, 0); - for (uint8_t i = 0; i < 10; i++) { - line_idx = (i << 6) + (i << 4); + uint8_t maxrow = 10; + int line_offset = (addr[0]-(maxrow-1) >= 0) ? addr[0]-(maxrow-1) : 0; + for (uint8_t i = 0; i < maxrow; i++) { + line_idx = (i+addr[0x22]+line_offset << 6) + (i+addr[0x22]+line_offset << 4); for (uint8_t j = 0; j < 0x50; j++) { wprintw(scr, "%02X", addr[tmpad+j+line_idx]); - if ((addr[0]+addr[0x22]) == i && addr[1] == j) { + if ((addr[0] == i+line_offset) && addr[1] == j) { iscursor=1; getyx(scr,row, col); wmove(scr, ln++, 0); @@ -133,19 +135,27 @@ void disasm(struct sux *cpu, uint64_t *operands, uint8_t lines, uint8_t opcode, wmove(scr, ln++, 0); } } - /*if (address == 0x4000 || tmpaddr == 0x4000 || addr[STEP_ADDR]) { - ln = 46; - tmpad = 0x4000; - line_idx = 0; - mvwprintw(scr, ln++, 0, "cmd_buf:"); - for (uint8_t i = 0; i < 5; i++) { - wmove(scr, ln++, 0); - line_idx = (i << 4)+(i << 6); - for (uint8_t j = 0; j < 0x50; j++) { - wprintw(scr, "%02X", addr[tmpad+j+line_idx]); - } - wprintw(scr, ", i: %02X", i); + /* + wmove(scr, 47, 0); + wclrtoeol(scr); + wprintw(scr, "a: $%02X,", addr[0x0A]); + wprintw(scr, " b: $%02X,", addr[0x0B]); + wprintw(scr, " c: $%02X,", addr[0x0C]); + wprintw(scr, " d: $%02X,", addr[0x0D]); + wprintw(scr, " e: $%02X,", addr[0x0E]); + wprintw(scr, " f: $%02X", addr[0x0F]); + tmpad = 0x33000; + line_idx = 0; + wprintw(scr, "cmd_buf:"); + for (uint8_t i = 0; i < 1; i++) { + wmove(scr, ln++, 0); + wclrtoeol(scr); + line_idx = (i << 4)+(i << 6); + for (uint8_t j = 0; j < 0x50; j++) { + wprintw(scr, "%02X", addr[tmpad+j+line_idx]); } + wprintw(scr, ", i: %02X", i); }*/ + } } @@ -361,7 +361,8 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) { break; case PTOK_SQUOTE: i++; - k = j; + k = 0; + j = 0; while (isdelm(str[i], dbg) != 8 || isesc) { isesc = (str[i] == '\\' && str[i-1] != '\\'); lexeme[j++] = str[i++]; @@ -373,6 +374,7 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) { switch (lexeme[++k]) { case 'n' : ch = '\n'; break; case 'r' : ch = '\r'; break; + case 't' : ch = '\t'; break; case 'b' : ch = '\b'; break; case '\'': ch = '\''; break; case '\"': ch = '\"'; break; diff --git a/programs/lexer.s b/programs/lexer.s deleted file mode 100644 index cd5bb54..0000000 --- a/programs/lexer.s +++ /dev/null @@ -1,231 +0,0 @@ -; Lexer, and supporting routines for SuBAsm. - -; Enums. - -; Directives. -DIR_ORG = 0 ; Origin. -DIR_BYTE = 1 ; Byte = 8 bits. -DIR_WORD = 2 ; Word = 16 bits. -DIR_DWORD = 3 ; Dword = 32 bits. -DIR_QWORD = 4 ; Qword = 64 bits. -DIR_INCL = 5 ; Include. - -; Tokens. -TOK_DIR = 0 ; Directive. -TOK_LOCAL = 1 ; Local syobol. -TOK_LABEL = 2 ; Label. -TOK_SYM = 3 ; Symbol. -TOK_EXPR = 4 ; Expression. -TOK_CSV = 5 ; Comma separated value. -TOK_STR = 6 ; String. -TOK_CHAR = 7 ; Character. -TOK_IND = 8 ; Indirect addressing. -TOK_IMM = 9 ; Immediate data. -TOK_MNE = 10 ; Opcode/Mnemonic. -TOK_RS = 11 ; Register size prefix. -TOK_COMM = 12 ; Comment. -TOK_HEX = 13 ; Hex value. -TOK_DEC = 14 ; Decimal value. -TOK_BIN = 15 ; Binary value. -TOK_INCL = 16 ; Include file. - -; Pre-Tokens. -PTOK_DOT = 0 ; . -PTOK_AT = 1 ; @ -PTOK_COLON = 2 ; : -PTOK_EQU = 3 ; = -PTOK_PLUS = 4 ; + -PTOK_MINUS = 5 ; - -PTOK_GT = 6 ; > -PTOK_LT = 7 ; < -PTOK_LBRAK = 8 ; ( -PTOK_RBRAK = 9 ; ) -PTOK_COMMA = 10 ; , -PTOK_X = 11 ; x -PTOK_Y = 12 ; y -PTOK_DQUOT = 13 ; " -PTOK_SQUOT = 14 ; ' -PTOK_HASH = 15 ; # -PTOK_SCOLN = 16 ; ; -PTOK_DOLR = 17 ; $ -PTOK_PRCNT = 18 ; % -PTOK_NUM = 19 ; 0-9 -PTOK_ALPH = 20 ; a-z A-Z -PTOK_OTHR = 21 ; Everything else. - -; Expressions. -EXPR_PLUS = 0 ; Plus. -EXPR_MINUS = 1 ; Minus. -EXPR_LOW = 2 ; Lower half of address. -EXPR_HIGH = 3 ; Upper half of address. -EXPR_NONE = 4 ; No expression. - - -; Data. -.org lexer_data -; Jump table for parsing pre-tokens. -swtab: - .word ptok_dot ; PTOK_DOT - .word ptok_at ; PTOK_AT - .word ptok_col ; PTOK_COLON - .word ptok_equ ; PTOK_EQU - .word ptok_plus ; PTOK_PLUS - .word ptok_min ; PTOK_MINUS - .word ptok_gt ; PTOK_GT - .word ptok_lt ; PTOK_LT - .word ptok_lbrk ; PTOK_LBRAK - .word ptok_rbrk ; PTOK_RBRAK - .word ptok_com ; PTOK_COMMA - .word ptok_xr ; PTOK_X - .word ptok_yr ; PTOK_Y - .word ptok_dqu ; PTOK_DQUOT - .word ptok_squ ; PTOK_SQUOT - .word ptok_hash ; PTOK_HASH - .word ptok_scol ; PTOK_SCOLN - .word ptok_dolr ; PTOK_DOLR - .word ptok_prcn ; PTOK_PRCNT - .word ptok_num ; PTOK_NUM - .word ptok_alph ; PTOK_ALPH - .word ptok_othr ; PTOK_OTHR - -; Data entry point for utility subroutines. -util_data: - - -; Program code. -.org lexer -lex: - ldx #0 ; Reset X. - txa ; Reset A. - phy #2 ; Preserve the screen buffer index. - txy ; Reset Y. - sty.q idx0 ; Clear the first index. - sty.q idx1 ; Clear the second index. - sty.q idx2 ; Clear the third index. -; lda (ptr), y ; Get a character from the line. -; pha #1 ; Preserve the character. -; jsr isdigit ; Is this character a digit? -; pla #1 ; Get the character back. -@getline: - lda #2 ; Get the third byte, of the line table address. - lsl #$10 ; Shift it by 2 bytes. - ldb #1 ; Set the second pointer - lda.w ltok ; to the last line. - jsr set_ptr ; - lda.w (ptr2) ; Get the next line. - jsr set_ptr ; Set the second pointer to the next line. - sta.w ctok ; Make it the current line. - and #0 ; Reset A. -@loop: - ldy.w idx0 ; Get the string index. - lda (ptr), y ; Get a character from the line. - jsr isdelm ; Get the delimiter. - cmp #1 ; Are we at the end of the line? - beq @end ; Yes, so we're done. -@spaces: - ldy.w idx0 ; Get the string index. - inc.w idx0 ; Increment the string index. - lda (ptr), y ; Get a character from the line. - pha #1 ; Preserve the character. - jsr isdelm ; Get the delimiter. - and #$10 ; Is this character, a space, or tab? - pla #1 ; Get the character back. - beq @isstart ; No, so check for the start of the line. - cmp #' ' ; Is this character, a space? - beq @incs ; Yes, so increment the starting space count. - cmp #'\t' ; No, but is it a tab? - beq @inct ; Yes, so increment the starting tab count. - jmp @spaces ; No, so keep looping. -@incs: - inc idx1 ; Increment the space count. - jmp @spaces ; Keep looping. -@inct: - inc idx1+1 ; Increment the tab count. - jmp @spaces ; Keep looping. -@isstart: - pha #2 ; Preserve the character. - lda.w idx1 ; Was there any whitespace? - pla #2 ; Get the character back. - beq @switch ; No, so start lexing. - cpb #1 ; Yes, and are we at the start of the line? - bne @switch ; No, so start lexing. -@whtspace: - ldy #2 ; Yes, so set the line index to the starting whitespace counters. - lda.w idx1 ; Get both indecies. - sta.w (ptr2), y ; Save them in the line. - and #0 ; Reset A. - sta.w idx1 ; Reset the second index. - deb ; Set the isstart flag to false. -@switch: - jsr get_ptok ; Get the pre-token. - jsr parse_ptok ; Parse the pre-token. - beq @end ; We got to the end of the string. - jmp @loop ; Keep looping. -@end: - ply #2 ; Get the screen buffer index back. - rts ; End of lex. - -parse_ptok: - pha #1 ; Preserve the pre-token. - ldb #2 ; Set the third pointer - lda.w #swtab ; to the start of the jump table. - jsr set_ptr ; - and #0 ; Reset A. - pla #1 ; Get the pre-token back. - phy #2 ; Preserve Y. - lsl #1 ; Multiply the pre-token by two, to get the jump index. - tay ; Get the index of the jump table. - lda.w (ptr3), y ; Get the address to jump to. - jsr set_ptr ; Set the third pointer to the case address. - and #0 ; Reset A. - tab ; Reset B. - ply #2 ; Get Y back. - jmp (ptr3) ; Jump to the case label. -ptok_dot: - rts ; End of parse_ptok. -ptok_at: - rts ; End of parse_ptok. -ptok_col: - rts ; End of parse_ptok. -ptok_equ: - rts ; End of parse_ptok. -ptok_plus: - rts ; End of parse_ptok. -ptok_min: - rts ; End of parse_ptok. -ptok_gt: - rts ; End of parse_ptok. -ptok_lt: - rts ; End of parse_ptok. -ptok_lbrk: - rts ; End of parse_ptok. -ptok_rbrk: - rts ; End of parse_ptok. -ptok_com: - rts ; End of parse_ptok. -ptok_xr: - rts ; End of parse_ptok. -ptok_yr: - rts ; End of parse_ptok. -ptok_dqu: - rts ; End of parse_ptok. -ptok_squ: - rts ; End of parse_ptok. -ptok_hash: - rts ; End of parse_ptok. -ptok_scol: - rts ; End of parse_ptok. -ptok_dolr: - rts ; End of parse_ptok. -ptok_prcn: - rts ; End of parse_ptok. -ptok_num: - rts ; End of parse_ptok. -ptok_alph: - rts ; End of parse_ptok. -ptok_othr: - rts ; End of parse_ptok. - - -; Entry point for utility subroutines. -utils: diff --git a/programs/sub-suite/lexer.s b/programs/sub-suite/lexer.s new file mode 100644 index 0000000..315bee4 --- /dev/null +++ b/programs/sub-suite/lexer.s @@ -0,0 +1,413 @@ +; Lexer, and supporting routines for SuBAsm. + +; Enums. + +; Directives. +DIR_ORG = 0 ; Origin. +DIR_BYTE = 1 ; Byte = 8 bits. +DIR_WORD = 2 ; Word = 16 bits. +DIR_DWORD = 3 ; Dword = 32 bits. +DIR_QWORD = 4 ; Qword = 64 bits. +DIR_INCL = 5 ; Include. + +; Tokens. +TOK_DIR = 0 ; Directive. +TOK_LOCAL = 1 ; Local syobol. +TOK_LABEL = 2 ; Label. +TOK_SYM = 3 ; Symbol. +TOK_EXPR = 4 ; Expression. +TOK_CSV = 5 ; Comma separated value. +TOK_STR = 6 ; String. +TOK_CHAR = 7 ; Character. +TOK_IND = 8 ; Indirect addressing. +TOK_IMM = 9 ; Immediate data. +TOK_MNE = 10 ; Opcode/Mnemonic. +TOK_RS = 11 ; Register size prefix. +TOK_COMM = 12 ; Comment. +TOK_HEX = 13 ; Hex value. +TOK_DEC = 14 ; Decimal value. +TOK_BIN = 15 ; Binary value. +TOK_INCL = 16 ; Include file. + +; Pre-Tokens. +PTOK_DOT = 0 ; . +PTOK_AT = 1 ; @ +PTOK_COLON = 2 ; : +PTOK_EQU = 3 ; = +PTOK_PLUS = 4 ; + +PTOK_MINUS = 5 ; - +PTOK_GT = 6 ; > +PTOK_LT = 7 ; < +PTOK_LBRAK = 8 ; ( +PTOK_RBRAK = 9 ; ) +PTOK_COMMA = 10 ; , +PTOK_X = 11 ; x +PTOK_Y = 12 ; y +PTOK_DQUOT = 13 ; " +PTOK_SQUOT = 14 ; ' +PTOK_HASH = 15 ; # +PTOK_SCOLN = 16 ; ; +PTOK_DOLR = 17 ; $ +PTOK_PRCNT = 18 ; % +PTOK_NUM = 19 ; 0-9 +PTOK_ALPH = 20 ; a-z A-Z +PTOK_OTHR = 21 ; Everything else. + +; Expressions. +EXPR_PLUS = 0 ; Plus. +EXPR_MINUS = 1 ; Minus. +EXPR_LOW = 2 ; Lower half of address. +EXPR_HIGH = 3 ; Upper half of address. +EXPR_NONE = 4 ; No expression. + + +; Data. +.org lexer_data +; Jump table for parsing pre-tokens. +swtab: + .word ptok_dot ; PTOK_DOT + .word ptok_at ; PTOK_AT + .word ptok_col ; PTOK_COLON + .word ptok_equ ; PTOK_EQU + .word ptok_plus ; PTOK_PLUS + .word ptok_min ; PTOK_MINUS + .word ptok_gt ; PTOK_GT + .word ptok_lt ; PTOK_LT + .word ptok_lbrk ; PTOK_LBRAK + .word ptok_rbrk ; PTOK_RBRAK + .word ptok_com ; PTOK_COMMA + .word ptok_xr ; PTOK_X + .word ptok_yr ; PTOK_Y + .word ptok_dqu ; PTOK_DQUOT + .word ptok_squ ; PTOK_SQUOT + .word ptok_hash ; PTOK_HASH + .word ptok_scol ; PTOK_SCOLN + .word ptok_dolr ; PTOK_DOLR + .word ptok_prcn ; PTOK_PRCNT + .word ptok_num ; PTOK_NUM + .word ptok_alph ; PTOK_ALPH + .word ptok_othr ; PTOK_OTHR + +; Data entry point for utility subroutines. +util_data: + + +; Program code. +.org lexer +lex: + ldx #0 ; Reset X. + txa ; Reset A. + phy #2 ; Preserve the screen buffer index. + txy ; Reset Y. + sty.q idx0 ; Clear the first index. + sty.q idx1 ; Clear the second index. + sty.q idx2 ; Clear the third index. + sty b ; Clear the isop flag. +; lda (ptr), y ; Get a character from the line. +; pha #1 ; Preserve the character. +; jsr isdigit ; Is this character a digit? +; pla #1 ; Get the character back. +@getline: + lda #2 ; Get the third byte, of the line table address. + lsl #$10 ; Shift it by 2 bytes. + ldb #1 ; Set the second pointer + lda.w ltok ; to the last line. + jsr set_ptr ; + lda.w (ptr2) ; Get the next line. + jsr set_ptr ; Set the second pointer to the next line. + sta.w ctok ; Make it the current line. + and #0 ; Reset A. +@loop: + ldy.w idx0 ; Get the string index. + lda (ptr), y ; Get a character from the line. + jsr isdelm ; Get the delimiter. + cmp #1 ; Are we at the end of the line? + beq @end ; Yes, so we're done. +@spaces: + ldy.w idx0 ; Get the string index. + lda (ptr), y ; Get a character from the line. + pha #1 ; Preserve the character. + jsr isdelm ; Get the delimiter. + and #$10 ; Is this character, a space, or tab? + pla #1 ; Get the character back. + beq @isstart ; No, so check for the start of the line. + inc.w idx0 ; Yes, so increment the string index. + cmp #' ' ; Is this character, a space? + beq @incs ; Yes, so increment the starting space count. + cmp #'\t' ; No, but is it a tab? + beq @inct ; Yes, so increment the starting tab count. + jmp @spaces ; No, so Keep looping. +@incs: + inc idx1 ; Increment the space count. + jmp @spaces ; Keep looping. +@inct: + inc idx1+1 ; Increment the tab count. + jmp @spaces ; Keep looping. +@isstart: + pha #2 ; Preserve the character. + lda.w idx1 ; Was there any whitespace? + pla #2 ; Get the character back. + beq @switch ; No, so start lexing. + cpb #1 ; Yes, and are we at the start of the line? + bne @switch ; No, so start lexing. +@whtspace: + ldy #2 ; Yes, so set the line index to the starting whitespace counters. + lda.w idx1 ; Get both indecies. + sta.w (ptr2), y ; Save them in the line. + and #0 ; Reset A. + sta.w idx1 ; Reset the second index. + deb ; Set the isstart flag to false. +@switch: + ldy.w idx0 ; Get the string index. + lda (ptr), y ; Get the character. + jsr get_ptok ; Get the pre-token. + jsr parse_ptok ; Parse the pre-token. +; beq @end ; We got to the end of the string. + jmp @loop ; Keep looping. +@end: + ply #2 ; Get the screen buffer index back. + rts ; End of lex. + + +parse_ptok: + pha #1 ; Preserve the pre-token. + ldb #2 ; Set the third pointer + lda.w #swtab ; to the start of the jump table. + jsr set_ptr ; + and #0 ; Reset A. + pla #1 ; Get the pre-token back. + phy #2 ; Preserve Y. + lsl #1 ; Multiply the pre-token by two, to get the jump index. + tay ; Get the index of the jump table. + lda.w (ptr3), y ; Get the address to jump to. + jsr set_ptr ; Set the third pointer to the case address. + and #0 ; Reset A. + tab ; Reset B. + ply #2 ; Get Y back. + jmp (ptr3) ; Jump to the case label. +ptok_dot: + ldb #1 ; Make init_lex increment the string index. + jsr init_lex ; Initialize the lexeme buffer for copying. + ldb #$11 ; Set the delimiter comparison value to whitespace. + jsr delmcpy ; Copy the string, to the lexeme buffer, until delimiter. +@isop: + lda b ; Has the isop flag been set? + beq @dir ; No, so check for a directive. +@rs: + lda #TOK_RS ; Yes, so set the lexeme type to TOK_RS. + sta lex_type ; + ldy.w idx1 ; Get the lexeme index. + dey ; Decrement the lexeme index. + lda (ptr3), y ; Get the suffix character. + jsr get_rs ; Get the register size. + jmp @end ; We are done. +@dir: + lda #TOK_DIR ; Set the lexeme type to TOK_DIR. + sta lex_type ; + ldb #0 ; Make the lexeme buffer, the first pointer. + stb.q idx1 ; Reset the first index. + jsr set_lexptr ; Set up the lexeme buffer. +@dir_loop: + lda.w #dir ; Get pointer to the start of the directive table. + clc ; Prepare for a non carrying add. + adc.w idx2 ; Offset the pointer, by the length of the previous string. + pha #8 ; Preserve the directive string pointer. + jsr strcasecmp ; Is the lexeme buffer, the same as the directive string? + pla #8 ; Get the directive string pointer back. + beq @found ; Yes, so create a new token. + ldb idx1 ; No, so Get the directive ID. + cpb #6 ; Have we reached the end of the directive table? + beq @end ; Yes, so we're done. + inc idx1 ; No, so increment the directive ID. +@getlen: + jsr strlen ; Get the string's length. + inx ; Add one to the length. + txa ; Place it in the accumulator. + clc ; Prepare for a non carrying add. + adc.w idx2 ; Add the string offset to the current length + sta.w idx2 ; Save the offset in the third index. + jmp @dir_loop ; Keep looping. +@found: + nop ; +@end: + jsr make_tok ; Create the token. + jsr set_cmdbuf ; Set the first pointer to the command buffer. + rts ; End of parse_ptok. +ptok_at: + rts ; End of parse_ptok. +ptok_col: + rts ; End of parse_ptok. +ptok_equ: + rts ; End of parse_ptok. +ptok_plus: + rts ; End of parse_ptok. +ptok_min: + rts ; End of parse_ptok. +ptok_gt: + rts ; End of parse_ptok. +ptok_lt: + rts ; End of parse_ptok. +ptok_lbrk: + rts ; End of parse_ptok. +ptok_rbrk: + rts ; End of parse_ptok. +ptok_com: + rts ; End of parse_ptok. +ptok_xr: + rts ; End of parse_ptok. +ptok_yr: + rts ; End of parse_ptok. +ptok_dqu: + ldb #1 ; Make init_lex increment the string index. + jsr init_lex ; Initialize the lexeme buffer for copying. + ldb #4 ; Set the delimiter comparison value to a double quote. + jsr delmcpy ; Copy the string, to the lexeme buffer, until delimiter. +@term: + rts ; End of parse_ptok. +ptok_squ: + rts ; End of parse_ptok. +ptok_hash: + rts ; End of parse_ptok. +ptok_scol: + rts ; End of parse_ptok. +ptok_dolr: + rts ; End of parse_ptok. +ptok_prcn: + rts ; End of parse_ptok. +ptok_num: + rts ; End of parse_ptok. +ptok_alph: + ldb #0 ; Do not let init_lex increment the string index. + jsr init_lex ; Initialize the lexeme buffer for copying. + ldb #1 ; Stop at any possible delimiter, except whitespace. + tba ; Use isdelm2 for the comparison. + jsr delmcpy ; Copy the string, to the lexeme buffer, until delimiter. + lda #0 ; Reset A. + sta b ; Clear the isop flag. +@isop: + ldb #0 ; Make the lexeme buffer, the first pointer. + stb.q idx1 ; Reset the first index. + jsr set_lexptr ; Set up the lexeme buffer. +@isop_loop: + lda.w #mne ; Get pointer to the start of the instruction table. + clc ; Prepare for a non carrying add. + adc.w idx2 ; Offset the pointer, by the length of the previous string. + jsr strcasecmp ; Is the lexeme buffer, the same as the mnemonic string? + beq @found ; Yes, so create a new token. + ldb idx1 ; No, so Get the instruction ID. + cpb #OPNUM-1 ; Have we reached the end of the instruction table? + beq @end ; Yes, so we're done. + inc idx1 ; No, so increment the instruction ID. +@offset: + lda #13 ; Get the base size of the instruction table. + clc ; Prepare for a non carrying multiply. + mul idx1 ; Multiply the base offset, by the instruction ID. + sta.w idx2 ; Save the offset in the third index. + jmp @isop_loop ; Keep looping. +@found: + lda #TOK_MNE ; Set the lexeme type to TOK_MNE. + sta lex_type ; + inc b ; Set the isop flag. +@end: + jsr make_tok ; Create the token. + jsr set_cmdbuf ; Set the first pointer to the command buffer. + rts ; End of parse_ptok. +ptok_othr: + rts ; End of parse_ptok. + + +set_lexptr: + lda.d #lexeme ; Set the pointer to the lexeme buffer. + jsr set_ptr ; + and #0 ; Reset A. + tab ; Reset B. + sta.q idx1 ; Reset the second index. + rts ; End of set_lexptr. + + +set_cmdbuf: + ldb #0 ; Set the first pointer + lda.d #cmd_buf ; to the command buffer. + jsr set_ptr ; + and #0 ; Reset A. + tab ; Reset B. + rts ; End of set_cmdbuf. + + +init_lex: + cpb #0 ; Do we need to increment the string index? + beq @init ; No, so skip that step. +@inc_str: + inc.w idx0 ; Yes, so increment the string index. +@init: + lda #0 ; Reset A. + sta.q idx1 ; Reset the second index + sta.q idx2 ; Reset the third index + ldb #2 ; Make the lexeme buffer, the third pointer. + jsr set_lexptr ; Set up the lexeme buffer. + rts ; End of init_lex. + + +delmcpy: + sta a ; Save the delimiter check flag. + stb c ; Save the delimiter comparison value. +@loop: + ldy.w idx0 ; Get the string index. + lda (ptr), y ; Get a character from the line. + pha #1 ; Preserve the character. + lda a ; Are we calling isdelm2? + pla #1 ; Get the character back. + bne @isdelm2 ; Yes, so use isdelm2. + jsr isdelm ; No, so get the delimiter value from isdelm. + and c ; Are both delimiter values, the same? + bne @end ; Yes, so we're done. + jmp @copy ; No, so start copying the character. +@isdelm2: + jsr isdelm2 ; Get the delimiter value from isdelm2. + cmp c ; Are both delimiter values, the same? + beq @end ; Yes, so we're done. +@copy: + lda (ptr), y ; Get a character from the line. + ldy.w idx1 ; Get the lexeme index. + sta (ptr3), y ; Copy the character to the lexeme buffer. + inc.w idx0 ; Increment the string index. + inc.w idx1 ; Increment the lexeme index. + jmp @loop ; Keep looping. +@end: + lda #0 ; Terminate the lexeme buffer. + sta (ptr3), y ; + rts ; End of delmcpy. + + +get_rs: + phb #1 ; Preserve B. + ldb #0 ; Set the isop flag to false. + plb #1 ; Get B back. + jsr tolower ; Convert the character to lowercase. + cmp #'w' ; Is it .w? + beq @r1 ; Yes, so return 1. + cmp #'d' ; No, but was it .d? + beq @r2 ; Yes, so return 2. + cmp #'q' ; No, but was it .d? + beq @r3 ; Yes, so return 3. +@r0: + lda #0 ; Return 0. + rts ; End of get_rs. +@r1: + lda #1 ; Return 1. + rts ; End of get_rs. +@r2: + lda #2 ; Return 2. + rts ; End of get_rs. +@r3: + lda #3 ; Return 3. + rts ; End of get_rs. + + +make_tok: + nop ; +@end: + rts ; End of make_tok. + +; Entry point for utility subroutines. +utils: diff --git a/programs/subasm.s b/programs/sub-suite/subasm.s index 3c8e767..9c6c3f0 100644 --- a/programs/subasm.s +++ b/programs/sub-suite/subasm.s @@ -4,6 +4,7 @@ ; by mr b0nk 500 <b0nk@b0nk.xyz> MAX_SYM = $800 ; Max symbol size. +OPNUM = 88 ; Instruction count. .include "lexer.s" .include "utils.s" @@ -141,7 +142,7 @@ mne: .byte "ASR", $F1, $F6, $FF, $FF, $FF, $FF, $FF, $F4, $FF .byte "ARB", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $F2 .byte "STX", $FF, $FD, $FF, $D9, $A5, $FF, $FF, $FC, $FF - .byte "INB" $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FE + .byte "INB", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FE ; Command subroutine table. cmd_srt: @@ -194,6 +195,10 @@ ctok: ltok: .word 0 +; Lexeme type. +lex_type: + .byte 0 + ; Lexeme string. lexeme: diff --git a/programs/subeditor.s b/programs/sub-suite/subeditor.s index 1768d62..1768d62 100644 --- a/programs/subeditor.s +++ b/programs/sub-suite/subeditor.s diff --git a/programs/utils.s b/programs/sub-suite/utils.s index d8d4aa2..580e4da 100644 --- a/programs/utils.s +++ b/programs/sub-suite/utils.s @@ -337,6 +337,7 @@ isdelm2: isdelm: ldx #0 ; Reset X. + stx a ; Reset the shift value. @loop: ldb dtab, x ; Get the compare value. beq @other ; We hit the end of the table, so check for the others. @@ -579,7 +579,7 @@ int main(int argc, char **argv) { } } else { #if debug - subdbg = !strcmp(argv[1], "programs/subeditor.s"); + subdbg = !strcmp(argv[1], "programs/sub-suite/subeditor.s"); #endif if (asmmon(argv[1]) == 2) { return 0; |