diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | programs/forg.s | 17 | ||||
-rw-r--r-- | programs/hex-to-bcd.s | 7 | ||||
-rw-r--r-- | programs/pos-check.s | 12 | ||||
-rw-r--r-- | programs/scr-to-buf.s | 7 | ||||
-rw-r--r-- | programs/subeditor.s | 900 | ||||
-rw-r--r-- | sux.c | 351 | ||||
-rw-r--r-- | test/fib-new.s | 73 | ||||
-rw-r--r-- | test/input-3.s | 546 |
9 files changed, 1635 insertions, 280 deletions
@@ -12,7 +12,7 @@ OBJS = asmmon.o sux.o OBJ_NAME = cisc-0.2 all : clean $(OBJ_NAME) cisc-0.2: $(OBJS) - $(CC) $(OBJS) $(CFLAGS) -lpthread -lcurses -o $(OBJ_NAME) + $(CC) $(OBJS) $(CFLAGS) -lpthread -lcurses -ltinfo -o $(OBJ_NAME) sux.o : $(CC) sux.c -c $(CFLAGS) -o sux.o asmmon.o : diff --git a/programs/forg.s b/programs/forg.s deleted file mode 100644 index 3e6aea1..0000000 --- a/programs/forg.s +++ /dev/null @@ -1,17 +0,0 @@ -forg: - iny ; Increment offset. - lda buf, y - jsr iswhite - bcs forg ; Reset y, if we hit the null terminator. - cmp #$2E ; Is this character a '.'? - bne forg_exit ; No, so return. - sty org ; Yes, so store the origin. -forg_end: - iny ; Increment offset. - lda buf, y - jsr istoken - bcs forg_end - dey - sty scr_col -forg_exit: - rts ; End of forg. diff --git a/programs/hex-to-bcd.s b/programs/hex-to-bcd.s deleted file mode 100644 index 53a3ff2..0000000 --- a/programs/hex-to-bcd.s +++ /dev/null @@ -1,7 +0,0 @@ -hex_to_bcd: - pla #1 ; Get argument. - div #10 ; Divide A by 10. - lsl #4 ; Shift the result left by 4 bits. - oab ; Or the result, with the remainder. - pha #1 ; Push the packed BCD result to the stack. - rts ; Return the result. diff --git a/programs/pos-check.s b/programs/pos-check.s deleted file mode 100644 index 315147b..0000000 --- a/programs/pos-check.s +++ /dev/null @@ -1,12 +0,0 @@ -cmd_clr: - lda scr_row - cmp #23 - beq cmd_vwrap - inc scr_row - jmp cmd_clr_end -cmd_vwrap: - jsl rset_row -cmd_clr_end: - jsl update_pos - lda #0 - rtl diff --git a/programs/scr-to-buf.s b/programs/scr-to-buf.s deleted file mode 100644 index 1787dc3..0000000 --- a/programs/scr-to-buf.s +++ /dev/null @@ -1,7 +0,0 @@ -scr_to_buf: - tax - mul #80 - adc scr_col - tay - txa - rtl diff --git a/programs/subeditor.s b/programs/subeditor.s new file mode 100644 index 0000000..159dc1f --- /dev/null +++ b/programs/subeditor.s @@ -0,0 +1,900 @@ +; SuBEditor. +; +; Writen in Sux assembly by +; mr b0nk 500 <b0nk@b0nk.xyz> + +; Instruction mnemonics, +; and opcodes. +.org $1000 +tok: + .byte "dab" +msg: + .byte "oof, you divided a, and b on me.\n" + +; Input buffer. +.org $2000 +buffer: + +.org $4000 +cmd_buf: + + +; Initalize some variables. +.org $0 +scr_row: + .byte $0 +scr_col: + .byte $0 +scr_trow: + .byte $0 +scr_tcol: + .byte $0 +scr_ptr: + .word $0 +a: + .byte $0 +b: + .byte $0 +c: + .byte $0 +d: + .byte $0 +e: + .byte $0 +f: + .byte $0 +string: + .byte "Please, type something.\n" +string2: + .byte "You typed, " +end: + .byte $0 +bits: + .byte $80 + .byte $40 + .byte $20 + .byte $10 + .byte $08 + .byte $04 + .byte $02 + .byte $01 +bitmask: + .byte $0 +bitabl: + .qword $0 + .qword $0 +scr_str: +.byte $0 +scr_end: +.byte $0 +wrapped: +.byte $0 + +; Pointers +ptr: + .qword buffer +cptr: + .qword cmd_buf +tptr: + .qword tok +mptr: + .qword msg + +; Main program +.org $8000 +reset: + cps + ldx.w #$FFFF + txs + ldy #0 + lda #23 + sta scr_end + lda #0 + sta scr_str + ldx #8 + sta.q bitabl + sta.q bitabl, x + tax + jsl clr_buf + jmp start +clr_buf: + lda #0 + cpy.w #$1FFF + beq clr_buf_end + sta (ptr), y + iny + jmp clr_buf +clr_buf_end: + ldy.w #0 + rtl + +start: + lda #0 + tax + sta $C000 + phy #2 + ldy.w #0 + jsl clr_cbuf + ply #2 + jmp print + +clr_cbuf: + cpy.w #$3FF + beq clr_cbuf_end + sta (cptr), y + iny + jmp clr_cbuf +clr_cbuf_end: + rtl + +pull_y: + ply #2 +rset_a: + lda #0 + sta $C000 + inc +read: + lda $C000 ; Get control register. + beq rset_a ; Loop until we get a character. + jsl getchar ; We got a key. + beq parse ; We got a newline, so start parsing the line. + jmp rset_a ; We didn't get a newline, so keep getting more characters. + +print: + phy #2 + txy + lda string, y ; Get character at offset x. + beq pull_y ; Did we find a null terminator? + ply #2 + inx + jsl print_char + jmp print + +getbit: + clc + lda scr_str + bne getbt0 + ldx scr_row + jmp getbt1 +getbt0: + lda scr_row + adc scr_str + tax +getbt1: + jsl bitpos + ldb bitabl, x + aba + cmp #1 + jmp bitout + +;putbit: +; ldx scr_row +;putbt1: +; bcc setbit + + +clrbit: + jsl bitpos + xor #$FF + ldb bitabl, x + aba +bitsav: + sta bitabl, x +bitout: + ldx bitmask + rtl + +setbit: + jsl bitpos + ldb bitabl, x + oab + jmp bitsav + +bitpos: + stx bitmask + txa + and #7 + tax + lda bits, x + pha #1 + lda bitmask + lsr #3 + tax + pla #1 + rtl + + +getchar: + lda $C002 ; Get typed character. + ldb #0 + stb e + pha #1 + phy #2 + cmp #10 + beq cmd_cpy +getchar_pnt: + ply #2 + pla #1 + ldb e + bne reset_row +getchar_pnt1: + jsl print_char + lda a + cmp #10 + beq getchar_line + jmp getchar_char +reset_row: + ldb e + stb scr_row + jmp getchar_pnt1 + + +cmd_cpy: + ldb scr_row + stb e + jsl findst + clc + lda scr_row + adc scr_str + mul #80 + tay + ldx.w #$0 +cmd_cpy_strt: + lda (ptr), y + beq getchar_pnt + phy #2 + txy + sta (cptr), y + inx + ply #2 + iny + jmp cmd_cpy_strt +getchar_line: + lda #0 + jmp getchar_end +getchar_char: + lda #1 +getchar_end: + rtl + +findst: + jsl getbit + bcc findst_done + dec scr_row + bpo findst + inc scr_row +findst_done: + rtl + +parse: + lda #0 + tax + jsl dabbed + beq start + lda #0 + tax + jmp result + +print_char: + sta a + cmp #$1B + beq esc + cmp #$A + beq nl ; Did the user type a newline? + cmp #$C + beq clr_scr + cmp #19 + beq en_step + cmp #18 + beq dis_step + cmp #8 + beq bs ; Did the user type a backspace? + cmp #$7F + beq bs ; Did the user type a backspace? + sta a +printc: + lda a + sta (ptr), y ; Store typed character into the input buffer. + inc scr_col ; Increment the cursor's x coordinate. + iny +printc_2: + ldb #1 + stb f + ldb scr_col + cpb #80 + bcs printc_4 +printc_3: + sta $C001 ; Echo typed character. + ldb f + beq printc_wrap + jmp printc_end +printc_4: + ldb scr_row + cpb #23 + bcs printc_scrl +printc_5: + ldb #0 + stb f + jmp printc_3 +printc_scrl: + sta $C001 ; Echo typed character. + clc + lda #1 + sta wrapped + jsl scrl_down +printc_wrap: + ldb #0 + stb scr_col + ldb scr_row + cpb #23 + bcs printc_wrap2 +printc_wrap1: + inc scr_row +printc_wrap2: + phx #2 + clc + lda scr_row + adc scr_str + tax + jsl setbit + plx #2 + jsl update_pos +printc_end: + rtl + +nl: + lda #0 + sta (ptr), y ; Store said terminator into the input buffer. + sta scr_col + lda scr_row + cmp #23 + bne nl_inc + jsl scrl_down + lda #10 + sta a + jmp printc_end +nl_inc: + inc scr_row + jsl update_pos + lda #10 + sta a + jmp printc_end + +clr_scr: + lda #23 + sta scr_end + lda #0 + sta scr_str + ldx #8 + sta.q bitabl + sta.q bitabl, x + tay + jsl clr_buf + sta scr_col + sta scr_row + jsl update_pos + lda #$C + sta $C001 + jmp printc_end + +en_step: + lda $C010 + beq step_en + jmp stp_end +step_en: + lda #1 + sta $C010 + jmp stp_end + +dis_step: + lda $C010 + bne step_dis + jmp stp_end +step_dis: + lda #0 + sta $C010 +stp_end: + jmp printc_end + +back: + lda #$7F + sta $C001 + dey ; Decrement buffer offset. + lda #0 ; Put a null terminator, in place of the backspace. + sta (ptr), y ; Place it into the input buffer. + dec scr_col + jsl update_pos + jmp printc_end ; Get next character. + +bs: + lda scr_col ; Are we at the start of the buffer? + beq back_wrap + jmp back ; We are not, so add the backspace to the buffer. +back_wrap: + jsl getbit + bcs back_wrap1 + jmp printc_end +back_wrap1: + lda scr_row + beq back_wrap2 + jmp backwrp +back_wrap2: + lda scr_str + bne back_scrl + jmp printc_end +back_scrl: + clc + jsl scrl_up + inc scr_row +backwrp: + clc + lda scr_row + adc scr_str + tax +backwrp2: + dec scr_row + jsl clrbit + ldb #80 + stb scr_col + jsl update_pos + jmp back + +esc: + lda $C000 ; Skip the '['. + lda $C002 + cmp #$1B + beq shftesc + lda $C000 ; Get the next character. + beq printc_end ; We have an error, so discard it, and go back to getting user input. + lda $C002 ; Get the escape code. + sta c ; Store the escape code, until we need it. + lda #0 + sta d + jsl isup ; Check if the user pressed up. + lda d + bne esc_end + jsl isdown ; Check if the user pressed down. + lda d + bne esc_end + lda #0 + jsl isleft ; Check if the user pressed left. + lda d + bne esc_end + jsl isright ; Check if the user pressed right. +esc_end: + lda #0 + sta d + jmp printc_end ; Go back to getting user input. + +shftesc: + lda $C000 ; Skip the '['. + lda $C000 ; Get the next character. + beq printc_end ; We have an error, so discard it, and go back to getting user input. + lda $C002 ; Get the escape code. + sta c ; Store the escape code, until we need it. + lda #0 + sta d + jsl isshftup ; Check if the user pressed shift+up. + lda d + bne shftesc_end + jsl isshftdown ; Check if the user pressed shift+down. +shftesc_end: + lda #0 + sta d + jmp printc_end ; Go back to getting user input. + +isup: + lda c ; No, so load the escape code back into the accumulator. + cmp #$41 ; Did the user press the up arrow key? + bne isup_done ; Yes, so return. + lda #1 + sta d + lda scr_row ; Is the cursor at the top of the screen? + beq isup_scrl ; Yes, so return. +isup_2: + lda c ; No, so load the escape code back into the accumulator. + cmp #$41 ; Did the user press the up arrow key? + beq up ; Yes, so move the cursor up. + jmp isup_done +isup_scrl: + lda scr_str + beq isup_done + jsl scrl_up +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? + bne isdown_done + lda scr_row ; Start checking the y coordinate of the cursor. + cmp #23 ; Is the cursor at the bottom of the screen? + beq isdown_scrl ; Yes, so return. + lda c ; No, so load the escape code back into the accumulator. + cmp #$42 ; Did the user press the down arrow key? + beq down ; Yes, so move the cursor down. + jmp isdown_done +isdown_scrl: + lda scr_row + sta scr_trow + lda scr_col + sta scr_tcol + jsl scrl_down + lda scr_trow + sta scr_row + lda scr_tcol + sta scr_col +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? + bne isright_done + lda scr_col ; Start checking the x coordinate of the cursor. + cmp #79 ; Is the cursor at the far right of the screen? + beq isright_wrp ; Yes, so check if this is a wrapped line. + jmp right ; No, so move the cursor right, like normal. +isright_wrp: + inc scr_row + jsl getbit + bcs wrap_inc + dec scr_row + jmp isright_done +isright_scrl: + lda scr_str + beq isright_end + lda #1 + sta wrapped + jsl scrl_down + dec scr_row + jmp isright_end +wrap_inc: + lda #0 + sta scr_col + lda scr_row + cmp #23 + bcs isright_scrl +isright_end: + jsl update_pos +isright_done: + lda #0 + sta wrapped + rtl ; End of isright. + +isleft: + lda c + cmp #$43 + beq isleft_done + lda scr_col ; 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? + beq left ; Yes, so move the cursor left. + jmp isleft_done +isleft_wrp: + jsl getbit + bcs wrap_dec + jmp isleft_done +wrap_dec: + lda scr_row + beq wrap_dec1 + lda #1 + sta wrapped + dec scr_row +wrap_dec1: + lda #79 + sta scr_col + lda #1 + sta d + lda scr_row + beq isleft_scrl + jmp isleft_end +isleft_scrl: + lda wrapped + bne isleft_end + lda scr_str + beq isleft_done + jsl scrl_up + jmp isleft_done +isleft_end: + jsl update_pos +isleft_done: + lda #0 + sta wrapped + rtl ; End of isleft. + +up: + dec scr_row + jsl update_pos + lda #1 + sta d + jmp isup_done +down: + inc scr_row + jsl update_pos + lda #1 + sta d + jmp isdown_done +right: + inc scr_col + jsl update_pos + jmp isright_done +left: + dec scr_col + jsl update_pos + lda #1 + sta d + jmp isleft_done + +isshftup: + lda c ; Load the escape code back into the accumulator. + cmp #$41 ; Did the user press the up arrow key? + bne isshftup_done + lda #1 + sta d + lda scr_str + beq isshftup_done + jmp shftup +isshftup_done: + rtl + +isshftdown: + lda c ; Load the escape code back into the accumulator. + cmp #$42 ; Did the user press the down arrow key? + bne isshftdown_done + lda #1 + sta d + lda scr_end + cmp #71 + bcs isshftdown_done + jmp shftdown +isshftdown_done: + rtl + +shftup: + jsl scrl_up + lda #1 + sta d + jmp isshftup_done + +shftdown: + jsl scrl_down + lda #1 + sta d + jmp isshftdown_done + +update_pos: + ldb #1 + stb f + clc + lda scr_row + adc scr_str + clc + mul #80 + clc + adc scr_col + tay + lda #$1B ; Print an escape character + sta $C001 ; to the screen. + lda #$5B ; Print '[' + sta $C001 ; 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' + sta $C001 ; 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 + sta $C001 ; print to the screen. + tba ; Get the remainder. + adc #$30 ; Convert it to ascii, and + sta $C001 ; print to the screen. + rtl ; End of getrow. + +getcol: + lda #$3B ; Print ';' + sta $C001 ; 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 + sta $C001 ; print to the screen. + tba ; Get the remainder. + clc + adc #$30 ; Convert it to ascii, and + sta $C001 ; print to the screen. + rtl ; End of getrow. + +scrl_down: + + inc scr_str + inc scr_end + lda #$1B ; Print an escape character + sta $C001 ; to the screen. + lda #$5B ; Print '[' + sta $C001 ; to the screen, and start the escape sequence. + lda #$54 ; Print 'T' + sta $C001 ; to the screen, and end the escape sequence. + lda wrapped + beq scrldn_save +scrldn1: + jsl rdrw_row + lda wrapped + beq scrldn_load + jmp scrldn_end +scrldn_save: + lda scr_row + pha #1 + lda scr_col + pha #1 + jmp scrldn1 +scrldn_load: + pla #1 + sta scr_col + pla #1 + sta scr_row + jsl update_pos +scrldn_end: + lda #0 + sta wrapped +scrldn_done: + rtl + +scrl_up: + dec scr_str + dec scr_end + lda #$1B ; Print an escape character + sta $C001 ; to the screen. + lda #$5B ; Print '[' + sta $C001 ; to the screen, and start the escape sequence. + lda #$53 ; Print 'S' + sta $C001 ; to the screen, and end the escape sequence. + lda scr_row + pha #1 + lda scr_col + pha #1 + lda #0 + sta scr_row + jsl rdrw_row + pla #1 + sta scr_col + pla #1 + sta scr_row + jsl update_pos +scrlup_done: + rtl + +rdrw_row: + lda #0 + sta scr_col + jsl update_pos +rdrow_st: + lda (ptr), y + beq rdrow_inc + sta $C001 +rdrow_inc: + inc scr_col + lda (ptr), y + beq rdrow_skip + iny +rdrow_inc1: + lda scr_col + cmp #80 + bcs rdrow_end + jmp rdrow_st +rdrow_skip: + jsl update_pos + jmp rdrow_inc1 +rdrow_end: + lda #0 + sta scr_col + jsl update_pos +rdrow_done: + rtl + + +;rdrw_scr: +; lda #$C +; sta $C001 +; lda scr_col +; sta scr_tcol +; lda scr_row +; sta scr_trow +; lda #0 +; sta scr_col +; sta scr_row +; phy #2 +; jsl update_pos +; ply #2 +; ldx scr_ptr +; phy #2 +; txy +; lda (ptr), y +; sta $C001 +; ply #2 +; rtl + +result: + phy #2 + txy + lda string2, y + beq rset_y ; Reset y, if we hit the null terminator. + ply #2 + jsl print_char ; Print 'You have typed, ' + inx + jmp result ; Keep printing. + +rset_y: + ply #2 + lda #0 ; Reset a. + tax ; Reset y. + jmp print_buf ; Print the input buffer. + +dabbed: + phy #2 + txy + lda (cptr), y ; Get a character from the input buffer. + beq dab_pend ; Are we done with printing the buffer? + cmp (tptr), y + bcc dab_pend + beq chk_str + bcs dab_pend +chk_str: + ply #2 + inx + cpx #3 + bne dabbed + ldx #0 +pnt_msg: + phy #2 + txy + lda (mptr), y ; Get a character from the input buffer. + beq dab_peqnd ; Are we done with printing the buffer? + ply #2 + jsl print_char + inx + jmp pnt_msg ; Keep printing the buffer. +dab_pend: + ply #2 + lda #1 + jmp dab_end +dab_peqnd: + ply #2 + lda #0 + jmp dab_end +dab_end: + rtl + +print_buf: + phy #2 + txy + lda (cptr), y ; Get a character from the input buffer. + beq cmd_clr ; Are we done with printing the buffer? + ply #2 + jsl print_char + inx + jmp print_buf ; Keep printing the buffer. + +cmd_clr: + ply #2 + lda #10 + jsl print_char + jmp start + +.org $FFC0 +.qword reset + +.org $FF50 +.qword spin +.qword spin +.qword spin +.qword spin +.qword spin +.qword spin +.qword spin +done + @@ -18,6 +18,7 @@ #define CTRL_ADDR 0xC000 #define TX_ADDR 0xC001 #define RX_ADDR 0xC002 +#define STEP_ADDR 0xC010 #define CURSES_BACKSPACE 0x7F #define setflag(flag, bit) (flag) ? (cpu->ps |= (bit << (thread << 3))) : (cpu->ps &= ~(bit << (thread << 3))) @@ -30,6 +31,7 @@ uint8_t threads_done = 0; uint8_t kbd_rdy = 0; uint8_t kbd_ln = 0; uint8_t wai = 0; +uint8_t step = 0; uint8_t irq = 0; #if !bench WINDOW *scr; @@ -115,10 +117,14 @@ void *run(void *args) { #if keypoll pthread_mutex_lock(&mutex); #endif - mvwprintw(scr, lines, 0, "pc: $%08llx, a: $%016llx, b: $%016llx, x: $%016llx, y: $%016llx" + /*mvwprintw(scr, lines, 0, "pc: $%08llx, a: $%016llx, b: $%016llx, x: $%016llx, y: $%016llx" ", sp: $%04lx, ps: $%016llx, prefix: $%02x, opcode: $%02x, thread: %u, inst: " , cpu->pc[thread], cpu->a[thread], cpu->b[thread], cpu->x[thread], cpu->y[thread] - , cpu->sp[thread], cpu->ps, prefix, opcode, thread); + , cpu->sp[thread], cpu->ps, prefix, opcode, thread);*/ + mvwprintw(scr, lines, 0, "pc: $%08llx, a: $%016llx, b: $%016llx, x: $%016llx, y: $%016llx" + ", sp: $%04lx, ps: $%016llx, prefix: $%02x, opcode: $%02x, inst: " + , cpu->pc[thread], cpu->a[thread], cpu->b[thread], cpu->x[thread], cpu->y[thread] + , cpu->sp[thread], cpu->ps, prefix, opcode); #if keypoll pthread_mutex_unlock(&mutex); #endif @@ -137,6 +143,8 @@ void *run(void *args) { case IMM: switch (opcode) { case TXS: + break; + case PHB: case PHP: case PHA: @@ -147,7 +155,6 @@ void *run(void *args) { case PLA: case PLY: case PLX: - break; case STT: case LSL: case LSR: @@ -317,15 +324,44 @@ void *run(void *args) { break; } - mvwprintw(scr, 29, 0, "address: $%016llx, scr_row: %02u, scr_col: %02u, scr_lnst: $%04x, scr_lncnt: $%04x\r", address, addr[0], addr[1], addr[2] | (addr[3] << 8), addr[4] | (addr[5] << 8)); - mvwprintw(scr, 32, 0, "%02x %02x %02x %02x %02x %02x %02x %02x " - "%02x %02x %02x %02x %02x %02x %02x %02x\r" - , addr[0x4000], addr[0x4001], addr[0x4002], addr[0x4003], addr[0x4004], addr[0x4005], addr[0x4006], addr[0x4007] - , addr[0x4008], addr[0x4009], addr[0x400A], addr[0x400B], addr[0x400C], addr[0x400D], addr[0x400E], addr[0x400F]); - mvwprintw(scr, 33, 0, "%02x %02x %02x %02x %02x %02x %02x %02x " + mvwprintw(scr, 29, 0, "address: $%016llx, scr_row: %02u, scr_col: %02u, scr_str: %02u, scr_end: %02u\r", address, addr[0], addr[1], addr[0x4B], addr[0x4C]); + mvwprintw(scr, 32, 0, "bitabl: %02x %02x %02x %02x %02x %02x %02x %02x " "%02x %02x %02x %02x %02x %02x %02x %02x\r" - , addr[0x4010], addr[0x4011], addr[0x4012], addr[0x4013], addr[0x4014], addr[0x4015], addr[0x4016], addr[0x4017] - , addr[0x4018], addr[0x4019], addr[0x401A], addr[0x401B], addr[0x401C], addr[0x401D], addr[0x401E], addr[0x401F]); + , addr[0x3B], addr[0x3C], addr[0x3D], addr[0x3E], addr[0x3F], addr[0x40], addr[0x41], addr[0x42] + , addr[0x43], addr[0x44], addr[0x45], addr[0x46], addr[0x47], addr[0x48], addr[0x49], addr[0x4A]); + mvwprintw(scr, 33, 0, "buffer:\r"); + uint8_t ln = 34; + uint16_t tmpad = 0x2000; + for (uint16_t i = 0; i < 20; i+=2) { + mvwprintw(scr, ln++, 0, "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x " + "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x, i: %02x\r" + , addr[tmpad+(0x00)+(i*0x10)], addr[tmpad+(0x01)+(i*0x10)], addr[tmpad+(0x02)+(i*0x10)], addr[tmpad+(0x03)+(i*0x10)] + , addr[tmpad+(0x04)+(i*0x10)], addr[tmpad+(0x05)+(i*0x10)], addr[tmpad+(0x06)+(i*0x10)], addr[tmpad+(0x07)+(i*0x10)] + , addr[tmpad+(0x08)+(i*0x10)], addr[tmpad+(0x09)+(i*0x10)], addr[tmpad+(0x0A)+(i*0x10)], addr[tmpad+(0x0B)+(i*0x10)] + , addr[tmpad+(0x0C)+(i*0x10)], addr[tmpad+(0x0D)+(i*0x10)], addr[tmpad+(0x0E)+(i*0x10)], addr[tmpad+(0x0F)+(i*0x10)] + , addr[tmpad+(0x10)+(i*0x10)], addr[tmpad+(0x11)+(i*0x10)], addr[tmpad+(0x12)+(i*0x10)], addr[tmpad+(0x13)+(i*0x10)] + , addr[tmpad+(0x14)+(i*0x10)], addr[tmpad+(0x15)+(i*0x10)], addr[tmpad+(0x16)+(i*0x10)], addr[tmpad+(0x17)+(i*0x10)] + , addr[tmpad+(0x18)+(i*0x10)], addr[tmpad+(0x19)+(i*0x10)], addr[tmpad+(0x1A)+(i*0x10)], addr[tmpad+(0x1B)+(i*0x10)] + , addr[tmpad+(0x1C)+(i*0x10)], addr[tmpad+(0x1D)+(i*0x10)], addr[tmpad+(0x1E)+(i*0x10)], addr[tmpad+(0x1F)+(i*0x10)] + , i); + + } + /*tmpad = 0x4000; + mvwprintw(scr, ln++, 0, "cmd_buf:\r"); + for (uint16_t i = 0; i < 20; i+=2) { + mvwprintw(scr, ln++, 0, "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x " + "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x, i: %02x\r" + , addr[tmpad+(0x00)+(i*0x10)], addr[tmpad+(0x01)+(i*0x10)], addr[tmpad+(0x02)+(i*0x10)], addr[tmpad+(0x03)+(i*0x10)] + , addr[tmpad+(0x04)+(i*0x10)], addr[tmpad+(0x05)+(i*0x10)], addr[tmpad+(0x06)+(i*0x10)], addr[tmpad+(0x07)+(i*0x10)] + , addr[tmpad+(0x08)+(i*0x10)], addr[tmpad+(0x09)+(i*0x10)], addr[tmpad+(0x0A)+(i*0x10)], addr[tmpad+(0x0B)+(i*0x10)] + , addr[tmpad+(0x0C)+(i*0x10)], addr[tmpad+(0x0D)+(i*0x10)], addr[tmpad+(0x0E)+(i*0x10)], addr[tmpad+(0x0F)+(i*0x10)] + , addr[tmpad+(0x10)+(i*0x10)], addr[tmpad+(0x11)+(i*0x10)], addr[tmpad+(0x12)+(i*0x10)], addr[tmpad+(0x13)+(i*0x10)] + , addr[tmpad+(0x14)+(i*0x10)], addr[tmpad+(0x15)+(i*0x10)], addr[tmpad+(0x16)+(i*0x10)], addr[tmpad+(0x17)+(i*0x10)] + , addr[tmpad+(0x18)+(i*0x10)], addr[tmpad+(0x19)+(i*0x10)], addr[tmpad+(0x1A)+(i*0x10)], addr[tmpad+(0x1B)+(i*0x10)] + , addr[tmpad+(0x1C)+(i*0x10)], addr[tmpad+(0x1D)+(i*0x10)], addr[tmpad+(0x1E)+(i*0x10)], addr[tmpad+(0x1F)+(i*0x10)] + , i); + + }*/ wrefresh(scr); #if keypoll pthread_mutex_unlock(&mutex); @@ -363,50 +399,30 @@ void *run(void *args) { setflag(cpu->i[thread], I); break; case PHB: /* PusH B register to stack. */ - tmp = addr[cpu->pc[thread]++]; - if (tmp > 7) - tmp = 7; - for (int8_t i = tmp<<3; i >= 0; i-=8) { - if (i) - addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->b[thread] >> i; - else - addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->b[thread] & 0xFF; - cpu->sp[thread]--; - } - break; case PHP: /* PusH Processor status to stack. */ - tmp = addr[cpu->pc[thread]++]; - if (tmp > 7) - tmp = 7; - for (int8_t i = tmp<<3; i >= 0; i-=8) { - if (i) - addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->ps >> i; - else - addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->ps & 0xFF; - cpu->sp[thread]--; - } - break; case PHA: /* PusH Accumulator to stack. */ - tmp = addr[cpu->pc[thread]++]; - if (tmp > 7) - tmp = 7; - for (int8_t i = tmp<<3; i >= 0; i-=8) { - if (i) - addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->a[thread] >> i; - else - addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->a[thread] & 0xFF; - cpu->sp[thread]--; - } - break; case PHY: /* PusH Y register to stack. */ - tmp = addr[cpu->pc[thread]++]; + case PHX: /* PusH X register to stack. */ + tmp = value; + if (opcode == PHB) { + reg = cpu->b[thread]; + } else if (opcode == PHP) { + reg = cpu->ps; + } else if (opcode == PHA) { + reg = cpu->a[thread]; + } else if (opcode == PHY) { + reg = cpu->y[thread]; + } else if (opcode == PHX) { + reg = cpu->x[thread]; + } + if (tmp > 7) tmp = 7; for (int8_t i = tmp<<3; i >= 0; i-=8) { if (i) - addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->y[thread] >> i; + addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = reg >> i; else - addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->y[thread] & 0xFF; + addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = reg & 0xFF; cpu->sp[thread]--; } break; @@ -422,28 +438,28 @@ void *run(void *args) { case TXS: /* Transfer X to Stack pointer. */ if (opcode == TAY) cpu->y[thread] = cpu->a[thread]; - if (opcode == TAX) + else if (opcode == TAX) cpu->x[thread] = cpu->a[thread]; - if (opcode == TYX) + else if (opcode == TYX) cpu->x[thread] = cpu->y[thread]; - if (opcode == TYA) + else if (opcode == TYA) cpu->a[thread] = cpu->y[thread]; - if (opcode == TXA) + else if (opcode == TXA) cpu->a[thread] = cpu->x[thread]; - if (opcode == TXY) + else if (opcode == TXY) cpu->y[thread] = cpu->x[thread]; - if (opcode == TAB) { + else if (opcode == TAB) { cpu->b[thread] = cpu->a[thread]; cpu->z[thread] = (cpu->b[thread] == 0); cpu->n[thread] = (cpu->b[thread] >> 63); } - if (opcode == TSX) { + else if (opcode == TSX) { cpu->x[thread] = cpu->sp[thread] & 0xFFFF; cpu->x[thread] = cpu->stk_st[thread] << 16; } - if (opcode == TBA) + else if (opcode == TBA) cpu->a[thread] = cpu->b[thread]; - if (opcode == TXS) { + else if (opcode == TXS) { cpu->sp[thread] = cpu->x[thread]; if (prefix == 0x17 && (value == thread+1 || value > 8)) { cpu->stk_st[thread] = value & 0xFF; @@ -455,29 +471,17 @@ void *run(void *args) { cpu->z[thread] = (cpu->a[thread] == 0); cpu->n[thread] = (cpu->a[thread] >> 63); } - if (opcode == TAY || opcode == TXY) { + else if (opcode == TAY || opcode == TXY) { cpu->z[thread] = (cpu->y[thread] == 0); cpu->n[thread] = (cpu->y[thread] >> 63); } - if (opcode == TAX || opcode == TYX) { + else if (opcode == TAX || opcode == TYX) { cpu->z[thread] = (cpu->x[thread] == 0); cpu->n[thread] = (cpu->x[thread] >> 63); } setflag(cpu->z[thread], Z); setflag(cpu->n[thread], N); break; - case PHX: /* PusH X register to stack. */ - tmp = addr[cpu->pc[thread]++]; - if (tmp > 7) - tmp = 7; - for (int8_t i = tmp<<3; i >= 0; i-=8) { - if (i) - addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->x[thread] >> i; - else - addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->x[thread] & 0xFF; - cpu->sp[thread]--; - } - break; case JMP: /* JMP Absolute. */ cpu->pc[thread] = address; break; @@ -500,63 +504,41 @@ void *run(void *args) { cpu->a[thread] = sum; break; case PLB: /* PuLl B register from stack. */ - tmp = addr[cpu->pc[thread]++]; - if (tmp > 7) - tmp = 7; - for (uint8_t i = 0; i < (tmp+1)<<3; i+=8) { - cpu->sp[thread]++; - if (i) - cpu->b[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << i; - else - cpu->b[thread] = (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] & 0xFF; - } - break; case PLP: /* PuLl Processor status from stack. */ - tmp = addr[cpu->pc[thread]++]; - if (tmp > 7) - tmp = 7; - for (uint8_t i = 0; i < (tmp+1)<<3; i+=8) { - cpu->sp[thread]++; - if (i) - cpu->ps += (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << i; - else - cpu->ps = (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] & 0xFF; - } - break; case PLA: /* PuLl Accumulator from stack. */ - tmp = addr[cpu->pc[thread]++]; - if (tmp > 7) - tmp = 7; - for (uint8_t i = 0; i < (tmp+1)<<3; i+=8) { - cpu->sp[thread]++; - if (i) - cpu->a[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << i; - else - cpu->a[thread] = (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] & 0xFF; - } - break; case PLY: /* PuLl Y register from stack. */ - tmp = addr[cpu->pc[thread]++]; - if (tmp > 7) - tmp = 7; - for (uint8_t i = 0; i < (tmp+1)<<3; i+=8) { - cpu->sp[thread]++; - if (i) - cpu->y[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << i; - else - cpu->y[thread] = (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] & 0xFF; - } - break; case PLX: /* PuLl X register from stack. */ - tmp = addr[cpu->pc[thread]++]; + tmp = value; + if (opcode == PLB) + reg = cpu->b[thread]; + else if (opcode == PLP) + reg = cpu->ps; + else if (opcode == PLA) + reg = cpu->a[thread]; + else if (opcode == PLY) + reg = cpu->y[thread]; + else if (opcode == PLX) + reg = cpu->x[thread]; + if (tmp > 7) tmp = 7; for (uint8_t i = 0; i < (tmp+1)<<3; i+=8) { cpu->sp[thread]++; if (i) - cpu->x[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << i; + reg += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << i; else - cpu->x[thread] = (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] & 0xFF; + reg = addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] & 0xFF; + } + if (opcode == PLB) { + cpu->b[thread] = reg; + } else if (opcode == PLP) { + cpu->ps = reg; + } else if (opcode == PLA) { + cpu->a[thread] = reg; + } else if (opcode == PLY) { + cpu->y[thread] = reg; + } else if (opcode == PLX) { + cpu->x[thread] = reg; } break; case 0x34: /* JSR Indirect. */ @@ -607,7 +589,7 @@ void *run(void *args) { break; case BPO: /* BPO Absolute. */ case 0x64: /* BPO Zero Matrix. */ - if (cpu->n[thread]) + if (!cpu->n[thread]) cpu->pc[thread] = address; break; case ORA: /* ORA Immediate. */ @@ -629,7 +611,7 @@ void *run(void *args) { break; case BNG: /* BNG Absolute. */ case 0x74: /* BNG Zero Matrix. */ - if (!cpu->n[thread]) + if (cpu->n[thread]) cpu->pc[thread] = address; break; case XOR: /* XOR Immediate. */ @@ -707,6 +689,9 @@ void *run(void *args) { if (opcode == STB || opcode == 0x4E || opcode == 0x6E || opcode == 0x8E || opcode == 0xAE || opcode == 0xCE || opcode == 0xEE) value = cpu->b[thread]; addr[address] = value & 0xFF; + if (address == STEP_ADDR) { + step = addr[address]; + } #if IO if (address == TX_ADDR) { #if keypoll @@ -755,6 +740,14 @@ void *run(void *args) { bcd[3] = 0; esc = 0; break; + case 'S': + wscrl(scr, -1); + esc = 0; + break; + case 'T': + wscrl(scr, 1); + esc = 0; + break; case '0': case '1': case '2': @@ -845,6 +838,10 @@ void *run(void *args) { bcd[3] = 0; esc = 0; break; + case 'S': + case 'T': + esc = 0; + break; case '0': case '1': case '2': @@ -963,6 +960,7 @@ void *run(void *args) { case 0xDE: /* LDB Indirect Indexed. */ case 0xD9: /* LDA Indirect Indexed. */ if (address == CTRL_ADDR) { + kbd_rdy = 1; pthread_mutex_lock(&main_mutex); pthread_cond_signal(&main_cond); pthread_mutex_unlock(&main_mutex); @@ -971,13 +969,14 @@ void *run(void *args) { pthread_cond_wait(&cond, &mutex); pthread_mutex_unlock(&mutex); #endif + kbd_rdy = 0; } - value = (uint64_t)addr[address]; + value = addr[address]; if (regsize >= 2) - value += (uint64_t)addr[address+1] << 8; + value += addr[address+1] << 8; if (regsize >= 4) { - value += (uint64_t)addr[address+2] << 16; - value += (uint64_t)addr[address+3] << 24; + value += addr[address+2] << 16; + value += addr[address+3] << 24; } if (regsize >= 8) { value += (uint64_t)addr[address+4] << 32; @@ -1151,10 +1150,10 @@ void *run(void *args) { if (opcode == CPX || opcode == 0xCB || opcode == 0xDB || opcode == 0xEB || opcode == 0xFB) reg = cpu->x[thread]; sum = reg-value; - cpu->n[thread] = (sum & 0x8000000000000000) ? 1 : 0; + cpu->n[thread] = (sum & 0x8000000000000000); cpu->v[thread] = ((reg^value) & 0x8000000000000000) && ((reg^sum) & 0x8000000000000000); - cpu->z[thread] = (sum == 0) ? 1 : 0; - cpu->c[thread] = (sum > value) ? 1 : 0; + cpu->z[thread] = (sum == 0); + cpu->c[thread] = (reg >= value); setflag(cpu->n[thread], N); setflag(cpu->v[thread], V); setflag(cpu->z[thread], Z); @@ -1249,6 +1248,10 @@ void *run(void *args) { case 0xC3: /* INC Absolute. */ case 0xC5: /* INC Zero Matrix. */ addr[address]++; + cpu->z[thread] = (addr[address] == 0); + cpu->n[thread] = (addr[address] >> 7); + setflag(cpu->z[thread], Z); + setflag(cpu->n[thread], N); break; case NOP: /* No OPeration. */ break; @@ -1268,6 +1271,10 @@ void *run(void *args) { case 0xD3: /* DEC Absolute. */ case 0xD5: /* DEC Zero Matrix. */ addr[address]--; + cpu->z[thread] = (addr[address] == 0); + cpu->n[thread] = (addr[address] >> 7); + setflag(cpu->z[thread], Z); + setflag(cpu->n[thread], N); break; case BRK: /* BReaK. */ for (int8_t i = stksize; i >= 0; i-=8) { @@ -1303,13 +1310,21 @@ void *run(void *args) { break; } ins++; - /*if (!addr[CTRL_ADDR]) + if (step) { + pthread_mutex_lock(&main_mutex); + pthread_cond_signal(&main_cond); + pthread_mutex_unlock(&main_mutex); + pthread_mutex_lock(&mutex); + pthread_cond_wait(&cond, &mutex); + pthread_mutex_unlock(&mutex); + } + if (!addr[CTRL_ADDR]) kbd_ln = 0; else kbd_ln = 1; - if (kbd_ln) + /*if (kbd_ln) usleep(16666); - /*usleep(500000);*/ + usleep(500000);*/ #if debug && !bench #if keypoll pthread_mutex_lock(&mutex); @@ -1419,47 +1434,79 @@ int main(int argc, char **argv) { assert(!result); } int c = 0; + uint8_t step_key = 0; #if !bench werase(scr); #endif while (threads_done < THREADS) { #if !bench int x, y, i = 0; - if ((c != EOF && c !=-1)) { - pthread_mutex_lock(&main_mutex); - curs_set(0); - pthread_cond_wait(&main_cond, &main_mutex); - pthread_mutex_unlock(&main_mutex); - curs_set(1); - c = 0; - addr[CTRL_ADDR] = 0; - kbd_ln = 0; + if ((step_key && step && !kbd_rdy) || !step || kbd_rdy) { + if ((c != EOF && c !=-1)) { + pthread_mutex_lock(&main_mutex); + curs_set(0); + pthread_cond_wait(&main_cond, &main_mutex); + pthread_mutex_unlock(&main_mutex); + curs_set(1); + c = 0; + step_key = 0; + addr[CTRL_ADDR] = 0; + kbd_ln = 0; + } } #if keypoll pthread_mutex_lock(&mutex); #endif getyx(scr, y, x); c = wgetch(scr); - switch (c) { - case ERR: - addr[CTRL_ADDR] = 0; - wmove(scr, getmaxy(scr)-1, 0); - wprintw(scr, "c: %i, x: %i, y: %i, i: %i.", c, x, y, i++); - wmove(scr, y, x); - wrefresh(scr); - break; - default: - addr[RX_ADDR] = (uint8_t)c; - addr[CTRL_ADDR] = 1; - if (c == '\n') - kbd_ln = 1; + if (c == 19) { + step = 1; + if (kbd_rdy) + c = wgetch(scr); + } + if (kbd_rdy) { + switch (c) { + case ERR: + addr[CTRL_ADDR] = 0; + wmove(scr, getmaxy(scr)-1, 0); + wprintw(scr, "c: %i, x: %i, y: %i, i: %i.", c, x, y, i++); + wmove(scr, y, x); + wrefresh(scr); + break; + default: + if (kbd_rdy && c < 0x100) { + addr[RX_ADDR] = (uint8_t)c; + addr[CTRL_ADDR] = 1; + #if debug && !bench + wmove(scr, getmaxy(scr)-1, 0); + wprintw(scr, "c: %i, x: %i, y: %i, i: %i.", c, x, y, i++); + wmove(scr, y, x); + wrefresh(scr); + #endif + } + if (c == '\n') + kbd_ln = 1; + #if !keypoll + pthread_mutex_lock(&mutex); + pthread_cond_signal(&cond); + pthread_mutex_unlock(&mutex); + #endif + break; + } + } else { + if ((c == 19 || c == 18) && step) { + if (c == 18) + step = 0; + else if (c == 19) + step_key = 1; #if !keypoll pthread_mutex_lock(&mutex); pthread_cond_signal(&cond); pthread_mutex_unlock(&mutex); #endif - break; + } } + addr[STEP_ADDR] = step; #if keypoll pthread_mutex_unlock(&mutex); #endif diff --git a/test/fib-new.s b/test/fib-new.s new file mode 100644 index 0000000..43538a0 --- /dev/null +++ b/test/fib-new.s @@ -0,0 +1,73 @@ +; Name: fib.s +; Description: Computes the Fibbonacci sequence. +; +; Written in Sux Assembly +; by mr b0nk 500 <b0nk@b0nk.xyz> + +; Variables for thread 0. +.org $0 +x: + .qword $0 +y: + .qword $0 +z: + .qword $0 + +; Variables for thread 1. +x2: + .qword $0 +y2: + .qword $0 +z2: + .qword $0 + +.org $1000 +init: + cps ; Clear the Processor Status register. + +start: + lda #$0 ; Clear the accumulator. + ldy #$1 ; y=1. + sty.q y ; 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 + bcs start ; Start all over again, if the carry flag was set. + jmp fib ; Otherwise, keep looping. + +.org $2000 +init2: + cps ; Clear the Processor Status register. + +start2: + lda #$0 ; Clear the accumulator. + ldy #$1 ; y2=1. + sty.q y2 ; Store y into memory. + +fib2: + ldx #$0 ; x2=0. + ldx.q x2 ; Output the value of x2. + adc.q y2 ; Add x2 with y2. + sta.q z2 ; z2=x2+y2 + ldy.q y2 + sty.q x2 ; x2=y2. + 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. + +.org $FFC0 +.qword init +; Set up the thread vectors. +.org $FF50 +.qword init2 +; Execute the program. +done + diff --git a/test/input-3.s b/test/input-3.s index a05cb9d..35547a7 100644 --- a/test/input-3.s +++ b/test/input-3.s @@ -18,14 +18,6 @@ buffer: .org $4000 cmd_buf: -.org $200 -bitmask: - .byte $0 -bitabl: - .qword $0 - .word $0 -bits: - .byte $0 ; Initalize some variables. .org $0 @@ -33,12 +25,12 @@ scr_row: .byte $0 scr_col: .byte $0 -scr_lnst: - .word $0 -scr_lncnt: - .word $0 -scr_rowst: +scr_trow: .byte $0 +scr_tcol: + .byte $0 +scr_ptr: + .word $0 a: .byte $0 b: @@ -49,12 +41,34 @@ d: .byte $0 e: .byte $0 +f: + .byte $0 string: .byte "Please, type something.\n" string2: .byte "You typed, " end: .byte $0 +bits: + .byte $80 + .byte $40 + .byte $20 + .byte $10 + .byte $08 + .byte $04 + .byte $02 + .byte $01 +bitmask: + .byte $0 +bitabl: + .qword $0 + .qword $0 +scr_str: +.byte $0 +scr_end: +.byte $0 +wrapped: +.byte $0 ; Pointers ptr: @@ -65,10 +79,6 @@ tptr: .qword tok mptr: .qword msg -bmptr: - .qword bitmask -btptr: - .qword bitabl ; Main program .org $8000 @@ -77,7 +87,14 @@ reset: ldx.w #$FFFF txs ldy #0 + lda #23 + sta scr_end lda #0 + sta scr_str + ldx #8 + sta.q bitabl + sta.q bitabl, x + tax jsl clr_buf jmp start clr_buf: @@ -99,8 +116,6 @@ start: ldy.w #0 jsl clr_cbuf ply #2 - lda #1 - sta $C000 jmp print clr_cbuf: @@ -124,9 +139,6 @@ read: jsl getchar ; We got a key. beq parse ; We got a newline, so start parsing the line. jmp rset_a ; We didn't get a newline, so keep getting more characters. -sleep: - lda end - bne spin ; Are we done with getting input? print: phy #2 @@ -139,17 +151,45 @@ print: jmp print getbit: - phy #2 + clc + lda scr_str + bne getbt0 ldx scr_row + jmp getbt1 +getbt0: + lda scr_row + adc scr_str + tax getbt1: jsl bitpos - txy - ldb (btptr), y - ply #2 + ldb bitabl, x aba cmp #1 jmp bitout +;putbit: +; ldx scr_row +;putbt1: +; bcc setbit + + +clrbit: + jsl bitpos + xor #$FF + ldb bitabl, x + aba +bitsav: + sta bitabl, x +bitout: + ldx bitmask + rtl + +setbit: + jsl bitpos + ldb bitabl, x + oab + jmp bitsav + bitpos: stx bitmask txa @@ -163,12 +203,11 @@ bitpos: pla #1 rtl -bitout: - ldx bitmask - rtl getchar: lda $C002 ; Get typed character. + ldb #0 + stb e pha #1 phy #2 cmp #10 @@ -176,13 +215,27 @@ getchar: getchar_pnt: ply #2 pla #1 + ldb e + bne reset_row +getchar_pnt1: jsl print_char lda a cmp #10 beq getchar_line jmp getchar_char +reset_row: + ldb e + stb scr_row + jmp getchar_pnt1 + + cmd_cpy: + ldb scr_row + stb e + jsl findst + clc lda scr_row + adc scr_str mul #80 tay ldx.w #$0 @@ -197,14 +250,22 @@ cmd_cpy_strt: iny jmp cmd_cpy_strt getchar_line: - lda #$0 - sta scr_lncnt + lda #0 jmp getchar_end getchar_char: - lda #$1 + lda #1 getchar_end: rtl +findst: + jsl getbit + bcc findst_done + dec scr_row + bpo findst + inc scr_row +findst_done: + rtl + parse: lda #0 tax @@ -222,31 +283,62 @@ print_char: beq nl ; Did the user type a newline? cmp #$C beq clr_scr + cmp #19 + beq en_step + cmp #18 + beq dis_step cmp #8 beq bs ; Did the user type a backspace? cmp #$7F beq bs ; Did the user type a backspace? sta a - ldb scr_col - cpb #79 - beq linewrap - jmp printc -linewrap: - ldb #0 - stb scr_col - lda #$42 - sta c - jsl isdown - ldb scr_row - cpb #23 - beq printc_end printc: lda a - inc scr_col ; Increment the cursor's x coordinate. - inc scr_lncnt sta (ptr), y ; Store typed character into the input buffer. + inc scr_col ; Increment the cursor's x coordinate. iny +printc_2: + ldb #1 + stb f + ldb scr_col + cpb #80 + bcs printc_4 +printc_3: + sta $C001 ; Echo typed character. + ldb f + beq printc_wrap + jmp printc_end +printc_4: + ldb scr_row + cpb #23 + bcs printc_scrl +printc_5: + ldb #0 + stb f + jmp printc_3 +printc_scrl: sta $C001 ; Echo typed character. + clc + lda #1 + sta wrapped + jsl scrl_down +printc_wrap: + ldb #0 + stb scr_col + ldb scr_row + cpb #23 + bcs printc_wrap2 +printc_wrap1: + inc scr_row +printc_wrap2: + phx #2 + clc + lda scr_row + adc scr_str + tax + jsl setbit + plx #2 + jsl update_pos printc_end: rtl @@ -257,22 +349,25 @@ nl: lda scr_row cmp #23 bne nl_inc - lda #1 + jsl scrl_down + lda #10 sta a jmp printc_end nl_inc: - lda #$42 - sta c - jsl isdown - sty.w scr_lnst + inc scr_row + jsl update_pos lda #10 sta a jmp printc_end clr_scr: + lda #23 + sta scr_end lda #0 - sta.w scr_lnst - sta scr_rowst + sta scr_str + ldx #8 + sta.q bitabl + sta.q bitabl, x tay jsl clr_buf sta scr_col @@ -282,25 +377,73 @@ clr_scr: sta $C001 jmp printc_end +en_step: + lda $C010 + beq step_en + jmp stp_end +step_en: + lda #1 + sta $C010 + jmp stp_end + +dis_step: + lda $C010 + bne step_dis + jmp stp_end +step_dis: + lda #0 + sta $C010 +stp_end: + jmp printc_end + back: lda #$7F sta $C001 dey ; Decrement buffer offset. lda #0 ; Put a null terminator, in place of the backspace. sta (ptr), y ; Place it into the input buffer. - lda #$44 dec scr_col - dec scr_lncnt jsl update_pos jmp printc_end ; Get next character. bs: lda scr_col ; Are we at the start of the buffer? - beq printc_end + beq back_wrap jmp back ; We are not, so add the backspace to the buffer. +back_wrap: + jsl getbit + bcs back_wrap1 + jmp printc_end +back_wrap1: + lda scr_row + beq back_wrap2 + jmp backwrp +back_wrap2: + lda scr_str + bne back_scrl + jmp printc_end +back_scrl: + clc + jsl scrl_up + inc scr_row +backwrp: + clc + lda scr_row + adc scr_str + tax +backwrp2: + dec scr_row + jsl clrbit + ldb #80 + stb scr_col + jsl update_pos + jmp back esc: lda $C000 ; Skip the '['. + lda $C002 + cmp #$1B + beq shftesc lda $C000 ; Get the next character. beq printc_end ; We have an error, so discard it, and go back to getting user input. lda $C002 ; Get the escape code. @@ -308,13 +451,9 @@ esc: lda #0 sta d jsl isup ; Check if the user pressed up. - lda e - bne esc_lnst lda d bne esc_end jsl isdown ; Check if the user pressed down. - lda e - bne esc_lnst lda d bne esc_end lda #0 @@ -322,61 +461,147 @@ esc: lda d bne esc_end jsl isright ; Check if the user pressed right. - jmp esc_end -esc_lnst: - lda scr_row - sta scr_rowst - mul #80 - sta.w scr_lnst esc_end: lda #0 sta d jmp printc_end ; Go back to getting user input. +shftesc: + lda $C000 ; Skip the '['. + lda $C000 ; Get the next character. + beq printc_end ; We have an error, so discard it, and go back to getting user input. + lda $C002 ; Get the escape code. + sta c ; Store the escape code, until we need it. + lda #0 + sta d + jsl isshftup ; Check if the user pressed shift+up. + lda d + bne shftesc_end + jsl isshftdown ; Check if the user pressed shift+down. +shftesc_end: + lda #0 + sta d + jmp printc_end ; Go back to getting user input. + isup: + lda c ; No, so load the escape code back into the accumulator. + cmp #$41 ; Did the user press the up arrow key? + bne isup_done ; Yes, so return. + lda #1 + sta d lda scr_row ; Is the cursor at the top of the screen? - beq isup_done ; Yes, so return. + beq isup_scrl ; Yes, so return. +isup_2: lda c ; No, so load the escape code back into the accumulator. cmp #$41 ; Did the user press the up arrow key? beq up ; Yes, so move the cursor up. + jmp isup_done +isup_scrl: + lda scr_str + beq isup_done + jsl scrl_up 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? + bne isdown_done lda scr_row ; Start checking the y coordinate of the cursor. cmp #23 ; Is the cursor at the bottom of the screen? - beq isdown_done ; Yes, so return. + beq isdown_scrl ; Yes, so return. lda c ; No, so load the escape code back into the accumulator. cmp #$42 ; Did the user press the down arrow key? beq down ; Yes, so move the cursor down. jmp isdown_done isdown_scrl: - lda #$1B ; Print an escape character - sta $C001 ; to the screen. - lda #$5B ; Print '[' - sta $C001 ; to the screen, and start the escape sequence. - lda #$54 ; Print 'T' - sta $C001 ; to the screen, and end the escape sequence. + lda scr_row + sta scr_trow + lda scr_col + sta scr_tcol + jsl scrl_down + lda scr_trow + sta scr_row + lda scr_tcol + sta scr_col isdown_done: rtl ; End of isdown. isright: - lda scr_col ; Start checking the x coordinate of the cursor. - cmp #79 ; Is the cursor at the far right of the screen? - beq isright_end ; Yes, so return. lda c ; No, so load the escape code back into the accumulator. cmp #$43 ; Did the user press the right arrow key? - beq right ; Yes, so move the cursor right. + bne isright_done + lda scr_col ; Start checking the x coordinate of the cursor. + cmp #79 ; Is the cursor at the far right of the screen? + beq isright_wrp ; Yes, so check if this is a wrapped line. + jmp right ; No, so move the cursor right, like normal. +isright_wrp: + inc scr_row + jsl getbit + bcs wrap_inc + dec scr_row + jmp isright_done +isright_scrl: + lda scr_str + beq isright_end + lda #1 + sta wrapped + jsl scrl_down + dec scr_row + jmp isright_end +wrap_inc: + lda #0 + sta scr_col + lda scr_row + cmp #23 + bcs isright_scrl isright_end: + jsl update_pos +isright_done: + lda #0 + sta wrapped rtl ; End of isright. isleft: + lda c + cmp #$43 + beq isleft_done lda scr_col ; Is the cursor at the far left of the screen? - beq isleft_done ; Yes, so return. + 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? beq left ; Yes, so move the cursor left. + jmp isleft_done +isleft_wrp: + jsl getbit + bcs wrap_dec + jmp isleft_done +wrap_dec: + lda scr_row + beq wrap_dec1 + lda #1 + sta wrapped + dec scr_row +wrap_dec1: + lda #79 + sta scr_col + lda #1 + sta d + lda scr_row + beq isleft_scrl + jmp isleft_end +isleft_scrl: + lda wrapped + bne isleft_end + lda scr_str + beq isleft_done + jsl scrl_up + jmp isleft_done +isleft_end: + jsl update_pos isleft_done: + lda #0 + sta wrapped rtl ; End of isleft. up: @@ -394,7 +619,7 @@ down: right: inc scr_col jsl update_pos - jmp isright_end + jmp isright_done left: dec scr_col jsl update_pos @@ -402,9 +627,52 @@ left: sta d jmp isleft_done +isshftup: + lda c ; Load the escape code back into the accumulator. + cmp #$41 ; Did the user press the up arrow key? + bne isshftup_done + lda #1 + sta d + lda scr_str + beq isshftup_done + jmp shftup +isshftup_done: + rtl + +isshftdown: + lda c ; Load the escape code back into the accumulator. + cmp #$42 ; Did the user press the down arrow key? + bne isshftdown_done + lda #1 + sta d + lda scr_end + cmp #71 + bcs isshftdown_done + jmp shftdown +isshftdown_done: + rtl + +shftup: + jsl scrl_up + lda #1 + sta d + jmp isshftup_done + +shftdown: + jsl scrl_down + lda #1 + sta d + jmp isshftdown_done + update_pos: + ldb #1 + stb f + clc lda scr_row + adc scr_str + clc mul #80 + clc adc scr_col tay lda #$1B ; Print an escape character @@ -432,13 +700,124 @@ getcol: sta $C001 ; 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 sta $C001 ; print to the screen. tba ; Get the remainder. + clc adc #$30 ; Convert it to ascii, and sta $C001 ; print to the screen. rtl ; End of getrow. +scrl_down: + + inc scr_str + inc scr_end + lda #$1B ; Print an escape character + sta $C001 ; to the screen. + lda #$5B ; Print '[' + sta $C001 ; to the screen, and start the escape sequence. + lda #$54 ; Print 'T' + sta $C001 ; to the screen, and end the escape sequence. + lda wrapped + beq scrldn_save +scrldn1: + jsl rdrw_row + lda wrapped + beq scrldn_load + jmp scrldn_end +scrldn_save: + lda scr_row + pha #1 + lda scr_col + pha #1 + jmp scrldn1 +scrldn_load: + pla #1 + sta scr_col + pla #1 + sta scr_row + jsl update_pos +scrldn_end: + lda #0 + sta wrapped +scrldn_done: + rtl + +scrl_up: + dec scr_str + dec scr_end + lda #$1B ; Print an escape character + sta $C001 ; to the screen. + lda #$5B ; Print '[' + sta $C001 ; to the screen, and start the escape sequence. + lda #$53 ; Print 'S' + sta $C001 ; to the screen, and end the escape sequence. + lda scr_row + pha #1 + lda scr_col + pha #1 + lda #0 + sta scr_row + jsl rdrw_row + pla #1 + sta scr_col + pla #1 + sta scr_row + jsl update_pos +scrlup_done: + rtl + +rdrw_row: + lda #0 + sta scr_col + jsl update_pos +rdrow_st: + lda (ptr), y + beq rdrow_inc + sta $C001 +rdrow_inc: + inc scr_col + lda (ptr), y + beq rdrow_skip + iny +rdrow_inc1: + lda scr_col + cmp #80 + bcs rdrow_end + jmp rdrow_st +rdrow_skip: + jsl update_pos + jmp rdrow_inc1 +rdrow_end: + lda #0 + sta scr_col + jsl update_pos +rdrow_done: + rtl + + +;rdrw_scr: +; lda #$C +; sta $C001 +; lda scr_col +; sta scr_tcol +; lda scr_row +; sta scr_trow +; lda #0 +; sta scr_col +; sta scr_row +; phy #2 +; jsl update_pos +; ply #2 +; ldx scr_ptr +; phy #2 +; txy +; lda (ptr), y +; sta $C001 +; ply #2 +; rtl + result: phy #2 txy @@ -461,9 +840,9 @@ dabbed: lda (cptr), y ; Get a character from the input buffer. beq dab_pend ; Are we done with printing the buffer? cmp (tptr), y - bcs dab_pend - beq chk_str bcc dab_pend + beq chk_str + bcs dab_pend chk_str: ply #2 inx @@ -517,6 +896,5 @@ cmd_clr: .qword spin .qword spin .qword spin -.org $FF50 done |