; SuBAsm ; The Sux Bootstrapped Assembler. ; ; 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: pha.q ; Preserve A. 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 ; psh d ; Preserve D. psh s ; Preserve S. psh f ; Preserve F. jsr lex ; No, so start lexing this line. pul d ; Restore D. pul s ; Restore S. pul f ; Restore F. bra @end ; We are done. @cmd: 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 s, (cmd_srt+s) ; Get the pointer, from the command subroutine table. lea b, cmd_srt ; No, so get the address of the command subroutine table. mov.w s, (b+2*s) ; Get the pointer, from the command subroutine table. and #0 ; Reset A. tab ; Reset B. jsr s ; Run the command's subroutine. @end: and #0 ; Reset A. jsr update_ptr ; Get the screen buffer index. tay ; Save it in Y. ins ; Cleanup the stack frame. pla.q ; Restore A. rts ; End of subasm. chk_shcmd: 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: 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: 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: and #0 ; Return false. bra @end ; We are done. @true: lda #1 ; Return true. @end: plb.q ; Restore B. rts ; End of chk_shcmd. chk_cmd: 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: 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: 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: lda #1 ; Return true. bra @end ; We are done. @false: lda #0 ; Return false. @end: 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: 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 ; 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 ; ads #$50 ; Cleanup the stack frame. plx.q ; Restore X. plb.q ; Restore B. pla.q ; Restore A. rts ; End of viewmem. list: nop ; @end: rts ; End of list. asm: nop ; @end: rts ; End of asm. help: nop ; @end: rts ; End of help. instruction: nop ; @end: rts ; End of instruction. run: nop ; @end: rts ; End of run. set_val: nop ; @end: rts ; End of set_val.