summaryrefslogtreecommitdiff
path: root/programs/sub-suite
diff options
context:
space:
mode:
Diffstat (limited to 'programs/sub-suite')
-rw-r--r--programs/sub-suite/declare.s430
-rw-r--r--programs/sub-suite/lexer.s152
-rw-r--r--programs/sub-suite/libc.s201
-rw-r--r--programs/sub-suite/subasm.s233
-rw-r--r--programs/sub-suite/subeditor.s232
-rw-r--r--programs/sub-suite/subsuite.s22
-rw-r--r--programs/sub-suite/utils.s257
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: