diff --git a/bsnes.exe b/bsnes.exe index 52006839..6081d321 100644 Binary files a/bsnes.exe and b/bsnes.exe differ diff --git a/src/apu/apu.h b/src/apu/apu.h index a9161316..2b37273e 100644 --- a/src/apu/apu.h +++ b/src/apu/apu.h @@ -23,6 +23,8 @@ APURegs regs; virtual void power() = 0; virtual void reset() = 0; +//debugging functions + virtual bool in_opcode(); void disassemble_opcode(char *output); inline uint16 __relb(int8 offset, int op_len); }; diff --git a/src/apu/bapu/bapu.cpp b/src/apu/bapu/bapu.cpp index 0ff12828..452fbc2d 100644 --- a/src/apu/bapu/bapu.cpp +++ b/src/apu/bapu/bapu.cpp @@ -226,7 +226,8 @@ void bAPU::reset() { regs.sp = 0xef; regs.p = 0x02; - status.cycle_pos = 0; + status.cycle_pos = 0; + status.cycles_executed = 0; //$f1 status.iplrom_enabled = true; diff --git a/src/apu/bapu/bapu.h b/src/apu/bapu/bapu.h index a603c547..b09d4338 100644 --- a/src/apu/bapu/bapu.h +++ b/src/apu/bapu/bapu.h @@ -53,6 +53,7 @@ enum { inline void stack_write(uint8 value); inline void exec_cycle(); + inline bool in_opcode(); inline void init_op_table(); inline uint8 op_adc (uint8 x, uint8 y); diff --git a/src/apu/bapu/bapu_exec.cpp b/src/apu/bapu/bapu_exec.cpp index 279d5fcb..37235466 100644 --- a/src/apu/bapu/bapu_exec.cpp +++ b/src/apu/bapu/bapu_exec.cpp @@ -15,6 +15,11 @@ uint8 op; } } +//only return true when we are on an opcode edge +bool bAPU::in_opcode() { + return (status.cycle_pos != 0); +} + void bAPU::init_op_table() { #include "bapu_optable.cpp" } diff --git a/src/apu/bapu/bapugen.cpp b/src/apu/bapu/bapugen.cpp index 8c5169e9..6900bf5a 100644 --- a/src/apu/bapu/bapugen.cpp +++ b/src/apu/bapu/bapugen.cpp @@ -107,16 +107,16 @@ int i, l; replace(t, "$5", op_list[i].arg[5]); replace(t, "$6", op_list[i].arg[6]); replace(t, "$7", op_list[i].arg[7]); - fprintf(fp, "%s\r\n\r\n", *t); + fprintf(fp, "%s\r\n\r\n", strptr(t)); strcpy(t, output_header); replace(t, "$$", op_list[i].name); - fprintf(fph, "%s", *t); + fprintf(fph, "%s", strptr(t)); strcpy(t, output_table); replace(t, "$$", op_list[i].name); replace(t, "$0", op_list[i].arg[0]); - fprintf(fpt, "%s", *t); + fprintf(fpt, "%s", strptr(t)); } } diff --git a/src/apu/bapu/bapugen.exe b/src/apu/bapu/bapugen.exe index e08b8e2d..4f0e81b9 100644 Binary files a/src/apu/bapu/bapugen.exe and b/src/apu/bapu/bapugen.exe differ diff --git a/src/apu/dapu.cpp b/src/apu/dapu.cpp index 5377cadd..52f844cc 100644 --- a/src/apu/dapu.cpp +++ b/src/apu/dapu.cpp @@ -1,12 +1,23 @@ +//virtual function, see src/cpu/dcpu.cpp +//for explanation of this function +bool APU::in_opcode() { return false; } + uint16 APU::__relb(int8 offset, int op_len) { uint16 pc = regs.pc + op_len; return pc + offset; } void APU::disassemble_opcode(char *output) { -char *s = output, t[512]; +char *s, t[512]; uint8 op, op0, op1; uint16 opw, opdp0, opdp1; + s = output; + + if(in_opcode() == true) { + strcpy(s, "..???? "); + return; + } + sprintf(s, "..%0.4x ", regs.pc); op = spcram_read(regs.pc); diff --git a/src/base.h b/src/base.h index 98efb23d..bbb683fb 100644 --- a/src/base.h +++ b/src/base.h @@ -1,6 +1,16 @@ #include #include "lib/libbase.h" +#if defined(_WIN32) + #define _WIN32_ + #undef _UNIX_ +#elif defined(__GNUC__) + #define _UNIX_ + #undef _WIN32_ +#else + #error "unknown architecture" +#endif + //structs typedef struct { uint8 *data; diff --git a/src/chip/sdd1/sdd1.cpp b/src/chip/sdd1/sdd1.cpp new file mode 100644 index 00000000..b26d0e3f --- /dev/null +++ b/src/chip/sdd1/sdd1.cpp @@ -0,0 +1,94 @@ +#include "../../base.h" +#include "sdd1emu.cpp" + +void SDD1::power() { + reset(); +} + +void SDD1::reset() { + sdd1.index[0] = 0x000000; + sdd1.index[1] = 0x100000; + sdd1.index[2] = 0x200000; + sdd1.index[3] = 0x300000; + + for(int i=0;i<8;i++) { + sdd1.active[i] = false; + } + + sdd1.dma_active = false; +} + +uint32 SDD1::offset(uint32 addr) { +uint8 b = (addr >> 16) & 0xff; + if(b <= 0xbf)return 0; + + b -= 0xc0; //b = 0x00-0x3f + b >>= 4; //b = 0-3 + b &= 3; //bitmask + + return sdd1.index[b] + (addr & 0x0fffff); +} + +uint8 SDD1::mmio_read(uint16 addr) { + switch(addr) { + //>>20 == 0x100000 == 1mb + case 0x4804:return (sdd1.index[0] >> 20) & 7; + case 0x4805:return (sdd1.index[1] >> 20) & 7; + case 0x4806:return (sdd1.index[2] >> 20) & 7; + case 0x4807:return (sdd1.index[3] >> 20) & 7; + } + + return cpu->regs.mdr; +} + +void SDD1::mmio_write(uint16 addr, uint8 data) { +int i; + switch(addr) { + case 0x4801: + for(i=0;i<8;i++) { + sdd1.active[i] = !!(data & (1 << i)); + } + break; + //<<20 == 0x100000 == 1mb + case 0x4804:sdd1.index[0] = (data & 7) << 20;break; + case 0x4805:sdd1.index[1] = (data & 7) << 20;break; + case 0x4806:sdd1.index[2] = (data & 7) << 20;break; + case 0x4807:sdd1.index[3] = (data & 7) << 20;break; + } +} + +void SDD1::dma_begin(uint8 channel, uint32 addr, uint16 length) { + if(sdd1.active[channel] == true) { + sdd1.active[channel] = false; + sdd1.dma_active = true; + sdd1.buffer_index = 0; + sdd1.buffer_size = length; + sdd1emu.decompress(addr, (length) ? length : 65536, sdd1.buffer); + } +} + +bool SDD1::dma_active() { + return sdd1.dma_active; +} + +uint8 SDD1::dma_read() { + if(--sdd1.buffer_size == 0) { + sdd1.dma_active = false; + } + +//sdd1.buffer[] is 65536 bytes, and sdd1.buffer_index +//is of type uint16, so no buffer overflow is possible + return sdd1.buffer[sdd1.buffer_index++]; +} + +SDD1::SDD1() { + mmio = new SDD1MMIO(); +} + +uint8 SDD1MMIO::read(uint32 addr) { + return sdd1->mmio_read(addr); +} + +void SDD1MMIO::write(uint32 addr, uint8 value) { + sdd1->mmio_write(addr, value); +} diff --git a/src/chip/sdd1/sdd1.h b/src/chip/sdd1/sdd1.h new file mode 100644 index 00000000..d8cba35b --- /dev/null +++ b/src/chip/sdd1/sdd1.h @@ -0,0 +1,36 @@ +#include "sdd1emu.h" + +class SDD1MMIO : public MMIO { +public: + inline uint8 read (uint32 addr); + inline void write(uint32 addr, uint8 value); +}; + +class SDD1 { +public: +SDD1emu sdd1emu; +SDD1MMIO *mmio; + +struct { + uint32 index[4]; //memory mapping registers + uint8 buffer[65536]; //pointer to decompressed S-DD1 data, + //max. DMA length is 65536 + uint16 buffer_index; //DMA read index into S-DD1 decompression buffer + uint16 buffer_size; + bool active[8]; //true when DMA channel should pass through S-DD1 + bool dma_active; +}sdd1; + void init(); + void power(); + void reset(); + uint32 offset(uint32 addr); + + void dma_begin(uint8 channel, uint32 addr, uint16 length); + bool dma_active(); + uint8 dma_read(); + + uint8 mmio_read(uint16 addr); + void mmio_write(uint16 addr, uint8 data); + + SDD1(); +}; diff --git a/src/chip/sdd1/sdd1emu.cpp b/src/chip/sdd1/sdd1emu.cpp new file mode 100644 index 00000000..c98506ee --- /dev/null +++ b/src/chip/sdd1/sdd1emu.cpp @@ -0,0 +1,447 @@ +/************************************************************************ + +S-DD1'algorithm emulation code +------------------------------ + +Author: Andreas Naive +Date: August 2003 +Last update: October 2004 + +This code is Public Domain. There is no copyright holded by the author. +Said this, the author wish to explicitly emphasize his inalienable moral rights +over this piece of intelectual work and the previous research that made it +possible, as recognized by most of the copyright laws around the world. + +This code is provided 'as-is', with no warranty, expressed or implied. +No responsability is assumed by the author in connection with it. + +The author is greatly indebted with The Dumper, without whose help and +patience providing him with real S-DD1 data the research would have never been +possible. He also wish to note that in the very beggining of his research, +Neviksti had done some steps in the right direction. By last, the author is +indirectly indebted to all the people that worked and contributed in the +S-DD1 issue in the past. + +An algorithm's documentation is available as a separate document. +The implementation is obvious when the algorithm is +understood. + +************************************************************************/ + +#define SDD1_read(__addr) (mem_bus->read(__addr)) + +//////////////////////////////////////////////////// + + +void SDD1_IM::prepareDecomp(uint32 in_buf) { + + byte_ptr=in_buf; + bit_count=4; + +} + +//////////////////////////////////////////////////// + + +uint8 SDD1_IM::getCodeword(uint8 code_len) { + + uint8 codeword; + uint8 comp_count; + + codeword = (SDD1_read(byte_ptr))<>(9-bit_count); + bit_count+=code_len; + } + + if (bit_count & 0x08) { + byte_ptr++; + bit_count&=0x07; + } + + return codeword; + +} + +////////////////////////////////////////////////////// + + +SDD1_GCD::SDD1_GCD(SDD1_IM *associatedIM) : + IM(associatedIM) +{ + +} + +////////////////////////////////////////////////////// + + +void SDD1_GCD::getRunCount(uint8 code_num, uint8 *MPScount, bool8 *LPSind) { + + const uint8 run_count[] = { + 0x00, 0x00, 0x01, 0x00, 0x03, 0x01, 0x02, 0x00, + 0x07, 0x03, 0x05, 0x01, 0x06, 0x02, 0x04, 0x00, + 0x0f, 0x07, 0x0b, 0x03, 0x0d, 0x05, 0x09, 0x01, + 0x0e, 0x06, 0x0a, 0x02, 0x0c, 0x04, 0x08, 0x00, + 0x1f, 0x0f, 0x17, 0x07, 0x1b, 0x0b, 0x13, 0x03, + 0x1d, 0x0d, 0x15, 0x05, 0x19, 0x09, 0x11, 0x01, + 0x1e, 0x0e, 0x16, 0x06, 0x1a, 0x0a, 0x12, 0x02, + 0x1c, 0x0c, 0x14, 0x04, 0x18, 0x08, 0x10, 0x00, + 0x3f, 0x1f, 0x2f, 0x0f, 0x37, 0x17, 0x27, 0x07, + 0x3b, 0x1b, 0x2b, 0x0b, 0x33, 0x13, 0x23, 0x03, + 0x3d, 0x1d, 0x2d, 0x0d, 0x35, 0x15, 0x25, 0x05, + 0x39, 0x19, 0x29, 0x09, 0x31, 0x11, 0x21, 0x01, + 0x3e, 0x1e, 0x2e, 0x0e, 0x36, 0x16, 0x26, 0x06, + 0x3a, 0x1a, 0x2a, 0x0a, 0x32, 0x12, 0x22, 0x02, + 0x3c, 0x1c, 0x2c, 0x0c, 0x34, 0x14, 0x24, 0x04, + 0x38, 0x18, 0x28, 0x08, 0x30, 0x10, 0x20, 0x00, + 0x7f, 0x3f, 0x5f, 0x1f, 0x6f, 0x2f, 0x4f, 0x0f, + 0x77, 0x37, 0x57, 0x17, 0x67, 0x27, 0x47, 0x07, + 0x7b, 0x3b, 0x5b, 0x1b, 0x6b, 0x2b, 0x4b, 0x0b, + 0x73, 0x33, 0x53, 0x13, 0x63, 0x23, 0x43, 0x03, + 0x7d, 0x3d, 0x5d, 0x1d, 0x6d, 0x2d, 0x4d, 0x0d, + 0x75, 0x35, 0x55, 0x15, 0x65, 0x25, 0x45, 0x05, + 0x79, 0x39, 0x59, 0x19, 0x69, 0x29, 0x49, 0x09, + 0x71, 0x31, 0x51, 0x11, 0x61, 0x21, 0x41, 0x01, + 0x7e, 0x3e, 0x5e, 0x1e, 0x6e, 0x2e, 0x4e, 0x0e, + 0x76, 0x36, 0x56, 0x16, 0x66, 0x26, 0x46, 0x06, + 0x7a, 0x3a, 0x5a, 0x1a, 0x6a, 0x2a, 0x4a, 0x0a, + 0x72, 0x32, 0x52, 0x12, 0x62, 0x22, 0x42, 0x02, + 0x7c, 0x3c, 0x5c, 0x1c, 0x6c, 0x2c, 0x4c, 0x0c, + 0x74, 0x34, 0x54, 0x14, 0x64, 0x24, 0x44, 0x04, + 0x78, 0x38, 0x58, 0x18, 0x68, 0x28, 0x48, 0x08, + 0x70, 0x30, 0x50, 0x10, 0x60, 0x20, 0x40, 0x00, + }; + + uint8 codeword=IM->getCodeword(code_num); + + if (codeword & 0x80) { + *LPSind=1; + *MPScount=run_count[codeword>>(code_num^0x07)]; + } + else { + *MPScount=(1<getRunCount(code_num, &MPScount, &LPSind); + + if (MPScount) { + bit=0; + MPScount--; + } + else { + bit=1; + LPSind=0; + } + + if (MPScount || LPSind) (*endOfRun)=0; + else (*endOfRun)=1; + + return bit; + +} + +///////////////////////////////////////////////// + + +SDD1_PEM::SDD1_PEM(SDD1_BG *associatedBG0, SDD1_BG *associatedBG1, + SDD1_BG *associatedBG2, SDD1_BG *associatedBG3, + SDD1_BG *associatedBG4, SDD1_BG *associatedBG5, + SDD1_BG *associatedBG6, SDD1_BG *associatedBG7) { + + BG[0]=associatedBG0; + BG[1]=associatedBG1; + BG[2]=associatedBG2; + BG[3]=associatedBG3; + BG[4]=associatedBG4; + BG[5]=associatedBG5; + BG[6]=associatedBG6; + BG[7]=associatedBG7; + +} + +///////////////////////////////////////////////////////// + + +const SDD1_PEM::state SDD1_PEM::evolution_table[]={ + { 0,25,25}, + { 0, 2, 1}, + { 0, 3, 1}, + { 0, 4, 2}, + { 0, 5, 3}, + { 1, 6, 4}, + { 1, 7, 5}, + { 1, 8, 6}, + { 1, 9, 7}, + { 2,10, 8}, + { 2,11, 9}, + { 2,12,10}, + { 2,13,11}, + { 3,14,12}, + { 3,15,13}, + { 3,16,14}, + { 3,17,15}, + { 4,18,16}, + { 4,19,17}, + { 5,20,18}, + { 5,21,19}, + { 6,22,20}, + { 6,23,21}, + { 7,24,22}, + { 7,24,23}, + { 0,26, 1}, + { 1,27, 2}, + { 2,28, 4}, + { 3,29, 8}, + { 4,30,12}, + { 5,31,16}, + { 6,32,18}, + { 7,24,22} + }; + +////////////////////////////////////////////////////// + + +void SDD1_PEM::prepareDecomp(void) { + + for (uint8 i=0; i<32; i++) { + contextInfo[i].status=0; + contextInfo[i].MPS=0; + } + +} + +///////////////////////////////////////////////////////// + + +uint8 SDD1_PEM::getBit(uint8 context) { + + bool8 endOfRun; + uint8 bit; + + SDD1_ContextInfo *pContInfo=&contextInfo[context]; + uint8 currStatus = pContInfo->status; + const state *pState=&SDD1_PEM::evolution_table[currStatus]; + uint8 currentMPS=pContInfo->MPS; + + bit=(BG[pState->code_num])->getBit(&endOfRun); + + if (endOfRun) + if (bit) { + if (!(currStatus & 0xfe)) (pContInfo->MPS)^=0x01; + (pContInfo->status)=pState->nextIfLPS; + } + else + (pContInfo->status)=pState->nextIfMPS; + + return bit^currentMPS; + +} + +////////////////////////////////////////////////////////////// + + +SDD1_CM::SDD1_CM(SDD1_PEM *associatedPEM) : + PEM(associatedPEM) +{ + +} + +////////////////////////////////////////////////////////////// + + +void SDD1_CM::prepareDecomp(uint32 first_byte) { + + bitplanesInfo = SDD1_read(first_byte) & 0xc0; + contextBitsInfo = SDD1_read(first_byte) & 0x30; + bit_number=0; + for (int i=0; i<8; i++) prevBitplaneBits[i]=0; + switch (bitplanesInfo) { + case 0x00: + currBitplane = 1; + break; + case 0x40: + currBitplane = 7; + break; + case 0x80: + currBitplane = 3; + } + +} + +///////////////////////////////////////////////////////////// + + +uint8 SDD1_CM::getBit(void) { + + uint8 currContext; + uint16 *context_bits; + + switch (bitplanesInfo) { + case 0x00: + currBitplane ^= 0x01; + break; + case 0x40: + currBitplane ^= 0x01; + if (!(bit_number & 0x7f)) currBitplane = ((currBitplane+2) & 0x07); + break; + case 0x80: + currBitplane ^= 0x01; + if (!(bit_number & 0x7f)) currBitplane ^= 0x02; + break; + case 0xc0: + currBitplane = bit_number & 0x07; + } + + context_bits = &prevBitplaneBits[currBitplane]; + + currContext=(currBitplane & 0x01)<<4; + switch (contextBitsInfo) { + case 0x00: + currContext|=((*context_bits & 0x01c0)>>5)|(*context_bits & 0x0001); + break; + case 0x10: + currContext|=((*context_bits & 0x0180)>>5)|(*context_bits & 0x0001); + break; + case 0x20: + currContext|=((*context_bits & 0x00c0)>>5)|(*context_bits & 0x0001); + break; + case 0x30: + currContext|=((*context_bits & 0x0180)>>5)|(*context_bits & 0x0003); + } + + uint8 bit=PEM->getBit(currContext); + + *context_bits <<= 1; + *context_bits |= bit; + + bit_number++; + + return bit; + +} + +////////////////////////////////////////////////// + + +SDD1_OL::SDD1_OL(SDD1_CM *associatedCM) : + CM(associatedCM) +{ + +} + +/////////////////////////////////////////////////// + + +void SDD1_OL::prepareDecomp(uint32 first_byte, uint16 out_len, uint8 *out_buf) { + + bitplanesInfo = SDD1_read(first_byte) & 0xc0; + length=out_len; + buffer=out_buf; + +} + +/////////////////////////////////////////////////// + + +void SDD1_OL::launch(void) { + + uint8 i; + uint8 register1, register2; + + switch (bitplanesInfo) { + case 0x00: + case 0x40: + case 0x80: + i=1; + do { //if length==0, we output 2^16 bytes + if (!i) { + *(buffer++)=register2; + i=~i; + } + else { + for (register1=register2=0, i=0x80; i; i>>=1) { + if (CM->getBit()) register1 |= i; + if (CM->getBit()) register2 |= i; + } + *(buffer++)=register1; + } + } while (--length); + break; + case 0xc0: + do { + for (register1=0, i=0x01; i; i<<=1) { + if (CM->getBit()) register1 |= i; + } + *(buffer++)=register1; + } while (--length); + } + +} + +/////////////////////////////////////////////////////// + + +void SDD1emu::decompress(uint32 in_buf, uint16 out_len, uint8 *out_buf) { + + IM.prepareDecomp(in_buf); + BG0.prepareDecomp(); + BG1.prepareDecomp(); + BG2.prepareDecomp(); + BG3.prepareDecomp(); + BG4.prepareDecomp(); + BG5.prepareDecomp(); + BG6.prepareDecomp(); + BG7.prepareDecomp(); + PEM.prepareDecomp(); + CM.prepareDecomp(in_buf); + OL.prepareDecomp(in_buf, out_len, out_buf); + + OL.launch(); + +} + +//////////////////////////////////////////////////////////// + + +SDD1emu::SDD1emu() : + GCD(&IM), + BG0(&GCD, 0), BG1(&GCD, 1), BG2(&GCD, 2), BG3(&GCD, 3), + BG4(&GCD, 4), BG5(&GCD, 5), BG6(&GCD, 6), BG7(&GCD, 7), + PEM(&BG0, &BG1, &BG2, &BG3, &BG4, &BG5, &BG6, &BG7), + CM(&PEM), + OL(&CM) +{ + +} + +/////////////////////////////////////////////////////////// diff --git a/src/chip/sdd1/sdd1emu.h b/src/chip/sdd1/sdd1emu.h new file mode 100644 index 00000000..94b723da --- /dev/null +++ b/src/chip/sdd1/sdd1emu.h @@ -0,0 +1,161 @@ +/************************************************************************ + +S-DD1'algorithm emulation code +------------------------------ + +Author: Andreas Naive +Date: August 2003 +Last update: October 2004 + +This code is Public Domain. There is no copyright holded by the author. +Said this, the author wish to explicitly emphasize his inalienable moral rights +over this piece of intelectual work and the previous research that made it +possible, as recognized by most of the copyright laws around the world. + +This code is provided 'as-is', with no warranty, expressed or implied. +No responsability is assumed by the author in connection with it. + +The author is greatly indebted with The Dumper, without whose help and +patience providing him with real S-DD1 data the research would have never been +possible. He also wish to note that in the very beggining of his research, +Neviksti had done some steps in the right direction. By last, the author is +indirectly indebted to all the people that worked and contributed in the +S-DD1 issue in the past. + +An algorithm's documentation is available as a separate document. +The implementation is obvious when the algorithm is +understood. + +************************************************************************/ + + +class SDD1_IM { //Input Manager + + public: + SDD1_IM(void) {} + void prepareDecomp(uint32 in_buf); + uint8 getCodeword(const uint8 code_len); + + private: + uint32 byte_ptr; + uint8 bit_count; + +}; + +//////////////////////////////////////////////////// + + +class SDD1_GCD { //Golomb-Code Decoder + + public: + SDD1_GCD(SDD1_IM *associatedIM); + void getRunCount(uint8 code_num, uint8 *MPScount, bool8 *LPSind); + + private: + SDD1_IM *const IM; + +}; + +////////////////////////////////////////////////////// + + +class SDD1_BG { // Bits Generator + + public: + SDD1_BG(SDD1_GCD *associatedGCD, uint8 code); + void prepareDecomp(void); + uint8 getBit(bool8 *endOfRun); + + private: + const uint8 code_num; + uint8 MPScount; + bool8 LPSind; + SDD1_GCD *const GCD; + +}; + +//////////////////////////////////////////////// + + +class SDD1_PEM { //Probability Estimation Module + + public: + SDD1_PEM(SDD1_BG *associatedBG0, SDD1_BG *associatedBG1, + SDD1_BG *associatedBG2, SDD1_BG *associatedBG3, + SDD1_BG *associatedBG4, SDD1_BG *associatedBG5, + SDD1_BG *associatedBG6, SDD1_BG *associatedBG7); + void prepareDecomp(void); + uint8 getBit(uint8 context); + + private: + struct state { + uint8 code_num; + uint8 nextIfMPS; + uint8 nextIfLPS; + }; + static const state evolution_table[]; + struct SDD1_ContextInfo { + uint8 status; + uint8 MPS; + } contextInfo[32]; + SDD1_BG * BG[8]; + +}; + +/////////////////////////////////////////////////// + + +class SDD1_CM { //Context Model + + public: + SDD1_CM(SDD1_PEM *associatedPEM); + void prepareDecomp(uint32 first_byte); + uint8 getBit(void); + + private: + uint8 bitplanesInfo; + uint8 contextBitsInfo; + uint8 bit_number; + uint8 currBitplane; + uint16 prevBitplaneBits[8]; + SDD1_PEM *const PEM; + +}; + +/////////////////////////////////////////////////// + + +class SDD1_OL { //Output Logic + + public: + SDD1_OL(SDD1_CM *associatedCM); + void prepareDecomp(uint32 first_byte, uint16 out_len, uint8 *out_buf); + void launch(void); + + private: + uint8 bitplanesInfo; + uint16 length; + uint8 *buffer; + SDD1_CM *const CM; + +}; + +///////////////////////////////////////////////////////// + + +class SDD1emu { + + public: + SDD1emu(void); + void decompress(uint32 in_buf, uint16 out_len, uint8 *out_buf); + + private: + SDD1_IM IM; + SDD1_GCD GCD; + SDD1_BG BG0; SDD1_BG BG1; SDD1_BG BG2; SDD1_BG BG3; + SDD1_BG BG4; SDD1_BG BG5; SDD1_BG BG6; SDD1_BG BG7; + SDD1_PEM PEM; + SDD1_CM CM; + SDD1_OL OL; + +}; diff --git a/src/cpu/bcpu/srtc.cpp b/src/chip/srtc/srtc.cpp similarity index 89% rename from src/cpu/bcpu/srtc.cpp rename to src/chip/srtc/srtc.cpp index d1c1281d..3601ecd9 100644 --- a/src/cpu/bcpu/srtc.cpp +++ b/src/chip/srtc/srtc.cpp @@ -50,7 +50,9 @@ whenever the RTC is set. */ -void bCPU::srtc_set_time() { +#include "../../base.h" + +void SRTC::set_time() { time_t rawtime; tm *t; ::time(&rawtime); @@ -72,12 +74,12 @@ tm *t; srtc.data[12] = t->tm_wday; } -void bCPU::srtc_power() { +void SRTC::power() { memset(&srtc, 0, sizeof(srtc)); reset(); } -void bCPU::srtc_reset() { +void SRTC::reset() { srtc.index = -1; srtc.mode = SRTC_READ; } @@ -87,7 +89,7 @@ void bCPU::srtc_reset() { //as reads will refresh the data array with the current system //time. The write method is only here for the sake of faux //emulation of the real hardware. -void bCPU::srtc_write(uint8 data) { +void SRTC::write(uint8 data) { data &= 0x0f; //only the low four bits are used if(data >= 0x0d) { @@ -140,10 +142,10 @@ void bCPU::srtc_write(uint8 data) { } } -uint8 bCPU::srtc_read() { +uint8 SRTC::read() { if(srtc.mode == SRTC_READ) { if(srtc.index < 0) { - srtc_set_time(); + set_time(); srtc.index++; return 0x0f; //send start message } else if(srtc.index > MAX_SRTC_INDEX) { @@ -156,3 +158,21 @@ uint8 bCPU::srtc_read() { return 0x00; } } + +SRTC::SRTC() { + mmio = new SRTCMMIO(); +} + +uint8 SRTCMMIO::read(uint32 addr) { + switch(addr) { + case 0x2800:return srtc->read(); + } + + return cpu->regs.mdr; +} + +void SRTCMMIO::write(uint32 addr, uint8 value) { + switch(addr) { + case 0x2801:srtc->write(value);break; + } +} diff --git a/src/cpu/bcpu/srtc.h b/src/chip/srtc/srtc.h similarity index 63% rename from src/cpu/bcpu/srtc.h rename to src/chip/srtc/srtc.h index 4a828e3f..8f0ef48b 100644 --- a/src/cpu/bcpu/srtc.h +++ b/src/chip/srtc/srtc.h @@ -1,10 +1,12 @@ -void srtc_set_time(); -void srtc_power(); -void srtc_reset(); -void srtc_write(uint8 data); -uint8 srtc_read(); +class SRTCMMIO : public MMIO { +public: + inline uint8 read (uint32 addr); + inline void write(uint32 addr, uint8 value); +}; -#define MAX_SRTC_INDEX 0x0c +class SRTC { +public: +enum { MAX_SRTC_INDEX = 0x0c }; enum { SRTC_READ = 0, @@ -18,9 +20,7 @@ enum { SRTC_COMMAND_CLEAR = 4 }; -#define DAYTICKS (60*60*24) -#define HOURTICKS (60*60) -#define MINUTETICKS (60) +SRTCMMIO *mmio; /****************************** [srtc.data structure] @@ -38,11 +38,18 @@ Index Description Range 9 Year ones 0-9 10 Year tens 0-9 11 Year hundreds 9-11 (9=19xx, 10=20xx, 11=21xx) - 12 Day of week 0-6 (0=Sunday, ...) + 12 Day of week 0-6 (0=Sunday, ...) ******************************/ - struct { int8 index; uint8 mode; uint8 data[MAX_SRTC_INDEX + 1]; }srtc; + void set_time(); + void power(); + void reset(); + void write(uint8 data); + uint8 read(); + + SRTC(); +}; diff --git a/src/cpu/bcpu/bcpu.cpp b/src/cpu/bcpu/bcpu.cpp index 94fe4f44..33ea3b4c 100644 --- a/src/cpu/bcpu/bcpu.cpp +++ b/src/cpu/bcpu/bcpu.cpp @@ -1,7 +1,5 @@ #include "../../base.h" -#include "srtc.cpp" - #include "bcpu_opfn.cpp" #include "bcpu_op_read.cpp" #include "bcpu_op_rmw.cpp" @@ -58,9 +56,11 @@ void bCPU::irq(uint16 addr) { snes->notify(SNES::CPU_EXEC_OPCODE_END); } +//vcounter range verified on real hardware, +//HDMA runs on the very first scanline of vblank bool bCPU::hdma_test() { if(status.hdma_triggered == false) { - if(vcounter() < (overscan()?239:224) && hcounter() >= 278) { + if(vcounter() <= (overscan()?239:224) && hcounter() >= 278) { status.hdma_triggered = true; return true; } @@ -68,41 +68,62 @@ bool bCPU::hdma_test() { return false; } +//NMI range: V==225/240,H>=12 ; V>225/240 bool bCPU::nmi_test() { - if(vcounter() >= ((overscan()?239:224) + 1) && status.nmi_triggered == false) { - if((vcounter() == ((overscan()?239:224) + 1) && hcycles() >= 12) || (vcounter() > ((overscan()?239:224) + 1))) { - status.nmi_triggered = true; - status.nmi_pin = 0; - if(status.nmi_enabled == true) { - return true; - } - } + if(status.nmi_exec == true)return false; + +//[status.cycle_count index] +// 6->12 +// 8->14 +int hc = status.cycle_count + 6; + if(vcounter() == ((overscan()?239:224) + 1) && hcycles() < hc) { + //dprintf("* miss at %3d,%4d,%3x : %d x=%0.4x", vcounter(), hcycles(), hcounter(), status.cycle_count, regs.x.w); } + + if( + (vcounter() == ((overscan()?239:224) + 1) && hcycles() >= hc) || + (vcounter() > ((overscan()?239:224) + 1)) + ) { + //dprintf("* %3d,%4d,%3x : %d x=%0.4x", vcounter(), hcycles(), hcounter(), status.cycle_count, regs.x.w); + status.nmi_exec = true; + return status.nmi_enabled; + } + return false; } bool bCPU::irq_test() { int vpos, hpos; if(regs.p.i)return false; //no interrupt can occur with I flag set - if(status.irq_pin == 0)return false; //same as above + if(status.irq_read == true)return false; //same as above if(status.virq_enabled == false && status.hirq_enabled == false)return false; +//if irq_exec is true, then an IRQ occurred already. +//IRQs will continue to fire until $4211 is read from, or +//$4200 is written to, where irq_exec is set back to false. + if(status.irq_exec == true) { + return true; + } + //calculate V/H positions required for IRQ to trigger vpos = status.virq_pos; hpos = (status.hirq_enabled) ? status.hirq_pos : 0; //positions that can never be latched - if(vpos == 261 && hpos == 339 && interlace() == false)return false; - if(vpos == 262 && interlace() == false)return false; - if(vpos == 262 && hpos == 339)return false; - if(vpos > 262)return false; +//region_scanlines() = 262/NTSC, 312/PAL +//PAL results are unverified on hardware + if(vpos == 240 && hpos == 339 && interlace() == false && interlace_field() == 1)return false; + if(vpos == (region_scanlines() - 1) && hpos == 339 && interlace() == false)return false; + if(vpos == region_scanlines() && interlace() == false)return false; + if(vpos == region_scanlines() && hpos == 339)return false; + if(vpos > region_scanlines())return false; if(hpos > 339)return false; if(hpos == 0) { - hpos = 24; + hpos = status.cycle_count + 14; } else { hpos <<= 2; - hpos += 24; //30 - status.cycle_count; + hpos += status.cycle_count + 18; //it should be OK to use the current line cycles/frame lines, //as the IRQ will only trigger on the correct scanline anyway... if(hpos >= time.line_cycles) { @@ -116,11 +137,8 @@ int vpos, hpos; if(status.virq_enabled == true && vcounter() != vpos)return false; - if(hcycles() >= hpos && status.irq_pin == 1) { - //dprintf("* vpos=%3d,hpos=%4d; v=%3d,h=%4d; lc=%d,virq=%3d,hirq=%3d", - // vpos, hpos, vcounter(), hcycles(), status.cycle_count, status.virq_pos, status.hirq_pos); - status.irq_triggered = true; - status.irq_pin = 0; + if(hcycles() >= hpos) { + status.irq_exec = true; return true; } @@ -134,20 +152,24 @@ void bCPU::run() { break; case CPUSTATE_RUN: case CPUSTATE_WAI: - if(nmi_test() == true) { - irq(0xffea); - break; + if(status.cycle_pos == 0) { + //interrupts only trigger on opcode edges + if(nmi_test() == true) { + irq(0xffea); + break; + } + if(irq_test() == true) { + irq(0xffee); + break; + } } - if(irq_test() == true) { - irq(0xffee); - break; - } - exec_opcode(); - break; + //fallthrough case CPUSTATE_STP: - exec_opcode(); + exec_cycle(); break; } + + cycle_edge(); } void bCPU::scanline() { @@ -164,23 +186,21 @@ void bCPU::scanline() { } if(status.virq_enabled == false) { - status.irq_pin = 1; + status.irq_read = false; } } void bCPU::frame() { hdma_initialize(); - status.nmi_triggered = false; - status.nmi_pin = 1; - status.r4210_read = false; + status.nmi_read = false; + status.nmi_exec = false; - status.irq_triggered = false; - status.irq_pin = 1; + status.irq_read = false; } void bCPU::power() { - srtc_power(); + region = snes->region(); regs.a = regs.x = regs.y = 0x0000; regs.s = 0x01ff; @@ -188,10 +208,6 @@ void bCPU::power() { } void bCPU::reset() { - srtc_reset(); - - frame(); - //reset vector location regs.pc = mem_bus->read(0xfffc) | (mem_bus->read(0xfffd) << 8); @@ -203,26 +219,33 @@ void bCPU::reset() { regs.db = 0x00; regs.p = 0x34; regs.e = 1; + regs.mdr = 0x00; time_reset(); mmio_reset(); dma_reset(); status.cpu_state = CPUSTATE_RUN; + status.dma_state = DMASTATE_STOP; + + status.cycle_pos = 0; + status.cycle_count = 0; + status.cycles_executed = 0; status.hdma_triggered = false; - status.nmi_triggered = false; - status.nmi_pin = 1; - status.r4210_read = false; + status.nmi_read = false; + status.nmi_exec = false; - status.irq_triggered = false; - status.irq_pin = 1; + status.irq_read = false; + status.irq_exec = false; apu_port[0] = 0x00; apu_port[1] = 0x00; apu_port[2] = 0x00; apu_port[3] = 0x00; + + frame(); } uint8 bCPU::port_read(uint8 port) { @@ -236,7 +259,6 @@ void bCPU::port_write(uint8 port, uint8 value) { void bCPU::cpu_c2() { if(regs.d.l != 0x00) { status.cycle_count = 6; - cycle_edge(); add_cycles(6); } } @@ -244,7 +266,6 @@ void bCPU::cpu_c2() { void bCPU::cpu_c4(uint16 x, uint16 y) { if(!regs.p.x && (x & 0xff00) != (y & 0xff00)) { status.cycle_count = 6; - cycle_edge(); add_cycles(6); } } @@ -252,30 +273,25 @@ void bCPU::cpu_c4(uint16 x, uint16 y) { void bCPU::cpu_c6(uint16 addr) { if(regs.e && (regs.pc.w & 0xff00) != (addr & 0xff00)) { status.cycle_count = 6; - cycle_edge(); add_cycles(6); } } void bCPU::cpu_io() { status.cycle_count = 6; - cycle_edge(); add_cycles(6); } uint8 bCPU::mem_read(uint32 addr) { -uint8 r; status.cycle_count = mem_bus->speed(addr); - cycle_edge(); add_cycles(2); - r = mem_bus->read(addr); + regs.mdr = mem_bus->read(addr); add_cycles(status.cycle_count - 2); - return r; + return regs.mdr; } void bCPU::mem_write(uint32 addr, uint8 value) { status.cycle_count = mem_bus->speed(addr); - cycle_edge(); add_cycles(6); mem_bus->write(addr, value); add_cycles(status.cycle_count - 6); @@ -345,9 +361,7 @@ void bCPU::stack_write(uint8 value) { } bCPU::bCPU() { - time_init(); mmio = new bCPUMMIO(this); - init_op_tables(); } diff --git a/src/cpu/bcpu/bcpu.h b/src/cpu/bcpu/bcpu.h index c398160d..121b5fca 100644 --- a/src/cpu/bcpu/bcpu.h +++ b/src/cpu/bcpu/bcpu.h @@ -13,8 +13,10 @@ private: typedef void (bCPU::*op)(); op optbl[256]; +enum { NTSC = 0, PAL = 1 }; +uint8 region; + public: -#include "srtc.h" #include "bcpu_timing.h" uint8 apu_port[4]; @@ -39,25 +41,33 @@ enum { enum { DMASTATE_STOP = 0, - DMASTATE_INIT, DMASTATE_DMASYNC, + DMASTATE_DMASYNC2, DMASTATE_RUN, - DMASTATE_CPUSYNC + DMASTATE_CPUSYNC, + DMASTATE_CPUSYNC2 }; struct { - uint8 cpu_state, cycle_count; + uint8 cpu_state, cycle_pos, cycle_count; + uint8 opcode; + uint32 cycles_executed; uint8 dma_state; uint32 dma_cycle_count; bool hdma_triggered; - bool nmi_triggered; - bool nmi_pin; - bool r4210_read; +//used by $4210 read bit 7 + bool nmi_read; +//used by NMI test, set when NMI executed this frame + bool nmi_exec; - bool irq_triggered; - bool irq_pin; +//IRQ is level-sensitive, so $4211 must be read to +//prevent multiple interrupts from occurring + bool irq_read; +//this is used to return $4211 bit 7 + bool irq_exec; +//$4207-$420a uint16 virq_trigger, hirq_trigger; //$2181-$2183 @@ -91,10 +101,12 @@ struct { }status; struct { + uint32 read_index; //set to 0 at beginning of DMA/HDMA + //$420b bool active; //$420c - bool hdma_active; + bool hdma_enabled; //$43x0 uint8 dmap; bool direction; @@ -104,14 +116,16 @@ struct { uint8 xfermode; //$43x1 uint8 destaddr; -//$43x2-$43x4 - uint32 srcaddr; +//$43x2-$43x3 + uint16 srcaddr; +//$43x4 + uint8 srcbank; //$43x5-$43x6 uint16 xfersize; //$43x7 - uint8 hdma_indirect_bank; + uint8 hdma_ibank; //$43x8-$43x9 - uint32 hdma_taddr; + uint16 hdma_addr; //$43xa uint8 hdma_line_counter; //$43xb/$43xf @@ -120,43 +134,41 @@ struct { //hdma-specific bool hdma_first_line; bool hdma_repeat; - uint32 hdma_itaddr; - bool hdma_completed; + uint16 hdma_iaddr; + bool hdma_active; }channel[8]; - inline bool hdma_test(); - inline bool nmi_test(); - inline bool irq_test(); - inline void irq(uint16 addr); + inline bool hdma_test(); + inline bool nmi_test(); + inline bool irq_test(); + inline void irq(uint16 addr); - inline uint8 pio_status(); - inline void run(); - inline void scanline(); - inline void frame(); - inline void power(); - inline void reset(); + inline uint8 pio_status(); + inline void run(); + inline uint32 cycles_executed(); + inline void scanline(); + inline void frame(); + inline void power(); + inline void reset(); //dma commands inline void dma_run(); inline void hdma_run(); inline void hdma_initialize(); - inline uint16 dma_cputommio(uint8 i, uint8 index); - inline uint16 dma_mmiotocpu(uint8 i, uint8 index); - inline void dma_xfer_type0(uint8 i); - inline void dma_xfer_type1(uint8 i); - inline void dma_xfer_type2(uint8 i); - inline void dma_xfer_type3(uint8 i); - inline void dma_xfer_type4(uint8 i); - inline void dma_xfer_type5(uint8 i); + inline void dma_cputommio(uint8 i, uint8 index); + inline void dma_mmiotocpu(uint8 i, uint8 index); + inline void dma_write(uint8 i, uint8 index); + inline uint32 dma_addr(uint8 i); + inline uint32 hdma_addr(uint8 i); + inline uint32 hdma_iaddr(uint8 i); inline void hdma_write(uint8 i, uint8 l, uint8 x); inline void dma_reset(); //mmio commands void mmio_reset(); uint8 mmio_r2180(); - uint8 mmio_r21c2(); - uint8 mmio_r21c3(); uint8 mmio_r4016(); + uint8 mmio_r4017(); uint8 mmio_r4210(); uint8 mmio_r4211(); uint8 mmio_r4212(); @@ -212,8 +224,9 @@ struct { void mmio_w43xb(uint8 value, uint8 i); enum { CYCLE_OPREAD = 0, CYCLE_READ, CYCLE_WRITE, CYCLE_IO }; - inline void exec_opcode(); + inline void exec_cycle(); inline void cycle_edge(); + inline bool in_opcode(); //cpu extra-cycle conditions inline void cpu_c2(); diff --git a/src/cpu/bcpu/bcpu_dma.cpp b/src/cpu/bcpu/bcpu_dma.cpp index 56957dcb..7388358e 100644 --- a/src/cpu/bcpu/bcpu_dma.cpp +++ b/src/cpu/bcpu/bcpu_dma.cpp @@ -1,92 +1,46 @@ -uint16 bCPU::dma_cputommio(uint8 i, uint8 index) { -uint8 x; - x = mem_bus->read(channel[i].srcaddr); - mem_bus->write(0x2100 | ((channel[i].destaddr + index) & 0xff), x); - if(channel[i].fixedxfer == false) { - channel[i].srcaddr = (channel[i].srcaddr & 0xff0000) + ((channel[i].srcaddr + channel[i].incmode) & 0xffff); - } - add_cycles(8); - return --channel[i].xfersize; +uint32 bCPU::dma_addr(uint8 i) { +uint32 r; + r = channel[i].srcaddr; + r |= (channel[i].srcbank << 16); + return r; } -uint16 bCPU::dma_mmiotocpu(uint8 i, uint8 index) { +void bCPU::dma_cputommio(uint8 i, uint8 index) { +uint8 x; + if(sdd1->dma_active() == true) { + x = sdd1->dma_read(); + } else { + x = mem_bus->read(dma_addr(i)); + } + + mem_bus->write(0x2100 | ((channel[i].destaddr + index) & 0xff), x); + + if(channel[i].fixedxfer == false) { + channel[i].srcaddr += channel[i].incmode; + } + + add_cycles(8); + channel[i].xfersize--; +} + +void bCPU::dma_mmiotocpu(uint8 i, uint8 index) { uint8 x; x = mem_bus->read(0x2100 | ((channel[i].destaddr + index) & 0xff)); - mem_bus->write(channel[i].srcaddr, x); + mem_bus->write(dma_addr(i), x); + if(channel[i].fixedxfer == false) { - channel[i].srcaddr = (channel[i].srcaddr & 0xff0000) + ((channel[i].srcaddr + channel[i].incmode) & 0xffff); + channel[i].srcaddr += channel[i].incmode; } + add_cycles(8); - return --channel[i].xfersize; + channel[i].xfersize--; } -void bCPU::dma_xfer_type0(uint8 i) { +void bCPU::dma_write(uint8 i, uint8 index) { if(channel[i].direction == 0) { - if(dma_cputommio(i, 0) == 0)return; + dma_cputommio(i, index); } else { - if(dma_mmiotocpu(i, 0) == 0)return; - } -} - -void bCPU::dma_xfer_type1(uint8 i) { - if(channel[i].direction == 0) { - if(dma_cputommio(i, 0) == 0)return; - if(dma_cputommio(i, 1) == 0)return; - } else { - if(dma_mmiotocpu(i, 0) == 0)return; - if(dma_mmiotocpu(i, 1) == 0)return; - } -} - -void bCPU::dma_xfer_type2(uint8 i) { - if(channel[i].direction == 0) { - if(dma_cputommio(i, 0) == 0)return; - if(dma_cputommio(i, 0) == 0)return; - } else { - if(dma_mmiotocpu(i, 0) == 0)return; - if(dma_mmiotocpu(i, 0) == 0)return; - } -} - -void bCPU::dma_xfer_type3(uint8 i) { - if(channel[i].direction == 0) { - if(dma_cputommio(i, 0) == 0)return; - if(dma_cputommio(i, 0) == 0)return; - if(dma_cputommio(i, 1) == 0)return; - if(dma_cputommio(i, 1) == 0)return; - } else { - if(dma_mmiotocpu(i, 0) == 0)return; - if(dma_mmiotocpu(i, 0) == 0)return; - if(dma_mmiotocpu(i, 1) == 0)return; - if(dma_mmiotocpu(i, 1) == 0)return; - } -} - -void bCPU::dma_xfer_type4(uint8 i) { - if(channel[i].direction == 0) { - if(dma_cputommio(i, 0) == 0)return; - if(dma_cputommio(i, 1) == 0)return; - if(dma_cputommio(i, 2) == 0)return; - if(dma_cputommio(i, 3) == 0)return; - } else { - if(dma_mmiotocpu(i, 0) == 0)return; - if(dma_mmiotocpu(i, 1) == 0)return; - if(dma_mmiotocpu(i, 2) == 0)return; - if(dma_mmiotocpu(i, 3) == 0)return; - } -} - -void bCPU::dma_xfer_type5(uint8 i) { - if(channel[i].direction == 0) { - if(dma_cputommio(i, 0) == 0)return; - if(dma_cputommio(i, 1) == 0)return; - if(dma_cputommio(i, 0) == 0)return; - if(dma_cputommio(i, 1) == 0)return; - } else { - if(dma_mmiotocpu(i, 0) == 0)return; - if(dma_mmiotocpu(i, 1) == 0)return; - if(dma_mmiotocpu(i, 0) == 0)return; - if(dma_mmiotocpu(i, 1) == 0)return; + dma_mmiotocpu(i, index); } } @@ -95,17 +49,24 @@ int i; for(i=0;i<8;i++) { if(channel[i].active == false)continue; - switch(channel[i].xfermode) { - case 0:dma_xfer_type0(i);break; - case 1:dma_xfer_type1(i);break; - case 2:dma_xfer_type2(i);break; - case 3:dma_xfer_type3(i);break; - case 4:dma_xfer_type4(i);break; - case 5:dma_xfer_type5(i);break; - case 6:dma_xfer_type2(i);break; - case 7:dma_xfer_type3(i);break; + //first byte transferred? + if(channel[i].read_index == 0) { + sdd1->dma_begin(i, dma_addr(i), channel[i].xfersize); } + switch(channel[i].xfermode) { + case 0:dma_write(i, 0); break; //0 + case 1:dma_write(i, channel[i].read_index & 1); break; //0,1 + case 2:dma_write(i, 0); break; //0,0 + case 3:dma_write(i, (channel[i].read_index >> 1) & 1);break; //0,0,1,1 + case 4:dma_write(i, channel[i].read_index & 3); break; //0,1,2,3 + case 5:dma_write(i, channel[i].read_index & 1); break; //0,1,0,1 + case 6:dma_write(i, 0); break; //0,0 [2] + case 7:dma_write(i, (channel[i].read_index >> 1) & 1);break; //0,0,1,1 [3] + } + + channel[i].read_index++; + if(channel[i].xfersize == 0) { channel[i].active = false; } @@ -116,30 +77,54 @@ int i; status.dma_state = DMASTATE_CPUSYNC; } +uint32 bCPU::hdma_addr(uint8 i) { +uint32 r; + r = channel[i].hdma_addr; + r |= (channel[i].srcbank << 16); + channel[i].hdma_addr++; + return r; +} + +uint32 bCPU::hdma_iaddr(uint8 i) { +uint32 r; + r = channel[i].hdma_iaddr; + r |= (channel[i].hdma_ibank << 16); + channel[i].hdma_iaddr++; + return r; +} + void bCPU::hdma_write(uint8 i, uint8 l, uint8 x) { +uint16 index; switch(channel[i].xfermode) { - case 0:mem_bus->write(0x2100 | ((channel[i].destaddr) & 0xff), x);break; - case 1:mem_bus->write(0x2100 | ((channel[i].destaddr + l) & 0xff), x);break; - case 2:mem_bus->write(0x2100 | ((channel[i].destaddr) & 0xff), x);break; - case 3:mem_bus->write(0x2100 | ((channel[i].destaddr + (l >> 1)) & 0xff), x);break; - case 4:mem_bus->write(0x2100 | ((channel[i].destaddr + l) & 0xff), x);break; - case 5:mem_bus->write(0x2100 | ((channel[i].destaddr + (l & 1)) & 0xff), x);break; - case 6:mem_bus->write(0x2100 | ((channel[i].destaddr) & 0xff), x);break; - case 7:mem_bus->write(0x2100 | ((channel[i].destaddr + (l >> 1)) & 0xff), x);break; + case 0:index = 0; break; //0 + case 1:index = l & 1; break; //0,1 + case 2:index = 0; break; //0,0 + case 3:index = (l >> 1) & 1;break; //0,0,1,1 + case 4:index = l & 3; break; //0,1,2,3 + case 5:index = l & 1; break; //0,1,0,1 + case 6:index = 0; break; //0,0 [2] + case 7:index = (l >> 1) & 1;break; //0,0,1,1 [3] } + + index = 0x2100 | ((channel[i].destaddr + index) & 0xff); + mem_bus->write(index, x); } void bCPU::hdma_run() { int l, xferlen; uint8 x, active_channels = 0; +static hdma_xferlen[8] = { 1, 2, 2, 4, 4, 4, 2, 4 }; for(int i=0;i<8;i++) { - if(channel[i].hdma_completed == true)continue; -// add_cycles(8); + if(channel[i].hdma_active == false)continue; + +// add_cycles(8); active_channels++; + if(channel[i].hdma_line_counter == 0) { - channel[i].hdma_line_counter = mem_bus->read(channel[i].hdma_taddr++); + channel[i].hdma_line_counter = mem_bus->read(hdma_addr(i)); + if(channel[i].hdma_line_counter == 0) { - channel[i].hdma_completed = true; + channel[i].hdma_active = false; continue; } @@ -151,13 +136,11 @@ uint8 x, active_channels = 0; } channel[i].hdma_first_line = true; - if(channel[i].hdma_indirect == false) { - channel[i].hdma_itaddr = channel[i].hdma_taddr; - } else { - channel[i].hdma_itaddr = mem_bus->read(channel[i].hdma_taddr++); - channel[i].hdma_itaddr |= mem_bus->read(channel[i].hdma_taddr++) << 8; - channel[i].hdma_itaddr |= channel[i].hdma_indirect_bank << 16; -// add_cycles(16); + + if(channel[i].hdma_indirect == true) { + channel[i].hdma_iaddr = mem_bus->read(hdma_addr(i)); + channel[i].hdma_iaddr |= mem_bus->read(hdma_addr(i)) << 8; +// add_cycles(16); } } @@ -165,44 +148,39 @@ uint8 x, active_channels = 0; if(channel[i].hdma_first_line == false && channel[i].hdma_repeat == false)continue; channel[i].hdma_first_line = false; - if(channel[i].hdma_indirect == false) { - channel[i].hdma_itaddr = channel[i].hdma_taddr; - } - - switch(channel[i].xfermode) { - case 0: xferlen = 1;break; - case 1:case 2:case 6: xferlen = 2;break; - case 3:case 4:case 5:case 7:xferlen = 4;break; - } - + xferlen = hdma_xferlen[channel[i].xfermode]; for(l=0;lread(channel[i].hdma_itaddr++); if(channel[i].hdma_indirect == false) { - channel[i].hdma_taddr++; + x = mem_bus->read(hdma_addr(i)); + } else { + x = mem_bus->read(hdma_iaddr(i)); } + hdma_write(i, l, x); // add_cycles(8); } } if(active_channels != 0) { -// add_cycles(18); +// add_cycles(18); } } void bCPU::hdma_initialize() { uint8 active_channels = 0; for(int i=0;i<8;i++) { - if(channel[i].hdma_active == false) { - channel[i].hdma_completed = true; + //does this happen when $420c channel bit is clear? + channel[i].hdma_addr = channel[i].srcaddr; + channel[i].hdma_line_counter = 0x00; + + if(channel[i].hdma_enabled == false) { + channel[i].hdma_active = false; continue; } + + channel[i].hdma_active = true; active_channels++; - channel[i].hdma_first_line = true; - channel[i].hdma_repeat = false; - channel[i].hdma_taddr = channel[i].srcaddr; - channel[i].hdma_line_counter = 0x00; - channel[i].hdma_completed = false; + if(channel[i].hdma_indirect == false) { add_cycles(8); } else { @@ -217,25 +195,26 @@ uint8 active_channels = 0; void bCPU::dma_reset() { for(int i=0;i<8;i++) { - channel[i].active = false; - channel[i].hdma_active = false; - channel[i].dmap = 0x00; - channel[i].direction = 0; - channel[i].hdma_indirect = false; - channel[i].incmode = 1; - channel[i].fixedxfer = false; - channel[i].xfermode = 0; - channel[i].destaddr = 0; - channel[i].srcaddr = 0; - channel[i].xfersize = 0; - channel[i].hdma_indirect_bank = 0; - channel[i].hdma_taddr = 0x000000; - channel[i].hdma_line_counter = 0x00; - channel[i].hdma_unknown = 0x00; + channel[i].read_index = 0; + channel[i].active = false; + channel[i].hdma_enabled = false; + channel[i].dmap = 0x00; + channel[i].direction = 0; + channel[i].hdma_indirect = false; + channel[i].incmode = 1; + channel[i].fixedxfer = false; + channel[i].xfermode = 0; + channel[i].destaddr = 0; + channel[i].srcaddr = 0; + channel[i].xfersize = 0; + channel[i].hdma_ibank = 0; + channel[i].hdma_addr = 0x0000; + channel[i].hdma_line_counter = 0x00; + channel[i].hdma_unknown = 0x00; - channel[i].hdma_first_line = false; - channel[i].hdma_repeat = false; - channel[i].hdma_itaddr = 0x000000; - channel[i].hdma_completed = true; + channel[i].hdma_active = false; + channel[i].hdma_first_line = false; + channel[i].hdma_repeat = false; + channel[i].hdma_iaddr = 0x0000; } } diff --git a/src/cpu/bcpu/bcpu_exec.cpp b/src/cpu/bcpu/bcpu_exec.cpp index 0ddebc2c..6e861392 100644 --- a/src/cpu/bcpu/bcpu_exec.cpp +++ b/src/cpu/bcpu/bcpu_exec.cpp @@ -2,10 +2,10 @@ inline void bCPU::cycle_edge() { int c, n, z; if(status.dma_state != DMASTATE_STOP) { switch(status.dma_state) { - case DMASTATE_INIT: - status.dma_state = DMASTATE_DMASYNC; - break; case DMASTATE_DMASYNC: + status.dma_state = DMASTATE_DMASYNC2; + break; + case DMASTATE_DMASYNC2: n = 8 - dma_counter() + 8; add_cycles(n); status.dma_cycle_count = n; @@ -13,14 +13,18 @@ int c, n, z; if(channel[z].active == false)continue; add_cycles(8); status.dma_cycle_count += 8; - status.dma_cycle_count += channel[z].xfersize << 3; } status.cpu_state = CPUSTATE_DMA; status.dma_state = DMASTATE_RUN; - while(status.dma_state == DMASTATE_RUN) { - dma_run(); - } + break; + case DMASTATE_RUN: + status.dma_cycle_count += 8; + break; + case DMASTATE_CPUSYNC: status.cpu_state = CPUSTATE_RUN; + status.dma_state = DMASTATE_CPUSYNC2; + break; + case DMASTATE_CPUSYNC2: c = status.cycle_count; z = c - (status.dma_cycle_count % c); if(!z)z = c; @@ -31,10 +35,22 @@ int c, n, z; } } -void bCPU::exec_opcode() { - snes->notify(SNES::CPU_EXEC_OPCODE_BEGIN); - (this->*optbl[op_read()])(); - snes->notify(SNES::CPU_EXEC_OPCODE_END); +void bCPU::exec_cycle() { + if(status.cycle_pos == 0) { + snes->notify(SNES::CPU_EXEC_OPCODE_BEGIN); + status.opcode = op_read(); + status.cycle_pos = 1; + } else { + (this->*optbl[status.opcode])(); + if(status.cycle_pos == 0) { + snes->notify(SNES::CPU_EXEC_OPCODE_END); + } + } +} + +//only return true when we are on an opcode edge +bool bCPU::in_opcode() { + return (status.cycle_pos != 0); } void bCPU::init_op_tables() { diff --git a/src/cpu/bcpu/bcpu_mmio.cpp b/src/cpu/bcpu/bcpu_mmio.cpp index 6a609ea1..e36680b2 100644 --- a/src/cpu/bcpu/bcpu_mmio.cpp +++ b/src/cpu/bcpu/bcpu_mmio.cpp @@ -41,16 +41,7 @@ uint8 r; return r; } -//??? -uint8 bCPU::mmio_r21c2() { - return 0x20; -} - -//??? -uint8 bCPU::mmio_r21c3() { - return 0x00; -} - +//JOYSER0 /* The joypad contains a small bit shifter that has 16 bits. Reading from 4016 reads one bit from this buffer, then moves @@ -61,9 +52,12 @@ uint8 bCPU::mmio_r21c3() { A zero must be written back to $4016 to unlock the buffer, so that reads will increment the bit shifting position. */ -//JOYSER0 +//7-2 = MDR +//1-0 = Joypad serial data uint8 bCPU::mmio_r4016() { -uint8 r = 0x00; +uint8 r; + r = regs.mdr & 0xfc; + if(status.joypad1_strobe_value == 1) { r |= (uint8)snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_B); } else { @@ -85,45 +79,85 @@ uint8 r = 0x00; } if(++status.joypad1_read_pos > 17)status.joypad1_read_pos = 17; } + + return r; +} + +//JOYSER1 +//7-5 = MDR +//4-2 = Always 1 +//1-0 = Joypad serial data +uint8 bCPU::mmio_r4017() { +uint8 r; + r = regs.mdr & 0xe0; + r |= 0x1c; + return r; } //RDNMI +/* $4210 bit 7 (NMI triggered bit) is set at: + * V=225/240,HC>=2, + * V>225 + * The bit is only set once per NMI trigger, so + * subsequent reads return this bit as being clear. + * There is but one exception: if the $4210 read + * occurs at *exactly* V=225/240,HC==2, then $4210 + * bit 7 will be set, and the next read will also + * have this bit set. + */ +//7 = NMI acknowledge +//6-4 = MDR +//3-0 = CPU (5a22) version uint8 bCPU::mmio_r4210() { -uint8 r = 0x00; +uint8 r; uint16 v, h, hc, vs; + r = regs.mdr & 0x70; + v = vcounter(); h = hcounter(); hc = hcycles(); vs = (overscan()?239:224); - if(status.r4210_read == false) { - if((v == (vs + 1) && hc >= 2) || v > (vs + 1)) { + if(status.nmi_read == false) { + if( + (v == (vs + 1) && hc >= 2) || + (v > (vs + 1)) + ) { r |= 0x80; - status.r4210_read = true; - status.nmi_pin = 1; + + //test for special case where NMI read not raised + if(v != (vs + 1) || hc != 2) { + status.nmi_read = true; + } } } - r |= 0x40; r |= 0x02; //cpu version number return r; } //TIMEUP +//7 = IRQ acknowledge +//6-0 = MDR uint8 bCPU::mmio_r4211() { -uint8 r = 0x00; - r |= 0x40; - if(status.irq_triggered == true)r |= 0x80; - status.irq_triggered = false; +uint8 r; + r = regs.mdr & 0x7f; + if(status.irq_exec == true)r |= 0x80; + status.irq_exec = false; + status.irq_read = true; return r; } //HVBJOY +//7 = in vblank +//6 = in hblank +//5-1 = MDR +//0 = joypad ready uint8 bCPU::mmio_r4212() { uint8 r; uint16 v, h, hc, vs; - r = 0x00; + r = regs.mdr & 0x3e; v = vcounter(); h = hcounter(); @@ -168,7 +202,7 @@ uint8 bCPU::mmio_r4217() { //JOY1L uint8 bCPU::mmio_r4218() { -uint8 r = 0x00; +uint8 r = 0x00; uint16 v = vcounter(); if(status.auto_joypad_poll == false)return 0x00; //can't read joypad if auto polling not enabled //if(v >= 225 && v <= 227)return 0x00; //can't read joypad while SNES is polling input @@ -181,7 +215,7 @@ uint16 v = vcounter(); //JOY1H uint8 bCPU::mmio_r4219() { -uint8 r = 0x00; +uint8 r = 0x00; uint16 v = vcounter(); if(status.auto_joypad_poll == false)return 0x00; //can't read joypad if auto polling not enabled //if(v >= 225 && v <= 227)return 0x00; //can't read joypad while SNES is polling input @@ -218,7 +252,7 @@ uint8 bCPU::mmio_r43x3(uint8 i) { //A1Bx uint8 bCPU::mmio_r43x4(uint8 i) { - return channel[i].srcaddr >> 16; + return channel[i].srcbank; } //DASxL @@ -233,17 +267,17 @@ uint8 bCPU::mmio_r43x6(uint8 i) { //DASBx uint8 bCPU::mmio_r43x7(uint8 i) { - return channel[i].hdma_indirect_bank; + return channel[i].hdma_ibank; } //A2AxL uint8 bCPU::mmio_r43x8(uint8 i) { - return channel[i].hdma_taddr; + return channel[i].hdma_addr; } //A2AxH uint8 bCPU::mmio_r43x9(uint8 i) { - return channel[i].hdma_taddr >> 8; + return channel[i].hdma_addr >> 8; } //NTRLx @@ -281,19 +315,17 @@ uint8 i; case 0x9:return cpu->mmio_r43x9(i); case 0xa:return cpu->mmio_r43xa(i); case 0xb:return cpu->mmio_r43xb(i); - case 0xc:return 0x43; //unmapped - case 0xd:return 0x43; //unmapped - case 0xe:return 0x43; //unmapped + case 0xc:return cpu->regs.mdr; //unmapped + case 0xd:return cpu->regs.mdr; //unmapped + case 0xe:return cpu->regs.mdr; //unmapped case 0xf:return cpu->mmio_r43xb(i); //mirror of 43xb } } switch(addr) { case 0x2180:return cpu->mmio_r2180(); //WMDATA - case 0x21c2:return cpu->mmio_r21c2(); //??? - case 0x21c3:return cpu->mmio_r21c3(); //??? - case 0x2800:return cpu->srtc_read(); case 0x4016:return cpu->mmio_r4016(); //JOYSER0 + case 0x4017:return cpu->mmio_r4017(); //JOYSER1 case 0x4210:return cpu->mmio_r4210(); //RDNMI case 0x4211:return cpu->mmio_r4211(); //TIMEUP case 0x4212:return cpu->mmio_r4212(); //HVBJOY @@ -306,7 +338,8 @@ uint8 i; case 0x4219:return cpu->mmio_r4219(); //JOY1H case 0x421a:case 0x421b:case 0x421c:case 0x421d:case 0x421e:case 0x421f:return 0x00; } - return 0x00; + + return cpu->regs.mdr; } //WMDATA @@ -351,11 +384,12 @@ void bCPU::mmio_w4200(uint8 value) { status.auto_joypad_poll = !!(value & 0x01); if(status.nmi_enabled == false) { - status.nmi_pin = 0; + status.nmi_read = false; } - if(status.virq_enabled == false && status.hirq_enabled == false) { - status.irq_pin = 0; + status.irq_exec = false; + if(status.virq_enabled == true || status.hirq_enabled == true) { + status.irq_read = false; } } @@ -397,37 +431,40 @@ void bCPU::mmio_w4206(uint8 value) { //HTIMEL void bCPU::mmio_w4207(uint8 value) { status.hirq_pos = (status.hirq_pos & 0xff00) | value; - if(status.irq_triggered == false)status.irq_pin = 1; + status.irq_read = false; } //HTIMEH void bCPU::mmio_w4208(uint8 value) { status.hirq_pos = (status.hirq_pos & 0x00ff) | (value << 8); - if(status.irq_triggered == false)status.irq_pin = 1; + status.irq_read = false; } //VTIMEL void bCPU::mmio_w4209(uint8 value) { status.virq_pos = (status.virq_pos & 0xff00) | value; - if(status.irq_triggered == false)status.irq_pin = 1; + status.irq_read = false; } //VTIMEH void bCPU::mmio_w420a(uint8 value) { status.virq_pos = (status.virq_pos & 0x00ff) | (value << 8); - if(status.irq_triggered == false)status.irq_pin = 1; + status.irq_read = false; } //DMAEN void bCPU::mmio_w420b(uint8 value) { +int len; if(value != 0x00) { - status.dma_state = DMASTATE_INIT; + status.dma_state = DMASTATE_DMASYNC; } for(int i=0;i<8;i++) { if(value & (1 << i)) { - channel[i].active = true; - channel[i].hdma_active = false; + channel[i].active = true; + channel[i].hdma_enabled = false; + channel[i].hdma_active = false; + channel[i].read_index = 0; } } } @@ -435,7 +472,8 @@ void bCPU::mmio_w420b(uint8 value) { //HDMAEN void bCPU::mmio_w420c(uint8 value) { for(int i=0;i<8;i++) { - channel[i].hdma_active = !!(value & (1 << i)); + channel[i].hdma_enabled = !!(value & (1 << i)); + channel[i].hdma_active = !!(value & (1 << i)); } } @@ -461,17 +499,17 @@ void bCPU::mmio_w43x1(uint8 value, uint8 i) { //A1TxL void bCPU::mmio_w43x2(uint8 value, uint8 i) { - channel[i].srcaddr = (channel[i].srcaddr & 0xffff00) | value; + channel[i].srcaddr = (channel[i].srcaddr & 0xff00) | value; } //A1TxH void bCPU::mmio_w43x3(uint8 value, uint8 i) { - channel[i].srcaddr = (channel[i].srcaddr & 0xff00ff) | (value << 8); + channel[i].srcaddr = (channel[i].srcaddr & 0x00ff) | (value << 8); } //A1Bx void bCPU::mmio_w43x4(uint8 value, uint8 i) { - channel[i].srcaddr = (channel[i].srcaddr & 0x00ffff) | (value << 16); + channel[i].srcbank = value; } //DASxL @@ -486,17 +524,17 @@ void bCPU::mmio_w43x6(uint8 value, uint8 i) { //DASBx void bCPU::mmio_w43x7(uint8 value, uint8 i) { - channel[i].hdma_indirect_bank = value; + channel[i].hdma_ibank = value; } //A2AxL void bCPU::mmio_w43x8(uint8 value, uint8 i) { - channel[i].hdma_taddr = (channel[i].hdma_taddr & 0xffff00) | value; + channel[i].hdma_addr = (channel[i].hdma_addr & 0xff00) | value; } //A2AxH void bCPU::mmio_w43x9(uint8 value, uint8 i) { - channel[i].hdma_taddr = (channel[i].hdma_taddr & 0xff00ff) | (value << 8); + channel[i].hdma_addr = (channel[i].hdma_addr & 0x00ff) | (value << 8); } //NTRLx @@ -547,7 +585,6 @@ uint8 i; case 0x2181:cpu->mmio_w2181(value);return; //WMADDL case 0x2182:cpu->mmio_w2182(value);return; //WMADDM case 0x2183:cpu->mmio_w2183(value);return; //WMADDH - case 0x2801:cpu->srtc_write(value);return; case 0x4016:cpu->mmio_w4016(value);return; //JOYSER0 case 0x4200:cpu->mmio_w4200(value);return; //NMITIMEN case 0x4201:cpu->mmio_w4201(value);return; //WRIO diff --git a/src/cpu/bcpu/bcpu_op_misc.cpp b/src/cpu/bcpu/bcpu_op_misc.cpp index e37c6e5f..9b6fe3af 100644 --- a/src/cpu/bcpu/bcpu_op_misc.cpp +++ b/src/cpu/bcpu/bcpu_op_misc.cpp @@ -1,551 +1,804 @@ void bCPU::op_nop() { -l1: - cpu_io(); + switch(status.cycle_pos++) { + case 1: + cpu_io(); + status.cycle_pos = 0; + break; + } } void bCPU::op_wdm() { -l1: - cpu_io(); - regs.pc.w++; + switch(status.cycle_pos++) { + case 1: + op_read(); + status.cycle_pos = 0; + break; + } } void bCPU::op_xba() { -l1: - cpu_io(); -l2: - cpu_io(); - regs.a.l ^= regs.a.h; - regs.a.h ^= regs.a.l; - regs.a.l ^= regs.a.h; - regs.p.n = !!(regs.a.l & 0x80); - regs.p.z = (regs.a.l == 0); + switch(status.cycle_pos++) { + case 1: + cpu_io(); + break; + case 2: + cpu_io(); + regs.a.l ^= regs.a.h; + regs.a.h ^= regs.a.l; + regs.a.l ^= regs.a.h; + regs.p.n = !!(regs.a.l & 0x80); + regs.p.z = (regs.a.l == 0); + status.cycle_pos = 0; + break; + } } void bCPU::op_mvn() { -l1: - dp = op_read(); -l2: - sp = op_read(); -l3: - regs.db = dp; - rd.l = op_read(OPMODE_LONG, (sp << 16) | regs.x.w); -l4: - op_write(OPMODE_LONG, (dp << 16) | regs.y.w, rd.l); -l5: - cpu_io(); - if(regs.p.x) { regs.x.l++; regs.y.l++; } - else { regs.x.w++; regs.y.w++; } -l6: - cpu_io(); - if(regs.a.w--)regs.pc.w -= 3; + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + sp = op_read(); + break; + case 3: + regs.db = dp; + rd.l = op_read(OPMODE_LONG, (sp << 16) | regs.x.w); + break; + case 4: + op_write(OPMODE_LONG, (dp << 16) | regs.y.w, rd.l); + break; + case 5: + cpu_io(); + if(regs.p.x) { regs.x.l++; regs.y.l++; } + else { regs.x.w++; regs.y.w++; } + break; + case 6: + cpu_io(); + if(regs.a.w--)regs.pc.w -= 3; + status.cycle_pos = 0; + break; + } } void bCPU::op_mvp() { -l1: - dp = op_read(); -l2: - sp = op_read(); -l3: - regs.db = dp; - rd.l = op_read(OPMODE_LONG, (sp << 16) | regs.x.w); -l4: - op_write(OPMODE_LONG, (dp << 16) | regs.y.w, rd.l); -l5: - cpu_io(); - if(regs.p.x) { regs.x.l--; regs.y.l--; } - else { regs.x.w--; regs.y.w--; } -l6: - cpu_io(); - if(regs.a.w--)regs.pc.w -= 3; + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + sp = op_read(); + break; + case 3: + regs.db = dp; + rd.l = op_read(OPMODE_LONG, (sp << 16) | regs.x.w); + break; + case 4: + op_write(OPMODE_LONG, (dp << 16) | regs.y.w, rd.l); + break; + case 5: + cpu_io(); + if(regs.p.x) { regs.x.l--; regs.y.l--; } + else { regs.x.w--; regs.y.w--; } + break; + case 6: + cpu_io(); + if(regs.a.w--)regs.pc.w -= 3; + status.cycle_pos = 0; + break; + } } void bCPU::op_brk() { -l1: - op_read(); - if(regs.e)goto l3; -l2: - stack_write(regs.pc.b); -l3: - stack_write(regs.pc.h); -l4: - stack_write(regs.pc.l); -l5: - stack_write(regs.p); -l6: - rd.l = op_read(OPMODE_LONG, (regs.e)?0xfffe:0xffe6); -l7: - rd.h = op_read(OPMODE_LONG, (regs.e)?0xffff:0xffe7); - regs.pc.b = 0x00; - regs.pc.w = rd.w; - regs.p.i = 1; - regs.p.d = 0; + switch(status.cycle_pos++) { + case 1: + op_read(); + if(regs.e)status.cycle_pos++; + break; + case 2: + stack_write(regs.pc.b); + break; + case 3: + stack_write(regs.pc.h); + break; + case 4: + stack_write(regs.pc.l); + break; + case 5: + stack_write(regs.p); + break; + case 6: + rd.l = op_read(OPMODE_LONG, (regs.e)?0xfffe:0xffe6); + break; + case 7: + rd.h = op_read(OPMODE_LONG, (regs.e)?0xffff:0xffe7); + regs.pc.b = 0x00; + regs.pc.w = rd.w; + regs.p.i = 1; + regs.p.d = 0; + status.cycle_pos = 0; + break; + } } void bCPU::op_cop() { -l1: - op_read(); - if(regs.e)goto l3; -l2: - stack_write(regs.pc.b); -l3: - stack_write(regs.pc.h); -l4: - stack_write(regs.pc.l); -l5: - stack_write(regs.p); -l6: - rd.l = op_read(OPMODE_LONG, (regs.e)?0xfff4:0xffe4); -l7: - rd.h = op_read(OPMODE_LONG, (regs.e)?0xfff5:0xffe5); - regs.pc.b = 0x00; - regs.pc.w = rd.w; - regs.p.i = 1; - regs.p.d = 0; + switch(status.cycle_pos++) { + case 1: + op_read(); + if(regs.e)status.cycle_pos++; + break; + case 2: + stack_write(regs.pc.b); + break; + case 3: + stack_write(regs.pc.h); + break; + case 4: + stack_write(regs.pc.l); + break; + case 5: + stack_write(regs.p); + break; + case 6: + rd.l = op_read(OPMODE_LONG, (regs.e)?0xfff4:0xffe4); + break; + case 7: + rd.h = op_read(OPMODE_LONG, (regs.e)?0xfff5:0xffe5); + regs.pc.b = 0x00; + regs.pc.w = rd.w; + regs.p.i = 1; + regs.p.d = 0; + status.cycle_pos = 0; + break; + } } void bCPU::op_stp() { -l1: - cpu_io(); - status.cpu_state = CPUSTATE_STP; -l2: - cpu_io(); - regs.pc.w--; + switch(status.cycle_pos++) { + case 1: + cpu_io(); + status.cpu_state = CPUSTATE_STP; + break; + case 2: + cpu_io(); + regs.pc.w--; + status.cycle_pos = 0; + break; + } } void bCPU::op_wai() { -l1: - cpu_io(); - status.cpu_state = CPUSTATE_WAI; -l2: - cpu_io(); - regs.pc.w--; + switch(status.cycle_pos++) { + case 1: + cpu_io(); + status.cpu_state = CPUSTATE_WAI; + break; + case 2: + cpu_io(); + regs.pc.w--; + status.cycle_pos = 0; + break; + } } void bCPU::op_xce() { -l1: - cpu_io(); -bool c = regs.p.c; - regs.p.c = regs.e; - regs.e = c; - if(regs.e) { - regs.p |= 0x30; - regs.x.h = 0x00; - regs.y.h = 0x00; - regs.s.h = 0x01; + switch(status.cycle_pos++) { + case 1: + cpu_io(); + bool c = regs.p.c; + regs.p.c = regs.e; + regs.e = c; + if(regs.e) { + regs.p |= 0x30; + regs.x.h = 0x00; + regs.y.h = 0x00; + regs.s.h = 0x01; + } + status.cycle_pos = 0; + break; } } void bCPU::op_clc() { -l1: - cpu_io(); - regs.p.c = 0; + switch(status.cycle_pos++) { + case 1: + cpu_io(); + regs.p.c = 0; + status.cycle_pos = 0; + break; + } } void bCPU::op_cld() { -l1: - cpu_io(); - regs.p.d = 0; + switch(status.cycle_pos++) { + case 1: + cpu_io(); + regs.p.d = 0; + status.cycle_pos = 0; + break; + } } void bCPU::op_cli() { -l1: - cpu_io(); - regs.p.i = 0; + switch(status.cycle_pos++) { + case 1: + cpu_io(); + regs.p.i = 0; + status.cycle_pos = 0; + break; + } } void bCPU::op_clv() { -l1: - cpu_io(); - regs.p.v = 0; + switch(status.cycle_pos++) { + case 1: + cpu_io(); + regs.p.v = 0; + status.cycle_pos = 0; + break; + } } void bCPU::op_sec() { -l1: - cpu_io(); - regs.p.c = 1; + switch(status.cycle_pos++) { + case 1: + cpu_io(); + regs.p.c = 1; + status.cycle_pos = 0; + break; + } } void bCPU::op_sed() { -l1: - cpu_io(); - regs.p.d = 1; + switch(status.cycle_pos++) { + case 1: + cpu_io(); + regs.p.d = 1; + status.cycle_pos = 0; + break; + } } void bCPU::op_sei() { -l1: - cpu_io(); - regs.p.i = 1; + switch(status.cycle_pos++) { + case 1: + cpu_io(); + regs.p.i = 1; + status.cycle_pos = 0; + break; + } } void bCPU::op_rep() { -l1: - rd.l = op_read(); -l2: - cpu_io(); - regs.p &=~ rd.l; - if(regs.e)regs.p |= 0x30; - if(regs.p.x) { - regs.x.h = 0x00; - regs.y.h = 0x00; + switch(status.cycle_pos++) { + case 1: + rd.l = op_read(); + break; + case 2: + cpu_io(); + regs.p &=~ rd.l; + if(regs.e)regs.p |= 0x30; + if(regs.p.x) { + regs.x.h = 0x00; + regs.y.h = 0x00; + } + status.cycle_pos = 0; + break; } } void bCPU::op_sep() { -l1: - rd.l = op_read(); -l2: - cpu_io(); - regs.p |= rd.l; - if(regs.e)regs.p |= 0x30; - if(regs.p.x) { - regs.x.h = 0x00; - regs.y.h = 0x00; + switch(status.cycle_pos++) { + case 1: + rd.l = op_read(); + break; + case 2: + cpu_io(); + regs.p |= rd.l; + if(regs.e)regs.p |= 0x30; + if(regs.p.x) { + regs.x.h = 0x00; + regs.y.h = 0x00; + } + status.cycle_pos = 0; + break; } } void bCPU::op_tax() { -l1: - cpu_io(); - if(regs.p.x) { - regs.x.l = regs.a.l; - regs.p.n = !!(regs.x.l & 0x80); - regs.p.z = (regs.x.l == 0); - } else { - regs.x.w = regs.a.w; - regs.p.n = !!(regs.x.w & 0x8000); - regs.p.z = (regs.x.w == 0); + switch(status.cycle_pos++) { + case 1: + cpu_io(); + if(regs.p.x) { + regs.x.l = regs.a.l; + regs.p.n = !!(regs.x.l & 0x80); + regs.p.z = (regs.x.l == 0); + } else { + regs.x.w = regs.a.w; + regs.p.n = !!(regs.x.w & 0x8000); + regs.p.z = (regs.x.w == 0); + } + status.cycle_pos = 0; + break; } } void bCPU::op_tay() { -l1: - cpu_io(); - if(regs.p.x) { - regs.y.l = regs.a.l; - regs.p.n = !!(regs.y.l & 0x80); - regs.p.z = (regs.y.l == 0); - } else { - regs.y.w = regs.a.w; - regs.p.n = !!(regs.y.w & 0x8000); - regs.p.z = (regs.y.w == 0); + switch(status.cycle_pos++) { + case 1: + cpu_io(); + if(regs.p.x) { + regs.y.l = regs.a.l; + regs.p.n = !!(regs.y.l & 0x80); + regs.p.z = (regs.y.l == 0); + } else { + regs.y.w = regs.a.w; + regs.p.n = !!(regs.y.w & 0x8000); + regs.p.z = (regs.y.w == 0); + } + status.cycle_pos = 0; + break; } } void bCPU::op_txa() { -l1: - cpu_io(); - if(regs.p.m) { - regs.a.l = regs.x.l; - regs.p.n = !!(regs.a.l & 0x80); - regs.p.z = (regs.a.l == 0); - } else { - regs.a.w = regs.x.w; - regs.p.n = !!(regs.a.w & 0x8000); - regs.p.z = (regs.a.w == 0); + switch(status.cycle_pos++) { + case 1: + cpu_io(); + if(regs.p.m) { + regs.a.l = regs.x.l; + regs.p.n = !!(regs.a.l & 0x80); + regs.p.z = (regs.a.l == 0); + } else { + regs.a.w = regs.x.w; + regs.p.n = !!(regs.a.w & 0x8000); + regs.p.z = (regs.a.w == 0); + } + status.cycle_pos = 0; + break; } } void bCPU::op_txy() { -l1: - cpu_io(); - if(regs.p.x) { - regs.y.l = regs.x.l; - regs.p.n = !!(regs.y.l & 0x80); - regs.p.z = (regs.y.l == 0); - } else { - regs.y.w = regs.x.w; - regs.p.n = !!(regs.y.w & 0x8000); - regs.p.z = (regs.y.w == 0); + switch(status.cycle_pos++) { + case 1: + cpu_io(); + if(regs.p.x) { + regs.y.l = regs.x.l; + regs.p.n = !!(regs.y.l & 0x80); + regs.p.z = (regs.y.l == 0); + } else { + regs.y.w = regs.x.w; + regs.p.n = !!(regs.y.w & 0x8000); + regs.p.z = (regs.y.w == 0); + } + status.cycle_pos = 0; + break; } } void bCPU::op_tya() { -l1: - cpu_io(); - if(regs.p.m) { - regs.a.l = regs.y.l; - regs.p.n = !!(regs.a.l & 0x80); - regs.p.z = (regs.a.l == 0); - } else { - regs.a.w = regs.y.w; - regs.p.n = !!(regs.a.w & 0x8000); - regs.p.z = (regs.a.w == 0); + switch(status.cycle_pos++) { + case 1: + cpu_io(); + if(regs.p.m) { + regs.a.l = regs.y.l; + regs.p.n = !!(regs.a.l & 0x80); + regs.p.z = (regs.a.l == 0); + } else { + regs.a.w = regs.y.w; + regs.p.n = !!(regs.a.w & 0x8000); + regs.p.z = (regs.a.w == 0); + } + status.cycle_pos = 0; + break; } } void bCPU::op_tyx() { -l1: - cpu_io(); - if(regs.p.x) { - regs.x.l = regs.y.l; - regs.p.n = !!(regs.x.l & 0x80); - regs.p.z = (regs.x.l == 0); - } else { - regs.x.w = regs.y.w; - regs.p.n = !!(regs.x.w & 0x8000); - regs.p.z = (regs.x.w == 0); + switch(status.cycle_pos++) { + case 1: + cpu_io(); + if(regs.p.x) { + regs.x.l = regs.y.l; + regs.p.n = !!(regs.x.l & 0x80); + regs.p.z = (regs.x.l == 0); + } else { + regs.x.w = regs.y.w; + regs.p.n = !!(regs.x.w & 0x8000); + regs.p.z = (regs.x.w == 0); + } + status.cycle_pos = 0; + break; } } void bCPU::op_tcd() { -l1: - cpu_io(); - regs.d.w = regs.a.w; - regs.p.n = !!(regs.d.w & 0x8000); - regs.p.z = (regs.d.w == 0); + switch(status.cycle_pos++) { + case 1: + cpu_io(); + regs.d.w = regs.a.w; + regs.p.n = !!(regs.d.w & 0x8000); + regs.p.z = (regs.d.w == 0); + status.cycle_pos = 0; + break; + } } void bCPU::op_tcs() { -l1: - cpu_io(); - regs.s.w = regs.a.w; - if(regs.e)regs.s.h = 0x01; + switch(status.cycle_pos++) { + case 1: + cpu_io(); + regs.s.w = regs.a.w; + if(regs.e)regs.s.h = 0x01; + status.cycle_pos = 0; + break; + } } void bCPU::op_tdc() { -l1: - cpu_io(); - regs.a.w = regs.d.w; - regs.p.n = !!(regs.a.w & 0x8000); - regs.p.z = (regs.a.w == 0); + switch(status.cycle_pos++) { + case 1: + cpu_io(); + regs.a.w = regs.d.w; + regs.p.n = !!(regs.a.w & 0x8000); + regs.p.z = (regs.a.w == 0); + status.cycle_pos = 0; + break; + } } void bCPU::op_tsc() { -l1: - cpu_io(); - regs.a.w = regs.s.w; - if(regs.e) { - regs.p.n = !!(regs.a.l & 0x80); - regs.p.z = (regs.a.l == 0); - } else { - regs.p.n = !!(regs.a.w & 0x8000); - regs.p.z = (regs.a.w == 0); + switch(status.cycle_pos++) { + case 1: + cpu_io(); + regs.a.w = regs.s.w; + if(regs.e) { + regs.p.n = !!(regs.a.l & 0x80); + regs.p.z = (regs.a.l == 0); + } else { + regs.p.n = !!(regs.a.w & 0x8000); + regs.p.z = (regs.a.w == 0); + } + status.cycle_pos = 0; + break; } } void bCPU::op_tsx() { -l1: - cpu_io(); - if(regs.p.x) { - regs.x.l = regs.s.l; - regs.p.n = !!(regs.x.l & 0x80); - regs.p.z = (regs.x.l == 0); - } else { - regs.x.w = regs.s.w; - regs.p.n = !!(regs.x.w & 0x8000); - regs.p.z = (regs.x.w == 0); + switch(status.cycle_pos++) { + case 1: + cpu_io(); + if(regs.p.x) { + regs.x.l = regs.s.l; + regs.p.n = !!(regs.x.l & 0x80); + regs.p.z = (regs.x.l == 0); + } else { + regs.x.w = regs.s.w; + regs.p.n = !!(regs.x.w & 0x8000); + regs.p.z = (regs.x.w == 0); + } + status.cycle_pos = 0; + break; } } void bCPU::op_txs() { -l1: - cpu_io(); - if(regs.e) { - regs.s.l = regs.x.l; - regs.p.n = !!(regs.s.l & 0x80); - regs.p.z = (regs.s.l == 0); - } else { - regs.s.w = regs.x.w; - regs.p.n = !!(regs.s.w & 0x8000); - regs.p.z = (regs.s.w == 0); + switch(status.cycle_pos++) { + case 1: + cpu_io(); + if(regs.e) { + regs.s.l = regs.x.l; + regs.p.n = !!(regs.s.l & 0x80); + regs.p.z = (regs.s.l == 0); + } else { + regs.s.w = regs.x.w; + regs.p.n = !!(regs.s.w & 0x8000); + regs.p.z = (regs.s.w == 0); + } + status.cycle_pos = 0; + break; } } void bCPU::op_pha() { -l1: - cpu_io(); - if(regs.p.m)goto l3; -l2: - stack_write(regs.a.h); -l3: - stack_write(regs.a.l); + switch(status.cycle_pos++) { + case 1: + cpu_io(); + if(regs.p.m)status.cycle_pos++; + break; + case 2: + stack_write(regs.a.h); + break; + case 3: + stack_write(regs.a.l); + status.cycle_pos = 0; + break; + } } void bCPU::op_phx() { -l1: - cpu_io(); - if(regs.p.x)goto l3; -l2: - stack_write(regs.x.h); -l3: - stack_write(regs.x.l); + switch(status.cycle_pos++) { + case 1: + cpu_io(); + if(regs.p.x)status.cycle_pos++; + break; + case 2: + stack_write(regs.x.h); + break; + case 3: + stack_write(regs.x.l); + status.cycle_pos = 0; + break; + } } void bCPU::op_phy() { -l1: - cpu_io(); - if(regs.p.x)goto l3; -l2: - stack_write(regs.y.h); -l3: - stack_write(regs.y.l); + switch(status.cycle_pos++) { + case 1: + cpu_io(); + if(regs.p.x)status.cycle_pos++; + break; + case 2: + stack_write(regs.y.h); + break; + case 3: + stack_write(regs.y.l); + status.cycle_pos = 0; + break; + } } void bCPU::op_phd() { -l1: - cpu_io(); - if(0)goto l3; -l2: - stack_write(regs. d.h); -l3: - stack_write(regs. d.l); + switch(status.cycle_pos++) { + case 1: + cpu_io(); + if(0)status.cycle_pos++; + break; + case 2: + stack_write(regs. d.h); + break; + case 3: + stack_write(regs. d.l); + status.cycle_pos = 0; + break; + } } void bCPU::op_phb() { -l1: - cpu_io(); -l2: - stack_write(regs.db); + switch(status.cycle_pos++) { + case 1: + cpu_io(); + break; + case 2: + stack_write(regs.db); + status.cycle_pos = 0; + break; + } } void bCPU::op_phk() { -l1: - cpu_io(); -l2: - stack_write(regs.pc.b); + switch(status.cycle_pos++) { + case 1: + cpu_io(); + break; + case 2: + stack_write(regs.pc.b); + status.cycle_pos = 0; + break; + } } void bCPU::op_php() { -l1: - cpu_io(); -l2: - stack_write(regs.p); + switch(status.cycle_pos++) { + case 1: + cpu_io(); + break; + case 2: + stack_write(regs.p); + status.cycle_pos = 0; + break; + } } void bCPU::op_pla() { -l1: - cpu_io(); -l2: - cpu_io(); -l3: - regs.a.l = stack_read(); - if(regs.p.m) { - regs.p.n = !!(regs.a.l & 0x80); - regs.p.z = (regs.a.l == 0); - return; + switch(status.cycle_pos++) { + case 1: + cpu_io(); + break; + case 2: + cpu_io(); + break; + case 3: + regs.a.l = stack_read(); + if(regs.p.m) { + regs.p.n = !!(regs.a.l & 0x80); + regs.p.z = (regs.a.l == 0); + status.cycle_pos = 0; + } + break; + case 4: + regs.a.h = stack_read(); + regs.p.n = !!(regs.a.w & 0x8000); + regs.p.z = (regs.a.w == 0); + status.cycle_pos = 0; + break; } -l4: - regs.a.h = stack_read(); - regs.p.n = !!(regs.a.w & 0x8000); - regs.p.z = (regs.a.w == 0); } void bCPU::op_plx() { -l1: - cpu_io(); -l2: - cpu_io(); -l3: - regs.x.l = stack_read(); - if(regs.p.x) { - regs.p.n = !!(regs.x.l & 0x80); - regs.p.z = (regs.x.l == 0); - return; + switch(status.cycle_pos++) { + case 1: + cpu_io(); + break; + case 2: + cpu_io(); + break; + case 3: + regs.x.l = stack_read(); + if(regs.p.x) { + regs.p.n = !!(regs.x.l & 0x80); + regs.p.z = (regs.x.l == 0); + status.cycle_pos = 0; + } + break; + case 4: + regs.x.h = stack_read(); + regs.p.n = !!(regs.x.w & 0x8000); + regs.p.z = (regs.x.w == 0); + status.cycle_pos = 0; + break; } -l4: - regs.x.h = stack_read(); - regs.p.n = !!(regs.x.w & 0x8000); - regs.p.z = (regs.x.w == 0); } void bCPU::op_ply() { -l1: - cpu_io(); -l2: - cpu_io(); -l3: - regs.y.l = stack_read(); - if(regs.p.x) { - regs.p.n = !!(regs.y.l & 0x80); - regs.p.z = (regs.y.l == 0); - return; + switch(status.cycle_pos++) { + case 1: + cpu_io(); + break; + case 2: + cpu_io(); + break; + case 3: + regs.y.l = stack_read(); + if(regs.p.x) { + regs.p.n = !!(regs.y.l & 0x80); + regs.p.z = (regs.y.l == 0); + status.cycle_pos = 0; + } + break; + case 4: + regs.y.h = stack_read(); + regs.p.n = !!(regs.y.w & 0x8000); + regs.p.z = (regs.y.w == 0); + status.cycle_pos = 0; + break; } -l4: - regs.y.h = stack_read(); - regs.p.n = !!(regs.y.w & 0x8000); - regs.p.z = (regs.y.w == 0); } void bCPU::op_pld() { -l1: - cpu_io(); -l2: - cpu_io(); -l3: - regs. d.l = stack_read(); - if(0) { - regs.p.n = !!(regs. d.l & 0x80); - regs.p.z = (regs. d.l == 0); - return; + switch(status.cycle_pos++) { + case 1: + cpu_io(); + break; + case 2: + cpu_io(); + break; + case 3: + regs. d.l = stack_read(); + if(0) { + regs.p.n = !!(regs. d.l & 0x80); + regs.p.z = (regs. d.l == 0); + status.cycle_pos = 0; + } + break; + case 4: + regs. d.h = stack_read(); + regs.p.n = !!(regs. d.w & 0x8000); + regs.p.z = (regs. d.w == 0); + status.cycle_pos = 0; + break; } -l4: - regs. d.h = stack_read(); - regs.p.n = !!(regs. d.w & 0x8000); - regs.p.z = (regs. d.w == 0); } void bCPU::op_plb() { -l1: - cpu_io(); -l2: - cpu_io(); -l3: - regs.db = stack_read(); - regs.p.n = !!(regs.db & 0x80); - regs.p.z = (regs.db == 0); + switch(status.cycle_pos++) { + case 1: + cpu_io(); + break; + case 2: + cpu_io(); + break; + case 3: + regs.db = stack_read(); + regs.p.n = !!(regs.db & 0x80); + regs.p.z = (regs.db == 0); + status.cycle_pos = 0; + break; + } } void bCPU::op_plp() { -l1: - cpu_io(); -l2: - cpu_io(); -l3: - regs.p = stack_read(); - if(regs.e)regs.p |= 0x30; - if(regs.p.x) { - regs.x.h = 0x00; - regs.y.h = 0x00; + switch(status.cycle_pos++) { + case 1: + cpu_io(); + break; + case 2: + cpu_io(); + break; + case 3: + regs.p = stack_read(); + if(regs.e)regs.p |= 0x30; + if(regs.p.x) { + regs.x.h = 0x00; + regs.y.h = 0x00; + } + status.cycle_pos = 0; + break; } } void bCPU::op_pea() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - stack_write(aa.h); -l4: - stack_write(aa.l); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + stack_write(aa.h); + break; + case 4: + stack_write(aa.l); + status.cycle_pos = 0; + break; + } } void bCPU::op_pei() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - aa.l = op_read(OPMODE_DP, dp); -l4: - aa.h = op_read(OPMODE_DP, dp + 1); -l5: - stack_write(aa.h); -l6: - stack_write(aa.l); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + aa.l = op_read(OPMODE_DP, dp); + break; + case 4: + aa.h = op_read(OPMODE_DP, dp + 1); + break; + case 5: + stack_write(aa.h); + break; + case 6: + stack_write(aa.l); + status.cycle_pos = 0; + break; + } } void bCPU::op_per() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - cpu_io(); - rd.w = regs.pc.d + (int16)aa.w; -l4: - stack_write(rd.h); -l5: - stack_write(rd.l); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + cpu_io(); + rd.w = regs.pc.d + (int16)aa.w; + break; + case 4: + stack_write(rd.h); + break; + case 5: + stack_write(rd.l); + status.cycle_pos = 0; + break; + } } diff --git a/src/cpu/bcpu/bcpu_op_pc.cpp b/src/cpu/bcpu/bcpu_op_pc.cpp index c17a7df6..94a23447 100644 --- a/src/cpu/bcpu/bcpu_op_pc.cpp +++ b/src/cpu/bcpu/bcpu_op_pc.cpp @@ -1,310 +1,457 @@ void bCPU::op_bra() { -l1: - rd.l = op_read(); - if(1) { - aa.w = regs.pc.d + (int8)rd.l; - regs.pc.w = aa.w; - } else { - return; + switch(status.cycle_pos++) { + case 1: + rd.l = op_read(); + if(1) { + aa.w = regs.pc.d + (int8)rd.l; + regs.pc.w = aa.w; + } else { + status.cycle_pos = 0; + } + break; + case 2: + cpu_c6(aa.w); + break; + case 3: + cpu_io(); + status.cycle_pos = 0; + break; } -l2: - cpu_c6(aa.w); -l3: - cpu_io(); } void bCPU::op_bcc() { -l1: - rd.l = op_read(); - if(!regs.p.c) { - aa.w = regs.pc.d + (int8)rd.l; - regs.pc.w = aa.w; - } else { - return; + switch(status.cycle_pos++) { + case 1: + rd.l = op_read(); + if(!regs.p.c) { + aa.w = regs.pc.d + (int8)rd.l; + regs.pc.w = aa.w; + } else { + status.cycle_pos = 0; + } + break; + case 2: + cpu_c6(aa.w); + break; + case 3: + cpu_io(); + status.cycle_pos = 0; + break; } -l2: - cpu_c6(aa.w); -l3: - cpu_io(); } void bCPU::op_bcs() { -l1: - rd.l = op_read(); - if(regs.p.c) { - aa.w = regs.pc.d + (int8)rd.l; - regs.pc.w = aa.w; - } else { - return; + switch(status.cycle_pos++) { + case 1: + rd.l = op_read(); + if(regs.p.c) { + aa.w = regs.pc.d + (int8)rd.l; + regs.pc.w = aa.w; + } else { + status.cycle_pos = 0; + } + break; + case 2: + cpu_c6(aa.w); + break; + case 3: + cpu_io(); + status.cycle_pos = 0; + break; } -l2: - cpu_c6(aa.w); -l3: - cpu_io(); } void bCPU::op_bne() { -l1: - rd.l = op_read(); - if(!regs.p.z) { - aa.w = regs.pc.d + (int8)rd.l; - regs.pc.w = aa.w; - } else { - return; + switch(status.cycle_pos++) { + case 1: + rd.l = op_read(); + if(!regs.p.z) { + aa.w = regs.pc.d + (int8)rd.l; + regs.pc.w = aa.w; + } else { + status.cycle_pos = 0; + } + break; + case 2: + cpu_c6(aa.w); + break; + case 3: + cpu_io(); + status.cycle_pos = 0; + break; } -l2: - cpu_c6(aa.w); -l3: - cpu_io(); } void bCPU::op_beq() { -l1: - rd.l = op_read(); - if(regs.p.z) { - aa.w = regs.pc.d + (int8)rd.l; - regs.pc.w = aa.w; - } else { - return; + switch(status.cycle_pos++) { + case 1: + rd.l = op_read(); + if(regs.p.z) { + aa.w = regs.pc.d + (int8)rd.l; + regs.pc.w = aa.w; + } else { + status.cycle_pos = 0; + } + break; + case 2: + cpu_c6(aa.w); + break; + case 3: + cpu_io(); + status.cycle_pos = 0; + break; } -l2: - cpu_c6(aa.w); -l3: - cpu_io(); } void bCPU::op_bpl() { -l1: - rd.l = op_read(); - if(!regs.p.n) { - aa.w = regs.pc.d + (int8)rd.l; - regs.pc.w = aa.w; - } else { - return; + switch(status.cycle_pos++) { + case 1: + rd.l = op_read(); + if(!regs.p.n) { + aa.w = regs.pc.d + (int8)rd.l; + regs.pc.w = aa.w; + } else { + status.cycle_pos = 0; + } + break; + case 2: + cpu_c6(aa.w); + break; + case 3: + cpu_io(); + status.cycle_pos = 0; + break; } -l2: - cpu_c6(aa.w); -l3: - cpu_io(); } void bCPU::op_bmi() { -l1: - rd.l = op_read(); - if(regs.p.n) { - aa.w = regs.pc.d + (int8)rd.l; - regs.pc.w = aa.w; - } else { - return; + switch(status.cycle_pos++) { + case 1: + rd.l = op_read(); + if(regs.p.n) { + aa.w = regs.pc.d + (int8)rd.l; + regs.pc.w = aa.w; + } else { + status.cycle_pos = 0; + } + break; + case 2: + cpu_c6(aa.w); + break; + case 3: + cpu_io(); + status.cycle_pos = 0; + break; } -l2: - cpu_c6(aa.w); -l3: - cpu_io(); } void bCPU::op_bvc() { -l1: - rd.l = op_read(); - if(!regs.p.v) { - aa.w = regs.pc.d + (int8)rd.l; - regs.pc.w = aa.w; - } else { - return; + switch(status.cycle_pos++) { + case 1: + rd.l = op_read(); + if(!regs.p.v) { + aa.w = regs.pc.d + (int8)rd.l; + regs.pc.w = aa.w; + } else { + status.cycle_pos = 0; + } + break; + case 2: + cpu_c6(aa.w); + break; + case 3: + cpu_io(); + status.cycle_pos = 0; + break; } -l2: - cpu_c6(aa.w); -l3: - cpu_io(); } void bCPU::op_bvs() { -l1: - rd.l = op_read(); - if(regs.p.v) { - aa.w = regs.pc.d + (int8)rd.l; - regs.pc.w = aa.w; - } else { - return; + switch(status.cycle_pos++) { + case 1: + rd.l = op_read(); + if(regs.p.v) { + aa.w = regs.pc.d + (int8)rd.l; + regs.pc.w = aa.w; + } else { + status.cycle_pos = 0; + } + break; + case 2: + cpu_c6(aa.w); + break; + case 3: + cpu_io(); + status.cycle_pos = 0; + break; } -l2: - cpu_c6(aa.w); -l3: - cpu_io(); } void bCPU::op_brl() { -l1: - rd.l = op_read(); -l2: - rd.h = op_read(); -l3: - cpu_io(); - regs.pc.w = regs.pc.d + (int16)rd.w; + switch(status.cycle_pos++) { + case 1: + rd.l = op_read(); + break; + case 2: + rd.h = op_read(); + break; + case 3: + cpu_io(); + regs.pc.w = regs.pc.d + (int16)rd.w; + status.cycle_pos = 0; + break; + } } void bCPU::op_jmp_addr() { -l1: - rd.l = op_read(); -l2: - rd.h = op_read(); - regs.pc.w = rd.w; + switch(status.cycle_pos++) { + case 1: + rd.l = op_read(); + break; + case 2: + rd.h = op_read(); + regs.pc.w = rd.w; + status.cycle_pos = 0; + break; + } } void bCPU::op_jmp_long() { -l1: - rd.l = op_read(); -l2: - rd.h = op_read(); -l3: - rd.b = op_read(); - regs.pc.d = rd.d & 0xffffff; + switch(status.cycle_pos++) { + case 1: + rd.l = op_read(); + break; + case 2: + rd.h = op_read(); + break; + case 3: + rd.b = op_read(); + regs.pc.d = rd.d & 0xffffff; + status.cycle_pos = 0; + break; + } } void bCPU::op_jmp_iaddr() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - rd.l = op_read(OPMODE_ADDR, aa.w); -l4: - rd.h = op_read(OPMODE_ADDR, aa.w + 1); - regs.pc.w = rd.w; + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + rd.l = op_read(OPMODE_ADDR, aa.w); + break; + case 4: + rd.h = op_read(OPMODE_ADDR, aa.w + 1); + regs.pc.w = rd.w; + status.cycle_pos = 0; + break; + } } void bCPU::op_jmp_iaddrx() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - cpu_io(); -l4: - rd.l = op_read(OPMODE_PBR, aa.w + regs.x.w); -l5: - rd.h = op_read(OPMODE_PBR, aa.w + regs.x.w + 1); - regs.pc.w = rd.w; + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + cpu_io(); + break; + case 4: + rd.l = op_read(OPMODE_PBR, aa.w + regs.x.w); + break; + case 5: + rd.h = op_read(OPMODE_PBR, aa.w + regs.x.w + 1); + regs.pc.w = rd.w; + status.cycle_pos = 0; + break; + } } void bCPU::op_jmp_iladdr() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - rd.l = op_read(OPMODE_ADDR, aa.w); -l4: - rd.h = op_read(OPMODE_ADDR, aa.w + 1); -l5: - rd.b = op_read(OPMODE_ADDR, aa.w + 2); - regs.pc.d = rd.d & 0xffffff; + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + rd.l = op_read(OPMODE_ADDR, aa.w); + break; + case 4: + rd.h = op_read(OPMODE_ADDR, aa.w + 1); + break; + case 5: + rd.b = op_read(OPMODE_ADDR, aa.w + 2); + regs.pc.d = rd.d & 0xffffff; + status.cycle_pos = 0; + break; + } } void bCPU::op_jsr_addr() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - cpu_io(); -l4: - regs.pc.w--; - stack_write(regs.pc.h); -l5: - stack_write(regs.pc.l); - regs.pc.w = aa.w; + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + cpu_io(); + break; + case 4: + regs.pc.w--; + stack_write(regs.pc.h); + break; + case 5: + stack_write(regs.pc.l); + regs.pc.w = aa.w; + status.cycle_pos = 0; + break; + } } void bCPU::op_jsr_long() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - stack_write(regs.pc.b); -l4: - cpu_io(); -l5: - aa.b = op_read(); -l6: - regs.pc.w--; - stack_write(regs.pc.h); -l7: - stack_write(regs.pc.l); - regs.pc.d = aa.d & 0xffffff; + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + stack_write(regs.pc.b); + break; + case 4: + cpu_io(); + break; + case 5: + aa.b = op_read(); + break; + case 6: + regs.pc.w--; + stack_write(regs.pc.h); + break; + case 7: + stack_write(regs.pc.l); + regs.pc.d = aa.d & 0xffffff; + status.cycle_pos = 0; + break; + } } void bCPU::op_jsr_iaddrx() { -l1: - aa.l = op_read(); -l2: - stack_write(regs.pc.h); -l3: - stack_write(regs.pc.l); -l4: - aa.h = op_read(); -l5: - cpu_io(); -l6: - rd.l = op_read(OPMODE_PBR, aa.w + regs.x.w); -l7: - rd.h = op_read(OPMODE_PBR, aa.w + regs.x.w + 1); - regs.pc.w = rd.w; + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + stack_write(regs.pc.h); + break; + case 3: + stack_write(regs.pc.l); + break; + case 4: + aa.h = op_read(); + break; + case 5: + cpu_io(); + break; + case 6: + rd.l = op_read(OPMODE_PBR, aa.w + regs.x.w); + break; + case 7: + rd.h = op_read(OPMODE_PBR, aa.w + regs.x.w + 1); + regs.pc.w = rd.w; + status.cycle_pos = 0; + break; + } } void bCPU::op_rti() { -l1: - cpu_io(); -l2: - cpu_io(); -l3: - regs.p = stack_read(); - if(regs.e)regs.p |= 0x30; - if(regs.p.x) { - regs.x.h = 0x00; - regs.y.h = 0x00; + switch(status.cycle_pos++) { + case 1: + cpu_io(); + break; + case 2: + cpu_io(); + break; + case 3: + regs.p = stack_read(); + if(regs.e)regs.p |= 0x30; + if(regs.p.x) { + regs.x.h = 0x00; + regs.y.h = 0x00; + } + break; + case 4: + rd.l = stack_read(); + break; + case 5: + rd.h = stack_read(); + if(regs.e) { + regs.pc.w = rd.w; + status.cycle_pos = 0; + } + break; + case 6: + rd.b = stack_read(); + regs.pc.d = rd.d & 0xffffff; + status.cycle_pos = 0; + break; } -l4: - rd.l = stack_read(); -l5: - rd.h = stack_read(); - if(regs.e) { - regs.pc.w = rd.w; - return; - } -l6: - rd.b = stack_read(); - regs.pc.d = rd.d & 0xffffff; } void bCPU::op_rts() { -l1: - cpu_io(); -l2: - cpu_io(); -l3: - rd.l = stack_read(); -l4: - rd.h = stack_read(); -l5: - cpu_io(); - regs.pc.w = rd.w; - regs.pc.w++; + switch(status.cycle_pos++) { + case 1: + cpu_io(); + break; + case 2: + cpu_io(); + break; + case 3: + rd.l = stack_read(); + break; + case 4: + rd.h = stack_read(); + break; + case 5: + cpu_io(); + regs.pc.w = rd.w; + regs.pc.w++; + status.cycle_pos = 0; + break; + } } void bCPU::op_rtl() { -l1: - cpu_io(); -l2: - cpu_io(); -l3: - rd.l = stack_read(); -l4: - rd.h = stack_read(); -l5: - rd.b = stack_read(); - regs.pc.d = rd.d & 0xffffff; - regs.pc.w++; + switch(status.cycle_pos++) { + case 1: + cpu_io(); + break; + case 2: + cpu_io(); + break; + case 3: + rd.l = stack_read(); + break; + case 4: + rd.h = stack_read(); + break; + case 5: + rd.b = stack_read(); + regs.pc.d = rd.d & 0xffffff; + regs.pc.w++; + status.cycle_pos = 0; + break; + } } diff --git a/src/cpu/bcpu/bcpu_op_read.cpp b/src/cpu/bcpu/bcpu_op_read.cpp index d670a879..8274a2dd 100644 --- a/src/cpu/bcpu/bcpu_op_read.cpp +++ b/src/cpu/bcpu/bcpu_op_read.cpp @@ -1,1913 +1,2931 @@ void bCPU::op_adc_const() { -l1: - rd.l = op_read(); - if(regs.p.m) { op_adc_b(); return; } -l2: - rd.h = op_read(); - op_adc_w(); + switch(status.cycle_pos++) { + case 1: + rd.l = op_read(); + if(regs.p.m) { op_adc_b(); status.cycle_pos = 0; } + break; + case 2: + rd.h = op_read(); + op_adc_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_and_const() { -l1: - rd.l = op_read(); - if(regs.p.m) { op_and_b(); return; } -l2: - rd.h = op_read(); - op_and_w(); + switch(status.cycle_pos++) { + case 1: + rd.l = op_read(); + if(regs.p.m) { op_and_b(); status.cycle_pos = 0; } + break; + case 2: + rd.h = op_read(); + op_and_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_cmp_const() { -l1: - rd.l = op_read(); - if(regs.p.m) { op_cmp_b(); return; } -l2: - rd.h = op_read(); - op_cmp_w(); + switch(status.cycle_pos++) { + case 1: + rd.l = op_read(); + if(regs.p.m) { op_cmp_b(); status.cycle_pos = 0; } + break; + case 2: + rd.h = op_read(); + op_cmp_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_cpx_const() { -l1: - rd.l = op_read(); - if(regs.p.x) { op_cpx_b(); return; } -l2: - rd.h = op_read(); - op_cpx_w(); + switch(status.cycle_pos++) { + case 1: + rd.l = op_read(); + if(regs.p.x) { op_cpx_b(); status.cycle_pos = 0; } + break; + case 2: + rd.h = op_read(); + op_cpx_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_cpy_const() { -l1: - rd.l = op_read(); - if(regs.p.x) { op_cpy_b(); return; } -l2: - rd.h = op_read(); - op_cpy_w(); + switch(status.cycle_pos++) { + case 1: + rd.l = op_read(); + if(regs.p.x) { op_cpy_b(); status.cycle_pos = 0; } + break; + case 2: + rd.h = op_read(); + op_cpy_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_eor_const() { -l1: - rd.l = op_read(); - if(regs.p.m) { op_eor_b(); return; } -l2: - rd.h = op_read(); - op_eor_w(); + switch(status.cycle_pos++) { + case 1: + rd.l = op_read(); + if(regs.p.m) { op_eor_b(); status.cycle_pos = 0; } + break; + case 2: + rd.h = op_read(); + op_eor_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_lda_const() { -l1: - rd.l = op_read(); - if(regs.p.m) { op_lda_b(); return; } -l2: - rd.h = op_read(); - op_lda_w(); + switch(status.cycle_pos++) { + case 1: + rd.l = op_read(); + if(regs.p.m) { op_lda_b(); status.cycle_pos = 0; } + break; + case 2: + rd.h = op_read(); + op_lda_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_ldx_const() { -l1: - rd.l = op_read(); - if(regs.p.x) { op_ldx_b(); return; } -l2: - rd.h = op_read(); - op_ldx_w(); + switch(status.cycle_pos++) { + case 1: + rd.l = op_read(); + if(regs.p.x) { op_ldx_b(); status.cycle_pos = 0; } + break; + case 2: + rd.h = op_read(); + op_ldx_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_ldy_const() { -l1: - rd.l = op_read(); - if(regs.p.x) { op_ldy_b(); return; } -l2: - rd.h = op_read(); - op_ldy_w(); + switch(status.cycle_pos++) { + case 1: + rd.l = op_read(); + if(regs.p.x) { op_ldy_b(); status.cycle_pos = 0; } + break; + case 2: + rd.h = op_read(); + op_ldy_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_ora_const() { -l1: - rd.l = op_read(); - if(regs.p.m) { op_ora_b(); return; } -l2: - rd.h = op_read(); - op_ora_w(); + switch(status.cycle_pos++) { + case 1: + rd.l = op_read(); + if(regs.p.m) { op_ora_b(); status.cycle_pos = 0; } + break; + case 2: + rd.h = op_read(); + op_ora_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_sbc_const() { -l1: - rd.l = op_read(); - if(regs.p.m) { op_sbc_b(); return; } -l2: - rd.h = op_read(); - op_sbc_w(); + switch(status.cycle_pos++) { + case 1: + rd.l = op_read(); + if(regs.p.m) { op_sbc_b(); status.cycle_pos = 0; } + break; + case 2: + rd.h = op_read(); + op_sbc_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_adc_addr() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - rd.l = op_read(OPMODE_DBR, aa.w); - if(regs.p.m) { op_adc_b(); return; } -l4: - rd.h = op_read(OPMODE_DBR, aa.w + 1); - op_adc_w(); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + rd.l = op_read(OPMODE_DBR, aa.w); + if(regs.p.m) { op_adc_b(); status.cycle_pos = 0; } + break; + case 4: + rd.h = op_read(OPMODE_DBR, aa.w + 1); + op_adc_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_and_addr() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - rd.l = op_read(OPMODE_DBR, aa.w); - if(regs.p.m) { op_and_b(); return; } -l4: - rd.h = op_read(OPMODE_DBR, aa.w + 1); - op_and_w(); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + rd.l = op_read(OPMODE_DBR, aa.w); + if(regs.p.m) { op_and_b(); status.cycle_pos = 0; } + break; + case 4: + rd.h = op_read(OPMODE_DBR, aa.w + 1); + op_and_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_bit_addr() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - rd.l = op_read(OPMODE_DBR, aa.w); - if(regs.p.m) { op_bit_b(); return; } -l4: - rd.h = op_read(OPMODE_DBR, aa.w + 1); - op_bit_w(); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + rd.l = op_read(OPMODE_DBR, aa.w); + if(regs.p.m) { op_bit_b(); status.cycle_pos = 0; } + break; + case 4: + rd.h = op_read(OPMODE_DBR, aa.w + 1); + op_bit_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_cmp_addr() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - rd.l = op_read(OPMODE_DBR, aa.w); - if(regs.p.m) { op_cmp_b(); return; } -l4: - rd.h = op_read(OPMODE_DBR, aa.w + 1); - op_cmp_w(); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + rd.l = op_read(OPMODE_DBR, aa.w); + if(regs.p.m) { op_cmp_b(); status.cycle_pos = 0; } + break; + case 4: + rd.h = op_read(OPMODE_DBR, aa.w + 1); + op_cmp_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_cpx_addr() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - rd.l = op_read(OPMODE_DBR, aa.w); - if(regs.p.x) { op_cpx_b(); return; } -l4: - rd.h = op_read(OPMODE_DBR, aa.w + 1); - op_cpx_w(); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + rd.l = op_read(OPMODE_DBR, aa.w); + if(regs.p.x) { op_cpx_b(); status.cycle_pos = 0; } + break; + case 4: + rd.h = op_read(OPMODE_DBR, aa.w + 1); + op_cpx_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_cpy_addr() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - rd.l = op_read(OPMODE_DBR, aa.w); - if(regs.p.x) { op_cpy_b(); return; } -l4: - rd.h = op_read(OPMODE_DBR, aa.w + 1); - op_cpy_w(); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + rd.l = op_read(OPMODE_DBR, aa.w); + if(regs.p.x) { op_cpy_b(); status.cycle_pos = 0; } + break; + case 4: + rd.h = op_read(OPMODE_DBR, aa.w + 1); + op_cpy_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_eor_addr() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - rd.l = op_read(OPMODE_DBR, aa.w); - if(regs.p.m) { op_eor_b(); return; } -l4: - rd.h = op_read(OPMODE_DBR, aa.w + 1); - op_eor_w(); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + rd.l = op_read(OPMODE_DBR, aa.w); + if(regs.p.m) { op_eor_b(); status.cycle_pos = 0; } + break; + case 4: + rd.h = op_read(OPMODE_DBR, aa.w + 1); + op_eor_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_lda_addr() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - rd.l = op_read(OPMODE_DBR, aa.w); - if(regs.p.m) { op_lda_b(); return; } -l4: - rd.h = op_read(OPMODE_DBR, aa.w + 1); - op_lda_w(); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + rd.l = op_read(OPMODE_DBR, aa.w); + if(regs.p.m) { op_lda_b(); status.cycle_pos = 0; } + break; + case 4: + rd.h = op_read(OPMODE_DBR, aa.w + 1); + op_lda_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_ldx_addr() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - rd.l = op_read(OPMODE_DBR, aa.w); - if(regs.p.x) { op_ldx_b(); return; } -l4: - rd.h = op_read(OPMODE_DBR, aa.w + 1); - op_ldx_w(); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + rd.l = op_read(OPMODE_DBR, aa.w); + if(regs.p.x) { op_ldx_b(); status.cycle_pos = 0; } + break; + case 4: + rd.h = op_read(OPMODE_DBR, aa.w + 1); + op_ldx_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_ldy_addr() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - rd.l = op_read(OPMODE_DBR, aa.w); - if(regs.p.x) { op_ldy_b(); return; } -l4: - rd.h = op_read(OPMODE_DBR, aa.w + 1); - op_ldy_w(); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + rd.l = op_read(OPMODE_DBR, aa.w); + if(regs.p.x) { op_ldy_b(); status.cycle_pos = 0; } + break; + case 4: + rd.h = op_read(OPMODE_DBR, aa.w + 1); + op_ldy_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_ora_addr() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - rd.l = op_read(OPMODE_DBR, aa.w); - if(regs.p.m) { op_ora_b(); return; } -l4: - rd.h = op_read(OPMODE_DBR, aa.w + 1); - op_ora_w(); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + rd.l = op_read(OPMODE_DBR, aa.w); + if(regs.p.m) { op_ora_b(); status.cycle_pos = 0; } + break; + case 4: + rd.h = op_read(OPMODE_DBR, aa.w + 1); + op_ora_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_sbc_addr() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - rd.l = op_read(OPMODE_DBR, aa.w); - if(regs.p.m) { op_sbc_b(); return; } -l4: - rd.h = op_read(OPMODE_DBR, aa.w + 1); - op_sbc_w(); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + rd.l = op_read(OPMODE_DBR, aa.w); + if(regs.p.m) { op_sbc_b(); status.cycle_pos = 0; } + break; + case 4: + rd.h = op_read(OPMODE_DBR, aa.w + 1); + op_sbc_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_adc_addrx() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - cpu_c4(aa.w, aa.w + regs.x.w); -l4: - rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); - if(regs.p.m) { op_adc_b(); return; } -l5: - rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); - op_adc_w(); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + cpu_c4(aa.w, aa.w + regs.x.w); + break; + case 4: + rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); + if(regs.p.m) { op_adc_b(); status.cycle_pos = 0; } + break; + case 5: + rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); + op_adc_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_and_addrx() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - cpu_c4(aa.w, aa.w + regs.x.w); -l4: - rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); - if(regs.p.m) { op_and_b(); return; } -l5: - rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); - op_and_w(); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + cpu_c4(aa.w, aa.w + regs.x.w); + break; + case 4: + rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); + if(regs.p.m) { op_and_b(); status.cycle_pos = 0; } + break; + case 5: + rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); + op_and_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_bit_addrx() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - cpu_c4(aa.w, aa.w + regs.x.w); -l4: - rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); - if(regs.p.m) { op_bit_b(); return; } -l5: - rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); - op_bit_w(); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + cpu_c4(aa.w, aa.w + regs.x.w); + break; + case 4: + rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); + if(regs.p.m) { op_bit_b(); status.cycle_pos = 0; } + break; + case 5: + rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); + op_bit_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_cmp_addrx() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - cpu_c4(aa.w, aa.w + regs.x.w); -l4: - rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); - if(regs.p.m) { op_cmp_b(); return; } -l5: - rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); - op_cmp_w(); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + cpu_c4(aa.w, aa.w + regs.x.w); + break; + case 4: + rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); + if(regs.p.m) { op_cmp_b(); status.cycle_pos = 0; } + break; + case 5: + rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); + op_cmp_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_eor_addrx() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - cpu_c4(aa.w, aa.w + regs.x.w); -l4: - rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); - if(regs.p.m) { op_eor_b(); return; } -l5: - rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); - op_eor_w(); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + cpu_c4(aa.w, aa.w + regs.x.w); + break; + case 4: + rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); + if(regs.p.m) { op_eor_b(); status.cycle_pos = 0; } + break; + case 5: + rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); + op_eor_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_lda_addrx() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - cpu_c4(aa.w, aa.w + regs.x.w); -l4: - rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); - if(regs.p.m) { op_lda_b(); return; } -l5: - rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); - op_lda_w(); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + cpu_c4(aa.w, aa.w + regs.x.w); + break; + case 4: + rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); + if(regs.p.m) { op_lda_b(); status.cycle_pos = 0; } + break; + case 5: + rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); + op_lda_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_ldy_addrx() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - cpu_c4(aa.w, aa.w + regs.x.w); -l4: - rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); - if(regs.p.x) { op_ldy_b(); return; } -l5: - rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); - op_ldy_w(); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + cpu_c4(aa.w, aa.w + regs.x.w); + break; + case 4: + rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); + if(regs.p.x) { op_ldy_b(); status.cycle_pos = 0; } + break; + case 5: + rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); + op_ldy_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_ora_addrx() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - cpu_c4(aa.w, aa.w + regs.x.w); -l4: - rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); - if(regs.p.m) { op_ora_b(); return; } -l5: - rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); - op_ora_w(); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + cpu_c4(aa.w, aa.w + regs.x.w); + break; + case 4: + rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); + if(regs.p.m) { op_ora_b(); status.cycle_pos = 0; } + break; + case 5: + rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); + op_ora_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_sbc_addrx() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - cpu_c4(aa.w, aa.w + regs.x.w); -l4: - rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); - if(regs.p.m) { op_sbc_b(); return; } -l5: - rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); - op_sbc_w(); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + cpu_c4(aa.w, aa.w + regs.x.w); + break; + case 4: + rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); + if(regs.p.m) { op_sbc_b(); status.cycle_pos = 0; } + break; + case 5: + rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); + op_sbc_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_adc_addry() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - cpu_c4(aa.w, aa.w + regs.y.w); -l4: - rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); - if(regs.p.m) { op_adc_b(); return; } -l5: - rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); - op_adc_w(); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + cpu_c4(aa.w, aa.w + regs.y.w); + break; + case 4: + rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); + if(regs.p.m) { op_adc_b(); status.cycle_pos = 0; } + break; + case 5: + rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); + op_adc_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_and_addry() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - cpu_c4(aa.w, aa.w + regs.y.w); -l4: - rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); - if(regs.p.m) { op_and_b(); return; } -l5: - rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); - op_and_w(); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + cpu_c4(aa.w, aa.w + regs.y.w); + break; + case 4: + rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); + if(regs.p.m) { op_and_b(); status.cycle_pos = 0; } + break; + case 5: + rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); + op_and_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_cmp_addry() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - cpu_c4(aa.w, aa.w + regs.y.w); -l4: - rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); - if(regs.p.m) { op_cmp_b(); return; } -l5: - rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); - op_cmp_w(); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + cpu_c4(aa.w, aa.w + regs.y.w); + break; + case 4: + rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); + if(regs.p.m) { op_cmp_b(); status.cycle_pos = 0; } + break; + case 5: + rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); + op_cmp_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_eor_addry() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - cpu_c4(aa.w, aa.w + regs.y.w); -l4: - rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); - if(regs.p.m) { op_eor_b(); return; } -l5: - rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); - op_eor_w(); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + cpu_c4(aa.w, aa.w + regs.y.w); + break; + case 4: + rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); + if(regs.p.m) { op_eor_b(); status.cycle_pos = 0; } + break; + case 5: + rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); + op_eor_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_lda_addry() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - cpu_c4(aa.w, aa.w + regs.y.w); -l4: - rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); - if(regs.p.m) { op_lda_b(); return; } -l5: - rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); - op_lda_w(); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + cpu_c4(aa.w, aa.w + regs.y.w); + break; + case 4: + rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); + if(regs.p.m) { op_lda_b(); status.cycle_pos = 0; } + break; + case 5: + rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); + op_lda_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_ldx_addry() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - cpu_c4(aa.w, aa.w + regs.y.w); -l4: - rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); - if(regs.p.x) { op_ldx_b(); return; } -l5: - rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); - op_ldx_w(); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + cpu_c4(aa.w, aa.w + regs.y.w); + break; + case 4: + rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); + if(regs.p.x) { op_ldx_b(); status.cycle_pos = 0; } + break; + case 5: + rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); + op_ldx_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_ora_addry() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - cpu_c4(aa.w, aa.w + regs.y.w); -l4: - rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); - if(regs.p.m) { op_ora_b(); return; } -l5: - rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); - op_ora_w(); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + cpu_c4(aa.w, aa.w + regs.y.w); + break; + case 4: + rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); + if(regs.p.m) { op_ora_b(); status.cycle_pos = 0; } + break; + case 5: + rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); + op_ora_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_sbc_addry() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - cpu_c4(aa.w, aa.w + regs.y.w); -l4: - rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); - if(regs.p.m) { op_sbc_b(); return; } -l5: - rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); - op_sbc_w(); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + cpu_c4(aa.w, aa.w + regs.y.w); + break; + case 4: + rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); + if(regs.p.m) { op_sbc_b(); status.cycle_pos = 0; } + break; + case 5: + rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); + op_sbc_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_adc_long() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - aa.b = op_read(); -l4: - rd.l = op_read(OPMODE_LONG, aa.d); - if(regs.p.m) { op_adc_b(); return; } -l5: - rd.h = op_read(OPMODE_LONG, aa.d + 1); - op_adc_w(); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + aa.b = op_read(); + break; + case 4: + rd.l = op_read(OPMODE_LONG, aa.d); + if(regs.p.m) { op_adc_b(); status.cycle_pos = 0; } + break; + case 5: + rd.h = op_read(OPMODE_LONG, aa.d + 1); + op_adc_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_and_long() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - aa.b = op_read(); -l4: - rd.l = op_read(OPMODE_LONG, aa.d); - if(regs.p.m) { op_and_b(); return; } -l5: - rd.h = op_read(OPMODE_LONG, aa.d + 1); - op_and_w(); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + aa.b = op_read(); + break; + case 4: + rd.l = op_read(OPMODE_LONG, aa.d); + if(regs.p.m) { op_and_b(); status.cycle_pos = 0; } + break; + case 5: + rd.h = op_read(OPMODE_LONG, aa.d + 1); + op_and_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_cmp_long() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - aa.b = op_read(); -l4: - rd.l = op_read(OPMODE_LONG, aa.d); - if(regs.p.m) { op_cmp_b(); return; } -l5: - rd.h = op_read(OPMODE_LONG, aa.d + 1); - op_cmp_w(); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + aa.b = op_read(); + break; + case 4: + rd.l = op_read(OPMODE_LONG, aa.d); + if(regs.p.m) { op_cmp_b(); status.cycle_pos = 0; } + break; + case 5: + rd.h = op_read(OPMODE_LONG, aa.d + 1); + op_cmp_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_eor_long() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - aa.b = op_read(); -l4: - rd.l = op_read(OPMODE_LONG, aa.d); - if(regs.p.m) { op_eor_b(); return; } -l5: - rd.h = op_read(OPMODE_LONG, aa.d + 1); - op_eor_w(); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + aa.b = op_read(); + break; + case 4: + rd.l = op_read(OPMODE_LONG, aa.d); + if(regs.p.m) { op_eor_b(); status.cycle_pos = 0; } + break; + case 5: + rd.h = op_read(OPMODE_LONG, aa.d + 1); + op_eor_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_lda_long() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - aa.b = op_read(); -l4: - rd.l = op_read(OPMODE_LONG, aa.d); - if(regs.p.m) { op_lda_b(); return; } -l5: - rd.h = op_read(OPMODE_LONG, aa.d + 1); - op_lda_w(); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + aa.b = op_read(); + break; + case 4: + rd.l = op_read(OPMODE_LONG, aa.d); + if(regs.p.m) { op_lda_b(); status.cycle_pos = 0; } + break; + case 5: + rd.h = op_read(OPMODE_LONG, aa.d + 1); + op_lda_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_ora_long() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - aa.b = op_read(); -l4: - rd.l = op_read(OPMODE_LONG, aa.d); - if(regs.p.m) { op_ora_b(); return; } -l5: - rd.h = op_read(OPMODE_LONG, aa.d + 1); - op_ora_w(); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + aa.b = op_read(); + break; + case 4: + rd.l = op_read(OPMODE_LONG, aa.d); + if(regs.p.m) { op_ora_b(); status.cycle_pos = 0; } + break; + case 5: + rd.h = op_read(OPMODE_LONG, aa.d + 1); + op_ora_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_sbc_long() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - aa.b = op_read(); -l4: - rd.l = op_read(OPMODE_LONG, aa.d); - if(regs.p.m) { op_sbc_b(); return; } -l5: - rd.h = op_read(OPMODE_LONG, aa.d + 1); - op_sbc_w(); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + aa.b = op_read(); + break; + case 4: + rd.l = op_read(OPMODE_LONG, aa.d); + if(regs.p.m) { op_sbc_b(); status.cycle_pos = 0; } + break; + case 5: + rd.h = op_read(OPMODE_LONG, aa.d + 1); + op_sbc_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_adc_longx() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - aa.b = op_read(); -l4: - rd.l = op_read(OPMODE_LONG, aa.d + regs.x.w); - if(regs.p.m) { op_adc_b(); return; } -l5: - rd.h = op_read(OPMODE_LONG, aa.d + regs.x.w + 1); - op_adc_w(); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + aa.b = op_read(); + break; + case 4: + rd.l = op_read(OPMODE_LONG, aa.d + regs.x.w); + if(regs.p.m) { op_adc_b(); status.cycle_pos = 0; } + break; + case 5: + rd.h = op_read(OPMODE_LONG, aa.d + regs.x.w + 1); + op_adc_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_and_longx() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - aa.b = op_read(); -l4: - rd.l = op_read(OPMODE_LONG, aa.d + regs.x.w); - if(regs.p.m) { op_and_b(); return; } -l5: - rd.h = op_read(OPMODE_LONG, aa.d + regs.x.w + 1); - op_and_w(); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + aa.b = op_read(); + break; + case 4: + rd.l = op_read(OPMODE_LONG, aa.d + regs.x.w); + if(regs.p.m) { op_and_b(); status.cycle_pos = 0; } + break; + case 5: + rd.h = op_read(OPMODE_LONG, aa.d + regs.x.w + 1); + op_and_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_cmp_longx() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - aa.b = op_read(); -l4: - rd.l = op_read(OPMODE_LONG, aa.d + regs.x.w); - if(regs.p.m) { op_cmp_b(); return; } -l5: - rd.h = op_read(OPMODE_LONG, aa.d + regs.x.w + 1); - op_cmp_w(); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + aa.b = op_read(); + break; + case 4: + rd.l = op_read(OPMODE_LONG, aa.d + regs.x.w); + if(regs.p.m) { op_cmp_b(); status.cycle_pos = 0; } + break; + case 5: + rd.h = op_read(OPMODE_LONG, aa.d + regs.x.w + 1); + op_cmp_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_eor_longx() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - aa.b = op_read(); -l4: - rd.l = op_read(OPMODE_LONG, aa.d + regs.x.w); - if(regs.p.m) { op_eor_b(); return; } -l5: - rd.h = op_read(OPMODE_LONG, aa.d + regs.x.w + 1); - op_eor_w(); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + aa.b = op_read(); + break; + case 4: + rd.l = op_read(OPMODE_LONG, aa.d + regs.x.w); + if(regs.p.m) { op_eor_b(); status.cycle_pos = 0; } + break; + case 5: + rd.h = op_read(OPMODE_LONG, aa.d + regs.x.w + 1); + op_eor_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_lda_longx() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - aa.b = op_read(); -l4: - rd.l = op_read(OPMODE_LONG, aa.d + regs.x.w); - if(regs.p.m) { op_lda_b(); return; } -l5: - rd.h = op_read(OPMODE_LONG, aa.d + regs.x.w + 1); - op_lda_w(); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + aa.b = op_read(); + break; + case 4: + rd.l = op_read(OPMODE_LONG, aa.d + regs.x.w); + if(regs.p.m) { op_lda_b(); status.cycle_pos = 0; } + break; + case 5: + rd.h = op_read(OPMODE_LONG, aa.d + regs.x.w + 1); + op_lda_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_ora_longx() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - aa.b = op_read(); -l4: - rd.l = op_read(OPMODE_LONG, aa.d + regs.x.w); - if(regs.p.m) { op_ora_b(); return; } -l5: - rd.h = op_read(OPMODE_LONG, aa.d + regs.x.w + 1); - op_ora_w(); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + aa.b = op_read(); + break; + case 4: + rd.l = op_read(OPMODE_LONG, aa.d + regs.x.w); + if(regs.p.m) { op_ora_b(); status.cycle_pos = 0; } + break; + case 5: + rd.h = op_read(OPMODE_LONG, aa.d + regs.x.w + 1); + op_ora_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_sbc_longx() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - aa.b = op_read(); -l4: - rd.l = op_read(OPMODE_LONG, aa.d + regs.x.w); - if(regs.p.m) { op_sbc_b(); return; } -l5: - rd.h = op_read(OPMODE_LONG, aa.d + regs.x.w + 1); - op_sbc_w(); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + aa.b = op_read(); + break; + case 4: + rd.l = op_read(OPMODE_LONG, aa.d + regs.x.w); + if(regs.p.m) { op_sbc_b(); status.cycle_pos = 0; } + break; + case 5: + rd.h = op_read(OPMODE_LONG, aa.d + regs.x.w + 1); + op_sbc_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_adc_dp() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - rd.l = op_read(OPMODE_DP, dp); - if(regs.p.m) { op_adc_b(); return; } -l4: - rd.h = op_read(OPMODE_DP, dp + 1); - op_adc_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + rd.l = op_read(OPMODE_DP, dp); + if(regs.p.m) { op_adc_b(); status.cycle_pos = 0; } + break; + case 4: + rd.h = op_read(OPMODE_DP, dp + 1); + op_adc_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_and_dp() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - rd.l = op_read(OPMODE_DP, dp); - if(regs.p.m) { op_and_b(); return; } -l4: - rd.h = op_read(OPMODE_DP, dp + 1); - op_and_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + rd.l = op_read(OPMODE_DP, dp); + if(regs.p.m) { op_and_b(); status.cycle_pos = 0; } + break; + case 4: + rd.h = op_read(OPMODE_DP, dp + 1); + op_and_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_bit_dp() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - rd.l = op_read(OPMODE_DP, dp); - if(regs.p.m) { op_bit_b(); return; } -l4: - rd.h = op_read(OPMODE_DP, dp + 1); - op_bit_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + rd.l = op_read(OPMODE_DP, dp); + if(regs.p.m) { op_bit_b(); status.cycle_pos = 0; } + break; + case 4: + rd.h = op_read(OPMODE_DP, dp + 1); + op_bit_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_cmp_dp() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - rd.l = op_read(OPMODE_DP, dp); - if(regs.p.m) { op_cmp_b(); return; } -l4: - rd.h = op_read(OPMODE_DP, dp + 1); - op_cmp_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + rd.l = op_read(OPMODE_DP, dp); + if(regs.p.m) { op_cmp_b(); status.cycle_pos = 0; } + break; + case 4: + rd.h = op_read(OPMODE_DP, dp + 1); + op_cmp_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_cpx_dp() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - rd.l = op_read(OPMODE_DP, dp); - if(regs.p.x) { op_cpx_b(); return; } -l4: - rd.h = op_read(OPMODE_DP, dp + 1); - op_cpx_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + rd.l = op_read(OPMODE_DP, dp); + if(regs.p.x) { op_cpx_b(); status.cycle_pos = 0; } + break; + case 4: + rd.h = op_read(OPMODE_DP, dp + 1); + op_cpx_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_cpy_dp() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - rd.l = op_read(OPMODE_DP, dp); - if(regs.p.x) { op_cpy_b(); return; } -l4: - rd.h = op_read(OPMODE_DP, dp + 1); - op_cpy_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + rd.l = op_read(OPMODE_DP, dp); + if(regs.p.x) { op_cpy_b(); status.cycle_pos = 0; } + break; + case 4: + rd.h = op_read(OPMODE_DP, dp + 1); + op_cpy_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_eor_dp() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - rd.l = op_read(OPMODE_DP, dp); - if(regs.p.m) { op_eor_b(); return; } -l4: - rd.h = op_read(OPMODE_DP, dp + 1); - op_eor_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + rd.l = op_read(OPMODE_DP, dp); + if(regs.p.m) { op_eor_b(); status.cycle_pos = 0; } + break; + case 4: + rd.h = op_read(OPMODE_DP, dp + 1); + op_eor_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_lda_dp() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - rd.l = op_read(OPMODE_DP, dp); - if(regs.p.m) { op_lda_b(); return; } -l4: - rd.h = op_read(OPMODE_DP, dp + 1); - op_lda_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + rd.l = op_read(OPMODE_DP, dp); + if(regs.p.m) { op_lda_b(); status.cycle_pos = 0; } + break; + case 4: + rd.h = op_read(OPMODE_DP, dp + 1); + op_lda_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_ldx_dp() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - rd.l = op_read(OPMODE_DP, dp); - if(regs.p.x) { op_ldx_b(); return; } -l4: - rd.h = op_read(OPMODE_DP, dp + 1); - op_ldx_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + rd.l = op_read(OPMODE_DP, dp); + if(regs.p.x) { op_ldx_b(); status.cycle_pos = 0; } + break; + case 4: + rd.h = op_read(OPMODE_DP, dp + 1); + op_ldx_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_ldy_dp() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - rd.l = op_read(OPMODE_DP, dp); - if(regs.p.x) { op_ldy_b(); return; } -l4: - rd.h = op_read(OPMODE_DP, dp + 1); - op_ldy_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + rd.l = op_read(OPMODE_DP, dp); + if(regs.p.x) { op_ldy_b(); status.cycle_pos = 0; } + break; + case 4: + rd.h = op_read(OPMODE_DP, dp + 1); + op_ldy_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_ora_dp() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - rd.l = op_read(OPMODE_DP, dp); - if(regs.p.m) { op_ora_b(); return; } -l4: - rd.h = op_read(OPMODE_DP, dp + 1); - op_ora_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + rd.l = op_read(OPMODE_DP, dp); + if(regs.p.m) { op_ora_b(); status.cycle_pos = 0; } + break; + case 4: + rd.h = op_read(OPMODE_DP, dp + 1); + op_ora_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_sbc_dp() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - rd.l = op_read(OPMODE_DP, dp); - if(regs.p.m) { op_sbc_b(); return; } -l4: - rd.h = op_read(OPMODE_DP, dp + 1); - op_sbc_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + rd.l = op_read(OPMODE_DP, dp); + if(regs.p.m) { op_sbc_b(); status.cycle_pos = 0; } + break; + case 4: + rd.h = op_read(OPMODE_DP, dp + 1); + op_sbc_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_adc_dpx() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - cpu_io(); -l4: - rd.l = op_read(OPMODE_DP, dp + regs.x.w); - if(regs.p.m) { op_adc_b(); return; } -l5: - rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); - op_adc_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + cpu_io(); + break; + case 4: + rd.l = op_read(OPMODE_DP, dp + regs.x.w); + if(regs.p.m) { op_adc_b(); status.cycle_pos = 0; } + break; + case 5: + rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); + op_adc_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_and_dpx() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - cpu_io(); -l4: - rd.l = op_read(OPMODE_DP, dp + regs.x.w); - if(regs.p.m) { op_and_b(); return; } -l5: - rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); - op_and_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + cpu_io(); + break; + case 4: + rd.l = op_read(OPMODE_DP, dp + regs.x.w); + if(regs.p.m) { op_and_b(); status.cycle_pos = 0; } + break; + case 5: + rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); + op_and_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_bit_dpx() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - cpu_io(); -l4: - rd.l = op_read(OPMODE_DP, dp + regs.x.w); - if(regs.p.m) { op_bit_b(); return; } -l5: - rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); - op_bit_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + cpu_io(); + break; + case 4: + rd.l = op_read(OPMODE_DP, dp + regs.x.w); + if(regs.p.m) { op_bit_b(); status.cycle_pos = 0; } + break; + case 5: + rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); + op_bit_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_cmp_dpx() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - cpu_io(); -l4: - rd.l = op_read(OPMODE_DP, dp + regs.x.w); - if(regs.p.m) { op_cmp_b(); return; } -l5: - rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); - op_cmp_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + cpu_io(); + break; + case 4: + rd.l = op_read(OPMODE_DP, dp + regs.x.w); + if(regs.p.m) { op_cmp_b(); status.cycle_pos = 0; } + break; + case 5: + rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); + op_cmp_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_eor_dpx() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - cpu_io(); -l4: - rd.l = op_read(OPMODE_DP, dp + regs.x.w); - if(regs.p.m) { op_eor_b(); return; } -l5: - rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); - op_eor_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + cpu_io(); + break; + case 4: + rd.l = op_read(OPMODE_DP, dp + regs.x.w); + if(regs.p.m) { op_eor_b(); status.cycle_pos = 0; } + break; + case 5: + rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); + op_eor_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_lda_dpx() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - cpu_io(); -l4: - rd.l = op_read(OPMODE_DP, dp + regs.x.w); - if(regs.p.m) { op_lda_b(); return; } -l5: - rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); - op_lda_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + cpu_io(); + break; + case 4: + rd.l = op_read(OPMODE_DP, dp + regs.x.w); + if(regs.p.m) { op_lda_b(); status.cycle_pos = 0; } + break; + case 5: + rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); + op_lda_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_ldy_dpx() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - cpu_io(); -l4: - rd.l = op_read(OPMODE_DP, dp + regs.x.w); - if(regs.p.x) { op_ldy_b(); return; } -l5: - rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); - op_ldy_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + cpu_io(); + break; + case 4: + rd.l = op_read(OPMODE_DP, dp + regs.x.w); + if(regs.p.x) { op_ldy_b(); status.cycle_pos = 0; } + break; + case 5: + rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); + op_ldy_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_ora_dpx() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - cpu_io(); -l4: - rd.l = op_read(OPMODE_DP, dp + regs.x.w); - if(regs.p.m) { op_ora_b(); return; } -l5: - rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); - op_ora_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + cpu_io(); + break; + case 4: + rd.l = op_read(OPMODE_DP, dp + regs.x.w); + if(regs.p.m) { op_ora_b(); status.cycle_pos = 0; } + break; + case 5: + rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); + op_ora_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_sbc_dpx() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - cpu_io(); -l4: - rd.l = op_read(OPMODE_DP, dp + regs.x.w); - if(regs.p.m) { op_sbc_b(); return; } -l5: - rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); - op_sbc_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + cpu_io(); + break; + case 4: + rd.l = op_read(OPMODE_DP, dp + regs.x.w); + if(regs.p.m) { op_sbc_b(); status.cycle_pos = 0; } + break; + case 5: + rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); + op_sbc_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_ldx_dpy() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - cpu_io(); -l4: - rd.l = op_read(OPMODE_DP, dp + regs.y.w); - if(regs.p.x) { op_ldx_b(); return; } -l5: - rd.h = op_read(OPMODE_DP, dp + regs.y.w + 1); - op_ldx_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + cpu_io(); + break; + case 4: + rd.l = op_read(OPMODE_DP, dp + regs.y.w); + if(regs.p.x) { op_ldx_b(); status.cycle_pos = 0; } + break; + case 5: + rd.h = op_read(OPMODE_DP, dp + regs.y.w + 1); + op_ldx_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_adc_idp() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - aa.l = op_read(OPMODE_DP, dp); -l4: - aa.h = op_read(OPMODE_DP, dp + 1); -l5: - rd.l = op_read(OPMODE_DBR, aa.w); - if(regs.p.m) { op_adc_b(); return; } -l6: - rd.h = op_read(OPMODE_DBR, aa.w + 1); - op_adc_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + aa.l = op_read(OPMODE_DP, dp); + break; + case 4: + aa.h = op_read(OPMODE_DP, dp + 1); + break; + case 5: + rd.l = op_read(OPMODE_DBR, aa.w); + if(regs.p.m) { op_adc_b(); status.cycle_pos = 0; } + break; + case 6: + rd.h = op_read(OPMODE_DBR, aa.w + 1); + op_adc_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_and_idp() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - aa.l = op_read(OPMODE_DP, dp); -l4: - aa.h = op_read(OPMODE_DP, dp + 1); -l5: - rd.l = op_read(OPMODE_DBR, aa.w); - if(regs.p.m) { op_and_b(); return; } -l6: - rd.h = op_read(OPMODE_DBR, aa.w + 1); - op_and_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + aa.l = op_read(OPMODE_DP, dp); + break; + case 4: + aa.h = op_read(OPMODE_DP, dp + 1); + break; + case 5: + rd.l = op_read(OPMODE_DBR, aa.w); + if(regs.p.m) { op_and_b(); status.cycle_pos = 0; } + break; + case 6: + rd.h = op_read(OPMODE_DBR, aa.w + 1); + op_and_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_cmp_idp() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - aa.l = op_read(OPMODE_DP, dp); -l4: - aa.h = op_read(OPMODE_DP, dp + 1); -l5: - rd.l = op_read(OPMODE_DBR, aa.w); - if(regs.p.m) { op_cmp_b(); return; } -l6: - rd.h = op_read(OPMODE_DBR, aa.w + 1); - op_cmp_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + aa.l = op_read(OPMODE_DP, dp); + break; + case 4: + aa.h = op_read(OPMODE_DP, dp + 1); + break; + case 5: + rd.l = op_read(OPMODE_DBR, aa.w); + if(regs.p.m) { op_cmp_b(); status.cycle_pos = 0; } + break; + case 6: + rd.h = op_read(OPMODE_DBR, aa.w + 1); + op_cmp_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_eor_idp() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - aa.l = op_read(OPMODE_DP, dp); -l4: - aa.h = op_read(OPMODE_DP, dp + 1); -l5: - rd.l = op_read(OPMODE_DBR, aa.w); - if(regs.p.m) { op_eor_b(); return; } -l6: - rd.h = op_read(OPMODE_DBR, aa.w + 1); - op_eor_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + aa.l = op_read(OPMODE_DP, dp); + break; + case 4: + aa.h = op_read(OPMODE_DP, dp + 1); + break; + case 5: + rd.l = op_read(OPMODE_DBR, aa.w); + if(regs.p.m) { op_eor_b(); status.cycle_pos = 0; } + break; + case 6: + rd.h = op_read(OPMODE_DBR, aa.w + 1); + op_eor_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_lda_idp() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - aa.l = op_read(OPMODE_DP, dp); -l4: - aa.h = op_read(OPMODE_DP, dp + 1); -l5: - rd.l = op_read(OPMODE_DBR, aa.w); - if(regs.p.m) { op_lda_b(); return; } -l6: - rd.h = op_read(OPMODE_DBR, aa.w + 1); - op_lda_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + aa.l = op_read(OPMODE_DP, dp); + break; + case 4: + aa.h = op_read(OPMODE_DP, dp + 1); + break; + case 5: + rd.l = op_read(OPMODE_DBR, aa.w); + if(regs.p.m) { op_lda_b(); status.cycle_pos = 0; } + break; + case 6: + rd.h = op_read(OPMODE_DBR, aa.w + 1); + op_lda_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_ora_idp() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - aa.l = op_read(OPMODE_DP, dp); -l4: - aa.h = op_read(OPMODE_DP, dp + 1); -l5: - rd.l = op_read(OPMODE_DBR, aa.w); - if(regs.p.m) { op_ora_b(); return; } -l6: - rd.h = op_read(OPMODE_DBR, aa.w + 1); - op_ora_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + aa.l = op_read(OPMODE_DP, dp); + break; + case 4: + aa.h = op_read(OPMODE_DP, dp + 1); + break; + case 5: + rd.l = op_read(OPMODE_DBR, aa.w); + if(regs.p.m) { op_ora_b(); status.cycle_pos = 0; } + break; + case 6: + rd.h = op_read(OPMODE_DBR, aa.w + 1); + op_ora_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_sbc_idp() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - aa.l = op_read(OPMODE_DP, dp); -l4: - aa.h = op_read(OPMODE_DP, dp + 1); -l5: - rd.l = op_read(OPMODE_DBR, aa.w); - if(regs.p.m) { op_sbc_b(); return; } -l6: - rd.h = op_read(OPMODE_DBR, aa.w + 1); - op_sbc_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + aa.l = op_read(OPMODE_DP, dp); + break; + case 4: + aa.h = op_read(OPMODE_DP, dp + 1); + break; + case 5: + rd.l = op_read(OPMODE_DBR, aa.w); + if(regs.p.m) { op_sbc_b(); status.cycle_pos = 0; } + break; + case 6: + rd.h = op_read(OPMODE_DBR, aa.w + 1); + op_sbc_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_adc_idpx() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - cpu_io(); -l4: - aa.l = op_read(OPMODE_DP, dp + regs.x.w); -l5: - aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); -l6: - rd.l = op_read(OPMODE_DBR, aa.w); - if(regs.p.m) { op_adc_b(); return; } -l7: - rd.h = op_read(OPMODE_DBR, aa.w + 1); - op_adc_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + cpu_io(); + break; + case 4: + aa.l = op_read(OPMODE_DP, dp + regs.x.w); + break; + case 5: + aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); + break; + case 6: + rd.l = op_read(OPMODE_DBR, aa.w); + if(regs.p.m) { op_adc_b(); status.cycle_pos = 0; } + break; + case 7: + rd.h = op_read(OPMODE_DBR, aa.w + 1); + op_adc_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_and_idpx() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - cpu_io(); -l4: - aa.l = op_read(OPMODE_DP, dp + regs.x.w); -l5: - aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); -l6: - rd.l = op_read(OPMODE_DBR, aa.w); - if(regs.p.m) { op_and_b(); return; } -l7: - rd.h = op_read(OPMODE_DBR, aa.w + 1); - op_and_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + cpu_io(); + break; + case 4: + aa.l = op_read(OPMODE_DP, dp + regs.x.w); + break; + case 5: + aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); + break; + case 6: + rd.l = op_read(OPMODE_DBR, aa.w); + if(regs.p.m) { op_and_b(); status.cycle_pos = 0; } + break; + case 7: + rd.h = op_read(OPMODE_DBR, aa.w + 1); + op_and_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_cmp_idpx() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - cpu_io(); -l4: - aa.l = op_read(OPMODE_DP, dp + regs.x.w); -l5: - aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); -l6: - rd.l = op_read(OPMODE_DBR, aa.w); - if(regs.p.m) { op_cmp_b(); return; } -l7: - rd.h = op_read(OPMODE_DBR, aa.w + 1); - op_cmp_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + cpu_io(); + break; + case 4: + aa.l = op_read(OPMODE_DP, dp + regs.x.w); + break; + case 5: + aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); + break; + case 6: + rd.l = op_read(OPMODE_DBR, aa.w); + if(regs.p.m) { op_cmp_b(); status.cycle_pos = 0; } + break; + case 7: + rd.h = op_read(OPMODE_DBR, aa.w + 1); + op_cmp_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_eor_idpx() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - cpu_io(); -l4: - aa.l = op_read(OPMODE_DP, dp + regs.x.w); -l5: - aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); -l6: - rd.l = op_read(OPMODE_DBR, aa.w); - if(regs.p.m) { op_eor_b(); return; } -l7: - rd.h = op_read(OPMODE_DBR, aa.w + 1); - op_eor_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + cpu_io(); + break; + case 4: + aa.l = op_read(OPMODE_DP, dp + regs.x.w); + break; + case 5: + aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); + break; + case 6: + rd.l = op_read(OPMODE_DBR, aa.w); + if(regs.p.m) { op_eor_b(); status.cycle_pos = 0; } + break; + case 7: + rd.h = op_read(OPMODE_DBR, aa.w + 1); + op_eor_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_lda_idpx() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - cpu_io(); -l4: - aa.l = op_read(OPMODE_DP, dp + regs.x.w); -l5: - aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); -l6: - rd.l = op_read(OPMODE_DBR, aa.w); - if(regs.p.m) { op_lda_b(); return; } -l7: - rd.h = op_read(OPMODE_DBR, aa.w + 1); - op_lda_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + cpu_io(); + break; + case 4: + aa.l = op_read(OPMODE_DP, dp + regs.x.w); + break; + case 5: + aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); + break; + case 6: + rd.l = op_read(OPMODE_DBR, aa.w); + if(regs.p.m) { op_lda_b(); status.cycle_pos = 0; } + break; + case 7: + rd.h = op_read(OPMODE_DBR, aa.w + 1); + op_lda_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_ora_idpx() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - cpu_io(); -l4: - aa.l = op_read(OPMODE_DP, dp + regs.x.w); -l5: - aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); -l6: - rd.l = op_read(OPMODE_DBR, aa.w); - if(regs.p.m) { op_ora_b(); return; } -l7: - rd.h = op_read(OPMODE_DBR, aa.w + 1); - op_ora_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + cpu_io(); + break; + case 4: + aa.l = op_read(OPMODE_DP, dp + regs.x.w); + break; + case 5: + aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); + break; + case 6: + rd.l = op_read(OPMODE_DBR, aa.w); + if(regs.p.m) { op_ora_b(); status.cycle_pos = 0; } + break; + case 7: + rd.h = op_read(OPMODE_DBR, aa.w + 1); + op_ora_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_sbc_idpx() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - cpu_io(); -l4: - aa.l = op_read(OPMODE_DP, dp + regs.x.w); -l5: - aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); -l6: - rd.l = op_read(OPMODE_DBR, aa.w); - if(regs.p.m) { op_sbc_b(); return; } -l7: - rd.h = op_read(OPMODE_DBR, aa.w + 1); - op_sbc_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + cpu_io(); + break; + case 4: + aa.l = op_read(OPMODE_DP, dp + regs.x.w); + break; + case 5: + aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); + break; + case 6: + rd.l = op_read(OPMODE_DBR, aa.w); + if(regs.p.m) { op_sbc_b(); status.cycle_pos = 0; } + break; + case 7: + rd.h = op_read(OPMODE_DBR, aa.w + 1); + op_sbc_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_adc_idpy() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - aa.l = op_read(OPMODE_DP, dp); -l4: - aa.h = op_read(OPMODE_DP, dp + 1); -l5: - cpu_c4(aa.w, aa.w + regs.y.w); -l6: - rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); - if(regs.p.m) { op_adc_b(); return; } -l7: - rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); - op_adc_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + aa.l = op_read(OPMODE_DP, dp); + break; + case 4: + aa.h = op_read(OPMODE_DP, dp + 1); + break; + case 5: + cpu_c4(aa.w, aa.w + regs.y.w); + break; + case 6: + rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); + if(regs.p.m) { op_adc_b(); status.cycle_pos = 0; } + break; + case 7: + rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); + op_adc_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_and_idpy() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - aa.l = op_read(OPMODE_DP, dp); -l4: - aa.h = op_read(OPMODE_DP, dp + 1); -l5: - cpu_c4(aa.w, aa.w + regs.y.w); -l6: - rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); - if(regs.p.m) { op_and_b(); return; } -l7: - rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); - op_and_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + aa.l = op_read(OPMODE_DP, dp); + break; + case 4: + aa.h = op_read(OPMODE_DP, dp + 1); + break; + case 5: + cpu_c4(aa.w, aa.w + regs.y.w); + break; + case 6: + rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); + if(regs.p.m) { op_and_b(); status.cycle_pos = 0; } + break; + case 7: + rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); + op_and_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_cmp_idpy() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - aa.l = op_read(OPMODE_DP, dp); -l4: - aa.h = op_read(OPMODE_DP, dp + 1); -l5: - cpu_c4(aa.w, aa.w + regs.y.w); -l6: - rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); - if(regs.p.m) { op_cmp_b(); return; } -l7: - rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); - op_cmp_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + aa.l = op_read(OPMODE_DP, dp); + break; + case 4: + aa.h = op_read(OPMODE_DP, dp + 1); + break; + case 5: + cpu_c4(aa.w, aa.w + regs.y.w); + break; + case 6: + rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); + if(regs.p.m) { op_cmp_b(); status.cycle_pos = 0; } + break; + case 7: + rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); + op_cmp_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_eor_idpy() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - aa.l = op_read(OPMODE_DP, dp); -l4: - aa.h = op_read(OPMODE_DP, dp + 1); -l5: - cpu_c4(aa.w, aa.w + regs.y.w); -l6: - rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); - if(regs.p.m) { op_eor_b(); return; } -l7: - rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); - op_eor_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + aa.l = op_read(OPMODE_DP, dp); + break; + case 4: + aa.h = op_read(OPMODE_DP, dp + 1); + break; + case 5: + cpu_c4(aa.w, aa.w + regs.y.w); + break; + case 6: + rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); + if(regs.p.m) { op_eor_b(); status.cycle_pos = 0; } + break; + case 7: + rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); + op_eor_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_lda_idpy() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - aa.l = op_read(OPMODE_DP, dp); -l4: - aa.h = op_read(OPMODE_DP, dp + 1); -l5: - cpu_c4(aa.w, aa.w + regs.y.w); -l6: - rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); - if(regs.p.m) { op_lda_b(); return; } -l7: - rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); - op_lda_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + aa.l = op_read(OPMODE_DP, dp); + break; + case 4: + aa.h = op_read(OPMODE_DP, dp + 1); + break; + case 5: + cpu_c4(aa.w, aa.w + regs.y.w); + break; + case 6: + rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); + if(regs.p.m) { op_lda_b(); status.cycle_pos = 0; } + break; + case 7: + rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); + op_lda_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_ora_idpy() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - aa.l = op_read(OPMODE_DP, dp); -l4: - aa.h = op_read(OPMODE_DP, dp + 1); -l5: - cpu_c4(aa.w, aa.w + regs.y.w); -l6: - rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); - if(regs.p.m) { op_ora_b(); return; } -l7: - rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); - op_ora_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + aa.l = op_read(OPMODE_DP, dp); + break; + case 4: + aa.h = op_read(OPMODE_DP, dp + 1); + break; + case 5: + cpu_c4(aa.w, aa.w + regs.y.w); + break; + case 6: + rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); + if(regs.p.m) { op_ora_b(); status.cycle_pos = 0; } + break; + case 7: + rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); + op_ora_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_sbc_idpy() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - aa.l = op_read(OPMODE_DP, dp); -l4: - aa.h = op_read(OPMODE_DP, dp + 1); -l5: - cpu_c4(aa.w, aa.w + regs.y.w); -l6: - rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); - if(regs.p.m) { op_sbc_b(); return; } -l7: - rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); - op_sbc_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + aa.l = op_read(OPMODE_DP, dp); + break; + case 4: + aa.h = op_read(OPMODE_DP, dp + 1); + break; + case 5: + cpu_c4(aa.w, aa.w + regs.y.w); + break; + case 6: + rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); + if(regs.p.m) { op_sbc_b(); status.cycle_pos = 0; } + break; + case 7: + rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); + op_sbc_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_adc_ildp() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - aa.l = op_read(OPMODE_DP, dp); -l4: - aa.h = op_read(OPMODE_DP, dp + 1); -l5: - aa.b = op_read(OPMODE_DP, dp + 2); -l6: - rd.l = op_read(OPMODE_LONG, aa.d); - if(regs.p.m) { op_adc_b(); return; } -l7: - rd.h = op_read(OPMODE_LONG, aa.d + 1); - op_adc_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + aa.l = op_read(OPMODE_DP, dp); + break; + case 4: + aa.h = op_read(OPMODE_DP, dp + 1); + break; + case 5: + aa.b = op_read(OPMODE_DP, dp + 2); + break; + case 6: + rd.l = op_read(OPMODE_LONG, aa.d); + if(regs.p.m) { op_adc_b(); status.cycle_pos = 0; } + break; + case 7: + rd.h = op_read(OPMODE_LONG, aa.d + 1); + op_adc_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_and_ildp() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - aa.l = op_read(OPMODE_DP, dp); -l4: - aa.h = op_read(OPMODE_DP, dp + 1); -l5: - aa.b = op_read(OPMODE_DP, dp + 2); -l6: - rd.l = op_read(OPMODE_LONG, aa.d); - if(regs.p.m) { op_and_b(); return; } -l7: - rd.h = op_read(OPMODE_LONG, aa.d + 1); - op_and_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + aa.l = op_read(OPMODE_DP, dp); + break; + case 4: + aa.h = op_read(OPMODE_DP, dp + 1); + break; + case 5: + aa.b = op_read(OPMODE_DP, dp + 2); + break; + case 6: + rd.l = op_read(OPMODE_LONG, aa.d); + if(regs.p.m) { op_and_b(); status.cycle_pos = 0; } + break; + case 7: + rd.h = op_read(OPMODE_LONG, aa.d + 1); + op_and_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_cmp_ildp() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - aa.l = op_read(OPMODE_DP, dp); -l4: - aa.h = op_read(OPMODE_DP, dp + 1); -l5: - aa.b = op_read(OPMODE_DP, dp + 2); -l6: - rd.l = op_read(OPMODE_LONG, aa.d); - if(regs.p.m) { op_cmp_b(); return; } -l7: - rd.h = op_read(OPMODE_LONG, aa.d + 1); - op_cmp_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + aa.l = op_read(OPMODE_DP, dp); + break; + case 4: + aa.h = op_read(OPMODE_DP, dp + 1); + break; + case 5: + aa.b = op_read(OPMODE_DP, dp + 2); + break; + case 6: + rd.l = op_read(OPMODE_LONG, aa.d); + if(regs.p.m) { op_cmp_b(); status.cycle_pos = 0; } + break; + case 7: + rd.h = op_read(OPMODE_LONG, aa.d + 1); + op_cmp_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_eor_ildp() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - aa.l = op_read(OPMODE_DP, dp); -l4: - aa.h = op_read(OPMODE_DP, dp + 1); -l5: - aa.b = op_read(OPMODE_DP, dp + 2); -l6: - rd.l = op_read(OPMODE_LONG, aa.d); - if(regs.p.m) { op_eor_b(); return; } -l7: - rd.h = op_read(OPMODE_LONG, aa.d + 1); - op_eor_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + aa.l = op_read(OPMODE_DP, dp); + break; + case 4: + aa.h = op_read(OPMODE_DP, dp + 1); + break; + case 5: + aa.b = op_read(OPMODE_DP, dp + 2); + break; + case 6: + rd.l = op_read(OPMODE_LONG, aa.d); + if(regs.p.m) { op_eor_b(); status.cycle_pos = 0; } + break; + case 7: + rd.h = op_read(OPMODE_LONG, aa.d + 1); + op_eor_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_lda_ildp() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - aa.l = op_read(OPMODE_DP, dp); -l4: - aa.h = op_read(OPMODE_DP, dp + 1); -l5: - aa.b = op_read(OPMODE_DP, dp + 2); -l6: - rd.l = op_read(OPMODE_LONG, aa.d); - if(regs.p.m) { op_lda_b(); return; } -l7: - rd.h = op_read(OPMODE_LONG, aa.d + 1); - op_lda_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + aa.l = op_read(OPMODE_DP, dp); + break; + case 4: + aa.h = op_read(OPMODE_DP, dp + 1); + break; + case 5: + aa.b = op_read(OPMODE_DP, dp + 2); + break; + case 6: + rd.l = op_read(OPMODE_LONG, aa.d); + if(regs.p.m) { op_lda_b(); status.cycle_pos = 0; } + break; + case 7: + rd.h = op_read(OPMODE_LONG, aa.d + 1); + op_lda_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_ora_ildp() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - aa.l = op_read(OPMODE_DP, dp); -l4: - aa.h = op_read(OPMODE_DP, dp + 1); -l5: - aa.b = op_read(OPMODE_DP, dp + 2); -l6: - rd.l = op_read(OPMODE_LONG, aa.d); - if(regs.p.m) { op_ora_b(); return; } -l7: - rd.h = op_read(OPMODE_LONG, aa.d + 1); - op_ora_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + aa.l = op_read(OPMODE_DP, dp); + break; + case 4: + aa.h = op_read(OPMODE_DP, dp + 1); + break; + case 5: + aa.b = op_read(OPMODE_DP, dp + 2); + break; + case 6: + rd.l = op_read(OPMODE_LONG, aa.d); + if(regs.p.m) { op_ora_b(); status.cycle_pos = 0; } + break; + case 7: + rd.h = op_read(OPMODE_LONG, aa.d + 1); + op_ora_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_sbc_ildp() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - aa.l = op_read(OPMODE_DP, dp); -l4: - aa.h = op_read(OPMODE_DP, dp + 1); -l5: - aa.b = op_read(OPMODE_DP, dp + 2); -l6: - rd.l = op_read(OPMODE_LONG, aa.d); - if(regs.p.m) { op_sbc_b(); return; } -l7: - rd.h = op_read(OPMODE_LONG, aa.d + 1); - op_sbc_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + aa.l = op_read(OPMODE_DP, dp); + break; + case 4: + aa.h = op_read(OPMODE_DP, dp + 1); + break; + case 5: + aa.b = op_read(OPMODE_DP, dp + 2); + break; + case 6: + rd.l = op_read(OPMODE_LONG, aa.d); + if(regs.p.m) { op_sbc_b(); status.cycle_pos = 0; } + break; + case 7: + rd.h = op_read(OPMODE_LONG, aa.d + 1); + op_sbc_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_adc_ildpy() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - aa.l = op_read(OPMODE_DP, dp); -l4: - aa.h = op_read(OPMODE_DP, dp + 1); -l5: - aa.b = op_read(OPMODE_DP, dp + 2); -l6: - rd.l = op_read(OPMODE_LONG, aa.d + regs.y.w); - if(regs.p.m) { op_adc_b(); return; } -l7: - rd.h = op_read(OPMODE_LONG, aa.d + regs.y.w + 1); - op_adc_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + aa.l = op_read(OPMODE_DP, dp); + break; + case 4: + aa.h = op_read(OPMODE_DP, dp + 1); + break; + case 5: + aa.b = op_read(OPMODE_DP, dp + 2); + break; + case 6: + rd.l = op_read(OPMODE_LONG, aa.d + regs.y.w); + if(regs.p.m) { op_adc_b(); status.cycle_pos = 0; } + break; + case 7: + rd.h = op_read(OPMODE_LONG, aa.d + regs.y.w + 1); + op_adc_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_and_ildpy() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - aa.l = op_read(OPMODE_DP, dp); -l4: - aa.h = op_read(OPMODE_DP, dp + 1); -l5: - aa.b = op_read(OPMODE_DP, dp + 2); -l6: - rd.l = op_read(OPMODE_LONG, aa.d + regs.y.w); - if(regs.p.m) { op_and_b(); return; } -l7: - rd.h = op_read(OPMODE_LONG, aa.d + regs.y.w + 1); - op_and_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + aa.l = op_read(OPMODE_DP, dp); + break; + case 4: + aa.h = op_read(OPMODE_DP, dp + 1); + break; + case 5: + aa.b = op_read(OPMODE_DP, dp + 2); + break; + case 6: + rd.l = op_read(OPMODE_LONG, aa.d + regs.y.w); + if(regs.p.m) { op_and_b(); status.cycle_pos = 0; } + break; + case 7: + rd.h = op_read(OPMODE_LONG, aa.d + regs.y.w + 1); + op_and_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_cmp_ildpy() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - aa.l = op_read(OPMODE_DP, dp); -l4: - aa.h = op_read(OPMODE_DP, dp + 1); -l5: - aa.b = op_read(OPMODE_DP, dp + 2); -l6: - rd.l = op_read(OPMODE_LONG, aa.d + regs.y.w); - if(regs.p.m) { op_cmp_b(); return; } -l7: - rd.h = op_read(OPMODE_LONG, aa.d + regs.y.w + 1); - op_cmp_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + aa.l = op_read(OPMODE_DP, dp); + break; + case 4: + aa.h = op_read(OPMODE_DP, dp + 1); + break; + case 5: + aa.b = op_read(OPMODE_DP, dp + 2); + break; + case 6: + rd.l = op_read(OPMODE_LONG, aa.d + regs.y.w); + if(regs.p.m) { op_cmp_b(); status.cycle_pos = 0; } + break; + case 7: + rd.h = op_read(OPMODE_LONG, aa.d + regs.y.w + 1); + op_cmp_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_eor_ildpy() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - aa.l = op_read(OPMODE_DP, dp); -l4: - aa.h = op_read(OPMODE_DP, dp + 1); -l5: - aa.b = op_read(OPMODE_DP, dp + 2); -l6: - rd.l = op_read(OPMODE_LONG, aa.d + regs.y.w); - if(regs.p.m) { op_eor_b(); return; } -l7: - rd.h = op_read(OPMODE_LONG, aa.d + regs.y.w + 1); - op_eor_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + aa.l = op_read(OPMODE_DP, dp); + break; + case 4: + aa.h = op_read(OPMODE_DP, dp + 1); + break; + case 5: + aa.b = op_read(OPMODE_DP, dp + 2); + break; + case 6: + rd.l = op_read(OPMODE_LONG, aa.d + regs.y.w); + if(regs.p.m) { op_eor_b(); status.cycle_pos = 0; } + break; + case 7: + rd.h = op_read(OPMODE_LONG, aa.d + regs.y.w + 1); + op_eor_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_lda_ildpy() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - aa.l = op_read(OPMODE_DP, dp); -l4: - aa.h = op_read(OPMODE_DP, dp + 1); -l5: - aa.b = op_read(OPMODE_DP, dp + 2); -l6: - rd.l = op_read(OPMODE_LONG, aa.d + regs.y.w); - if(regs.p.m) { op_lda_b(); return; } -l7: - rd.h = op_read(OPMODE_LONG, aa.d + regs.y.w + 1); - op_lda_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + aa.l = op_read(OPMODE_DP, dp); + break; + case 4: + aa.h = op_read(OPMODE_DP, dp + 1); + break; + case 5: + aa.b = op_read(OPMODE_DP, dp + 2); + break; + case 6: + rd.l = op_read(OPMODE_LONG, aa.d + regs.y.w); + if(regs.p.m) { op_lda_b(); status.cycle_pos = 0; } + break; + case 7: + rd.h = op_read(OPMODE_LONG, aa.d + regs.y.w + 1); + op_lda_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_ora_ildpy() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - aa.l = op_read(OPMODE_DP, dp); -l4: - aa.h = op_read(OPMODE_DP, dp + 1); -l5: - aa.b = op_read(OPMODE_DP, dp + 2); -l6: - rd.l = op_read(OPMODE_LONG, aa.d + regs.y.w); - if(regs.p.m) { op_ora_b(); return; } -l7: - rd.h = op_read(OPMODE_LONG, aa.d + regs.y.w + 1); - op_ora_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + aa.l = op_read(OPMODE_DP, dp); + break; + case 4: + aa.h = op_read(OPMODE_DP, dp + 1); + break; + case 5: + aa.b = op_read(OPMODE_DP, dp + 2); + break; + case 6: + rd.l = op_read(OPMODE_LONG, aa.d + regs.y.w); + if(regs.p.m) { op_ora_b(); status.cycle_pos = 0; } + break; + case 7: + rd.h = op_read(OPMODE_LONG, aa.d + regs.y.w + 1); + op_ora_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_sbc_ildpy() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - aa.l = op_read(OPMODE_DP, dp); -l4: - aa.h = op_read(OPMODE_DP, dp + 1); -l5: - aa.b = op_read(OPMODE_DP, dp + 2); -l6: - rd.l = op_read(OPMODE_LONG, aa.d + regs.y.w); - if(regs.p.m) { op_sbc_b(); return; } -l7: - rd.h = op_read(OPMODE_LONG, aa.d + regs.y.w + 1); - op_sbc_w(); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + aa.l = op_read(OPMODE_DP, dp); + break; + case 4: + aa.h = op_read(OPMODE_DP, dp + 1); + break; + case 5: + aa.b = op_read(OPMODE_DP, dp + 2); + break; + case 6: + rd.l = op_read(OPMODE_LONG, aa.d + regs.y.w); + if(regs.p.m) { op_sbc_b(); status.cycle_pos = 0; } + break; + case 7: + rd.h = op_read(OPMODE_LONG, aa.d + regs.y.w + 1); + op_sbc_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_adc_sr() { -l1: - sp = op_read(); -l2: - cpu_io(); -l3: - rd.l = op_read(OPMODE_SP, sp); - if(regs.p.m) { op_adc_b(); return; } -l4: - rd.h = op_read(OPMODE_SP, sp + 1); - op_adc_w(); + switch(status.cycle_pos++) { + case 1: + sp = op_read(); + break; + case 2: + cpu_io(); + break; + case 3: + rd.l = op_read(OPMODE_SP, sp); + if(regs.p.m) { op_adc_b(); status.cycle_pos = 0; } + break; + case 4: + rd.h = op_read(OPMODE_SP, sp + 1); + op_adc_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_and_sr() { -l1: - sp = op_read(); -l2: - cpu_io(); -l3: - rd.l = op_read(OPMODE_SP, sp); - if(regs.p.m) { op_and_b(); return; } -l4: - rd.h = op_read(OPMODE_SP, sp + 1); - op_and_w(); + switch(status.cycle_pos++) { + case 1: + sp = op_read(); + break; + case 2: + cpu_io(); + break; + case 3: + rd.l = op_read(OPMODE_SP, sp); + if(regs.p.m) { op_and_b(); status.cycle_pos = 0; } + break; + case 4: + rd.h = op_read(OPMODE_SP, sp + 1); + op_and_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_cmp_sr() { -l1: - sp = op_read(); -l2: - cpu_io(); -l3: - rd.l = op_read(OPMODE_SP, sp); - if(regs.p.m) { op_cmp_b(); return; } -l4: - rd.h = op_read(OPMODE_SP, sp + 1); - op_cmp_w(); + switch(status.cycle_pos++) { + case 1: + sp = op_read(); + break; + case 2: + cpu_io(); + break; + case 3: + rd.l = op_read(OPMODE_SP, sp); + if(regs.p.m) { op_cmp_b(); status.cycle_pos = 0; } + break; + case 4: + rd.h = op_read(OPMODE_SP, sp + 1); + op_cmp_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_eor_sr() { -l1: - sp = op_read(); -l2: - cpu_io(); -l3: - rd.l = op_read(OPMODE_SP, sp); - if(regs.p.m) { op_eor_b(); return; } -l4: - rd.h = op_read(OPMODE_SP, sp + 1); - op_eor_w(); + switch(status.cycle_pos++) { + case 1: + sp = op_read(); + break; + case 2: + cpu_io(); + break; + case 3: + rd.l = op_read(OPMODE_SP, sp); + if(regs.p.m) { op_eor_b(); status.cycle_pos = 0; } + break; + case 4: + rd.h = op_read(OPMODE_SP, sp + 1); + op_eor_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_lda_sr() { -l1: - sp = op_read(); -l2: - cpu_io(); -l3: - rd.l = op_read(OPMODE_SP, sp); - if(regs.p.m) { op_lda_b(); return; } -l4: - rd.h = op_read(OPMODE_SP, sp + 1); - op_lda_w(); + switch(status.cycle_pos++) { + case 1: + sp = op_read(); + break; + case 2: + cpu_io(); + break; + case 3: + rd.l = op_read(OPMODE_SP, sp); + if(regs.p.m) { op_lda_b(); status.cycle_pos = 0; } + break; + case 4: + rd.h = op_read(OPMODE_SP, sp + 1); + op_lda_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_ora_sr() { -l1: - sp = op_read(); -l2: - cpu_io(); -l3: - rd.l = op_read(OPMODE_SP, sp); - if(regs.p.m) { op_ora_b(); return; } -l4: - rd.h = op_read(OPMODE_SP, sp + 1); - op_ora_w(); + switch(status.cycle_pos++) { + case 1: + sp = op_read(); + break; + case 2: + cpu_io(); + break; + case 3: + rd.l = op_read(OPMODE_SP, sp); + if(regs.p.m) { op_ora_b(); status.cycle_pos = 0; } + break; + case 4: + rd.h = op_read(OPMODE_SP, sp + 1); + op_ora_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_sbc_sr() { -l1: - sp = op_read(); -l2: - cpu_io(); -l3: - rd.l = op_read(OPMODE_SP, sp); - if(regs.p.m) { op_sbc_b(); return; } -l4: - rd.h = op_read(OPMODE_SP, sp + 1); - op_sbc_w(); + switch(status.cycle_pos++) { + case 1: + sp = op_read(); + break; + case 2: + cpu_io(); + break; + case 3: + rd.l = op_read(OPMODE_SP, sp); + if(regs.p.m) { op_sbc_b(); status.cycle_pos = 0; } + break; + case 4: + rd.h = op_read(OPMODE_SP, sp + 1); + op_sbc_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_adc_isry() { -l1: - sp = op_read(); -l2: - cpu_io(); -l3: - aa.l = op_read(OPMODE_SP, sp); -l4: - aa.h = op_read(OPMODE_SP, sp + 1); -l5: - cpu_io(); -l6: - rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); - if(regs.p.m) { op_adc_b(); return; } -l7: - rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); - op_adc_w(); + switch(status.cycle_pos++) { + case 1: + sp = op_read(); + break; + case 2: + cpu_io(); + break; + case 3: + aa.l = op_read(OPMODE_SP, sp); + break; + case 4: + aa.h = op_read(OPMODE_SP, sp + 1); + break; + case 5: + cpu_io(); + break; + case 6: + rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); + if(regs.p.m) { op_adc_b(); status.cycle_pos = 0; } + break; + case 7: + rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); + op_adc_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_and_isry() { -l1: - sp = op_read(); -l2: - cpu_io(); -l3: - aa.l = op_read(OPMODE_SP, sp); -l4: - aa.h = op_read(OPMODE_SP, sp + 1); -l5: - cpu_io(); -l6: - rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); - if(regs.p.m) { op_and_b(); return; } -l7: - rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); - op_and_w(); + switch(status.cycle_pos++) { + case 1: + sp = op_read(); + break; + case 2: + cpu_io(); + break; + case 3: + aa.l = op_read(OPMODE_SP, sp); + break; + case 4: + aa.h = op_read(OPMODE_SP, sp + 1); + break; + case 5: + cpu_io(); + break; + case 6: + rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); + if(regs.p.m) { op_and_b(); status.cycle_pos = 0; } + break; + case 7: + rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); + op_and_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_cmp_isry() { -l1: - sp = op_read(); -l2: - cpu_io(); -l3: - aa.l = op_read(OPMODE_SP, sp); -l4: - aa.h = op_read(OPMODE_SP, sp + 1); -l5: - cpu_io(); -l6: - rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); - if(regs.p.m) { op_cmp_b(); return; } -l7: - rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); - op_cmp_w(); + switch(status.cycle_pos++) { + case 1: + sp = op_read(); + break; + case 2: + cpu_io(); + break; + case 3: + aa.l = op_read(OPMODE_SP, sp); + break; + case 4: + aa.h = op_read(OPMODE_SP, sp + 1); + break; + case 5: + cpu_io(); + break; + case 6: + rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); + if(regs.p.m) { op_cmp_b(); status.cycle_pos = 0; } + break; + case 7: + rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); + op_cmp_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_eor_isry() { -l1: - sp = op_read(); -l2: - cpu_io(); -l3: - aa.l = op_read(OPMODE_SP, sp); -l4: - aa.h = op_read(OPMODE_SP, sp + 1); -l5: - cpu_io(); -l6: - rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); - if(regs.p.m) { op_eor_b(); return; } -l7: - rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); - op_eor_w(); + switch(status.cycle_pos++) { + case 1: + sp = op_read(); + break; + case 2: + cpu_io(); + break; + case 3: + aa.l = op_read(OPMODE_SP, sp); + break; + case 4: + aa.h = op_read(OPMODE_SP, sp + 1); + break; + case 5: + cpu_io(); + break; + case 6: + rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); + if(regs.p.m) { op_eor_b(); status.cycle_pos = 0; } + break; + case 7: + rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); + op_eor_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_lda_isry() { -l1: - sp = op_read(); -l2: - cpu_io(); -l3: - aa.l = op_read(OPMODE_SP, sp); -l4: - aa.h = op_read(OPMODE_SP, sp + 1); -l5: - cpu_io(); -l6: - rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); - if(regs.p.m) { op_lda_b(); return; } -l7: - rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); - op_lda_w(); + switch(status.cycle_pos++) { + case 1: + sp = op_read(); + break; + case 2: + cpu_io(); + break; + case 3: + aa.l = op_read(OPMODE_SP, sp); + break; + case 4: + aa.h = op_read(OPMODE_SP, sp + 1); + break; + case 5: + cpu_io(); + break; + case 6: + rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); + if(regs.p.m) { op_lda_b(); status.cycle_pos = 0; } + break; + case 7: + rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); + op_lda_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_ora_isry() { -l1: - sp = op_read(); -l2: - cpu_io(); -l3: - aa.l = op_read(OPMODE_SP, sp); -l4: - aa.h = op_read(OPMODE_SP, sp + 1); -l5: - cpu_io(); -l6: - rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); - if(regs.p.m) { op_ora_b(); return; } -l7: - rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); - op_ora_w(); + switch(status.cycle_pos++) { + case 1: + sp = op_read(); + break; + case 2: + cpu_io(); + break; + case 3: + aa.l = op_read(OPMODE_SP, sp); + break; + case 4: + aa.h = op_read(OPMODE_SP, sp + 1); + break; + case 5: + cpu_io(); + break; + case 6: + rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); + if(regs.p.m) { op_ora_b(); status.cycle_pos = 0; } + break; + case 7: + rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); + op_ora_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_sbc_isry() { -l1: - sp = op_read(); -l2: - cpu_io(); -l3: - aa.l = op_read(OPMODE_SP, sp); -l4: - aa.h = op_read(OPMODE_SP, sp + 1); -l5: - cpu_io(); -l6: - rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); - if(regs.p.m) { op_sbc_b(); return; } -l7: - rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); - op_sbc_w(); + switch(status.cycle_pos++) { + case 1: + sp = op_read(); + break; + case 2: + cpu_io(); + break; + case 3: + aa.l = op_read(OPMODE_SP, sp); + break; + case 4: + aa.h = op_read(OPMODE_SP, sp + 1); + break; + case 5: + cpu_io(); + break; + case 6: + rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); + if(regs.p.m) { op_sbc_b(); status.cycle_pos = 0; } + break; + case 7: + rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); + op_sbc_w(); + status.cycle_pos = 0; + break; + } } void bCPU::op_bit_const() { -l1: - rd.l = op_read(); - if(regs.p.m) { - regs.p.z = ((rd.l & regs.a.l) == 0); - return; + switch(status.cycle_pos++) { + case 1: + rd.l = op_read(); + if(regs.p.m) { + regs.p.z = ((rd.l & regs.a.l) == 0); + status.cycle_pos = 0; + } + break; + case 2: + rd.h = op_read(); + regs.p.z = ((rd.w & regs.a.w) == 0); + status.cycle_pos = 0; + break; } -l2: - rd.h = op_read(); - regs.p.z = ((rd.w & regs.a.w) == 0); } diff --git a/src/cpu/bcpu/bcpu_op_rmw.cpp b/src/cpu/bcpu/bcpu_op_rmw.cpp index 6c4af89a..8d716c91 100644 --- a/src/cpu/bcpu/bcpu_op_rmw.cpp +++ b/src/cpu/bcpu/bcpu_op_rmw.cpp @@ -1,740 +1,1072 @@ void bCPU::op_inc() { -l1: - cpu_io(); - if(regs.p.m) { - regs.a.l++; - regs.p.n = !!(regs.a.l & 0x80); - regs.p.z = (regs.a.l == 0); - } else { - regs.a.w++; - regs.p.n = !!(regs.a.w & 0x8000); - regs.p.z = (regs.a.w == 0); + switch(status.cycle_pos++) { + case 1: + cpu_io(); + if(regs.p.m) { + regs.a.l++; + regs.p.n = !!(regs.a.l & 0x80); + regs.p.z = (regs.a.l == 0); + } else { + regs.a.w++; + regs.p.n = !!(regs.a.w & 0x8000); + regs.p.z = (regs.a.w == 0); + } + status.cycle_pos = 0; + break; } } void bCPU::op_inx() { -l1: - cpu_io(); - if(regs.p.x) { - regs.x.l++; - regs.p.n = !!(regs.x.l & 0x80); - regs.p.z = (regs.x.l == 0); - } else { - regs.x.w++; - regs.p.n = !!(regs.x.w & 0x8000); - regs.p.z = (regs.x.w == 0); + switch(status.cycle_pos++) { + case 1: + cpu_io(); + if(regs.p.x) { + regs.x.l++; + regs.p.n = !!(regs.x.l & 0x80); + regs.p.z = (regs.x.l == 0); + } else { + regs.x.w++; + regs.p.n = !!(regs.x.w & 0x8000); + regs.p.z = (regs.x.w == 0); + } + status.cycle_pos = 0; + break; } } void bCPU::op_iny() { -l1: - cpu_io(); - if(regs.p.x) { - regs.y.l++; - regs.p.n = !!(regs.y.l & 0x80); - regs.p.z = (regs.y.l == 0); - } else { - regs.y.w++; - regs.p.n = !!(regs.y.w & 0x8000); - regs.p.z = (regs.y.w == 0); + switch(status.cycle_pos++) { + case 1: + cpu_io(); + if(regs.p.x) { + regs.y.l++; + regs.p.n = !!(regs.y.l & 0x80); + regs.p.z = (regs.y.l == 0); + } else { + regs.y.w++; + regs.p.n = !!(regs.y.w & 0x8000); + regs.p.z = (regs.y.w == 0); + } + status.cycle_pos = 0; + break; } } void bCPU::op_dec() { -l1: - cpu_io(); - if(regs.p.m) { - regs.a.l--; - regs.p.n = !!(regs.a.l & 0x80); - regs.p.z = (regs.a.l == 0); - } else { - regs.a.w--; - regs.p.n = !!(regs.a.w & 0x8000); - regs.p.z = (regs.a.w == 0); + switch(status.cycle_pos++) { + case 1: + cpu_io(); + if(regs.p.m) { + regs.a.l--; + regs.p.n = !!(regs.a.l & 0x80); + regs.p.z = (regs.a.l == 0); + } else { + regs.a.w--; + regs.p.n = !!(regs.a.w & 0x8000); + regs.p.z = (regs.a.w == 0); + } + status.cycle_pos = 0; + break; } } void bCPU::op_dex() { -l1: - cpu_io(); - if(regs.p.x) { - regs.x.l--; - regs.p.n = !!(regs.x.l & 0x80); - regs.p.z = (regs.x.l == 0); - } else { - regs.x.w--; - regs.p.n = !!(regs.x.w & 0x8000); - regs.p.z = (regs.x.w == 0); + switch(status.cycle_pos++) { + case 1: + cpu_io(); + if(regs.p.x) { + regs.x.l--; + regs.p.n = !!(regs.x.l & 0x80); + regs.p.z = (regs.x.l == 0); + } else { + regs.x.w--; + regs.p.n = !!(regs.x.w & 0x8000); + regs.p.z = (regs.x.w == 0); + } + status.cycle_pos = 0; + break; } } void bCPU::op_dey() { -l1: - cpu_io(); - if(regs.p.x) { - regs.y.l--; - regs.p.n = !!(regs.y.l & 0x80); - regs.p.z = (regs.y.l == 0); - } else { - regs.y.w--; - regs.p.n = !!(regs.y.w & 0x8000); - regs.p.z = (regs.y.w == 0); + switch(status.cycle_pos++) { + case 1: + cpu_io(); + if(regs.p.x) { + regs.y.l--; + regs.p.n = !!(regs.y.l & 0x80); + regs.p.z = (regs.y.l == 0); + } else { + regs.y.w--; + regs.p.n = !!(regs.y.w & 0x8000); + regs.p.z = (regs.y.w == 0); + } + status.cycle_pos = 0; + break; } } void bCPU::op_asl() { -l1: - cpu_io(); - if(regs.p.m) { - regs.p.c = !!(regs.a.l & 0x80); - regs.a.l <<= 1; - regs.p.n = !!(regs.a.l & 0x80); - regs.p.z = (regs.a.l == 0); - } else { - regs.p.c = !!(regs.a.w & 0x8000); - regs.a.w <<= 1; - regs.p.n = !!(regs.a.w & 0x8000); - regs.p.z = (regs.a.w == 0); + switch(status.cycle_pos++) { + case 1: + cpu_io(); + if(regs.p.m) { + regs.p.c = !!(regs.a.l & 0x80); + regs.a.l <<= 1; + regs.p.n = !!(regs.a.l & 0x80); + regs.p.z = (regs.a.l == 0); + } else { + regs.p.c = !!(regs.a.w & 0x8000); + regs.a.w <<= 1; + regs.p.n = !!(regs.a.w & 0x8000); + regs.p.z = (regs.a.w == 0); + } + status.cycle_pos = 0; + break; } } void bCPU::op_lsr() { -l1: - cpu_io(); - if(regs.p.m) { - regs.p.c = regs.a.l & 1; - regs.a.l >>= 1; - regs.p.n = !!(regs.a.l & 0x80); - regs.p.z = (regs.a.l == 0); - } else { - regs.p.c = regs.a.w & 1; - regs.a.w >>= 1; - regs.p.n = !!(regs.a.w & 0x8000); - regs.p.z = (regs.a.w == 0); + switch(status.cycle_pos++) { + case 1: + cpu_io(); + if(regs.p.m) { + regs.p.c = regs.a.l & 1; + regs.a.l >>= 1; + regs.p.n = !!(regs.a.l & 0x80); + regs.p.z = (regs.a.l == 0); + } else { + regs.p.c = regs.a.w & 1; + regs.a.w >>= 1; + regs.p.n = !!(regs.a.w & 0x8000); + regs.p.z = (regs.a.w == 0); + } + status.cycle_pos = 0; + break; } } void bCPU::op_rol() { -l1: - cpu_io(); - uint16 c = regs.p.c; - if(regs.p.m) { - regs.p.c = !!(regs.a.l & 0x80); - regs.a.l <<= 1; - regs.a.l |= c; - regs.p.n = !!(regs.a.l & 0x80); - regs.p.z = (regs.a.l == 0); - } else { - regs.p.c = !!(regs.a.w & 0x8000); - regs.a.w <<= 1; - regs.a.w |= c; - regs.p.n = !!(regs.a.w & 0x8000); - regs.p.z = (regs.a.w == 0); + switch(status.cycle_pos++) { + case 1: + cpu_io(); + uint16 c = regs.p.c; + if(regs.p.m) { + regs.p.c = !!(regs.a.l & 0x80); + regs.a.l <<= 1; + regs.a.l |= c; + regs.p.n = !!(regs.a.l & 0x80); + regs.p.z = (regs.a.l == 0); + } else { + regs.p.c = !!(regs.a.w & 0x8000); + regs.a.w <<= 1; + regs.a.w |= c; + regs.p.n = !!(regs.a.w & 0x8000); + regs.p.z = (regs.a.w == 0); + } + status.cycle_pos = 0; + break; } } void bCPU::op_ror() { -l1: - cpu_io(); - uint16 c; - if(regs.p.m) { - c = (regs.p.c)?0x80:0; - regs.p.c = regs.a.l & 1; - regs.a.l >>= 1; - regs.a.l |= c; - regs.p.n = !!(regs.a.l & 0x80); - regs.p.z = (regs.a.l == 0); - } else { - c = (regs.p.c)?0x8000:0; - regs.p.c = regs.a.w & 1; - regs.a.w >>= 1; - regs.a.w |= c; - regs.p.n = !!(regs.a.w & 0x8000); - regs.p.z = (regs.a.w == 0); + switch(status.cycle_pos++) { + case 1: + cpu_io(); + uint16 c; + if(regs.p.m) { + c = (regs.p.c)?0x80:0; + regs.p.c = regs.a.l & 1; + regs.a.l >>= 1; + regs.a.l |= c; + regs.p.n = !!(regs.a.l & 0x80); + regs.p.z = (regs.a.l == 0); + } else { + c = (regs.p.c)?0x8000:0; + regs.p.c = regs.a.w & 1; + regs.a.w >>= 1; + regs.a.w |= c; + regs.p.n = !!(regs.a.w & 0x8000); + regs.p.z = (regs.a.w == 0); + } + status.cycle_pos = 0; + break; } } void bCPU::op_inc_addr() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - rd.l = op_read(OPMODE_DBR, aa.w); - if(regs.p.m)goto l5; -l4: - rd.h = op_read(OPMODE_DBR, aa.w + 1); -l5: - cpu_io(); - if(regs.p.m) { op_inc_b(); goto l7; } - else op_inc_w(); -l6: - op_write(OPMODE_DBR, aa.w + 1, rd.h); -l7: - op_write(OPMODE_DBR, aa.w, rd.l); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + rd.l = op_read(OPMODE_DBR, aa.w); + if(regs.p.m)status.cycle_pos++; + break; + case 4: + rd.h = op_read(OPMODE_DBR, aa.w + 1); + break; + case 5: + cpu_io(); + if(regs.p.m) { op_inc_b(); status.cycle_pos++; } + else op_inc_w(); + break; + case 6: + op_write(OPMODE_DBR, aa.w + 1, rd.h); + break; + case 7: + op_write(OPMODE_DBR, aa.w, rd.l); + status.cycle_pos = 0; + break; + } } void bCPU::op_dec_addr() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - rd.l = op_read(OPMODE_DBR, aa.w); - if(regs.p.m)goto l5; -l4: - rd.h = op_read(OPMODE_DBR, aa.w + 1); -l5: - cpu_io(); - if(regs.p.m) { op_dec_b(); goto l7; } - else op_dec_w(); -l6: - op_write(OPMODE_DBR, aa.w + 1, rd.h); -l7: - op_write(OPMODE_DBR, aa.w, rd.l); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + rd.l = op_read(OPMODE_DBR, aa.w); + if(regs.p.m)status.cycle_pos++; + break; + case 4: + rd.h = op_read(OPMODE_DBR, aa.w + 1); + break; + case 5: + cpu_io(); + if(regs.p.m) { op_dec_b(); status.cycle_pos++; } + else op_dec_w(); + break; + case 6: + op_write(OPMODE_DBR, aa.w + 1, rd.h); + break; + case 7: + op_write(OPMODE_DBR, aa.w, rd.l); + status.cycle_pos = 0; + break; + } } void bCPU::op_asl_addr() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - rd.l = op_read(OPMODE_DBR, aa.w); - if(regs.p.m)goto l5; -l4: - rd.h = op_read(OPMODE_DBR, aa.w + 1); -l5: - cpu_io(); - if(regs.p.m) { op_asl_b(); goto l7; } - else op_asl_w(); -l6: - op_write(OPMODE_DBR, aa.w + 1, rd.h); -l7: - op_write(OPMODE_DBR, aa.w, rd.l); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + rd.l = op_read(OPMODE_DBR, aa.w); + if(regs.p.m)status.cycle_pos++; + break; + case 4: + rd.h = op_read(OPMODE_DBR, aa.w + 1); + break; + case 5: + cpu_io(); + if(regs.p.m) { op_asl_b(); status.cycle_pos++; } + else op_asl_w(); + break; + case 6: + op_write(OPMODE_DBR, aa.w + 1, rd.h); + break; + case 7: + op_write(OPMODE_DBR, aa.w, rd.l); + status.cycle_pos = 0; + break; + } } void bCPU::op_lsr_addr() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - rd.l = op_read(OPMODE_DBR, aa.w); - if(regs.p.m)goto l5; -l4: - rd.h = op_read(OPMODE_DBR, aa.w + 1); -l5: - cpu_io(); - if(regs.p.m) { op_lsr_b(); goto l7; } - else op_lsr_w(); -l6: - op_write(OPMODE_DBR, aa.w + 1, rd.h); -l7: - op_write(OPMODE_DBR, aa.w, rd.l); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + rd.l = op_read(OPMODE_DBR, aa.w); + if(regs.p.m)status.cycle_pos++; + break; + case 4: + rd.h = op_read(OPMODE_DBR, aa.w + 1); + break; + case 5: + cpu_io(); + if(regs.p.m) { op_lsr_b(); status.cycle_pos++; } + else op_lsr_w(); + break; + case 6: + op_write(OPMODE_DBR, aa.w + 1, rd.h); + break; + case 7: + op_write(OPMODE_DBR, aa.w, rd.l); + status.cycle_pos = 0; + break; + } } void bCPU::op_rol_addr() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - rd.l = op_read(OPMODE_DBR, aa.w); - if(regs.p.m)goto l5; -l4: - rd.h = op_read(OPMODE_DBR, aa.w + 1); -l5: - cpu_io(); - if(regs.p.m) { op_rol_b(); goto l7; } - else op_rol_w(); -l6: - op_write(OPMODE_DBR, aa.w + 1, rd.h); -l7: - op_write(OPMODE_DBR, aa.w, rd.l); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + rd.l = op_read(OPMODE_DBR, aa.w); + if(regs.p.m)status.cycle_pos++; + break; + case 4: + rd.h = op_read(OPMODE_DBR, aa.w + 1); + break; + case 5: + cpu_io(); + if(regs.p.m) { op_rol_b(); status.cycle_pos++; } + else op_rol_w(); + break; + case 6: + op_write(OPMODE_DBR, aa.w + 1, rd.h); + break; + case 7: + op_write(OPMODE_DBR, aa.w, rd.l); + status.cycle_pos = 0; + break; + } } void bCPU::op_ror_addr() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - rd.l = op_read(OPMODE_DBR, aa.w); - if(regs.p.m)goto l5; -l4: - rd.h = op_read(OPMODE_DBR, aa.w + 1); -l5: - cpu_io(); - if(regs.p.m) { op_ror_b(); goto l7; } - else op_ror_w(); -l6: - op_write(OPMODE_DBR, aa.w + 1, rd.h); -l7: - op_write(OPMODE_DBR, aa.w, rd.l); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + rd.l = op_read(OPMODE_DBR, aa.w); + if(regs.p.m)status.cycle_pos++; + break; + case 4: + rd.h = op_read(OPMODE_DBR, aa.w + 1); + break; + case 5: + cpu_io(); + if(regs.p.m) { op_ror_b(); status.cycle_pos++; } + else op_ror_w(); + break; + case 6: + op_write(OPMODE_DBR, aa.w + 1, rd.h); + break; + case 7: + op_write(OPMODE_DBR, aa.w, rd.l); + status.cycle_pos = 0; + break; + } } void bCPU::op_trb_addr() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - rd.l = op_read(OPMODE_DBR, aa.w); - if(regs.p.m)goto l5; -l4: - rd.h = op_read(OPMODE_DBR, aa.w + 1); -l5: - cpu_io(); - if(regs.p.m) { op_trb_b(); goto l7; } - else op_trb_w(); -l6: - op_write(OPMODE_DBR, aa.w + 1, rd.h); -l7: - op_write(OPMODE_DBR, aa.w, rd.l); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + rd.l = op_read(OPMODE_DBR, aa.w); + if(regs.p.m)status.cycle_pos++; + break; + case 4: + rd.h = op_read(OPMODE_DBR, aa.w + 1); + break; + case 5: + cpu_io(); + if(regs.p.m) { op_trb_b(); status.cycle_pos++; } + else op_trb_w(); + break; + case 6: + op_write(OPMODE_DBR, aa.w + 1, rd.h); + break; + case 7: + op_write(OPMODE_DBR, aa.w, rd.l); + status.cycle_pos = 0; + break; + } } void bCPU::op_tsb_addr() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - rd.l = op_read(OPMODE_DBR, aa.w); - if(regs.p.m)goto l5; -l4: - rd.h = op_read(OPMODE_DBR, aa.w + 1); -l5: - cpu_io(); - if(regs.p.m) { op_tsb_b(); goto l7; } - else op_tsb_w(); -l6: - op_write(OPMODE_DBR, aa.w + 1, rd.h); -l7: - op_write(OPMODE_DBR, aa.w, rd.l); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + rd.l = op_read(OPMODE_DBR, aa.w); + if(regs.p.m)status.cycle_pos++; + break; + case 4: + rd.h = op_read(OPMODE_DBR, aa.w + 1); + break; + case 5: + cpu_io(); + if(regs.p.m) { op_tsb_b(); status.cycle_pos++; } + else op_tsb_w(); + break; + case 6: + op_write(OPMODE_DBR, aa.w + 1, rd.h); + break; + case 7: + op_write(OPMODE_DBR, aa.w, rd.l); + status.cycle_pos = 0; + break; + } } void bCPU::op_inc_addrx() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - cpu_io(); -l4: - rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); - if(regs.p.m)goto l6; -l5: - rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); -l6: - cpu_io(); - if(regs.p.m) { op_inc_b(); goto l8; } - else op_inc_w(); -l7: - op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h); -l8: - op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + cpu_io(); + break; + case 4: + rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); + if(regs.p.m)status.cycle_pos++; + break; + case 5: + rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); + break; + case 6: + cpu_io(); + if(regs.p.m) { op_inc_b(); status.cycle_pos++; } + else op_inc_w(); + break; + case 7: + op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h); + break; + case 8: + op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); + status.cycle_pos = 0; + break; + } } void bCPU::op_dec_addrx() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - cpu_io(); -l4: - rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); - if(regs.p.m)goto l6; -l5: - rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); -l6: - cpu_io(); - if(regs.p.m) { op_dec_b(); goto l8; } - else op_dec_w(); -l7: - op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h); -l8: - op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + cpu_io(); + break; + case 4: + rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); + if(regs.p.m)status.cycle_pos++; + break; + case 5: + rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); + break; + case 6: + cpu_io(); + if(regs.p.m) { op_dec_b(); status.cycle_pos++; } + else op_dec_w(); + break; + case 7: + op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h); + break; + case 8: + op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); + status.cycle_pos = 0; + break; + } } void bCPU::op_asl_addrx() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - cpu_io(); -l4: - rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); - if(regs.p.m)goto l6; -l5: - rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); -l6: - cpu_io(); - if(regs.p.m) { op_asl_b(); goto l8; } - else op_asl_w(); -l7: - op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h); -l8: - op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + cpu_io(); + break; + case 4: + rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); + if(regs.p.m)status.cycle_pos++; + break; + case 5: + rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); + break; + case 6: + cpu_io(); + if(regs.p.m) { op_asl_b(); status.cycle_pos++; } + else op_asl_w(); + break; + case 7: + op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h); + break; + case 8: + op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); + status.cycle_pos = 0; + break; + } } void bCPU::op_lsr_addrx() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - cpu_io(); -l4: - rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); - if(regs.p.m)goto l6; -l5: - rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); -l6: - cpu_io(); - if(regs.p.m) { op_lsr_b(); goto l8; } - else op_lsr_w(); -l7: - op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h); -l8: - op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + cpu_io(); + break; + case 4: + rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); + if(regs.p.m)status.cycle_pos++; + break; + case 5: + rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); + break; + case 6: + cpu_io(); + if(regs.p.m) { op_lsr_b(); status.cycle_pos++; } + else op_lsr_w(); + break; + case 7: + op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h); + break; + case 8: + op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); + status.cycle_pos = 0; + break; + } } void bCPU::op_rol_addrx() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - cpu_io(); -l4: - rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); - if(regs.p.m)goto l6; -l5: - rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); -l6: - cpu_io(); - if(regs.p.m) { op_rol_b(); goto l8; } - else op_rol_w(); -l7: - op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h); -l8: - op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + cpu_io(); + break; + case 4: + rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); + if(regs.p.m)status.cycle_pos++; + break; + case 5: + rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); + break; + case 6: + cpu_io(); + if(regs.p.m) { op_rol_b(); status.cycle_pos++; } + else op_rol_w(); + break; + case 7: + op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h); + break; + case 8: + op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); + status.cycle_pos = 0; + break; + } } void bCPU::op_ror_addrx() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - cpu_io(); -l4: - rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); - if(regs.p.m)goto l6; -l5: - rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); -l6: - cpu_io(); - if(regs.p.m) { op_ror_b(); goto l8; } - else op_ror_w(); -l7: - op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h); -l8: - op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + cpu_io(); + break; + case 4: + rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); + if(regs.p.m)status.cycle_pos++; + break; + case 5: + rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); + break; + case 6: + cpu_io(); + if(regs.p.m) { op_ror_b(); status.cycle_pos++; } + else op_ror_w(); + break; + case 7: + op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h); + break; + case 8: + op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); + status.cycle_pos = 0; + break; + } } void bCPU::op_inc_dp() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - rd.l = op_read(OPMODE_DP, dp); - if(regs.p.m)goto l5; -l4: - rd.h = op_read(OPMODE_DP, dp + 1); -l5: - cpu_io(); - if(regs.p.m) { op_inc_b(); goto l7; } - else op_inc_w(); -l6: - op_write(OPMODE_DP, dp + 1, rd.h); -l7: - op_write(OPMODE_DP, dp, rd.l); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + rd.l = op_read(OPMODE_DP, dp); + if(regs.p.m)status.cycle_pos++; + break; + case 4: + rd.h = op_read(OPMODE_DP, dp + 1); + break; + case 5: + cpu_io(); + if(regs.p.m) { op_inc_b(); status.cycle_pos++; } + else op_inc_w(); + break; + case 6: + op_write(OPMODE_DP, dp + 1, rd.h); + break; + case 7: + op_write(OPMODE_DP, dp, rd.l); + status.cycle_pos = 0; + break; + } } void bCPU::op_dec_dp() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - rd.l = op_read(OPMODE_DP, dp); - if(regs.p.m)goto l5; -l4: - rd.h = op_read(OPMODE_DP, dp + 1); -l5: - cpu_io(); - if(regs.p.m) { op_dec_b(); goto l7; } - else op_dec_w(); -l6: - op_write(OPMODE_DP, dp + 1, rd.h); -l7: - op_write(OPMODE_DP, dp, rd.l); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + rd.l = op_read(OPMODE_DP, dp); + if(regs.p.m)status.cycle_pos++; + break; + case 4: + rd.h = op_read(OPMODE_DP, dp + 1); + break; + case 5: + cpu_io(); + if(regs.p.m) { op_dec_b(); status.cycle_pos++; } + else op_dec_w(); + break; + case 6: + op_write(OPMODE_DP, dp + 1, rd.h); + break; + case 7: + op_write(OPMODE_DP, dp, rd.l); + status.cycle_pos = 0; + break; + } } void bCPU::op_asl_dp() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - rd.l = op_read(OPMODE_DP, dp); - if(regs.p.m)goto l5; -l4: - rd.h = op_read(OPMODE_DP, dp + 1); -l5: - cpu_io(); - if(regs.p.m) { op_asl_b(); goto l7; } - else op_asl_w(); -l6: - op_write(OPMODE_DP, dp + 1, rd.h); -l7: - op_write(OPMODE_DP, dp, rd.l); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + rd.l = op_read(OPMODE_DP, dp); + if(regs.p.m)status.cycle_pos++; + break; + case 4: + rd.h = op_read(OPMODE_DP, dp + 1); + break; + case 5: + cpu_io(); + if(regs.p.m) { op_asl_b(); status.cycle_pos++; } + else op_asl_w(); + break; + case 6: + op_write(OPMODE_DP, dp + 1, rd.h); + break; + case 7: + op_write(OPMODE_DP, dp, rd.l); + status.cycle_pos = 0; + break; + } } void bCPU::op_lsr_dp() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - rd.l = op_read(OPMODE_DP, dp); - if(regs.p.m)goto l5; -l4: - rd.h = op_read(OPMODE_DP, dp + 1); -l5: - cpu_io(); - if(regs.p.m) { op_lsr_b(); goto l7; } - else op_lsr_w(); -l6: - op_write(OPMODE_DP, dp + 1, rd.h); -l7: - op_write(OPMODE_DP, dp, rd.l); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + rd.l = op_read(OPMODE_DP, dp); + if(regs.p.m)status.cycle_pos++; + break; + case 4: + rd.h = op_read(OPMODE_DP, dp + 1); + break; + case 5: + cpu_io(); + if(regs.p.m) { op_lsr_b(); status.cycle_pos++; } + else op_lsr_w(); + break; + case 6: + op_write(OPMODE_DP, dp + 1, rd.h); + break; + case 7: + op_write(OPMODE_DP, dp, rd.l); + status.cycle_pos = 0; + break; + } } void bCPU::op_rol_dp() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - rd.l = op_read(OPMODE_DP, dp); - if(regs.p.m)goto l5; -l4: - rd.h = op_read(OPMODE_DP, dp + 1); -l5: - cpu_io(); - if(regs.p.m) { op_rol_b(); goto l7; } - else op_rol_w(); -l6: - op_write(OPMODE_DP, dp + 1, rd.h); -l7: - op_write(OPMODE_DP, dp, rd.l); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + rd.l = op_read(OPMODE_DP, dp); + if(regs.p.m)status.cycle_pos++; + break; + case 4: + rd.h = op_read(OPMODE_DP, dp + 1); + break; + case 5: + cpu_io(); + if(regs.p.m) { op_rol_b(); status.cycle_pos++; } + else op_rol_w(); + break; + case 6: + op_write(OPMODE_DP, dp + 1, rd.h); + break; + case 7: + op_write(OPMODE_DP, dp, rd.l); + status.cycle_pos = 0; + break; + } } void bCPU::op_ror_dp() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - rd.l = op_read(OPMODE_DP, dp); - if(regs.p.m)goto l5; -l4: - rd.h = op_read(OPMODE_DP, dp + 1); -l5: - cpu_io(); - if(regs.p.m) { op_ror_b(); goto l7; } - else op_ror_w(); -l6: - op_write(OPMODE_DP, dp + 1, rd.h); -l7: - op_write(OPMODE_DP, dp, rd.l); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + rd.l = op_read(OPMODE_DP, dp); + if(regs.p.m)status.cycle_pos++; + break; + case 4: + rd.h = op_read(OPMODE_DP, dp + 1); + break; + case 5: + cpu_io(); + if(regs.p.m) { op_ror_b(); status.cycle_pos++; } + else op_ror_w(); + break; + case 6: + op_write(OPMODE_DP, dp + 1, rd.h); + break; + case 7: + op_write(OPMODE_DP, dp, rd.l); + status.cycle_pos = 0; + break; + } } void bCPU::op_trb_dp() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - rd.l = op_read(OPMODE_DP, dp); - if(regs.p.m)goto l5; -l4: - rd.h = op_read(OPMODE_DP, dp + 1); -l5: - cpu_io(); - if(regs.p.m) { op_trb_b(); goto l7; } - else op_trb_w(); -l6: - op_write(OPMODE_DP, dp + 1, rd.h); -l7: - op_write(OPMODE_DP, dp, rd.l); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + rd.l = op_read(OPMODE_DP, dp); + if(regs.p.m)status.cycle_pos++; + break; + case 4: + rd.h = op_read(OPMODE_DP, dp + 1); + break; + case 5: + cpu_io(); + if(regs.p.m) { op_trb_b(); status.cycle_pos++; } + else op_trb_w(); + break; + case 6: + op_write(OPMODE_DP, dp + 1, rd.h); + break; + case 7: + op_write(OPMODE_DP, dp, rd.l); + status.cycle_pos = 0; + break; + } } void bCPU::op_tsb_dp() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - rd.l = op_read(OPMODE_DP, dp); - if(regs.p.m)goto l5; -l4: - rd.h = op_read(OPMODE_DP, dp + 1); -l5: - cpu_io(); - if(regs.p.m) { op_tsb_b(); goto l7; } - else op_tsb_w(); -l6: - op_write(OPMODE_DP, dp + 1, rd.h); -l7: - op_write(OPMODE_DP, dp, rd.l); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + rd.l = op_read(OPMODE_DP, dp); + if(regs.p.m)status.cycle_pos++; + break; + case 4: + rd.h = op_read(OPMODE_DP, dp + 1); + break; + case 5: + cpu_io(); + if(regs.p.m) { op_tsb_b(); status.cycle_pos++; } + else op_tsb_w(); + break; + case 6: + op_write(OPMODE_DP, dp + 1, rd.h); + break; + case 7: + op_write(OPMODE_DP, dp, rd.l); + status.cycle_pos = 0; + break; + } } void bCPU::op_inc_dpx() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - cpu_io(); -l4: - rd.l = op_read(OPMODE_DP, dp + regs.x.w); - if(regs.p.m)goto l6; -l5: - rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); -l6: - cpu_io(); - if(regs.p.m) { op_inc_b(); goto l8; } - else op_inc_w(); -l7: - op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h); -l8: - op_write(OPMODE_DP, dp + regs.x.w, rd.l); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + cpu_io(); + break; + case 4: + rd.l = op_read(OPMODE_DP, dp + regs.x.w); + if(regs.p.m)status.cycle_pos++; + break; + case 5: + rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); + break; + case 6: + cpu_io(); + if(regs.p.m) { op_inc_b(); status.cycle_pos++; } + else op_inc_w(); + break; + case 7: + op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h); + break; + case 8: + op_write(OPMODE_DP, dp + regs.x.w, rd.l); + status.cycle_pos = 0; + break; + } } void bCPU::op_dec_dpx() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - cpu_io(); -l4: - rd.l = op_read(OPMODE_DP, dp + regs.x.w); - if(regs.p.m)goto l6; -l5: - rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); -l6: - cpu_io(); - if(regs.p.m) { op_dec_b(); goto l8; } - else op_dec_w(); -l7: - op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h); -l8: - op_write(OPMODE_DP, dp + regs.x.w, rd.l); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + cpu_io(); + break; + case 4: + rd.l = op_read(OPMODE_DP, dp + regs.x.w); + if(regs.p.m)status.cycle_pos++; + break; + case 5: + rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); + break; + case 6: + cpu_io(); + if(regs.p.m) { op_dec_b(); status.cycle_pos++; } + else op_dec_w(); + break; + case 7: + op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h); + break; + case 8: + op_write(OPMODE_DP, dp + regs.x.w, rd.l); + status.cycle_pos = 0; + break; + } } void bCPU::op_asl_dpx() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - cpu_io(); -l4: - rd.l = op_read(OPMODE_DP, dp + regs.x.w); - if(regs.p.m)goto l6; -l5: - rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); -l6: - cpu_io(); - if(regs.p.m) { op_asl_b(); goto l8; } - else op_asl_w(); -l7: - op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h); -l8: - op_write(OPMODE_DP, dp + regs.x.w, rd.l); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + cpu_io(); + break; + case 4: + rd.l = op_read(OPMODE_DP, dp + regs.x.w); + if(regs.p.m)status.cycle_pos++; + break; + case 5: + rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); + break; + case 6: + cpu_io(); + if(regs.p.m) { op_asl_b(); status.cycle_pos++; } + else op_asl_w(); + break; + case 7: + op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h); + break; + case 8: + op_write(OPMODE_DP, dp + regs.x.w, rd.l); + status.cycle_pos = 0; + break; + } } void bCPU::op_lsr_dpx() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - cpu_io(); -l4: - rd.l = op_read(OPMODE_DP, dp + regs.x.w); - if(regs.p.m)goto l6; -l5: - rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); -l6: - cpu_io(); - if(regs.p.m) { op_lsr_b(); goto l8; } - else op_lsr_w(); -l7: - op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h); -l8: - op_write(OPMODE_DP, dp + regs.x.w, rd.l); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + cpu_io(); + break; + case 4: + rd.l = op_read(OPMODE_DP, dp + regs.x.w); + if(regs.p.m)status.cycle_pos++; + break; + case 5: + rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); + break; + case 6: + cpu_io(); + if(regs.p.m) { op_lsr_b(); status.cycle_pos++; } + else op_lsr_w(); + break; + case 7: + op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h); + break; + case 8: + op_write(OPMODE_DP, dp + regs.x.w, rd.l); + status.cycle_pos = 0; + break; + } } void bCPU::op_rol_dpx() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - cpu_io(); -l4: - rd.l = op_read(OPMODE_DP, dp + regs.x.w); - if(regs.p.m)goto l6; -l5: - rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); -l6: - cpu_io(); - if(regs.p.m) { op_rol_b(); goto l8; } - else op_rol_w(); -l7: - op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h); -l8: - op_write(OPMODE_DP, dp + regs.x.w, rd.l); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + cpu_io(); + break; + case 4: + rd.l = op_read(OPMODE_DP, dp + regs.x.w); + if(regs.p.m)status.cycle_pos++; + break; + case 5: + rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); + break; + case 6: + cpu_io(); + if(regs.p.m) { op_rol_b(); status.cycle_pos++; } + else op_rol_w(); + break; + case 7: + op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h); + break; + case 8: + op_write(OPMODE_DP, dp + regs.x.w, rd.l); + status.cycle_pos = 0; + break; + } } void bCPU::op_ror_dpx() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - cpu_io(); -l4: - rd.l = op_read(OPMODE_DP, dp + regs.x.w); - if(regs.p.m)goto l6; -l5: - rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); -l6: - cpu_io(); - if(regs.p.m) { op_ror_b(); goto l8; } - else op_ror_w(); -l7: - op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h); -l8: - op_write(OPMODE_DP, dp + regs.x.w, rd.l); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + cpu_io(); + break; + case 4: + rd.l = op_read(OPMODE_DP, dp + regs.x.w); + if(regs.p.m)status.cycle_pos++; + break; + case 5: + rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); + break; + case 6: + cpu_io(); + if(regs.p.m) { op_ror_b(); status.cycle_pos++; } + else op_ror_w(); + break; + case 7: + op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h); + break; + case 8: + op_write(OPMODE_DP, dp + regs.x.w, rd.l); + status.cycle_pos = 0; + break; + } } diff --git a/src/cpu/bcpu/bcpu_op_write.cpp b/src/cpu/bcpu/bcpu_op_write.cpp index 8a294337..6bff82ad 100644 --- a/src/cpu/bcpu/bcpu_op_write.cpp +++ b/src/cpu/bcpu/bcpu_op_write.cpp @@ -1,340 +1,534 @@ void bCPU::op_sta_addr() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - op_write(OPMODE_DBR, aa.w, regs.a.w); - if(regs.p.m)return; -l4: - op_write(OPMODE_DBR, aa.w + 1, regs.a.w >> 8); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + op_write(OPMODE_DBR, aa.w, regs.a.w); + if(regs.p.m)status.cycle_pos = 0; + break; + case 4: + op_write(OPMODE_DBR, aa.w + 1, regs.a.w >> 8); + status.cycle_pos = 0; + break; + } } void bCPU::op_stx_addr() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - op_write(OPMODE_DBR, aa.w, regs.x.w); - if(regs.p.x)return; -l4: - op_write(OPMODE_DBR, aa.w + 1, regs.x.w >> 8); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + op_write(OPMODE_DBR, aa.w, regs.x.w); + if(regs.p.x)status.cycle_pos = 0; + break; + case 4: + op_write(OPMODE_DBR, aa.w + 1, regs.x.w >> 8); + status.cycle_pos = 0; + break; + } } void bCPU::op_sty_addr() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - op_write(OPMODE_DBR, aa.w, regs.y.w); - if(regs.p.x)return; -l4: - op_write(OPMODE_DBR, aa.w + 1, regs.y.w >> 8); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + op_write(OPMODE_DBR, aa.w, regs.y.w); + if(regs.p.x)status.cycle_pos = 0; + break; + case 4: + op_write(OPMODE_DBR, aa.w + 1, regs.y.w >> 8); + status.cycle_pos = 0; + break; + } } void bCPU::op_stz_addr() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - op_write(OPMODE_DBR, aa.w, 0x0000); - if(regs.p.m)return; -l4: - op_write(OPMODE_DBR, aa.w + 1, 0x0000 >> 8); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + op_write(OPMODE_DBR, aa.w, 0x0000); + if(regs.p.m)status.cycle_pos = 0; + break; + case 4: + op_write(OPMODE_DBR, aa.w + 1, 0x0000 >> 8); + status.cycle_pos = 0; + break; + } } void bCPU::op_sta_addrx() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - cpu_c4(aa.w, aa.w + regs.x.w); -l4: - op_write(OPMODE_DBR, aa.w + regs.x.w, regs.a.w); - if(regs.p.m)return; -l5: - op_write(OPMODE_DBR, aa.w + regs.x.w + 1, regs.a.w >> 8); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + cpu_c4(aa.w, aa.w + regs.x.w); + break; + case 4: + op_write(OPMODE_DBR, aa.w + regs.x.w, regs.a.w); + if(regs.p.m)status.cycle_pos = 0; + break; + case 5: + op_write(OPMODE_DBR, aa.w + regs.x.w + 1, regs.a.w >> 8); + status.cycle_pos = 0; + break; + } } void bCPU::op_stz_addrx() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - cpu_c4(aa.w, aa.w + regs.x.w); -l4: - op_write(OPMODE_DBR, aa.w + regs.x.w, 0x0000); - if(regs.p.m)return; -l5: - op_write(OPMODE_DBR, aa.w + regs.x.w + 1, 0x0000 >> 8); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + cpu_c4(aa.w, aa.w + regs.x.w); + break; + case 4: + op_write(OPMODE_DBR, aa.w + regs.x.w, 0x0000); + if(regs.p.m)status.cycle_pos = 0; + break; + case 5: + op_write(OPMODE_DBR, aa.w + regs.x.w + 1, 0x0000 >> 8); + status.cycle_pos = 0; + break; + } } void bCPU::op_sta_addry() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - cpu_c4(aa.w, aa.w + regs.y.w); -l4: - op_write(OPMODE_DBR, aa.w + regs.y.w, regs.a.l); - if(regs.p.m)return; -l5: - op_write(OPMODE_DBR, aa.w + regs.y.w + 1, regs.a.h); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + cpu_c4(aa.w, aa.w + regs.y.w); + break; + case 4: + op_write(OPMODE_DBR, aa.w + regs.y.w, regs.a.l); + if(regs.p.m)status.cycle_pos = 0; + break; + case 5: + op_write(OPMODE_DBR, aa.w + regs.y.w + 1, regs.a.h); + status.cycle_pos = 0; + break; + } } void bCPU::op_sta_long() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - aa.b = op_read(); -l4: - op_write(OPMODE_LONG, aa.d, regs.a.l); - if(regs.p.m)return; -l5: - op_write(OPMODE_LONG, aa.d + 1, regs.a.h); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + aa.b = op_read(); + break; + case 4: + op_write(OPMODE_LONG, aa.d, regs.a.l); + if(regs.p.m)status.cycle_pos = 0; + break; + case 5: + op_write(OPMODE_LONG, aa.d + 1, regs.a.h); + status.cycle_pos = 0; + break; + } } void bCPU::op_sta_longx() { -l1: - aa.l = op_read(); -l2: - aa.h = op_read(); -l3: - aa.b = op_read(); -l4: - op_write(OPMODE_LONG, aa.d + regs.x.w, regs.a.l); - if(regs.p.m)return; -l5: - op_write(OPMODE_LONG, aa.d + regs.x.w + 1, regs.a.h); + switch(status.cycle_pos++) { + case 1: + aa.l = op_read(); + break; + case 2: + aa.h = op_read(); + break; + case 3: + aa.b = op_read(); + break; + case 4: + op_write(OPMODE_LONG, aa.d + regs.x.w, regs.a.l); + if(regs.p.m)status.cycle_pos = 0; + break; + case 5: + op_write(OPMODE_LONG, aa.d + regs.x.w + 1, regs.a.h); + status.cycle_pos = 0; + break; + } } void bCPU::op_sta_dp() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - op_write(OPMODE_DP, dp, regs.a.w); - if(regs.p.m)return; -l4: - op_write(OPMODE_DP, dp + 1, regs.a.w >> 8); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + op_write(OPMODE_DP, dp, regs.a.w); + if(regs.p.m)status.cycle_pos = 0; + break; + case 4: + op_write(OPMODE_DP, dp + 1, regs.a.w >> 8); + status.cycle_pos = 0; + break; + } } void bCPU::op_stx_dp() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - op_write(OPMODE_DP, dp, regs.x.w); - if(regs.p.x)return; -l4: - op_write(OPMODE_DP, dp + 1, regs.x.w >> 8); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + op_write(OPMODE_DP, dp, regs.x.w); + if(regs.p.x)status.cycle_pos = 0; + break; + case 4: + op_write(OPMODE_DP, dp + 1, regs.x.w >> 8); + status.cycle_pos = 0; + break; + } } void bCPU::op_sty_dp() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - op_write(OPMODE_DP, dp, regs.y.w); - if(regs.p.x)return; -l4: - op_write(OPMODE_DP, dp + 1, regs.y.w >> 8); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + op_write(OPMODE_DP, dp, regs.y.w); + if(regs.p.x)status.cycle_pos = 0; + break; + case 4: + op_write(OPMODE_DP, dp + 1, regs.y.w >> 8); + status.cycle_pos = 0; + break; + } } void bCPU::op_stz_dp() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - op_write(OPMODE_DP, dp, 0x0000); - if(regs.p.m)return; -l4: - op_write(OPMODE_DP, dp + 1, 0x0000 >> 8); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + op_write(OPMODE_DP, dp, 0x0000); + if(regs.p.m)status.cycle_pos = 0; + break; + case 4: + op_write(OPMODE_DP, dp + 1, 0x0000 >> 8); + status.cycle_pos = 0; + break; + } } void bCPU::op_sta_dpx() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - cpu_io(); -l4: - op_write(OPMODE_DP, dp + regs.x.w, regs.a.w); - if(regs.p.m)return; -l5: - op_write(OPMODE_DP, dp + regs.x.w + 1, regs.a.w >> 8); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + cpu_io(); + break; + case 4: + op_write(OPMODE_DP, dp + regs.x.w, regs.a.w); + if(regs.p.m)status.cycle_pos = 0; + break; + case 5: + op_write(OPMODE_DP, dp + regs.x.w + 1, regs.a.w >> 8); + status.cycle_pos = 0; + break; + } } void bCPU::op_sty_dpx() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - cpu_io(); -l4: - op_write(OPMODE_DP, dp + regs.x.w, regs.y.w); - if(regs.p.x)return; -l5: - op_write(OPMODE_DP, dp + regs.x.w + 1, regs.y.w >> 8); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + cpu_io(); + break; + case 4: + op_write(OPMODE_DP, dp + regs.x.w, regs.y.w); + if(regs.p.x)status.cycle_pos = 0; + break; + case 5: + op_write(OPMODE_DP, dp + regs.x.w + 1, regs.y.w >> 8); + status.cycle_pos = 0; + break; + } } void bCPU::op_stz_dpx() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - cpu_io(); -l4: - op_write(OPMODE_DP, dp + regs.x.w, 0x0000); - if(regs.p.m)return; -l5: - op_write(OPMODE_DP, dp + regs.x.w + 1, 0x0000 >> 8); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + cpu_io(); + break; + case 4: + op_write(OPMODE_DP, dp + regs.x.w, 0x0000); + if(regs.p.m)status.cycle_pos = 0; + break; + case 5: + op_write(OPMODE_DP, dp + regs.x.w + 1, 0x0000 >> 8); + status.cycle_pos = 0; + break; + } } void bCPU::op_stx_dpy() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - cpu_io(); -l4: - op_write(OPMODE_DP, dp + regs.y.w, regs.x.l); - if(regs.p.x)return; -l5: - op_write(OPMODE_DP, dp + regs.y.w + 1, regs.x.h); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + cpu_io(); + break; + case 4: + op_write(OPMODE_DP, dp + regs.y.w, regs.x.l); + if(regs.p.x)status.cycle_pos = 0; + break; + case 5: + op_write(OPMODE_DP, dp + regs.y.w + 1, regs.x.h); + status.cycle_pos = 0; + break; + } } void bCPU::op_sta_idp() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - aa.l = op_read(OPMODE_DP, dp); -l4: - aa.h = op_read(OPMODE_DP, dp + 1); -l5: - op_write(OPMODE_DBR, aa.w, regs.a.l); - if(regs.p.m)return; -l6: - op_write(OPMODE_DBR, aa.w + 1, regs.a.h); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + aa.l = op_read(OPMODE_DP, dp); + break; + case 4: + aa.h = op_read(OPMODE_DP, dp + 1); + break; + case 5: + op_write(OPMODE_DBR, aa.w, regs.a.l); + if(regs.p.m)status.cycle_pos = 0; + break; + case 6: + op_write(OPMODE_DBR, aa.w + 1, regs.a.h); + status.cycle_pos = 0; + break; + } } void bCPU::op_sta_ildp() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - aa.l = op_read(OPMODE_DP, dp); -l4: - aa.h = op_read(OPMODE_DP, dp + 1); -l5: - aa.b = op_read(OPMODE_DP, dp + 2); -l6: - op_write(OPMODE_LONG, aa.d, regs.a.l); - if(regs.p.m)return; -l7: - op_write(OPMODE_LONG, aa.d + 1, regs.a.h); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + aa.l = op_read(OPMODE_DP, dp); + break; + case 4: + aa.h = op_read(OPMODE_DP, dp + 1); + break; + case 5: + aa.b = op_read(OPMODE_DP, dp + 2); + break; + case 6: + op_write(OPMODE_LONG, aa.d, regs.a.l); + if(regs.p.m)status.cycle_pos = 0; + break; + case 7: + op_write(OPMODE_LONG, aa.d + 1, regs.a.h); + status.cycle_pos = 0; + break; + } } void bCPU::op_sta_idpx() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - cpu_io(); -l4: - aa.l = op_read(OPMODE_DP, dp + regs.x.w); -l5: - aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); -l6: - op_write(OPMODE_DBR, aa.w, regs.a.l); - if(regs.p.m)return; -l7: - op_write(OPMODE_DBR, aa.w + 1, regs.a.h); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + cpu_io(); + break; + case 4: + aa.l = op_read(OPMODE_DP, dp + regs.x.w); + break; + case 5: + aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); + break; + case 6: + op_write(OPMODE_DBR, aa.w, regs.a.l); + if(regs.p.m)status.cycle_pos = 0; + break; + case 7: + op_write(OPMODE_DBR, aa.w + 1, regs.a.h); + status.cycle_pos = 0; + break; + } } void bCPU::op_sta_idpy() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - aa.l = op_read(OPMODE_DP, dp); -l4: - aa.h = op_read(OPMODE_DP, dp + 1); -l5: - cpu_c4(aa.w, aa.w + regs.y.w); -l6: - op_write(OPMODE_DBR, aa.w + regs.y.w, regs.a.l); - if(regs.p.m)return; -l7: - op_write(OPMODE_DBR, aa.w + regs.y.w + 1, regs.a.h); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + aa.l = op_read(OPMODE_DP, dp); + break; + case 4: + aa.h = op_read(OPMODE_DP, dp + 1); + break; + case 5: + cpu_c4(aa.w, aa.w + regs.y.w); + break; + case 6: + op_write(OPMODE_DBR, aa.w + regs.y.w, regs.a.l); + if(regs.p.m)status.cycle_pos = 0; + break; + case 7: + op_write(OPMODE_DBR, aa.w + regs.y.w + 1, regs.a.h); + status.cycle_pos = 0; + break; + } } void bCPU::op_sta_ildpy() { -l1: - dp = op_read(); -l2: - cpu_c2(); -l3: - aa.l = op_read(OPMODE_DP, dp); -l4: - aa.h = op_read(OPMODE_DP, dp + 1); -l5: - aa.b = op_read(OPMODE_DP, dp + 2); -l6: - op_write(OPMODE_LONG, aa.d + regs.y.w, regs.a.l); - if(regs.p.m)return; -l7: - op_write(OPMODE_LONG, aa.d + regs.y.w + 1, regs.a.h); + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + cpu_c2(); + break; + case 3: + aa.l = op_read(OPMODE_DP, dp); + break; + case 4: + aa.h = op_read(OPMODE_DP, dp + 1); + break; + case 5: + aa.b = op_read(OPMODE_DP, dp + 2); + break; + case 6: + op_write(OPMODE_LONG, aa.d + regs.y.w, regs.a.l); + if(regs.p.m)status.cycle_pos = 0; + break; + case 7: + op_write(OPMODE_LONG, aa.d + regs.y.w + 1, regs.a.h); + status.cycle_pos = 0; + break; + } } void bCPU::op_sta_sr() { -l1: - sp = op_read(); -l2: - cpu_io(); -l3: - op_write(OPMODE_SP, sp, regs.a.l); - if(regs.p.m)return; -l4: - op_write(OPMODE_SP, sp + 1, regs.a.h); + switch(status.cycle_pos++) { + case 1: + sp = op_read(); + break; + case 2: + cpu_io(); + break; + case 3: + op_write(OPMODE_SP, sp, regs.a.l); + if(regs.p.m)status.cycle_pos = 0; + break; + case 4: + op_write(OPMODE_SP, sp + 1, regs.a.h); + status.cycle_pos = 0; + break; + } } void bCPU::op_sta_isry() { -l1: - sp = op_read(); -l2: - cpu_io(); -l3: - aa.l = op_read(OPMODE_SP, sp); -l4: - aa.h = op_read(OPMODE_SP, sp + 1); -l5: - cpu_io(); -l6: - op_write(OPMODE_DBR, aa.w + regs.y.w, regs.a.l); - if(regs.p.m)return; -l7: - op_write(OPMODE_DBR, aa.w + regs.y.w + 1, regs.a.h); + switch(status.cycle_pos++) { + case 1: + sp = op_read(); + break; + case 2: + cpu_io(); + break; + case 3: + aa.l = op_read(OPMODE_SP, sp); + break; + case 4: + aa.h = op_read(OPMODE_SP, sp + 1); + break; + case 5: + cpu_io(); + break; + case 6: + op_write(OPMODE_DBR, aa.w + regs.y.w, regs.a.l); + if(regs.p.m)status.cycle_pos = 0; + break; + case 7: + op_write(OPMODE_DBR, aa.w + regs.y.w + 1, regs.a.h); + status.cycle_pos = 0; + break; + } } diff --git a/src/cpu/bcpu/bcpu_timing.cpp b/src/cpu/bcpu/bcpu_timing.cpp index 3e9cd83e..d5e10792 100644 --- a/src/cpu/bcpu/bcpu_timing.cpp +++ b/src/cpu/bcpu/bcpu_timing.cpp @@ -1,21 +1,55 @@ -uint16 bCPU::vcounter() { return time.v; } -uint16 bCPU::hcounter() { return get_hcounter(); } -uint16 bCPU::hcycles() { return time.hc; } -bool bCPU::interlace() { return time.interlace; } -bool bCPU::interlace_field() { return time.interlace_field; } -bool bCPU::overscan() { return time.overscan; } +/* Notes about PAL timing: + * As I do not have PAL hardware to run timing tests on, I've + * had to guess on a lot of things. Below is how I've arrived + * at various calculations: + * + * NTSC timing crystal: ~21477272hz + * PAL timing crystal: ~21281370hz + * NTSC ~60fps, PAL ~50fps + * NTSC ~262 lines/frame, PAL ~312 lines/frame + * NTSC 21477272 / (262 * 60) = ~1366 cycles/line + * PAL 21281370 / (312 * 50) = ~1364 cycles/line + * + * As the cycles/line are very close between the two systems, + * I have left the known NTSC anomalies intact for PAL timing. + * In reality, some of these may not exist, and some may be + * slightly different. + * + * [known] + * - DRAM refresh occurs at about the same time every + * scanline on PAL units (per Overload). + * [unknown] + * - Are dots 323/327 still 2 cycles longer than the + * other dots? + * - Is scanline 240 on non-interlace odd frames still + * 4 cycles short? + */ + +uint16 bCPU::vcounter() { return time.v; } +uint16 bCPU::hcounter() { return get_hcounter(); } +uint16 bCPU::hcycles() { return time.hc; } +bool bCPU::interlace() { return time.interlace; } +bool bCPU::interlace_field() { return time.interlace_field; } +bool bCPU::overscan() { return time.overscan; } +uint16 bCPU::region_scanlines() { return time.region_scanlines; } void bCPU::set_interlace(bool r) { time.interlace = r; } void bCPU::set_overscan(bool r) { time.overscan = r; } -uint8 bCPU::dma_counter() { return (time.dma_counter + time.hc) & 6; } +uint8 bCPU::dma_counter() { return (time.dma_counter + time.hc) & 6; } //all scanlines are 1364 cycles long, except scanline 240 //on non-interlace odd-frames, which is 1360 cycles long. +//[NTSC] //interlace mode has 525 scanlines: 263 on the even frame, //and 262 on the odd. //non-interlace mode has 524 scanlines: 262 scanlines on //both even and odd frames. +//[PAL] +//interlace mode has 625 scanlines: 313 on the even frame, +//and 312 on the odd. +//non-interlace mode has 624 scanlines: 312 scanlines on +//both even and odd frames. // //cycles per frame: // 263 * 1364 = 358732 @@ -28,9 +62,9 @@ void bCPU::inc_vcounter() { time.interlace_field ^= 1; if(time.interlace == true && time.interlace_field == 0) { - time.frame_lines = 263; + time.frame_lines = time.region_scanlines + 1; } else { - time.frame_lines = 262; + time.frame_lines = time.region_scanlines; } } @@ -44,31 +78,19 @@ void bCPU::inc_vcounter() { time.dram_refreshed = false; } -//all dots are 4 cycles long, except dots 322 and 326. dots 322 and 326 +//all dots are 4 cycles long, except dots 323 and 327. dots 323 and 327 //are 6 cycles long. this holds true for all scanlines except scanline //240 on non-interlace odd frames. the reason for this is because this //scanline is only 1360 cycles long, instead of 1364 like all other //scanlines. //this makes the effective range of hscan_pos 0-339 at all times. -//dot 322 range = { 1288, 1290, 1292 } -//dot 326 range = { 1306, 1308, 1310 } +//dot 323 range = { 1292, 1294, 1296 } +//dot 327 range = { 1310, 1312, 1314 } uint16 bCPU::get_hcounter() { if(time.v == 240 && time.interlace == false && time.interlace_field == 1) { return time.hc >> 2; } - return (time.hc - ((time.hc > 1288) << 1) - ((time.hc > 1306) << 1)) >> 2; -} - -void bCPU::apu_sync() { -int cycles; - while(apusync.cycles >= 0) { - apu->run(); - - cycles = apu->cycles_executed(); - if(cycles) { - apusync.cycles -= apusync.cpu_multbl[cycles]; - } - } + return (time.hc - ((time.hc > 1292) << 1) - ((time.hc > 1310) << 1)) >> 2; } void bCPU::dram_refresh() { @@ -76,15 +98,22 @@ void bCPU::dram_refresh() { add_cycles(40); if(time.v != 240 || time.interlace != false || time.interlace_field != 1) { //alternate between 534 and 538 every scanline except 240ni1 + //in reality, this is probably based on frame cycle length... time.dram_refresh_pos ^= 12; } } +uint32 bCPU::cycles_executed() { +uint32 r = status.cycles_executed; + status.cycles_executed = 0; + return r; +} + void bCPU::add_cycles(int cycles) { + status.cycles_executed += cycles; + cycles >>= 1; while(cycles--) { - apusync.cycles += apusync.apu_freq << 1; - apu_sync(); time.hc += 2; if(time.hc >= time.line_cycles) { @@ -119,23 +148,20 @@ void bCPU::time_reset() { time.interlace_field = false; time.overscan = false; time.line_cycles = 1364; - time.frame_lines = 262; time.dram_refreshed = false; time.dram_refresh_pos = 538; time.dma_counter = 0; - apusync.cycles = apusync.cpu_multbl[255]; -} - -void bCPU::time_init() { - apusync.cpu_freq = 21477272 >> 3; - apusync.apu_freq = 24576000 >> 3; - -int i; - for(i=0;i<1024;i++) { - apusync.cpu_multbl[i] = i * apusync.cpu_freq; - apusync.apu_multbl[i] = i * apusync.apu_freq; + switch(region) { + case NTSC: + time.region_scanlines = 262; + break; + case PAL: + time.region_scanlines = 312; + break; } + + time.frame_lines = time.region_scanlines; } diff --git a/src/cpu/bcpu/bcpu_timing.h b/src/cpu/bcpu/bcpu_timing.h index 76a91a15..c6fd4dd6 100644 --- a/src/cpu/bcpu/bcpu_timing.h +++ b/src/cpu/bcpu/bcpu_timing.h @@ -8,6 +8,8 @@ struct { uint16 dram_refresh_pos; uint8 dma_counter; + + uint16 region_scanlines; }time; inline uint16 vcounter(); @@ -16,6 +18,7 @@ inline uint16 hcycles(); inline bool interlace(); inline bool interlace_field(); inline bool overscan(); +inline uint16 region_scanlines(); inline void set_interlace(bool r); inline void set_overscan (bool r); @@ -24,15 +27,6 @@ inline uint8 dma_counter(); inline void inc_vcounter(); inline uint16 get_hcounter(); -inline void apu_sync(); inline void dram_refresh(); inline void add_cycles(int cycles); inline void time_reset(); -inline void time_init(); - -//APU synchronization -struct { -int32 cpu_freq, apu_freq; -int32 cpu_multbl[1024], apu_multbl[1024]; -int32 cycles; -}apusync; diff --git a/src/cpu/bcpu/bcpugen.cpp b/src/cpu/bcpu/bcpugen.cpp index ca22a068..9f49452f 100644 --- a/src/cpu/bcpu/bcpugen.cpp +++ b/src/cpu/bcpu/bcpugen.cpp @@ -44,7 +44,7 @@ char t[4096]; i++; } - sprintf(output_op, "void bCPU::op_$$() {\r\n"); + sprintf(output_op, "void bCPU::op_$$() {\r\n switch(status.cycle_pos++) {\r\n"); sprintf(output_header, "void op_$$();\r\n"); sprintf(output_table, "optbl[$0] = &bCPU::op_$$;\r\n"); @@ -54,8 +54,8 @@ char t[4096]; void update_line(int i, int n) { char t[4096]; sprintf(t, "goto l%d;", n + 2); - replace(line[i], "end;", "return;"); - replace(line[i], "skip;", t); + replace(line[i], "end;", "status.cycle_pos = 0;"); + replace(line[i], "skip;", "status.cycle_pos++;"); } void gen_op() { @@ -67,12 +67,12 @@ char t[4096]; n = strdec(line[i]); sprintf(t, "%d:", n); strltrim(line[i], t); - sprintf(t, "l%d:\r\n", n); + sprintf(t, " case %d:\r\n", n); strcat(output_op, t); update_line(i, n); if(strcmp(line[i], "")) { - strcat(output_op, " "); + strcat(output_op, " "); strcat(output_op, line[i]); strcat(output_op, "\r\n"); } @@ -82,13 +82,16 @@ char t[4096]; if((strptr(line[i])[1]) == ':' || !strcmp(line[i], "}"))break; update_line(i, n); + strcat(output_op, " "); strcat(output_op, line[i]); strcat(output_op, "\r\n"); i++; } + if(!strcmp(line[i], "}"))strcat(output_op, " status.cycle_pos = 0;\r\n"); + strcat(output_op, " break;\r\n"); } - strcat(output_op, "}"); + strcat(output_op, " }\r\n}"); line_num = i + 1; } @@ -107,16 +110,16 @@ int i, l; replace(t, "$5", op_list[i].arg[5]); replace(t, "$6", op_list[i].arg[6]); replace(t, "$7", op_list[i].arg[7]); - fprintf(fp, "%s\r\n\r\n", *t); + fprintf(fp, "%s\r\n\r\n", strptr(t)); strcpy(t, output_header); replace(t, "$$", op_list[i].name); - fprintf(fph, "%s", *t); + fprintf(fph, "%s", strptr(t)); strcpy(t, output_table); replace(t, "$$", op_list[i].name); replace(t, "$0", op_list[i].arg[0]); - fprintf(fpt, "%s", *t); + fprintf(fpt, "%s", strptr(t)); } } diff --git a/src/cpu/bcpu/bcpugen.exe b/src/cpu/bcpu/bcpugen.exe index 2f635841..db34eb92 100644 Binary files a/src/cpu/bcpu/bcpugen.exe and b/src/cpu/bcpu/bcpugen.exe differ diff --git a/src/cpu/bcpu/op_misc.b b/src/cpu/bcpu/op_misc.b index 2c115c32..d35fac92 100644 --- a/src/cpu/bcpu/op_misc.b +++ b/src/cpu/bcpu/op_misc.b @@ -3,8 +3,7 @@ nop(0xea) { } wdm(0x42) { -1:cpu_io(); - regs.pc.w++; +1:op_read(); } xba(0xeb) { diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 92777167..9d1a01f5 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -26,33 +26,37 @@ CPURegs regs; }; virtual uint8 pio_status() = 0; virtual void run() = 0; + virtual uint32 cycles_executed() = 0; virtual void scanline() = 0; virtual void frame() = 0; virtual void power() = 0; virtual void reset() = 0; //opcode disassembler - enum { - OPTYPE_DP = 0, //dp - OPTYPE_DPX, //dp,x - OPTYPE_DPY, //dp,y - OPTYPE_IDP, //(dp) - OPTYPE_IDPX, //(dp,x) - OPTYPE_IDPY, //(dp),y - OPTYPE_ILDP, //[dp] - OPTYPE_ILDPY, //[dp],y - OPTYPE_ADDR, //addr - OPTYPE_ADDRX, //addr,x - OPTYPE_ADDRY, //addr,y - OPTYPE_IADDRX, //(addr,x) - OPTYPE_ILADDR, //[addr] - OPTYPE_LONG, //long - OPTYPE_LONGX, //long, x - OPTYPE_SR, //sr,s - OPTYPE_ISRY, //(sr,s),y - OPTYPE_ADDR_PC, //pbr:addr - OPTYPE_IADDR_PC //pbr:(addr) - }; +enum { + OPTYPE_DP = 0, //dp + OPTYPE_DPX, //dp,x + OPTYPE_DPY, //dp,y + OPTYPE_IDP, //(dp) + OPTYPE_IDPX, //(dp,x) + OPTYPE_IDPY, //(dp),y + OPTYPE_ILDP, //[dp] + OPTYPE_ILDPY, //[dp],y + OPTYPE_ADDR, //addr + OPTYPE_ADDRX, //addr,x + OPTYPE_ADDRY, //addr,y + OPTYPE_IADDRX, //(addr,x) + OPTYPE_ILADDR, //[addr] + OPTYPE_LONG, //long + OPTYPE_LONGX, //long, x + OPTYPE_SR, //sr,s + OPTYPE_ISRY, //(sr,s),y + OPTYPE_ADDR_PC, //pbr:addr + OPTYPE_IADDR_PC //pbr:(addr) +}; +//see dcpu.cpp for notes on this function + virtual bool in_opcode(); + void disassemble_opcode(char *output); uint32 resolve_offset(uint8 offset_type, uint32 addr); uint8 opcode_length(); diff --git a/src/cpu/cpuregs.h b/src/cpu/cpuregs.h index 215ef2eb..7fa4c078 100644 --- a/src/cpu/cpuregs.h +++ b/src/cpu/cpuregs.h @@ -82,6 +82,7 @@ CPUReg24 pc; CPUReg16 a, x, y, s, d; CPURegFlags p; uint8 db; +uint8 mdr; //memory data register (openbus) bool e; - CPURegs() { db = 0; e = false; } + CPURegs() { db = 0; mdr = 0x00; e = false; } }; diff --git a/src/cpu/dcpu.cpp b/src/cpu/dcpu.cpp index 26137d2d..be6896d0 100644 --- a/src/cpu/dcpu.cpp +++ b/src/cpu/dcpu.cpp @@ -1,3 +1,17 @@ +//this is a virtual function. +//in opcode-based CPU emulators, the main emulation routine +//will only be able to call the disassemble_opcode() function +//on clean opcode edges. but with cycle-based CPU emulators, +//the CPU may be in the middle of executing an opcode when the +//emulator (e.g. debugger) wants to disassemble an opcode. this +//would mean that important registers may not reflect what they +//did at the start of the opcode (especially regs.pc), so in +//cycle-based emulators, this function should be overridden to +//reflect whether or not an opcode has only been partially +//executed. if not, the debugger should abort attempts to skip, +//disable, or disassemble the current opcode. +bool CPU::in_opcode() { return false; } + uint16 CPU::__relb(int8 offset) { uint32 addr; addr = (regs.pc.d & 0xff0000) | ((regs.pc.d + 2) & 0xffff); @@ -81,16 +95,24 @@ uint32 r = 0; } void CPU::disassemble_opcode(char *output) { -char *s = output; +char *s; char t[256]; uint8 op, op0, op1, op2; - sprintf(s, "%0.6x ", regs.pc.d); +static CPUReg24 pc; + s = output; -//TODO: This should wrap around the bank byte - op = mem_bus->read(regs.pc.d); - op0 = mem_bus->read(regs.pc.d + 1); - op1 = mem_bus->read(regs.pc.d + 2); - op2 = mem_bus->read(regs.pc.d + 3); + if(in_opcode() == true) { + strcpy(s, "?????? "); + return; + } + + pc.d = regs.pc.d; + sprintf(s, "%0.6x ", pc.d); + + op = mem_bus->read(pc.d); pc.w++; + op0 = mem_bus->read(pc.d); pc.w++; + op1 = mem_bus->read(pc.d); pc.w++; + op2 = mem_bus->read(pc.d); switch(op) { case 0x00:sprintf(t, "brk #$%0.2x ", op0);break; @@ -431,6 +453,10 @@ static uint8 op_len_tbl[256] = { 6,2,2,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0xen 2,2,2,2, 3,2,2,2, 1,3,1,1, 3,3,3,4 //0xfn }; + if(in_opcode() == true) { + return 0; + } + op = mem_bus->read(regs.pc.d); len = op_len_tbl[op]; if(len == 5)return (regs.p.m)?2:3; diff --git a/src/interface.h b/src/interface.h index 0a6cedca..ca3281a7 100644 --- a/src/interface.h +++ b/src/interface.h @@ -21,10 +21,18 @@ extern PPU *ppu; #include "snes/snes.h" extern SNES *snes; +#include "chip/srtc/srtc.h" +#include "chip/sdd1/sdd1.h" +extern SRTC *srtc; +extern SDD1 *sdd1; + #ifdef INTERFACE_MAIN MemBus *mem_bus; CPU *cpu; APU *apu; PPU *ppu; SNES *snes; + + SRTC *srtc; + SDD1 *sdd1; #endif diff --git a/src/lib/libbase.h b/src/lib/libbase.h index ed7810d9..55648c03 100644 --- a/src/lib/libbase.h +++ b/src/lib/libbase.h @@ -1,5 +1,5 @@ /* - libbase : version 0.01 ~byuu + libbase : version 0.03 ~byuu (08/20/05) */ #ifndef __LIBBASE @@ -10,10 +10,21 @@ #include #include +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +typedef unsigned int uint; + typedef unsigned char byte; typedef unsigned short word; typedef unsigned long ulong; +typedef unsigned char bool8; typedef unsigned char uint8; typedef unsigned short uint16; typedef unsigned long uint32; diff --git a/src/lib/libconfig.cpp b/src/lib/libconfig.cpp index 247ea6f2..f4d43221 100644 --- a/src/lib/libconfig.cpp +++ b/src/lib/libconfig.cpp @@ -1,21 +1,6 @@ #include "libbase.h" #include "libconfig.h" -//if this function returns true, the option is written -//to the configuration file. by always returning true, -//every option is always written. disable the first line -//to only output options after they have been changed by -//the program from their default values first. -bool config_item::changed() { - return true; - - if(is_string == true) { - if(!strcmp(*strsource, strdef))return false; - return true; - } - return (*source != def); -} - config_item::config_item() { strcpy(name, ""); strcpy(strdef, ""); @@ -67,34 +52,6 @@ uint32 config::find(char *name) { return null; } -uint32 config::get(char *name) { -int i = find(name); - if(i == null)return 0; - return *item[i]->source; -} - -string &config::strget(char *name) { -int i = find(name); - if(i == null) { - static string not_found; - strcmp(not_found, ""); - return not_found; - } - return *item[i]->strsource; -} - -void config::set(char *name, uint32 value) { -int i = find(name); - if(i == null)return; - *item[i]->source = value; -} - -void config::set(char *name, char *value) { -int i = find(name); - if(i == null)return; - strcpy(*item[i]->strsource, value); -} - void config::load(char *fn) { FILE *fp; char *buffer; @@ -130,8 +87,8 @@ uint32 l; qreplace(line[i], " ", ""); //remove comment, if it exists - if(strqpos(line[i], "#") != null) { - strset(line[i], strqpos(line[i], "#"), 0); + if(qstrpos(line[i], "#") != null) { + strset(line[i], qstrpos(line[i], "#"), 0); } //ignore blank lines @@ -139,7 +96,7 @@ uint32 l; qsplit(part, "=", line[i]); - l = find(*part[0]); + l = find(strptr(part[0])); if(l != null) { //if the config item name is valid... update item value if(item[l]->is_string == true) { @@ -153,7 +110,7 @@ uint32 l; !strcmp(part[1], "off") || !strcmp(part[1], "disabled")) { *item[l]->source = 0; } else if(item[l]->type == HEX) { - *item[l]->source = strhex(*part[1] + 2); //skip 0x prefix + *item[l]->source = strhex(strptr(part[1]) + 2); //skip 0x prefix } else { /* fall back on DEC */ *item[l]->source = strdec(part[1]); } @@ -161,6 +118,7 @@ uint32 l; } } } +void config::load(substring &fn) { load(strptr(fn)); } //create a text string from config item[i] to be output via config->save() void config::set_newline(int i) { @@ -246,8 +204,8 @@ bool blank = false; for(i=0;ichanged() == false)continue; set_newline(i); //prevent a newline from appearing at the top of the file //when the config file is created for the first time if(lines_written == 0 && blank == false)fprintf(fp, "\r\n"); - fprintf(fp, "%s\r\n", *newline); + fprintf(fp, "%s\r\n", strptr(newline)); lines_written++; } fclose(fp); } +void config::save(substring &fn) { save(strptr(fn)); } config::config() { item_count = 0; diff --git a/src/lib/libconfig.h b/src/lib/libconfig.h index 57373799..de553388 100644 --- a/src/lib/libconfig.h +++ b/src/lib/libconfig.h @@ -1,5 +1,5 @@ /* - libconfig : version 0.02 ~byuu + libconfig : version 0.03 ~byuu (08/20/05) */ #ifndef __LIBCONFIG @@ -13,7 +13,6 @@ uint32 *source, def, type; string *strsource, strdef; bool is_string; string name; - bool changed(); config_item(); }; @@ -35,13 +34,10 @@ enum { void add(uint32 *variable, char *name, uint32 def, uint32 type = DEC); void add(string *variable, char *name, char *def, uint32 type = STR); uint32 find(char *name); - uint32 get(char *name); - string &strget(char *name); - void set(char *name, uint32 value); - void set(char *name, char *value); - void load(char *fn); + void load(substring &fn); void save(char *fn); + void save(substring &fn); void set_newline(int i); config(); diff --git a/src/lib/libstring.cpp b/src/lib/libstring.cpp index 97e66b71..288541d9 100644 --- a/src/lib/libstring.cpp +++ b/src/lib/libstring.cpp @@ -1,23 +1,26 @@ #include "libbase.h" #include "libstring.h" -_string::_string() { +substring::substring() { size = 16; s = (char*)malloc(size + 1); *s = 0; } -_string::~_string() { - free(s); -} - -void string::addto(uint32 num) { - while(listcount < (num + 1)) { - list[listcount++] = new _string(); +substring::~substring() { + if(s) { + free(s); + s = 0; } } -_string &string::str(uint32 num) { +void string::addto(uint num) { + while(listcount < (num + 1)) { + list[listcount++] = new substring(); + } +} + +substring &string::str(uint num) { if(listcount < (num + 1)) { addto(num); } return *list[num]; } @@ -31,60 +34,68 @@ string::string() { string::~string() { int i; for(i=listcount-1;i>=0;i--) { - delete((_string*)list[i]); + delete((substring*)list[i]); } } -uint32 count(string &str) { - return str.count; +char chrlower(char c) { + if(c >= 'A' && c <= 'Z')return c + ('a' - 'A'); + return c; } -void strresize(_string &str, uint32 size) { -char *t; -int sl; - if(str.size == size)return; - sl = strlen(str.s); - t = (char*)malloc(size + 1); - strcpy(t, str.s); - free(str.s); - str.s = t; +char chrupper(char c) { + if(c >= 'a' && c <= 'z')return c - ('a' - 'A'); + return c; +} + +uint count(string &str) { return str.count; } + +void strresize(substring &str, uint size) { + str.s = (char*)realloc(str.s, size + 1); + str.s[size] = 0; str.size = size; } -char *strptr(_string &str) { - return str.s; -} +char *strptr(substring &str) { return str.s; } -void strcpy(_string &dest, char *src) { +uint strlen(substring &str) { return strlen(strptr(str)); } + +int strcmp(substring &dest, const char *src) { return strcmp(strptr(dest), src); } +int strcmp(const char *dest, substring &src) { return strcmp(dest, strptr(src)); } +int strcmp(substring &dest, substring &src) { return strcmp(strptr(dest), strptr(src)); } + +void strcpy(substring &dest, const char *src) { int srclen = strlen(src); if(srclen > dest.size) { strresize(dest, srclen); } strcpy(dest.s, src); } +void strcpy(substring &dest, substring &src) { strcpy(dest, strptr(src)); } -void strset(_string &dest, uint32 pos, uint8 c) { +void strset(substring &dest, uint pos, uint8 c) { char *s; if(pos > dest.size) { strresize(dest, pos); } dest.s[pos] = c; } -void strcat(_string &dest, char *src) { +void strcat(substring &dest, const char *src) { int srclen, destlen; srclen = strlen(src); destlen = strlen(dest.s); if(srclen + destlen > dest.size) { strresize(dest, srclen + destlen); } strcat(dest.s, src); } +void strcat(substring &dest, substring &src) { strcat(dest, strptr(src)); } -void strinsert(_string &dest, char *src, uint32 pos) { -_string *s = new _string(); - strcpy(*s, strptr(dest) + pos); +void strinsert(substring &dest, const char *src, uint pos) { +static substring s; + strcpy(s, strptr(dest) + pos); strset(dest, pos, 0); strcat(dest, src); - strcat(dest, *s); - delete(s); + strcat(dest, s); } +void strinsert(substring &dest, substring &src, uint pos) { strinsert(dest, strptr(src), pos); } -void strremove(_string &dest, uint32 start, uint32 length) { +void strremove(substring &dest, uint start, uint length) { int destlen; char *s; int i, sl = strlen(dest.s); @@ -98,36 +109,35 @@ int i, sl = strlen(dest.s); s[i] = 0; } -bool stricmp(char *dest, char *src) { -int i, sl = strlen(dest); - if(sl != strlen(src))return false; - for(i=0;i= 'A' && dest[i] <= 'Z') { - if(dest[i] != src[i] && dest[i] + 0x20 != src[i])return false; - } else if(dest[i] >='a' && dest[i] <= 'z') { - if(dest[i] != src[i] && dest[i] - 0x20 != src[i])return false; - } else { - if(dest[i] != src[i])return false; - } +int __stricmp(const char *dest, const char *src) { + while(*dest && *src) { + if(chrlower(*dest) != chrlower(*src))break; + dest++; + src++; } - return true; + return (int)chrlower(*dest) - (int)chrlower(*src); } +int stricmp(substring &dest, const char *src) { return __stricmp(strptr(dest), src); } +int stricmp(const char *dest, substring &src) { return __stricmp(dest, strptr(src)); } +int stricmp(substring &dest, substring &src) { return __stricmp(strptr(dest), strptr(src)); } void strlower(char *str) { -int i, sl = strlen(str); - for(i=0;i= 'A' && str[i] <= 'Z')str[i] += 0x20; + while(*str) { + *str = chrlower(*str); + str++; } } +void strlower(substring &str) { strlower(strptr(str)); } void strupper(char *str) { -int i, sl = strlen(str); - for(i=0;i= 'a' && str[i] <= 'z')str[i] -= 0x20; + while(*str) { + *str = chrupper(*str); + str++; } } +void strupper(substring &str) { strupper(strptr(str)); } -uint32 strpos(char *str, char *key) { +uint strpos(const char *str, const char *key) { int i, ssl = strlen(str), ksl = strlen(key); if(ksl > ssl)return null; for(i=0;i<=ssl-ksl;i++) { @@ -135,8 +145,11 @@ int i, ssl = strlen(str), ksl = strlen(key); } return null; } +uint strpos(substring &str, const char *key) { return strpos(strptr(str), key); } +uint strpos(const char *str, substring &key) { return strpos(str, strptr(key)); } +uint strpos(substring &str, substring &key) { return strpos(strptr(str), strptr(key)); } -uint32 strqpos(char *str, char *key) { +uint qstrpos(const char *str, const char *key) { int i, z, ssl = strlen(str), ksl = strlen(key); uint8 x; if(ksl > ssl)return null; @@ -155,8 +168,11 @@ uint8 x; } return null; } +uint qstrpos(substring &str, const char *key) { return qstrpos(strptr(str), key); } +uint qstrpos(const char *str, substring &key) { return qstrpos(str, strptr(key)); } +uint qstrpos(substring &str, substring &key) { return qstrpos(strptr(str), strptr(key)); } -void strtr(char *dest, char *before, char *after) { +void strtr(char *dest, const char *before, const char *after) { int i, l, sl = strlen(dest), bsl = strlen(before), asl = strlen(after); if((bsl != asl) || bsl == 0)return; for(i=0;i ssl)return 1; if(!memcmp(str, key, ksl))return 0; return 1; } +uint strbegin(substring &str, const char *key) { return strbegin(strptr(str), key); } -uint32 stribegin(char *str, char *key) { +uint stribegin(const char *str, const char *key) { int i, ssl = strlen(str), ksl = strlen(key); if(ksl > ssl)return 1; for(i=0;i ssl)return 1; if(!memcmp(str + ssl - ksl, key, ksl))return 0; return 1; } +uint strend(substring &str, const char *key) { return strend(strptr(str), key); } -uint32 striend(char *str, char *key) { +uint striend(const char *str, const char *key) { int i, z, ssl = strlen(str), ksl = strlen(key); if(ksl > ssl)return 1; for(i=ssl-ksl, z=0;i ssl)return; if(!strbegin(str, key)) { @@ -218,8 +239,9 @@ int i, ssl = strlen(str), ksl = strlen(key); str[i] = 0; } } +void strltrim(substring &str, const char *key) { strltrim(strptr(str), key); } -void striltrim(char *str, char *key) { +void striltrim(char *str, const char *key) { int i, ssl = strlen(str), ksl = strlen(key); if(ksl > ssl)return; if(!stribegin(str, key)) { @@ -227,25 +249,28 @@ int i, ssl = strlen(str), ksl = strlen(key); str[i] = 0; } } +void striltrim(substring &str, const char *key) { striltrim(strptr(str), key); } -void strrtrim(char *str, char *key) { +void strrtrim(char *str, const char *key) { int ssl = strlen(str), ksl = strlen(key); if(ksl > ssl)return; if(!strend(str, key)) { str[ssl - ksl] = 0; } } +void strrtrim(substring &str, const char *key) { strrtrim(strptr(str), key); } -void strirtrim(char *str, char *key) { +void strirtrim(char *str, const char *key) { int ssl = strlen(str), ksl = strlen(key); if(ksl > ssl)return; if(!striend(str, key)) { str[ssl - ksl] = 0; } } +void strirtrim(substring &str, const char *key) { strirtrim(strptr(str), key); } -/* does not work on type char* because function increases string length */ -void strquote(_string &str) { +//does not work on type char* because function increases string length +void strquote(substring &str) { static string t; strcpy(t, "\""); strcat(t, str); @@ -255,15 +280,15 @@ static string t; bool strunquote(char *str) { int i, ssl = strlen(str); -/* make sure string is long enough to have quotes */ +//make sure string is long enough to have quotes if(ssl < 2)return false; -/* make sure string actually has quotes */ +//make sure string actually has quotes if(str[0] == '\"' && str[ssl - 1] == '\"'); else if(str[0] == '\'' && str[ssl - 1] == '\''); else return false; -/* now remove them */ +//now remove them for(i=0;i= '0' && str[i] <= '9'); - else if(str[i] == '-' && i == 0); else break; } for(--i;i>=0;i--, m*=10) { x = str[i]; if(x >= '0' && x <= '9')x -= '0'; - else if(i == 0 && str[i] == '-') { - r *= -1; - return r; - } else return r; r += x * m; } return r; } +uint strdec(substring &str) { return strdec(strptr(str)); } -uint32 strbin(char *str) { -uint32 r = 0, m = 0; +int sstrdec(const char *str) { + if(str[0] == '-') { + return -strdec(str + 1); + } + return strdec(str); +} +int sstrdec(substring &str) { return sstrdec(strptr(str)); } + +uint strbin(const char *str) { +uint r = 0, m = 0; int i, ssl = strlen(str); uint8 x; for(i=0;i list; -uint32 count, listcount; - void addto(uint32 num); //creates all needed strings to make list[num] valid - _string &str(uint32 num); //gets a _string reference, creating it + new strings if needed +vector list; +uint listcount, count; + void addto(uint num); //creates all needed strings to make list[num] valid + substring &str(uint num); //gets a substring reference, creating it + new strings if needed - inline char* operator*() { return strptr(str(0)); } - -#ifdef __LIBSTRING_OVERLOADS - inline string& operator=(char *cpy); - inline string& operator=(_string &cpy); - inline string& operator=(string &cpy); - - inline string& operator+=(char *cat); - inline string& operator+=(_string &cat); - inline string& operator+=(string &cat); - - inline string& operator-=(char *cut); - inline string& operator-=(_string &cut); - inline string& operator-=(string &cut); - - inline bool operator==(char *cmp); - inline bool operator==(_string &cmp); - inline bool operator==(string &cmp); - - inline bool operator!=(char *cmp); - inline bool operator!=(_string &cmp); - inline bool operator!=(string &cmp); -#endif - - inline operator char*() { return str(0).s; } - inline operator _string&() { return str(0); } - inline _string& operator[](uint32 i) { return str(i); } - inline _string& operator[](int i) { return str(i); } +//inline char* operator*() { return strptr(str(0)); } +//inline operator char*() { return str(0).s; } + inline operator substring&() { return str(0); } + inline substring& operator[](uint i) { return str(i); } + inline substring& operator[](uint8 i) { return str(i); } + inline substring& operator[](uint16 i) { return str(i); } + inline substring& operator[](uint32 i) { return str(i); } + inline substring& operator[](int i) { return str(i); } + inline substring& operator[](int8 i) { return str(i); } + inline substring& operator[](int16 i) { return str(i); } + inline substring& operator[](int32 i) { return str(i); } string(); ~string(); }; -#ifdef __LIBSTRING_OVERLOADS -inline _string& _string::operator=(char *cpy) { - strcpy(*this, cpy); - return *this; -} -inline _string& _string::operator=(_string &cpy) { - strcpy(*this, cpy); - return *this; -} -inline _string& _string::operator=(string &cpy) { - strcpy(*this, cpy.str(0)); - return *this; -} - -inline string& string::operator=(char *cpy) { - strcpy(str(0), cpy); - return *this; -} -inline string& string::operator=(_string &cpy) { - strcpy(str(0), cpy); - return *this; -} -inline string& string::operator=(string &cpy) { - strcpy(str(0), cpy.str(0)); - return *this; -} - -inline _string& _string::operator+=(char *cat) { - strcat(*this, cat); - return *this; -} -inline _string& _string::operator+=(_string &cat) { - strcat(*this, cat); - return *this; -} -inline _string& _string::operator+=(string &cat) { - strcat(*this, cat.str(0)); - return *this; -} - -inline string& string::operator+=(char *cat) { - strcat(str(0), cat); - return *this; -} -inline string& string::operator+=(_string &cat) { - strcat(str(0), cat); - return *this; -} -inline string& string::operator+=(string &cat) { - strcat(str(0), cat.str(0)); - return *this; -} - -inline _string& _string::operator-=(char *cut) { - strrtrim(*this, cut); - return *this; -} -inline _string& _string::operator-=(_string &cut) { - strrtrim(*this, cut); - return *this; -} -inline _string& _string::operator-=(string &cut) { - strrtrim(*this, cut.str(0)); - return *this; -} - -inline string& string::operator-=(char *cut) { - strrtrim(str(0), cut); - return *this; -} -inline string& string::operator-=(_string &cut) { - strrtrim(str(0), cut); - return *this; -} -inline string& string::operator-=(string &cut) { - strrtrim(str(0), cut.str(0)); - return *this; -} - -inline bool _string::operator==(char *cmp) { - if(!strcmp(*this, cmp))return true; - return false; -} -inline bool _string::operator==(_string &cmp) { - if(!strcmp(*this, cmp))return true; - return false; -} -inline bool _string::operator==(string &cmp) { - if(!strcmp(*this, cmp.str(0)))return true; - return false; -} - -inline bool string::operator==(char *cmp) { - if(!strcmp(str(0), cmp))return true; - return false; -} -inline bool string::operator==(_string &cmp) { - if(!strcmp(str(0), cmp))return true; - return false; -} -inline bool string::operator==(string &cmp) { - if(!strcmp(str(0), cmp.str(0)))return true; - return false; -} - -inline bool _string::operator!=(char *cmp) { - if(!strcmp(*this, cmp))return false; - return true; -} -inline bool _string::operator!=(_string &cmp) { - if(!strcmp(*this, cmp))return false; - return true; -} -inline bool _string::operator!=(string &cmp) { - if(!strcmp(*this, cmp.str(0)))return false; - return true; -} - -inline bool string::operator!=(char *cmp) { - if(!strcmp(str(0), cmp))return false; - return true; -} -inline bool string::operator!=(_string &cmp) { - if(!strcmp(str(0), cmp))return false; - return true; -} -inline bool string::operator!=(string &cmp) { - if(!strcmp(str(0), cmp.str(0)))return false; - return true; -} -#endif //__LIBSTRING_OVERLOADS - #endif //__LIBSTRING diff --git a/src/lib/libstring_math.cpp b/src/lib/libstring_math.cpp index e2c26697..07d969c4 100644 --- a/src/lib/libstring_math.cpp +++ b/src/lib/libstring_math.cpp @@ -43,10 +43,10 @@ strmath(str) str, and returns numerical result example: strmath("5+5")=10 ***************************************/ -uint32 p_strmath(char *str) { -int i = 0, ssl = strlen(str); +uint p_strmath(const char *str) { +int i = 0, ssl = strlen(str); +uint r, array[128], array_size = 0, z = 0; uint8 x, mode = 0; -uint32 r, array[128], array_size = 0, z = 0; uint8 array_gate[128]; char *s1; if(!ssl)return 0; @@ -95,11 +95,11 @@ char *s1; return r; } -uint32 strmath(char *in_str) { -uint32 r = 0; -uint32 pdepth = 0, cpdepth, maxpdepth = 0; -uint32 pstart, pend, spos; -int i, sc, sl = strlen(in_str); +uint strmath(const char *in_str) { +uint r = 0; +uint pdepth = 0, cpdepth, maxpdepth = 0; +uint pstart, pend, spos; +int i, sc, sl = strlen(in_str); char *str = (char*)malloc(sl + 1), *str0; char *pstr; char num[64]; @@ -165,13 +165,15 @@ char num[64]; free(str); return r; } +uint strmath(substring &in_str) { return strmath(strptr(in_str)); } -uint32 strmathentity(char *str) { +bool strmathentity(const char *str) { int i, ssl = strlen(str); for(i=0;i' && str[i+1] == '>'))return 1; + (str[i] == '<' && str[i+1] == '<') || (str[i] == '>' && str[i+1] == '>'))return true; } - return 0; + return false; } +bool strmathentity(substring &str) { return strmathentity(strptr(str)); } diff --git a/src/lib/libstring_replace.cpp b/src/lib/libstring_replace.cpp index 9857ec16..88df3c91 100644 --- a/src/lib/libstring_replace.cpp +++ b/src/lib/libstring_replace.cpp @@ -1,6 +1,6 @@ -void replace(_string &str, char *key, char *token) { -int i, z, ksl = strlen(key), tsl = strlen(token), ssl = strlen(str); -uint32 replace_count = 0, size = ssl; +void replace(substring &str, const char *key, const char *token) { +int i, z, ksl = strlen(key), tsl = strlen(token), ssl = strlen(str); +uint replace_count = 0, size = ssl; char *data; if(ksl > ssl)return; if(tsl > ksl) { //the new string may be longer than the old string... @@ -27,11 +27,12 @@ char *data; strcpy(str, data); free(data); } +void replace(substring &str, const char *key, substring &token) { replace(str, key, strptr(token)); } -void qreplace(_string &str, char *key, char *token) { -int i, l, z, ksl = strlen(key), tsl = strlen(token), ssl = strlen(str); +void qreplace(substring &str, const char *key, const char *token) { +int i, l, z, ksl = strlen(key), tsl = strlen(token), ssl = strlen(str); +uint replace_count = 0, size = ssl; uint8 x; -uint32 replace_count = 0, size = ssl; char *data; if(ksl > ssl)return; if(tsl > ksl) { @@ -80,3 +81,4 @@ char *data; strcpy(str, data); free(data); } +void qreplace(substring &str, const char *key, substring &token) { qreplace(str, key, strptr(token)); } diff --git a/src/lib/libstring_split.cpp b/src/lib/libstring_split.cpp index 1e2eefbe..e0b1ae44 100644 --- a/src/lib/libstring_split.cpp +++ b/src/lib/libstring_split.cpp @@ -1,7 +1,7 @@ -void split(string &dest, char *key, char *src) { -int i, ssl = strlen(src), ksl = strlen(key); +void split(string &dest, const char *key, char *src) { +int i, ssl = strlen(src), ksl = strlen(key); +uint lp = 0, split_count = 0; uint8 x; -uint32 lp = 0, split_count = 0; for(i=0;i<=ssl-ksl;) { if(!memcmp(src + i, key, ksl)) { x = src[i]; @@ -15,11 +15,12 @@ uint32 lp = 0, split_count = 0; strcpy(dest[split_count++], src + lp); dest.count = split_count; } +void split(string &dest, const char *key, substring &src) { split(dest, key, strptr(src)); } -void qsplit(string &dest, char *key, char *src) { -int i, z, ssl = strlen(src), ksl = strlen(key); +void qsplit(string &dest, const char *key, char *src) { +int i, z, ssl = strlen(src), ksl = strlen(key); +uint lp = 0, split_count = 0; uint8 x; -uint32 lp = 0, split_count = 0; for(i=0;i<=ssl-ksl;) { x = src[i]; if(x=='\"' || x=='\'') { @@ -39,3 +40,4 @@ uint32 lp = 0, split_count = 0; strcpy(dest[split_count++], src + lp); dest.count = split_count; } +void qsplit(string &dest, const char *key, substring &src) { qsplit(dest, key, strptr(src)); } diff --git a/src/lib/libstring_sprintf.cpp b/src/lib/libstring_sprintf.cpp index d1c0ab40..0844a2b7 100644 --- a/src/lib/libstring_sprintf.cpp +++ b/src/lib/libstring_sprintf.cpp @@ -1,5 +1,5 @@ -void numtobin(char *s, uint32 num) { -uint32 mask = 0x80000000, len = 0, z = 0; +void numtobin(char *s, uint num) { +uint mask = 0x80000000, len = 0, z = 0; for(;mask;mask>>=1,len++) { if(num&mask)break; } len = 32 - len; do { @@ -9,7 +9,7 @@ uint32 mask = 0x80000000, len = 0, z = 0; s[z] = 0; } -void sprintf(_string &str, char *s, ...) { +void sprintf(substring &str, const char *s, ...) { va_list args; char t[2], n[256]; int i, l, sl, z; @@ -17,7 +17,7 @@ uint8 pad_type, pad_len; uint32 num; char *r; va_start(args, s); - strcpy(*str, ""); + strcpy(str, ""); for(i=0;i class vector { -public: +private: T *array; int size, sizelimit; +//find next array size that is a power of two int findsize(int newsize) { int r = 1; while(r >= 1) { r <<= 1; - if(r > sizelimit)return sizelimit; - if(r >= newsize)return r; + if(r > sizelimit)return sizelimit; + if(r >= newsize) return r; } return size; } +public: void resize(int newsize) { - T *newarray; newsize = findsize(newsize); if(newsize > sizelimit)newsize = sizelimit; if(newsize == size)return; - newarray = (T*)malloc(sizeof(T) * newsize); - if(newsize >= size) { - memcpy(newarray, array, sizeof(T) * size); - } else { - memcpy(newarray, array, sizeof(T) * newsize); - } - free(array); + array = (T*)realloc(array, sizeof(T) * newsize); - array = newarray; - size = newsize; + if(newsize > size) { + for(int i=size;i= size)resize(index + 1); if(index > sizelimit)return array[size - 1]; diff --git a/src/memory/bmemory/bcart_exlorom.cpp b/src/memory/bmemory/bcart_exlorom.cpp new file mode 100644 index 00000000..5957e21c --- /dev/null +++ b/src/memory/bmemory/bcart_exlorom.cpp @@ -0,0 +1,106 @@ +void bCartExLoROM::write_protect(bool r) { write_protected = r; } + +uint8 bCartExLoROM::read(uint32 addr) { +uint32 b, w; + addr &= 0xffffff; + b = (addr >> 16); + w = (addr & 0xffff); + +//SRAM Region A + if((b & 0x7f) >= 0x30 && (b & 0x7f) <= 0x3f && (w & 0xe000) == 0x6000) { + b &= 0x7f; + if(b >= 0x30 && b <= 0x3f) { + if(sram_size) { + addr = (b - 0x30) * 0x2000 + (w - 0x6000); + addr &= (sram_size - 1); + return sram[addr]; + } else { + return 0x00; //no SRAM available + } + } else { + return 0x00; //unmapped + } + } + +//SRAM Region B + if(b >= 0x70 && b <= 0x7d) { + if(sram_size) { + addr = (addr & 0xffffff) - 0x700000; + addr &= (sram_size - 1); + return sram[addr]; + } else { + return 0x00; //no SRAM available + } + } + + if(b <= 0x3f) { + addr = (b << 15) | (addr & 0x7fff); + } else if(b <= 0x7f) { + addr &= 0x3fffff; + } else if(b <= 0xbf) { + b &= 0x7f; + addr = (b << 15) | (addr & 0x7fff); + } else { + addr = sdd1->offset(addr); + } + + if(addr < rom_size)return rom[addr]; + return 0x00; +} + +void bCartExLoROM::write(uint32 addr, uint8 value) { +uint32 b, w; + addr &= 0xffffff; + b = (addr >> 16); + w = (addr & 0xffff); + +//SRAM Region A + if((b & 0x7f) >= 0x30 && (b & 0x7f) <= 0x3f && (w & 0xe000) == 0x6000) { + b &= 0x7f; + if(b >= 0x30 && b <= 0x3f) { + if(sram_size) { + addr = (b - 0x30) * 0x2000 + (w - 0x6000); + addr &= (sram_size - 1); + sram[addr] = value; + return; + } else { + return; //no SRAM available + } + } else { + return; //unmapped + } + } + +//SRAM Region B + if(b >= 0x70 && b <= 0x7d) { + if(sram_size) { + addr = (addr & 0xffffff) - 0x700000; + addr &= (sram_size - 1); + sram[addr] = value; + } else { + return; //no SRAM available + } + } + + if(write_protected == true)return; + + if(b <= 0x3f) { + addr = (b << 15) | (addr & 0x7fff); + } else if(b <= 0x7f) { + addr &= 0x3fffff; + } else if(b <= 0xbf) { + b &= 0x7f; + addr = (b << 15) | (addr & 0x7fff); + } else { + addr = sdd1->offset(addr); + } + + if(addr < rom_size)rom[addr] = value; +} + +void bCartExLoROM::set_cartinfo(CartInfo *ci) { + rom = ci->rom; + sram = ci->sram; + rom_size = ci->rom_size; + sram_size = ci->sram_size; +} diff --git a/src/memory/bmemory/bcart_exlorom.h b/src/memory/bmemory/bcart_exlorom.h new file mode 100644 index 00000000..a3996a05 --- /dev/null +++ b/src/memory/bmemory/bcart_exlorom.h @@ -0,0 +1,14 @@ +class bCartExLoROM : public Cart { +private: +bool write_protected; + +public: +uint8 *rom, *sram; +uint32 rom_size, sram_size; + uint8 read (uint32 addr); + void write(uint32 addr, byte value); + void write_protect(bool r); + void set_cartinfo(CartInfo *ci); + + bCartExLoROM() : write_protected(true) {} +}; diff --git a/src/memory/bmemory/bcart_hirom.cpp b/src/memory/bmemory/bcart_hirom.cpp index 3bbc9e53..175c4d88 100644 --- a/src/memory/bmemory/bcart_hirom.cpp +++ b/src/memory/bmemory/bcart_hirom.cpp @@ -33,10 +33,13 @@ uint32 b, w; } } - addr &= 0x3fffff; - if(addr < rom_size)return rom[addr]; + addr &= ROM_mask; - return 0x00; + if(addr >= P0_size) { + addr = P0_size + (addr & (P1_size - 1)); + } + + return rom[addr]; } void bCartHiROM::write(uint32 addr, uint8 value) { @@ -74,8 +77,14 @@ uint32 b, w; } if(write_protected == true)return; - addr &= 0x3fffff; - if(addr < rom_size)rom[addr] = value; + + addr &= ROM_mask; + + if(addr >= P0_size) { + addr = P0_size + (addr & (P1_size - 1)); + } + + rom[addr] = value; } void bCartHiROM::set_cartinfo(CartInfo *ci) { @@ -83,4 +92,15 @@ void bCartHiROM::set_cartinfo(CartInfo *ci) { sram = ci->sram; rom_size = ci->rom_size; sram_size = ci->sram_size; + +//calculate highest power of 2, which is the size of the first ROM chip + P0_size = 0x800000; + while(!(rom_size & P0_size))P0_size >>= 1; + P1_size = rom_size - P0_size; + + if(rom_size == P0_size) { //cart only contains one ROM chip + ROM_mask = (P0_size - 1); + } else { //cart contains two ROM chips + ROM_mask = (P0_size + P0_size - 1); + } } diff --git a/src/memory/bmemory/bcart_hirom.h b/src/memory/bmemory/bcart_hirom.h index cccce628..f8eba666 100644 --- a/src/memory/bmemory/bcart_hirom.h +++ b/src/memory/bmemory/bcart_hirom.h @@ -1,6 +1,7 @@ class bCartHiROM : public Cart { private: -bool write_protected; +bool write_protected; +uint32 P0_size, P1_size, ROM_mask; public: uint8 *rom, *sram; diff --git a/src/memory/bmemory/bcart_lorom.cpp b/src/memory/bmemory/bcart_lorom.cpp index 85ea74d7..59e43946 100644 --- a/src/memory/bmemory/bcart_lorom.cpp +++ b/src/memory/bmemory/bcart_lorom.cpp @@ -35,17 +35,20 @@ uint32 b, w; if(w & 0x8000) { b &= 0x7f; - b %= 0x60; addr = (b << 15) | (addr & 0x7fff); } else { b &= 0x7f; - b %= 0x60; - if(b == 0x00)b = 0x60; + if(b == 0x00)b = 0x7f; addr = (((b << 15) | (addr & 0x7fff)) - 0x8000); } - if(addr < rom_size)return rom[addr]; - return 0x00; + addr &= ROM_mask; + + if(addr >= P0_size) { + addr = P0_size + (addr & (P1_size - 1)); + } + + return rom[addr]; } void bCartLoROM::write(uint32 addr, uint8 value) { @@ -83,17 +86,23 @@ uint32 b, w; } if(write_protected == true)return; + if(w & 0x8000) { b &= 0x7f; - b %= 0x60; addr = (b << 15) | (addr & 0x7fff); } else { b &= 0x7f; - b %= 0x60; - if(b == 0x00)b = 0x60; + if(b == 0x00)b = 0x7f; addr = (((b << 15) | (addr & 0x7fff)) - 0x8000); } - if(addr < rom_size)rom[addr] = value; + + addr &= ROM_mask; + + if(addr >= P0_size) { + addr = P0_size + (addr & (P1_size - 1)); + } + + rom[addr] = value; } void bCartLoROM::set_cartinfo(CartInfo *ci) { @@ -101,4 +110,15 @@ void bCartLoROM::set_cartinfo(CartInfo *ci) { sram = ci->sram; rom_size = ci->rom_size; sram_size = ci->sram_size; + +//calculate highest power of 2, which is the size of the first ROM chip + P0_size = 0x800000; + while(!(rom_size & P0_size))P0_size >>= 1; + P1_size = rom_size - P0_size; + + if(rom_size == P0_size) { //cart only contains one ROM chip + ROM_mask = (P0_size - 1); + } else { //cart contains two ROM chips + ROM_mask = (P0_size + P0_size - 1); + } } diff --git a/src/memory/bmemory/bcart_lorom.h b/src/memory/bmemory/bcart_lorom.h index cf279308..8fdd058c 100644 --- a/src/memory/bmemory/bcart_lorom.h +++ b/src/memory/bmemory/bcart_lorom.h @@ -1,6 +1,7 @@ class bCartLoROM : public Cart { private: -bool write_protected; +bool write_protected; +uint32 P0_size, P1_size, ROM_mask; public: uint8 *rom, *sram; diff --git a/src/memory/bmemory/bmemory.cpp b/src/memory/bmemory/bmemory.cpp index 66cde60b..08a7ebf4 100644 --- a/src/memory/bmemory/bmemory.cpp +++ b/src/memory/bmemory/bmemory.cpp @@ -1,22 +1,36 @@ #include "../../base.h" #include "bcart_lorom.cpp" #include "bcart_hirom.cpp" +#include "bcart_exlorom.cpp" #include "bcart_exhirom.cpp" bool bMemBus::load_cart(Reader *rf) { uint32 cksum, icksum, index; char cart_title[24]; -uint8 mapper; +uint8 mapper, region; if(rom_loaded == true)return false; - rf->read(&rom); - + rf->read(&rom_image); + rom = rom_image; rom_size = rf->size(); - if(rom_size < 32768)return false; + if(rom_size < 32768) { + free(rom_image); + return false; + } + +//check for ROM header (currently unused) + if((rom_size & 0x1fff) == 0x0200) { + rom_size -= 512; + rom += 512; + } if(rom_size >= 0x410000) { - mapper = EXHIROM; + if(rom[0x7fd5] == 0x32) { + mapper = EXLOROM; + } else { + mapper = EXHIROM; + } goto end; } @@ -33,10 +47,17 @@ uint8 mapper; mapper = LOROM; } + if(rom[0x7fd5] == 0x32 && rom[0xffd5] == 0x32) { + //SFA2 detected + mapper = EXLOROM; + goto end; + } + end: switch(mapper) { case LOROM: index = 0x007fc0;break; case HIROM: index = 0x00ffc0;break; + case EXLOROM:index = 0x007fc0;break; case EXHIROM:index = 0x40ffc0;break; } memcpy(cart_title, (char*)rom + index, 21); @@ -53,7 +74,10 @@ end: case 7:sram_size = 128 * 1024;break; } + region = rom[index + 0x19]; + dprintf("* Image Name : \"%s\"", cart_title); + dprintf("* Region : %s", (region <= 1)?"NTSC":"PAL"); dprintf("* MAD : %0.2x", mapper); dprintf("* SRAM Size : %dkb", sram_size / 1024); dprintf("* Reset:%0.4x NMI:%0.4x IRQ:%0.4x BRK[n]:%0.4x COP[n]:%0.4x BRK[e]:%0.4x COP[e]:%0.4x", @@ -76,12 +100,20 @@ CartInfo ci; switch(mapper) { case LOROM: cart = new bCartLoROM(); break; case HIROM: cart = new bCartHiROM(); break; + case EXLOROM:cart = new bCartExLoROM();break; case EXHIROM:cart = new bCartExHiROM();break; default:return false; } cart->set_cartinfo(&ci); rom_loaded = true; + + if(region == 0 || region == 1) { + snes->set_region(SNES::NTSC); + } else { + snes->set_region(SNES::PAL); + } + return true; } @@ -108,7 +140,7 @@ bool bMemBus::save_sram(Writer *wf) { void bMemBus::unload_cart() { if(rom_loaded == false)return; - if(rom) free(rom); + if(rom_image)free(rom_image); if(sram)free(sram); delete(cart); diff --git a/src/memory/bmemory/bmemory.h b/src/memory/bmemory/bmemory.h index ae9831f9..5c633d9e 100644 --- a/src/memory/bmemory/bmemory.h +++ b/src/memory/bmemory/bmemory.h @@ -1,14 +1,21 @@ #include "bcart_lorom.h" #include "bcart_hirom.h" +#include "bcart_exlorom.h" #include "bcart_exhirom.h" class bMemBus : public MemBus { public: -uint8 *rom, *sram, *wram; + +//rom_image is the actual image, including header. +//rom is the image sans header, which is actually +//just a pointer to rom_image (with no header), or +//rom_image + 512 (if a header is present). +//rom should never be allocated or released directly. +uint8 *rom_image, *rom, *sram, *wram; uint32 rom_size, sram_size; bool rom_loaded; -enum { LOROM = 0x20, HIROM = 0x21, EXHIROM = 0x25 }; +enum { LOROM = 0x20, HIROM = 0x21, EXLOROM = 0x22, EXHIROM = 0x25 }; uint8 read (uint32 addr); void write(uint32 addr, byte value); diff --git a/src/memory/memory.cpp b/src/memory/memory.cpp index f144d5c5..4308c031 100644 --- a/src/memory/memory.cpp +++ b/src/memory/memory.cpp @@ -79,7 +79,7 @@ void Memory::write_long(uint32 addr, uint32 value, uint8 wrap) { } MMIO mmio_unmapped; -uint8 MMIO::read (uint32 addr) { return 0x00; } +uint8 MMIO::read (uint32 addr) { return cpu->regs.mdr; } void MMIO::write(uint32 addr, uint8 value) {} uint8 MemBus::speed(uint32 addr) { diff --git a/src/ppu/bppu/bppu.cpp b/src/ppu/bppu/bppu.cpp index 44868895..43ee573d 100644 --- a/src/ppu/bppu/bppu.cpp +++ b/src/ppu/bppu/bppu.cpp @@ -75,6 +75,9 @@ void bPPU::power() { memset(vram, 0, 65536); memset(oam, 0, 544); memset(cgram, 0, 512); + + region = snes->region(); + reset(); } @@ -84,6 +87,10 @@ void bPPU::reset() { memset(sprite_list, 0, sizeof(sprite_list)); +//open bus support + regs.ppu1_mdr = 0xff; + regs.ppu2_mdr = 0xff; + //$2100 regs.display_disabled = 0; regs.display_brightness = 0; @@ -133,6 +140,8 @@ void bPPU::reset() { regs.bg_tdaddr[BG4] = 0x0000; //$210d-$2114 + regs.bg_ofslatch = 0x00; + regs.m7_hofs = regs.m7_vofs = 0x0000; regs.bg_hofs[BG1] = regs.bg_vofs[BG1] = 0x0000; regs.bg_hofs[BG2] = regs.bg_vofs[BG2] = 0x0000; regs.bg_hofs[BG3] = regs.bg_vofs[BG3] = 0x0000; @@ -152,6 +161,7 @@ void bPPU::reset() { regs.mode7_hflip = false; //$211b-$2120 + regs.m7_latch = 0x00; regs.m7a = 0x0000; regs.m7b = 0x0000; regs.m7c = 0x0000; @@ -300,13 +310,21 @@ void bPPU::oam_write(uint16 addr, uint8 value) { uint8 bPPU::cgram_read(uint16 addr) { uint8 r; - r = cgram[addr & 511]; + addr &= 511; + r = cgram[addr]; + if(addr & 1) { + r &= 0x7f; + } snes->notify(SNES::CGRAM_READ, addr, r); return r; } void bPPU::cgram_write(uint16 addr, uint8 value) { - cgram[addr & 511] = value; + addr &= 511; + if(addr & 1) { + value &= 0x7f; + } + cgram[addr] = value; snes->notify(SNES::CGRAM_WRITE, addr, value); } @@ -326,31 +344,31 @@ bPPU::bPPU() { init_tiledata_cache(); -int i, l; -byte r, g, b; -double m; +int i, l; +uint8 r, g, b; +float m; uint16 *ptr; for(l=0;l<16;l++) { - mosaic_table[l] = (uint16*)memalloc(4096 * 2, "bPPU::mosaic_table[%2d]", l); + mosaic_table[l] = (uint16*)malloc(4096 * 2); for(i=0;i<4096;i++) { mosaic_table[l][i] = (i / (l + 1)) * (l + 1); } } - light_table = (uint16*)memalloc(16 * 65536 * 2, "bPPU::light_table"); - ptr = (word*)light_table; + light_table = (uint16*)malloc(16 * 32768 * 2); + ptr = (uint16*)light_table; for(l=0;l<16;l++) { - m = (double)l / 15.0; - for(i=0;i<65536;i++) { + m = (float)l / 15.0; + for(i=0;i<32768;i++) { r = (i ) & 31; g = (i >> 5) & 31; b = (i >> 10) & 31; if(l == 0) { r = g = b = 0; } else if(l == 15); else { - r = (uint8)((double)r * m); - g = (uint8)((double)g * m); - b = (uint8)((double)b * m); + r = (uint8)((float)r * m); + g = (uint8)((float)g * m); + b = (uint8)((float)b * m); } *ptr++ = (r) | (g << 5) | (b << 10); } @@ -360,14 +378,30 @@ uint16 *ptr; bPPU::~bPPU() { delete(mmio); - if(vram) memfree(vram, "bPPU::vram"); - if(oam) memfree(oam, "bPPU::oam"); - if(cgram)memfree(cgram, "bPPU::cgram"); + if(vram) { + free(vram); + vram = 0; + } + if(oam) { + free(oam); + oam = 0; + } + if(cgram) { + free(cgram); + cgram = 0; + } for(int i=0;i<16;i++) { - if(mosaic_table[i])memfree(mosaic_table[i], "bPPU::mosaic_table[%2d]", i); + if(mosaic_table[i]) { + free(mosaic_table[i]); + mosaic_table[i] = 0; + } + } + + if(light_table) { + memfree(light_table); + light_table = 0; } - if(light_table)memfree(light_table, "bPPU::light_table"); } bPPUMMIO::bPPUMMIO(bPPU *_ppu) { diff --git a/src/ppu/bppu/bppu.h b/src/ppu/bppu/bppu.h index 6a30848b..36c7740c 100644 --- a/src/ppu/bppu/bppu.h +++ b/src/ppu/bppu/bppu.h @@ -11,7 +11,9 @@ bPPU *ppu; class bPPU : public PPU { public: uint8 *vram, *oam, *cgram; +uint8 region; +enum { NTSC = 0, PAL = 1 }; enum { BG1 = 0, BG2 = 1, BG3 = 2, BG4 = 3, OAM = 4, BACK = 5 }; enum { SC_32x32 = 0, SC_32x64 = 1, SC_64x32 = 2, SC_64x64 = 3 }; @@ -31,6 +33,9 @@ struct { }settings; struct { +//open bus support + uint8 ppu1_mdr, ppu2_mdr; + //$2100 bool display_disabled; uint8 display_brightness; @@ -64,6 +69,8 @@ struct { uint16 bg_tdaddr[4]; //$210d-$2114 + uint8 bg_ofslatch; + uint16 m7_hofs, m7_vofs; uint16 bg_hofs[4]; uint16 bg_vofs[4]; @@ -81,6 +88,7 @@ struct { bool mode7_hflip; //$211b-$2120 + uint8 m7_latch; uint16 m7a, m7b, m7c, m7d, m7x, m7y; //$2121 diff --git a/src/ppu/bppu/bppu_mmio.cpp b/src/ppu/bppu/bppu_mmio.cpp index 2f81b8ea..c0dfdfd0 100644 --- a/src/ppu/bppu/bppu_mmio.cpp +++ b/src/ppu/bppu/bppu_mmio.cpp @@ -117,42 +117,56 @@ void bPPU::mmio_w210c(uint8 value) { //BG1HOFS void bPPU::mmio_w210d(uint8 value) { - regs.bg_hofs[BG1] = (value << 8) | (regs.bg_hofs[BG1] >> 8); + regs.m7_hofs = (value << 8) | regs.m7_latch; + regs.m7_latch = value; + + regs.bg_hofs[BG1] = (value << 8) | (regs.bg_ofslatch & 0xf8) | ((regs.bg_hofs[BG1] >> 8) & 7); + regs.bg_ofslatch = value; } //BG1VOFS void bPPU::mmio_w210e(uint8 value) { - regs.bg_vofs[BG1] = (value << 8) | (regs.bg_vofs[BG1] >> 8); + regs.m7_vofs = (value << 8) | regs.m7_latch; + regs.m7_latch = value; + + regs.bg_vofs[BG1] = (value << 8) | (regs.bg_ofslatch & 0xf8) | ((regs.bg_vofs[BG1] >> 8) & 7); + regs.bg_ofslatch = value; } //BG2HOFS void bPPU::mmio_w210f(uint8 value) { - regs.bg_hofs[BG2] = (value << 8) | (regs.bg_hofs[BG2] >> 8); + regs.bg_hofs[BG2] = (value << 8) | (regs.bg_ofslatch & 0xf8) | ((regs.bg_hofs[BG2] >> 8) & 7); + regs.bg_ofslatch = value; } //BG2VOFS void bPPU::mmio_w2110(uint8 value) { - regs.bg_vofs[BG2] = (value << 8) | (regs.bg_vofs[BG2] >> 8); + regs.bg_vofs[BG2] = (value << 8) | (regs.bg_ofslatch & 0xf8) | ((regs.bg_vofs[BG2] >> 8) & 7); + regs.bg_ofslatch = value; } //BG3HOFS void bPPU::mmio_w2111(uint8 value) { - regs.bg_hofs[BG3] = (value << 8) | (regs.bg_hofs[BG3] >> 8); + regs.bg_hofs[BG3] = (value << 8) | (regs.bg_ofslatch & 0xf8) | ((regs.bg_hofs[BG3] >> 8) & 7); + regs.bg_ofslatch = value; } //BG3VOFS void bPPU::mmio_w2112(uint8 value) { - regs.bg_vofs[BG3] = (value << 8) | (regs.bg_vofs[BG3] >> 8); + regs.bg_vofs[BG3] = (value << 8) | (regs.bg_ofslatch & 0xf8) | ((regs.bg_vofs[BG3] >> 8) & 7); + regs.bg_ofslatch = value; } //BG4HOFS void bPPU::mmio_w2113(uint8 value) { - regs.bg_hofs[BG4] = (value << 8) | (regs.bg_hofs[BG4] >> 8); + regs.bg_hofs[BG4] = (value << 8) | (regs.bg_ofslatch & 0xf8) | ((regs.bg_hofs[BG4] >> 8) & 7); + regs.bg_ofslatch = value; } //BG4VOFS void bPPU::mmio_w2114(uint8 value) { - regs.bg_vofs[BG4] = (value << 8) | (regs.bg_vofs[BG4] >> 8); + regs.bg_vofs[BG4] = (value << 8) | (regs.bg_ofslatch & 0xf8) | ((regs.bg_vofs[BG4] >> 8) & 7); + regs.bg_ofslatch = value; } //VMAIN @@ -210,38 +224,44 @@ uint16 addr = get_vram_address() + 1; //M7SEL void bPPU::mmio_w211a(uint8 value) { regs.mode7_repeat = (value >> 6) & 3; - regs.mode7_vflip = !!(value & 0x02); - regs.mode7_hflip = !!(value & 0x01); + regs.mode7_vflip = !!(value & 0x02); + regs.mode7_hflip = !!(value & 0x01); } //M7A void bPPU::mmio_w211b(uint8 value) { - regs.m7a = (value << 8) | (regs.m7a >> 8); + regs.m7a = (value << 8) | regs.m7_latch; + regs.m7_latch = value; } //M7B void bPPU::mmio_w211c(uint8 value) { - regs.m7b = (value << 8) | (regs.m7b >> 8); + regs.m7b = (value << 8) | regs.m7_latch; + regs.m7_latch = value; } //M7C void bPPU::mmio_w211d(uint8 value) { - regs.m7c = (value << 8) | (regs.m7c >> 8); + regs.m7c = (value << 8) | regs.m7_latch; + regs.m7_latch = value; } //M7D void bPPU::mmio_w211e(uint8 value) { - regs.m7d = (value << 8) | (regs.m7d >> 8); + regs.m7d = (value << 8) | regs.m7_latch; + regs.m7_latch = value; } //M7X void bPPU::mmio_w211f(uint8 value) { - regs.m7x = (value << 8) | (regs.m7x >> 8); + regs.m7x = (value << 8) | regs.m7_latch; + regs.m7_latch = value; } //M7Y void bPPU::mmio_w2120(uint8 value) { - regs.m7y = (value << 8) | (regs.m7y >> 8); + regs.m7y = (value << 8) | regs.m7_latch; + regs.m7_latch = value; } //CGADD @@ -250,7 +270,13 @@ void bPPU::mmio_w2121(uint8 value) { } //CGDATA +//note: CGRAM palette data format is 15-bits +//(0,bbbbb,ggggg,rrrrr). Highest bit is ignored, +//as evidenced by $213b CGRAM data reads. void bPPU::mmio_w2122(uint8 value) { + if(regs.cgram_addr & 1) { + value &= 0x7f; + } cgram_write(regs.cgram_addr, value); regs.cgram_addr++; regs.cgram_addr &= 0x01ff; @@ -404,21 +430,24 @@ void bPPU::mmio_w2133(uint8 value) { uint8 bPPU::mmio_r2134() { uint32 r; r = ((int16)regs.m7a * (int8)(regs.m7b >> 8)); - return (r); + regs.ppu1_mdr = r; + return regs.ppu1_mdr; } //MPYM uint8 bPPU::mmio_r2135() { uint32 r; r = ((int16)regs.m7a * (int8)(regs.m7b >> 8)); - return (r >> 8); + regs.ppu1_mdr = r >> 8; + return regs.ppu1_mdr; } //MPYH uint8 bPPU::mmio_r2136() { uint32 r; r = ((int16)regs.m7a * (int8)(regs.m7b >> 8)); - return (r >> 16); + regs.ppu1_mdr = r >> 16; + return regs.ppu1_mdr; } //SLHV @@ -426,70 +455,84 @@ uint8 bPPU::mmio_r2137() { if(cpu->pio_status() & 0x80) { latch_counters(); } - return 0x00; + return cpu->regs.mdr; } //OAMDATAREAD uint8 bPPU::mmio_r2138() { -uint8 r; - r = oam_read(regs.oam_addr); + regs.ppu1_mdr = oam_read(regs.oam_addr); if(!(regs.oam_addr & 1)) { - regs.oam_latchdata = r; + regs.oam_latchdata = regs.ppu1_mdr; } regs.oam_addr++; regs.oam_addr &= 0x03ff; - return r; + return regs.ppu1_mdr; } //VMDATALREAD uint8 bPPU::mmio_r2139() { uint16 addr = get_vram_address(); -uint8 r = regs.vram_readbuffer; + regs.ppu1_mdr = regs.vram_readbuffer; if(regs.vram_incmode == 0) { addr &= 0xfffe; regs.vram_readbuffer = vram_read(addr); regs.vram_readbuffer |= vram_read(addr + 1) << 8; regs.vram_addr += regs.vram_incsize; } - return r; + return regs.ppu1_mdr; } //VMDATAHREAD uint8 bPPU::mmio_r213a() { uint16 addr = get_vram_address() + 1; -uint8 r = regs.vram_readbuffer >> 8; + regs.ppu1_mdr = regs.vram_readbuffer >> 8; if(regs.vram_incmode == 1) { addr &= 0xfffe; regs.vram_readbuffer = vram_read(addr); regs.vram_readbuffer |= vram_read(addr + 1) << 8; regs.vram_addr += regs.vram_incsize; } - return r; + return regs.ppu1_mdr; } //CGDATAREAD +//note: CGRAM palette data is 15-bits (0,bbbbb,ggggg,rrrrr) +//therefore, the high byte read from each color does not +//update bit 7 of the PPU2 MDR. uint8 bPPU::mmio_r213b() { -uint8 r; - r = cgram_read(regs.cgram_addr); + if(!(regs.cgram_addr & 1)) { + regs.ppu2_mdr = cgram_read(regs.cgram_addr) & 0xff; + } else { + regs.ppu2_mdr &= 0x80; + regs.ppu2_mdr |= cgram_read(regs.cgram_addr) & 0x7f; + } regs.cgram_addr++; regs.cgram_addr &= 0x01ff; - return r; + return regs.ppu2_mdr; } //OPHCT uint8 bPPU::mmio_r213c() { -uint16 r = regs.hcounter; - if(regs.latch_hcounter)r >>= 8; + if(!regs.latch_hcounter) { + regs.ppu2_mdr = regs.hcounter & 0xff; + } else { + regs.ppu2_mdr &= 0xfe; + regs.ppu2_mdr |= (regs.hcounter >> 8) & 1; + } regs.latch_hcounter ^= 1; - return r; + return regs.ppu2_mdr; } //OPVCT uint8 bPPU::mmio_r213d() { -uint16 r = regs.vcounter; - if(regs.latch_vcounter)r >>= 8; + if(!regs.latch_vcounter) { + regs.ppu2_mdr = regs.vcounter & 0xff; + } else { + regs.ppu2_mdr &= 0xfe; + regs.ppu2_mdr |= (regs.vcounter >> 8) & 1; + } regs.latch_vcounter ^= 1; - return r; + return regs.ppu2_mdr; } //STAT77 @@ -498,7 +541,8 @@ uint8 r = 0x00; r |= (regs.time_over) ?0x80:0x00; r |= (regs.range_over)?0x40:0x00; r |= 0x01; //PPU1 version number - return r; + regs.ppu1_mdr = r; + return regs.ppu1_mdr; } //STAT78 @@ -509,19 +553,39 @@ uint8 r = 0x00; r |= cpu->interlace_field() << 7; if(!(cpu->pio_status() & 0x80)) { - r |= 1 << 6; + r |= 0x40; } else if(regs.counters_latched == true) { - r |= 1 << 6; + r |= 0x40; regs.counters_latched = false; } - r |= (1 << 5); + r |= (regs.ppu2_mdr & 0x20); + r |= (region << 4); //0 = NTSC, 1 = PAL r |= 0x03; //PPU2 version number - return r; + regs.ppu2_mdr = r; + return regs.ppu2_mdr; } uint8 bPPUMMIO::read(uint32 addr) { -//cpu->sync(); switch(addr) { + case 0x2104: + case 0x2105: + case 0x2106: + case 0x2108: + case 0x2109: + case 0x210a: + case 0x2114: + case 0x2115: + case 0x2116: + case 0x2118: + case 0x2119: + case 0x211a: + case 0x2124: + case 0x2125: + case 0x2126: + case 0x2128: + case 0x2129: + case 0x212a: + return ppu->regs.ppu1_mdr; case 0x2134:return ppu->mmio_r2134(); //MPYL case 0x2135:return ppu->mmio_r2135(); //MPYM case 0x2136:return ppu->mmio_r2136(); //MPYH @@ -535,11 +599,11 @@ uint8 bPPUMMIO::read(uint32 addr) { case 0x213e:return ppu->mmio_r213e(); //STAT77 case 0x213f:return ppu->mmio_r213f(); //STAT78 } - return 0x00; + + return cpu->regs.mdr; } void bPPUMMIO::write(uint32 addr, uint8 value) { -//cpu->sync(); switch(addr) { case 0x2100:ppu->mmio_w2100(value);return; //INIDISP case 0x2101:ppu->mmio_w2101(value);return; //OBSEL diff --git a/src/ppu/bppu/bppu_render_bg.cpp b/src/ppu/bppu/bppu_render_bg.cpp index d0b52853..cad885ae 100644 --- a/src/ppu/bppu/bppu_render_bg.cpp +++ b/src/ppu/bppu/bppu_render_bg.cpp @@ -18,6 +18,25 @@ uint16 opt_valid_bit; //offset-per-tile valid flag bit opt_valid_bit = 0x0000; } +//Mode 0 uses a special palette-indexing mode. +//Since there are 8 selectable palettes per tile, +//and there are 4 colors per palette on all four +//BGs for Mode 0, each BG has a unique palette +//entry point. This allows all 256 palette colors +//to be used, instead of just the first 32. +//entry = bg * 32, where 32 is from 8 * 4 +uint8 bgpal_index; + if(regs.bg_mode == 0) { + switch(bg) { + case BG1:bgpal_index = 0;break; + case BG2:bgpal_index = 32;break; + case BG3:bgpal_index = 64;break; + case BG4:bgpal_index = 96;break; + } + } else { + bgpal_index = 0; + } + uint8 pal_size, tiledata_size; switch(color_depth) { case COLORDEPTH_4: @@ -193,7 +212,7 @@ int _pri; render_bg_tile(color_depth, tile_num); } - pal_index = ((t >> 10) & 7) * pal_size; + pal_index = ((t >> 10) & 7) * pal_size + bgpal_index; if(mirror_y) { ypos = (7 - (mosaic_y & 7)); } else { ypos = ( (mosaic_y & 7)); } diff --git a/src/ppu/bppu/bppu_render_line.cpp b/src/ppu/bppu/bppu_render_line.cpp index 67e087ad..ee83802d 100644 --- a/src/ppu/bppu/bppu_render_line.cpp +++ b/src/ppu/bppu/bppu_render_line.cpp @@ -59,7 +59,7 @@ uint16 *ptr; } uint16 *ltable; - ltable = (uint16*)light_table + (regs.display_brightness << 16); + ltable = (uint16*)light_table + (regs.display_brightness << 15); if(_screen_width == 256) { for(x=0;x<256;x++) { diff --git a/src/ppu/bppu/bppu_render_mode7.cpp b/src/ppu/bppu/bppu_render_mode7.cpp index 128cdd12..8ed29b5b 100644 --- a/src/ppu/bppu/bppu_render_mode7.cpp +++ b/src/ppu/bppu/bppu_render_mode7.cpp @@ -2,25 +2,25 @@ ((x) & ((1 << 10) - 1)) + (((((x) & (1 << 13)) ^ (1 << 13)) - (1 << 13)) >> 3) #define CAST_WORDTOINT(x) \ - (int)(((x & 0x8000)?(x | 0xffff0000):(x & 0x00007fff))) + (int32)(((x & 0x8000) ? (x | 0xffff0000) : (x & 0x00007fff))) void bPPU::render_line_mode7(uint8 bg1_pri, uint8 bg2b_pri, uint8 bg2a_pri) { -int x; -int step_m7a, step_m7c, m7a, m7b, m7c, m7d; -int hoffset, voffset; -int centerx, centery; -int xx, yy; -int px, py; -int tx, ty, tile, palette; +int32 x; +int32 step_m7a, step_m7c, m7a, m7b, m7c, m7d; +int32 hoffset, voffset; +int32 centerx, centery; +int32 xx, yy; +int32 px, py; +int32 tx, ty, tile, palette; uint8 layer_pos; - hoffset = (CAST_WORDTOINT(regs.bg_hofs[BG1]) << 7) >> 7; - voffset = (CAST_WORDTOINT(regs.bg_vofs[BG1]) << 7) >> 7; + hoffset = ((int32)regs.m7_hofs << 19) >> 19; + voffset = ((int32)regs.m7_vofs << 19) >> 19; - centerx = (CAST_WORDTOINT(regs.m7x) << 7) >> 7; - centery = (CAST_WORDTOINT(regs.m7y) << 7) >> 7; + centerx = ((int32)regs.m7x << 19) >> 19; + centery = ((int32)regs.m7y << 19) >> 19; if(regs.mode7_vflip == true) { - yy = 223 - _y; + yy = 255 - _y; } else { yy = _y; } diff --git a/src/ppu/bppu/old_bppu_render_oam.cpp b/src/ppu/bppu/old_bppu_render_oam.cpp deleted file mode 100644 index c6060e19..00000000 --- a/src/ppu/bppu/old_bppu_render_oam.cpp +++ /dev/null @@ -1,230 +0,0 @@ -void bPPU::set_sprite_attributes(uint8 sprite_num) { -uint32 t; -uint8 size, b; -uint16 x; - t = *((uint32*)oam + sprite_num); - b = oam[512 + (sprite_num >> 2)]; - - switch(sprite_num & 3) { - case 0: size = !!(b & 0x02); x = (b & 0x01)?0x100:0; break; - case 1: size = !!(b & 0x08); x = (b & 0x04)?0x100:0; break; - case 2: size = !!(b & 0x20); x = (b & 0x10)?0x100:0; break; - case 3: size = !!(b & 0x80); x = (b & 0x40)?0x100:0; break; - } - - current_sprite.num = sprite_num; - current_sprite.priority = (t >> 28) & 3; - current_sprite.x = x | (t & 0xff); - current_sprite.y = ((t >> 8) + 1) & 0xff; - current_sprite.v_flip = !!(t & 0x80000000); - current_sprite.h_flip = !!(t & 0x40000000); - current_sprite.palette = (t >> 25) & 7; - current_sprite.character = (t >> 16) & 0x01ff; - -//size: 0 = small, 1 = large - switch(regs.oam_basesize) { - case 0: - if(!size) { current_sprite.width = 8; current_sprite.height = 8; } - else { current_sprite.width = 16; current_sprite.height = 16; } - break; - case 1: - if(!size) { current_sprite.width = 8; current_sprite.height = 8; } - else { current_sprite.width = 32; current_sprite.height = 32; } - break; - case 2: - if(!size) { current_sprite.width = 8; current_sprite.height = 8; } - else { current_sprite.width = 64; current_sprite.height = 64; } - break; - case 3: - if(!size) { current_sprite.width = 16; current_sprite.height = 16; } - else { current_sprite.width = 32; current_sprite.height = 32; } - break; - case 4: - if(!size) { current_sprite.width = 16; current_sprite.height = 16; } - else { current_sprite.width = 64; current_sprite.height = 64; } - break; - case 5: - if(!size) { current_sprite.width = 32; current_sprite.height = 32; } - else { current_sprite.width = 64; current_sprite.height = 64; } - break; - case 6: - if(!size) { current_sprite.width = 16; current_sprite.height = 32; } - else { current_sprite.width = 32; current_sprite.height = 64; } - break; - case 7: - if(!size) { current_sprite.width = 16; current_sprite.height = 32; } - else { current_sprite.width = 32; current_sprite.height = 32; } - break; - } -} - -void bPPU::render_oam_sprite() { -uint16 pos, col, chr, tiledata_inc; -uint8 d0, d1, d2, d3, pal_index; -int x, y, z, x1, mx, mask, p; -int tile_width; -//uint8 item_inc, tile_inc; - tile_width = current_sprite.width >> 3; //e.x. 16x16 sprite = 2x2 tiles - - regs.oam_itemcount++; -//add all visible tiles to regs.oam_tilecount - if(current_sprite.x > 256) { - //if sprite clips on left edge of the screen - regs.oam_tilecount += ((current_sprite.x + current_sprite.width + 7) & 511) >> 3; - } else if(current_sprite.x + current_sprite.width >= 257) { - //if sprite clips on right edge of screen - regs.oam_tilecount += (257 - current_sprite.x + 7) >> 3; - } else { - //if entire sprite is visible - regs.oam_tilecount += current_sprite.width >> 3; - } - -//if(_y == 0xa0)dprintf("* oam_itemcount=%d, oam_tilecount=%d", regs.oam_itemcount, regs.oam_tilecount); - - if(regs.bg_enabled[OAM] == false && regs.bgsub_enabled[OAM] == false)return; - if(regs.oam_tilecount > 34)return; - if(regs.oam_itemcount > 32)return; - - if(_interlace == true && _screen_width == 512) { - y = (_y << 1) + _interlace_field; - } else { - y = _y; - } - - x = current_sprite.x; - if(_screen_width == 512) { - x <<= 1; - } - - if(current_sprite.v_flip) { - y = ((current_sprite.height - 1) - (_y - current_sprite.y)); - } else { - y = (_y - current_sprite.y); - } - if(regs.oam_halve == true) { - y <<= 1; - if(_interlace == true && _screen_width == 512) { - y += _interlace_field; - } - } - y &= 255; - - chr = current_sprite.character; - tiledata_inc = (chr & 0x100)?(regs.oam_nameselect << 13):0; - chr += (y >> 3) << 4; - pal_index = (current_sprite.palette << 4); - for(x1=0;x1> z; - } - x &= 511; - if(x < _screen_width) { - col = 0; - if(d0 & mask)col += 1; - if(d1 & mask)col += 2; - if(d2 & mask)col += 4; - if(d3 & mask)col += 8; - if(col) { - col += pal_index; - col += 128; - if(oam_line_pri[x] == OAM_PRI_NONE) { - oam_line_pal[x] = col; - oam_line_pri[x] = current_sprite.priority; - } - if(_screen_width == 512) { - if(oam_line_pri[x + 1] == OAM_PRI_NONE) { - oam_line_pal[x + 1] = col; - oam_line_pri[x + 1] = current_sprite.priority; - } - } - } - } - x += (_screen_width == 512)?2:1; - } - } -} - -void bPPU::render_line_oam(uint8 pri0_pos, uint8 pri1_pos, uint8 pri2_pos, uint8 pri3_pos) { -int s, x; -bool _bg_enabled = regs.bg_enabled[OAM]; -bool _bgsub_enabled = regs.bgsub_enabled[OAM]; - -uint8 *wt_main = main_windowtable[OAM]; -uint8 *wt_sub = sub_windowtable[OAM]; - build_window_tables(OAM); - - regs.oam_itemcount = 0; - regs.oam_tilecount = 0; - memset(oam_line_pri, OAM_PRI_NONE, 512); - for(s=0;s<128;s++) { - set_sprite_attributes((s + regs.oam_firstsprite) & 127); - - //if sprite is entirely offscreen and doesn't wrap around to the left side of the screen, - //then it is not counted. 256 is correct, and not 255 -- as one might first expect - if(current_sprite.x > 256 && ((current_sprite.x + current_sprite.width) & 511) > 256)continue; - -//if(_y == 0xa0) -//dprintf("* y: %d, fs: %d, sprite: %d, width: %d, height: %d, x: %d, y: %d", -// _y, regs.oam_firstsprite, (s + regs.oam_firstsprite) & 127, -// current_sprite.width, current_sprite.height, current_sprite.x, current_sprite.y); - - if(regs.oam_halve == false) { - if(_y >= current_sprite.y && _y < (current_sprite.y + current_sprite.height)) { - render_oam_sprite(); - } else if((current_sprite.y + current_sprite.height) >= 256 && _y < ((current_sprite.y + current_sprite.height) & 255)) { - render_oam_sprite(); - } - } else { - if(_y >= current_sprite.y && _y < (current_sprite.y + (current_sprite.height >> 1))) { - render_oam_sprite(); - } else if((current_sprite.y + (current_sprite.height >> 1)) >= 256 && _y < ((current_sprite.y + (current_sprite.height >> 1)) & 255)) { - render_oam_sprite(); - } - } - } - - regs.time_over |= (regs.oam_tilecount > 34); - regs.range_over |= (regs.oam_itemcount > 32); -//dprintf("* line: %d, t = %d, r = %d, tc = %d, ic = %d", _y, -//regs.time_over, regs.range_over, regs.oam_tilecount, regs.oam_itemcount); - - if(_bg_enabled == false && _bgsub_enabled == false)return; -int _pri; - for(x=0;x<_screen_width;x++) { - if(oam_line_pri[x] == OAM_PRI_NONE)continue; - - switch(oam_line_pri[x]) { - case 0:_pri = pri0_pos;break; - case 1:_pri = pri1_pos;break; - case 2:_pri = pri2_pos;break; - case 3:_pri = pri3_pos;break; - } - - if(main_colorwindowtable[x]) { - if(_bg_enabled == true && !wt_main[x]) { - if(pixel_cache[x].pri_main < _pri) { - pixel_cache[x].pri_main = _pri; - pixel_cache[x].bg_main = PC_OAM; - pixel_cache[x].src_main = oam_line_pal[x]; - } - } - if(_bgsub_enabled == true && !wt_sub[x]) { - if(pixel_cache[x].pri_sub < _pri) { - pixel_cache[x].pri_sub = _pri; - pixel_cache[x].bg_sub = PC_OAM; - pixel_cache[x].src_sub = oam_line_pal[x]; - } - } - } - } -} diff --git a/src/reader/filereader.cpp b/src/reader/filereader.cpp new file mode 100644 index 00000000..26f796f2 --- /dev/null +++ b/src/reader/filereader.cpp @@ -0,0 +1,73 @@ +uint32 FileReader::size() { + return fsize; +} + +//This function will allocate memory even if open() fails. +//This is needed so that when SRAM files do not exist, the +//memory for the SRAM data will be allocated still. +//The memory is flushed to 0x00 when no file is opened. +void FileReader::read(uint8 **buffer, uint32 length) { +uint8 *data; + if(length == 0) { + //read the entire file into RAM + data = (uint8*)memalloc(fsize); + memset(data, 0, fsize); + if(fp)fread(data, 1, fsize, fp); + } else if(length > fsize) { + //read the entire file into RAM, pad the rest with 0x00s + data = (uint8*)memalloc(length); + memset(data, 0, length); + if(fp)fread(data, 1, fsize, fp); + } else { //fsize >= length + //read only what was requested + data = (uint8*)memalloc(length); + memset(data, 0, length); + if(fp)fread(data, 1, length, fp); + } + *buffer = data; +} + +bool FileReader::open(char *fn) { + fp = fopen(fn, "rb"); + if(!fp)return false; + + fseek(fp, 0, SEEK_END); + fsize = ftell(fp); + fseek(fp, 0, SEEK_SET); + +//empty file? + if(fsize == 0) { + fclose(fp); + fp = 0; + return false; + } + + return true; +} + +void FileReader::close() { + if(fp) { + fclose(fp); + fp = 0; + } +} + +void FileWriter::write(uint8 *buffer, uint32 length) { + if(!fp)return; + + fwrite(buffer, 1, length, fp); +} + +bool FileWriter::open(char *fn) { + fp = fopen(fn, "wb"); + if(!fp)return false; + + return true; +} + +void FileWriter::close() { + if(fp) { + fclose(fp); + fp = 0; + } +} diff --git a/src/reader/filereader.h b/src/reader/filereader.h new file mode 100644 index 00000000..aab88908 --- /dev/null +++ b/src/reader/filereader.h @@ -0,0 +1,27 @@ +class FileReader : public Reader { +private: +FILE *fp; +uint32 fsize; + +public: + uint32 size(); + void read(uint8 **buffer, uint32 length = 0); + bool open(char *fn); + void close(); + + FileReader() { fp = 0; fsize = 0; } + ~FileReader() { if(fp)fclose(fp); } +}; + +class FileWriter : public Writer { +private: +FILE *fp; + +public: + void write(uint8 *buffer, uint32 length); + bool open(char *fn); + void close(); + + FileWriter() { fp = 0; } + ~FileWriter() { if(fp)fclose(fp); } +}; diff --git a/src/reader/reader.cpp b/src/reader/reader.cpp index f4b1a90e..68985773 100644 --- a/src/reader/reader.cpp +++ b/src/reader/reader.cpp @@ -1,79 +1,2 @@ #include "../base.h" - -uint32 FileReader::size() { - return fsize; -} - -/* - This function will allocate memory even if open() fails. - This is needed so that when SRAM files do not exist, the - memory for the SRAM data will be allocated still. - - The memory is flushed to 0x00 when no file is opened. -*/ -void FileReader::read(uint8 **buffer, uint32 length) { -uint8 *data; - if(length == 0) { - /* read the entire file into RAM */ - data = (uint8*)memalloc(fsize); - memset(data, 0, fsize); - if(fp)fread(data, 1, fsize, fp); - } else if(length > fsize) { - /* read the entire file into RAM, pad the rest with 0x00s */ - data = (uint8*)memalloc(length); - memset(data, 0, length); - if(fp)fread(data, 1, fsize, fp); - } else { //fsize >= length - /* read as much of the file as possible, truncate the rest */ - data = (uint8*)memalloc(length); - memset(data, 0, length); - if(fp)fread(data, 1, length, fp); - } - *buffer = data; -} - -bool FileReader::open(uint8 type, char *fn) { - fp = fopen(fn, "rb"); - if(!fp)return false; - - fseek(fp, 0, SEEK_END); - fsize = ftell(fp); - fseek(fp, 0, SEEK_SET); - - if(type == TYPE_ROM) { - /* remove header if it exists */ - if((fsize & 0xfff) == 0x200) { - fsize -= 0x200; - fseek(fp, 0x200, SEEK_SET); - } - } - -/* empty file? */ - if(fsize == 0) { - fclose(fp); - return false; - } - - return true; -} - -void FileReader::close() { - if(fp)fclose(fp); -} - -void FileWriter::write(uint8 *buffer, uint32 length) { - if(!fp)return; - - fwrite(buffer, 1, length, fp); -} - -bool FileWriter::open(char *fn) { - fp = fopen(fn, "wb"); - if(!fp)return false; - - return true; -} - -void FileWriter::close() { - if(fp)fclose(fp); -} +#include "filereader.cpp" diff --git a/src/reader/reader.h b/src/reader/reader.h index 200fe92f..695f989c 100644 --- a/src/reader/reader.h +++ b/src/reader/reader.h @@ -4,39 +4,9 @@ public: virtual void read(uint8 **buffer, uint32 length = 0) = 0; }; -class FileReader : public Reader { -private: -FILE *fp; -uint32 fsize; - -public: -enum { - TYPE_ROM = 0, - TYPE_SRAM = 1 -}; - uint32 size(); - void read(uint8 **buffer, uint32 length = 0); - bool open(uint8 type, char *fn); - void close(); - - FileReader() { fp = 0; fsize = 0; } - ~FileReader() { if(fp)fclose(fp); } -}; - class Writer { public: virtual void write(uint8 *buffer, uint32 length) = 0; }; -class FileWriter : public Writer { -private: -FILE *fp; - -public: - void write(uint8 *buffer, uint32 length); - bool open(char *fn); - void close(); - - FileWriter() { fp = 0; } - ~FileWriter() { if(fp)fclose(fp); } -}; +#include "filereader.h" diff --git a/src/sdl/Makefile b/src/sdl/Makefile index eba1c93b..7d81aeb3 100644 --- a/src/sdl/Makefile +++ b/src/sdl/Makefile @@ -7,7 +7,8 @@ OBJS = sdlmain.o \ cpu.o bcpu.o \ apu.o bapu.o bapuskip.o \ ppu.o bppu.o \ - snes.o + snes.o \ + srtc.o sdd1.o all: $(OBJS) $(CC) $(CFLAGS) $(OBJS) `sdl11-config --cflags --libs` -o bsnes_sdl @@ -71,7 +72,7 @@ bppu.o: ../ppu/bppu/* ############## ### reader ### ############## -reader.o: ../reader/reader.cpp ../reader/reader.h +reader.o: ../reader/*.cpp ../reader/*.h $(CC) $(CFLAGS) -c ../reader/reader.cpp ############ @@ -79,3 +80,15 @@ reader.o: ../reader/reader.cpp ../reader/reader.h ############ snes.o: ../snes/*.cpp ../snes/*.h $(CC) $(CFLAGS) -c ../snes/snes.cpp + +############ +### srtc ### +############ +srtc.o: ../chip/srtc/*.cpp ../chip/srtc/*.h + $(CC) $(CFLAGS) -c ../chip/srtc/srtc.cpp + +############ +### sdd1 ### +############ +sdd1.o: ../chip/sdd1/*.cpp ../chip/sdd1/*.h + $(CC) $(CFLAGS) -c ../chip/sdd1/sdd1.cpp diff --git a/src/sdl/Makefile.win32 b/src/sdl/Makefile.win32 index fee7b835..53c00b32 100644 --- a/src/sdl/Makefile.win32 +++ b/src/sdl/Makefile.win32 @@ -7,7 +7,8 @@ OBJS = sdlmain.obj \ cpu.obj bcpu.obj \ apu.obj bapu.obj bapuskip.obj \ ppu.obj bppu.obj \ - snes.obj + snes.obj \ + srtc.obj sdd1.obj LIBS = kernel32.lib user32.lib gdi32.lib sdlmain.lib sdl.lib all: $(OBJS) @@ -72,7 +73,7 @@ bppu.obj: ../ppu/bppu/* ############## ### reader ### ############## -reader.obj: ../reader/reader.cpp ../reader/reader.h +reader.obj: ../reader/*.cpp ../reader/*.h $(CC) $(CFLAGS) /c ../reader/reader.cpp ############ @@ -80,3 +81,15 @@ reader.obj: ../reader/reader.cpp ../reader/reader.h ############ snes.obj: ../snes/*.cpp ../snes/*.h $(CC) $(CFLAGS) /c ../snes/snes.cpp + +############ +### srtc ### +############ +srtc.obj: ../chip/srtc/*.cpp ../chip/srtc/*.h + $(CC) $(CFLAGS) /c ../chip/srtc/srtc.cpp + +############ +### sdd1 ### +############ +sdd1.obj: ../chip/sdd1/*.cpp ../chip/sdd1/*.h + $(CC) $(CFLAGS) /c ../chip/sdd1/sdd1.cpp diff --git a/src/sdl/rom.cpp b/src/sdl/rom.cpp index 7df0f250..f5beae7a 100644 --- a/src/sdl/rom.cpp +++ b/src/sdl/rom.cpp @@ -23,7 +23,7 @@ bool ROMImage::load() { dprintf("* Loading \"%s\"...", rom_fn); FileReader *rf = new FileReader(); - if(!rf->open(FileReader::TYPE_ROM, rom_fn)) { + if(!rf->open(rom_fn)) { alert("Error loading image file [%s]!", rom_fn); return false; } @@ -33,7 +33,7 @@ FileReader *rf = new FileReader(); CartInfo ci; mem_bus->get_cartinfo(&ci); if(ci.sram_size != 0) { - rf->open(FileReader::TYPE_SRAM, sram_fn); + rf->open(sram_fn); mem_bus->load_sram(static_cast(rf)); rf->close(); } diff --git a/src/sdl/sdlmain.cpp b/src/sdl/sdlmain.cpp index 1648d9b1..e4f8f270 100644 --- a/src/sdl/sdlmain.cpp +++ b/src/sdl/sdlmain.cpp @@ -1,10 +1,8 @@ -#define _WIN32_ - #define INTERFACE_MAIN -#define BSNES_VERSION "0.010" +#define BSNES_VERSION "0.011" #define BSNES_TITLE "bsnes/SDL v" BSNES_VERSION -#include "sdlmain.h" #include "../base.h" +#include "sdlmain.h" #ifdef _WIN32_ HWND hwnd; @@ -57,6 +55,8 @@ void init_snes() { ppu = new bPPU(); snes = new bSNES(); bsnes = static_cast(snes); + + snes->init(); } void term_snes() { diff --git a/src/snes/snes.cpp b/src/snes/snes.cpp index 9ba56f14..d80cffe8 100644 --- a/src/snes/snes.cpp +++ b/src/snes/snes.cpp @@ -1,40 +1,87 @@ #include "../base.h" void SNES::run() { - cpu->run(); +uint32 cycles; + if(apusync.cycles < 0) { + cpu->run(); + apusync.cycles += apusync.apu_multbl[cpu->cycles_executed()]; + } else { + apu->run(); + apusync.cycles -= apusync.cpu_multbl[apu->cycles_executed()]; + } +} + +void SNES::init() { + srtc = new SRTC(); + sdd1 = new SDD1(); } void SNES::power() { cpu->power(); apu->power(); ppu->power(); -//clock->power(); mem_bus->power(); + srtc->power(); + sdd1->power(); + int i; mem_bus->flush_mmio_mappers(); for(i=0x2100;i<=0x213f;i++)mem_bus->set_mmio_mapper(i, ppu->mmio); for(i=0x2140;i<=0x217f;i++)mem_bus->set_mmio_mapper(i, cpu->mmio); for(i=0x2180;i<=0x2183;i++)mem_bus->set_mmio_mapper(i, cpu->mmio); -//unknown - mem_bus->set_mmio_mapper(0x21c2, cpu->mmio); - mem_bus->set_mmio_mapper(0x21c3, cpu->mmio); //S-RTC - mem_bus->set_mmio_mapper(0x2800, cpu->mmio); - mem_bus->set_mmio_mapper(0x2801, cpu->mmio); + mem_bus->set_mmio_mapper(0x2800, srtc->mmio); + mem_bus->set_mmio_mapper(0x2801, srtc->mmio); //input mem_bus->set_mmio_mapper(0x4016, cpu->mmio); mem_bus->set_mmio_mapper(0x4017, cpu->mmio); for(i=0x4200;i<=0x421f;i++)mem_bus->set_mmio_mapper(i, cpu->mmio); for(i=0x4300;i<=0x437f;i++)mem_bus->set_mmio_mapper(i, cpu->mmio); +//S-DD1 + for(i=0x4800;i<=0x4807;i++)mem_bus->set_mmio_mapper(i, sdd1->mmio); } void SNES::reset() { + apusync.cycles = -apusync.cpu_multbl[32]; + cpu->reset(); apu->reset(); ppu->reset(); -//clock->reset(); mem_bus->reset(); + + srtc->reset(); + sdd1->reset(); +} + +void SNES::set_region(uint8 new_region) { + if(new_region == NTSC) { + snes_region = NTSC; + } else if(new_region == PAL) { + snes_region = PAL; + } else { + alert("Unsupported region : %0.2x", new_region); + } + + update_timing(); +} + +uint8 SNES::region() { return snes_region; } + +void SNES::update_timing() { + apusync.cycles = 0; + if(snes_region == NTSC) { + apusync.cpu_freq = 21477272 >> 3; + } else if(snes_region == PAL) { + apusync.cpu_freq = 21281370 >> 3; + } + apusync.apu_freq = 24576000 >> 3; + +int i; + for(i=0;i<1024;i++) { + apusync.cpu_multbl[i] = i * apusync.cpu_freq; + apusync.apu_multbl[i] = i * apusync.apu_freq; + } } /*************************** @@ -56,4 +103,7 @@ bool SNES::debugger_enabled() { SNES::SNES() { is_debugger_enabled = true; + + snes_region = NTSC; + update_timing(); } diff --git a/src/snes/snes.h b/src/snes/snes.h index b66abed2..a5e1699f 100644 --- a/src/snes/snes.h +++ b/src/snes/snes.h @@ -2,12 +2,28 @@ class SNES { protected: bool is_debugger_enabled; +uint8 snes_region; + +//APU synchronization +struct { +int32 cpu_freq, apu_freq; +int32 cpu_multbl[1024], apu_multbl[1024]; +int32 cycles; +}apusync; + +void update_timing(); + public: +enum { NTSC = 0, PAL = 1 }; + //system functions void run(); - virtual void render_frame() = 0; - virtual void power(); - virtual void reset(); + virtual void render_frame() = 0; + virtual void init(); + virtual void power(); + virtual void reset(); + virtual uint8 region(); + virtual void set_region(uint8 new_region); //input functions enum { diff --git a/src/win/Makefile b/src/win/Makefile index ceb050d9..eb4de871 100644 --- a/src/win/Makefile +++ b/src/win/Makefile @@ -7,7 +7,8 @@ OBJS = winmain.obj \ cpu.obj bcpu.obj \ apu.obj bapu.obj bapuskip.obj \ ppu.obj bppu.obj \ - snes.obj + snes.obj \ + srtc.obj sdd1.obj LIBS = kernel32.lib user32.lib gdi32.lib comdlg32.lib ddraw.lib dxguid.lib all: $(OBJS) @@ -73,7 +74,7 @@ bppu.obj: ../ppu/bppu/* ############## ### reader ### ############## -reader.obj: ../reader/reader.cpp ../reader/reader.h +reader.obj: ../reader/*.cpp ../reader/*.h $(CC) $(CFLAGS) /c ../reader/reader.cpp ############ @@ -81,3 +82,15 @@ reader.obj: ../reader/reader.cpp ../reader/reader.h ############ snes.obj: ../snes/*.cpp ../snes/*.h $(CC) $(CFLAGS) /c ../snes/snes.cpp + +############ +### srtc ### +############ +srtc.obj: ../chip/srtc/*.cpp ../chip/srtc/*.h + $(CC) $(CFLAGS) /c ../chip/srtc/srtc.cpp + +############ +### sdd1 ### +############ +sdd1.obj: ../chip/sdd1/*.cpp ../chip/sdd1/*.h + $(CC) $(CFLAGS) /c ../chip/sdd1/sdd1.cpp diff --git a/src/win/bsnes.cpp b/src/win/bsnes.cpp index c8063fed..ee5a828f 100644 --- a/src/win/bsnes.cpp +++ b/src/win/bsnes.cpp @@ -12,11 +12,22 @@ uint8 cpu_op; status.cpu_ran = false; break; case RUNTOCPUPROCEED: - cpu_op = mem_bus->read(cpu->regs.pc); - /* proceed only skips subroutines (jsr ). 0x20, 0x22, and 0xfc are all three jsr opcodes */ - if(cpu_op == 0x20 || cpu_op == 0x22 || cpu_op == 0xfc) { + cpu_op = mem_bus->read(cpu->regs.pc.d); + + if(cpu_op == 0x10 || //bpl rel + cpu_op == 0x30 || //bmi rel + cpu_op == 0x50 || //bvc rel + cpu_op == 0x70 || //bvs rel + cpu_op == 0x90 || //bcc rel + cpu_op == 0xb0 || //bcs rel + cpu_op == 0xd0 || //bne rel + cpu_op == 0xf0 || //beq rel + cpu_op == 0x20 || //jsr addr + cpu_op == 0x22 || //jsl long + cpu_op == 0xfc //jsr (addr,x) + ) { w_console->is_running(true); - status.cpu_stop_pos = (cpu->regs.pc.b << 16) | ((cpu->regs.pc + cpu->opcode_length()) & 0xffff); + status.cpu_stop_pos = (cpu->regs.pc.b << 16) | ((cpu->regs.pc.d + cpu->opcode_length()) & 0xffff); } else { status.cpu_ran = false; run_status = RUNTOCPUSTEP; @@ -78,7 +89,7 @@ void bSNES::snes_run() { break; case RUNTOCPUPROCEED: run(); - if(status.cpu_stop_pos == cpu->regs.pc) { + if(cpu->in_opcode() == false && status.cpu_stop_pos == cpu->regs.pc.d) { set_status(STOP); disassemble_cpu_op(); } else if(w_bp->hit() == true) { @@ -110,7 +121,7 @@ void bSNES::render_frame() { *** Input functions *** ***********************/ void bSNES::poll_input() { -/* Only capture input when main window has focus */ +//only capture input when main window has focus if(GetForegroundWindow() == w_main->hwnd) { joypad1.up = KeyDown(cfg.input.joypad1.up); joypad1.down = KeyDown(cfg.input.joypad1.down); @@ -131,7 +142,7 @@ void bSNES::poll_input() { joypad1.l = joypad1.r = 0; } -//Check for debugger-based key locks +//check for debugger-based key locks if(is_debugger_enabled == true) { if(w_console->joypad_lock.up )joypad1.up = true; if(w_console->joypad_lock.down )joypad1.down = true; @@ -147,7 +158,7 @@ void bSNES::poll_input() { if(w_console->joypad_lock.start )joypad1.start = true; } -//It's impossible to hold both up+down, or left+right down +//it's impossible to hold both up+down, or left+right down //at the same time on a directional pad; and besides, allowing //this to happen causes glitches in many SNES games. if(joypad1.up) joypad1.down = 0; @@ -274,6 +285,7 @@ void bSNES::notify(uint32 message, uint32 param1, uint32 param2) { case CPU_EXEC_OPCODE_END: status.cpu_ran = true; status.cpu_trace_pos++; + //test next opcode for breakpoint w_bp->test(message, cpu->regs.pc.d, 0); disassemble_cpu_op(); break; diff --git a/src/win/dd_renderer.cpp b/src/win/dd_renderer.cpp index 4aace022..1c2484ec 100644 --- a/src/win/dd_renderer.cpp +++ b/src/win/dd_renderer.cpp @@ -22,7 +22,7 @@ int i, r, g, b; lpddsb->GetSurfaceDesc(&ddsd); color_depth = ddsd.ddpfPixelFormat.dwRGBBitCount; if(color_depth == 15) { - for(i=0;i<65536;i++) { + for(i=0;i<32768;i++) { r = (i ) & 31; g = (i >> 5) & 31; b = (i >> 10) & 31; @@ -34,7 +34,7 @@ int i, r, g, b; color_lookup_table[i] = (r << 10) | (g << 5) | (b); } } else if(color_depth == 16) { - for(i=0;i<65536;i++) { + for(i=0;i<32768;i++) { r = (i ) & 31; g = (i >> 5) & 31; b = (i >> 10) & 31; @@ -48,7 +48,7 @@ int i, r, g, b; color_lookup_table[i] = (r << 11) | (g << 5) | (b); } } else if(color_depth == 32) { - for(i=0;i<65536;i++) { + for(i=0;i<32768;i++) { r = (i ) & 31; g = (i >> 5) & 31; b = (i >> 10) & 31; diff --git a/src/win/dd_renderer.h b/src/win/dd_renderer.h index f1054b1d..3a9c8f5d 100644 --- a/src/win/dd_renderer.h +++ b/src/win/dd_renderer.h @@ -13,7 +13,7 @@ bool fullscreen; int width, height; //used for fullscreen mode clipping only uint8 color_depth; uint8 color_curve_table[32]; -uint32 color_lookup_table[65536]; +uint32 color_lookup_table[32768]; void set_window(HWND hwnd_handle); void create_backbuffer(); void to_windowed(); diff --git a/src/win/rom.cpp b/src/win/rom.cpp index 282be928..e2a33fb5 100644 --- a/src/win/rom.cpp +++ b/src/win/rom.cpp @@ -23,7 +23,7 @@ bool ROMImage::load() { dprintf("* Loading \"%s\"...", rom_fn); FileReader *rf = new FileReader(); - if(!rf->open(FileReader::TYPE_ROM, rom_fn)) { + if(!rf->open(rom_fn)) { alert("Error loading image file [%s]!", rom_fn); return false; } @@ -33,7 +33,7 @@ FileReader *rf = new FileReader(); CartInfo ci; mem_bus->get_cartinfo(&ci); if(ci.sram_size != 0) { - rf->open(FileReader::TYPE_SRAM, sram_fn); + rf->open(sram_fn); mem_bus->load_sram(static_cast(rf)); rf->close(); } diff --git a/src/win/ui.h b/src/win/ui.h index eda78049..8d207ca4 100644 --- a/src/win/ui.h +++ b/src/win/ui.h @@ -36,6 +36,7 @@ enum { MENU_SETTINGS_APUENABLED, MENU_SETTINGS_INPUTCFG_JOYPAD1, MENU_SETTINGS_DEBUGGER, + MENU_MISC_SCREENSHOT, MENU_MISC_ABOUT }; diff --git a/src/win/ui_bp.cpp b/src/win/ui_bp.cpp index af88494e..ed47955d 100644 --- a/src/win/ui_bp.cpp +++ b/src/win/ui_bp.cpp @@ -22,7 +22,7 @@ int i; if(!(bp[i].flags & FLAG_X))continue; if(bp[i].source != DRAM)continue; if(bp[i].addr != addr)continue; - dprintf("* Breakpoint %d hit (exec)", i); + dprintf("* Breakpoint %d hit (CPU exec)", i); bp[i].hit_count++; bp_hit = true; w_bp->refresh(); @@ -31,7 +31,7 @@ int i; if(!(bp[i].flags & FLAG_X))continue; if(bp[i].source != SPCRAM)continue; if(bp[i].addr != addr)continue; - dprintf("* Breakpoint %d hit (exec)", i); + dprintf("* Breakpoint %d hit (APU exec)", i); bp[i].hit_count++; bp_hit = true; w_bp->refresh(); diff --git a/src/win/ui_console.cpp b/src/win/ui_console.cpp index eb2a8f68..dcd1c059 100644 --- a/src/win/ui_console.cpp +++ b/src/win/ui_console.cpp @@ -29,13 +29,21 @@ HDC hdc; break; case CONSOLE_CPUPROCEED: if(bsnes->get_status() == bSNES::STOP) { - bsnes->set_status(bSNES::RUNTOCPUPROCEED); + if(cpu->in_opcode() == true) { + dprintf("* CPU within opcode, proceed aborted"); + } else { + bsnes->set_status(bSNES::RUNTOCPUPROCEED); + } } break; case CONSOLE_CPUSKIP: if(bsnes->get_status() == bSNES::STOP) { - cpu->regs.pc.w += cpu->opcode_length(); - bsnes->disassemble_cpu_op(); + if(cpu->in_opcode() == true) { + dprintf("* CPU within opcode, skip aborted"); + } else { + cpu->regs.pc.w += cpu->opcode_length(); + bsnes->disassemble_cpu_op(); + } } break; case CONSOLE_CPUTRACE: @@ -49,13 +57,17 @@ HDC hdc; break; case CONSOLE_CPUDISABLE: if(bsnes->get_status() == bSNES::STOP) { - addr = cpu->regs.pc.d; - len = cpu->opcode_length(); - for(i=0;iwrite(bSNES::DRAM, (addr & 0xff0000) | ((addr + i) & 0xffff), 0xea); + if(cpu->in_opcode() == true) { + dprintf("* CPU within opcode, disable aborted"); + } else { + addr = cpu->regs.pc.d; + len = cpu->opcode_length(); + for(i=0;iwrite(bSNES::DRAM, (addr & 0xff0000) | ((addr + i) & 0xffff), 0xea); + } + //cpu->regs.pc.w += len; + bsnes->disassemble_cpu_op(); } -// cpu->regs.pc.w += len; - bsnes->disassemble_cpu_op(); } break; case CONSOLE_APUSTEP: @@ -111,21 +123,25 @@ HDC hdc; value = strhex(t); pos = SendDlgItemMessage(hwnd, CONSOLE_CFGREGTYPE, CB_GETCURSEL, 0, 0); if(pos == 0) { //Set CPU register - pos = SendDlgItemMessage(hwnd, CONSOLE_CFGREGNUM, CB_GETCURSEL, 0, 0); - switch(pos) { - case 0:cpu->regs.a.w = value;break; - case 1:cpu->regs.x.w = value;break; - case 2:cpu->regs.y.w = value;break; - case 3:cpu->regs.s.w = value;break; - case 4:cpu->regs.d.w = value;break; - case 5:cpu->regs.db = value;break; - case 6:cpu->regs.p = value;break; - case 7:cpu->regs.e = value;break; - case 8:cpu->regs.pc.d = value;break; + if(cpu->in_opcode() == true) { + dprintf("* CPU within opcode, register set aborted"); + } else { + pos = SendDlgItemMessage(hwnd, CONSOLE_CFGREGNUM, CB_GETCURSEL, 0, 0); + switch(pos) { + case 0:cpu->regs.a.w = value;break; + case 1:cpu->regs.x.w = value;break; + case 2:cpu->regs.y.w = value;break; + case 3:cpu->regs.s.w = value;break; + case 4:cpu->regs.d.w = value;break; + case 5:cpu->regs.db = value;break; + case 6:cpu->regs.p = value;break; + case 7:cpu->regs.e = value;break; + case 8:cpu->regs.pc.d = value;break; + } + //these bits can never be clear in emulation mode + if(cpu->regs.e)cpu->regs.p |= 0x30; + bsnes->disassemble_cpu_op(); } - //these bits can never be clear in emulation mode - if(cpu->regs.e)cpu->regs.p |= 0x30; - bsnes->disassemble_cpu_op(); } else { //Set APU register } break; diff --git a/src/win/ui_main.cpp b/src/win/ui_main.cpp index efa883c6..855670bf 100644 --- a/src/win/ui_main.cpp +++ b/src/win/ui_main.cpp @@ -132,6 +132,7 @@ void MainWindow::menu_unload() { } long __stdcall wndproc_main(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { +time_t timeout; switch(msg) { case WM_KEYDOWN: if(wparam == VK_ESCAPE) { @@ -144,6 +145,13 @@ long __stdcall wndproc_main(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { } break; case WM_COMMAND: +//below code fails becahse it is triggered after snes->poll_input()... +//unsure how to fix this... +// timeout = time(NULL); +// while(difftime(time(NULL), timeout) < 5) { +// if(!KeyDown(VK_RETURN))break; +// } + switch(LOWORD(wparam)) { case MENU_FILE_LOAD: w_main->menu_load(); @@ -227,6 +235,8 @@ long __stdcall wndproc_main(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { w_main->set_video_mode(VIDEOMODE_256x224w); } break; + case MENU_MISC_SCREENSHOT: + break; case MENU_MISC_ABOUT: w_about->center(); w_about->show(); @@ -315,6 +325,8 @@ HMENU hsubmenu, hbranchmenu; AppendMenu(hmenu, MF_STRING | MF_POPUP, (unsigned int)hsubmenu, "&Settings"); hsubmenu = CreatePopupMenu(); + AppendMenu(hsubmenu, MF_STRING | MF_GRAYED, MENU_MISC_SCREENSHOT, "&Capture Screenshot"); + AppendMenu(hsubmenu, MF_SEPARATOR, 0, ""); AppendMenu(hsubmenu, MF_STRING, MENU_MISC_ABOUT, "&About..."); AppendMenu(hmenu, MF_STRING | MF_POPUP, (unsigned int)hsubmenu, "&Misc"); diff --git a/src/win/winmain.cpp b/src/win/winmain.cpp index 58b4cf24..0d50ac7d 100644 --- a/src/win/winmain.cpp +++ b/src/win/winmain.cpp @@ -1,5 +1,5 @@ #define INTERFACE_MAIN -#define BSNES_VERSION "0.010" +#define BSNES_VERSION "0.011" #define BSNES_TITLE "bsnes v" BSNES_VERSION #include "winmain.h" #include "../base.h" @@ -31,6 +31,8 @@ void init_snes() { ppu = new bPPU(); snes = new bSNES(); bsnes = static_cast(snes); + + snes->init(); } void term_snes() {