summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--disasm.c65
-rw-r--r--lexer.c33
-rw-r--r--programs/sub-suite/declare.s120
-rw-r--r--programs/sub-suite/lexer.s228
-rw-r--r--programs/sub-suite/subeditor.s37
-rw-r--r--programs/sub-suite/subsuite.s1
-rw-r--r--programs/sub-suite/utils.s99
-rw-r--r--sux.c49
-rw-r--r--sux.h68
-rw-r--r--test/asr.s16
-rw-r--r--test/fib-new.s45
-rw-r--r--test/fib.s48
-rw-r--r--test/load-store.s22
-rw-r--r--test/nop.s2
-rw-r--r--test/reg-transfer.s2
15 files changed, 565 insertions, 270 deletions
diff --git a/disasm.c b/disasm.c
index 707e237..4a39c4f 100644
--- a/disasm.c
+++ b/disasm.c
@@ -55,7 +55,7 @@ void disasm(struct sux *cpu, uint8_t lines, uint8_t opcode, uint8_t prefix, uint
for (uint8_t i = 0; i < addrsize+1; i++) {
mask.u8[i] = (i == addrsize && addrsize != 0xFF) ? 0x7F : 0xFF;
}
- value = read_value(cpu, cpu->pc, addrsize, 0, 0);
+ value = read_value(cpu, 0, cpu->pc, addrsize, 0, 0);
if ((prefix >> 6) == 1 || (prefix >> 6) == 2 || optype[opcode] == REL) {
switch (addrsize) {
case 0 : sign = ((int8_t )value < 0) ? "-" : "+"; break;
@@ -97,6 +97,7 @@ void disasm(struct sux *cpu, uint8_t lines, uint8_t opcode, uint8_t prefix, uint
int row, col;
uint8_t iscursor = 0;
union reg ptr;
+ ptr.u64 = 0;
uint32_t adr;
if (address == CTRL_ADDR || addr[STEP_ADDR]) {
adr = 0x30000;
@@ -133,38 +134,58 @@ void disasm(struct sux *cpu, uint8_t lines, uint8_t opcode, uint8_t prefix, uint
wmove(scr, ln++, 0);
}
}
+ /*wclrtoeol(scr);
+ wprintw(scr, "rega: $%02X, ", addr[0x0A]);
+ wprintw(scr, "regb: $%02X, ", addr[0x0B]);
+ wprintw(scr, "regc: $%02X, ", addr[0x0C]);
+ wprintw(scr, "regd: $%02X, ", addr[0x0D]);
+ wprintw(scr, "rege: $%02X, ", addr[0x0E]);
+ wprintw(scr, "regf: $%02X, ", addr[0x0F]);
+ wprintw(scr, "regg: $%02X", addr[0x10]);*/
+
wmove(scr, 30, 0);
wclrtoeol(scr);
+
adr = 0x25;
- ptr.u8[0] = addr[adr+0]; ptr.u8[1] = addr[adr+1];
- 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];
+ ptr.u64 = read_value(cpu, 0, adr, 7, 0, 0);
wprintw(scr, "ptr1: $%04"PRIX64, ptr.u64);
+
adr = 0x2D;
- ptr.u8[0] = addr[adr+0]; ptr.u8[1] = addr[adr+1];
- 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];
+ ptr.u64 = read_value(cpu, 0, adr, 7, 0, 0);
wprintw(scr, ", ptr2: $%04"PRIX64, ptr.u64);
+
adr = 0x35;
- ptr.u8[0] = addr[adr+0]; ptr.u8[1] = addr[adr+1];
- 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];
+ ptr.u64 = read_value(cpu, 0, adr, 7, 0, 0);
wprintw(scr, ", ptr3: $%04"PRIX64, ptr.u64);
- adr = 0x3349A;
- ptr.u8[0] = addr[adr+0]; ptr.u8[1] = addr[adr+1];
- 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];
+
+ adr = 0x02049A;
+ ptr.u64 = read_value(cpu, 0, adr, 7, 0, 0);
wprintw(scr, ", idx0: $%04"PRIX64, ptr.u64);
+
adr = 0x334BA;
- ptr.u8[0] = addr[adr+0]; ptr.u8[1] = addr[adr+1];
- 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];
+ ptr.u64 = read_value(cpu, 0, adr, 7, 0, 0);
wprintw(scr, ", valbuf: $%016"PRIX64, ptr.u64);
+
+
+ wmove(scr, 31, 0);
+ wclrtoeol(scr);
+ adr = 0x204CA;
+ ptr.u64 = read_value(cpu, 0, adr, 3, 0, 0);
+ wprintw(scr, "t_id: $%02X", ptr.u8[0]);
+ wprintw(scr, ", t_type: $%02X", ptr.u8[1]);
+ wprintw(scr, ", t_space: $%02X", ptr.u8[2]);
+ wprintw(scr, ", t_tab: $%02X", ptr.u8[3]);
+ adr += 4;
+ ptr.u64 = read_value(cpu, 0, adr, 7, 0, 0);
+ wprintw(scr, ", t_val: $%"PRIX64, ptr.u64);
+ adr += 8;
+ ptr.u64 = read_value(cpu, 0, adr, 7, 0, 0);
+ wprintw(scr, ", t_str: $%"PRIX64, ptr.u64);
+ adr += 8;
+ ptr.u64 = read_value(cpu, 0, adr, 7, 0, 0);
+ wprintw(scr, ", t_sym: $%"PRIX64, ptr.u64);
+
+
/*
wmove(scr, 47, 0);
wclrtoeol(scr);
diff --git a/lexer.c b/lexer.c
index e315155..2b7c8e7 100644
--- a/lexer.c
+++ b/lexer.c
@@ -198,7 +198,8 @@ uint64_t lex(char *str, uint64_t address, uint16_t bline, uint8_t dbg) {
lex_type = 0xFF;
uint8_t k = 0;
- uint8_t ch = 0;
+ union reg ch;
+ ch.u64 =0;
uint8_t rs = 0;
uint8_t of = 0;
uint8_t base = 0;
@@ -395,23 +396,25 @@ uint64_t lex(char *str, uint64_t address, uint16_t bline, uint8_t dbg) {
}
isesc = 0;
lexeme[j] = '\0';
- switch (lexeme[k]) {
- case '\\':
- 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;
- case '\\': ch = '\\'; break;
- }
- break;
- default: ch = lexeme[k];
+ for (j = 0; lexeme[k] != '\0' && j < 7; k++) {
+ switch (lexeme[k]) {
+ case '\\':
+ switch (lexeme[++k]) {
+ case 'n' : ch.u8[j++] = '\n'; break;
+ case 'r' : ch.u8[j++] = '\r'; break;
+ case 't' : ch.u8[j++] = '\t'; break;
+ case 'b' : ch.u8[j++] = '\b'; break;
+ case '\'': ch.u8[j++] = '\''; break;
+ case '\"': ch.u8[j++] = '\"'; break;
+ case '\\': ch.u8[j++] = '\\'; break;
+ }
+ break;
+ default: ch.u8[j++] = lexeme[k];
+ }
}
lex_type = TOK_CHAR;
l->count++;
- t = make_token(lex_type, 0, space, tab, ch, "", NULL);
+ t = make_token(lex_type, 0, space, tab, ch.u64, "", NULL);
break;
case PTOK_LBRACK:
case PTOK_HASH :
diff --git a/programs/sub-suite/declare.s b/programs/sub-suite/declare.s
index 55ccc2b..166197b 100644
--- a/programs/sub-suite/declare.s
+++ b/programs/sub-suite/declare.s
@@ -12,7 +12,7 @@ maxrow = 23 ; Screen's row count.
maxcol = 79 ; Screen's column count.
MAX_SYM = $800 ; Max symbol size.
-OPNUM = 87 ; Instruction count.
+OPNUM = 74 ; Instruction count.
; Directives.
DIR_ORG = 0 ; Origin.
@@ -34,13 +34,15 @@ 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.
+TOK_BREG = 10 ; B register.
+TOK_MNE = 11 ; Opcode/Mnemonic.
+TOK_RS = 12 ; Register size prefix.
+TOK_OF = 13 ; Offset register prefix.
+TOK_COMM = 14 ; Comment.
+TOK_HEX = 15 ; Hex value.
+TOK_DEC = 16 ; Decimal value.
+TOK_BIN = 17 ; Binary value.
+TOK_INCL = 18 ; Include file.
; Pre-Tokens.
PTOK_DOT = 0 ; .
@@ -55,19 +57,20 @@ PTOK_PIPE = 8 ; |
PTOK_LBRAK = 9 ; (
PTOK_RBRAK = 10 ; )
PTOK_COMMA = 11 ; ,
-PTOK_X = 12 ; x
-PTOK_Y = 13 ; y
-PTOK_S = 14 ; s
-PTOK_P = 15 ; p
-PTOK_DQUOT = 16 ; "
-PTOK_SQUOT = 17 ; '
-PTOK_HASH = 18 ; #
-PTOK_SCOLN = 19 ; ;
-PTOK_DOLR = 20 ; $
-PTOK_PRCNT = 21 ; %
-PTOK_NUM = 22 ; 0-9
-PTOK_ALPH = 23 ; a-z A-Z
-PTOK_OTHR = 24 ; Everything else.
+PTOK_B = 12 ; b
+PTOK_X = 13 ; x
+PTOK_Y = 14 ; y
+PTOK_S = 15 ; s
+PTOK_P = 16 ; p
+PTOK_DQUOT = 17 ; "
+PTOK_SQUOT = 18 ; '
+PTOK_HASH = 19 ; #
+PTOK_SCOLN = 20 ; ;
+PTOK_DOLR = 21 ; $
+PTOK_PRCNT = 22 ; %
+PTOK_NUM = 23 ; 0-9
+PTOK_ALPH = 24 ; a-z A-Z
+PTOK_OTHR = 25 ; Everything else.
; Expressions.
EXPR_PLUS = 0 ; Plus.
@@ -201,14 +204,50 @@ valbuf:
cpybuf:
.res 8
-; Current token line.
+; Token ID, used by make_tok.
+t_id:
+ .res 1
+
+; Token type, used by make_tok.
+t_type:
+ .res 1
+
+; Number of spaces before a token, used by make_tok.
+t_space:
+ .res 1
+
+; Number of tabs before a token, used by make_tok.
+t_tab:
+ .res 1
+
+; Token value, used by make_tok.
+t_val:
+ .res 8
+
+; Token string, used by make_tok.
+t_str:
+ .res 8
+
+; Token symbol, used by make_tok.
+t_sym:
+ .res 8
+
+; Current token.
ctok:
.res 2
-; Last token line.
+; Last token.
ltok:
.res 2
+; Current line.
+cline:
+ .res 2
+
+; Last line.
+lline:
+ .res 2
+
; Lexeme type.
lex_type:
.res 1
@@ -679,6 +718,38 @@ cmd_srt:
.word run
.word set
+; Return table used by get_ctrlidx.
+ct_rtb:
+ .byte 2
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 3
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 5
+ .byte 4
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 6
+
+; Jump table for print_char's control codes.
+ct_jtb:
+ .word printc ; Everything else (print it).
+ .word nl ; Newline.
+ .word bs ; Backspace.
+ .word clr_scr ; Ctrl+L.
+ .word en_step ; Ctrl+S.
+ .word dis_step ; Ctrl+R.
+ .word esc ; Escape.
; Jump table for parsing pre-tokens.
swtab:
@@ -694,6 +765,7 @@ swtab:
.word ptok_lbrk ; PTOK_LBRAK
.word ptok_rbrk ; PTOK_RBRAK
.word ptok_com ; PTOK_COMMA
+ .word ptok_br ; PTOK_B
.word ptok_xr ; PTOK_X
.word ptok_yr ; PTOK_Y
.word ptok_sp ; PTOK_S
@@ -715,7 +787,7 @@ hex_char:
; Compare, and return table for pre-tokens.
ptok_tab:
- .byte ".@:=+-><|(),xysp\"\'#;$%"
+ .byte ".@:=+-><|(),bxysp\"\'#;$%"
; Compare, and return table for isdelm.
dtab:
.byte "\n,\"\' \\"
diff --git a/programs/sub-suite/lexer.s b/programs/sub-suite/lexer.s
index 3a856b5..72f1db6 100644
--- a/programs/sub-suite/lexer.s
+++ b/programs/sub-suite/lexer.s
@@ -8,6 +8,10 @@ lex:
sty.q idx0 ; Clear the first index.
sty.q idx1 ; Clear the second index.
sty.q idx2 ; Clear the third index.
+ sty.d t_id ; Clear the token ID, type, space count, and tab count.
+ sty.q t_val ; Clear the token value.
+ sty.q t_str ; Clear the token string.
+ sty.q t_sym ; Clear the token symbol.
sty regb ; Clear the isop flag.
; lda (ptr), y ; Get a character from the line.
; pha ; Preserve the character.
@@ -17,11 +21,11 @@ lex:
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.
+ lda.w lline ; 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.
+ sta.w cline ; Make it the current line.
and #0 ; Reset A.
@loop:
ldy.w idx0 ; Get the string index.
@@ -36,7 +40,7 @@ lex:
jsr isdelm ; Get the delimiter.
and #$10 ; Is this character, a space, or tab?
pla ; Get the character back.
- beq @isstart ; No, so check for the start of the line.
+ beq @switch ; No, so start lexing.
inc.w idx0 ; Yes, so increment the string index.
cmp #' ' ; Is this character, a space?
beq @incs ; Yes, so increment the starting space count.
@@ -44,31 +48,66 @@ lex:
beq @inct ; Yes, so increment the starting tab count.
bra @spaces ; No, so Keep looping.
@incs:
- inc idx1 ; Increment the space count.
+ inc t_space ; Increment the space count.
bra @spaces ; Keep looping.
@inct:
- inc idx1+1 ; Increment the tab count.
+ inc t_tab ; Increment the tab count.
bra @spaces ; Keep looping.
-@isstart:
- pha.w ; Preserve the character.
- lda.w idx1 ; Was there any whitespace?
- pla.w ; 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.
+ pha ; Preserve the pre-token.
+ jsr is_altok ; Is this one of the single letter pre-tokens?
+ pla ; Get the pre-token back.
+ bne @is_altok ; Yes, so check the rest of the pre-token.
+@parse:
jsr parse_ptok ; Parse the pre-token.
; beq @end ; We got to the end of the string.
+ lda lex_type ; Get the lexeme type.
+ cmp #TOK_EXPR ; Was this token, an expression?
+ beq @inc_idx ; Yes, so increment the index.
+ ldy.w idx0 ; No, so get the string index.
+ lda (ptr), y ; Get a character from the line.
+ jsr isdelm2 ; Is this not a delimiter?
+ beq @inc_idx ; Yes, so increment the index.
+ bra @loop ; No, so keep looping.
+@is_altok:
+ sta lex_type ; Save the pre-token in the lexeme type.
+ iny ; Increment the offset.
+ cmp #PTOK_S ; Is this pre-token, PTOK_S?
+ bne @ptok_p ; No, so check for PTOK_P.
+ lda (ptr), y ; Yes, so get the next character after it.
+ jsr tolower ; Convert it to lowercase.
+ cmp #'p' ; Is the next character 'p'?
+ bne @ptok_p ; No, so check for PTOK_P.
+ bra @inc_offset ; Yes, so increment the offset.
+@ptok_p:
+ cmp #PTOK_P ; Is this pre-token, PTOK_P?
+ bne @is_altok2 ; No, so skip incrementing the offset.
+ lda (ptr), y ; Yes, so get the next character after it.
+ jsr tolower ; Convert it to lowercase.
+ cmp #'c' ; Is the next character 'c'?
+ bne @is_altok2 ; No, so skip incrementing the offset.
+@inc_offset:
+ iny ; Increment the offset.
+@is_altok2:
+ lda (ptr), y ; Yes, so get the character, at the current offset.
+ jsr get_ptok ; Get the pre-token of the character.
+ cmp #PTOK_P ; Is this pre-token greater than PTOK_P?
+ bcc @ptok_num ; No, so check for PTOK_NUM.
+ beq @ptok_num ;
+ cmp #PTOK_B ; Yes, and is this pre-token greater than, or equal to PTOK_B?
+ bcs @ptok_al ; Yes, so set the pre-token to PTOK_ALPH.
+ lda lex_type ; No, so get the original pre-token back.
+ ldy.w idx0 ; Get the string index.
+ bra @parse ; Go back to parsing the pre-token.
+@ptok_al:
+ lda #PTOK_ALPH ; Set the pre-token to PTOK_ALPH.
+ ldy.w idx0 ; Get the string index.
+ bra @parse ; Go back to parsing the pre-token.
+@inc_idx:
+ inc.w idx0 ; Increment the string index.
bra @loop ; Keep looping.
@end:
jsr update_ptr ; Get the screen buffer index.
@@ -97,21 +136,23 @@ 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.
+ lda #0 ; Set the isesc flag to false.
+ pha ;
jsr delmcpy ; Copy the string, to the lexeme buffer, until delimiter.
+ pla ;
@isop:
lda regb ; 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 ;
+ sta t_id ; Also set the token ID to TOK_RS.
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.
bra @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.
@@ -135,7 +176,11 @@ ptok_dot:
sta.w idx2 ; Save the offset in the third index.
bra @dir_loop ; Keep looping.
@found:
- nop ;
+ lda #TOK_DIR ; Set the lexeme type to TOK_DIR.
+ sta lex_type ;
+ sta t_id ; Also set the token ID to TOK_DIR.
+ lda idx1 ; Set the token type to the directive ID.
+ sta t_type ;
@end:
jsr make_tok ; Create the token.
jsr set_cmdbuf ; Set the first pointer to the command buffer.
@@ -156,7 +201,6 @@ ptok_min:
lda #EXPR_MINUS ; Set the expresion type to EXPR_MINUS.
bra ptok_expr ; Set up the token.
ptok_gt:
-
lda #EXPR_LOW ; Set the expresion type to EXPR_LOW.
bra ptok_expr ; Set up the token.
ptok_lt:
@@ -165,7 +209,9 @@ ptok_lt:
ptok_pipe:
lda #EXPR_OR ; Set the expresion type to EXPR_OR.
ptok_expr:
+ sta t_type ; Set the token type to the expression type.
lda #TOK_EXPR ; Set the lexeme type to TOK_EXPR.
+ sta t_id ; Also set the token ID to TOK_EXPR.
sta lex_type ;
inc.w idx0 ;
; ldb #1 ; Make init_lex increment the string index.
@@ -182,6 +228,9 @@ ptok_rbrk:
ptok_com:
inc.w idx0 ;
rts ; End of parse_ptok.
+ptok_br:
+ inc.w idx0 ;
+ rts ; End of parse_ptok.
ptok_xr:
inc.w idx0 ;
rts ; End of parse_ptok.
@@ -197,16 +246,36 @@ ptok_pc:
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.
+ ldb #5 ; Set the delimiter comparison value to a double quote, or EOL.
+ lda #1 ; Set the isesc flag to true.
+ pha ;
+ and #0 ; Make delmcpy use isdelm.
jsr delmcpy ; Copy the string, to the lexeme buffer, until delimiter.
+ pla ;
+ lda #TOK_DQUOT ; Set the lexeme type to TOK_DQUOT.
+ sta lex_type ;
+ sta t_id ; Also set the token ID to TOK_DQUOT.
+ lda.d ptr3 ; Get the address of the lexeme buffer.
+ sta.q t_str ; Save it in the token string.
@end:
+ jsr make_tok ; Create the token.
rts ; End of parse_ptok.
ptok_squ:
ldb #1 ; Make init_lex increment the string index.
jsr init_lex ; Initialize the lexeme buffer for copying.
- ldb #8 ; Set the delimiter comparison value to a single quote.
+ ldb #9 ; Set the delimiter comparison value to a single quote, or EOL.
+ lda #1 ; Set the isesc flag to true.
+ pha ;
+ and #0 ; Make delmcpy use isdelm.
jsr delmcpy ; Copy the string, to the lexeme buffer, until delimiter.
+ pla ;
+ lda #TOK_SQUOT ; Set the lexeme type to TOK_SQUOT.
+ sta lex_type ;
+ sta t_id ; Also set the token ID to TOK_SQUOT.
+ lda.d ptr3 ; Get the address of the lexeme buffer.
+ sta.q t_str ; Save it in the token string.
@end:
+ jsr make_tok ; Create the token.
rts ; End of parse_ptok.
ptok_hash:
inc.w idx0 ;
@@ -215,33 +284,49 @@ ptok_scol:
ldb #1 ; Make init_lex increment the string index.
jsr init_lex ; Initialize the lexeme buffer for copying.
ldb #1 ; Set the delimiter to EOL.
+ lda #0 ; Set the isesc flag to false.
+ pha ;
jsr delmcpy ; Copy the string, to the lexeme buffer, until EOL.
+ pla ;
+ lda #TOK_SCOLN ; Set the lexeme type to TOK_SCOLN.
+ sta lex_type ;
+ sta t_id ; Also set the token ID to TOK_SCOLN.
+ lda.d ptr3 ; Get the address of the lexeme buffer.
+ sta.q t_str ; Save it in the token string.
@end:
+ jsr make_tok ; Create the token.
rts ; End of parse_ptok.
ptok_dolr:
lda #TOK_HEX ; Set the lexeme type to TOK_HEX.
sta lex_type ;
+ sta t_id ; Also set the token ID to TOK_HEX.
lda #$10 ; Set the base to Hexadecimal.
ldb #1 ; Make init_lex increment the string index.
bra ptok_num2 ; Parse the value.
ptok_prcn:
lda #TOK_BIN ; Set the lexeme type to TOK_BIN.
sta lex_type ;
+ sta t_id ; Also set the token ID to TOK_BIN.
lda #2 ; Set the base to Binary.
ldb #1 ; Make init_lex increment the string index.
bra ptok_num2 ; Parse the value.
ptok_num:
lda #TOK_DEC ; Set the lexeme type to TOK_DEC.
sta lex_type ;
+ sta t_id ; Also set the token ID to TOK_DEC.
lda #10 ; Set the base to Decimal.
ldb #0 ; Do not let init_lex increment the string index.
ptok_num2:
pha ; Preserve the base.
jsr init_lex ; Initialize the lexeme buffer for copying.
ldb #3 ; Set the delimiter to both the EOL, and a comma.
+ lda #0 ; Set the isesc flag to false.
+ pha ;
jsr delmcpy ; Copy the string, to the lexeme buffer, until delimiter.
+ pla ;
pla ; Get the base back.
jsr strtoullg ; Convert the string into a numeric value.
+ sta.q t_val ; Set the token value to the converted value.
jsr make_tok ; Create the token.
jsr set_cmdbuf ; Set the first pointer to the command buffer.
rts ; End of parse_ptok.
@@ -249,17 +334,21 @@ ptok_alph:
ldb #0 ; Do not let init_lex increment the string index.
jsr init_lex ; Initialize the lexeme buffer for copying.
ldb #3 ; Stop at any possible delimiter.
+ lda #0 ; Set the isesc flag to false.
+ pha ;
tba ; Use isdelm2 for the comparison.
jsr delmcpy ; Copy the string, to the lexeme buffer, until delimiter.
+ pla ;
lda #0 ; Reset A.
sta regb ; Clear the isop flag.
@isop:
ldb #0 ; Make the lexeme buffer, the first pointer.
stb.q idx1 ; Reset the second index.
+ stb.q idx2 ; Reset the third index.
jsr set_lexptr ; Set up the lexeme buffer.
@isop_loop:
ldb idx1 ; Get the instruction ID.
- cpb #OPNUM-1 ; Have we reached the end of the mnemonic table?
+ cpb #OPNUM ; Have we reached the end of the mnemonic table?
beq @end ; Yes, so we're done.
lda.w #mne ; No, so get the start of the mnemonic table.
clc ; Prepare for a non carrying add.
@@ -268,7 +357,6 @@ ptok_alph:
jsr strcaseg ; Is the lexeme buffer, the same as the mnemonic string?
pla.q ; Get the mnemonic string pointer back.
beq @found ; Yes, so create a new token.
- beq @end ; Yes, so we're done.
inc idx1 ; No, so increment the instruction ID.
@offset:
jsr strlen ; Get the string's length.
@@ -280,6 +368,11 @@ ptok_alph:
@found:
lda #TOK_MNE ; Set the lexeme type to TOK_MNE.
sta lex_type ;
+ sta t_id ; Also set the token ID to TOK_MNE.
+ lda.q idx1 ; Get the instruction ID.
+ sta.q t_val ; Set the token value to the instruction ID.
+ lda #$FF ; Set the token type to -1.
+ sta t_type ;
inc regb ; Set the isop flag.
@end:
jsr make_tok ; Create the token.
@@ -333,79 +426,96 @@ init_lex:
delmcpy:
- sta rega ; Save the delimiter check flag.
- stb regc ; Save the delimiter comparison value.
+ pha ; Save the delimiter check flag.
+ phb ; Save the delimiter comparison value.
+ and #0 ; Reset A.
+ pha ; Reset the isesc flag.
+; sta rega ; Save the delimiter check flag.
+; stb regc ; Save the delimiter comparison value.
@loop:
- ldb #0 ; Reset the B register.
- stb regg ; Reset the byte count.
ldy.w idx0 ; Get the string index.
- lda.q (ptr), y ; Get eight bytes from the current line.
-@loop1:
- pha.q ; Save the string buffer.
- and #$FF ; Get the current byte.
+ lda (ptr), y ; Get a character from the line.
pha ; Preserve the character.
- lda rega ; Are we calling isdelm2?
- pla ; Get the character back.
+ lda sp+4 ; Are we calling isdelm2?
+ pla ; Get the character back.
bne @isdelm2 ; Yes, so use isdelm2.
jsr isdelm ; No, so get the delimiter value from isdelm.
@delmchk:
- and regc ; Are both delimiter values, the same?
- pla.q ; Get back the string buffer.
- bne @end ; Yes, so we're done.
- bra @copy ; No, so start copying the character.
+ and sp+2 ; Are both delimiter values, the same?
+ beq @copy ; No, so copy the character.
+@isesc:
+ lda sp+1 ; Was the isesc flag true?
+ beq @end ; No, so we're done.
+ bra @copy ; Yes, so copy the character.
@isdelm2:
jsr isdelm2 ; Get the delimiter value from isdelm2.
bra @delmchk ; Check the delimiter.
@copy:
+ lda sp+12 ; Was the do_isesc flag set?
+ bne @do_isesc ; Yes, so set the isesc flag.
+@copy1:
+ lda (ptr), y ; Get a character from the line.
ldy.w idx1 ; Get the lexeme index.
- sta (ptr3), y ; Copy one byte from the screen buffer, to the command buffer.
+ sta (ptr3), y ; Copy the character to the lexeme buffer.
inc.w idx0 ; Increment the string index.
inc.w idx1 ; Increment the lexeme index.
- lsr #8 ; Shift in the next byte.
- inc regg ; Increment the byte count.
- ldb regg ; Get back the byte count.
- cpb #7 ; Did we shift in eight bytes?
- beq @loop ; Yes, so get eight more bytes.
- bra @loop1 ; No, so keep shifting in more bytes.
+ bra @loop ; Keep looping.
+@do_isesc:
+ jsr isesc ; Check if this is an escaped character.
+ sta sp+1 ; Save it in the isesc flag.
+ bra @copy1 ; Copy the character.
@end:
- ldb #0 ; Reset B.
+ pla.w ; Pull both arguments off the stack.
+ pla ; Pull the isesc flag off the stack.
+ and #0 ; Reset A.
ldy.w idx1 ; Get the lexeme index.
- stb (ptr3), y ; Terminate the command buffer.
-@end1:
+ sta (ptr3), y ; Terminate the lexeme buffer.
ldy.w idx0 ; Get the string index.
- tba ; Reset A.
rts ; End of delmcpy.
;@loop:
+; ldb #0 ; Reset the B register.
+; stb regg ; Reset the byte count.
; ldy.w idx0 ; Get the string index.
-; lda (ptr), y ; Get a character from the line.
+; lda.q (ptr), y ; Get eight bytes from the current line.
+;@loop1:
+; pha.q ; Save the string buffer.
+; and #$FF ; Get the current byte.
; pha ; Preserve the character.
; lda rega ; Are we calling isdelm2?
-; pla ; Get the character back.
+; pla ; Get the character back.
; bne @isdelm2 ; Yes, so use isdelm2.
; jsr isdelm ; No, so get the delimiter value from isdelm.
;@delmchk:
; and regc ; Are both delimiter values, the same?
+; pla.q ; Get back the string buffer.
; bne @end ; Yes, so we're done.
; bra @copy ; No, so start copying the character.
;@isdelm2:
; jsr isdelm2 ; Get the delimiter value from isdelm2.
; bra @delmchk ; Check the delimiter.
;@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.
+; sta (ptr3), y ; Copy one byte from the screen buffer, to the command buffer.
; inc.w idx0 ; Increment the string index.
; inc.w idx1 ; Increment the lexeme index.
-; bra @loop ; Keep looping.
+; lsr #8 ; Shift in the next byte.
+; inc regg ; Increment the byte count.
+; ldb regg ; Get back the byte count.
+; cpb #7 ; Did we shift in eight bytes?
+; beq @loop ; Yes, so get eight more bytes.
+; bra @loop1 ; No, so keep shifting in more bytes.
;@end:
+; ldb #0 ; Reset B.
; ldy.w idx1 ; Get the lexeme index.
-; lda #0 ; Terminate the lexeme buffer.
-; sta (ptr3), y ;
+; stb (ptr3), y ; Terminate the command buffer.
+;@end1:
; ldy.w idx0 ; Get the string index.
+; tba ; Reset A.
; rts ; End of delmcpy.
+
get_rs:
phb ; Preserve B.
ldb #0 ; Set the isop flag to false.
diff --git a/programs/sub-suite/subeditor.s b/programs/sub-suite/subeditor.s
index e624990..aec613e 100644
--- a/programs/sub-suite/subeditor.s
+++ b/programs/sub-suite/subeditor.s
@@ -129,7 +129,9 @@ print_str:
tay ; Save it in Y.
tba ; Get the character back.
inx ; Increment the string index.
+ phx ; Preserve the string index.
jsr print_char ; Print the character.
+ plx ; Get the string index back.
bra @loop ; Keep looping.
@end:
ldb #0 ; Enable insert mode.
@@ -365,29 +367,23 @@ findend:
print_char:
- sta rega ; Save the typed character for now.
+ sta rega ; Preserve the character.
ldb #2 ; Make sure that set_ptr sets the third pointer.
lda.d #buffer ; Set the third pointer to the start of the screen buffer.
jsr set_ptr ;
- ldb #0 ; Set B to zero.
- tba ; Set the Accumulator to zero.
- lda rega ; Get back the character.
- cmp #$1B ; Did the user type an escape character?
- beq esc ; Yes, so go check the escape code.
- 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.
- cmp #19 ; No, but did the user type Ctrl+S?
- 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 #'\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.
+ deb ; Set B to one.
+ tba ; Reset A.
+ lda rega ; Get the character back.
+ jsr get_ctrlidx ; Get the control code jump table index.
+ lsl #1 ; Multiply the return value by two, to get the index.
+ tax ;
+ lda.w ct_jtb, x ; Get the address of the control code handler.
+ jsr set_ptr ; Set the second pointer to the control code handler.
+ deb ; Reset B.
+ tba ; Reset A.
+ jmp (ptr2) ; Jump to the handler for that control code.
printc:
- lda #0 ; No, so start trying to print a character.
+ lda #0 ; start trying to print a character.
sta regd ;
lda (ptr3), y ; Are we at the end of the string?
beq @save ; Yes, so just print the character.
@@ -402,9 +398,6 @@ printc:
@update1:
jsr findend ; Find the end of the line.
sta rege ; Use it for redrawing the line.
-; sta scr_row ; Set the row position to to the end of the line.
-; jsr findst ; Find the start of the line.
-; lda scr_row ; Get the start of the line.
lda scr_trow ; Get the current row position.
@update2:
sta regf ; Set the starting line, to the current row position.
diff --git a/programs/sub-suite/subsuite.s b/programs/sub-suite/subsuite.s
index d425550..d28b4f2 100644
--- a/programs/sub-suite/subsuite.s
+++ b/programs/sub-suite/subsuite.s
@@ -2,7 +2,6 @@
; Include Declarations.
.include "declare.s"
-
; Include SuBEditor.
.include "subeditor.s"
; Include SuBAsm.
diff --git a/programs/sub-suite/utils.s b/programs/sub-suite/utils.s
index 3ab948b..7e7469c 100644
--- a/programs/sub-suite/utils.s
+++ b/programs/sub-suite/utils.s
@@ -3,8 +3,9 @@
print_hi:
and #0 ; Reset A.
sta idx3 ; Clear the string index.
+ tax ; Reset X.
lda #'$' ; Print the hex delimiter.
- jsr charcpy ;
+ sta strbuf, x ; Save it in the string buffer.
lda.q idx0 ; Get the masked address.
ldx #$10 ; Set digit count to 16.
jsr print_hex ; Print the address.
@@ -14,23 +15,27 @@ print_hi:
sta.q strbuf+9 ; Save it in the string buffer.
ldx #$11 ; Add 16 to the index.
stx idx3 ;
- lda #':' ; Print a colon.
- jsr charcpy ;
- lda # ' ' ; Print a space.
- jsr charcpy ;
+ lda.w #': ' ; Print a space.
+ sta.w strbuf, x ; Save it in the string buffer.
+ inc idx3 ; Increment the string index twice.
+ inc idx3 ;
+ and #0 ; Reset A.
rts ; End of print_hi.
+
print_lo:
- lda #0 ; Reset A.
+ and #0 ; Reset A.
sta idx3 ; Clear the string index.
@loop:
ldx #2 ; Set digit count to 2.
pha ; Preserve the nibble offset.
jsr print_hex ; Print the low nibble offset.
lda.w (ptr3) ; Get the two digits.
- jsr charcpy ; Copy the first digit.
- lsr #8 ; Copy the next digit.
- jsr charcpy ;
+ ldx idx3 ; Get the string index.
+ sta.w strbuf, x ; Save it in the string buffer.
+ inc idx3 ; Increment the string index twice.
+ inc idx3 ;
+ ldx idx3 ; Get the string index.
pla ; Get the nibble offset back.
inc ; Increment the offset.
cmp #$10 ; Are we at the last offset?
@@ -38,11 +43,11 @@ print_lo:
@loop1:
pha ; No, so preserve the nibble offset.
lda #' ' ; Add a space to the string buffer.
- jsr charcpy ;
+ sta strbuf, x ; Save it in the string buffer.
+ inc idx3 ; Increment the string index.
pla ; Get the nibble offset back.
bra @loop ; Keep looping.
@end:
- inx ; Increment the index by one.
lda #0 ; Null terminate the string buffer.
sta strbuf, x ;
tax ; Reset X.
@@ -50,6 +55,7 @@ print_lo:
jsr print_str ;
rts ; End of print_lo.
+
print_chunk:
ldx #0 ; Reset X.
phy.w ; Preserve the screen buffer index.
@@ -60,14 +66,17 @@ print_chunk:
lda (idx0), y ; Get the byte at that address.
jsr print_hex ; Print the byte.
lda.w (ptr3) ; Get the two digits.
- jsr charcpy ; Copy the first digit.
- lsr #8 ; Copy the next digit.
- jsr charcpy ;
+ ldx idx3 ; Get the string index.
+ sta.w strbuf, x ; Save it in the string buffer.
+ inc idx3 ; Increment the string index twice.
+ inc idx3 ;
+ ldx idx3 ; Get the string index.
iny ; Increment the byte index.
cpy #$10 ; Have we read 16 bytes?
beq @end ; Yes, so we're done.
lda #' ' ; No, so add a soace to the string buffer.
- jsr charcpy ;
+ sta strbuf, x ; Save it in the string buffer.
+ inc idx3 ; Increment the string index.
bra @loop ; Keep looping.
@end:
ply.w ; Get the screen buffer index back.
@@ -202,7 +211,6 @@ isdelm2:
isdelm:
ldx #0 ; Reset X.
- stx rega ; 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.
@@ -222,13 +230,47 @@ isdelm:
lda #0 ; Return 0.
rts ; End of isdelm.
@rshft:
- stx rega ; Save the shift value.
- ldx #0 ; Reset X.
lda #1 ; Set up the bitshift.
- lsl rega ; Return 1 << X.
+ phx ; Push the shift value to stack.
+ lsl sp+1 ; Return 1 << X.
+ plx ; Pull the shift value off the stack.
+ ldx #0 ; Reset X.
rts ; End of isdelm.
+isesc:
+ ldy.w idx0 ; Get the string index.
+ lda (ptr), y ; Get the current character.
+ cmp #'\\' ; Is it a backslash?
+ bne @false ; No, so return false.
+@dec:
+ dey ; Decrement the string index.
+ lda (ptr), y ; Get the current character.
+ iny ; Set the string index back.
+ cmp #'\\' ; Is it a backslash?
+ beq @false ; Yes, so return false.
+ lda #1 ; No, so return true.
+ rts ; End of isesc.
+@false:
+ and #0 ; Return false.
+ rts ; End of isesc.
+
+
+is_altok:
+ sec ; Do a non borrowing subtract.
+ sbc #12 ; Subtract 12 from the token.
+ and #$FF ; Make sure the value is 8 bits.
+ cmp #4 ; Is the token in between PTOK_B, and PTOK_P?
+ bcc @r1 ; Yes, so return 1.
+ beq @r1 ;
+@r0:
+ lda #0 ; Return 0.
+ rts ; End of is_altok.
+@r1:
+ lda #1 ; Return 1.
+ rts ; End of is_altok.
+
+
get_ptok:
ldx #0 ; Reset X.
jsr tolower ; Conver the character to lowercase.
@@ -257,3 +299,22 @@ get_ptok:
@ralph:
lda #PTOK_ALPH ; Return PTOK_ALPH.
rts ; End of get_ptok.
+
+
+get_ctrlidx:
+ cmp #$7F ; Is this a delete character?
+ beq @del ; Yes, so return the same value as backspace.
+ sec ; Do a non borrowing subtract.
+ sbc #8 ; Subtract 8 from the character, to get the index.
+ tax ; Copy the index to X.
+ and #0 ; Reset A.
+ cpx #19 ; Are we less than, or equal to the max size of the table?
+ bcc @get_rtval ; Yes, so get the return value from the table.
+ beq @get_rtval ;
+ rts ; End of get_ctrlidx.
+@get_rtval:
+ lda ct_rtb, x ; Get the return value from the table.
+ rts ; End of get_ctrlidx.
+@del:
+ lda #2 ; Return 2.
+ rts ; End of get_ctrlidx.
diff --git a/sux.c b/sux.c
index 62ef371..c53e7b8 100644
--- a/sux.c
+++ b/sux.c
@@ -100,6 +100,43 @@ static inline uint8_t isrw(uint8_t opcode) {
return 1; /* Reading. */
}
}
+static inline uint8_t isread(uint8_t opcode) {
+ switch (opcode) {
+ case LDA_IMM: /* LDA Immediate. */
+ case LDA_AB: /* LDA Absolute. */
+ case LDA_Z: /* LDA Zero Matrix. */
+ case LDA_ZX: /* LDA Zero Matrix, Indexed with X. */
+ case LDA_ZY: /* LDA Zero Matrix, Indexed with Y. */
+ case LDA_IN: /* LDA Indirect. */
+ case LDA_IX: /* LDA Indexed Indirect. */
+ case LDA_IY: /* LDA Indirect Indexed. */
+ case LDB_IMM: /* LDB Immediate. */
+ case LDB_AB: /* LDB Absolute. */
+ case LDB_Z: /* LDB Zero Matrix. */
+ case LDB_ZX: /* LDB Zero Matrix, Indexed with X. */
+ case LDB_ZY: /* LDB Zero Matrix, Indexed with Y. */
+ case LDB_IN: /* LDB Indirect. */
+ case LDB_IX: /* LDB Indexed Indirect. */
+ case LDB_IY: /* LDB Indirect Indexed. */
+ case LDY_IMM: /* LDY Immediate. */
+ case LDY_AB: /* LDY Absolute. */
+ case LDY_Z: /* LDY Zero Matrix. */
+ case LDY_IN: /* LDY Indirect. */
+ case LDX_IMM: /* LDX Immediate. */
+ case LDX_AB: /* LDX Absolute. */
+ case LDX_Z: /* LDX Zero Matrix. */
+ case LDX_IN: /* LDX Indirect. */
+ case JMP_AB: /* JMP Absolute. */
+ case JMP_Z: /* JMP Zero Matrix. */
+ case JMP_IN: /* JMP Indirect. */
+ case JSR_IN: /* JSR Indirect. */
+ case JSR_AB: /* Jump to SubRoutine. */
+ case JSR_Z: /* JSR Zero Matrix. */
+ return 0;
+ default:
+ return 1;
+ }
+}
void *run(void *args) {
struct suxthr *thr = (void *)args;
@@ -200,8 +237,8 @@ void *run(void *args) {
addr[STEP_ADDR] = 1;
step = 1;
}
- if (isrw(opcode) && am != REL) {
- value.u64 = read_value(cpu, address.u64, size, 1, check_io);
+ if (isrw(opcode) && am != REL && isread(opcode)) {
+ value.u64 = read_value(cpu, 0, address.u64, size, 1, check_io);
}
}
switch(opcode) {
@@ -361,7 +398,7 @@ void *run(void *args) {
case LDB_IN: /* LDB Indirect. */
case LDB_IX: /* LDB Indexed Indirect. */
case LDB_IY: /* LDB Indirect Indexed. */
- cpu->b = load(cpu, value.u64, thread);
+ cpu->b = load(cpu, cpu->b, address.u64, size, thread);
break;
case LDA_IMM: /* LDA Immediate. */
case LDA_AB: /* LDA Absolute. */
@@ -371,19 +408,19 @@ void *run(void *args) {
case LDA_IN: /* LDA Indirect. */
case LDA_IX: /* LDA Indexed Indirect. */
case LDA_IY: /* LDA Indirect Indexed. */
- cpu->a = load(cpu, value.u64, thread);
+ cpu->a = load(cpu, cpu->a, address.u64, size, thread);
break;
case LDY_IMM: /* LDY Immediate. */
case LDY_AB: /* LDY Absolute. */
case LDY_Z: /* LDY Zero Matrix. */
case LDY_IN: /* LDY Indirect. */
- cpu->y = load(cpu, value.u64, thread);
+ cpu->y = load(cpu, cpu->y, address.u64, size, thread);
break;
case LDX_IMM: /* LDX Immediate. */
case LDX_AB: /* LDX Absolute. */
case LDX_Z: /* LDX Zero Matrix. */
case LDX_IN: /* LDX Indirect. */
- cpu->x = load(cpu, value.u64, thread);
+ cpu->x = load(cpu, cpu->x, address.u64, size, thread);
break;
case BEQ_REL: /* BEQ Relative. */
if (getflag(Z)) {
diff --git a/sux.h b/sux.h
index 6ed0fc0..f3eb222 100644
--- a/sux.h
+++ b/sux.h
@@ -49,9 +49,7 @@ extern int get_key(WINDOW *scr);
extern void io(uint64_t address, uint8_t rw);
extern void init_scr();
-static inline uint64_t read_value(struct sux *cpu, uint64_t address, uint8_t size, uint8_t inc_clk, uint8_t check_io) {
- union reg value;
- value.u64 = 0;
+static inline uint64_t read_value(struct sux *cpu, uint64_t reg, uint64_t address, uint8_t size, uint8_t inc_clk, uint8_t check_io) {
#if (IO || debug) && !branch
#if keypoll
pthread_mutex_lock(&mutex);
@@ -63,33 +61,18 @@ static inline uint64_t read_value(struct sux *cpu, uint64_t address, uint8_t siz
pthread_mutex_unlock(&mutex);
#endif
#endif
- switch (size) {
- case 7: value.u8[7] = addr[address+7];
- case 6: value.u8[6] = addr[address+6];
- case 5: value.u8[5] = addr[address+5];
- case 4: value.u8[4] = addr[address+4];
- case 3: value.u8[3] = addr[address+3];
- case 2: value.u8[2] = addr[address+2];
- case 1: value.u8[1] = addr[address+1];
- case 0: value.u8[0] = addr[address+0];
- }
+ size = (size > 7) ? 7 : size;
+ uint64_t mask = (-(uint64_t)1 >> ((7 - size) * 8));
#if getclk
cpu->clk += inc_clk;
#endif
- return value.u64;
+ return (reg & ~mask) | (*(uint64_t *)(addr+address) & mask);
}
-static inline void write_value(struct sux *cpu, union reg value, uint64_t address, uint8_t size, uint8_t inc_clk, uint8_t check_io) {
- switch (size) {
- case 7: addr[address+7] = value.u8[7];
- case 6: addr[address+6] = value.u8[6];
- case 5: addr[address+5] = value.u8[5];
- case 4: addr[address+4] = value.u8[4];
- case 3: addr[address+3] = value.u8[3];
- case 2: addr[address+2] = value.u8[2];
- case 1: addr[address+1] = value.u8[1];
- case 0: addr[address+0] = value.u8[0];
- }
+static inline void write_value(struct sux *cpu, uint64_t value, uint64_t address, uint8_t size, uint8_t inc_clk, uint8_t check_io) {
+ size = (size > 7) ? 7 : size;
+ uint64_t mask = (-(uint64_t)1 >> ((7 - size) * 8));
+ *(uint64_t *)(addr+address) = (*(uint64_t *)(addr+address) & ~mask) | (value & mask);
#if (IO || debug) && !branch
#if keypoll
pthread_mutex_lock(&mutex);
@@ -135,9 +118,9 @@ static inline uint64_t read_addr(struct sux *cpu, uint8_t prefix, uint8_t inc_cl
uint64_t address;
uint8_t size = get_addrsize(prefix, type);
if (prefix >> 6) {
- address = offset_addr(cpu, read_value(cpu, cpu->pc, size, inc_clk, 0), size, inc_clk, prefix);
+ address = offset_addr(cpu, read_value(cpu, 0, cpu->pc, size, inc_clk, 0), size, inc_clk, prefix);
} else {
- address = read_value(cpu, cpu->pc, size, inc_clk, 0);
+ address = read_value(cpu, 0, cpu->pc, size, inc_clk, 0);
}
if (inc_pc) {
cpu->pc += size+1;
@@ -161,14 +144,14 @@ static inline uint64_t zmy_addr(struct sux *cpu, uint8_t prefix, uint8_t inc_clk
static inline uint64_t ind_addr(struct sux *cpu, uint8_t prefix, uint8_t inc_clk, uint8_t inc_pc) {
- return read_value(cpu, read_addr(cpu, prefix, inc_clk, ZM, inc_pc), 7, inc_clk, 0);
+ return read_value(cpu, 0, read_addr(cpu, prefix, inc_clk, ZM, inc_pc), 7, inc_clk, 0);
}
static inline uint64_t indx_addr(struct sux *cpu, uint8_t prefix, uint8_t inc_clk, uint8_t inc_pc) {
#if getclk
cpu->clk += inc_clk;
#endif
- return read_value(cpu, read_addr(cpu, prefix, inc_clk, ZM, inc_pc)+cpu->x, 7, inc_clk, 0);
+ return read_value(cpu, 0, read_addr(cpu, prefix, inc_clk, ZM, inc_pc)+cpu->x, 7, inc_clk, 0);
}
static inline uint64_t indy_addr(struct sux *cpu, uint8_t prefix, uint8_t inc_clk, uint8_t inc_pc) {
@@ -181,7 +164,7 @@ static inline uint64_t indy_addr(struct sux *cpu, uint8_t prefix, uint8_t inc_cl
static inline uint64_t rel_addr(struct sux *cpu, uint8_t prefix, uint8_t inc_clk, uint8_t inc_pc) {
uint8_t rs = (prefix >> 4) & 3;
uint8_t size = (1 << rs) - 1;
- uint64_t offset = read_value(cpu, cpu->pc, size, inc_clk, 0);
+ uint64_t offset = read_value(cpu, 0, cpu->pc, size, inc_clk, 0);
uint64_t address;
if (inc_pc) {
cpu->pc += (size + 1);
@@ -278,16 +261,14 @@ static inline void transfer(struct sux *cpu, uint64_t value, uint8_t opcode, uin
}
static inline void push(struct sux *cpu, uint64_t value, uint8_t size, uint8_t thread) {
- union reg reg;
- reg.u64 = value;
uint64_t sbr = (cpu->stk_st << 16);
- write_value(cpu, reg, (sbr+cpu->sp)-size, size, 1, 0);
+ write_value(cpu, value, (sbr+cpu->sp)-size, size, 1, 0);
cpu->sp -= size+1;
}
static inline uint64_t pull(struct sux *cpu, uint8_t size, uint8_t thread) {
uint64_t sbr = (cpu->stk_st << 16);
- uint64_t value = read_value(cpu, sbr+cpu->sp+1, size, 1, 0);
+ uint64_t value = read_value(cpu, 0, sbr+cpu->sp+1, size, 1, 0);
cpu->sp += size+1;
return value;
}
@@ -393,12 +374,12 @@ static inline uint64_t idr(struct sux *cpu, uint64_t reg, uint8_t inc, uint8_t t
/* Increment, or Decrement memory. */
static inline void idm(struct sux *cpu, uint64_t address, uint8_t prefix, uint8_t inc, uint8_t thread) {
uint8_t size = (1 << ((prefix >> 4) & 3))-1;
- union reg value;
- value.u64 = read_value(cpu, address, size, 1, 0);
+ uint64_t value;
+ value = read_value(cpu, 0, address, size, 1, 0);
if (inc) {
- value.u64++;
+ value++;
} else {
- value.u64--;
+ value--;
}
uint8_t sign = 0;
switch ((prefix >> 4) & 3) {
@@ -407,12 +388,13 @@ static inline void idm(struct sux *cpu, uint64_t address, uint8_t prefix, uint8_
case 2: sign = 31; break;
case 3: sign = 63; break;
}
- setflag(value.u64 == 0, Z);
- setflag(value.u64 >> sign, N);
+ setflag(value == 0, Z);
+ setflag(value >> sign, N);
write_value(cpu, value, address, size, 1, 1);
}
-static inline uint64_t load(struct sux *cpu, uint64_t value, uint8_t thread) {
+static inline uint64_t load(struct sux *cpu, uint64_t reg, uint64_t address, uint8_t size, uint8_t thread) {
+ uint64_t value = read_value(cpu, reg, address, size, 1, 1);
setflag(value == 0, Z);
setflag(value >> 63, N);
return value;
@@ -420,7 +402,5 @@ static inline uint64_t load(struct sux *cpu, uint64_t value, uint8_t thread) {
static inline void store(struct sux *cpu, uint64_t address, uint64_t reg, uint8_t prefix, uint8_t thread) {
uint8_t size = (1 << ((prefix >> 4) & 3))-1;
- union reg value;
- value.u64 = reg;
- write_value(cpu, value, address, size, 1, 1);
+ write_value(cpu, reg, address, size, 1, 1);
}
diff --git a/test/asr.s b/test/asr.s
index b251a84..ffcd46b 100644
--- a/test/asr.s
+++ b/test/asr.s
@@ -2,23 +2,23 @@
;
; Writen by mr b0nk 500 <b0nk@b0nk.xyz>
+.org $8000
reset:
cps
start:
clc
- lda #0
- sbc.w #$FFFF
- ldb #0
- deb
+ and #0
+ dec
+ tab
+ lsl #$10
signshft:
asr #1
- cab
+ cmp b
beq start
- jmp signshft
+ bra signshft
.org $FFC0
.qword reset
a
-done
-
+d
diff --git a/test/fib-new.s b/test/fib-new.s
index 5a8ae83..6b0b717 100644
--- a/test/fib-new.s
+++ b/test/fib-new.s
@@ -5,21 +5,21 @@
; by mr b0nk 500 <b0nk@b0nk.xyz>
; Variables for thread 0.
-.org $0
-x:
- .byte $0
-y:
- .byte $0
-z:
- .byte $0
+.org 0
+x1:
+ .res 1
+y1:
+ .res 1
+z1:
+ .res 1
; Variables for thread 1.
x2:
- .byte $0
+ .res 1
y2:
- .byte $0
+ .res 1
z2:
- .byte $0
+ .res 1
.org $1000
init:
@@ -27,21 +27,21 @@ init:
start:
lda #$0 ; Clear the accumulator.
ldy #$1 ; y=1.
- sty y ; Store y into memory.
+ sty y1 ; Store y into memory.
fib:
ldx #$0 ; x=0.
- ldx x ; Output the value of x.
- adc y ; Add x with y.
- sta z ; z=x+y
- ldy y
- sty x ; x=y.
- sta y ; y=z.
- lda x
+ ldx x1 ; Output the value of x.
+ adc y1 ; Add x with y.
+ sta z1 ; z=x+y
+ ldy y1
+ sty x1 ; x=y.
+ sta y1 ; y=z.
+ lda x1
bcs start ; Start all over again, if the carry flag was set.
- jmp fib ; Otherwise, keep looping.
+ bra fib ; Otherwise, keep looping.
+
-.org $2000
init2:
cps ; Clear the Processor Status register.
start2:
@@ -59,7 +59,7 @@ fib2:
sta y2 ; y2=z2.
lda x2
bcs start2 ; Start all over again, if the carry flag was set.
- jmp fib2 ; Otherwise, keep looping.
+ bra fib2 ; Otherwise, keep looping.
.org $FFC0
.qword init
@@ -68,5 +68,4 @@ fib2:
.qword init2
; Execute the program.
a
-done
-
+d
diff --git a/test/fib.s b/test/fib.s
index dd8c618..65912ad 100644
--- a/test/fib.s
+++ b/test/fib.s
@@ -5,45 +5,44 @@
; by mr b0nk 500 <b0nk@b0nk.xyz>
; Variables for thread 0.
-.org $1000
-x:
- .qword $0
-y:
- .qword $0
-z:
- .qword $0
+.org 0
+x1:
+ .res 8
+y1:
+ .res 8
+z1:
+ .res 8
; Variables for thread 1.
-.org $2000
x2:
- .qword $0
+ .res 8
y2:
- .qword $0
+ .res 8
z2:
- .qword $0
+ .res 8
-.org $0
+.org $8000
init:
cps ; Clear the Processor Status register.
start:
lda #$0 ; Clear the accumulator.
ldy #$1 ; y=1.
- sty.q y ; Store y into memory.
+ sty.q y1 ; Store y into memory.
fib:
ldx #$0 ; x=0.
- ldx.q x ; Output the value of x.
- adc.q y ; Add x with y.
- sta.q z ; z=x+y
- ldy.q y
- sty.q x ; x=y.
- sta.q y ; y=z.
- lda.q x
+ ldx.q x1 ; Output the value of x.
+ adc.q y1 ; Add x with y.
+ sta.q z1 ; z=x+y
+ ldy.q y1
+ sty.q x1 ; x=y.
+ sta.q y1 ; y=z.
+ lda.q x1
bcs start ; Start all over again, if the carry flag was set.
- jmp fib ; Otherwise, keep looping.
+ bra fib ; Otherwise, keep looping.
+
-.org $8000
init2:
cps ; Clear the Processor Status register.
@@ -62,12 +61,11 @@ fib2:
sta.q y2 ; y2=z2.
lda.q x2
bcs start2 ; Start all over again, if the carry flag was set.
- jmp fib2 ; Otherwise, keep looping.
+ bra fib2 ; Otherwise, keep looping.
; Set up the thread vectors.
.org $FF50
.qword init2
; Execute the program.
a
-done
-
+d
diff --git a/test/load-store.s b/test/load-store.s
new file mode 100644
index 0000000..60a5a8f
--- /dev/null
+++ b/test/load-store.s
@@ -0,0 +1,22 @@
+.org $8000
+
+reset:
+ cps
+ ldx.w #$FFFF
+ txs
+@clear:
+ and #0
+ tax
+ tab
+ deb
+@loop:
+ lsl #8
+ lda #$FF
+ cmp b
+ beq @clear
+ bra @loop
+
+.org $FFC0
+.qword reset
+a
+d
diff --git a/test/nop.s b/test/nop.s
index 8fbb14f..8d0d75d 100644
--- a/test/nop.s
+++ b/test/nop.s
@@ -7,6 +7,6 @@ nop_loop:
nop
nop
nop
- jmp nop_loop
+ bra nop_loop
a
done
diff --git a/test/reg-transfer.s b/test/reg-transfer.s
index b9d1280..754940d 100644
--- a/test/reg-transfer.s
+++ b/test/reg-transfer.s
@@ -10,7 +10,7 @@ bench:
tay ; Transfer the accumulator to the y register.
tax ; Do the same thing, but with the x register.
tab ;
- jmp bench ; Loop forever.
+ bra bench ; Loop forever.
.org $FFC0
.qword reset