From 1ec19679b3db209429b0897f6ccda6d09d018a70 Mon Sep 17 00:00:00 2001 From: mrb0nk500 Date: Sat, 8 Aug 2020 10:28:36 -0400 Subject: Did a ton of stuff. - Changed the file structure of the SuB Suite, so that all variable declarations, symbols, and constants are in a single file. - Moved the C library functionss into a separate file, and made them use stack frames. - Added support for using the emulator's assembler for realtime debugging, to enter it, get in to stepping mode by pressing Ctrl+s, press any other key, then press F1, The reason for having to press some other key before pressing F1 is because it only allows entering the assembler when the keyboard is not ready. - Added the ".res" directive to the emulator's assembler, the ".res" directive tells the assembler to reserve however many bytes specified by the operand. - Fixed some bugs in the emulator's assembler. --- programs/sub-suite/declare.s | 430 +++++++++++++++++++++++++++++++++++++++++ programs/sub-suite/lexer.s | 152 ++++----------- programs/sub-suite/libc.s | 201 +++++++++++++++++++ programs/sub-suite/subasm.s | 233 +--------------------- programs/sub-suite/subeditor.s | 232 ++++++---------------- programs/sub-suite/subsuite.s | 22 +++ programs/sub-suite/utils.s | 257 ++++-------------------- 7 files changed, 792 insertions(+), 735 deletions(-) create mode 100644 programs/sub-suite/declare.s create mode 100644 programs/sub-suite/libc.s create mode 100644 programs/sub-suite/subsuite.s (limited to 'programs') 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 -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 -; 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: -- cgit v1.2.3-13-gbd6f