diff options
author | mrb0nk500 <b0nk@b0nk.xyz> | 2019-12-24 22:18:32 -0500 |
---|---|---|
committer | mrb0nk500 <b0nk@b0nk.xyz> | 2019-12-24 22:18:32 -0500 |
commit | 1dfc78b8bf5b708cb1118a9d6646397772a1b894 (patch) | |
tree | f3e9a0a87c4aa5a13a773fc1046a6d17fb4631f4 | |
parent | cd08c7e030dd269ffd0d3bdb6170e15998c796ec (diff) |
Added support for Indirect addressing modes, and allow
for use of the B register as an operand, for ALU based
instructions.
This allows for both low code size, and high
performance.
This means we can save upto 9 bytes, by just using
the B register for ALU operations, rather than using a
memory address.
The indirect addressing modes, give Sux the abillity
to now use pointers.
Hope you guys have a Merry Christmas!
From mr b0nk 500 <b0nk@b0nk.xyz>
-rw-r--r-- | asmmon.c | 357 | ||||
-rw-r--r-- | opcode.h | 348 | ||||
-rw-r--r-- | programs/subasm.s | 232 | ||||
-rw-r--r-- | sux.c | 1264 | ||||
-rw-r--r-- | test/input.s | 45 |
5 files changed, 1354 insertions, 892 deletions
@@ -4,11 +4,12 @@ #define debug 1 -#define OPNUM 91 -#define SETOP(num, _mne, _IMM, _ZM, _ZMX, _ZMY, _ABS, _IMPL) \ +#define OPNUM 93 +#define SETOP(num, _mne, _IMM, _ZM, _ZMX, _ZMY, _IND, _INX, _INY, _ABS, _IMPL) \ {opcodes[num].mnemonic[3] = '\0'; strncpy(opcodes[num].mnemonic, _mne, 3); \ opcodes[num].imm = _IMM; \ opcodes[num].zm = _ZM; opcodes[num].zmx = _ZMX; opcodes[num].zmy = _ZMY; \ +opcodes[num].ind = _IND; opcodes[num].inx = _INX; opcodes[num].iny = _INY; \ opcodes[num].abs = _ABS; opcodes[num].impl = _IMPL;} @@ -125,98 +126,100 @@ void viewmem(uint64_t address) { } int asmmon(const char *fn) { opent opcodes[OPNUM]; - /* mne IMM ZM ZMX ZMY ABS IMPL*/ - SETOP(0, "CPS", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); - SETOP(1, "ADC", 0x01, 0x05, 0x00, 0x00, 0x03, 0x00); - SETOP(2, "PHP", 0x08, 0x00, 0x00, 0x00, 0x00, 0x00); - SETOP(3, "PHA", 0x09, 0x00, 0x00, 0x00, 0x00, 0x00); - SETOP(4, "PHY", 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00); - SETOP(5, "TAY", 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B); - SETOP(6, "PHX", 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00); - SETOP(7, "TAX", 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D); - SETOP(8, "TYX", 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E); - SETOP(9, "JMP", 0x00, 0xD0, 0x00, 0x00, 0x10, 0x00); - SETOP(10, "SBC", 0x11, 0x15, 0x00, 0x00, 0x13, 0x00); - SETOP(11, "PLP", 0x18, 0x00, 0x00, 0x00, 0x00, 0x00); - SETOP(12, "PLA", 0x19, 0x00, 0x00, 0x00, 0x00, 0x00); - SETOP(13, "PLY", 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00); - SETOP(14, "TYA", 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B); - SETOP(15, "PLX", 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00); - SETOP(16, "TXA", 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D); - SETOP(17, "TXY", 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E); - SETOP(18, "JSR", 0x00, 0x20, 0x00, 0x00, 0x00, 0x00); - SETOP(19, "AND", 0x21, 0x2B, 0x00, 0x00, 0x29, 0x00); - SETOP(20, "ANY", 0x22, 0x82, 0x00, 0x00, 0x52, 0x00); - SETOP(21, "AAY", 0x00, 0x00, 0x00, 0x00, 0x00, 0x23); - SETOP(22, "ANX", 0x24, 0x84, 0x00, 0x00, 0x54, 0x00); - SETOP(23, "AAX", 0x00, 0x00, 0x00, 0x00, 0x00, 0x25); - SETOP(24, "STT", 0x28, 0x00, 0x00, 0x00, 0x00, 0x00); - SETOP(25, "TAB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x2C); - SETOP(26, "TSX", 0x00, 0x00, 0x00, 0x00, 0x00, 0x2E); - SETOP(27, "BPO", 0x00, 0x00, 0x00, 0x00, 0x30, 0x00); - SETOP(28, "ORA", 0x31, 0x3B, 0x00, 0x00, 0x39, 0x00); - SETOP(29, "ORY", 0x32, 0x00, 0x00, 0x00, 0x62, 0x00); - SETOP(23, "OAY", 0x00, 0x00, 0x00, 0x00, 0x00, 0x33); - SETOP(31, "ORX", 0x34, 0x94, 0x00, 0x00, 0x64, 0x00); - SETOP(32, "OAX", 0x00, 0x00, 0x00, 0x00, 0x00, 0x35); - SETOP(33, "SEI", 0x00, 0x00, 0x00, 0x00, 0x00, 0x38); - SETOP(34, "TBA", 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C); - SETOP(35, "TXS", 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00); - SETOP(36, "BNG", 0x00, 0x00, 0x00, 0x00, 0x40, 0x00); - SETOP(37, "XOR", 0x41, 0x4B, 0x00, 0x00, 0x49, 0x00); - SETOP(38, "XRY", 0x42, 0xA2, 0x00, 0x00, 0x72, 0x00); - SETOP(39, "XAY", 0x00, 0x00, 0x00, 0x00, 0x00, 0x43); - SETOP(40, "XRX", 0x44, 0xA4, 0x00, 0x00, 0x74, 0x00); - SETOP(41, "XAX", 0x00, 0x00, 0x00, 0x00, 0x00, 0x45); - SETOP(42, "CLI", 0x00, 0x00, 0x00, 0x00, 0x00, 0x48); - SETOP(43, "BCS", 0x00, 0x00, 0x00, 0x00, 0x50, 0x00); - SETOP(44, "LSL", 0x51, 0x55, 0x00, 0x00, 0x53, 0x00); - SETOP(45, "SEC", 0x00, 0x00, 0x00, 0x00, 0x00, 0x58); - SETOP(46, "STA", 0x00, 0x7B, 0x8B, 0x9B, 0x5B, 0x00); - SETOP(47, "STY", 0x00, 0x7D, 0x8D, 0x00, 0x5D, 0x00); - SETOP(48, "STX", 0x00, 0x7E, 0x00, 0x9E, 0x5E, 0x00); - SETOP(49, "BCC", 0x00, 0x00, 0x00, 0x00, 0x60, 0x00); - SETOP(50, "LSR", 0x61, 0x65, 0x00, 0x00, 0x63, 0x00); - SETOP(51, "CLC", 0x00, 0x00, 0x00, 0x00, 0x00, 0x68); - SETOP(52, "LDA", 0x69, 0x79, 0x89, 0x99, 0x59, 0x00); - SETOP(53, "LDY", 0x6A, 0x7A, 0x8A, 0x00, 0x5A, 0x00); - SETOP(54, "LDX", 0x6C, 0x7C, 0x00, 0x9C, 0x5C, 0x00); - SETOP(55, "BEQ", 0x00, 0x00, 0x00, 0x00, 0x70, 0x00); - SETOP(56, "ROL", 0x71, 0x75, 0x00, 0x00, 0x73, 0x00); - SETOP(57, "SSP", 0x00, 0x00, 0x00, 0x00, 0x00, 0x78); - SETOP(58, "BNE", 0x00, 0x00, 0x00, 0x00, 0x80, 0x00); - SETOP(59, "ROR", 0x81, 0x85, 0x00, 0x00, 0x83, 0x00); - SETOP(60, "CSP", 0x00, 0x00, 0x00, 0x00, 0x00, 0x88); - SETOP(61, "BVS", 0x00, 0x00, 0x00, 0x00, 0x90, 0x00); - SETOP(62, "MUL", 0x91, 0x95, 0x00, 0x00, 0x93, 0x00); - SETOP(63, "SEV", 0x00, 0x00, 0x00, 0x00, 0x00, 0x98); - SETOP(64, "BVC", 0x00, 0x00, 0x00, 0x00, 0xA0, 0x00); - SETOP(65, "DIV", 0xA1, 0xA5, 0x00, 0x00, 0xA3, 0x00); - SETOP(66, "CLV", 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8); - SETOP(67, "ASR", 0xA9, 0xAD, 0x00, 0x00, 0xAB, 0x00); - SETOP(68, "RTS", 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0); - SETOP(69, "CMP", 0xB1, 0xF5, 0x00, 0x00, 0xE5, 0x00); - SETOP(70, "CPY", 0xB2, 0xF2, 0x00, 0x00, 0xE2, 0x00); - SETOP(71, "CAY", 0x00, 0x00, 0x00, 0x00, 0x00, 0xB3); - SETOP(72, "CPX", 0xB4, 0xF4, 0x00, 0x00, 0xE4, 0x00); - SETOP(73, "CAX", 0x00, 0x00, 0x00, 0x00, 0x00, 0xB5); - SETOP(74, "ENT", 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00); - SETOP(75, "RTI", 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0); - SETOP(76, "INC", 0x00, 0xE3, 0x00, 0x00, 0xE1, 0xC1); - SETOP(77, "INY", 0x00, 0x00, 0x00, 0x00, 0x00, 0xC2); - SETOP(78, "IAY", 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3); - SETOP(79, "INX", 0x00, 0x00, 0x00, 0x00, 0x00, 0xC4); - SETOP(80, "IAX", 0x00, 0x00, 0x00, 0x00, 0x00, 0xC5); - SETOP(81, "DEC", 0x00, 0xF3, 0x00, 0x00, 0xF1, 0xD1); - SETOP(82, "DEY", 0x00, 0x00, 0x00, 0x00, 0x00, 0xD2); - SETOP(83, "DAY", 0x00, 0x00, 0x00, 0x00, 0x00, 0xD3); - SETOP(84, "DEX", 0x00, 0x00, 0x00, 0x00, 0x00, 0xD4); - SETOP(85, "DAX", 0x00, 0x00, 0x00, 0x00, 0x00, 0xD5); - SETOP(86, "WAI", 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8); - SETOP(87, "JSL", 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00); - SETOP(88, "NOP", 0x00, 0x00, 0x00, 0x00, 0x00, 0xE8); - SETOP(89, "RTL", 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0); - SETOP(90, "BRK", 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8); + /* mne IMM ZM ZMX ZMY IND INX INY ABS IMPL*/ + SETOP( 0, "CPS", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); + SETOP( 1, "ADC", 0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00); + SETOP( 2, "AAB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02); + SETOP( 3, "PHB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06); + SETOP( 4, "PHP", 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); + SETOP( 5, "PHA", 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); + SETOP( 6, "PHY", 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); + SETOP( 7, "TAY", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B); + SETOP( 8, "PHX", 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); + SETOP( 9, "TAX", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D); + SETOP(10, "TYX", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E); + SETOP(11, "JMP", 0x00, 0xD0, 0x00, 0x00, 0x04, 0x14, 0x24, 0x10, 0x00); + SETOP(12, "SBC", 0x11, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00); + SETOP(13, "SAB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12); + SETOP(14, "PLB", 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); + SETOP(15, "PLP", 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); + SETOP(16, "PLA", 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); + SETOP(17, "PLY", 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); + SETOP(18, "TYA", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B); + SETOP(19, "PLX", 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); + SETOP(20, "TXA", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D); + SETOP(21, "TXY", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E); + SETOP(22, "JSR", 0x00, 0x20, 0x00, 0x00, 0x34, 0x44, 0x54, 0x00, 0x00); + SETOP(23, "AND", 0x21, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00); + SETOP(24, "ABA", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22); + SETOP(25, "STT", 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); + SETOP(26, "TAB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26); + SETOP(27, "TSX", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2E); + SETOP(28, "BPO", 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00); + SETOP(29, "ORA", 0x31, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x00); + SETOP(30, "OAB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32); + SETOP(31, "TBA", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36); + SETOP(32, "SEI", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38); + SETOP(33, "TXS", 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); + SETOP(34, "BNG", 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00); + SETOP(35, "XOR", 0x41, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x00); + SETOP(36, "XAB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42); + SETOP(37, "CLI", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48); + SETOP(38, "BCS", 0x00, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00); + SETOP(39, "LSL", 0x51, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x00); + SETOP(40, "LLB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52); + SETOP(41, "STB", 0x00, 0x7F, 0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0x5F, 0x00); + SETOP(42, "SEC", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58); + SETOP(43, "STA", 0x00, 0x7B, 0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0x5B, 0x00); + SETOP(44, "STY", 0x00, 0x7D, 0x8D, 0x00, 0xAD, 0xBD, 0x00, 0x5D, 0x00); + SETOP(45, "STX", 0x00, 0x7E, 0x00, 0x9E, 0xAE, 0x00, 0xCE, 0x5E, 0x00); + SETOP(46, "BCC", 0x00, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00); + SETOP(47, "LSR", 0x61, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x00); + SETOP(48, "LRB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62); + SETOP(49, "LDB", 0x66, 0x76, 0x86, 0x96, 0xA6, 0xB6, 0xC6, 0x56, 0x00); + SETOP(50, "CLC", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68); + SETOP(51, "LDA", 0x69, 0x79, 0x89, 0x99, 0xA9, 0xB9, 0xC9, 0x59, 0x00); + SETOP(52, "LDY", 0x6A, 0x7A, 0x8A, 0x00, 0xAA, 0xBA, 0x00, 0x5A, 0x00); + SETOP(53, "LDX", 0x6C, 0x7C, 0x00, 0x9C, 0xAC, 0x00, 0xCC, 0x5C, 0x00); + SETOP(54, "BEQ", 0x00, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00); + SETOP(55, "ROL", 0x71, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x00); + SETOP(56, "RLB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72); + SETOP(57, "SSP", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78); + SETOP(58, "BNE", 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00); + SETOP(59, "ROR", 0x81, 0x85, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x00); + SETOP(60, "RRB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82); + SETOP(61, "CSP", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88); + SETOP(62, "BVS", 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x00); + SETOP(63, "MUL", 0x91, 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x93, 0x00); + SETOP(64, "MAB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x92); + SETOP(65, "SEV", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98); + SETOP(66, "BVC", 0x00, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x00); + SETOP(67, "DIV", 0xA1, 0xA5, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x00); + SETOP(68, "DAB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2); + SETOP(69, "CLV", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8); + SETOP(70, "RTS", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0); + SETOP(71, "CMP", 0xB1, 0xB5, 0x00, 0x00, 0xE9, 0xEB, 0xED, 0xB3, 0x00); + SETOP(72, "CAB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB2); + SETOP(73, "CPY", 0x2A, 0x3B, 0x00, 0x00, 0xEA, 0xFA, 0x00, 0x2B, 0x00); + SETOP(74, "CPX", 0xBC, 0x3D, 0x00, 0x00, 0xEC, 0x00, 0xFC, 0x2D, 0x00); + SETOP(75, "CPB", 0xD6, 0xF6, 0x00, 0x00, 0xDF, 0xEF, 0xFF, 0xE6, 0x00); + SETOP(76, "ENT", 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); + SETOP(77, "RTI", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0); + SETOP(78, "INC", 0x00, 0xC5, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3, 0xC1); + SETOP(79, "IAB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC2); + SETOP(80, "INY", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3A); + SETOP(81, "INX", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C); + SETOP(82, "DEC", 0x00, 0xD5, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD3, 0xD1); + SETOP(83, "DBA", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD2); + SETOP(84, "DEY", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4A); + SETOP(85, "DEX", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4C); + SETOP(86, "WAI", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8); + SETOP(87, "JSL", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00); + SETOP(88, "ASR", 0xE1, 0xE5, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE3, 0x00); + SETOP(89, "ARB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE2); + SETOP(90, "NOP", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE8); + SETOP(91, "RTL", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0); + SETOP(92, "BRK", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8); FILE *fp; if (strcasecmp(fn, "stdin") != 0) { fp = fopen(fn, "r"); @@ -256,30 +259,31 @@ int asmmon(const char *fn) { strtok_r(ins, ".", &postfix); if (oprand != NULL) { for (int i = 0; i < strlen(oprand); i++) { + if (oprand[i] == '(') + addrmode = 6; if (oprand[i] == '"') break; - if (oprand[i] == 'x' || oprand[i] == 'X') { - ir[0] = 'x'; - ir[1] = '\0'; - break; - } - if (oprand[i] == 'y' || oprand[i] == 'Y') { - ir[0] = 'y'; - ir[1] = '\0'; - break; + if (a && oprand[a] == ',') { + if (oprand[i] == 'x' || oprand[i] == 'X') { + ir[0] = 'x'; + ir[1] = '\0'; + } + if (oprand[i] == 'y' || oprand[i+1] == 'Y') { + ir[0] = 'y'; + ir[1] = '\0'; + } } - if (oprand[i] == ',' || oprand[i] == ';') { + if (oprand[i] == ',' || oprand[i] == ';') a = i; - } } if (a) oprand[a] = '\0'; } } - if (strcasecmp(cmd, "quit") == 0 || strcasecmp(cmd, "q") == 0) { + if (!strcasecmp(cmd, "quit") || !strcasecmp(cmd, "q")) { return 2; } - if (strcasecmp(cmd, "viewmem") == 0) { + if (!strcasecmp(cmd, "viewmem") || !strcasecmp(cmd, "vm") || !strcasecmp(cmd, "v")) { done |= 4; viewmem(address); } @@ -437,51 +441,56 @@ int asmmon(const char *fn) { } } - if (oprand == NULL && !strcasecmp(ins, "TXS")) + if (oprand == NULL && !strcasecmp(ins, "TXS")) { addrmode = 1; + done |= 32; + } else if (oprand != NULL && !strcasecmp(ins, "TXS")) addr[address++] = 0x17; if (!(done & 2) && oprand != NULL) { - if (oprand[0] == '#' || oprand[0] == '$') { - if(oprand[0] == '#' && (oprand[1] == '$' || oprand[1] == '%')) { - mode[1] = oprand[1]; - mode[2] = '\0'; - } else { - mode[1] = '\0'; - } - mode[0] = oprand[0]; - oprand = strtok(oprand, "#$%"); + mode[0] = oprand[0]; + mode[1] = oprand[1]; + if (oprand[0] == '#' || oprand[0] == '$' || oprand[0] == '(') { + oprand = strtok(oprand, "#($%"); if (mode[0] == '#') { addrmode = 1; + done |= 32; if (mode[1] == '$') value = strtoull(oprand, NULL, 16); - if (mode[1] == '%') + else if (mode[1] == '%') value = strtoull(oprand, NULL, 2); - } - if (mode[0] == '$') { - value = strtoull(oprand, NULL, 16); - if (value == 0) - addrmode = 2; - if (value & 0xFFFFFFFF) { - char *stf[] = {"BPO", "BNG", "BCS", "BCC", "BEQ", "BNE", "BVS", "BVC"}; - for (int i = 0; i < 8; i++) { - if (strcasecmp(ins, stf[i]) == 0) { - addrmode = 5; - break; - } else { - addrmode = 2; - } + else + value = strtoull(oprand, NULL, 10); + } else { + if (mode[0] == '$' || mode[1] == '$') + value = strtoull(oprand, NULL, 16); + else if (mode[0] == '%' || mode[1] == '%') + value = strtoull(oprand, NULL, 2); + else + value = strtoull(oprand, NULL, 10); + if (mode[0] != '(') { + if (value & 0xFFFFFFFF || !value) { + addrmode = 2; + } else if (value & 0xFFFFFFFF00000000) { + addrmode = 5; } - } else if (value & 0xFFFFFFFF00000000) { - addrmode = 5; } - if (addrmode == 2 && ir != NULL) { + if ((addrmode == 2 || addrmode == 6) && ir != NULL) { switch (ir[0]) { case 'x': - addrmode = 3; + if (addrmode == 2) + addrmode = 3; + else if (addrmode == 6) + addrmode = 7; break; case 'y': - addrmode = 4; + if (addrmode == 2) + addrmode = 4; + else if (addrmode == 6) + addrmode = 8; + break; + default: + done |= 32; break; } } @@ -494,28 +503,29 @@ int asmmon(const char *fn) { } if ((isalnum(oprand[i]) || oprand[i] == '_') && oprand[i] != '"') { value = use_label(oprand, address); - if (value == 0) - addrmode = 2; - if (value & 0xFFFFFFFF || value == 0) { - char *stf[] = {"BPO", "BNG", "BCS", "BCC", "BEQ", "BNE", "BVS", "BVC"}; - for (int i = 0; i < 8; i++) { - if (!strcasecmp(ins, stf[i])) { - addrmode = 5; - break; - } else { - addrmode = 2; - } + if (mode[0] != '(') { + if (value & 0xFFFFFFFF || !value) { + addrmode = 2; + } else if (value & 0xFFFFFFFF00000000) { + addrmode = 5; } - } else if (value & 0xFFFFFFFF00000000) { - addrmode = 5; } - if (addrmode == 2 && ir != NULL) { + if ((addrmode == 2 || addrmode == 6) && ir != NULL && a) { switch (ir[0]) { case 'x': - addrmode = 3; + if (addrmode == 2) + addrmode = 3; + else if (addrmode == 6) + addrmode = 7; break; case 'y': - addrmode = 4; + if (addrmode == 2) + addrmode = 4; + else if (addrmode == 6) + addrmode = 8; + break; + default: + done |= 32; break; } } @@ -716,6 +726,45 @@ int asmmon(const char *fn) { fprintf(stderr, "oof, %s cannot be an absolute dictator.\n", op.mnemonic); } break; + case 6: + if (op.ind) { + addr[address++] = op.ind; + addr[address] = value & 0xFF; + addr[address+1] = value >> 8; + addr[address+2] = value >> 16; + addr[address+3] = value >> 24; + address+=4; + break; + } else { + fprintf(stderr, "oof, %s cannot use pointers.\n", op.mnemonic); + } + break; + case 7: + if (op.inx) { + addr[address++] = op.inx; + addr[address] = value & 0xFF; + addr[address+1] = value >> 8; + addr[address+2] = value >> 16; + addr[address+3] = value >> 24; + address+=4; + break; + } else { + fprintf(stderr, "oof, %s does not use Indexed Indirect.\n", op.mnemonic); + } + break; + case 8: + if (op.iny) { + addr[address++] = op.iny; + addr[address] = value & 0xFF; + addr[address+1] = value >> 8; + addr[address+2] = value >> 16; + addr[address+3] = value >> 24; + address+=4; + break; + } else { + fprintf(stderr, "oof, %s does not use Indirect Indexed.\n", op.mnemonic); + } + break; } #if debug if (!(done & 6)) { @@ -726,7 +775,7 @@ int asmmon(const char *fn) { printf("Postfix: %s, ", (postfix[0] != '\0') ? postfix : "none"); #endif printf("Operand: %s, ", (oprand != NULL && !(done & 16)) ? oprand : "none"); - printf("Index Register: %s, ", (ir != NULL) ? ir : "none"); + printf("Index Register: %s, ", (ir != NULL && !(done & 32)) ? ir : "none"); printf("Address: $%llx\n", address); } #endif @@ -3,9 +3,11 @@ #include <stdlib.h> #include <unistd.h> -#define OPNAME(opcode) [opcode] = #opcode /* Get name of Opcode, for dissambly. */ +#define OPNAME(opcode) [opcode] = #opcode /* Get name of Opcode, for disassembly. */ #define CPS 0x00 /* Clear Processor Status. */ #define ADC 0x01 /* ADd with Carry. */ +#define AAB 0x02 /* Add Accumulator with carry by B register. */ +#define PHB 0x06 /* PusH B register to stack. */ #define PHP 0x08 /* PusH Processor status to stack. */ #define PHA 0x09 /* PusH Accumulator to stack. */ #define PHY 0x0A /* PusH Y register to stack. */ @@ -15,6 +17,8 @@ #define TYX 0x0E /* Transfer Y to X. */ #define JMP 0x10 /* JuMP to memory location. */ #define SBC 0x11 /* SuBtract with Carry. */ +#define SAB 0x12 /* Subtract Accumulator with carry by B register. */ +#define PLB 0x16 /* PuLl B register to stack. */ #define PLP 0x18 /* PuLl Processor status from stack. */ #define PLA 0x19 /* PuLl Accumulator from stack. */ #define PLY 0x1A /* PuLl Y register from stack. */ @@ -24,74 +28,72 @@ #define TXY 0x1E /* Transfer X to Y. */ #define JSR 0x20 /* Jump to SubRoutine. */ #define AND 0x21 /* bitwise AND with accumulator. */ -#define ANY 0x22 /* bitwise ANd with Y register.*/ -#define AAY 0x23 /* bitwise And with Accumulator, and Y register. */ -#define ANX 0x24 /* bitwise ANd with X register. */ -#define AAX 0x25 /* bitwise And with Accumulator, and X register. */ +#define ABA 0x22 /* bitwise And with Accumulator, and B register. */ +#define TAB 0x26 /* Transfer Accumulator to B. */ #define STT 0x28 /* STart Threads. */ -#define TAB 0x2C /* Transfer Accumulator to B. */ +#define CPY 0x2A /* ComPare Y register. */ +#define CPX 0x2C /* ComPare X register. */ #define TSX 0x2E /* Transfer Stack pointer to X. */ #define BPO 0x30 /* Branch if POsitive. */ #define ORA 0x31 /* bitwise OR with Accumulator. */ -#define ORY 0x32 /* bitwise OR with Y register. */ -#define OAY 0x33 /* bitwise Or with Accumulator, and Y register. */ -#define ORX 0x34 /* bitwise OR with X register. */ -#define OAX 0x35 /* bitwise Or with Accumulator, and X register. */ +#define OAB 0x32 /* bitwise Or with Accumulator, and B register. */ +#define TBA 0x36 /* Transfer B to Accumulator. */ #define SEI 0x38 /* SEt Interupt flag. */ -#define TBA 0x3C /* Transfer B to Accumulator. */ +#define INY 0x3A /* INcrement Y register. */ +#define INX 0x3C /* INcrement X register. */ #define TXS 0x3E /* Transfer X to Stack pointer. */ #define BNG 0x40 /* Branch if NeGative. */ #define XOR 0x41 /* bitwise XOR with accumulator. */ -#define XRY 0x42 /* bitwise XoR with Y register. */ -#define XAY 0x43 /* bitwise Xor with Accumulator, and Y register. */ -#define XRX 0x44 /* bitwise XoR with X register. */ -#define XAX 0x45 /* bitwise Xor with Accumulator, and X register. */ +#define XAB 0x42 /* bitwise Xor with Accumulator, and B register. */ #define CLI 0x48 /* CLear Interupt flag. */ +#define DEY 0x4A /* DEcrement Y register. */ +#define DEX 0x4C /* DEcrement X register. */ #define BCS 0x50 /* Branch if Carry Set. */ #define LSL 0x51 /* Logical Shift Left. */ +#define LLB 0x52 /* Logical shift Left accumulator by B. */ #define SEC 0x58 /* SEt Carry flag. */ #define STA 0x5B /* STore Accumulator. */ #define STY 0x5D /* STore Y register. */ #define STX 0x5E /* STore X register. */ +#define STB 0x5F /* STore B register. */ #define BCC 0x60 /* Branch if Carry Clear. */ #define LSR 0x61 /* Logical Shift Right. */ +#define LRB 0x62 /* Logical shift Right accumulator by B. */ +#define LDB 0x66 /* LoaD B register. */ #define CLC 0x68 /* CLear Carry flag. */ #define LDA 0x69 /* LoaD Accumulator. */ #define LDY 0x6A /* LoaD Y register. */ #define LDX 0x6C /* LoaD X register. */ #define BEQ 0x70 /* Branch if EQual. */ #define ROL 0x71 /* ROtate Left. */ +#define RLB 0x72 /* Rotate Left accumulator by B. */ #define SSP 0x78 /* Set Stack Protection flag. */ #define BNE 0x80 /* Branch if Not Equal. */ #define ROR 0x81 /* ROtate Right. */ +#define RRB 0x82 /* Rotate Right accumulator by B. */ #define CSP 0x88 /* Clear Stack Protection flag. */ #define BVS 0x90 /* Branch if oVerflow Set. */ -#define MUL 0x91 /* MULtiply with accumulator. */ +#define MUL 0x91 /* MULtiply accumulator. */ +#define MAB 0x92 /* Multiply Accumulator by B. */ #define SEV 0x98 /* SEt oVerflow flag. */ #define BVC 0xA0 /* Branch if oVerflow Clear. */ #define DIV 0xA1 /* DIVide with accumulator. */ +#define DAB 0xA2 /* Divide Accumulator by B. */ #define CLV 0xA8 /* CLear oVerflow flag. */ -#define ASR 0xA9 /* Arithmetic Shift Right. */ #define RTS 0xB0 /* ReTurn from Subroutine. */ #define CMP 0xB1 /* CoMPare accumulator. */ -#define CPY 0xB2 /* ComPare Y register. */ -#define CAY 0xB3 /* Compare Accumulator, and Y register. */ -#define CPX 0xB4 /* ComPare X register. */ -#define CAX 0xB5 /* Compare Accumulator, and X register. */ +#define CAB 0xB2 /* Compare Accumulator, and B. */ #define ENT 0xB8 /* ENd Threads. */ #define RTI 0xC0 /* ReTurn from Interrupt. */ #define INC 0xC1 /* INCrement accumulator. */ -#define INY 0xC2 /* INcrement Y register. */ -#define IAY 0xC3 /* Increment Accumulator, and Y register. */ -#define INX 0xC4 /* INcrement X register. */ -#define IAX 0xC5 /* Increment Accumulator, and X register. */ +#define IAB 0xC2 /* Increment Accumulator, and B register. */ #define DEC 0xD1 /* DECrement accumulator. */ -#define DEY 0xD2 /* DEcrement Y register. */ -#define DAY 0xD3 /* Decrement Accumulator, and Y register. */ -#define DEX 0xD4 /* DEcrement X register. */ -#define DAX 0xD5 /* Decrement Accumulator, and X register. */ +#define DBA 0xD2 /* Decrement Accumulator, and B register. */ +#define CPB 0xD6 /* ComPare B register. */ #define WAI 0xD8 /* WAit for Interrupt. */ #define JSL 0xE0 /* Jump to Subroutine Long. */ +#define ASR 0xE1 /* Arithmetic Shift Right. */ +#define ARB 0xE2 /* Arithmetic shift Right accumulator by B. */ #define NOP 0xE8 /* No OPeration. */ #define RTL 0xF0 /* ReTurn from subroutine Long. */ #define BRK 0xF8 /* BReaK. */ @@ -126,165 +128,211 @@ typedef struct { uint8_t zm; uint8_t zmy; uint8_t zmx; + uint8_t ind; + uint8_t inx; + uint8_t iny; uint8_t impl; } opent; static const char *opname[0x100] = { - OPNAME(CPS), - [ADC] = "ADC #", + [0x00] = "CPS", + [0x01] = "ADC #", + [0x02] = "AAB", [0x03] = "ADC a", + [0x04] = "JMP (ind)", [0x05] = "ADC zm", - OPNAME(PHP), - OPNAME(PHA), - OPNAME(PHY), - OPNAME(TAY), - OPNAME(PHX), - OPNAME(TAX), - OPNAME(TYX), - OPNAME(JMP), - [SBC] = "SBC #", + [0x06] = "PHB", + [0x08] = "PHP", + [0x09] = "PHA", + [0x0A] = "PHY", + [0x0B] = "TAY", + [0x0C] = "PHX", + [0x0D] = "TAX", + [0x0E] = "TYX", + [0x10] = "JMP a", + [0x11] = "SBC #", + [0x12] = "SAB", [0x13] = "SBC a", + [0x14] = "JMP (ind, x)", [0x15] = "SBC zm", - OPNAME(PLP), - OPNAME(PLA), - OPNAME(PLY), - OPNAME(TYA), - OPNAME(PLX), - OPNAME(TXA), - OPNAME(TXY), - OPNAME(JSR), - [AND] = "AND #", - [ANY] = "ANY #", - OPNAME(AAY), - [ANX] = "ANX #", - OPNAME(AAX), - OPNAME(STT), - OPNAME(TSX), - [0x29] = "AND a", - [0x2B] = "AND zm", - OPNAME(TAB), - OPNAME(BPO), - [ORA] = "ORA #", - [ORY] = "ORY #", - OPNAME(OAY), - [ORX] = "ORX #", - OPNAME(OAX), - OPNAME(SEI), - OPNAME(TXS), - [0x39] = "ORA a", - [0x3B] = "ORA zm", - OPNAME(TBA), - OPNAME(BNG), - [XOR] = "XOR #", - [XRY] = "XRY #", - OPNAME(XAY), - [XRX] = "XRX #", - OPNAME(XAX), - OPNAME(CLI), - [0x49] = "XOR a", - [0x4B] = "XOR zm", - OPNAME(BCS), - [LSL] = "LSL #", - [0x52] = "ANY a", + [0x16] = "PLB", + [0x18] = "PLP", + [0x19] = "PLA", + [0x1A] = "PLY", + [0x1B] = "TYA", + [0x1C] = "PLX", + [0x1D] = "TXA", + [0x1E] = "TXY", + [0x20] = "JSR", + [0x21] = "AND #", + [0x22] = "ABA", + [0x23] = "AND a", + [0x24] = "JMP (ind), y", + [0x25] = "AND zm", + [0x26] = "TAB", + [0x28] = "STT", + [0x2A] = "CPY #", + [0x2B] = "CPY a", + [0x2C] = "CPX #", + [0x2D] = "CPX a", + [0x2E] = "TSX", + [0x30] = "BPO a", + [0x31] = "ORA #", + [0x32] = "OAB", + [0x33] = "ORA a", + [0x34] = "JSR (ind)", + [0x35] = "ORA zm", + [0x36] = "TBA", + [0x38] = "SEI", + [0x3A] = "INY", + [0x3B] = "CPY zm", + [0x3C] = "INX", + [0x3D] = "CPX zm", + [0x3E] = "TXS", + [0x40] = "BNG a", + [0x41] = "XOR #", + [0x42] = "XAB", + [0x43] = "XOR a", + [0x44] = "JSR (ind, x)", + [0x45] = "XOR zm", + [0x48] = "CLI", + [0x4A] = "DEY", + [0x4C] = "DEX", + [0x50] = "BCS a", + [0x51] = "LSL #", + [0x52] = "LLB", [0x53] = "LSL a", - [0x54] = "ANX a", + [0x54] = "JSR (ind), y", [0x55] = "LSL zm", - OPNAME(SEC), + [0x56] = "LDB a", + [0x58] = "SEC", [0x59] = "LDA a", [0x5A] = "LDY a", - [STA] = "STA a", + [0x5B] = "STA a", [0x5C] = "LDX a", - [STY] = "STY a", - [STX] = "STX a", - OPNAME(BCC), - [LSR] = "LSR #", - [0x62] = "ORY a", + [0x5D] = "STY a", + [0x5E] = "STX a", + [0x5F] = "STB a", + [0x60] = "BCC a", + [0x61] = "LSR #", + [0x62] = "LRB", [0x63] = "LSR a", - [0x64] = "ORX a", + [0x64] = "BPO zm", [0x65] = "LSR zm", - OPNAME(CLC), - [LDA]= "LDA #", - [LDY]= "LDY #", - [LDX]= "LDX #", - OPNAME(BEQ), - [ROL] = "ROL #", - [0x72] = "XRY a", + [0x66] = "LDB #", + [0x68] = "CLC", + [0x69] = "LDA #", + [0x6A] = "LDY #", + [0x6C] = "LDX #", + [0x70] = "BEQ a", + [0x71] = "ROL #", + [0x72] = "RLB", [0x73] = "ROL a", - [0x74] = "XRX a", + [0x74] = "BNG zm", [0x75] = "ROL zm", - OPNAME(SSP), + [0x76] = "LDB zm", + [0x78] = "SSP", [0x79] = "LDA zm", [0x7A] = "LDY zm", [0x7B] = "STA zm", [0x7C] = "LDX zm", [0x7D] = "STY zm", [0x7E] = "STX zm", - OPNAME(BNE), - [ROR] = "ROR #", - [0x82] = "ANY zm", + [0x7F] = "STB zm", + [0x80] = "BNE a", + [0x81] = "ROR #", + [0x82] = "RRB", [0x83] = "ROR a", - [0x84] = "ANX zm", + [0x84] = "BCS zm", [0x85] = "ROR zm", - OPNAME(CSP), + [0x86] = "LDB zm, x", + [0x88] = "CSP", [0x89] = "LDA zm, x", [0x8A] = "LDY zm, x", [0x8B] = "STA zm, x", [0x8D] = "STY zm, x", - OPNAME(BVS), - [MUL] = "MUL #", - [0x92] = "ORY zm", + [0x8F] = "STB zm, x", + [0x90] = "BVS a", + [0x91] = "MUL #", + [0x92] = "MAB", [0x93] = "MUL a", - [0x94] = "ORX zm", + [0x94] = "BCC zm", [0x95] = "MUL zm", - OPNAME(SEV), + [0x96] = "LDB zm, y", + [0x98] = "SEV", [0x99] = "LDA zm, y", [0x9B] = "STA zm, y", [0x9C] = "LDX zm, y", [0x9E] = "STX zm, y", - OPNAME(BVC), - [DIV] = "DIV #", - [0xA2] = "XRY zm", + [0x9F] = "STB zm, y", + [0xA0] = "BVC a", + [0xA1] = "DIV #", + [0xA2] = "DAB", [0xA3] = "DIV a", - [0xA4] = "XRX zm", + [0xA4] = "BEQ zm", [0xA5] = "DIV zm", - OPNAME(CLV), - [ASR] = "ASR #", - [0xAB] = "ASR a", - [0xAD] = "ASR zm", - OPNAME(RTS), - [CMP] = "CMP #", - [CPY] = "CPY #", - OPNAME(CAY), - [CPX] = "CPX #", - OPNAME(CAX), - OPNAME(ENT), - OPNAME(RTI), - [INC] = "INC A", - OPNAME(INY), - OPNAME(IAY), - OPNAME(INX), - OPNAME(IAX), + [0xA6] = "LDB (ind)", + [0xA8] = "CLV", + [0xA9] = "LDA (ind)", + [0xAA] = "LDY (ind)", + [0xAB] = "STA (ind)", + [0xAC] = "LDX (ind)", + [0xAD] = "STY (ind)", + [0xAE] = "STX (ind)", + [0xAF] = "STB (ind)", + [0xB0] = "RTS", + [0xB1] = "CMP #", + [0xB2] = "CAB", + [0xB3] = "CMP a", + [0xB4] = "BNE zm", + [0xB5] = "CMP zm", + [0xB6] = "LDB (ind, x)", + [0xB8] = "ENT", + [0xB9] = "LDA (ind, x)", + [0xBA] = "LDY (ind, x)", + [0xBB] = "STA (ind, x)", + [0xBD] = "STY (ind, x)", + [0xBF] = "STB (ind, x)", + [0xC0] = "RTI", + [0xC1] = "INC A", + [0xC2] = "IAB", + [0xC3] = "INC a", + [0xC4] = "BVS zm", + [0xC5] = "INC zm", + [0xC6] = "LDB (ind), y", + [0xC9] = "LDA (ind), y", + [0xCB] = "STA (ind), y", + [0xCC] = "LDX (ind), y", + [0xCE] = "STX (ind), y", + [0xCF] = "STB (ind), y", [0xD0] = "JMP zm", - [DEC] = "DEC A", - OPNAME(DEY), - OPNAME(DAY), - OPNAME(DEX), - OPNAME(DAX), - OPNAME(WAI), - OPNAME(JSL), - [0xE1] = "INC a", - [0xE2] = "CPY a", - [0xE3] = "INC zm", - [0xE4] = "CPX a", - [0xE5] = "CMP a", - OPNAME(NOP), - OPNAME(RTL), - [0xF1] = "DEC a", - [0xF2] = "CPY zm", - [0xF3] = "DEC zm", - [0xF4] = "CPX zm", - [0xF4] = "CMP zm", - OPNAME(BRK), + [0xD1] = "DEC A", + [0xD2] = "DBA", + [0xD3] = "DEC a", + [0xD4] = "BVC zm", + [0xD5] = "DEC zm", + [0xD6] = "CPB #", + [0xD8] = "WAI", + [0xDF] = "CPB (ind)", + [0xE0] = "JSL", + [0xE1] = "ASR #", + [0xE2] = "ARB", + [0xE3] = "ASR a", + [0xE5] = "ASR zm", + [0xE6] = "CPB a", + [0xE8] = "NOP", + [0xE9] = "CMP (ind)", + [0xEA] = "CPY (ind)", + [0xEB] = "CMP (ind, x)", + [0xEC] = "CPX (ind)", + [0xED] = "CMP (ind), y", + [0xEF] = "CPB (ind, x)", + [0xF0] = "RTL", + [0xF6] = "CPB zm", + [0xF8] = "BRK", + [0xFA] = "CPY (ind, x)", + [0xFC] = "CPX (ind), y", + [0xFF] = "CPB (ind), y" }; extern int asmmon(); diff --git a/programs/subasm.s b/programs/subasm.s index 46effce..ddb7ba2 100644 --- a/programs/subasm.s +++ b/programs/subasm.s @@ -11,9 +11,18 @@ ver_txt: .byte ", version " ver_num: .byte "0.1" -x: + +scr_row: + .byte $0 +scr_col: + .byte $0 +a: + .word $0 +b: + .word $0 +c: .word $0 -y: +d: .word $0 str_buf: @@ -109,64 +118,137 @@ store_char: esc: lda ctrl_reg ; Skip the '['. lda ctrl_reg ; Get the next character. - beq read ; We have an error, so discard it, and read the next character. + beq read ; We have an error, so discard it, and go back to getting user input. lda kbd ; Get the escape code. - cmp #$41 ; Did the user press the up arrow? + sta c ; Store the escape code, until we need it. + jsr isup ; Check if the user pressed up. + lda d + cmp #$0 + bne esc_end + jsr isdown ; Check if the user pressed down. + lda d + cmp #$0 + bne esc_end + lda #$0 + jsr isleft ; Check if the user pressed left. + lda d + cmp #$0 + bne esc_end + jsr isright ; Check if the user pressed right. +esc_end: + lda #$0 + sta d + jmp rset_a ; Go back to getting user input. + +isup: + lda scr_row ; Is the cursor at the top of the screen? + beq isup_done ; Yes, so return. + lda c ; No, so load the escape code back into the accumulator. + cmp #$41 ; Did the user press the up arrow key? beq up ; Yes, so move the cursor up. - cmp #$42 ; Did the user press the down arrow? +isup_done: + rts ; End of isup. + +isdown: + lda scr_row ; Start checking the y coordinate of the cursor. + cmp #$17 ; Is the cursor at the bottom of the screen? + beq isdown_done ; Yes, so return. + lda c ; No, so load the escape code back into the accumulator. + cmp #$42 ; Did the user press the down arrow key? beq down ; Yes, so move the cursor down. - cmp #$43 ; Did the user press the left arrow? - beq left ; Yes, so move the cursor left. - cmp #$44 ; Did the user press the right arrow? +isdown_done: + rts ; End of isdown. + +isright: + lda scr_col ; Start checking the x coordinate of the cursor. + cmp #$4F ; Is the cursor at the far right of the screen? + beq isright_end ; Yes, so return. + lda c ; No, so load the escape code back into the accumulator. + cmp #$43 ; Did the user press the right arrow key? beq right ; Yes, so move the cursor right. +isright_end: + rts ; End of isright. + +isleft: + lda scr_col ; Is the cursor at the far left of the screen? + beq isleft_done ; Yes, so return. + lda c ; No, so load the escape code back into the accumulator. + cmp #$44 ; Did the user press the left arrow key? + beq left ; Yes, so move the cursor left. +isleft_done: + rts ; End of isleft. up: - lda #$1B - sta scr - lda #$5B - sta scr - lda #$41 - sta scr - jmp read + dec scr_row + jsr update_pos + lda #$1 + sta d + jmp isup_done down: - lda #$1B - sta scr - lda #$5B - sta scr - lda #$42 - sta scr - jmp read -left: - lda #$1B - sta scr - lda #$5B - sta scr - lda #$43 - sta scr - jmp read + inc scr_row + jsr update_pos + lda #$1 + sta d + jmp isdown_done right: - lda #$1B - sta scr - lda #$5B - sta scr - lda #$44 - sta scr - jmp read + inc scr_col + jsr update_pos + jmp isright_end +left: + dec scr_col + jsr update_pos + lda #$1 + sta d + jmp isleft_done + +update_pos: + lda #$1B ; Print an escape character + sta scr ; to the screen. + lda #$5B ; Print '[' + sta scr ; to the screen, and start the escape sequence. + jsr getrow ; Start printing the row number to the screen. + jsr getcol ; Start printing the column number to the screen. + lda #$48 ; Print 'H' + sta scr ; to the screen. + rts ; End of update_pos. +getrow: + lda scr_row ; Get the cursor's y coordinate. + div #$A ; Divide A by 10. + adc #$30 ; Convert it to ascii, and + sta scr ; print to the screen. + tba ; Get the remainder. + adc #$30 ; Convert it to ascii, and + sta scr ; print to the screen. + rts ; End of getrow. +getcol: + lda #$3B ; Print ';' + sta scr ; to the screen. + lda scr_col ; Get the cursor's x coordinate. + div #$A ; Divide A by 10. + adc #$30 ; Convert it to ascii, and + sta scr ; print to the screen. + tba ; Get the remainder. + adc #$30 ; Convert it to ascii, and + sta scr ; print to the screen. + rts ; End of getrow. nl: sta scr ; Print newline. + inc scr_row ; Move the cursor down one line. lda #$0 ; Put a null terminator, in place of the newline. - sta buf, y ; Place it into the input buffer. + sta scr_col ; Move the cursor back to column 0. + sta str_buf, y ; Place it into the input buffer. ldy.w #$0 ; Reset y, to parse the input. - jmp parse + jsr parse ; Start parsing input. back: - jsr echo ; Print backspace. + sta scr ; Print backspace. lda #$0 ; Put a null terminator, in place of the backspace. - sta buf, y ; Place it into the input buffer. + sta str_buf, y ; Place it into the input buffer. dey ; Decrement buffer offset. + dec scr_col jmp read ; Get next character. bs: @@ -175,11 +257,55 @@ bs: jmp back ; We are not, so add the backspace to the buffer. parse: - lda buf, y - beq clr_buf ; Reset y, if we hit the null terminator. - sta scr ; Print 'You have typed, ' + jmp parse ; Keep printing. + jsr clr_sbuf + rts + +forg: iny ; Increment offset. - jmp result ; Keep printing. + lda str_buf, y + jsr iswhite + bcs forg ; Reset y, if we hit the null terminator. + cmp #$2E ; Is this character a '.'? + bne forg_exit ; No, so return. + sty org ; Yes, so store the origin. +forg_end: + iny ; Increment offset. + lda str_buf, y + jsr istoken + bcs forg_end + dey + sty scr_col +forg_exit: + rts ; End of forg. + +istoken: + cmp #$20 ; Is this character a space? + beq istoken_f ; Yes, so return false. + cmp #$09 ; Is this character a tab? + beq istoken_f ; Yes, so return false. + cmp #$A ; Is this character a newline? + beq istoken_f ; Yes, so return false. + cmp #$3B ; Is this character a ';'? + beq istoken_f ; Yes, so return false. + cmp #$0 ; Is this character a null terminator? + beq istoken_f ; Yes, so return false. + sec ; Return true. + rts ; End of istoken. +istoken_f + clc ; Return false. + rts ; End of istoken_f. + +iswhite: + cmp #$20 ; Is this character a space? + beq iswhite_t ; Yes, so return true. + cmp #$09 ; Is this character a tab? + beq iswhite_t ; Yes, so return true. + clc ; No, so return false. + rts ; End of iswhite. +iswhite_t: + sec ; Return true. + rts ; End of iswhite_t. rset_y: ldy.w #$0 @@ -217,7 +343,23 @@ clr_end: rts echo: + sta a + ldx scr_col + cpx #$4F + bne echo_print + cmp #$A + beq linewrap +linewrap: + inc scr_row + ldx #$0 + stx scr_col + jsr update_pos +echo_print: + lda a sta scr ; Echo typed character. + inc scr_col ; Increment the cursor's x coordinate. + sta str_buf, y ; Store typed character into the input buffer. + iny ; Increment the buffer offset. rts ; Return. .org $FFC0 @@ -5,8 +5,8 @@ #include <string.h> #include <pthread.h> #define bench 0 -#define debug 0 -#define IO 1 +#define debug 1 +#define IO 0 #define keypoll 0 #if bench #include <sys/time.h> @@ -90,7 +90,7 @@ void *run(void *args) { kbd_rdy &= (uint8_t)~(1 << thread); } prefix = addr[cpu->pc[thread]]; - if ((prefix & 0x07) == 0x07) + if ((prefix & 0x0F) == 0x07) cpu->pc[thread]++; else prefix = 0; @@ -132,45 +132,50 @@ void *run(void *args) { cpu->ps &= 0; break; case ADC: /* ADC Immediate. */ + case AAB: /* Add Accumulator with carry by B register. */ case 0x03: /* ADC Absolute. */ case 0x05: /* ADC Zero Matrix. */ - if (opcode == ADC) { - address = cpu->pc[thread]; - cpu->pc[thread]+=regsize; - } - if (opcode == 0x03) { - address = (uint64_t)addr[cpu->pc[thread]] - | (uint64_t)addr[cpu->pc[thread]+1] << 8 - | (uint64_t)addr[cpu->pc[thread]+2] << 16 - | (uint64_t)addr[cpu->pc[thread]+3] << 24 - | (uint64_t)addr[cpu->pc[thread]+4] << 32 - | (uint64_t)addr[cpu->pc[thread]+5] << 40 - | (uint64_t)addr[cpu->pc[thread]+6] << 48 - | (uint64_t)addr[cpu->pc[thread]+7] << 56; - cpu->pc[thread]+=8; - iclk++; - } - if (opcode == 0x05) { - address = addr[cpu->pc[thread]] - | addr[cpu->pc[thread]+1] << 8 - | addr[cpu->pc[thread]+2] << 16 - | addr[cpu->pc[thread]+3] << 24; - cpu->pc[thread]+=4; - iclk++; - } - value = addr[address]; - if (regsize >= 2) { - value += (uint64_t)addr[address+1] << 8; - } - if (regsize >= 4) { - value += (uint64_t)addr[address+2] << 16; - value += (uint64_t)addr[address+3] << 24; - } - if (regsize >= 8) { - value += (uint64_t)addr[address+4] << 32; - value += (uint64_t)addr[address+5] << 40; - value += (uint64_t)addr[address+6] << 48; - value += (uint64_t)addr[address+7] << 56; + if (opcode != AAB) { + if (opcode == ADC) { + address = cpu->pc[thread]; + cpu->pc[thread]+=regsize; + } + if (opcode == 0x03) { + address = (uint64_t)addr[cpu->pc[thread]] + | (uint64_t)addr[cpu->pc[thread]+1] << 8 + | (uint64_t)addr[cpu->pc[thread]+2] << 16 + | (uint64_t)addr[cpu->pc[thread]+3] << 24 + | (uint64_t)addr[cpu->pc[thread]+4] << 32 + | (uint64_t)addr[cpu->pc[thread]+5] << 40 + | (uint64_t)addr[cpu->pc[thread]+6] << 48 + | (uint64_t)addr[cpu->pc[thread]+7] << 56; + cpu->pc[thread]+=8; + iclk++; + } + if (opcode == 0x05) { + address = addr[cpu->pc[thread]] + | addr[cpu->pc[thread]+1] << 8 + | addr[cpu->pc[thread]+2] << 16 + | addr[cpu->pc[thread]+3] << 24; + cpu->pc[thread]+=4; + iclk++; + } + value = addr[address]; + if (regsize >= 2) { + value += (uint64_t)addr[address+1] << 8; + } + if (regsize >= 4) { + value += (uint64_t)addr[address+2] << 16; + value += (uint64_t)addr[address+3] << 24; + } + if (regsize >= 8) { + value += (uint64_t)addr[address+4] << 32; + value += (uint64_t)addr[address+5] << 40; + value += (uint64_t)addr[address+6] << 48; + value += (uint64_t)addr[address+7] << 56; + } + } else { + value = cpu->b[thread]; } sum = cpu->a[thread]+value+cpu->c[thread]; cpu->a[thread] = sum; @@ -183,6 +188,18 @@ void *run(void *args) { (cpu->v[thread]) ? (cpu->ps |= (V << 8*thread)) : (cpu->ps &= ~(V << 8*thread)); (cpu->c[thread]) ? (cpu->ps |= (C << 8*thread)) : (cpu->ps &= ~(C << 8*thread)); break; + case PHB: /* PusH B register to stack. */ + tmp = addr[cpu->pc[thread]++]; + if (tmp > 7) + tmp = 7; + for (int8_t i = tmp*8; i >= 0; i-=8) { + if (i) + addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->b[thread] >> i; + else + addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->b[thread] & 0xFF; + cpu->sp[thread]--; + } + break; case PHP: /* PusH Processor status to stack. */ tmp = addr[cpu->pc[thread]++]; if (tmp > 7) @@ -301,45 +318,50 @@ void *run(void *args) { cpu->pc[thread] = address; break; case SBC: /* SBC Immediate. */ + case SAB: /* Subtract Accumulator with carry by B register. */ case 0x13: /* SBC Absolute. */ case 0x15: /* SBC Zero Matrix. */ - if (opcode == SBC) { - address = cpu->pc[thread]; - cpu->pc[thread]+=regsize; - } - if (opcode == 0x13) { - address = (uint64_t)addr[cpu->pc[thread]] - | (uint64_t)addr[cpu->pc[thread]+1] << 8 - | (uint64_t)addr[cpu->pc[thread]+2] << 16 - | (uint64_t)addr[cpu->pc[thread]+3] << 24 - | (uint64_t)addr[cpu->pc[thread]+4] << 32 - | (uint64_t)addr[cpu->pc[thread]+5] << 40 - | (uint64_t)addr[cpu->pc[thread]+6] << 48 - | (uint64_t)addr[cpu->pc[thread]+7] << 56; - cpu->pc[thread]+=8; - iclk++; - } - if (opcode == 0x15) { - address = addr[cpu->pc[thread]] - | addr[cpu->pc[thread]+1] << 8 - | addr[cpu->pc[thread]+2] << 16 - | addr[cpu->pc[thread]+3] << 24; - cpu->pc[thread]+=4; - iclk++; - } - value = addr[address]; - if (regsize >= 2) { - value += (uint64_t)addr[address+1] << 8; - } - if (regsize >= 4) { - value += (uint64_t)addr[address+2] << 16; - value += (uint64_t)addr[address+3] << 24; - } - if (regsize >= 8) { - value += (uint64_t)addr[address+4] << 32; - value += (uint64_t)addr[address+5] << 40; - value += (uint64_t)addr[address+6] << 48; - value += (uint64_t)addr[address+7] << 56; + if (opcode != SAB) { + if (opcode == SBC) { + address = cpu->pc[thread]; + cpu->pc[thread]+=regsize; + } + if (opcode == 0x13) { + address = (uint64_t)addr[cpu->pc[thread]] + | (uint64_t)addr[cpu->pc[thread]+1] << 8 + | (uint64_t)addr[cpu->pc[thread]+2] << 16 + | (uint64_t)addr[cpu->pc[thread]+3] << 24 + | (uint64_t)addr[cpu->pc[thread]+4] << 32 + | (uint64_t)addr[cpu->pc[thread]+5] << 40 + | (uint64_t)addr[cpu->pc[thread]+6] << 48 + | (uint64_t)addr[cpu->pc[thread]+7] << 56; + cpu->pc[thread]+=8; + iclk++; + } + if (opcode == 0x15) { + address = addr[cpu->pc[thread]] + | addr[cpu->pc[thread]+1] << 8 + | addr[cpu->pc[thread]+2] << 16 + | addr[cpu->pc[thread]+3] << 24; + cpu->pc[thread]+=4; + iclk++; + } + value = addr[address]; + if (regsize >= 2) { + value += (uint64_t)addr[address+1] << 8; + } + if (regsize >= 4) { + value += (uint64_t)addr[address+2] << 16; + value += (uint64_t)addr[address+3] << 24; + } + if (regsize >= 8) { + value += (uint64_t)addr[address+4] << 32; + value += (uint64_t)addr[address+5] << 40; + value += (uint64_t)addr[address+6] << 48; + value += (uint64_t)addr[address+7] << 56; + } + } else { + value = cpu->b[thread]; } sum = cpu->a[thread]-value-!cpu->c[thread]; cpu->z[thread] = (sum == 0); @@ -352,6 +374,18 @@ void *run(void *args) { (cpu->c[thread]) ? (cpu->ps |= (C << 8*thread)) : (cpu->ps &= ~(C << 8*thread)); cpu->a[thread] = sum; break; + case PLB: /* PuLl B register from stack. */ + tmp = addr[cpu->pc[thread]++]; + if (tmp > 7) + tmp = 7; + for (uint8_t i = 0; i < (tmp+1)*8; i+=8) { + cpu->sp[thread]++; + if (i) + cpu->b[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << i; + else + cpu->b[thread] = (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] & 0xFF; + } + break; case PLP: /* PuLl Processor status from stack. */ tmp = addr[cpu->pc[thread]++]; if (tmp > 7) @@ -400,11 +434,28 @@ void *run(void *args) { cpu->x[thread] = (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] & 0xFF; } break; + case 0x34: /* JSR Indirect. */ + case 0x44: /* JSR Indexed Indirect. */ + case 0x54: /* JSR Indirect Indexed. */ case JSR: /* Jump to SubRoutine. */ address = (uint64_t)addr[cpu->pc[thread]] | (uint64_t)addr[cpu->pc[thread]+1] << 8 | (uint64_t)addr[cpu->pc[thread]+2] << 16 | (uint64_t)addr[cpu->pc[thread]+3] << 24; + if (opcode == 0x34 || opcode == 0x44 || opcode == 0x54) { + address = (uint64_t)addr[address] + | (uint64_t)addr[address+1] << 8 + | (uint64_t)addr[address+2] << 16 + | (uint64_t)addr[address+3] << 24 + | (uint64_t)addr[address+4] << 32 + | (uint64_t)addr[address+5] << 40 + | (uint64_t)addr[address+6] << 48 + | (uint64_t)addr[address+7] << 56; + if (opcode == 0x44) + address += cpu->x[thread]; + if (opcode == 0x54) + address += cpu->y[thread]; + } cpu->pc[thread]+=4; for (int8_t i = 24; i >= 0; i-=8) { if (i) @@ -416,73 +467,54 @@ void *run(void *args) { cpu->pc[thread] = address; break; case AND: /* AND Immediate. */ - case 0x29: /* AND Absolute. */ - case 0x2B: /* AND Zero Matrix. */ - case ANY: /* ANY Immediate. */ - case 0x52: /* ANY Absolute. */ - case 0x82: /* ANY Zero Matrix. */ - case ANX: /* ANX Immediate. */ - case 0x54: /* ANX Absolute. */ - case 0x84: /* ANX Zero Matrix. */ - if (opcode == AND || opcode == ANY || opcode == ANX) { - address = cpu->pc[thread]; - cpu->pc[thread]+=regsize; - } - if (opcode == 0x29 || opcode == 0x52 || opcode == 0x54) { - address = (uint64_t)addr[cpu->pc[thread]] - | (uint64_t)addr[cpu->pc[thread]+1] << 8 - | (uint64_t)addr[cpu->pc[thread]+2] << 16 - | (uint64_t)addr[cpu->pc[thread]+3] << 24 - | (uint64_t)addr[cpu->pc[thread]+4] << 32 - | (uint64_t)addr[cpu->pc[thread]+5] << 40 - | (uint64_t)addr[cpu->pc[thread]+6] << 48 - | (uint64_t)addr[cpu->pc[thread]+7] << 56; - cpu->pc[thread]+=8; - iclk++; - } - if (opcode == 0x2B || opcode == 0x82 || opcode == 0x84) { - address = addr[cpu->pc[thread]] - | addr[cpu->pc[thread]+1] << 8 - | addr[cpu->pc[thread]+2] << 16 - | addr[cpu->pc[thread]+3] << 24; - cpu->pc[thread]+=4; - iclk++; - } - value = (uint64_t)addr[address]; - if (regsize >= 2) - value += (uint64_t)addr[address+1] << 8; - if (regsize >= 4) { - value += (uint64_t)addr[address+2] << 16; - value += (uint64_t)addr[address+3] << 24; - } - if (regsize >= 8) { - value += (uint64_t)addr[address+4] << 32; - value += (uint64_t)addr[address+5] << 40; - value += (uint64_t)addr[address+6] << 48; - value += (uint64_t)addr[address+7] << 56; + case ABA: /* bitwise And with Accumulator, and B register. */ + case 0x23: /* AND Absolute. */ + case 0x25: /* AND Zero Matrix. */ + if (opcode != ABA) { + if (opcode == AND) { + address = cpu->pc[thread]; + cpu->pc[thread]+=regsize; + } + if (opcode == 0x23) { + address = (uint64_t)addr[cpu->pc[thread]] + | (uint64_t)addr[cpu->pc[thread]+1] << 8 + | (uint64_t)addr[cpu->pc[thread]+2] << 16 + | (uint64_t)addr[cpu->pc[thread]+3] << 24 + | (uint64_t)addr[cpu->pc[thread]+4] << 32 + | (uint64_t)addr[cpu->pc[thread]+5] << 40 + | (uint64_t)addr[cpu->pc[thread]+6] << 48 + | (uint64_t)addr[cpu->pc[thread]+7] << 56; + cpu->pc[thread]+=8; + iclk++; + } + if (opcode == 0x25) { + address = addr[cpu->pc[thread]] + | addr[cpu->pc[thread]+1] << 8 + | addr[cpu->pc[thread]+2] << 16 + | addr[cpu->pc[thread]+3] << 24; + cpu->pc[thread]+=4; + iclk++; + } + value = (uint64_t)addr[address]; + if (regsize >= 2) + value += (uint64_t)addr[address+1] << 8; + if (regsize >= 4) { + value += (uint64_t)addr[address+2] << 16; + value += (uint64_t)addr[address+3] << 24; + } + if (regsize >= 8) { + value += (uint64_t)addr[address+4] << 32; + value += (uint64_t)addr[address+5] << 40; + value += (uint64_t)addr[address+6] << 48; + value += (uint64_t)addr[address+7] << 56; + } } - if (opcode == AND || opcode == 0x29 || opcode == 0x2B) - cpu->a[thread] &= value; - if (opcode == ANY || opcode == 0x52 || opcode == 0x82) - cpu->y[thread] &= value; - if (opcode == ANX || opcode == 0x54 || opcode == 0x84) - cpu->x[thread] &= value; + cpu->a[thread] &= value; cpu->z[thread] = (value == 0); cpu->n[thread] = (value >> 63); (cpu->z[thread]) ? (cpu->ps |= (Z << 8*thread)) : (cpu->ps &= ~(Z << 8*thread)); (cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread)); break; - case AAY: - case AAX: - if (opcode == AAY) - cpu->a[thread] &= cpu->y[thread]; - if (opcode == AAX) - cpu->a[thread] &= cpu->x[thread]; - cpu->z[thread] = (sum == 0); - cpu->n[thread] = (sum >> 63); - (cpu->z[thread]) ? (cpu->ps |= (Z << 8*thread)) : (cpu->ps &= ~(Z << 8*thread)); - (cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread)); - break; case STT: /* STart Thread. */ address = cpu->pc[thread]; cpu->pc[thread]++; @@ -502,34 +534,9 @@ void *run(void *args) { } } break; - case BPO: /* Branch if POsitive. */ - address = (uint64_t)addr[cpu->pc[thread]] - | (uint64_t)addr[cpu->pc[thread]+1] << 8 - | (uint64_t)addr[cpu->pc[thread]+2] << 16 - | (uint64_t)addr[cpu->pc[thread]+3] << 24 - | (uint64_t)addr[cpu->pc[thread]+4] << 32 - | (uint64_t)addr[cpu->pc[thread]+5] << 40 - | (uint64_t)addr[cpu->pc[thread]+6] << 48 - | (uint64_t)addr[cpu->pc[thread]+7] << 56; - cpu->pc[thread]+=8; - iclk++; - if (cpu->n[thread]) - cpu->pc[thread] = address; - break; - case ORA: /* ORA Immediate. */ - case 0x39: /* ORA Absolute. */ - case 0x3B: /* ORA Zero Matrix. */ - case ORY: /* ORY Immediate. */ - case 0x62: /* ORY Absolute. */ - case 0x92: /* ORY Zero Matrix. */ - case ORX: /* ORX Immediate. */ - case 0x64: /* ORX Absolute. */ - case 0x94: /* ORX Zero Matrix. */ - if (opcode == ORA || opcode == ORY || opcode == ORX) { - address = cpu->pc[thread]; - cpu->pc[thread]+=regsize; - } - if (opcode == 0x39 || opcode == 0x62 || opcode == 0x64) { + case BPO: /* BPO Absolute. */ + case 0x64: /* BPO Zero Matrix. */ + if (opcode == BPO) { address = (uint64_t)addr[cpu->pc[thread]] | (uint64_t)addr[cpu->pc[thread]+1] << 8 | (uint64_t)addr[cpu->pc[thread]+2] << 16 @@ -540,8 +547,7 @@ void *run(void *args) { | (uint64_t)addr[cpu->pc[thread]+7] << 56; cpu->pc[thread]+=8; iclk++; - } - if (opcode == 0x3B || opcode == 0x92 || opcode == 0x94) { + } else { address = addr[cpu->pc[thread]] | addr[cpu->pc[thread]+1] << 8 | addr[cpu->pc[thread]+2] << 16 @@ -549,73 +555,67 @@ void *run(void *args) { cpu->pc[thread]+=4; iclk++; } - value = (uint64_t)addr[address]; - if (regsize >= 2) - value += (uint64_t)addr[address+1] << 8; - if (regsize >= 4) { - value += (uint64_t)addr[address+2] << 16; - value += (uint64_t)addr[address+3] << 24; - } - if (regsize >= 8) { - value += (uint64_t)addr[address+4] << 32; - value += (uint64_t)addr[address+5] << 40; - value += (uint64_t)addr[address+6] << 48; - value += (uint64_t)addr[address+7] << 56; + if (cpu->n[thread]) + cpu->pc[thread] = address; + break; + case ORA: /* ORA Immediate. */ + case OAB: /* bitwise Or with Accumulator, and B register. */ + case 0x33: /* ORA Absolute. */ + case 0x35: /* ORA Zero Matrix. */ + if (opcode != OAB) { + if (opcode == ORA) { + address = cpu->pc[thread]; + cpu->pc[thread]+=regsize; + } + if (opcode == 0x39) { + address = (uint64_t)addr[cpu->pc[thread]] + | (uint64_t)addr[cpu->pc[thread]+1] << 8 + | (uint64_t)addr[cpu->pc[thread]+2] << 16 + | (uint64_t)addr[cpu->pc[thread]+3] << 24 + | (uint64_t)addr[cpu->pc[thread]+4] << 32 + | (uint64_t)addr[cpu->pc[thread]+5] << 40 + | (uint64_t)addr[cpu->pc[thread]+6] << 48 + | (uint64_t)addr[cpu->pc[thread]+7] << 56; + cpu->pc[thread]+=8; + iclk++; + } + if (opcode == 0x3B) { + address = addr[cpu->pc[thread]] + | addr[cpu->pc[thread]+1] << 8 + | addr[cpu->pc[thread]+2] << 16 + | addr[cpu->pc[thread]+3] << 24; + cpu->pc[thread]+=4; + iclk++; + } + value = (uint64_t)addr[address]; + if (regsize >= 2) + value += (uint64_t)addr[address+1] << 8; + if (regsize >= 4) { + value += (uint64_t)addr[address+2] << 16; + value += (uint64_t)addr[address+3] << 24; + } + if (regsize >= 8) { + value += (uint64_t)addr[address+4] << 32; + value += (uint64_t)addr[address+5] << 40; + value += (uint64_t)addr[address+6] << 48; + value += (uint64_t)addr[address+7] << 56; + } + } else { + value = cpu->b[thread]; } - if (opcode == ORA || opcode == 0x39 || opcode == 0x3B) - cpu->a[thread] |= value; - if (opcode == ORY || opcode == 0x62 || opcode == 0x92) - cpu->y[thread] |= value; - if (opcode == ORX || opcode == 0x64 || opcode == 0x94) - cpu->x[thread] |= value; + cpu->a[thread] |= value; cpu->z[thread] = (value == 0); cpu->n[thread] = (value >> 63); (cpu->z[thread]) ? (cpu->ps |= (Z << 8*thread)) : (cpu->ps &= ~(Z << 8*thread)); (cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread)); break; - case OAY: - case OAX: - if (opcode == OAY) - cpu->a[thread] |= cpu->y[thread]; - if (opcode == OAX) - cpu->a[thread] |= cpu->x[thread]; - cpu->z[thread] = (sum == 0); - cpu->n[thread] = (sum >> 63); - (cpu->z[thread]) ? (cpu->ps |= (Z << 8*thread)) : (cpu->ps &= ~(Z << 8*thread)); - (cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread)); - break; case SEI: /* SEt Interrupt. */ cpu->i[thread] = 1; (cpu->ps |= (I << 8*thread)); break; - case BNG: /* Branch if NeGative. */ - address = (uint64_t)addr[cpu->pc[thread]] - | (uint64_t)addr[cpu->pc[thread]+1] << 8 - | (uint64_t)addr[cpu->pc[thread]+2] << 16 - | (uint64_t)addr[cpu->pc[thread]+3] << 24 - | (uint64_t)addr[cpu->pc[thread]+4] << 32 - | (uint64_t)addr[cpu->pc[thread]+5] << 40 - | (uint64_t)addr[cpu->pc[thread]+6] << 48 - | (uint64_t)addr[cpu->pc[thread]+7] << 56; - cpu->pc[thread]+=8; - iclk++; - if (!cpu->n[thread]) - cpu->pc[thread] = address; - break; - case XOR: /* XOR Immediate. */ - case 0x49: /* XOR Absolute. */ - case 0x4B: /* XOR Zero Matrix. */ - case XRY: /* XRY Immediate. */ - case 0x72: /* XRY Absolute. */ - case 0xA2: /* XRY Zero Matrix. */ - case XRX: /* XRX Immediate. */ - case 0x74: /* XRX Absolute. */ - case 0xA4: /* XRX Zero Matrix. */ - if (opcode == XOR || opcode == XRY || opcode == XRX) { - address = cpu->pc[thread]; - cpu->pc[thread]+=regsize; - } - if (opcode == 0x49 || opcode == 0x72 || opcode == 0x74) { + case BNG: /* BNG Absolute. */ + case 0x74: /* BNG Zero Matrix. */ + if (opcode == BNG) { address = (uint64_t)addr[cpu->pc[thread]] | (uint64_t)addr[cpu->pc[thread]+1] << 8 | (uint64_t)addr[cpu->pc[thread]+2] << 16 @@ -626,8 +626,7 @@ void *run(void *args) { | (uint64_t)addr[cpu->pc[thread]+7] << 56; cpu->pc[thread]+=8; iclk++; - } - if (opcode == 0x4B || opcode == 0xA2 || opcode == 0xA4) { + } else { address = addr[cpu->pc[thread]] | addr[cpu->pc[thread]+1] << 8 | addr[cpu->pc[thread]+2] << 16 @@ -635,67 +634,67 @@ void *run(void *args) { cpu->pc[thread]+=4; iclk++; } - value = (uint64_t)addr[address]; - if (regsize >= 2) - value += (uint64_t)addr[address+1] << 8; - if (regsize >= 4) { - value += (uint64_t)addr[address+2] << 16; - value += (uint64_t)addr[address+3] << 24; - } - if (regsize >= 8) { - value += (uint64_t)addr[address+4] << 32; - value += (uint64_t)addr[address+5] << 40; - value += (uint64_t)addr[address+6] << 48; - value += (uint64_t)addr[address+7] << 56; + if (!cpu->n[thread]) + cpu->pc[thread] = address; + break; + case XOR: /* XOR Immediate. */ + case XAB: /* bitwise Xor with Accumulator, and B register. */ + case 0x43: /* XOR Absolute. */ + case 0x45: /* XOR Zero Matrix. */ + if (opcode != XAB) { + if (opcode == XOR) { + address = cpu->pc[thread]; + cpu->pc[thread]+=regsize; + } + if (opcode == 0x49) { + address = (uint64_t)addr[cpu->pc[thread]] + | (uint64_t)addr[cpu->pc[thread]+1] << 8 + | (uint64_t)addr[cpu->pc[thread]+2] << 16 + | (uint64_t)addr[cpu->pc[thread]+3] << 24 + | (uint64_t)addr[cpu->pc[thread]+4] << 32 + | (uint64_t)addr[cpu->pc[thread]+5] << 40 + | (uint64_t)addr[cpu->pc[thread]+6] << 48 + | (uint64_t)addr[cpu->pc[thread]+7] << 56; + cpu->pc[thread]+=8; + iclk++; + } + if (opcode == 0x4B) { + address = addr[cpu->pc[thread]] + | addr[cpu->pc[thread]+1] << 8 + | addr[cpu->pc[thread]+2] << 16 + | addr[cpu->pc[thread]+3] << 24; + cpu->pc[thread]+=4; + iclk++; + } + value = (uint64_t)addr[address]; + if (regsize >= 2) + value += (uint64_t)addr[address+1] << 8; + if (regsize >= 4) { + value += (uint64_t)addr[address+2] << 16; + value += (uint64_t)addr[address+3] << 24; + } + if (regsize >= 8) { + value += (uint64_t)addr[address+4] << 32; + value += (uint64_t)addr[address+5] << 40; + value += (uint64_t)addr[address+6] << 48; + value += (uint64_t)addr[address+7] << 56; + } + } else { + value = cpu->b[thread]; } - if (opcode == XOR || opcode == 0x49 || opcode == 0x4B) - cpu->a[thread] ^= value; - if (opcode == ORY || opcode == 0x72 || opcode == 0xA2) - cpu->y[thread] ^= value; - if (opcode == ORX || opcode == 0x74 || opcode == 0xA4) - cpu->x[thread] ^= value; + cpu->a[thread] ^= value; cpu->z[thread] = (value == 0); cpu->n[thread] = (value >> 63); (cpu->z[thread]) ? (cpu->ps |= (Z << 8*thread)) : (cpu->ps &= ~(Z << 8*thread)); (cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread)); break; - case XAY: - case XAX: - if (opcode == XAY) - cpu->a[thread] ^= cpu->y[thread]; - if (opcode == XAX) - cpu->a[thread] ^= cpu->x[thread]; - cpu->z[thread] = (sum == 0); - cpu->n[thread] = (sum >> 63); - (cpu->z[thread]) ? (cpu->ps |= (Z << 8*thread)) : (cpu->ps &= ~(Z << 8*thread)); - (cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread)); - break; case CLI: /* CLear Interrupt. */ cpu->i[thread] = 0; (cpu->ps &= ~(I << 8*thread)); break; - case BCS: /* Branch if Carry Set. */ - address = (uint64_t)addr[cpu->pc[thread]] - | (uint64_t)addr[cpu->pc[thread]+1] << 8 - | (uint64_t)addr[cpu->pc[thread]+2] << 16 - | (uint64_t)addr[cpu->pc[thread]+3] << 24 - | (uint64_t)addr[cpu->pc[thread]+4] << 32 - | (uint64_t)addr[cpu->pc[thread]+5] << 40 - | (uint64_t)addr[cpu->pc[thread]+6] << 48 - | (uint64_t)addr[cpu->pc[thread]+7] << 56; - cpu->pc[thread]+=8; - iclk++; - if (cpu->c[thread]) - cpu->pc[thread] = address; - break; - case LSL: /* LSL Immediate. */ - case 0x53: /* LSL Absolute. */ - case 0x55: /* LSL Zero Matrix. */ - if (opcode == LSL) { - address = cpu->pc[thread]; - cpu->pc[thread]++; - } - if (opcode == 0x53) { + case BCS: /* BCS Absolute. */ + case 0x84: /* BCS Zero Matrix. */ + if (opcode == BCS) { address = (uint64_t)addr[cpu->pc[thread]] | (uint64_t)addr[cpu->pc[thread]+1] << 8 | (uint64_t)addr[cpu->pc[thread]+2] << 16 @@ -704,11 +703,9 @@ void *run(void *args) { | (uint64_t)addr[cpu->pc[thread]+5] << 40 | (uint64_t)addr[cpu->pc[thread]+6] << 48 | (uint64_t)addr[cpu->pc[thread]+7] << 56; - cpu->pc[thread]+=8; iclk++; - } - if (opcode == 0x55) { + } else { address = addr[cpu->pc[thread]] | addr[cpu->pc[thread]+1] << 8 | addr[cpu->pc[thread]+2] << 16 @@ -716,7 +713,43 @@ void *run(void *args) { cpu->pc[thread]+=4; iclk++; } - value = addr[address]; + if (cpu->c[thread]) + cpu->pc[thread] = address; + break; + case LSL: /* LSL Immediate. */ + case LLB: /* Logical shift Left accumulator by B. */ + case 0x53: /* LSL Absolute. */ + case 0x55: /* LSL Zero Matrix. */ + if (opcode != LLB) { + if (opcode == LSL) { + address = cpu->pc[thread]; + cpu->pc[thread]++; + } + if (opcode == 0x53) { + address = (uint64_t)addr[cpu->pc[thread]] + | (uint64_t)addr[cpu->pc[thread]+1] << 8 + | (uint64_t)addr[cpu->pc[thread]+2] << 16 + | (uint64_t)addr[cpu->pc[thread]+3] << 24 + | (uint64_t)addr[cpu->pc[thread]+4] << 32 + | (uint64_t)addr[cpu->pc[thread]+5] << 40 + | (uint64_t)addr[cpu->pc[thread]+6] << 48 + | (uint64_t)addr[cpu->pc[thread]+7] << 56; + + cpu->pc[thread]+=8; + iclk++; + } + if (opcode == 0x55) { + address = addr[cpu->pc[thread]] + | addr[cpu->pc[thread]+1] << 8 + | addr[cpu->pc[thread]+2] << 16 + | addr[cpu->pc[thread]+3] << 24; + cpu->pc[thread]+=4; + iclk++; + } + value = addr[address]; + } else { + value = cpu->b[thread]; + } sum = (value < 64) ? cpu->a[thread] << value : 0; cpu->z[thread] = (sum == 0); cpu->n[thread] = (sum >> 63); @@ -733,14 +766,28 @@ void *run(void *args) { case STA: /* STA Absolute. */ case STY: /* STY Absolute. */ case STX: /* STX Absolute. */ + case STB: /* STB Absolute. */ case 0x7B: /* STA Zero Matrix. */ case 0x7D: /* STY Zero Matrix. */ case 0x7E: /* STX Zero Matrix. */ + case 0x7F: /* STB Zero Matrix. */ case 0x8B: /* STA Zero Matrix, Indexed with X. */ case 0x8D: /* STY Zero Matrix, Indexed with X. */ + case 0x8F: /* STA Zero Matrix, Indexed with X. */ case 0x9B: /* STA Zero Matrix, Indexed with Y. */ case 0x9E: /* STX Zero Matrix, Indexed with Y. */ - if (opcode == STA || opcode == STY || opcode == STX) { + case 0x9F: /* STA Zero Matrix, Indexed with Y. */ + case 0xAB: /* STA Indirect. */ + case 0xAD: /* STY Indirect. */ + case 0xAE: /* STX Indirect. */ + case 0xAF: /* STB Indirect. */ + case 0xBB: /* STA Indexed Indirect. */ + case 0xBD: /* STY Indexed Indirect. */ + case 0xBF: /* STB Indexed Indirect. */ + case 0xCB: /* STA Indirect Indexed. */ + case 0xCE: /* STX Indirect Indexed. */ + case 0xCF: /* STB Indirect Indexed. */ + if (opcode == STA || opcode == STY || opcode == STX || opcode == STB) { address = (uint64_t)addr[cpu->pc[thread]] | (uint64_t)addr[cpu->pc[thread]+1] << 8 | (uint64_t)addr[cpu->pc[thread]+2] << 16 @@ -751,15 +798,27 @@ void *run(void *args) { | (uint64_t)addr[cpu->pc[thread]+7] << 56; cpu->pc[thread]+=8; iclk++; - } - if (opcode == 0x7B || opcode == 0x7D || opcode == 0x7E || opcode == 0x8B || opcode == 0x8D || opcode == 0x9B || opcode == 0x9E) { + } else { address = addr[cpu->pc[thread]] | addr[cpu->pc[thread]+1] << 8 | addr[cpu->pc[thread]+2] << 16 | addr[cpu->pc[thread]+3] << 24; - if (opcode == 0x8B || opcode == 0x8D) + if (opcode == 0xAB || opcode == 0xAD || opcode == 0xAE || opcode == 0xAF || opcode == 0xBB || + opcode == 0xBD || opcode == 0xBF || opcode == 0xCB || opcode == 0xCE || opcode == 0xCF) { + address = (uint64_t)addr[address] + | (uint64_t)addr[address+1] << 8 + | (uint64_t)addr[address+2] << 16 + | (uint64_t)addr[address+3] << 24 + | (uint64_t)addr[address+4] << 32 + | (uint64_t)addr[address+5] << 40 + | (uint64_t)addr[address+6] << 48 + | (uint64_t)addr[address+7] << 56; + } + if (opcode == 0x8B || opcode == 0x8D || opcode == 0x8F || + opcode == 0xBB || opcode == 0xBD || opcode == 0xBF) address += cpu->x[thread]; - if (opcode == 0x9B || opcode == 0x9E) + if (opcode == 0x9B || opcode == 0x9E || opcode == 0x9F || + opcode == 0xCB || opcode == 0xCE || opcode == 0xCF) address += cpu->y[thread]; cpu->pc[thread]+=4; iclk++; @@ -770,6 +829,8 @@ void *run(void *args) { value = cpu->y[thread]; if (opcode == STX || opcode == 0x7E || opcode == 0x9E) value = cpu->x[thread]; + if (opcode == STB || opcode == 0x7F || opcode == 0x8F || opcode == 0x9F) + value = cpu->b[thread]; addr[address] = value & 0xFF; #if IO if (address == TX_ADDR) { @@ -894,6 +955,7 @@ void *run(void *args) { x = 0; else x = ((bcd[1]*10) + bcd[0]); + mvwprintw(scr, getmaxy(scr)-25, 0, "x: %i, y: %i ", x, y); idx = 3; bcd[0] = 0; bcd[1] = 0; @@ -916,6 +978,7 @@ void *run(void *args) { default: iscol = (addr[address] == ';'); break; + } } else { if (addr[address] == CURSES_BACKSPACE || addr[address] == '\b') { if (x > 0) { @@ -947,31 +1010,9 @@ void *run(void *args) { addr[address+7] = value >> 56; } break; - case BCC: /* Branch if Carry Clear. */ - address = (uint64_t)addr[cpu->pc[thread]] - | (uint64_t)addr[cpu->pc[thread]+1] << 8 - | (uint64_t)addr[cpu->pc[thread]+2] << 16 - | (uint64_t)addr[cpu->pc[thread]+3] << 24 - | (uint64_t)addr[cpu->pc[thread]+4] << 32 - | (uint64_t)addr[cpu->pc[thread]+5] << 40 - | (uint64_t)addr[cpu->pc[thread]+6] << 48 - | (uint64_t)addr[cpu->pc[thread]+7] << 56; - cpu->pc[thread]+=8; - iclk++; - if (!cpu->c[thread]) - cpu->pc[thread] = address; - break; - case LSR: /* LSR Immediate. */ - case 0x63: /* LSR Absolute. */ - case 0x65: /* LSR Zero Matrix. */ - case ASR: /* ASR Immediate. */ - case 0xAB: /* ASR Absolute. */ - case 0xAD: /* ASR Zero Matrix. */ - if (opcode == LSR || opcode == ASR) { - address = cpu->pc[thread]; - cpu->pc[thread]++; - } - if (opcode == 0x63 || opcode == 0xAB) { + case BCC: /* BCC Absolute. */ + case 0x94: /* BCC Zero Matrix. */ + if (opcode == BCC) { address = (uint64_t)addr[cpu->pc[thread]] | (uint64_t)addr[cpu->pc[thread]+1] << 8 | (uint64_t)addr[cpu->pc[thread]+2] << 16 @@ -982,8 +1023,7 @@ void *run(void *args) { | (uint64_t)addr[cpu->pc[thread]+7] << 56; cpu->pc[thread]+=8; iclk++; - } - if (opcode == 0x65 || opcode == 0xAD) { + } else { address = addr[cpu->pc[thread]] | addr[cpu->pc[thread]+1] << 8 | addr[cpu->pc[thread]+2] << 16 @@ -991,12 +1031,51 @@ void *run(void *args) { cpu->pc[thread]+=4; iclk++; } - value = addr[address]; - if (opcode == ASR || opcode == 0xAB || opcode == 0xAD) { + if (!cpu->c[thread]) + cpu->pc[thread] = address; + break; + case LSR: /* LSR Immediate. */ + case LRB: /* Logical shift Right accumulator by B. */ + case 0x63: /* LSR Absolute. */ + case 0x65: /* LSR Zero Matrix. */ + case ASR: /* ASR Immediate. */ + case ARB: /* Arithmetic shift Right accumulator by B. */ + case 0xE3: /* ASR Absolute. */ + case 0xE5: /* ASR Zero Matrix. */ + if (opcode != LRB || opcode != ARB) { + if (opcode == LSR || opcode == ASR) { + address = cpu->pc[thread]; + cpu->pc[thread]++; + } + if (opcode == 0x63 || opcode == 0xE3) { + address = (uint64_t)addr[cpu->pc[thread]] + | (uint64_t)addr[cpu->pc[thread]+1] << 8 + | (uint64_t)addr[cpu->pc[thread]+2] << 16 + | (uint64_t)addr[cpu->pc[thread]+3] << 24 + | (uint64_t)addr[cpu->pc[thread]+4] << 32 + | (uint64_t)addr[cpu->pc[thread]+5] << 40 + | (uint64_t)addr[cpu->pc[thread]+6] << 48 + | (uint64_t)addr[cpu->pc[thread]+7] << 56; + cpu->pc[thread]+=8; + iclk++; + } + if (opcode == 0x65 || opcode == 0xE5) { + address = addr[cpu->pc[thread]] + | addr[cpu->pc[thread]+1] << 8 + | addr[cpu->pc[thread]+2] << 16 + | addr[cpu->pc[thread]+3] << 24; + cpu->pc[thread]+=4; + iclk++; + } + value = addr[address]; + } else { + value = cpu->b[thread]; + } + if (opcode == ASR || opcode == ARB || opcode == 0xE3 || opcode == 0xE5) { sign = cpu->a[thread] & 0x8000000000000000; sum = (value < 64) ? (cpu->a[thread] >> value) | sign : 0; } - if (opcode == LSR || opcode == 0x63 || opcode == 0x65) { + if (opcode == LSR || opcode == LRB || opcode == 0x63 || opcode == 0x65) { sum = (value < 64) ? cpu->a[thread] >> value : 0; } cpu->z[thread] = (sum == 0); @@ -1011,24 +1090,38 @@ void *run(void *args) { cpu->c[thread] = 0; (cpu->ps &= ~(C << 8*thread)); break; + case 0x56: /* LDB Absolute. */ case 0x59: /* LDA Absolute. */ case 0x5A: /* LDY Absolute. */ case 0x5C: /* LDX Absolute. */ + case LDB: /* LDB Immediate. */ case LDA: /* LDA Immediate. */ case LDY: /* LDY Immediate. */ case LDX: /* LDX Immediate. */ + case 0x76: /* LDB Zero Matrix. */ case 0x79: /* LDA Zero Matrix. */ case 0x7A: /* LDY Zero Matrix. */ case 0x7C: /* LDX Zero Matrix. */ + case 0x86: /* LDB Zero Matrix, Indexed with X. */ case 0x89: /* LDA Zero Matrix, Indexed with X. */ case 0x8A: /* LDY Zero Matrix, Indexed with X. */ + case 0x96: /* LDB Zero Matrix, Indexed with Y. */ case 0x99: /* LDA Zero Matrix, Indexed with Y. */ case 0x9C: /* LDX Zero Matrix, Indexed with Y. */ - if (opcode == LDA || opcode == LDY || opcode == LDX) { + case 0xA6: /* LDB Indirect. */ + case 0xA9: /* LDA Indirect. */ + case 0xAA: /* LDY Indirect. */ + case 0xAC: /* LDX Indirect. */ + case 0xB6: /* LDB Indexed Indirect. */ + case 0xB9: /* LDA Indexed Indirect. */ + case 0xBA: /* LDY Indexed Indirect. */ + case 0xC6: /* LDB Indirect Indexed. */ + case 0xC9: /* LDA Indirect Indexed. */ + case 0xCC: /* LDX Indirect Indexed. */ + if (opcode == LDB || opcode == LDA || opcode == LDY || opcode == LDX) { address = cpu->pc[thread]; cpu->pc[thread]+=regsize; - } - if (opcode == 0x59 || opcode == 0x5A || opcode == 0x5C) { + } else if (opcode == 0x56 || opcode == 0x59 || opcode == 0x5A || opcode == 0x5C) { address = (uint64_t)addr[cpu->pc[thread]] | (uint64_t)addr[cpu->pc[thread]+1] << 8 | (uint64_t)addr[cpu->pc[thread]+2] << 16 @@ -1039,15 +1132,27 @@ void *run(void *args) { | (uint64_t)addr[cpu->pc[thread]+7] << 56; cpu->pc[thread]+=8; iclk++; - } - if (opcode == 0x79 || opcode == 0x7A || opcode == 0x7C || opcode == 0x89 || opcode == 0x8A || opcode == 0x99 || opcode == 0x9C) { + } else { address = addr[cpu->pc[thread]] | addr[cpu->pc[thread]+1] << 8 | addr[cpu->pc[thread]+2] << 16 | addr[cpu->pc[thread]+3] << 24; - if (opcode == 0x89 || opcode == 0x8A) + if (opcode == 0xA6 || opcode == 0xA9 || opcode == 0xAA || opcode == 0xAC || opcode == 0xB6 || + opcode == 0xB9 || opcode == 0xBA || opcode == 0xC6 || opcode == 0xC9 || opcode == 0xCC) { + address = (uint64_t)addr[address] + | (uint64_t)addr[address+1] << 8 + | (uint64_t)addr[address+2] << 16 + | (uint64_t)addr[address+3] << 24 + | (uint64_t)addr[address+4] << 32 + | (uint64_t)addr[address+5] << 40 + | (uint64_t)addr[address+6] << 48 + | (uint64_t)addr[address+7] << 56; + } + if (opcode == 0x86 || opcode == 0x89 || opcode == 0x8A || + opcode == 0xB6 || opcode == 0xB9 || opcode == 0xBA) address += cpu->x[thread]; - if (opcode == 0x99 || opcode == 0x9C) + if (opcode == 0x96 || opcode == 0x99 || opcode == 0x9C || + opcode == 0xC6 || opcode == 0xC9 || opcode == 0xCC) address += cpu->y[thread]; cpu->pc[thread]+=4; iclk++; @@ -1075,6 +1180,8 @@ void *run(void *args) { value += (uint64_t)addr[address+6] << 48; value += (uint64_t)addr[address+7] << 56; } + if (opcode == LDB || opcode == 0x56 || opcode == 0x76 || opcode == 0x86 || opcode == 0x96) + cpu->b[thread] = value; if (opcode == LDA || opcode == 0x59 || opcode == 0x79 || opcode == 0x89 || opcode == 0x99) cpu->a[thread] = value; if (opcode == LDY || opcode == 0x5A || opcode == 0x7A || opcode == 0x8A) @@ -1086,28 +1193,9 @@ void *run(void *args) { (cpu->z[thread]) ? (cpu->ps |= (Z << 8*thread)) : (cpu->ps &= ~(Z << 8*thread)); (cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread)); break; - case BEQ: /* Branch if EQual. */ - address = (uint64_t)addr[cpu->pc[thread]] - | (uint64_t)addr[cpu->pc[thread]+1] << 8 - | (uint64_t)addr[cpu->pc[thread]+2] << 16 - | (uint64_t)addr[cpu->pc[thread]+3] << 24 - | (uint64_t)addr[cpu->pc[thread]+4] << 32 - | (uint64_t)addr[cpu->pc[thread]+5] << 40 - | (uint64_t)addr[cpu->pc[thread]+6] << 48 - | (uint64_t)addr[cpu->pc[thread]+7] << 56; - cpu->pc[thread]+=8; - iclk++; - if (cpu->z[thread]) - cpu->pc[thread] = address; - break; - case ROL: /* ROL Immediate. */ - case 0x73: /* ROL Absolute. */ - case 0x75: /* ROL Zero Matrix. */ - if (opcode == ROL) { - address = cpu->pc[thread]; - cpu->pc[thread]++; - } - if (opcode == 0x73) { + case BEQ: /* BEQ Absolute. */ + case 0xA4: /* BEQ Zero Matrix. */ + if (opcode == BEQ) { address = (uint64_t)addr[cpu->pc[thread]] | (uint64_t)addr[cpu->pc[thread]+1] << 8 | (uint64_t)addr[cpu->pc[thread]+2] << 16 @@ -1118,8 +1206,7 @@ void *run(void *args) { | (uint64_t)addr[cpu->pc[thread]+7] << 56; cpu->pc[thread]+=8; iclk++; - } - if (opcode == 0x75) { + } else { address = addr[cpu->pc[thread]] | addr[cpu->pc[thread]+1] << 8 | addr[cpu->pc[thread]+2] << 16 @@ -1127,7 +1214,42 @@ void *run(void *args) { cpu->pc[thread]+=4; iclk++; } - value = addr[address]; + if (cpu->z[thread]) + cpu->pc[thread] = address; + break; + case ROL: /* ROL Immediate. */ + case RLB: /* Rotate Left accumulator by B. */ + case 0x73: /* ROL Absolute. */ + case 0x75: /* ROL Zero Matrix. */ + if (opcode != RLB) { + if (opcode == ROL) { + address = cpu->pc[thread]; + cpu->pc[thread]++; + } + if (opcode == 0x73) { + address = (uint64_t)addr[cpu->pc[thread]] + | (uint64_t)addr[cpu->pc[thread]+1] << 8 + | (uint64_t)addr[cpu->pc[thread]+2] << 16 + | (uint64_t)addr[cpu->pc[thread]+3] << 24 + | (uint64_t)addr[cpu->pc[thread]+4] << 32 + | (uint64_t)addr[cpu->pc[thread]+5] << 40 + | (uint64_t)addr[cpu->pc[thread]+6] << 48 + | (uint64_t)addr[cpu->pc[thread]+7] << 56; + cpu->pc[thread]+=8; + iclk++; + } + if (opcode == 0x75) { + address = addr[cpu->pc[thread]] + | addr[cpu->pc[thread]+1] << 8 + | addr[cpu->pc[thread]+2] << 16 + | addr[cpu->pc[thread]+3] << 24; + cpu->pc[thread]+=4; + iclk++; + } + value = addr[address]; + } else { + value = cpu->b[thread]; + } sum = cpu->a[thread] << value; sum |= cpu->c[thread]; cpu->z[thread] = (sum == 0); @@ -1142,28 +1264,9 @@ void *run(void *args) { cpu->s[thread] = 1; (cpu->ps |= (S << 8*thread)); break; - case BNE: /* Branch if Not Equal. */ - address = (uint64_t)addr[cpu->pc[thread]] - | (uint64_t)addr[cpu->pc[thread]+1] << 8 - | (uint64_t)addr[cpu->pc[thread]+2] << 16 - | (uint64_t)addr[cpu->pc[thread]+3] << 24 - | (uint64_t)addr[cpu->pc[thread]+4] << 32 - | (uint64_t)addr[cpu->pc[thread]+5] << 40 - | (uint64_t)addr[cpu->pc[thread]+6] << 48 - | (uint64_t)addr[cpu->pc[thread]+7] << 56; - cpu->pc[thread]+=8; - iclk++; - if (!cpu->z[thread]) - cpu->pc[thread] = address; - break; - case ROR: /* ROR Immediate. */ - case 0x83: /* ROR Absolute. */ - case 0x85: /* ROR Zero Matrix. */ - if (opcode == ROR) { - address = cpu->pc[thread]; - cpu->pc[thread]++; - } - if (opcode == 0x83) { + case BNE: /* BNE Absolute. */ + case 0xB4: /* BNE Zero Matrix. */ + if (opcode == BNE) { address = (uint64_t)addr[cpu->pc[thread]] | (uint64_t)addr[cpu->pc[thread]+1] << 8 | (uint64_t)addr[cpu->pc[thread]+2] << 16 @@ -1174,8 +1277,7 @@ void *run(void *args) { | (uint64_t)addr[cpu->pc[thread]+7] << 56; cpu->pc[thread]+=8; iclk++; - } - if (opcode == 0x85) { + } else { address = addr[cpu->pc[thread]] | addr[cpu->pc[thread]+1] << 8 | addr[cpu->pc[thread]+2] << 16 @@ -1183,7 +1285,42 @@ void *run(void *args) { cpu->pc[thread]+=4; iclk++; } - value = addr[address]; + if (!cpu->z[thread]) + cpu->pc[thread] = address; + break; + case ROR: /* ROR Immediate. */ + case RRB: /* Rotate Right accumulator by B. */ + case 0x83: /* ROR Absolute. */ + case 0x85: /* ROR Zero Matrix. */ + if (opcode != RRB) { + if (opcode == ROR) { + address = cpu->pc[thread]; + cpu->pc[thread]++; + } + if (opcode == 0x83) { + address = (uint64_t)addr[cpu->pc[thread]] + | (uint64_t)addr[cpu->pc[thread]+1] << 8 + | (uint64_t)addr[cpu->pc[thread]+2] << 16 + | (uint64_t)addr[cpu->pc[thread]+3] << 24 + | (uint64_t)addr[cpu->pc[thread]+4] << 32 + | (uint64_t)addr[cpu->pc[thread]+5] << 40 + | (uint64_t)addr[cpu->pc[thread]+6] << 48 + | (uint64_t)addr[cpu->pc[thread]+7] << 56; + cpu->pc[thread]+=8; + iclk++; + } + if (opcode == 0x85) { + address = addr[cpu->pc[thread]] + | addr[cpu->pc[thread]+1] << 8 + | addr[cpu->pc[thread]+2] << 16 + | addr[cpu->pc[thread]+3] << 24; + cpu->pc[thread]+=4; + iclk++; + } + value = addr[address]; + } else { + value = cpu->b[thread]; + } sum = cpu->a[thread] >> value; sum |= (uint64_t)cpu->c[thread] << (uint64_t)64-value; cpu->z[thread] = (sum == 0); @@ -1198,28 +1335,9 @@ void *run(void *args) { cpu->s[thread] = 0; (cpu->ps &= ~(S << 8*thread)); break; - case BVS: /* Branch if oVerflow Set. */ - address = (uint64_t)addr[cpu->pc[thread]] - | (uint64_t)addr[cpu->pc[thread]+1] << 8 - | (uint64_t)addr[cpu->pc[thread]+2] << 16 - | (uint64_t)addr[cpu->pc[thread]+3] << 24 - | (uint64_t)addr[cpu->pc[thread]+4] << 32 - | (uint64_t)addr[cpu->pc[thread]+5] << 40 - | (uint64_t)addr[cpu->pc[thread]+6] << 48 - | (uint64_t)addr[cpu->pc[thread]+7] << 56; - cpu->pc[thread]+=8; - iclk++; - if (cpu->v[thread]) - cpu->pc[thread] = address; - break; - case MUL: /* MUL Immediate. */ - case 0x93: /* MUL Absolute. */ - case 0x95: /* MUL Zero Matrix. */ - if (opcode == MUL) { - address = cpu->pc[thread]; - cpu->pc[thread]+=regsize; - } - if (opcode == 0x93) { + case BVS: /* BVS Absolute. */ + case 0xC4: /* BVS Zero Matrix. */ + if (opcode == BVS) { address = (uint64_t)addr[cpu->pc[thread]] | (uint64_t)addr[cpu->pc[thread]+1] << 8 | (uint64_t)addr[cpu->pc[thread]+2] << 16 @@ -1230,8 +1348,7 @@ void *run(void *args) { | (uint64_t)addr[cpu->pc[thread]+7] << 56; cpu->pc[thread]+=8; iclk++; - } - if (opcode == 0x95) { + } else { address = addr[cpu->pc[thread]] | addr[cpu->pc[thread]+1] << 8 | addr[cpu->pc[thread]+2] << 16 @@ -1239,19 +1356,54 @@ void *run(void *args) { cpu->pc[thread]+=4; iclk++; } - value = addr[address]; - if (regsize >= 2) { - value += (uint64_t)addr[address+1] << 8; - } - if (regsize >= 4) { - value += (uint64_t)addr[address+2] << 16; - value += (uint64_t)addr[address+3] << 24; - } - if (regsize >= 8) { - value += (uint64_t)addr[address+4] << 32; - value += (uint64_t)addr[address+5] << 40; - value += (uint64_t)addr[address+6] << 48; - value += (uint64_t)addr[address+7] << 56; + if (cpu->v[thread]) + cpu->pc[thread] = address; + break; + case MUL: /* MUL Immediate. */ + case MAB: /* Multiply Accumulator by B. */ + case 0x93: /* MUL Absolute. */ + case 0x95: /* MUL Zero Matrix. */ + if (opcode != MAB) { + if (opcode == MUL) { + address = cpu->pc[thread]; + cpu->pc[thread]+=regsize; + } + if (opcode == 0x93) { + address = (uint64_t)addr[cpu->pc[thread]] + | (uint64_t)addr[cpu->pc[thread]+1] << 8 + | (uint64_t)addr[cpu->pc[thread]+2] << 16 + | (uint64_t)addr[cpu->pc[thread]+3] << 24 + | (uint64_t)addr[cpu->pc[thread]+4] << 32 + | (uint64_t)addr[cpu->pc[thread]+5] << 40 + | (uint64_t)addr[cpu->pc[thread]+6] << 48 + | (uint64_t)addr[cpu->pc[thread]+7] << 56; + cpu->pc[thread]+=8; + iclk++; + } + if (opcode == 0x95) { + address = addr[cpu->pc[thread]] + | addr[cpu->pc[thread]+1] << 8 + | addr[cpu->pc[thread]+2] << 16 + | addr[cpu->pc[thread]+3] << 24; + cpu->pc[thread]+=4; + iclk++; + } + value = addr[address]; + if (regsize >= 2) { + value += (uint64_t)addr[address+1] << 8; + } + if (regsize >= 4) { + value += (uint64_t)addr[address+2] << 16; + value += (uint64_t)addr[address+3] << 24; + } + if (regsize >= 8) { + value += (uint64_t)addr[address+4] << 32; + value += (uint64_t)addr[address+5] << 40; + value += (uint64_t)addr[address+6] << 48; + value += (uint64_t)addr[address+7] << 56; + } + } else { + value = cpu->b[thread]; } sum = cpu->a[thread]*value+cpu->c[thread]; cpu->a[thread] = sum; @@ -1268,28 +1420,9 @@ void *run(void *args) { cpu->v[thread] = 1; (cpu->ps |= (V << 8*thread)); break; - case BVC: /* Branch if oVerflow Clear. */ - address = (uint64_t)addr[cpu->pc[thread]] - | (uint64_t)addr[cpu->pc[thread]+1] << 8 - | (uint64_t)addr[cpu->pc[thread]+2] << 16 - | (uint64_t)addr[cpu->pc[thread]+3] << 24 - | (uint64_t)addr[cpu->pc[thread]+4] << 32 - | (uint64_t)addr[cpu->pc[thread]+5] << 40 - | (uint64_t)addr[cpu->pc[thread]+6] << 48 - | (uint64_t)addr[cpu->pc[thread]+7] << 56; - cpu->pc[thread]+=8; - iclk++; - if (!cpu->v[thread]) - cpu->pc[thread] = address; - break; - case DIV: /* DIV Immediate. */ - case 0xA3: /* DIV Absolute. */ - case 0xA5: /* DIV Zero Matrix. */ - if (opcode == DIV) { - address = cpu->pc[thread]; - cpu->pc[thread]+=regsize; - } - if (opcode == 0xA3) { + case BVC: /* BVC Absolute. */ + case 0xD4: /* BVC Zero Matrix. */ + if (opcode == BVC) { address = (uint64_t)addr[cpu->pc[thread]] | (uint64_t)addr[cpu->pc[thread]+1] << 8 | (uint64_t)addr[cpu->pc[thread]+2] << 16 @@ -1300,8 +1433,7 @@ void *run(void *args) { | (uint64_t)addr[cpu->pc[thread]+7] << 56; cpu->pc[thread]+=8; iclk++; - } - if (opcode == 0xA5) { + } else { address = addr[cpu->pc[thread]] | addr[cpu->pc[thread]+1] << 8 | addr[cpu->pc[thread]+2] << 16 @@ -1309,21 +1441,57 @@ void *run(void *args) { cpu->pc[thread]+=4; iclk++; } - value = addr[address]; - if (regsize >= 2) { - value += (uint64_t)addr[address+1] << 8; - } - if (regsize >= 4) { - value += (uint64_t)addr[address+2] << 16; - value += (uint64_t)addr[address+3] << 24; - } - if (regsize >= 8) { - value += (uint64_t)addr[address+4] << 32; - value += (uint64_t)addr[address+5] << 40; - value += (uint64_t)addr[address+6] << 48; - value += (uint64_t)addr[address+7] << 56; + if (!cpu->v[thread]) + cpu->pc[thread] = address; + break; + case DIV: /* DIV Immediate. */ + case DAB: /* Divide Accumulator by B. */ + case 0xA3: /* DIV Absolute. */ + case 0xA5: /* DIV Zero Matrix. */ + if (opcode != DAB) { + if (opcode == DIV) { + address = cpu->pc[thread]; + cpu->pc[thread]+=regsize; + } + if (opcode == 0xA3) { + address = (uint64_t)addr[cpu->pc[thread]] + | (uint64_t)addr[cpu->pc[thread]+1] << 8 + | (uint64_t)addr[cpu->pc[thread]+2] << 16 + | (uint64_t)addr[cpu->pc[thread]+3] << 24 + | (uint64_t)addr[cpu->pc[thread]+4] << 32 + | (uint64_t)addr[cpu->pc[thread]+5] << 40 + | (uint64_t)addr[cpu->pc[thread]+6] << 48 + | (uint64_t)addr[cpu->pc[thread]+7] << 56; + cpu->pc[thread]+=8; + iclk++; + } + if (opcode == 0xA5) { + address = addr[cpu->pc[thread]] + | addr[cpu->pc[thread]+1] << 8 + | addr[cpu->pc[thread]+2] << 16 + | addr[cpu->pc[thread]+3] << 24; + cpu->pc[thread]+=4; + iclk++; + } + value = addr[address]; + if (regsize >= 2) { + value += (uint64_t)addr[address+1] << 8; + } + if (regsize >= 4) { + value += (uint64_t)addr[address+2] << 16; + value += (uint64_t)addr[address+3] << 24; + } + if (regsize >= 8) { + value += (uint64_t)addr[address+4] << 32; + value += (uint64_t)addr[address+5] << 40; + value += (uint64_t)addr[address+6] << 48; + value += (uint64_t)addr[address+7] << 56; + } + cpu->b[thread] = cpu->a[thread] % value; + } else { + value = cpu->b[thread]; + cpu->x[thread] = cpu->a[thread] % value; } - cpu->b[thread] = cpu->a[thread] % value; sum = cpu->a[thread]/value; cpu->a[thread] = sum; cpu->z[thread] = (sum == 0); @@ -1344,53 +1512,84 @@ void *run(void *args) { cpu->pc[thread] = addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]]; } break; + case CPB: /* CPB Immediate. */ case CMP: /* CMP Immediate. */ + case CAB: /* Compare Accumulator, and B. */ case CPY: /* CPY Immediate. */ case CPX: /* CPX Immediate. */ - case 0xE2: /* CPY Absolute. */ - case 0xE4: /* CPX Absolute. */ - case 0xE5: /* CMP Absolute. */ - case 0xF2: /* CPY Zero Matrix. */ - case 0xF4: /* CPX Zero Matrix. */ - case 0xF5: /* CMP Zero Matrix. */ - if (opcode == CMP || opcode == CPY || opcode == CPX) { - address = cpu->pc[thread]; - cpu->pc[thread]+=regsize; - } - if (opcode == 0xE5 || opcode == 0xE2 || opcode == 0xE4) { - address = (uint64_t)addr[cpu->pc[thread]] - | (uint64_t)addr[cpu->pc[thread]+1] << 8 - | (uint64_t)addr[cpu->pc[thread]+2] << 16 - | (uint64_t)addr[cpu->pc[thread]+3] << 24 - | (uint64_t)addr[cpu->pc[thread]+4] << 32 - | (uint64_t)addr[cpu->pc[thread]+5] << 40 - | (uint64_t)addr[cpu->pc[thread]+6] << 48 - | (uint64_t)addr[cpu->pc[thread]+7] << 56; - cpu->pc[thread]+=8; - iclk++; - } - if (opcode == 0xF5 || opcode == 0xF2 || opcode == 0xF4) { - address = addr[cpu->pc[thread]] - | addr[cpu->pc[thread]+1] << 8 - | addr[cpu->pc[thread]+2] << 16 - | addr[cpu->pc[thread]+3] << 24; - cpu->pc[thread]+=4; - iclk++; - } - value = (uint64_t)addr[address]; - if (regsize >= 2) - value += (uint64_t)addr[address+1] << 8; - if (regsize >= 4) { - value += (uint64_t)addr[address+2] << 16; - value += (uint64_t)addr[address+3] << 24; - } - if (regsize >= 8) { - value += (uint64_t)addr[address+4] << 32; - value += (uint64_t)addr[address+5] << 40; - value += (uint64_t)addr[address+6] << 48; - value += (uint64_t)addr[address+7] << 56; + case 0x2B: /* CPY Absolute. */ + case 0x2D: /* CPX Absolute. */ + case 0xB3: /* CMP Absolute. */ + case 0xE6: /* CPB Absolute. */ + case 0x3B: /* CPY Zero Matrix. */ + case 0x3D: /* CPX Zero Matrix. */ + case 0xB5: /* CMP Zero Matrix. */ + case 0xF6: /* CPB Zero Matrix. */ + case 0xE9: /* CMP Indirect. */ + case 0xEA: /* CPY Indirect. */ + case 0xEC: /* CPX Indirect. */ + case 0xDF: /* CPB Indirect. */ + case 0xEB: /* CMP Indexed Indirect. */ + case 0xFA: /* CPY Indexed Indirect. */ + case 0xEF: /* CPB Indexed Indirect. */ + case 0xED: /* CMP Indirect Indexed. */ + case 0xFC: /* CPX Indirect Indexed. */ + case 0xFF: /* CPB Indirect Indexed. */ + if (opcode != CAB) { + if (opcode == CMP || opcode == CPY || opcode == CPX || opcode == CPB) { + address = cpu->pc[thread]; + cpu->pc[thread]+=regsize; + } else if (opcode == 0xB3 || opcode == 0x2B || opcode == 0x2D) { + address = (uint64_t)addr[cpu->pc[thread]] + | (uint64_t)addr[cpu->pc[thread]+1] << 8 + | (uint64_t)addr[cpu->pc[thread]+2] << 16 + | (uint64_t)addr[cpu->pc[thread]+3] << 24 + | (uint64_t)addr[cpu->pc[thread]+4] << 32 + | (uint64_t)addr[cpu->pc[thread]+5] << 40 + | (uint64_t)addr[cpu->pc[thread]+6] << 48 + | (uint64_t)addr[cpu->pc[thread]+7] << 56; + cpu->pc[thread]+=8; + iclk++; + } else { + address = addr[cpu->pc[thread]] + | addr[cpu->pc[thread]+1] << 8 + | addr[cpu->pc[thread]+2] << 16 + | addr[cpu->pc[thread]+3] << 24; + if (opcode == 0xDF || opcode == 0xE9 || opcode == 0xEA || opcode == 0xEB || opcode == 0xEC || + opcode == 0xED || opcode == 0xEF || opcode == 0xFA || opcode == 0xFC || opcode == 0xFF) { + address = (uint64_t)addr[address] + | (uint64_t)addr[address+1] << 8 + | (uint64_t)addr[address+2] << 16 + | (uint64_t)addr[address+3] << 24 + | (uint64_t)addr[address+4] << 32 + | (uint64_t)addr[address+5] << 40 + | (uint64_t)addr[address+6] << 48 + | (uint64_t)addr[address+7] << 56; + if (opcode == 0xEB || opcode == 0xEF || opcode == 0xFA) + address += cpu->x[thread]; + if (opcode == 0xED || opcode == 0xFC || opcode == 0xFF) + address += cpu->y[thread]; + } + cpu->pc[thread]+=4; + iclk++; + } + value = (uint64_t)addr[address]; + if (regsize >= 2) + value += (uint64_t)addr[address+1] << 8; + if (regsize >= 4) { + value += (uint64_t)addr[address+2] << 16; + value += (uint64_t)addr[address+3] << 24; + } + if (regsize >= 8) { + value += (uint64_t)addr[address+4] << 32; + value += (uint64_t)addr[address+5] << 40; + value += (uint64_t)addr[address+6] << 48; + value += (uint64_t)addr[address+7] << 56; + } + } else { + value = cpu->b[thread]; } - if (opcode == CMP || opcode == 0xE5 || opcode == 0xF5) + if (opcode == CMP || opcode == CAB || opcode == 0xE5 || opcode == 0xF5) sum = cpu->a[thread]-value; if (opcode == CPY || opcode == 0xE2 || opcode == 0xF2) sum = cpu->y[thread]-value; @@ -1403,22 +1602,6 @@ void *run(void *args) { (cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread)); (cpu->c[thread]) ? (cpu->ps |= (C << 8*thread)) : (cpu->ps &= ~(C << 8*thread)); break; - case CAY: - case CAX: - if (opcode == CAY) - sum = cpu->a[thread]-cpu->y[thread]; - if (opcode == CAX) - sum = cpu->a[thread]-cpu->x[thread]; - cpu->n[thread] = (sum & 0x8000000000000000) ? 1 : 0; - cpu->z[thread] = (sum == 0) ? 1 : 0; - if (opcode == CAY) - cpu->c[thread] = (sum > cpu->y[thread]) ? 1 : 0; - if (opcode == CAX) - cpu->c[thread] = (sum > cpu->x[thread]) ? 1 : 0; - (cpu->z[thread]) ? (cpu->ps |= (Z << 8*thread)) : (cpu->ps &= ~(Z << 8*thread)); - (cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread)); - (cpu->c[thread]) ? (cpu->ps |= (C << 8*thread)) : (cpu->ps &= ~(C << 8*thread)); - break; case ENT: /* ENd Thread. */ value = addr[address]; cpu->crt &= ~value; @@ -1438,60 +1621,80 @@ void *run(void *args) { } break; case INC: /* INC Accumulator. */ + case IAB: case INY: - case IAY: case INX: - case IAX: - if (opcode == INC || opcode == IAY || opcode == IAX) { + if (opcode == INC || opcode == IAB) { cpu->a[thread]+=1; + if (opcode == IAB) + cpu->b[thread]+=1; cpu->z[thread] = (cpu->a[thread] == 0); cpu->n[thread] = (cpu->a[thread] >> 63); - (cpu->z[thread]) ? (cpu->ps |= (Z << 8*thread)) : (cpu->ps &= ~(Z << 8*thread)); - (cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread)); } - if (opcode == INY || opcode == IAY) { + if (opcode == INY) { cpu->y[thread]+=1; cpu->z[thread] = (cpu->y[thread] == 0); cpu->n[thread] = (cpu->y[thread] >> 63); } - if (opcode == INX || opcode == IAX) { + if (opcode == INX) { cpu->x[thread]+=1; cpu->z[thread] = (cpu->x[thread] == 0); cpu->n[thread] = (cpu->x[thread] >> 63); } + (cpu->z[thread]) ? (cpu->ps |= (Z << 8*thread)) : (cpu->ps &= ~(Z << 8*thread)); + (cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread)); break; + case 0x04: /* JMP Indirect. */ + case 0x14: /* JMP Indexed Indirect. */ + case 0x24: /* JMP Indirect Indexed. */ case 0xD0: /* JMP Zero Matrix. */ address = (uint32_t)addr[cpu->pc[thread]] |(uint32_t)addr[cpu->pc[thread]+1] << 8 |(uint32_t)addr[cpu->pc[thread]+2] << 16 |(uint32_t)addr[cpu->pc[thread]+3] << 24; + + if (opcode == 0x04 || opcode == 0x14 || opcode == 0x24) { + address = (uint64_t)addr[address] + | (uint64_t)addr[address+1] << 8 + | (uint64_t)addr[address+2] << 16 + | (uint64_t)addr[address+3] << 24 + | (uint64_t)addr[address+4] << 32 + | (uint64_t)addr[address+5] << 40 + | (uint64_t)addr[address+6] << 48 + | (uint64_t)addr[address+7] << 56; + if (opcode == 0x14) + address += cpu->x[thread]; + if (opcode == 0x24) + address += cpu->y[thread]; + } cpu->pc[thread]+=4; iclk++; cpu->pc[thread] = address; break; case DEC: /* DEC Accumulator. */ + case DBA: case DEY: - case DAY: case DEX: - case DAX: - if (opcode == DEC || opcode == DAY || opcode == DAX) { + if (opcode == DEC || opcode == DBA) { cpu->a[thread]-=1; + if (opcode == DBA) + cpu->b[thread]-=1; cpu->z[thread] = (cpu->a[thread] == 0); cpu->n[thread] = (cpu->a[thread] >> 63); - (cpu->z[thread]) ? (cpu->ps |= (Z << 8*thread)) : (cpu->ps &= ~(Z << 8*thread)); - (cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread)); } - if (opcode == DEY || opcode == DAY) { + if (opcode == DEY) { cpu->y[thread]-=1; cpu->z[thread] = (cpu->y[thread] == 0); cpu->n[thread] = (cpu->y[thread] >> 63); } - if (opcode == DEX || opcode == DAX) { + if (opcode == DEX) { cpu->x[thread]-=1; cpu->z[thread] = (cpu->x[thread] == 0); cpu->n[thread] = (cpu->x[thread] >> 63); } + (cpu->z[thread]) ? (cpu->ps |= (Z << 8*thread)) : (cpu->ps &= ~(Z << 8*thread)); + (cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread)); break; case JSL: /* Jump to Subroutine Long. */ address = (uint64_t)addr[cpu->pc[thread]] @@ -1512,9 +1715,9 @@ void *run(void *args) { } cpu->pc[thread] = address; break; - case 0xE1: /* INC Absolute. */ - case 0xE3: /* INC Zero Matrix. */ - if (opcode == 0xE1) { + case 0xC3: /* INC Absolute. */ + case 0xC5: /* INC Zero Matrix. */ + if (opcode == 0xC3) { address = (uint64_t)addr[cpu->pc[thread]] | (uint64_t)addr[cpu->pc[thread]+1] << 8 | (uint64_t)addr[cpu->pc[thread]+2] << 16 @@ -1526,7 +1729,7 @@ void *run(void *args) { cpu->pc[thread]+=8; iclk++; } - if (opcode == 0xE3) { + if (opcode == 0xC5) { address = addr[cpu->pc[thread]] | addr[cpu->pc[thread]+1] << 8 | addr[cpu->pc[thread]+2] << 16 @@ -1549,9 +1752,9 @@ void *run(void *args) { cpu->pc[thread] = addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]]; } break; - case 0xF1: /* DEC Absolute. */ - case 0xF3: /* DEC Zero Matrix. */ - if (opcode == 0xF1) { + case 0xD3: /* DEC Absolute. */ + case 0xD5: /* DEC Zero Matrix. */ + if (opcode == 0xD3) { address = (uint64_t)addr[cpu->pc[thread]] | (uint64_t)addr[cpu->pc[thread]+1] << 8 | (uint64_t)addr[cpu->pc[thread]+2] << 16 @@ -1563,7 +1766,7 @@ void *run(void *args) { cpu->pc[thread]+=8; iclk++; } - if (opcode == 0xF3) { + if (opcode == 0xD5) { address = addr[cpu->pc[thread]] | addr[cpu->pc[thread]+1] << 8 | addr[cpu->pc[thread]+2] << 16 @@ -1607,6 +1810,7 @@ void *run(void *args) { break; } ins++; + usleep(100000); #if debug && !bench #if keypoll pthread_mutex_lock(&mutex); diff --git a/test/input.s b/test/input.s index 169372f..20ab3d1 100644 --- a/test/input.s +++ b/test/input.s @@ -18,6 +18,8 @@ c: .word $0 d: .word $0 +e: + .word $0 string: .byte "Please, type something.\n" string2: @@ -93,19 +95,20 @@ getchar: echo: sta a ldx scr_col - cpx #$79 + cpx #$4F bne echo_print linewrap: inc scr_row ldx #$0 stx scr_col + lda scr_row jsr update_pos echo_print: lda a sta $C001 ; Echo typed character. inc scr_col ; Increment the cursor's x coordinate. sta buffer, y ; Store typed character into the input buffer. - iny ; Increment the buffer offset. + iny jmp rset_a ; Start getting user input. esc: @@ -173,22 +176,30 @@ isleft_done: up: dec scr_row + lda #$0 + sta e jsr update_pos lda #$1 sta d jmp isup_done down: inc scr_row + lda #$1 + sta e jsr update_pos lda #$1 sta d jmp isdown_done right: inc scr_col + lda #$2 + sta e jsr update_pos jmp isright_end left: dec scr_col + lda #$3 + sta e jsr update_pos lda #$1 sta d @@ -260,9 +271,9 @@ bs: result: ldx scr_col - cpx #$79 + cpx #$4F bne result_print -linewrap: +linewrap2: inc scr_row ldx #$0 stx scr_col @@ -277,14 +288,14 @@ result_print: rset_y: - ldy.w #$0 + ldy.w #$0 ; Reset y. jmp print_buf ; Print the input buffer. print_buf: ldx scr_col - cpx #$79 + cpx #$4F bne buf_print -linewrap: +linewrap3: inc scr_row ldx #$0 stx scr_col @@ -297,6 +308,14 @@ buf_print: iny jmp print_buf ; Keep printing the buffer. +scr_to_buf: + tax + mul #$50 + adc scr_col + tay + txa + rts + spin: nop nop @@ -317,12 +336,12 @@ spin: .org $FFA0 .qword irq_routine -.org $8000 -viewmem -.org $8100 -viewmem -.org $8200 -viewmem +;.org $8000 +;viewmem +;.org $8100 +;viewmem +;.org $8200 +;viewmem ;q done |