From cd6982e5da1f5facdc1e0154b3a27c01e8b076c9 Mon Sep 17 00:00:00 2001 From: mrb0nk500 Date: Wed, 27 Jan 2021 13:42:57 -0500 Subject: - Fixed some bugs in the emulator. - Started work on implementing the Super VIA emulation. - Added support for disabling disassembly per instruction, when in debug mode. - Did some more work on rewriting the SuB Suite to work with the new calling convention. - Rewrote the symbol handling code in the emulator's assembler, to make it both simpler, and to add support for arbitrarily deep symbol scopes. - Added support for arbitrarily deep local symbol scopes. For example, to declare a symbol of depth 2, you add two '@' characters to the start of the symbol name. In other words, the number of '@' characters before the symbol name is what determines the scope of that symbol. And to use a symbol thats outside the current scope, you would use the same syntax as using a struct member, so you would do `global.local`. --- programs/sub-suite/subasm.s | 361 ++++++++++++++++++++++++++++---------------- 1 file changed, 234 insertions(+), 127 deletions(-) (limited to 'programs/sub-suite/subasm.s') diff --git a/programs/sub-suite/subasm.s b/programs/sub-suite/subasm.s index 80aaa47..f22ee60 100644 --- a/programs/sub-suite/subasm.s +++ b/programs/sub-suite/subasm.s @@ -3,153 +3,260 @@ ; ; by mr b0nk 500 +;subasm: +; ldb #0 ; Set the first pointer +; lda.q cmd_buf ; to the command buffer. +; jsr set_ptr ; +; tba ; Reset A. +; tax ; Reset X. +; jsr chk_shcmd ; Did we get a shortend command? +; bne @cmd ; Yes, so skip everything else. +; jsr chk_cmd ; No, but did we get a full command? +; bne @cmd ; Yes, so skip everything else. +; jsr lex ; No, so start lexing this line. +; bra @end ; We are done. +;@cmd: +; lda regf ; Get the command ID. +; cmp #8 ; Is the command ID greater than the command count? +; bcs @end ; Yes, so we're done. +; lsl #1 ; No, so multiply the command ID by two. +; phx.q ; Preserve X. +; tax ; Set the index to the offset that we just calculated. +; lea.w (cmd_srt, x); Get the pointer, from the command subroutine table. +; plx.q ; Restore X. +; and #0 ; Reset A. +; tab ; Reset B. +; jsr (e) ; Run the command's subroutine. +;@end: +; and #0 ; Reset A. +; jsr update_ptr ; Get the screen buffer index. +; tay ; Save it in Y. +; and #0 ; Reset A. +; rts ; End of subasm. +; +;chk_shcmd: +; and #0 ; Reset A. +; tab ; Reset B. +;; inb ; Set the second pointer +;; lda.w #sh_cmds ; to the shortend command table. +;; jsr set_ptr ; +;; deb ; Reset B. +;; tba ; Reset A. +; lea sh_cmds ; Get the address of the short command table. +; phy.w ; Preserve the screen buffer position. +; txy ; Set our index to zero. +; lda (ptr), y ; Is there nothing in the command buffer? +; beq @false ; Yes, so return that we failed. +; cmp #' ' ; No, but is this character, a space? +; beq @false ; Yes, so return that we failed. +; jsr tolower ; No, so convert it to lowercase. +;@loop: +;; ldb (ptr2), y ; Are we at the end of the table? +; ldb (e) ; Are we at the end of the table? +; beq @false ; Yes, so return that we failed. +; cmp b ; No, so did the character match? +; beq @found ; Yes, so check if there are any arguments. +; ine ; No, so check the next command. +; iny ; +; bra @loop ; Keep looping. +;@found: +; sty regf ; Save the command ID. +; lea (ptr) ; Get the address of the next character. +; ine ; +;; ldy #1 ; Check the next character in the command buffer. +;; lda (ptr), y ; Is this the end of the buffer? +; lda (e) ; Is this the end of the buffer? +; beq @true ; Yes, so return true. +; cmp #' ' ; No, but is this a space? +; beq @true ; Yes, so return true. +;@false: +; ldb #0 ; Reset B. +; tba ; Return false. +; tax ; Reset X. +; bra @end ; We are done. +;@true: +; lda #1 ; Return true. +;@end: +; ply.w ; Get back the screen buffer position. +; rts ; End of chk_shcmd. +; +; +;chk_cmd: +; and #0 ; Reset A. +; tab ; Reset B. +; tax ; Reset X. +; sta.q idx0 ; Reset the first index. +; sta.q idx1 ; Reset the second index. +; mov.q ptr, d ; Set the first pointer to the command buffer. +;@loop: +; lda.w #cmds ; Get pointer to the start of the command table. +; add.w idx0 ; Offset the pointer, by the length of the previous string. +; pha.q ; Preserve the command string pointer. +; jsr strcaseg ; Is the command buffer, the same as the command string? +; pla.q ; Get the command string pointer back. +; beq @true ; Yes, so return true. +; ldb idx1 ; No, so Get the command ID. +; cpb #7 ; Have we reached the end of the command table? +; beq @false ; Yes, so return false. +; inc idx1 ; No, so increment the command ID. +;@getlen: +; mov d, a ; Get the string. +; jsr strlen ; Get the string's length. +; inc ; Add one to the length. +; add.w idx0, a ; Add the string offset to the current length +; bra @loop ; Keep looping. +;@true: +; ldb idx1 ; Get the command ID. +; stb regf ; Return the command ID. +; ldb #1 ; Return true. +; bra @end ; We are done. +;@false: +; ldb #0 ; Return false. +;@end: +; rts ; End of chk_cmd. + + subasm: - ldb #0 ; Set the first pointer - lda.q cmd_buf ; to the command buffer. - jsr set_ptr ; - tba ; Reset A. - tax ; Reset X. - jsr chk_shcmd ; Did we get a shortend command? - bne @cmd ; Yes, so skip everything else. - jsr chk_cmd ; No, but did we get a full command? - bne @cmd ; Yes, so skip everything else. - jsr lex ; No, so start lexing this line. - bra @end ; We are done. + pha.q ; Preserve A. + phe.q ; Preserve E. + des ; Make room for the command id. + and #0 ; Reset A. + lea d, (cmd_buf) ; Get the command buffer. + lea s, (sp+1) ; Get the pointer to the command id. + jsr chk_shcmd ; Did we get a shortend command? + bne @cmd ; Yes, so skip everything else. + jsr chk_cmd ; No, but did we get a full command? + bne @cmd ; Yes, so skip everything else. + mov.q ptr, d ; + jsr lex ; No, so start lexing this line. + bra @end ; We are done. @cmd: - lda regf ; Get the command ID. - cmp #8 ; Is the command ID greater than the command count? - bcs @end ; Yes, so we're done. - lsl #1 ; No, so multiply the command ID by two. - phx.q ; Preserve X. - tax ; Set the index to the offset that we just calculated. - lea.w (cmd_srt, x); Get the pointer, from the command subroutine table. - plx.q ; Restore X. - and #0 ; Reset A. - tab ; Reset B. - jsr (e) ; Run the command's subroutine. + mov s, (s) ; Get the command ID. + cmp s, #7 ; Is the command ID greater than the command count? + bcs @end ; Yes, so we're done. + lsl s, #1 ; No, so multiply the command ID by two. + lea.w e, (cmd_srt+s) ; Get the pointer, from the command subroutine table. + and #0 ; Reset A. + tab ; Reset B. + jsr (e) ; Run the command's subroutine. @end: - and #0 ; Reset A. - jsr update_ptr ; Get the screen buffer index. - tay ; Save it in Y. - and #0 ; Reset A. - rts ; End of subasm. + and #0 ; Reset A. + jsr update_ptr ; Get the screen buffer index. + tay ; Save it in Y. + ins ; Cleanup the stack frame. + ple.q ; Restore E. + pla.q ; Restore A. + rts ; End of subasm. + chk_shcmd: - and #0 ; Reset A. - tab ; Reset B. -; inb ; Set the second pointer -; lda.w #sh_cmds ; to the shortend command table. -; jsr set_ptr ; -; deb ; Reset B. -; tba ; Reset A. - lea sh_cmds ; Get the address of the short command table. - phy.w ; Preserve the screen buffer position. - txy ; Set our index to zero. - lda (ptr), y ; Is there nothing in the command buffer? - beq @false ; Yes, so return that we failed. - cmp #' ' ; No, but is this character, a space? - beq @false ; Yes, so return that we failed. - jsr tolower ; No, so convert it to lowercase. + phb.q ; Preserve B. + lea b, sh_cmds ; Get the address of the short command table. + mov a, (d) ; Is the string empty? + beq @false ; Yes, so return that we failed. + cmp #' ' ; No, but is this character, a space? + beq @false ; Yes, so return that we failed. + jsr tolower ; No, so convert it to lowercase. @loop: -; ldb (ptr2), y ; Are we at the end of the table? - ldb (e) ; Are we at the end of the table? - beq @false ; Yes, so return that we failed. - cmp b ; No, so did the character match? - beq @found ; Yes, so check if there are any arguments. - ine ; No, so check the next command. - iny ; - bra @loop ; Keep looping. + cmp (b), #0 ; Are we at the end of the table? + beq @false ; Yes, so return that we failed. + cmp a, (b) ; No, so did the character match? + beq @found ; Yes, so check if there are any arguments. + inb ; No, so check the next command. + bra @loop ; Keep looping. @found: - sty regf ; Save the command ID. - lea (ptr) ; Get the address of the next character. - ine ; -; ldy #1 ; Check the next character in the command buffer. -; lda (ptr), y ; Is this the end of the buffer? - lda (e) ; Is this the end of the buffer? - beq @true ; Yes, so return true. - cmp #' ' ; No, but is this a space? - beq @true ; Yes, so return true. + sub.w b, #sh_cmds ; Get the command ID. + mov (s), b ; Save the command ID. + mov a, (d+1) ; Is this the end of the string? + beq @true ; Yes, so return true. + cmp #' ' ; No, but is this a space? + beq @true ; Yes, so return true. @false: - ldb #0 ; Reset B. - tba ; Return false. - tax ; Reset X. - bra @end ; We are done. + and #0 ; Return false. + bra @end ; We are done. @true: - lda #1 ; Return true. + lda #1 ; Return true. @end: - ply.w ; Get back the screen buffer position. - rts ; End of chk_shcmd. + plb.q ; Restore B. + rts ; End of chk_shcmd. chk_cmd: - tba ; Reset A. - tax ; Reset X. - sta.q idx0 ; Reset the first index. - sta.q idx1 ; Reset the second index. + phb.q ; Preserve B. + phx.q ; Preserve X. + phy.q ; Preserve Y. + and #0 ; Reset A. + tab ; Reset B. + mov x, s ; Preserve the command ID pointer. + mov y, d ; Preserve the string pointer. + lea s, cmds ; Get pointer to the start of the command table. @loop: - lda.w #cmds ; Get pointer to the start of the command table. - clc ; Prepare for a non carrying add. - adc.w idx0 ; Offset the pointer, by the length of the previous string. - pha.q ; Preserve the command string pointer. - jsr strcaseg ; Is the command buffer, the same as the command string? - pla.q ; Get the command string pointer back. - beq @true ; Yes, so return true. - ldb idx1 ; No, so Get the command ID. - cpb #7 ; Have we reached the end of the command table? - beq @false ; Yes, so return false. - inc idx1 ; No, so increment the command ID. + jsr strcasecmp ; Is the command buffer, the same as the command string? + beq @true ; Yes, so return true. + inb ; No, so increment the command ID. + cpb #7 ; Have we reached the end of the command table? + bcs @false ; Yes, so return false. @getlen: - jsr strlen ; Get the string's length. - inc ; Add one to the length. - clc ; Prepare for a non carrying add. - adc.w idx0 ; Add the string offset to the current length - sta.w idx0 ; Save the offset in the first index. - bra @loop ; Keep looping. + mov d, s ; Get the command table string. + jsr strlen ; Get the string's length. + mov d, y ; Restore the string pointer. + inc ; Add one to the length. + add s, a ; Add the string offset to the current length + bra @loop ; Keep looping. @true: - ldb idx1 ; Get the command ID. - stb regf ; Return the command ID. - ldb #1 ; Return true. - bra @end ; We are done. + lda #1 ; Return true. + bra @end ; We are done. @false: - ldb #0 ; Return false. + lda #0 ; Return false. @end: - rts ; End of chk_cmd. + mov s, x ; Restore the command ID pointer. + mov (s), b ; Save the command ID. + and a, a ; Set the flags accordingly. + ply.q ; Restore Y. + plx.q ; Restore X. + plb.q ; Restore B. + rts ; End of chk_cmd. + viewmem: - lda.q prg_cnt ; Get the program counter. - sta.q idx0 ; Save the address in the first index. - and #$F0 ; Clear the first four bits of the address. - sta idx0 ; Overwrite the first byte, with the masked byte. - lda #19 ; Move the cursor to the right, by 19 columns. - sta scr_col ; - jsr update_pos ; - jsr print_lo ; Print the low nibble offsets. - ldx #0 ; Reset X. - ldb #0 ; Reset B. - stb idx1 ; Reset the byte count. + pha.q ; Preserve A. + phb.q ; Preserve B. + phx.q ; Preserve X. + sbs #$50 ; Make room for the string buffer. + and #0 ; Reset A. + tab ; Reset B. + ldx.q prg_cnt ; Get the program counter. + lda #19 ; Move the cursor to the right, by 19 columns. + sta scr_col ; + jsr update_pos ; + jsr print_lo ; Print the low nibble offsets. @loop: - lda #'\n' ; Print a newline. - jsr print_char ; - jsr print_hi ; Place the address in the string buffer. - jsr print_chunk ; Place the next 16 bytes in the string buffer. - lea strbuf ; Print the string buffer. -; jsr print_str ; - jsr print_sfast ; - inc idx1 ; Increment the chunk count. - ldb idx1 ; Get the chunk count. - cpb #$10 ; Did we print 16 chunks? - beq @end ; Yes, so we're done. - lda.q idx0 ; No, so get the address index. - clc ; Prepare for a non carrying add. - adc #$10 ; Add 16 to the address. - sta.q idx0 ; Put it back into the address. - and #0 ; Reset A. - bra @loop ; Keep looping. + lda #'\n' ; Print a newline. + jsr print_char ; + lea d, (sp+1) ; Get the address of the string buffer. + mov s, x ; Get the program counter. + jsr print_hi ; Print the address to the string buffer. + mov d, a ; Get the string buffer pointer after the printed address. + mov s, x ; Get the program counter. + jsr print_chunk ; Print the next 16 bytes to the string buffer. + lea d, (sp+1) ; Get the address of the string buffer. + lea s, (buffer)+y ; Get the address of the screen buffer, at the current cursor position. +; jsr print_str ; Print the string buffer. + jsr print_sfast ; + inb ; Increment the chunk count. + cpb #$10 ; Did we print 16 chunks? + beq @end ; Yes, so we're done. + add x, #$10 ; No, so add 16 to the address. + and #0 ; Reset A. + bra @loop ; Keep looping. @end: - lda #'\n' ; Print a newline. - jsr print_char ; - and #0 ; Reset A. - rts ; End of viewmem. + lda #'\n' ; Print a newline. + jsr print_char ; + ads #$50 ; Cleanup the stack frame. + plx.q ; Restore X. + plb.q ; Restore B. + pla.q ; Restore A. + rts ; End of viewmem. list: @@ -164,10 +271,10 @@ help: nop ; @end: rts ; End of help. -inst: +instruction: nop ; @end: - rts ; End of inst. + rts ; End of instruction. run: nop ; @end: -- cgit v1.2.3-13-gbd6f