From 4ed07ca38b99abdca750c6612c512f30965f1714 Mon Sep 17 00:00:00 2001 From: mrb0nk500 Date: Sun, 30 Aug 2020 12:44:21 -0400 Subject: - Did some more work on SuBAsm's lexer. - Optimized the memory read, and write functions. - Made the emulator faster, and cleaner in general. --- disasm.c | 65 ++++++++---- lexer.c | 33 +++--- programs/sub-suite/declare.s | 120 +++++++++++++++++----- programs/sub-suite/lexer.s | 228 ++++++++++++++++++++++++++++++----------- programs/sub-suite/subeditor.s | 37 +++---- programs/sub-suite/subsuite.s | 1 - programs/sub-suite/utils.s | 99 ++++++++++++++---- sux.c | 49 +++++++-- sux.h | 68 +++++------- test/asr.s | 16 +-- test/fib-new.s | 45 ++++---- test/fib.s | 48 +++++---- test/load-store.s | 22 ++++ test/nop.s | 2 +- test/reg-transfer.s | 2 +- 15 files changed, 565 insertions(+), 270 deletions(-) create mode 100644 test/load-store.s 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 +.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 ; 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 ; 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 -- cgit v1.2.3-13-gbd6f