summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormrb0nk500 <b0nk@b0nk.xyz>2020-05-09 14:14:08 -0400
committermrb0nk500 <b0nk@b0nk.xyz>2020-05-09 14:14:08 -0400
commit545bb8591e8003912b6c6b494acefd74e6b3abfd (patch)
treec290a49fc4fff8f15c092a2440576f5f1627b6d1
parent11c8d71babb0210d070dd6ab12a255a5fa3159a5 (diff)
Added support for single quote marks to the emulator's
assembler. Single quote marks works in the assembler just like they do in C, except that it only supports a handful of escaped characters, like '\n', and '\r'.
-rw-r--r--asmmon.c60
-rw-r--r--asmmon.h3
-rw-r--r--lexer.c154
-rw-r--r--programs/subeditor.s65
-rw-r--r--test/lex.s13
5 files changed, 172 insertions, 123 deletions
diff --git a/asmmon.c b/asmmon.c
index 453ff3c..198254c 100644
--- a/asmmon.c
+++ b/asmmon.c
@@ -114,6 +114,8 @@ void list(struct line *l, uint16_t start, uint16_t end, uint8_t all, uint8_t ln,
uint8_t spaces;
uint8_t tabs;
char mne_lower[4];
+ char ch[6];
+
if (all) {
end = lineidx;
}
@@ -202,10 +204,28 @@ void list(struct line *l, uint16_t start, uint16_t end, uint8_t all, uint8_t ln,
}
}
+ j = 0;
+
+ if (l[i].opbase == BASE_CHAR) {
+ switch (l[i].op) {
+ default : ch[j++] = l[i].op; break;
+ case '\n': ch[j++] = '\\'; ch[j++] = 'n' ; break;
+ case '\r': ch[j++] = '\\'; ch[j++] = 'r' ; break;
+ case '\b': ch[j++] = '\\'; ch[j++] = 'b' ; break;
+ case '\\': ch[j++] = '\\'; ch[j++] = '\\'; break;
+ case '\'': ch[j++] = '\\'; ch[j++] = '\''; break;
+ case '\"': ch[j++] = '\\'; ch[j++] = '\"'; break;
+ }
+ }
+
+ ch[j] = '\0';
+ j = 0;
+
switch (l[i].opbase) {
- case BASE_HEX: printf("$%"PRIX64, l[i].op); break;
- case BASE_DEC: printf("%"PRIu64, l[i].op); break;
- case BASE_BIN: printf("%%%s", showbits(l[i].op, bitnum, dbg)); break;
+ case BASE_HEX: printf("$%"PRIX64, l[i].op); break;
+ case BASE_DEC: printf("%"PRIu64, l[i].op); break;
+ case BASE_BIN: printf("%%%s", showbits(l[i].op, bitnum, dbg)); break;
+ case BASE_CHAR: printf("\'%s\'", ch); break;
}
bitnum = 0;
opsize = 0;
@@ -226,10 +246,29 @@ void list(struct line *l, uint16_t start, uint16_t end, uint8_t all, uint8_t ln,
if (opsize) {
bitnum = bitsize[opsize-1];
}
+
+ j = 0;
+
+ if (l[i].aopbase == BASE_CHAR) {
+ switch (l[i].aop) {
+ default : ch[j++] = l[i].aop; break;
+ case '\n': ch[j++] = '\\'; ch[j++] = 'n' ; break;
+ case '\r': ch[j++] = '\\'; ch[j++] = 'r' ; break;
+ case '\b': ch[j++] = '\\'; ch[j++] = 'b' ; break;
+ case '\\': ch[j++] = '\\'; ch[j++] = '\\'; break;
+ case '\'': ch[j++] = '\\'; ch[j++] = '\''; break;
+ case '\"': ch[j++] = '\\'; ch[j++] = '\"'; break;
+ }
+ }
+
+ ch[j] = '\0';
+ j = 0;
+
switch (l[i].aopbase) {
- case BASE_HEX: printf("$%"PRIX64, l[i].aop); break;
- case BASE_DEC: printf("%"PRIu64, l[i].aop); break;
- case BASE_BIN: printf("%%%s", showbits(l[i].aop, bitnum, dbg)); break;
+ case BASE_HEX : printf("$%"PRIX64, l[i].aop); break;
+ case BASE_DEC : printf("%"PRIu64, l[i].aop); break;
+ case BASE_BIN : printf("%%%s", showbits(l[i].aop, bitnum, dbg)); break;
+ case BASE_CHAR: printf("\'%s\'", ch); break;
}
bitnum = 0;
opsize = 0;
@@ -443,14 +482,7 @@ uint64_t assemble(struct line *line, uint8_t dbg) {
}
tmpaddr += tmp;
tmp = 0;
- if (skip || flags & 0x80) {
- if (dbg) {
- printf("assemble(): The address that this line starts at is, $%"PRIX64".\n", address);
- printf("assemble(): The address that this line ends on is, $%"PRIX64".\n", tmpaddr);
- }
- continue;
- }
- if (flags == 0x108) {
+ if (skip | (flags & 0x80) | (flags == 0x108)) {
if (dbg) {
printf("assemble(): The address that this line starts at is, $%"PRIX64".\n", address);
printf("assemble(): The address that this line ends on is, $%"PRIX64".\n", tmpaddr);
diff --git a/asmmon.h b/asmmon.h
index 54b2ab7..58b4918 100644
--- a/asmmon.h
+++ b/asmmon.h
@@ -35,7 +35,8 @@ enum {
enum {
BASE_HEX,
BASE_DEC,
- BASE_BIN
+ BASE_BIN,
+ BASE_CHAR
};
static const uint8_t opcodes[OPNUM][9] = {
diff --git a/lexer.c b/lexer.c
index 5a79325..6ed6cf4 100644
--- a/lexer.c
+++ b/lexer.c
@@ -153,14 +153,9 @@ uint16_t get_comment(const char *com, uint8_t dbg) {
break;
}
}
- if (comment[i] == NULL) {
+ if (comment[i] == NULL || i == comidx) {
if (dbg) {
printf("get_comment(): oof, the index $%04X is NULL.\n", i);
- }
- return 0xFFFF;
- }
- if (i == comidx) {
- if (dbg) {
printf("get_comment(): oof, the comment \"%s\", was not found in the comment table.\n", com);
}
return 0xFFFF;
@@ -175,25 +170,17 @@ uint16_t get_string(const char *str, uint8_t dbg) {
uint16_t i = 0;
uint8_t isstr = 0;
for (; i < stridx; i++) {
- if (string[i] != NULL) {
+ if (isstr || string[i] == NULL) {
+ break;
+ } else {
if (str[0] == string[i][0]) {
isstr = !strcmp(str, string[i]);
}
- } else {
- break;
- }
- if (isstr) {
- break;
}
}
- if (string[i] == NULL) {
+ if (string[i] == NULL || i == stridx) {
if (dbg) {
printf("get_string(): oof, the index $%04X is NULL.\n", i);
- }
- return 0xFFFF;
- }
- if (i == stridx) {
- if (dbg) {
printf("get_string(): oof, the string \"%s\", was not found in the string table.\n", str);
}
return 0xFFFF;
@@ -405,12 +392,10 @@ uint64_t update_addr(struct line *ln, uint64_t address, uint8_t fixup, uint16_t
uint16_t find_line(struct line *l, uint16_t ln, uint8_t dbg) {
uint16_t i = 0;
for (; i < lineidx && l[i].linenum != ln; i++);
- if (l[i].linenum == ln) {
- if (dbg) {
+ if (dbg) {
+ if (l[i].linenum == ln) {
printf("find_line(): Found line number %u, at line index %X.\n", ln, i);
}
- }
- if (dbg) {
printf("find_line(): linenum: %u, i: %X\n", l[i].linenum, i);
}
return i;
@@ -425,15 +410,22 @@ uint64_t lex(char *str, struct line *l, uint64_t address, uint8_t dbg) {
uint16_t symid = 0;
uint16_t line = 0;
lex_type = 0xFF;
+
uint8_t k = 0;
+ uint8_t ch = 0;
uint8_t rs = 0;
- uint8_t isop = 0;
uint8_t base = 0;
+
+ uint8_t isop = 0;
int num = 0;
int isch = 0;
+ uint8_t isesc = 0;
+ uint8_t islinenum;
+
int16_t ln = -1;
+
char lnum[6];
- uint8_t islinenum;
+
uint8_t space = 0;
uint8_t tab = 0;
uint8_t isstart = 1;
@@ -505,11 +497,9 @@ uint64_t lex(char *str, struct line *l, uint64_t address, uint8_t dbg) {
lexeme[j] = '\0';
if (!isop) {
for (k = 0; k < 6; k++) {
- if (tolower(lexeme[0]) == dir_t[k][0]) {
- if (!strcasecmp(lexeme, dir_t[k])) {
- lex_type = TOK_DIR;
- break;
- }
+ if (tolower(lexeme[0]) == dir_t[k][0] && !strcasecmp(lexeme, dir_t[k])) {
+ lex_type = TOK_DIR;
+ break;
}
}
l[line].dir = k;
@@ -549,28 +539,18 @@ uint64_t lex(char *str, struct line *l, uint64_t address, uint8_t dbg) {
string[strid] = malloc(j+1);
memcpy(string[strid], lexeme, j+1);
l[line].str = strid;
- if (dbg) {
- printf("lex(): str[0x%04X]: %s\n", strid, string[strid]);
- }
stridx += (line == lineidx);
} else {
l[line].str = strid;
- if (dbg) {
- printf("lex(): str[0x%04X]: %s\n", strid, string[strid]);
- }
+ }
+ if (dbg) {
+ printf("lex(): str[0x%04X]: %s\n", strid, string[strid]);
}
if (l[line].dir == DIR_INCLUDE) {
l[line].incl = strid;
}
lex_type = TOK_STRING;
break;
- case '#':
- lexeme[j] = '#';
- lexeme[j+1] = '\0';
- lexeme[j+2] = '\0';
- l[line].am = IMM;
- lex_type = TOK_IMM;
- break;
if (str[i] == '$') {
case '$': base = 16;
} else if (str[i] == '%') {
@@ -586,10 +566,10 @@ uint64_t lex(char *str, struct line *l, uint64_t address, uint8_t dbg) {
if (l[line].cm != 0xFF) {
case TOK_PLUS :
case TOK_MINUS: l[line].aop = strtoull(lexeme, NULL, base);
- l[line].aopbase = (base & 16) ? TOK_HEX : TOK_BIN;
+ l[line].aopbase = (base & 16) ? BASE_HEX : BASE_BIN;
} else {
case TOK_SYM: l[line].op = strtoull(lexeme, NULL, base);
- l[line].opbase = (base & 16) ? TOK_HEX : TOK_BIN;
+ l[line].opbase = (base & 16) ? BASE_HEX : BASE_BIN;
}
if (lex_type == TOK_SYM) {
mksymbol(sym, l[line].op, 1, 0, 0, dbg);
@@ -604,23 +584,59 @@ uint64_t lex(char *str, struct line *l, uint64_t address, uint8_t dbg) {
lex_type = (base & 16) ? TOK_HEX : TOK_BIN;
break;
- case '+':
- lexeme[j] = '+';
- lexeme[j+1] = '\0';
- l[line].cm = 0;
- lex_type = TOK_PLUS;
- break;
- case '-':
- lexeme[j] = '-';
- lexeme[j+1] = '\0';
- l[line].cm = 1;
- lex_type = TOK_MINUS;
+ case '\'':
+ i++;
+ k = j;
+ while (str[i] != '\'' || isesc) {
+ isesc = (str[i] == '\\' && str[i-1] != '\\');
+ lexeme[j++] = str[i++];
+ }
+ isesc = 0;
+ lexeme[j] = '\0';
+ switch (lexeme[k]) {
+ case '\\':
+ switch (lexeme[++k]) {
+ case 'n' : ch = '\n'; break;
+ case 'r' : ch = '\r'; break;
+ case 'b' : ch = '\b'; break;
+ case '\'': ch = '\''; break;
+ case '\"': ch = '\"'; break;
+ case '\\': ch = '\\'; break;
+ }
+ break;
+ default: ch = lexeme[k];
+ }
+ switch (lex_type) {
+ case TOK_PLUS :
+ case TOK_MINUS:
+ l[line].aop = ch;
+ l[line].aopbase = BASE_CHAR;
+ break;
+ default:
+ l[line].op = ch;
+ l[line].opbase = BASE_CHAR;
+ break;
+ }
+ lex_type = TOK_CHAR;
break;
case '(':
- lexeme[j] = '(';
- lexeme[j+1] = '\0';
- lexeme[j+2] = '\0';
- l[line].am = IND;
+ if (str[i] == '#' || str[i] == '(') {
+ if (str[i] == '#') {
+ case '#': lex_type = TOK_IMM;
+ }
+ l[line].am = (str[i] == '#') ? IMM : IND;
+ } else {
+ case '+':
+ case '-': l[line].cm = (str[i] == '-');
+ lex_type = (str[i] == '-') ? TOK_MINUS : TOK_PLUS;
+ }
+ memset(lexeme, 0, strlen(lexeme)+1);
+ lexeme[j] = str[i];
+ if (str[i] == '=') {
+ case '=': i++;
+ l[line].issym = 1;
+ lex_type = TOK_SYM;
+ }
break;
case ')':
i++;
@@ -679,13 +695,6 @@ uint64_t lex(char *str, struct line *l, uint64_t address, uint8_t dbg) {
printf("lex(): isfixup: %u\n", isfixup);
}
break;
- case '=':
- i++;
- lexeme[j] = '=';
- lexeme[j+1] = 0;
- l[line].issym = 1;
- lex_type = TOK_SYM;
- break;
case ';':
i++;
while (str[i] != '\0' && str[i] != '\n') {
@@ -702,15 +711,12 @@ uint64_t lex(char *str, struct line *l, uint64_t address, uint8_t dbg) {
comment[comid] = malloc(j+1);
memcpy(comment[comid], lexeme, j+1);
l[line].com = comid;
- if (dbg) {
- printf("lex(): com[0x%04X]: %s\n", comid, comment[comid]);
- }
comidx += (line == lineidx);
} else {
l[line].com = comid;
- if (dbg) {
- printf("lex(): com[0x%04X]: %s\n", comid, comment[comid]);
- }
+ }
+ if (dbg) {
+ printf("lex(): com[0x%04X]: %s\n", comid, comment[comid]);
}
lex_type = TOK_COMMENT;
break;
@@ -794,10 +800,10 @@ uint64_t lex(char *str, struct line *l, uint64_t address, uint8_t dbg) {
if (l[line].cm != 0xFF) {
case TOK_PLUS :
case TOK_MINUS: l[line].aop = strtoull(lexeme, NULL, 10);
- l[line].aopbase = TOK_DEC;
+ l[line].aopbase = BASE_DEC;
} else {
case TOK_SYM: l[line].op = strtoull(lexeme, NULL, 10);
- l[line].opbase = TOK_DEC;
+ l[line].opbase = BASE_DEC;
}
if (lex_type == TOK_SYM) {
mksymbol(sym, l[line].op, 1, 0, 0, dbg);
diff --git a/programs/subeditor.s b/programs/subeditor.s
index 1842b5a..d16915d 100644
--- a/programs/subeditor.s
+++ b/programs/subeditor.s
@@ -300,7 +300,7 @@ getchar:
stb b ; Enable insert mode.
pha #1 ; Save the character.
phy #2 ; Save the cursor index.
- cmp #10 ; Was the character that was typed, a newline?
+ cmp #'\n' ; Was the character that was typed, a newline?
bne getchar_pnt ; No, so just print the character.
jsl cmd_cpy ; Yes, so start copying the line to the command buffer.
getchar_pnt:
@@ -311,7 +311,7 @@ getchar_pnt:
getchar_pt1:
jsl print_char ; No, so print the character.
lda a ; Get the return value.
- cmp #10 ; Is the return value, a newline?
+ cmp #'\n' ; Is the return value, a newline?
beq getchar_ln ; Yes, so return 0.
jmp getchar_chr ; No, so return 1.
reset_row:
@@ -449,7 +449,7 @@ print_char:
lda a ; Get back the character.
cmp #$1B ; Did the user type an escape character?
beq esc ; Yes, so go check the escape code.
- cmp #10 ; No, but did the user type a newline?
+ cmp #'\n' ; No, but did the user type a newline?
beq nl ; Yes, so handle the newline.
cmp #$C ; No, but did the user type Ctrl+L?
beq clr_scr ; Yes, so clear the screen.
@@ -457,7 +457,7 @@ print_char:
beq en_step ; Yes, so enable clock/instruction stepping.
cmp #18 ; No, but did the user type Ctrl+R?
beq dis_step ; Yes, so disable clock/instruction stepping.
- cmp #8 ; No, but did the user type a backspace?
+ cmp #'\b' ; No, but did the user type a backspace?
beq bs ; Yes, so handle the backspace.
cmp #$7F ; No, but did they type Delete?
beq bs ; Yes, so treat it as a backspace.
@@ -571,13 +571,12 @@ nl1:
cmp #maxrow ;
bcc nl_inc ;
jsl scrl_down ;
- lda #10 ;
- sta a ;
- jmp printc_end ;
+ jmp nl_end ;
nl_inc:
inc scr_row ;
jsl update_pos ;
- lda #10 ;
+nl_end:
+ lda #'\n' ;
sta a ;
jmp printc_end ;
@@ -826,14 +825,14 @@ shftesc_end:
jmp printc_end ; We are done.
isup:
- lda c ; No, so load the escape code back into the accumulator.
- cmp #$41 ; Did the user press the up arrow key?
+ lda c ; Load the escape code into the accumulator.
+ cmp #'A' ; Did the user press the up arrow key?
bne isup_done ; No, so we're done.
lda scr_row ; Yes, but is the cursor at the top of the screen?
beq isup_scrl ; Yes, so check if we need to scroll.
isup_2:
lda c ; No, so load the escape code back into the accumulator.
- cmp #$41 ; Did the user press the up arrow key?
+ cmp #'A' ; Did the user press the up arrow key?
beq up ; Yes, so move the cursor up.
jmp isup_done ; No, so we're done
isup_scrl:
@@ -846,14 +845,14 @@ isup_done:
rtl ; End of isup.
isdown:
- lda c ; No, so load the escape code back into the accumulator.
- cmp #$42 ; Did the user press the down arrow key?
+ lda c ; Load the escape code into the accumulator.
+ cmp #'B' ; Did the user press the down arrow key?
bne isdown_done ; No, so we're done.
lda scr_row ; Yes, so start checking the y coordinate of the cursor.
cmp #maxrow ; Is the cursor at the bottom of the screen?
beq isdown_scrl ; Yes, so scroll down.
lda c ; No, so load the escape code back into the accumulator.
- cmp #$42 ; Did the user press the down arrow key?
+ cmp #'B' ; Did the user press the down arrow key?
beq down ; Yes, so move the cursor down.
jmp isdown_done
isdown_scrl:
@@ -872,8 +871,8 @@ isdown_done:
rtl ; End of isdown.
isright:
- lda c ; No, so load the escape code back into the accumulator.
- cmp #$43 ; Did the user press the right arrow key?
+ lda c ; Load the escape code into the accumulator.
+ cmp #'C' ; Did the user press the right arrow key?
bne isright_dne ; No, so we're done.
lda scr_col ; Yes, so start checking the x coordinate of the cursor.
cmp #maxcol ; Is the cursor at the far right of the screen?
@@ -910,13 +909,13 @@ isright_dne:
rtl ; End of isright.
isleft:
- lda c ; Get the saved character.
- cmp #$43 ; Did the user press right?
+ lda c ; Load the escape code into the accumulator.
+ cmp #'C' ; Did the user press right?
beq isleft_done ; Yes, so we're done
lda scr_col ; No, but is the cursor at the far left of the screen?
beq isleft_wrp ; Yes, so start checking if this is a wrapped line.
lda c ; No, so load the escape code back into the accumulator.
- cmp #$44 ; Did the user press the left arrow key?
+ cmp #'D' ; Did the user press the left arrow key?
beq left ; Yes, so move the cursor left.
jmp isleft_done ; No, so we're done.
isleft_wrp:
@@ -976,7 +975,7 @@ left:
isshftup:
lda c ; Load the escape code back into the accumulator.
- cmp #$41 ; Did the user press the up arrow key?
+ cmp #'A' ; Did the user press the up arrow key?
bne shftup_done ;
lda #1 ;
sta d ;
@@ -988,7 +987,7 @@ shftup_done:
isshftdown:
lda c ; Load the escape code back into the accumulator.
- cmp #$42 ; Did the user press the down arrow key?
+ cmp #'B' ; Did the user press the down arrow key?
bne shftdn_done ;
lda #1 ;
sta d ;
@@ -1023,35 +1022,35 @@ update_pos:
tay ; Place the index into the Y register.
lda #$1B ; Print an escape character
sta scr ; to the screen.
- lda #$5B ; Print '['
+ lda #'[' ; Print '['
sta scr ; to the screen, and start the escape sequence.
jsl getrow ; Start printing the row number to the screen.
jsl getcol ; Start printing the column number to the screen.
- lda #$48 ; Print 'H'
+ lda #'H' ; Print 'H'
sta scr ; to the screen.
rtl ; End of update_pos.
getrow:
lda scr_row ; Get the cursor's y coordinate.
div #10 ; Divide A by 10.
- adc #$30 ; Convert it to ascii, and
+ adc #'0' ; Convert it to ascii, and
sta scr ; print to the screen.
tba ; Get the remainder.
- adc #$30 ; Convert it to ascii, and
+ adc #'0' ; Convert it to ascii, and
sta scr ; print to the screen.
rtl ; End of getrow.
getcol:
- lda #$3B ; Print ';'
+ lda #';' ; Print ';'
sta scr ; to the screen.
lda scr_col ; Get the cursor's x coordinate.
div #10 ; Divide A by 10.
clc
- adc #$30 ; Convert it to ascii, and
+ adc #'0' ; Convert it to ascii, and
sta scr ; print to the screen.
tba ; Get the remainder.
clc
- adc #$30 ; Convert it to ascii, and
+ adc #'0' ; Convert it to ascii, and
sta scr ; print to the screen.
rtl ; End of getrow.
@@ -1060,9 +1059,9 @@ scrl_down:
inc scr_end ; Increment the ending line of the screen.
lda #$1B ; Print an escape character
sta scr ; to the screen.
- lda #$5B ; Print '['
+ lda #'[' ; Print '['
sta scr ; to the screen, and start the escape sequence.
- lda #$54 ; Print 'T'
+ lda #'T' ; Print 'T'
sta scr ; to the screen, and end the escape sequence.
lda scr_row ; Get the cursor's line number.
pha #1 ; Save it in the stack.
@@ -1094,9 +1093,9 @@ scrl_up:
dec scr_end ;
lda #$1B ; Print an escape character
sta scr ; to the screen.
- lda #$5B ; Print '['
+ lda #'[' ; Print '['
sta scr ; to the screen, and start the escape sequence.
- lda #$53 ; Print 'S'
+ lda #'S' ; Print 'S'
sta scr ; to the screen, and end the escape sequence.
lda scr_row ;
pha #1 ;
@@ -1133,7 +1132,7 @@ rdrow_inc2:
bcs rdrow_end ;
jmp rdrow_st ;
rdrow_skip:
- lda #$20 ;
+ lda #' ' ;
sta scr ; to the screen.
jmp rdrow_inc1 ;
rdrow_end:
diff --git a/test/lex.s b/test/lex.s
index 543a3d8..037ce2b 100644
--- a/test/lex.s
+++ b/test/lex.s
@@ -1,7 +1,9 @@
; aaaaaaaaaaaaaaaaa
+
SYM = $10
SYM1 = 10
SYM2 = %00000010
+
.org $A000
; String Literals/Constants.
tok:
@@ -12,6 +14,7 @@ string:
.byte "Please, type something.\n"
string2:
.byte "You typed, "
+
.org $1000
lex:
.byte $0
@@ -33,8 +36,16 @@ reset:
sta lex, x ; same with this one
sta $1000 ; lol
lda.w #cmd_buf+8;
+ lda 'a' ; cool.
+ lda ' ' ; cool.
+ lda '\n' ; cool.
+ lda '\r' ; cool.
+ lda '\b' ; cool.
+ lda '\\' ; cool.
+ lda '\'' ; cool.
+l
a
-.org $A000
+.org $8000
v
q