From 8499c64756dd895436c2b6627a652a70d092ec8e Mon Sep 17 00:00:00 2001 From: Tim Allen Date: Sun, 15 Jan 2017 11:58:47 +1100 Subject: [PATCH] Update to v101r33 release. byuu says: Changelog: - PCE: HuC6280 core completed There's bound to be a countless stream of bugs, and the cycle counts are almost certainly not exact yet, but ... all instructions are implemented. So at this point, I can start comparing trace logs against Mednafen's debugger output. Of course, we're very likely to immediately slam into a wall of needing I/O registers implemented for the VDC in order to proceed further. --- higan/emulator/emulator.hpp | 2 +- higan/pce/cpu/cpu.cpp | 3 + higan/pce/cpu/cpu.hpp | 1 + higan/processor/huc6280/disassembler.cpp | 119 ++++++- higan/processor/huc6280/huc6280.hpp | 75 ++-- higan/processor/huc6280/instruction.cpp | 428 ++++++++++++++--------- higan/processor/huc6280/instructions.cpp | 423 +++++++++++++++------- 7 files changed, 730 insertions(+), 321 deletions(-) diff --git a/higan/emulator/emulator.hpp b/higan/emulator/emulator.hpp index f3a17647..8155071c 100644 --- a/higan/emulator/emulator.hpp +++ b/higan/emulator/emulator.hpp @@ -12,7 +12,7 @@ using namespace nall; namespace Emulator { static const string Name = "higan"; - static const string Version = "101.32"; + static const string Version = "101.33"; static const string Author = "byuu"; static const string License = "GPLv3"; static const string Website = "http://byuu.org/"; diff --git a/higan/pce/cpu/cpu.cpp b/higan/pce/cpu/cpu.cpp index 7a548a05..df42b27a 100644 --- a/higan/pce/cpu/cpu.cpp +++ b/higan/pce/cpu/cpu.cpp @@ -51,6 +51,9 @@ auto CPU::write(uint21 addr, uint8 data) -> void { if(bank == 0xff) return; //hardware } +auto CPU::st(uint2 addr, uint8 data) -> void { +} + auto CPU::lastCycle() -> void { } diff --git a/higan/pce/cpu/cpu.hpp b/higan/pce/cpu/cpu.hpp index 01dfc3d7..94f3624d 100644 --- a/higan/pce/cpu/cpu.hpp +++ b/higan/pce/cpu/cpu.hpp @@ -9,6 +9,7 @@ struct CPU : Processor::HuC6280, Thread { auto read(uint21 addr) -> uint8 override; auto write(uint21 addr, uint8 data) -> void override; + auto st(uint2 addr, uint8 data) -> void override; auto lastCycle() -> void override; vector peripherals; diff --git a/higan/processor/huc6280/disassembler.cpp b/higan/processor/huc6280/disassembler.cpp index 839cb78a..556438ca 100644 --- a/higan/processor/huc6280/disassembler.cpp +++ b/higan/processor/huc6280/disassembler.cpp @@ -18,12 +18,46 @@ auto HuC6280::disassemble(uint16 pc_) -> string { auto indirect = [&]() -> string { return {"($", hex(readByte(), 2L), ")"}; }; auto indirectX = [&]() -> string { return {"($", hex(readByte(), 2L), ",x)"}; }; auto indirectY = [&]() -> string { return {"($", hex(readByte(), 2L), "),y"}; }; + auto indirectLong = [&]() -> string { return {"($", hex(readWord(), 4L), ")"}; }; + auto indirectLongX = [&]() -> string { return {"($", hex(readWord(), 4L), ",x)"}; }; auto memory = [&]() -> string { return {"(x),#$", hex(readByte(), 2L)}; }; auto relative = [&]() -> string { auto displacement = readByte(); return {"$", hex(pc + (int8)displacement, 4L)}; }; auto zeropage = [&]() -> string { return {"$", hex(readByte(), 2L)}; }; auto zeropageX = [&]() -> string { return {"$", hex(readByte(), 2L), ",x"}; }; auto zeropageY = [&]() -> string { return {"$", hex(readByte(), 2L), ",y"}; }; + auto immediateAbsolute = [&](string index = "") -> string { + auto immediate = readByte(); + auto absolute = readWord(); + if(index) index.prepend(","); + return {"#$", hex(immediate, 2L), ",$", hex(absolute, 4L), index}; + }; + + auto immediateZeropage = [&](string index = "") -> string { + auto immediate = readByte(); + auto zeropage = readByte(); + if(index) index.prepend(","); + return {"#$", hex(immediate, 2L), ",$", hex(zeropage, 2L), index}; + }; + + auto zeropageBit = [&](uint3 bit) -> string { + auto zeropage = readByte(); + return {"$", hex(zeropage, 2L), ":", bit}; + }; + + auto zeropageBitRelative = [&](uint3 bit) -> string { + auto zeropage = readByte(); + auto displacement = readByte(); + return {"$", hex(zeropage, 2L), ":", bit, ",$", hex(pc + (int8)displacement, 4L)}; + }; + + auto blockMove = [&]() -> string { + auto source = readWord(); + auto target = readWord(); + auto length = readWord(); + return {"$", hex(source, 4L), ",$", hex(target, 4L), ",$", hex(length, 4L)}; + }; + uint8 opcode = readByte(); #define op(id, name, ...) case id: o = {name, " ", string_vector{__VA_ARGS__}.merge(",")}; break; @@ -36,59 +70,87 @@ auto HuC6280::disassemble(uint16 pc_) -> string { op(0x69, "adc", memory()) } + #define U if(T == 0) switch(opcode) { + op(0x00, "brk") op(0x01, "ora", indirectX()) op(0x02, "sxy") + op(0x03, "st0") + op(0x04, "tsb", zeropage()) op(0x05, "ora", zeropage()) op(0x06, "asl", zeropage()) + op(0x07, "rmb", zeropageBit(0)) op(0x08, "php") op(0x09, "ora", immediate()) op(0x0a, "asl") +U op(0x0b, "nop", "$0b") + op(0x0c, "tsb", absolute()) op(0x0d, "ora", absolute()) op(0x0e, "asl", absolute()) + op(0x0f, "bbr", zeropageBitRelative(0)) op(0x10, "bpl", relative()) op(0x11, "ora", indirectY()) op(0x12, "ora", indirect()) + op(0x13, "st1") + op(0x14, "trb", zeropage()) op(0x15, "ora", zeropageX()) op(0x16, "asl", zeropageX()) + op(0x17, "rmb", zeropageBit(1)) op(0x18, "clc") op(0x19, "ora", absoluteY()) op(0x1a, "inc") +U op(0x1b, "nop", "$1b") + op(0x1c, "trb", absolute()) op(0x1d, "ora", absoluteX()) op(0x1e, "asl", absoluteX()) + op(0x1f, "bbr", zeropageBitRelative(1)) + op(0x20, "jsr", absolute()) op(0x21, "and", indirectX()) op(0x22, "sax") + op(0x23, "st2") op(0x24, "bit", zeropage()) op(0x25, "and", zeropage()) op(0x26, "rol", zeropage()) + op(0x27, "rmb", zeropageBit(2)) op(0x28, "plp") op(0x29, "and", immediate()) op(0x2a, "rol") +U op(0x2b, "nop", "$2b") op(0x2c, "bit", absolute()) op(0x2d, "and", absolute()) op(0x2e, "rol", absolute()) + op(0x2f, "bbr", zeropageBitRelative(2)) op(0x30, "bmi", relative()) op(0x31, "and", indirectY()) op(0x32, "and", indirect()) op(0x34, "bit", zeropageX()) op(0x35, "and", zeropageX()) op(0x36, "rol", zeropageX()) + op(0x37, "rmb", zeropageBit(3)) op(0x38, "sec") op(0x39, "and", absoluteY()) op(0x3a, "dec") +U op(0x3b, "nop", "$3b") op(0x3c, "bit", absoluteX()) op(0x3d, "and", absoluteX()) op(0x3e, "rol", absoluteX()) + op(0x3f, "bbr", zeropageBitRelative(3)) + op(0x40, "rti") op(0x41, "eor", indirectX()) op(0x42, "say") op(0x43, "tma", immediate()) + op(0x44, "bsr", relative()) op(0x45, "eor", zeropage()) op(0x46, "lsr", zeropage()) + op(0x47, "rmb", zeropageBit(4)) op(0x48, "pha") op(0x49, "eor", immediate()) op(0x4a, "lsr") +U op(0x4b, "nop", "$4b") + op(0x4c, "jmp", absolute()) op(0x4d, "eor", absolute()) op(0x4e, "lsr", absolute()) + op(0x4f, "bbr", zeropageBitRelative(4)) op(0x50, "bvc", relative()) op(0x51, "eor", indirectY()) op(0x52, "eor", indirect()) @@ -96,125 +158,180 @@ auto HuC6280::disassemble(uint16 pc_) -> string { op(0x54, "csl") op(0x55, "eor", zeropageX()) op(0x56, "lsr", zeropageX()) + op(0x57, "rmb", zeropageBit(5)) op(0x58, "cli") op(0x59, "eor", absoluteY()) op(0x5a, "phy") +U op(0x5b, "nop", "$5b") +U op(0x5c, "nop", "$5c") op(0x5d, "eor", absoluteX()) op(0x5e, "lsr", absoluteX()) + op(0x5f, "bbr", zeropageBitRelative(5)) + op(0x60, "rts") op(0x61, "adc", indirectX()) op(0x62, "cla") +U op(0x63, "nop", "$63") op(0x64, "stz", zeropage()) op(0x65, "adc", zeropage()) op(0x66, "ror", zeropage()) + op(0x67, "rmb", zeropageBit(6)) op(0x68, "pla") op(0x69, "adc", immediate()) op(0x6a, "ror") +U op(0x6b, "nop", "$6b") + op(0x6c, "jmp", indirectLong()) op(0x6d, "adc", absolute()) op(0x6e, "ror", absolute()) + op(0x6f, "bbr", zeropageBitRelative(6)) op(0x70, "bvs", relative()) op(0x71, "adc", indirectY()) op(0x72, "adc", indirect()) + op(0x73, "tii", blockMove()) op(0x74, "stz", zeropageX()) op(0x75, "adc", zeropageX()) op(0x76, "ror", zeropageX()) + op(0x77, "rmb", zeropageBit(7)) op(0x78, "sei") op(0x79, "adc", absoluteY()) op(0x7a, "ply") +U op(0x7b, "nop", "$7b") + op(0x7c, "jmp", indirectLongX()) op(0x7d, "adc", absoluteX()) op(0x7e, "ror", absoluteX()) + op(0x7f, "bbr", zeropageBitRelative(7)) op(0x80, "bra", relative()) op(0x81, "sta", indirectX()) op(0x82, "clx") + op(0x83, "tst", immediateZeropage()) op(0x84, "sty", zeropage()) op(0x85, "sta", zeropage()) op(0x86, "stx", zeropage()) + op(0x87, "smb", zeropageBit(0)) op(0x88, "dey") op(0x89, "bit", immediate()) op(0x8a, "txa") +U op(0x8b, "nop", "$8b") op(0x8c, "sty", absolute()) op(0x8d, "sta", absolute()) op(0x8e, "stx", absolute()) + op(0x8f, "bbs", zeropageBitRelative(0)) op(0x90, "bcc", relative()) op(0x91, "sta", indirectY()) op(0x92, "sta", indirect()) + op(0x93, "tst", immediateAbsolute()) op(0x94, "sty", zeropageX()) op(0x95, "sta", zeropageX()) op(0x96, "stx", zeropageY()) + op(0x97, "smb", zeropageBit(1)) op(0x98, "tya") op(0x99, "sta", absoluteY()) op(0x9a, "txs") +U op(0x9b, "nop", "$9b") op(0x9c, "stz", absolute()) op(0x9d, "sta", absoluteX()) op(0x9e, "stz", absoluteX()) + op(0x9f, "bbs", zeropageBitRelative(1)) op(0xa0, "ldy", immediate()) op(0xa1, "lda", indirectX()) op(0xa2, "ldx", immediate()) + op(0xa3, "tst", immediateZeropage("x")) op(0xa4, "ldy", zeropage()) op(0xa5, "lda", zeropage()) op(0xa6, "ldx", zeropage()) + op(0xa7, "smb", zeropageBit(2)) op(0xa8, "tay") op(0xa9, "lda", immediate()) op(0xaa, "tax") +U op(0xab, "nop", "$ab") op(0xac, "ldy", absolute()) op(0xad, "lda", absolute()) op(0xae, "ldx", absolute()) + op(0xaf, "bbs", zeropageBitRelative(2)) op(0xb0, "bcs", relative()) op(0xb1, "lda", indirectY()) op(0xb2, "lda", indirect()) + op(0xb3, "tst", immediateAbsolute("x")) op(0xb4, "ldy", zeropageX()) op(0xb5, "lda", zeropageX()) op(0xb6, "ldx", zeropageY()) + op(0xb7, "smb", zeropageBit(3)) op(0xb8, "clv") op(0xb9, "lda", absoluteY()) op(0xba, "tsx") +U op(0xbb, "nop", "$bb") op(0xbc, "ldy", absoluteX()) op(0xbd, "lda", absoluteX()) op(0xbe, "ldx", absoluteY()) + op(0xbf, "bbs", zeropageBitRelative(3)) op(0xc0, "cpy", immediate()) op(0xc1, "cmp", indirectX()) op(0xc2, "cly") + op(0xc3, "tdd", blockMove()) + op(0xc4, "cpy", zeropage()) op(0xc5, "cmp", zeropage()) op(0xc6, "dec", zeropage()) + op(0xc7, "smb", zeropageBit(4)) op(0xc8, "iny") op(0xc9, "cmp", immediate()) op(0xca, "dex") +U op(0xcb, "nop", "$cb") + op(0xcc, "cpy", absolute()) op(0xcd, "cmp", absolute()) op(0xce, "dec", absolute()) + op(0xcf, "bbs", zeropageBitRelative(4)) op(0xd0, "bne", relative()) op(0xd1, "cmp", indirectY()) op(0xd2, "cmp", indirect()) + op(0xd3, "tin", blockMove()) op(0xd4, "csh") op(0xd5, "cmp", zeropageX()) op(0xd6, "dec", zeropageX()) + op(0xd7, "smb", zeropageBit(5)) op(0xd8, "cld") op(0xd9, "cmp", absoluteY()) op(0xda, "phx") +U op(0xdb, "nop", "$db") +U op(0xdc, "nop", "$dc") op(0xdd, "cmp", absoluteX()) op(0xde, "dec", absoluteX()) + op(0xdf, "bbs", zeropageBitRelative(5)) op(0xe0, "cpx", immediate()) op(0xe1, "sbc", indirectX()) +U op(0xe2, "nop", "$e2") + op(0xe3, "tia", blockMove()) + op(0xe4, "cpx", zeropage()) op(0xe5, "sbc", zeropage()) op(0xe6, "inc", zeropage()) + op(0xe7, "smb", zeropageBit(6)) op(0xe8, "inx") op(0xe9, "sbc", immediate()) op(0xea, "nop") +U op(0xeb, "nop", "$eb") + op(0xec, "cpx", absolute()) op(0xed, "sbc", absolute()) op(0xee, "inc", absolute()) + op(0xef, "bbs", zeropageBitRelative(6)) op(0xf0, "beq", relative()) op(0xf1, "sbc", indirectY()) op(0xf2, "sbc", indirect()) + op(0xf3, "tai", blockMove()) op(0xf4, "set") op(0xf5, "sbc", zeropageX()) op(0xf6, "inc", zeropageX()) + op(0xf7, "smb", zeropageBit(7)) op(0xf8, "sed") op(0xf9, "sbc", absoluteY()) op(0xfa, "plx") +U op(0xfb, "nop", "$fb") +U op(0xfc, "nop", "$fc") op(0xfd, "sbc", absoluteX()) op(0xfe, "inc", absoluteX()) + op(0xff, "bbs", zeropageBitRelative(7)) } + #undef U if(!o) o = {"??? (", hex(opcode, 2L), ")"}; - s.append(pad(o, -16L, ' ')); + s.append(pad(o, -22L, ' ')); #undef op s.append(" A:", hex(r.a, 2L)); diff --git a/higan/processor/huc6280/huc6280.hpp b/higan/processor/huc6280/huc6280.hpp index 31785ae1..706e6f1c 100644 --- a/higan/processor/huc6280/huc6280.hpp +++ b/higan/processor/huc6280/huc6280.hpp @@ -8,6 +8,7 @@ struct HuC6280 { virtual auto step(uint clocks) -> void = 0; virtual auto read(uint21 addr) -> uint8 = 0; virtual auto write(uint21 addr, uint8 data) -> void = 0; + virtual auto st(uint2, uint8) -> void = 0; virtual auto lastCycle() -> void = 0; auto power() -> void; @@ -28,6 +29,7 @@ struct HuC6280 { auto instruction() -> void; //instructions.cpp + using fp = auto (HuC6280::*)(uint8) -> uint8; auto ADC(uint8) -> uint8; auto AND(uint8) -> uint8; auto ASL(uint8) -> uint8; @@ -44,39 +46,60 @@ struct HuC6280 { auto ROL(uint8) -> uint8; auto ROR(uint8) -> uint8; auto SBC(uint8) -> uint8; + auto TRB(uint8) -> uint8; + auto TSB(uint8) -> uint8; - using fp = auto (HuC6280::*)(uint8) -> uint8; - auto instruction_alu_absolute(fp, uint8 = 0) -> void; - auto instruction_alu_immediate(fp) -> void; - auto instruction_alu_implied(fp, uint8&) -> void; - auto instruction_alu_indirect(fp, uint8 = 0) -> void; - auto instruction_alu_indirectY(fp) -> void; - auto instruction_alu_memory(fp) -> void; - auto instruction_alu_zeropage(fp, uint8 = 0) -> void; - auto instruction_bra(bool) -> void; - auto instruction_CLb(uint8&) -> void; - auto instruction_CLf(bool&) -> void; + using bp = auto (HuC6280::*)(uint16&, uint16&) -> void; + auto TAI(uint16&, uint16&) -> void; + auto TDD(uint16&, uint16&) -> void; + auto TIA(uint16&, uint16&) -> void; + auto TII(uint16&, uint16&) -> void; + auto TIN(uint16&, uint16&) -> void; + + auto instruction_absoluteLoad(fp, uint8&, uint8 = 0) -> void; + auto instruction_absoluteModify(fp, uint8 = 0) -> void; + auto instruction_absoluteStore(uint8, uint8 = 0) -> void; + auto instruction_blockmove(bp) -> void; + auto instruction_branch(bool) -> void; + auto instruction_clear(uint8&) -> void; + auto instruction_clear(bool&) -> void; + auto instruction_immediate(fp, uint8&) -> void; + auto instruction_implied(fp, uint8&) -> void; + auto instruction_indirectLoad(fp, uint8&, uint8 = 0) -> void; + auto instruction_indirectStore(uint8, uint8 = 0) -> void; + auto instruction_indirectYLoad(fp, uint8&) -> void; + auto instruction_indirectYStore(uint8) -> void; + auto instruction_memory(fp) -> void; + auto instruction_pull(uint8&) -> void; + auto instruction_pullP() -> void; + auto instruction_push(uint8) -> void; + auto instruction_set(bool&) -> void; + auto instruction_swap(uint8&, uint8&) -> void; + auto instruction_transfer(uint8&, uint8&) -> void; + auto instruction_zeropageLoad(fp, uint8&, uint8 = 0) -> void; + auto instruction_zeropageModify(fp, uint8 = 0) -> void; + auto instruction_zeropageStore(uint8, uint8 = 0) -> void; + + auto instruction_BBR(uint3) -> void; + auto instruction_BBS(uint3) -> void; + auto instruction_BRK() -> void; + auto instruction_BSR() -> void; auto instruction_CSL() -> void; auto instruction_CSH() -> void; - auto instruction_LDA_indirect(uint8 index = 0) -> void; - auto instruction_LDA_indirectY() -> void; - auto instruction_LDb_absolute(uint8&, uint8 = 0) -> void; - auto instruction_LDb_immediate(uint8&) -> void; - auto instruction_LDb_zeropage(uint8&, uint8 = 0) -> void; + auto instruction_JMP_absolute() -> void; + auto instruction_JMP_indirect(uint8 = 0) -> void; + auto instruction_JSR() -> void; auto instruction_NOP() -> void; - auto instruction_PHb(uint8&) -> void; auto instruction_PHP() -> void; - auto instruction_PLb(uint8&) -> void; - auto instruction_PLP() -> void; - auto instruction_SEf(bool&) -> void; - auto instruction_STA_indirect(uint8 index = 0) -> void; - auto instruction_STA_indirectY() -> void; - auto instruction_STb_absolute(uint8, uint8 = 0) -> void; - auto instruction_STb_zeropage(uint8, uint8 = 0) -> void; - auto instruction_Sbb(uint8&, uint8&) -> void; + auto instruction_RMB(uint3) -> void; + auto instruction_RTI() -> void; + auto instruction_RTS() -> void; + auto instruction_SMB(uint3) -> void; + auto instruction_ST(uint2) -> void; auto instruction_TAM() -> void; - auto instruction_Tbb(uint8&, uint8&) -> void; auto instruction_TMA() -> void; + auto instruction_TST_absolute(uint8 = 0) -> void; + auto instruction_TST_zeropage(uint8 = 0) -> void; auto instruction_TXS() -> void; //disassembler.cpp diff --git a/higan/processor/huc6280/instruction.cpp b/higan/processor/huc6280/instruction.cpp index 7a3b8ec8..cc81fffb 100644 --- a/higan/processor/huc6280/instruction.cpp +++ b/higan/processor/huc6280/instruction.cpp @@ -7,189 +7,273 @@ auto HuC6280::instruction() -> void { if(T) { T = 0; switch(code) { - op(0x09, alu_memory, fp(ORA)) - op(0x29, alu_memory, fp(AND)) - op(0x49, alu_memory, fp(EOR)) - op(0x69, alu_memory, fp(ADC)) + op(0x09, memory, fp(ORA)) + op(0x29, memory, fp(AND)) + op(0x49, memory, fp(EOR)) + op(0x69, memory, fp(ADC)) } } + #define U switch(code) { - op(0x01, alu_indirect, fp(ORA), X) - op(0x02, Sbb, X, Y) - op(0x05, alu_zeropage, fp(ORA)) - op(0x06, alu_zeropage, fp(ASL)) - op(0x08, PHP) - op(0x09, alu_immediate, fp(ORA)) - op(0x0a, alu_implied, fp(ASL), A) - op(0x0d, alu_absolute, fp(ORA)) - op(0x0e, alu_absolute, fp(ASL)) - op(0x10, bra, N == 0) - op(0x11, alu_indirectY, fp(ORA)) - op(0x12, alu_indirect, fp(ORA)) - op(0x15, alu_zeropage, fp(ORA), X) - op(0x16, alu_zeropage, fp(ASL), X) - op(0x18, CLf, C) - op(0x19, alu_absolute, fp(ORA), Y) - op(0x1a, alu_implied, fp(INC), A) - op(0x1d, alu_absolute, fp(ORA), X) - op(0x1e, alu_absolute, fp(ASL), X) - op(0x21, alu_indirect, fp(AND), X) - op(0x22, Sbb, A, X) - op(0x24, alu_zeropage, fp(BIT)) - op(0x25, alu_zeropage, fp(AND)) - op(0x26, alu_zeropage, fp(ROL)) - op(0x28, PLP) - op(0x29, alu_immediate, fp(AND)) - op(0x2a, alu_implied, fp(ROL), A) - op(0x2c, alu_absolute, fp(BIT)) - op(0x2d, alu_absolute, fp(AND)) - op(0x2e, alu_absolute, fp(ROL)) - op(0x30, bra, N == 1) - op(0x31, alu_indirectY, fp(AND)) - op(0x32, alu_indirect, fp(AND)) - op(0x34, alu_zeropage, fp(BIT), X) - op(0x35, alu_zeropage, fp(AND), X) - op(0x36, alu_zeropage, fp(ROL), X) - op(0x38, SEf, C) - op(0x39, alu_absolute, fp(AND), Y) - op(0x3a, alu_implied, fp(DEC), A) - op(0x3c, alu_absolute, fp(BIT), X) - op(0x3d, alu_absolute, fp(AND), X) - op(0x3e, alu_absolute, fp(ROL), X) - op(0x41, alu_indirect, fp(EOR), X) - op(0x42, Sbb, A, Y) + op(0x00, BRK) + op(0x01, indirectLoad, fp(ORA), A, X) + op(0x02, swap, X, Y) + op(0x03, ST, 0) + op(0x04, zeropageModify, fp(TSB)) + op(0x05, zeropageLoad, fp(ORA), A) + op(0x06, zeropageModify, fp(ASL)) + op(0x07, RMB, 0) + op(0x08, push, P) + op(0x09, immediate, fp(ORA), A) + op(0x0a, implied, fp(ASL), A) +U op(0x0b, NOP) + op(0x0c, absoluteModify, fp(TSB)) + op(0x0d, absoluteLoad, fp(ORA), A) + op(0x0e, absoluteModify, fp(ASL)) + op(0x0f, BBR, 0) + op(0x10, branch, N == 0) + op(0x11, indirectYLoad, fp(ORA), A) + op(0x12, indirectLoad, fp(ORA), A) + op(0x13, ST, 1) + op(0x14, zeropageModify, fp(TRB)) + op(0x15, zeropageLoad, fp(ORA), A, X) + op(0x16, zeropageModify, fp(ASL), X) + op(0x17, RMB, 1) + op(0x18, clear, C) + op(0x19, absoluteLoad, fp(ORA), A, Y) + op(0x1a, implied, fp(INC), A) +U op(0x1b, NOP) + op(0x1c, absoluteModify, fp(TRB)) + op(0x1d, absoluteLoad, fp(ORA), A, X) + op(0x1e, absoluteModify, fp(ASL), X) + op(0x1f, BBR, 1) + op(0x20, JSR) + op(0x21, indirectLoad, fp(AND), A, X) + op(0x22, swap, A, X) + op(0x23, ST, 2) + op(0x24, zeropageLoad, fp(BIT), A) + op(0x25, zeropageLoad, fp(AND), A) + op(0x26, zeropageModify, fp(ROL)) + op(0x27, RMB, 2) + op(0x28, pullP) + op(0x29, immediate, fp(AND), A) + op(0x2a, implied, fp(ROL), A) +U op(0x2b, NOP) + op(0x2c, absoluteLoad, fp(BIT), A) + op(0x2d, absoluteLoad, fp(AND), A) + op(0x2e, absoluteModify, fp(ROL)) + op(0x2f, BBR, 2) + op(0x30, branch, N == 1) + op(0x31, indirectYLoad, fp(AND), A) + op(0x32, indirectLoad, fp(AND), A) +U op(0x33, NOP) + op(0x34, zeropageLoad, fp(BIT), A, X) + op(0x35, zeropageLoad, fp(AND), A, X) + op(0x36, zeropageModify, fp(ROL), X) + op(0x37, RMB, 3) + op(0x38, set, C) + op(0x39, absoluteLoad, fp(AND), A, Y) + op(0x3a, implied, fp(DEC), A) +U op(0x3b, NOP) + op(0x3c, absoluteLoad, fp(BIT), A, X) + op(0x3d, absoluteLoad, fp(AND), A, X) + op(0x3e, absoluteModify, fp(ROL), X) + op(0x3f, BBR, 3) + op(0x40, RTI) + op(0x41, indirectLoad, fp(EOR), A, X) + op(0x42, swap, A, Y) op(0x43, TMA) - op(0x45, alu_zeropage, fp(EOR)) - op(0x46, alu_zeropage, fp(LSR)) - op(0x48, PHb, A) - op(0x49, alu_immediate, fp(EOR)) - op(0x4a, alu_implied, fp(LSR), A) - op(0x4d, alu_absolute, fp(EOR)) - op(0x4e, alu_absolute, fp(LSR)) - op(0x50, bra, V == 0) - op(0x51, alu_indirectY, fp(EOR)) - op(0x52, alu_indirect, fp(EOR)) + op(0x44, BSR) + op(0x45, zeropageLoad, fp(EOR), A) + op(0x46, zeropageModify, fp(LSR)) + op(0x47, RMB, 4) + op(0x48, push, A) + op(0x49, immediate, fp(EOR), A) + op(0x4a, implied, fp(LSR), A) +U op(0x4b, NOP) + op(0x4c, JMP_absolute) + op(0x4d, absoluteLoad, fp(EOR), A) + op(0x4e, absoluteModify, fp(LSR)) + op(0x4f, BBR, 4) + op(0x50, branch, V == 0) + op(0x51, indirectYLoad, fp(EOR), A) + op(0x52, indirectLoad, fp(EOR), A) op(0x53, TAM) op(0x54, CSL) - op(0x55, alu_zeropage, fp(EOR), X) - op(0x56, alu_zeropage, fp(LSR), X) - op(0x58, CLf, I) - op(0x59, alu_absolute, fp(EOR), Y) - op(0x5a, PHb, Y) - op(0x5d, alu_absolute, fp(EOR), X) - op(0x5e, alu_absolute, fp(LSR), X) - op(0x61, alu_indirect, fp(ADC), X) - op(0x62, CLb, A) - op(0x64, STb_zeropage, 0) - op(0x65, alu_zeropage, fp(ADC)) - op(0x66, alu_zeropage, fp(ROR)) - op(0x68, PLb, A) - op(0x69, alu_immediate, fp(ADC)) - op(0x6a, alu_implied, fp(ROR), A) - op(0x6d, alu_absolute, fp(ADC)) - op(0x6e, alu_absolute, fp(ROR)) - op(0x70, bra, V == 1) - op(0x71, alu_indirectY, fp(ADC)) - op(0x72, alu_indirect, fp(ADC)) - op(0x74, STb_zeropage, 0, X) - op(0x75, alu_zeropage, fp(ADC), X) - op(0x76, alu_zeropage, fp(ROR), X) - op(0x78, SEf, I) - op(0x79, alu_absolute, fp(ADC), Y) - op(0x7a, PLb, Y) - op(0x7d, alu_absolute, fp(ADC), X) - op(0x7e, alu_absolute, fp(ROR), X) - op(0x80, bra, 1) - op(0x81, STA_indirect, X) - op(0x82, CLb, X) - op(0x84, STb_zeropage, Y) - op(0x85, STb_zeropage, A) - op(0x86, STb_zeropage, X) - op(0x88, alu_implied, fp(DEC), Y) - op(0x89, alu_immediate, fp(BIT)) - op(0x8a, Tbb, X, A) - op(0x8c, STb_absolute, Y) - op(0x8d, STb_absolute, A) - op(0x8e, STb_absolute, X) - op(0x90, bra, C == 0) - op(0x91, STA_indirectY) - op(0x92, STA_indirect) - op(0x94, STb_zeropage, Y, X) - op(0x95, STb_zeropage, A, X) - op(0x96, STb_zeropage, X, Y) - op(0x98, Tbb, Y, A) - op(0x99, STb_absolute, A, Y) + op(0x55, zeropageLoad, fp(EOR), A, X) + op(0x56, zeropageModify, fp(LSR), X) + op(0x57, RMB, 5) + op(0x58, clear, I) + op(0x59, absoluteLoad, fp(EOR), A, Y) + op(0x5a, push, Y) +U op(0x5b, NOP) +U op(0x5c, NOP) + op(0x5d, absoluteLoad, fp(EOR), A, X) + op(0x5e, absoluteModify, fp(LSR), X) + op(0x5f, BBR, 5) + op(0x60, RTS) + op(0x61, indirectLoad, fp(ADC), A, X) + op(0x62, clear, A) +U op(0x63, NOP) + op(0x64, zeropageStore, 0) + op(0x65, zeropageLoad, fp(ADC), A) + op(0x66, zeropageModify, fp(ROR)) + op(0x67, RMB, 6) + op(0x68, pull, A) + op(0x69, immediate, fp(ADC), A) + op(0x6a, implied, fp(ROR), A) +U op(0x6b, NOP) + op(0x6c, JMP_indirect) + op(0x6d, absoluteLoad, fp(ADC), A) + op(0x6e, absoluteModify, fp(ROR)) + op(0x6f, BBR, 6) + op(0x70, branch, V == 1) + op(0x71, indirectYLoad, fp(ADC), A) + op(0x72, indirectLoad, fp(ADC), A) + op(0x73, blockmove, fp(TII)) + op(0x74, zeropageStore, 0, X) + op(0x75, zeropageLoad, fp(ADC), A, X) + op(0x76, zeropageModify, fp(ROR), X) + op(0x77, RMB, 7) + op(0x78, set, I) + op(0x79, absoluteLoad, fp(ADC), A, Y) + op(0x7a, pull, Y) +U op(0x7b, NOP) + op(0x7c, JMP_indirect, X) + op(0x7d, absoluteLoad, fp(ADC), A, X) + op(0x7e, absoluteModify, fp(ROR), X) + op(0x7f, BBR, 7) + op(0x80, branch, 1) + op(0x81, indirectStore, A, X) + op(0x82, clear, X) + op(0x83, TST_zeropage) + op(0x84, zeropageStore, Y) + op(0x85, zeropageStore, A) + op(0x86, zeropageStore, X) + op(0x87, SMB, 0) + op(0x88, implied, fp(DEC), Y) + op(0x89, immediate, fp(BIT), A) + op(0x8a, transfer, X, A) +U op(0x8b, NOP) + op(0x8c, absoluteStore, Y) + op(0x8d, absoluteStore, A) + op(0x8e, absoluteStore, X) + op(0x8f, BBS, 0) + op(0x90, branch, C == 0) + op(0x91, indirectYStore, A) + op(0x92, indirectStore, A) + op(0x93, TST_absolute) + op(0x94, zeropageStore, Y, X) + op(0x95, zeropageStore, A, X) + op(0x96, zeropageStore, X, Y) + op(0x97, SMB, 1) + op(0x98, transfer, Y, A) + op(0x99, absoluteStore, A, Y) op(0x9a, TXS) - op(0x9c, STb_absolute, 0) - op(0x9d, STb_absolute, A, X) - op(0x9e, STb_absolute, 0, X) - op(0xa0, LDb_immediate, Y) - op(0xa1, LDA_indirect, X) - op(0xa2, LDb_immediate, X) - op(0xa4, LDb_zeropage, Y) - op(0xa5, LDb_zeropage, A) - op(0xa6, LDb_zeropage, X) - op(0xa8, Tbb, A, Y) - op(0xa9, LDb_immediate, A) - op(0xaa, Tbb, A, X) - op(0xac, LDb_absolute, Y) - op(0xad, LDb_absolute, A) - op(0xae, LDb_absolute, X) - op(0xb0, bra, C == 1) - op(0xb1, LDA_indirectY) - op(0xb2, LDA_indirect) - op(0xb4, LDb_zeropage, Y, X) - op(0xb5, LDb_zeropage, A, X) - op(0xb6, LDb_zeropage, X, Y) - op(0xb8, CLf, V) - op(0xb9, LDb_absolute, A, Y) - op(0xba, Tbb, S, X) - op(0xbc, LDb_absolute, Y, X) - op(0xbd, LDb_absolute, A, X) - op(0xbe, LDb_absolute, X, Y) - op(0xc0, alu_immediate, fp(CPY)) - op(0xc1, alu_indirect, fp(CMP), X) - op(0xc2, CLb, Y) - op(0xc5, alu_zeropage, fp(CMP)) - op(0xc6, alu_zeropage, fp(DEC)) - op(0xc8, alu_implied, fp(INC), Y) - op(0xc9, alu_immediate, fp(CMP)) - op(0xca, alu_implied, fp(DEC), X) - op(0xcd, alu_absolute, fp(CMP)) - op(0xce, alu_absolute, fp(DEC)) - op(0xd0, bra, Z == 0) - op(0xd1, alu_indirectY, fp(CMP)) - op(0xd2, alu_indirect, fp(CMP)) +U op(0x9b, NOP) + op(0x9c, absoluteStore, 0) + op(0x9d, absoluteStore, A, X) + op(0x9e, absoluteStore, 0, X) + op(0x9f, BBS, 1) + op(0xa0, immediate, fp(LD), Y) + op(0xa1, indirectLoad, fp(LD), A, X) + op(0xa2, immediate, fp(LD), X) + op(0xa3, TST_zeropage, X) + op(0xa4, zeropageLoad, fp(LD), Y) + op(0xa5, zeropageLoad, fp(LD), A) + op(0xa6, zeropageLoad, fp(LD), X) + op(0xa7, SMB, 2) + op(0xa8, transfer, A, Y) + op(0xa9, immediate, fp(LD), A) + op(0xaa, transfer, A, X) +U op(0xab, NOP) + op(0xac, absoluteLoad, fp(LD), Y) + op(0xad, absoluteLoad, fp(LD), A) + op(0xae, absoluteLoad, fp(LD), X) + op(0xaf, BBS, 2) + op(0xb0, branch, C == 1) + op(0xb1, indirectYLoad, fp(LD), A) + op(0xb2, indirectLoad, fp(LD), A) + op(0xb3, TST_absolute, X) + op(0xb4, zeropageLoad, fp(LD), Y, X) + op(0xb5, zeropageLoad, fp(LD), A, X) + op(0xb6, zeropageLoad, fp(LD), X, Y) + op(0xb7, SMB, 3) + op(0xb8, clear, V) + op(0xb9, absoluteLoad, fp(LD), A, Y) + op(0xba, transfer, S, X) +U op(0xbb, NOP) + op(0xbc, absoluteLoad, fp(LD), Y, X) + op(0xbd, absoluteLoad, fp(LD), A, X) + op(0xbe, absoluteLoad, fp(LD), X, Y) + op(0xbf, BBS, 3) + op(0xc0, immediate, fp(CPY), Y) + op(0xc1, indirectLoad, fp(CMP), A, X) + op(0xc2, clear, Y) + op(0xc3, blockmove, fp(TDD)) + op(0xc4, zeropageLoad, fp(CPY), Y) + op(0xc5, zeropageLoad, fp(CMP), A) + op(0xc6, zeropageModify, fp(DEC)) + op(0xc7, SMB, 4) + op(0xc8, implied, fp(INC), Y) + op(0xc9, immediate, fp(CMP), A) + op(0xca, implied, fp(DEC), X) +U op(0xcb, NOP) + op(0xcc, absoluteLoad, fp(CPY), Y) + op(0xcd, absoluteLoad, fp(CMP), A) + op(0xce, absoluteModify, fp(DEC)) + op(0xcf, BBS, 4) + op(0xd0, branch, Z == 0) + op(0xd1, indirectYLoad, fp(CMP), A) + op(0xd2, indirectLoad, fp(CMP), A) + op(0xd3, blockmove, fp(TIN)) op(0xd4, CSH) - op(0xd5, alu_zeropage, fp(CMP), X) - op(0xd6, alu_zeropage, fp(DEC), X) - op(0xd8, CLf, D) - op(0xd9, alu_absolute, fp(CMP), Y) - op(0xda, PHb, X) - op(0xdd, alu_absolute, fp(CMP), X) - op(0xde, alu_absolute, fp(DEC), X) - op(0xe0, alu_immediate, fp(CPX)) - op(0xe1, alu_indirect, fp(SBC), X) - op(0xe5, alu_zeropage, fp(SBC)) - op(0xe6, alu_zeropage, fp(INC)) - op(0xe8, alu_implied, fp(INC), X) - op(0xe9, alu_immediate, fp(SBC)) + op(0xd5, zeropageLoad, fp(CMP), A, X) + op(0xd6, zeropageModify, fp(DEC), X) + op(0xd7, SMB, 5) + op(0xd8, clear, D) + op(0xd9, absoluteLoad, fp(CMP), A, Y) + op(0xda, push, X) +U op(0xdb, NOP) +U op(0xdc, NOP) + op(0xdd, absoluteLoad, fp(CMP), A, X) + op(0xde, absoluteModify, fp(DEC), X) + op(0xdf, BBS, 5) + op(0xe0, immediate, fp(CPX), X) + op(0xe1, indirectLoad, fp(SBC), A, X) +U op(0xe2, NOP) + op(0xe3, blockmove, fp(TIA)) + op(0xe4, zeropageLoad, fp(CPX), X) + op(0xe5, zeropageLoad, fp(SBC), A) + op(0xe6, zeropageModify, fp(INC)) + op(0xe7, SMB, 6) + op(0xe8, implied, fp(INC), X) + op(0xe9, immediate, fp(SBC), A) op(0xea, NOP) - op(0xed, alu_absolute, fp(SBC)) - op(0xee, alu_absolute, fp(INC)) - op(0xf0, bra, Z == 1) - op(0xf1, alu_indirectY, fp(SBC)) - op(0xf2, alu_indirect, fp(SBC)) - op(0xf4, SEf, T) - op(0xf5, alu_zeropage, fp(SBC), X) - op(0xf6, alu_zeropage, fp(INC), X) - op(0xf8, SEf, D) - op(0xf9, alu_absolute, fp(SBC), Y) - op(0xfa, PLb, X) - op(0xfd, alu_absolute, fp(SBC), X) - op(0xfe, alu_absolute, fp(INC), X) +U op(0xeb, NOP) + op(0xec, absoluteLoad, fp(CPX), X) + op(0xed, absoluteLoad, fp(SBC), A) + op(0xee, absoluteModify, fp(INC)) + op(0xef, BBS, 6) + op(0xf0, branch, Z == 1) + op(0xf1, indirectYLoad, fp(SBC), A) + op(0xf2, indirectLoad, fp(SBC), A) + op(0xf3, blockmove, fp(TAI)) + op(0xf4, set, T) + op(0xf5, zeropageLoad, fp(SBC), A, X) + op(0xf6, zeropageModify, fp(INC), X) + op(0xf7, SMB, 7) + op(0xf8, set, D) + op(0xf9, absoluteLoad, fp(SBC), A, Y) + op(0xfa, pull, X) +U op(0xfb, NOP) +U op(0xfc, NOP) + op(0xfd, absoluteLoad, fp(SBC), A, X) + op(0xfe, absoluteModify, fp(INC), X) + op(0xff, BBS, 7) } + #undef U } #undef op diff --git a/higan/processor/huc6280/instructions.cpp b/higan/processor/huc6280/instructions.cpp index 8874615b..ea436da7 100644 --- a/higan/processor/huc6280/instructions.cpp +++ b/higan/processor/huc6280/instructions.cpp @@ -117,76 +117,263 @@ auto HuC6280::SBC(uint8 i) -> uint8 { return ADC(~i); } +auto HuC6280::TRB(uint8 i) -> uint8 { + uint8 o = i & A; + Z = o == 0; + V = o.bit(6); + N = o.bit(7); + return i & ~A; +} + +auto HuC6280::TSB(uint8 i) -> uint8 { + uint8 o = i & A; + Z = o == 0; + V = o.bit(6); + N = o.bit(7); + return i | A; +} + // -auto HuC6280::instruction_alu_absolute(fp alu, uint8 index) -> void { +auto HuC6280::TAI(uint16& source, uint16& target) -> void { + source ^= 1; + target++; +} + +auto HuC6280::TDD(uint16& source, uint16& target) -> void { + source--; + target--; +} + +auto HuC6280::TIA(uint16& source, uint16& target) -> void { + source++; + target ^= 1; +} + +auto HuC6280::TII(uint16& source, uint16& target) -> void { + source++; + target++; +} + +auto HuC6280::TIN(uint16& source, uint16& target) -> void { + source++; +} + +// + +auto HuC6280::instruction_absoluteLoad(fp alu, uint8& data, uint8 index) -> void { uint16 absolute = operand(); absolute |= operand() << 8; io(); -L A = ALU(load(absolute + index)); +L data = ALU(load(absolute + index)); } -auto HuC6280::instruction_alu_immediate(fp alu) -> void { - A = ALU(operand()); +auto HuC6280::instruction_absoluteModify(fp alu, uint8 index) -> void { + uint16 absolute = operand(); + absolute |= operand() << 8; + io(); + io(); + auto data = ALU(load(absolute + index)); +L store(absolute + index, data); +} + +auto HuC6280::instruction_absoluteStore(uint8 data, uint8 index) -> void { + uint16 absolute = operand(); + absolute |= operand() << 8; + io(); +L store(absolute + index, data); +} + +auto HuC6280::instruction_blockmove(bp alu) -> void { + uint16 source = operand(); + source |= operand() << 8; + uint16 target = operand(); + target |= operand() << 8; + uint16 length = operand(); + length |= operand() << 8; + do { + auto data = load(source); + store(target, data); + ALU(source, target); + } while(--length); L io(); } -auto HuC6280::instruction_alu_implied(fp alu, uint8& b) -> void { - b = ALU(b); -L io(); -} - -auto HuC6280::instruction_alu_indirect(fp alu, uint8 index) -> void { - auto zeropage = operand(); - io(); - auto absolute = load(0x2000 + zeropage + index); - absolute |= load(0x2001 + zeropage + index) << 8; -L A = ALU(load(absolute)); -} - -auto HuC6280::instruction_alu_indirectY(fp alu) -> void { - auto zeropage = operand(); - io(); - auto absolute = load(0x2000 + zeropage); - absolute |= load(0x2001 + zeropage) << 8; -L A = ALU(load(absolute + Y)); -} - -auto HuC6280::instruction_alu_memory(fp alu) -> void { - auto a = A; - A = load(0x2000 + X); - instruction_alu_immediate(alu); - store(0x2000 + X, A); - A = a; -} - -auto HuC6280::instruction_alu_zeropage(fp alu, uint8 index) -> void { - auto zeropage = operand(); - io(); -L A = ALU(load(0x2000 + zeropage + index)); -} - -auto HuC6280::instruction_bra(bool c) -> void { - if(!c) { +auto HuC6280::instruction_branch(bool take) -> void { + if(!take) { L operand(); } else { auto displacement = operand(); io(); L io(); - PC = PC + (int8)displacement; + PC += (int8)displacement; } } -auto HuC6280::instruction_CLb(uint8& b) -> void { - b = 0; +auto HuC6280::instruction_clear(uint8& data) -> void { + data = 0; L io(); } -auto HuC6280::instruction_CLf(bool& f) -> void { - f = 0; +auto HuC6280::instruction_clear(bool& flag) -> void { + flag = 0; L io(); } +auto HuC6280::instruction_immediate(fp alu, uint8& data) -> void { + data = ALU(operand()); +L io(); +} + +auto HuC6280::instruction_implied(fp alu, uint8& data) -> void { + data = ALU(data); +L io(); +} + +auto HuC6280::instruction_indirectLoad(fp alu, uint8& data, uint8 index) -> void { + auto zeropage = operand(); + io(); + uint16 absolute = load(0x2000 + zeropage + index); + absolute |= load(0x2001 + zeropage + index) << 8; + io(); +L data = ALU(load(absolute)); +} + +auto HuC6280::instruction_indirectStore(uint8 data, uint8 index) -> void { + auto zeropage = operand(); + io(); + auto absolute = load(0x2000 + zeropage + index); + absolute |= load(0x2001 + zeropage + index) << 8; +L store(absolute, data); +} + +auto HuC6280::instruction_indirectYLoad(fp alu, uint8& data) -> void { + auto zeropage = operand(); + io(); + uint16 absolute = load(0x2000 + zeropage); + absolute |= load(0x2001 + zeropage) << 8; + io(); +L data = ALU(load(absolute + Y)); +} + +auto HuC6280::instruction_indirectYStore(uint8 data) -> void { + auto zeropage = operand(); + io(); + auto absolute = load(0x2000 + zeropage); + absolute |= load(0x2001 + zeropage) << 8; +L store(absolute + Y, data); +} + +auto HuC6280::instruction_memory(fp alu) -> void { + auto a = A; + A = ALU(load(0x2000 + X)); +L store(0x2000 + X, A); + A = a; +} + +auto HuC6280::instruction_pull(uint8& data) -> void { + io(); + io(); +L data = pull(); +} + +auto HuC6280::instruction_pullP() -> void { + io(); + io(); +L P = pull(); +} + +auto HuC6280::instruction_push(uint8 data) -> void { + io(); +L push(data); +} + +auto HuC6280::instruction_set(bool& flag) -> void { + flag = 1; +L io(); +} + +auto HuC6280::instruction_swap(uint8& lhs, uint8& rhs) -> void { + swap(lhs, rhs); + io(); +L io(); +} + +auto HuC6280::instruction_transfer(uint8& source, uint8& target) -> void { + target = source; +L io(); + Z = target == 0; + N = target.bit(7); +} + +auto HuC6280::instruction_zeropageLoad(fp alu, uint8& data, uint8 index) -> void { + auto zeropage = operand(); + io(); +L data = ALU(load(0x2000 + zeropage + index)); +} + +auto HuC6280::instruction_zeropageModify(fp alu, uint8 index) -> void { + auto zeropage = operand(); + io(); + io(); + auto data = ALU(load(0x2000 + zeropage + index)); +L store(0x2000 + zeropage + index, data); +} + +auto HuC6280::instruction_zeropageStore(uint8 data, uint8 index) -> void { + auto zeropage = operand(); + io(); +L store(0x2000 + zeropage + index, data); +} + +// + +auto HuC6280::instruction_BBR(uint3 index) -> void { + auto zeropage = operand(); + auto displacement = operand(); + io(); + io(); +L io(); + if(zeropage.bit(index) == 0) { + PC += (int8)displacement; + } +} + +auto HuC6280::instruction_BBS(uint3 index) -> void { + auto zeropage = operand(); + auto displacement = operand(); + io(); + io(); +L io(); + if(zeropage.bit(index) == 1) { + PC += (int8)displacement; + } +} + +auto HuC6280::instruction_BRK() -> void { + operand(); + io(); + push(PC >> 8); + push(PC >> 0); + uint8 p = P; + push(p | 0x10); //B flag set on push + I = 1; + D = 0; + PC.byte(0) = load(0xfff6); +L PC.byte(1) = load(0xfff7); +} + +auto HuC6280::instruction_BSR() -> void { + auto displacement = operand(); + io(); + io(); + io(); + io(); + push((PC - 1) >> 8); +L push((PC - 1) >> 0); + PC += (int8)displacement; +} + auto HuC6280::instruction_CSL() -> void { r.cs = 12; L io(); @@ -197,104 +384,80 @@ auto HuC6280::instruction_CSH() -> void { L io(); } -auto HuC6280::instruction_LDA_indirect(uint8 index) -> void { - auto zeropage = operand(); - io(); - auto absolute = load(0x2000 + zeropage + index); - absolute |= load(0x2001 + zeropage + index) << 8; -L A = LD(load(absolute)); -} - -auto HuC6280::instruction_LDA_indirectY() -> void { - auto zeropage = operand(); - io(); - auto absolute = load(0x2000 + zeropage); - absolute |= load(0x2001 + zeropage) << 8; -L A = LD(load(absolute + Y)); -} - -auto HuC6280::instruction_LDb_absolute(uint8& b, uint8 index) -> void { - uint16 absolute = operand(); - absolute |= operand() << 8; - io(); -L b = LD(load(absolute + index)); -} - -auto HuC6280::instruction_LDb_immediate(uint8& b) -> void { - b = LD(operand()); +auto HuC6280::instruction_JMP_absolute() -> void { + uint16 address = operand(); + address |= operand() << 8; L io(); + PC = address; } -auto HuC6280::instruction_LDb_zeropage(uint8& b, uint8 index) -> void { - auto zeropage = operand(); +auto HuC6280::instruction_JMP_indirect(uint8 index) -> void { + uint16 address = operand(); + address |= operand() << 8; io(); -L b = LD(load(0x2000 + zeropage + index)); + io(); + PC.byte(0) = load(address + index + 0); +L PC.byte(1) = load(address + index + 1); +} + +auto HuC6280::instruction_JSR() -> void { + uint16 address = operand(); + address |= operand() << 8; + io(); + io(); + push((PC - 1) >> 8); +L push((PC - 1) >> 0); + PC = address; } auto HuC6280::instruction_NOP() -> void { L io(); } -auto HuC6280::instruction_PHb(uint8& b) -> void { +auto HuC6280::instruction_RMB(uint3 index) -> void { + auto zeropage = operand(); io(); -L push(b); + io(); + io(); + auto data = load(0x2000 + zeropage); + data.bit(index) = 0; +L store(0x2000 + zeropage, data); } -auto HuC6280::instruction_PHP() -> void { +auto HuC6280::instruction_RTI() -> void { io(); -L push(P); + io(); + io(); + P = pull(); + PC.byte(0) = pull(); +L PC.byte(1) = pull(); } -auto HuC6280::instruction_PLb(uint8& b) -> void { +auto HuC6280::instruction_RTS() -> void { io(); io(); -L b = pull(); -} - -auto HuC6280::instruction_PLP() -> void { io(); - io(); -L P = pull(); -} - -auto HuC6280::instruction_SEf(bool& f) -> void { - f = 1; + PC.byte(0) = pull(); + PC.byte(1) = pull(); L io(); + PC++; } -auto HuC6280::instruction_STA_indirect(uint8 index) -> void { +auto HuC6280::instruction_SMB(uint3 index) -> void { auto zeropage = operand(); io(); - auto absolute = load(0x2000 + zeropage + index); - absolute |= load(0x2001 + zeropage + index) << 8; -L store(absolute, A); -} - -auto HuC6280::instruction_STA_indirectY() -> void { - auto zeropage = operand(); io(); - auto absolute = load(0x2000 + zeropage); - absolute |= load(0x2001 + zeropage) << 8; -L store(absolute + Y, A); -} - -auto HuC6280::instruction_STb_absolute(uint8 b, uint8 index) -> void { - uint16 absolute = operand(); - absolute |= operand() << 8; io(); -L store(absolute + index, b); + auto data = load(0x2000 + zeropage); + data.bit(index) = 1; +L store(0x2000 + zeropage, data); } -auto HuC6280::instruction_STb_zeropage(uint8 b, uint8 index) -> void { - auto zeropage = operand(); - io(); -L store(0x2000 + zeropage + index, b); -} - -auto HuC6280::instruction_Sbb(uint8& lhs, uint8& rhs) -> void { - swap(lhs, rhs); +auto HuC6280::instruction_ST(uint2 index) -> void { + auto data = operand(); io(); L io(); + st(index, data); } auto HuC6280::instruction_TAM() -> void { @@ -307,13 +470,6 @@ L io(); } } -auto HuC6280::instruction_Tbb(uint8& source, uint8& target) -> void { - target = source; -L io(); - Z = target == 0; - N = target.bit(7); -} - auto HuC6280::instruction_TMA() -> void { auto mask = operand(); io(); @@ -323,6 +479,31 @@ L io(); } } +auto HuC6280::instruction_TST_absolute(uint8 index) -> void { + auto mask = operand(); + uint16 absolute = operand(); + absolute |= operand() << 8; + io(); + io(); + io(); +L uint8 data = load(absolute + index) & mask; + Z = data == 0; + V = data.bit(6); + N = data.bit(7); +} + +auto HuC6280::instruction_TST_zeropage(uint8 index) -> void { + auto mask = operand(); + auto zeropage = operand(); + io(); + io(); + io(); +L uint8 data = load(0x2000 + zeropage + index) & mask; + Z = data == 0; + V = data.bit(6); + N = data.bit(7); +} + auto HuC6280::instruction_TXS() -> void { S = X; L io();