From 071edf621a6722f94027f37720a5a5f73d9696c0 Mon Sep 17 00:00:00 2001 From: mrb0nk500 Date: Tue, 17 Mar 2020 15:07:20 -0400 Subject: Revamped the opcode table, made the emulator more efficient, and ported SuBEditor to C. I revamped the opcode table to add another prefix bit for the addressing mode, finally giving access to all addresses, without wasting any bytes. I made the stack based operations more efficient, by sort of applying Duff's device to it. And I ported SuBEditor to C, to make it easier for me to figure out how to implement SuBAsm. --- programs/subeditor.s | 509 +++++++++++++++++++++++++++++---------------------- 1 file changed, 290 insertions(+), 219 deletions(-) (limited to 'programs/subeditor.s') diff --git a/programs/subeditor.s b/programs/subeditor.s index 159dc1f..5769936 100644 --- a/programs/subeditor.s +++ b/programs/subeditor.s @@ -3,13 +3,28 @@ ; Writen in Sux assembly by ; mr b0nk 500 -; Instruction mnemonics, -; and opcodes. +; String Literals/Constants. .org $1000 tok: .byte "dab" msg: .byte "oof, you divided a, and b on me.\n" +string: + .byte "Please, type something.\n" +string2: + .byte "You typed, " + +; Linewrap bitmask table. +.org $1100 +bits: + .byte $80 + .byte $40 + .byte $20 + .byte $10 + .byte $08 + .byte $04 + .byte $02 + .byte $01 ; Input buffer. .org $2000 @@ -31,6 +46,7 @@ scr_tcol: .byte $0 scr_ptr: .word $0 +; Registers. a: .byte $0 b: @@ -43,21 +59,12 @@ e: .byte $0 f: .byte $0 -string: - .byte "Please, type something.\n" -string2: - .byte "You typed, " +; This register is always zero. +zero: + .qword $0 +; End of registers. end: .byte $0 -bits: - .byte $80 - .byte $40 - .byte $20 - .byte $10 - .byte $08 - .byte $04 - .byte $02 - .byte $01 bitmask: .byte $0 bitabl: @@ -72,13 +79,17 @@ wrapped: ; Pointers ptr: - .qword buffer -cptr: - .qword cmd_buf -tptr: - .qword tok -mptr: - .qword msg + .qword $0 +ptr2: + .qword $0 +ptr3: + .qword $0 +ptr4: + .qword $0 +ptr5: + .qword $0 +ptr6: + .qword $0 ; Main program .org $8000 @@ -87,44 +98,93 @@ reset: ldx.w #$FFFF txs ldy #0 + tyx lda #23 sta scr_end - lda #0 + lda.w #buffer + sta.q ptr5 + lda.w #cmd_buf + sta.q ptr6 + tya sta scr_str - ldx #8 sta.q bitabl - sta.q bitabl, x - tax + sta.q bitabl+8 jsl clr_buf jmp start clr_buf: - lda #0 + phb #1 + ldb #0 +clr_buf_st: cpy.w #$1FFF - beq clr_buf_end - sta (ptr), y - iny - jmp clr_buf + bcs clr_buf_end + sta.q (ptr5), y + tya + adc #8 + tay + tba + sta.q (ptr5), y + tya + adc #8 + tay + tba + sta.q (ptr5), y + tya + adc #8 + tay + tba + sta.q (ptr5), y + tya + adc #8 + tay + tba + jmp clr_buf_st clr_buf_end: - ldy.w #0 + ldy.w zero + plb #1 rtl start: lda #0 - tax sta $C000 + tax phy #2 - ldy.w #0 + tay jsl clr_cbuf ply #2 - jmp print + lda.w #string + jsl print_str + lda.w zero + jmp rset_a clr_cbuf: + phb #1 + ldb #0 +clr_cbuf_st: cpy.w #$3FF - beq clr_cbuf_end - sta (cptr), y - iny - jmp clr_cbuf + bcs clr_cbuf_end + sta.q (ptr6), y + tya + adc #8 + tay + tba + sta.q (ptr6), y + tya + adc #8 + tay + tba + sta.q (ptr6), y + tya + adc #8 + tay + tba + sta.q (ptr6), y + tya + adc #8 + tay + tba + jmp clr_cbuf_st clr_cbuf_end: + plb #1 rtl pull_y: @@ -140,15 +200,23 @@ read: 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: +print_str: + sta.q ptr + ldb #0 + tba +pntstr_st: phy #2 txy - lda string, y ; Get character at offset x. - beq pull_y ; Did we find a null terminator? + lda (ptr), y ; Get character at offset x. + beq pntstr_end ; Did we find a null terminator? ply #2 inx jsl print_char - jmp print + jmp pntstr_st +pntstr_end: + ply #2 + rtl + getbit: clc @@ -167,12 +235,6 @@ getbt1: cmp #1 jmp bitout -;putbit: -; ldx scr_row -;putbt1: -; bcc setbit - - clrbit: jsl bitpos xor #$FF @@ -191,11 +253,19 @@ setbit: jmp bitsav bitpos: + pha #1 + lda.w #bits + sta.q ptr3 + lda.w zero + pla #1 stx bitmask txa and #7 + phy #2 + tay tax - lda bits, x + lda (ptr3), y + ply #2 pha #1 lda bitmask lsr #3 @@ -240,11 +310,11 @@ cmd_cpy: tay ldx.w #$0 cmd_cpy_strt: - lda (ptr), y + lda (ptr5), y beq getchar_pnt phy #2 txy - sta (cptr), y + sta (ptr6), y inx ply #2 iny @@ -294,7 +364,7 @@ print_char: sta a printc: lda a - sta (ptr), y ; Store typed character into the input buffer. + sta (ptr5), y ; Store typed character into the input buffer. inc scr_col ; Increment the cursor's x coordinate. iny printc_2: @@ -344,7 +414,7 @@ printc_end: nl: lda #0 - sta (ptr), y ; Store said terminator into the input buffer. + sta (ptr5), y ; Store said terminator into the input buffer. sta scr_col lda scr_row cmp #23 @@ -365,11 +435,12 @@ clr_scr: sta scr_end lda #0 sta scr_str - ldx #8 sta.q bitabl - sta.q bitabl, x + sta.q bitabl+8 tay jsl clr_buf + tay + jsl clr_cbuf sta scr_col sta scr_row jsl update_pos @@ -397,73 +468,73 @@ 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. + lda #$7F ; Print a backspace to the screen. + sta $C001 ; + dey ; Decrement the buffer's offset. + lda #0 ; Place a null terminator + sta (ptr5), y ; into the buffer. + dec scr_col ; Move the cursor back by one column, + jsl update_pos ; and update it's position. + jmp printc_end ; We are done. 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. + lda scr_col ; Are we at the far left of the screen? + beq back_wrap ; Yes, so check for a wrapped line. + jmp back ; No, so add the backspace to the buffer. back_wrap: - jsl getbit - bcs back_wrap1 - jmp printc_end + jsl getbit ; Is this line, a wrapped line? + bcs back_wrap1 ; Yes, so check if the cursor is at the top. + jmp printc_end ; No, so we're done. back_wrap1: - lda scr_row - beq back_wrap2 - jmp backwrp + lda scr_row ; Are we at the top of the screen? + beq back_wrap2 ; Yes, so check if the screen is at the top of the buffer. + jmp backwrp ; No, so start clearing the wrap bit. back_wrap2: - lda scr_str - bne back_scrl - jmp printc_end + lda scr_str ; Are we at the top of the buffer? + bne back_scrl ; Yes, so scroll up. + jmp printc_end ; No, so we're done. back_scrl: - clc - jsl scrl_up - inc scr_row + clc ; Clear the carry flag, so that we don't get odd behaviour. + jsl scrl_up ; Scroll up. + inc scr_row ; Move down by one row. backwrp: - clc - lda scr_row - adc scr_str - tax + clc ; Clear the carry flag. + lda scr_row ; Add the cursor's row position, + adc scr_str ; and the screen's starting row. + tax ; Transfer that into X. backwrp2: - dec scr_row - jsl clrbit - ldb #80 - stb scr_col - jsl update_pos - jmp back + dec scr_row ; Move up by one row. + jsl clrbit ; Clear the wrap bit for this row. + ldb #80 ; Move the cursor to the absolute right of the screen. + stb scr_col ; + jsl update_pos ; Update the cursor's position. + jmp back ; Delete the previous character. esc: - lda $C000 ; Skip the '['. - lda $C002 - cmp #$1B - beq shftesc lda $C000 ; Get the next character. + lda $C002 ; + cmp #$1B ; Is this character an escape character? + beq shftesc ; Yes, so check the other set of escape routines. + lda $C000 ; No, so wait for 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 + lda #0 ; Set the D pseudo register to zero. + 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. + lda d ; Did the user press up? + bne esc_end ; Yes, so we're done. + jsl isdown ; No, so check if the user pressed down. + lda d ; Did the user press down? + bne esc_end ; Yes, so we're done. + lda #0 ; No, so check if the user pressed left. + jsl isleft ; + lda d ; Did the user press left? + bne esc_end ; Yes, so we're done. + jsl isright ; No, so check if the user pressed right. esc_end: - lda #0 - sta d + lda #0 ; Set the D pseudo register to zero. + sta d ; jmp printc_end ; Go back to getting user input. shftesc: @@ -472,34 +543,32 @@ shftesc: 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 + lda #0 ; + sta d ; jsl isshftup ; Check if the user pressed shift+up. - lda d - bne shftesc_end + lda d ; + bne shftesc_end ; jsl isshftdown ; Check if the user pressed shift+down. shftesc_end: - lda #0 - sta d + 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. + bne isup_done ; Yes, so we're done. + lda scr_row ; No, so is the cursor at the top of the screen? + beq isup_scrl ; Yes, so check if we need to scroll. isup_2: lda c ; No, so load the escape code back into the accumulator. cmp #$41 ; Did the user press the up arrow key? beq up ; Yes, so move the cursor up. - jmp isup_done + jmp isup_done ; No, so we're done isup_scrl: - lda scr_str - beq isup_done - jsl scrl_up + lda scr_str ; Are we at the top of the screen buffer? + beq isup_done ; Yes, so we're done. + jsl scrl_up ; No, so scroll up. isup_done: rtl ; End of isup. @@ -515,51 +584,53 @@ isdown: 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 + lda scr_row ; Save the cursor's row number. + sta scr_trow ; + lda scr_col ; Save the cursor's column number. + sta scr_tcol ; + jsl scrl_down ; Scroll down. + lda scr_trow ; Load the cursor's row number. + sta scr_row ; + lda scr_tcol ; Load the cursor's column number. + 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. + bne isright_dne ; No, so we're done. + lda scr_col ; Yes, so 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 + inc scr_row ; Move down a row. + jsl getbit ; Is the current line, a wrapped line? + bcs wrap_inc ; Yes, so leave the cursor where it is. + dec scr_row ; No, so move the cursor back up a row. + jmp isright_dne ; We are done. +isright_scr: + lda scr_str ; Are we at the top of the screen buffer? + beq isright_end ; Yes, so we're done. + lda #1 ; No, so scroll down. + sta wrapped ; Set the wrapped flag. + jsl scrl_down ; Scroll down. + jmp isright_end ; We are done. wrap_inc: - lda #0 - sta scr_col - lda scr_row - cmp #23 - bcs isright_scrl + lda #0 ; Set the cursor to the far left of the screen. + sta scr_col ; + lda scr_row ; Get the current row number. + cmp #23 ; Are we at the bottom of the screen? + bcs isright_scr ; Yes, so check if we are scrolling down. + jmp isright_nd2 ; We are done. isright_end: - jsl update_pos -isright_done: - lda #0 - sta wrapped + dec scr_row ; Move back up a row. +isright_nd2: + jsl update_pos ; Update the cursor position. +isright_dne: + lda #0 ; Unset the wrapped flag. + sta wrapped ; rtl ; End of isright. isleft: @@ -571,37 +642,37 @@ isleft: 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 + jmp isleft_done ; We are done. isleft_wrp: - jsl getbit - bcs wrap_dec - jmp isleft_done + jsl getbit ; Is the current line, a wrapped line? + bcs wrap_dec ; Yes, so wrap back up a line. + jmp isleft_done ; No, so return. wrap_dec: - lda scr_row - beq wrap_dec1 - lda #1 - sta wrapped - dec scr_row + lda scr_row ; Is the cursor at the top of the screen? + beq wrap_dec1 ; Yes, so don't move up a row. + lda #1 ; No, so move up a row. + sta wrapped ; Set the wrapped flag. + dec scr_row ; Move the cursor up by one row. wrap_dec1: - lda #79 - sta scr_col - lda #1 - sta d - lda scr_row - beq isleft_scrl - jmp isleft_end + lda #79 ; Move the Cursor to the far right of the screen. + sta scr_col ; + lda #1 ; Tell the escape routine to stop after this. + sta d ; + lda scr_row ; Are we at the top of the screen? + beq isleft_scrl ; Yes, so check if we need to scroll. + jmp isleft_end ; No, so we're done. isleft_scrl: - lda wrapped - bne isleft_end - lda scr_str - beq isleft_done - jsl scrl_up - jmp isleft_done + lda wrapped ; Was the wrapped flag set somewhere else? + bne isleft_end ; Yes so we're done. + lda scr_str ; No, but are we actually at the top of the screen buffer? + beq isleft_done ; Yes, so we're done. + jsl scrl_up ; No, so scroll up. + jmp isleft_done ; We are done. isleft_end: - jsl update_pos + jsl update_pos ; Update the cursor position. isleft_done: - lda #0 - sta wrapped + lda #0 ; Unset the wrapped flag. + sta wrapped ; rtl ; End of isleft. up: @@ -619,7 +690,7 @@ down: right: inc scr_col jsl update_pos - jmp isright_done + jmp isright_dne left: dec scr_col jsl update_pos @@ -773,12 +844,12 @@ rdrw_row: sta scr_col jsl update_pos rdrow_st: - lda (ptr), y + lda (ptr5), y beq rdrow_inc sta $C001 rdrow_inc: inc scr_col - lda (ptr), y + lda (ptr5), y beq rdrow_skip iny rdrow_inc1: @@ -819,68 +890,54 @@ rdrow_done: ; 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.w #string2 + ldx.w zero + jsl print_str +rset_x: lda #0 ; Reset a. - tax ; Reset y. + tax ; Reset x. jmp print_buf ; Print the input buffer. dabbed: + ldb #0 + lda.w #tok + sta.q ptr2 + tba +dab_st: phy #2 txy - lda (cptr), y ; Get a character from the input buffer. + lda (ptr6), y ; Get a character from the input buffer. beq dab_pend ; Are we done with printing the buffer? - cmp (tptr), y - bcc dab_pend + cmp (ptr2), y beq chk_str - bcs dab_pend + jmp dab_pend chk_str: ply #2 inx cpx #3 - bne dabbed + bne dab_st 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. + lda.w #msg + ldx #0 + stx.q ptr + jsl print_str + jmp dab_peqnd 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. - + lda.w #cmd_buf + jsl print_str + lda.w zero cmd_clr: - ply #2 lda #10 jsl print_char jmp start @@ -896,5 +953,19 @@ cmd_clr: .qword spin .qword spin .qword spin +r +;.org $8000 +;v +;.org $8100 +;v +;.org $8200 +;v +;.org $8300 +;v +;.org $8400 +;v +;.org $8500 +;v +;q done -- cgit v1.2.3-13-gbd6f