summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormrb0nk500 <b0nk@b0nk.xyz>2020-07-06 20:04:41 -0400
committermrb0nk500 <b0nk@b0nk.xyz>2020-07-06 20:04:41 -0400
commit756c606af68be8ccca7aced3b9c3d56fb2d5087f (patch)
treefbc02b63feb1933a213d26ae68ab1b1a104e4ef3
parent887802efcdb3b56263069cc6778a8f53ed89d599 (diff)
- Implemented a new opcode table.
- Added a new preifx called the OF prefix, which adds the contents of a specific register to the current operand. - Added a table generator, which parses opcode table csv files.
-rw-r--r--Makefile10
-rw-r--r--asmmon.h572
-rw-r--r--assemble.c129
-rw-r--r--csv-parse.c113
-rw-r--r--csv-parse.h32
-rw-r--r--disasm.c73
-rw-r--r--disasm.h353
-rw-r--r--enums.h490
-rw-r--r--lexer.c28
-rw-r--r--lexer.h2
-rw-r--r--opcode-gen.c505
-rw-r--r--opcode.h4
-rw-r--r--programs/sub-suite/lexer.s180
-rw-r--r--programs/sub-suite/subasm.s34
-rw-r--r--programs/sub-suite/subeditor.s405
-rw-r--r--programs/sub-suite/utils.s130
-rw-r--r--sux.c221
-rw-r--r--sux.h103
-rw-r--r--tables.h353
-rw-r--r--test/stack-frame.s32
20 files changed, 2400 insertions, 1369 deletions
diff --git a/Makefile b/Makefile
index 0bf43f0..454ea42 100644
--- a/Makefile
+++ b/Makefile
@@ -37,11 +37,14 @@ endif
OBJS = sux.o io.o $(DBG_OBJ) asmmon.o assemble.o lexer.o
+OBJS2 = subasm.o subeditor.o
+OBJS3 = opcode-gen.o csv-parse.o
CFLAGS = $(PCC_CFLAGS) $(DBG_CFLAGS) $(IO_CFLAGS) $(BENCH_CFLAGS) $(CFLAGS_EXTRA)
-OBJS2 = subasm.o subeditor.o
+
OBJ_NAME = cisc-0.2
OBJ_NAME2 = subeditor-c
+OBJ_NAME3 = opcode-gen
all : clean $(OBJ_NAME)
@@ -49,11 +52,12 @@ subeditor : clean $(OBJS2)
$(CC) $(OBJS2) $(CFLAGS) -lcurses -ltinfo -o $(OBJ_NAME2)
cisc-0.2: $(OBJS)
$(CC) $(OBJS) $(CFLAGS) -lpthread -lcurses -ltinfo -o $(OBJ_NAME)
-
+opcode-gen : clean $(OBJS3)
+ $(CC) $(OBJS3) $(CFLAGS) -o $(OBJ_NAME3)
%.o : %.c
$(CC) -c $< -o $@ $(CFLAGS)
clean :
- rm -f $(OBJ_NAME) $(OBJ_NAME2) *.o
+ rm -f $(OBJ_NAME) $(OBJ_NAME2) $(OBJ_NAME3) *.o
install :
install -D -m755 $(OBJ_NAME) $(BIN_DIR)/$(OBJ_NAME)
uninstall :
diff --git a/asmmon.h b/asmmon.h
index 39e2d19..eadbc83 100644
--- a/asmmon.h
+++ b/asmmon.h
@@ -93,6 +93,7 @@ enum token {
TOK_IMM,
TOK_OPCODE,
TOK_RS,
+ TOK_OF,
TOK_COMMENT,
TOK_HEX,
TOK_DEC,
@@ -114,6 +115,8 @@ enum pre_token {
PTOK_COMMA,
PTOK_X,
PTOK_Y,
+ PTOK_S,
+ PTOK_P,
PTOK_DQUOTE,
PTOK_SQUOTE,
PTOK_HASH,
@@ -133,96 +136,95 @@ enum expr {
EXPR_NONE
};
-static const uint8_t opcodes[OPNUM][9] = {
- /* IMM ZM ZMX ZMY IND INDX INDY ABS IMPL*/
- [ 0] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00},
- [ 1] = {0x01, 0x06, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x04, 0xFF},
- [ 2] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x02},
- [ 3] = {0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
- [ 4] = {0x09, 0x2D, 0xFF, 0xFF, 0x55, 0xAD, 0xAC, 0x2C, 0xFF},
- [ 5] = {0x0A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
- [ 6] = {0xFF, 0x0D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0C, 0xE5},
- [ 7] = {0xFF, 0x0E, 0xFF, 0xFF, 0xCE, 0xFF, 0xFF, 0x10, 0xFF},
- [ 8] = {0x11, 0x16, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x14, 0xFF},
- [ 9] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x12},
- [10] = {0x18, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
- [11] = {0x19, 0x3D, 0xFF, 0xFF, 0x85, 0xFF, 0xFF, 0x4C, 0xFF},
- [12] = {0x1A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
- [13] = {0xFF, 0x1D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1C, 0xF5},
- [14] = {0xFF, 0x1E, 0xFF, 0xFF, 0xBE, 0xFF, 0xFF, 0x20, 0xFF},
- [15] = {0x21, 0x26, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x24, 0xFF},
- [16] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x22},
- [17] = {0x28, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
- [18] = {0x29, 0x4D, 0xFF, 0xFF, 0xB5, 0xFF, 0xFF, 0x3C, 0xFF},
- [19] = {0x2A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
- [20] = {0xFF, 0x2E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x30, 0xFF},
- [21] = {0x31, 0x36, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x34, 0xFF},
- [22] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x32},
- [23] = {0x38, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
- [24] = {0x3A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
- [25] = {0xFF, 0x3E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0xFF},
- [26] = {0x41, 0x46, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x44, 0xFF},
- [27] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x42},
- [28] = {0x48, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
- [29] = {0x4A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
- [30] = {0xFF, 0x4E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x50, 0xFF},
- [31] = {0x51, 0x56, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x54, 0xFF},
- [32] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x52},
- [33] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x58},
- [34] = {0x5A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
- [35] = {0xFF, 0x5E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x60, 0xFF},
- [36] = {0x61, 0x66, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x64, 0xFF},
- [37] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x62},
- [38] = {0x68, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
- [39] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x6A},
- [40] = {0xFF, 0x6E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x70, 0xFF},
- [41] = {0x71, 0x76, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x74, 0xFF},
- [42] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x72},
- [43] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x78},
- [44] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7A},
- [45] = {0xFF, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0xFF},
- [46] = {0x81, 0x86, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x84, 0xFF},
- [47] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x82},
- [48] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x88},
- [49] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x8A},
- [50] = {0xFF, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x90, 0xFF},
- [51] = {0x91, 0x96, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x94, 0xFF},
- [52] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x92},
- [53] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x98},
- [54] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9A},
- [55] = {0xFF, 0x9E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA0, 0xFF},
- [56] = {0xA1, 0xA6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA4, 0xFF},
- [57] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA2},
- [58] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA8},
- [59] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAA},
- [60] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAE},
- [61] = {0xB1, 0xB6, 0xFF, 0xFF, 0x25, 0x7D, 0x7C, 0xB4, 0xFF},
- [62] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB2},
- [63] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB8},
- [64] = {0xB9, 0xBD, 0xFF, 0xC9, 0x95, 0xFF, 0xFF, 0xBC, 0xFF},
- [65] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBA},
- [66] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0},
- [67] = {0xC1, 0xC6, 0x79, 0x39, 0x05, 0x5D, 0x5C, 0xC4, 0xFF},
- [68] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC5},
- [69] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC8},
- [70] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCA},
- [71] = {0xFF, 0xCD, 0x89, 0x49, 0x15, 0x6D, 0x6C, 0xCC, 0xFF},
- [72] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0},
- [73] = {0xD1, 0xD6, 0x99, 0x59, 0x35, 0x8D, 0x8C, 0xD4, 0xFF},
- [74] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD5},
- [75] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD8},
- [76] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDA},
- [77] = {0xFF, 0xDD, 0xA9, 0x69, 0x45, 0x9D, 0x9C, 0xDC, 0xFF},
- [78] = {0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
- [79] = {0xE1, 0xE6, 0xE9, 0xFF, 0x65, 0xFF, 0xFF, 0xE4, 0xFF},
- [80] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE8},
- [81] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEA},
- [82] = {0xFF, 0xED, 0xF9, 0xFF, 0x75, 0xFF, 0xFF, 0xEC, 0xFF},
- [83] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEE},
- [84] = {0xF1, 0xF6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xFF},
- [85] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF2},
- [86] = {0xFF, 0xFD, 0xFF, 0xD9, 0xA5, 0xFF, 0xFF, 0xFC, 0xFF},
- [87] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE}
+static const uint8_t opcodes[OPNUM][10] = {
+ /* IMM ZM ZMX ZMY IND INDX INDY ABS REL IMPL*/
+ [AAB] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x02}, /* AAB */
+ [ABA] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x22}, /* ABA */
+ [ADC] = {0x01, 0x06, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x04, 0xFF, 0xFF}, /* ADC */
+ [AND] = {0x21, 0x26, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x24, 0xFF, 0xFF}, /* AND */
+ [ARB] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF2}, /* ARB */
+ [ASR] = {0xF1, 0xF6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xFF, 0xFF}, /* ASR */
+ [BCC] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0xFF}, /* BCC */
+ [BCS] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x70, 0xFF}, /* BCS */
+ [BEQ] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x90, 0xFF}, /* BEQ */
+ [BNE] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA0, 0xFF}, /* BNE */
+ [BNG] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x60, 0xFF}, /* BNG */
+ [BPO] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x50, 0xFF}, /* BPO */
+ [BRA] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0xFF}, /* BRA */
+ [BRK] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x68}, /* BRK */
+ [BVC] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0xFF}, /* BVC */
+ [BVS] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB0, 0xFF}, /* BVS */
+ [CAB] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB2}, /* CAB */
+ [CLC] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x08}, /* CLC */
+ [CLI] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x28}, /* CLI */
+ [CLV] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x48}, /* CLV */
+ [CMP] = {0xB1, 0xB6, 0xFF, 0xFF, 0x25, 0x7D, 0x7C, 0xB4, 0xFF, 0xFF}, /* CMP */
+ [CPB] = {0x2A, 0x2D, 0xFF, 0xFF, 0x55, 0xAD, 0xAC, 0x2C, 0xFF, 0xFF}, /* CPB */
+ [CPS] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00}, /* CPS */
+ [CPX] = {0x3A, 0x4D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3C, 0xFF, 0xFF}, /* CPX */
+ [CPY] = {0x4A, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x4C, 0xFF, 0xFF}, /* CPY */
+ [DAB] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA2}, /* DAB */
+ [DEB] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC2}, /* DEB */
+ [DEC] = {0xFF, 0x0D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0C, 0xFF, 0x0A}, /* DEC */
+ [DEX] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x09}, /* DEX */
+ [DEY] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x29}, /* DEY */
+ [DIV] = {0xA1, 0xA6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA4, 0xFF, 0xFF}, /* DIV */
+ [INB] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD2}, /* INB */
+ [INC] = {0xFF, 0x1D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1C, 0xFF, 0x1A}, /* INC */
+ [INX] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x19}, /* INX */
+ [INY] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x39}, /* INY */
+ [JMP] = {0xFF, 0x30, 0xFF, 0xFF, 0xB5, 0xFF, 0xFF, 0x10, 0xFF, 0xFF}, /* JMP */
+ [JSR] = {0xFF, 0x40, 0xFF, 0xFF, 0xA5, 0xFF, 0xFF, 0x20, 0xFF, 0xFF}, /* JSR */
+ [LDA] = {0xC1, 0xC6, 0xB8, 0x78, 0x05, 0x5D, 0x5C, 0xC4, 0xFF, 0xFF}, /* LDA */
+ [LDB] = {0xD1, 0xD6, 0xD8, 0x98, 0x35, 0x8D, 0x8C, 0xD4, 0xFF, 0xFF}, /* LDB */
+ [LDX] = {0xB9, 0xBD, 0xFF, 0xFF, 0x85, 0xFF, 0xFF, 0xBC, 0xFF, 0xFF}, /* LDX */
+ [LDY] = {0xE1, 0xE6, 0xFF, 0xFF, 0x65, 0xFF, 0xFF, 0xE4, 0xFF, 0xFF}, /* LDY */
+ [LLB] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x52}, /* LLB */
+ [LRB] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x62}, /* LRB */
+ [LSL] = {0x51, 0x56, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x54, 0xFF, 0xFF}, /* LSL */
+ [LSR] = {0x61, 0x66, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x64, 0xFF, 0xFF}, /* LSR */
+ [MAB] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x92}, /* MAB */
+ [MUL] = {0x91, 0x96, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x94, 0xFF, 0xFF}, /* MUL */
+ [NOP] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEA}, /* NOP */
+ [OAB] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x32}, /* OAB */
+ [ORA] = {0x31, 0x36, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x34, 0xFF, 0xFF}, /* ORA */
+ [PHA] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x79}, /* PHA */
+ [PHB] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x99}, /* PHB */
+ [PHP] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x59}, /* PHP */
+ [PHX] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE9}, /* PHX */
+ [PHY] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9}, /* PHY */
+ [PLA] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x89}, /* PLA */
+ [PLB] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA9}, /* PLB */
+ [PLP] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x69}, /* PLP */
+ [PLX] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9}, /* PLX */
+ [PLY] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD9}, /* PLY */
+ [RLB] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x72}, /* RLB */
+ [ROL] = {0x71, 0x76, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x74, 0xFF, 0xFF}, /* ROL */
+ [ROR] = {0x81, 0x86, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x84, 0xFF, 0xFF}, /* ROR */
+ [RRB] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x82}, /* RRB */
+ [RTI] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0}, /* RTI */
+ [RTS] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0}, /* RTS */
+ [SAB] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x12}, /* SAB */
+ [SBC] = {0x11, 0x16, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x14, 0xFF, 0xFF}, /* SBC */
+ [SEC] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x18}, /* SEC */
+ [SEI] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x38}, /* SEI */
+ [STA] = {0xFF, 0xCD, 0xC8, 0x88, 0x15, 0x6D, 0x6C, 0xCC, 0xFF, 0xFF}, /* STA */
+ [STB] = {0xFF, 0xDD, 0xE8, 0xA8, 0x45, 0x9D, 0x9C, 0xDC, 0xFF, 0xFF}, /* STB */
+ [STX] = {0xFF, 0xFD, 0xFF, 0xFF, 0x95, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF}, /* STX */
+ [STY] = {0xFF, 0xED, 0xFF, 0xFF, 0x75, 0xFF, 0xFF, 0xEC, 0xFF, 0xFF}, /* STY */
+ [TAB] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x5A}, /* TAB */
+ [TAX] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9A}, /* TAX */
+ [TAY] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7A}, /* TAY */
+ [TBA] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x6A}, /* TBA */
+ [TSX] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDA}, /* TSX */
+ [TXA] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAA}, /* TXA */
+ [TXS] = {0xFA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, /* TXS */
+ [TXY] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCA}, /* TXY */
+ [TYA] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x8A}, /* TYA */
+ [TYX] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBA}, /* TYX */
+ [WAI] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x58}, /* WAI */
+ [XAB] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x42}, /* XAB */
+ [XOR] = {0x41, 0x46, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x44, 0xFF, 0xFF} /* XOR */
};
static const char *dir_t[6] = {
@@ -241,27 +243,28 @@ static const char *rs_t[4] = {
[3] = ".q"
};
-static const char *lex_tok[17] = {
- [0x00] = "TOK_DIR",
- [0x01] = "TOK_LOCAL",
- [0x02] = "TOK_LABEL",
- [0x03] = "TOK_SYM",
- [0x04] = "TOK_EXPR",
- [0x05] = "TOK_CSV",
- [0x06] = "TOK_STRING",
- [0x07] = "TOK_CHAR",
- [0x08] = "TOK_IND",
- [0x09] = "TOK_IMM",
- [0x0A] = "TOK_OPCODE",
- [0x0B] = "TOK_RS",
- [0x0C] = "TOK_COMMENT",
- [0x0D] = "TOK_HEX",
- [0x0E] = "TOK_DEC",
- [0x0F] = "TOK_BIN",
- [0x10] = "TOK_INCLUDE"
+static const char *lex_tok[18] = {
+ [TOK_DIR ] = "TOK_DIR",
+ [TOK_LOCAL ] = "TOK_LOCAL",
+ [TOK_LABEL ] = "TOK_LABEL",
+ [TOK_SYM ] = "TOK_SYM",
+ [TOK_EXPR ] = "TOK_EXPR",
+ [TOK_CSV ] = "TOK_CSV",
+ [TOK_STRING ] = "TOK_STRING",
+ [TOK_CHAR ] = "TOK_CHAR",
+ [TOK_IND ] = "TOK_IND",
+ [TOK_IMM ] = "TOK_IMM",
+ [TOK_OPCODE ] = "TOK_OPCODE",
+ [TOK_RS ] = "TOK_RS",
+ [TOK_OF ] = "TOK_OF",
+ [TOK_COMMENT] = "TOK_COMMENT",
+ [TOK_HEX ] = "TOK_HEX",
+ [TOK_DEC ] = "TOK_DEC",
+ [TOK_BIN ] = "TOK_BIN",
+ [TOK_INCLUDE] = "TOK_INCLUDE"
};
-static const char *adrmode[9] = {
+static const char *adrmode[10] = {
[IMM ] = "IMM",
[ZM ] = "ZM",
[ZMX ] = "ZMX",
@@ -270,189 +273,188 @@ static const char *adrmode[9] = {
[INDX] = "INDX",
[INDY] = "INDY",
[ABS ] = "ABS",
+ [REL ] = "REL",
[IMPL] = "IMPL"
};
static const char *mne[OPNUM] = {
- [ 0] = "CPS",
- [ 1] = "ADC",
- [ 2] = "AAB",
- [ 3] = "PHP",
- [ 4] = "CPB",
- [ 5] = "PHB",
- [ 6] = "DEC",
- [ 7] = "JMP",
- [ 8] = "SBC",
- [ 9] = "SAB",
- [10] = "ENT",
- [11] = "CPY",
- [12] = "PLB",
- [13] = "INC",
- [14] = "JSR",
- [15] = "AND",
- [16] = "ABA",
- [17] = "PLP",
- [18] = "CPX",
- [19] = "PHY",
- [20] = "BPO",
- [21] = "ORA",
- [22] = "OAB",
- [23] = "STT",
- [24] = "PLY",
- [25] = "BNG",
- [26] = "XOR",
- [27] = "XAB",
- [28] = "PHA",
- [29] = "PHX",
- [30] = "BCS",
- [31] = "LSL",
- [32] = "LLB",
- [33] = "CLC",
- [34] = "PLX",
- [35] = "BCC",
- [36] = "LSR",
- [37] = "LRB",
- [38] = "PLA",
- [39] = "TAB",
- [40] = "BEQ",
- [41] = "ROL",
- [42] = "RLB",
- [43] = "SEC",
- [44] = "TBA",
- [45] = "BNE",
- [46] = "ROR",
- [47] = "RRB",
- [48] = "DEY",
- [49] = "TAY",
- [50] = "BVS",
- [51] = "MUL",
- [52] = "MAB",
- [53] = "CLI",
- [54] = "TYA",
- [55] = "BVC",
- [56] = "DIV",
- [57] = "DAB",
- [58] = "INY",
- [59] = "TAX",
- [60] = "RTS",
- [61] = "CMP",
- [62] = "CAB",
- [63] = "SEI",
- [64] = "LDX",
- [65] = "TXA",
- [66] = "RTI",
- [67] = "LDA",
- [68] = "DEX",
- [69] = "CLV",
- [70] = "TYX",
- [71] = "STA",
- [72] = "TSX",
- [73] = "LDB",
- [74] = "INX",
- [75] = "WAI",
- [76] = "TXY",
- [77] = "STB",
- [78] = "TXS",
- [79] = "LDY",
- [80] = "BRK",
- [81] = "NOP",
- [82] = "STY",
- [83] = "DEB",
- [84] = "ASR",
- [85] = "ARB",
- [86] = "STX",
- [87] = "INB"
+ [AAB] = "AAB",
+ [ABA] = "ABA",
+ [ADC] = "ADC",
+ [AND] = "AND",
+ [ARB] = "ARB",
+ [ASR] = "ASR",
+ [BCC] = "BCC",
+ [BCS] = "BCS",
+ [BEQ] = "BEQ",
+ [BNE] = "BNE",
+ [BNG] = "BNG",
+ [BPO] = "BPO",
+ [BRA] = "BRA",
+ [BRK] = "BRK",
+ [BVC] = "BVC",
+ [BVS] = "BVS",
+ [CAB] = "CAB",
+ [CLC] = "CLC",
+ [CLI] = "CLI",
+ [CLV] = "CLV",
+ [CMP] = "CMP",
+ [CPB] = "CPB",
+ [CPS] = "CPS",
+ [CPX] = "CPX",
+ [CPY] = "CPY",
+ [DAB] = "DAB",
+ [DEB] = "DEB",
+ [DEC] = "DEC",
+ [DEX] = "DEX",
+ [DEY] = "DEY",
+ [DIV] = "DIV",
+ [INB] = "INB",
+ [INC] = "INC",
+ [INX] = "INX",
+ [INY] = "INY",
+ [JMP] = "JMP",
+ [JSR] = "JSR",
+ [LDA] = "LDA",
+ [LDB] = "LDB",
+ [LDX] = "LDX",
+ [LDY] = "LDY",
+ [LLB] = "LLB",
+ [LRB] = "LRB",
+ [LSL] = "LSL",
+ [LSR] = "LSR",
+ [MAB] = "MAB",
+ [MUL] = "MUL",
+ [NOP] = "NOP",
+ [OAB] = "OAB",
+ [ORA] = "ORA",
+ [PHA] = "PHA",
+ [PHB] = "PHB",
+ [PHP] = "PHP",
+ [PHX] = "PHX",
+ [PHY] = "PHY",
+ [PLA] = "PLA",
+ [PLB] = "PLB",
+ [PLP] = "PLP",
+ [PLX] = "PLX",
+ [PLY] = "PLY",
+ [RLB] = "RLB",
+ [ROL] = "ROL",
+ [ROR] = "ROR",
+ [RRB] = "RRB",
+ [RTI] = "RTI",
+ [RTS] = "RTS",
+ [SAB] = "SAB",
+ [SBC] = "SBC",
+ [SEC] = "SEC",
+ [SEI] = "SEI",
+ [STA] = "STA",
+ [STB] = "STB",
+ [STX] = "STX",
+ [STY] = "STY",
+ [TAB] = "TAB",
+ [TAX] = "TAX",
+ [TAY] = "TAY",
+ [TBA] = "TBA",
+ [TSX] = "TSX",
+ [TXA] = "TXA",
+ [TXS] = "TXS",
+ [TXY] = "TXY",
+ [TYA] = "TYA",
+ [TYX] = "TYX",
+ [WAI] = "WAI",
+ [XAB] = "XAB",
+ [XOR] = "XOR"
};
static const char *instdesc[OPNUM] = {
- [ 0] = "Clears the Processor Status register.",
- [ 1] = "ADd accumulator, with operand, Carry if needed.",
- [ 2] = "Add Accumulator, with B, carry if needed.",
- [ 3] = "PusH the number of bytes specified, from the Processor status register to the stack.",
- [ 4] = "ComPare the B register, with operand.",
- [ 5] = "PusH the number of bytes specified, from the B register to the stack.",
- [ 6] = "DECrement accumulator, or memory.",
- [ 7] = "JuMP to the address specified.",
- [ 8] = "SuBtract accumulator, with operand, Carry if needed",
- [ 9] = "Subtract Accumulator, with B, carry if needed.",
- [10] = "ENd a Thread.",
- [11] = "ComPare the Y register, with operand.",
- [12] = "PuLl the number of bytes specified, from the stack, to the B register.",
- [13] = "INCrement accumulator, or memory.",
- [14] = "Jump to a SubRoutine.",
- [15] = "Bitwise AND accumulator, with operand.",
- [16] = "Bitwise AND Accumulator, with B.",
- [17] = "PuLl the number of bytes specified, from the stack, to the Processor status register.",
- [18] = "ComPare the X register, with operand.",
- [19] = "PusH the number of bytes specified, from the Y register to the stack.",
- [20] = "Branch if POsitive.",
- [21] = "Bitwise OR Accumulator, with operand.",
- [22] = "Bitwise OR Accumulator, with B.",
- [23] = "STart a Thread.",
- [24] = "PuLl the number of bytes specified, from the stack, to the Y register.",
- [25] = "Branch if NeGative.",
- [26] = "Bitwise XOR Accumulator, with operand.",
- [27] = "Bitwise XOR Accumulator, with B.",
- [28] = "PusH the number of bytes specified, from the Accumulator to the stack.",
- [29] = "PusH the number of bytes specified, from the X register to the stack.",
- [30] = "Branch if the Carry flag is Set.",
- [31] = "Logical Shift Left accumulator, with operand.",
- [32] = "Logical Shift Left accumulator, with B.",
- [33] = "CLear the Carry flag.",
- [34] = "PuLl the number of bytes specified, from the stack, to the X register.",
- [35] = "Branch if the Carry flag has been Cleared.",
- [36] = "Logical Shift Right accumulator, with operand.",
- [37] = "Logical Shift Right accumulator, with B.",
- [38] = "PuLl the number of bytes specified, from the stack, to the Accumulator.",
- [39] = "Transfer the value from the Accumulator, to the B register.",
- [40] = "Branch if EQual (the zero flag has been set).",
- [41] = "ROtate Left accumulator, with operand.",
- [42] = "Rotate Left accumulator, with B.",
- [43] = "SEt the Carry flag.",
- [44] = "Transfer the value from the Y register, to the Accumulator.",
- [45] = "Branch if Not Equal (the zero flag has been cleared)",
- [46] = "ROtate Right accumulator, with operand.",
- [47] = "Rotate Right accumulator, with B.",
- [48] = "DEcrement the Y register.",
- [49] = "Transfer the value from the Accumulator, to the Y register.",
- [50] = "Branch if the oVerflow flag is Set.",
- [51] = "MULtiply accumulator, with operand.",
- [52] = "Multiply Accumulator, with B.",
- [53] = "CLear the Interrupt flag.",
- [54] = "Transfer the value from the Y register, to the Accumulator.",
- [55] = "Branch if the oVerflow flag has been Cleared.",
- [56] = "DIVide accumulator, with operand, and put the remainder into the B register.",
- [57] = "Divide Accumulator, with B, and put the remainder into the X register.",
- [58] = "INcrement the Y register.",
- [59] = "Transfer the value from the Accumulator, to the X register.",
- [60] = "ReTurn from a Subroutine.",
- [61] = "CoMPare acumulator, with operand.",
- [62] = "Compare Accumulator, with B.",
- [63] = "SEt the Interrupt flag.",
- [64] = "LoaD the value from the operand, to the X register.",
- [65] = "Transfer the value from the X register, to the Accumulator.",
- [66] = "ReTurn from an Interrupt.",
- [67] = "LoaD the value from the operand, to the Accumulator.",
- [68] = "DEcrement the X register.",
- [69] = "CLear the oVerflow flag.",
- [70] = "Transfer the value from the Y register, to the X register.",
- [71] = "STore the value from the Accumulator, in memory.",
- [72] = "Transfer the value from the Stack pointer, to the X register.",
- [73] = "LoaD the value from the operand, to the B register.",
- [74] = "INcrement the X register.",
- [75] = "WAIt for an interrupt",
- [76] = "Transfer the value from the X register, to the Y register.",
- [77] = "STore the value from the B register, in memory.",
- [78] = "Transfer the value from the X register, to the Stack pointer.",
- [79] = "LoaD the value from the operand, to the Y register.",
- [80] = "BReaKpoint",
- [81] = "NO oPeration",
- [82] = "STore the value from the Y register, in memory.",
- [83] = "DEcrement the B register.",
- [84] = "Arithmetic Shift Right accumulator, with operand.",
- [85] = "Arithmetic shift Right accumulator, with B.",
- [86] = "STore the value from the X register, in memory.",
- [87] = "INcrement the B register."
+ [AAB] = "Add Accumulator, with B, carry if needed.",
+ [ABA] = "Bitwise AND Accumulator, with B.",
+ [ADC] = "ADd accumulator, with operand, Carry if needed.",
+ [AND] = "Bitwise AND accumulator, with operand.",
+ [ARB] = "Arithmetic shift Right accumulator, with B.",
+ [ASR] = "Arithmetic Shift Right accumulator, with operand.",
+ [BCC] = "Branch if the Carry flag has been Cleared.",
+ [BCS] = "Branch if the Carry flag is Set.",
+ [BEQ] = "Branch if EQual (the zero flag has been set).",
+ [BNE] = "Branch if Not Equal (the zero flag has been cleared)",
+ [BNG] = "Branch if NeGative.",
+ [BPO] = "Branch if POsitive.",
+ [BRA] = "BRanch Always.",
+ [BRK] = "BReaKpoint",
+ [BVC] = "Branch if the oVerflow flag has been Cleared.",
+ [BVS] = "Branch if the oVerflow flag is Set.",
+ [CAB] = "Compare Accumulator, with B.",
+ [CLC] = "CLear the Carry flag.",
+ [CLI] = "CLear the Interrupt flag.",
+ [CLV] = "CLear the oVerflow flag.",
+ [CMP] = "CoMPare acumulator, with operand.",
+ [CPB] = "ComPare the B register, with operand.",
+ [CPS] = "Clears the Processor Status register.",
+ [CPX] = "ComPare the X register, with operand.",
+ [CPY] = "ComPare the Y register, with operand.",
+ [DAB] = "Divide Accumulator, with B, and put the remainder into the X register.",
+ [DEB] = "DEcrement the B register.",
+ [DEC] = "DECrement accumulator, or memory.",
+ [DEX] = "DEcrement the X register.",
+ [DEY] = "DEcrement the Y register.",
+ [DIV] = "DIVide accumulator, with operand, and put the remainder into the B register.",
+ [INB] = "INcrement the B register.",
+ [INC] = "INCrement accumulator, or memory.",
+ [INX] = "INcrement the X register.",
+ [INY] = "INcrement the Y register.",
+ [JMP] = "JuMP to the address specified.",
+ [JSR] = "Jump to a SubRoutine.",
+ [LDA] = "LoaD the value from the operand, to the Accumulator.",
+ [LDB] = "LoaD the value from the operand, to the B register.",
+ [LDX] = "LoaD the value from the operand, to the X register.",
+ [LDY] = "LoaD the value from the operand, to the Y register.",
+ [LLB] = "Logical Shift Left accumulator, with B.",
+ [LRB] = "Logical Shift Right accumulator, with B.",
+ [LSL] = "Logical Shift Left accumulator, with operand.",
+ [LSR] = "Logical Shift Right accumulator, with operand.",
+ [MAB] = "Multiply Accumulator, with B.",
+ [MUL] = "MULtiply accumulator, with operand.",
+ [NOP] = "NO oPeration",
+ [OAB] = "Bitwise OR Accumulator, with B.",
+ [ORA] = "Bitwise OR Accumulator, with operand.",
+ [PHA] = "PusH the number of bytes specified, from the Accumulator to the stack.",
+ [PHB] = "PusH the number of bytes specified, from the B register to the stack.",
+ [PHP] = "PusH the number of bytes specified, from the Processor status register to the stack.",
+ [PHX] = "PusH the number of bytes specified, from the X register to the stack.",
+ [PHY] = "PusH the number of bytes specified, from the Y register to the stack.",
+ [PLA] = "PuLl the number of bytes specified, from the stack, to the Accumulator.",
+ [PLB] = "PuLl the number of bytes specified, from the stack, to the B register.",
+ [PLP] = "PuLl the number of bytes specified, from the stack, to the Processor status register.",
+ [PLX] = "PuLl the number of bytes specified, from the stack, to the X register.",
+ [PLY] = "PuLl the number of bytes specified, from the stack, to the Y register.",
+ [RLB] = "Rotate Left accumulator, with B.",
+ [ROL] = "ROtate Left accumulator, with operand.",
+ [ROR] = "ROtate Right accumulator, with operand.",
+ [RRB] = "Rotate Right accumulator, with B.",
+ [RTI] = "ReTurn from an Interrupt.",
+ [RTS] = "ReTurn from a Subroutine.",
+ [SAB] = "Subtract Accumulator, with B, carry if needed.",
+ [SBC] = "SuBtract accumulator, with operand, Carry if needed",
+ [SEC] = "SEt the Carry flag.",
+ [SEI] = "SEt the Interrupt flag.",
+ [STA] = "STore the value from the Accumulator, in memory.",
+ [STB] = "STore the value from the B register, in memory.",
+ [STX] = "STore the value from the X register, in memory.",
+ [STY] = "STore the value from the Y register, in memory.",
+ [TAB] = "Transfer the value from the Accumulator, to the B register.",
+ [TAX] = "Transfer the value from the Accumulator, to the X register.",
+ [TAY] = "Transfer the value from the Accumulator, to the Y register.",
+ [TBA] = "Transfer the value from the Y register, to the Accumulator.",
+ [TSX] = "Transfer the value from the Stack pointer, to the X register.",
+ [TXA] = "Transfer the value from the X register, to the Accumulator.",
+ [TXS] = "Transfer the value from the X register, to the Stack pointer.",
+ [TXY] = "Transfer the value from the X register, to the Y register.",
+ [TYA] = "Transfer the value from the Y register, to the Accumulator.",
+ [TYX] = "Transfer the value from the Y register, to the X register.",
+ [WAI] = "WAIt for an interrupt",
+ [XAB] = "Bitwise XOR Accumulator, with B.",
+ [XOR] = "Bitwise XOR Accumulator, with operand."
};
static const uint8_t bitsize[4] = {
diff --git a/assemble.c b/assemble.c
index 1ed4960..b8b377e 100644
--- a/assemble.c
+++ b/assemble.c
@@ -22,10 +22,19 @@ uint8_t get_rs(token *t, uint8_t inst, uint8_t dbg) {
}
}
+uint8_t get_of(token *t, uint8_t dbg) {
+ if (t->id == TOK_OF) {
+ return t->type;
+ } else {
+ return 0xFF;
+ }
+}
+
uint64_t get_val(token *t, uint64_t addr, uint8_t size, uint8_t dbg) {
uint64_t value = 0;
uint64_t tmp_val = 0;
uint8_t type = EXPR_NONE;
+ uint8_t isstart = 1;
do {
if (t->id == TOK_EXPR) {
type = t->type;
@@ -40,9 +49,10 @@ uint64_t get_val(token *t, uint64_t addr, uint8_t size, uint8_t dbg) {
case TOK_LABEL: tmp_val = (t->sym) ? t->sym->val : addr; t = t-> next; break;
}
switch (type) {
- case EXPR_PLUS : value += tmp_val; break;
- case EXPR_MINUS: value -= tmp_val; break;
+ case EXPR_PLUS : (isstart) ? (value = tmp_val) : (value += tmp_val); break;
+ case EXPR_MINUS: (isstart) ? (value = -tmp_val) : (value -= tmp_val); break;
case EXPR_LOW :
+ value = tmp_val;
switch (size) {
default:
case 2 : value &= 0xFFFFFFFF; break;
@@ -51,6 +61,7 @@ uint64_t get_val(token *t, uint64_t addr, uint8_t size, uint8_t dbg) {
}
break;
case EXPR_HIGH :
+ value = tmp_val;
switch (size) {
default:
case 2 : value >>= 0x20; break;
@@ -60,6 +71,7 @@ uint64_t get_val(token *t, uint64_t addr, uint8_t size, uint8_t dbg) {
break;
case EXPR_NONE : value = tmp_val; break;
}
+ isstart = 0;
} while (t && t->id == TOK_EXPR && isexpr(t->type, dbg));
return value;
}
@@ -166,6 +178,8 @@ uint64_t handle_opcode(token *t, bytecount *bc, uint8_t isasm, uint64_t address,
uint8_t tmp = 0;
uint8_t prefix = 0;
uint8_t rs = 0;
+ uint8_t of = 0;
+ uint8_t tmp_prefix = 0;
for (; t; t = t->next) {
if (t->id == TOK_OPCODE) {
@@ -180,11 +194,24 @@ uint64_t handle_opcode(token *t, bytecount *bc, uint8_t isasm, uint64_t address,
if (t->next) {
rs = get_rs(t->next, inst, dbg);
t = (rs != 0xFF) ? t->next : t;
+ if (t->next && t->next->id == TOK_OF) {
+ of = get_of(t->next, dbg);
+ t = (of != 0xFF) ? t->next : t;
+ }
}
- prefix = (rs != 0xFF) ? ((rs << 4) | 3) : 0;
- if (opcodes[inst][IMPL] != 0xFF && (!t->next || t->next->id == TOK_COMMENT)) {
+ if (rs != 0xFF || of != 0xFF) {
+ tmp_prefix = (rs != 0xFF) ? (rs << 0) : tmp_prefix;
+ tmp_prefix |= (of != 0xFF) ? (of << 2) : tmp_prefix;
+ }
+ prefix = (tmp_prefix) ? ((tmp_prefix << 4) | 3) : 0;
+ uint8_t isincdec = (inst == INC || inst == DEC);
+ uint8_t isimplied = (!t->next || (t->next->id == TOK_COMMENT));
+ if (opcodes[inst][IMPL] != 0xFF && isimplied) {
type = IMPL;
} else {
+ if (opcodes[inst][REL] != 0xFF) {
+ type = REL;
+ }
if (t->next) {
t = t->next;
}
@@ -192,7 +219,7 @@ uint64_t handle_opcode(token *t, bytecount *bc, uint8_t isasm, uint64_t address,
}
opcode = opcodes[inst][type];
/* Special case for TXS. */
- if (inst == TXS_MNE_ID) {
+ if (inst == TXS) {
if (type == IMM) {
rs = 1;
} else {
@@ -200,40 +227,87 @@ uint64_t handle_opcode(token *t, bytecount *bc, uint8_t isasm, uint64_t address,
opcode = opcodes[inst][IMM];
}
}
+ uint64_t saveaddr = address;
switch (type) {
case IMPL:
+ if (prefix) {
+ if (isasm) {
+ addr[address] = prefix;
+ }
+ address++;
+ bc->progsize++;
+ }
if (isasm) {
addr[address] = opcode;
}
address++;
bc->progsize++;
break;
+ case REL:
case IMM:
+ rs = (rs != 0xFF) ? rs : 0;
+ tmp = (1 << rs);
+ if (type == REL) {
+ uint64_t max_sign = 0;
+ uint8_t offset = 1;
+ uint64_t tmp_val;
+ tmp_val = val.u64;
+ offset += (prefix != 0);
+ tmp_val -= offset+tmp;
+ tmp_val -= address;
+ switch (rs) {
+ default: max_sign = (int8_t )(1 << 7); break;
+ case 1 : max_sign = (int16_t)(1 << 15); break;
+ case 2 : max_sign = (int32_t)(1 << 31); break;
+ case 3 : max_sign = (int64_t)((uint64_t)1 << 63); break;
+ }
+ if ((int64_t)tmp_val > ~(int64_t)max_sign || (int64_t)tmp_val < (int64_t)max_sign) {
+ offset += (!rs);
+ rs += (rs <= 3);
+ tmp = (1 << rs);
+ tmp_val = val.u64;
+ tmp_val -= offset+tmp;
+ tmp_val -= address;
+ prefix = ((rs << 4) | 3);
+ }
+ val.u64 = tmp_val;
+ }
if (prefix) {
if (isasm) {
addr[address] = prefix;
}
address++;
+ bc->progsize++;
}
if (isasm) {
addr[address] = opcode;
}
address++;
bc->progsize++;
- rs = (rs != 0xFF) ? rs : 0;
- tmp = (1 << rs);
if (isasm) {
setreg(addr, +, address, val.u8, +, 0, tmp-1);
}
break;
default:
- opsize = (val.u64 > 0x00000000000000FF) ? 2 : opsize;
- opsize = (val.u64 > 0x000000000000FFFF) ? 3 : opsize;
- opsize = (val.u64 > 0x0000000000FFFFFF) ? 4 : opsize;
- opsize = (val.u64 > 0x00000000FFFFFFFF) ? 5 : opsize;
- opsize = (val.u64 > 0x000000FFFFFFFFFF) ? 6 : opsize;
- opsize = (val.u64 > 0x0000FFFFFFFFFFFF) ? 7 : opsize;
- opsize = (val.u64 > 0x00FFFFFFFFFFFFFF) ? 8 : opsize;
+ if (of != 0xFF) {
+ uint64_t shift = 1;
+ uint8_t i = 8;
+ uint8_t j = 1;
+ for (; i <= 64; i += 8, j++) {
+ if ((int64_t)val.u64 >= ~(int64_t)(shift << (i-1)) || (int64_t)val.u64 <= (int64_t)(shift << (i-1))) {
+ opsize = j;
+ break;
+ }
+ }
+ } else {
+ opsize = (val.u64 > 0x00000000000000FF) ? 2 : opsize;
+ opsize = (val.u64 > 0x000000000000FFFF) ? 3 : opsize;
+ opsize = (val.u64 > 0x0000000000FFFFFF) ? 4 : opsize;
+ opsize = (val.u64 > 0x00000000FFFFFFFF) ? 5 : opsize;
+ opsize = (val.u64 > 0x000000FFFFFFFFFF) ? 6 : opsize;
+ opsize = (val.u64 > 0x0000FFFFFFFFFFFF) ? 7 : opsize;
+ opsize = (val.u64 > 0x00FFFFFFFFFFFFFF) ? 8 : opsize;
+ }
if (type == 0xFF) {
switch (opsize-1) {
case 0: case 2: case 5: case 3: type = ZM ; break;
@@ -321,9 +395,32 @@ token *make_token(uint8_t id, uint8_t type, uint64_t value, char *str, symbol *s
void assemble(line *ln, bytecount *bc, uint8_t dbg) {
uint64_t address = 0;
- for (; ln; ln = ln->next) {
- address = parse_tokens(ln->tok, bc, 1, address, dbg);
+ line *l = ln;
+ for (int i = 0; i < 2; i++) {
+ l = ln;
+ for (; l; l = l->next) {
+ l->addr = address;
+ token *t = l->tok;
+ address = parse_tokens(t, bc, 0, address, dbg);
+ }
+ l = ln;
+ for (; l; l = l->next) {
+ address = l->addr;
+ token *t = l->tok;
+ for (; t; t = t->next) {
+ if (t->id == TOK_LABEL && t->sym->val != address) {
+ t->sym->val = l->addr;
+ }
+ }
+ }
}
+ l = ln;
+ bc->progsize = 0;
+ bc->datasize = 0;
+ for (; l; l = l->next) {
+ address = parse_tokens(l->tok, bc, 1, address, dbg);
+ }
+
}
static inline void free_tokens(token *t) {
diff --git a/csv-parse.c b/csv-parse.c
new file mode 100644
index 0000000..6feefcb
--- /dev/null
+++ b/csv-parse.c
@@ -0,0 +1,113 @@
+#include "csv-parse.h"
+
+token *tokens = 0;
+token *last_tok = 0;
+
+line *lines = 0;
+line *last_line = 0;
+
+
+inline int iseol(char c) {
+ return (c == '\n' || c == '\0');
+}
+
+token *make_token(char *value) {
+ token *new_tok = malloc(sizeof(token));
+ (last_tok) ? (last_tok->next = new_tok) : (tokens = new_tok);
+ new_tok->value = value;
+ new_tok->next = NULL;
+ last_tok = new_tok;
+ return new_tok;
+}
+
+line *get_line(char *str) {
+ token *t = NULL;
+ int skip = 0; /* Blank column count. */
+ int isblank = 0; /* Used to check if this line is blank. */
+ int i = 0;
+ while (!iseol(str[i])) {
+ char *value = NULL;
+ switch (str[i]) {
+ case '\"': for (++str; str[i] != '\"' && !iseol(str[i]); i++); break;
+ default : for ( ; str[i] != ',' && !iseol(str[i]); i++); break;
+ }
+ /* Is there anything in this column? */
+ if (i) {
+ /* Copy the column contents, and null terminate it. */
+ value = malloc(i+1);
+ memcpy(value, str, i);
+ value[i] = '\0';
+ /* Create the new column. */
+ t = make_token(value);
+ t->skip = skip;
+ skip = 0;
+ t = t->next;
+ } else {
+ value = NULL;
+ skip += (t == NULL);
+ }
+ str += i+1; /* Shift the start of the line to the start of the next column. */
+ i = 0;
+ }
+ isblank = (tokens == NULL && last_tok == NULL);
+ /* Is this line blank? */
+ if (!isblank) {
+ line *l = malloc(sizeof(line));
+ /* If there was a previous line, set the next line to the new line.
+ * Otherwise, set the starting line to the new line. */
+ (last_line) ? (last_line->next = l) : (lines = l);
+ /* Save the starting, and ending columns for this line. */
+ l->tok = tokens;
+ l->last_tok = last_tok;
+
+ tokens = NULL;
+ last_tok = NULL;
+
+ l->next = NULL;
+ last_line = l;
+ return l;
+ } else {
+ return NULL;
+ }
+}
+
+void parse_csv(FILE *fp) {
+ char buf[0x1000];
+ int blank_lines = 0;
+ line *l;
+
+ while (fgets(buf, sizeof(buf), fp) != NULL && !feof(fp)) {
+ l = get_line(buf);
+ blank_lines += (l == NULL);
+ if (l != NULL) {
+ l->skip = blank_lines;
+ blank_lines = 0;
+ }
+ }
+}
+
+void free_tokens(token *t, token *lt, int row) {
+ token *tok;
+ int i = 0;
+ int skip = 0;
+ while (t != NULL) {
+ tok = t;
+ free(tok->value);
+ t = t->next;
+ i++;
+ free(tok);
+ }
+}
+
+void free_lines() {
+ line *l = lines;
+ line *ln;
+ int i = 0;
+ while (l != NULL) {
+ free_tokens(l->tok, l->last_tok, i);
+ i++;
+ ln = l;
+ l = l->next;
+ free(ln);
+ }
+}
diff --git a/csv-parse.h b/csv-parse.h
new file mode 100644
index 0000000..8fc5d29
--- /dev/null
+++ b/csv-parse.h
@@ -0,0 +1,32 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+struct tok {
+ int skip; /* Number of blank tokens to skip. */
+ char *value;
+ struct tok *next;
+};
+
+typedef struct tok token;
+
+struct line {
+ int skip; /* Number of blank lines to skip. */
+ token *tok;
+ token *last_tok;
+ struct line *next;
+};
+
+typedef struct line line;
+
+extern token *tokens;
+extern token *last_tok;
+extern line *lines;
+extern line *last_line;
+
+extern int iseol(char c);
+extern token *make_token(char *value);
+extern line *get_line(char *str);
+extern void parse_csv(FILE *fp);
+extern void free_tokens(token *t, token *lt, int row);
+extern void free_lines();
diff --git a/disasm.c b/disasm.c
index 5ccede4..67a8945 100644
--- a/disasm.c
+++ b/disasm.c
@@ -6,21 +6,32 @@ void disasm(struct sux *cpu, uint64_t *operands, uint8_t lines, uint8_t opcode,
uint64_t address = operands[1];
uint64_t tmpaddr = operands[2];
char postfix[3];
+ char *of;
char op[4];
+ char sign;
+ uint8_t tmp = 0;
op[0] = opname[opcode][0];
op[1] = opname[opcode][1];
op[2] = opname[opcode][2];
op[3] = '\0';
- switch(1 << (prefix >> 4)) {
+ switch ((1 << ((prefix >> 4) & 3))) {
case 1: postfix[0] = 0; postfix[1] = 0; postfix[2] = 0; break;
case 2: postfix[0] = '.'; postfix[1] = 'W'; postfix[2] = 0; break;
case 4: postfix[0] = '.'; postfix[1] = 'D'; postfix[2] = 0; break;
case 8: postfix[0] = '.'; postfix[1] = 'Q'; postfix[2] = 0; break;
}
+ if (prefix >> 6) {
+ tmp = 0;
+ }
+ switch (prefix >> 6) {
+ default: of = ""; break;
+ case 1 : of = "SP, "; break;
+ case 2 : of = "PC, "; break;
+ }
switch (optype[opcode]) {
- case IMPL: wprintw(scr, "%s\r" , opname[opcode]); break;
+ case IMPL: wprintw(scr, "%s%s" , opname[opcode], postfix); break;
case IMM:
- switch(1 << (prefix >> 4)) {
+ switch ((1 << ((prefix >> 4) & 3))) {
case 1: wprintw(scr, "%s #$%02X\r" , op, value); break;
case 2: wprintw(scr, "%s%s #$%04X\r" , op, postfix, value); break;
case 4: wprintw(scr, "%s%s #$%08X\r" , op, postfix, value); break;
@@ -35,29 +46,49 @@ void disasm(struct sux *cpu, uint64_t *operands, uint8_t lines, uint8_t opcode,
case ZMY: tmpaddr = address - cpu->y; break;
}
switch ((prefix & 0x0C) >> 2) {
- case 3: wprintw(scr, "%s%s $%08X%s\r" , op, postfix, tmpaddr, (optype[opcode] == ZM) ? "" : ((optype[opcode] == ZMX) ? ", x" : ", y")); break;
- case 2: wprintw(scr, "%s%s $%014"PRIX64"%s\r" , op, postfix, tmpaddr, (optype[opcode] == ZM) ? "" : ((optype[opcode] == ZMX) ? ", x" : ", y")); break;
- case 1: wprintw(scr, "%s%s $%06X%s\r" , op, postfix, tmpaddr, (optype[opcode] == ZM) ? "" : ((optype[opcode] == ZMX) ? ", x" : ", y")); break;
- case 0: wprintw(scr, "%s%s $%02X%s\r" , op, postfix, tmpaddr, (optype[opcode] == ZM) ? "" : ((optype[opcode] == ZMX) ? ", x" : ", y")); break;
+ case 3: wprintw(scr, "%s%s %s$%08X%s\r" , op, postfix, of, tmpaddr, (optype[opcode] == ZM) ? "" : ((optype[opcode] == ZMX) ? ", x" : ", y")); break;
+ case 2: wprintw(scr, "%s%s %s$%014"PRIX64"%s\r" , op, postfix, of, tmpaddr, (optype[opcode] == ZM) ? "" : ((optype[opcode] == ZMX) ? ", x" : ", y")); break;
+ case 1: wprintw(scr, "%s%s %s$%06X%s\r" , op, postfix, of, tmpaddr, (optype[opcode] == ZM) ? "" : ((optype[opcode] == ZMX) ? ", x" : ", y")); break;
+ case 0: wprintw(scr, "%s%s %s$%02X%s\r" , op, postfix, of, tmpaddr, (optype[opcode] == ZM) ? "" : ((optype[opcode] == ZMX) ? ", x" : ", y")); break;
}
break;
case IND:
case INDX:
case INDY:
switch ((prefix & 0x0C) >> 2) {
- case 3: wprintw(scr, "%s%s ($%08X%s\r" , op, postfix, tmpaddr, (optype[opcode] == IND) ? ")" : ((optype[opcode] == INDX) ? ", x)" : "), y")); break;
- case 2: wprintw(scr, "%s%s ($%012"PRIX64"%s\r" , op, postfix, tmpaddr, (optype[opcode] == IND) ? ")" : ((optype[opcode] == INDX) ? ", x)" : "), y")); break;
- case 1: wprintw(scr, "%s%s ($%06X%s\r" , op, postfix, tmpaddr, (optype[opcode] == IND) ? ")" : ((optype[opcode] == INDX) ? ", x)" : "), y")); break;
- case 0: wprintw(scr, "%s%s ($%02X%s\r" , op, postfix, tmpaddr, (optype[opcode] == IND) ? ")" : ((optype[opcode] == INDX) ? ", x)" : "), y")); break;
+ case 3: wprintw(scr, "%s%s (%s$%08X%s\r", op, postfix, of, tmpaddr, (optype[opcode] == IND) ? ")" : ((optype[opcode] == INDX) ? ", x)" : "), y")); break;
+ case 2: wprintw(scr, "%s%s (%s$%012"PRIX64"%s\r", op, postfix, of, tmpaddr, (optype[opcode] == IND) ? ")" : ((optype[opcode] == INDX) ? ", x)" : "), y")); break;
+ case 1: wprintw(scr, "%s%s (%s$%06X%s\r", op, postfix, of, tmpaddr, (optype[opcode] == IND) ? ")" : ((optype[opcode] == INDX) ? ", x)" : "), y")); break;
+ case 0: wprintw(scr, "%s%s (%s$%02X%s\r", op, postfix, of, tmpaddr, (optype[opcode] == IND) ? ")" : ((optype[opcode] == INDX) ? ", x)" : "), y")); break;
}
break;
case ABS:
tmpaddr = address;
switch ((prefix & 0x0C) >> 2) {
- case 3: wprintw(scr, "%s%s $%016"PRIX64"\r" , op, postfix, tmpaddr); break;
- case 2: wprintw(scr, "%s%s $%014"PRIX64"\r" , op, postfix, tmpaddr); break;
- case 1: wprintw(scr, "%s%s $%010"PRIX64"\r" , op, postfix, tmpaddr); break;
- case 0: wprintw(scr, "%s%s $%04" PRIX64"\r" , op, postfix, tmpaddr); break;
+ case 3: wprintw(scr, "%s%s %s$%016"PRIX64"\r" , op, postfix, of, tmpaddr); break;
+ case 2: wprintw(scr, "%s%s %s$%014"PRIX64"\r" , op, postfix, of, tmpaddr); break;
+ case 1: wprintw(scr, "%s%s %s$%010"PRIX64"\r" , op, postfix, of, tmpaddr); break;
+ case 0: wprintw(scr, "%s%s %s$%04" PRIX64"\r" , op, postfix, of, tmpaddr); break;
+ }
+ break;
+ case REL:
+ switch((1 << ((prefix >> 4) & 3))) {
+ case 1:
+ sign = ((int8_t)value < 0) ? '-' : '+';
+ wprintw(scr, "%s %c$%02X" , op, sign, value & 0x7F);
+ break;
+ case 2:
+ sign = ((int16_t)value < 0) ? '-' : '+';
+ wprintw(scr, "%s%s %c$%04X" , op, postfix, sign, value & ~(1 << 15));
+ break;
+ case 4:
+ sign = ((int32_t)value < 0) ? '-' : '+';
+ wprintw(scr, "%s%s %c$%08X" , op, postfix, sign, value & ~(1 << 31));
+ break;
+ case 8:
+ sign = ((int64_t)value < 0) ? '-' : '+';
+ wprintw(scr, "%s%s %c$%016"PRIX64 , op, postfix, sign, value & ~((uint64_t)1 << 63));
+ break;
}
break;
}
@@ -74,7 +105,7 @@ void disasm(struct sux *cpu, uint64_t *operands, uint8_t lines, uint8_t opcode,
uint8_t iscursor = 0;
union reg ptr;
uint32_t adr;
- /*wmove(scr, 30, 0);
+ wmove(scr, 30, 0);
wclrtoeol(scr);
adr = 0x25;
ptr.u8[0] = addr[adr+0]; ptr.u8[1] = addr[adr+1];
@@ -99,10 +130,16 @@ void disasm(struct sux *cpu, uint64_t *operands, uint8_t lines, uint8_t opcode,
ptr.u8[2] = addr[adr+2]; ptr.u8[3] = addr[adr+3];
ptr.u8[4] = addr[adr+4]; ptr.u8[5] = addr[adr+5];
ptr.u8[6] = addr[adr+6]; ptr.u8[7] = addr[adr+7];
- wprintw(scr, ", idx0: $%04"PRIX64, ptr.u64);*/
+ wprintw(scr, ", idx0: $%04"PRIX64, ptr.u64);
+ adr = 0x334BA;
+ ptr.u8[0] = addr[adr+0]; ptr.u8[1] = addr[adr+1];
+ ptr.u8[2] = addr[adr+2]; ptr.u8[3] = addr[adr+3];
+ ptr.u8[4] = addr[adr+4]; ptr.u8[5] = addr[adr+5];
+ ptr.u8[6] = addr[adr+6]; ptr.u8[7] = addr[adr+7];
+ wprintw(scr, ", valbuf: $%016"PRIX64, ptr.u64);
if (address == CTRL_ADDR || addr[STEP_ADDR]) {
- mvwprintw(scr, 29, 0, "address: $%04"PRIX64", scr_row: %02u, scr_col: %02u, scr_str: %02u, scr_end: %02u\r", address, addr[0], addr[1], addr[0x22], addr[0x23]);
adr = 0x30000;
+ mvwprintw(scr, 29, 0, "address: $%04"PRIX64", scr_row: %02u, scr_col: %02u, scr_str: %02u, scr_end: %02u\r", address, addr[0], addr[1], addr[0x22], addr[0x23]);
wmove(scr, 32, 0);
wprintw(scr, "bitabl: ");
for (uint8_t i = 0; i < 16; i++) {
diff --git a/disasm.h b/disasm.h
index ce35ad3..6164d94 100644
--- a/disasm.h
+++ b/disasm.h
@@ -1,186 +1,171 @@
static const char *opname[0x100] = {
- [0x00] = "CPS",
- [0x01] = "ADC #",
- [0x02] = "AAB",
- [0x04] = "ADC a",
- [0x05] = "LDA ind",
- [0x06] = "ADC zm",
- [0x08] = "PHP #",
- [0x09] = "CPB #",
- [0x0A] = "PHB #",
- [0x0C] = "DEC a",
- [0x0D] = "DEC zm",
- [0x0E] = "JMP zm",
- [0x10] = "JMP a",
- [0x11] = "SBC #",
- [0x12] = "SAB",
- [0x14] = "SBC a",
- [0x15] = "STA ind",
- [0x16] = "SBC zm",
- [0x18] = "ENT #",
- [0x19] = "CPY #",
- [0x1A] = "PLB #",
- [0x1C] = "INC a",
- [0x1D] = "INC zm",
- [0x1E] = "JSR zm",
- [0x20] = "JSR a",
- [0x21] = "AND #",
- [0x22] = "ABA",
- [0x24] = "AND a",
- [0x25] = "CMP ind",
- [0x26] = "AND zm",
- [0x28] = "PLP #",
- [0x29] = "CPX #",
- [0x2A] = "PHY #",
- [0x2C] = "CPB a",
- [0x2D] = "CPB zm",
- [0x2E] = "BPO zm",
- [0x30] = "BPO a",
- [0x31] = "ORA #",
- [0x32] = "OAB",
- [0x34] = "ORA a",
- [0x35] = "LDB ind",
- [0x36] = "ORA zm",
- [0x38] = "STT #",
- [0x39] = "LDA zmy",
- [0x3A] = "PLY #",
- [0x3C] = "CPX a",
- [0x3D] = "CPY zm",
- [0x3E] = "BNG zm",
- [0x40] = "BNG a",
- [0x41] = "XOR #",
- [0x42] = "XAB",
- [0x44] = "XOR a",
- [0x45] = "STB ind",
- [0x46] = "XOR zm",
- [0x48] = "PHA #",
- [0x49] = "STA zmy",
- [0x4A] = "PHX #",
- [0x4C] = "CPY a",
- [0x4D] = "CPX zm",
- [0x4E] = "BCS zm",
- [0x50] = "BCS a",
- [0x51] = "LSL #",
- [0x52] = "LLB",
- [0x54] = "LSL a",
- [0x55] = "CPB ind",
- [0x56] = "LSL zm",
- [0x58] = "CLC",
- [0x59] = "LDB zmy",
- [0x5A] = "PLX #",
- [0x5C] = "LDA iny",
- [0x5D] = "LDA inx",
- [0x5E] = "BCC zm",
- [0x60] = "BCC a",
- [0x61] = "LSR #",
- [0x62] = "LRB",
- [0x64] = "LSR a",
- [0x65] = "LDY ind",
- [0x66] = "LSR zm",
- [0x68] = "PLA #",
- [0x69] = "STB zmy",
- [0x6A] = "TAB",
- [0x6C] = "STA iny",
- [0x6D] = "STA inx",
- [0x6E] = "BEQ zm",
- [0x70] = "BEQ a",
- [0x71] = "ROL #",
- [0x72] = "RLB",
- [0x74] = "ROL a",
- [0x75] = "STY ind",
- [0x76] = "ROL zm",
- [0x78] = "SEC",
- [0x79] = "LDA zmx",
- [0x7A] = "TBA",
- [0x7C] = "CMP iny",
- [0x7D] = "CMP inx",
- [0x7E] = "BNE zm",
- [0x80] = "BNE a",
- [0x81] = "ROR #",
- [0x82] = "RRB",
- [0x84] = "ROR a",
- [0x85] = "CPY ind",
- [0x86] = "ROR zm",
- [0x88] = "DEY",
- [0x89] = "STA zmx",
- [0x8A] = "TAY",
- [0x8C] = "LDB iny",
- [0x8D] = "LDB inx",
- [0x8E] = "BVS zm",
- [0x90] = "BVS a",
- [0x91] = "MUL #",
- [0x92] = "MAB",
- [0x94] = "MUL a",
- [0x95] = "LDX ind",
- [0x96] = "MUL zm",
- [0x98] = "CLI",
- [0x99] = "LDB zmx",
- [0x9A] = "TYA",
- [0x9C] = "STB iny",
- [0x9D] = "STB inx",
- [0x9E] = "BVC zm",
- [0xA0] = "BVC a",
- [0xA1] = "DIV #",
- [0xA2] = "DAB",
- [0xA4] = "DIV a",
- [0xA5] = "STX ind",
- [0xA6] = "DIV zm",
- [0xA8] = "INY",
- [0xA9] = "STB zmx",
- [0xAA] = "TAX",
- [0xAC] = "CPB iny",
- [0xAD] = "CPB inx",
- [0xAE] = "RTS",
- [0xB1] = "CMP #",
- [0xB2] = "CAB",
- [0xB4] = "CMP a",
- [0xB5] = "CPX ind",
- [0xB6] = "CMP zm",
- [0xB8] = "SEI",
- [0xB9] = "LDX #",
- [0xBA] = "TXA",
- [0xBC] = "LDX a",
- [0xBD] = "LDX zm",
- [0xBE] = "JSR ind",
- [0xC0] = "RTI",
- [0xC1] = "LDA #",
- [0xC4] = "LDA a",
- [0xC5] = "DEX",
- [0xC6] = "LDA zm",
- [0xC8] = "CLV",
- [0xC9] = "LDX zmy",
- [0xCA] = "TYX",
- [0xCC] = "STA a",
- [0xCD] = "STA zm",
- [0xCE] = "JMP ind",
- [0xD0] = "TSX",
- [0xD1] = "LDB #",
- [0xD4] = "LDB a",
- [0xD5] = "INX",
- [0xD6] = "LDB zm",
- [0xD8] = "WAI",
- [0xD9] = "STX zmy",
- [0xDA] = "TXY",
- [0xDC] = "STB a",
- [0xDD] = "STB zm",
- [0xE0] = "TXS #",
- [0xE1] = "LDY #",
- [0xE4] = "LDY a",
- [0xE5] = "DEC A",
- [0xE6] = "LDY zm",
- [0xE8] = "BRK",
- [0xE9] = "LDY zmx",
- [0xEA] = "NOP",
- [0xEC] = "STY a",
- [0xED] = "STY zm",
- [0xEE] = "DEB",
- [0xF1] = "ASR #",
- [0xF2] = "ARB",
- [0xF4] = "ASR a",
- [0xF5] = "INC A",
- [0xF6] = "ASR zm",
- [0xF9] = "STY zmx",
- [0xFC] = "STX a",
- [0xFD] = "STX zm",
- [0xFE] = "INB"
+ [CPS_IMP ] = "CPS",
+ [ADC_IMM ] = "ADC #",
+ [AAB_IMP ] = "AAB",
+ [ADC_AB ] = "ADC a",
+ [LDA_IN ] = "LDA ind",
+ [ADC_Z ] = "ADC zm",
+ [CLC_IMP ] = "CLC",
+ [DEX_IMP ] = "DEX",
+ [DEC_IMP ] = "DEC",
+ [DEC_AB ] = "DEC a",
+ [DEC_Z ] = "DEC zm",
+ [JMP_AB ] = "JMP a",
+ [SBC_IMM ] = "SBC #",
+ [SAB_IMP ] = "SAB",
+ [SBC_AB ] = "SBC a",
+ [STA_IN ] = "STA ind",
+ [SBC_Z ] = "SBC zm",
+ [SEC_IMP ] = "SEC",
+ [INX_IMP ] = "INX",
+ [INC_IMP ] = "INC",
+ [INC_AB ] = "INC a",
+ [INC_Z ] = "INC zm",
+ [JSR_AB ] = "JSR a",
+ [AND_IMM ] = "AND #",
+ [ABA_IMP ] = "ABA",
+ [AND_AB ] = "AND a",
+ [CMP_IN ] = "CMP ind",
+ [AND_Z ] = "AND zm",
+ [CLI_IMP ] = "CLI",
+ [DEY_IMP ] = "DEY",
+ [CPB_IMM ] = "CPB #",
+ [CPB_AB ] = "CPB a",
+ [CPB_Z ] = "CPB zm",
+ [JMP_Z ] = "JMP zm",
+ [ORA_IMM ] = "ORA #",
+ [OAB_IMP ] = "OAB",
+ [ORA_AB ] = "ORA a",
+ [LDB_IN ] = "LDB ind",
+ [ORA_Z ] = "ORA zm",
+ [SEI_IMP ] = "SEI",
+ [INY_IMP ] = "INY",
+ [CPX_IMM ] = "CPX #",
+ [CPX_AB ] = "CPX a",
+ [CPY_Z ] = "CPY zm",
+ [JSR_Z ] = "JSR zm",
+ [XOR_IMM ] = "XOR #",
+ [XAB_IMP ] = "XAB",
+ [XOR_AB ] = "XOR a",
+ [STB_IN ] = "STB ind",
+ [XOR_Z ] = "XOR zm",
+ [CLV_IMP ] = "CLV",
+ [CPY_IMM ] = "CPY #",
+ [CPY_AB ] = "CPY a",
+ [CPX_Z ] = "CPX zm",
+ [BPO_REL ] = "BPO rel",
+ [LSL_IMM ] = "LSL #",
+ [LLB_IMP ] = "LLB",
+ [LSL_AB ] = "LSL a",
+ [CPB_IN ] = "CPB ind",
+ [LSL_Z ] = "LSL zm",
+ [WAI_IMP ] = "WAI",
+ [PHP_IMP ] = "PHP",
+ [TAB_IMP ] = "TAB",
+ [LDA_IY ] = "LDA indy",
+ [LDA_IX ] = "LDA indx",
+ [BNG_REL ] = "BNG rel",
+ [LSR_IMM ] = "LSR #",
+ [LRB_IMP ] = "LRB",
+ [LSR_AB ] = "LSR a",
+ [LDY_IN ] = "LDY ind",
+ [LSR_Z ] = "LSR zm",
+ [BRK_IMP ] = "BRK",
+ [PLP_IMP ] = "PLP",
+ [TBA_IMP ] = "TBA",
+ [STA_IY ] = "STA indy",
+ [STA_IX ] = "STA indx",
+ [BCS_REL ] = "BCS rel",
+ [ROL_IMM ] = "ROL #",
+ [RLB_IMP ] = "RLB",
+ [ROL_AB ] = "ROL a",
+ [STY_IN ] = "STY ind",
+ [ROL_Z ] = "ROL zm",
+ [LDA_ZY ] = "LDA zmy",
+ [PHA_IMP ] = "PHA",
+ [TAY_IMP ] = "TAY",
+ [CMP_IY ] = "CMP indy",
+ [CMP_IX ] = "CMP indx",
+ [BCC_REL ] = "BCC rel",
+ [ROR_IMM ] = "ROR #",
+ [RRB_IMP ] = "RRB",
+ [ROR_AB ] = "ROR a",
+ [LDX_IN ] = "LDX ind",
+ [ROR_Z ] = "ROR zm",
+ [STA_ZY ] = "STA zmy",
+ [PLA_IMP ] = "PLA",
+ [TYA_IMP ] = "TYA",
+ [LDB_IY ] = "LDB indy",
+ [LDB_IX ] = "LDB indx",
+ [BEQ_REL ] = "BEQ rel",
+ [MUL_IMM ] = "MUL #",
+ [MAB_IMP ] = "MAB",
+ [MUL_AB ] = "MUL a",
+ [STX_IN ] = "STX ind",
+ [MUL_Z ] = "MUL zm",
+ [LDB_ZY ] = "LDB zmy",
+ [PHB_IMP ] = "PHB",
+ [TAX_IMP ] = "TAX",
+ [STB_IY ] = "STB indy",
+ [STB_IX ] = "STB indx",
+ [BNE_REL ] = "BNE rel",
+ [DIV_IMM ] = "DIV #",
+ [DAB_IMP ] = "DAB",
+ [DIV_AB ] = "DIV a",
+ [JSR_IN ] = "JSR ind",
+ [DIV_Z ] = "DIV zm",
+ [STB_ZY ] = "STB zmy",
+ [PLB_IMP ] = "PLB",
+ [TXA_IMP ] = "TXA",
+ [CPB_IY ] = "CPB indy",
+ [CPB_IX ] = "CPB indx",
+ [BVS_REL ] = "BVS rel",
+ [CMP_IMM ] = "CMP #",
+ [CAB_IMP ] = "CAB",
+ [CMP_AB ] = "CMP a",
+ [JMP_IN ] = "JMP ind",
+ [CMP_Z ] = "CMP zm",
+ [LDA_ZX ] = "LDA zmx",
+ [LDX_IMM ] = "LDX #",
+ [TYX_IMP ] = "TYX",
+ [LDX_AB ] = "LDX a",
+ [LDX_Z ] = "LDX zm",
+ [BVC_REL ] = "BVC rel",
+ [LDA_IMM ] = "LDA #",
+ [DEB_IMP ] = "DEB",
+ [LDA_AB ] = "LDA a",
+ [LDA_Z ] = "LDA zm",
+ [STA_ZX ] = "STA zmx",
+ [PHY_IMP ] = "PHY",
+ [TXY_IMP ] = "TXY",
+ [STA_AB ] = "STA a",
+ [STA_Z ] = "STA zm",
+ [BRA_REL ] = "BRA rel",
+ [LDB_IMM ] = "LDB #",
+ [INB_IMP ] = "INB",
+ [LDB_AB ] = "LDB a",
+ [LDB_Z ] = "LDB zm",
+ [LDB_ZX ] = "LDB zmx",
+ [PLY_IMP ] = "PLY",
+ [TSX_IMP ] = "TSX",
+ [STB_AB ] = "STB a",
+ [STB_Z ] = "STB zm",
+ [RTS_IMP ] = "RTS",
+ [LDY_IMM ] = "LDY #",
+ [LDY_AB ] = "LDY a",
+ [LDY_Z ] = "LDY zm",
+ [STB_ZX ] = "STB zmx",
+ [PHX_IMP ] = "PHX",
+ [NOP_IMP ] = "NOP",
+ [STY_AB ] = "STY a",
+ [STY_Z ] = "STY zm",
+ [RTI_IMP ] = "RTI",
+ [ASR_IMM ] = "ASR #",
+ [ARB_IMP ] = "ARB",
+ [ASR_AB ] = "ASR a",
+ [ASR_Z ] = "ASR zm",
+ [PLX_IMP ] = "PLX",
+ [TXS_IMM ] = "TXS #",
+ [STX_AB ] = "STX a",
+ [STX_Z ] = "STX zm"
};
diff --git a/enums.h b/enums.h
index 451f5c2..955c27c 100644
--- a/enums.h
+++ b/enums.h
@@ -1,189 +1,287 @@
+enum am {
+ /* Part of Base ISA. */
+ IMM, /* Immediate Data. */
+ ZM, /* Zero Matrix. */
+ ZMX, /* Zero Matrix, indexed with X. */
+ ZMY, /* Zero Matrix, indexed with Y. */
+ IND, /* Indirect. */
+ INDX, /* Indexed Indirect. */
+ INDY, /* Indirect Indexed. */
+ ABS, /* Absolute. */
+ REL, /* Relative to Program Counter. */
+ IMPL, /* Implied. */
+ /* Part of Base Extension. */
+ ABSX, /* Absolute, Indexed with X. */
+ ABSY, /* Absolute, Indexed with Y. */
+ SPI, /* Stack Pointer, Immediate Offset. */
+ SPX, /* Stack Pointer, Offset with X. */
+ SPY, /* Stack Pointer, Offset with Y. */
+ INA, /* Absolute Indirect. */
+ INAX, /* Absolute Indexed Indirect. */
+ INAY, /* Absolute Indirect Indexed. */
+ EIND, /* Effective Address Register, Indirect. */
+};
+
+enum mne {
+ AAB = 0,
+ ABA = 1,
+ ADC = 2,
+ AND = 3,
+ ARB = 4,
+ ASR = 5,
+ BCC = 6,
+ BCS = 7,
+ BEQ = 8,
+ BNE = 9,
+ BNG = 10,
+ BPO = 11,
+ BRA = 12,
+ BRK = 13,
+ BVC = 14,
+ BVS = 15,
+ CAB = 16,
+ CLC = 17,
+ CLI = 18,
+ CLV = 19,
+ CMP = 20,
+ CPB = 21,
+ CPS = 22,
+ CPX = 23,
+ CPY = 24,
+ DAB = 25,
+ DEB = 26,
+ DEC = 27,
+ DEX = 28,
+ DEY = 29,
+ DIV = 30,
+ INB = 31,
+ INC = 32,
+ INX = 33,
+ INY = 34,
+ JMP = 35,
+ JSR = 36,
+ LDA = 37,
+ LDB = 38,
+ LDX = 39,
+ LDY = 40,
+ LLB = 41,
+ LRB = 42,
+ LSL = 43,
+ LSR = 44,
+ MAB = 45,
+ MUL = 46,
+ NOP = 47,
+ OAB = 48,
+ ORA = 49,
+ PHA = 50,
+ PHB = 51,
+ PHP = 52,
+ PHX = 53,
+ PHY = 54,
+ PLA = 55,
+ PLB = 56,
+ PLP = 57,
+ PLX = 58,
+ PLY = 59,
+ RLB = 60,
+ ROL = 61,
+ ROR = 62,
+ RRB = 63,
+ RTI = 64,
+ RTS = 65,
+ SAB = 66,
+ SBC = 67,
+ SEC = 68,
+ SEI = 69,
+ STA = 70,
+ STB = 71,
+ STX = 72,
+ STY = 73,
+ TAB = 74,
+ TAX = 75,
+ TAY = 76,
+ TBA = 77,
+ TSX = 78,
+ TXA = 79,
+ TXS = 80,
+ TXY = 81,
+ TYA = 82,
+ TYX = 83,
+ WAI = 84,
+ XAB = 85,
+ XOR = 86
+};
enum base_isa {
- CPS = 0x00, /* Clear Processor Status. */
- ADC = 0x01, /* ADd with Carry. */
- AAB = 0x02, /* Add Accumulator with carry by B register. */
- ADC_AB = 0x04, /* ADC Absolute. */
- LDA_IN = 0x05, /* LDA Indirect. */
- ADC_Z = 0x06, /* ADC Zero Matrix. */
- PHP = 0x08, /* PusH Processor status to stack. */
- CPB = 0x09, /* ComPare B register. */
- PHB = 0x0A, /* PusH B register to stack. */
- DEC_AB = 0x0C, /* DEC Absolute. */
- DEC_Z = 0x0D, /* DEC Zero Matrix. */
- JMP_Z = 0x0E, /* JuMP to memory location. */
- JMP = 0x10, /* JMP Absolute. */
- SBC = 0x11, /* SuBtract with Carry. */
- SAB = 0x12, /* Subtract Accumulator with carry by B register. */
- SBC_AB = 0x14, /* SBC Absolute. */
- STA_IN = 0x15, /* STA Indirect. */
- SBC_Z = 0x16, /* SBC Zero Matrix. */
- ENT = 0x18, /* ENd Threads. */
- CPY = 0x19, /* ComPare Y register. */
- PLB = 0x1A, /* PuLl B register to stack. */
- INC_AB = 0x1C, /* INC Absolute. */
- INC_Z = 0x1D, /* INC Zero Matrix. */
- JSR_Z = 0x1E, /* Jump to SubRoutine. */
- JSR = 0x20, /* JSR Absolute. */
- AND = 0x21, /* bitwise AND with accumulator. */
- ABA = 0x22, /* bitwise And with Accumulator, and B register. */
- AND_AB = 0x24, /* AND Absolute. */
- CMP_IN = 0x25, /* CMP Indirect. */
- AND_Z = 0x26, /* AND Zero Matrix. */
- PLP = 0x28, /* PuLl Processor status from stack. */
- CPX = 0x29, /* ComPare X register. */
- PHY = 0x2A, /* PusH Y register to stack. */
- CPB_AB = 0x2C, /* CPB Absolute. */
- CPB_Z = 0x2D, /* CPB Zero Matrix. */
- BPO_Z = 0x2E, /* Branch if POsitive. */
- BPO = 0x30, /* BPO Absolute. */
- ORA = 0x31, /* bitwise OR with Accumulator. */
- OAB = 0x32, /* bitwise Or with Accumulator, and B register. */
- ORA_AB = 0x34, /* ORA Absolute. */
- LDB_IN = 0x35, /* LDB Indirect. */
- ORA_Z = 0x36, /* ORA Zero Matrix. */
- STT = 0x38, /* STart Threads. */
- LDA_ZY = 0x39, /* LDA Zero Matrix, indexed with Y. */
- PLY = 0x3A, /* PuLl Y register from stack. */
- CPX_AB = 0x3C, /* CPX Absolute. */
- CPY_Z = 0x3D, /* CPY Zero Matrix. */
- BNG_Z = 0x3E, /* Branch if NeGative. */
- BNG = 0x40, /* BNG Absolute. */
- XOR = 0x41, /* bitwise XOR with accumulator. */
- XAB = 0x42, /* bitwise Xor with Accumulator, and B register. */
- XOR_AB = 0x44, /* XOR Absolute. */
- STB_IN = 0x45, /* STB Indirect. */
- XOR_Z = 0x46, /* XOR Zero Matrix. */
- PHA = 0x48, /* PusH Accumulator to stack. */
- STA_ZY = 0x49, /* STA Zero Matrix, indexed with Y. */
- PHX = 0x4A, /* PusH X register to stack. */
- CPY_AB = 0x4C, /* CPY Absolute. */
- CPX_Z = 0x4D, /* CPX Zero Matrix. */
- BCS_Z = 0x4E, /* Branch if Carry Set. */
- BCS = 0x50, /* BCS Absolute. */
- LSL = 0x51, /* Logical Shift Left. */
- LLB = 0x52, /* Logical shift Left accumulator by B. */
- LSL_AB = 0x54, /* LSL Absolute. */
- CPB_IN = 0x55, /* CPB Indirect. */
- LSL_Z = 0x56, /* LSL Zero Matrix. */
- CLC = 0x58, /* CLear Carry flag. */
- LDB_ZY = 0x59, /* LDB Zero Matrix, indexed with Y. */
- PLX = 0x5A, /* PuLl X register from stack. */
- LDA_IY = 0x5C, /* LDA Indirect Indexed. */
- LDA_IX = 0x5D, /* LDA Indexed Indirect. */
- BCC_Z = 0x5E, /* Branch if Carry Clear. */
- BCC = 0x60, /* BCC Absolute. */
- LSR = 0x61, /* Logical Shift Right. */
- LRB = 0x62, /* Logical shift Right accumulator by B. */
- LSR_AB = 0x64, /* LSR Absolute. */
- LDY_IN = 0x65, /* LDY Indirect. */
- LSR_Z = 0x66, /* LSR Zero Matrix. */
- PLA = 0x68, /* PuLl Accumulator from stack. */
- STB_ZY = 0x69, /* STB Zero Matrix, indexed with Y. */
- TAB = 0x6A, /* Transfer Accumulator to B. */
- STA_IY = 0x6C, /* STA Indirect Indexed. */
- STA_IX = 0x6D, /* STA Indexed Indirect. */
- BEQ_Z = 0x6E, /* Branch if EQual. */
- BEQ = 0x70, /* BEQ Absolute. */
- ROL = 0x71, /* ROtate Left. */
- RLB = 0x72, /* Rotate Left accumulator by B. */
- ROL_AB = 0x74, /* ROL Absolute. */
- STY_IN = 0x75, /* STY Indirect. */
- ROL_Z = 0x76, /* ROL Zero Matrix. */
- SEC = 0x78, /* SEt Carry flag. */
- LDA_ZX = 0x79, /* LDA Zero Matrix, indexed with X. */
- TBA = 0x7A, /* Transfer B to Accumulator. */
- CMP_IY = 0x7C, /* CMP Indirect Indexed. */
- CMP_IX = 0x7D, /* CMP Indexed Indirect. */
- BNE_Z = 0x7E, /* Branch if Not Equal. */
- BNE = 0x80, /* BNE Absolute. */
- ROR = 0x81, /* ROtate Right. */
- RRB = 0x82, /* Rotate Right accumulator by B. */
- ROR_AB = 0x84, /* ROR Absolute. */
- CPY_IN = 0x85, /* CPY Indirect. */
- ROR_Z = 0x86, /* ROR Zero Matrix. */
- DEY = 0x88, /* DEcrement Y register. */
- STA_ZX = 0x89, /* STA Zero Matrix, indexed with X. */
- TAY = 0x8A, /* Transfer Accumulator to Y. */
- LDB_IY = 0x8C, /* LDB Indirect Indexed. */
- LDB_IX = 0x8D, /* LDB Indexed Indirect. */
- BVS_Z = 0x8E, /* Branch if oVerflow Set. */
- BVS = 0x90, /* BVS Absolute. */
- MUL = 0x91, /* MULtiply accumulator. */
- MAB = 0x92, /* Multiply Accumulator by B. */
- MUL_AB = 0x94, /* MUL Absolute. */
- LDX_IN = 0x95, /* LDX Indirect. */
- MUL_Z = 0x96, /* MUL Zero Matrix. */
- CLI = 0x98, /* CLear Interupt flag. */
- LDB_ZX = 0x99, /* LDB Zero Matrix, indexed with X. */
- TYA = 0x9A, /* Transfer Y to Accumulator. */
- STB_IY = 0x9C, /* STB Indirect Indexed. */
- STB_IX = 0x9D, /* STB Indexed Indirect. */
- BVC_Z = 0x9E, /* Branch if oVerflow Clear. */
- BVC = 0xA0, /* BVC Absolute. */
- DIV = 0xA1, /* DIVide with accumulator. */
- DAB = 0xA2, /* Divide Accumulator by B. */
- DIV_AB = 0xA4, /* DIV Absolute. */
- STX_IN = 0xA5, /* STX Indirect. */
- DIV_Z = 0xA6, /* DIV Zero Matrix. */
- INY = 0xA8, /* INcrement Y register. */
- STB_ZX = 0xA9, /* STB Zero Matrix, indexed with X. */
- TAX = 0xAA, /* Transfer Accumulator to X. */
- CPB_IY = 0xAC, /* CPB Indirect Indexed. */
- CPB_IX = 0xAD, /* CPB Indexed Indirect. */
- RTS = 0xAE, /* ReTurn from Subroutine. */
- CMP = 0xB1, /* CoMPare accumulator. */
- CAB = 0xB2, /* Compare Accumulator, and B. */
- CMP_AB = 0xB4, /* CMP Absolute. */
- CPX_IN = 0xB5, /* CPX Indirect. */
- CMP_Z = 0xB6, /* CMP Zero Matrix. */
- SEI = 0xB8, /* SEt Interupt flag. */
- LDX = 0xB9, /* LoaD X register. */
- TXA = 0xBA, /* Transfer X to Accumulator. */
- LDX_AB = 0xBC, /* LDX Absolute. */
- LDX_Z = 0xBD, /* LDX Zero Matrix. */
- JSR_IN = 0xBE, /* JSR Indirect. */
- RTI = 0xC0, /* ReTurn from Interrupt. */
- LDA = 0xC1, /* LoaD Accumulator. */
- LDA_AB = 0xC4, /* LDA Absolute. */
- DEX = 0xC5, /* DEcrement X register. */
- LDA_Z = 0xC6, /* LDA Zero Matrix. */
- CLV = 0xC8, /* CLear oVerflow flag. */
- LDX_ZY = 0xC9, /* LDX Zero Matrix, indexed with Y. */
- TYX = 0xCA, /* Transfer Y to X. */
- STA = 0xCC, /* STA Absolute. */
- STA_Z = 0xCD, /* STore Accumulator. */
- JMP_IN = 0xCE, /* JMP Indirect. */
- TSX = 0xD0, /* Transfer Stack pointer to X. */
- LDB = 0xD1, /* LoaD B register. */
- LDB_AB = 0xD4, /* LDB Absolute. */
- INX = 0xD5, /* INcrement X register. */
- LDB_Z = 0xD6, /* LDB Zero Matrix. */
- WAI = 0xD8, /* WAit for Interrupt. */
- STX_ZY = 0xD9, /* STX Zero Matrix, indexed with Y. */
- TXY = 0xDA, /* Transfer X to Y. */
- STB = 0xDC, /* STB Absolute. */
- STB_Z = 0xDD, /* STore B register. */
- TXS = 0xE0, /* Transfer X to Stack pointer. */
- LDY = 0xE1, /* LoaD Y register. */
- LDY_AB = 0xE4, /* LDY Absolute. */
- DEC = 0xE5, /* DECrement accumulator. */
- LDY_Z = 0xE6, /* LDY Zero Matrix. */
- BRK = 0xE8, /* BReaK. */
- LDY_ZX = 0xE9, /* LDY Zero Matrix, indexed with X. */
- NOP = 0xEA, /* No OPeration. */
- STY = 0xEC, /* STY Absolute. */
- STY_Z = 0xED, /* STore Y register. */
- DEB = 0xEE, /* Decrement B register. */
- ASR = 0xF1, /* Arithmetic Shift Right. */
- ARB = 0xF2, /* Arithmetic shift Right accumulator by B. */
- ASR_AB = 0xF4, /* ASR Absolute. */
- INC = 0xF5, /* INCrement accumulator. */
- ASR_Z = 0xF6, /* ASR Zero Matrix. */
- STY_ZX = 0xF9, /* STY Zero Matrix, indexed with X. */
- STX = 0xFC, /* STX Absolute. */
- STX_Z = 0xFD, /* STore X register. */
- INB = 0xFE /* Increment B register. */
+ CPS_IMP = 0x00, /* Clear Processor Status. */
+ ADC_IMM = 0x01, /* ADd with Carry. */
+ AAB_IMP = 0x02, /* Add Accumulator with carry by B register. */
+ ADC_AB = 0x04, /* ADC Absolute. */
+ LDA_IN = 0x05, /* LDA Indirect */
+ ADC_Z = 0x06, /* ADC Zero Matrix. */
+ CLC_IMP = 0x08, /* CLear Carry flag. */
+ DEX_IMP = 0x09, /* DEcrement X register. */
+ DEC_IMP = 0x0A, /* DECrement accumulator. */
+ DEC_AB = 0x0C, /* DEC Absolute. */
+ DEC_Z = 0x0D, /* DEC Zero Matrix. */
+ JMP_AB = 0x10, /* JMP Absolute. */
+ SBC_IMM = 0x11, /* SuBtract with Carry. */
+ SAB_IMP = 0x12, /* Subtract Accumulator with carry by B register. */
+ SBC_AB = 0x14, /* SBC Absolute. */
+ STA_IN = 0x15, /* STA Indirect */
+ SBC_Z = 0x16, /* SBC Zero Matrix. */
+ SEC_IMP = 0x18, /* SEt Carry flag. */
+ INX_IMP = 0x19, /* INcrement X register. */
+ INC_IMP = 0x1A, /* INCrement accumulator. */
+ INC_AB = 0x1C, /* INC Absolute. */
+ INC_Z = 0x1D, /* INC Zero Matrix. */
+ JSR_AB = 0x20, /* JSR Absolute. */
+ AND_IMM = 0x21, /* bitwise AND with accumulator. */
+ ABA_IMP = 0x22, /* bitwise And with Accumulator, and B register. */
+ AND_AB = 0x24, /* AND Absolute. */
+ CMP_IN = 0x25, /* CMP Indirect */
+ AND_Z = 0x26, /* AND Zero Matrix. */
+ CLI_IMP = 0x28, /* CLear Interupt flag. */
+ DEY_IMP = 0x29, /* DEcrement Y register. */
+ CPB_IMM = 0x2A, /* ComPare B register. */
+ CPB_AB = 0x2C, /* CPB Absolute. */
+ CPB_Z = 0x2D, /* CPB Zero Matrix. */
+ JMP_Z = 0x30, /* JuMP to memory location. */
+ ORA_IMM = 0x31, /* bitwise OR with Accumulator. */
+ OAB_IMP = 0x32, /* bitwise Or with Accumulator, and B register. */
+ ORA_AB = 0x34, /* ORA Absolute. */
+ LDB_IN = 0x35, /* LDB Indirect */
+ ORA_Z = 0x36, /* ORA Zero Matrix. */
+ SEI_IMP = 0x38, /* SEt Interupt flag. */
+ INY_IMP = 0x39, /* INcrement Y register. */
+ CPX_IMM = 0x3A, /* ComPare X register. */
+ CPX_AB = 0x3C, /* CPX Absolute. */
+ CPY_Z = 0x3D, /* CPY Zero Matrix. */
+ JSR_Z = 0x40, /* Jump to SubRoutine. */
+ XOR_IMM = 0x41, /* bitwise XOR with accumulator. */
+ XAB_IMP = 0x42, /* bitwise Xor with Accumulator, and B register. */
+ XOR_AB = 0x44, /* XOR Absolute. */
+ STB_IN = 0x45, /* STB Indirect */
+ XOR_Z = 0x46, /* XOR Zero Matrix. */
+ CLV_IMP = 0x48, /* CLear oVerflow flag. */
+ CPY_IMM = 0x4A, /* ComPare Y register. */
+ CPY_AB = 0x4C, /* CPY Absolute. */
+ CPX_Z = 0x4D, /* CPX Zero Matrix. */
+ BPO_REL = 0x50, /* Branch if POsitive. */
+ LSL_IMM = 0x51, /* Logical Shift Left. */
+ LLB_IMP = 0x52, /* Logical shift Left accumulator by B. */
+ LSL_AB = 0x54, /* LSL Absolute. */
+ CPB_IN = 0x55, /* CPB Indirect */
+ LSL_Z = 0x56, /* LSL Zero Matrix. */
+ WAI_IMP = 0x58, /* WAit for Interrupt. */
+ PHP_IMP = 0x59, /* PusH Processor status to stack. */
+ TAB_IMP = 0x5A, /* Transfer Accumulator to B. */
+ LDA_IY = 0x5C, /* LDA Indirect Indexed. */
+ LDA_IX = 0x5D, /* LDA Indexed Indirect. */
+ BNG_REL = 0x60, /* Branch if NeGative. */
+ LSR_IMM = 0x61, /* Logical Shift Right. */
+ LRB_IMP = 0x62, /* Logical shift Right accumulator by B. */
+ LSR_AB = 0x64, /* LSR Absolute. */
+ LDY_IN = 0x65, /* LDY Indirect */
+ LSR_Z = 0x66, /* LSR Zero Matrix. */
+ BRK_IMP = 0x68, /* BReaK. */
+ PLP_IMP = 0x69, /* PuLl Processor status from stack. */
+ TBA_IMP = 0x6A, /* Transfer B to Accumulator. */
+ STA_IY = 0x6C, /* STA Indirect Indexed. */
+ STA_IX = 0x6D, /* STA Indexed Indirect. */
+ BCS_REL = 0x70, /* Branch if Carry Set. */
+ ROL_IMM = 0x71, /* ROtate Left. */
+ RLB_IMP = 0x72, /* Rotate Left accumulator by B. */
+ ROL_AB = 0x74, /* ROL Absolute. */
+ STY_IN = 0x75, /* STY Indirect */
+ ROL_Z = 0x76, /* ROL Zero Matrix. */
+ LDA_ZY = 0x78, /* LDA Zero Marrix, Indexed with Y. */
+ PHA_IMP = 0x79, /* PusH Accumulator to stack. */
+ TAY_IMP = 0x7A, /* Transfer Accumulator to Y. */
+ CMP_IY = 0x7C, /* CMP Indirect Indexed. */
+ CMP_IX = 0x7D, /* CMP Indexed Indirect. */
+ BCC_REL = 0x80, /* Branch if Carry Clear. */
+ ROR_IMM = 0x81, /* ROtate Right. */
+ RRB_IMP = 0x82, /* Rotate Right accumulator by B. */
+ ROR_AB = 0x84, /* ROR Absolute. */
+ LDX_IN = 0x85, /* LDX Indirect */
+ ROR_Z = 0x86, /* ROR Zero Matrix. */
+ STA_ZY = 0x88, /* STA Zero Marrix, Indexed with Y. */
+ PLA_IMP = 0x89, /* PuLl Accumulator from stack. */
+ TYA_IMP = 0x8A, /* Transfer Y to Accumulator. */
+ LDB_IY = 0x8C, /* LDB Indirect Indexed. */
+ LDB_IX = 0x8D, /* LDB Indexed Indirect. */
+ BEQ_REL = 0x90, /* Branch if EQual. */
+ MUL_IMM = 0x91, /* MULtiply accumulator. */
+ MAB_IMP = 0x92, /* Multiply Accumulator by B. */
+ MUL_AB = 0x94, /* MUL Absolute. */
+ STX_IN = 0x95, /* STX Indirect */
+ MUL_Z = 0x96, /* MUL Zero Matrix. */
+ LDB_ZY = 0x98, /* LDB Zero Marrix, Indexed with Y. */
+ PHB_IMP = 0x99, /* PusH B register to stack. */
+ TAX_IMP = 0x9A, /* Transfer Accumulator to X. */
+ STB_IY = 0x9C, /* STB Indirect Indexed. */
+ STB_IX = 0x9D, /* STB Indexed Indirect. */
+ BNE_REL = 0xA0, /* Branch if Not Equal. */
+ DIV_IMM = 0xA1, /* DIVide with accumulator. */
+ DAB_IMP = 0xA2, /* Divide Accumulator by B. */
+ DIV_AB = 0xA4, /* DIV Absolute. */
+ JSR_IN = 0xA5, /* JSR Indirect */
+ DIV_Z = 0xA6, /* DIV Zero Matrix. */
+ STB_ZY = 0xA8, /* STB Zero Marrix, Indexed with Y. */
+ PLB_IMP = 0xA9, /* PuLl B register to stack. */
+ TXA_IMP = 0xAA, /* Transfer X to Accumulator. */
+ CPB_IY = 0xAC, /* CPB Indirect Indexed. */
+ CPB_IX = 0xAD, /* CPB Indexed Indirect. */
+ BVS_REL = 0xB0, /* Branch if oVerflow Set. */
+ CMP_IMM = 0xB1, /* CoMPare accumulator. */
+ CAB_IMP = 0xB2, /* Compare Accumulator, and B. */
+ CMP_AB = 0xB4, /* CMP Absolute. */
+ JMP_IN = 0xB5, /* JMP Indirect */
+ CMP_Z = 0xB6, /* CMP Zero Matrix. */
+ LDA_ZX = 0xB8, /* LDA Zero Marrix, Indexed with X. */
+ LDX_IMM = 0xB9, /* LoaD X register. */
+ TYX_IMP = 0xBA, /* Transfer Y to X. */
+ LDX_AB = 0xBC, /* LDX Absolute. */
+ LDX_Z = 0xBD, /* LDX Zero Matrix. */
+ BVC_REL = 0xC0, /* Branch if oVerflow Clear. */
+ LDA_IMM = 0xC1, /* LoaD Accumulator. */
+ DEB_IMP = 0xC2, /* Decrement B register. */
+ LDA_AB = 0xC4, /* LDA Absolute. */
+ LDA_Z = 0xC6, /* LDA Zero Matrix. */
+ STA_ZX = 0xC8, /* STA Zero Marrix, Indexed with X. */
+ PHY_IMP = 0xC9, /* PusH Y register to stack. */
+ TXY_IMP = 0xCA, /* Transfer X to Y. */
+ STA_AB = 0xCC, /* STA Absolute. */
+ STA_Z = 0xCD, /* STore Accumulator. */
+ BRA_REL = 0xD0, /* BRanch Always. */
+ LDB_IMM = 0xD1, /* LoaD B register. */
+ INB_IMP = 0xD2, /* Increment B register. */
+ LDB_AB = 0xD4, /* LDB Absolute. */
+ LDB_Z = 0xD6, /* LDB Zero Matrix. */
+ LDB_ZX = 0xD8, /* LDB Zero Marrix, Indexed with X. */
+ PLY_IMP = 0xD9, /* PuLl Y register from stack. */
+ TSX_IMP = 0xDA, /* Transfer Stack pointer to X. */
+ STB_AB = 0xDC, /* STB Absolute. */
+ STB_Z = 0xDD, /* STore B register. */
+ RTS_IMP = 0xE0, /* ReTurn from Subroutine. */
+ LDY_IMM = 0xE1, /* LoaD Y register. */
+ LDY_AB = 0xE4, /* LDY Absolute. */
+ LDY_Z = 0xE6, /* LDY Zero Matrix. */
+ STB_ZX = 0xE8, /* STB Zero Marrix, Indexed with X. */
+ PHX_IMP = 0xE9, /* PusH X register to stack. */
+ NOP_IMP = 0xEA, /* No OPeration. */
+ STY_AB = 0xEC, /* STY Absolute. */
+ STY_Z = 0xED, /* STore Y register. */
+ RTI_IMP = 0xF0, /* ReTurn from Interrupt. */
+ ASR_IMM = 0xF1, /* Arithmetic Shift Right. */
+ ARB_IMP = 0xF2, /* Arithmetic shift Right accumulator by B. */
+ ASR_AB = 0xF4, /* ASR Absolute. */
+ ASR_Z = 0xF6, /* ASR Zero Matrix. */
+ PLX_IMP = 0xF9, /* PuLl X register from stack. */
+ TXS_IMM = 0xFA, /* Transfer X to Stack pointer. */
+ STX_AB = 0xFC, /* STX Absolute. */
+ STX_Z = 0xFD /* STore X register. */
};
enum base_ext {
@@ -306,27 +404,3 @@ enum base_ext {
NOT_E = 0xF4, /* NOT E Indirect. */
STX_E = 0xFC, /* STX E Indirect. */
};
-
-enum am {
- /* Part of Base ISA. */
- IMM, /* Immediate Data. */
- ZM, /* Zero Matrix. */
- ZMX, /* Zero Matrix, indexed with X. */
- ZMY, /* Zero Matrix, indexed with Y. */
- IND, /* Indirect. */
- INDX, /* Indexed Indirect. */
- INDY, /* Indirect Indexed. */
- ABS, /* Absolute. */
- IMPL, /* Implied. */
- /* Part of Base Extension. */
- ABSX, /* Absolute, Indexed with X. */
- ABSY, /* Absolute, Indexed with Y. */
- SPI, /* Stack Pointer, Immediate Offset. */
- SPX, /* Stack Pointer, Offset with X. */
- SPY, /* Stack Pointer, Offset with Y. */
- REL, /* Relative to Program Counter. */
- INA, /* Absolute Indirect. */
- INAX, /* Absolute Indexed Indirect. */
- INAY, /* Absolute Indirect Indexed. */
- EIND, /* Effective Address Register, Indirect. */
-};
diff --git a/lexer.c b/lexer.c
index 55eb576..14bf1c4 100644
--- a/lexer.c
+++ b/lexer.c
@@ -184,6 +184,7 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) {
uint8_t k = 0;
uint8_t ch = 0;
uint8_t rs = 0;
+ uint8_t of = 0;
uint8_t base = 0;
uint8_t islocal = 0;
@@ -234,6 +235,7 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) {
}
l->addr = address;
while (isdelm(str[i], dbg) != 1) {
+ uint8_t offset = 0;
base = 0;
space = 0;
tab = 0;
@@ -257,8 +259,12 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) {
for (; isdelm(str[i], dbg) == 16; i++);
}
uint8_t ptok = get_ptok(str[i], dbg);
- if (ptok == PTOK_X || ptok == PTOK_Y) {
- switch (get_ptok(str[i+1], dbg)) {
+ if (ptok == PTOK_X || ptok == PTOK_Y || ptok == PTOK_S || ptok == PTOK_P) {
+ offset++;
+ if ((ptok == PTOK_S && toupper(str[i+1]) == 'P') || (ptok == PTOK_P && toupper(str[i+1]) == 'C')) {
+ offset++;
+ }
+ switch (get_ptok(str[i+offset], dbg)) {
case PTOK_ALPHA :
case PTOK_NUMBER: ptok = PTOK_ALPHA; break;
}
@@ -425,7 +431,7 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) {
break;
case PTOK_COMMA:
i++;
- if (lex_type != TOK_IND) {
+ if (lex_type != TOK_IND && lex_type != TOK_OF) {
lex_type = TOK_CSV;
}
lexeme[j] = ',';
@@ -445,6 +451,22 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) {
case PTOK_Y: l->tok->type = (lex_type == TOK_IND) ? INDY : ZMY; break;
}
break;
+ case PTOK_S:
+ case PTOK_P:
+ lexeme[j] = str[i++];
+ if (str[i] != ',') {
+ lexeme[j+1] = str[i++];
+ } else {
+ lexeme[j+1] = '\0';
+ }
+ lexeme[j+2] = '\0';
+ switch (ptok) {
+ case PTOK_S: of = 1; break;
+ case PTOK_P: of = 2; break;
+ }
+ lex_type = TOK_OF;
+ t = make_token(lex_type, of, 0, "", NULL);
+ break;
case PTOK_AT:
memset(lexeme, 0, strlen(lexeme)+1);
lexeme[j] = '@';
diff --git a/lexer.h b/lexer.h
index e756325..952d525 100644
--- a/lexer.h
+++ b/lexer.h
@@ -46,6 +46,8 @@ static inline uint8_t get_ptok(char c, uint8_t dbg) {
case ',' : return PTOK_COMMA ;
case 'X': case 'x' : return PTOK_X ;
case 'Y': case 'y' : return PTOK_Y ;
+ case 'S': case 's' : return PTOK_S ;
+ case 'P': case 'p' : return PTOK_P ;
case '\"': return PTOK_DQUOTE ;
case '\'': return PTOK_SQUOTE ;
case '#' : return PTOK_HASH ;
diff --git a/opcode-gen.c b/opcode-gen.c
new file mode 100644
index 0000000..3091e05
--- /dev/null
+++ b/opcode-gen.c
@@ -0,0 +1,505 @@
+#include "csv-parse.h"
+#include <ctype.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <unistd.h>
+
+struct instruction {
+ char *mne; /* Mnemonic. */
+ char *desc; /* Description */
+ char *com; /* Comment. */
+ uint8_t op[10]; /* Opcodes. */
+};
+
+struct opcode {
+ char *mne; /* Mnemonic. */
+ uint8_t am; /* Addressing Mode. */
+ uint8_t op; /* opcode. */
+ struct opcode *next;
+};
+
+typedef struct instruction inst;
+typedef struct opcode opcode;
+
+struct list {
+ struct list *next;
+ inst *inst;
+};
+
+typedef struct list list;
+
+list *lists = 0;
+list *last_list = 0;
+
+opcode *opcodes = 0;
+opcode *last_opcode = 0;
+
+const char *ams[] = { /* Addressing modes. */
+ "IMM ",
+ "Z ",
+ "ZX ",
+ "ZY ",
+ "IN ",
+ "IX ",
+ "IY ",
+ "AB ",
+ "REL ",
+ "IMP "
+};
+
+enum am {
+ /* Part of Base ISA. */
+ IMM, /* Immediate Data. */
+ ZM, /* Zero Matrix. */
+ ZMX, /* Zero Matrix, indexed with X. */
+ ZMY, /* Zero Matrix, indexed with Y. */
+ IND, /* Indirect. */
+ INDX, /* Indexed Indirect. */
+ INDY, /* Indirect Indexed. */
+ ABS, /* Absolute. */
+ REL, /* Relative to Program Counter. */
+ IMPL, /* Implied. */
+ /* Part of Base Extension. */
+ ABSX, /* Absolute, Indexed with X. */
+ ABSY, /* Absolute, Indexed with Y. */
+ SPI, /* Stack Pointer, Immediate Offset. */
+ SPX, /* Stack Pointer, Offset with X. */
+ SPY, /* Stack Pointer, Offset with Y. */
+ INA, /* Absolute Indirect. */
+ INAX, /* Absolute Indexed Indirect. */
+ INAY, /* Absolute Indirect Indexed. */
+ EIND, /* Effective Address Register, Indirect. */
+};
+
+static const char *addrmodes[10] = {
+ [IMM ] = "IMM",
+ [ZM ] = "ZM",
+ [ZMX ] = "ZMX",
+ [ZMY ] = "ZMY",
+ [IND ] = "IND",
+ [INDX] = "INDX",
+ [INDY] = "INDY",
+ [ABS ] = "ABS",
+ [REL ] = "REL",
+ [IMPL] = "IMPL"
+};
+
+static const char *amcom[10] = {
+ [IMM ] = "Immediate.",
+ [ZM ] = "Zero Matrix.",
+ [ZMX ] = "Zero Marrix, Indexed with X.",
+ [ZMY ] = "Zero Marrix, Indexed with Y.",
+ [IND ] = "Indirect",
+ [INDX] = "Indexed Indirect.",
+ [INDY] = "Indirect Indexed.",
+ [ABS ] = "Absolute.",
+ [REL ] = "Relative.",
+ [IMPL] = "Implied."
+};
+
+static const char *am_tok[10] = {
+ [IMM ] = "#",
+ [ZM ] = "zm",
+ [ZMX ] = "zmx",
+ [ZMY ] = "zmy",
+ [IND ] = "ind",
+ [INDX] = "indx",
+ [INDY] = "indy",
+ [ABS ] = "a",
+ [REL ] = "rel",
+};
+
+int get_instcount(list *l) {
+ int i = 0;
+ for (; l != NULL; l = l->next, i++);
+ return i;
+}
+
+inst *make_inst(opcode *opc, char *mne, char *desc, char *com) {
+ inst *ins = malloc(sizeof(inst));
+ ins->mne = mne;
+ ins->desc = desc;
+ ins->com = com;
+
+ for (int i = 0; i < 10; i++) {
+ ins->op[i] = 0xFF;
+ }
+
+ while (opc != NULL) {
+ if (!strcasecmp(opc->mne, mne)) {
+ ins->op[opc->am] = opc->op;
+ }
+ opc = opc->next;
+ }
+ return ins;
+}
+
+list *make_list(char *mne, char *desc, char *com) {
+ list *l = malloc(sizeof(list));
+ (last_list) ? (last_list->next = l) : (lists = l);
+ l->inst = make_inst(opcodes, mne, desc, com);
+ l->next = NULL;
+ last_list = l;
+ return l;
+}
+
+void free_lists() {
+ list *l = lists;
+ list *nl;
+ while (l != NULL) {
+ nl = l;
+ l = l->next;
+ /*free(nl->inst->mne);*/
+ free(nl->inst);
+ free(nl);
+ }
+}
+
+void free_opcodes() {
+ opcode *opc = opcodes;
+ opcode *op;
+ while (opc != NULL) {
+ op = opc;
+ opc = opc->next;
+ /*if (op->mne == NULL) {
+ free(op->mne);
+ }*/
+ free(op);
+ }
+}
+
+void print_optable(list *l, int maxop) {
+ int i = 0;
+ puts("static const uint8_t opcodes[OPNUM][10] = {");
+ puts("\t/*\t IMM\t ZM ZMX ZMY IND INDX INDY ABS REL IMPL*/");
+ while (l) {
+ inst *ins = l->inst;
+ printf("\t[%s] = {", ins->mne);
+ for (int j = 0; j < 10; j++) {
+ printf("0x%02X%s", ins->op[j], (j < 9) ? ", " : "}");
+ }
+ putchar((l->next) ? ',' : ' ');
+ printf(" /* %s */\n", ins->mne);
+ i++;
+ l = l->next;
+ }
+ puts("};");
+}
+
+opcode *lex_value(char *str, int op) {
+ opcode *opc = malloc(sizeof(opcode));
+ (last_opcode) ? (last_opcode->next = opc) : (opcodes = opc);
+ int i = 0;
+ char *mnemonic;
+
+ for (;str[i] != ' ' && !iseol(str[i]); i++);
+ mnemonic = malloc(i+1);
+ memcpy(mnemonic, str, i);
+ mnemonic[i] = '\0';
+ opc->mne = mnemonic;
+ opc->op = op;
+
+ if (iseol(str[i])) {
+ opc->am = IMPL;
+ } else {
+ i++;
+ }
+
+ while (!iseol(str[i])) {
+ int ismulti = 0; /* Is this a multi character token? */
+ switch(str[i]) {
+ default : ismulti = 1;
+ case 'A': opc->am = IMPL; break;
+ case '#': opc->am = IMM ; break;
+ case 'a': opc->am = ABS ; break;
+ case 'r': opc->am = REL ; i += 2; break;
+ case 'z':
+ switch (str[i+2]) {
+ case 'x': opc->am = ZMX; break;
+ case 'y': opc->am = ZMY; break;
+ default : opc->am = ZM ; break;
+ }
+ i += 2;
+ break;
+ case 'i':
+ switch (str[i+2]) {
+ case 'x': opc->am = INDX; break;
+ case 'y': opc->am = INDY; break;
+ default : opc->am = IND ; break;
+ }
+ i += 2;
+ break;
+ }
+ /*if (ismulti) {
+ if (!strcmp(str, "zm")) {
+ switch (i+2) {
+ case 'x': ins->op[ZMX] = opcode; break;
+ case 'y': ins->op[ZMY] = opcode; break;
+ default : ins->op[ZM ] = opcode; break;
+ }
+ i += 2;
+ } else if (!strcmp(str, "in")) {
+ switch (i+2) {
+ case 'x': ins->op[INDX] = opcode; break;
+ case 'y': ins->op[INDY] = opcode; break;
+ default : ins->op[IND ] = opcode; break;
+ }
+ i += 2;
+ } else if (!strcmp(str, "rel")) {
+ ins->op[REL] = opcode;
+ }
+ }*/
+ i++;
+ }
+ opc->next = NULL;
+ last_opcode = opc;
+ return opc;
+}
+
+int get_lownibble(line *l, int col) {
+ token *t = l->tok;
+ int i = 0;
+ while (t != NULL) {
+ i += t->skip;
+ if (i == col) {
+ return strtol(t->value, NULL, 16);
+ }
+ i++;
+ t = t->next;
+ }
+ return 0xFF;
+}
+
+uint8_t get_optotal(opcode *opc) {
+ uint8_t i = 0;
+ for (; opc != NULL; opc = opc->next, i++);
+ return i;
+}
+
+inst *find_inst(char *mne) {
+ list *l = lists;
+ while (l != NULL) {
+ inst *ins = l->inst;
+ if (!strcasecmp(mne, ins->mne)) {
+ return ins;
+ }
+ l = l->next;
+ }
+ return NULL;
+}
+
+void print_openum(opcode *opc, char *name) {
+ printf("enum %s {\n", name);
+ while (opc != NULL) {
+ inst *ins = find_inst(opc->mne);
+ if (ins == NULL) {
+ opc = opc->next;
+ continue;
+ }
+ uint8_t i = 0;
+ for (; ins->op[i] == 0xFF; i++);
+ putchar('\t');
+ /*if (i == opc->am || opc->am == IMPL) {
+ printf("%s ", opc->mne);
+ } else {
+ printf("%s_%s", opc->mne, ams[opc->am]);
+ }*/
+ printf("%s_%s", opc->mne, ams[opc->am]);
+ printf("= 0x%02X", opc->op);
+ putchar((opc->next != NULL) ? ',' : ' ');
+ if ((opc->am == IMPL && ins->op[IMPL] != 0xFF) || (i == opc->am && ins->op[IMPL] == 0xFF)) {
+ printf(" /* %s */", ins->com);
+ } else {
+ printf(" /* %s %s */", opc->mne, amcom[opc->am]);
+ }
+ putchar('\n');
+ opc = opc->next;
+ }
+ puts("};");
+}
+
+void print_mneenum(list *l, char *name) {
+ int i = 0;
+ int inst_count = get_instcount(l);
+ printf("enum %s {\n", name);
+ while (l) {
+ inst *ins = l->inst;
+ putchar('\t');
+ printf("%s = ", ins->mne);
+ if (i < 100 && inst_count >= 100) {
+ putchar(' ');
+ }
+ if (i < 10 && inst_count >= 10) {
+ putchar(' ');
+ }
+ printf("%i", i);
+ putchar((l->next) ? ',' : ' ');
+ putchar('\n');
+ i++;
+ l = l->next;
+ }
+ puts("};");
+}
+
+void print_optype(opcode *opc) {
+ uint8_t optotal = get_optotal(opc);
+ puts("static const uint8_t optype[0x100] = {");
+ while (opc != NULL) {
+ inst *ins = find_inst(opc->mne);
+ if (ins == NULL) {
+ opc = opc->next;
+ continue;
+ }
+ uint8_t i = 0;
+ for (; ins->op[i] == 0xFF; i++);
+ putchar('\t');
+ putchar('[');
+ printf("%s_%s", opc->mne, ams[opc->am]);
+ printf("] = %s", addrmodes[opc->am]);
+ putchar((opc->next != NULL) ? ',' : ' ');
+ putchar('\n');
+ opc = opc->next;
+ }
+ puts("};");
+}
+
+void print_mne(list *l) {
+ puts("static const char *mne[OPNUM] = {");
+ while (l != NULL) {
+ inst *ins = l->inst;
+ printf("\t[%s] = \"%s\"", ins->mne, ins->mne);
+ putchar((l->next) ? ',' : ' ');
+ putchar('\n');
+ l = l->next;
+ }
+ puts("};");
+}
+
+void print_instdesc(list *l) {
+ puts("static const char *instdesc[OPNUM] = {");
+ while (l != NULL) {
+ inst *ins = l->inst;
+ printf("\t[%s] = \"%s\"", ins->mne, ins->desc);
+ putchar((l->next) ? ',' : ' ');
+ putchar('\n');
+ l = l->next;
+ }
+ puts("};");
+}
+
+void print_opname(opcode *opc) {
+ puts("static const char *opname[0x100] = {");
+ while (opc != NULL) {
+ inst *ins = find_inst(opc->mne);
+ if (ins == NULL) {
+ opc = opc->next;
+ continue;
+ }
+ uint8_t i = 0;
+ for (; ins->op[i] == 0xFF; i++);
+ putchar('\t');
+ printf("[%s_%s", opc->mne, ams[opc->am]);
+ printf("] = \"%s", opc->mne);
+ if (opc->am != IMPL) {
+ printf(" %s", am_tok[opc->am]);
+ }
+ putchar('\"');
+ putchar((opc->next != NULL) ? ',' : ' ');
+ putchar('\n');
+ opc = opc->next;
+ }
+ puts("};");
+}
+
+int main(int argc, char **argv) {
+ FILE *fp;
+ char *fn = (argc) ? argv[1] : NULL;
+ int i = 0;
+ int j = 0;
+ int maxop = 0;
+ fp = (fn) ? fopen(fn, "r") : stdin;
+ if (fp == NULL) {
+ return 1;
+ }
+
+ parse_csv(fp);
+
+ line *l = lines;
+ line *lns = l; /* Low nibbles. */
+ list *ls;
+ opcode *opc;
+ l = l->next;
+ i = 0;
+ int done = 0;
+ int isdesc = 0;
+ while (l != NULL) {
+ token *t = l->tok;
+ j = 0;
+ i += l->skip;
+ if (!done) {
+ int size = strlen(t->value);
+ int high_nibble = 0xFF;
+ if (isxdigit(t->value[0]) && !l->skip) {
+ high_nibble = strtol(t->value, NULL, 16);
+ t = t->next;
+ j++;
+ }
+ while (t != NULL) {
+ j += t->skip;
+ int low_nibble = get_lownibble(lns, j);
+ int op = (high_nibble << 4) | low_nibble;
+ if (op > 0xFF) {
+ done = 1;
+ break;
+ }
+
+ opc = lex_value(t->value, op);
+
+ /*printf("opcode: $%02X, Row %i, Column %i: %s\n", op, i, j, t->value);*/
+ t = t->next;
+ j++;
+ }
+ } else {
+ while (t != NULL) {
+ if (!strcasecmp(t->value, "mnemonic")) {
+ isdesc = 1;
+ break;
+ }
+ if (isdesc) {
+ char *mne;
+ char *desc;
+ char *com;
+
+ mne = t->value;
+ t = t->next;
+ desc = t->value;
+ t = t->next;
+ com = t->value;
+
+ ls = make_list(mne, desc, com);
+ }
+ t = t->next;
+ }
+ }
+ l = l->next;
+ i++;
+ }
+
+ i = 0;
+ int inst_count = get_instcount(lists);
+ printf("#define OPNUM %i\n", inst_count);
+ print_mneenum(lists, "mne");
+ print_optable(lists, inst_count);
+ print_openum(opcodes, "base_isa");
+ print_optype(opcodes);
+ print_opname(opcodes);
+ print_mne(lists);
+ print_instdesc(lists);
+
+ free_lines();
+ free_lists();
+ free_opcodes();
+
+ fclose(fp);
+ return 0;
+}
diff --git a/opcode.h b/opcode.h
index b98803b..696ad9d 100644
--- a/opcode.h
+++ b/opcode.h
@@ -10,7 +10,7 @@
#define getclk 0
#define keypoll 0
-#define OPNUM 88
+#define OPNUM 87
#define C (1 << 0) /* Carry flag. */
#define Z (1 << 1) /* Zero flag. */
@@ -38,7 +38,7 @@ extern uint8_t get_addrsize(uint8_t prefix, uint8_t addrmode);
#define setreg_sw(reg, reg_idx, val, val_idx, prefix, addrmode, type) {\
switch (type) {\
- case RS: setreg(reg, +, reg_idx, val, +, val_idx, (1 << (prefix >> 4))-1); break;\
+ case RS: setreg(reg, +, reg_idx, val, +, val_idx, (1 << ((prefix >> 4) & 3))-1); break;\
case AM: setreg(reg, +, reg_idx, val, +, val_idx, get_addrsize(prefix, addrmode)); break;\
}\
}
diff --git a/programs/sub-suite/lexer.s b/programs/sub-suite/lexer.s
index 315bee4..cd7a33a 100644
--- a/programs/sub-suite/lexer.s
+++ b/programs/sub-suite/lexer.s
@@ -97,16 +97,16 @@ util_data:
lex:
ldx #0 ; Reset X.
txa ; Reset A.
- phy #2 ; Preserve the screen buffer index.
+ phy.w ; Preserve the screen buffer index.
txy ; Reset Y.
sty.q idx0 ; Clear the first index.
sty.q idx1 ; Clear the second index.
sty.q idx2 ; Clear the third index.
sty b ; Clear the isop flag.
; lda (ptr), y ; Get a character from the line.
-; pha #1 ; Preserve the character.
+; pha ; Preserve the character.
; jsr isdigit ; Is this character a digit?
-; pla #1 ; Get the character back.
+; pla ; Get the character back.
@getline:
lda #2 ; Get the third byte, of the line table address.
lsl #$10 ; Shift it by 2 bytes.
@@ -126,27 +126,27 @@ lex:
@spaces:
ldy.w idx0 ; Get the string index.
lda (ptr), y ; Get a character from the line.
- pha #1 ; Preserve the character.
+ pha ; Preserve the character.
jsr isdelm ; Get the delimiter.
and #$10 ; Is this character, a space, or tab?
- pla #1 ; Get the character back.
+ pla ; Get the character back.
beq @isstart ; No, so check for the start of the line.
inc.w idx0 ; Yes, so increment the string index.
cmp #' ' ; Is this character, a space?
beq @incs ; Yes, so increment the starting space count.
cmp #'\t' ; No, but is it a tab?
beq @inct ; Yes, so increment the starting tab count.
- jmp @spaces ; No, so Keep looping.
+ bra @spaces ; No, so Keep looping.
@incs:
inc idx1 ; Increment the space count.
- jmp @spaces ; Keep looping.
+ bra @spaces ; Keep looping.
@inct:
inc idx1+1 ; Increment the tab count.
- jmp @spaces ; Keep looping.
+ bra @spaces ; Keep looping.
@isstart:
- pha #2 ; Preserve the character.
+ pha.w ; Preserve the character.
lda.w idx1 ; Was there any whitespace?
- pla #2 ; Get the character back.
+ pla.w ; Get the character back.
beq @switch ; No, so start lexing.
cpb #1 ; Yes, and are we at the start of the line?
bne @switch ; No, so start lexing.
@@ -163,27 +163,27 @@ lex:
jsr get_ptok ; Get the pre-token.
jsr parse_ptok ; Parse the pre-token.
; beq @end ; We got to the end of the string.
- jmp @loop ; Keep looping.
+ bra @loop ; Keep looping.
@end:
- ply #2 ; Get the screen buffer index back.
+ ply.w ; Get the screen buffer index back.
rts ; End of lex.
parse_ptok:
- pha #1 ; Preserve the pre-token.
+ pha ; Preserve the pre-token.
ldb #2 ; Set the third pointer
lda.w #swtab ; to the start of the jump table.
jsr set_ptr ;
and #0 ; Reset A.
- pla #1 ; Get the pre-token back.
- phy #2 ; Preserve Y.
+ pla ; Get the pre-token back.
+ phy.w ; Preserve Y.
lsl #1 ; Multiply the pre-token by two, to get the jump index.
tay ; Get the index of the jump table.
lda.w (ptr3), y ; Get the address to jump to.
jsr set_ptr ; Set the third pointer to the case address.
and #0 ; Reset A.
tab ; Reset B.
- ply #2 ; Get Y back.
+ ply.w ; Get Y back.
jmp (ptr3) ; Jump to the case label.
ptok_dot:
ldb #1 ; Make init_lex increment the string index.
@@ -200,7 +200,7 @@ ptok_dot:
dey ; Decrement the lexeme index.
lda (ptr3), y ; Get the suffix character.
jsr get_rs ; Get the register size.
- jmp @end ; We are done.
+ bra @end ; We are done.
@dir:
lda #TOK_DIR ; Set the lexeme type to TOK_DIR.
sta lex_type ;
@@ -211,9 +211,9 @@ ptok_dot:
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 #8 ; Preserve the directive string pointer.
+ pha.q ; Preserve the directive string pointer.
jsr strcasecmp ; Is the lexeme buffer, the same as the directive string?
- pla #8 ; Get the directive string pointer back.
+ 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?
@@ -226,7 +226,7 @@ ptok_dot:
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.
- jmp @dir_loop ; Keep looping.
+ bra @dir_loop ; Keep looping.
@found:
nop ;
@end:
@@ -234,59 +234,102 @@ ptok_dot:
jsr set_cmdbuf ; Set the first pointer to the command buffer.
rts ; End of parse_ptok.
ptok_at:
+ inc.w idx0 ;
rts ; End of parse_ptok.
ptok_col:
+ inc.w idx0 ;
rts ; End of parse_ptok.
ptok_equ:
+ inc.w idx0 ;
rts ; End of parse_ptok.
ptok_plus:
+ inc.w idx0 ;
rts ; End of parse_ptok.
ptok_min:
+ inc.w idx0 ;
rts ; End of parse_ptok.
ptok_gt:
+ inc.w idx0 ;
rts ; End of parse_ptok.
ptok_lt:
+ inc.w idx0 ;
rts ; End of parse_ptok.
ptok_lbrk:
+ inc.w idx0 ;
rts ; End of parse_ptok.
ptok_rbrk:
+ inc.w idx0 ;
rts ; End of parse_ptok.
ptok_com:
+ inc.w idx0 ;
rts ; End of parse_ptok.
ptok_xr:
+ inc.w idx0 ;
rts ; End of parse_ptok.
ptok_yr:
+ 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.
ldb #4 ; Set the delimiter comparison value to a double quote.
jsr delmcpy ; Copy the string, to the lexeme buffer, until delimiter.
-@term:
+@end:
rts ; End of parse_ptok.
ptok_squ:
+ ldb #1 ; Make init_lex increment the string index.
+ jsr init_lex ; Initialize the lexeme buffer for copying.
+ ldb #8 ; Set the delimiter comparison value to a single quote.
+ jsr delmcpy ; Copy the string, to the lexeme buffer, until delimiter.
+@end:
rts ; End of parse_ptok.
ptok_hash:
+ inc.w idx0 ;
rts ; End of parse_ptok.
ptok_scol:
+ ldb #1 ; Make init_lex increment the string index.
+ jsr init_lex ; Initialize the lexeme buffer for copying.
+ jsr delmcpy ; Copy the string, to the lexeme buffer, until EOL.
+@end:
rts ; End of parse_ptok.
ptok_dolr:
- rts ; End of parse_ptok.
+ lda #TOK_HEX ; Set the lexeme type to TOK_HEX.
+ sta lex_type ;
+ lda #$10 ; Set the base to Hexadecimal.
+ ldb #1 ; Make init_lex increment the string index.
+ bra ptok_num2 ; Parse the value.
ptok_prcn:
- rts ; End of parse_ptok.
+ lda #TOK_BIN ; Set the lexeme type to TOK_BIN.
+ sta lex_type ;
+ lda #2 ; Set the base to Binary.
+ ldb #1 ; Make init_lex increment the string index.
+ bra ptok_num2 ; Parse the value.
ptok_num:
+ lda #TOK_DEC ; Set the lexeme type to TOK_DEC.
+ sta lex_type ;
+ lda #10 ; Set the base to Decimal.
+ ldb #0 ; Do not let init_lex increment the string index.
+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.
+ 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 make_tok ; Create the token.
+ jsr set_cmdbuf ; Set the first pointer to the command buffer.
rts ; End of parse_ptok.
ptok_alph:
ldb #0 ; Do not let init_lex increment the string index.
jsr init_lex ; Initialize the lexeme buffer for copying.
- ldb #1 ; Stop at any possible delimiter, except whitespace.
+ ldb #3 ; Stop at any possible delimiter.
tba ; Use isdelm2 for the comparison.
jsr delmcpy ; Copy the string, to the lexeme buffer, until delimiter.
lda #0 ; Reset A.
sta b ; Clear the isop flag.
@isop:
ldb #0 ; Make the lexeme buffer, the first pointer.
- stb.q idx1 ; Reset the first index.
+ stb.q idx1 ; Reset the second index.
jsr set_lexptr ; Set up the lexeme buffer.
@isop_loop:
lda.w #mne ; Get pointer to the start of the instruction table.
@@ -303,7 +346,7 @@ ptok_alph:
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.
- jmp @isop_loop ; Keep looping.
+ bra @isop_loop ; Keep looping.
@found:
lda #TOK_MNE ; Set the lexeme type to TOK_MNE.
sta lex_type ;
@@ -313,6 +356,7 @@ ptok_alph:
jsr set_cmdbuf ; Set the first pointer to the command buffer.
rts ; End of parse_ptok.
ptok_othr:
+ inc.w idx0 ;
rts ; End of parse_ptok.
@@ -322,6 +366,7 @@ set_lexptr:
and #0 ; Reset A.
tab ; Reset B.
sta.q idx1 ; Reset the second index.
+ sta.q idx2 ; Reset the third index
rts ; End of set_lexptr.
@@ -340,11 +385,19 @@ init_lex:
@inc_str:
inc.w idx0 ; Yes, so increment the string index.
@init:
- lda #0 ; Reset A.
- sta.q idx1 ; Reset the second index
- sta.q idx2 ; Reset the third index
ldb #2 ; Make the lexeme buffer, the third pointer.
jsr set_lexptr ; Set up the lexeme buffer.
+ phy.w ; Preserve Y.
+ tay ; Reset Y.
+@loop:
+ lda (ptr3), y ; Have we hit the end of the previous lexeme string?
+ beq @end ; Yes, so we're done.
+ lda #0 ; No, so start clearing the character.
+ sta (ptr3), y ; Clear the character.
+ iny ; Increment the lexeme index.
+ bra @loop ; Keep looping.
+@end:
+ ply.w ; Get Y back.
rts ; End of init_lex.
@@ -352,37 +405,80 @@ delmcpy:
sta a ; Save the delimiter check flag.
stb c ; Save the delimiter comparison value.
@loop:
+ ldb #0 ; Reset the B register.
+ stb g ; Reset the byte count.
ldy.w idx0 ; Get the string index.
- lda (ptr), y ; Get a character from the line.
- pha #1 ; Preserve the character.
+ lda.q (ptr), y ; Get eight bytes from the current line.
+@loop1:
+ pha.q ; Save the string buffer.
+ and #$FF ; Get the current byte.
+ pha ; Preserve the character.
lda a ; Are we calling isdelm2?
- pla #1 ; 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:
and c ; Are both delimiter values, the same?
+ pla.q ; Get back the string buffer.
bne @end ; Yes, so we're done.
- jmp @copy ; No, so start copying the character.
+ bra @copy ; No, so start copying the character.
@isdelm2:
jsr isdelm2 ; Get the delimiter value from isdelm2.
- cmp c ; Are both delimiter values, the same?
- beq @end ; Yes, so we're done.
+ bra @delmchk ; Check the delimiter.
@copy:
- lda (ptr), y ; Get a character from the line.
ldy.w idx1 ; Get the lexeme index.
- sta (ptr3), y ; Copy the character to the lexeme buffer.
+ sta (ptr3), y ; Copy one byte from the screen buffer, to the command buffer.
inc.w idx0 ; Increment the string index.
inc.w idx1 ; Increment the lexeme index.
- jmp @loop ; Keep looping.
+ lsr #8 ; Shift in the next byte.
+ inc g ; Increment the byte count.
+ ldb g ; Get back the byte count.
+ cpb #7 ; Did we shift in eight bytes?
+ beq @loop ; Yes, so get eight more bytes.
+ bra @loop1 ; No, so keep shifting in more bytes.
@end:
- lda #0 ; Terminate the lexeme buffer.
- sta (ptr3), y ;
+ ldb #0 ; Reset B.
+ ldy.w idx1 ; Get the lexeme index.
+ stb (ptr3), y ; Terminate the command buffer.
+@end1:
+ ldy.w idx0 ; Get the string index.
+ tba ; Reset A.
rts ; End of delmcpy.
+;@loop:
+; ldy.w idx0 ; Get the string index.
+; lda (ptr), y ; Get a character from the line.
+; pha ; Preserve the character.
+; lda a ; Are we calling isdelm2?
+; pla ; Get the character back.
+; bne @isdelm2 ; Yes, so use isdelm2.
+; jsr isdelm ; No, so get the delimiter value from isdelm.
+;@delmchk:
+; and c ; Are both delimiter values, the same?
+; bne @end ; Yes, so we're done.
+; bra @copy ; No, so start copying the character.
+;@isdelm2:
+; jsr isdelm2 ; Get the delimiter value from isdelm2.
+; bra @delmchk ; Check the delimiter.
+;@copy:
+; lda (ptr), y ; Get a character from the line.
+; ldy.w idx1 ; Get the lexeme index.
+; sta (ptr3), y ; Copy the character to the lexeme buffer.
+; inc.w idx0 ; Increment the string index.
+; inc.w idx1 ; Increment the lexeme index.
+; bra @loop ; Keep looping.
+;@end:
+; ldy.w idx1 ; Get the lexeme index.
+; lda #0 ; Terminate the lexeme buffer.
+; sta (ptr3), y ;
+; ldy.w idx0 ; Get the string index.
+; rts ; End of delmcpy.
+
get_rs:
- phb #1 ; Preserve B.
+ phb ; Preserve B.
ldb #0 ; Set the isop flag to false.
- plb #1 ; Get B back.
+ plb ; Get B back.
jsr tolower ; Convert the character to lowercase.
cmp #'w' ; Is it .w?
beq @r1 ; Yes, so return 1.
diff --git a/programs/sub-suite/subasm.s b/programs/sub-suite/subasm.s
index 9c6c3f0..d661695 100644
--- a/programs/sub-suite/subasm.s
+++ b/programs/sub-suite/subasm.s
@@ -187,6 +187,14 @@ idx2:
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
@@ -225,7 +233,7 @@ subasm:
jsr chk_cmd ; No, but did we get a full command?
bne @cmd ; Yes, so skip everything else.
jsr lex ; No, so start lexing this line.
- jmp @end ; We are done.
+ bra @end ; We are done.
@cmd:
ldb #1 ; Set the second pointer
lda.d #cmd_srt ; to the command subroutine table.
@@ -236,10 +244,10 @@ 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 #2 ; Preserve the screen buffer position.
+ 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 #2 ; Get back the screen buffer position.
+ ply.w ; Get back the screen buffer position.
ldb #2 ; Save it in the third pointer.
jsr set_ptr ;
ldb #0 ; Reset B.
@@ -254,7 +262,7 @@ chk_shcmd:
jsr set_ptr ;
deb ; Reset B.
tba ; Reset A.
- phy #2 ; Preserve the screen buffer position.
+ phy.w ; Preserve the screen buffer position.
txy ; Set our index to zero.
lda (ptr), y ; Is there nothing in the command buffer?
beq @false ; Yes, so return that we failed.
@@ -267,7 +275,7 @@ chk_shcmd:
cab ; No, so did the character match?
beq @found ; Yes, so check if there are any arguments.
iny ; No, so check the next command.
- jmp @loop ; Keep looping.
+ bra @loop ; Keep looping.
@found:
sty f ; Save the command ID.
ldy #1 ; Check the next character in the command buffer.
@@ -275,16 +283,16 @@ chk_shcmd:
beq @true ; Yes, so return that we succeded.
cmp #' ' ; No, but is this a space?
beq @true ; Yes, so return that we succeded.
- jmp @false ; No, so return that we failed.
+ bra @false ; No, so return that we failed.
@true:
lda #1 ; Return true.
- jmp @end ; We are done.
+ bra @end ; We are done.
@false:
ldb #0 ; Reset B.
tba ; Return false.
tax ; Reset X.
@end:
- ply #2 ; Get back the screen buffer position.
+ ply.w ; Get back the screen buffer position.
rts ; End of chk_shcmd.
@@ -297,9 +305,9 @@ chk_cmd:
lda.w #cmds ; Get pointer to the start of the command table.
clc ; Prepare for a non carrying add.
adc.w idx0 ; Offset the pointer, by the length of the previous string.
- pha #8 ; Preserve the command string pointer.
+ pha.q ; Preserve the command string pointer.
jsr strcasecmp ; Is the command buffer, the same as the command string?
- pla #8 ; Get the command string pointer back.
+ pla.q ; Get the command string pointer back.
beq @true ; Yes, so return true.
ldb idx1 ; No, so Get the command ID.
cpb #7 ; Have we reached the end of the command table?
@@ -312,12 +320,12 @@ chk_cmd:
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.
- jmp @loop ; Keep looping.
+ bra @loop ; Keep looping.
@true:
ldb idx1 ; Get the command ID.
stb f ; Return the command ID.
ldb #1 ; Return true.
- jmp @end ; We are done.
+ bra @end ; We are done.
@false:
ldb #0 ; Return false.
@end:
@@ -351,7 +359,7 @@ viewmem:
adc #$10 ; Add 16 to the address.
sta.q idx0 ; Put it back into the address.
and #0 ; Reset A.
- jmp @loop ; Keep looping.
+ bra @loop ; Keep looping.
@end:
lda #'\n' ; Print a newline.
jsr print_char ;
diff --git a/programs/sub-suite/subeditor.s b/programs/sub-suite/subeditor.s
index 1768d62..cc18b4c 100644
--- a/programs/sub-suite/subeditor.s
+++ b/programs/sub-suite/subeditor.s
@@ -140,10 +140,12 @@ reset:
lda.d #buffer ; Set the array to be cleared to the screen buffer.
jsr clr_arr ; Clear the screen buffer.
jsr pnt_strt ; Print the starting message.
- jmp start ; Goto the start of the main program.
+ lda #$C ; Clear the screen.
+ sta scr ;
+ bra start ; Goto the start of the main program.
clr_arr:
- phb #1 ; Preserve whatever was in B.
+ phb ; Preserve whatever was in B.
ldb #0 ; Clear B.
jsr set_ptr ; Set the first pointer to the parameter.
adc #8 ; Set the second pointer to the parameter, plus eight.
@@ -166,10 +168,10 @@ clr_arr:
adc #$10 ;
tay ;
tba ;
- jmp @loop ; Keep looping.
+ bra @loop ; Keep looping.
@end:
ldy.w zero ; Set the index back to zero.
- plb #1 ; Get whatever was in the B register, back.
+ plb ; Get whatever was in the B register, back.
rts ; End of clr_arr.
pnt_strt:
@@ -195,16 +197,16 @@ 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 #2 ; Save the cursor index for later.
+ phy.w ; Save the cursor index for later.
tay ; Reset the cursor index.
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 #2 ; Get back the cursor index.
+ ply.w ; Get back the cursor index.
and #0 ; Reset the Accumulator.
sta end ;
- jmp read ; Start reading the keyboard.
+ bra read ; Start reading the keyboard.
read:
lda #0 ; Reset the Accumulator.
@@ -214,7 +216,14 @@ read:
beq read ; No, so try again.
jsr getchar ; Yes, and was it a newline?
beq parse ; Yes, so start parsing the line.
- jmp read ; No, so keep looping.
+ bra read ; No, so keep looping.
+
+parse:
+ lda #0 ;
+ tax ;
+ jsr subasm ;
+ bra start ;
+
print_str:
ldx #0 ; Reset X.
@@ -231,14 +240,14 @@ print_str:
cmp.q end ; Did the pointer change?
bne @reset ; Yes, so set it back.
and #0 ; No, reset the accumulator.
- phy #2 ; Save the cursor index.
+ 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 #2 ; Get the cursor index back.
+ ply.w ; Get the cursor index back.
beq @end ; Yes, so we're done.
inx ; No, so increment the string index.
jsr print_char ; Print the character.
- jmp @loop ; Keep looping.
+ bra @loop ; Keep looping.
@end:
ldb #0 ; Enable insert mode.
stb b ;
@@ -249,81 +258,81 @@ getbit:
lda scr_str ; Has the screen been scrolled?
bne getbt0 ; Yes, so add the screen offset to the current line number.
ldx scr_row ; No, so just use the current line number.
- jmp getbt1 ; Start getting the bit.
+ bra getbt1 ; Start getting the bit.
getbt0:
lda scr_row ; Get the current line number.
adc scr_str ; Add the screen offset to it.
tax ; Use it as the wrap index.
getbt1:
- pha #1 ; Save the parameter.
+ pha ; Save the parameter.
ldb #1 ; Make sure that set_ptr sets the second pointer.
lda.d #bitabl ; Set the second pointer to the linewrap table.
jsr set_ptr ;
lsr #$10 ; Clear the Accumulator.
- pla #1 ; Get the return byte back.
+ pla ; Get the return byte back.
jsr bitpos ; Get the bit, and byte position.
- phy #2 ; Save the screen index.
+ phy.w ; Save the screen index.
txy ; Get the byte position.
ldb (ptr2), y ; Get one byte of the wrap table.
- ply #2 ; Get the screen index back.
+ ply.w ; Get the screen index back.
aba ; Mask out the bit of the current line number.
cmp #1 ; Set the carry flag, if true.
- jmp bitout ; We are done.
+ bra bitout ; We are done.
clrbit:
- pha #1 ; Save the parameter.
+ pha ; Save the parameter.
ldb #1 ; Make sure that set_ptr sets the second pointer.
lda.d #bitabl ; Set the second pointer to the linewrap table.
jsr set_ptr ;
and #0 ; Clear the Accumulator.
- pla #1 ; Get the return byte back.
+ pla ; Get the return byte back.
jsr bitpos ; Get the bit, and byte position.
xor #$FF ; Invert the bitmask.
- phy #2 ; Save the screen index.
+ phy.w ; Save the screen index.
txy ; Get the byte position.
ldb (ptr2), y ; Get one byte of the wrap table.
aba ; Clear the bit of the current line number.
bitsav:
sta (ptr2), y ; Update the wrap table.
- ply #2 ; Get the screen index back.
+ ply.w ; Get the screen index back.
bitout:
ldx bitmask ; Return the bitmask.
rts ; We are done.
setbit:
- pha #1 ; Save the parameter.
+ pha ; Save the parameter.
ldb #1 ; Make sure that set_ptr sets the second pointer.
lda.d #bitabl ; Set the second pointer to the linewrap table.
jsr set_ptr ;
and #0 ; Clear the Accumulator.
- pla #1 ; Get the return byte back.
+ pla ; Get the return byte back.
jsr bitpos ; Get the bit, and byte position.
- phy #2 ; Save the screen index.
+ phy.w ; Save the screen index.
txy ; Get the byte position.
ldb (ptr2), y ; Get one byte of the wrap table.
oab ; Set the bit of the current line number.
- jmp bitsav ; Save the bit.
+ bra bitsav ; Save the bit.
bitpos:
- pha #1 ; Save the parameter.
+ pha ; Save the parameter.
ldb #0 ; Make sure that set_ptr sets the first pointer.
lda.w #bits ; Set the first pointer to the bitmask table.
jsr set_ptr ;
and #0 ; Clear the Accumulator.
- pla #1 ; Get the parameter back.
+ pla ; Get the parameter back.
stx bitmask ; Make the line number the bitmask.
txa ; Copy it to the Accumulator.
and #7 ; Get the bit position.
- phy #2 ; Save the cursor index.
+ phy.w ; Save the cursor index.
tay ; Use the bit position as the index.
tax ; Copy it into X.
lda (ptr), y ; Get the bitmask.
- ply #2 ; Get back the cursor index.
- pha #1 ; Save the bitmask.
+ ply.w ; Get back the cursor index.
+ pha ; Save the bitmask.
lda bitmask ; Get the line number.
lsr #3 ; Get the byte position.
tax ; Copy it into X.
- pla #1 ; Get back the bitmask.
+ pla ; Get back the bitmask.
rts ; End of bitpos.
getchar:
@@ -331,14 +340,14 @@ getchar:
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.
- pha #1 ; Save the character.
- phy #2 ; Save the cursor index.
+ pha ; Save the character.
+ phy.w ; Save the cursor index.
cmp #'\n' ; Was the character that was typed, a newline?
bne @print ; No, so just print the character.
jsr cmd_cpy ; Yes, so start copying the line to the command buffer.
@print:
- ply #2 ; Get back the cursor index.
- pla #1 ; Get back the character.
+ ply.w ; Get back the cursor index.
+ pla ; Get back the character.
ldb e ; Is the temporary row position non zero?
bne @row ; Yes, so reset the row positon.
@print1:
@@ -346,21 +355,21 @@ getchar:
lda a ; Get the return value.
cmp #'\n' ; Is the return value, a newline?
beq @true ; Yes, so return true.
- jmp @false ; No, so return false.
+ bra @false ; No, so return false.
@row:
ldb e ; Get the temporary row position.
cpb #maxrow ; Is temporary row position, at, or above the bottom of the screen?
beq @row2 ; Yes, so leave it as is.
bcs @row1 ; No, so set it to the bottom of the screen.
- jmp @row2 ; Yes, so leave it as is.
+ bra @row2 ; Yes, so leave it as is.
@row1:
ldb #maxrow ; Set the row position to the bottom of the screen.
@row2:
stb scr_row ; Set the row position.
- jmp @print1 ; Print the character.
+ bra @print1 ; Print the character.
@true:
lda #0 ; Return true.
- jmp @end ; We are done.
+ bra @end ; We are done.
@false:
lda #1 ; Return false.
@end:
@@ -399,11 +408,11 @@ cmd_cpy:
ldb #0 ; Reset the B register.
lda.q (ptr), y ; Get eight bytes from the current line.
@loop1:
- phy #2 ; Save the screen index.
+ phy.w ; Save the screen index.
txy ; Get the command buffer index.
sta (ptr2), y ; Copy one byte from the screen buffer, to the command buffer.
inx ; Increment the command buffer index.
- ply #2 ; Get back the screen index.
+ ply.w ; Get back the screen index.
cpx.w #$3FF ; Are we at the end of the command buffer?
bcs @end ; Yes, so we're done.
iny ; No, so increment the screen index.
@@ -417,13 +426,13 @@ cmd_cpy:
ldb g ; Get back the byte count.
cpb #7 ; Did we shift in eight bytes?
beq @loop ; Yes, so get eight more bytes.
- jmp @loop1 ; No, so keep shifting in more bytes.
+ bra @loop1 ; No, so keep shifting in more bytes.
@end:
ldb #0 ; Reset B.
- phy #2 ; Save the screen index.
+ phy.w ; Save the screen index.
txy ; Get the command buffer index.
stb (ptr2), y ; Terminate the command buffer.
- ply #2 ; Get back the screen index.
+ ply.w ; Get back the screen index.
@end1:
tab ; The B register is zero, so clear the Accumulator.
rts ; End of cmd_cpy.
@@ -432,9 +441,9 @@ cmd_cpy:
findst:
lda #0 ; Reset A.
@loop:
- pha #1 ; Save the current line number.
+ pha ; Save the current line number.
jsr getbit ; Is this the start of the line?
- pla #1 ; Get the current line number back.
+ pla ; Get the current line number back.
bcc @end ; Yes, so we're done.
inc ; No, so check the next physical line.
dec scr_row ; Are we at the top of the screen?
@@ -447,21 +456,21 @@ findst:
fndend:
- phb #1 ; Save the contents of the B register.
+ phb ; Save the contents of the B register.
ldb #0 ; Make sure that set_ptr sets the first pointer.
lda.d #buffer ; Set the first pointer to the start of the screen buffer.
jsr set_ptr ;
tba ; Set the Accumulator to zero.
- plb #1 ; Restore the contents of the B register.
- phy #2 ;
+ plb ; Restore the contents of the B register.
+ phy.w ;
@loop:
lda (ptr), y ; Are we at the end of the string?
beq @end ; Yes, so we're done.
iny ; No, so increment the cursor index.
- jmp @loop ; Keep looping.
+ bra @loop ; Keep looping.
@end:
sty.w scr_ptr3 ;
- ply #2 ;
+ ply.w ;
rts ; End of fndend.
findend:
@@ -470,11 +479,6 @@ findend:
div #maxcol+1 ;
rts ;
-parse:
- lda #0 ;
- tax ;
- jsr subasm ;
- jmp start ;
print_char:
sta a ; Save the typed character for now.
@@ -507,7 +511,7 @@ printc:
bne @save ; Yes, so don't shift the line.
sty.w scr_ptr ; No, so save the cursor index for later.
jsr fndend ; Find the end of the line.
- jmp @shift ; Start shifting the line right.
+ bra @shift ; Start shifting the line right.
@update:
lda scr_col ; Save the current column position for later.
sta scr_tcol ;
@@ -526,7 +530,7 @@ printc:
sta scr_col ;
jsr update_pos ; Update the cursor's position.
dec d ;
- jmp @save1 ;
+ bra @save1 ;
@shift:
ldy.w scr_ptr3 ;
inc scr_ptr3 ;
@@ -541,7 +545,7 @@ printc:
sta (ptr3), y ; store typed character into the input buffer.
lda scr_row ;
sta scr_trow ;
- jmp @update ;
+ bra @update ;
@save:
ldb d ;
bne @update ;
@@ -561,7 +565,7 @@ printc:
sta scr ; Echo typed character.
ldb f ;
beq @wrap ;
- jmp printc_end ;
+ bra printc_end ;
@scrolled:
ldb scr_row ;
cpb #maxrow ;
@@ -569,7 +573,7 @@ printc:
@wrapped2:
ldb #0 ;
stb f ;
- jmp @print ;
+ bra @print ;
@scroll:
sta scr ; Echo typed character.
clc ;
@@ -585,13 +589,13 @@ printc:
@wrap1:
inc scr_row ;
@wrap2:
- phx #2 ;
+ phx.w ;
clc ;
lda scr_row ;
adc scr_str ;
tax ;
jsr setbit ;
- plx #2 ;
+ plx.w ;
jsr update_pos ;
printc_end:
rts ;
@@ -607,14 +611,15 @@ nl:
cmp #maxrow ; Are we at the bottom of the screen?
bcc @incr ; No, so move down one line.
jsr scrl_down ; Yes, so scroll down one line.
- jmp @end ; We are done.
+ bra @end ; We are done.
@incr:
inc scr_row ; Move the cursor down by one line.
jsr update_pos ; Update the cursor's position.
@end:
lda #'\n' ; Print the newline.
sta a ;
- jmp printc_end ;
+ rts ;
+
clr_scr:
lda #maxrow ;
@@ -638,26 +643,57 @@ clr_scr:
jsr update_pos ;
lda #$C ;
sta scr ;
- jmp printc_end ;
+ rts ;
en_step:
lda step ;
beq step_en ;
- jmp printc_end ;
+ rts ;
step_en:
lda #1 ;
sta step ;
- jmp printc_end ;
+ rts ;
dis_step:
lda step ;
bne step_dis ;
- jmp printc_end ;
+ rts ;
step_dis:
lda #0 ;
sta step ;
- jmp printc_end ;
+ rts ;
+
+bs:
+ lda scr_col ; Are we at the far left of the screen?
+ beq @wrap ; Yes, so check for a wrapped line.
+ bra back ; No, so add the backspace to the buffer.
+@wrap:
+ jsr getbit ; Is this line, a wrapped line?
+ bcs @wrap1 ; Yes, so check if the cursor is at the top.
+ rts ; No, so we're done.
+@wrap1:
+ lda scr_row ; Are we at the top of the screen?
+ beq @wrap2 ; Yes, so check if the screen is at the top of the buffer.
+ bra @wrap3 ; No, so start clearing the wrap bit.
+@wrap2:
+ lda scr_str ; Are we at the top of the buffer?
+ bne @scroll ; Yes, so scroll up.
+ rts ; No, so we're done.
+@scroll:
+ clc ; Clear the carry flag, so that we don't get odd behaviour.
+ jsr scrl_up ; Scroll up.
+ inc scr_row ; Move down by one row.
+@wrap3:
+ clc ; Clear the carry flag.
+ lda scr_row ; Add the cursor's row position,
+ adc scr_str ; and the screen's starting row.
+ tax ; Transfer that into X.
+@wrap4:
+ dec scr_row ; Move up by one row.
+ ldb #maxcol+1 ; Move the cursor to the absolute right of the screen.
+ stb scr_col ;
+ jsr update_pos ; Update the cursor's position.
back:
ldb #0 ; Reset B, and some flags.
stb e ;
@@ -698,54 +734,23 @@ back:
sta scr_row ;
dec scr_col ; Move the cursor back by one column,
jsr update_pos ; and update it's position.
- jmp printc_end ; We are done.
+ rts ; We are done.
@update:
lda scr_row ; Set the line to start redrawing, to the start of the line.
sta f ;
inc e ; Set the redraw flag to true.
- jmp @shift ; Start shifting the line back.
+ bra @shift ; Start shifting the line back.
-bs:
- lda scr_col ; Are we at the far left of the screen?
- beq @wrap ; Yes, so check for a wrapped line.
- jmp back ; No, so add the backspace to the buffer.
-@wrap:
- jsr getbit ; Is this line, a wrapped line?
- bcs @wrap1 ; Yes, so check if the cursor is at the top.
- jmp printc_end ; No, so we're done.
-@wrap1:
- lda scr_row ; Are we at the top of the screen?
- beq @wrap2 ; Yes, so check if the screen is at the top of the buffer.
- jmp @wrap3 ; No, so start clearing the wrap bit.
-@wrap2:
- lda scr_str ; Are we at the top of the buffer?
- bne @scroll ; Yes, so scroll up.
- jmp printc_end ; No, so we're done.
-@scroll:
- clc ; Clear the carry flag, so that we don't get odd behaviour.
- jsr scrl_up ; Scroll up.
- inc scr_row ; Move down by one row.
-@wrap3:
- clc ; Clear the carry flag.
- lda scr_row ; Add the cursor's row position,
- adc scr_str ; and the screen's starting row.
- tax ; Transfer that into X.
-@wrap4:
- dec scr_row ; Move up by one row.
- ldb #maxcol+1 ; Move the cursor to the absolute right of the screen.
- stb scr_col ;
- jsr update_pos ; Update the cursor's position.
- jmp back ; Delete the previous character.
shftln:
ldb d ; Is the flag not set?
beq @dec_loop ; Yes, so shift, and decrement.
ldb #0 ; Clear the B register.
- jmp @inc_loop ; No, so shift, and increment.
+ bra @inc_loop ; No, so shift, and increment.
@neg:
ldy.w zero ; Set the source poition to 0.
stb (ptr3), y ; Clear the character that is in the source.
- jmp @end ; We are done.
+ bra @end ; We are done.
@inc_loop:
sty.w scr_ptr2 ; Save the source position for later.
ldy.w scr_ptr ; Get the previous cursor index.
@@ -755,35 +760,35 @@ shftln:
@inc_loop1:
ldy.w scr_ptr2 ; Get the source position.
lda (ptr3), y ; Get the character from the source position.
- phy #2 ; Save the source position for later.
+ phy.w ; Save the source position for later.
txy ; Set our position to the destination.
sta (ptr3), y ; Place the character from the source position, to the destination position.
- ply #2 ; Set our position back to the source.
+ ply.w ; Set our position back to the source.
stb (ptr3), y ; Clear the character that is in the source.
bng @neg ; The source underflowed, so set it back to zero,
dey ; Decrement the source position.
dex ; Decrement the destination position.
- jmp @inc_loop ; Keep looping.
+ bra @inc_loop ; Keep looping.
@dec_loop:
stx.w scr_ptr2 ; Save the destination position for later.
lda (ptr3), y ; Is the character at the source position, a null terminator?
beq @end3 ; Yes, so we're done.
- phy #2 ; No, so save the source position for later.
+ phy.w ; No, so save the source position for later.
txy ; Set our position to the destination.
sta (ptr3), y ; Place the character from the source position, to the destination position.
inx ; Increment the destination position.
- ply #2 ; Set our position back to the source.
+ ply.w ; Set our position back to the source.
stb (ptr3), y ; Clear the character that is in the source.
iny ; Increment the source position.
- jmp @dec_loop ; Keep looping.
+ bra @dec_loop ; Keep looping.
@wrap:
tax ; Use the ending line as a parameter for setbit.
jsr setbit ; Set the wrap bit of the ending line.
- jmp @end5 ; We are done.
+ bra @end5 ; We are done.
@wrap1:
tax ; Use the ending line as a parameter for clrbit.
jsr clrbit ; Clear the wrap bit of the ending line.
- jmp @end5 ; We are done.
+ bra @end5 ; We are done.
@end:
lda (ptr3), y ; Is this character a null terminator?
bne @end1 ; No, so just find the end of the line.
@@ -802,12 +807,12 @@ shftln:
cmp scr_row ; Is the ending line greater than the starting line?
beq @end5 ; No, so we're done.
bcs @wrap ; Yes, so set the wrap bit.
- jmp @end5 ; No, so we're done.
+ bra @end5 ; No, so we're done.
@end3:
jsr findend ; Find the ending line.
cpb #0 ; Is the remainder zero?
beq @end4 ; Yes, so check if the ending line is greater than the starting line.
- jmp @end5 ; No, so we're done.
+ bra @end5 ; No, so we're done.
@end4:
cmp scr_row ; Is the ending line greater than the starting line?
beq @end5 ; No, so we're done.
@@ -821,44 +826,45 @@ esc:
cmp #$1B ; Is this character an escape character?
beq shftesc ; Yes, so check the other set of escape routines.
lda status ; No, so wait for the next character.
- beq printc_end ; We have an error, so discard it, and go back to getting user input.
+ beq @end ; We have an error, so discard it, and go back to getting user input.
lda kbd ; Get the escape code.
sta c ; Store the escape code, until we need it.
lda #0 ; Set the D pseudo register to zero.
sta d ;
jsr isup ; Check if the user pressed up.
lda d ; Did the user press up?
- bne esc_end ; Yes, so we're done.
+ bne @end ; Yes, so we're done.
jsr isdown ; No, so check if the user pressed down.
lda d ; Did the user press down?
- bne esc_end ; Yes, so we're done.
+ bne @end ; Yes, so we're done.
lda #0 ; No, so check if the user pressed left.
jsr isleft ;
lda d ; Did the user press left?
- bne esc_end ; Yes, so we're done.
+ bne @end ; Yes, so we're done.
jsr isright ; No, so check if the user pressed right.
-esc_end:
+@end:
lda #0 ; Clear the D pseudo register.
sta d ;
- jmp printc_end ; We are done.
+ rts ; We are done.
shftesc:
lda status ; Skip the '['.
lda kbd ;
lda status ; Wait for the next character.
- beq printc_end ; We have an error, so discard it, and go back to getting user input.
+ beq @end ; We have an error, so discard it, and go back to getting user input.
lda kbd ; Get the escape code.
sta c ; Store the escape code, until we need it.
lda #0 ; Use the D pseudo register as a skip flag.
sta d ;
jsr isshftup ; Check if the user pressed shift+up.
lda d ; Was it successful?
- bne shftesc_end ; Yes, so we're done.
+ bne @end ; Yes, so we're done.
jsr isshftdown ; No, so check if the user pressed shift+down.
-shftesc_end:
+@end:
lda #0 ; Clear the D pseudo register.
sta d ;
- jmp printc_end ; We are done.
+ rts ; We are done.
+
isup:
lda c ; Load the escape code into the accumulator.
@@ -869,8 +875,14 @@ isup:
@check2:
lda c ; No, so load the escape code back into the accumulator.
cmp #'A' ; Did the user press the up arrow key?
- beq up ; Yes, so move the cursor up.
- jmp @end ; No, so we're done.
+ beq @up ; Yes, so move the cursor up.
+ bra @end ; No, so we're done.
+@up:
+ dec scr_row ; Move the cursor up a line.
+ jsr update_pos ; Update it's position.
+ lda #1 ; Tell the escape routine that we succeded.
+ sta d ;
+ rts ; We are done.
@scroll:
lda scr_str ; Are we at the top of the screen buffer?
beq @end ; Yes, so we're done.
@@ -878,9 +890,9 @@ isup:
lda #1 ; Tell the escape routine that we were successful.
sta d ;
@end:
-isup_done:
rts ; End of isup.
+
isdown:
lda c ; Load the escape code into the accumulator.
cmp #'B' ; Did the user press the down arrow key?
@@ -890,8 +902,14 @@ isdown:
beq @scroll ; Yes, so scroll down.
lda c ; No, so load the escape code back into the accumulator.
cmp #'B' ; Did the user press the down arrow key?
- beq down ; Yes, so move the cursor down.
- jmp @end ; No, so we're done.
+ beq @down ; Yes, so move the cursor down.
+ bra @end ; No, so we're done.
+@down:
+ inc scr_row ; Move the cursor down a line.
+ jsr update_pos ; Update it's position.
+ lda #1 ; Tell the escape routine that we succeded.
+ sta d ;
+ rts ; We are done.
@scroll:
lda scr_row ; Save the cursor's row number.
sta scr_trow ;
@@ -905,9 +923,9 @@ isdown:
lda #1 ; Tell the escape routine that we were successful.
sta d ;
@end:
-isdown_done:
rts ; End of isdown.
+
isright:
lda c ; Load the escape code into the accumulator.
cmp #'C' ; Did the user press the right arrow key?
@@ -915,20 +933,20 @@ isright:
lda scr_col ; Yes, so start checking the x coordinate of the cursor.
cmp #maxcol ; Is the cursor at the far right of the screen?
beq @wrap ; Yes, so check if this is a wrapped line.
- jmp right ; No, so move the cursor right, like normal.
+ bra @right ; No, so move the cursor right, like normal.
@wrap:
inc scr_row ; Move down a row.
jsr getbit ; Is the current line, a wrapped line?
bcs @incr ; Yes, so leave the cursor where it is.
dec scr_row ; No, so move the cursor back up a row.
- jmp @end2 ; We are done.
+ bra @end2 ; We are done.
@scroll:
lda scr_str ; Are we at the top of the screen buffer?
beq @end ; Yes, so we're done.
lda #1 ; No, so scroll down.
sta wrapped ; Set the wrapped flag.
jsr scrl_down ; Scroll down.
- jmp @end ; We are done.
+ bra @end ; We are done.
@incr:
lda #0 ; Set the cursor to the far left of the screen.
sta scr_col ;
@@ -936,17 +954,21 @@ isright:
cmp #maxrow ; Are we at the bottom of the screen?
beq @end1 ; No, so we're done.
bcs @scroll ; Yes, so check if we are scrolling down.
- jmp @end1 ; No, so we're done.
+ bra @end1 ; No, so we're done.
+@right:
+ inc scr_col ; Move the cursor right by one character.
+ jsr update_pos ; Update it's position.
+ rts ; End of isright.
@end:
dec scr_row ; Move back up a row.
@end1:
jsr update_pos ; Update the cursor position.
@end2:
-isright_dne:
lda #0 ; Unset the wrapped flag.
sta wrapped ;
rts ; End of isright.
+
isleft:
lda c ; Load the escape code into the accumulator.
cmp #'C' ; Did the user press right?
@@ -955,12 +977,12 @@ isleft:
beq @wrap ; Yes, so start checking if this is a wrapped line.
lda c ; No, so load the escape code back into the accumulator.
cmp #'D' ; Did the user press the left arrow key?
- beq left ; Yes, so move the cursor left.
- jmp @end1 ; No, so we're done.
+ beq @left ; Yes, so move the cursor left.
+ bra @end1 ; No, so we're done.
@wrap:
jsr getbit ; Is the current line, a wrapped line?
bcs @decr ; Yes, so wrap back up a line.
- jmp @end1 ; No, so we're done.
+ bra @end1 ; No, so we're done.
@decr:
lda scr_row ; Is the cursor at the top of the screen?
beq @decr1 ; Yes, so don't move up a line.
@@ -974,81 +996,60 @@ isleft:
sta d ;
lda scr_row ; Are we at the top of the screen?
beq @scroll ; Yes, so check if we need to scroll.
- jmp @end ; No, so we're done.
+ bra @end ; No, so we're done.
@scroll:
lda wrapped ; Was the wrapped flag set somewhere else?
bne @end ; Yes so we're done.
lda scr_str ; No, but are we actually at the top of the screen buffer?
beq @end1 ; Yes, so we're done.
jsr scrl_up ; No, so scroll up.
- jmp @end1 ; We are done.
+ bra @end1 ; We are done.
+@left:
+ dec scr_col ; Move the cursor left a character.
+ jsr update_pos ; Update it's position.
+ lda #1 ; Tell the escape routine that we succeded.
+ sta d ;
+ rts ; We are done
@end:
jsr update_pos ; Update the cursor position.
@end1:
-isleft_done:
lda #0 ; Unset the wrapped flag.
sta wrapped ;
rts ; End of isleft.
-up:
- dec scr_row ; Move the cursor up a line.
- jsr update_pos ; Update it's position.
- lda #1 ; Tell the escape routine that we succeded.
- sta d ;
- jmp isup_done ; We are done.
-down:
- inc scr_row ; Move the cursor down a line.
- jsr update_pos ; Update it's position.
- lda #1 ; Tell the escape routine that we succeded.
- sta d ;
- jmp isdown_done ; We are done.
-right:
- inc scr_col ; Move the cursor right by one character.
- jsr update_pos ; Update it's position.
- jmp isright_dne ; We are done.
-left:
- dec scr_col ; Move the cursor left a character.
- jsr update_pos ; Update it's position.
- lda #1 ; Tell the escape routine that we succeded.
- sta d ;
- jmp isleft_done ; We are done
isshftup:
lda c ; Load the escape code back into the accumulator.
cmp #'A' ; Did the user press the up arrow key?
- bne shftup_done ;
+ bne @end ;
lda #1 ;
sta d ;
lda scr_str ;
- beq shftup_done ;
- jmp shftup ;
-shftup_done:
+ beq @end ;
+@shftup:
+ jsr scrl_up ;
+ lda #1 ;
+ sta d ;
+@end:
rts ;
+
isshftdown:
lda c ; Load the escape code back into the accumulator.
cmp #'B' ; Did the user press the down arrow key?
- bne shftdn_done ;
+ bne @end ;
lda #1 ;
sta d ;
lda scr_end ;
cmp #71 ;
- bcs shftdn_done ;
- jmp shftdown ;
-shftdn_done:
- rts ;
-
-shftup:
- jsr scrl_up ;
- lda #1 ;
- sta d ;
- jmp shftup_done ;
-
-shftdown:
+ bcs @end ;
+@shftdown:
jsr scrl_down ;
lda #1 ;
sta d ;
- jmp shftdn_done ;
+@end:
+ rts ;
+
update_pos:
ldb #1 ; Set the F pseudo register to one, to fix some bugs.
@@ -1074,7 +1075,7 @@ update_pos:
getrow:
lda scr_row ; Get the cursor's y coordinate.
- jmp bcd ; Convert it to BCD.
+ bra bcd ; Convert it to BCD.
getcol:
lda #';' ; Print ';'
sta scr ; to the screen.
@@ -1098,23 +1099,23 @@ scrl_down:
lda #'T' ; Print 'T'
sta scr ; to the screen, and end the escape sequence.
lda scr_row ; Get the cursor's line number.
- pha #1 ; Save it in the stack.
+ pha ; Save it in the stack.
lda wrapped ; Was the wrapped flag set?
beq @save ; Yes, so save the cursor position.
@redraw:
jsr rdrw_row ; No, so redraw this row.
lda wrapped ; Was the wrapped flag set?
beq @load ; Yes, so load the previous cursor position back.
- jmp @end ; No, so we're done.
+ bra @end ; No, so we're done.
@save:
lda scr_col ; Get the cursor's column number.
- pha #1 ; Save it in the stack.
- jmp @redraw ; Start redrawing the current row.
+ pha ; Save it in the stack.
+ bra @redraw ; Start redrawing the current row.
@load:
- pla #1 ; Get the cursor's previous column number back.
+ pla ; Get the cursor's previous column number back.
sta scr_col ;
@end:
- pla #1 ; Get the cursor's previous line number back.
+ pla ; Get the cursor's previous line number back.
sta scr_row ;
jsr update_pos ; Update the cursor's position.
lda #0 ; Clear the wrapped flag.
@@ -1132,15 +1133,15 @@ scrl_up:
lda #'S' ; Print 'S'
sta scr ; to the screen, and end the escape sequence.
lda scr_row ;
- pha #1 ;
+ pha ;
lda scr_col ;
- pha #1 ;
+ pha ;
lda #0 ;
sta scr_row ;
jsr rdrw_row ;
- pla #1 ;
+ pla ;
sta scr_col ;
- pla #1 ;
+ pla ;
sta scr_row ;
jsr update_pos ;
@end:
@@ -1164,11 +1165,11 @@ rdrw_row:
lda scr_col ;
cmp #maxcol+1 ;
bcs @end ;
- jmp @loop ;
+ bra @loop ;
@skip:
lda #' ' ;
sta scr ; to the screen.
- jmp @incr1 ;
+ bra @incr1 ;
@end:
lda #0 ;
sta scr_col ;
@@ -1178,11 +1179,11 @@ rdrw_row:
rdrw_ln:
lda scr_row ;
- pha #1 ;
+ pha ;
lda f ;
sta scr_row ;
lda scr_col ;
- pha #1 ;
+ pha ;
jsr update_pos ;
@loop:
lda scr_row ;
@@ -1193,11 +1194,11 @@ rdrw_ln:
jsr rdrw_row ;
@incr:
inc scr_row ;
- jmp @loop ;
+ bra @loop ;
@end:
- pla #1 ;
+ pla ;
sta scr_col ;
- pla #1 ;
+ pla ;
sta scr_row ;
jsr update_pos ;
lda #0 ;
@@ -1213,11 +1214,11 @@ set_ptr:
@ptr1:
stb.q ptr ; Reset the first pointer.
sta.q ptr ; No, so set the first pointer.
- jmp @end ; We are done.
+ bra @end ; We are done.
@ptr2:
stb.q ptr2 ; Reset the second pointer.
sta.q ptr2 ; Set the second pointer.
- jmp @end ; We are done.
+ bra @end ; We are done.
@ptr3:
stb.q ptr3 ; Reset the third pointer.
sta.q ptr3 ; Set the third pointer.
diff --git a/programs/sub-suite/utils.s b/programs/sub-suite/utils.s
index 580e4da..a66f036 100644
--- a/programs/sub-suite/utils.s
+++ b/programs/sub-suite/utils.s
@@ -42,22 +42,22 @@ print_lo:
sta idx3 ; Clear the string index.
@loop:
ldx #2 ; Set digit count to 2.
- pha #1 ; Preserve the nibble offset.
+ pha ; Preserve the nibble offset.
jsr print_hex ; Print the low nibble offset.
lda.w (ptr3) ; Get the two digits.
jsr charcpy ; Copy the first digit.
lsr #8 ; Copy the next digit.
jsr charcpy ;
- pla #1 ; Get the nibble offset back.
+ pla ; Get the nibble offset back.
inc ; Increment the offset.
cmp #$10 ; Are we at the last offset?
bcs @end ; Yes, so we're done.
@loop1:
- pha #1 ; No, so preserve the nibble offset.
+ pha ; No, so preserve the nibble offset.
lda #' ' ; Add a space to the string buffer.
jsr charcpy ;
- pla #1 ; Get the nibble offset back.
- jmp @loop ; Keep looping.
+ pla ; Get the nibble offset back.
+ bra @loop ; Keep looping.
@end:
inx ; Increment the index by one.
lda #0 ; Null terminate the string buffer.
@@ -69,7 +69,7 @@ print_lo:
print_chunk:
ldx #0 ; Reset X.
- phy #2 ; Preserve the screen buffer index.
+ phy.w ; Preserve the screen buffer index.
txy ; Copy the byte index to it.
@loop:
and #0 ; Reset A.
@@ -85,9 +85,9 @@ print_chunk:
beq @end ; Yes, so we're done.
lda #' ' ; No, so add a soace to the string buffer.
jsr charcpy ;
- jmp @loop ; Keep looping.
+ bra @loop ; Keep looping.
@end:
- ply #2 ; Get the screen buffer index back.
+ ply.w ; Get the screen buffer index back.
inx ; Increment the index by one.
and #0 ; Null terminate the string.
sta strbuf, x ;
@@ -97,7 +97,7 @@ print_chunk:
print_hex:
- pha #8 ; Preserve the hex value.
+ pha.q ; Preserve the hex value.
and #0 ; Reset A.
ldb #1 ; Set the second pointer
lda.w #hex_char ; to the start of hex character table.
@@ -108,37 +108,79 @@ print_hex:
adc #$10 ;
jsr set_ptr ;
ldb #0 ; Reset B.
- pla #8 ; Get the hex value back.
+ pla.q ; Get the hex value back.
@loop:
- pha #8 ; Preserve the hex value.
+ pha.q ; Preserve the hex value.
and #$F ; Mask the lowest nibble.
- phy #2 ; Preserve the screen buffer position.
+ phy.w ; Preserve the screen buffer position.
tay ; Get the index for the hex digit.
lda (ptr2), y ; Get the hex digit.
dec ptr3 ; Decrement the string pointer.
sta (ptr3) ; Save the hex digit character in the string.
- ply #2 ; Get back the screen buffer position.
- pla #8 ; Get the hex value back.
+ ply.w ; Get back the screen buffer position.
+ pla.q ; Get the hex value back.
@isauto:
cpx #1 ; Is the digit count less than one?
bcc @auto ; Yes, so don't decrement the digit count.
dex ; No, but was the digit count zero, when decremented?
beq @end ; Yes, so we're done.
- jmp @next ; No, so get the next nibble.
+ bra @next ; No, so get the next nibble.
@auto:
ldb #1 ; Enable auto digit count.
@next:
lsr #4 ; Is the next nibble, a zero?
beq @isauto1 ; Yes, so check if auto digit count is enabled.
- jmp @loop ; No, so print the next digit.
+ bra @loop ; No, so print the next digit.
@isauto1:
cpb #1 ; Is auto digit count enabled?
beq @end ; Yes, so we're done.
- jmp @loop ; No, so keep printing more digits.
+ bra @loop ; No, so keep printing more digits.
@end:
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.
@@ -152,16 +194,16 @@ strlen:
deb ; Reset B.
tba ; Reset A.
tax ; Reset X.
- phy #2 ; Preserve Y.
+ 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.
- jmp @loop ; Keep looping.
+ bra @loop ; Keep looping.
@end:
tyx ; Return the length in X.
- ply #2 ; Get the preserved value back.
+ ply.w ; Get the preserved value back.
rts ; End of strlen.
@@ -170,7 +212,7 @@ strcmp:
jsr set_ptr ; to the passed pointer.
deb ; Reset B.
tba ; Reset A.
- phy #2 ; Preserve Y.
+ phy.w ; Preserve Y.
tay ; Reset Y.
@loop:
ldb #0 ; Set the islong flag to false.
@@ -180,14 +222,14 @@ strcmp:
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.
- jmp @loop ; Keep looping.
+ 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 #2 ; Preserve Y.
+ phy.w ; Preserve Y.
tay ; Reset Y.
@loop:
ldb #0 ; Set the islong flag to false.
@@ -195,17 +237,17 @@ strcasecmp:
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 #1 ; Preserve the islong flag.
- pha #1 ; Preserve the converted character.
+ 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 #1 ; Get the character of string 1 back.
+ pla ; Get the character of string 1 back.
cab ; Is the character of both strings, the same?
- plb #1 ; Get the islong flag back.
+ 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.
- jmp @loop ; Keep looping.
+ bra @loop ; Keep looping.
cmpr:
lda (ptr2), y ; Are we at the end of the second string?
@@ -218,14 +260,14 @@ cmpr:
bne @equ ; No, so return 0.
@long:
lda #1 ; Yes, so return 1.
- jmp @end ; We are done.
+ bra @end ; We are done.
@equ:
lda #0 ; Return 0.
- jmp @end ; We are done.
+ bra @end ; We are done.
@short:
lda #$FF ; Return -1.
@end:
- ply #2 ; Get the preserved value back.
+ ply.w ; Get the preserved value back.
rts ; End of strcmp.
@@ -237,16 +279,16 @@ isdigit:
bcs @false ; No, so return false.
@true:
lda #1 ; Yes, so return true.
- jmp @end ; We are done.
+ bra @end ; We are done.
@false:
lda #0 ; Return false.
@end:
rts ; End of isdigit.
isxdigit:
- pha #1 ; Preserve the character.
+ pha ; Preserve the character.
jsr isdigit ; Is this character, a decimal digit?
- pla #1 ; Get the character back.
+ pla ; Get the character back.
bne @true ; Yes, so return true.
@alpha:
sec ; No, so prepare for a non carrying subtract.
@@ -257,7 +299,7 @@ isxdigit:
bcs @false ; No, so return false.
@true:
lda #1 ; Yes, so return true.
- jmp @end ; We are done.
+ bra @end ; We are done.
@false:
lda #0 ; Return false.
@end:
@@ -267,7 +309,7 @@ isxdigit:
isupper:
sec ; Prepare for a non carrying subtraction.
sbc #'A' ; Subtract $41 from the passed character.
- jmp isletter ; Check if it's less than 26.
+ 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.
@@ -277,7 +319,7 @@ isletter:
bcs @false ; No, so return false.
@true:
lda #1 ; Yes, so return true.
- jmp @end ; We are done.
+ bra @end ; We are done.
@false:
lda #0 ; Return false.
@end:
@@ -285,9 +327,9 @@ isletter:
tolower:
- pha #1 ; Preserve the character.
+ pha ; Preserve the character.
jsr isupper ; Is this character, an uppercase character?
- pla #1 ; Get the character back.
+ pla ; Get the character back.
beq @end ; No, so we're done.
@lower:
ora #$20 ; Yes, so convert it to lowercase.
@@ -296,9 +338,9 @@ tolower:
toupper:
- pha #1 ; Preserve the character.
+ pha ; Preserve the character.
jsr islower ; Is this character, a lowercase character?
- pla #1 ; Get the character back.
+ pla ; Get the character back.
beq @end ; No, so we're done.
@upper:
and #$5F ; Yes, so convert it to uppercase.
@@ -314,7 +356,7 @@ isdelm2:
cab ; Are they the same?
beq @r1 ; Yes, so return 1.
inx ; No, so increment the table index.
- jmp @loop ; Keep looping.
+ bra @loop ; Keep looping.
@other:
ldx #0 ; Reset X.
cmp #0 ; Is this a null terminator?
@@ -344,7 +386,7 @@ isdelm:
cab ; Are they the same?
beq @rshft ; Yes, so return 1 << index.
inx ; No, so increment the table index.
- jmp @loop ; Keep looping.
+ bra @loop ; Keep looping.
@other:
ldx #0 ; Reset X.
cmp #0 ; Is this a null terminator?
@@ -373,7 +415,7 @@ get_ptok:
cab ; Are they the same?
beq @rtab ; Yes, so return X.
inx ; No, so increment the table index.
- jmp @loop ; Keep looping.
+ bra @loop ; Keep looping.
@rtab:
txa ; Return X.
rts ; End of get_ptok.
diff --git a/sux.c b/sux.c
index a2fc04b..ae62304 100644
--- a/sux.c
+++ b/sux.c
@@ -146,6 +146,14 @@ void *run(void *args) {
if (optype[opcode] != IMPL) {
address.u64 = get_addr(cpu, &tmpaddr, opcode, prefix, thread);
setreg_sw(value.u8, 0, addr, address.u64, prefix, 0, RS);
+ if (optype[opcode] == REL) {
+ switch ((prefix >> 4) & 3) {
+ default: address.u64 = cpu->pc + (int8_t )value.u8[0] ; break;
+ case 1 : address.u64 = cpu->pc + (int16_t)value.u16[0]; break;
+ case 2 : address.u64 = cpu->pc + (int32_t)value.u32[0]; break;
+ case 3 : address.u64 = cpu->pc + (int64_t)value.u64 ; break;
+ }
+ }
#if getclk
++iclk;
#endif
@@ -165,123 +173,105 @@ void *run(void *args) {
#endif
#endif
switch(opcode) {
- case CPS: /* Clear Processor Status. */
+ case CPS_IMP: /* Clear Processor Status. */
cpu->ps.u64 = 0;
break;
- case AAB: /* Add Accumulator with carry by B register. */
+ case AAB_IMP: /* Add Accumulator with carry by B register. */
value.u64 = cpu->b; /* Falls Through. */
- case ADC: /* ADC Immediate. */
+ case ADC_IMM: /* ADC Immediate. */
case ADC_AB: /* ADC Absolute. */
case ADC_Z: /* ADC Zero Matrix. */
adc(cpu, value.u64, thread);
break;
- case PHP: push(cpu, value.u64, cpu->ps.u64, thread); break; /* PusH Processor status to stack. */
- case PHA: push(cpu, value.u64, cpu->a , thread); break; /* PusH Accumulator to stack. */
- case PHB: push(cpu, value.u64, cpu->b , thread); break; /* PusH B register to stack. */
- case PHY: push(cpu, value.u64, cpu->y , thread); break; /* PusH Y register to stack. */
- case PHX: push(cpu, value.u64, cpu->x , thread); break; /* PusH X register to stack. */
- case TAY: /* Transfer Accumulator to Y. */
- case TAX: /* Transfer Accumulator to Y. */
- case TYX: /* Transfer Y to X. */
- case TYA: /* Transfer Y to Accumulator. */
- case TXA: /* Transfer X to Accumulator. */
- case TXY: /* Transfer X to Y. */
- case TAB: /* Transfer Accumulator to B. */
- case TSX: /* Transfer Stack pointer to X. */
- case TBA: /* Transfer B to Accumulator. */
- case TXS: /* Transfer X to Stack pointer. */
+ case PHP_IMP: push(cpu, cpu->ps.u64, 0, thread); break; /* PusH Processor status to stack. */
+ case PHA_IMP: push(cpu, cpu->a , prefix, thread); break; /* PusH Accumulator to stack. */
+ case PHB_IMP: push(cpu, cpu->b , prefix, thread); break; /* PusH B register to stack. */
+ case PHY_IMP: push(cpu, cpu->y , prefix, thread); break; /* PusH Y register to stack. */
+ case PHX_IMP: push(cpu, cpu->x , prefix, thread); break; /* PusH X register to stack. */
+ case TAY_IMP: /* Transfer Accumulator to Y. */
+ case TAX_IMP: /* Transfer Accumulator to Y. */
+ case TYX_IMP: /* Transfer Y to X. */
+ case TYA_IMP: /* Transfer Y to Accumulator. */
+ case TXA_IMP: /* Transfer X to Accumulator. */
+ case TXY_IMP: /* Transfer X to Y. */
+ case TAB_IMP: /* Transfer Accumulator to B. */
+ case TSX_IMP: /* Transfer Stack pointer to X. */
+ case TBA_IMP: /* Transfer B to Accumulator. */
+ case TXS_IMM: /* Transfer X to Stack pointer. */
transfer(cpu, value.u64, opcode, prefix, thread);
break;
- case JMP: /* JMP Absolute. */
+ case BRA_REL: /* BRA Relative. */
+ case JMP_AB: /* JMP Absolute. */
case JMP_Z: /* JMP Zero Matrix. */
case JMP_IN: /* JMP Indirect. */
cpu->pc = address.u64;
break;
- case SAB: /* Subtract Accumulator with carry by B register. */
+ case SAB_IMP: /* Subtract Accumulator with carry by B register. */
value.u64 = cpu->b; /* Falls Through. */
- case SBC: /* SBC Immediate. */
+ case SBC_IMM: /* SBC Immediate. */
case SBC_AB: /* SBC Absolute. */
case SBC_Z: /* SBC Zero Matrix. */
sbc(cpu, value.u64, thread);
break;
- case PLP: cpu->ps.u64 = pull(cpu, value.u64, thread); break; /* PuLl Processor status from stack. */
- case PLA: cpu->a = pull(cpu, value.u64, thread); break; /* PuLl Accumulator from stack. */
- case PLB: cpu->b = pull(cpu, value.u64, thread); break; /* PuLl B register from stack. */
- case PLY: cpu->y = pull(cpu, value.u64, thread); break; /* PuLl Y register from stack. */
- case PLX: cpu->x = pull(cpu, value.u64, thread); break; /* PuLl X register from stack. */
+ case PLP_IMP: cpu->ps.u64 = pull(cpu, 0, thread); break; /* PuLl Processor status from stack. */
+ case PLA_IMP: cpu->a = pull(cpu, prefix, thread); break; /* PuLl Accumulator from stack. */
+ case PLB_IMP: cpu->b = pull(cpu, prefix, thread); break; /* PuLl B register from stack. */
+ case PLY_IMP: cpu->y = pull(cpu, prefix, thread); break; /* PuLl Y register from stack. */
+ case PLX_IMP: cpu->x = pull(cpu, prefix, thread); break; /* PuLl X register from stack. */
break;
- case ABA: /* bitwise And with Accumulator, and B register. */
+ case ABA_IMP: /* bitwise And with Accumulator, and B register. */
value.u64 = cpu->b; /* Falls Through. */
- case AND: /* AND Immediate. */
+ case AND_IMM: /* AND Immediate. */
case AND_AB: /* AND Absolute. */
case AND_Z: /* AND Zero Matrix. */
and(cpu, value.u64, thread);
break;
- case STT: /* STart Thread. */
- /*cpu->crt |= value;
- for (uint8_t i = 0; i < 7; i++) {
- if ((value >> i) & 1) {
- address = (uint64_t)addr[tv+(i<<3)]
- | (uint64_t)addr[tv+1+(i<<3)] << 8
- | (uint64_t)addr[tv+2+(i<<3)] << 16
- | (uint64_t)addr[tv+3+(i<<3)] << 24
- | (uint64_t)addr[tv+4+(i<<3)] << 32
- | (uint64_t)addr[tv+5+(i<<3)] << 40
- | (uint64_t)addr[tv+6+(i<<3)] << 48
- | (uint64_t)addr[tv+7+(i<<3)] << 56;
- cpu->pc[i+1] = address;
- }
- }*/
- break;
- case BPO: /* BPO Absolute. */
- case BPO_Z: /* BPO Zero Matrix. */
+ case BPO_REL: /* BPO Relative. */
if (!getflag(N)) {
cpu->pc = address.u64;
}
break;
- case OAB: /* bitwise Or with Accumulator, and B register. */
+ case OAB_IMP: /* bitwise Or with Accumulator, and B register. */
value.u64 = cpu->b; /* Falls Through. */
- case ORA: /* ORA Immediate. */
+ case ORA_IMM: /* ORA Immediate. */
case ORA_AB: /* ORA Absolute. */
case ORA_Z: /* ORA Zero Matrix. */
or(cpu, value.u64, thread);
break;
- case SEI: /* SEt Interrupt. */
+ case SEI_IMP: /* SEt Interrupt. */
setflag(1, I);
break;
- case BNG: /* BNG Absolute. */
- case BNG_Z: /* BNG Zero Matrix. */
+ case BNG_REL: /* BNG Relative. */
if (getflag(N)) {
cpu->pc = address.u64;
}
break;
- case XAB: /* bitwise Xor with Accumulator, and B register. */
+ case XAB_IMP: /* bitwise Xor with Accumulator, and B register. */
value.u64 = cpu->b; /* Falls Through. */
- case XOR: /* XOR Immediate. */
+ case XOR_IMM: /* XOR Immediate. */
case XOR_AB: /* XOR Absolute. */
case XOR_Z: /* XOR Zero Matrix. */
xor(cpu, value.u64, thread);
break;
- case CLI: /* CLear Interrupt. */
+ case CLI_IMP: /* CLear Interrupt. */
setflag(0, I);
break;
- case BCS: /* BCS Absolute. */
- case BCS_Z: /* BCS Zero Matrix. */
+ case BCS_REL: /* BCS Relative. */
if (getflag(C)) {
cpu->pc = address.u64;
}
break;
- case LLB: /* Logical shift Left accumulator by B. */
+ case LLB_IMP: /* Logical shift Left accumulator by B. */
value.u64 = cpu->b; /* Falls Through. */
- case LSL: /* LSL Immediate. */
+ case LSL_IMM: /* LSL Immediate. */
case LSL_AB: /* LSL Absolute. */
case LSL_Z: /* LSL Zero Matrix. */
lsl(cpu, value.u64, thread);
break;
- case SEC: /* SEt Carry flag.*/
+ case SEC_IMP: /* SEt Carry flag.*/
setflag(1, C);
break;
- case STA: /* STA Absolute. */
+ case STA_AB: /* STA Absolute. */
case STA_Z: /* STA Zero Matrix. */
case STA_ZX: /* STA Zero Matrix, Indexed with X. */
case STA_ZY: /* STA Zero Matrix, Indexed with Y. */
@@ -290,19 +280,17 @@ void *run(void *args) {
case STA_IY: /* STA Indirect Indexed. */
store(cpu, address.u64, cpu->a, prefix, thread);
break;
- case STY: /* STY Absolute. */
+ case STY_AB: /* STY Absolute. */
case STY_Z: /* STY Zero Matrix. */
- case STY_ZX: /* STY Zero Matrix, Indexed with X. */
case STY_IN: /* STY Indirect. */
store(cpu, address.u64, cpu->y, prefix, thread);
break;
- case STX: /* STX Absolute. */
+ case STX_AB: /* STX Absolute. */
case STX_Z: /* STX Zero Matrix. */
- case STX_ZY: /* STX Zero Matrix, Indexed with Y. */
case STX_IN: /* STX Indirect. */
store(cpu, address.u64, cpu->x, prefix, thread);
break;
- case STB: /* STB Absolute. */
+ case STB_AB: /* STB Absolute. */
case STB_Z: /* STB Zero Matrix. */
case STB_ZX: /* STB Zero Matrix, Indexed with X. */
case STB_ZY: /* STB Zero Matrix, Indexed with Y. */
@@ -311,30 +299,29 @@ void *run(void *args) {
case STB_IY: /* STB Indirect Indexed. */
store(cpu, address.u64, cpu->b, prefix, thread);
break;
- case BCC: /* BCC Absolute. */
- case BCC_Z: /* BCC Zero Matrix. */
+ case BCC_REL: /* BCC Relative. */
if (!getflag(C)) {
cpu->pc = address.u64;
}
break;
- case LRB: /* Logical shift Right accumulator by B. */
+ case LRB_IMP: /* Logical shift Right accumulator by B. */
value.u64 = cpu->b; /* Falls Through. */
- case LSR: /* LSR Immediate. */
+ case LSR_IMM: /* LSR Immediate. */
case LSR_AB: /* LSR Absolute. */
case LSR_Z: /* LSR Zero Matrix. */
lsr(cpu, value.u64, thread);
break;
- case ARB: /* Arithmetic shift Right accumulator by B. */
+ case ARB_IMP: /* Arithmetic shift Right accumulator by B. */
value.u64 = cpu->b; /* Falls Through. */
- case ASR: /* ASR Immediate. */
+ case ASR_IMM: /* ASR Immediate. */
case ASR_AB: /* ASR Absolute. */
case ASR_Z: /* ASR Zero Matrix. */
asr(cpu, value.u64, thread);
break;
- case CLC: /* CLear Carry flag. */
+ case CLC_IMP: /* CLear Carry flag. */
setflag(0, C);
break;
- case LDB: /* LDB Immediate. */
+ case LDB_IMM: /* LDB Immediate. */
case LDB_AB: /* LDB Absolute. */
case LDB_Z: /* LDB Zero Matrix. */
case LDB_ZX: /* LDB Zero Matrix, Indexed with X. */
@@ -344,7 +331,7 @@ void *run(void *args) {
case LDB_IY: /* LDB Indirect Indexed. */
cpu->b = load(cpu, address.u64, cpu->b, prefix, thread);
break;
- case LDA: /* LDA Immediate. */
+ case LDA_IMM: /* LDA Immediate. */
case LDA_AB: /* LDA Absolute. */
case LDA_Z: /* LDA Zero Matrix. */
case LDA_ZX: /* LDA Zero Matrix, Indexed with X. */
@@ -354,75 +341,69 @@ void *run(void *args) {
case LDA_IY: /* LDA Indirect Indexed. */
cpu->a = load(cpu, address.u64, cpu->a, prefix, thread);
break;
- case LDY: /* LDY Immediate. */
+ case LDY_IMM: /* LDY Immediate. */
case LDY_AB: /* LDY Absolute. */
case LDY_Z: /* LDY Zero Matrix. */
- case LDY_ZX: /* LDY Zero Matrix, Indexed with X. */
case LDY_IN: /* LDY Indirect. */
cpu->y = load(cpu, address.u64, cpu->y, prefix, thread);
break;
- case LDX: /* LDX Immediate. */
+ case LDX_IMM: /* LDX Immediate. */
case LDX_AB: /* LDX Absolute. */
case LDX_Z: /* LDX Zero Matrix. */
- case LDX_ZY: /* LDX Zero Matrix, Indexed with Y. */
case LDX_IN: /* LDX Indirect. */
cpu->x = load(cpu, address.u64, cpu->x, prefix, thread);
break;
- case BEQ: /* BEQ Absolute. */
- case BEQ_Z: /* BEQ Zero Matrix. */
+ case BEQ_REL: /* BEQ Relative. */
if (getflag(Z)) {
cpu->pc = address.u64;
}
break;
- case RLB: /* Rotate Left accumulator by B. */
+ case RLB_IMP: /* Rotate Left accumulator by B. */
value.u64 = cpu->b; /* Falls Through. */
- case ROL: /* ROL Immediate. */
+ case ROL_IMM: /* ROL Immediate. */
case ROL_AB: /* ROL Absolute. */
case ROL_Z: /* ROL Zero Matrix. */
rol(cpu, value.u64, thread);
break;
- case BNE: /* BNE Absolute. */
- case BNE_Z: /* BNE Zero Matrix. */
+ case BNE_REL: /* BNE Relative. */
if (!getflag(Z)) {
cpu->pc = address.u64;
}
break;
- case RRB: /* Rotate Right accumulator by B. */
+ case RRB_IMP: /* Rotate Right accumulator by B. */
value.u64 = cpu->b; /* Falls Through. */
- case ROR: /* ROR Immediate. */
+ case ROR_IMM: /* ROR Immediate. */
case ROR_AB: /* ROR Absolute. */
case ROR_Z: /* ROR Zero Matrix. */
ror(cpu, value.u64, thread);
break;
- case BVS: /* BVS Absolute. */
- case BVS_Z: /* BVS Zero Matrix. */
+ case BVS_REL: /* BVS Relative. */
if (getflag(V)) {
cpu->pc = address.u64;
}
break;
- case MAB: /* Multiply Accumulator by B. */
+ case MAB_IMP: /* Multiply Accumulator by B. */
value.u64 = cpu->b; /* Falls Through. */
- case MUL: /* MUL Immediate. */
+ case MUL_IMM: /* MUL Immediate. */
case MUL_AB: /* MUL Absolute. */
case MUL_Z: /* MUL Zero Matrix. */
mul(cpu, value.u64, thread);
break;
- case BVC: /* BVC Absolute. */
- case BVC_Z: /* BVC Zero Matrix. */
+ case BVC_REL: /* BVC Relative. */
if (!getflag(V)) {
cpu->pc = address.u64;
}
break;
- case DIV: /* DIV Immediate. */
- case DAB: /* Divide Accumulator by B. */
+ case DIV_IMM: /* DIV Immediate. */
+ case DAB_IMP: /* Divide Accumulator by B. */
case DIV_AB: /* DIV Absolute. */
case DIV_Z: /* DIV Zero Matrix. */
divd(cpu, value.u64, opcode, thread);
break;
- case CLV: /* CLear oVerflow flag. */
+ case CLV_IMP: /* CLear oVerflow flag. */
setflag(0, V);
break;
- case CPB: /* CPB Immediate. */
+ case CPB_IMM: /* CPB Immediate. */
case CPB_AB: /* CPB Absolute. */
case CPB_Z: /* CPB Zero Matrix. */
case CPB_IN: /* CPB Indirect. */
@@ -430,9 +411,9 @@ void *run(void *args) {
case CPB_IY: /* CPB Indirect Indexed. */
cmp(cpu, value.u64, cpu->b, thread);
break;
- case CAB: /* Compare Accumulator, and B. */
+ case CAB_IMP: /* Compare Accumulator, and B. */
value.u64 = cpu->b; /* Falls Through. */
- case CMP: /* CMP Immediate. */
+ case CMP_IMM: /* CMP Immediate. */
case CMP_AB: /* CMP Absolute. */
case CMP_Z: /* CMP Zero Matrix. */
case CMP_IN: /* CMP Indirect. */
@@ -440,34 +421,26 @@ void *run(void *args) {
case CMP_IY: /* CMP Indirect Indexed. */
cmp(cpu, value.u64, cpu->a, thread);
break;
- case CPY: /* CPY Immediate. */
+ case CPY_IMM: /* CPY Immediate. */
case CPY_AB: /* CPY Absolute. */
case CPY_Z: /* CPY Zero Matrix. */
- case CPY_IN: /* CPY Indirect. */
cmp(cpu, value.u64, cpu->y, thread);
break;
- case CPX: /* CPX Immediate. */
+ case CPX_IMM: /* CPX Immediate. */
case CPX_AB: /* CPX Absolute. */
case CPX_Z: /* CPX Zero Matrix. */
- case CPX_IN: /* CPX Indirect. */
cmp(cpu, value.u64, cpu->x, thread);
break;
- case ENT: /* ENd Thread. */
- /* cpu->crt &= ~value;
- for (uint8_t i = 0; i < 7; i++)
- if ((value >> i) & 1)
- cpu->pc[i+1] = cpu->pc[0]+(i+1);*/
- break;
- case INC: cpu->a = idr(cpu, cpu->a, 1, thread); break;
- case INB: cpu->b = idr(cpu, cpu->b, 1, thread); break;
- case INY: cpu->y = idr(cpu, cpu->y, 1, thread); break;
- case INX: cpu->x = idr(cpu, cpu->x, 1, thread); break;
- case DEC: cpu->a = idr(cpu, cpu->a, 0, thread); break;
- case DEB: cpu->b = idr(cpu, cpu->b, 0, thread); break;
- case DEY: cpu->y = idr(cpu, cpu->y, 0, thread); break;
- case DEX: cpu->x = idr(cpu, cpu->x, 0, thread); break;
+ case INC_IMP: cpu->a = idr(cpu, cpu->a, 1, thread); break;
+ case INB_IMP: cpu->b = idr(cpu, cpu->b, 1, thread); break;
+ case INY_IMP: cpu->y = idr(cpu, cpu->y, 1, thread); break;
+ case INX_IMP: cpu->x = idr(cpu, cpu->x, 1, thread); break;
+ case DEC_IMP: cpu->a = idr(cpu, cpu->a, 0, thread); break;
+ case DEB_IMP: cpu->b = idr(cpu, cpu->b, 0, thread); break;
+ case DEY_IMP: cpu->y = idr(cpu, cpu->y, 0, thread); break;
+ case DEX_IMP: cpu->x = idr(cpu, cpu->x, 0, thread); break;
case JSR_IN: /* JSR Indirect. */
- case JSR: /* Jump to SubRoutine. */
+ case JSR_AB: /* Jump to SubRoutine. */
case JSR_Z: /* JSR Zero Matrix. */
value.u64 = cpu->pc;
setreg(addr, -, (cpu->stk_st << 16)+cpu->sp, value.u8, +, 0, 7);
@@ -478,12 +451,12 @@ void *run(void *args) {
case INC_Z: /* INC Zero Matrix. */
idm(cpu, address.u64, prefix, 1, thread);
break;
- case NOP: /* No OPeration. */
+ case NOP_IMP: /* No OPeration. */
break;
- case RTI: /* ReTurn from Interrupt routine. */
+ case RTI_IMP: /* ReTurn from Interrupt routine. */
cpu->sp += 1;
cpu->ps.u8[thread] = addr[(cpu->stk_st << 16)+(cpu->sp)]; /* Falls through. */
- case RTS: /* ReTurn from Subroutine. */
+ case RTS_IMP: /* ReTurn from Subroutine. */
cpu->sp += 8;
setreg(value.u8, +, 0, addr, -, (cpu->stk_st << 16)+cpu->sp, 7);
cpu->pc = value.u64;
@@ -492,9 +465,9 @@ void *run(void *args) {
case DEC_Z: /* DEC Zero Matrix. */
idm(cpu, address.u64, prefix, 0, thread);
break;
- case BRK: /* BReaK. */
- case WAI: /* WAit for Interrupt. */
- if (opcode == WAI) {
+ case BRK_IMP: /* BReaK. */
+ case WAI_IMP: /* WAit for Interrupt. */
+ if (opcode == WAI_IMP) {
pthread_mutex_lock(&main_mutex);
pthread_cond_signal(&main_cond);
pthread_mutex_unlock(&main_mutex);
@@ -508,7 +481,7 @@ void *run(void *args) {
cpu->sp -= 9;
setflag(1, I);
setreg(value.u8, +, 0, addr, +, (opcode == BRK) ? 0xFFE0 : 0xFFA0, 7);
- if (opcode == WAI) {
+ if (opcode == WAI_IMP) {
kbd_rdy &= (uint8_t)~(1 << thread);
}
cpu->pc = value.u64;
diff --git a/sux.h b/sux.h
index 84cc3a6..77736c4 100644
--- a/sux.h
+++ b/sux.h
@@ -43,6 +43,8 @@ static inline uint64_t get_addr(struct sux *cpu, uint64_t *tmpaddr, uint8_t opco
union reg address;
union reg value;
uint8_t tmp = 0;
+ uint64_t tmp2 = 0;
+ union reg saveaddr;
address.u64 = 0;
value.u64 = 0;
switch (optype[opcode]) {
@@ -51,25 +53,13 @@ static inline uint64_t get_addr(struct sux *cpu, uint64_t *tmpaddr, uint8_t opco
case IMM:
address.u64 = cpu->pc;
switch (opcode) {
- case PHB:
- case PHP:
- case PHA:
- case PHY:
- case PHX:
- case PLB:
- case PLP:
- case PLA:
- case PLY:
- case PLX:
- case STT:
- case LSL:
- case LSR:
- case ROL:
- case ROR:
- case ASR:
- case ENT: ++cpu->pc; break;
- default : cpu->pc+=(1 << (prefix >> 4)); /* Falls Through. */
- case TXS: break;
+ case LSL_IMM:
+ case LSR_IMM:
+ case ROL_IMM:
+ case ROR_IMM:
+ case ASR_IMM: ++cpu->pc; break;
+ default : cpu->pc+=(1 << ((prefix >> 4) & 3)); /* Falls Through. */
+ case TXS_IMM: break;
}
break;
case ZM:
@@ -83,6 +73,7 @@ static inline uint64_t get_addr(struct sux *cpu, uint64_t *tmpaddr, uint8_t opco
/* Unroll Loop by implementing Duff's Device. */
tmp = get_addrsize(prefix, ZM)+1;
setreg_sw(address.u8, 0, addr, cpu->pc, prefix, ZM, AM);
+
cpu->pc+=tmp;
#if debug && !bench
*tmpaddr = address.u64;
@@ -91,6 +82,21 @@ static inline uint64_t get_addr(struct sux *cpu, uint64_t *tmpaddr, uint8_t opco
iclk++;
#endif
uint64_t reg = 0;
+ saveaddr.u64 = 0;
+ if (prefix >> 6) {
+ switch (prefix >> 6) {
+ case 1: tmp2 = ((cpu->stk_st << 16) | cpu->sp); break;
+ case 2: tmp2 = cpu->pc ; break;
+ }
+ saveaddr = address;
+ switch ((prefix & 0x0C) >> 2) {
+ case 0: saveaddr.u64 = tmp2 + (int8_t )address.u8[0] ; break;
+ case 2: saveaddr.u64 = tmp2 + (int64_t)address.u64 ; break;
+ case 1:
+ case 3: saveaddr.u64 = tmp2 + (int32_t)address.u32[0]; break;
+ }
+ (optype[opcode] != INDY) ? (address.u64 = saveaddr.u64) : (reg = saveaddr.u64);
+ }
switch (optype[opcode]) {
case ZMX:
address.u64 += cpu->x;
@@ -112,7 +118,7 @@ static inline uint64_t get_addr(struct sux *cpu, uint64_t *tmpaddr, uint8_t opco
iclk++;
#endif
} else {
- reg = cpu->y;
+ reg += cpu->y;
#if getclk
iclk++;
#endif
@@ -134,6 +140,25 @@ static inline uint64_t get_addr(struct sux *cpu, uint64_t *tmpaddr, uint8_t opco
#if getclk
iclk++;
#endif
+ saveaddr.u64 = 0;
+ if (prefix >> 6) {
+ switch (prefix >> 6) {
+ case 1: tmp2 = ((cpu->stk_st << 16) | cpu->sp); break;
+ case 2: tmp2 = cpu->pc ; break;
+ }
+ saveaddr = address;
+ switch ((prefix & 0x0C) >> 2) {
+ case 0: saveaddr.u64 = tmp2 + (int16_t)address.u16[0]; break;
+ case 1:
+ case 2:
+ case 3: saveaddr.u64 = tmp2 + (int64_t)address.u64 ; break;
+ }
+ address.u64 = saveaddr.u64;
+ }
+ break;
+ case REL:
+ address.u64 = cpu->pc;
+ cpu->pc+=(1 << ((prefix >> 4) & 3));
break;
}
@@ -160,16 +185,16 @@ static inline void sbc(struct sux *cpu, uint64_t value, uint8_t thread) {
static inline void transfer(struct sux *cpu, uint64_t value, uint8_t opcode, uint8_t prefix, uint8_t thread) {
uint64_t reg;
switch (opcode) {
- case TBA: cpu->a = cpu->b; reg = cpu->a; break;
- case TXA: cpu->a = cpu->x; reg = cpu->a; break;
- case TYA: cpu->a = cpu->y; reg = cpu->a; break;
- case TAB: cpu->b = cpu->a; reg = cpu->b; break;
- case TAY: cpu->y = cpu->a; reg = cpu->y; break;
- case TXY: cpu->y = cpu->x; reg = cpu->y; break;
- case TAX: cpu->x = cpu->a; reg = cpu->x; break;
- case TYX: cpu->x = cpu->y; reg = cpu->x; break;
- case TSX: cpu->x = cpu->sp & 0xFFFF; cpu->x = cpu->stk_st << 16; break;
- case TXS: cpu->sp = cpu->x;
+ case TBA_IMP: cpu->a = cpu->b; reg = cpu->a; break;
+ case TXA_IMP: cpu->a = cpu->x; reg = cpu->a; break;
+ case TYA_IMP: cpu->a = cpu->y; reg = cpu->a; break;
+ case TAB_IMP: cpu->b = cpu->a; reg = cpu->b; break;
+ case TAY_IMP: cpu->y = cpu->a; reg = cpu->y; break;
+ case TXY_IMP: cpu->y = cpu->x; reg = cpu->y; break;
+ case TAX_IMP: cpu->x = cpu->a; reg = cpu->x; break;
+ case TYX_IMP: cpu->x = cpu->y; reg = cpu->x; break;
+ case TSX_IMP: cpu->x = cpu->sp & 0xFFFF; cpu->x = cpu->stk_st << 16; break;
+ case TXS_IMM: cpu->sp = cpu->x;
if (prefix == 0x13 && (value == thread+1 || value > 8)) {
cpu->stk_st = value & 0xFF;
cpu->stk_st += value << 16;
@@ -181,22 +206,18 @@ static inline void transfer(struct sux *cpu, uint64_t value, uint8_t opcode, uin
setflag(reg >> 63, N);
}
-static inline void push(struct sux *cpu, uint64_t size, uint64_t value, uint8_t thread) {
+static inline void push(struct sux *cpu, uint64_t value, uint8_t prefix, uint8_t thread) {
union reg reg;
reg.u64 = value;
- size = (size > 0) ? size-1 : 0;
- uint8_t tmp = (size <= 7) ? size : 7;
- setreg(addr, -, (cpu->stk_st << 16)+cpu->sp, reg.u8, +, 0, tmp);
- cpu->sp -= (tmp+1);
+ setreg(addr, -, (cpu->stk_st << 16)+cpu->sp, reg.u8, +, 0, (1 << ((prefix >> 4) & 3))-1);
+ cpu->sp -= (1 << ((prefix >> 4) & 3));
}
-static inline uint64_t pull(struct sux *cpu, uint64_t size, uint8_t thread) {
+static inline uint64_t pull(struct sux *cpu, uint8_t prefix, uint8_t thread) {
union reg reg;
reg.u64 = 0;
- size = (size > 0) ? size-1 : 0;
- uint8_t tmp = (size <= 7) ? size : 7;
- cpu->sp += (tmp+1);
- setreg(reg.u8, +, 0, addr, -, (cpu->stk_st << 16)+cpu->sp, tmp);
+ cpu->sp += (1 << ((prefix >> 4) & 3));
+ setreg(reg.u8, +, 0, addr, -, (cpu->stk_st << 16)+cpu->sp, (1 << ((prefix >> 4) & 3))-1);
return reg.u64;
}
@@ -268,7 +289,7 @@ static inline void mul(struct sux *cpu, uint64_t value, uint8_t thread) {
static inline void divd(struct sux *cpu, uint64_t value, uint8_t opcode, uint8_t thread) {
uint64_t sum = cpu->a/value;
- if (opcode != DAB) {
+ if (opcode != DAB_IMP) {
cpu->b = cpu->a % value;
} else {
value = cpu->b;
diff --git a/tables.h b/tables.h
index 45c0910..0c955dd 100644
--- a/tables.h
+++ b/tables.h
@@ -1,188 +1,173 @@
#include "enums.h"
static const uint8_t optype[0x100] = {
- [CPS ] = IMPL,
- [ADC ] = IMM,
- [AAB ] = IMPL,
- [ADC_AB ] = ABS,
- [LDA_IN ] = IND,
- [ADC_Z ] = ZM,
- [PHP ] = IMM,
- [CPB ] = IMM,
- [PHB ] = IMM,
- [DEC_AB ] = ABS,
- [DEC_Z ] = ZM,
- [JMP_Z ] = ZM,
- [JMP ] = ABS,
- [SBC ] = IMM,
- [SAB ] = IMPL,
- [SBC_AB ] = ABS,
- [STA_IN ] = IND,
- [SBC_Z ] = ZM,
- [ENT ] = IMM,
- [CPY ] = IMM,
- [PLB ] = IMM,
- [INC_AB ] = ABS,
- [INC_Z ] = ZM,
- [JSR_Z ] = ZM,
- [JSR ] = ABS,
- [AND ] = IMM,
- [ABA ] = IMPL,
- [AND_AB ] = ABS,
- [CMP_IN ] = IND,
- [AND_Z ] = ZM,
- [PLP ] = IMM,
- [CPX ] = IMM,
- [PHY ] = IMM,
- [CPB_AB ] = ABS,
- [CPB_Z ] = ZM,
- [BPO_Z ] = ZM,
- [BPO ] = ABS,
- [ORA ] = IMM,
- [OAB ] = IMPL,
- [ORA_AB ] = ABS,
- [LDB_IN ] = IND,
- [ORA_Z ] = ZM,
- [STT ] = IMM,
- [LDA_ZY ] = ZMY,
- [PLY ] = IMM,
- [CPX_AB ] = ABS,
- [CPY_Z ] = ZM,
- [BNG_Z ] = ZM,
- [BNG ] = ABS,
- [XOR ] = IMM,
- [XAB ] = IMPL,
- [XOR_AB ] = ABS,
- [STB_IN ] = IND,
- [XOR_Z ] = ZM,
- [PHA ] = IMM,
- [STA_ZY ] = ZMY,
- [PHX ] = IMM,
- [CPY_AB ] = ABS,
- [CPX_Z ] = ZM,
- [BCS_Z ] = ZM,
- [BCS ] = ABS,
- [LSL ] = IMM,
- [LLB ] = IMPL,
- [LSL_AB ] = ABS,
- [CPB_IN ] = IND,
- [LSL_Z ] = ZM,
- [CLC ] = IMPL,
- [LDB_ZY ] = ZMY,
- [PLX ] = IMM,
- [LDA_IY ] = INDY,
- [LDA_IX ] = INDX,
- [BCC_Z ] = ZM,
- [BCC ] = ABS,
- [LSR ] = IMM,
- [LRB ] = IMPL,
- [LSR_AB ] = ABS,
- [LDY_IN ] = IND,
- [LSR_Z ] = ZM,
- [PLA ] = IMM,
- [STB_ZY ] = ZMY,
- [TAB ] = IMPL,
- [STA_IY ] = INDY,
- [STA_IX ] = INDX,
- [BEQ_Z ] = ZM,
- [BEQ ] = ABS,
- [ROL ] = IMM,
- [RLB ] = IMPL,
- [ROL_AB ] = ABS,
- [STY_IN ] = IND,
- [ROL_Z ] = ZM,
- [SEC ] = IMPL,
- [LDA_ZX ] = ZMX,
- [TBA ] = IMPL,
- [CMP_IY ] = INDY,
- [CMP_IX ] = INDX,
- [BNE_Z ] = ZM,
- [BNE ] = ABS,
- [ROR ] = IMM,
- [RRB ] = IMPL,
- [ROR_AB ] = ABS,
- [CPY_IN ] = IND,
- [ROR_Z ] = ZM,
- [DEY ] = IMPL,
- [STA_ZX ] = ZMX,
- [TAY ] = IMPL,
- [LDB_IY ] = INDY,
- [LDB_IX ] = INDX,
- [BVS_Z ] = ZM,
- [BVS ] = ABS,
- [MUL ] = IMM,
- [MAB ] = IMPL,
- [MUL_AB ] = ABS,
- [LDX_IN ] = IND,
- [MUL_Z ] = ZM,
- [CLI ] = IMPL,
- [LDB_ZX ] = ZMX,
- [TYA ] = IMPL,
- [STB_IY ] = INDY,
- [STB_IX ] = INDX,
- [BVC_Z ] = ZM,
- [BVC ] = ABS,
- [DIV ] = IMM,
- [DAB ] = IMPL,
- [DIV_AB ] = ABS,
- [STX_IN ] = IND,
- [DIV_Z ] = ZM,
- [INY ] = IMPL,
- [STB_ZX ] = ZMX,
- [TAX ] = IMPL,
- [CPB_IY ] = INDY,
- [CPB_IX ] = INDX,
- [RTS ] = IMPL,
- [CMP ] = IMM,
- [CAB ] = IMPL,
- [CMP_AB ] = ABS,
- [CPX_IN ] = IND,
- [CMP_Z ] = ZM,
- [SEI ] = IMPL,
- [LDX ] = IMM,
- [TXA ] = IMPL,
- [LDX_AB ] = ABS,
- [LDX_Z ] = ZM,
- [JSR_IN ] = IND,
- [RTI ] = IMPL,
- [LDA ] = IMM,
- [LDA_AB ] = ABS,
- [DEX ] = IMPL,
- [LDA_Z ] = ZM,
- [CLV ] = IMPL,
- [LDX_ZY ] = ZMY,
- [TYX ] = IMPL,
- [STA ] = ABS,
- [STA_Z ] = ZM,
- [JMP_IN ] = IND,
- [TSX ] = IMPL,
- [LDB ] = IMM,
- [LDB_AB ] = ABS,
- [INX ] = IMPL,
- [LDB_Z ] = ZM,
- [WAI ] = IMPL,
- [STX_ZY ] = ZMY,
- [TXY ] = IMPL,
- [STB ] = ABS,
- [STB_Z ] = ZM,
- [TXS ] = IMM,
- [LDY ] = IMM,
- [LDY_AB ] = ABS,
- [DEC ] = IMPL,
- [LDY_Z ] = ZM,
- [BRK ] = IMPL,
- [LDY_ZX ] = ZMX,
- [NOP ] = IMPL,
- [STY ] = ABS,
- [STY_Z ] = ZM,
- [DEB ] = IMPL,
- [ASR ] = IMM,
- [ARB ] = IMPL,
- [ASR_AB ] = ABS,
- [INC ] = IMPL,
- [ASR_Z ] = ZM,
- [STY_ZX ] = ZMX,
- [STX ] = ABS,
- [STX_Z ] = ZM,
- [INB ] = IMPL
+ [CPS_IMP ] = IMPL,
+ [ADC_IMM ] = IMM,
+ [AAB_IMP ] = IMPL,
+ [ADC_AB ] = ABS,
+ [LDA_IN ] = IND,
+ [ADC_Z ] = ZM,
+ [CLC_IMP ] = IMPL,
+ [DEX_IMP ] = IMPL,
+ [DEC_IMP ] = IMPL,
+ [DEC_AB ] = ABS,
+ [DEC_Z ] = ZM,
+ [JMP_AB ] = ABS,
+ [SBC_IMM ] = IMM,
+ [SAB_IMP ] = IMPL,
+ [SBC_AB ] = ABS,
+ [STA_IN ] = IND,
+ [SBC_Z ] = ZM,
+ [SEC_IMP ] = IMPL,
+ [INX_IMP ] = IMPL,
+ [INC_IMP ] = IMPL,
+ [INC_AB ] = ABS,
+ [INC_Z ] = ZM,
+ [JSR_AB ] = ABS,
+ [AND_IMM ] = IMM,
+ [ABA_IMP ] = IMPL,
+ [AND_AB ] = ABS,
+ [CMP_IN ] = IND,
+ [AND_Z ] = ZM,
+ [CLI_IMP ] = IMPL,
+ [DEY_IMP ] = IMPL,
+ [CPB_IMM ] = IMM,
+ [CPB_AB ] = ABS,
+ [CPB_Z ] = ZM,
+ [JMP_Z ] = ZM,
+ [ORA_IMM ] = IMM,
+ [OAB_IMP ] = IMPL,
+ [ORA_AB ] = ABS,
+ [LDB_IN ] = IND,
+ [ORA_Z ] = ZM,
+ [SEI_IMP ] = IMPL,
+ [INY_IMP ] = IMPL,
+ [CPX_IMM ] = IMM,
+ [CPX_AB ] = ABS,
+ [CPY_Z ] = ZM,
+ [JSR_Z ] = ZM,
+ [XOR_IMM ] = IMM,
+ [XAB_IMP ] = IMPL,
+ [XOR_AB ] = ABS,
+ [STB_IN ] = IND,
+ [XOR_Z ] = ZM,
+ [CLV_IMP ] = IMPL,
+ [CPY_IMM ] = IMM,
+ [CPY_AB ] = ABS,
+ [CPX_Z ] = ZM,
+ [BPO_REL ] = REL,
+ [LSL_IMM ] = IMM,
+ [LLB_IMP ] = IMPL,
+ [LSL_AB ] = ABS,
+ [CPB_IN ] = IND,
+ [LSL_Z ] = ZM,
+ [WAI_IMP ] = IMPL,
+ [PHP_IMP ] = IMPL,
+ [TAB_IMP ] = IMPL,
+ [LDA_IY ] = INDY,
+ [LDA_IX ] = INDX,
+ [BNG_REL ] = REL,
+ [LSR_IMM ] = IMM,
+ [LRB_IMP ] = IMPL,
+ [LSR_AB ] = ABS,
+ [LDY_IN ] = IND,
+ [LSR_Z ] = ZM,
+ [BRK_IMP ] = IMPL,
+ [PLP_IMP ] = IMPL,
+ [TBA_IMP ] = IMPL,
+ [STA_IY ] = INDY,
+ [STA_IX ] = INDX,
+ [BCS_REL ] = REL,
+ [ROL_IMM ] = IMM,
+ [RLB_IMP ] = IMPL,
+ [ROL_AB ] = ABS,
+ [STY_IN ] = IND,
+ [ROL_Z ] = ZM,
+ [LDA_ZY ] = ZMY,
+ [PHA_IMP ] = IMPL,
+ [TAY_IMP ] = IMPL,
+ [CMP_IY ] = INDY,
+ [CMP_IX ] = INDX,
+ [BCC_REL ] = REL,
+ [ROR_IMM ] = IMM,
+ [RRB_IMP ] = IMPL,
+ [ROR_AB ] = ABS,
+ [LDX_IN ] = IND,
+ [ROR_Z ] = ZM,
+ [STA_ZY ] = ZMY,
+ [PLA_IMP ] = IMPL,
+ [TYA_IMP ] = IMPL,
+ [LDB_IY ] = INDY,
+ [LDB_IX ] = INDX,
+ [BEQ_REL ] = REL,
+ [MUL_IMM ] = IMM,
+ [MAB_IMP ] = IMPL,
+ [MUL_AB ] = ABS,
+ [STX_IN ] = IND,
+ [MUL_Z ] = ZM,
+ [LDB_ZY ] = ZMY,
+ [PHB_IMP ] = IMPL,
+ [TAX_IMP ] = IMPL,
+ [STB_IY ] = INDY,
+ [STB_IX ] = INDX,
+ [BNE_REL ] = REL,
+ [DIV_IMM ] = IMM,
+ [DAB_IMP ] = IMPL,
+ [DIV_AB ] = ABS,
+ [JSR_IN ] = IND,
+ [DIV_Z ] = ZM,
+ [STB_ZY ] = ZMY,
+ [PLB_IMP ] = IMPL,
+ [TXA_IMP ] = IMPL,
+ [CPB_IY ] = INDY,
+ [CPB_IX ] = INDX,
+ [BVS_REL ] = REL,
+ [CMP_IMM ] = IMM,
+ [CAB_IMP ] = IMPL,
+ [CMP_AB ] = ABS,
+ [JMP_IN ] = IND,
+ [CMP_Z ] = ZM,
+ [LDA_ZX ] = ZMX,
+ [LDX_IMM ] = IMM,
+ [TYX_IMP ] = IMPL,
+ [LDX_AB ] = ABS,
+ [LDX_Z ] = ZM,
+ [BVC_REL ] = REL,
+ [LDA_IMM ] = IMM,
+ [DEB_IMP ] = IMPL,
+ [LDA_AB ] = ABS,
+ [LDA_Z ] = ZM,
+ [STA_ZX ] = ZMX,
+ [PHY_IMP ] = IMPL,
+ [TXY_IMP ] = IMPL,
+ [STA_AB ] = ABS,
+ [STA_Z ] = ZM,
+ [BRA_REL ] = REL,
+ [LDB_IMM ] = IMM,
+ [INB_IMP ] = IMPL,
+ [LDB_AB ] = ABS,
+ [LDB_Z ] = ZM,
+ [LDB_ZX ] = ZMX,
+ [PLY_IMP ] = IMPL,
+ [TSX_IMP ] = IMPL,
+ [STB_AB ] = ABS,
+ [STB_Z ] = ZM,
+ [RTS_IMP ] = IMPL,
+ [LDY_IMM ] = IMM,
+ [LDY_AB ] = ABS,
+ [LDY_Z ] = ZM,
+ [STB_ZX ] = ZMX,
+ [PHX_IMP ] = IMPL,
+ [NOP_IMP ] = IMPL,
+ [STY_AB ] = ABS,
+ [STY_Z ] = ZM,
+ [RTI_IMP ] = IMPL,
+ [ASR_IMM ] = IMM,
+ [ARB_IMP ] = IMPL,
+ [ASR_AB ] = ABS,
+ [ASR_Z ] = ZM,
+ [PLX_IMP ] = IMPL,
+ [TXS_IMM ] = IMM,
+ [STX_AB ] = ABS,
+ [STX_Z ] = ZM
};
diff --git a/test/stack-frame.s b/test/stack-frame.s
new file mode 100644
index 0000000..6e64b86
--- /dev/null
+++ b/test/stack-frame.s
@@ -0,0 +1,32 @@
+; Testing stack frames.
+; Written by mr b0nk 500 <b0nk@b0nk.xyz>
+
+.org $8000
+reset:
+ cps ;
+ ldx.w #$FFFF ;
+ txs ;
+ lda #0 ;
+ tay ;
+ tax ;
+ tab ;
+start:
+ inc ;
+ pha ;
+ ldb sp, $1 ;
+ pla ;
+ sta $0 ;
+ phy.q ;
+ ldb (sp, $8) ;
+ ply.q ;
+ ldb (sp, -$8) ;
+ bra start ;
+
+.org $FFC0
+.qword reset
+a
+;.org reset
+;v
+;q
+d
+