summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormrb0nk500 <b0nk@b0nk.xyz>2019-12-24 22:18:32 -0500
committermrb0nk500 <b0nk@b0nk.xyz>2019-12-24 22:18:32 -0500
commit1dfc78b8bf5b708cb1118a9d6646397772a1b894 (patch)
treef3e9a0a87c4aa5a13a773fc1046a6d17fb4631f4
parentcd08c7e030dd269ffd0d3bdb6170e15998c796ec (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.c357
-rw-r--r--opcode.h348
-rw-r--r--programs/subasm.s232
-rw-r--r--sux.c1264
-rw-r--r--test/input.s45
5 files changed, 1354 insertions, 892 deletions
diff --git a/asmmon.c b/asmmon.c
index 000cf49..7af4695 100644
--- a/asmmon.c
+++ b/asmmon.c
@@ -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
diff --git a/opcode.h b/opcode.h
index a3775db..3e754c2 100644
--- a/opcode.h
+++ b/opcode.h
@@ -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
diff --git a/sux.c b/sux.c
index 0b8da2e..85280c1 100644
--- a/sux.c
+++ b/sux.c
@@ -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