diff options
Diffstat (limited to 'programs')
-rw-r--r-- | programs/sub-suite/declare.s | 430 | ||||
-rw-r--r-- | programs/sub-suite/lexer.s | 152 | ||||
-rw-r--r-- | programs/sub-suite/libc.s | 201 | ||||
-rw-r--r-- | programs/sub-suite/subasm.s | 233 | ||||
-rw-r--r-- | programs/sub-suite/subeditor.s | 232 | ||||
-rw-r--r-- | programs/sub-suite/subsuite.s | 22 | ||||
-rw-r--r-- | programs/sub-suite/utils.s | 257 |
7 files changed, 792 insertions, 735 deletions
diff --git a/programs/sub-suite/declare.s b/programs/sub-suite/declare.s new file mode 100644 index 0000000..745445b --- /dev/null +++ b/programs/sub-suite/declare.s @@ -0,0 +1,430 @@ + +; Enums. + +; I/O constants. +status = $100 ; Keyboard status. +scr = $101 ; Character that is to be printed. +kbd = $102 ; Character from the Keyboard. +step = $110 ; Enables clock stepping, when set. + +; Screen constants. +maxrow = 23 ; Screen's row count. +maxcol = 79 ; Screen's column count. + +MAX_SYM = $800 ; Max symbol size. +OPNUM = 87 ; Instruction count. + +; Directives. +DIR_ORG = 0 ; Origin. +DIR_BYTE = 1 ; Byte = 8 bits. +DIR_WORD = 2 ; Word = 16 bits. +DIR_DWORD = 3 ; Dword = 32 bits. +DIR_QWORD = 4 ; Qword = 64 bits. +DIR_INCL = 5 ; Include. +DIR_RES = 6 ; Reserved bytes. + +; Tokens. +TOK_DIR = 0 ; Directive. +TOK_LOCAL = 1 ; Local syobol. +TOK_LABEL = 2 ; Label. +TOK_SYM = 3 ; Symbol. +TOK_EXPR = 4 ; Expression. +TOK_CSV = 5 ; Comma separated value. +TOK_STR = 6 ; String. +TOK_CHAR = 7 ; Character. +TOK_IND = 8 ; Indirect addressing. +TOK_IMM = 9 ; Immediate data. +TOK_MNE = 10 ; Opcode/Mnemonic. +TOK_RS = 11 ; Register size prefix. +TOK_COMM = 12 ; Comment. +TOK_HEX = 13 ; Hex value. +TOK_DEC = 14 ; Decimal value. +TOK_BIN = 15 ; Binary value. +TOK_INCL = 16 ; Include file. + +; Pre-Tokens. +PTOK_DOT = 0 ; . +PTOK_AT = 1 ; @ +PTOK_COLON = 2 ; : +PTOK_EQU = 3 ; = +PTOK_PLUS = 4 ; + +PTOK_MINUS = 5 ; - +PTOK_GT = 6 ; > +PTOK_LT = 7 ; < +PTOK_LBRAK = 8 ; ( +PTOK_RBRAK = 9 ; ) +PTOK_COMMA = 10 ; , +PTOK_X = 11 ; x +PTOK_Y = 12 ; y +PTOK_S = 13 ; s +PTOK_P = 14 ; p +PTOK_DQUOT = 15 ; " +PTOK_SQUOT = 16 ; ' +PTOK_HASH = 17 ; # +PTOK_SCOLN = 18 ; ; +PTOK_DOLR = 19 ; $ +PTOK_PRCNT = 20 ; % +PTOK_NUM = 21 ; 0-9 +PTOK_ALPH = 22 ; a-z A-Z +PTOK_OTHR = 23 ; Everything else. + +; Expressions. +EXPR_PLUS = 0 ; Plus. +EXPR_MINUS = 1 ; Minus. +EXPR_LOW = 2 ; Lower half of address. +EXPR_HIGH = 3 ; Upper half of address. +EXPR_NONE = 4 ; No expression. + +; RAM declarations. + +; Linewrap table. +.org $30000 +bitabl: + .res $1000 + +; Screen buffer. +buffer: + .res $2000 + +; Command buffer. +cmd_buf: + .res $400 + +; Screen variables. +.org 0 +scr_row: + .res 1 +scr_col: + .res 1 +scr_trow: + .res 1 +scr_tcol: + .res 1 +scr_ptr: + .res 2 +scr_ptr2: + .res 2 +scr_ptr3: + .res 2 + +; Pseudo registers. +a: + .res 1 +b: + .res 1 +c: + .res 1 +d: + .res 1 +e: + .res 1 +f: + .res 1 +g: + .res 1 +; This pseudo register is always zero. +zero: + .res 8 +; End of pseudo registers. + +end: + .res 8 +bitmask: + .res 1 +scr_str: + .res 1 +scr_end: + .res 1 +wrapped: + .res 1 + +; Pointers +ptr: + .res 8 +ptr2: + .res 8 +ptr3: + .res 8 + + +; Token table. +.org $20000 +tokline: + .res $400 + +; Program Counter. +prg_cnt: + .res 8 +; Hex digit string buffer. +hex_str: + .res 16 +; String buffer. +strbuf: + .res $80 + +; Subroutine pointer. +sub_ptr: + .res 2 + +; Indecies. +idx0: + .res 8 +idx1: + .res 8 +idx2: + .res 8 +idx3: + .res 8 + +; Value buffer used by strtoull. +valbuf: + .res 8 + +; Copy buffer used by delmcpy. +cpybuf: + .res 8 + +; Current token line. +ctok: + .res 2 + +; Last token line. +ltok: + .res 2 + +; Lexeme type. +lex_type: + .res 1 + +; Lexeme string. +lexeme: + .res $100 + +; Symbol table. +sym: + .res $8000 + +; Fixup table. +; Fixups are unresolved symbols. +fix: + .res $2000 + +; ROM data declarations. + +.org $A000 +; String Literals/Constants. +tok: + .byte "dab" +msg: + .byte "oof, you divided a, and b on me.\n" + +ed_name: + .byte "SuBEditor" +ed_ver: + .byte "1" +ed_sver: + .byte ".0.0" + +ver_str: + .byte ", version " +made: + .byte "Created by, " + +author: + .byte "mr b0nk 500" + +string2: + .byte "You typed, " + +asm_name: + .byte "SuBAsm" +asm_ver: + .byte "0.1" + +; Directives. +dir: + .byte "org" + .byte "byte" + .byte "word" + .byte "dword" + .byte "qword" + .byte "include" + .byte "res" + +; Short form Commands. +sh_cmds: + .byte "vlahirs" + +; Commands. +cmds: + .byte "viewmem" + .byte "list" + .byte "asm" + .byte "help" + .byte "inst" + .byte "run" + .byte "set" + +; Linewrap bitmask table. +bits: + .byte $80, $40, $20, $10, $08, $04, $02, $01 + + +; 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. +; rel = Relative. +; imp = Implied. + +mne: +; mne imm, zm, zmx, zmy, ind, idx, idy, abs, rel, imp + .byte "ADC", $01, $06, $FF, $FF, $FF, $FF, $FF, $04, $FF, $FF + .byte "AAB", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $02 + .byte "ABA", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $22 + .byte "ADC", $01, $06, $FF, $FF, $FF, $FF, $FF, $04, $FF, $FF + .byte "AND", $21, $26, $FF, $FF, $FF, $FF, $FF, $24, $FF, $FF + .byte "ARB", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $F2 + .byte "ASR", $F1, $F6, $FF, $FF, $FF, $FF, $FF, $F4, $FF, $FF + .byte "BCC", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $80, $FF + .byte "BCS", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $70, $FF + .byte "BEQ", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $90, $FF + .byte "BNE", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $A0, $FF + .byte "BNG", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $60, $FF + .byte "BPO", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $50, $FF + .byte "BRA", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $D0, $FF + .byte "BRK", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $68 + .byte "BVC", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $C0, $FF + .byte "BVS", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $B0, $FF + .byte "CAB", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $B2 + .byte "CLC", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $08 + .byte "CLI", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $28 + .byte "CLV", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $48 + .byte "CMP", $B1, $B6, $FF, $FF, $25, $7D, $7C, $B4, $FF, $FF + .byte "CPB", $2A, $2D, $FF, $FF, $55, $AD, $AC, $2C, $FF, $FF + .byte "CPS", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $00 + .byte "CPX", $3A, $4D, $FF, $FF, $FF, $FF, $FF, $3C, $FF, $FF + .byte "CPY", $4A, $3D, $FF, $FF, $FF, $FF, $FF, $4C, $FF, $FF + .byte "DAB", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $A2 + .byte "DEB", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $C2 + .byte "DEC", $FF, $0D, $FF, $FF, $FF, $FF, $FF, $0C, $FF, $0A + .byte "DEX", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $09 + .byte "DEY", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $29 + .byte "DIV", $A1, $A6, $FF, $FF, $FF, $FF, $FF, $A4, $FF, $FF + .byte "INB", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $D2 + .byte "INC", $FF, $1D, $FF, $FF, $FF, $FF, $FF, $1C, $FF, $1A + .byte "INX", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $19 + .byte "INY", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $39 + .byte "JMP", $FF, $30, $FF, $FF, $B5, $FF, $FF, $10, $FF, $FF + .byte "JSR", $FF, $40, $FF, $FF, $A5, $FF, $FF, $20, $FF, $FF + .byte "LDA", $C1, $C6, $B8, $78, $05, $5D, $5C, $C4, $FF, $FF + .byte "LDB", $D1, $D6, $D8, $98, $35, $8D, $8C, $D4, $FF, $FF + .byte "LDX", $B9, $BD, $FF, $FF, $85, $FF, $FF, $BC, $FF, $FF + .byte "LDY", $E1, $E6, $FF, $FF, $65, $FF, $FF, $E4, $FF, $FF + .byte "LLB", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $52 + .byte "LRB", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $62 + .byte "LSL", $51, $56, $FF, $FF, $FF, $FF, $FF, $54, $FF, $FF + .byte "LSR", $61, $66, $FF, $FF, $FF, $FF, $FF, $64, $FF, $FF + .byte "MAB", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $92 + .byte "MUL", $91, $96, $FF, $FF, $FF, $FF, $FF, $94, $FF, $FF + .byte "NOP", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $EA + .byte "OAB", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $32 + .byte "ORA", $31, $36, $FF, $FF, $FF, $FF, $FF, $34, $FF, $FF + .byte "PHA", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $79 + .byte "PHB", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $99 + .byte "PHP", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $59 + .byte "PHX", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $E9 + .byte "PHY", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $C9 + .byte "PLA", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $89 + .byte "PLB", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $A9 + .byte "PLP", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $69 + .byte "PLX", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $F9 + .byte "PLY", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $D9 + .byte "RLB", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $72 + .byte "ROL", $71, $76, $FF, $FF, $FF, $FF, $FF, $74, $FF, $FF + .byte "ROR", $81, $86, $FF, $FF, $FF, $FF, $FF, $84, $FF, $FF + .byte "RRB", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $82 + .byte "RTI", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $F0 + .byte "RTS", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $E0 + .byte "SAB", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $12 + .byte "SBC", $11, $16, $FF, $FF, $FF, $FF, $FF, $14, $FF, $FF + .byte "SEC", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $18 + .byte "SEI", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $38 + .byte "STA", $FF, $CD, $C8, $88, $15, $6D, $6C, $CC, $FF, $FF + .byte "STB", $FF, $DD, $E8, $A8, $45, $9D, $9C, $DC, $FF, $FF + .byte "STX", $FF, $FD, $FF, $FF, $95, $FF, $FF, $FC, $FF, $FF + .byte "STY", $FF, $ED, $FF, $FF, $75, $FF, $FF, $EC, $FF, $FF + .byte "TAB", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $5A + .byte "TAX", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $9A + .byte "TAY", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $7A + .byte "TBA", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $6A + .byte "TSX", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $DA + .byte "TXA", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $AA + .byte "TXS", $FA, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF + .byte "TXY", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $CA + .byte "TYA", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $8A + .byte "TYX", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $BA + .byte "WAI", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $58 + .byte "XAB", $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $42 + .byte "XOR", $41, $46, $FF, $FF, $FF, $FF, $FF, $44, $FF, $FF + +; Command subroutine table. +cmd_srt: + .word viewmem + .word list + .word asm + .word help + .word inst + .word run + .word set + + +; Jump table for parsing pre-tokens. +swtab: + .word ptok_dot ; PTOK_DOT + .word ptok_at ; PTOK_AT + .word ptok_col ; PTOK_COLON + .word ptok_equ ; PTOK_EQU + .word ptok_plus ; PTOK_PLUS + .word ptok_min ; PTOK_MINUS + .word ptok_gt ; PTOK_GT + .word ptok_lt ; PTOK_LT + .word ptok_lbrk ; PTOK_LBRAK + .word ptok_rbrk ; PTOK_RBRAK + .word ptok_com ; PTOK_COMMA + .word ptok_xr ; PTOK_X + .word ptok_yr ; PTOK_Y + .word ptok_sp ; PTOK_S + .word ptok_pc ; PTOK_P + .word ptok_dqu ; PTOK_DQUOT + .word ptok_squ ; PTOK_SQUOT + .word ptok_hash ; PTOK_HASH + .word ptok_scol ; PTOK_SCOLN + .word ptok_dolr ; PTOK_DOLR + .word ptok_prcn ; PTOK_PRCNT + .word ptok_num ; PTOK_NUM + .word ptok_alph ; PTOK_ALPH + .word ptok_othr ; PTOK_OTHR + + +; Hex character table. +hex_char: + .byte "0123456789ABCDEF" + +; Compare, and return table for pre-tokens. +ptok_tab: + .byte ".@:=+-><(),xysp\"\'#;$%" +; Compare, and return table for isdelm. +dtab: + .byte "\n,\"\' \\" +; Compare, and return table for isdelm2. +dtab2: + .byte "),.+<>-=;\n" diff --git a/programs/sub-suite/lexer.s b/programs/sub-suite/lexer.s index cd7a33a..c144f9a 100644 --- a/programs/sub-suite/lexer.s +++ b/programs/sub-suite/lexer.s @@ -1,103 +1,9 @@ ; Lexer, and supporting routines for SuBAsm. -; Enums. - -; Directives. -DIR_ORG = 0 ; Origin. -DIR_BYTE = 1 ; Byte = 8 bits. -DIR_WORD = 2 ; Word = 16 bits. -DIR_DWORD = 3 ; Dword = 32 bits. -DIR_QWORD = 4 ; Qword = 64 bits. -DIR_INCL = 5 ; Include. - -; Tokens. -TOK_DIR = 0 ; Directive. -TOK_LOCAL = 1 ; Local syobol. -TOK_LABEL = 2 ; Label. -TOK_SYM = 3 ; Symbol. -TOK_EXPR = 4 ; Expression. -TOK_CSV = 5 ; Comma separated value. -TOK_STR = 6 ; String. -TOK_CHAR = 7 ; Character. -TOK_IND = 8 ; Indirect addressing. -TOK_IMM = 9 ; Immediate data. -TOK_MNE = 10 ; Opcode/Mnemonic. -TOK_RS = 11 ; Register size prefix. -TOK_COMM = 12 ; Comment. -TOK_HEX = 13 ; Hex value. -TOK_DEC = 14 ; Decimal value. -TOK_BIN = 15 ; Binary value. -TOK_INCL = 16 ; Include file. - -; Pre-Tokens. -PTOK_DOT = 0 ; . -PTOK_AT = 1 ; @ -PTOK_COLON = 2 ; : -PTOK_EQU = 3 ; = -PTOK_PLUS = 4 ; + -PTOK_MINUS = 5 ; - -PTOK_GT = 6 ; > -PTOK_LT = 7 ; < -PTOK_LBRAK = 8 ; ( -PTOK_RBRAK = 9 ; ) -PTOK_COMMA = 10 ; , -PTOK_X = 11 ; x -PTOK_Y = 12 ; y -PTOK_DQUOT = 13 ; " -PTOK_SQUOT = 14 ; ' -PTOK_HASH = 15 ; # -PTOK_SCOLN = 16 ; ; -PTOK_DOLR = 17 ; $ -PTOK_PRCNT = 18 ; % -PTOK_NUM = 19 ; 0-9 -PTOK_ALPH = 20 ; a-z A-Z -PTOK_OTHR = 21 ; Everything else. - -; Expressions. -EXPR_PLUS = 0 ; Plus. -EXPR_MINUS = 1 ; Minus. -EXPR_LOW = 2 ; Lower half of address. -EXPR_HIGH = 3 ; Upper half of address. -EXPR_NONE = 4 ; No expression. - - -; Data. -.org lexer_data -; Jump table for parsing pre-tokens. -swtab: - .word ptok_dot ; PTOK_DOT - .word ptok_at ; PTOK_AT - .word ptok_col ; PTOK_COLON - .word ptok_equ ; PTOK_EQU - .word ptok_plus ; PTOK_PLUS - .word ptok_min ; PTOK_MINUS - .word ptok_gt ; PTOK_GT - .word ptok_lt ; PTOK_LT - .word ptok_lbrk ; PTOK_LBRAK - .word ptok_rbrk ; PTOK_RBRAK - .word ptok_com ; PTOK_COMMA - .word ptok_xr ; PTOK_X - .word ptok_yr ; PTOK_Y - .word ptok_dqu ; PTOK_DQUOT - .word ptok_squ ; PTOK_SQUOT - .word ptok_hash ; PTOK_HASH - .word ptok_scol ; PTOK_SCOLN - .word ptok_dolr ; PTOK_DOLR - .word ptok_prcn ; PTOK_PRCNT - .word ptok_num ; PTOK_NUM - .word ptok_alph ; PTOK_ALPH - .word ptok_othr ; PTOK_OTHR - -; Data entry point for utility subroutines. -util_data: - - ; Program code. -.org lexer lex: ldx #0 ; Reset X. txa ; Reset A. - phy.w ; Preserve the screen buffer index. txy ; Reset Y. sty.q idx0 ; Clear the first index. sty.q idx1 ; Clear the second index. @@ -165,7 +71,9 @@ lex: ; beq @end ; We got to the end of the string. bra @loop ; Keep looping. @end: - ply.w ; Get the screen buffer index back. + jsr update_ptr ; Get the screen buffer index. + tay ; Save it in Y. + and #0 ; Reset A. rts ; End of lex. @@ -208,21 +116,20 @@ ptok_dot: stb.q idx1 ; Reset the first index. jsr set_lexptr ; Set up the lexeme buffer. @dir_loop: + ldb idx1 ; Get the directive ID. + cpb #7 ; Have we reached the end of the directive table? + beq @end ; Yes, so we're done. lda.w #dir ; Get pointer to the start of the directive table. clc ; Prepare for a non carrying add. adc.w idx2 ; Offset the pointer, by the length of the previous string. pha.q ; Preserve the directive string pointer. - jsr strcasecmp ; Is the lexeme buffer, the same as the directive string? + jsr strcaseptr ; Is the lexeme buffer, the same as the directive string? pla.q ; Get the directive string pointer back. beq @found ; Yes, so create a new token. - ldb idx1 ; No, so Get the directive ID. - cpb #6 ; Have we reached the end of the directive table? - beq @end ; Yes, so we're done. inc idx1 ; No, so increment the directive ID. @getlen: jsr strlen ; Get the string's length. - inx ; Add one to the length. - txa ; Place it in the accumulator. + inc ; Add one to the length. clc ; Prepare for a non carrying add. adc.w idx2 ; Add the string offset to the current length sta.w idx2 ; Save the offset in the third index. @@ -243,16 +150,24 @@ ptok_equ: inc.w idx0 ; rts ; End of parse_ptok. ptok_plus: - inc.w idx0 ; - rts ; End of parse_ptok. + lda #EXPR_PLUS ; Set the expresion type to EXPR_PLUS. + bra ptok_expr ; Set up the token. ptok_min: - inc.w idx0 ; - rts ; End of parse_ptok. + lda #EXPR_MINUS ; Set the expresion type to EXPR_MINUS. + bra ptok_expr ; Set up the token. ptok_gt: - inc.w idx0 ; - rts ; End of parse_ptok. + lda #EXPR_LOW ; Set the expresion type to EXPR_LOW. + bra ptok_expr ; Set up the token. ptok_lt: + lda #EXPR_HIGH ; Set the expresion type to EXPR_HIGH. +ptok_expr: + lda #TOK_EXPR ; Set the lexeme type to TOK_EXPR. + sta lex_type ; inc.w idx0 ; +; ldb #1 ; Make init_lex increment the string index. +; jsr init_lex ; Initialize the lexeme buffer for copying. + jsr make_tok ; Create the token. + jsr set_cmdbuf ; Set the first pointer to the command buffer. rts ; End of parse_ptok. ptok_lbrk: inc.w idx0 ; @@ -269,6 +184,12 @@ ptok_xr: ptok_yr: inc.w idx0 ; rts ; End of parse_ptok. +ptok_sp: + inc.w idx0 ; + rts ; End of parse_ptok. +ptok_pc: + inc.w idx0 ; + rts ; End of parse_ptok. ptok_dqu: ldb #1 ; Make init_lex increment the string index. jsr init_lex ; Initialize the lexeme buffer for copying. @@ -289,6 +210,7 @@ ptok_hash: ptok_scol: ldb #1 ; Make init_lex increment the string index. jsr init_lex ; Initialize the lexeme buffer for copying. + ldb #1 ; Set the delimiter to EOL. jsr delmcpy ; Copy the string, to the lexeme buffer, until EOL. @end: rts ; End of parse_ptok. @@ -312,10 +234,10 @@ ptok_num: ptok_num2: pha ; Preserve the base. jsr init_lex ; Initialize the lexeme buffer for copying. - ldb #3 ; Set the delimiter to both the EOL, or a comma. + ldb #3 ; Set the delimiter to both the EOL, and a comma. jsr delmcpy ; Copy the string, to the lexeme buffer, until delimiter. pla ; Get the base back. - jsr strtoull ; Convert the string into a numeric value. + jsr strtoullg ; Convert the string into a numeric value. jsr make_tok ; Create the token. jsr set_cmdbuf ; Set the first pointer to the command buffer. rts ; End of parse_ptok. @@ -335,14 +257,14 @@ ptok_alph: lda.w #mne ; Get pointer to the start of the instruction table. clc ; Prepare for a non carrying add. adc.w idx2 ; Offset the pointer, by the length of the previous string. - jsr strcasecmp ; Is the lexeme buffer, the same as the mnemonic string? + jsr strcaseg ; Is the lexeme buffer, the same as the mnemonic string? beq @found ; Yes, so create a new token. ldb idx1 ; No, so Get the instruction ID. cpb #OPNUM-1 ; Have we reached the end of the instruction table? beq @end ; Yes, so we're done. inc idx1 ; No, so increment the instruction ID. @offset: - lda #13 ; Get the base size of the instruction table. + lda #14 ; Get the base size of the instruction table. clc ; Prepare for a non carrying multiply. mul idx1 ; Multiply the base offset, by the instruction ID. sta.w idx2 ; Save the offset in the third index. @@ -371,7 +293,8 @@ set_lexptr: set_cmdbuf: - ldb #0 ; Set the first pointer + and #0 ; Reset A. + tab ; Reset B. lda.d #cmd_buf ; to the command buffer. jsr set_ptr ; and #0 ; Reset A. @@ -414,7 +337,7 @@ delmcpy: and #$FF ; Get the current byte. pha ; Preserve the character. lda a ; Are we calling isdelm2? - pla ; Get the character back. + pla ; Get the character back. bne @isdelm2 ; Yes, so use isdelm2. jsr isdelm ; No, so get the delimiter value from isdelm. @delmchk: @@ -504,6 +427,3 @@ make_tok: nop ; @end: rts ; End of make_tok. - -; Entry point for utility subroutines. -utils: diff --git a/programs/sub-suite/libc.s b/programs/sub-suite/libc.s new file mode 100644 index 0000000..bd55f9c --- /dev/null +++ b/programs/sub-suite/libc.s @@ -0,0 +1,201 @@ +; Simple libc implementation for the SuB Suite + +strtoull: + phy.w ; Preserve Y. + and #0 ; Reset A. + tay ; Reset Y. + pha.q ; Reset the value buffer. +@loop: + lda (sp+20), y ; Get a character from the string. + pha ; Preserve the character. + jsr isdigit ; Is this character, a digit? + pla ; Get the character back. + bne @digit ; Yes, so extract the value from it. + jsr tolower ; No, so convert the character to lowercase. + pha ; Preserve the character. + jsr islower ; Is this an alphabetical character? + pla ; Get the character back. + beq @end ; No, so we're done. +@alpha: + sec ; Yes, so prepare for a non borrowing subtract. + sbc #'a'-10 ; Get the numeric value from this digit. + bra @chkbase ; Check if the value matches the base. +@digit: + sec ; Prepare for a non borrowing subtract. + sbc #'0' ; Get the numeric value from this digit. +@chkbase: + cmp sp+19 ; Does the value match the base? + bcs @end ; No, so we're done. +@addval: + tab ; Save the digit value. + lda.q sp+1 ; Get the value from the value buffer. + mul sp+19 ; Multiply the value by the base. + clc ; Prepare for a non carrying add. + aab ; Add the digit value to the total value. + sta.q sp+1 ; Place the value in the value buffer. + iny ; Increment the string index. + and #0 ; Reset A. + bra @loop ; Keep looping. +@end: + pla.q ; Get the value buffer back. + ply.w ; Get Y back. + ldb #0 ; Reset B. + rts ; End of strtoull. + + +strlen: + pha.q ; Set the temp variable to the argument. + ldb #0 ; Reset B. + tba ; Reset A. + tax ; Reset X. + phy.w ; Preserve Y. + txy ; Reset Y. +@loop: + lda (sp+3), y ; Are we at the end of the string? + beq @end ; Yes, so we're done. + iny ; No, so increment the index. + bra @loop ; Keep looping. +@end: + tyx ; Return the length in X. + ply.w ; Get the preserved value back. + pla.q ; Get the argument back. + txa ; Get the return value. + rts ; End of strlen. + + +strcmp: + ldb #0 ; Reset B. + tba ; Reset A. + phy.w ; Preserve Y. + tay ; Reset Y. +@loop: + ldb #0 ; Set the islong flag to false. + lda (sp+19), y ; Are we at the end of the first string? + beq cmpr ; Yes, so check if we're too short, or too long. + ldb #1 ; No, so set the islong flag to true. + cmp (sp+11), y ; Is the character of both strings, the same? + bne cmpr ; No, so check if we're too short, or too long. + iny ; Yes, so increment the index. + bra @loop ; Keep looping. + +strccmp: +strcasecmp: + ldb #0 ; Reset B. + tba ; Reset A. + phy.w ; Preserve Y. + tay ; Reset Y. +@loop: + ldb #0 ; Set the islong flag to false. + lda (sp+19), y ; Are we at the end of the first string? + beq cmpr ; Yes, so check if we're too short, or too long. + ldb #1 ; No, so set the islong flag to true. + jsr tolower ; Convert the character of string 1 to lowercase. + phb ; Preserve the islong flag. + pha ; Preserve the converted character. + lda (sp+13), y ; Get the character of the second string. + jsr tolower ; Convert the character of string 2 to lowercase. + tab ; Place it in B. + pla ; Get the character of string 1 back. + cab ; Is the character of both strings, the same? + plb ; Get the islong flag back. + bne cmpr ; No, so check if we're too short, or too long. + iny ; Yes, so increment the index. + bra @loop ; Keep looping. + +cmpr: + lda (sp+11), y ; Are we at the end of the second string? + beq @islong ; Yes, so check the islong flag. +@isshort: + lda (sp+19), y ; No, but are we at the end of the first string? + beq @short ; Yes, so return -1. +@islong: + cpb #1 ; Is the islong flag true? + bne @equ ; No, so return 0. +@long: + lda #1 ; Yes, so return 1. + bra @end ; We are done. +@equ: + lda #0 ; Return 0. + bra @end ; We are done. +@short: + lda #$FF ; Return -1. +@end: + ply.w ; Get the preserved value back. + rts ; End of cmpr. + + +isdigit: + sec ; Prepare for a non carrying subtraction. + sbc #'0' ; Subtract $30 from the passed character. + and #$FF ; Make sure that we have only one byte. + cmp #10 ; Is the subtracted value, less than 10? + bcs @false ; No, so return false. +@true: + lda #1 ; Yes, so return true. + bra @end ; We are done. +@false: + lda #0 ; Return false. +@end: + rts ; End of isdigit. + +isxdigit: + pha ; Preserve the character. + jsr isdigit ; Is this character, a decimal digit? + pla ; Get the character back. + bne @true ; Yes, so return true. +@alpha: + sec ; No, so prepare for a non carrying subtract. + ora #$20 ; Convert it to lowercase. + sbc #'a' ; Subtract $61 from the character. + and #$FF ; Make sure that we have only one byte. + cmp #6 ; Is the subtracted value, less than 6? + bcs @false ; No, so return false. +@true: + lda #1 ; Yes, so return true. + bra @end ; We are done. +@false: + lda #0 ; Return false. +@end: + rts ; End of isxdigit. + + +isupper: + sec ; Prepare for a non carrying subtraction. + sbc #'A' ; Subtract $41 from the passed character. + bra isletter ; Check if it's less than 26. +islower: + sec ; Prepare for a non carrying subtraction. + sbc #'a' ; Subtract $61 from the passed character. +isletter: + and #$FF ; Make sure that we have only one byte. + cmp #26 ; Is the subtracted value, less than 26? + bcs @false ; No, so return false. +@true: + lda #1 ; Yes, so return true. + bra @end ; We are done. +@false: + lda #0 ; Return false. +@end: + rts ; End of isletter. + + +tolower: + pha ; Preserve the character. + jsr isupper ; Is this character, an uppercase character? + pla ; Get the character back. + beq @end ; No, so we're done. +@lower: + ora #$20 ; Yes, so convert it to lowercase. +@end: + rts ; End of tolower. + + +toupper: + pha ; Preserve the character. + jsr islower ; Is this character, a lowercase character? + pla ; Get the character back. + beq @end ; No, so we're done. +@upper: + and #$5F ; Yes, so convert it to uppercase. +@end: + rts ; End of toupper. diff --git a/programs/sub-suite/subasm.s b/programs/sub-suite/subasm.s index d661695..0a7640d 100644 --- a/programs/sub-suite/subasm.s +++ b/programs/sub-suite/subasm.s @@ -3,225 +3,6 @@ ; ; by mr b0nk 500 <b0nk@b0nk.xyz> -MAX_SYM = $800 ; Max symbol size. -OPNUM = 88 ; Instruction count. - -.include "lexer.s" -.include "utils.s" - -.org incl -; String Constants. -asm_name: - .byte "SuBAsm" -asm_ver: - .byte "0.1" - -; Directives. -dir: - .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. - -mne: -; 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, $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 "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 - -; Data entry point for the lexer. -lexer_data: - - -; 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 - -; Value buffer used by strtoull. -valbuf: - .qword 0 - -; Copy buffer used by delmcpy. -cpybuf: - .qword 0 - -; Current token line. -ctok: - .word 0 - -; Last token line. -ltok: - .word 0 - -; Lexeme type. -lex_type: - .byte 0 - -; Lexeme string. -lexeme: - -; Symbol table. -.org lexeme+$100 -sym: - -; Fixup table. -; Fixups are unresolved symbols. -.org sym+$8000 -fix: - - -; Start of program code. -.org parser subasm: ldb #0 ; Set the first pointer lda.d #cmd_buf ; to the command buffer. @@ -244,15 +25,17 @@ subasm: 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. - phy.w ; 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.w ; Get back the screen buffer position. ldb #2 ; Save it in the third pointer. jsr set_ptr ; ldb #0 ; Reset B. jsr (ptr3) ; 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: @@ -306,7 +89,7 @@ chk_cmd: 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 strcasecmp ; Is the command buffer, the same as the command string? + 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. @@ -315,8 +98,7 @@ chk_cmd: inc idx1 ; No, so increment the command ID. @getlen: jsr strlen ; Get the string's length. - inx ; Add one to the length. - txa ; Place it in the accumulator. + 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. @@ -391,6 +173,3 @@ set: nop ; @end: rts ; End of set. - -; Entry point for utility subroutines. -lexer: diff --git a/programs/sub-suite/subeditor.s b/programs/sub-suite/subeditor.s index cc18b4c..2282a72 100644 --- a/programs/sub-suite/subeditor.s +++ b/programs/sub-suite/subeditor.s @@ -3,145 +3,15 @@ ; Writen in Sux assembly by ; mr b0nk 500 <b0nk@b0nk.xyz> -; I/O constants. -status = $100 ; Keyboard status. -scr = $101 ; Character that is to be printed. -kbd = $102 ; Character from the Keyboard. -step = $110 ; Enables clock stepping, when set. - -; Screen constants. -maxrow = 23 ; Screen's row count. -maxcol = 79 ; Screen's column count. - -; Include SuBAsm. -.include "subasm.s" - -.org $A000 -; String Literals/Constants. -tok: - .byte "dab" -msg: - .byte "oof, you divided a, and b on me.\n" - -ed_name: - .byte "SuBEditor" -ed_ver: - .byte "1" -ed_sver: - .byte ".0.0" - -ver_str: - .byte ", version " -made: - .byte "Created by, " - -author: - .byte "mr b0nk 500" - -string2: - .byte "You typed, " - -; Linewrap bitmask table. -bits: - .byte $80, $40, $20, $10, $08, $04, $02, $01 - -; This label is for any included files. -incl: - -; Linewrap table. -.org $30000 -bitabl: - .qword 0 - .qword 0 - -; SCreen buffer. -.org bitabl+$1000 -buffer: - -; Command buffer. -.org buffer+$2000 -cmd_buf: - - -; Screen variables. -.org 0 -scr_row: - .byte 0 -scr_col: - .byte 0 -scr_trow: - .byte 0 -scr_tcol: - .byte 0 -scr_ptr: - .word 0 -scr_ptr2: - .word 0 -scr_ptr3: - .word 0 - -; Pseudo registers. -a: - .byte 0 -b: - .byte 0 -c: - .byte 0 -d: - .byte 0 -e: - .byte 0 -f: - .byte 0 -g: - .byte 0 -; This pseudo register is always zero. -zero: - .qword 0 -; End of pseudo registers. - -end: - .qword 0 -bitmask: - .byte 0 -scr_str: - .byte 0 -scr_end: - .byte 0 -wrapped: - .byte 0 - -; Pointers -ptr: - .qword 0 -ptr2: - .qword 0 -ptr3: - .qword 0 - -; Main program .org $8000 reset: cps ; Reset the processor status register. ldx.w #$FFFF ; Reset the stack pointer. txs ; - ldy #0 ; Reset the Y register. - sty end ; - tyx ; Reset the X register. - lda #maxrow ; Set the end of the screen to the screen's max row count. - sta scr_end ; - tya ; Reset the Accumulator. - sta scr_str ; Set the start of the screen back to zero. - sta.q bitabl ; Reset the first half of the linewrap table. - sta.q bitabl+8 ; Reset the second half of the linewrap table. - inc end ; - lda.w #$1FFF ; Set the clear count to $1FFF. - sta.w scr_ptr ; - lda.d #buffer ; Set the array to be cleared to the screen buffer. - jsr clr_arr ; Clear the screen buffer. + ldy #0 ; Reset Y. + tyx ; Reset X. + jsr clr_scr ; Clear the screen. jsr pnt_strt ; Print the starting message. - lda #$C ; Clear the screen. - sta scr ; bra start ; Goto the start of the main program. clr_arr: @@ -193,30 +63,32 @@ pnt_strt: jsr print_char ; rts ; End of pnt_strt. -start: - lda #0 ; TODO: Update this for the Super VIA. - sta status ; Clear the control register of the I/O adapter. - tax ; Reset X. - phy.w ; Save the cursor index for later. - tay ; Reset the cursor index. + +clr_cmd: + and #0 ; Reset A. + tay ; Reset Y. lda.w #$3FF ; Set the clear count to $3FF. sta.w scr_ptr ; lda.d #cmd_buf ; Set the array to be cleared to the command buffer. jsr clr_arr ; Clear the command buffer. - ply.w ; Get back the cursor index. + rts ; End of clr_cmd. + + +start: + lda #0 ; TODO: Update this for the Super VIA. + sta status ; Clear the control register of the I/O adapter. + tax ; Reset X. + jsr clr_cmd ; Clear the command buffer. + jsr update_ptr ; Get the screen buffer index. + tay ; Save it in Y. and #0 ; Reset the Accumulator. - sta end ; bra read ; Start reading the keyboard. read: - lda #0 ; Reset the Accumulator. - sta end ; Disable the dummy flag. - inc end ; Enable the dummy flag. - lda status ; Did we get a key? - beq read ; No, so try again. - jsr getchar ; Yes, and was it a newline? - beq parse ; Yes, so start parsing the line. - bra read ; No, so keep looping. + jsr getchar ; Get a character. + jsr handle_char ; Send the character to the handler routine. + beq parse ; The handled character was a newline, so start parsing. + bra read ; Keep looping. parse: lda #0 ; @@ -225,6 +97,16 @@ parse: bra start ; +getchar: + and #0 ; Reset A. +@loop: + lda status ; Did we get a key? + beq @loop ; No, so try again. + lda kbd ; Yes, so get the typed character. +@end: + rts ; End of getchar. + + print_str: ldx #0 ; Reset X. sta.q end ; Save the parameter. @@ -240,17 +122,19 @@ print_str: cmp.q end ; Did the pointer change? bne @reset ; Yes, so set it back. and #0 ; No, reset the accumulator. - phy.w ; Save the cursor index. txy ; Copy the string index into Y. - lda (ptr), y ; Are we at the end of the string? - ply.w ; Get the cursor index back. - beq @end ; Yes, so we're done. - inx ; No, so increment the string index. + ldb (ptr), y ; Are we at the end of the string? + beq @end ; Yes, so we're done. + jsr update_ptr ; No, so get the screen buffer index. + tay ; Save it in Y. + tba ; Get the character back. + inx ; Increment the string index. jsr print_char ; Print the character. bra @loop ; Keep looping. @end: ldb #0 ; Enable insert mode. stb b ; + tba ; Reset A. rts ; End of print_str. getbit: @@ -335,8 +219,8 @@ bitpos: pla ; Get back the bitmask. rts ; End of bitpos. -getchar: - lda kbd ; Get the character that was typed from the keyboard. + +handle_char: ldb #0 ; Reset the B register. stb e ; Set the temporary row position to zero, in case we get a newline. stb b ; Enable insert mode. @@ -354,7 +238,7 @@ getchar: jsr print_char ; No, so print the character. lda a ; Get the return value. cmp #'\n' ; Is the return value, a newline? - beq @true ; Yes, so return true. + beq @true ; Yes, so return true. bra @false ; No, so return false. @row: ldb e ; Get the temporary row position. @@ -373,7 +257,7 @@ getchar: @false: lda #1 ; Return false. @end: - rts ; End of getchar. + rts ; End of handle_char. cmd_cpy: @@ -633,11 +517,11 @@ clr_scr: sta.w scr_ptr ; lda.d #buffer ; Set the array to be cleared to the screen buffer. jsr clr_arr ; Clear the screen buffer. - tay ; - lda.w #$3FF ; Set the clear count to $3FF. - sta.w scr_ptr ; - lda.d #cmd_buf ; Set the array to be cleared to the command buffer. - jsr clr_arr ; Clear the screen buffer. +; tay ; +; lda.w #$3FF ; Set the clear count to $3FF. +; sta.w scr_ptr ; +; lda.d #cmd_buf ; Set the array to be cleared to the command buffer. +; jsr clr_arr ; Clear the screen buffer. sta scr_col ; sta scr_row ; jsr update_pos ; @@ -1051,9 +935,7 @@ isshftdown: rts ; -update_pos: - ldb #1 ; Set the F pseudo register to one, to fix some bugs. - stb f ; +update_ptr: clc ; Clear the carry flag. lda scr_row ; Add the cursor's line number, adc scr_str ; with the starting line number to get the absolute line number. @@ -1061,6 +943,13 @@ update_pos: mul #maxcol+1 ; Multiply the line number by the screen's max column count, plus 1. clc ; Clear the carry flag. adc scr_col ; Add the cursor's column number to get the screen index. + rts ; End of update_ptr. + + +update_pos: + ldb #1 ; Set the F pseudo register to one, to fix some bugs. + stb f ; + jsr update_ptr ; Update the screen buffer index. tay ; Place the index into the Y register. tba ; Reset A. lda #$1B ; Print an escape character @@ -1071,6 +960,7 @@ update_pos: jsr getcol ; Start printing the column number to the screen. lda #'H' ; Print 'H' sta scr ; to the screen. + ;inc step ; rts ; End of update_pos. getrow: @@ -1206,6 +1096,7 @@ rdrw_ln: sta f ; rts ; + set_ptr: cpb #1 ; Are we setting the second pointer? beq @ptr2 ; Yes, so start setting it. @@ -1224,12 +1115,3 @@ set_ptr: sta.q ptr3 ; Set the third pointer. @end: rts ; End of set_ptr. - -; Entry point for SuBAsm. -parser: - -.org $FFC0 -.qword reset -a -d - diff --git a/programs/sub-suite/subsuite.s b/programs/sub-suite/subsuite.s new file mode 100644 index 0000000..36ac541 --- /dev/null +++ b/programs/sub-suite/subsuite.s @@ -0,0 +1,22 @@ +.org 0 + +; Include Declarations. +.include "declare.s" + +; Include SuBEditor. +.include "subeditor.s" +; Include SuBAsm. +.include "subasm.s" +; Include Lexer. +.include "lexer.s" +; Include Utility subroutines. +.include "utils.s" +; Include libc routines. +.include "libc.s" + +.org $FFC0 +.qword reset +a +;l a +;q +d diff --git a/programs/sub-suite/utils.s b/programs/sub-suite/utils.s index a66f036..046164a 100644 --- a/programs/sub-suite/utils.s +++ b/programs/sub-suite/utils.s @@ -1,22 +1,5 @@ ; Utility subroutines for SuBAsm. -.org util_data -; Hex character table. -hex_char: - .byte "0123456789ABCDEF" - -; Compare, and return table for pre-tokens. -ptok_tab: - .byte ".@:=+-><(),xy\"\'#;$%" -; Compare, and return table for isdelm. -dtab: - .byte "\n,\"\' " -; Compare, and return table for isdelm2. -dtab2: - .byte "),.+<>-=;\n" - -.org utils - print_hi: and #0 ; Reset A. sta idx3 ; Clear the string index. @@ -139,48 +122,6 @@ print_hex: rts ; End of print_hex. -strtoull: - phy.w ; Preserve Y. - sta f ; Save the base. - and #0 ; Reset A. - tay ; Reset Y. - sta.q valbuf ; Reset the value buffer. -@loop: - lda (ptr3), y ; Get a character from the string. - pha ; Preserve the character. - jsr isdigit ; Is this character, a digit? - pla ; Get the character back. - bne @digit ; Yes, so extract the value from it. - jsr tolower ; No, so convert the character to lowercase. - pha ; Preserve the character. - jsr islower ; Is this an alphabetical character? - pla ; Get the character back. - beq @end ; No, so we're done. -@alpha: - sec ; Yes, so prepare for a non borrowing subtract. - sbc #'a'-10 ; Get the numeric value from this digit. - bra @chkbase ; Check if the value matches the base. -@digit: - sec ; Prepare for a non borrowing subtract. - sbc #'0' ; Get the numeric value from this digit. -@chkbase: - cmp f ; Does the value match the base? - bcs @end ; No, so we're done. -@addval: - tab ; Save the digit value. - lda.q valbuf ; Get the value from the value buffer. - mul f ; Multiply the value by the base. - clc ; Prepare for a non carrying add. - aab ; Add the digit value to the total value. - sta.q valbuf ; Place the value in the value buffer. - iny ; Increment the string index. - bra @loop ; Keep looping. -@end: - ply.w ; Get Y back. - ldb #0 ; Reset B. - rts ; End of strtoull. - - charcpy: ldx idx3 ; Get the string index. sta strbuf, x ; Save it in the string buffer. @@ -188,164 +129,46 @@ charcpy: rts ; End of charcpy. -strlen: - ldb #1 ; Set the second pointer - jsr set_ptr ; to the passed pointer. - deb ; Reset B. - tba ; Reset A. - tax ; Reset X. - phy.w ; Preserve Y. - txy ; Reset Y. -@loop: - lda (ptr2), y ; Are we at the end of the string? - beq @end ; Yes, so we're done. - iny ; No, so increment the index. - bra @loop ; Keep looping. -@end: - tyx ; Return the length in X. - ply.w ; Get the preserved value back. - rts ; End of strlen. - - -strcmp: - ldb #1 ; Set the second pointer - jsr set_ptr ; to the passed pointer. - deb ; Reset B. - tba ; Reset A. - phy.w ; Preserve Y. - tay ; Reset Y. -@loop: - ldb #0 ; Set the islong flag to false. - lda (ptr), y ; Are we at the end of the first string? - beq cmpr ; Yes, so check if we're too short, or too long. - ldb #1 ; No, so set the islong flag to true. - cmp (ptr2), y ; Is the character of both strings, the same? - bne cmpr ; No, so check if we're too short, or too long. - iny ; Yes, so increment the index. - bra @loop ; Keep looping. - -strcasecmp: - ldb #1 ; Set the second pointer - jsr set_ptr ; to the passed pointer. - deb ; Reset B. - tba ; Reset A. - phy.w ; Preserve Y. - tay ; Reset Y. -@loop: - ldb #0 ; Set the islong flag to false. - lda (ptr), y ; Are we at the end of the first string? - beq cmpr ; Yes, so check if we're too short, or too long. - ldb #1 ; No, so set the islong flag to true. - jsr tolower ; Convert the character of string 1 to lowercase. - phb ; Preserve the islong flag. - pha ; Preserve the converted character. - lda (ptr2), y ; Get the character of the second string. - jsr tolower ; Convert the character of string 2 to lowercase. - tab ; Place it in B. - pla ; Get the character of string 1 back. - cab ; Is the character of both strings, the same? - plb ; Get the islong flag back. - bne cmpr ; No, so check if we're too short, or too long. - iny ; Yes, so increment the index. - bra @loop ; Keep looping. - -cmpr: - lda (ptr2), y ; Are we at the end of the second string? - beq @islong ; Yes, so check the islong flag. -@isshort: - lda (ptr), y ; No, but are we at the end of the first string? - beq @short ; Yes, so return -1. -@islong: - cpb #1 ; Is the islong flag true? - bne @equ ; No, so return 0. -@long: - lda #1 ; Yes, so return 1. - bra @end ; We are done. -@equ: - lda #0 ; Return 0. - bra @end ; We are done. -@short: - lda #$FF ; Return -1. -@end: - ply.w ; Get the preserved value back. - rts ; End of strcmp. - - -isdigit: - sec ; Prepare for a non carrying subtraction. - sbc #'0' ; Subtract $30 from the passed character. - and #$FF ; Make sure that we have only one byte. - cmp #10 ; Is the subtracted value, less than 10? - bcs @false ; No, so return false. -@true: - lda #1 ; Yes, so return true. - bra @end ; We are done. -@false: - lda #0 ; Return false. -@end: - rts ; End of isdigit. - -isxdigit: - pha ; Preserve the character. - jsr isdigit ; Is this character, a decimal digit? - pla ; Get the character back. - bne @true ; Yes, so return true. -@alpha: - sec ; No, so prepare for a non carrying subtract. - ora #$20 ; Convert it to lowercase. - sbc #'a' ; Subtract $61 from the character. - and #$FF ; Make sure that we have only one byte. - cmp #6 ; Is the subtracted value, less than 6? - bcs @false ; No, so return false. -@true: - lda #1 ; Yes, so return true. - bra @end ; We are done. -@false: - lda #0 ; Return false. -@end: - rts ; End of isxdigit. - - -isupper: - sec ; Prepare for a non carrying subtraction. - sbc #'A' ; Subtract $41 from the passed character. - bra isletter ; Check if it's less than 26. -islower: - sec ; Prepare for a non carrying subtraction. - sbc #'a' ; Subtract $61 from the passed character. -isletter: - and #$FF ; Make sure that we have only one byte. - cmp #26 ; Is the subtracted value, less than 26? - bcs @false ; No, so return false. -@true: - lda #1 ; Yes, so return true. - bra @end ; We are done. -@false: - lda #0 ; Return false. -@end: - rts ; End of isletter. - - -tolower: - pha ; Preserve the character. - jsr isupper ; Is this character, an uppercase character? - pla ; Get the character back. - beq @end ; No, so we're done. -@lower: - ora #$20 ; Yes, so convert it to lowercase. -@end: - rts ; End of tolower. - - -toupper: - pha ; Preserve the character. - jsr islower ; Is this character, a lowercase character? - pla ; Get the character back. - beq @end ; No, so we're done. -@upper: - and #$5F ; Yes, so convert it to uppercase. -@end: - rts ; End of toupper. +strcmpg: + ldb.w #strcmp ; Get the address of strcmp. + phb.q ; Use it for an indirect call. + ldb.q ptr ; Get the first pointer. + bra gargs ; Jump to the argument handler. +strcaseg: + ldb.w #strccmp ; Get the address of strcasecmp. + phb.q ; Use it for an indirect call. + ldb.q ptr ; Get the first pointer. + bra gargs ; Jump to the argument handler. +gargs: + phb.q ; Use the pointer in B as the first arg. + pha.q ; Use the value in A as the second arg. + and #0 ; reset a. + tab ; reset b. + jsr (sp+17) ; call the pushed routine. + tab ; Preserve the return value. + pla.q ; Get the second arg back. + pla.q ; Get the first arg back. + pla.q ; Get the pushed routine back. + tba ; Get the return value back. + rts ; End of gargs. + + +strtoullg: + ldb.q ptr3 ; Get the third pointer. + phb.q ; Push the first arg. + pha ; Push the second arg. + and #0 ; Reset A. + tab ; Reset B. + jsr strtoull ; Call strtoull. + tab ; Preserve the return value. + pla ; Get the second arg back. + pla.q ; Get the first arg back. + tba ; Get the return value back. + pha.q ; Preserve the return value. + and #0 ; Reset A. + tab ; Reset B. + pla.q ; Get the return value back. + rts ; End of strtoullg. isdelm2: |