diff options
-rw-r--r-- | Makefile | 10 | ||||
-rw-r--r-- | asmmon.h | 572 | ||||
-rw-r--r-- | assemble.c | 129 | ||||
-rw-r--r-- | csv-parse.c | 113 | ||||
-rw-r--r-- | csv-parse.h | 32 | ||||
-rw-r--r-- | disasm.c | 73 | ||||
-rw-r--r-- | disasm.h | 353 | ||||
-rw-r--r-- | enums.h | 490 | ||||
-rw-r--r-- | lexer.c | 28 | ||||
-rw-r--r-- | lexer.h | 2 | ||||
-rw-r--r-- | opcode-gen.c | 505 | ||||
-rw-r--r-- | opcode.h | 4 | ||||
-rw-r--r-- | programs/sub-suite/lexer.s | 180 | ||||
-rw-r--r-- | programs/sub-suite/subasm.s | 34 | ||||
-rw-r--r-- | programs/sub-suite/subeditor.s | 405 | ||||
-rw-r--r-- | programs/sub-suite/utils.s | 130 | ||||
-rw-r--r-- | sux.c | 221 | ||||
-rw-r--r-- | sux.h | 103 | ||||
-rw-r--r-- | tables.h | 353 | ||||
-rw-r--r-- | test/stack-frame.s | 32 |
20 files changed, 2400 insertions, 1369 deletions
@@ -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 : @@ -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] = { @@ -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(); @@ -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++) { @@ -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" }; @@ -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. */ -}; @@ -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] = '@'; @@ -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; +} @@ -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. @@ -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; @@ -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; @@ -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 + |