diff options
Diffstat (limited to 'programs/subasm.s')
-rw-r--r-- | programs/subasm.s | 1019 |
1 files changed, 457 insertions, 562 deletions
diff --git a/programs/subasm.s b/programs/subasm.s index 50f2e8d..350e105 100644 --- a/programs/subasm.s +++ b/programs/subasm.s @@ -3,576 +3,471 @@ ; ; by mr b0nk 500 <b0nk@b0nk.xyz> -; Variables -.org $1000 -prg_name: +MAX_SYM = $800 ; Max symbol size. + +.org incl +; String Constants. +asm_name: .byte "SuBAsm" -ver_txt: - .byte ", version " -ver_num: +asm_ver: .byte "0.1" ; Directives. dir: - .byte "org" + .byte "org", .byte "byte" .byte "word" .byte "dword" .byte "qword" + .byte "include" + +; Short form Commands. +sh_cmds: + .byte "vlahirs" + +; Commands. +cmds: + .byte "viewmem" + .byte "list" + .byte "asm" + .byte "help" + .byte "inst" + .byte "run" + .byte "set" + +; Instruction mnemonics, and opcodes. + +; Legend. +; mne = Mnemonic. +; imm = Immediate data. +; zm = Zero Matrix. +; zmx = Zero Matrix, indexed with X. +; zmy = Zero Matrix, indexed with Y. +; ind = Indirect. +; idx = Indexed Indirect. +; idy = Indirect Indexed. +; abs = Absolute. +; imp = Implied. -; Instruction mnemonics. mne: - .byte "CPS" - .byte "ADC" - .byte "AAB" - .byte "PHB" - .byte "PHP" - .byte "PHA" - .byte "PHY" - .byte "TAY" - .byte "PHX" - .byte "TAX" - .byte "TYX" - .byte "JMP" - .byte "SBC" - .byte "SAB" - .byte "PLB" - .byte "PLP" - .byte "PLA" - .byte "PLY" - .byte "TYA" - .byte "PLX" - .byte "TXA" - .byte "TXY" - .byte "JSR" - .byte "AND" - .byte "ABA" - .byte "STT" - .byte "TAB" - .byte "TSX" - .byte "BPO" - .byte "ORA" - .byte "OAB" - .byte "TBA" - .byte "SEI" - .byte "TXS" - .byte "BNG" - .byte "XOR" - .byte "XAB" - .byte "CLI" - .byte "BCS" - .byte "LSL" - .byte "LLB" - .byte "STB" - .byte "SEC" - .byte "STA" - .byte "STY" - .byte "STX" - .byte "BCC" - .byte "LSR" - .byte "LRB" - .byte "LDB" - .byte "CLC" - .byte "LDA" - .byte "LDY" - .byte "LDX" - .byte "BEQ" - .byte "ROL" - .byte "RLB" - .byte "SSP" - .byte "BNE" - .byte "ROR" - .byte "RRB" - .byte "CSP" - .byte "BVS" - .byte "MUL" - .byte "MAB" - .byte "SEV" - .byte "BVC" - .byte "DIV" - .byte "DAB" - .byte "CLV" - .byte "RTS" - .byte "CMP" - .byte "CAB" - .byte "CPY" - .byte "CPX" - .byte "CPB" - .byte "ENT" - .byte "RTI" - .byte "INC" - .byte "IAB" - .byte "INY" - .byte "INX" - .byte "DEC" - .byte "DBA" - .byte "DEY" - .byte "DEX" - .byte "WAI" - .byte "JSL" - .byte "ASR" - .byte "ARB" - .byte "NOP" - .byte "RTL" - .byte "BRK" - - -scr_row: - .byte $0 -scr_col: - .byte $0 -a: - .word $0 -b: - .word $0 -c: - .word $0 -d: - .word $0 - -str_buf: - -; Input buffer. -.org $2000 -buf: - -.org $2400 -ptr1: - .qword $2500 - -ptr2: - .qword $2900 - -; Control Register. -.org $C000 -ctrl_reg: - -; Screen. -.org $C001 -scr: - -; Keyboard. -.org $C002 -kbd: - -; Main program. -.org $0 -reset: - cps - ldx.w #$FFFF - txs - ldy #0 - jsr clr_buf - ldx.w #0 ; Reset x. - ldy #0 ; Reset y. - jmp print_title - -read: - lda ctrl_reg ; Is the keyboard ready? - beq read ; Loop until the keyboard is ready. - lda #0 ; Start resetting the control register. - sta ctrl_reg ; Reset the control register. - jmp getchar ; We got a key. - -rset_x: - - ldx #0 ; Reset x. - stx.w x - rts - -print_title: - lda prg_name, x - beq print_ver ; Did we find a null terminator? - sta ; Print character. - inx ; Increment offset. - inc x - jmp print_title ; Keep printing more characters. - -print_ver - jsr rset_x - lda ver_txt, x - beq print_num ; Did we find a null terminator? - sta scr ; Print character. - inx ; Increment offset. - jmp print_ver ; Keep printing more characters. - -print_num: - lda ver_num, x - beq getline ; Did we find a null terminator? - sta scr ; Print character. - inx ; Increment offset. - jmp print_num ; Keep printing more characters. -getline: - lda #$A - sta scr ; Print newline - inc scr_row - lda #0 - sta scr_col - inc y - jsr rset_x - jmp read - -getchar: - lda kbd ; Get typed character. - cmp #$1B ; Did the user type an escape? - beq esc ; Yes, so start getting the escape code. - cmp #$A ; Did the user type a newline? - beq nl ; Yes, so start parsing the input. - cmp #8 ; Did the user type a backspace? - beq bs ; Yes, so start checking the buffer. - jsr echo ; Print character to screen. - -store_char: - sta buf, y ; Store typed character into the input buffer. - iny ; Increment buffer offset. - jmp read ; Get another character. - -esc: - lda ctrl_reg ; Skip the '['. - lda ctrl_reg ; Get the next character. - beq read ; We have an error, so discard it, and go back to getting user input. - lda kbd ; Get the escape code. - sta c ; Store the escape code, until we need it. - jsr isup ; Check if the user pressed up. - lda d - cmp #0 - bne esc_end - jsr isdown ; Check if the user pressed down. - lda d - cmp #0 - bne esc_end - lda #0 - jsr isleft ; Check if the user pressed left. - lda d - cmp #0 - bne esc_end - jsr isright ; Check if the user pressed right. -esc_end: - lda #$0 - sta d - jmp rset_a ; Go back to getting user input. - -isup: - lda scr_row ; Is the cursor at the top of the screen? - beq isup_done ; Yes, so return. - 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. -isup_done: - rts ; End of isup. - -isdown: - lda scr_row ; Start checking the y coordinate of the cursor. - cmp #$17 ; Is the cursor at the bottom of the screen? - beq isdown_done ; 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. -isdown_done: - rts ; End of isdown. - -isright: - lda scr_col ; Start checking the x coordinate of the cursor. - cmp #$4F ; 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. -isright_end: - rts ; End of isright. - -isleft: - lda scr_col ; Is the cursor at the far left of the screen? - beq isleft_done ; Yes, so return. - 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. -isleft_done: - rts ; End of isleft. - -up: - dec scr_row - jsr update_pos - lda #1 - sta d - jmp isup_done -down: - inc scr_row - jsr update_pos - lda #1 - sta d - jmp isdown_done -right: - inc scr_col - jsr update_pos - jmp isright_end -left: - dec scr_col - jsr update_pos - lda #1 - sta d - jmp isleft_done - -update_pos: - lda #$1B ; Print an escape character - sta scr ; to the screen. - lda #$5B ; Print '[' - sta scr ; to the screen, and start the escape sequence. - jsr getrow ; Start printing the row number to the screen. - jsr getcol ; Start printing the column number to the screen. - lda #$48 ; Print 'H' - sta scr ; to the screen. - rts ; End of update_pos. -getrow: - lda scr_row ; Get the cursor's y coordinate. - div #$A ; Divide A by 10. - adc #$30 ; Convert it to ascii, and - sta scr ; print to the screen. - tba ; Get the remainder. - adc #$30 ; Convert it to ascii, and - sta scr ; print to the screen. - rts ; End of getrow. -getcol: - lda #$3B ; Print ';' - sta scr ; to the screen. - lda scr_col ; Get the cursor's x coordinate. - div #$A ; Divide A by 10. - adc #$30 ; Convert it to ascii, and - sta scr ; print to the screen. - tba ; Get the remainder. - adc #$30 ; Convert it to ascii, and - sta scr ; print to the screen. - rts ; End of getrow. - - - -nl: - sta scr ; Print newline. - inc scr_row ; Move the cursor down one line. - lda #0 ; Put a null terminator, in place of the newline. - sta scr_col ; Move the cursor back to column 0. - sta buf, y ; Place it into the input buffer. - ldy.w #0 ; Reset y, to parse the input. - jsr parse ; Start parsing input. - -back: - sta scr ; Print backspace. - lda #0 ; Put a null terminator, in place of the backspace. - sta buf, y ; Place it into the input buffer. - dey ; Decrement buffer offset. - dec scr_col - jmp read ; Get next character. - -bs: - cpy #0 ; Are we at the start of the buffer? - beq read ; We are, so do not store the backspace into the buffer. - jmp back ; We are not, so add the backspace to the buffer. - -parse: - jsr getdir - jsr - rts - -getdir: - iny ; Increment offset. - lda buf, y - jsr iswhite - bcs getdir ; Reset y, if we hit the null terminator. - cmp #$2E ; Is this character a '.'? - bne getdir_exit ; No, so return. - jsr clr_ptr - -getdir_end: - iny ; Increment offset. - lda buf, y - jsr iswhite - bcs getdir_cmp - ora #%00100000 ; Make character lower case. - sta (ptr1), y - jmp getdir_end -gettok: - ply #1 - iny -gettok2: - lda buf, y - jsr istoken - bcs gettok3 - jmp gettok2 -gettok3: - cmp #$ - cmp #$24 ; Is this character, a '$'? - beq getaddr ; Yes, so start getting the address. - - - -getdir_cmp: - phy #1 - ldy.w #0 - tyx -getdir_cpl: - ldb dir, x ; Start checking if the directive we're using, is "org". - stb (ptr2), y - beq getdir_scmp - inx - iny - jmp getdir_cpl -getdir_scmp: - ldy #0 - jsr strcmp - cpx #0 - beq getdir_tok -getdir_exit: - rts ; End of getdir. - - -istoken: - cmp #$20 ; Is this character a space? - beq istoken_f ; Yes, so return false. - cmp #$09 ; Is this character a tab? - beq istoken_f ; Yes, so return false. - cmp #$A ; Is this character a newline? - beq istoken_f ; Yes, so return false. - cmp #$3B ; Is this character a ';'? - beq istoken_f ; Yes, so return false. - cmp #0 ; Is this character a null terminator? - beq istoken_f ; Yes, so return false. - sec ; Return true. - rts ; End of istoken. -istoken_f - clc ; Return false. - rts ; End of istoken_f. - -iswhite: - cmp #$20 ; Is this character a space? - beq iswhite_t ; Yes, so return true. - cmp #9 ; Is this character a tab? - beq iswhite_t ; Yes, so return true. - clc ; No, so return false. - rts ; End of iswhite. -iswhite_t: - sec ; Return true. - rts ; End of iswhite_t. - -rset_y: - ldy.w #0 - jmp print_buf ; Print the input buffer. - -print_buf: - lda buf, y ; Get a character from the input buffer. - beq fin ; Are we done with printing the buffer? - sta scr ; Print said character. - iny - jmp print_buf ; Keep printing the buffer. - -spin: - nop - nop - nop - jmp spin - -clr_buf: - lda #0 - cpy.w #$3FF - beq clr_end - sta buf, y - iny - jmp clr_buf -clr_sbuf: - lda #0 - cpy.w #$1FF - beq clr_end - sta str_buf, y - iny - jmp clr_sbuf - -clr_end: - rts - -echo: - tab - ldx scr_col - cpx #$4F - bne echo_print - cmp #$A - beq linewrap -linewrap: - inc scr_row - ldx #0 - stx scr_col - jsr update_pos -echo_print: - tba - sta scr ; Echo typed character. - inc scr_col ; Increment the cursor's x coordinate. - sta buf, y ; Store typed character into the input buffer. - iny ; Increment the buffer offset. - rts ; Return. - -clr_ptr: - lda #0 - cpy.w #$3FF - beq ptr_end - sta (ptr1), y - sta (ptr2), y - iny - jmp clr_ptr -ptr_end: - rts - -strcmp: - lda (ptr1), y - cmp (ptr2), y - bne strcmp_l1 - tax - beq strcmp_l3 - iny - bne strcmp - jmp strcmp - - -strcmp_l1: - bcs strcmp_l2 - ldx #0 - dex - rts - -strcmp_l2: - ldx #1 -strcmp_l3: - rts - - -.org $FFC0 -.qword reset - -.org $FF50 -.qword spin -.qword spin -.qword spin -.qword spin -.qword spin -.qword spin -.qword spin - -.org $FFA0 -.qword irq_routine -.org $0 -v -.org $100 -v -.org $200 -v -.org $300 -v -.org $1000 -v -.org $1100 -v -.org $1200 -v -.org $1300 -v -.org $1400 -v -q - +; mne imm, zm, zmx, zmy, ind, idx, idy, abs, imp + .byte "CPS", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $00 + .byte "ADC", $01, $06, $FF, $FF, $FF, $FF, $FF, $04, $FF + .byte "AAB", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $02 + .byte "PHP", $08, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF + .byte "CPB", $09, $2D, $FF, $FF, $55, $AD, $AC, $2C, $FF + .byte "PHB", $0A, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF + .byte "DEC", $FF, $0D, $FF, $FF, $FF, $FF, $FF, $0C, $E5 + .byte "JMP", $FF, $0E, $FF, $FF, $CE, $FF, $FF, $10, $FF + .byte "SBC", $11, $16, $FF, $FF, $FF, $FF, $FF, $14, $FF + .byte "SAB", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $12 + .byte "ENT", $18, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF + .byte "CPY", $19, $3D, $FF, $FF, $85, $FF, $FF, $4C, $FF + .byte "PLB", $1A, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF + .byte "INC", $FF, $1D, $FF, $FF, $FF, $FF, $FF, $1C, $F5 + .byte "JSR", $FF, $1E, $FF, $FF, $BE, $FF, $FF, $FF, $FF + .byte "JSL", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $20, $FF + .byte "AND", $21, $26, $FF, $FF, $FF, $FF, $FF, $24, $FF + .byte "ABA", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $22 + .byte "PLP", $28, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF + .byte "CPX", $29, $4D, $FF, $FF, $B5, $FF, $FF, $3C, $FF + .byte "PHY", $2A, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF + .byte "BPO", $FF, $2E, $FF, $FF, $FF, $FF, $FF, $30, $FF + .byte "ORA", $31, $36, $FF, $FF, $FF, $FF, $FF, $34, $FF + .byte "OAB", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $32 + .byte "STT", $38, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF + .byte "PLY", $3A, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF + .byte "BNG", $FF, $3E, $FF, $FF, $FF, $FF, $FF, $40, $FF + .byte "XOR", $41, $46, $FF, $FF, $FF, $FF, $FF, $44, $FF + .byte "XAB", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $42 + .byte "PHA", $48, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF + .byte "PHX", $4A, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF + .byte "BCS", $FF, $4E, $FF, $FF, $FF, $FF, $FF, $50, $FF + .byte "LSL", $51, $56, $FF, $FF, $FF, $FF, $FF, $54, $FF + .byte "LLB", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $52 + .byte "CLC", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $58 + .byte "PLX", $5A, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF + .byte "BCC", $FF, $5E, $FF, $FF, $FF, $FF, $FF, $60, $FF + .byte "LSR", $61, $66, $FF, $FF, $FF, $FF, $FF, $64, $FF + .byte "LRB", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $62 + .byte "PLA", $68, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF + .byte "TAB", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $6A + .byte "BEQ", $FF, $6E, $FF, $FF, $FF, $FF, $FF, $70, $FF + .byte "ROL", $71, $76, $FF, $FF, $FF, $FF, $FF, $74, $FF + .byte "RLB", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $72 + .byte "SEC", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $78 + .byte "TBA", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $7A + .byte "BNE", $FF, $7E, $FF, $FF, $FF, $FF, $FF, $80, $FF + .byte "ROR", $81, $86, $FF, $FF, $FF, $FF, $FF, $84, $FF + .byte "RRB", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $82 + .byte "DEY", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $88 + .byte "TAY", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $8A + .byte "BVS", $FF, $8E, $FF, $FF, $FF, $FF, $FF, $90, $FF + .byte "MUL", $91, $96, $FF, $FF, $FF, $FF, $FF, $94, $FF + .byte "MAB", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $92 + .byte "CLI", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $98 + .byte "TYA", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $9A + .byte "BVC", $FF, $9E, $FF, $FF, $FF, $FF, $FF, $A0, $FF + .byte "DIV", $A1, $A6, $FF, $FF, $FF, $FF, $FF, $A4, $FF + .byte "DAB", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $A2 + .byte "INY", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $A8 + .byte "TAX", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $AA + .byte "RTS", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $AE + .byte "RTL", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $B0 + .byte "CMP", $B1, $B6, $FF, $FF, $25, $7D, $7C, $B4, $FF + .byte "CAB", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $B2 + .byte "SEI", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $B8 + .byte "LDX", $B9, $BD, $FF, $C9, $95, $FF, $FF, $BC, $FF + .byte "TXA", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $BA + .byte "RTI", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $C0 + .byte "LDA", $C1, $C6, $79, $39, $05, $5D, $5C, $C4, $FF + .byte "DEX", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $C5 + .byte "CLV", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $C8 + .byte "TYX", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $CA + .byte "STA", $FF, $CD, $89, $49, $15, $6D, $6C, $CC, $FF + .byte "TSX", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $D0 + .byte "LDB", $D1, $D6, $99, $59, $35, $8D, $8C, $D4, $FF + .byte "INX", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $D5 + .byte "WAI", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $D8 + .byte "TXY", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $DA + .byte "STB", $FF, $DD, $A9, $69, $45, $9D, $9C, $DC, $FF + .byte "TXS", $E0, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF + .byte "LDY", $E1, $E6, $E9, $FF, $65, $FF, $FF, $E4, $FF + .byte "BRK", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $E8 + .byte "NOP", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $EA + .byte "STY", $FF, $ED, $F9, $FF, $75, $FF, $FF, $EC, $FF + .byte "DEB", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $EE + .byte "ASR", $F1, $F6, $FF, $FF, $FF, $FF, $FF, $F4, $FF + .byte "ARB", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $F2 + .byte "STX", $FF, $FD, $FF, $D9, $A5, $FF, $FF, $FC, $FF + .byte "INB" $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FE + +; Command subroutine table. +cmd_srt: + .word viewmem + .word list + .word asm + .word help + .word inst + .word run + .word set + +; Hex character table. +hex_char: + .byte "0123456789ABCDEF" + + +; Token table. +.org $20000 +tokline: + +.org cmd_buf+$400 +; Program Counter. +prg_cnt: + .qword 0 +; Hex digit string buffer. +hex_str: + .qword 0, 0 +; String buffer. +strbuf: + +.org strbuf+$80 +; Subroutine pointer. +sub_ptr: + .word 0 + +; Indecies. +idx0: + .qword 0 +idx1: + .qword 0 +idx2: + .qword 0 +idx3: + .qword 0 + +; Lexeme string. +lexeme: + +; Symbol tables. +.org lexeme+$100 +sym_val: +.org sym_val+$4000 +sym_id: +.org sym_id+$1000 +sym_def: +.org sym_def+$100 +sym_name: + +; Fixup table. +; Fixups are unresolved symbols. +.org sym_name+$1000 +fix_sym: +.org fix_sym+$1000 +fix_ln: +.org fix_ln+$1000 +fix_val: + + +; Start of program code. +.org parser +subasm: + ldb #0 ; Set the first pointer + lda.d #cmd_buf ; to the command buffer. + jsl set_ptr ; + tba ; Reset A. + tax ; Reset X. + jsl chk_shcmd ; Did we get a shortend command? + bne parse_cmd ; Yes, so skip everything else. + jmp subasm_end ; + jsl chk_cmd ; No, but did we get a full command? + bne parse_cmd ; Yes, so skip everything else. + jsl lexer ; No, so start lexing this line. +subasm_end: + rtl ; End of subasm. + +parse_cmd: + ldb #1 ; Set the second pointer + lda.d #cmd_srt ; to the command subroutine table. + jsl set_ptr ; + deb ; Reset B. + tba ; Reset A. + lda f ; Get the command ID. + cmp #8 ; Is the command ID greater than the command count? + bcs subasm_end ; Yes, so we're done. + lsl #1 ; No, so multiply the command ID by two. + phy #2 ; Preserve the screen buffer position. + tay ; Set the index to the offset that we just calculated. + lda.w (ptr2), y ; Get the command subroutine, from the command subroutine table. + ply #2 ; Get back the screen buffer position. + ldb #2 ; Save it in the third pointer. + jsl set_ptr ; + ldb #0 ; Reset B. + jsr (ptr3) ; Run the command's subroutine. + jmp subasm_end ; We are done. + +chk_shcmd: + tba ; Reset A. + inb ; Set the second pointer + lda.w #sh_cmds ; to the shortend command table. + jsl set_ptr ; + deb ; Reset B. + tba ; Reset A. + phy #2 ; Preserve the screen buffer position. + txy ; Set our index to zero. + lda (ptr), y ; Is there nothing in the command buffer? + beq shcmd_fail ; Yes, so return that we failed. + cmp #' ' ; No, but is this character, a space? + beq shcmd_fail ; Yes, so return that we failed. +shcmd_loop: + ldb (ptr2), y ; Are we at the end of the table? + beq shcmd_fail ; Yes, so return that we failed. + cab ; No, so did the character match? + beq shcmd_fnd ; Yes, so check if there are any arguments. + iny ; No, so check the next command. + jmp shcmd_loop ; Keep looping. +shcmd_fnd: + sty f ; Save the command ID. + ldy #1 ; Check the next character in the command buffer. + lda (ptr), y ; Is this the end of the buffer? + beq shcmd_true ; Yes, so return that we succeded. + cmp #' ' ; No, but is this a space? + beq shcmd_true ; Yes, so return that we succeded. + jmp shcmd_fail ; No, so return that we failed. +shcmd_true: + lda #1 ; Return true. + jmp shcmd_end ; We are done. +shcmd_fail: + ldb #0 ; Reset B. + tba ; Return false. + tax ; Reset X. +shcmd_end: + ply #2 ; Get back the screen buffer position. + rtl ; End of chk_shcmd. + +print_hex: + pha #8 ; Preserve the hex value. + and #0 ; Reset A. + ldb #1 ; Set the second pointer + lda.w #hex_char ; to the start of hex character table. + jsl set_ptr ; + inb ; Set the third pointer + lda.d #hex_str ; to the end of hex string buffer. + clc ; Do a non carrying add. + adc #$10 ; + jsl set_ptr ; + ldb #0 ; Reset B. + pla #8 ; Get the hex value back. +pnthex_lp: + pha #8 ; Preserve the hex value. + and #$F ; Mask the lowest nibble. + phy #2 ; Preserve the screen buffer position. + tay ; Get the index for the hex digit. + lda (ptr2), y ; Get the hex digit. + dec ptr3 ; Decrement the string pointer. + sta (ptr3) ; Save the hex digit character in the string. + ply #2 ; Get back the screen buffer position. + pla #8 ; Get the hex value back. +pnthex_lp1: + cpx #1 ; Is the digit count less than one? + bcc pnthex_lp2 ; Yes, so don't decrement the digit count. + dex ; No, but was the digit count zero, when decremented? + beq pnthex_end ; Yes, so we're done. + jmp pnthex_lp3 ; No, so get the next nibble. +pnthex_lp2: + ldb #1 ; Enable auto digit count. +pnthex_lp3: + lsr #4 ; No, but is the next nibble, a zero? + beq pnthex_lp4 ; Yes, so check if auto digit count is enabled. + jmp pnthex_lp ; No, so print the next digit. +pnthex_lp4: + cpb #1 ; Is auto digit count enabled? + beq pnthex_end ; Yes, so we're done. + jmp pnthex_lp ; No, so keep printing more digits. +pnthex_end: + rtl ; End of print_hex. + +charcpy: + ldx idx3 ; Get the string index. + sta strbuf, x ; Save it in the string buffer. + inc idx3 ; Increment the string index. + rtl ; End of charcpy. + +print_hi: + and #0 ; Reset A. + sta idx3 ; Clear the string index. + lda #'$' ; Print the hex delimiter. + jsl charcpy ; + lda.q idx0 ; Get the masked address. + ldx #$10 ; Set digit count to 16. + jsl print_hex ; Print the address. + lda.q hex_str ; Get the lower half of the string. + sta.q strbuf+1 ; Save it in the string buffer. + lda.q hex_str+8 ; Get the upper half of the string. + sta.q strbuf+9 ; Save it in the string buffer. + ldx #$11 ; Add 16 to the index. + stx idx3 ; + lda #':' ; Print a colon. + jsl charcpy ; + lda # ' ' ; Print a space. + jsl charcpy ; + rtl ; End of print_hi. + +print_lo: + lda #0 ; Reset A. + sta idx3 ; Clear the string index. +pntlo_lp: + ldx #2 ; Set digit count to 2. + pha #1 ; Preserve the nibble offset. + jsl print_hex ; Print the low nibble offset. + lda.w (ptr3) ; Get the two digits. + jsl charcpy ; Copy the first digit. + lsr #8 ; Copy the next digit. + jsl charcpy ; + pla #1 ; Get the nibble offset back. + inc ; Increment the offset. + cmp #$10 ; Are we at the last offset? + bcs pntlo_end ; Yes, so we're done. +pntlo_lp1: + pha #1 ; No, so preserve the nibble offset. + lda #' ' ; Add a space to the string buffer. + jsl charcpy ; + pla #1 ; Get the nibble offset back. + jmp pntlo_lp ; Keep looping. +pntlo_end: + inx ; Increment the index by one. + lda #0 ; Null terminate the string buffer. + sta strbuf, x ; + tax ; Reset X. + lda.d #strbuf ; Print the string buffer. + jsl print_str ; + rtl ; End of print_lo. + +print_chunk: + ldx #0 ; Reset X. + phy #2 ; Preserve the screen buffer index. + txy ; Copy the byte index to it. +pntchnk_lp: + and #0 ; Reset A. + ldx #2 ; Set the digit count to 2. + lda (idx0), y ; Get the byte at that address. + jsl print_hex ; Print the byte. + lda.w (ptr3) ; Get the two digits. + jsl charcpy ; Copy the first digit. + lsr #8 ; Copy the next digit. + jsl charcpy ; + iny ; Increment the byte index. + cpy #$10 ; Have we read 16 bytes? + beq pntchnk_end ; Yes, so we're done. + lda #' ' ; No, so add a soace to the string buffer. + jsl charcpy ; + jmp pntchnk_lp ; Keep looping. +pntchnk_end: + ply #2 ; Get the screen buffer index back. + inx ; Increment the index by one. + and #0 ; Null terminate the string. + sta strbuf, x ; + tax ; Reset X. + sta idx3 ; Clear the string index. + rtl ; End of print_chunk. + +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 ; + jsl update_pos ; + jsl print_lo ; Print the low nibble offsets. + ldx #0 ; Reset X. + ldb #0 ; Reset B. + stb idx1 ; Reset the byte count. +vmem_lp0: + lda #'\n' ; Print a newline. + jsl print_char ; + jsl print_hi ; Place the address in the string buffer. + jsl print_chunk ; Place the next 16 bytes in the string buffer. + lda.d #strbuf ; Print the string buffer. + jsl print_str ; + inc idx1 ; Increment the chunk count. + ldb idx1 ; Get the chunk count. + cpb #$10 ; Did we print 16 chunks? + beq vmem_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. + jmp vmem_lp0 ; Keep looping. +vmem_end: + lda #'\n' ; Print a newline. + jsl print_char ; + and #0 ; Reset A. + rts ; End of viewmem. + + +list: + nop ; +list_end: + rts ; End of list. +asm: + nop ; +asm_end: + rts ; End of asm. +help: + nop ; +help_end: + rts ; End of help. +inst: + nop ; +inst_end: + rts ; End of inst. +run: + nop ; +run_end: + rts ; End of run. +set: + nop ; +set_end: + rts ; End of set. |