diff --git a/bsnes.cfg b/bsnes.cfg index 897d2416..2e683772 100644 --- a/bsnes.cfg +++ b/bsnes.cfg @@ -1,5 +1,8 @@ #[bsnes v0.009 configuration file] +#[apu enable] +apu.enabled = true + #[video mode] # 0: 256x224w # 1: 512x448w @@ -34,3 +37,21 @@ gui.show_fps = true #[wait for vertical retrace] video.vblank = false + +#[joypad 1 configuration] +# Key numbers are standard windows VK_* keys. +# Unfortunately, I don't have a table of common +# key mappings to list here... use GUI joypad +# configuration utility to edit these. +input.joypad1.up = 0x26 +input.joypad1.down = 0x28 +input.joypad1.left = 0x25 +input.joypad1.right = 0x27 +input.joypad1.a = 0x58 +input.joypad1.b = 0x5a +input.joypad1.x = 0x53 +input.joypad1.y = 0x41 +input.joypad1.l = 0x44 +input.joypad1.r = 0x43 +input.joypad1.select = 0x10 +input.joypad1.start = 0x0d diff --git a/bsnes.exe b/bsnes.exe new file mode 100644 index 00000000..52006839 Binary files /dev/null and b/bsnes.exe differ diff --git a/bsnes_g2.exe b/bsnes_g2.exe deleted file mode 100644 index 2681758f..00000000 Binary files a/bsnes_g2.exe and /dev/null differ diff --git a/license.txt b/license.txt index 8f1afb6f..ae85df60 100644 --- a/license.txt +++ b/license.txt @@ -1,10 +1,21 @@ -bsnes Licensing Agreement: - +bsnes License: +-------------- You are free to redistribute this software, and its source code; provided there is no charge for the software, nor any charge for the medium used to distribute the software. You are also free to use and modify the source code as you desire for personal use only. No publically-released derivative works -of this source code are permitted without my permission. You must also abide -by the terms of any additional source code licenses contained within my code. -At present, this only includes the mode7 renderer, which was derived from the -snes9x mode7 renderer. +of this source code are permitted without my permission, though I will likely +grant you permission if you ask me. You must also abide by the terms of any +additional source code licenses contained within this program. + +Simple DirectMedia Layer License: +--------------------------------- +The Simple DirectMedia Layer (SDL for short) is a cross-platform library +designed to make it easy to write multi-media software, such as games and +emulators. + +The Simple DirectMedia Layer library source code is available from: +http://www.libsdl.org/ + +This library is distributed under the terms of the GNU LGPL license: +http://www.gnu.org/copyleft/lesser.html diff --git a/src/apu/apu.cpp b/src/apu/apu.cpp new file mode 100644 index 00000000..3700272a --- /dev/null +++ b/src/apu/apu.cpp @@ -0,0 +1,2 @@ +#include "../base.h" +#include "dapu.cpp" diff --git a/src/apu/apu.h b/src/apu/apu.h new file mode 100644 index 00000000..a9161316 --- /dev/null +++ b/src/apu/apu.h @@ -0,0 +1,28 @@ +#define _APU_IPLROM +#include "iplrom.h" +#include "apuregs.h" + +class APU { +public: +APURegs regs; + enum { + FLAG_N = 0x80, FLAG_V = 0x40, + FLAG_P = 0x20, FLAG_B = 0x10, + FLAG_H = 0x08, FLAG_I = 0x04, + FLAG_Z = 0x02, FLAG_C = 0x01 + }; + + virtual uint8 spcram_read (uint16 addr) = 0; + virtual void spcram_write(uint16 addr, uint8 value) = 0; +//$f4-$f7 + virtual uint8 port_read (uint8 port) = 0; + virtual void port_write(uint8 port, uint8 value) = 0; + + virtual void run() = 0; + virtual uint32 cycles_executed() = 0; + virtual void power() = 0; + virtual void reset() = 0; + + void disassemble_opcode(char *output); + inline uint16 __relb(int8 offset, int op_len); +}; diff --git a/src/apu/apuregs.h b/src/apu/apuregs.h new file mode 100644 index 00000000..3d96dd6f --- /dev/null +++ b/src/apu/apuregs.h @@ -0,0 +1,48 @@ +class APURegFlags { +private: + template class bit { + public: + uint8 _b; + inline operator bool() { return (_b & B); } + inline bool operator = (bool i) { (i) ? _b |= B : _b &= ~B; return (_b & B); } + inline bool operator & (bool i) { if(i)_b &= ~B; return (_b & B); } + inline bool operator &= (bool i) { if(i)_b &= ~B; return (_b & B); } + inline bool operator | (bool i) { if(i)_b |= B; return (_b & B); } + inline bool operator |= (bool i) { if(i)_b |= B; return (_b & B); } + inline bool operator ^ (bool i) { if(i)_b ^= B; return (_b & B); } + inline bool operator ^= (bool i) { if(i)_b ^= B; return (_b & B); } + }; +public: + union { + uint8 _b; + bit<0x80> n; + bit<0x40> v; + bit<0x20> p; + bit<0x10> b; + bit<0x08> h; + bit<0x04> i; + bit<0x02> z; + bit<0x01> c; + }; + + APURegFlags() { _b = 0; } + inline operator uint8() { return _b; } + inline unsigned operator = (uint8 i) { _b = i; return _b; } + inline unsigned operator &= (uint8 i) { _b &= i; return _b; } + inline unsigned operator |= (uint8 i) { _b |= i; return _b; } + inline unsigned operator ^= (uint8 i) { _b ^= i; return _b; } +}; + +class APURegs { +public: +uint16 pc; +union { + uint16 ya; +//not endian-safe + struct { + uint8 a, y; + }; +}; +uint8 x, sp; +APURegFlags p; +}; diff --git a/src/apu/bapu/bapu.cpp b/src/apu/bapu/bapu.cpp new file mode 100644 index 00000000..0ff12828 --- /dev/null +++ b/src/apu/bapu/bapu.cpp @@ -0,0 +1,293 @@ +#include "../../base.h" + +#include "bapu_op_fn.cpp" +#include "bapu_op_mov.cpp" +#include "bapu_op_pc.cpp" +#include "bapu_op_read.cpp" +#include "bapu_op_rmw.cpp" +#include "bapu_op_misc.cpp" + +#include "bapu_exec.cpp" + +uint8 bAPU::spcram_read(uint16 addr) { +uint8 r; + if(addr >= 0x00f0 && addr <= 0x00ff) { + switch(addr) { + case 0xf0: //TEST -- operation unknown, supposedly returns 0x00 + r = 0x00; + break; + case 0xf1: //CONTROL -- write-only register, always returns 0x00 + r = 0x00; + break; + case 0xf2: //DSPADDR + r = status.dsp_addr; + break; + case 0xf3: //DSPDATA + //0x80-0xff is a read-only mirror of 0x00-0x7f + r = dsp_regs[status.dsp_addr & 0x7f]; + break; + case 0xf4: //CPUIO0 + case 0xf5: //CPUIO1 + case 0xf6: //CPUIO2 + case 0xf7: //CPUIO3 + r = cpu->port_read(addr & 3); + break; + case 0xf8: //??? + case 0xf9: //??? -- Mapped to SPCRAM + r = spcram[addr]; + break; + case 0xfa: //T0TARGET + case 0xfb: //T1TARGET + case 0xfc: //T2TARGET -- write-only registers, always return 0x00 + r = 0x00; + break; + case 0xfd: //T0OUT -- 4-bit counter value + r = t0.stage3_ticks & 15; + t0.stage3_ticks = 0; + break; + case 0xfe: //T1OUT -- 4-bit counter value + r = t1.stage3_ticks & 15; + t1.stage3_ticks = 0; + break; + case 0xff: //T2OUT -- 4-bit counter value + r = t2.stage3_ticks & 15; + t2.stage3_ticks = 0; + break; + } + } else if(addr < 0xffc0) { + r = spcram[addr]; + } else { + if(status.iplrom_enabled == true) { + r = iplrom[addr & 0x3f]; + } else { + r = spcram[addr]; + } + } + snes->notify(SNES::SPCRAM_READ, addr, r); + return r; +} + +void bAPU::spcram_write(uint16 addr, uint8 value) { + if(addr >= 0x00f0 && addr <= 0x00ff) { + switch(addr) { + case 0xf0: //TEST -- operation unknown + break; + case 0xf1: //CONTROL + status.iplrom_enabled = !!(value & 0x80); + + //one-time clearing of APU port read registers, + //emulated by simulating CPU writes of 0x00 + if(value & 0x20) { + cpu->port_write(2, 0x00); + cpu->port_write(3, 0x00); + } + if(value & 0x10) { + cpu->port_write(0, 0x00); + cpu->port_write(1, 0x00); + } + + //0->1 transistion resets timers + if(t2.enabled == false && (value & 0x04)) { + t2.stage2_ticks = 0; + t2.stage3_ticks = 0; + } + t2.enabled = !!(value & 0x04); + + if(t1.enabled == false && (value & 0x02)) { + t1.stage2_ticks = 0; + t1.stage3_ticks = 0; + } + t1.enabled = !!(value & 0x02); + + if(t0.enabled == false && (value & 0x01)) { + t0.stage2_ticks = 0; + t0.stage3_ticks = 0; + } + t0.enabled = !!(value & 0x01); + break; + case 0xf2: //DSPADDR + status.dsp_addr = value; + break; + case 0xf3: //DSPDATA + //0x80-0xff is a read-only mirror of 0x00-0x7f + if(status.dsp_addr < 0x80) { + dsp_regs[status.dsp_addr & 0x7f] = value; + } + break; + case 0xf4: //CPUIO0 + case 0xf5: //CPUIO1 + case 0xf6: //CPUIO2 + case 0xf7: //CPUIO3 + port_write(addr & 3, value); + break; + case 0xf8: //??? + case 0xf9: //??? - Mapped to SPCRAM + spcram[addr] = value; + break; + case 0xfa: //T0TARGET + t0.target = value; + break; + case 0xfb: //T1TARGET + t1.target = value; + break; + case 0xfc: //T2TARGET + t2.target = value; + break; + case 0xfd: //T0OUT + case 0xfe: //T1OUT + case 0xff: //T2OUT -- read-only registers + break; + } + } else { + //writes to $ffc0-$ffff always go to spcram, + //even if the iplrom is enabled. + spcram[addr] = value; + } + snes->notify(SNES::SPCRAM_WRITE, addr, value); +} + +uint8 bAPU::port_read(uint8 port) { + return spcram[0xf4 + (port & 3)]; +} + +void bAPU::port_write(uint8 port, uint8 value) { + spcram[0xf4 + (port & 0x03)] = value; +} + +void bAPU::add_cycles(int cycles) { + status.cycles_executed += cycles; + + t0.add_cycles(cycles); + t1.add_cycles(cycles); + t2.add_cycles(cycles); +} + +uint32 bAPU::cycles_executed() { +uint32 r = status.cycles_executed; + status.cycles_executed = 0; + return (r << 4) + (r << 3); +} + +uint8 bAPU::op_read() { +uint8 r; + r = spcram_read(regs.pc); + regs.pc++; + return r; +} + +uint8 bAPU::op_read(uint8 mode, uint16 addr) { +uint8 r; + switch(mode) { + case OPMODE_ADDR: + r = spcram_read(addr); + break; + case OPMODE_DP: + r = spcram_read(((regs.p.p)?0x100:0x000) + (addr & 0xff)); + break; + } + return r; +} + +void bAPU::op_write(uint8 mode, uint16 addr, uint8 value) { + switch(mode) { + case OPMODE_ADDR: + spcram_write(addr, value); + break; + case OPMODE_DP: + spcram_write(((regs.p.p)?0x100:0x000) + (addr & 0xff), value); + break; + } +} + +uint8 bAPU::stack_read() { + regs.sp++; + return spcram_read(0x0100 | regs.sp); +} + +void bAPU::stack_write(uint8 value) { + spcram_write(0x0100 | regs.sp, value); + regs.sp--; +} + +void bAPU::run() { + exec_cycle(); +} + +void bAPU::power() { + memset(spcram, 0x00, 65536); + reset(); +} + +void bAPU::reset() { + regs.pc = 0xffc0; + regs.a = 0x00; + regs.x = 0x00; + regs.y = 0x00; + regs.sp = 0xef; + regs.p = 0x02; + + status.cycle_pos = 0; + +//$f1 + status.iplrom_enabled = true; + + t0.enabled = false; + t1.enabled = false; + t2.enabled = false; + + t0.stage1_ticks = 0; + t1.stage1_ticks = 0; + t2.stage1_ticks = 0; + + t0.stage2_ticks = 0; + t1.stage2_ticks = 0; + t2.stage2_ticks = 0; + + t0.stage3_ticks = 0; + t1.stage3_ticks = 0; + t2.stage3_ticks = 0; + + memset(dsp_regs, 0, 128); +} + +bAPU::bAPU() { + init_op_table(); + + spcram = (uint8*)malloc(65536); + memcpy(iplrom, spc700_iplrom, 64); + + t0.cycle_frequency = 128; //1.024mhz / 8khz = 128 + t1.cycle_frequency = 128; //1.024mhz / 8khz = 128 + t2.cycle_frequency = 16; //1.024mhz / 64khz = 16 + +//targets not initialized/changed upon reset + t0.target = 0; + t1.target = 0; + t2.target = 0; +} + +bAPU::~bAPU() { + if(spcram)free(spcram); +} + +//cycles should never be greater than 12. since the minimum +//cycle_frequency value is 16, we don't have to worry about +//two ticks occuring in one call to this function. +void bAPUTimer::add_cycles(int cycles) { +//stage 1 increment + stage1_ticks += cycles; + if(stage1_ticks < cycle_frequency)return; + + stage1_ticks -= cycle_frequency; + if(enabled == false)return; + +//stage 2 increment + stage2_ticks++; + + if(stage2_ticks != target)return; + +//stage 3 increment + stage2_ticks = 0; + stage3_ticks++; + stage3_ticks &= 15; +} diff --git a/src/apu/bapu/bapu.h b/src/apu/bapu/bapu.h new file mode 100644 index 00000000..a603c547 --- /dev/null +++ b/src/apu/bapu/bapu.h @@ -0,0 +1,79 @@ +class bAPU; + +class bAPUTimer { +public: +uint8 cycle_frequency, target; +uint8 stage1_ticks, stage2_ticks, stage3_ticks; +bool enabled; + inline void add_cycles(int cycles); +}; + +class bAPU : public APU { +private: +typedef void (bAPU::*op)(); +op optbl[256]; + +public: +uint16 dp, sp, rd, wr, bit, ya; + +struct { + uint8 cycle_pos, opcode; + uint32 cycles_executed; + +//$f1 + bool iplrom_enabled; + +//$f2 + uint8 dsp_addr; +}status; + +bAPUTimer t0, t1, t2; + +uint8 *spcram, iplrom[64], dsp_regs[128]; + inline uint8 spcram_read (uint16 addr); + inline void spcram_write(uint16 addr, uint8 value); + inline uint8 port_read (uint8 port); + inline void port_write(uint8 port, uint8 value); + + inline void run(); + inline uint32 cycles_executed(); + inline void power(); + inline void reset(); + + inline void add_cycles(int cycles); + +enum { + OPMODE_ADDR = 0, + OPMODE_DP = 1 +}; + inline uint8 op_read(); + inline uint8 op_read (uint8 mode, uint16 addr); + inline void op_write(uint8 mode, uint16 addr, uint8 value); + inline uint8 stack_read(); + inline void stack_write(uint8 value); + + inline void exec_cycle(); + inline void init_op_table(); + + inline uint8 op_adc (uint8 x, uint8 y); + inline uint16 op_addw(uint16 x, uint16 y); + inline uint8 op_and (uint8 x, uint8 y); + inline uint8 op_cmp (uint8 x, uint8 y); + inline uint16 op_cmpw(uint16 x, uint16 y); + inline uint8 op_eor (uint8 x, uint8 y); + inline uint8 op_inc (uint8 x); + inline uint16 op_incw(uint16 x); + inline uint8 op_dec (uint8 x); + inline uint16 op_decw(uint16 x); + inline uint8 op_or (uint8 x, uint8 y); + inline uint8 op_sbc (uint8 x, uint8 y); + inline uint16 op_subw(uint16 x, uint16 y); + inline uint8 op_asl (uint8 x); + inline uint8 op_lsr (uint8 x); + inline uint8 op_rol (uint8 x); + inline uint8 op_ror (uint8 x); +#include "bapu_op.h" + + bAPU(); + ~bAPU(); +}; diff --git a/src/apu/bapu/bapu_exec.cpp b/src/apu/bapu/bapu_exec.cpp new file mode 100644 index 00000000..279d5fcb --- /dev/null +++ b/src/apu/bapu/bapu_exec.cpp @@ -0,0 +1,20 @@ +void bAPU::exec_cycle() { +uint8 op; + if(status.cycle_pos == 0) { + op = spcram_read(regs.pc); + snes->notify(SNES::APU_EXEC_OPCODE_BEGIN); + status.opcode = op_read(); + status.cycle_pos = 1; + add_cycles(1); + } else { + (this->*optbl[status.opcode])(); + add_cycles(1); + if(status.cycle_pos == 0) { + snes->notify(SNES::APU_EXEC_OPCODE_END); + } + } +} + +void bAPU::init_op_table() { +#include "bapu_optable.cpp" +} diff --git a/src/apu/bapu/bapu_op.h b/src/apu/bapu/bapu_op.h new file mode 100644 index 00000000..da2b2856 --- /dev/null +++ b/src/apu/bapu/bapu_op.h @@ -0,0 +1,256 @@ +void op_mov_a_x(); +void op_mov_a_y(); +void op_mov_x_a(); +void op_mov_y_a(); +void op_mov_x_sp(); +void op_mov_sp_x(); +void op_mov_a_const(); +void op_mov_x_const(); +void op_mov_y_const(); +void op_mov_a_ix(); +void op_mov_a_ixinc(); +void op_mov_a_dp(); +void op_mov_x_dp(); +void op_mov_y_dp(); +void op_mov_a_dpx(); +void op_mov_x_dpy(); +void op_mov_y_dpx(); +void op_mov_a_addr(); +void op_mov_x_addr(); +void op_mov_y_addr(); +void op_mov_a_addrx(); +void op_mov_a_addry(); +void op_mov_a_idpx(); +void op_mov_a_idpy(); +void op_mov_dp_dp(); +void op_mov_dp_const(); +void op_mov_ix_a(); +void op_mov_ixinc_a(); +void op_mov_dp_a(); +void op_mov_dp_x(); +void op_mov_dp_y(); +void op_mov_dpx_a(); +void op_mov_dpy_x(); +void op_mov_dpx_y(); +void op_mov_addr_a(); +void op_mov_addr_x(); +void op_mov_addr_y(); +void op_mov_addrx_a(); +void op_mov_addry_a(); +void op_mov_idpx_a(); +void op_mov_idpy_a(); +void op_movw_ya_dp(); +void op_movw_dp_ya(); +void op_mov1_c_bit(); +void op_mov1_bit_c(); +void op_bra(); +void op_beq(); +void op_bne(); +void op_bcs(); +void op_bcc(); +void op_bvs(); +void op_bvc(); +void op_bmi(); +void op_bpl(); +void op_bbs0(); +void op_bbc0(); +void op_bbs1(); +void op_bbc1(); +void op_bbs2(); +void op_bbc2(); +void op_bbs3(); +void op_bbc3(); +void op_bbs4(); +void op_bbc4(); +void op_bbs5(); +void op_bbc5(); +void op_bbs6(); +void op_bbc6(); +void op_bbs7(); +void op_bbc7(); +void op_cbne_dp(); +void op_cbne_dpx(); +void op_dbnz_dp(); +void op_dbnz_y(); +void op_jmp_addr(); +void op_jmp_iaddrx(); +void op_call(); +void op_pcall(); +void op_tcall_0(); +void op_tcall_1(); +void op_tcall_2(); +void op_tcall_3(); +void op_tcall_4(); +void op_tcall_5(); +void op_tcall_6(); +void op_tcall_7(); +void op_tcall_8(); +void op_tcall_9(); +void op_tcall_10(); +void op_tcall_11(); +void op_tcall_12(); +void op_tcall_13(); +void op_tcall_14(); +void op_tcall_15(); +void op_brk(); +void op_ret(); +void op_reti(); +void op_adc_a_const(); +void op_and_a_const(); +void op_cmp_a_const(); +void op_cmp_x_const(); +void op_cmp_y_const(); +void op_eor_a_const(); +void op_or_a_const(); +void op_sbc_a_const(); +void op_adc_a_ix(); +void op_and_a_ix(); +void op_cmp_a_ix(); +void op_eor_a_ix(); +void op_or_a_ix(); +void op_sbc_a_ix(); +void op_adc_a_dp(); +void op_and_a_dp(); +void op_cmp_a_dp(); +void op_cmp_x_dp(); +void op_cmp_y_dp(); +void op_eor_a_dp(); +void op_or_a_dp(); +void op_sbc_a_dp(); +void op_adc_a_dpx(); +void op_and_a_dpx(); +void op_cmp_a_dpx(); +void op_eor_a_dpx(); +void op_or_a_dpx(); +void op_sbc_a_dpx(); +void op_adc_a_addr(); +void op_and_a_addr(); +void op_cmp_a_addr(); +void op_cmp_x_addr(); +void op_cmp_y_addr(); +void op_eor_a_addr(); +void op_or_a_addr(); +void op_sbc_a_addr(); +void op_adc_a_addrx(); +void op_adc_a_addry(); +void op_and_a_addrx(); +void op_and_a_addry(); +void op_cmp_a_addrx(); +void op_cmp_a_addry(); +void op_eor_a_addrx(); +void op_eor_a_addry(); +void op_or_a_addrx(); +void op_or_a_addry(); +void op_sbc_a_addrx(); +void op_sbc_a_addry(); +void op_adc_a_idpx(); +void op_and_a_idpx(); +void op_cmp_a_idpx(); +void op_eor_a_idpx(); +void op_or_a_idpx(); +void op_sbc_a_idpx(); +void op_adc_a_idpy(); +void op_and_a_idpy(); +void op_cmp_a_idpy(); +void op_eor_a_idpy(); +void op_or_a_idpy(); +void op_sbc_a_idpy(); +void op_adc_ix_iy(); +void op_and_ix_iy(); +void op_cmp_ix_iy(); +void op_eor_ix_iy(); +void op_or_ix_iy(); +void op_sbc_ix_iy(); +void op_adc_dp_dp(); +void op_and_dp_dp(); +void op_cmp_dp_dp(); +void op_eor_dp_dp(); +void op_or_dp_dp(); +void op_sbc_dp_dp(); +void op_adc_dp_const(); +void op_and_dp_const(); +void op_cmp_dp_const(); +void op_eor_dp_const(); +void op_or_dp_const(); +void op_sbc_dp_const(); +void op_addw_ya_dp(); +void op_cmpw_ya_dp(); +void op_subw_ya_dp(); +void op_and1_bit(); +void op_and1_notbit(); +void op_eor1_bit(); +void op_not1_bit(); +void op_or1_bit(); +void op_or1_notbit(); +void op_inc_a(); +void op_inc_x(); +void op_inc_y(); +void op_dec_a(); +void op_dec_x(); +void op_dec_y(); +void op_asl_a(); +void op_lsr_a(); +void op_rol_a(); +void op_ror_a(); +void op_inc_dp(); +void op_dec_dp(); +void op_asl_dp(); +void op_lsr_dp(); +void op_rol_dp(); +void op_ror_dp(); +void op_inc_dpx(); +void op_dec_dpx(); +void op_asl_dpx(); +void op_lsr_dpx(); +void op_rol_dpx(); +void op_ror_dpx(); +void op_inc_addr(); +void op_dec_addr(); +void op_asl_addr(); +void op_lsr_addr(); +void op_rol_addr(); +void op_ror_addr(); +void op_incw_dp(); +void op_decw_dp(); +void op_nop(); +void op_sleep(); +void op_stop(); +void op_xcn(); +void op_daa(); +void op_das(); +void op_clrc(); +void op_clrp(); +void op_setc(); +void op_setp(); +void op_clrv(); +void op_notc(); +void op_ei(); +void op_di(); +void op_set0_dp(); +void op_clr0_dp(); +void op_set1_dp(); +void op_clr1_dp(); +void op_set2_dp(); +void op_clr2_dp(); +void op_set3_dp(); +void op_clr3_dp(); +void op_set4_dp(); +void op_clr4_dp(); +void op_set5_dp(); +void op_clr5_dp(); +void op_set6_dp(); +void op_clr6_dp(); +void op_set7_dp(); +void op_clr7_dp(); +void op_tset_addr_a(); +void op_tclr_addr_a(); +void op_push_a(); +void op_push_x(); +void op_push_y(); +void op_push_p(); +void op_pop_a(); +void op_pop_x(); +void op_pop_y(); +void op_pop_p(); +void op_mul_ya(); +void op_div_ya_x(); diff --git a/src/apu/bapu/bapu_op_fn.cpp b/src/apu/bapu/bapu_op_fn.cpp new file mode 100644 index 00000000..4819c448 --- /dev/null +++ b/src/apu/bapu/bapu_op_fn.cpp @@ -0,0 +1,140 @@ +uint8 bAPU::op_adc(uint8 x, uint8 y) { +int16 r = x + y + regs.p.c; + regs.p.n = !!(r & 0x80); + regs.p.v = !!(~(x ^ y) & (y ^ (uint8)r) & 0x80); + regs.p.h = !!((x ^ y ^ (uint8)r) & 0x10); + regs.p.z = ((uint8)r == 0); + regs.p.c = (r > 0xff); + return r; +} + +uint16 bAPU::op_addw(uint16 x, uint16 y) { +int32 r = x + y; + regs.p.n = !!(r & 0x8000); + regs.p.v = !!(~(x ^ y) & (y ^ (uint16)r) & 0x8000); + regs.p.h = !!((x ^ y ^ (uint16)r) & 0x10); + regs.p.z = ((uint16)r == 0); + regs.p.c = (r > 0xffff); + return r; +} + +uint8 bAPU::op_and(uint8 x, uint8 y) { + x &= y; + regs.p.n = !!(x & 0x80); + regs.p.z = (x == 0); + return x; +} + +uint8 bAPU::op_cmp(uint8 x, uint8 y) { +int16 r = x - y; + regs.p.n = !!(r & 0x80); + regs.p.z = ((uint8)r == 0); + regs.p.c = (r >= 0); + return x; +} + +uint16 bAPU::op_cmpw(uint16 x, uint16 y) { +int32 r = x - y; + regs.p.n = !!(r & 0x8000); + regs.p.z = ((uint16)r == 0); + regs.p.c = (r >= 0); + return x; +} + +uint8 bAPU::op_eor(uint8 x, uint8 y) { + x ^= y; + regs.p.n = !!(x & 0x80); + regs.p.z = (x == 0); + return x; +} + +uint8 bAPU::op_or(uint8 x, uint8 y) { + x |= y; + regs.p.n = !!(x & 0x80); + regs.p.z = (x == 0); + return x; +} + +uint8 bAPU::op_sbc(uint8 x, uint8 y) { +int16 r = x - y - !regs.p.c; + regs.p.n = !!(r & 0x80); + regs.p.v = !!((x ^ y) & (x ^ (uint8)r) & 0x80); + regs.p.h = !((x ^ y ^ (uint8)r) & 0x10); + regs.p.z = ((uint8)r == 0); + regs.p.c = (r >= 0); + return r; +} + +uint16 bAPU::op_subw(uint16 x, uint16 y) { +int32 r = x - y; + regs.p.n = !!(r & 0x8000); + regs.p.v = !!((x ^ y) & (x ^ (uint16)r) & 0x8000); + regs.p.h = !((x ^ y ^ (uint16)r) & 0x10); + regs.p.z = ((uint16)r == 0); + regs.p.c = (r >= 0); + return r; +} + +uint8 bAPU::op_inc(uint8 x) { + x++; + regs.p.n = !!(x & 0x80); + regs.p.z = (x == 0); + return x; +} + +uint16 bAPU::op_incw(uint16 x) { + x++; + regs.p.n = !!(x & 0x8000); + regs.p.z = (x == 0); + return x; +} + +uint8 bAPU::op_dec(uint8 x) { + x--; + regs.p.n = !!(x & 0x80); + regs.p.z = (x == 0); + return x; +} + +uint16 bAPU::op_decw(uint16 x) { + x--; + regs.p.n = !!(x & 0x8000); + regs.p.z = (x == 0); + return x; +} + +uint8 bAPU::op_asl(uint8 x) { + regs.p.c = !!(x & 0x80); + x <<= 1; + regs.p.n = !!(x & 0x80); + regs.p.z = (x == 0); + return x; +} + +uint8 bAPU::op_lsr(uint8 x) { + regs.p.c = !!(x & 0x01); + x >>= 1; + regs.p.n = !!(x & 0x80); + regs.p.z = (x == 0); + return x; +} + +uint8 bAPU::op_rol(uint8 x) { +uint8 c = regs.p.c; + regs.p.c = !!(x & 0x80); + x <<= 1; + x |= c; + regs.p.n = !!(x & 0x80); + regs.p.z = (x == 0); + return x; +} + +uint8 bAPU::op_ror(uint8 x) { +uint8 c = (regs.p.c)?0x80:0x00; + regs.p.c = !!(x & 0x01); + x >>= 1; + x |= c; + regs.p.n = !!(x & 0x80); + regs.p.z = (x == 0); + return x; +} diff --git a/src/apu/bapu/bapu_op_misc.cpp b/src/apu/bapu/bapu_op_misc.cpp new file mode 100644 index 00000000..43978f61 --- /dev/null +++ b/src/apu/bapu/bapu_op_misc.cpp @@ -0,0 +1,643 @@ +void bAPU::op_nop() { + switch(status.cycle_pos++) { + case 1: + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_sleep() { + switch(status.cycle_pos++) { + case 1: + break; + case 2: + regs.pc--; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_stop() { + switch(status.cycle_pos++) { + case 1: + break; + case 2: + regs.pc--; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_xcn() { + switch(status.cycle_pos++) { + case 1: + break; + case 2: + break; + case 3: + break; + case 4: + regs.a = (regs.a >> 4) | (regs.a << 4); + regs.p.n = !!(regs.a & 0x80); + regs.p.z = (regs.a == 0); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_daa() { + switch(status.cycle_pos++) { + case 1: + break; + case 2: + if(regs.p.c || (regs.a) > 0x99) { + regs.a += 0x60; + regs.p.c = 1; + } + if(regs.p.h || (regs.a & 15) > 0x09) { + regs.a += 0x06; + } + regs.p.n = !!(regs.a & 0x80); + regs.p.z = (regs.a == 0); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_das() { + switch(status.cycle_pos++) { + case 1: + break; + case 2: + if(!regs.p.c || (regs.a) > 0x99) { + regs.a -= 0x60; + regs.p.c = 0; + } + if(!regs.p.h || (regs.a & 15) > 0x09) { + regs.a -= 0x06; + } + regs.p.n = !!(regs.a & 0x80); + regs.p.z = (regs.a == 0); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_clrc() { + switch(status.cycle_pos++) { + case 1: + regs.p.c = 0; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_clrp() { + switch(status.cycle_pos++) { + case 1: + regs.p.p = 0; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_setc() { + switch(status.cycle_pos++) { + case 1: + regs.p.c = 1; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_setp() { + switch(status.cycle_pos++) { + case 1: + regs.p.p = 1; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_clrv() { + switch(status.cycle_pos++) { + case 1: + regs.p.v = 0; + regs.p.h = 0; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_notc() { + switch(status.cycle_pos++) { + case 1: + break; + case 2: + regs.p.c ^= 1; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_ei() { + switch(status.cycle_pos++) { + case 1: + break; + case 2: + regs.p.i = 1; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_di() { + switch(status.cycle_pos++) { + case 1: + break; + case 2: + regs.p.i = 0; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_set0_dp() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(OPMODE_DP, dp); + break; + case 3: + rd |= 0x01; + op_write(OPMODE_DP, dp, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_clr0_dp() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(OPMODE_DP, dp); + break; + case 3: + rd &= ~0x01; + op_write(OPMODE_DP, dp, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_set1_dp() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(OPMODE_DP, dp); + break; + case 3: + rd |= 0x02; + op_write(OPMODE_DP, dp, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_clr1_dp() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(OPMODE_DP, dp); + break; + case 3: + rd &= ~0x02; + op_write(OPMODE_DP, dp, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_set2_dp() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(OPMODE_DP, dp); + break; + case 3: + rd |= 0x04; + op_write(OPMODE_DP, dp, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_clr2_dp() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(OPMODE_DP, dp); + break; + case 3: + rd &= ~0x04; + op_write(OPMODE_DP, dp, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_set3_dp() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(OPMODE_DP, dp); + break; + case 3: + rd |= 0x08; + op_write(OPMODE_DP, dp, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_clr3_dp() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(OPMODE_DP, dp); + break; + case 3: + rd &= ~0x08; + op_write(OPMODE_DP, dp, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_set4_dp() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(OPMODE_DP, dp); + break; + case 3: + rd |= 0x10; + op_write(OPMODE_DP, dp, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_clr4_dp() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(OPMODE_DP, dp); + break; + case 3: + rd &= ~0x10; + op_write(OPMODE_DP, dp, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_set5_dp() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(OPMODE_DP, dp); + break; + case 3: + rd |= 0x20; + op_write(OPMODE_DP, dp, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_clr5_dp() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(OPMODE_DP, dp); + break; + case 3: + rd &= ~0x20; + op_write(OPMODE_DP, dp, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_set6_dp() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(OPMODE_DP, dp); + break; + case 3: + rd |= 0x40; + op_write(OPMODE_DP, dp, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_clr6_dp() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(OPMODE_DP, dp); + break; + case 3: + rd &= ~0x40; + op_write(OPMODE_DP, dp, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_set7_dp() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(OPMODE_DP, dp); + break; + case 3: + rd |= 0x80; + op_write(OPMODE_DP, dp, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_clr7_dp() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(OPMODE_DP, dp); + break; + case 3: + rd &= ~0x80; + op_write(OPMODE_DP, dp, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_tset_addr_a() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + dp |= op_read() << 8; + break; + case 3: + rd = op_read(OPMODE_ADDR, dp); + break; + case 4: + regs.p.n = !!((rd & regs.a) & 0x80); + regs.p.z = ((rd & regs.a) == 0); + rd |= regs.a; + break; + case 5: + op_write(OPMODE_ADDR, dp, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_tclr_addr_a() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + dp |= op_read() << 8; + break; + case 3: + rd = op_read(OPMODE_ADDR, dp); + break; + case 4: + regs.p.n = !!((rd & regs.a) & 0x80); + regs.p.z = ((rd & regs.a) == 0); + rd &=~ regs.a; + break; + case 5: + op_write(OPMODE_ADDR, dp, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_push_a() { + switch(status.cycle_pos++) { + case 1: + break; + case 2: + break; + case 3: + stack_write(regs.a); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_push_x() { + switch(status.cycle_pos++) { + case 1: + break; + case 2: + break; + case 3: + stack_write(regs.x); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_push_y() { + switch(status.cycle_pos++) { + case 1: + break; + case 2: + break; + case 3: + stack_write(regs.y); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_push_p() { + switch(status.cycle_pos++) { + case 1: + break; + case 2: + break; + case 3: + stack_write(regs.p); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_pop_a() { + switch(status.cycle_pos++) { + case 1: + break; + case 2: + break; + case 3: + regs.a = stack_read(); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_pop_x() { + switch(status.cycle_pos++) { + case 1: + break; + case 2: + break; + case 3: + regs.x = stack_read(); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_pop_y() { + switch(status.cycle_pos++) { + case 1: + break; + case 2: + break; + case 3: + regs.y = stack_read(); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_pop_p() { + switch(status.cycle_pos++) { + case 1: + break; + case 2: + break; + case 3: + regs.p = stack_read(); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_mul_ya() { + switch(status.cycle_pos++) { + case 1: + break; + case 2: + break; + case 3: + break; + case 4: + break; + case 5: + break; + case 6: + break; + case 7: + break; + case 8: + ya = regs.y * regs.a; + regs.a = ya; + regs.y = ya >> 8; + //result is set based on y (high-byte) only + regs.p.n = !!(regs.y & 0x80); + regs.p.z = (regs.y == 0); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_div_ya_x() { + switch(status.cycle_pos++) { + case 1: + break; + case 2: + break; + case 3: + break; + case 4: + break; + case 5: + break; + case 6: + break; + case 7: + break; + case 8: + break; + case 9: + break; + case 10: + break; + case 11: + ya = regs.ya; + //overflow set if quotient >= 256 + regs.p.v = !!(regs.y >= regs.x); + regs.p.h = !!((regs.y & 15) >= (regs.x & 15)); + if(regs.y < (regs.x << 1)) { + //if quotient is <= 511 (will fit into 9-bit result) + regs.a = ya / regs.x; + regs.y = ya % regs.x; + } else { + //otherwise, the quotient won't fit into regs.p.v + regs.a + //this emulates the odd behavior of the SPC700 in this case + regs.a = 255 - (ya - (regs.x << 9)) / (256 - regs.x); + regs.y = regs.x + (ya - (regs.x << 9)) % (256 - regs.x); + } + //result is set based on a (quotient) only + regs.p.n = !!(regs.a & 0x80); + regs.p.z = (regs.a == 0); + status.cycle_pos = 0; + break; + } +} + diff --git a/src/apu/bapu/bapu_op_mov.cpp b/src/apu/bapu/bapu_op_mov.cpp new file mode 100644 index 00000000..c97d8132 --- /dev/null +++ b/src/apu/bapu/bapu_op_mov.cpp @@ -0,0 +1,710 @@ +void bAPU::op_mov_a_x() { + switch(status.cycle_pos++) { + case 1: + regs.a = regs.x; + regs.p.n = !!(regs.a & 0x80); + regs.p.z = (regs.a == 0); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_mov_a_y() { + switch(status.cycle_pos++) { + case 1: + regs.a = regs.y; + regs.p.n = !!(regs.a & 0x80); + regs.p.z = (regs.a == 0); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_mov_x_a() { + switch(status.cycle_pos++) { + case 1: + regs.x = regs.a; + regs.p.n = !!(regs.x & 0x80); + regs.p.z = (regs.x == 0); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_mov_y_a() { + switch(status.cycle_pos++) { + case 1: + regs.y = regs.a; + regs.p.n = !!(regs.y & 0x80); + regs.p.z = (regs.y == 0); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_mov_x_sp() { + switch(status.cycle_pos++) { + case 1: + regs.x = regs.sp; + regs.p.n = !!(regs.x & 0x80); + regs.p.z = (regs.x == 0); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_mov_sp_x() { + switch(status.cycle_pos++) { + case 1: + regs.sp = regs.x; + regs.p.n = !!(regs.sp & 0x80); + regs.p.z = (regs.sp == 0); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_mov_a_const() { + switch(status.cycle_pos++) { + case 1: + regs.a = op_read(); + regs.p.n = !!(regs.a & 0x80); + regs.p.z = (regs.a == 0); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_mov_x_const() { + switch(status.cycle_pos++) { + case 1: + regs.x = op_read(); + regs.p.n = !!(regs.x & 0x80); + regs.p.z = (regs.x == 0); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_mov_y_const() { + switch(status.cycle_pos++) { + case 1: + regs.y = op_read(); + regs.p.n = !!(regs.y & 0x80); + regs.p.z = (regs.y == 0); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_mov_a_ix() { + switch(status.cycle_pos++) { + case 1: + break; + case 2: + regs.a = op_read(OPMODE_DP, regs.x); + regs.p.n = !!(regs.a & 0x80); + regs.p.z = (regs.a == 0); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_mov_a_ixinc() { + switch(status.cycle_pos++) { + case 1: + break; + case 2: + break; + case 3: + regs.a = op_read(OPMODE_DP, regs.x++); + regs.p.n = !!(regs.a & 0x80); + regs.p.z = (regs.a == 0); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_mov_a_dp() { + switch(status.cycle_pos++) { + case 1: + sp = op_read(); + break; + case 2: + regs.a = op_read(OPMODE_DP, sp); + regs.p.n = !!(regs.a & 0x80); + regs.p.z = (regs.a == 0); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_mov_x_dp() { + switch(status.cycle_pos++) { + case 1: + sp = op_read(); + break; + case 2: + regs.x = op_read(OPMODE_DP, sp); + regs.p.n = !!(regs.x & 0x80); + regs.p.z = (regs.x == 0); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_mov_y_dp() { + switch(status.cycle_pos++) { + case 1: + sp = op_read(); + break; + case 2: + regs.y = op_read(OPMODE_DP, sp); + regs.p.n = !!(regs.y & 0x80); + regs.p.z = (regs.y == 0); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_mov_a_dpx() { + switch(status.cycle_pos++) { + case 1: + sp = op_read(); + break; + case 2: + break; + case 3: + regs.a = op_read(OPMODE_DP, sp + regs.x); + regs.p.n = !!(regs.a & 0x80); + regs.p.z = (regs.a == 0); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_mov_x_dpy() { + switch(status.cycle_pos++) { + case 1: + sp = op_read(); + break; + case 2: + break; + case 3: + regs.x = op_read(OPMODE_DP, sp + regs.y); + regs.p.n = !!(regs.x & 0x80); + regs.p.z = (regs.x == 0); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_mov_y_dpx() { + switch(status.cycle_pos++) { + case 1: + sp = op_read(); + break; + case 2: + break; + case 3: + regs.y = op_read(OPMODE_DP, sp + regs.x); + regs.p.n = !!(regs.y & 0x80); + regs.p.z = (regs.y == 0); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_mov_a_addr() { + switch(status.cycle_pos++) { + case 1: + sp = op_read(); + break; + case 2: + sp |= op_read() << 8; + break; + case 3: + regs.a = op_read(OPMODE_ADDR, sp); + regs.p.n = !!(regs.a & 0x80); + regs.p.z = (regs.a == 0); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_mov_x_addr() { + switch(status.cycle_pos++) { + case 1: + sp = op_read(); + break; + case 2: + sp |= op_read() << 8; + break; + case 3: + regs.x = op_read(OPMODE_ADDR, sp); + regs.p.n = !!(regs.x & 0x80); + regs.p.z = (regs.x == 0); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_mov_y_addr() { + switch(status.cycle_pos++) { + case 1: + sp = op_read(); + break; + case 2: + sp |= op_read() << 8; + break; + case 3: + regs.y = op_read(OPMODE_ADDR, sp); + regs.p.n = !!(regs.y & 0x80); + regs.p.z = (regs.y == 0); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_mov_a_addrx() { + switch(status.cycle_pos++) { + case 1: + sp = op_read(); + break; + case 2: + sp |= op_read() << 8; + break; + case 3: + break; + case 4: + regs.a = op_read(OPMODE_ADDR, sp + regs.x); + regs.p.n = !!(regs.a & 0x80); + regs.p.z = (regs.a == 0); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_mov_a_addry() { + switch(status.cycle_pos++) { + case 1: + sp = op_read(); + break; + case 2: + sp |= op_read() << 8; + break; + case 3: + break; + case 4: + regs.a = op_read(OPMODE_ADDR, sp + regs.y); + regs.p.n = !!(regs.a & 0x80); + regs.p.z = (regs.a == 0); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_mov_a_idpx() { + switch(status.cycle_pos++) { + case 1: + dp = op_read() + regs.x; + break; + case 2: + break; + case 3: + sp = op_read(OPMODE_DP, dp); + break; + case 4: + sp |= op_read(OPMODE_DP, dp + 1) << 8; + break; + case 5: + regs.a = op_read(OPMODE_ADDR, sp); + regs.p.n = !!(regs.a & 0x80); + regs.p.z = (regs.a == 0); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_mov_a_idpy() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + break; + case 3: + sp = op_read(OPMODE_DP, dp); + break; + case 4: + sp |= op_read(OPMODE_DP, dp + 1) << 8; + break; + case 5: + regs.a = op_read(OPMODE_ADDR, sp + regs.y); + regs.p.n = !!(regs.a & 0x80); + regs.p.z = (regs.a == 0); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_mov_dp_dp() { + switch(status.cycle_pos++) { + case 1: + sp = op_read(); + break; + case 2: + dp = op_read(); + break; + case 3: + rd = op_read(OPMODE_DP, sp); + break; + case 4: + op_write(OPMODE_DP, dp, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_mov_dp_const() { + switch(status.cycle_pos++) { + case 1: + rd = op_read(); + break; + case 2: + dp = op_read(); + break; + case 3: + break; + case 4: + op_write(OPMODE_DP, dp, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_mov_ix_a() { + switch(status.cycle_pos++) { + case 1: + break; + case 2: + break; + case 3: + op_write(OPMODE_DP, regs.x, regs.a); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_mov_ixinc_a() { + switch(status.cycle_pos++) { + case 1: + break; + case 2: + break; + case 3: + op_write(OPMODE_DP, regs.x++, regs.a); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_mov_dp_a() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + break; + case 3: + op_write(OPMODE_DP, dp, regs.a); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_mov_dp_x() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + break; + case 3: + op_write(OPMODE_DP, dp, regs.x); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_mov_dp_y() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + break; + case 3: + op_write(OPMODE_DP, dp, regs.y); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_mov_dpx_a() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + break; + case 3: + break; + case 4: + op_write(OPMODE_DP, dp + regs.x, regs.a); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_mov_dpy_x() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + break; + case 3: + break; + case 4: + op_write(OPMODE_DP, dp + regs.y, regs.x); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_mov_dpx_y() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + break; + case 3: + break; + case 4: + op_write(OPMODE_DP, dp + regs.x, regs.y); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_mov_addr_a() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + dp |= op_read() << 8; + break; + case 3: + break; + case 4: + op_write(OPMODE_ADDR, dp, regs.a); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_mov_addr_x() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + dp |= op_read() << 8; + break; + case 3: + break; + case 4: + op_write(OPMODE_ADDR, dp, regs.x); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_mov_addr_y() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + dp |= op_read() << 8; + break; + case 3: + break; + case 4: + op_write(OPMODE_ADDR, dp, regs.y); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_mov_addrx_a() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + dp |= op_read() << 8; + break; + case 3: + break; + case 4: + break; + case 5: + op_write(OPMODE_ADDR, dp + regs.x, regs.a); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_mov_addry_a() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + dp |= op_read() << 8; + break; + case 3: + break; + case 4: + break; + case 5: + op_write(OPMODE_ADDR, dp + regs.y, regs.a); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_mov_idpx_a() { + switch(status.cycle_pos++) { + case 1: + sp = op_read() + regs.x; + break; + case 2: + break; + case 3: + dp = op_read(OPMODE_DP, sp); + break; + case 4: + dp |= op_read(OPMODE_DP, sp + 1) << 8; + break; + case 5: + break; + case 6: + op_write(OPMODE_ADDR, dp, regs.a); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_mov_idpy_a() { + switch(status.cycle_pos++) { + case 1: + sp = op_read(); + break; + case 2: + break; + case 3: + dp = op_read(OPMODE_DP, sp); + break; + case 4: + dp |= op_read(OPMODE_DP, sp + 1) << 8; + break; + case 5: + break; + case 6: + op_write(OPMODE_ADDR, dp + regs.y, regs.a); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_movw_ya_dp() { + switch(status.cycle_pos++) { + case 1: + sp = op_read(); + break; + case 2: + break; + case 3: + regs.a = op_read(OPMODE_DP, sp); + break; + case 4: + regs.y = op_read(OPMODE_DP, sp + 1); + regs.p.n = !!(regs.ya & 0x8000); + regs.p.z = (regs.ya == 0); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_movw_dp_ya() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + break; + case 3: + op_write(OPMODE_DP, dp, regs.a); + break; + case 4: + op_write(OPMODE_DP, dp + 1, regs.y); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_mov1_c_bit() { + switch(status.cycle_pos++) { + case 1: + sp = op_read(); + break; + case 2: + sp |= op_read() << 8; + break; + case 3: + bit = sp >> 13; + sp &= 0x1fff; + rd = op_read(OPMODE_ADDR, sp); + regs.p.c = !!(rd & (1 << bit)); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_mov1_bit_c() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + dp |= op_read() << 8; + break; + case 3: + bit = dp >> 13; + dp &= 0x1fff; + rd = op_read(OPMODE_ADDR, dp); + if(regs.p.c)rd |= (1 << bit); + else rd &= ~(1 << bit); + break; + case 4: + op_write(OPMODE_ADDR, dp, rd); + status.cycle_pos = 0; + break; + } +} + diff --git a/src/apu/bapu/bapu_op_pc.cpp b/src/apu/bapu/bapu_op_pc.cpp new file mode 100644 index 00000000..98f4e788 --- /dev/null +++ b/src/apu/bapu/bapu_op_pc.cpp @@ -0,0 +1,1155 @@ +void bAPU::op_bra() { + switch(status.cycle_pos++) { + case 1: + rd = op_read(); + if(0)status.cycle_pos = 0; + break; + case 2: + break; + case 3: + regs.pc += (int8)rd; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_beq() { + switch(status.cycle_pos++) { + case 1: + rd = op_read(); + if(!regs.p.z)status.cycle_pos = 0; + break; + case 2: + break; + case 3: + regs.pc += (int8)rd; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_bne() { + switch(status.cycle_pos++) { + case 1: + rd = op_read(); + if(regs.p.z)status.cycle_pos = 0; + break; + case 2: + break; + case 3: + regs.pc += (int8)rd; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_bcs() { + switch(status.cycle_pos++) { + case 1: + rd = op_read(); + if(!regs.p.c)status.cycle_pos = 0; + break; + case 2: + break; + case 3: + regs.pc += (int8)rd; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_bcc() { + switch(status.cycle_pos++) { + case 1: + rd = op_read(); + if(regs.p.c)status.cycle_pos = 0; + break; + case 2: + break; + case 3: + regs.pc += (int8)rd; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_bvs() { + switch(status.cycle_pos++) { + case 1: + rd = op_read(); + if(!regs.p.v)status.cycle_pos = 0; + break; + case 2: + break; + case 3: + regs.pc += (int8)rd; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_bvc() { + switch(status.cycle_pos++) { + case 1: + rd = op_read(); + if(regs.p.v)status.cycle_pos = 0; + break; + case 2: + break; + case 3: + regs.pc += (int8)rd; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_bmi() { + switch(status.cycle_pos++) { + case 1: + rd = op_read(); + if(!regs.p.n)status.cycle_pos = 0; + break; + case 2: + break; + case 3: + regs.pc += (int8)rd; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_bpl() { + switch(status.cycle_pos++) { + case 1: + rd = op_read(); + if(regs.p.n)status.cycle_pos = 0; + break; + case 2: + break; + case 3: + regs.pc += (int8)rd; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_bbs0() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(); + break; + case 3: + sp = op_read(OPMODE_DP, dp); + break; + case 4: + if((sp & 0x01) != 0x01)status.cycle_pos = 0; + break; + case 5: + break; + case 6: + regs.pc += (int8)rd; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_bbc0() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(); + break; + case 3: + sp = op_read(OPMODE_DP, dp); + break; + case 4: + if((sp & 0x01) == 0x01)status.cycle_pos = 0; + break; + case 5: + break; + case 6: + regs.pc += (int8)rd; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_bbs1() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(); + break; + case 3: + sp = op_read(OPMODE_DP, dp); + break; + case 4: + if((sp & 0x02) != 0x02)status.cycle_pos = 0; + break; + case 5: + break; + case 6: + regs.pc += (int8)rd; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_bbc1() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(); + break; + case 3: + sp = op_read(OPMODE_DP, dp); + break; + case 4: + if((sp & 0x02) == 0x02)status.cycle_pos = 0; + break; + case 5: + break; + case 6: + regs.pc += (int8)rd; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_bbs2() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(); + break; + case 3: + sp = op_read(OPMODE_DP, dp); + break; + case 4: + if((sp & 0x04) != 0x04)status.cycle_pos = 0; + break; + case 5: + break; + case 6: + regs.pc += (int8)rd; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_bbc2() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(); + break; + case 3: + sp = op_read(OPMODE_DP, dp); + break; + case 4: + if((sp & 0x04) == 0x04)status.cycle_pos = 0; + break; + case 5: + break; + case 6: + regs.pc += (int8)rd; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_bbs3() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(); + break; + case 3: + sp = op_read(OPMODE_DP, dp); + break; + case 4: + if((sp & 0x08) != 0x08)status.cycle_pos = 0; + break; + case 5: + break; + case 6: + regs.pc += (int8)rd; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_bbc3() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(); + break; + case 3: + sp = op_read(OPMODE_DP, dp); + break; + case 4: + if((sp & 0x08) == 0x08)status.cycle_pos = 0; + break; + case 5: + break; + case 6: + regs.pc += (int8)rd; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_bbs4() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(); + break; + case 3: + sp = op_read(OPMODE_DP, dp); + break; + case 4: + if((sp & 0x10) != 0x10)status.cycle_pos = 0; + break; + case 5: + break; + case 6: + regs.pc += (int8)rd; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_bbc4() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(); + break; + case 3: + sp = op_read(OPMODE_DP, dp); + break; + case 4: + if((sp & 0x10) == 0x10)status.cycle_pos = 0; + break; + case 5: + break; + case 6: + regs.pc += (int8)rd; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_bbs5() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(); + break; + case 3: + sp = op_read(OPMODE_DP, dp); + break; + case 4: + if((sp & 0x20) != 0x20)status.cycle_pos = 0; + break; + case 5: + break; + case 6: + regs.pc += (int8)rd; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_bbc5() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(); + break; + case 3: + sp = op_read(OPMODE_DP, dp); + break; + case 4: + if((sp & 0x20) == 0x20)status.cycle_pos = 0; + break; + case 5: + break; + case 6: + regs.pc += (int8)rd; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_bbs6() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(); + break; + case 3: + sp = op_read(OPMODE_DP, dp); + break; + case 4: + if((sp & 0x40) != 0x40)status.cycle_pos = 0; + break; + case 5: + break; + case 6: + regs.pc += (int8)rd; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_bbc6() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(); + break; + case 3: + sp = op_read(OPMODE_DP, dp); + break; + case 4: + if((sp & 0x40) == 0x40)status.cycle_pos = 0; + break; + case 5: + break; + case 6: + regs.pc += (int8)rd; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_bbs7() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(); + break; + case 3: + sp = op_read(OPMODE_DP, dp); + break; + case 4: + if((sp & 0x80) != 0x80)status.cycle_pos = 0; + break; + case 5: + break; + case 6: + regs.pc += (int8)rd; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_bbc7() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(); + break; + case 3: + sp = op_read(OPMODE_DP, dp); + break; + case 4: + if((sp & 0x80) == 0x80)status.cycle_pos = 0; + break; + case 5: + break; + case 6: + regs.pc += (int8)rd; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_cbne_dp() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(); + break; + case 3: + sp = op_read(OPMODE_DP, dp + 0); + break; + case 4: + if(regs.a == sp)status.cycle_pos = 0; + break; + case 5: + break; + case 6: + regs.pc += (int8)rd; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_cbne_dpx() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(); + break; + case 3: + sp = op_read(OPMODE_DP, dp + regs.x); + break; + case 4: + if(regs.a == sp)status.cycle_pos = 0; + break; + case 5: + break; + case 6: + regs.pc += (int8)rd; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_dbnz_dp() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(); + break; + case 3: + wr = op_read(OPMODE_DP, dp); + break; + case 4: + wr--; + op_write(OPMODE_DP, dp, wr); + if(wr == 0x00)status.cycle_pos = 0; + break; + case 5: + break; + case 6: + regs.pc += (int8)rd; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_dbnz_y() { + switch(status.cycle_pos++) { + case 1: + rd = op_read(); + break; + case 2: + regs.y--; + break; + case 3: + if(regs.y == 0x00)status.cycle_pos = 0; + break; + case 4: + break; + case 5: + regs.pc += (int8)rd; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_jmp_addr() { + switch(status.cycle_pos++) { + case 1: + rd = op_read(); + break; + case 2: + rd |= op_read() << 8; + regs.pc = rd; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_jmp_iaddrx() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + dp |= op_read() << 8; + break; + case 3: + dp += regs.x; + break; + case 4: + rd = op_read(OPMODE_ADDR, dp); + break; + case 5: + rd |= op_read(OPMODE_ADDR, dp + 1) << 8; + regs.pc = rd; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_call() { + switch(status.cycle_pos++) { + case 1: + rd = op_read(); + break; + case 2: + rd |= op_read() << 8; + break; + case 3: + break; + case 4: + break; + case 5: + break; + case 6: + stack_write(regs.pc >> 8); + break; + case 7: + stack_write(regs.pc); + regs.pc = rd; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_pcall() { + switch(status.cycle_pos++) { + case 1: + rd = op_read(); + break; + case 2: + break; + case 3: + break; + case 4: + stack_write(regs.pc >> 8); + break; + case 5: + stack_write(regs.pc); + regs.pc = 0xff00 | rd; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_tcall_0() { + switch(status.cycle_pos++) { + case 1: + dp = 0xffde - (0 << 1); + rd = op_read(OPMODE_ADDR, dp); + break; + case 2: + rd |= op_read(OPMODE_ADDR, dp + 1) << 8; + break; + case 3: + break; + case 4: + break; + case 5: + break; + case 6: + stack_write(regs.pc >> 8); + break; + case 7: + stack_write(regs.pc); + regs.pc = rd; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_tcall_1() { + switch(status.cycle_pos++) { + case 1: + dp = 0xffde - (1 << 1); + rd = op_read(OPMODE_ADDR, dp); + break; + case 2: + rd |= op_read(OPMODE_ADDR, dp + 1) << 8; + break; + case 3: + break; + case 4: + break; + case 5: + break; + case 6: + stack_write(regs.pc >> 8); + break; + case 7: + stack_write(regs.pc); + regs.pc = rd; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_tcall_2() { + switch(status.cycle_pos++) { + case 1: + dp = 0xffde - (2 << 1); + rd = op_read(OPMODE_ADDR, dp); + break; + case 2: + rd |= op_read(OPMODE_ADDR, dp + 1) << 8; + break; + case 3: + break; + case 4: + break; + case 5: + break; + case 6: + stack_write(regs.pc >> 8); + break; + case 7: + stack_write(regs.pc); + regs.pc = rd; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_tcall_3() { + switch(status.cycle_pos++) { + case 1: + dp = 0xffde - (3 << 1); + rd = op_read(OPMODE_ADDR, dp); + break; + case 2: + rd |= op_read(OPMODE_ADDR, dp + 1) << 8; + break; + case 3: + break; + case 4: + break; + case 5: + break; + case 6: + stack_write(regs.pc >> 8); + break; + case 7: + stack_write(regs.pc); + regs.pc = rd; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_tcall_4() { + switch(status.cycle_pos++) { + case 1: + dp = 0xffde - (4 << 1); + rd = op_read(OPMODE_ADDR, dp); + break; + case 2: + rd |= op_read(OPMODE_ADDR, dp + 1) << 8; + break; + case 3: + break; + case 4: + break; + case 5: + break; + case 6: + stack_write(regs.pc >> 8); + break; + case 7: + stack_write(regs.pc); + regs.pc = rd; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_tcall_5() { + switch(status.cycle_pos++) { + case 1: + dp = 0xffde - (5 << 1); + rd = op_read(OPMODE_ADDR, dp); + break; + case 2: + rd |= op_read(OPMODE_ADDR, dp + 1) << 8; + break; + case 3: + break; + case 4: + break; + case 5: + break; + case 6: + stack_write(regs.pc >> 8); + break; + case 7: + stack_write(regs.pc); + regs.pc = rd; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_tcall_6() { + switch(status.cycle_pos++) { + case 1: + dp = 0xffde - (6 << 1); + rd = op_read(OPMODE_ADDR, dp); + break; + case 2: + rd |= op_read(OPMODE_ADDR, dp + 1) << 8; + break; + case 3: + break; + case 4: + break; + case 5: + break; + case 6: + stack_write(regs.pc >> 8); + break; + case 7: + stack_write(regs.pc); + regs.pc = rd; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_tcall_7() { + switch(status.cycle_pos++) { + case 1: + dp = 0xffde - (7 << 1); + rd = op_read(OPMODE_ADDR, dp); + break; + case 2: + rd |= op_read(OPMODE_ADDR, dp + 1) << 8; + break; + case 3: + break; + case 4: + break; + case 5: + break; + case 6: + stack_write(regs.pc >> 8); + break; + case 7: + stack_write(regs.pc); + regs.pc = rd; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_tcall_8() { + switch(status.cycle_pos++) { + case 1: + dp = 0xffde - (8 << 1); + rd = op_read(OPMODE_ADDR, dp); + break; + case 2: + rd |= op_read(OPMODE_ADDR, dp + 1) << 8; + break; + case 3: + break; + case 4: + break; + case 5: + break; + case 6: + stack_write(regs.pc >> 8); + break; + case 7: + stack_write(regs.pc); + regs.pc = rd; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_tcall_9() { + switch(status.cycle_pos++) { + case 1: + dp = 0xffde - (9 << 1); + rd = op_read(OPMODE_ADDR, dp); + break; + case 2: + rd |= op_read(OPMODE_ADDR, dp + 1) << 8; + break; + case 3: + break; + case 4: + break; + case 5: + break; + case 6: + stack_write(regs.pc >> 8); + break; + case 7: + stack_write(regs.pc); + regs.pc = rd; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_tcall_10() { + switch(status.cycle_pos++) { + case 1: + dp = 0xffde - (10 << 1); + rd = op_read(OPMODE_ADDR, dp); + break; + case 2: + rd |= op_read(OPMODE_ADDR, dp + 1) << 8; + break; + case 3: + break; + case 4: + break; + case 5: + break; + case 6: + stack_write(regs.pc >> 8); + break; + case 7: + stack_write(regs.pc); + regs.pc = rd; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_tcall_11() { + switch(status.cycle_pos++) { + case 1: + dp = 0xffde - (11 << 1); + rd = op_read(OPMODE_ADDR, dp); + break; + case 2: + rd |= op_read(OPMODE_ADDR, dp + 1) << 8; + break; + case 3: + break; + case 4: + break; + case 5: + break; + case 6: + stack_write(regs.pc >> 8); + break; + case 7: + stack_write(regs.pc); + regs.pc = rd; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_tcall_12() { + switch(status.cycle_pos++) { + case 1: + dp = 0xffde - (12 << 1); + rd = op_read(OPMODE_ADDR, dp); + break; + case 2: + rd |= op_read(OPMODE_ADDR, dp + 1) << 8; + break; + case 3: + break; + case 4: + break; + case 5: + break; + case 6: + stack_write(regs.pc >> 8); + break; + case 7: + stack_write(regs.pc); + regs.pc = rd; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_tcall_13() { + switch(status.cycle_pos++) { + case 1: + dp = 0xffde - (13 << 1); + rd = op_read(OPMODE_ADDR, dp); + break; + case 2: + rd |= op_read(OPMODE_ADDR, dp + 1) << 8; + break; + case 3: + break; + case 4: + break; + case 5: + break; + case 6: + stack_write(regs.pc >> 8); + break; + case 7: + stack_write(regs.pc); + regs.pc = rd; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_tcall_14() { + switch(status.cycle_pos++) { + case 1: + dp = 0xffde - (14 << 1); + rd = op_read(OPMODE_ADDR, dp); + break; + case 2: + rd |= op_read(OPMODE_ADDR, dp + 1) << 8; + break; + case 3: + break; + case 4: + break; + case 5: + break; + case 6: + stack_write(regs.pc >> 8); + break; + case 7: + stack_write(regs.pc); + regs.pc = rd; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_tcall_15() { + switch(status.cycle_pos++) { + case 1: + dp = 0xffde - (15 << 1); + rd = op_read(OPMODE_ADDR, dp); + break; + case 2: + rd |= op_read(OPMODE_ADDR, dp + 1) << 8; + break; + case 3: + break; + case 4: + break; + case 5: + break; + case 6: + stack_write(regs.pc >> 8); + break; + case 7: + stack_write(regs.pc); + regs.pc = rd; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_brk() { + switch(status.cycle_pos++) { + case 1: + rd = op_read(OPMODE_ADDR, 0xffde); + break; + case 2: + rd |= op_read(OPMODE_ADDR, 0xffdf) << 8; + break; + case 3: + break; + case 4: + break; + case 5: + stack_write(regs.pc >> 8); + break; + case 6: + stack_write(regs.pc); + break; + case 7: + stack_write(regs.p); + regs.pc = rd; + regs.p.b = 1; + regs.p.i = 0; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_ret() { + switch(status.cycle_pos++) { + case 1: + rd = stack_read(); + break; + case 2: + rd |= stack_read() << 8; + break; + case 3: + break; + case 4: + regs.pc = rd; + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_reti() { + switch(status.cycle_pos++) { + case 1: + regs.p = stack_read(); + break; + case 2: + rd = stack_read(); + break; + case 3: + rd |= stack_read() << 8; + break; + case 4: + break; + case 5: + regs.pc = rd; + status.cycle_pos = 0; + break; + } +} + diff --git a/src/apu/bapu/bapu_op_read.cpp b/src/apu/bapu/bapu_op_read.cpp new file mode 100644 index 00000000..c83f37c0 --- /dev/null +++ b/src/apu/bapu/bapu_op_read.cpp @@ -0,0 +1,1467 @@ +void bAPU::op_adc_a_const() { + switch(status.cycle_pos++) { + case 1: + rd = op_read(); + regs.a = op_adc(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_and_a_const() { + switch(status.cycle_pos++) { + case 1: + rd = op_read(); + regs.a = op_and(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_cmp_a_const() { + switch(status.cycle_pos++) { + case 1: + rd = op_read(); + regs.a = op_cmp(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_cmp_x_const() { + switch(status.cycle_pos++) { + case 1: + rd = op_read(); + regs.x = op_cmp(regs.x, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_cmp_y_const() { + switch(status.cycle_pos++) { + case 1: + rd = op_read(); + regs.y = op_cmp(regs.y, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_eor_a_const() { + switch(status.cycle_pos++) { + case 1: + rd = op_read(); + regs.a = op_eor(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_or_a_const() { + switch(status.cycle_pos++) { + case 1: + rd = op_read(); + regs.a = op_or(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_sbc_a_const() { + switch(status.cycle_pos++) { + case 1: + rd = op_read(); + regs.a = op_sbc(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_adc_a_ix() { + switch(status.cycle_pos++) { + case 1: + rd = op_read(OPMODE_DP, regs.x); + break; + case 2: + regs.a = op_adc(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_and_a_ix() { + switch(status.cycle_pos++) { + case 1: + rd = op_read(OPMODE_DP, regs.x); + break; + case 2: + regs.a = op_and(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_cmp_a_ix() { + switch(status.cycle_pos++) { + case 1: + rd = op_read(OPMODE_DP, regs.x); + break; + case 2: + regs.a = op_cmp(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_eor_a_ix() { + switch(status.cycle_pos++) { + case 1: + rd = op_read(OPMODE_DP, regs.x); + break; + case 2: + regs.a = op_eor(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_or_a_ix() { + switch(status.cycle_pos++) { + case 1: + rd = op_read(OPMODE_DP, regs.x); + break; + case 2: + regs.a = op_or(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_sbc_a_ix() { + switch(status.cycle_pos++) { + case 1: + rd = op_read(OPMODE_DP, regs.x); + break; + case 2: + regs.a = op_sbc(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_adc_a_dp() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(OPMODE_DP, dp); + regs.a = op_adc(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_and_a_dp() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(OPMODE_DP, dp); + regs.a = op_and(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_cmp_a_dp() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(OPMODE_DP, dp); + regs.a = op_cmp(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_cmp_x_dp() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(OPMODE_DP, dp); + regs.x = op_cmp(regs.x, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_cmp_y_dp() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(OPMODE_DP, dp); + regs.y = op_cmp(regs.y, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_eor_a_dp() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(OPMODE_DP, dp); + regs.a = op_eor(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_or_a_dp() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(OPMODE_DP, dp); + regs.a = op_or(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_sbc_a_dp() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(OPMODE_DP, dp); + regs.a = op_sbc(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_adc_a_dpx() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + break; + case 3: + rd = op_read(OPMODE_DP, dp + regs.x); + regs.a = op_adc(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_and_a_dpx() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + break; + case 3: + rd = op_read(OPMODE_DP, dp + regs.x); + regs.a = op_and(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_cmp_a_dpx() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + break; + case 3: + rd = op_read(OPMODE_DP, dp + regs.x); + regs.a = op_cmp(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_eor_a_dpx() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + break; + case 3: + rd = op_read(OPMODE_DP, dp + regs.x); + regs.a = op_eor(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_or_a_dpx() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + break; + case 3: + rd = op_read(OPMODE_DP, dp + regs.x); + regs.a = op_or(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_sbc_a_dpx() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + break; + case 3: + rd = op_read(OPMODE_DP, dp + regs.x); + regs.a = op_sbc(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_adc_a_addr() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + dp |= op_read() << 8; + break; + case 3: + rd = op_read(OPMODE_ADDR, dp); + regs.a = op_adc(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_and_a_addr() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + dp |= op_read() << 8; + break; + case 3: + rd = op_read(OPMODE_ADDR, dp); + regs.a = op_and(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_cmp_a_addr() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + dp |= op_read() << 8; + break; + case 3: + rd = op_read(OPMODE_ADDR, dp); + regs.a = op_cmp(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_cmp_x_addr() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + dp |= op_read() << 8; + break; + case 3: + rd = op_read(OPMODE_ADDR, dp); + regs.x = op_cmp(regs.x, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_cmp_y_addr() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + dp |= op_read() << 8; + break; + case 3: + rd = op_read(OPMODE_ADDR, dp); + regs.y = op_cmp(regs.y, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_eor_a_addr() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + dp |= op_read() << 8; + break; + case 3: + rd = op_read(OPMODE_ADDR, dp); + regs.a = op_eor(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_or_a_addr() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + dp |= op_read() << 8; + break; + case 3: + rd = op_read(OPMODE_ADDR, dp); + regs.a = op_or(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_sbc_a_addr() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + dp |= op_read() << 8; + break; + case 3: + rd = op_read(OPMODE_ADDR, dp); + regs.a = op_sbc(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_adc_a_addrx() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + dp |= op_read() << 8; + break; + case 3: + break; + case 4: + rd = op_read(OPMODE_ADDR, dp + regs.x); + regs.a = op_adc(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_adc_a_addry() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + dp |= op_read() << 8; + break; + case 3: + break; + case 4: + rd = op_read(OPMODE_ADDR, dp + regs.y); + regs.a = op_adc(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_and_a_addrx() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + dp |= op_read() << 8; + break; + case 3: + break; + case 4: + rd = op_read(OPMODE_ADDR, dp + regs.x); + regs.a = op_and(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_and_a_addry() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + dp |= op_read() << 8; + break; + case 3: + break; + case 4: + rd = op_read(OPMODE_ADDR, dp + regs.y); + regs.a = op_and(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_cmp_a_addrx() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + dp |= op_read() << 8; + break; + case 3: + break; + case 4: + rd = op_read(OPMODE_ADDR, dp + regs.x); + regs.a = op_cmp(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_cmp_a_addry() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + dp |= op_read() << 8; + break; + case 3: + break; + case 4: + rd = op_read(OPMODE_ADDR, dp + regs.y); + regs.a = op_cmp(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_eor_a_addrx() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + dp |= op_read() << 8; + break; + case 3: + break; + case 4: + rd = op_read(OPMODE_ADDR, dp + regs.x); + regs.a = op_eor(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_eor_a_addry() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + dp |= op_read() << 8; + break; + case 3: + break; + case 4: + rd = op_read(OPMODE_ADDR, dp + regs.y); + regs.a = op_eor(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_or_a_addrx() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + dp |= op_read() << 8; + break; + case 3: + break; + case 4: + rd = op_read(OPMODE_ADDR, dp + regs.x); + regs.a = op_or(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_or_a_addry() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + dp |= op_read() << 8; + break; + case 3: + break; + case 4: + rd = op_read(OPMODE_ADDR, dp + regs.y); + regs.a = op_or(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_sbc_a_addrx() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + dp |= op_read() << 8; + break; + case 3: + break; + case 4: + rd = op_read(OPMODE_ADDR, dp + regs.x); + regs.a = op_sbc(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_sbc_a_addry() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + dp |= op_read() << 8; + break; + case 3: + break; + case 4: + rd = op_read(OPMODE_ADDR, dp + regs.y); + regs.a = op_sbc(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_adc_a_idpx() { + switch(status.cycle_pos++) { + case 1: + dp = op_read() + regs.x; + break; + case 2: + break; + case 3: + sp = op_read(OPMODE_DP, dp); + break; + case 4: + sp |= op_read(OPMODE_DP, dp + 1) << 8; + break; + case 5: + rd = op_read(OPMODE_ADDR, sp); + regs.a = op_adc(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_and_a_idpx() { + switch(status.cycle_pos++) { + case 1: + dp = op_read() + regs.x; + break; + case 2: + break; + case 3: + sp = op_read(OPMODE_DP, dp); + break; + case 4: + sp |= op_read(OPMODE_DP, dp + 1) << 8; + break; + case 5: + rd = op_read(OPMODE_ADDR, sp); + regs.a = op_and(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_cmp_a_idpx() { + switch(status.cycle_pos++) { + case 1: + dp = op_read() + regs.x; + break; + case 2: + break; + case 3: + sp = op_read(OPMODE_DP, dp); + break; + case 4: + sp |= op_read(OPMODE_DP, dp + 1) << 8; + break; + case 5: + rd = op_read(OPMODE_ADDR, sp); + regs.a = op_cmp(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_eor_a_idpx() { + switch(status.cycle_pos++) { + case 1: + dp = op_read() + regs.x; + break; + case 2: + break; + case 3: + sp = op_read(OPMODE_DP, dp); + break; + case 4: + sp |= op_read(OPMODE_DP, dp + 1) << 8; + break; + case 5: + rd = op_read(OPMODE_ADDR, sp); + regs.a = op_eor(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_or_a_idpx() { + switch(status.cycle_pos++) { + case 1: + dp = op_read() + regs.x; + break; + case 2: + break; + case 3: + sp = op_read(OPMODE_DP, dp); + break; + case 4: + sp |= op_read(OPMODE_DP, dp + 1) << 8; + break; + case 5: + rd = op_read(OPMODE_ADDR, sp); + regs.a = op_or(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_sbc_a_idpx() { + switch(status.cycle_pos++) { + case 1: + dp = op_read() + regs.x; + break; + case 2: + break; + case 3: + sp = op_read(OPMODE_DP, dp); + break; + case 4: + sp |= op_read(OPMODE_DP, dp + 1) << 8; + break; + case 5: + rd = op_read(OPMODE_ADDR, sp); + regs.a = op_sbc(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_adc_a_idpy() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + break; + case 3: + sp = op_read(OPMODE_DP, dp); + break; + case 4: + sp |= op_read(OPMODE_DP, dp + 1) << 8; + break; + case 5: + rd = op_read(OPMODE_ADDR, sp + regs.y); + regs.a = op_adc(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_and_a_idpy() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + break; + case 3: + sp = op_read(OPMODE_DP, dp); + break; + case 4: + sp |= op_read(OPMODE_DP, dp + 1) << 8; + break; + case 5: + rd = op_read(OPMODE_ADDR, sp + regs.y); + regs.a = op_and(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_cmp_a_idpy() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + break; + case 3: + sp = op_read(OPMODE_DP, dp); + break; + case 4: + sp |= op_read(OPMODE_DP, dp + 1) << 8; + break; + case 5: + rd = op_read(OPMODE_ADDR, sp + regs.y); + regs.a = op_cmp(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_eor_a_idpy() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + break; + case 3: + sp = op_read(OPMODE_DP, dp); + break; + case 4: + sp |= op_read(OPMODE_DP, dp + 1) << 8; + break; + case 5: + rd = op_read(OPMODE_ADDR, sp + regs.y); + regs.a = op_eor(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_or_a_idpy() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + break; + case 3: + sp = op_read(OPMODE_DP, dp); + break; + case 4: + sp |= op_read(OPMODE_DP, dp + 1) << 8; + break; + case 5: + rd = op_read(OPMODE_ADDR, sp + regs.y); + regs.a = op_or(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_sbc_a_idpy() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + break; + case 3: + sp = op_read(OPMODE_DP, dp); + break; + case 4: + sp |= op_read(OPMODE_DP, dp + 1) << 8; + break; + case 5: + rd = op_read(OPMODE_ADDR, sp + regs.y); + regs.a = op_sbc(regs.a, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_adc_ix_iy() { + switch(status.cycle_pos++) { + case 1: + wr = op_read(OPMODE_DP, regs.x); + break; + case 2: + rd = op_read(OPMODE_DP, regs.y); + break; + case 3: + wr = op_adc(wr, rd); + break; + case 4: + if(1)op_write(OPMODE_DP, regs.x, wr); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_and_ix_iy() { + switch(status.cycle_pos++) { + case 1: + wr = op_read(OPMODE_DP, regs.x); + break; + case 2: + rd = op_read(OPMODE_DP, regs.y); + break; + case 3: + wr = op_and(wr, rd); + break; + case 4: + if(1)op_write(OPMODE_DP, regs.x, wr); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_cmp_ix_iy() { + switch(status.cycle_pos++) { + case 1: + wr = op_read(OPMODE_DP, regs.x); + break; + case 2: + rd = op_read(OPMODE_DP, regs.y); + break; + case 3: + wr = op_cmp(wr, rd); + break; + case 4: + if(0)op_write(OPMODE_DP, regs.x, wr); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_eor_ix_iy() { + switch(status.cycle_pos++) { + case 1: + wr = op_read(OPMODE_DP, regs.x); + break; + case 2: + rd = op_read(OPMODE_DP, regs.y); + break; + case 3: + wr = op_eor(wr, rd); + break; + case 4: + if(1)op_write(OPMODE_DP, regs.x, wr); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_or_ix_iy() { + switch(status.cycle_pos++) { + case 1: + wr = op_read(OPMODE_DP, regs.x); + break; + case 2: + rd = op_read(OPMODE_DP, regs.y); + break; + case 3: + wr = op_or(wr, rd); + break; + case 4: + if(1)op_write(OPMODE_DP, regs.x, wr); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_sbc_ix_iy() { + switch(status.cycle_pos++) { + case 1: + wr = op_read(OPMODE_DP, regs.x); + break; + case 2: + rd = op_read(OPMODE_DP, regs.y); + break; + case 3: + wr = op_sbc(wr, rd); + break; + case 4: + if(1)op_write(OPMODE_DP, regs.x, wr); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_adc_dp_dp() { + switch(status.cycle_pos++) { + case 1: + sp = op_read(); + break; + case 2: + dp = op_read(); + break; + case 3: + wr = op_read(OPMODE_DP, dp); + break; + case 4: + rd = op_read(OPMODE_DP, sp); + break; + case 5: + wr = op_adc(wr, rd); + if(1)op_write(OPMODE_DP, dp, wr); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_and_dp_dp() { + switch(status.cycle_pos++) { + case 1: + sp = op_read(); + break; + case 2: + dp = op_read(); + break; + case 3: + wr = op_read(OPMODE_DP, dp); + break; + case 4: + rd = op_read(OPMODE_DP, sp); + break; + case 5: + wr = op_and(wr, rd); + if(1)op_write(OPMODE_DP, dp, wr); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_cmp_dp_dp() { + switch(status.cycle_pos++) { + case 1: + sp = op_read(); + break; + case 2: + dp = op_read(); + break; + case 3: + wr = op_read(OPMODE_DP, dp); + break; + case 4: + rd = op_read(OPMODE_DP, sp); + break; + case 5: + wr = op_cmp(wr, rd); + if(0)op_write(OPMODE_DP, dp, wr); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_eor_dp_dp() { + switch(status.cycle_pos++) { + case 1: + sp = op_read(); + break; + case 2: + dp = op_read(); + break; + case 3: + wr = op_read(OPMODE_DP, dp); + break; + case 4: + rd = op_read(OPMODE_DP, sp); + break; + case 5: + wr = op_eor(wr, rd); + if(1)op_write(OPMODE_DP, dp, wr); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_or_dp_dp() { + switch(status.cycle_pos++) { + case 1: + sp = op_read(); + break; + case 2: + dp = op_read(); + break; + case 3: + wr = op_read(OPMODE_DP, dp); + break; + case 4: + rd = op_read(OPMODE_DP, sp); + break; + case 5: + wr = op_or(wr, rd); + if(1)op_write(OPMODE_DP, dp, wr); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_sbc_dp_dp() { + switch(status.cycle_pos++) { + case 1: + sp = op_read(); + break; + case 2: + dp = op_read(); + break; + case 3: + wr = op_read(OPMODE_DP, dp); + break; + case 4: + rd = op_read(OPMODE_DP, sp); + break; + case 5: + wr = op_sbc(wr, rd); + if(1)op_write(OPMODE_DP, dp, wr); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_adc_dp_const() { + switch(status.cycle_pos++) { + case 1: + rd = op_read(); + break; + case 2: + dp = op_read(); + break; + case 3: + wr = op_read(OPMODE_DP, dp); + break; + case 4: + wr = op_adc(wr, rd); + if(1)op_write(OPMODE_DP, dp, wr); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_and_dp_const() { + switch(status.cycle_pos++) { + case 1: + rd = op_read(); + break; + case 2: + dp = op_read(); + break; + case 3: + wr = op_read(OPMODE_DP, dp); + break; + case 4: + wr = op_and(wr, rd); + if(1)op_write(OPMODE_DP, dp, wr); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_cmp_dp_const() { + switch(status.cycle_pos++) { + case 1: + rd = op_read(); + break; + case 2: + dp = op_read(); + break; + case 3: + wr = op_read(OPMODE_DP, dp); + break; + case 4: + wr = op_cmp(wr, rd); + if(0)op_write(OPMODE_DP, dp, wr); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_eor_dp_const() { + switch(status.cycle_pos++) { + case 1: + rd = op_read(); + break; + case 2: + dp = op_read(); + break; + case 3: + wr = op_read(OPMODE_DP, dp); + break; + case 4: + wr = op_eor(wr, rd); + if(1)op_write(OPMODE_DP, dp, wr); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_or_dp_const() { + switch(status.cycle_pos++) { + case 1: + rd = op_read(); + break; + case 2: + dp = op_read(); + break; + case 3: + wr = op_read(OPMODE_DP, dp); + break; + case 4: + wr = op_or(wr, rd); + if(1)op_write(OPMODE_DP, dp, wr); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_sbc_dp_const() { + switch(status.cycle_pos++) { + case 1: + rd = op_read(); + break; + case 2: + dp = op_read(); + break; + case 3: + wr = op_read(OPMODE_DP, dp); + break; + case 4: + wr = op_sbc(wr, rd); + if(1)op_write(OPMODE_DP, dp, wr); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_addw_ya_dp() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(OPMODE_DP, dp); + break; + case 3: + rd |= op_read(OPMODE_DP, dp + 1) << 8; + break; + case 4: + regs.ya = op_addw(regs.ya, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_cmpw_ya_dp() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(OPMODE_DP, dp); + break; + case 3: + rd |= op_read(OPMODE_DP, dp + 1) << 8; + break; + case 4: + regs.ya = op_cmpw(regs.ya, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_subw_ya_dp() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(OPMODE_DP, dp); + break; + case 3: + rd |= op_read(OPMODE_DP, dp + 1) << 8; + break; + case 4: + regs.ya = op_subw(regs.ya, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_and1_bit() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + dp |= op_read() << 8; + break; + case 3: + bit = dp >> 13; + dp &= 0x1fff; + rd = op_read(OPMODE_ADDR, dp); + regs.p.c = regs.p.c & !!(rd & (1 << bit)); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_and1_notbit() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + dp |= op_read() << 8; + break; + case 3: + bit = dp >> 13; + dp &= 0x1fff; + rd = op_read(OPMODE_ADDR, dp); + regs.p.c = regs.p.c & !(rd & (1 << bit)); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_eor1_bit() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + dp |= op_read() << 8; + break; + case 3: + bit = dp >> 13; + dp &= 0x1fff; + rd = op_read(OPMODE_ADDR, dp); + break; + case 4: + regs.p.c = regs.p.c ^ !!(rd & (1 << bit)); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_not1_bit() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + dp |= op_read() << 8; + break; + case 3: + bit = dp >> 13; + dp &= 0x1fff; + rd = op_read(OPMODE_ADDR, dp); + rd ^= (1 << bit); + break; + case 4: + op_write(OPMODE_ADDR, dp, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_or1_bit() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + dp |= op_read() << 8; + break; + case 3: + bit = dp >> 13; + dp &= 0x1fff; + rd = op_read(OPMODE_ADDR, dp); + break; + case 4: + regs.p.c = regs.p.c | !!(rd & (1 << bit)); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_or1_notbit() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + dp |= op_read() << 8; + break; + case 3: + bit = dp >> 13; + dp &= 0x1fff; + rd = op_read(OPMODE_ADDR, dp); + break; + case 4: + regs.p.c = regs.p.c | !(rd & (1 << bit)); + status.cycle_pos = 0; + break; + } +} + diff --git a/src/apu/bapu/bapu_op_rmw.cpp b/src/apu/bapu/bapu_op_rmw.cpp new file mode 100644 index 00000000..dd7909bf --- /dev/null +++ b/src/apu/bapu/bapu_op_rmw.cpp @@ -0,0 +1,452 @@ +void bAPU::op_inc_a() { + switch(status.cycle_pos++) { + case 1: + regs.a = op_inc(regs.a); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_inc_x() { + switch(status.cycle_pos++) { + case 1: + regs.x = op_inc(regs.x); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_inc_y() { + switch(status.cycle_pos++) { + case 1: + regs.y = op_inc(regs.y); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_dec_a() { + switch(status.cycle_pos++) { + case 1: + regs.a = op_dec(regs.a); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_dec_x() { + switch(status.cycle_pos++) { + case 1: + regs.x = op_dec(regs.x); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_dec_y() { + switch(status.cycle_pos++) { + case 1: + regs.y = op_dec(regs.y); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_asl_a() { + switch(status.cycle_pos++) { + case 1: + regs.a = op_asl(regs.a); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_lsr_a() { + switch(status.cycle_pos++) { + case 1: + regs.a = op_lsr(regs.a); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_rol_a() { + switch(status.cycle_pos++) { + case 1: + regs.a = op_rol(regs.a); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_ror_a() { + switch(status.cycle_pos++) { + case 1: + regs.a = op_ror(regs.a); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_inc_dp() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(OPMODE_DP, dp); + break; + case 3: + rd = op_inc(rd); + op_write(OPMODE_DP, dp, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_dec_dp() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(OPMODE_DP, dp); + break; + case 3: + rd = op_dec(rd); + op_write(OPMODE_DP, dp, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_asl_dp() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(OPMODE_DP, dp); + break; + case 3: + rd = op_asl(rd); + op_write(OPMODE_DP, dp, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_lsr_dp() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(OPMODE_DP, dp); + break; + case 3: + rd = op_lsr(rd); + op_write(OPMODE_DP, dp, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_rol_dp() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(OPMODE_DP, dp); + break; + case 3: + rd = op_rol(rd); + op_write(OPMODE_DP, dp, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_ror_dp() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(OPMODE_DP, dp); + break; + case 3: + rd = op_ror(rd); + op_write(OPMODE_DP, dp, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_inc_dpx() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + break; + case 3: + rd = op_read(OPMODE_DP, dp + regs.x); + break; + case 4: + rd = op_inc(rd); + op_write(OPMODE_DP, dp + regs.x, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_dec_dpx() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + break; + case 3: + rd = op_read(OPMODE_DP, dp + regs.x); + break; + case 4: + rd = op_dec(rd); + op_write(OPMODE_DP, dp + regs.x, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_asl_dpx() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + break; + case 3: + rd = op_read(OPMODE_DP, dp + regs.x); + break; + case 4: + rd = op_asl(rd); + op_write(OPMODE_DP, dp + regs.x, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_lsr_dpx() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + break; + case 3: + rd = op_read(OPMODE_DP, dp + regs.x); + break; + case 4: + rd = op_lsr(rd); + op_write(OPMODE_DP, dp + regs.x, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_rol_dpx() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + break; + case 3: + rd = op_read(OPMODE_DP, dp + regs.x); + break; + case 4: + rd = op_rol(rd); + op_write(OPMODE_DP, dp + regs.x, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_ror_dpx() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + break; + case 3: + rd = op_read(OPMODE_DP, dp + regs.x); + break; + case 4: + rd = op_ror(rd); + op_write(OPMODE_DP, dp + regs.x, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_inc_addr() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + dp |= op_read() << 8; + break; + case 3: + rd = op_read(OPMODE_ADDR, dp); + break; + case 4: + rd = op_inc(rd); + op_write(OPMODE_ADDR, dp, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_dec_addr() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + dp |= op_read() << 8; + break; + case 3: + rd = op_read(OPMODE_ADDR, dp); + break; + case 4: + rd = op_dec(rd); + op_write(OPMODE_ADDR, dp, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_asl_addr() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + dp |= op_read() << 8; + break; + case 3: + rd = op_read(OPMODE_ADDR, dp); + break; + case 4: + rd = op_asl(rd); + op_write(OPMODE_ADDR, dp, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_lsr_addr() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + dp |= op_read() << 8; + break; + case 3: + rd = op_read(OPMODE_ADDR, dp); + break; + case 4: + rd = op_lsr(rd); + op_write(OPMODE_ADDR, dp, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_rol_addr() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + dp |= op_read() << 8; + break; + case 3: + rd = op_read(OPMODE_ADDR, dp); + break; + case 4: + rd = op_rol(rd); + op_write(OPMODE_ADDR, dp, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_ror_addr() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + dp |= op_read() << 8; + break; + case 3: + rd = op_read(OPMODE_ADDR, dp); + break; + case 4: + rd = op_ror(rd); + op_write(OPMODE_ADDR, dp, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_incw_dp() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(OPMODE_DP, dp); + break; + case 3: + rd |= op_read(OPMODE_DP, dp + 1) << 8; + break; + case 4: + rd = op_incw(rd); + op_write(OPMODE_DP, dp + 1, rd >> 8); + break; + case 5: + op_write(OPMODE_DP, dp, rd); + status.cycle_pos = 0; + break; + } +} + +void bAPU::op_decw_dp() { + switch(status.cycle_pos++) { + case 1: + dp = op_read(); + break; + case 2: + rd = op_read(OPMODE_DP, dp); + break; + case 3: + rd |= op_read(OPMODE_DP, dp + 1) << 8; + break; + case 4: + rd = op_decw(rd); + op_write(OPMODE_DP, dp + 1, rd >> 8); + break; + case 5: + op_write(OPMODE_DP, dp, rd); + status.cycle_pos = 0; + break; + } +} + diff --git a/src/apu/bapu/bapu_optable.cpp b/src/apu/bapu/bapu_optable.cpp new file mode 100644 index 00000000..1dc4c66b --- /dev/null +++ b/src/apu/bapu/bapu_optable.cpp @@ -0,0 +1,256 @@ +optbl[0x7d] = &bAPU::op_mov_a_x; +optbl[0xdd] = &bAPU::op_mov_a_y; +optbl[0x5d] = &bAPU::op_mov_x_a; +optbl[0xfd] = &bAPU::op_mov_y_a; +optbl[0x9d] = &bAPU::op_mov_x_sp; +optbl[0xbd] = &bAPU::op_mov_sp_x; +optbl[0xe8] = &bAPU::op_mov_a_const; +optbl[0xcd] = &bAPU::op_mov_x_const; +optbl[0x8d] = &bAPU::op_mov_y_const; +optbl[0xe6] = &bAPU::op_mov_a_ix; +optbl[0xbf] = &bAPU::op_mov_a_ixinc; +optbl[0xe4] = &bAPU::op_mov_a_dp; +optbl[0xf8] = &bAPU::op_mov_x_dp; +optbl[0xeb] = &bAPU::op_mov_y_dp; +optbl[0xf4] = &bAPU::op_mov_a_dpx; +optbl[0xf9] = &bAPU::op_mov_x_dpy; +optbl[0xfb] = &bAPU::op_mov_y_dpx; +optbl[0xe5] = &bAPU::op_mov_a_addr; +optbl[0xe9] = &bAPU::op_mov_x_addr; +optbl[0xec] = &bAPU::op_mov_y_addr; +optbl[0xf5] = &bAPU::op_mov_a_addrx; +optbl[0xf6] = &bAPU::op_mov_a_addry; +optbl[0xe7] = &bAPU::op_mov_a_idpx; +optbl[0xf7] = &bAPU::op_mov_a_idpy; +optbl[0xfa] = &bAPU::op_mov_dp_dp; +optbl[0x8f] = &bAPU::op_mov_dp_const; +optbl[0xc6] = &bAPU::op_mov_ix_a; +optbl[0xaf] = &bAPU::op_mov_ixinc_a; +optbl[0xc4] = &bAPU::op_mov_dp_a; +optbl[0xd8] = &bAPU::op_mov_dp_x; +optbl[0xcb] = &bAPU::op_mov_dp_y; +optbl[0xd4] = &bAPU::op_mov_dpx_a; +optbl[0xd9] = &bAPU::op_mov_dpy_x; +optbl[0xdb] = &bAPU::op_mov_dpx_y; +optbl[0xc5] = &bAPU::op_mov_addr_a; +optbl[0xc9] = &bAPU::op_mov_addr_x; +optbl[0xcc] = &bAPU::op_mov_addr_y; +optbl[0xd5] = &bAPU::op_mov_addrx_a; +optbl[0xd6] = &bAPU::op_mov_addry_a; +optbl[0xc7] = &bAPU::op_mov_idpx_a; +optbl[0xd7] = &bAPU::op_mov_idpy_a; +optbl[0xba] = &bAPU::op_movw_ya_dp; +optbl[0xda] = &bAPU::op_movw_dp_ya; +optbl[0xaa] = &bAPU::op_mov1_c_bit; +optbl[0xca] = &bAPU::op_mov1_bit_c; +optbl[0x2f] = &bAPU::op_bra; +optbl[0xf0] = &bAPU::op_beq; +optbl[0xd0] = &bAPU::op_bne; +optbl[0xb0] = &bAPU::op_bcs; +optbl[0x90] = &bAPU::op_bcc; +optbl[0x70] = &bAPU::op_bvs; +optbl[0x50] = &bAPU::op_bvc; +optbl[0x30] = &bAPU::op_bmi; +optbl[0x10] = &bAPU::op_bpl; +optbl[0x03] = &bAPU::op_bbs0; +optbl[0x13] = &bAPU::op_bbc0; +optbl[0x23] = &bAPU::op_bbs1; +optbl[0x33] = &bAPU::op_bbc1; +optbl[0x43] = &bAPU::op_bbs2; +optbl[0x53] = &bAPU::op_bbc2; +optbl[0x63] = &bAPU::op_bbs3; +optbl[0x73] = &bAPU::op_bbc3; +optbl[0x83] = &bAPU::op_bbs4; +optbl[0x93] = &bAPU::op_bbc4; +optbl[0xa3] = &bAPU::op_bbs5; +optbl[0xb3] = &bAPU::op_bbc5; +optbl[0xc3] = &bAPU::op_bbs6; +optbl[0xd3] = &bAPU::op_bbc6; +optbl[0xe3] = &bAPU::op_bbs7; +optbl[0xf3] = &bAPU::op_bbc7; +optbl[0x2e] = &bAPU::op_cbne_dp; +optbl[0xde] = &bAPU::op_cbne_dpx; +optbl[0x6e] = &bAPU::op_dbnz_dp; +optbl[0xfe] = &bAPU::op_dbnz_y; +optbl[0x5f] = &bAPU::op_jmp_addr; +optbl[0x1f] = &bAPU::op_jmp_iaddrx; +optbl[0x3f] = &bAPU::op_call; +optbl[0x4f] = &bAPU::op_pcall; +optbl[0x01] = &bAPU::op_tcall_0; +optbl[0x11] = &bAPU::op_tcall_1; +optbl[0x21] = &bAPU::op_tcall_2; +optbl[0x31] = &bAPU::op_tcall_3; +optbl[0x41] = &bAPU::op_tcall_4; +optbl[0x51] = &bAPU::op_tcall_5; +optbl[0x61] = &bAPU::op_tcall_6; +optbl[0x71] = &bAPU::op_tcall_7; +optbl[0x81] = &bAPU::op_tcall_8; +optbl[0x91] = &bAPU::op_tcall_9; +optbl[0xa1] = &bAPU::op_tcall_10; +optbl[0xb1] = &bAPU::op_tcall_11; +optbl[0xc1] = &bAPU::op_tcall_12; +optbl[0xd1] = &bAPU::op_tcall_13; +optbl[0xe1] = &bAPU::op_tcall_14; +optbl[0xf1] = &bAPU::op_tcall_15; +optbl[0x0f] = &bAPU::op_brk; +optbl[0x6f] = &bAPU::op_ret; +optbl[0x7f] = &bAPU::op_reti; +optbl[0x88] = &bAPU::op_adc_a_const; +optbl[0x28] = &bAPU::op_and_a_const; +optbl[0x68] = &bAPU::op_cmp_a_const; +optbl[0xc8] = &bAPU::op_cmp_x_const; +optbl[0xad] = &bAPU::op_cmp_y_const; +optbl[0x48] = &bAPU::op_eor_a_const; +optbl[0x08] = &bAPU::op_or_a_const; +optbl[0xa8] = &bAPU::op_sbc_a_const; +optbl[0x86] = &bAPU::op_adc_a_ix; +optbl[0x26] = &bAPU::op_and_a_ix; +optbl[0x66] = &bAPU::op_cmp_a_ix; +optbl[0x46] = &bAPU::op_eor_a_ix; +optbl[0x06] = &bAPU::op_or_a_ix; +optbl[0xa6] = &bAPU::op_sbc_a_ix; +optbl[0x84] = &bAPU::op_adc_a_dp; +optbl[0x24] = &bAPU::op_and_a_dp; +optbl[0x64] = &bAPU::op_cmp_a_dp; +optbl[0x3e] = &bAPU::op_cmp_x_dp; +optbl[0x7e] = &bAPU::op_cmp_y_dp; +optbl[0x44] = &bAPU::op_eor_a_dp; +optbl[0x04] = &bAPU::op_or_a_dp; +optbl[0xa4] = &bAPU::op_sbc_a_dp; +optbl[0x94] = &bAPU::op_adc_a_dpx; +optbl[0x34] = &bAPU::op_and_a_dpx; +optbl[0x74] = &bAPU::op_cmp_a_dpx; +optbl[0x54] = &bAPU::op_eor_a_dpx; +optbl[0x14] = &bAPU::op_or_a_dpx; +optbl[0xb4] = &bAPU::op_sbc_a_dpx; +optbl[0x85] = &bAPU::op_adc_a_addr; +optbl[0x25] = &bAPU::op_and_a_addr; +optbl[0x65] = &bAPU::op_cmp_a_addr; +optbl[0x1e] = &bAPU::op_cmp_x_addr; +optbl[0x5e] = &bAPU::op_cmp_y_addr; +optbl[0x45] = &bAPU::op_eor_a_addr; +optbl[0x05] = &bAPU::op_or_a_addr; +optbl[0xa5] = &bAPU::op_sbc_a_addr; +optbl[0x95] = &bAPU::op_adc_a_addrx; +optbl[0x96] = &bAPU::op_adc_a_addry; +optbl[0x35] = &bAPU::op_and_a_addrx; +optbl[0x36] = &bAPU::op_and_a_addry; +optbl[0x75] = &bAPU::op_cmp_a_addrx; +optbl[0x76] = &bAPU::op_cmp_a_addry; +optbl[0x55] = &bAPU::op_eor_a_addrx; +optbl[0x56] = &bAPU::op_eor_a_addry; +optbl[0x15] = &bAPU::op_or_a_addrx; +optbl[0x16] = &bAPU::op_or_a_addry; +optbl[0xb5] = &bAPU::op_sbc_a_addrx; +optbl[0xb6] = &bAPU::op_sbc_a_addry; +optbl[0x87] = &bAPU::op_adc_a_idpx; +optbl[0x27] = &bAPU::op_and_a_idpx; +optbl[0x67] = &bAPU::op_cmp_a_idpx; +optbl[0x47] = &bAPU::op_eor_a_idpx; +optbl[0x07] = &bAPU::op_or_a_idpx; +optbl[0xa7] = &bAPU::op_sbc_a_idpx; +optbl[0x97] = &bAPU::op_adc_a_idpy; +optbl[0x37] = &bAPU::op_and_a_idpy; +optbl[0x77] = &bAPU::op_cmp_a_idpy; +optbl[0x57] = &bAPU::op_eor_a_idpy; +optbl[0x17] = &bAPU::op_or_a_idpy; +optbl[0xb7] = &bAPU::op_sbc_a_idpy; +optbl[0x99] = &bAPU::op_adc_ix_iy; +optbl[0x39] = &bAPU::op_and_ix_iy; +optbl[0x79] = &bAPU::op_cmp_ix_iy; +optbl[0x59] = &bAPU::op_eor_ix_iy; +optbl[0x19] = &bAPU::op_or_ix_iy; +optbl[0xb9] = &bAPU::op_sbc_ix_iy; +optbl[0x89] = &bAPU::op_adc_dp_dp; +optbl[0x29] = &bAPU::op_and_dp_dp; +optbl[0x69] = &bAPU::op_cmp_dp_dp; +optbl[0x49] = &bAPU::op_eor_dp_dp; +optbl[0x09] = &bAPU::op_or_dp_dp; +optbl[0xa9] = &bAPU::op_sbc_dp_dp; +optbl[0x98] = &bAPU::op_adc_dp_const; +optbl[0x38] = &bAPU::op_and_dp_const; +optbl[0x78] = &bAPU::op_cmp_dp_const; +optbl[0x58] = &bAPU::op_eor_dp_const; +optbl[0x18] = &bAPU::op_or_dp_const; +optbl[0xb8] = &bAPU::op_sbc_dp_const; +optbl[0x7a] = &bAPU::op_addw_ya_dp; +optbl[0x5a] = &bAPU::op_cmpw_ya_dp; +optbl[0x9a] = &bAPU::op_subw_ya_dp; +optbl[0x4a] = &bAPU::op_and1_bit; +optbl[0x6a] = &bAPU::op_and1_notbit; +optbl[0x8a] = &bAPU::op_eor1_bit; +optbl[0xea] = &bAPU::op_not1_bit; +optbl[0x0a] = &bAPU::op_or1_bit; +optbl[0x2a] = &bAPU::op_or1_notbit; +optbl[0xbc] = &bAPU::op_inc_a; +optbl[0x3d] = &bAPU::op_inc_x; +optbl[0xfc] = &bAPU::op_inc_y; +optbl[0x9c] = &bAPU::op_dec_a; +optbl[0x1d] = &bAPU::op_dec_x; +optbl[0xdc] = &bAPU::op_dec_y; +optbl[0x1c] = &bAPU::op_asl_a; +optbl[0x5c] = &bAPU::op_lsr_a; +optbl[0x3c] = &bAPU::op_rol_a; +optbl[0x7c] = &bAPU::op_ror_a; +optbl[0xab] = &bAPU::op_inc_dp; +optbl[0x8b] = &bAPU::op_dec_dp; +optbl[0x0b] = &bAPU::op_asl_dp; +optbl[0x4b] = &bAPU::op_lsr_dp; +optbl[0x2b] = &bAPU::op_rol_dp; +optbl[0x6b] = &bAPU::op_ror_dp; +optbl[0xbb] = &bAPU::op_inc_dpx; +optbl[0x9b] = &bAPU::op_dec_dpx; +optbl[0x1b] = &bAPU::op_asl_dpx; +optbl[0x5b] = &bAPU::op_lsr_dpx; +optbl[0x3b] = &bAPU::op_rol_dpx; +optbl[0x7b] = &bAPU::op_ror_dpx; +optbl[0xac] = &bAPU::op_inc_addr; +optbl[0x8c] = &bAPU::op_dec_addr; +optbl[0x0c] = &bAPU::op_asl_addr; +optbl[0x4c] = &bAPU::op_lsr_addr; +optbl[0x2c] = &bAPU::op_rol_addr; +optbl[0x6c] = &bAPU::op_ror_addr; +optbl[0x3a] = &bAPU::op_incw_dp; +optbl[0x1a] = &bAPU::op_decw_dp; +optbl[0x00] = &bAPU::op_nop; +optbl[0xef] = &bAPU::op_sleep; +optbl[0xff] = &bAPU::op_stop; +optbl[0x9f] = &bAPU::op_xcn; +optbl[0xdf] = &bAPU::op_daa; +optbl[0xbe] = &bAPU::op_das; +optbl[0x60] = &bAPU::op_clrc; +optbl[0x20] = &bAPU::op_clrp; +optbl[0x80] = &bAPU::op_setc; +optbl[0x40] = &bAPU::op_setp; +optbl[0xe0] = &bAPU::op_clrv; +optbl[0xed] = &bAPU::op_notc; +optbl[0xa0] = &bAPU::op_ei; +optbl[0xc0] = &bAPU::op_di; +optbl[0x02] = &bAPU::op_set0_dp; +optbl[0x12] = &bAPU::op_clr0_dp; +optbl[0x22] = &bAPU::op_set1_dp; +optbl[0x32] = &bAPU::op_clr1_dp; +optbl[0x42] = &bAPU::op_set2_dp; +optbl[0x52] = &bAPU::op_clr2_dp; +optbl[0x62] = &bAPU::op_set3_dp; +optbl[0x72] = &bAPU::op_clr3_dp; +optbl[0x82] = &bAPU::op_set4_dp; +optbl[0x92] = &bAPU::op_clr4_dp; +optbl[0xa2] = &bAPU::op_set5_dp; +optbl[0xb2] = &bAPU::op_clr5_dp; +optbl[0xc2] = &bAPU::op_set6_dp; +optbl[0xd2] = &bAPU::op_clr6_dp; +optbl[0xe2] = &bAPU::op_set7_dp; +optbl[0xf2] = &bAPU::op_clr7_dp; +optbl[0x0e] = &bAPU::op_tset_addr_a; +optbl[0x4e] = &bAPU::op_tclr_addr_a; +optbl[0x2d] = &bAPU::op_push_a; +optbl[0x4d] = &bAPU::op_push_x; +optbl[0x6d] = &bAPU::op_push_y; +optbl[0x0d] = &bAPU::op_push_p; +optbl[0xae] = &bAPU::op_pop_a; +optbl[0xce] = &bAPU::op_pop_x; +optbl[0xee] = &bAPU::op_pop_y; +optbl[0x8e] = &bAPU::op_pop_p; +optbl[0xcf] = &bAPU::op_mul_ya; +optbl[0x9e] = &bAPU::op_div_ya_x; diff --git a/src/apu/bapu/bapugen.cpp b/src/apu/bapu/bapugen.cpp new file mode 100644 index 00000000..8c5169e9 --- /dev/null +++ b/src/apu/bapu/bapugen.cpp @@ -0,0 +1,168 @@ +#include "../../lib/libbase.h" +#include "../../lib/libstring.h" +#include "../../lib/libstring.cpp" + +FILE *fp, *fph, *fpt; + +string data, line, part, subpart; +string output_table, output_header, output_op; + +int op_count; +struct _op_list { +string name; +string arg; +}op_list[64]; + +int line_num; + +void clear_op_list() { + op_count = 0; + for(int i=0;i<64;i++) { + strcpy(op_list[i].name, ""); + for(int l=0;l<8;l++) { + strcpy(op_list[i].arg[l], ""); + } + } +} + +void gen_header() { +int i = line_num, l, n, z; +char t[4096]; + clear_op_list(); + while(1) { + z = op_count++; + strcpy(part, line[i]); + strrtrim(part, "),"); + strrtrim(part, ") {"); + split(subpart, "(", part); + strcpy(op_list[z].name, subpart[0]); + split(part, ", ", subpart[1]); + for(l=0;l= count(line))break; + + gen_header(); + gen_op(); + gen_final(); + } + + fclose(fp); +} + +int main() { + fph = fopen("bapu_op.h", "wb"); + fpt = fopen("bapu_optable.cpp", "wb"); + + generate("bapu_op_mov.cpp", "op_mov.b"); + generate("bapu_op_pc.cpp", "op_pc.b"); + generate("bapu_op_read.cpp", "op_read.b"); + generate("bapu_op_rmw.cpp", "op_rmw.b"); + generate("bapu_op_misc.cpp", "op_misc.b"); + + fclose(fph); + fclose(fpt); + + return 0; +} diff --git a/src/apu/bapu/bapugen.exe b/src/apu/bapu/bapugen.exe new file mode 100644 index 00000000..e08b8e2d Binary files /dev/null and b/src/apu/bapu/bapugen.exe differ diff --git a/src/apu/bapu/cc.bat b/src/apu/bapu/cc.bat new file mode 100644 index 00000000..b6e446fd --- /dev/null +++ b/src/apu/bapu/cc.bat @@ -0,0 +1,3 @@ +cl /ML /O2 bapugen.cpp +@pause +@del *.obj \ No newline at end of file diff --git a/src/apu/bapu/clean.bat b/src/apu/bapu/clean.bat new file mode 100644 index 00000000..d807f14d --- /dev/null +++ b/src/apu/bapu/clean.bat @@ -0,0 +1 @@ +@del *.exe diff --git a/src/apu/bapu/op_misc.b b/src/apu/bapu/op_misc.b new file mode 100644 index 00000000..489da50d --- /dev/null +++ b/src/apu/bapu/op_misc.b @@ -0,0 +1,164 @@ +nop(0x00) { +1: +} + +sleep(0xef), +stop(0xff) { +1: +2:regs.pc--; +} + +xcn(0x9f) { +1: +2: +3: +4:regs.a = (regs.a >> 4) | (regs.a << 4); + regs.p.n = !!(regs.a & 0x80); + regs.p.z = (regs.a == 0); +} + +daa(0xdf) { +1: +2:if(regs.p.c || (regs.a) > 0x99) { + regs.a += 0x60; + regs.p.c = 1; + } + if(regs.p.h || (regs.a & 15) > 0x09) { + regs.a += 0x06; + } + regs.p.n = !!(regs.a & 0x80); + regs.p.z = (regs.a == 0); +} + +das(0xbe) { +1: +2:if(!regs.p.c || (regs.a) > 0x99) { + regs.a -= 0x60; + regs.p.c = 0; + } + if(!regs.p.h || (regs.a & 15) > 0x09) { + regs.a -= 0x06; + } + regs.p.n = !!(regs.a & 0x80); + regs.p.z = (regs.a == 0); +} + +clrc(0x60, regs.p.c = 0), +clrp(0x20, regs.p.p = 0), +setc(0x80, regs.p.c = 1), +setp(0x40, regs.p.p = 1) { +1:$1; +} + +clrv(0xe0) { +1:regs.p.v = 0; + regs.p.h = 0; +} + +notc(0xed) { +1: +2:regs.p.c ^= 1; +} + +ei(0xa0, 1), +di(0xc0, 0) { +1: +2:regs.p.i = $1; +} + +set0_dp(0x02, rd |= 0x01), +clr0_dp(0x12, rd &= ~0x01), +set1_dp(0x22, rd |= 0x02), +clr1_dp(0x32, rd &= ~0x02), +set2_dp(0x42, rd |= 0x04), +clr2_dp(0x52, rd &= ~0x04), +set3_dp(0x62, rd |= 0x08), +clr3_dp(0x72, rd &= ~0x08), +set4_dp(0x82, rd |= 0x10), +clr4_dp(0x92, rd &= ~0x10), +set5_dp(0xa2, rd |= 0x20), +clr5_dp(0xb2, rd &= ~0x20), +set6_dp(0xc2, rd |= 0x40), +clr6_dp(0xd2, rd &= ~0x40), +set7_dp(0xe2, rd |= 0x80), +clr7_dp(0xf2, rd &= ~0x80) { +1:dp = op_read(); +2:rd = op_read(OPMODE_DP, dp); +3:$1; + op_write(OPMODE_DP, dp, rd); +} + +tset_addr_a(0x0e, |=), +tclr_addr_a(0x4e, &=~) { +1:dp = op_read(); +2:dp |= op_read() << 8; +3:rd = op_read(OPMODE_ADDR, dp); +4:regs.p.n = !!((rd & regs.a) & 0x80); + regs.p.z = ((rd & regs.a) == 0); + rd $1 regs.a; +5:op_write(OPMODE_ADDR, dp, rd); +} + +push_a(0x2d, a), +push_x(0x4d, x), +push_y(0x6d, y), +push_p(0x0d, p) { +1: +2: +3:stack_write(regs.$1); +} + +pop_a(0xae, a), +pop_x(0xce, x), +pop_y(0xee, y), +pop_p(0x8e, p) { +1: +2: +3:regs.$1 = stack_read(); +} + +mul_ya(0xcf) { +1: +2: +3: +4: +5: +6: +7: +8:ya = regs.y * regs.a; + regs.a = ya; + regs.y = ya >> 8; +//result is set based on y (high-byte) only + regs.p.n = !!(regs.y & 0x80); + regs.p.z = (regs.y == 0); +} + +div_ya_x(0x9e) { +1: +2: +3: +4: +5: +6: +7: +8: +9: +10: +11:ya = regs.ya; +//overflow set if quotient >= 256 + regs.p.v = !!(regs.y >= regs.x); + regs.p.h = !!((regs.y & 15) >= (regs.x & 15)); + if(regs.y < (regs.x << 1)) { + //if quotient is <= 511 (will fit into 9-bit result) + regs.a = ya / regs.x; + regs.y = ya % regs.x; + } else { + //otherwise, the quotient won't fit into regs.p.v + regs.a + //this emulates the odd behavior of the SPC700 in this case + regs.a = 255 - (ya - (regs.x << 9)) / (256 - regs.x); + regs.y = regs.x + (ya - (regs.x << 9)) % (256 - regs.x); + } +//result is set based on a (quotient) only + regs.p.n = !!(regs.a & 0x80); + regs.p.z = (regs.a == 0); +} diff --git a/src/apu/bapu/op_mov.b b/src/apu/bapu/op_mov.b new file mode 100644 index 00000000..43b1d58d --- /dev/null +++ b/src/apu/bapu/op_mov.b @@ -0,0 +1,207 @@ +mov_a_x(0x7d, a, x), +mov_a_y(0xdd, a, y), +mov_x_a(0x5d, x, a), +mov_y_a(0xfd, y, a), +mov_x_sp(0x9d, x, sp), +mov_sp_x(0xbd, sp, x) { +1:regs.$1 = regs.$2; + regs.p.n = !!(regs.$1 & 0x80); + regs.p.z = (regs.$1 == 0); +} + +mov_a_const(0xe8, a), +mov_x_const(0xcd, x), +mov_y_const(0x8d, y) { +1:regs.$1 = op_read(); + regs.p.n = !!(regs.$1 & 0x80); + regs.p.z = (regs.$1 == 0); +} + +mov_a_ix(0xe6) { +1: +2:regs.a = op_read(OPMODE_DP, regs.x); + regs.p.n = !!(regs.a & 0x80); + regs.p.z = (regs.a == 0); +} + +mov_a_ixinc(0xbf) { +1: +2: +3:regs.a = op_read(OPMODE_DP, regs.x++); + regs.p.n = !!(regs.a & 0x80); + regs.p.z = (regs.a == 0); +} + +mov_a_dp(0xe4, a), +mov_x_dp(0xf8, x), +mov_y_dp(0xeb, y) { +1:sp = op_read(); +2:regs.$1 = op_read(OPMODE_DP, sp); + regs.p.n = !!(regs.$1 & 0x80); + regs.p.z = (regs.$1 == 0); +} + +mov_a_dpx(0xf4, a, x), +mov_x_dpy(0xf9, x, y), +mov_y_dpx(0xfb, y, x) { +1:sp = op_read(); +2: +3:regs.$1 = op_read(OPMODE_DP, sp + regs.$2); + regs.p.n = !!(regs.$1 & 0x80); + regs.p.z = (regs.$1 == 0); +} + +mov_a_addr(0xe5, a), +mov_x_addr(0xe9, x), +mov_y_addr(0xec, y) { +1:sp = op_read(); +2:sp |= op_read() << 8; +3:regs.$1 = op_read(OPMODE_ADDR, sp); + regs.p.n = !!(regs.$1 & 0x80); + regs.p.z = (regs.$1 == 0); +} + +mov_a_addrx(0xf5, x), +mov_a_addry(0xf6, y) { +1:sp = op_read(); +2:sp |= op_read() << 8; +3: +4:regs.a = op_read(OPMODE_ADDR, sp + regs.$1); + regs.p.n = !!(regs.a & 0x80); + regs.p.z = (regs.a == 0); +} + +mov_a_idpx(0xe7) { +1:dp = op_read() + regs.x; +2: +3:sp = op_read(OPMODE_DP, dp); +4:sp |= op_read(OPMODE_DP, dp + 1) << 8; +5:regs.a = op_read(OPMODE_ADDR, sp); + regs.p.n = !!(regs.a & 0x80); + regs.p.z = (regs.a == 0); +} + +mov_a_idpy(0xf7) { +1:dp = op_read(); +2: +3:sp = op_read(OPMODE_DP, dp); +4:sp |= op_read(OPMODE_DP, dp + 1) << 8; +5:regs.a = op_read(OPMODE_ADDR, sp + regs.y); + regs.p.n = !!(regs.a & 0x80); + regs.p.z = (regs.a == 0); +} + +mov_dp_dp(0xfa) { +1:sp = op_read(); +2:dp = op_read(); +3:rd = op_read(OPMODE_DP, sp); +4:op_write(OPMODE_DP, dp, rd); +} + +mov_dp_const(0x8f) { +1:rd = op_read(); +2:dp = op_read(); +3: +4:op_write(OPMODE_DP, dp, rd); +} + +mov_ix_a(0xc6) { +1: +2: +3:op_write(OPMODE_DP, regs.x, regs.a); +} + +mov_ixinc_a(0xaf) { +1: +2: +3:op_write(OPMODE_DP, regs.x++, regs.a); +} + +mov_dp_a(0xc4, a), +mov_dp_x(0xd8, x), +mov_dp_y(0xcb, y) { +1:dp = op_read(); +2: +3:op_write(OPMODE_DP, dp, regs.$1); +} + +mov_dpx_a(0xd4, x, a), +mov_dpy_x(0xd9, y, x), +mov_dpx_y(0xdb, x, y) { +1:dp = op_read(); +2: +3: +4:op_write(OPMODE_DP, dp + regs.$1, regs.$2); +} + +mov_addr_a(0xc5, a), +mov_addr_x(0xc9, x), +mov_addr_y(0xcc, y) { +1:dp = op_read(); +2:dp |= op_read() << 8; +3: +4:op_write(OPMODE_ADDR, dp, regs.$1); +} + +mov_addrx_a(0xd5, x), +mov_addry_a(0xd6, y) { +1:dp = op_read(); +2:dp |= op_read() << 8; +3: +4: +5:op_write(OPMODE_ADDR, dp + regs.$1, regs.a); +} + +mov_idpx_a(0xc7) { +1:sp = op_read() + regs.x; +2: +3:dp = op_read(OPMODE_DP, sp); +4:dp |= op_read(OPMODE_DP, sp + 1) << 8; +5: +6:op_write(OPMODE_ADDR, dp, regs.a); +} + +mov_idpy_a(0xd7) { +1:sp = op_read(); +2: +3:dp = op_read(OPMODE_DP, sp); +4:dp |= op_read(OPMODE_DP, sp + 1) << 8; +5: +6:op_write(OPMODE_ADDR, dp + regs.y, regs.a); +} + +movw_ya_dp(0xba) { +1:sp = op_read(); +2: +3:regs.a = op_read(OPMODE_DP, sp); +4:regs.y = op_read(OPMODE_DP, sp + 1); + regs.p.n = !!(regs.ya & 0x8000); + regs.p.z = (regs.ya == 0); +} + +movw_dp_ya(0xda) { +1:dp = op_read(); +2: +3:op_write(OPMODE_DP, dp, regs.a); +4:op_write(OPMODE_DP, dp + 1, regs.y); +} + +mov1_c_bit(0xaa) { +1:sp = op_read(); +2:sp |= op_read() << 8; +3:bit = sp >> 13; + sp &= 0x1fff; + rd = op_read(OPMODE_ADDR, sp); + regs.p.c = !!(rd & (1 << bit)); +} + +mov1_bit_c(0xca) { +1:dp = op_read(); +2:dp |= op_read() << 8; +3:bit = dp >> 13; + dp &= 0x1fff; + rd = op_read(OPMODE_ADDR, dp); + if(regs.p.c)rd |= (1 << bit); + else rd &= ~(1 << bit); +4:op_write(OPMODE_ADDR, dp, rd); +} diff --git a/src/apu/bapu/op_pc.b b/src/apu/bapu/op_pc.b new file mode 100644 index 00000000..d6e0b989 --- /dev/null +++ b/src/apu/bapu/op_pc.b @@ -0,0 +1,157 @@ +bra(0x2f, 0), +beq(0xf0, !regs.p.z), +bne(0xd0, regs.p.z), +bcs(0xb0, !regs.p.c), +bcc(0x90, regs.p.c), +bvs(0x70, !regs.p.v), +bvc(0x50, regs.p.v), +bmi(0x30, !regs.p.n), +bpl(0x10, regs.p.n) { +1:rd = op_read(); + if($1)end; +2: +3:regs.pc += (int8)rd; +} + +bbs0(0x03, 0x01, !=), +bbc0(0x13, 0x01, ==), +bbs1(0x23, 0x02, !=), +bbc1(0x33, 0x02, ==), +bbs2(0x43, 0x04, !=), +bbc2(0x53, 0x04, ==), +bbs3(0x63, 0x08, !=), +bbc3(0x73, 0x08, ==), +bbs4(0x83, 0x10, !=), +bbc4(0x93, 0x10, ==), +bbs5(0xa3, 0x20, !=), +bbc5(0xb3, 0x20, ==), +bbs6(0xc3, 0x40, !=), +bbc6(0xd3, 0x40, ==), +bbs7(0xe3, 0x80, !=), +bbc7(0xf3, 0x80, ==) { +1:dp = op_read(); +2:rd = op_read(); +3:sp = op_read(OPMODE_DP, dp); +4:if((sp & $1) $2 $1)end; +5: +6:regs.pc += (int8)rd; +} + +cbne_dp(0x2e, 0), +cbne_dpx(0xde, regs.x) { +1:dp = op_read(); +2:rd = op_read(); +3:sp = op_read(OPMODE_DP, dp + $1); +4:if(regs.a == sp)end; +5: +6:regs.pc += (int8)rd; +} + +dbnz_dp(0x6e) { +1:dp = op_read(); +2:rd = op_read(); +3:wr = op_read(OPMODE_DP, dp); +4:wr--; + op_write(OPMODE_DP, dp, wr); + if(wr == 0x00)end; +5: +6:regs.pc += (int8)rd; +} + +dbnz_y(0xfe) { +1:rd = op_read(); +2:regs.y--; +3:if(regs.y == 0x00)end; +4: +5:regs.pc += (int8)rd; +} + +jmp_addr(0x5f) { +1:rd = op_read(); +2:rd |= op_read() << 8; + regs.pc = rd; +} + +jmp_iaddrx(0x1f) { +1:dp = op_read(); +2:dp |= op_read() << 8; +3:dp += regs.x; +4:rd = op_read(OPMODE_ADDR, dp); +5:rd |= op_read(OPMODE_ADDR, dp + 1) << 8; + regs.pc = rd; +} + +call(0x3f) { +1:rd = op_read(); +2:rd |= op_read() << 8; +3: +4: +5: +6:stack_write(regs.pc >> 8); +7:stack_write(regs.pc); + regs.pc = rd; +} + +pcall(0x4f) { +1:rd = op_read(); +2: +3: +4:stack_write(regs.pc >> 8); +5:stack_write(regs.pc); + regs.pc = 0xff00 | rd; +} + +tcall_0(0x01, 0), +tcall_1(0x11, 1), +tcall_2(0x21, 2), +tcall_3(0x31, 3), +tcall_4(0x41, 4), +tcall_5(0x51, 5), +tcall_6(0x61, 6), +tcall_7(0x71, 7), +tcall_8(0x81, 8), +tcall_9(0x91, 9), +tcall_10(0xa1, 10), +tcall_11(0xb1, 11), +tcall_12(0xc1, 12), +tcall_13(0xd1, 13), +tcall_14(0xe1, 14), +tcall_15(0xf1, 15) { +1:dp = 0xffde - ($1 << 1); + rd = op_read(OPMODE_ADDR, dp); +2:rd |= op_read(OPMODE_ADDR, dp + 1) << 8; +3: +4: +5: +6:stack_write(regs.pc >> 8); +7:stack_write(regs.pc); + regs.pc = rd; +} + +brk(0x0f) { +1:rd = op_read(OPMODE_ADDR, 0xffde); +2:rd |= op_read(OPMODE_ADDR, 0xffdf) << 8; +3: +4: +5:stack_write(regs.pc >> 8); +6:stack_write(regs.pc); +7:stack_write(regs.p); + regs.pc = rd; + regs.p.b = 1; + regs.p.i = 0; +} + +ret(0x6f) { +1:rd = stack_read(); +2:rd |= stack_read() << 8; +3: +4:regs.pc = rd; +} + +reti(0x7f) { +1:regs.p = stack_read(); +2:rd = stack_read(); +3:rd |= stack_read() << 8; +4: +5:regs.pc = rd; +} diff --git a/src/apu/bapu/op_read.b b/src/apu/bapu/op_read.b new file mode 100644 index 00000000..c67f3571 --- /dev/null +++ b/src/apu/bapu/op_read.b @@ -0,0 +1,194 @@ +adc_a_const(0x88, adc, a), +and_a_const(0x28, and, a), +cmp_a_const(0x68, cmp, a), +cmp_x_const(0xc8, cmp, x), +cmp_y_const(0xad, cmp, y), +eor_a_const(0x48, eor, a), +or_a_const(0x08, or, a), +sbc_a_const(0xa8, sbc, a) { +1:rd = op_read(); + regs.$2 = op_$1(regs.$2, rd); +} + +adc_a_ix(0x86, adc), +and_a_ix(0x26, and), +cmp_a_ix(0x66, cmp), +eor_a_ix(0x46, eor), +or_a_ix(0x06, or), +sbc_a_ix(0xa6, sbc) { +1:rd = op_read(OPMODE_DP, regs.x); +2:regs.a = op_$1(regs.a, rd); +} + +adc_a_dp(0x84, adc, a), +and_a_dp(0x24, and, a), +cmp_a_dp(0x64, cmp, a), +cmp_x_dp(0x3e, cmp, x), +cmp_y_dp(0x7e, cmp, y), +eor_a_dp(0x44, eor, a), +or_a_dp(0x04, or, a), +sbc_a_dp(0xa4, sbc, a) { +1:dp = op_read(); +2:rd = op_read(OPMODE_DP, dp); + regs.$2 = op_$1(regs.$2, rd); +} + +adc_a_dpx(0x94, adc), +and_a_dpx(0x34, and), +cmp_a_dpx(0x74, cmp), +eor_a_dpx(0x54, eor), +or_a_dpx(0x14, or), +sbc_a_dpx(0xb4, sbc) { +1:dp = op_read(); +2: +3:rd = op_read(OPMODE_DP, dp + regs.x); + regs.a = op_$1(regs.a, rd); +} + +adc_a_addr(0x85, adc, a), +and_a_addr(0x25, and, a), +cmp_a_addr(0x65, cmp, a), +cmp_x_addr(0x1e, cmp, x), +cmp_y_addr(0x5e, cmp, y), +eor_a_addr(0x45, eor, a), +or_a_addr(0x05, or, a), +sbc_a_addr(0xa5, sbc, a) { +1:dp = op_read(); +2:dp |= op_read() << 8; +3:rd = op_read(OPMODE_ADDR, dp); + regs.$2 = op_$1(regs.$2, rd); +} + +adc_a_addrx(0x95, adc, x), +adc_a_addry(0x96, adc, y), +and_a_addrx(0x35, and, x), +and_a_addry(0x36, and, y), +cmp_a_addrx(0x75, cmp, x), +cmp_a_addry(0x76, cmp, y), +eor_a_addrx(0x55, eor, x), +eor_a_addry(0x56, eor, y), +or_a_addrx(0x15, or, x), +or_a_addry(0x16, or, y), +sbc_a_addrx(0xb5, sbc, x), +sbc_a_addry(0xb6, sbc, y) { +1:dp = op_read(); +2:dp |= op_read() << 8; +3: +4:rd = op_read(OPMODE_ADDR, dp + regs.$2); + regs.a = op_$1(regs.a, rd); +} + +adc_a_idpx(0x87, adc), +and_a_idpx(0x27, and), +cmp_a_idpx(0x67, cmp), +eor_a_idpx(0x47, eor), +or_a_idpx(0x07, or), +sbc_a_idpx(0xa7, sbc) { +1:dp = op_read() + regs.x; +2: +3:sp = op_read(OPMODE_DP, dp); +4:sp |= op_read(OPMODE_DP, dp + 1) << 8; +5:rd = op_read(OPMODE_ADDR, sp); + regs.a = op_$1(regs.a, rd); +} + +adc_a_idpy(0x97, adc), +and_a_idpy(0x37, and), +cmp_a_idpy(0x77, cmp), +eor_a_idpy(0x57, eor), +or_a_idpy(0x17, or), +sbc_a_idpy(0xb7, sbc) { +1:dp = op_read(); +2: +3:sp = op_read(OPMODE_DP, dp); +4:sp |= op_read(OPMODE_DP, dp + 1) << 8; +5:rd = op_read(OPMODE_ADDR, sp + regs.y); + regs.a = op_$1(regs.a, rd); +} + +adc_ix_iy(0x99, adc, 1), +and_ix_iy(0x39, and, 1), +cmp_ix_iy(0x79, cmp, 0), +eor_ix_iy(0x59, eor, 1), +or_ix_iy(0x19, or, 1), +sbc_ix_iy(0xb9, sbc, 1) { +1:wr = op_read(OPMODE_DP, regs.x); +2:rd = op_read(OPMODE_DP, regs.y); +3:wr = op_$1(wr, rd); +4:if($2)op_write(OPMODE_DP, regs.x, wr); +} + +adc_dp_dp(0x89, adc, 1), +and_dp_dp(0x29, and, 1), +cmp_dp_dp(0x69, cmp, 0), +eor_dp_dp(0x49, eor, 1), +or_dp_dp(0x09, or, 1), +sbc_dp_dp(0xa9, sbc, 1) { +1:sp = op_read(); +2:dp = op_read(); +3:wr = op_read(OPMODE_DP, dp); +4:rd = op_read(OPMODE_DP, sp); +5:wr = op_$1(wr, rd); + if($2)op_write(OPMODE_DP, dp, wr); +} + +adc_dp_const(0x98, adc, 1), +and_dp_const(0x38, and, 1), +cmp_dp_const(0x78, cmp, 0), +eor_dp_const(0x58, eor, 1), +or_dp_const(0x18, or, 1), +sbc_dp_const(0xb8, sbc, 1) { +1:rd = op_read(); +2:dp = op_read(); +3:wr = op_read(OPMODE_DP, dp); +4:wr = op_$1(wr, rd); + if($2)op_write(OPMODE_DP, dp, wr); +} + +addw_ya_dp(0x7a, addw), +cmpw_ya_dp(0x5a, cmpw), +subw_ya_dp(0x9a, subw) { +1:dp = op_read(); +2:rd = op_read(OPMODE_DP, dp); +3:rd |= op_read(OPMODE_DP, dp + 1) << 8; +4:regs.ya = op_$1(regs.ya, rd); +} + +and1_bit(0x4a, !!), +and1_notbit(0x6a, !) { +1:dp = op_read(); +2:dp |= op_read() << 8; +3:bit = dp >> 13; + dp &= 0x1fff; + rd = op_read(OPMODE_ADDR, dp); + regs.p.c = regs.p.c & $1(rd & (1 << bit)); +} + +eor1_bit(0x8a) { +1:dp = op_read(); +2:dp |= op_read() << 8; +3:bit = dp >> 13; + dp &= 0x1fff; + rd = op_read(OPMODE_ADDR, dp); +4:regs.p.c = regs.p.c ^ !!(rd & (1 << bit)); +} + +not1_bit(0xea) { +1:dp = op_read(); +2:dp |= op_read() << 8; +3:bit = dp >> 13; + dp &= 0x1fff; + rd = op_read(OPMODE_ADDR, dp); + rd ^= (1 << bit); +4:op_write(OPMODE_ADDR, dp, rd); +} + +or1_bit(0x0a, !!), +or1_notbit(0x2a, !) { +1:dp = op_read(); +2:dp |= op_read() << 8; +3:bit = dp >> 13; + dp &= 0x1fff; + rd = op_read(OPMODE_ADDR, dp); +4:regs.p.c = regs.p.c | $1(rd & (1 << bit)); +} diff --git a/src/apu/bapu/op_rmw.b b/src/apu/bapu/op_rmw.b new file mode 100644 index 00000000..6084310d --- /dev/null +++ b/src/apu/bapu/op_rmw.b @@ -0,0 +1,60 @@ +inc_a(0xbc, inc, a), +inc_x(0x3d, inc, x), +inc_y(0xfc, inc, y), +dec_a(0x9c, dec, a), +dec_x(0x1d, dec, x), +dec_y(0xdc, dec, y), +asl_a(0x1c, asl, a), +lsr_a(0x5c, lsr, a), +rol_a(0x3c, rol, a), +ror_a(0x7c, ror, a) { +1:regs.$2 = op_$1(regs.$2); +} + +inc_dp(0xab, inc), +dec_dp(0x8b, dec), +asl_dp(0x0b, asl), +lsr_dp(0x4b, lsr), +rol_dp(0x2b, rol), +ror_dp(0x6b, ror) { +1:dp = op_read(); +2:rd = op_read(OPMODE_DP, dp); +3:rd = op_$1(rd); + op_write(OPMODE_DP, dp, rd); +} + +inc_dpx(0xbb, inc), +dec_dpx(0x9b, dec), +asl_dpx(0x1b, asl), +lsr_dpx(0x5b, lsr), +rol_dpx(0x3b, rol), +ror_dpx(0x7b, ror) { +1:dp = op_read(); +2: +3:rd = op_read(OPMODE_DP, dp + regs.x); +4:rd = op_$1(rd); + op_write(OPMODE_DP, dp + regs.x, rd); +} + +inc_addr(0xac, inc), +dec_addr(0x8c, dec), +asl_addr(0x0c, asl), +lsr_addr(0x4c, lsr), +rol_addr(0x2c, rol), +ror_addr(0x6c, ror) { +1:dp = op_read(); +2:dp |= op_read() << 8; +3:rd = op_read(OPMODE_ADDR, dp); +4:rd = op_$1(rd); + op_write(OPMODE_ADDR, dp, rd); +} + +incw_dp(0x3a, incw), +decw_dp(0x1a, decw) { +1:dp = op_read(); +2:rd = op_read(OPMODE_DP, dp); +3:rd |= op_read(OPMODE_DP, dp + 1) << 8; +4:rd = op_$1(rd); + op_write(OPMODE_DP, dp + 1, rd >> 8); +5:op_write(OPMODE_DP, dp, rd); +} diff --git a/src/apu/bapuskip/bapuskip.cpp b/src/apu/bapuskip/bapuskip.cpp new file mode 100644 index 00000000..597a93bd --- /dev/null +++ b/src/apu/bapuskip/bapuskip.cpp @@ -0,0 +1,171 @@ +#include "../../base.h" + +uint8 bAPUSkip::spcram_read (uint16 addr) { return 0xff; } +void bAPUSkip::spcram_write(uint16 addr, uint8 value) {} + +/* + This routine is very serious. It will eat holes through + the ROM to skip APU test conditions. Or in other words, + it will disable and/or force branches when neccesary. + + It can very easily break or corrupt a game and prevent it + from being playable until the ROM is reloaded (ROM writes + are only performed in memory, of course). + + However, this kind of brute force approach is required to + get many games playable without proper SPC700 emulation. +*/ +uint8 bAPUSkip::port_read(uint8 port) { + port &= 3; +_apu_port *p = &apu_port[port]; +int i, x, y, z, t; +uint32 addr; + + addr = cpu->regs.pc.d; + p->read_addr[p->read_pos & 31] = addr; + +//- lda $214x +// cmp $214x +// bne - +// cmp ??? +// beq/bne - +__test1: +//look for an lda/cmp read pattern + if(addr == p->read_addr[(p->read_pos - 1) & 31])goto __test2; + if(addr != p->read_addr[(p->read_pos - 2) & 31])goto __test2; + if(addr == p->read_addr[(p->read_pos - 3) & 31])goto __test2; + if(addr != p->read_addr[(p->read_pos - 4) & 31])goto __test2; + if(p->read_addr[(p->read_pos - 1) & 31] != p->read_addr[(p->read_pos - 3) & 31])goto __test2; +//try and find compare opcode + for(i=0;i<24;i++) { + x = mem_bus->read(addr + i); + if(x == OP_CMP_CONST || x == OP_CPX_CONST || x == OP_CPY_CONST)break; + if(x == OP_CMP_ADDR || x == OP_CPX_ADDR || x == OP_CPY_ADDR) break; + if(x == OP_CMP_LONG)break; + } + if(i == 24)goto __test2; +//seek to next opcode + if(x == OP_CMP_CONST) { + i += (cpu->regs.p.m)?2:3; + } else if(x == OP_CPX_CONST || x == OP_CPY_CONST) { + i += (cpu->regs.p.x)?2:3; + } else if(x == OP_CMP_ADDR || x == OP_CPX_ADDR || x == OP_CPY_ADDR) { + i += 3; + } else { //(x == OP_CMP_LONG) { + i += 4; + } + x = mem_bus->read(addr + i); + if(x == OP_BNE) { + mem_bus->cart->write_protect(false); + mem_bus->write(addr + i, OP_NOP); + mem_bus->write(addr + i + 1, OP_NOP); + mem_bus->cart->write_protect(true); + } else if(x == OP_BEQ) { + mem_bus->cart->write_protect(false); + mem_bus->write(addr + i, OP_BRA); + mem_bus->cart->write_protect(true); + } else goto __test2; + goto __pass; + +//- lda $214x +// cmp ??? +// beq/bne - +__test2: +//look for a repeated read pattern + if(addr != p->read_addr[(p->read_pos - 1) & 31])goto __test3; + if(addr != p->read_addr[(p->read_pos - 2) & 31])goto __test3; + if(addr != p->read_addr[(p->read_pos - 3) & 31])goto __test3; + if(addr != p->read_addr[(p->read_pos - 4) & 31])goto __test3; + if(addr != p->read_addr[(p->read_pos - 5) & 31])goto __test3; + if(addr != p->read_addr[(p->read_pos - 6) & 31])goto __test3; + if(addr != p->read_addr[(p->read_pos - 7) & 31])goto __test3; + if(addr != p->read_addr[(p->read_pos - 8) & 31])goto __test3; +//try and find compare opcode + for(i=0;i<24;i++) { + x = mem_bus->read(addr + i); + if(x == OP_CMP_CONST || x == OP_CPX_CONST || x == OP_CPY_CONST)break; + if(x == OP_CMP_ADDR || x == OP_CPX_ADDR || x == OP_CPY_ADDR) break; + if(x == OP_CMP_LONG)break; + } + if(i == 24)goto __test3; +//seek to next opcode + if(x == OP_CMP_CONST) { + i += (cpu->regs.p.m)?2:3; + } else if(x == OP_CPX_CONST || x == OP_CPY_CONST) { + i += (cpu->regs.p.x)?2:3; + } else if(x == OP_CMP_ADDR || x == OP_CPX_ADDR || x == OP_CPY_ADDR) { + i += 3; + } else if(x == OP_CMP_LONG) { + i += 4; + } + x = mem_bus->read(addr + i); + if(x == OP_BNE) { + mem_bus->cart->write_protect(false); + mem_bus->write(addr + i, OP_NOP); + mem_bus->write(addr + i + 1, OP_NOP); + mem_bus->cart->write_protect(true); + } else if(x == OP_BEQ) { + mem_bus->cart->write_protect(false); + mem_bus->write(addr + i, OP_BRA); + mem_bus->cart->write_protect(true); + } else goto __test3; + goto __pass; + +//fallback +__test3: + if(p->pos < 4) { + if(!(port & 1)) { + p->value = cpu->regs.a.l; + } else { + p->value = cpu->regs.a.h; + } + } else if(p->pos < 8) { + if(!(port & 1)) { + p->value = cpu->regs.x.l; + } else { + p->value = cpu->regs.x.h; + } + } else if(p->pos < 12) { + if(!(port & 1)) { + p->value = cpu->regs.y.l; + } else { + p->value = cpu->regs.y.h; + } + } else if(p->pos < 16) { + p->value = rand(); + } + if(++p->pos == 16)p->pos = 0; + +__pass: + p->read_pos++; + p->read_pos &= 31; + return p->value; +} + +void bAPUSkip::port_write(uint8 port, uint8 value) { + port &= 3; + apu_port[port].value = value; +} + +void bAPUSkip::run() { + snes->notify(SNES::APU_EXEC_OPCODE_BEGIN); + snes->notify(SNES::APU_EXEC_OPCODE_END); +} + +void bAPUSkip::power() { + reset(); +} + +void bAPUSkip::reset() { + regs.a = 0x00; + regs.x = 0x00; + regs.y = 0x00; + regs.sp = 0x00; + regs.p = 0x02; + regs.pc = 0xffc0; + + memset(&apu_port[0], 0, sizeof(_apu_port)); + memset(&apu_port[1], 0, sizeof(_apu_port)); + memset(&apu_port[2], 0, sizeof(_apu_port)); + memset(&apu_port[3], 0, sizeof(_apu_port)); +} diff --git a/src/apu/bapuskip/bapuskip.h b/src/apu/bapuskip/bapuskip.h new file mode 100644 index 00000000..9d907c23 --- /dev/null +++ b/src/apu/bapuskip/bapuskip.h @@ -0,0 +1,33 @@ +class bAPUSkip : public APU { +public: + +struct _apu_port { + uint8 value; + uint8 step, pos; + uint32 read_addr[32], read_pos; +}apu_port[4]; + +enum { + OP_CMP_CONST = 0xc9, + OP_CPX_CONST = 0xe0, + OP_CPY_CONST = 0xc0, + OP_CMP_ADDR = 0xcd, + OP_CPX_ADDR = 0xec, + OP_CPY_ADDR = 0xcc, + OP_CMP_LONG = 0xcf, + OP_BNE = 0xd0, + OP_BEQ = 0xf0, + OP_BRA = 0x80, + OP_NOP = 0xea +}; + + uint8 spcram_read (uint16 addr); + void spcram_write(uint16 addr, uint8 value); + uint8 port_read (uint8 port); + void port_write (uint8 port, uint8 value); + + void run(); + uint32 cycles_executed() { return 12 * 24; } + void power(); + void reset(); +}; diff --git a/src/apu/dapu.cpp b/src/apu/dapu.cpp new file mode 100644 index 00000000..5377cadd --- /dev/null +++ b/src/apu/dapu.cpp @@ -0,0 +1,295 @@ +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]; +uint8 op, op0, op1; +uint16 opw, opdp0, opdp1; + sprintf(s, "..%0.4x ", regs.pc); + + op = spcram_read(regs.pc); + op0 = spcram_read(regs.pc + 1); + op1 = spcram_read(regs.pc + 2); + opw = (op0) | (op1 << 8); + opdp0 = ((regs.p.p)?0x100:0x000) + op0; + opdp1 = ((regs.p.p)?0x100:0x000) + op1; + + strcpy(t, " "); + switch(op) { + case 0x00:sprintf(t, "nop"); break; + case 0x01:sprintf(t, "tcall 0"); break; + case 0x02:sprintf(t, "set0 $%0.3x", opdp0); break; + case 0x03:sprintf(t, "bbs0 $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break; + case 0x04:sprintf(t, "or a,$%0.3x", opdp0); break; + case 0x05:sprintf(t, "or a,$%0.4x", opw); break; + case 0x06:sprintf(t, "or a,(x)"); break; + case 0x07:sprintf(t, "or a,($%0.3x+x)", opdp0); break; + case 0x08:sprintf(t, "or a,#$%0.2x", op0); break; + case 0x09:sprintf(t, "or $%0.3x,$%0.3x", opdp1, opdp0); break; + case 0x0a:sprintf(t, "or1 c,$%0.4x:%d", opw & 0x1fff, opw >> 13); break; + case 0x0b:sprintf(t, "asl $%0.3x", opdp0); break; + case 0x0c:sprintf(t, "asl $%0.4x", opw); break; + case 0x0d:sprintf(t, "push p"); break; + case 0x0e:sprintf(t, "tset $%0.4x,a", opw); break; + case 0x0f:sprintf(t, "brk"); break; + case 0x10:sprintf(t, "bpl $%0.4x", __relb(op0, 2)); break; + case 0x11:sprintf(t, "tcall 1"); break; + case 0x12:sprintf(t, "clr0 $%0.3x", opdp0); break; + case 0x13:sprintf(t, "bbc0 $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break; + case 0x14:sprintf(t, "or a,$%0.3x+x", opdp0); break; + case 0x15:sprintf(t, "or a,$%0.4x+x", opw); break; + case 0x16:sprintf(t, "or a,$%0.4x+y", opw); break; + case 0x17:sprintf(t, "or a,($%0.3x)+y", opdp0); break; + case 0x18:sprintf(t, "or $%0.3x,#$%0.2x", opdp1, op0); break; + case 0x19:sprintf(t, "or (x),(y)"); break; + case 0x1a:sprintf(t, "decw $%0.3x", opdp0); break; + case 0x1b:sprintf(t, "asl $%0.3x+x", opdp0); break; + case 0x1c:sprintf(t, "asl a"); break; + case 0x1d:sprintf(t, "dec x"); break; + case 0x1e:sprintf(t, "cmp x,$%0.4x", opw); break; + case 0x1f:sprintf(t, "jmp ($%0.4x+x)", opw); break; + case 0x20:sprintf(t, "clrp"); break; + case 0x21:sprintf(t, "tcall 2"); break; + case 0x22:sprintf(t, "set1 $%0.3x", opdp0); break; + case 0x23:sprintf(t, "bbs1 $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break; + case 0x24:sprintf(t, "and a,$%0.3x", opdp0); break; + case 0x25:sprintf(t, "and a,$%0.4x", opw); break; + case 0x26:sprintf(t, "and a,(x)"); break; + case 0x27:sprintf(t, "and a,($%0.3x+x)", opdp0); break; + case 0x28:sprintf(t, "and a,#$%0.2x", op0); break; + case 0x29:sprintf(t, "and $%0.3x,$%0.3x", opdp1, opdp0); break; + case 0x2a:sprintf(t, "or1 c,!$%0.4x:%d", opw & 0x1fff, opw >> 13); break; + case 0x2b:sprintf(t, "rol $%0.3x", opdp0); break; + case 0x2c:sprintf(t, "rol $%0.4x", opw); break; + case 0x2d:sprintf(t, "push a"); break; + case 0x2e:sprintf(t, "cbne $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break; + case 0x2f:sprintf(t, "bra $%0.4x", __relb(op0, 2)); break; + case 0x30:sprintf(t, "bmi $%0.4x", __relb(op0, 2)); break; + case 0x31:sprintf(t, "tcall 3"); break; + case 0x32:sprintf(t, "clr1 $%0.3x", opdp0); break; + case 0x33:sprintf(t, "bbc1 $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break; + case 0x34:sprintf(t, "and a,$%0.3x+x", opdp0); break; + case 0x35:sprintf(t, "and a,$%0.4x+x", opw); break; + case 0x36:sprintf(t, "and a,$%0.4x+y", opw); break; + case 0x37:sprintf(t, "and a,($%0.3x)+y", opdp0); break; + case 0x38:sprintf(t, "and $%0.3x,#$%0.2x", opdp1, op0); break; + case 0x39:sprintf(t, "and (x),(y)"); break; + case 0x3a:sprintf(t, "incw $%0.3x", opdp0); break; + case 0x3b:sprintf(t, "rol $%0.3x+x", opdp0); break; + case 0x3c:sprintf(t, "rol a"); break; + case 0x3d:sprintf(t, "inc x"); break; + case 0x3e:sprintf(t, "cmp x,$%0.3x", opdp0); break; + case 0x3f:sprintf(t, "call $%0.4x", opw); break; + case 0x40:sprintf(t, "setp"); break; + case 0x41:sprintf(t, "tcall 4"); break; + case 0x42:sprintf(t, "set2 $%0.3x", opdp0); break; + case 0x43:sprintf(t, "bbs2 $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break; + case 0x44:sprintf(t, "eor a,$%0.3x", opdp0); break; + case 0x45:sprintf(t, "eor a,$%0.4x", opw); break; + case 0x46:sprintf(t, "eor a,(x)"); break; + case 0x47:sprintf(t, "eor a,($%0.3x+x)", opdp0); break; + case 0x48:sprintf(t, "eor a,#$%0.2x", op0); break; + case 0x49:sprintf(t, "eor $%0.3x,$%0.3x", opdp1, opdp0); break; + case 0x4a:sprintf(t, "and1 c,$%0.4x:%d", opw & 0x1fff, opw >> 13); break; + case 0x4b:sprintf(t, "lsr $%0.3x", opdp0); break; + case 0x4c:sprintf(t, "lsr $%0.4x", opw); break; + case 0x4d:sprintf(t, "push x"); break; + case 0x4e:sprintf(t, "tclr $%0.4x,a", opw); break; + case 0x4f:sprintf(t, "pcall $ff%0.2x", op0); break; + case 0x50:sprintf(t, "bvc $%0.4x", __relb(op0, 2)); break; + case 0x51:sprintf(t, "tcall 5"); break; + case 0x52:sprintf(t, "clr2 $%0.3x", opdp0); break; + case 0x53:sprintf(t, "bbc2 $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break; + case 0x54:sprintf(t, "eor a,$%0.3x+x", opdp0); break; + case 0x55:sprintf(t, "eor a,$%0.4x+x", opw); break; + case 0x56:sprintf(t, "eor a,$%0.4x+y", opw); break; + case 0x57:sprintf(t, "eor a,($%0.3x)+y", opdp0); break; + case 0x58:sprintf(t, "eor $%0.3x,#$%0.2x", opdp1, op0); break; + case 0x59:sprintf(t, "eor (x),(y)"); break; + case 0x5a:sprintf(t, "cmpw ya,$%0.3x", opdp0); break; + case 0x5b:sprintf(t, "lsr $%0.3x+x", opdp0); break; + case 0x5c:sprintf(t, "lsr a"); break; + case 0x5d:sprintf(t, "mov x,a"); break; + case 0x5e:sprintf(t, "cmp y,$%0.4x", opw); break; + case 0x5f:sprintf(t, "jmp $%0.4x", opw); break; + case 0x60:sprintf(t, "clrc"); break; + case 0x61:sprintf(t, "tcall 6"); break; + case 0x62:sprintf(t, "set3 $%0.3x", opdp0); break; + case 0x63:sprintf(t, "bbs3 $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break; + case 0x64:sprintf(t, "cmp a,$%0.3x", opdp0); break; + case 0x65:sprintf(t, "cmp a,$%0.4x", opw); break; + case 0x66:sprintf(t, "cmp a,(x)"); break; + case 0x67:sprintf(t, "cmp a,($%0.3x+x)", opdp0); break; + case 0x68:sprintf(t, "cmp a,#$%0.2x", op0); break; + case 0x69:sprintf(t, "cmp $%0.3x,$%0.3x", opdp1, opdp0); break; + case 0x6a:sprintf(t, "and1 c,!$%0.4x:%d", opw & 0x1fff, opw >> 13); break; + case 0x6b:sprintf(t, "ror $%0.3x", opdp0); break; + case 0x6c:sprintf(t, "ror $%0.4x", opw); break; + case 0x6d:sprintf(t, "push y"); break; + case 0x6e:sprintf(t, "dbnz $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break; + case 0x6f:sprintf(t, "ret"); break; + case 0x70:sprintf(t, "bvs $%0.4x", __relb(op0, 2)); break; + case 0x71:sprintf(t, "tcall 7"); break; + case 0x72:sprintf(t, "clr3 $%0.3x", opdp0); break; + case 0x73:sprintf(t, "bbc3 $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break; + case 0x74:sprintf(t, "cmp a,$%0.3x+x", opdp0); break; + case 0x75:sprintf(t, "cmp a,$%0.4x+x", opw); break; + case 0x76:sprintf(t, "cmp a,$%0.4x+y", opw); break; + case 0x77:sprintf(t, "cmp a,($%0.3x)+y", opdp0); break; + case 0x78:sprintf(t, "cmp $%0.3x,#$%0.2x", opdp1, op0); break; + case 0x79:sprintf(t, "cmp (x),(y)"); break; + case 0x7a:sprintf(t, "addw ya,$%0.3x", opdp0); break; + case 0x7b:sprintf(t, "ror $%0.3x+x", opdp0); break; + case 0x7c:sprintf(t, "ror a"); break; + case 0x7d:sprintf(t, "mov a,x"); break; + case 0x7e:sprintf(t, "cmp y,$%0.3x", opdp0); break; + case 0x7f:sprintf(t, "reti"); break; + case 0x80:sprintf(t, "setc"); break; + case 0x81:sprintf(t, "tcall 8"); break; + case 0x82:sprintf(t, "set4 $%0.3x", opdp0); break; + case 0x83:sprintf(t, "bbs4 $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break; + case 0x84:sprintf(t, "adc a,$%0.3x", opdp0); break; + case 0x85:sprintf(t, "adc a,$%0.4x", opw); break; + case 0x86:sprintf(t, "adc a,(x)"); break; + case 0x87:sprintf(t, "adc a,($%0.3x+x)", opdp0); break; + case 0x88:sprintf(t, "adc a,#$%0.2x", op0); break; + case 0x89:sprintf(t, "adc $%0.3x,$%0.3x", opdp1, opdp0); break; + case 0x8a:sprintf(t, "eor1 c,$%0.4x:%d", opw & 0x1fff, opw >> 13); break; + case 0x8b:sprintf(t, "dec $%0.3x", opdp0); break; + case 0x8c:sprintf(t, "dec $%0.4x", opw); break; + case 0x8d:sprintf(t, "mov y,#$%0.2x", op0); break; + case 0x8e:sprintf(t, "pop p"); break; + case 0x8f:sprintf(t, "mov $%0.3x,#$%0.2x", opdp1, op0); break; + case 0x90:sprintf(t, "bcc $%0.4x", __relb(op0, 2)); break; + case 0x91:sprintf(t, "tcall 9"); break; + case 0x92:sprintf(t, "clr4 $%0.3x", opdp0); break; + case 0x93:sprintf(t, "bbc4 $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break; + case 0x94:sprintf(t, "adc a,$%0.3x+x", opdp0); break; + case 0x95:sprintf(t, "adc a,$%0.4x+x", opw); break; + case 0x96:sprintf(t, "adc a,$%0.4x+y", opw); break; + case 0x97:sprintf(t, "adc a,($%0.3x)+y", opdp0); break; + case 0x98:sprintf(t, "adc $%0.3x,#$%0.2x", opdp1, op0); break; + case 0x99:sprintf(t, "adc (x),(y)"); break; + case 0x9a:sprintf(t, "subw ya,$%0.3x", opdp0); break; + case 0x9b:sprintf(t, "dec $%0.3x+x", opdp0); break; + case 0x9c:sprintf(t, "dec a"); break; + case 0x9d:sprintf(t, "mov x,sp"); break; + case 0x9e:sprintf(t, "div ya,x"); break; + case 0x9f:sprintf(t, "xcn a"); break; + case 0xa0:sprintf(t, "ei"); break; + case 0xa1:sprintf(t, "tcall 10"); break; + case 0xa2:sprintf(t, "set5 $%0.3x", opdp0); break; + case 0xa3:sprintf(t, "bbs5 $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break; + case 0xa4:sprintf(t, "sbc a,$%0.3x", opdp0); break; + case 0xa5:sprintf(t, "sbc a,$%0.4x", opw); break; + case 0xa6:sprintf(t, "sbc a,(x)"); break; + case 0xa7:sprintf(t, "sbc a,($%0.3x+x)", opdp0); break; + case 0xa8:sprintf(t, "sbc a,#$%0.2x", op0); break; + case 0xa9:sprintf(t, "sbc $%0.3x,$%0.3x", opdp1, opdp0); break; + case 0xaa:sprintf(t, "mov1 c,$%0.4x:%d", opw & 0x1fff, opw >> 13); break; + case 0xab:sprintf(t, "inc $%0.3x", opdp0); break; + case 0xac:sprintf(t, "inc $%0.4x", opw); break; + case 0xad:sprintf(t, "cmp y,#$%0.2x", op0); break; + case 0xae:sprintf(t, "pop a"); break; + case 0xaf:sprintf(t, "mov (x)+,a"); break; + case 0xb0:sprintf(t, "bcs $%0.4x", __relb(op0, 2)); break; + case 0xb1:sprintf(t, "tcall 11"); break; + case 0xb2:sprintf(t, "clr5 $%0.3x", opdp0); break; + case 0xb3:sprintf(t, "bbc5 $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break; + case 0xb4:sprintf(t, "sbc a,$%0.3x+x", opdp0); break; + case 0xb5:sprintf(t, "sbc a,$%0.4x+x", opw); break; + case 0xb6:sprintf(t, "sbc a,$%0.4x+y", opw); break; + case 0xb7:sprintf(t, "sbc a,($%0.3x)+y", opdp0); break; + case 0xb8:sprintf(t, "sbc $%0.3x,#$%0.2x", opdp1, op0); break; + case 0xb9:sprintf(t, "sbc (x),(y)"); break; + case 0xba:sprintf(t, "movw ya,$%0.3x", opdp0); break; + case 0xbb:sprintf(t, "inc $%0.3x+x", opdp0); break; + case 0xbc:sprintf(t, "inc a"); break; + case 0xbd:sprintf(t, "mov sp,x"); break; + case 0xbe:sprintf(t, "das a"); break; + case 0xbf:sprintf(t, "mov a,(x)+"); break; + case 0xc0:sprintf(t, "di"); break; + case 0xc1:sprintf(t, "tcall 12"); break; + case 0xc2:sprintf(t, "set6 $%0.3x", opdp0); break; + case 0xc3:sprintf(t, "bbs6 $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break; + case 0xc4:sprintf(t, "mov $%0.3x,a", opdp0); break; + case 0xc5:sprintf(t, "mov $%0.4x,a", opw); break; + case 0xc6:sprintf(t, "mov (x),a"); break; + case 0xc7:sprintf(t, "mov ($%0.3x+x),a", opdp0); break; + case 0xc8:sprintf(t, "cmp x,#$%0.2x", op0); break; + case 0xc9:sprintf(t, "mov $%0.4x,x", opw); break; + case 0xca:sprintf(t, "mov1 $%0.4x:%d,c", opw & 0x1fff, opw >> 13); break; + case 0xcb:sprintf(t, "mov $%0.3x,y", opdp0); break; + case 0xcc:sprintf(t, "mov $%0.4x,y", opw); break; + case 0xcd:sprintf(t, "mov x,#$%0.2x", op0); break; + case 0xce:sprintf(t, "pop x"); break; + case 0xcf:sprintf(t, "mul ya"); break; + case 0xd0:sprintf(t, "bne $%0.4x", __relb(op0, 2)); break; + case 0xd1:sprintf(t, "tcall 13"); break; + case 0xd2:sprintf(t, "clr6 $%0.3x", opdp0); break; + case 0xd3:sprintf(t, "bbc6 $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break; + case 0xd4:sprintf(t, "mov $%0.3x+x,a", opdp0); break; + case 0xd5:sprintf(t, "mov $%0.4x+x,a", opw); break; + case 0xd6:sprintf(t, "mov $%0.4x+y,a", opw); break; + case 0xd7:sprintf(t, "mov ($%0.3x)+y,a", opdp0); break; + case 0xd8:sprintf(t, "mov $%0.3x,x", opdp0); break; + case 0xd9:sprintf(t, "mov $%0.3x+y,x", opdp0); break; + case 0xda:sprintf(t, "movw $%0.3x,ya", opdp0); break; + case 0xdb:sprintf(t, "mov $%0.3x+x,y", opdp0); break; + case 0xdc:sprintf(t, "dec y"); break; + case 0xdd:sprintf(t, "mov a,y"); break; + case 0xde:sprintf(t, "cbne $%0.3x+x,$%0.4x", opdp0, __relb(op1, 3));break; + case 0xdf:sprintf(t, "daa a"); break; + case 0xe0:sprintf(t, "clrv"); break; + case 0xe1:sprintf(t, "tcall 14"); break; + case 0xe2:sprintf(t, "set7 $%0.3x", opdp0); break; + case 0xe3:sprintf(t, "bbs7 $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break; + case 0xe4:sprintf(t, "mov a,$%0.3x", opdp0); break; + case 0xe5:sprintf(t, "mov a,$%0.4x", opw); break; + case 0xe6:sprintf(t, "mov a,(x)"); break; + case 0xe7:sprintf(t, "mov a,($%0.3x+x)", opdp0); break; + case 0xe8:sprintf(t, "mov a,#$%0.2x", op0); break; + case 0xe9:sprintf(t, "mov x,$%0.4x", opw); break; + case 0xea:sprintf(t, "not1 c,$%0.4x:%d", opw & 0x1fff, opw >> 13); break; + case 0xeb:sprintf(t, "mov y,$%0.3x", opdp0); break; + case 0xec:sprintf(t, "mov y,$%0.4x", opw); break; + case 0xed:sprintf(t, "notc"); break; + case 0xee:sprintf(t, "pop y"); break; + case 0xef:sprintf(t, "sleep"); break; + case 0xf0:sprintf(t, "beq $%0.4x", __relb(op0, 2)); break; + case 0xf1:sprintf(t, "tcall 15"); break; + case 0xf2:sprintf(t, "clr7 $%0.3x", opdp0); break; + case 0xf3:sprintf(t, "bbc7 $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break; + case 0xf4:sprintf(t, "mov a,$%0.3x+x", opdp0); break; + case 0xf5:sprintf(t, "mov a,$%0.4x+x", opw); break; + case 0xf6:sprintf(t, "mov a,$%0.4x+y", opw); break; + case 0xf7:sprintf(t, "mov a,($%0.3x)+y", opdp0); break; + case 0xf8:sprintf(t, "mov x,$%0.3x", opdp0); break; + case 0xf9:sprintf(t, "mov x,$%0.3x+y", opdp0); break; + case 0xfa:sprintf(t, "mov $%0.3x,$%0.3x", opdp1, opdp0); break; + case 0xfb:sprintf(t, "mov y,$%0.3x+x", opdp0); break; + case 0xfc:sprintf(t, "inc y"); break; + case 0xfd:sprintf(t, "mov y,a"); break; + case 0xfe:sprintf(t, "dbnz y,$%0.4x", __relb(op0, 2)); break; + case 0xff:sprintf(t, "stop"); break; + } + t[strlen(t)] = ' '; + strcat(s, t); + + sprintf(t, "A:%0.2x X:%0.2x Y:%0.2x SP:01%0.2x YA:%0.4x ", + regs.a, regs.x, regs.y, regs.sp, regs.ya); + strcat(s, t); + + sprintf(t, "%c%c%c%c%c%c%c%c", + (regs.p.n)?'N':'n', + (regs.p.v)?'V':'v', + (regs.p.p)?'P':'p', + (regs.p.b)?'B':'b', + (regs.p.h)?'H':'h', + (regs.p.i)?'I':'i', + (regs.p.z)?'Z':'z', + (regs.p.c)?'C':'c'); + strcat(s, t); +} diff --git a/src/apu/iplrom.h b/src/apu/iplrom.h new file mode 100644 index 00000000..84cb6441 --- /dev/null +++ b/src/apu/iplrom.h @@ -0,0 +1,48 @@ +//This is the IPLROM for the SPC700 coprocessor. +//This array is *read-only*. The SPC700 does not +//allow writing to the IPLROM, all writes are +//instead mapped to the extended SPC700 RAM region, +//accessible when $f1 bit 7 is clear. +//If you use this buffer directly, make sure not +//to write to it, as this will break other APU +//implementations that attempt to use this buffer. + +#ifdef _APU_IPLROM +const uint8 spc700_iplrom[64] = { +/*ffc0*/ 0xcd, 0xef, //mov x,#$ef +/*ffc2*/ 0xbd, //mov sp,x +/*ffc3*/ 0xe8, 0x00, //mov a,#$00 +/*ffc5*/ 0xc6, //mov (x),a +/*ffc6*/ 0x1d, //dec x +/*ffc7*/ 0xd0, 0xfc, //bne $ffc5 +/*ffc9*/ 0x8f, 0xaa, 0xf4, //mov $f4,#$aa +/*ffcc*/ 0x8f, 0xbb, 0xf5, //mov $f5,#$bb +/*ffcf*/ 0x78, 0xcc, 0xf4, //cmp $f4,#$cc +/*ffd2*/ 0xd0, 0xfb, //bne $ffcf +/*ffd4*/ 0x2f, 0x19, //bra $ffef +/*ffd6*/ 0xeb, 0xf4, //mov y,$f4 +/*ffd8*/ 0xd0, 0xfc, //bne $ffd6 +/*ffda*/ 0x7e, 0xf4, //cmp y,$f4 +/*ffdc*/ 0xd0, 0x0b, //bne $ffe9 +/*ffde*/ 0xe4, 0xf5, //mov a,$f5 +/*ffe0*/ 0xcb, 0xf4, //mov $f4,y +/*ffe2*/ 0xd7, 0x00, //mov ($00)+y,a +/*ffe4*/ 0xfc, //inc y +/*ffe5*/ 0xd0, 0xf3, //bne $ffda +/*ffe7*/ 0xab, 0x01, //inc $01 +/*ffe9*/ 0x10, 0xef, //bpl $ffda +/*ffeb*/ 0x7e, 0xf4, //cmp y,$f4 +/*ffed*/ 0x10, 0xeb, //bpl $ffda +/*ffef*/ 0xba, 0xf6, //movw ya,$f6 +/*fff1*/ 0xda, 0x00, //movw $00,ya +/*fff3*/ 0xba, 0xf4, //movw ya,$f4 +/*fff5*/ 0xc4, 0xf4, //mov $f4,a +/*fff7*/ 0xdd, //mov a,y +/*fff8*/ 0x5d, //mov x,a +/*fff9*/ 0xd0, 0xdb, //bne $ffd6 +/*fffb*/ 0x1f, 0x00, 0x00, //jmp ($0000+x) +/*fffe*/ 0xc0, 0xff //---reset vector location ($ffc0) +}; +#else +extern const uint8 spc700_iplrom[64]; +#endif diff --git a/src/base.h b/src/base.h index 0be99a9b..98efb23d 100644 --- a/src/base.h +++ b/src/base.h @@ -1,3 +1,4 @@ +#include #include "lib/libbase.h" //structs diff --git a/src/clock/bclock/bclock.cpp b/src/clock/bclock/bclock.cpp deleted file mode 100644 index 4c38f5d9..00000000 --- a/src/clock/bclock/bclock.cpp +++ /dev/null @@ -1,201 +0,0 @@ -#include "../../base.h" - -void bClock::frameskip_update_status() { - if(frameskip.changed == true) { - frameskip.changed = false; - frameskip.count = frameskip.new_count; - frameskip.pos = 0; - } else { - frameskip.pos++; - frameskip.pos %= (frameskip.count + 1); - } - - frameskip.notify_ppu = (frameskip.pos == 0)?true:false; -} - -void bClock::dram_refresh_test() { - if(cc1.dram_refreshed == false && status.hcycles >= cc1.dram_refresh_pos) { - cc1.dram_refreshed = true; - - if(status.interlace != false || status.interlace_field != 1 || status.vcounter != 240) { - if(cc1.dram_refresh_pos == 534) { - cc1.dram_refresh_pos = 538; - } else { //cc1.dram_refresh_pos == 538 - cc1.dram_refresh_pos = 534; - } - } - - cc1.pos += 40; - cc1.frame_pos += 40; - status.hcycles += 40; - } -} - -/* - all scanlines are 1364 cycles long, except scanline 240 - on non-interlace odd-frames, which is 1360 cycles long. - 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. - - cycles per frame: - 263 * 1364 = 358732 - 262 * 1364 = 357368 - 262 * 1364 - 4 = 357364 -*/ -void bClock::inc_vcounter() { - status.hcycles -= cc1.line_cycles; - - status.vcounter++; - if(status.vcounter >= cc1.frame_lines) { - frameskip_update_status(); - - cc1.frame_pos -= cc1.frame_cycles; - status.vcounter = 0; - status.interlace_field ^= 1; - if(status.interlace == true) { - if(status.interlace_field == 0) { - cc1.frame_cycles = 263 * 1364; - cc1.frame_lines = 263; - } else { - cc1.frame_cycles = 262 * 1364; - cc1.frame_lines = 262; - } - } else { - if(status.interlace_field == 0) { - cc1.frame_cycles = 262 * 1364; - cc1.frame_lines = 262; - } else { - cc1.frame_cycles = (262 * 1364) - 4; - cc1.frame_lines = 262; - } - } - signal_frame = true; - } - - if(status.interlace == false && status.interlace_field == 1 && status.vcounter == 240) { - cc1.line_cycles = 1360; - } else { - cc1.line_cycles = 1364; - } - - cc1.dram_refreshed = false; - signal_scanline = true; -} - -/* - all dots are 4 cycles long, except dots 322 and 326. dots 322 and 326 - 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 } -*/ -void bClock::sync() { -uint32 new_cycles, cycles; - new_cycles = cc1.pos - cc1.last_pos; - while(new_cycles) { - if(new_cycles > 40) { - cycles = 40; - new_cycles -= 40; - } else { - cycles = new_cycles; - new_cycles = 0; - } - - status.hcycles += cycles; - cc1.frame_pos += cycles; - dram_refresh_test(); - if(status.hcycles >= cc1.line_cycles) { - inc_vcounter(); - } - } - - if(status.interlace == false && status.interlace_field == 1 && status.vcounter == 240) { - status.hcounter = status.hcycles >> 2; - } else { - //1288 = 322 * 4, 1306 = 326 * 4 + 2 - status.hcounter = (status.hcycles - ((status.hcycles > 1288) << 1) - ((status.hcycles > 1306) << 1)) >> 2; - } - - cc1.last_pos = cc1.pos; - if(cc1.pos > cc1.frequency) { - cc1.pos -= cc1.frequency; - cc1.last_pos -= cc1.frequency; - } -} - -void bClock::set_frameskip(uint8 fs) { - frameskip.changed = true; - frameskip.new_count = fs; -} - -void bClock::power() { - reset(); -} - -void bClock::reset() { -//upon SNES reset, start at scanline 0 non-interlace - cc1.frame_cycles = 262 * 1364; - cc1.frame_lines = 262; - cc1.line_cycles = 1364; - -/* - Initial latch values for $213c/$213d - 0035:0000 (53.0 -> 212) [lda $2137] - 0038:0000 (56.5 -> 226) [nop : lda $2137] -*/ - cc1.pos = 188; - cc1.last_pos = 0; - cc1.frame_pos = 0; - status.vcounter = 0; - status.hcounter = 0; - status.hcycles = 0; - - cc1.dram_refresh_pos = 538; - cc1.dram_refreshed = false; - - cc2.pos = 0; - - signal_scanline = false; - signal_frame = false; - sync(); -} - -void bClock::run() { - cpu->run(); - if(frameskip.notify_ppu == true)ppu->run(); - sync(); - - if(signal_frame == true) { - signal_frame = false; - cpu->frame(); - if(frameskip.notify_ppu == true)ppu->frame(); - } - - if(signal_scanline == true) { - signal_scanline = false; - cpu->scanline(); - if(frameskip.notify_ppu == true)ppu->scanline(); - } -} - -void bClock::add_cc1_cycles(uint32 cycles) { - cc1.pos += cycles; -} - -void bClock::add_cc2_cycles(uint32 cycles) { - cc2.pos += cycles; -} - -bClock::bClock() { - cc1.frequency = 21477272; - cc2.frequency = 24576000; - - frameskip.changed = false; - frameskip.count = 0; - frameskip.pos = 0; -} diff --git a/src/clock/bclock/bclock.h b/src/clock/bclock/bclock.h deleted file mode 100644 index 4de562e6..00000000 --- a/src/clock/bclock/bclock.h +++ /dev/null @@ -1,37 +0,0 @@ -class bClock : public Clock { -private: -struct { -bool changed, notify_ppu; -uint8 count, new_count, pos; -}frameskip; -bool signal_scanline, signal_frame; - inline void frameskip_update_status(); - inline void inc_vcounter(); - inline void dram_refresh_test(); - -public: - struct { - uint32 frequency; - uint32 pos, last_pos; - uint32 frame_cycles, frame_lines, frame_pos; - uint16 line_cycles; - bool dram_refreshed; //whether or not dram has been refreshed on this line - uint16 dram_refresh_pos; - }cc1; - struct { - uint32 frequency; - uint32 pos, last_pos; - }cc2; - - inline void set_frameskip(uint8 fs); - - inline void add_cc1_cycles(uint32 cycles); - inline void add_cc2_cycles(uint32 cycles); - inline void sync(); - inline void run(); - inline void power(); - inline void reset(); - - bClock(); - ~bClock(); -}; diff --git a/src/clock/clock.cpp b/src/clock/clock.cpp deleted file mode 100644 index 5bfc6823..00000000 --- a/src/clock/clock.cpp +++ /dev/null @@ -1,49 +0,0 @@ -#include "../base.h" - -void Clock::enable_overscan(bool n) { - status.overscan = n; -} - -void Clock::enable_interlace(bool n) { - status.interlace = n; -} - -bool Clock::overscan() { - return status.overscan; -} - -bool Clock::interlace() { - return status.interlace; -} - -bool Clock::interlace_field() { - return status.interlace_field; -} - -uint16 Clock::vcounter() { - return status.vcounter; -} - -uint16 Clock::hcounter() { - return status.hcounter; -} - -uint16 Clock::hcycles() { - return status.hcycles; -} - -uint16 Clock::visible_scanlines() { - return (status.overscan)?239:224; -} - -void Clock::set_frameskip(uint8 fs) {} - -Clock::Clock() { - status.overscan = false; - status.interlace = false; - status.interlace_field = 0; - - status.vcounter = 0; - status.hcounter = 0; - status.hcycles = 0; -} diff --git a/src/clock/clock.h b/src/clock/clock.h deleted file mode 100644 index 4795c330..00000000 --- a/src/clock/clock.h +++ /dev/null @@ -1,36 +0,0 @@ -class Clock { -private: -struct { - bool overscan; - bool interlace; - bool interlace_field; - - uint16 vcounter; - uint16 hcounter; - uint16 hcycles; -}status; - -public: - virtual void enable_overscan(bool n); - virtual void enable_interlace(bool n); - virtual bool overscan(); - virtual bool interlace(); - virtual bool interlace_field(); - virtual uint16 vcounter(); - virtual uint16 hcounter(); - virtual uint16 hcycles(); - virtual uint16 visible_scanlines(); - - virtual void set_frameskip(uint8 fs); - - virtual void add_cc1_cycles(uint32 cycles) = 0; - virtual void add_cc2_cycles(uint32 cycles) = 0; - virtual void sync() = 0; - virtual void run() = 0; - virtual void power() = 0; - virtual void reset() = 0; - - Clock(); - - friend class bClock; -}; diff --git a/src/cpu/bcpu/bcpu.cpp b/src/cpu/bcpu/bcpu.cpp index 410300e2..94fe4f44 100644 --- a/src/cpu/bcpu/bcpu.cpp +++ b/src/cpu/bcpu/bcpu.cpp @@ -1,20 +1,19 @@ #include "../../base.h" -#include "bcpu_op_adc.cpp" -#include "bcpu_op_and.cpp" -#include "bcpu_op_cmp.cpp" -#include "bcpu_op_eor.cpp" -#include "bcpu_op_incdec.cpp" -#include "bcpu_op_lda.cpp" -#include "bcpu_op_misc.cpp" -#include "bcpu_op_ora.cpp" +#include "srtc.cpp" + +#include "bcpu_opfn.cpp" +#include "bcpu_op_read.cpp" +#include "bcpu_op_rmw.cpp" +#include "bcpu_op_write.cpp" #include "bcpu_op_pc.cpp" -#include "bcpu_op_sbc.cpp" -#include "bcpu_op_shift.cpp" -#include "bcpu_op_sta.cpp" -#include "bcpu_op_stack.cpp" +#include "bcpu_op_misc.cpp" + #include "bcpu_exec.cpp" #include "bcpu_mmio.cpp" +#include "bcpu_dma.cpp" + +#include "bcpu_timing.cpp" uint8 bCPU::pio_status() { return status.pio; @@ -24,7 +23,7 @@ uint8 bCPU::pio_status() { *** IRQ *** *********** cycles: - [1] pbr,pc ; io + [1] pbr,pc ; io/opcode [2] pbr,pc ; io [3] 0,s ; pbr [4] 0,s-1 ; pch @@ -34,90 +33,117 @@ cycles: [8] 0,va+1 ; aavh */ void bCPU::irq(uint16 addr) { - if(cpustate == CPUSTATE_WAI) { + if(status.cpu_state == CPUSTATE_WAI) { + status.cpu_state = CPUSTATE_RUN; regs.pc.w++; - cpustate = CPUSTATE_RUN; } - clock->add_cc1_cycles(mem_bus->speed(regs.pc)); //1 - clock->add_cc1_cycles(6); //2 - stack_write(regs.pc.b); //3 - stack_write(regs.pc.h); //4 - stack_write(regs.pc.l); //5 - stack_write(regs.p); //6 - rd.l = op_read(OPMODE_ADDR, addr); //7 - rd.h = op_read(OPMODE_ADDR, addr + 1); //8 +//GTE documentation is incorrect, first cycle +//is a memory read fetch from PBR:PC + add_cycles(mem_bus->speed(regs.pc.d)); + add_cycles(6); + stack_write(regs.pc.b); + stack_write(regs.pc.h); + stack_write(regs.pc.l); + stack_write(regs.p); + rd.l = op_read(OPMODE_ADDR, addr); + rd.h = op_read(OPMODE_ADDR, addr + 1); + regs.pc.b = 0x00; regs.pc.w = rd.w; + regs.p.i = 1; + regs.p.d = 0; - regs.p.d = 0; - regs.p.i = 1; +//let debugger know the new IRQ opcode address + snes->notify(SNES::CPU_EXEC_OPCODE_END); +} - snes->notify(SNES::CPU_EXEC_OPCODE); +bool bCPU::hdma_test() { + if(status.hdma_triggered == false) { + if(vcounter() < (overscan()?239:224) && hcounter() >= 278) { + status.hdma_triggered = true; + return true; + } + } + return false; +} + +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; + } + } + } + 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.virq_enabled == false && status.hirq_enabled == false)return false; + +//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; + if(hpos > 339)return false; + + if(hpos == 0) { + hpos = 24; + } else { + hpos <<= 2; + hpos += 24; //30 - status.cycle_count; + //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) { + hpos -= time.line_cycles; + vpos++; + if(vpos >= time.frame_lines) { + vpos = 0; + } + } + } + + 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; + return true; + } + + return false; } void bCPU::run() { -uint16 v, h, hc, vs; - v = clock->vcounter(); - h = clock->hcounter(); - hc = clock->hcycles(); - vs = clock->visible_scanlines(); - -//HDMA test - if(v < vs && h >= 278) { - if(status.hdma_triggered == false) { - status.hdma_triggered = true; - dma->hdma_run(); - return; - } - } - - switch(cpustate) { + switch(status.cpu_state) { + case CPUSTATE_DMA: + dma_run(); + break; case CPUSTATE_RUN: case CPUSTATE_WAI: - //NMI test - if(v >= (vs + 1) && status.nmi_triggered == false) { - if((v == (vs + 1) && hc >= 12) || (v > (vs + 1))) { - status.nmi_triggered = true; - status.nmi_pin = 0; - if(status.nmi_enabled == true) { - irq(0xffea); - return; - } - } + if(nmi_test() == true) { + irq(0xffea); + break; } - - //IRQ test - if(!regs.p.i) { - if(status.virq_enabled == true && status.hirq_enabled == true) { - if(v == status.virq_pos && h >= status.hirq_pos && status.irq_pin == 1) { - status.irq_triggered = true; - status.irq_pin = 0; - irq(0xffee); - return; - } - } else if(status.virq_enabled == true) { - if(v == status.virq_pos && status.irq_pin == 1) { - status.irq_triggered = true; - status.irq_pin = 0; - irq(0xffee); - return; - } - } else if(status.hirq_enabled == true) { - if(h >= status.hirq_pos && status.irq_pin == 1) { - status.irq_triggered = true; - status.irq_pin = 0; - irq(0xffee); - return; - } - } + if(irq_test() == true) { + irq(0xffee); + break; } - exec_opcode(); break; - case CPUSTATE_DMA: - dma->run(); - break; case CPUSTATE_STP: exec_opcode(); break; @@ -125,62 +151,25 @@ uint16 v, h, hc, vs; } void bCPU::scanline() { -uint16 v = clock->vcounter(); status.hdma_triggered = false; - if(v == 225 && status.auto_joypad_poll == true) { + if(vcounter() == 225 && status.auto_joypad_poll == true) { snes->poll_input(); -//When the SNES auto-polls the joypads, it writes 1, then 0 to -//$4016, then reads from each 16 times to get the joypad state -//information. As a result, the joypad read positions are set -//to 16 after such a poll. Position 16 is the controller -//connected status bit. + //When the SNES auto-polls the joypads, it writes 1, then 0 to + //$4016, then reads from each 16 times to get the joypad state + //information. As a result, the joypad read positions are set + //to 16 after such a poll. Position 16 is the controller + //connected status bit. status.joypad1_read_pos = 16; } + if(status.virq_enabled == false) { status.irq_pin = 1; } } void bCPU::frame() { - status.hdma_triggered = false; - - status.nmi_triggered = false; - status.r4210_read = false; - - status.irq_triggered = false; - status.irq_pin = 1; - - dma->hdma_initialize(); -} - -void bCPU::power() { - regs.a = regs.x = regs.y = 0x0000; - regs.s = 0x01ff; - reset(); -} - -void bCPU::reset() { -/* reset vector location */ - regs.pc = mem_bus->read(0xfffc) | (mem_bus->read(0xfffd) << 8); - -/* registers are not fully reset by SNES */ - regs.x.h = 0x00; - regs.y.h = 0x00; - regs.s.h = 0x01; - regs.d = 0x0000; - regs.db = 0x00; - regs.p = 0x34; - regs.e = 1; - - cpustate = CPUSTATE_RUN; - - dma->reset(); - mmio_reset(); - - optbl = optbl_e; - - status.hdma_triggered = false; + hdma_initialize(); status.nmi_triggered = false; status.nmi_pin = 1; @@ -190,113 +179,164 @@ void bCPU::reset() { status.irq_pin = 1; } +void bCPU::power() { + srtc_power(); + + regs.a = regs.x = regs.y = 0x0000; + regs.s = 0x01ff; + reset(); +} + +void bCPU::reset() { + srtc_reset(); + + frame(); + +//reset vector location + regs.pc = mem_bus->read(0xfffc) | (mem_bus->read(0xfffd) << 8); + +//registers are not fully reset by SNES + regs.x.h = 0x00; + regs.y.h = 0x00; + regs.s.h = 0x01; + regs.d = 0x0000; + regs.db = 0x00; + regs.p = 0x34; + regs.e = 1; + + time_reset(); + mmio_reset(); + dma_reset(); + + status.cpu_state = CPUSTATE_RUN; + + status.hdma_triggered = false; + + status.nmi_triggered = false; + status.nmi_pin = 1; + status.r4210_read = false; + + status.irq_triggered = false; + status.irq_pin = 1; + + apu_port[0] = 0x00; + apu_port[1] = 0x00; + apu_port[2] = 0x00; + apu_port[3] = 0x00; +} + +uint8 bCPU::port_read(uint8 port) { + return apu_port[port & 3]; +} + +void bCPU::port_write(uint8 port, uint8 value) { + apu_port[port & 3] = value; +} + void bCPU::cpu_c2() { if(regs.d.l != 0x00) { - clock->add_cc1_cycles(6); + status.cycle_count = 6; + cycle_edge(); + add_cycles(6); } } -void bCPU::cpu_c4(uint16 a, uint16 b) { - if(((a & 0xff00) != (b & 0xff00)) || !regs.p.x) { - clock->add_cc1_cycles(6); +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); } } -void bCPU::cpu_c6(uint16 a) { - if(regs.e) { - if((regs.pc.w & 0xff00) != (a & 0xff00)) { - clock->add_cc1_cycles(6); - } +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() { - clock->add_cc1_cycles(6); + 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); + add_cycles(status.cycle_count - 2); + return r; +} + +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); +} + +uint32 bCPU::op_addr(uint8 mode, uint32 addr) { + switch(mode) { + case OPMODE_ADDR: + addr &= 0xffff; + break; + case OPMODE_LONG: + addr &= 0xffffff; + break; + case OPMODE_DBR: + addr &= 0xffffff; + addr = (regs.db << 16) + addr; + break; + case OPMODE_PBR: + addr &= 0xffff; + addr = (regs.pc.b << 16) | addr; + break; + case OPMODE_DP: + addr &= 0xffff; + addr = (regs.d + addr) & 0xffff; + break; + case OPMODE_SP: + addr &= 0xffff; + addr = (regs.s + addr) & 0xffff; + break; + } + return addr; } uint8 bCPU::op_read() { uint8 r; - r = mem_bus->read(regs.pc); - clock->add_cc1_cycles(mem_bus->speed(regs.pc)); + r = mem_read(regs.pc.d); regs.pc.w++; return r; } uint8 bCPU::op_read(uint8 mode, uint32 addr) { -uint8 r; - switch(mode) { - case OPMODE_ADDR: - addr &= 0xffff; - break; - case OPMODE_LONG: - addr &= 0xffffff; - break; - case OPMODE_DBR: - addr &= 0xffffff; - addr = (regs.db << 16) + addr; - break; - case OPMODE_PBR: - addr &= 0xffff; - addr = (regs.pc.b << 16) | addr; - break; - case OPMODE_DP: - addr &= 0xffff; - addr = (regs.d + addr) & 0xffff; - break; - case OPMODE_SP: - addr &= 0xffff; - addr = (regs.s + addr) & 0xffff; - break; - } - r = mem_bus->read(addr); - clock->add_cc1_cycles(mem_bus->speed(addr)); - return r; + addr = op_addr(mode, addr); + return mem_read(addr); } void bCPU::op_write(uint8 mode, uint32 addr, uint8 value) { - switch(mode) { - case OPMODE_ADDR: - addr &= 0xffff; - break; - case OPMODE_LONG: - addr &= 0xffffff; - break; - case OPMODE_DBR: - addr &= 0xffffff; - addr = (regs.db << 16) + addr; - break; - case OPMODE_PBR: - addr &= 0xffff; - addr = (regs.pc.b << 16) | addr; - break; - case OPMODE_DP: - addr &= 0xffff; - addr = (regs.d + addr) & 0xffff; - break; - case OPMODE_SP: - addr &= 0xffff; - addr = (regs.s + addr) & 0xffff; - break; - } - mem_bus->write(addr, value); - clock->add_cc1_cycles(mem_bus->speed(addr)); + addr = op_addr(mode, addr); + mem_write(addr, value); } uint8 bCPU::stack_read() { -byte r; if(regs.e) { regs.s.l++; } else { regs.s.w++; } - r = mem_bus->read(regs.s); - clock->add_cc1_cycles(mem_bus->speed(regs.s)); - return r; + return mem_read(regs.s); } void bCPU::stack_write(uint8 value) { - mem_bus->write(regs.s, value); - clock->add_cc1_cycles(mem_bus->speed(regs.s)); + mem_write(regs.s, value); if(regs.e) { regs.s.l--; } else { @@ -305,7 +345,7 @@ void bCPU::stack_write(uint8 value) { } bCPU::bCPU() { - dma = new bDMA(this); + time_init(); mmio = new bCPUMMIO(this); init_op_tables(); @@ -313,5 +353,4 @@ bCPU::bCPU() { bCPU::~bCPU() { delete(mmio); - delete(dma); } diff --git a/src/cpu/bcpu/bcpu.h b/src/cpu/bcpu/bcpu.h index 4570bf8a..c398160d 100644 --- a/src/cpu/bcpu/bcpu.h +++ b/src/cpu/bcpu/bcpu.h @@ -1,79 +1,55 @@ class bCPU; -class bDMA { -public: -bCPU *cpu; -struct { -//$420b - bool active; -//$420c - bool hdma_active; -//$43x0 - bool direction; - bool hdma_indirect; - int8 incmode; - bool fixedxfer; - uint8 xfermode; -//$43x1 - uint8 destaddr; -//$43x2-$43x4 - uint32 srcaddr; -//$43x5-$43x6 - uint16 xfersize; -//$43x7 - uint8 hdma_indirect_bank; - -//hdma-specific - bool hdma_first_line; - bool hdma_repeat; - uint16 hdma_line_counter; - uint32 hdma_address, hdma_iaddress; - bool hdma_completed; -}channel[8]; - void hdma_write(uint8 i, uint8 l, uint8 x); - void hdma_run(); - void hdma_initialize(); - void run(); - void reset(); - uint16 dma_cputommio(uint8 i, uint8 index); - uint16 dma_mmiotocpu(uint8 i, uint8 index); - void dma_xfer_type0(uint8 i); - void dma_xfer_type1(uint8 i); - void dma_xfer_type2(uint8 i); - void dma_xfer_type3(uint8 i); - void dma_xfer_type4(uint8 i); - void dma_xfer_type5(uint8 i); - - bDMA(bCPU *_cpu); -}; - class bCPUMMIO : public MMIO { public: bCPU *cpu; - uint8 read (uint32 addr); - void write(uint32 addr, uint8 value); + inline uint8 read (uint32 addr); + inline void write(uint32 addr, uint8 value); bCPUMMIO(bCPU *_cpu); }; class bCPU : public CPU { private: typedef void (bCPU::*op)(); -op *optbl, optbl_e[256], optbl_MX[256], optbl_Mx[256], optbl_mX[256], optbl_mx[256]; +op optbl[256]; public: -enum { CPUSTATE_RUN = 0, CPUSTATE_DMA, CPUSTATE_WAI, CPUSTATE_STP }; -uint8 cpustate; +#include "srtc.h" +#include "bcpu_timing.h" + +uint8 apu_port[4]; + inline uint8 port_read (uint8 port); + inline void port_write(uint8 port, uint8 value); + +enum { + OPMODE_ADDR = 1, OPMODE_LONG = 2, + OPMODE_DBR = 3, OPMODE_PBR = 4, + OPMODE_DP = 5, OPMODE_SP = 6 +}; -bDMA *dma; - enum { - OPMODE_ADDR = 1, OPMODE_LONG = 2, - OPMODE_DBR = 3, OPMODE_PBR = 4, - OPMODE_DP = 5, OPMODE_SP = 6 - }; CPUReg24 aa, rd; uint8 dp, sp; +enum { + CPUSTATE_RUN = 0, + CPUSTATE_WAI, + CPUSTATE_STP, + CPUSTATE_DMA +}; + +enum { + DMASTATE_STOP = 0, + DMASTATE_INIT, + DMASTATE_DMASYNC, + DMASTATE_RUN, + DMASTATE_CPUSYNC +}; + struct { + uint8 cpu_state, cycle_count; + + uint8 dma_state; + uint32 dma_cycle_count; bool hdma_triggered; bool nmi_triggered; @@ -82,6 +58,7 @@ struct { bool irq_triggered; bool irq_pin; + uint16 virq_trigger, hirq_trigger; //$2181-$2183 uint32 wram_addr; @@ -113,13 +90,66 @@ struct { uint16 r4216; }status; - uint8 pio_status(); - void irq(uint16 addr); - void run(); - void scanline(); - void frame(); - void power(); - void reset(); +struct { +//$420b + bool active; +//$420c + bool hdma_active; +//$43x0 + uint8 dmap; + bool direction; + bool hdma_indirect; + int8 incmode; + bool fixedxfer; + uint8 xfermode; +//$43x1 + uint8 destaddr; +//$43x2-$43x4 + uint32 srcaddr; +//$43x5-$43x6 + uint16 xfersize; +//$43x7 + uint8 hdma_indirect_bank; +//$43x8-$43x9 + uint32 hdma_taddr; +//$43xa + uint8 hdma_line_counter; +//$43xb/$43xf + uint8 hdma_unknown; + +//hdma-specific + bool hdma_first_line; + bool hdma_repeat; + uint32 hdma_itaddr; + bool hdma_completed; +}channel[8]; + + 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(); + +//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 hdma_write(uint8 i, uint8 l, uint8 x); + inline void dma_reset(); //mmio commands void mmio_reset(); @@ -137,6 +167,18 @@ struct { uint8 mmio_r4217(); uint8 mmio_r4218(); uint8 mmio_r4219(); + uint8 mmio_r43x0(uint8 i); + uint8 mmio_r43x1(uint8 i); + uint8 mmio_r43x2(uint8 i); + uint8 mmio_r43x3(uint8 i); + uint8 mmio_r43x4(uint8 i); + uint8 mmio_r43x5(uint8 i); + uint8 mmio_r43x6(uint8 i); + uint8 mmio_r43x7(uint8 i); + uint8 mmio_r43x8(uint8 i); + uint8 mmio_r43x9(uint8 i); + uint8 mmio_r43xa(uint8 i); + uint8 mmio_r43xb(uint8 i); void mmio_w2180(uint8 value); void mmio_w2181(uint8 value); void mmio_w2182(uint8 value); @@ -164,520 +206,76 @@ struct { void mmio_w43x5(uint8 value, uint8 i); void mmio_w43x6(uint8 value, uint8 i); void mmio_w43x7(uint8 value, uint8 i); + void mmio_w43x8(uint8 value, uint8 i); + void mmio_w43x9(uint8 value, uint8 i); + void mmio_w43xa(uint8 value, uint8 i); + void mmio_w43xb(uint8 value, uint8 i); - inline void exec_opcode(); - - inline uint8 op_read (); - inline uint8 op_read (uint8 mode, uint32 addr); - inline void op_write(uint8 mode, uint32 addr, uint8 value); - inline uint8 stack_read (); - inline void stack_write(uint8 value); +enum { CYCLE_OPREAD = 0, CYCLE_READ, CYCLE_WRITE, CYCLE_IO }; + inline void exec_opcode(); + inline void cycle_edge(); //cpu extra-cycle conditions inline void cpu_c2(); - inline void cpu_c4(uint16 a, uint16 b); - inline void cpu_c6(uint16 a); + inline void cpu_c4(uint16 x, uint16 y); + inline void cpu_c6(uint16 addr); inline void cpu_io(); -//opcode functions - void init_op_tables(); + inline uint8 mem_read (uint32 addr); + inline void mem_write(uint32 addr, uint8 value); + inline uint32 op_addr(uint8 mode, uint32 addr); + inline uint8 op_read(); + inline uint8 op_read(uint8 mode, uint32 addr); + inline void op_write(uint8 mode, uint32 addr, uint8 value); + inline uint8 stack_read(); + inline void stack_write(uint8 value); -//op_adc - inline void flags_adc_b(); - inline void flags_adc_w(); - void op_adc_constb(); - void op_adc_constw(); - void op_adc_addrb(); - void op_adc_addrw(); - void op_adc_addrxb(); - void op_adc_addrxw(); - void op_adc_dpb(); - void op_adc_dpw(); - void op_adc_idpb(); - void op_adc_idpw(); - void op_adc_ildpb(); - void op_adc_ildpw(); - void op_adc_longb(); - void op_adc_longw(); - void op_adc_longxb(); - void op_adc_longxw(); - void op_adc_addryb(); - void op_adc_addryw(); - void op_adc_dpxb(); - void op_adc_dpxw(); - void op_adc_idpxb(); - void op_adc_idpxw(); - void op_adc_idpyb(); - void op_adc_idpyw(); - void op_adc_ildpyb(); - void op_adc_ildpyw(); - void op_adc_srb(); - void op_adc_srw(); - void op_adc_isryb(); - void op_adc_isryw(); -//op_and - inline void flags_and_b(); - inline void flags_and_w(); - void op_and_constb(); - void op_and_constw(); - void op_and_addrb(); - void op_and_addrw(); - void op_and_addrxb(); - void op_and_addrxw(); - void op_and_dpb(); - void op_and_dpw(); - void op_and_idpb(); - void op_and_idpw(); - void op_and_ildpb(); - void op_and_ildpw(); - void op_and_longb(); - void op_and_longw(); - void op_and_longxb(); - void op_and_longxw(); - void op_and_addryb(); - void op_and_addryw(); - void op_and_dpxb(); - void op_and_dpxw(); - void op_and_idpxb(); - void op_and_idpxw(); - void op_and_idpyb(); - void op_and_idpyw(); - void op_and_ildpyb(); - void op_and_ildpyw(); - void op_and_srb(); - void op_and_srw(); - void op_and_isryb(); - void op_and_isryw(); -//op_cmp - inline void flags_cmp_b(); - inline void flags_cmp_w(); - void op_cmp_constb(); - void op_cmp_constw(); - void op_cmp_addrb(); - void op_cmp_addrw(); - void op_cmp_addrxb(); - void op_cmp_addrxw(); - void op_cmp_dpb(); - void op_cmp_dpw(); - void op_cmp_idpb(); - void op_cmp_idpw(); - void op_cmp_ildpb(); - void op_cmp_ildpw(); - void op_cmp_longb(); - void op_cmp_longw(); - void op_cmp_longxb(); - void op_cmp_longxw(); - void op_cmp_addryb(); - void op_cmp_addryw(); - void op_cmp_dpxb(); - void op_cmp_dpxw(); - void op_cmp_idpxb(); - void op_cmp_idpxw(); - void op_cmp_idpyb(); - void op_cmp_idpyw(); - void op_cmp_ildpyb(); - void op_cmp_ildpyw(); - void op_cmp_srb(); - void op_cmp_srw(); - void op_cmp_isryb(); - void op_cmp_isryw(); -//op_eor - inline void flags_eor_b(); - inline void flags_eor_w(); - void op_eor_constb(); - void op_eor_constw(); - void op_eor_addrb(); - void op_eor_addrw(); - void op_eor_addrxb(); - void op_eor_addrxw(); - void op_eor_dpb(); - void op_eor_dpw(); - void op_eor_idpb(); - void op_eor_idpw(); - void op_eor_ildpb(); - void op_eor_ildpw(); - void op_eor_longb(); - void op_eor_longw(); - void op_eor_longxb(); - void op_eor_longxw(); - void op_eor_addryb(); - void op_eor_addryw(); - void op_eor_dpxb(); - void op_eor_dpxw(); - void op_eor_idpxb(); - void op_eor_idpxw(); - void op_eor_idpyb(); - void op_eor_idpyw(); - void op_eor_ildpyb(); - void op_eor_ildpyw(); - void op_eor_srb(); - void op_eor_srw(); - void op_eor_isryb(); - void op_eor_isryw(); -//op_incdec - void op_incb(); - void op_incw(); - void op_inc_addrb(); - void op_inc_addrw(); - void op_inc_addrxb(); - void op_inc_addrxw(); - void op_inc_dpb(); - void op_inc_dpw(); - void op_inc_dpxb(); - void op_inc_dpxw(); - void op_inxb(); - void op_inxw(); - void op_inyb(); - void op_inyw(); - void op_decb(); - void op_decw(); - void op_dec_addrb(); - void op_dec_addrw(); - void op_dec_addrxb(); - void op_dec_addrxw(); - void op_dec_dpb(); - void op_dec_dpw(); - void op_dec_dpxb(); - void op_dec_dpxw(); - void op_dexb(); - void op_dexw(); - void op_deyb(); - void op_deyw(); -//op_lda - inline void flags_lda_b(); - inline void flags_lda_w(); - void op_lda_constb(); - void op_lda_constw(); - void op_lda_addrb(); - void op_lda_addrw(); - void op_lda_addrxb(); - void op_lda_addrxw(); - void op_lda_dpb(); - void op_lda_dpw(); - void op_lda_idpb(); - void op_lda_idpw(); - void op_lda_ildpb(); - void op_lda_ildpw(); - void op_lda_longb(); - void op_lda_longw(); - void op_lda_longxb(); - void op_lda_longxw(); - void op_lda_addryb(); - void op_lda_addryw(); - void op_lda_dpxb(); - void op_lda_dpxw(); - void op_lda_idpxb(); - void op_lda_idpxw(); - void op_lda_idpyb(); - void op_lda_idpyw(); - void op_lda_ildpyb(); - void op_lda_ildpyw(); - void op_lda_srb(); - void op_lda_srw(); - void op_lda_isryb(); - void op_lda_isryw(); -//op_misc - inline void flags_bit_b(); - inline void flags_bit_w(); - void op_bit_constb(); - void op_bit_constw(); - void op_bit_addrb(); - void op_bit_addrw(); - void op_bit_addrxb(); - void op_bit_addrxw(); - void op_bit_dpb(); - void op_bit_dpw(); - void op_bit_dpxb(); - void op_bit_dpxw(); - inline void flags_cpx_b(); - inline void flags_cpx_w(); - void op_cpx_constb(); - void op_cpx_constw(); - void op_cpx_addrb(); - void op_cpx_addrw(); - void op_cpx_dpb(); - void op_cpx_dpw(); - inline void flags_cpy_b(); - inline void flags_cpy_w(); - void op_cpy_constb(); - void op_cpy_constw(); - void op_cpy_addrb(); - void op_cpy_addrw(); - void op_cpy_dpb(); - void op_cpy_dpw(); - inline void flags_ldx_b(); - inline void flags_ldx_w(); - void op_ldx_constb(); - void op_ldx_constw(); - void op_ldx_addrb(); - void op_ldx_addrw(); - void op_ldx_addryb(); - void op_ldx_addryw(); - void op_ldx_dpb(); - void op_ldx_dpw(); - void op_ldx_dpyb(); - void op_ldx_dpyw(); - inline void flags_ldy_b(); - inline void flags_ldy_w(); - void op_ldy_constb(); - void op_ldy_constw(); - void op_ldy_addrb(); - void op_ldy_addrw(); - void op_ldy_addrxb(); - void op_ldy_addrxw(); - void op_ldy_dpb(); - void op_ldy_dpw(); - void op_ldy_dpxb(); - void op_ldy_dpxw(); - void op_stx_addrb(); - void op_stx_addrw(); - void op_stx_dpb(); - void op_stx_dpw(); - void op_stx_dpyb(); - void op_stx_dpyw(); - void op_sty_addrb(); - void op_sty_addrw(); - void op_sty_dpb(); - void op_sty_dpw(); - void op_sty_dpxb(); - void op_sty_dpxw(); - void op_stz_addrb(); - void op_stz_addrw(); - void op_stz_addrxb(); - void op_stz_addrxw(); - void op_stz_dpb(); - void op_stz_dpw(); - void op_stz_dpxb(); - void op_stz_dpxw(); - void op_xba(); - void op_trb_addrb(); - void op_trb_addrw(); - void op_trb_dpb(); - void op_trb_dpw(); - void op_tsb_addrb(); - void op_tsb_addrw(); - void op_tsb_dpb(); - void op_tsb_dpw(); - void op_mvn(); - void op_mvp(); - void op_brk(); - void op_cop(); - void op_stp(); - void op_wai(); - void op_xce(); - void op_nop(); - void op_wdm(); - void op_clc(); - void op_cld(); - void op_cli(); - void op_clv(); - void op_sec(); - void op_sed(); - void op_sei(); - void op_rep(); - void op_sep(); - void op_taxb(); - void op_taxw(); - void op_tayb(); - void op_tayw(); - void op_tcd(); - void op_tcs(); - void op_tdc(); - void op_tsc(); - void op_tsxb(); - void op_tsxw(); - void op_txab(); - void op_txaw(); - void op_txsb(); - void op_txsw(); - void op_txyb(); - void op_txyw(); - void op_tyab(); - void op_tyaw(); - void op_tyxb(); - void op_tyxw(); -//op_ora - inline void flags_ora_b(); - inline void flags_ora_w(); - void op_ora_constb(); - void op_ora_constw(); - void op_ora_addrb(); - void op_ora_addrw(); - void op_ora_addrxb(); - void op_ora_addrxw(); - void op_ora_dpb(); - void op_ora_dpw(); - void op_ora_idpb(); - void op_ora_idpw(); - void op_ora_ildpb(); - void op_ora_ildpw(); - void op_ora_longb(); - void op_ora_longw(); - void op_ora_longxb(); - void op_ora_longxw(); - void op_ora_addryb(); - void op_ora_addryw(); - void op_ora_dpxb(); - void op_ora_dpxw(); - void op_ora_idpxb(); - void op_ora_idpxw(); - void op_ora_idpyb(); - void op_ora_idpyw(); - void op_ora_ildpyb(); - void op_ora_ildpyw(); - void op_ora_srb(); - void op_ora_srw(); - void op_ora_isryb(); - void op_ora_isryw(); -//op_pc - void op_jmp_addr(); - void op_jmp_long(); - void op_jmp_iaddr(); - void op_jmp_iaddrx(); - void op_jmp_iladdr(); - void op_jsr_addr(); - void op_jsr_long(); - void op_jsr_iaddrx(); - void op_rtie(); - void op_rtin(); - void op_rts(); - void op_rtl(); - void op_bra(); - void op_brl(); - void op_bcc(); - void op_bcs(); - void op_bne(); - void op_beq(); - void op_bpl(); - void op_bmi(); - void op_bvc(); - void op_bvs(); -//op_sbc - inline void flags_sbc_b(); - inline void flags_sbc_w(); - void op_sbc_constb(); - void op_sbc_constw(); - void op_sbc_addrb(); - void op_sbc_addrw(); - void op_sbc_addrxb(); - void op_sbc_addrxw(); - void op_sbc_dpb(); - void op_sbc_dpw(); - void op_sbc_idpb(); - void op_sbc_idpw(); - void op_sbc_ildpb(); - void op_sbc_ildpw(); - void op_sbc_longb(); - void op_sbc_longw(); - void op_sbc_longxb(); - void op_sbc_longxw(); - void op_sbc_addryb(); - void op_sbc_addryw(); - void op_sbc_dpxb(); - void op_sbc_dpxw(); - void op_sbc_idpxb(); - void op_sbc_idpxw(); - void op_sbc_idpyb(); - void op_sbc_idpyw(); - void op_sbc_ildpyb(); - void op_sbc_ildpyw(); - void op_sbc_srb(); - void op_sbc_srw(); - void op_sbc_isryb(); - void op_sbc_isryw(); -//op_shift - void op_aslb(); - void op_aslw(); - void op_asl_addrb(); - void op_asl_addrw(); - void op_asl_addrxb(); - void op_asl_addrxw(); - void op_asl_dpb(); - void op_asl_dpw(); - void op_asl_dpxb(); - void op_asl_dpxw(); - void op_lsrb(); - void op_lsrw(); - void op_lsr_addrb(); - void op_lsr_addrw(); - void op_lsr_addrxb(); - void op_lsr_addrxw(); - void op_lsr_dpb(); - void op_lsr_dpw(); - void op_lsr_dpxb(); - void op_lsr_dpxw(); - void op_rolb(); - void op_rolw(); - void op_rol_addrb(); - void op_rol_addrw(); - void op_rol_addrxb(); - void op_rol_addrxw(); - void op_rol_dpb(); - void op_rol_dpw(); - void op_rol_dpxb(); - void op_rol_dpxw(); - void op_rorb(); - void op_rorw(); - void op_ror_addrb(); - void op_ror_addrw(); - void op_ror_addrxb(); - void op_ror_addrxw(); - void op_ror_dpb(); - void op_ror_dpw(); - void op_ror_dpxb(); - void op_ror_dpxw(); -//op_sta - void op_sta_addrb(); - void op_sta_addrw(); - void op_sta_addrxb(); - void op_sta_addrxw(); - void op_sta_dpb(); - void op_sta_dpw(); - void op_sta_idpb(); - void op_sta_idpw(); - void op_sta_ildpb(); - void op_sta_ildpw(); - void op_sta_longb(); - void op_sta_longw(); - void op_sta_longxb(); - void op_sta_longxw(); - void op_sta_addryb(); - void op_sta_addryw(); - void op_sta_dpxb(); - void op_sta_dpxw(); - void op_sta_idpxb(); - void op_sta_idpxw(); - void op_sta_idpyb(); - void op_sta_idpyw(); - void op_sta_ildpyb(); - void op_sta_ildpyw(); - void op_sta_srb(); - void op_sta_srw(); - void op_sta_isryb(); - void op_sta_isryw(); -//op_stack - void op_phab(); - void op_phaw(); - void op_phb(); - void op_phd(); - void op_phk(); - void op_php(); - void op_phxb(); - void op_phxw(); - void op_phyb(); - void op_phyw(); - void op_plab(); - void op_plaw(); - void op_plb(); - void op_pld(); - void op_plp(); - void op_plxb(); - void op_plxw(); - void op_plyb(); - void op_plyw(); - void op_pea(); - void op_pei(); - void op_per(); +//opcode functions + inline void init_op_tables(); + +//op_read + inline void op_adc_b(); + inline void op_adc_w(); + inline void op_and_b(); + inline void op_and_w(); + inline void op_bit_b(); + inline void op_bit_w(); + inline void op_cmp_b(); + inline void op_cmp_w(); + inline void op_cpx_b(); + inline void op_cpx_w(); + inline void op_cpy_b(); + inline void op_cpy_w(); + inline void op_eor_b(); + inline void op_eor_w(); + inline void op_lda_b(); + inline void op_lda_w(); + inline void op_ldx_b(); + inline void op_ldx_w(); + inline void op_ldy_b(); + inline void op_ldy_w(); + inline void op_ora_b(); + inline void op_ora_w(); + inline void op_sbc_b(); + inline void op_sbc_w(); +//op_rmw + inline void op_inc_b(); + inline void op_inc_w(); + inline void op_dec_b(); + inline void op_dec_w(); + inline void op_asl_b(); + inline void op_asl_w(); + inline void op_lsr_b(); + inline void op_lsr_w(); + inline void op_rol_b(); + inline void op_rol_w(); + inline void op_ror_b(); + inline void op_ror_w(); + inline void op_trb_b(); + inline void op_trb_w(); + inline void op_tsb_b(); + inline void op_tsb_w(); +#include "bcpu_op.h" bCPU(); ~bCPU(); diff --git a/src/cpu/bcpu/bcpu_dma.cpp b/src/cpu/bcpu/bcpu_dma.cpp new file mode 100644 index 00000000..56957dcb --- /dev/null +++ b/src/cpu/bcpu/bcpu_dma.cpp @@ -0,0 +1,241 @@ +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; +} + +uint16 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); + 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; +} + +void bCPU::dma_xfer_type0(uint8 i) { + if(channel[i].direction == 0) { + if(dma_cputommio(i, 0) == 0)return; + } 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; + } +} + +void bCPU::dma_run() { +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; + } + + if(channel[i].xfersize == 0) { + channel[i].active = false; + } + + return; + } + + status.dma_state = DMASTATE_CPUSYNC; +} + +void bCPU::hdma_write(uint8 i, uint8 l, uint8 x) { + 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; + } +} + +void bCPU::hdma_run() { +int l, xferlen; +uint8 x, active_channels = 0; + for(int i=0;i<8;i++) { + if(channel[i].hdma_completed == true)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++); + if(channel[i].hdma_line_counter == 0) { + channel[i].hdma_completed = true; + continue; + } + + if(channel[i].hdma_line_counter > 0x80) { + channel[i].hdma_repeat = true; + channel[i].hdma_line_counter -= 0x80; + } else { + channel[i].hdma_repeat = false; + } + + 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); + } + } + + channel[i].hdma_line_counter--; + 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; + } + + for(l=0;lread(channel[i].hdma_itaddr++); + if(channel[i].hdma_indirect == false) { + channel[i].hdma_taddr++; + } + hdma_write(i, l, x); +// add_cycles(8); + } + } + + if(active_channels != 0) { +// 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; + continue; + } + 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 { + add_cycles(24); + } + } + + if(active_channels != 0) { + add_cycles(18); + } +} + +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].hdma_first_line = false; + channel[i].hdma_repeat = false; + channel[i].hdma_itaddr = 0x000000; + channel[i].hdma_completed = true; + } +} diff --git a/src/cpu/bcpu/bcpu_exec.cpp b/src/cpu/bcpu/bcpu_exec.cpp index b809ce03..0ddebc2c 100644 --- a/src/cpu/bcpu/bcpu_exec.cpp +++ b/src/cpu/bcpu/bcpu_exec.cpp @@ -1,519 +1,42 @@ +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: + n = 8 - dma_counter() + 8; + add_cycles(n); + status.dma_cycle_count = n; + for(z=0;z<8;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(); + } + status.cpu_state = CPUSTATE_RUN; + c = status.cycle_count; + z = c - (status.dma_cycle_count % c); + if(!z)z = c; + add_cycles(z); + status.dma_state = DMASTATE_STOP; + break; + } + } +} + void bCPU::exec_opcode() { + snes->notify(SNES::CPU_EXEC_OPCODE_BEGIN); (this->*optbl[op_read()])(); - snes->notify(SNES::CPU_EXEC_OPCODE); + snes->notify(SNES::CPU_EXEC_OPCODE_END); } void bCPU::init_op_tables() { - optbl = optbl_e; - -/* 0x */ - optbl[0x00] = op_brk; - optbl[0x01] = op_ora_idpxb; - optbl[0x02] = op_cop; - optbl[0x03] = op_ora_srb; - optbl[0x04] = op_tsb_dpb; - optbl[0x05] = op_ora_dpb; - optbl[0x06] = op_asl_dpb; - optbl[0x07] = op_ora_ildpb; - optbl[0x08] = op_php; - optbl[0x09] = op_ora_constb; - optbl[0x0a] = op_aslb; - optbl[0x0b] = op_phd; - optbl[0x0c] = op_tsb_addrb; - optbl[0x0d] = op_ora_addrb; - optbl[0x0e] = op_asl_addrb; - optbl[0x0f] = op_ora_longb; -/* 1x */ - optbl[0x10] = op_bpl; - optbl[0x11] = op_ora_idpyb; - optbl[0x12] = op_ora_idpb; - optbl[0x13] = op_ora_isryb; - optbl[0x14] = op_trb_dpb; - optbl[0x15] = op_ora_dpxb; - optbl[0x16] = op_asl_dpxb; - optbl[0x17] = op_ora_ildpyb; - optbl[0x18] = op_clc; - optbl[0x19] = op_ora_addryb; - optbl[0x1a] = op_incb; - optbl[0x1b] = op_tcs; - optbl[0x1c] = op_trb_addrb; - optbl[0x1d] = op_ora_addrxb; - optbl[0x1e] = op_asl_addrxb; - optbl[0x1f] = op_ora_longxb; -/* 2x */ - optbl[0x20] = op_jsr_addr; - optbl[0x21] = op_and_idpxb; - optbl[0x22] = op_jsr_long; - optbl[0x23] = op_and_srb; - optbl[0x24] = op_bit_dpb; - optbl[0x25] = op_and_dpb; - optbl[0x26] = op_rol_dpb; - optbl[0x27] = op_and_ildpb; - optbl[0x28] = op_plp; - optbl[0x29] = op_and_constb; - optbl[0x2a] = op_rolb; - optbl[0x2b] = op_pld; - optbl[0x2c] = op_bit_addrb; - optbl[0x2d] = op_and_addrb; - optbl[0x2e] = op_rol_addrb; - optbl[0x2f] = op_and_longb; -/* 3x */ - optbl[0x30] = op_bmi; - optbl[0x31] = op_and_idpyb; - optbl[0x32] = op_and_idpb; - optbl[0x33] = op_and_isryb; - optbl[0x34] = op_bit_dpxb; - optbl[0x35] = op_and_dpxb; - optbl[0x36] = op_rol_dpxb; - optbl[0x37] = op_and_ildpyb; - optbl[0x38] = op_sec; - optbl[0x39] = op_and_addryb; - optbl[0x3a] = op_decb; - optbl[0x3b] = op_tsc; - optbl[0x3c] = op_bit_addrxb; - optbl[0x3d] = op_and_addrxb; - optbl[0x3e] = op_rol_addrxb; - optbl[0x3f] = op_and_longxb; -/* 4x */ - optbl[0x40] = op_rtie; - optbl[0x41] = op_eor_idpxb; - optbl[0x42] = op_wdm; - optbl[0x43] = op_eor_srb; - optbl[0x44] = op_mvp; - optbl[0x45] = op_eor_dpb; - optbl[0x46] = op_lsr_dpb; - optbl[0x47] = op_eor_ildpb; - optbl[0x48] = op_phab; - optbl[0x49] = op_eor_constb; - optbl[0x4a] = op_lsrb; - optbl[0x4b] = op_phk; - optbl[0x4c] = op_jmp_addr; - optbl[0x4d] = op_eor_addrb; - optbl[0x4e] = op_lsr_addrb; - optbl[0x4f] = op_eor_longb; -/* 5x */ - optbl[0x50] = op_bvc; - optbl[0x51] = op_eor_idpyb; - optbl[0x52] = op_eor_idpb; - optbl[0x53] = op_eor_isryb; - optbl[0x54] = op_mvn; - optbl[0x55] = op_eor_dpxb; - optbl[0x56] = op_lsr_dpxb; - optbl[0x57] = op_eor_ildpyb; - optbl[0x58] = op_cli; - optbl[0x59] = op_eor_addryb; - optbl[0x5a] = op_phyb; - optbl[0x5b] = op_tcd; - optbl[0x5c] = op_jmp_long; - optbl[0x5d] = op_eor_addrxb; - optbl[0x5e] = op_lsr_addrxb; - optbl[0x5f] = op_eor_longxb; -/* 6x */ - optbl[0x60] = op_rts; - optbl[0x61] = op_adc_idpxb; - optbl[0x62] = op_per; - optbl[0x63] = op_adc_srb; - optbl[0x64] = op_stz_dpb; - optbl[0x65] = op_adc_dpb; - optbl[0x66] = op_ror_dpb; - optbl[0x67] = op_adc_ildpb; - optbl[0x68] = op_plab; - optbl[0x69] = op_adc_constb; - optbl[0x6a] = op_rorb; - optbl[0x6b] = op_rtl; - optbl[0x6c] = op_jmp_iaddr; - optbl[0x6d] = op_adc_addrb; - optbl[0x6e] = op_ror_addrb; - optbl[0x6f] = op_adc_longb; -/* 7x */ - optbl[0x70] = op_bvs; - optbl[0x71] = op_adc_idpyb; - optbl[0x72] = op_adc_idpb; - optbl[0x73] = op_adc_isryb; - optbl[0x74] = op_stz_dpxb; - optbl[0x75] = op_adc_dpxb; - optbl[0x76] = op_ror_dpxb; - optbl[0x77] = op_adc_ildpyb; - optbl[0x78] = op_sei; - optbl[0x79] = op_adc_addryb; - optbl[0x7a] = op_plyb; - optbl[0x7b] = op_tdc; - optbl[0x7c] = op_jmp_iaddrx; - optbl[0x7d] = op_adc_addrxb; - optbl[0x7e] = op_ror_addrxb; - optbl[0x7f] = op_adc_longxb; -/* 8x */ - optbl[0x80] = op_bra; - optbl[0x81] = op_sta_idpxb; - optbl[0x82] = op_brl; - optbl[0x83] = op_sta_srb; - optbl[0x84] = op_sty_dpb; - optbl[0x85] = op_sta_dpb; - optbl[0x86] = op_stx_dpb; - optbl[0x87] = op_sta_ildpb; - optbl[0x88] = op_deyb; - optbl[0x89] = op_bit_constb; - optbl[0x8a] = op_txab; - optbl[0x8b] = op_phb; - optbl[0x8c] = op_sty_addrb; - optbl[0x8d] = op_sta_addrb; - optbl[0x8e] = op_stx_addrb; - optbl[0x8f] = op_sta_longb; -/* 9x */ - optbl[0x90] = op_bcc; - optbl[0x91] = op_sta_idpyb; - optbl[0x92] = op_sta_idpb; - optbl[0x93] = op_sta_isryb; - optbl[0x94] = op_sty_dpxb; - optbl[0x95] = op_sta_dpxb; - optbl[0x96] = op_stx_dpyb; - optbl[0x97] = op_sta_ildpyb; - optbl[0x98] = op_tyab; - optbl[0x99] = op_sta_addryb; - optbl[0x9a] = op_txsb; - optbl[0x9b] = op_txyb; - optbl[0x9c] = op_stz_addrb; - optbl[0x9d] = op_sta_addrxb; - optbl[0x9e] = op_stz_addrxb; - optbl[0x9f] = op_sta_longxb; -/* ax */ - optbl[0xa0] = op_ldy_constb; - optbl[0xa1] = op_lda_idpxb; - optbl[0xa2] = op_ldx_constb; - optbl[0xa3] = op_lda_srb; - optbl[0xa4] = op_ldy_dpb; - optbl[0xa5] = op_lda_dpb; - optbl[0xa6] = op_ldx_dpb; - optbl[0xa7] = op_lda_ildpb; - optbl[0xa8] = op_tayb; - optbl[0xa9] = op_lda_constb; - optbl[0xaa] = op_taxb; - optbl[0xab] = op_plb; - optbl[0xac] = op_ldy_addrb; - optbl[0xad] = op_lda_addrb; - optbl[0xae] = op_ldx_addrb; - optbl[0xaf] = op_lda_longb; -/* bx */ - optbl[0xb0] = op_bcs; - optbl[0xb1] = op_lda_idpyb; - optbl[0xb2] = op_lda_idpb; - optbl[0xb3] = op_lda_isryb; - optbl[0xb4] = op_ldy_dpxb; - optbl[0xb5] = op_lda_dpxb; - optbl[0xb6] = op_ldx_dpyb; - optbl[0xb7] = op_lda_ildpyb; - optbl[0xb8] = op_clv; - optbl[0xb9] = op_lda_addryb; - optbl[0xba] = op_tsxb; - optbl[0xbb] = op_tyxb; - optbl[0xbc] = op_ldy_addrxb; - optbl[0xbd] = op_lda_addrxb; - optbl[0xbe] = op_ldx_addryb; - optbl[0xbf] = op_lda_longxb; -/* cx */ - optbl[0xc0] = op_cpy_constb; - optbl[0xc1] = op_cmp_idpxb; - optbl[0xc2] = op_rep; - optbl[0xc3] = op_cmp_srb; - optbl[0xc4] = op_cpy_dpb; - optbl[0xc5] = op_cmp_dpb; - optbl[0xc6] = op_dec_dpb; - optbl[0xc7] = op_cmp_ildpb; - optbl[0xc8] = op_inyb; - optbl[0xc9] = op_cmp_constb; - optbl[0xca] = op_dexb; - optbl[0xcb] = op_wai; - optbl[0xcc] = op_cpy_addrb; - optbl[0xcd] = op_cmp_addrb; - optbl[0xce] = op_dec_addrb; - optbl[0xcf] = op_cmp_longb; -/* dx */ - optbl[0xd0] = op_bne; - optbl[0xd1] = op_cmp_idpyb; - optbl[0xd2] = op_cmp_idpb; - optbl[0xd3] = op_cmp_isryb; - optbl[0xd4] = op_pei; - optbl[0xd5] = op_cmp_dpxb; - optbl[0xd6] = op_dec_dpxb; - optbl[0xd7] = op_cmp_ildpyb; - optbl[0xd8] = op_cld; - optbl[0xd9] = op_cmp_addryb; - optbl[0xda] = op_phxb; - optbl[0xdb] = op_stp; - optbl[0xdc] = op_jmp_iladdr; - optbl[0xdd] = op_cmp_addrxb; - optbl[0xde] = op_dec_addrxb; - optbl[0xdf] = op_cmp_longxb; -/* ex */ - optbl[0xe0] = op_cpx_constb; - optbl[0xe1] = op_sbc_idpxb; - optbl[0xe2] = op_sep; - optbl[0xe3] = op_sbc_srb; - optbl[0xe4] = op_cpx_dpb; - optbl[0xe5] = op_sbc_dpb; - optbl[0xe6] = op_inc_dpb; - optbl[0xe7] = op_sbc_ildpb; - optbl[0xe8] = op_inxb; - optbl[0xe9] = op_sbc_constb; - optbl[0xea] = op_nop; - optbl[0xeb] = op_xba; - optbl[0xec] = op_cpx_addrb; - optbl[0xed] = op_sbc_addrb; - optbl[0xee] = op_inc_addrb; - optbl[0xef] = op_sbc_longb; -/* fx */ - optbl[0xf0] = op_beq; - optbl[0xf1] = op_sbc_idpyb; - optbl[0xf2] = op_sbc_idpb; - optbl[0xf3] = op_sbc_isryb; - optbl[0xf4] = op_pea; - optbl[0xf5] = op_sbc_dpxb; - optbl[0xf6] = op_inc_dpxb; - optbl[0xf7] = op_sbc_ildpyb; - optbl[0xf8] = op_sed; - optbl[0xf9] = op_sbc_addryb; - optbl[0xfa] = op_plxb; - optbl[0xfb] = op_xce; - optbl[0xfc] = op_jsr_iaddrx; - optbl[0xfd] = op_sbc_addrxb; - optbl[0xfe] = op_inc_addrxb; - optbl[0xff] = op_sbc_longxb; - - memcpy(optbl_MX, optbl_e, sizeof(optbl_e)); - memcpy(optbl_Mx, optbl_e, sizeof(optbl_e)); - memcpy(optbl_mX, optbl_e, sizeof(optbl_e)); - memcpy(optbl_mx, optbl_e, sizeof(optbl_e)); - -/* adc */ - optbl_mX[0x69] = optbl_mx[0x69] = op_adc_constw; - optbl_mX[0x6d] = optbl_mx[0x6d] = op_adc_addrw; - optbl_mX[0x7d] = optbl_mx[0x7d] = op_adc_addrxw; - optbl_mX[0x65] = optbl_mx[0x65] = op_adc_dpw; - optbl_mX[0x72] = optbl_mx[0x72] = op_adc_idpw; - optbl_mX[0x67] = optbl_mx[0x67] = op_adc_ildpw; - optbl_mX[0x6f] = optbl_mx[0x6f] = op_adc_longw; - optbl_mX[0x7f] = optbl_mx[0x7f] = op_adc_longxw; - optbl_mX[0x79] = optbl_mx[0x79] = op_adc_addryw; - optbl_mX[0x75] = optbl_mx[0x75] = op_adc_dpxw; - optbl_mX[0x61] = optbl_mx[0x61] = op_adc_idpxw; - optbl_mX[0x71] = optbl_mx[0x71] = op_adc_idpyw; - optbl_mX[0x77] = optbl_mx[0x77] = op_adc_ildpyw; - optbl_mX[0x63] = optbl_mx[0x63] = op_adc_srw; - optbl_mX[0x73] = optbl_mx[0x73] = op_adc_isryw; - -/* and */ - optbl_mX[0x29] = optbl_mx[0x29] = op_and_constw; - optbl_mX[0x2d] = optbl_mx[0x2d] = op_and_addrw; - optbl_mX[0x3d] = optbl_mx[0x3d] = op_and_addrxw; - optbl_mX[0x25] = optbl_mx[0x25] = op_and_dpw; - optbl_mX[0x32] = optbl_mx[0x32] = op_and_idpw; - optbl_mX[0x27] = optbl_mx[0x27] = op_and_ildpw; - optbl_mX[0x2f] = optbl_mx[0x2f] = op_and_longw; - optbl_mX[0x3f] = optbl_mx[0x3f] = op_and_longxw; - optbl_mX[0x39] = optbl_mx[0x39] = op_and_addryw; - optbl_mX[0x35] = optbl_mx[0x35] = op_and_dpxw; - optbl_mX[0x21] = optbl_mx[0x21] = op_and_idpxw; - optbl_mX[0x31] = optbl_mx[0x31] = op_and_idpyw; - optbl_mX[0x37] = optbl_mx[0x37] = op_and_ildpyw; - optbl_mX[0x23] = optbl_mx[0x23] = op_and_srw; - optbl_mX[0x33] = optbl_mx[0x33] = op_and_isryw; - -/* cmp */ - optbl_mX[0xc9] = optbl_mx[0xc9] = op_cmp_constw; - optbl_mX[0xcd] = optbl_mx[0xcd] = op_cmp_addrw; - optbl_mX[0xdd] = optbl_mx[0xdd] = op_cmp_addrxw; - optbl_mX[0xc5] = optbl_mx[0xc5] = op_cmp_dpw; - optbl_mX[0xd2] = optbl_mx[0xd2] = op_cmp_idpw; - optbl_mX[0xc7] = optbl_mx[0xc7] = op_cmp_ildpw; - optbl_mX[0xcf] = optbl_mx[0xcf] = op_cmp_longw; - optbl_mX[0xdf] = optbl_mx[0xdf] = op_cmp_longxw; - optbl_mX[0xd9] = optbl_mx[0xd9] = op_cmp_addryw; - optbl_mX[0xd5] = optbl_mx[0xd5] = op_cmp_dpxw; - optbl_mX[0xc1] = optbl_mx[0xc1] = op_cmp_idpxw; - optbl_mX[0xd1] = optbl_mx[0xd1] = op_cmp_idpyw; - optbl_mX[0xd7] = optbl_mx[0xd7] = op_cmp_ildpyw; - optbl_mX[0xc3] = optbl_mx[0xc3] = op_cmp_srw; - optbl_mX[0xd3] = optbl_mx[0xd3] = op_cmp_isryw; - -/* eor */ - optbl_mX[0x49] = optbl_mx[0x49] = op_eor_constw; - optbl_mX[0x4d] = optbl_mx[0x4d] = op_eor_addrw; - optbl_mX[0x5d] = optbl_mx[0x5d] = op_eor_addrxw; - optbl_mX[0x45] = optbl_mx[0x45] = op_eor_dpw; - optbl_mX[0x52] = optbl_mx[0x52] = op_eor_idpw; - optbl_mX[0x47] = optbl_mx[0x47] = op_eor_ildpw; - optbl_mX[0x4f] = optbl_mx[0x4f] = op_eor_longw; - optbl_mX[0x5f] = optbl_mx[0x5f] = op_eor_longxw; - optbl_mX[0x59] = optbl_mx[0x59] = op_eor_addryw; - optbl_mX[0x55] = optbl_mx[0x55] = op_eor_dpxw; - optbl_mX[0x41] = optbl_mx[0x41] = op_eor_idpxw; - optbl_mX[0x51] = optbl_mx[0x51] = op_eor_idpyw; - optbl_mX[0x57] = optbl_mx[0x57] = op_eor_ildpyw; - optbl_mX[0x43] = optbl_mx[0x43] = op_eor_srw; - optbl_mX[0x53] = optbl_mx[0x53] = op_eor_isryw; - -/* lda */ - optbl_mX[0xa9] = optbl_mx[0xa9] = op_lda_constw; - optbl_mX[0xad] = optbl_mx[0xad] = op_lda_addrw; - optbl_mX[0xbd] = optbl_mx[0xbd] = op_lda_addrxw; - optbl_mX[0xa5] = optbl_mx[0xa5] = op_lda_dpw; - optbl_mX[0xb2] = optbl_mx[0xb2] = op_lda_idpw; - optbl_mX[0xa7] = optbl_mx[0xa7] = op_lda_ildpw; - optbl_mX[0xaf] = optbl_mx[0xaf] = op_lda_longw; - optbl_mX[0xbf] = optbl_mx[0xbf] = op_lda_longxw; - optbl_mX[0xb9] = optbl_mx[0xb9] = op_lda_addryw; - optbl_mX[0xb5] = optbl_mx[0xb5] = op_lda_dpxw; - optbl_mX[0xa1] = optbl_mx[0xa1] = op_lda_idpxw; - optbl_mX[0xb1] = optbl_mx[0xb1] = op_lda_idpyw; - optbl_mX[0xb7] = optbl_mx[0xb7] = op_lda_ildpyw; - optbl_mX[0xa3] = optbl_mx[0xa3] = op_lda_srw; - optbl_mX[0xb3] = optbl_mx[0xb3] = op_lda_isryw; - -/* ora */ - optbl_mX[0x09] = optbl_mx[0x09] = op_ora_constw; - optbl_mX[0x0d] = optbl_mx[0x0d] = op_ora_addrw; - optbl_mX[0x1d] = optbl_mx[0x1d] = op_ora_addrxw; - optbl_mX[0x05] = optbl_mx[0x05] = op_ora_dpw; - optbl_mX[0x12] = optbl_mx[0x12] = op_ora_idpw; - optbl_mX[0x07] = optbl_mx[0x07] = op_ora_ildpw; - optbl_mX[0x0f] = optbl_mx[0x0f] = op_ora_longw; - optbl_mX[0x1f] = optbl_mx[0x1f] = op_ora_longxw; - optbl_mX[0x19] = optbl_mx[0x19] = op_ora_addryw; - optbl_mX[0x15] = optbl_mx[0x15] = op_ora_dpxw; - optbl_mX[0x01] = optbl_mx[0x01] = op_ora_idpxw; - optbl_mX[0x11] = optbl_mx[0x11] = op_ora_idpyw; - optbl_mX[0x17] = optbl_mx[0x17] = op_ora_ildpyw; - optbl_mX[0x03] = optbl_mx[0x03] = op_ora_srw; - optbl_mX[0x13] = optbl_mx[0x13] = op_ora_isryw; - -/* sbc */ - optbl_mX[0xe9] = optbl_mx[0xe9] = op_sbc_constw; - optbl_mX[0xed] = optbl_mx[0xed] = op_sbc_addrw; - optbl_mX[0xfd] = optbl_mx[0xfd] = op_sbc_addrxw; - optbl_mX[0xe5] = optbl_mx[0xe5] = op_sbc_dpw; - optbl_mX[0xf2] = optbl_mx[0xf2] = op_sbc_idpw; - optbl_mX[0xe7] = optbl_mx[0xe7] = op_sbc_ildpw; - optbl_mX[0xef] = optbl_mx[0xef] = op_sbc_longw; - optbl_mX[0xff] = optbl_mx[0xff] = op_sbc_longxw; - optbl_mX[0xf9] = optbl_mx[0xf9] = op_sbc_addryw; - optbl_mX[0xf5] = optbl_mx[0xf5] = op_sbc_dpxw; - optbl_mX[0xe1] = optbl_mx[0xe1] = op_sbc_idpxw; - optbl_mX[0xf1] = optbl_mx[0xf1] = op_sbc_idpyw; - optbl_mX[0xf7] = optbl_mx[0xf7] = op_sbc_ildpyw; - optbl_mX[0xe3] = optbl_mx[0xe3] = op_sbc_srw; - optbl_mX[0xf3] = optbl_mx[0xf3] = op_sbc_isryw; - -/* sta */ - optbl_mX[0x8d] = optbl_mx[0x8d] = op_sta_addrw; - optbl_mX[0x9d] = optbl_mx[0x9d] = op_sta_addrxw; - optbl_mX[0x85] = optbl_mx[0x85] = op_sta_dpw; - optbl_mX[0x92] = optbl_mx[0x92] = op_sta_idpw; - optbl_mX[0x87] = optbl_mx[0x87] = op_sta_ildpw; - optbl_mX[0x8f] = optbl_mx[0x8f] = op_sta_longw; - optbl_mX[0x9f] = optbl_mx[0x9f] = op_sta_longxw; - optbl_mX[0x99] = optbl_mx[0x99] = op_sta_addryw; - optbl_mX[0x95] = optbl_mx[0x95] = op_sta_dpxw; - optbl_mX[0x81] = optbl_mx[0x81] = op_sta_idpxw; - optbl_mX[0x91] = optbl_mx[0x91] = op_sta_idpyw; - optbl_mX[0x97] = optbl_mx[0x97] = op_sta_ildpyw; - optbl_mX[0x83] = optbl_mx[0x83] = op_sta_srw; - optbl_mX[0x93] = optbl_mx[0x93] = op_sta_isryw; - -/* incdec */ - optbl_mX[0x1a] = optbl_mx[0x1a] = op_incw; - optbl_mX[0xee] = optbl_mx[0xee] = op_inc_addrw; - optbl_mX[0xfe] = optbl_mx[0xfe] = op_inc_addrxw; - optbl_mX[0xe6] = optbl_mx[0xe6] = op_inc_dpw; - optbl_mX[0xf6] = optbl_mx[0xf6] = op_inc_dpxw; - optbl_mX[0x3a] = optbl_mx[0x3a] = op_decw; - optbl_mX[0xce] = optbl_mx[0xce] = op_dec_addrw; - optbl_mX[0xde] = optbl_mx[0xde] = op_dec_addrxw; - optbl_mX[0xc6] = optbl_mx[0xc6] = op_dec_dpw; - optbl_mX[0xd6] = optbl_mx[0xd6] = op_dec_dpxw; - - optbl_Mx[0xe8] = optbl_mx[0xe8] = op_inxw; - optbl_Mx[0xc8] = optbl_mx[0xc8] = op_inyw; - optbl_Mx[0xca] = optbl_mx[0xca] = op_dexw; - optbl_Mx[0x88] = optbl_mx[0x88] = op_deyw; - -/* misc */ - optbl_mX[0x89] = optbl_mx[0x89] = op_bit_constw; - optbl_mX[0x2c] = optbl_mx[0x2c] = op_bit_addrw; - optbl_mX[0x3c] = optbl_mx[0x3c] = op_bit_addrxw; - optbl_mX[0x24] = optbl_mx[0x24] = op_bit_dpw; - optbl_mX[0x34] = optbl_mx[0x34] = op_bit_dpxw; - optbl_mX[0x9c] = optbl_mx[0x9c] = op_stz_addrw; - optbl_mX[0x9e] = optbl_mx[0x9e] = op_stz_addrxw; - optbl_mX[0x64] = optbl_mx[0x64] = op_stz_dpw; - optbl_mX[0x74] = optbl_mx[0x74] = op_stz_dpxw; - optbl_mX[0x1c] = optbl_mx[0x1c] = op_trb_addrw; - optbl_mX[0x14] = optbl_mx[0x14] = op_trb_dpw; - optbl_mX[0x0c] = optbl_mx[0x0c] = op_tsb_addrw; - optbl_mX[0x04] = optbl_mx[0x04] = op_tsb_dpw; - optbl_mX[0x8a] = optbl_mx[0x8a] = op_txaw; - optbl_mX[0x98] = optbl_mx[0x98] = op_tyaw; - - optbl_Mx[0xe0] = optbl_mx[0xe0] = op_cpx_constw; - optbl_Mx[0xec] = optbl_mx[0xec] = op_cpx_addrw; - optbl_Mx[0xe4] = optbl_mx[0xe4] = op_cpx_dpw; - optbl_Mx[0xc0] = optbl_mx[0xc0] = op_cpy_constw; - optbl_Mx[0xcc] = optbl_mx[0xcc] = op_cpy_addrw; - optbl_Mx[0xc4] = optbl_mx[0xc4] = op_cpy_dpw; - optbl_Mx[0xa2] = optbl_mx[0xa2] = op_ldx_constw; - optbl_Mx[0xae] = optbl_mx[0xae] = op_ldx_addrw; - optbl_Mx[0xbe] = optbl_mx[0xbe] = op_ldx_addryw; - optbl_Mx[0xa6] = optbl_mx[0xa6] = op_ldx_dpw; - optbl_Mx[0xb6] = optbl_mx[0xb6] = op_ldx_dpyw; - optbl_Mx[0xa0] = optbl_mx[0xa0] = op_ldy_constw; - optbl_Mx[0xac] = optbl_mx[0xac] = op_ldy_addrw; - optbl_Mx[0xbc] = optbl_mx[0xbc] = op_ldy_addrxw; - optbl_Mx[0xa4] = optbl_mx[0xa4] = op_ldy_dpw; - optbl_Mx[0xb4] = optbl_mx[0xb4] = op_ldy_dpxw; - optbl_Mx[0x8e] = optbl_mx[0x8e] = op_stx_addrw; - optbl_Mx[0x86] = optbl_mx[0x86] = op_stx_dpw; - optbl_Mx[0x96] = optbl_mx[0x96] = op_stx_dpyw; - optbl_Mx[0x8c] = optbl_mx[0x8c] = op_sty_addrw; - optbl_Mx[0x84] = optbl_mx[0x84] = op_sty_dpw; - optbl_Mx[0x94] = optbl_mx[0x94] = op_sty_dpxw; - optbl_Mx[0xaa] = optbl_mx[0xaa] = op_taxw; - optbl_Mx[0xa8] = optbl_mx[0xa8] = op_tayw; - optbl_Mx[0xba] = optbl_mx[0xba] = op_tsxw; - optbl_Mx[0x9a] = optbl_mx[0x9a] = op_txsw; - optbl_Mx[0x9b] = optbl_mx[0x9b] = op_txyw; - optbl_Mx[0xbb] = optbl_mx[0xbb] = op_tyxw; - -/* pc */ - optbl_MX[0x40] = optbl_Mx[0x40] = op_rtin; - optbl_mX[0x40] = optbl_mx[0x40] = op_rtin; - -/* shift */ - optbl_mX[0x0a] = optbl_mx[0x0a] = op_aslw; - optbl_mX[0x0e] = optbl_mx[0x0e] = op_asl_addrw; - optbl_mX[0x1e] = optbl_mx[0x1e] = op_asl_addrxw; - optbl_mX[0x06] = optbl_mx[0x06] = op_asl_dpw; - optbl_mX[0x16] = optbl_mx[0x16] = op_asl_dpxw; - optbl_mX[0x4a] = optbl_mx[0x4a] = op_lsrw; - optbl_mX[0x4e] = optbl_mx[0x4e] = op_lsr_addrw; - optbl_mX[0x5e] = optbl_mx[0x5e] = op_lsr_addrxw; - optbl_mX[0x46] = optbl_mx[0x46] = op_lsr_dpw; - optbl_mX[0x56] = optbl_mx[0x56] = op_lsr_dpxw; - optbl_mX[0x2a] = optbl_mx[0x2a] = op_rolw; - optbl_mX[0x2e] = optbl_mx[0x2e] = op_rol_addrw; - optbl_mX[0x3e] = optbl_mx[0x3e] = op_rol_addrxw; - optbl_mX[0x26] = optbl_mx[0x26] = op_rol_dpw; - optbl_mX[0x36] = optbl_mx[0x36] = op_rol_dpxw; - optbl_mX[0x6a] = optbl_mx[0x6a] = op_rorw; - optbl_mX[0x6e] = optbl_mx[0x6e] = op_ror_addrw; - optbl_mX[0x7e] = optbl_mx[0x7e] = op_ror_addrxw; - optbl_mX[0x66] = optbl_mx[0x66] = op_ror_dpw; - optbl_mX[0x76] = optbl_mx[0x76] = op_ror_dpxw; - -/* stack */ - optbl_mX[0x48] = optbl_mx[0x48] = op_phaw; - optbl_mX[0x68] = optbl_mx[0x68] = op_plaw; - - optbl_Mx[0xda] = optbl_mx[0xda] = op_phxw; - optbl_Mx[0x5a] = optbl_mx[0x5a] = op_phyw; - optbl_Mx[0xfa] = optbl_mx[0xfa] = op_plxw; - optbl_Mx[0x7a] = optbl_mx[0x7a] = op_plyw; +#include "bcpu_optable.cpp" } diff --git a/src/cpu/bcpu/bcpu_mmio.cpp b/src/cpu/bcpu/bcpu_mmio.cpp index 55c175f7..6a609ea1 100644 --- a/src/cpu/bcpu/bcpu_mmio.cpp +++ b/src/cpu/bcpu/bcpu_mmio.cpp @@ -91,26 +91,22 @@ uint8 r = 0x00; //RDNMI uint8 bCPU::mmio_r4210() { uint8 r = 0x00; -uint16 v, h, hcycles, visible_scanlines; - v = clock->vcounter(); - h = clock->hcounter(); - hcycles = clock->hcycles(); - visible_scanlines = clock->visible_scanlines(); +uint16 v, h, hc, vs; + v = vcounter(); + h = hcounter(); + hc = hcycles(); + vs = (overscan()?239:224); + if(status.r4210_read == false) { - if(v == 0 && hcycles < 2) { - r |= 0x80; - status.r4210_read = true; - } else if(v == (visible_scanlines + 1) && hcycles >= 2) { - r |= 0x80; - status.r4210_read = true; - } else if(v >= (visible_scanlines + 1)) { + if((v == (vs + 1) && hc >= 2) || v > (vs + 1)) { r |= 0x80; status.r4210_read = true; + status.nmi_pin = 1; } } + r |= 0x40; r |= 0x02; //cpu version number - status.nmi_pin = 1; return r; } @@ -126,24 +122,22 @@ uint8 r = 0x00; //HVBJOY uint8 bCPU::mmio_r4212() { uint8 r; -uint16 v, h, hcycles, visible_scanlines; +uint16 v, h, hc, vs; r = 0x00; - v = clock->vcounter(); - h = clock->hcounter(); - hcycles = clock->hcycles(); - visible_scanlines = clock->visible_scanlines(); + v = vcounter(); + h = hcounter(); + hc = hcycles(); + vs = (overscan()?239:224); //auto joypad polling - if(v >= (visible_scanlines + 1) && v <= (visible_scanlines + 3))r |= 0x01; + if(v >= (vs + 1) && v <= (vs + 3))r |= 0x01; //hblank - if(hcycles <= 4 || hcycles >= 1098)r |= 0x40; + if(hc <= 2 || hc >= 1096)r |= 0x40; //vblank - if(v == 0 && hcycles < 2)r |= 0x80; - if(v == (visible_scanlines + 1) && hcycles >= 2)r |= 0x80; - if(v > (visible_scanlines + 1))r |= 0x80; + if(v >= (vs + 1))r |= 0x80; return r; } @@ -175,7 +169,7 @@ uint8 bCPU::mmio_r4217() { //JOY1L uint8 bCPU::mmio_r4218() { uint8 r = 0x00; -uint16 v = clock->vcounter(); +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 r |= (uint8)snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_A) << 7; @@ -188,7 +182,7 @@ uint16 v = clock->vcounter(); //JOY1H uint8 bCPU::mmio_r4219() { uint8 r = 0x00; -uint16 v = clock->vcounter(); +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 r |= (uint8)snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_B) << 7; @@ -202,12 +196,103 @@ uint16 v = clock->vcounter(); return r; } +//DMAPx +uint8 bCPU::mmio_r43x0(uint8 i) { + return channel[i].dmap; +} + +//BBADx +uint8 bCPU::mmio_r43x1(uint8 i) { + return channel[i].destaddr; +} + +//A1TxL +uint8 bCPU::mmio_r43x2(uint8 i) { + return channel[i].srcaddr; +} + +//A1TxH +uint8 bCPU::mmio_r43x3(uint8 i) { + return channel[i].srcaddr >> 8; +} + +//A1Bx +uint8 bCPU::mmio_r43x4(uint8 i) { + return channel[i].srcaddr >> 16; +} + +//DASxL +uint8 bCPU::mmio_r43x5(uint8 i) { + return channel[i].xfersize; +} + +//DASxH +uint8 bCPU::mmio_r43x6(uint8 i) { + return channel[i].xfersize >> 8; +} + +//DASBx +uint8 bCPU::mmio_r43x7(uint8 i) { + return channel[i].hdma_indirect_bank; +} + +//A2AxL +uint8 bCPU::mmio_r43x8(uint8 i) { + return channel[i].hdma_taddr; +} + +//A2AxH +uint8 bCPU::mmio_r43x9(uint8 i) { + return channel[i].hdma_taddr >> 8; +} + +//NTRLx +uint8 bCPU::mmio_r43xa(uint8 i) { + return channel[i].hdma_line_counter; +} + +//??? +uint8 bCPU::mmio_r43xb(uint8 i) { + return channel[i].hdma_unknown; +} + uint8 bCPUMMIO::read(uint32 addr) { - clock->sync(); +uint8 i; +//cpu->sync(); + +//APU + if(addr >= 0x2140 && addr <= 0x217f) { + return apu->port_read(addr & 3); + } + +//HDMA + if(addr >= 0x4300 && addr <= 0x437f) { + i = (addr >> 4) & 7; + switch(addr & 0xf) { + case 0x0:return cpu->mmio_r43x0(i); + case 0x1:return cpu->mmio_r43x1(i); + case 0x2:return cpu->mmio_r43x2(i); + case 0x3:return cpu->mmio_r43x3(i); + case 0x4:return cpu->mmio_r43x4(i); + case 0x5:return cpu->mmio_r43x5(i); + case 0x6:return cpu->mmio_r43x6(i); + case 0x7:return cpu->mmio_r43x7(i); + case 0x8:return cpu->mmio_r43x8(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 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 0x4210:return cpu->mmio_r4210(); //RDNMI case 0x4211:return cpu->mmio_r4211(); //TIMEUP @@ -219,6 +304,7 @@ uint8 bCPUMMIO::read(uint32 addr) { case 0x4217:return cpu->mmio_r4217(); //RDMPYH case 0x4218:return cpu->mmio_r4218(); //JOY1L case 0x4219:return cpu->mmio_r4219(); //JOY1H + case 0x421a:case 0x421b:case 0x421c:case 0x421d:case 0x421e:case 0x421f:return 0x00; } return 0x00; } @@ -263,6 +349,14 @@ void bCPU::mmio_w4200(uint8 value) { status.virq_enabled = !!(value & 0x20); status.hirq_enabled = !!(value & 0x10); status.auto_joypad_poll = !!(value & 0x01); + + if(status.nmi_enabled == false) { + status.nmi_pin = 0; + } + + if(status.virq_enabled == false && status.hirq_enabled == false) { + status.irq_pin = 0; + } } //WRIO @@ -296,8 +390,8 @@ void bCPU::mmio_w4205(uint8 value) { //WRDIVB void bCPU::mmio_w4206(uint8 value) { status.div_b = value; - status.r4214 = (status.div_b)?status.div_a / status.div_b:0; - status.r4216 = (status.div_b)?status.div_a % status.div_b:0; + status.r4214 = (status.div_b)?status.div_a / status.div_b : 0xffff; + status.r4216 = (status.div_b)?status.div_a % status.div_b : status.div_a; } //HTIMEL @@ -327,15 +421,13 @@ void bCPU::mmio_w420a(uint8 value) { //DMAEN void bCPU::mmio_w420b(uint8 value) { if(value != 0x00) { - clock->add_cc1_cycles(18); + status.dma_state = DMASTATE_INIT; } for(int i=0;i<8;i++) { if(value & (1 << i)) { - dma->channel[i].active = true; - dma->channel[i].hdma_active = false; - clock->add_cc1_cycles(8); - cpustate = CPUSTATE_DMA; + channel[i].active = true; + channel[i].hdma_active = false; } } } @@ -343,7 +435,7 @@ void bCPU::mmio_w420b(uint8 value) { //HDMAEN void bCPU::mmio_w420c(uint8 value) { for(int i=0;i<8;i++) { - dma->channel[i].hdma_active = !!(value & (1 << i)); + channel[i].hdma_active = !!(value & (1 << i)); } } @@ -354,56 +446,108 @@ void bCPU::mmio_w420d(uint8 value) { //DMAPx void bCPU::mmio_w43x0(uint8 value, uint8 i) { - dma->channel[i].direction = !!(value & 0x80); - dma->channel[i].hdma_indirect = !!(value & 0x40); - dma->channel[i].incmode = (value & 0x10)?-1:1; - dma->channel[i].fixedxfer = !!(value & 0x08); - dma->channel[i].xfermode = value & 7; + channel[i].dmap = value; + channel[i].direction = !!(value & 0x80); + channel[i].hdma_indirect = !!(value & 0x40); + channel[i].incmode = (value & 0x10)?-1:1; + channel[i].fixedxfer = !!(value & 0x08); + channel[i].xfermode = value & 7; } //BBADx void bCPU::mmio_w43x1(uint8 value, uint8 i) { - dma->channel[i].destaddr = value; + channel[i].destaddr = value; } //A1TxL void bCPU::mmio_w43x2(uint8 value, uint8 i) { - dma->channel[i].srcaddr = (dma->channel[i].srcaddr & 0xffff00) | value; + channel[i].srcaddr = (channel[i].srcaddr & 0xffff00) | value; } //A1TxH void bCPU::mmio_w43x3(uint8 value, uint8 i) { - dma->channel[i].srcaddr = (dma->channel[i].srcaddr & 0xff00ff) | (value << 8); + channel[i].srcaddr = (channel[i].srcaddr & 0xff00ff) | (value << 8); } //A1Bx void bCPU::mmio_w43x4(uint8 value, uint8 i) { - dma->channel[i].srcaddr = (dma->channel[i].srcaddr & 0x00ffff) | (value << 16); + channel[i].srcaddr = (channel[i].srcaddr & 0x00ffff) | (value << 16); } //DASxL void bCPU::mmio_w43x5(uint8 value, uint8 i) { - dma->channel[i].xfersize = (dma->channel[i].xfersize & 0xff00) | value; + channel[i].xfersize = (channel[i].xfersize & 0xff00) | value; } //DASxH void bCPU::mmio_w43x6(uint8 value, uint8 i) { - dma->channel[i].xfersize = (dma->channel[i].xfersize & 0x00ff) | (value << 8); + channel[i].xfersize = (channel[i].xfersize & 0x00ff) | (value << 8); } //DASBx void bCPU::mmio_w43x7(uint8 value, uint8 i) { - dma->channel[i].hdma_indirect_bank = value; + channel[i].hdma_indirect_bank = value; +} + +//A2AxL +void bCPU::mmio_w43x8(uint8 value, uint8 i) { + channel[i].hdma_taddr = (channel[i].hdma_taddr & 0xffff00) | value; +} + +//A2AxH +void bCPU::mmio_w43x9(uint8 value, uint8 i) { + channel[i].hdma_taddr = (channel[i].hdma_taddr & 0xff00ff) | (value << 8); +} + +//NTRLx +void bCPU::mmio_w43xa(uint8 value, uint8 i) { + channel[i].hdma_line_counter = value; +} + +//??? +void bCPU::mmio_w43xb(uint8 value, uint8 i) { + channel[i].hdma_unknown = value; } void bCPUMMIO::write(uint32 addr, uint8 value) { -int i; - clock->sync(); +uint8 i; +//cpu->sync(); + +//APU + if(addr >= 0x2140 && addr <= 0x217f) { + cpu->port_write(addr & 3, value); + return; + } + +//HDMA + if(addr >= 0x4300 && addr <= 0x437f) { + i = (addr >> 4) & 7; + switch(addr & 0xf) { + case 0x0:cpu->mmio_w43x0(value, i);return; + case 0x1:cpu->mmio_w43x1(value, i);return; + case 0x2:cpu->mmio_w43x2(value, i);return; + case 0x3:cpu->mmio_w43x3(value, i);return; + case 0x4:cpu->mmio_w43x4(value, i);return; + case 0x5:cpu->mmio_w43x5(value, i);return; + case 0x6:cpu->mmio_w43x6(value, i);return; + case 0x7:cpu->mmio_w43x7(value, i);return; + case 0x8:cpu->mmio_w43x8(value, i);return; + case 0x9:cpu->mmio_w43x9(value, i);return; + case 0xa:cpu->mmio_w43xa(value, i);return; + case 0xb:cpu->mmio_w43xb(value, i);return; + case 0xc:return; //unmapped + case 0xd:return; //unmapped + case 0xe:return; //unmapped + case 0xf:cpu->mmio_w43xb(value, i);return; //mirror of 43xb + } + } + switch(addr) { case 0x2180:cpu->mmio_w2180(value);return; //WMDATA 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 @@ -419,288 +563,9 @@ int i; case 0x420b:cpu->mmio_w420b(value);return; //DMAEN case 0x420c:cpu->mmio_w420c(value);return; //HDMAEN case 0x420d:cpu->mmio_w420d(value);return; //MEMSEL -//DMAPx - case 0x4300:case 0x4310:case 0x4320:case 0x4330: - case 0x4340:case 0x4350:case 0x4360:case 0x4370: - cpu->mmio_w43x0(value, (addr >> 4) & 7); - return; -//BBADx - case 0x4301:case 0x4311:case 0x4321:case 0x4331: - case 0x4341:case 0x4351:case 0x4361:case 0x4371: - cpu->mmio_w43x1(value, (addr >> 4) & 7); - return; -//A1TxL - case 0x4302:case 0x4312:case 0x4322:case 0x4332: - case 0x4342:case 0x4352:case 0x4362:case 0x4372: - cpu->mmio_w43x2(value, (addr >> 4) & 7); - return; -//A1TxH - case 0x4303:case 0x4313:case 0x4323:case 0x4333: - case 0x4343:case 0x4353:case 0x4363:case 0x4373: - cpu->mmio_w43x3(value, (addr >> 4) & 7); - return; -//A1Bx - case 0x4304:case 0x4314:case 0x4324:case 0x4334: - case 0x4344:case 0x4354:case 0x4364:case 0x4374: - cpu->mmio_w43x4(value, (addr >> 4) & 7); - return; -//DASxL - case 0x4305:case 0x4315:case 0x4325:case 0x4335: - case 0x4345:case 0x4355:case 0x4365:case 0x4375: - cpu->mmio_w43x5(value, (addr >> 4) & 7); - return; -//DASxH - case 0x4306:case 0x4316:case 0x4326:case 0x4336: - case 0x4346:case 0x4356:case 0x4366:case 0x4376: - cpu->mmio_w43x6(value, (addr >> 4) & 7); - return; -//DASBx - case 0x4307:case 0x4317:case 0x4327:case 0x4337: - case 0x4347:case 0x4357:case 0x4367:case 0x4377: - cpu->mmio_w43x7(value, (addr >> 4) & 7); - return; } } bCPUMMIO::bCPUMMIO(bCPU *_cpu) { cpu = _cpu; } - -uint16 bDMA::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); - } - clock->add_cc1_cycles(8); - return --channel[i].xfersize; -} - -uint16 bDMA::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); - if(channel[i].fixedxfer == false) { - channel[i].srcaddr = (channel[i].srcaddr & 0xff0000) + ((channel[i].srcaddr + channel[i].incmode) & 0xffff); - } - clock->add_cc1_cycles(8); - return --channel[i].xfersize; -} - -void bDMA::dma_xfer_type0(uint8 i) { - if(channel[i].direction == 0) { - if(dma_cputommio(i, 0) == 0)return; - } else { - if(dma_mmiotocpu(i, 0) == 0)return; - } -} - -void bDMA::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 bDMA::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 bDMA::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 bDMA::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 bDMA::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; - } -} - -void bDMA::run() { - for(int 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; - } - if(channel[i].xfersize == 0) { - channel[i].active = false; - } - return; - } - cpu->cpustate = bCPU::CPUSTATE_RUN; -} - -void bDMA::hdma_write(uint8 i, uint8 l, uint8 x) { - 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; - } -} - -void bDMA::hdma_run() { -int l, xferlen; -uint8 x, active_channels = 0; - for(int i=0;i<8;i++) { - if(channel[i].hdma_completed == true)continue; - clock->add_cc1_cycles(8); - active_channels++; - if(channel[i].hdma_line_counter == 0) { - channel[i].hdma_line_counter = mem_bus->read(channel[i].hdma_address++); -// channel[i].r43x8 = channel[i].hdma_address; - if(channel[i].hdma_line_counter == 0) { - channel[i].hdma_completed = true; - continue; - } - - if(channel[i].hdma_line_counter > 0x80) { - channel[i].hdma_repeat = true; - channel[i].hdma_line_counter -= 0x80; - } else { - channel[i].hdma_repeat = false; - } - - channel[i].hdma_first_line = true; - if(channel[i].hdma_indirect == false) { - channel[i].hdma_iaddress = channel[i].hdma_address; - } else { - channel[i].hdma_iaddress = mem_bus->read(channel[i].hdma_address); - channel[i].hdma_iaddress |= mem_bus->read(channel[i].hdma_address + 1) << 8; - channel[i].hdma_iaddress |= channel[i].hdma_indirect_bank << 16; - channel[i].hdma_address += 2; - clock->add_cc1_cycles(16); - } - } - - channel[i].hdma_line_counter--; - 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_iaddress = channel[i].hdma_address; - } - - 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; - } - - for(l=0;lread(channel[i].hdma_iaddress++); - if(channel[i].hdma_indirect == false) { - channel[i].hdma_address++; - } - hdma_write(i, l, x); - clock->add_cc1_cycles(8); - } - } - if(active_channels != 0) { - clock->add_cc1_cycles(18); - } -} - -void bDMA::hdma_initialize() { -uint8 active_channels = 0; - for(int i=0;i<8;i++) { - if(channel[i].hdma_active == false) { - channel[i].hdma_completed = true; - continue; - } - active_channels++; - channel[i].hdma_first_line = true; - channel[i].hdma_repeat = false; - channel[i].hdma_line_counter = 0; - channel[i].hdma_address = channel[i].srcaddr; - channel[i].hdma_completed = false; - if(channel[i].hdma_indirect == false) { - clock->add_cc1_cycles(8); - } else { - clock->add_cc1_cycles(24); - } - } - if(active_channels != 0) { - clock->add_cc1_cycles(18); - } -} - -void bDMA::reset() { - for(int i=0;i<8;i++) { - channel[i].active = false; - channel[i].hdma_active = false; - 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_first_line = false; - channel[i].hdma_repeat = false; - channel[i].hdma_line_counter = 0; - channel[i].hdma_address = 0; - channel[i].hdma_iaddress = 0; - channel[i].hdma_completed = true; - } -} - -bDMA::bDMA(bCPU *_cpu) { - cpu = _cpu; - reset(); -} diff --git a/src/cpu/bcpu/bcpu_op.h b/src/cpu/bcpu/bcpu_op.h new file mode 100644 index 00000000..63b88b2d --- /dev/null +++ b/src/cpu/bcpu/bcpu_op.h @@ -0,0 +1,256 @@ +void op_adc_const(); +void op_and_const(); +void op_cmp_const(); +void op_cpx_const(); +void op_cpy_const(); +void op_eor_const(); +void op_lda_const(); +void op_ldx_const(); +void op_ldy_const(); +void op_ora_const(); +void op_sbc_const(); +void op_adc_addr(); +void op_and_addr(); +void op_bit_addr(); +void op_cmp_addr(); +void op_cpx_addr(); +void op_cpy_addr(); +void op_eor_addr(); +void op_lda_addr(); +void op_ldx_addr(); +void op_ldy_addr(); +void op_ora_addr(); +void op_sbc_addr(); +void op_adc_addrx(); +void op_and_addrx(); +void op_bit_addrx(); +void op_cmp_addrx(); +void op_eor_addrx(); +void op_lda_addrx(); +void op_ldy_addrx(); +void op_ora_addrx(); +void op_sbc_addrx(); +void op_adc_addry(); +void op_and_addry(); +void op_cmp_addry(); +void op_eor_addry(); +void op_lda_addry(); +void op_ldx_addry(); +void op_ora_addry(); +void op_sbc_addry(); +void op_adc_long(); +void op_and_long(); +void op_cmp_long(); +void op_eor_long(); +void op_lda_long(); +void op_ora_long(); +void op_sbc_long(); +void op_adc_longx(); +void op_and_longx(); +void op_cmp_longx(); +void op_eor_longx(); +void op_lda_longx(); +void op_ora_longx(); +void op_sbc_longx(); +void op_adc_dp(); +void op_and_dp(); +void op_bit_dp(); +void op_cmp_dp(); +void op_cpx_dp(); +void op_cpy_dp(); +void op_eor_dp(); +void op_lda_dp(); +void op_ldx_dp(); +void op_ldy_dp(); +void op_ora_dp(); +void op_sbc_dp(); +void op_adc_dpx(); +void op_and_dpx(); +void op_bit_dpx(); +void op_cmp_dpx(); +void op_eor_dpx(); +void op_lda_dpx(); +void op_ldy_dpx(); +void op_ora_dpx(); +void op_sbc_dpx(); +void op_ldx_dpy(); +void op_adc_idp(); +void op_and_idp(); +void op_cmp_idp(); +void op_eor_idp(); +void op_lda_idp(); +void op_ora_idp(); +void op_sbc_idp(); +void op_adc_idpx(); +void op_and_idpx(); +void op_cmp_idpx(); +void op_eor_idpx(); +void op_lda_idpx(); +void op_ora_idpx(); +void op_sbc_idpx(); +void op_adc_idpy(); +void op_and_idpy(); +void op_cmp_idpy(); +void op_eor_idpy(); +void op_lda_idpy(); +void op_ora_idpy(); +void op_sbc_idpy(); +void op_adc_ildp(); +void op_and_ildp(); +void op_cmp_ildp(); +void op_eor_ildp(); +void op_lda_ildp(); +void op_ora_ildp(); +void op_sbc_ildp(); +void op_adc_ildpy(); +void op_and_ildpy(); +void op_cmp_ildpy(); +void op_eor_ildpy(); +void op_lda_ildpy(); +void op_ora_ildpy(); +void op_sbc_ildpy(); +void op_adc_sr(); +void op_and_sr(); +void op_cmp_sr(); +void op_eor_sr(); +void op_lda_sr(); +void op_ora_sr(); +void op_sbc_sr(); +void op_adc_isry(); +void op_and_isry(); +void op_cmp_isry(); +void op_eor_isry(); +void op_lda_isry(); +void op_ora_isry(); +void op_sbc_isry(); +void op_bit_const(); +void op_inc(); +void op_inx(); +void op_iny(); +void op_dec(); +void op_dex(); +void op_dey(); +void op_asl(); +void op_lsr(); +void op_rol(); +void op_ror(); +void op_inc_addr(); +void op_dec_addr(); +void op_asl_addr(); +void op_lsr_addr(); +void op_rol_addr(); +void op_ror_addr(); +void op_trb_addr(); +void op_tsb_addr(); +void op_inc_addrx(); +void op_dec_addrx(); +void op_asl_addrx(); +void op_lsr_addrx(); +void op_rol_addrx(); +void op_ror_addrx(); +void op_inc_dp(); +void op_dec_dp(); +void op_asl_dp(); +void op_lsr_dp(); +void op_rol_dp(); +void op_ror_dp(); +void op_trb_dp(); +void op_tsb_dp(); +void op_inc_dpx(); +void op_dec_dpx(); +void op_asl_dpx(); +void op_lsr_dpx(); +void op_rol_dpx(); +void op_ror_dpx(); +void op_sta_addr(); +void op_stx_addr(); +void op_sty_addr(); +void op_stz_addr(); +void op_sta_addrx(); +void op_stz_addrx(); +void op_sta_addry(); +void op_sta_long(); +void op_sta_longx(); +void op_sta_dp(); +void op_stx_dp(); +void op_sty_dp(); +void op_stz_dp(); +void op_sta_dpx(); +void op_sty_dpx(); +void op_stz_dpx(); +void op_stx_dpy(); +void op_sta_idp(); +void op_sta_ildp(); +void op_sta_idpx(); +void op_sta_idpy(); +void op_sta_ildpy(); +void op_sta_sr(); +void op_sta_isry(); +void op_bra(); +void op_bcc(); +void op_bcs(); +void op_bne(); +void op_beq(); +void op_bpl(); +void op_bmi(); +void op_bvc(); +void op_bvs(); +void op_brl(); +void op_jmp_addr(); +void op_jmp_long(); +void op_jmp_iaddr(); +void op_jmp_iaddrx(); +void op_jmp_iladdr(); +void op_jsr_addr(); +void op_jsr_long(); +void op_jsr_iaddrx(); +void op_rti(); +void op_rts(); +void op_rtl(); +void op_nop(); +void op_wdm(); +void op_xba(); +void op_mvn(); +void op_mvp(); +void op_brk(); +void op_cop(); +void op_stp(); +void op_wai(); +void op_xce(); +void op_clc(); +void op_cld(); +void op_cli(); +void op_clv(); +void op_sec(); +void op_sed(); +void op_sei(); +void op_rep(); +void op_sep(); +void op_tax(); +void op_tay(); +void op_txa(); +void op_txy(); +void op_tya(); +void op_tyx(); +void op_tcd(); +void op_tcs(); +void op_tdc(); +void op_tsc(); +void op_tsx(); +void op_txs(); +void op_pha(); +void op_phx(); +void op_phy(); +void op_phd(); +void op_phb(); +void op_phk(); +void op_php(); +void op_pla(); +void op_plx(); +void op_ply(); +void op_pld(); +void op_plb(); +void op_plp(); +void op_pea(); +void op_pei(); +void op_per(); diff --git a/src/cpu/bcpu/bcpu_op_adc.cpp b/src/cpu/bcpu/bcpu_op_adc.cpp deleted file mode 100644 index fdf6e152..00000000 --- a/src/cpu/bcpu/bcpu_op_adc.cpp +++ /dev/null @@ -1,464 +0,0 @@ -inline void bCPU::flags_adc_b() { -int32 r = regs.a.l + rd.l + regs.p.c; -//bcd - if(regs.p.d) { - if(((r ) & 15) > 9)r += 6; - if(((r >> 4) & 15) > 9)r += 6 << 4; - } - regs.p.n = !!(r & 0x80); - regs.p.v = !!(~(regs.a.l ^ rd.l) & (regs.a.l ^ r) & 0x80); - regs.p.z = ((byte)r == 0); - regs.p.c = (r > 0xff); - regs.a.l = r; -} - -inline void bCPU::flags_adc_w() { -int32 r = regs.a.w + rd.w + regs.p.c; -//bcd - if(regs.p.d) { - if(((r ) & 15) > 9)r += 6; - if(((r >> 4) & 15) > 9)r += 6 << 4; - if(((r >> 8) & 15) > 9)r += 6 << 8; - if(((r >> 12) & 15) > 9)r += 6 << 12; - } - regs.p.n = !!(r & 0x8000); - regs.p.v = !!(~(regs.a.w ^ rd.w) & (regs.a.w ^ r) & 0x8000); - regs.p.z = ((word)r == 0); - regs.p.c = (r > 0xffff); - regs.a.w = r; -} - -/************************ - *** 0x69: adc #const *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; idl - [2a] pbr,pc+2 ; idh [1] -*/ -void bCPU::op_adc_constb() { - rd.l = op_read(); //2 - flags_adc_b(); -} - -void bCPU::op_adc_constw() { - rd.l = op_read(); //2 - rd.h = op_read(); //2a - flags_adc_w(); -} - -/********************** - *** 0x6d: adc addr *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [4 ] dbr,aa ; data low - [4a] dbr,aa+1 ; data high [1] -*/ -void bCPU::op_adc_addrb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - rd.l = op_read(OPMODE_DBR, aa.w); //4 - flags_adc_b(); -} - -void bCPU::op_adc_addrw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - rd.l = op_read(OPMODE_DBR, aa.w); //4 - rd.h = op_read(OPMODE_DBR, aa.w + 1); //4a - flags_adc_w(); -} - -/************************ - *** 0x7d: adc addr,x *** - ************************ -cycles: - [1 ] pbr,pc ; operadc - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [3a] dbr,aah,aal+xl ; io [4] - [4 ] dbr,aa+x ; data low - [4a] dbr,aa+x+1 ; data high [1] -*/ -void bCPU::op_adc_addrxb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_c4(aa.w, aa.w + regs.x.w); //3a - rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //4 - flags_adc_b(); -} - -void bCPU::op_adc_addrxw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_c4(aa.w, aa.w + regs.x.w); //3a - rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //4 - rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); //4a - flags_adc_w(); -} - -/******************** - *** 0x65: adc dp *** - ******************** -cycles: - [1 ] pbr,pc ; operadc - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; data low - [3a] 0,d+dp+1 ; data high [1] -*/ -void bCPU::op_adc_dpb() { - dp = op_read(); //2 - cpu_c2(); //2a - rd.l = op_read(OPMODE_DP, dp); //3 - flags_adc_b(); -} - -void bCPU::op_adc_dpw() { - dp = op_read(); //2 - cpu_c2(); //2a - rd.l = op_read(OPMODE_DP, dp); //3 - rd.h = op_read(OPMODE_DP, dp + 1); //3a - flags_adc_w(); -} - -/********************** - *** 0x72: adc (dp) *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; aal - [4 ] 0,d+dp+1 ; aah - [5 ] dbr,aa ; data low - [5a] dbr,aa+1 ; data high [1] -*/ -void bCPU::op_adc_idpb() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - rd.l = op_read(OPMODE_DBR, aa.w); //5 - flags_adc_b(); -} - -void bCPU::op_adc_idpw() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - rd.l = op_read(OPMODE_DBR, aa.w); //5 - rd.h = op_read(OPMODE_DBR, aa.w + 1); //5 - flags_adc_w(); -} - -/********************** - *** 0x67: adc [dp] *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; aal - [4 ] 0,d+dp+1 ; aah - [5 ] 0,d+dp+2 ; aab - [6 ] aab,aa ; data low - [6a] aab,aa+1 ; data high [1] -*/ -void bCPU::op_adc_ildpb() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - aa.b = op_read(OPMODE_DP, dp + 2); //5 - rd.l = op_read(OPMODE_LONG, aa.d); //6 - flags_adc_b(); -} - -void bCPU::op_adc_ildpw() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - aa.b = op_read(OPMODE_DP, dp + 2); //5 - rd.l = op_read(OPMODE_LONG, aa.d); //6 - rd.h = op_read(OPMODE_LONG, aa.d + 1); //6a - flags_adc_w(); -} - -/********************** - *** 0x6f: adc long *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [4 ] pbr,pc+3 ; aab - [5 ] aab,aa ; data low - [5a] aab,aa+1 ; data high -*/ -void bCPU::op_adc_longb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - aa.b = op_read(); //4 - rd.l = op_read(OPMODE_LONG, aa.d); //5 - flags_adc_b(); -} - -void bCPU::op_adc_longw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - aa.b = op_read(); //4 - rd.l = op_read(OPMODE_LONG, aa.d); //5 - rd.h = op_read(OPMODE_LONG, aa.d + 1); //5a - flags_adc_w(); -} - -/************************ - *** 0x7f: adc long,x *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [4 ] pbr,pc+3 ; aab - [5 ] aab,aa+x ; data low - [5a] aab,aa+x+1 ; data high -*/ -void bCPU::op_adc_longxb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - aa.b = op_read(); //4 - rd.l = op_read(OPMODE_LONG, aa.d + regs.x.w); //5 - flags_adc_b(); -} - -void bCPU::op_adc_longxw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - aa.b = op_read(); //4 - rd.l = op_read(OPMODE_LONG, aa.d + regs.x.w); //5 - rd.h = op_read(OPMODE_LONG, aa.d + regs.x.w + 1); //5a - flags_adc_w(); -} - -/************************ - *** 0x79: adc addr,y *** - ************************ -cycles: - [1 ] pbr,pc ; operadc - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [3a] dbr,aah,aal+yl ; io [4] - [4 ] dbr,aa+y ; data low - [4a] dbr,aa+y+1 ; data high [1] -*/ -void bCPU::op_adc_addryb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_c4(aa.w, aa.w + regs.y.w); //3a - rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //4 - flags_adc_b(); -} - -void bCPU::op_adc_addryw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_c4(aa.w, aa.w + regs.y.w); //3a - rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //4 - rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //4a - flags_adc_w(); -} - -/********************** - *** 0x75: adc dp,x *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io - [3 ] pbr,pc+1 ; io - [4 ] 0,d+dp+x ; data low - [4a] 0,d+dp+x+1 ; data high -*/ -void bCPU::op_adc_dpxb() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4 - flags_adc_b(); -} - -void bCPU::op_adc_dpxw() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4 - rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //4a - flags_adc_w(); -} - -/************************ - *** 0x61: adc (dp,x) *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] pbr,pc+1 ; io - [4 ] 0,d+dp+x ; aal - [5 ] 0,d+dp+x+1 ; aah - [6 ] dbr,aa ; data low - [6a] dbr,aa+1 ; data high [1] -*/ -void bCPU::op_adc_idpxb() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - aa.l = op_read(OPMODE_DP, dp + regs.x.w); //4 - aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //5 - rd.l = op_read(OPMODE_DBR, aa.w); //6 - flags_adc_b(); -} - -void bCPU::op_adc_idpxw() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - aa.l = op_read(OPMODE_DP, dp + regs.x.w); //4 - aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //5 - rd.l = op_read(OPMODE_DBR, aa.w); //6 - rd.h = op_read(OPMODE_DBR, aa.w + 1); //6a - flags_adc_w(); -} - -/************************ - *** 0x71: adc (dp),y *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; aal - [4 ] 0,d+dp+1 ; aah - [4a] dbr,aah,aal+yl ; io [4] - [5 ] dbr,aa+y ; data low - [5a] dbr,aa+y+1 ; data high [1] -*/ -void bCPU::op_adc_idpyb() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - cpu_c4(aa.w, aa.w + regs.y.w); //4a - rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //5 - flags_adc_b(); -} - -void bCPU::op_adc_idpyw() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - cpu_c4(aa.w, aa.w + regs.y.w); //4a - rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //5 - rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //5a - flags_adc_w(); -} - -/************************ - *** 0x77: adc [dp],y *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; aal - [4 ] 0,d+dp+1 ; aah - [5 ] 0,d+dp+2 ; aab - [6 ] aab,aa+y ; data low - [6a] aab,aa+y+1 ; data high [1] -*/ -void bCPU::op_adc_ildpyb() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - aa.b = op_read(OPMODE_DP, dp + 2); //5 - rd.l = op_read(OPMODE_LONG, aa.d + regs.y.w); //6 - flags_adc_b(); -} - -void bCPU::op_adc_ildpyw() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - aa.b = op_read(OPMODE_DP, dp + 2); //5 - rd.l = op_read(OPMODE_LONG, aa.d + regs.y.w); //6 - rd.h = op_read(OPMODE_LONG, aa.d + regs.y.w + 1); //6a - flags_adc_w(); -} - -/********************** - *** 0x63: adc sr,s *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; sp - [3 ] pbr,pc+1 ; io - [4 ] 0,s+sp ; data low - [4a] 0,s+sp+1 ; data high [1] -*/ -void bCPU::op_adc_srb() { - sp = op_read(); //2 - cpu_io(); //3 - rd.l = op_read(OPMODE_SP, sp); //4 - flags_adc_b(); -} - -void bCPU::op_adc_srw() { - sp = op_read(); //2 - cpu_io(); //3 - rd.l = op_read(OPMODE_SP, sp); //4 - rd.h = op_read(OPMODE_SP, sp + 1); //4a - flags_adc_w(); -} - -/************************** - *** 0x73: adc (sr,s),y *** - ************************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; sp - [3 ] pbr,pc+1 ; io - [4 ] 0,s+sp ; aal - [5 ] 0,s+sp+1 ; aah - [6 ] 0,s+sp+1 ; io - [7 ] dbr,aa+y ; data low - [7a] dbr,aa+y+1 ; data high [1] -*/ -void bCPU::op_adc_isryb() { - sp = op_read(); //2 - cpu_io(); //3 - aa.l = op_read(OPMODE_SP, sp); //4 - aa.h = op_read(OPMODE_SP, sp + 1); //5 - cpu_io(); //6 - rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //7 - flags_adc_b(); -} - -void bCPU::op_adc_isryw() { - sp = op_read(); //2 - cpu_io(); //3 - aa.l = op_read(OPMODE_SP, sp); //4 - aa.h = op_read(OPMODE_SP, sp + 1); //5 - cpu_io(); //6 - rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //7 - rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //7a - flags_adc_w(); -} diff --git a/src/cpu/bcpu/bcpu_op_and.cpp b/src/cpu/bcpu/bcpu_op_and.cpp deleted file mode 100644 index 4960ae05..00000000 --- a/src/cpu/bcpu/bcpu_op_and.cpp +++ /dev/null @@ -1,444 +0,0 @@ -inline void bCPU::flags_and_b() { - regs.p.n = !!(regs.a.l & 0x80); - regs.p.z = (regs.a.l == 0); -} - -inline void bCPU::flags_and_w() { - regs.p.n = !!(regs.a.w & 0x8000); - regs.p.z = (regs.a.w == 0); -} - -/************************ - *** 0x29: and #const *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; idl - [2a] pbr,pc+2 ; idh [1] -*/ -void bCPU::op_and_constb() { - regs.a.l &= op_read(); //2 - flags_and_b(); -} - -void bCPU::op_and_constw() { - regs.a.l &= op_read(); //2 - regs.a.h &= op_read(); //2a - flags_and_w(); -} - -/********************** - *** 0x2d: and addr *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [4 ] dbr,aa ; data low - [4a] dbr,aa+1 ; data high [1] -*/ -void bCPU::op_and_addrb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - regs.a.l &= op_read(OPMODE_DBR, aa.w); //4 - flags_and_b(); -} - -void bCPU::op_and_addrw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - regs.a.l &= op_read(OPMODE_DBR, aa.w); //4 - regs.a.h &= op_read(OPMODE_DBR, aa.w + 1); //4a - flags_and_w(); -} - -/************************ - *** 0x3d: and addr,x *** - ************************ -cycles: - [1 ] pbr,pc ; operand - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [3a] dbr,aah,aal+xl ; io [4] - [4 ] dbr,aa+x ; data low - [4a] dbr,aa+x+1 ; data high [1] -*/ -void bCPU::op_and_addrxb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_c4(aa.w, aa.w + regs.x.w); //3a - regs.a.l &= op_read(OPMODE_DBR, aa.w + regs.x.w); //4 - flags_and_b(); -} - -void bCPU::op_and_addrxw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_c4(aa.w, aa.w + regs.x.w); //3a - regs.a.l &= op_read(OPMODE_DBR, aa.w + regs.x.w); //4 - regs.a.h &= op_read(OPMODE_DBR, aa.w + regs.x.w + 1); //4a - flags_and_w(); -} - -/******************** - *** 0x25: and dp *** - ******************** -cycles: - [1 ] pbr,pc ; operand - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; data low - [3a] 0,d+dp+1 ; data high [1] -*/ -void bCPU::op_and_dpb() { - dp = op_read(); //2 - cpu_c2(); //2a - regs.a.l &= op_read(OPMODE_DP, dp); //3 - flags_and_b(); -} - -void bCPU::op_and_dpw() { - dp = op_read(); //2 - cpu_c2(); //2a - regs.a.l &= op_read(OPMODE_DP, dp); //3 - regs.a.h &= op_read(OPMODE_DP, dp + 1); //3a - flags_and_w(); -} - -/********************** - *** 0x32: and (dp) *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; aal - [4 ] 0,d+dp+1 ; aah - [5 ] dbr,aa ; data low - [5a] dbr,aa+1 ; data high [1] -*/ -void bCPU::op_and_idpb() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - regs.a.l &= op_read(OPMODE_DBR, aa.w); //5 - flags_and_b(); -} - -void bCPU::op_and_idpw() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - regs.a.l &= op_read(OPMODE_DBR, aa.w); //5 - regs.a.h &= op_read(OPMODE_DBR, aa.w + 1); //5 - flags_and_w(); -} - -/********************** - *** 0x27: and [dp] *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; aal - [4 ] 0,d+dp+1 ; aah - [5 ] 0,d+dp+2 ; aab - [6 ] aab,aa ; data low - [6a] aab,aa+1 ; data high [1] -*/ -void bCPU::op_and_ildpb() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - aa.b = op_read(OPMODE_DP, dp + 2); //5 - regs.a.l &= op_read(OPMODE_LONG, aa.d); //6 - flags_and_b(); -} - -void bCPU::op_and_ildpw() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - aa.b = op_read(OPMODE_DP, dp + 2); //5 - regs.a.l &= op_read(OPMODE_LONG, aa.d); //6 - regs.a.h &= op_read(OPMODE_LONG, aa.d + 1); //6a - flags_and_w(); -} - -/********************** - *** 0x2f: and long *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [4 ] pbr,pc+3 ; aab - [5 ] aab,aa ; data low - [5a] aab,aa+1 ; data high -*/ -void bCPU::op_and_longb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - aa.b = op_read(); //4 - regs.a.l &= op_read(OPMODE_LONG, aa.d); //5 - flags_and_b(); -} - -void bCPU::op_and_longw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - aa.b = op_read(); //4 - regs.a.l &= op_read(OPMODE_LONG, aa.d); //5 - regs.a.h &= op_read(OPMODE_LONG, aa.d + 1); //5a - flags_and_w(); -} - -/************************ - *** 0x3f: and long,x *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [4 ] pbr,pc+3 ; aab - [5 ] aab,aa+x ; data low - [5a] aab,aa+x+1 ; data high -*/ -void bCPU::op_and_longxb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - aa.b = op_read(); //4 - regs.a.l &= op_read(OPMODE_LONG, aa.d + regs.x.w); //5 - flags_and_b(); -} - -void bCPU::op_and_longxw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - aa.b = op_read(); //4 - regs.a.l &= op_read(OPMODE_LONG, aa.d + regs.x.w); //5 - regs.a.h &= op_read(OPMODE_LONG, aa.d + regs.x.w + 1); //5a - flags_and_w(); -} - -/************************ - *** 0x39: and addr,y *** - ************************ -cycles: - [1 ] pbr,pc ; operand - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [3a] dbr,aah,aal+yl ; io [4] - [4 ] dbr,aa+y ; data low - [4a] dbr,aa+y+1 ; data high [1] -*/ -void bCPU::op_and_addryb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_c4(aa.w, aa.w + regs.y.w); //3a - regs.a.l &= op_read(OPMODE_DBR, aa.w + regs.y.w); //4 - flags_and_b(); -} - -void bCPU::op_and_addryw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_c4(aa.w, aa.w + regs.y.w); //3a - regs.a.l &= op_read(OPMODE_DBR, aa.w + regs.y.w); //4 - regs.a.h &= op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //4a - flags_and_w(); -} - -/********************** - *** 0x35: and dp,x *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io - [3 ] pbr,pc+1 ; io - [4 ] 0,d+dp+x ; data low - [4a] 0,d+dp+x+1 ; data high -*/ -void bCPU::op_and_dpxb() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - regs.a.l &= op_read(OPMODE_DP, dp + regs.x.w); //4 - flags_and_b(); -} - -void bCPU::op_and_dpxw() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - regs.a.l &= op_read(OPMODE_DP, dp + regs.x.w); //4 - regs.a.h &= op_read(OPMODE_DP, dp + regs.x.w + 1); //4a - flags_and_w(); -} - -/************************ - *** 0x21: and (dp,x) *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] pbr,pc+1 ; io - [4 ] 0,d+dp+x ; aal - [5 ] 0,d+dp+x+1 ; aah - [6 ] dbr,aa ; data low - [6a] dbr,aa+1 ; data high [1] -*/ -void bCPU::op_and_idpxb() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - aa.l = op_read(OPMODE_DP, dp + regs.x.w); //4 - aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //5 - regs.a.l &= op_read(OPMODE_DBR, aa.w); //6 - flags_and_b(); -} - -void bCPU::op_and_idpxw() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - aa.l = op_read(OPMODE_DP, dp + regs.x.w); //4 - aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //5 - regs.a.l &= op_read(OPMODE_DBR, aa.w); //6 - regs.a.h &= op_read(OPMODE_DBR, aa.w + 1); //6a - flags_and_w(); -} - -/************************ - *** 0x31: and (dp),y *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; aal - [4 ] 0,d+dp+1 ; aah - [4a] dbr,aah,aal+yl ; io [4] - [5 ] dbr,aa+y ; data low - [5a] dbr,aa+y+1 ; data high [1] -*/ -void bCPU::op_and_idpyb() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - cpu_c4(aa.w, aa.w + regs.y.w); //4a - regs.a.l &= op_read(OPMODE_DBR, aa.w + regs.y.w); //5 - flags_and_b(); -} - -void bCPU::op_and_idpyw() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - cpu_c4(aa.w, aa.w + regs.y.w); //4a - regs.a.l &= op_read(OPMODE_DBR, aa.w + regs.y.w); //5 - regs.a.h &= op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //5a - flags_and_w(); -} - -/************************ - *** 0x37: and [dp],y *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; aal - [4 ] 0,d+dp+1 ; aah - [5 ] 0,d+dp+2 ; aab - [6 ] aab,aa+y ; data low - [6a] aab,aa+y+1 ; data high [1] -*/ -void bCPU::op_and_ildpyb() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - aa.b = op_read(OPMODE_DP, dp + 2); //5 - regs.a.l &= op_read(OPMODE_LONG, aa.d + regs.y.w); //6 - flags_and_b(); -} - -void bCPU::op_and_ildpyw() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - aa.b = op_read(OPMODE_DP, dp + 2); //5 - regs.a.l &= op_read(OPMODE_LONG, aa.d + regs.y.w); //6 - regs.a.h &= op_read(OPMODE_LONG, aa.d + regs.y.w + 1); //6a - flags_and_w(); -} - -/********************** - *** 0x23: and sr,s *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; sp - [3 ] pbr,pc+1 ; io - [4 ] 0,s+sp ; data low - [4a] 0,s+sp+1 ; data high [1] -*/ -void bCPU::op_and_srb() { - sp = op_read(); //2 - cpu_io(); //3 - regs.a.l &= op_read(OPMODE_SP, sp); //4 - flags_and_b(); -} - -void bCPU::op_and_srw() { - sp = op_read(); //2 - cpu_io(); //3 - regs.a.l &= op_read(OPMODE_SP, sp); //4 - regs.a.h &= op_read(OPMODE_SP, sp + 1); //4a - flags_and_w(); -} - -/************************** - *** 0x33: and (sr,s),y *** - ************************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; sp - [3 ] pbr,pc+1 ; io - [4 ] 0,s+sp ; aal - [5 ] 0,s+sp+1 ; aah - [6 ] 0,s+sp+1 ; io - [7 ] dbr,aa+y ; data low - [7a] dbr,aa+y+1 ; data high [1] -*/ -void bCPU::op_and_isryb() { - sp = op_read(); //2 - cpu_io(); //3 - aa.l = op_read(OPMODE_SP, sp); //4 - aa.h = op_read(OPMODE_SP, sp + 1); //5 - cpu_io(); //6 - regs.a.l &= op_read(OPMODE_DBR, aa.w + regs.y.w); //7 - flags_and_b(); -} - -void bCPU::op_and_isryw() { - sp = op_read(); //2 - cpu_io(); //3 - aa.l = op_read(OPMODE_SP, sp); //4 - aa.h = op_read(OPMODE_SP, sp + 1); //5 - cpu_io(); //6 - regs.a.l &= op_read(OPMODE_DBR, aa.w + regs.y.w); //7 - regs.a.h &= op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //7a - flags_and_w(); -} diff --git a/src/cpu/bcpu/bcpu_op_cmp.cpp b/src/cpu/bcpu/bcpu_op_cmp.cpp deleted file mode 100644 index fd370f3c..00000000 --- a/src/cpu/bcpu/bcpu_op_cmp.cpp +++ /dev/null @@ -1,448 +0,0 @@ -inline void bCPU::flags_cmp_b() { -int32 r = regs.a.l - rd.l; - regs.p.n = !!(r & 0x80); - regs.p.z = ((uint8)r == 0); - regs.p.c = (r >= 0); -} - -inline void bCPU::flags_cmp_w() { -int32 r = regs.a.w - rd.w; - regs.p.n = !!(r & 0x8000); - regs.p.z = ((uint16)r == 0); - regs.p.c = (r >= 0); -} - -/************************ - *** 0xc9: cmp #const *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; idl - [2a] pbr,pc+2 ; idh [1] -*/ -void bCPU::op_cmp_constb() { - rd.l = op_read(); //2 - flags_cmp_b(); -} - -void bCPU::op_cmp_constw() { - rd.l = op_read(); //2 - rd.h = op_read(); //2a - flags_cmp_w(); -} - -/********************** - *** 0xcd: cmp addr *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [4 ] dbr,aa ; data low - [4a] dbr,aa+1 ; data high [1] -*/ -void bCPU::op_cmp_addrb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - rd.l = op_read(OPMODE_DBR, aa.w); //4 - flags_cmp_b(); -} - -void bCPU::op_cmp_addrw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - rd.l = op_read(OPMODE_DBR, aa.w); //4 - rd.h = op_read(OPMODE_DBR, aa.w + 1); //4a - flags_cmp_w(); -} - -/************************ - *** 0xdd: cmp addr,x *** - ************************ -cycles: - [1 ] pbr,pc ; opercmp - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [3a] dbr,aah,aal+xl ; io [4] - [4 ] dbr,aa+x ; data low - [4a] dbr,aa+x+1 ; data high [1] -*/ -void bCPU::op_cmp_addrxb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_c4(aa.w, aa.w + regs.x.w); //3a - rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //4 - flags_cmp_b(); -} - -void bCPU::op_cmp_addrxw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_c4(aa.w, aa.w + regs.x.w); //3a - rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //4 - rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); //4a - flags_cmp_w(); -} - -/******************** - *** 0xc5: cmp dp *** - ******************** -cycles: - [1 ] pbr,pc ; opercmp - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; data low - [3a] 0,d+dp+1 ; data high [1] -*/ -void bCPU::op_cmp_dpb() { - dp = op_read(); //2 - cpu_c2(); //2a - rd.l = op_read(OPMODE_DP, dp); //3 - flags_cmp_b(); -} - -void bCPU::op_cmp_dpw() { - dp = op_read(); //2 - cpu_c2(); //2a - rd.l = op_read(OPMODE_DP, dp); //3 - rd.h = op_read(OPMODE_DP, dp + 1); //3a - flags_cmp_w(); -} - -/********************** - *** 0xd2: cmp (dp) *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; aal - [4 ] 0,d+dp+1 ; aah - [5 ] dbr,aa ; data low - [5a] dbr,aa+1 ; data high [1] -*/ -void bCPU::op_cmp_idpb() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - rd.l = op_read(OPMODE_DBR, aa.w); //5 - flags_cmp_b(); -} - -void bCPU::op_cmp_idpw() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - rd.l = op_read(OPMODE_DBR, aa.w); //5 - rd.h = op_read(OPMODE_DBR, aa.w + 1); //5 - flags_cmp_w(); -} - -/********************** - *** 0xc7: cmp [dp] *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; aal - [4 ] 0,d+dp+1 ; aah - [5 ] 0,d+dp+2 ; aab - [6 ] aab,aa ; data low - [6a] aab,aa+1 ; data high [1] -*/ -void bCPU::op_cmp_ildpb() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - aa.b = op_read(OPMODE_DP, dp + 2); //5 - rd.l = op_read(OPMODE_LONG, aa.d); //6 - flags_cmp_b(); -} - -void bCPU::op_cmp_ildpw() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - aa.b = op_read(OPMODE_DP, dp + 2); //5 - rd.l = op_read(OPMODE_LONG, aa.d); //6 - rd.h = op_read(OPMODE_LONG, aa.d + 1); //6a - flags_cmp_w(); -} - -/********************** - *** 0xcf: cmp long *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [4 ] pbr,pc+3 ; aab - [5 ] aab,aa ; data low - [5a] aab,aa+1 ; data high -*/ -void bCPU::op_cmp_longb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - aa.b = op_read(); //4 - rd.l = op_read(OPMODE_LONG, aa.d); //5 - flags_cmp_b(); -} - -void bCPU::op_cmp_longw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - aa.b = op_read(); //4 - rd.l = op_read(OPMODE_LONG, aa.d); //5 - rd.h = op_read(OPMODE_LONG, aa.d + 1); //5a - flags_cmp_w(); -} - -/************************ - *** 0xdf: cmp long,x *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [4 ] pbr,pc+3 ; aab - [5 ] aab,aa+x ; data low - [5a] aab,aa+x+1 ; data high -*/ -void bCPU::op_cmp_longxb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - aa.b = op_read(); //4 - rd.l = op_read(OPMODE_LONG, aa.d + regs.x.w); //5 - flags_cmp_b(); -} - -void bCPU::op_cmp_longxw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - aa.b = op_read(); //4 - rd.l = op_read(OPMODE_LONG, aa.d + regs.x.w); //5 - rd.h = op_read(OPMODE_LONG, aa.d + regs.x.w + 1); //5a - flags_cmp_w(); -} - -/************************ - *** 0xd9: cmp addr,y *** - ************************ -cycles: - [1 ] pbr,pc ; opercmp - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [3a] dbr,aah,aal+yl ; io [4] - [4 ] dbr,aa+y ; data low - [4a] dbr,aa+y+1 ; data high [1] -*/ -void bCPU::op_cmp_addryb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_c4(aa.w, aa.w + regs.y.w); //3a - rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //4 - flags_cmp_b(); -} - -void bCPU::op_cmp_addryw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_c4(aa.w, aa.w + regs.y.w); //3a - rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //4 - rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //4a - flags_cmp_w(); -} - -/********************** - *** 0xd5: cmp dp,x *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io - [3 ] pbr,pc+1 ; io - [4 ] 0,d+dp+x ; data low - [4a] 0,d+dp+x+1 ; data high -*/ -void bCPU::op_cmp_dpxb() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4 - flags_cmp_b(); -} - -void bCPU::op_cmp_dpxw() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4 - rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //4a - flags_cmp_w(); -} - -/************************ - *** 0xc1: cmp (dp,x) *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] pbr,pc+1 ; io - [4 ] 0,d+dp+x ; aal - [5 ] 0,d+dp+x+1 ; aah - [6 ] dbr,aa ; data low - [6a] dbr,aa+1 ; data high [1] -*/ -void bCPU::op_cmp_idpxb() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - aa.l = op_read(OPMODE_DP, dp + regs.x.w); //4 - aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //5 - rd.l = op_read(OPMODE_DBR, aa.w); //6 - flags_cmp_b(); -} - -void bCPU::op_cmp_idpxw() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - aa.l = op_read(OPMODE_DP, dp + regs.x.w); //4 - aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //5 - rd.l = op_read(OPMODE_DBR, aa.w); //6 - rd.h = op_read(OPMODE_DBR, aa.w + 1); //6a - flags_cmp_w(); -} - -/************************ - *** 0xd1: cmp (dp),y *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; aal - [4 ] 0,d+dp+1 ; aah - [4a] dbr,aah,aal+yl ; io [4] - [5 ] dbr,aa+y ; data low - [5a] dbr,aa+y+1 ; data high [1] -*/ -void bCPU::op_cmp_idpyb() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - cpu_c4(aa.w, aa.w + regs.y.w); //4a - rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //5 - flags_cmp_b(); -} - -void bCPU::op_cmp_idpyw() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - cpu_c4(aa.w, aa.w + regs.y.w); //4a - rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //5 - rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //5a - flags_cmp_w(); -} - -/************************ - *** 0xd7: cmp [dp],y *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; aal - [4 ] 0,d+dp+1 ; aah - [5 ] 0,d+dp+2 ; aab - [6 ] aab,aa+y ; data low - [6a] aab,aa+y+1 ; data high [1] -*/ -void bCPU::op_cmp_ildpyb() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - aa.b = op_read(OPMODE_DP, dp + 2); //5 - rd.l = op_read(OPMODE_LONG, aa.d + regs.y.w); //6 - flags_cmp_b(); -} - -void bCPU::op_cmp_ildpyw() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - aa.b = op_read(OPMODE_DP, dp + 2); //5 - rd.l = op_read(OPMODE_LONG, aa.d + regs.y.w); //6 - rd.h = op_read(OPMODE_LONG, aa.d + regs.y.w + 1); //6a - flags_cmp_w(); -} - -/********************** - *** 0xc3: cmp sr,s *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; sp - [3 ] pbr,pc+1 ; io - [4 ] 0,s+sp ; data low - [4a] 0,s+sp+1 ; data high [1] -*/ -void bCPU::op_cmp_srb() { - sp = op_read(); //2 - cpu_io(); //3 - rd.l = op_read(OPMODE_SP, sp); //4 - flags_cmp_b(); -} - -void bCPU::op_cmp_srw() { - sp = op_read(); //2 - cpu_io(); //3 - rd.l = op_read(OPMODE_SP, sp); //4 - rd.h = op_read(OPMODE_SP, sp + 1); //4a - flags_cmp_w(); -} - -/************************** - *** 0xd3: cmp (sr,s),y *** - ************************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; sp - [3 ] pbr,pc+1 ; io - [4 ] 0,s+sp ; aal - [5 ] 0,s+sp+1 ; aah - [6 ] 0,s+sp+1 ; io - [7 ] dbr,aa+y ; data low - [7a] dbr,aa+y+1 ; data high [1] -*/ -void bCPU::op_cmp_isryb() { - sp = op_read(); //2 - cpu_io(); //3 - aa.l = op_read(OPMODE_SP, sp); //4 - aa.h = op_read(OPMODE_SP, sp + 1); //5 - cpu_io(); //6 - rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //7 - flags_cmp_b(); -} - -void bCPU::op_cmp_isryw() { - sp = op_read(); //2 - cpu_io(); //3 - aa.l = op_read(OPMODE_SP, sp); //4 - aa.h = op_read(OPMODE_SP, sp + 1); //5 - cpu_io(); //6 - rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //7 - rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //7a - flags_cmp_w(); -} diff --git a/src/cpu/bcpu/bcpu_op_eor.cpp b/src/cpu/bcpu/bcpu_op_eor.cpp deleted file mode 100644 index 98508be7..00000000 --- a/src/cpu/bcpu/bcpu_op_eor.cpp +++ /dev/null @@ -1,444 +0,0 @@ -inline void bCPU::flags_eor_b() { - regs.p.n = !!(regs.a.l & 0x80); - regs.p.z = (regs.a.l == 0); -} - -inline void bCPU::flags_eor_w() { - regs.p.n = !!(regs.a.w & 0x8000); - regs.p.z = (regs.a.w == 0); -} - -/************************ - *** 0x49: eor #const *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; idl - [2a] pbr,pc+2 ; idh [1] -*/ -void bCPU::op_eor_constb() { - regs.a.l ^= op_read(); //2 - flags_eor_b(); -} - -void bCPU::op_eor_constw() { - regs.a.l ^= op_read(); //2 - regs.a.h ^= op_read(); //2a - flags_eor_w(); -} - -/********************** - *** 0x4d: eor addr *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [4 ] dbr,aa ; data low - [4a] dbr,aa+1 ; data high [1] -*/ -void bCPU::op_eor_addrb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - regs.a.l ^= op_read(OPMODE_DBR, aa.w); //4 - flags_eor_b(); -} - -void bCPU::op_eor_addrw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - regs.a.l ^= op_read(OPMODE_DBR, aa.w); //4 - regs.a.h ^= op_read(OPMODE_DBR, aa.w + 1); //4a - flags_eor_w(); -} - -/************************ - *** 0x5d: eor addr,x *** - ************************ -cycles: - [1 ] pbr,pc ; opereor - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [3a] dbr,aah,aal+xl ; io [4] - [4 ] dbr,aa+x ; data low - [4a] dbr,aa+x+1 ; data high [1] -*/ -void bCPU::op_eor_addrxb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_c4(aa.w, aa.w + regs.x.w); //3a - regs.a.l ^= op_read(OPMODE_DBR, aa.w + regs.x.w); //4 - flags_eor_b(); -} - -void bCPU::op_eor_addrxw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_c4(aa.w, aa.w + regs.x.w); //3a - regs.a.l ^= op_read(OPMODE_DBR, aa.w + regs.x.w); //4 - regs.a.h ^= op_read(OPMODE_DBR, aa.w + regs.x.w + 1); //4a - flags_eor_w(); -} - -/******************** - *** 0x45: eor dp *** - ******************** -cycles: - [1 ] pbr,pc ; opereor - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; data low - [3a] 0,d+dp+1 ; data high [1] -*/ -void bCPU::op_eor_dpb() { - dp = op_read(); //2 - cpu_c2(); //2a - regs.a.l ^= op_read(OPMODE_DP, dp); //3 - flags_eor_b(); -} - -void bCPU::op_eor_dpw() { - dp = op_read(); //2 - cpu_c2(); //2a - regs.a.l ^= op_read(OPMODE_DP, dp); //3 - regs.a.h ^= op_read(OPMODE_DP, dp + 1); //3a - flags_eor_w(); -} - -/********************** - *** 0x52: eor (dp) *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; aal - [4 ] 0,d+dp+1 ; aah - [5 ] dbr,aa ; data low - [5a] dbr,aa+1 ; data high [1] -*/ -void bCPU::op_eor_idpb() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - regs.a.l ^= op_read(OPMODE_DBR, aa.w); //5 - flags_eor_b(); -} - -void bCPU::op_eor_idpw() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - regs.a.l ^= op_read(OPMODE_DBR, aa.w); //5 - regs.a.h ^= op_read(OPMODE_DBR, aa.w + 1); //5 - flags_eor_w(); -} - -/********************** - *** 0x47: eor [dp] *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; aal - [4 ] 0,d+dp+1 ; aah - [5 ] 0,d+dp+2 ; aab - [6 ] aab,aa ; data low - [6a] aab,aa+1 ; data high [1] -*/ -void bCPU::op_eor_ildpb() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - aa.b = op_read(OPMODE_DP, dp + 2); //5 - regs.a.l ^= op_read(OPMODE_LONG, aa.d); //6 - flags_eor_b(); -} - -void bCPU::op_eor_ildpw() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - aa.b = op_read(OPMODE_DP, dp + 2); //5 - regs.a.l ^= op_read(OPMODE_LONG, aa.d); //6 - regs.a.h ^= op_read(OPMODE_LONG, aa.d + 1); //6a - flags_eor_w(); -} - -/********************** - *** 0x4f: eor long *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [4 ] pbr,pc+3 ; aab - [5 ] aab,aa ; data low - [5a] aab,aa+1 ; data high -*/ -void bCPU::op_eor_longb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - aa.b = op_read(); //4 - regs.a.l ^= op_read(OPMODE_LONG, aa.d); //5 - flags_eor_b(); -} - -void bCPU::op_eor_longw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - aa.b = op_read(); //4 - regs.a.l ^= op_read(OPMODE_LONG, aa.d); //5 - regs.a.h ^= op_read(OPMODE_LONG, aa.d + 1); //5a - flags_eor_w(); -} - -/************************ - *** 0x5f: eor long,x *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [4 ] pbr,pc+3 ; aab - [5 ] aab,aa+x ; data low - [5a] aab,aa+x+1 ; data high -*/ -void bCPU::op_eor_longxb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - aa.b = op_read(); //4 - regs.a.l ^= op_read(OPMODE_LONG, aa.d + regs.x.w); //5 - flags_eor_b(); -} - -void bCPU::op_eor_longxw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - aa.b = op_read(); //4 - regs.a.l ^= op_read(OPMODE_LONG, aa.d + regs.x.w); //5 - regs.a.h ^= op_read(OPMODE_LONG, aa.d + regs.x.w + 1); //5a - flags_eor_w(); -} - -/************************ - *** 0x59: eor addr,y *** - ************************ -cycles: - [1 ] pbr,pc ; opereor - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [3a] dbr,aah,aal+yl ; io [4] - [4 ] dbr,aa+y ; data low - [4a] dbr,aa+y+1 ; data high [1] -*/ -void bCPU::op_eor_addryb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_c4(aa.w, aa.w + regs.y.w); //3a - regs.a.l ^= op_read(OPMODE_DBR, aa.w + regs.y.w); //4 - flags_eor_b(); -} - -void bCPU::op_eor_addryw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_c4(aa.w, aa.w + regs.y.w); //3a - regs.a.l ^= op_read(OPMODE_DBR, aa.w + regs.y.w); //4 - regs.a.h ^= op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //4a - flags_eor_w(); -} - -/********************** - *** 0x55: eor dp,x *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io - [3 ] pbr,pc+1 ; io - [4 ] 0,d+dp+x ; data low - [4a] 0,d+dp+x+1 ; data high -*/ -void bCPU::op_eor_dpxb() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - regs.a.l ^= op_read(OPMODE_DP, dp + regs.x.w); //4 - flags_eor_b(); -} - -void bCPU::op_eor_dpxw() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - regs.a.l ^= op_read(OPMODE_DP, dp + regs.x.w); //4 - regs.a.h ^= op_read(OPMODE_DP, dp + regs.x.w + 1); //4a - flags_eor_w(); -} - -/************************ - *** 0x41: eor (dp,x) *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] pbr,pc+1 ; io - [4 ] 0,d+dp+x ; aal - [5 ] 0,d+dp+x+1 ; aah - [6 ] dbr,aa ; data low - [6a] dbr,aa+1 ; data high [1] -*/ -void bCPU::op_eor_idpxb() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - aa.l = op_read(OPMODE_DP, dp + regs.x.w); //4 - aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //5 - regs.a.l ^= op_read(OPMODE_DBR, aa.w); //6 - flags_eor_b(); -} - -void bCPU::op_eor_idpxw() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - aa.l = op_read(OPMODE_DP, dp + regs.x.w); //4 - aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //5 - regs.a.l ^= op_read(OPMODE_DBR, aa.w); //6 - regs.a.h ^= op_read(OPMODE_DBR, aa.w + 1); //6a - flags_eor_w(); -} - -/************************ - *** 0x51: eor (dp),y *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; aal - [4 ] 0,d+dp+1 ; aah - [4a] dbr,aah,aal+yl ; io [4] - [5 ] dbr,aa+y ; data low - [5a] dbr,aa+y+1 ; data high [1] -*/ -void bCPU::op_eor_idpyb() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - cpu_c4(aa.w, aa.w + regs.y.w); //4a - regs.a.l ^= op_read(OPMODE_DBR, aa.w + regs.y.w); //5 - flags_eor_b(); -} - -void bCPU::op_eor_idpyw() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - cpu_c4(aa.w, aa.w + regs.y.w); //4a - regs.a.l ^= op_read(OPMODE_DBR, aa.w + regs.y.w); //5 - regs.a.h ^= op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //5a - flags_eor_w(); -} - -/************************ - *** 0x57: eor [dp],y *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; aal - [4 ] 0,d+dp+1 ; aah - [5 ] 0,d+dp+2 ; aab - [6 ] aab,aa+y ; data low - [6a] aab,aa+y+1 ; data high [1] -*/ -void bCPU::op_eor_ildpyb() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - aa.b = op_read(OPMODE_DP, dp + 2); //5 - regs.a.l ^= op_read(OPMODE_LONG, aa.d + regs.y.w); //6 - flags_eor_b(); -} - -void bCPU::op_eor_ildpyw() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - aa.b = op_read(OPMODE_DP, dp + 2); //5 - regs.a.l ^= op_read(OPMODE_LONG, aa.d + regs.y.w); //6 - regs.a.h ^= op_read(OPMODE_LONG, aa.d + regs.y.w + 1); //6a - flags_eor_w(); -} - -/********************** - *** 0x43: eor sr,s *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; sp - [3 ] pbr,pc+1 ; io - [4 ] 0,s+sp ; data low - [4a] 0,s+sp+1 ; data high [1] -*/ -void bCPU::op_eor_srb() { - sp = op_read(); //2 - cpu_io(); //3 - regs.a.l ^= op_read(OPMODE_SP, sp); //4 - flags_eor_b(); -} - -void bCPU::op_eor_srw() { - sp = op_read(); //2 - cpu_io(); //3 - regs.a.l ^= op_read(OPMODE_SP, sp); //4 - regs.a.h ^= op_read(OPMODE_SP, sp + 1); //4a - flags_eor_w(); -} - -/************************** - *** 0x53: eor (sr,s),y *** - ************************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; sp - [3 ] pbr,pc+1 ; io - [4 ] 0,s+sp ; aal - [5 ] 0,s+sp+1 ; aah - [6 ] 0,s+sp+1 ; io - [7 ] dbr,aa+y ; data low - [7a] dbr,aa+y+1 ; data high [1] -*/ -void bCPU::op_eor_isryb() { - sp = op_read(); //2 - cpu_io(); //3 - aa.l = op_read(OPMODE_SP, sp); //4 - aa.h = op_read(OPMODE_SP, sp + 1); //5 - cpu_io(); //6 - regs.a.l ^= op_read(OPMODE_DBR, aa.w + regs.y.w); //7 - flags_eor_b(); -} - -void bCPU::op_eor_isryw() { - sp = op_read(); //2 - cpu_io(); //3 - aa.l = op_read(OPMODE_SP, sp); //4 - aa.h = op_read(OPMODE_SP, sp + 1); //5 - cpu_io(); //6 - regs.a.l ^= op_read(OPMODE_DBR, aa.w + regs.y.w); //7 - regs.a.h ^= op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //7a - flags_eor_w(); -} diff --git a/src/cpu/bcpu/bcpu_op_incdec.cpp b/src/cpu/bcpu/bcpu_op_incdec.cpp deleted file mode 100644 index 64a28e0c..00000000 --- a/src/cpu/bcpu/bcpu_op_incdec.cpp +++ /dev/null @@ -1,433 +0,0 @@ -/***************** - *** 0x1a: inc *** - ***************** -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; io -*/ -void bCPU::op_incb() { - cpu_io(); //2 - regs.a.l++; - regs.p.n = !!(regs.a.l & 0x80); - regs.p.z = (regs.a.l == 0); -} - -void bCPU::op_incw() { - cpu_io(); //2 - regs.a.w++; - regs.p.n = !!(regs.a.w & 0x8000); - regs.p.z = (regs.a.w == 0); -} - -/********************** - *** 0xee: inc addr *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [4 ] dbr,aa ; data low - [4a] dbr,aa+1 ; data high [1] - [5 ] dbr,aa+1 ; io - [6a] dbr,aa+1 ; data high [1] - [6 ] dbr,aa ; data low -*/ -void bCPU::op_inc_addrb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - rd.l = op_read(OPMODE_DBR, aa.w); //4 - rd.l++; - cpu_io(); //5 - op_write(OPMODE_DBR, aa.w, rd.l); //6 - regs.p.n = !!(rd.l & 0x80); - regs.p.z = (rd.l == 0); -} - -void bCPU::op_inc_addrw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - rd.l = op_read(OPMODE_DBR, aa.w); //4 - rd.h = op_read(OPMODE_DBR, aa.w + 1); //4a - rd.w++; - cpu_io(); //5 - op_write(OPMODE_DBR, aa.w + 1, rd.h); //6a - op_write(OPMODE_DBR, aa.w, rd.l); //6 - regs.p.n = !!(rd.w & 0x8000); - regs.p.z = (rd.w == 0); -} - -/************************ - *** 0xfe: inc addr,x *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [4 ] dbr,aah,aal+xl ; io - [5 ] dbr,aa+x ; data low - [5a] dbr,aa+x+1 ; data high [1] - [6 ] dbr,aa+x+1 ; io - [7a] dbr,aa+x+1 ; data high [1] - [7 ] dbr,aa+x ; data low -*/ -void bCPU::op_inc_addrxb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_io(); //4 - rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //5 - rd.l++; - cpu_io(); //6 - op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); //7 - regs.p.n = !!(rd.l & 0x80); - regs.p.z = (rd.l == 0); -} - -void bCPU::op_inc_addrxw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_io(); //4 - rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //5 - rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); //5a - rd.w++; - cpu_io(); //6 - op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h); //7a - op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); //7 - regs.p.n = !!(rd.w & 0x8000); - regs.p.z = (rd.w == 0); -} - -/******************** - *** 0xe6: inc dp *** - ******************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; data low - [3a] 0,d+dp+1 ; data high [1] - [4 ] 0,d+dp+1 ; io - [5a] 0,d+dp+1 ; data high [1] - [5 ] 0,d+dp ; data low -*/ -void bCPU::op_inc_dpb() { - dp = op_read(); //2 - cpu_c2(); //2a - rd.l = op_read(OPMODE_DP, dp); //3 - rd.l++; - cpu_io(); //4 - op_write(OPMODE_DP, dp, rd.l); //5 - regs.p.n = !!(rd.l & 0x80); - regs.p.z = (rd.l == 0); -} - -void bCPU::op_inc_dpw() { - dp = op_read(); //2 - cpu_c2(); //2a - rd.l = op_read(OPMODE_DP, dp); //3 - rd.h = op_read(OPMODE_DP, dp + 1); //3a - rd.w++; - cpu_io(); //4 - op_write(OPMODE_DP, dp + 1, rd.h); //5a - op_write(OPMODE_DP, dp, rd.l); //5 - regs.p.n = !!(rd.w & 0x8000); - regs.p.z = (rd.w == 0); -} - -/********************** - *** 0xf6: inc dp,x *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] pbr,pc+1 ; io - [4 ] 0,d+dp+x ; data low - [4a] 0,d+dp+x+1 ; data high [1] - [5 ] 0,d+dp+x+1 ; io - [6a] 0,d+dp+x+1 ; data high [1] - [6 ] 0,d+dp+x ; data low -*/ -void bCPU::op_inc_dpxb() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4 - rd.l++; - cpu_io(); //5 - op_write(OPMODE_DP, dp + regs.x.w, rd.l); //6 - regs.p.n = !!(rd.l & 0x80); - regs.p.z = (rd.l == 0); -} - -void bCPU::op_inc_dpxw() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4 - rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //4a - rd.w++; - cpu_io(); //5 - op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h); //6a - op_write(OPMODE_DP, dp + regs.x.w, rd.l); //6 - regs.p.n = !!(rd.w & 0x8000); - regs.p.z = (rd.w == 0); -} - -/***************** - *** 0xe8: inx *** - ***************** -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; io -*/ -void bCPU::op_inxb() { - cpu_io(); //2 - regs.x.l++; - regs.p.n = !!(regs.x.l & 0x80); - regs.p.z = (regs.x.l == 0); -} - -void bCPU::op_inxw() { - cpu_io(); //2 - regs.x.w++; - regs.p.n = !!(regs.x.w & 0x8000); - regs.p.z = (regs.x.w == 0); -} - -/***************** - *** 0xc8: iny *** - ***************** -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; io -*/ -void bCPU::op_inyb() { - cpu_io(); //2 - regs.y.l++; - regs.p.n = !!(regs.y.l & 0x80); - regs.p.z = (regs.y.l == 0); -} - -void bCPU::op_inyw() { - cpu_io(); //2 - regs.y.w++; - regs.p.n = !!(regs.y.w & 0x8000); - regs.p.z = (regs.y.w == 0); -} - -/***************** - *** 0x3a: dec *** - ***************** -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; io -*/ -void bCPU::op_decb() { - cpu_io(); //2 - regs.a.l--; - regs.p.n = !!(regs.a.l & 0x80); - regs.p.z = (regs.a.l == 0); -} - -void bCPU::op_decw() { - cpu_io(); //2 - regs.a.w--; - regs.p.n = !!(regs.a.w & 0x8000); - regs.p.z = (regs.a.w == 0); -} - -/********************** - *** 0xce: dec addr *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [4 ] dbr,aa ; data low - [4a] dbr,aa+1 ; data high [1] - [5 ] dbr,aa+1 ; io - [6a] dbr,aa+1 ; data high [1] - [6 ] dbr,aa ; data low -*/ -void bCPU::op_dec_addrb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - rd.l = op_read(OPMODE_DBR, aa.w); //4 - rd.l--; - cpu_io(); //5 - op_write(OPMODE_DBR, aa.w, rd.l); //6 - regs.p.n = !!(rd.l & 0x80); - regs.p.z = (rd.l == 0); -} - -void bCPU::op_dec_addrw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - rd.l = op_read(OPMODE_DBR, aa.w); //4 - rd.h = op_read(OPMODE_DBR, aa.w + 1); //4a - rd.w--; - cpu_io(); //5 - op_write(OPMODE_DBR, aa.w + 1, rd.h); //6a - op_write(OPMODE_DBR, aa.w, rd.l); //6 - regs.p.n = !!(rd.w & 0x8000); - regs.p.z = (rd.w == 0); -} - -/************************ - *** 0xde: dec addr,x *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [4 ] dbr,aah,aal+xl ; io - [5 ] dbr,aa+x ; data low - [5a] dbr,aa+x+1 ; data high [1] - [6 ] dbr,aa+x+1 ; io - [7a] dbr,aa+x+1 ; data high [1] - [7 ] dbr,aa+x ; data low -*/ -void bCPU::op_dec_addrxb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_io(); //4 - rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //5 - rd.l--; - cpu_io(); //6 - op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); //7 - regs.p.n = !!(rd.l & 0x80); - regs.p.z = (rd.l == 0); -} - -void bCPU::op_dec_addrxw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_io(); //4 - rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //5 - rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); //5a - rd.w--; - cpu_io(); //6 - op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h); //7a - op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); //7 - regs.p.n = !!(rd.w & 0x8000); - regs.p.z = (rd.w == 0); -} - -/******************** - *** 0xc6: dec dp *** - ******************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; data low - [3a] 0,d+dp+1 ; data high [1] - [4 ] 0,d+dp+1 ; io - [5a] 0,d+dp+1 ; data high [1] - [5 ] 0,d+dp ; data low -*/ -void bCPU::op_dec_dpb() { - dp = op_read(); //2 - cpu_c2(); //2a - rd.l = op_read(OPMODE_DP, dp); //3 - rd.l--; - cpu_io(); //4 - op_write(OPMODE_DP, dp, rd.l); //5 - regs.p.n = !!(rd.l & 0x80); - regs.p.z = (rd.l == 0); -} - -void bCPU::op_dec_dpw() { - dp = op_read(); //2 - cpu_c2(); //2a - rd.l = op_read(OPMODE_DP, dp); //3 - rd.h = op_read(OPMODE_DP, dp + 1); //3a - rd.w--; - cpu_io(); //4 - op_write(OPMODE_DP, dp + 1, rd.h); //5a - op_write(OPMODE_DP, dp, rd.l); //5 - regs.p.n = !!(rd.w & 0x8000); - regs.p.z = (rd.w == 0); -} - -/********************** - *** 0xd6: dec dp,x *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] pbr,pc+1 ; io - [4 ] 0,d+dp+x ; data low - [4a] 0,d+dp+x+1 ; data high [1] - [5 ] 0,d+dp+x+1 ; io - [6a] 0,d+dp+x+1 ; data high [1] - [6 ] 0,d+dp+x ; data low -*/ -void bCPU::op_dec_dpxb() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4 - rd.l--; - cpu_io(); //5 - op_write(OPMODE_DP, dp + regs.x.w, rd.l); //6 - regs.p.n = !!(rd.l & 0x80); - regs.p.z = (rd.l == 0); -} - -void bCPU::op_dec_dpxw() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4 - rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //4a - rd.w--; - cpu_io(); //5 - op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h); //6a - op_write(OPMODE_DP, dp + regs.x.w, rd.l); //6 - regs.p.n = !!(rd.w & 0x8000); - regs.p.z = (rd.w == 0); -} - -/***************** - *** 0xca: dex *** - ***************** -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; io -*/ -void bCPU::op_dexb() { - cpu_io(); //2 - regs.x.l--; - regs.p.n = !!(regs.x.l & 0x80); - regs.p.z = (regs.x.l == 0); -} - -void bCPU::op_dexw() { - cpu_io(); //2 - regs.x.w--; - regs.p.n = !!(regs.x.w & 0x8000); - regs.p.z = (regs.x.w == 0); -} - -/***************** - *** 0x88: dey *** - ***************** -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; io -*/ -void bCPU::op_deyb() { - cpu_io(); //2 - regs.y.l--; - regs.p.n = !!(regs.y.l & 0x80); - regs.p.z = (regs.y.l == 0); -} - -void bCPU::op_deyw() { - cpu_io(); //2 - regs.y.w--; - regs.p.n = !!(regs.y.w & 0x8000); - regs.p.z = (regs.y.w == 0); -} diff --git a/src/cpu/bcpu/bcpu_op_lda.cpp b/src/cpu/bcpu/bcpu_op_lda.cpp deleted file mode 100644 index 09acc1a6..00000000 --- a/src/cpu/bcpu/bcpu_op_lda.cpp +++ /dev/null @@ -1,444 +0,0 @@ -inline void bCPU::flags_lda_b() { - regs.p.n = !!(regs.a.l & 0x80); - regs.p.z = (regs.a.l == 0); -} - -inline void bCPU::flags_lda_w() { - regs.p.n = !!(regs.a.w & 0x8000); - regs.p.z = (regs.a.w == 0); -} - -/************************ - *** 0xa9: lda #const *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; idl - [2a] pbr,pc+2 ; idh [1] -*/ -void bCPU::op_lda_constb() { - regs.a.l = op_read(); //2 - flags_lda_b(); -} - -void bCPU::op_lda_constw() { - regs.a.l = op_read(); //2 - regs.a.h = op_read(); //2a - flags_lda_w(); -} - -/********************** - *** 0xad: lda addr *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [4 ] dbr,aa ; data low - [4a] dbr,aa+1 ; data high [1] -*/ -void bCPU::op_lda_addrb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - regs.a.l = op_read(OPMODE_DBR, aa.w); //4 - flags_lda_b(); -} - -void bCPU::op_lda_addrw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - regs.a.l = op_read(OPMODE_DBR, aa.w); //4 - regs.a.h = op_read(OPMODE_DBR, aa.w + 1); //4a - flags_lda_w(); -} - -/************************ - *** 0xbd: lda addr,x *** - ************************ -cycles: - [1 ] pbr,pc ; operand - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [3a] dbr,aah,aal+xl ; io [4] - [4 ] dbr,aa+x ; data low - [4a] dbr,aa+x+1 ; data high [1] -*/ -void bCPU::op_lda_addrxb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_c4(aa.w, aa.w + regs.x.w); //3a - regs.a.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //4 - flags_lda_b(); -} - -void bCPU::op_lda_addrxw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_c4(aa.w, aa.w + regs.x.w); //3a - regs.a.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //4 - regs.a.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); //4a - flags_lda_w(); -} - -/******************** - *** 0xa5: lda dp *** - ******************** -cycles: - [1 ] pbr,pc ; operand - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; data low - [3a] 0,d+dp+1 ; data high [1] -*/ -void bCPU::op_lda_dpb() { - dp = op_read(); //2 - cpu_c2(); //2a - regs.a.l = op_read(OPMODE_DP, dp); //3 - flags_lda_b(); -} - -void bCPU::op_lda_dpw() { - dp = op_read(); //2 - cpu_c2(); //2a - regs.a.l = op_read(OPMODE_DP, dp); //3 - regs.a.h = op_read(OPMODE_DP, dp + 1); //3a - flags_lda_w(); -} - -/********************** - *** 0xb2: lda (dp) *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; aal - [4 ] 0,d+dp+1 ; aah - [5 ] dbr,aa ; data low - [5a] dbr,aa+1 ; data high [1] -*/ -void bCPU::op_lda_idpb() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - regs.a.l = op_read(OPMODE_DBR, aa.w); //5 - flags_lda_b(); -} - -void bCPU::op_lda_idpw() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - regs.a.l = op_read(OPMODE_DBR, aa.w); //5 - regs.a.h = op_read(OPMODE_DBR, aa.w + 1); //5 - flags_lda_w(); -} - -/********************** - *** 0xa7: lda [dp] *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; aal - [4 ] 0,d+dp+1 ; aah - [5 ] 0,d+dp+2 ; aab - [6 ] aab,aa ; data low - [6a] aab,aa+1 ; data high [1] -*/ -void bCPU::op_lda_ildpb() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - aa.b = op_read(OPMODE_DP, dp + 2); //5 - regs.a.l = op_read(OPMODE_LONG, aa.d); //6 - flags_lda_b(); -} - -void bCPU::op_lda_ildpw() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - aa.b = op_read(OPMODE_DP, dp + 2); //5 - regs.a.l = op_read(OPMODE_LONG, aa.d); //6 - regs.a.h = op_read(OPMODE_LONG, aa.d + 1); //6a - flags_lda_w(); -} - -/********************** - *** 0xaf: lda long *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [4 ] pbr,pc+3 ; aab - [5 ] aab,aa ; data low - [5a] aab,aa+1 ; data high -*/ -void bCPU::op_lda_longb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - aa.b = op_read(); //4 - regs.a.l = op_read(OPMODE_LONG, aa.d); //5 - flags_lda_b(); -} - -void bCPU::op_lda_longw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - aa.b = op_read(); //4 - regs.a.l = op_read(OPMODE_LONG, aa.d); //5 - regs.a.h = op_read(OPMODE_LONG, aa.d + 1); //5a - flags_lda_w(); -} - -/************************ - *** 0xbf: lda long,x *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [4 ] pbr,pc+3 ; aab - [5 ] aab,aa+x ; data low - [5a] aab,aa+x+1 ; data high -*/ -void bCPU::op_lda_longxb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - aa.b = op_read(); //4 - regs.a.l = op_read(OPMODE_LONG, aa.d + regs.x.w); //5 - flags_lda_b(); -} - -void bCPU::op_lda_longxw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - aa.b = op_read(); //4 - regs.a.l = op_read(OPMODE_LONG, aa.d + regs.x.w); //5 - regs.a.h = op_read(OPMODE_LONG, aa.d + regs.x.w + 1); //5a - flags_lda_w(); -} - -/************************ - *** 0xb9: lda addr,y *** - ************************ -cycles: - [1 ] pbr,pc ; operand - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [3a] dbr,aah,aal+yl ; io [4] - [4 ] dbr,aa+y ; data low - [4a] dbr,aa+y+1 ; data high [1] -*/ -void bCPU::op_lda_addryb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_c4(aa.w, aa.w + regs.y.w); //3a - regs.a.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //4 - flags_lda_b(); -} - -void bCPU::op_lda_addryw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_c4(aa.w, aa.w + regs.y.w); //3a - regs.a.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //4 - regs.a.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //4a - flags_lda_w(); -} - -/********************** - *** 0xb5: lda dp,x *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io - [3 ] pbr,pc+1 ; io - [4 ] 0,d+dp+x ; data low - [4a] 0,d+dp+x+1 ; data high -*/ -void bCPU::op_lda_dpxb() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - regs.a.l = op_read(OPMODE_DP, dp + regs.x.w); //4 - flags_lda_b(); -} - -void bCPU::op_lda_dpxw() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - regs.a.l = op_read(OPMODE_DP, dp + regs.x.w); //4 - regs.a.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //4a - flags_lda_w(); -} - -/************************ - *** 0xa1: lda (dp,x) *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] pbr,pc+1 ; io - [4 ] 0,d+dp+x ; aal - [5 ] 0,d+dp+x+1 ; aah - [6 ] dbr,aa ; data low - [6a] dbr,aa+1 ; data high [1] -*/ -void bCPU::op_lda_idpxb() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - aa.l = op_read(OPMODE_DP, dp + regs.x.w); //4 - aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //5 - regs.a.l = op_read(OPMODE_DBR, aa.w); //6 - flags_lda_b(); -} - -void bCPU::op_lda_idpxw() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - aa.l = op_read(OPMODE_DP, dp + regs.x.w); //4 - aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //5 - regs.a.l = op_read(OPMODE_DBR, aa.w); //6 - regs.a.h = op_read(OPMODE_DBR, aa.w + 1); //6a - flags_lda_w(); -} - -/************************ - *** 0xb1: lda (dp),y *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; aal - [4 ] 0,d+dp+1 ; aah - [4a] dbr,aah,aal+yl ; io [4] - [5 ] dbr,aa+y ; data low - [5a] dbr,aa+y+1 ; data high [1] -*/ -void bCPU::op_lda_idpyb() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - cpu_c4(aa.w, aa.w + regs.y.w); //4a - regs.a.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //5 - flags_lda_b(); -} - -void bCPU::op_lda_idpyw() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - cpu_c4(aa.w, aa.w + regs.y.w); //4a - regs.a.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //5 - regs.a.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //5a - flags_lda_w(); -} - -/************************ - *** 0xb7: lda [dp],y *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; aal - [4 ] 0,d+dp+1 ; aah - [5 ] 0,d+dp+2 ; aab - [6 ] aab,aa+y ; data low - [6a] aab,aa+y+1 ; data high [1] -*/ -void bCPU::op_lda_ildpyb() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - aa.b = op_read(OPMODE_DP, dp + 2); //5 - regs.a.l = op_read(OPMODE_LONG, aa.d + regs.y.w); //6 - flags_lda_b(); -} - -void bCPU::op_lda_ildpyw() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - aa.b = op_read(OPMODE_DP, dp + 2); //5 - regs.a.l = op_read(OPMODE_LONG, aa.d + regs.y.w); //6 - regs.a.h = op_read(OPMODE_LONG, aa.d + regs.y.w + 1); //6a - flags_lda_w(); -} - -/********************** - *** 0xa3: lda sr,s *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; sp - [3 ] pbr,pc+1 ; io - [4 ] 0,s+sp ; data low - [4a] 0,s+sp+1 ; data high [1] -*/ -void bCPU::op_lda_srb() { - sp = op_read(); //2 - cpu_io(); //3 - regs.a.l = op_read(OPMODE_SP, sp); //4 - flags_lda_b(); -} - -void bCPU::op_lda_srw() { - sp = op_read(); //2 - cpu_io(); //3 - regs.a.l = op_read(OPMODE_SP, sp); //4 - regs.a.h = op_read(OPMODE_SP, sp + 1); //4a - flags_lda_w(); -} - -/************************** - *** 0xb3: lda (sr,s),y *** - ************************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; sp - [3 ] pbr,pc+1 ; io - [4 ] 0,s+sp ; aal - [5 ] 0,s+sp+1 ; aah - [6 ] 0,s+sp+1 ; io - [7 ] dbr,aa+y ; data low - [7a] dbr,aa+y+1 ; data high [1] -*/ -void bCPU::op_lda_isryb() { - sp = op_read(); //2 - cpu_io(); //3 - aa.l = op_read(OPMODE_SP, sp); //4 - aa.h = op_read(OPMODE_SP, sp + 1); //5 - cpu_io(); //6 - regs.a.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //7 - flags_lda_b(); -} - -void bCPU::op_lda_isryw() { - sp = op_read(); //2 - cpu_io(); //3 - aa.l = op_read(OPMODE_SP, sp); //4 - aa.h = op_read(OPMODE_SP, sp + 1); //5 - cpu_io(); //6 - regs.a.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //7 - regs.a.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //7a - flags_lda_w(); -} diff --git a/src/cpu/bcpu/bcpu_op_misc.cpp b/src/cpu/bcpu/bcpu_op_misc.cpp index f09ded99..e37c6e5f 100644 --- a/src/cpu/bcpu/bcpu_op_misc.cpp +++ b/src/cpu/bcpu/bcpu_op_misc.cpp @@ -1,829 +1,19 @@ -inline void bCPU::flags_bit_b() { - regs.p.n = !!(rd.l & 0x80); - regs.p.v = !!(rd.l & 0x40); - regs.p.z = ((rd.l & regs.a.l) == 0); +void bCPU::op_nop() { +l1: + cpu_io(); } -inline void bCPU::flags_bit_w() { - regs.p.n = !!(rd.w & 0x8000); - regs.p.v = !!(rd.w & 0x4000); - regs.p.z = ((rd.w & regs.a.w) == 0); +void bCPU::op_wdm() { +l1: + cpu_io(); + regs.pc.w++; } -/************************ - *** 0x89: bit #const *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; idl - [2a] pbr,pc+2 ; idh [1] -*/ -void bCPU::op_bit_constb() { - rd.l = op_read(); //2 - regs.p.z = ((rd.l & regs.a.l) == 0); -} - -void bCPU::op_bit_constw() { - rd.l = op_read(); //2 - rd.h = op_read(); //2a - regs.p.z = ((rd.w & regs.a.w) == 0); -} - -/********************** - *** 0x2c: bit addr *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [4 ] dbr,aa ; data low - [4a] dbr,aa+1 ; data high [1] -*/ -void bCPU::op_bit_addrb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - rd.l = op_read(OPMODE_DBR, aa.w); //4 - flags_bit_b(); -} - -void bCPU::op_bit_addrw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - rd.l = op_read(OPMODE_DBR, aa.w); //4 - rd.h = op_read(OPMODE_DBR, aa.w + 1); //4a - flags_bit_w(); -} - -/************************ - *** 0x3c: bit addr,x *** - ************************ -cycles: - [1 ] pbr,pc ; operand - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [3a] dbr,aah,aal+xl ; io [4] - [4 ] dbr,aa+x ; data low - [4a] dbr,aa+x+1 ; data high [1] -*/ -void bCPU::op_bit_addrxb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_c4(aa.w, aa.w + regs.x.w); //3a - rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //4 - flags_bit_b(); -} - -void bCPU::op_bit_addrxw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_c4(aa.w, aa.w + regs.x.w); //3a - rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //4 - rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); //4a - flags_bit_w(); -} - -/******************** - *** 0x24: bit dp *** - ******************** -cycles: - [1 ] pbr,pc ; operand - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; data low - [3a] 0,d+dp+1 ; data high [1] -*/ -void bCPU::op_bit_dpb() { - dp = op_read(); //2 - cpu_c2(); //2a - rd.l = op_read(OPMODE_DP, dp); //3 - flags_bit_b(); -} - -void bCPU::op_bit_dpw() { - dp = op_read(); //2 - cpu_c2(); //2a - rd.l = op_read(OPMODE_DP, dp); //3 - rd.h = op_read(OPMODE_DP, dp + 1); //3a - flags_bit_w(); -} - -/********************** - *** 0x34: bit dp,x *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io - [3 ] pbr,pc+1 ; io - [4 ] 0,d+dp+x ; data low - [4a] 0,d+dp+x+1 ; data high -*/ -void bCPU::op_bit_dpxb() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4 - flags_bit_b(); -} - -void bCPU::op_bit_dpxw() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4 - rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //4a - flags_bit_w(); -} - -inline void bCPU::flags_cpx_b() { -int32 r = regs.x.l - rd.l; - regs.p.n = !!(r & 0x80); - regs.p.z = ((uint8)r == 0); - regs.p.c = (r >= 0); -} - -inline void bCPU::flags_cpx_w() { -int32 r = regs.x.w - rd.w; - regs.p.n = !!(r & 0x8000); - regs.p.z = ((uint16)r == 0); - regs.p.c = (r >= 0); -} - -/************************ - *** 0xe0: cpx #const *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; idl - [2a] pbr,pc+2 ; idh [1] -*/ -void bCPU::op_cpx_constb() { - rd.l = op_read(); //2 - flags_cpx_b(); -} - -void bCPU::op_cpx_constw() { - rd.l = op_read(); //2 - rd.h = op_read(); //2a - flags_cpx_w(); -} - -/********************** - *** 0xec: cpx addr *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [4 ] dbr,aa ; data low - [4a] dbr,aa+1 ; data high [1] -*/ -void bCPU::op_cpx_addrb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - rd.l = op_read(OPMODE_DBR, aa.w); //4 - flags_cpx_b(); -} - -void bCPU::op_cpx_addrw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - rd.l = op_read(OPMODE_DBR, aa.w); //4 - rd.h = op_read(OPMODE_DBR, aa.w + 1); //4a - flags_cpx_w(); -} - -/******************** - *** 0xe4: cpx dp *** - ******************** -cycles: - [1 ] pbr,pc ; opercmp - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; data low - [3a] 0,d+dp+1 ; data high [1] -*/ -void bCPU::op_cpx_dpb() { - dp = op_read(); //2 - cpu_c2(); //2a - rd.l = op_read(OPMODE_DP, dp); //3 - flags_cpx_b(); -} - -void bCPU::op_cpx_dpw() { - dp = op_read(); //2 - cpu_c2(); //2a - rd.l = op_read(OPMODE_DP, dp); //3 - rd.h = op_read(OPMODE_DP, dp + 1); //3a - flags_cpx_w(); -} - -inline void bCPU::flags_cpy_b() { -int32 r = regs.y.l - rd.l; - regs.p.n = !!(r & 0x80); - regs.p.z = ((uint8)r == 0); - regs.p.c = (r >= 0); -} - -inline void bCPU::flags_cpy_w() { -int32 r = regs.y.w - rd.w; - regs.p.n = !!(r & 0x8000); - regs.p.z = ((uint16)r == 0); - regs.p.c = (r >= 0); -} - -/************************ - *** 0xc0: cpy #const *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; idl - [2a] pbr,pc+2 ; idh [1] -*/ -void bCPU::op_cpy_constb() { - rd.l = op_read(); //2 - flags_cpy_b(); -} - -void bCPU::op_cpy_constw() { - rd.l = op_read(); //2 - rd.h = op_read(); //2a - flags_cpy_w(); -} - -/********************** - *** 0xcc: cpy addr *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [4 ] dbr,aa ; data low - [4a] dbr,aa+1 ; data high [1] -*/ -void bCPU::op_cpy_addrb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - rd.l = op_read(OPMODE_DBR, aa.w); //4 - flags_cpy_b(); -} - -void bCPU::op_cpy_addrw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - rd.l = op_read(OPMODE_DBR, aa.w); //4 - rd.h = op_read(OPMODE_DBR, aa.w + 1); //4a - flags_cpy_w(); -} - -/******************** - *** 0xc4: cpy dp *** - ******************** -cycles: - [1 ] pbr,pc ; opercmp - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; data low - [3a] 0,d+dp+1 ; data high [1] -*/ -void bCPU::op_cpy_dpb() { - dp = op_read(); //2 - cpu_c2(); //2a - rd.l = op_read(OPMODE_DP, dp); //3 - flags_cpy_b(); -} - -void bCPU::op_cpy_dpw() { - dp = op_read(); //2 - cpu_c2(); //2a - rd.l = op_read(OPMODE_DP, dp); //3 - rd.h = op_read(OPMODE_DP, dp + 1); //3a - flags_cpy_w(); -} - -inline void bCPU::flags_ldx_b() { - regs.p.n = !!(regs.x.l & 0x80); - regs.p.z = (regs.x.l == 0); -} - -inline void bCPU::flags_ldx_w() { - regs.p.n = !!(regs.x.w & 0x8000); - regs.p.z = (regs.x.w == 0); -} - -/************************ - *** 0xa2: ldx #const *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; idl - [2a] pbr,pc+2 ; idh [1] -*/ -void bCPU::op_ldx_constb() { - regs.x.l = op_read(); //2 - flags_ldx_b(); -} - -void bCPU::op_ldx_constw() { - regs.x.l = op_read(); //2 - regs.x.h = op_read(); //2a - flags_ldx_w(); -} - -/********************** - *** 0xae: ldx addr *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [4 ] dbr,aa ; data low - [4a] dbr,aa+1 ; data high [1] -*/ -void bCPU::op_ldx_addrb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - regs.x.l = op_read(OPMODE_DBR, aa.w); //4 - flags_ldx_b(); -} - -void bCPU::op_ldx_addrw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - regs.x.l = op_read(OPMODE_DBR, aa.w); //4 - regs.x.h = op_read(OPMODE_DBR, aa.w + 1); //4a - flags_ldx_w(); -} - -/************************ - *** 0xbe: ldx addr,y *** - ************************ -cycles: - [1 ] pbr,pc ; operand - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [3a] dbr,aah,aal+xl ; io [4] - [4 ] dbr,aa+x ; data low - [4a] dbr,aa+x+1 ; data high [1] -*/ -void bCPU::op_ldx_addryb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_c4(aa.w, aa.w + regs.y.w); //3a - regs.x.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //4 - flags_ldx_b(); -} - -void bCPU::op_ldx_addryw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_c4(aa.w, aa.w + regs.y.w); //3a - regs.x.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //4 - regs.x.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //4a - flags_ldx_w(); -} - -/******************** - *** 0xa6: ldx dp *** - ******************** -cycles: - [1 ] pbr,pc ; operand - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; data low - [3a] 0,d+dp+1 ; data high [1] -*/ -void bCPU::op_ldx_dpb() { - dp = op_read(); //2 - cpu_c2(); //2a - regs.x.l = op_read(OPMODE_DP, dp); //3 - flags_ldx_b(); -} - -void bCPU::op_ldx_dpw() { - dp = op_read(); //2 - cpu_c2(); //2a - regs.x.l = op_read(OPMODE_DP, dp); //3 - regs.x.h = op_read(OPMODE_DP, dp + 1); //3a - flags_ldx_w(); -} - -/********************** - *** 0xb6: ldx dp,y *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io - [3 ] pbr,pc+1 ; io - [4 ] 0,d+dp+x ; data low - [4a] 0,d+dp+x+1 ; data high -*/ -void bCPU::op_ldx_dpyb() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - regs.x.l = op_read(OPMODE_DP, dp + regs.y.w); //4 - flags_ldx_b(); -} - -void bCPU::op_ldx_dpyw() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - regs.x.l = op_read(OPMODE_DP, dp + regs.y.w); //4 - regs.x.h = op_read(OPMODE_DP, dp + regs.y.w + 1); //4a - flags_ldx_w(); -} - -inline void bCPU::flags_ldy_b() { - regs.p.n = !!(regs.y.l & 0x80); - regs.p.z = (regs.y.l == 0); -} - -inline void bCPU::flags_ldy_w() { - regs.p.n = !!(regs.y.w & 0x8000); - regs.p.z = (regs.y.w == 0); -} - -/************************ - *** 0xa0: ldy #const *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; idl - [2a] pbr,pc+2 ; idh [1] -*/ -void bCPU::op_ldy_constb() { - regs.y.l = op_read(); //2 - flags_ldy_b(); -} - -void bCPU::op_ldy_constw() { - regs.y.l = op_read(); //2 - regs.y.h = op_read(); //2a - flags_ldy_w(); -} - -/********************** - *** 0xac: ldy addr *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [4 ] dbr,aa ; data low - [4a] dbr,aa+1 ; data high [1] -*/ -void bCPU::op_ldy_addrb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - regs.y.l = op_read(OPMODE_DBR, aa.w); //4 - flags_ldy_b(); -} - -void bCPU::op_ldy_addrw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - regs.y.l = op_read(OPMODE_DBR, aa.w); //4 - regs.y.h = op_read(OPMODE_DBR, aa.w + 1); //4a - flags_ldy_w(); -} - -/************************ - *** 0xbc: ldy addr,x *** - ************************ -cycles: - [1 ] pbr,pc ; operand - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [3a] dbr,aah,aal+xl ; io [4] - [4 ] dbr,aa+x ; data low - [4a] dbr,aa+x+1 ; data high [1] -*/ -void bCPU::op_ldy_addrxb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_c4(aa.w, aa.w + regs.x.w); //3a - regs.y.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //4 - flags_ldy_b(); -} - -void bCPU::op_ldy_addrxw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_c4(aa.w, aa.w + regs.x.w); //3a - regs.y.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //4 - regs.y.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); //4a - flags_ldy_w(); -} - -/******************** - *** 0xa4: ldy dp *** - ******************** -cycles: - [1 ] pbr,pc ; operand - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; data low - [3a] 0,d+dp+1 ; data high [1] -*/ -void bCPU::op_ldy_dpb() { - dp = op_read(); //2 - cpu_c2(); //2a - regs.y.l = op_read(OPMODE_DP, dp); //3 - flags_ldy_b(); -} - -void bCPU::op_ldy_dpw() { - dp = op_read(); //2 - cpu_c2(); //2a - regs.y.l = op_read(OPMODE_DP, dp); //3 - regs.y.h = op_read(OPMODE_DP, dp + 1); //3a - flags_ldy_w(); -} - -/********************** - *** 0xb4: ldy dp,x *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io - [3 ] pbr,pc+1 ; io - [4 ] 0,d+dp+x ; data low - [4a] 0,d+dp+x+1 ; data high -*/ -void bCPU::op_ldy_dpxb() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - regs.y.l = op_read(OPMODE_DP, dp + regs.x.w); //4 - flags_ldy_b(); -} - -void bCPU::op_ldy_dpxw() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - regs.y.l = op_read(OPMODE_DP, dp + regs.x.w); //4 - regs.y.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //4a - flags_ldy_w(); -} - -/********************** - *** 0x8e: stx addr *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [4 ] dbr,aa ; data low - [4a] dbr,aa+1 ; data high [1] -*/ -void bCPU::op_stx_addrb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - op_write(OPMODE_DBR, aa.w, regs.x.l); //4 -} - -void bCPU::op_stx_addrw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - op_write(OPMODE_DBR, aa.w, regs.x.l); //4 - op_write(OPMODE_DBR, aa.w + 1, regs.x.h); //4a -} - -/******************** - *** 0x86: stx dp *** - ******************** -cycles: - [1 ] pbr,pc ; operand - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; data low - [3a] 0,d+dp+1 ; data high [1] -*/ -void bCPU::op_stx_dpb() { - dp = op_read(); //2 - cpu_c2(); //2a - op_write(OPMODE_DP, dp, regs.x.l); //3 -} - -void bCPU::op_stx_dpw() { - dp = op_read(); //2 - cpu_c2(); //2a - op_write(OPMODE_DP, dp, regs.x.l); //3 - op_write(OPMODE_DP, dp + 1, regs.x.h); //3a -} - -/********************** - *** 0x96: stx dp,y *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io - [3 ] pbr,pc+1 ; io - [4 ] 0,d+dp+x ; data low - [4a] 0,d+dp+x+1 ; data high -*/ -void bCPU::op_stx_dpyb() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - op_write(OPMODE_DP, dp + regs.y.w, regs.x.l); //4 -} - -void bCPU::op_stx_dpyw() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - op_write(OPMODE_DP, dp + regs.y.w, regs.x.l); //4 - op_write(OPMODE_DP, dp + regs.y.w + 1, regs.x.h); //4a -} - -/********************** - *** 0x8c: sty addr *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [4 ] dbr,aa ; data low - [4a] dbr,aa+1 ; data high [1] -*/ -void bCPU::op_sty_addrb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - op_write(OPMODE_DBR, aa.w, regs.y.l); //4 -} - -void bCPU::op_sty_addrw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - op_write(OPMODE_DBR, aa.w, regs.y.l); //4 - op_write(OPMODE_DBR, aa.w + 1, regs.y.h); //4a -} - -/******************** - *** 0x84: sty dp *** - ******************** -cycles: - [1 ] pbr,pc ; operand - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; data low - [3a] 0,d+dp+1 ; data high [1] -*/ -void bCPU::op_sty_dpb() { - dp = op_read(); //2 - cpu_c2(); //2a - op_write(OPMODE_DP, dp, regs.y.l); //3 -} - -void bCPU::op_sty_dpw() { - dp = op_read(); //2 - cpu_c2(); //2a - op_write(OPMODE_DP, dp, regs.y.l); //3 - op_write(OPMODE_DP, dp + 1, regs.y.h); //3a -} - -/********************** - *** 0x94: sty dp,x *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io - [3 ] pbr,pc+1 ; io - [4 ] 0,d+dp+x ; data low - [4a] 0,d+dp+x+1 ; data high -*/ -void bCPU::op_sty_dpxb() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - op_write(OPMODE_DP, dp + regs.x.w, regs.y.l); //4 -} - -void bCPU::op_sty_dpxw() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - op_write(OPMODE_DP, dp + regs.x.w, regs.y.l); //4 - op_write(OPMODE_DP, dp + regs.x.w + 1, regs.y.h); //4a -} - -/********************** - *** 0x9c: stz addr *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [4 ] dbr,aa ; data low - [4a] dbr,aa+1 ; data high [1] -*/ -void bCPU::op_stz_addrb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - op_write(OPMODE_DBR, aa.w, 0); //4 -} - -void bCPU::op_stz_addrw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - op_write(OPMODE_DBR, aa.w, 0); //4 - op_write(OPMODE_DBR, aa.w + 1, 0); //4a -} - -/************************ - *** 0x9e: stz addr,x *** - ************************ -cycles: - [1 ] pbr,pc ; operand - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [3a] dbr,aah,aal+xl ; io [4] - [4 ] dbr,aa+x ; data low - [4a] dbr,aa+x+1 ; data high [1] -*/ -void bCPU::op_stz_addrxb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_c4(aa.w, aa.w + regs.x.w); //3a - op_write(OPMODE_DBR, aa.w + regs.x.w, 0); //4 -} - -void bCPU::op_stz_addrxw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_c4(aa.w, aa.w + regs.x.w); //3a - op_write(OPMODE_DBR, aa.w + regs.x.w, 0); //4 - op_write(OPMODE_DBR, aa.w + regs.x.w + 1, 0); //4a -} - -/******************** - *** 0x64: stz dp *** - ******************** -cycles: - [1 ] pbr,pc ; operand - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; data low - [3a] 0,d+dp+1 ; data high [1] -*/ -void bCPU::op_stz_dpb() { - dp = op_read(); //2 - cpu_c2(); //2a - op_write(OPMODE_DP, dp, 0); //3 -} - -void bCPU::op_stz_dpw() { - dp = op_read(); //2 - cpu_c2(); //2a - op_write(OPMODE_DP, dp, 0); //3 - op_write(OPMODE_DP, dp + 1, 0); //3a -} - -/********************** - *** 0x74: stz dp,x *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io - [3 ] pbr,pc+1 ; io - [4 ] 0,d+dp+x ; data low - [4a] 0,d+dp+x+1 ; data high -*/ -void bCPU::op_stz_dpxb() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - op_write(OPMODE_DP, dp + regs.x.w, 0); //4 -} - -void bCPU::op_stz_dpxw() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - op_write(OPMODE_DP, dp + regs.x.w, 0); //4 - op_write(OPMODE_DP, dp + regs.x.w + 1, 0); //4a -} - -/***************** - *** 0xeb: xba *** - ***************** -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; io - [3] pbr,pc+1 ; io -*/ void bCPU::op_xba() { - cpu_io(); //2 - cpu_io(); //3 +l1: + cpu_io(); +l2: + cpu_io(); regs.a.l ^= regs.a.h; regs.a.h ^= regs.a.l; regs.a.l ^= regs.a.h; @@ -831,588 +21,298 @@ void bCPU::op_xba() { regs.p.z = (regs.a.l == 0); } -/********************** - *** 0x1c: trb addr *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [4 ] dbr,aa ; data low - [4a] dbr,aa+1 ; data high [1] - [5 ] dbr,aa+1 ; io - [6a] dbr,aa+1 ; data high [1] - [6 ] dbr,aa ; data low -*/ -void bCPU::op_trb_addrb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - rd.l = op_read(OPMODE_DBR, aa.w); //4 - cpu_io(); //5 - regs.p.z = ((rd.l & regs.a.l) == 0); - rd.l &= ~regs.a.l; - op_write(OPMODE_DBR, aa.w, rd.l); //6 -} - -void bCPU::op_trb_addrw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - rd.l = op_read(OPMODE_DBR, aa.w); //4 - rd.h = op_read(OPMODE_DBR, aa.w + 1); //4a - cpu_io(); //5 - regs.p.z = ((rd.w & regs.a.w) == 0); - rd.w &= ~regs.a.w; - op_write(OPMODE_DBR, aa.w + 1, rd.h); //6a - op_write(OPMODE_DBR, aa.w, rd.l); //6 -} - -/******************** - *** 0x14: trb dp *** - ******************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; data low - [3a] 0,d+dp+1 ; data high [1] - [4 ] 0,d+dp+1 ; io - [5a] 0,d+dp+1 ; data high [1] - [5 ] 0,d+dp ; data low -*/ -void bCPU::op_trb_dpb() { - dp = op_read(); //2 - cpu_c2(); //2a - rd.l = op_read(OPMODE_DP, dp); //3 - cpu_io(); //4 - regs.p.z = ((rd.l & regs.a.l) == 0); - rd.l &= ~regs.a.l; - op_write(OPMODE_DP, dp, rd.l); //5 -} - -void bCPU::op_trb_dpw() { - dp = op_read(); //2 - cpu_c2(); //2a - rd.l = op_read(OPMODE_DP, dp); //3 - rd.h = op_read(OPMODE_DP, dp + 1); //3a - cpu_io(); //4 - regs.p.z = ((rd.w & regs.a.w) == 0); - rd.w &= ~regs.a.w; - op_write(OPMODE_DP, dp + 1, rd.h); //5a - op_write(OPMODE_DP, dp, rd.l); //5 -} - -/********************** - *** 0x0c: tsb addr *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [4 ] dbr,aa ; data low - [4a] dbr,aa+1 ; data high [1] - [5 ] dbr,aa+1 ; io - [6a] dbr,aa+1 ; data high [1] - [6 ] dbr,aa ; data low -*/ -void bCPU::op_tsb_addrb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - rd.l = op_read(OPMODE_DBR, aa.w); //4 - cpu_io(); //5 - regs.p.z = ((rd.l & regs.a.l) == 0); - rd.l |= regs.a.l; - op_write(OPMODE_DBR, aa.w, rd.l); //6 -} - -void bCPU::op_tsb_addrw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - rd.l = op_read(OPMODE_DBR, aa.w); //4 - rd.h = op_read(OPMODE_DBR, aa.w + 1); //4a - cpu_io(); //5 - regs.p.z = ((rd.w & regs.a.w) == 0); - rd.w |= regs.a.w; - op_write(OPMODE_DBR, aa.w + 1, rd.h); //6a - op_write(OPMODE_DBR, aa.w, rd.l); //6 -} - -/******************** - *** 0x04: tsb dp *** - ******************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; data low - [3a] 0,d+dp+1 ; data high [1] - [4 ] 0,d+dp+1 ; io - [5a] 0,d+dp+1 ; data high [1] - [5 ] 0,d+dp ; data low -*/ -void bCPU::op_tsb_dpb() { - dp = op_read(); //2 - cpu_c2(); //2a - rd.l = op_read(OPMODE_DP, dp); //3 - cpu_io(); //4 - regs.p.z = ((rd.l & regs.a.l) == 0); - rd.l |= regs.a.l; - op_write(OPMODE_DP, dp, rd.l); //5 -} - -void bCPU::op_tsb_dpw() { - dp = op_read(); //2 - cpu_c2(); //2a - rd.l = op_read(OPMODE_DP, dp); //3 - rd.h = op_read(OPMODE_DP, dp + 1); //3a - cpu_io(); //4 - regs.p.z = ((rd.w & regs.a.w) == 0); - rd.w |= regs.a.w; - op_write(OPMODE_DP, dp + 1, rd.h); //5a - op_write(OPMODE_DP, dp, rd.l); //5 -} - -/************************** - *** 0x54: mvn src,dest *** - ************************** -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; dba - [3] pbr,pc+2 ; sba - [4] sba,x ; src data - [5] dba,y ; dest data - [6] dba,y ; io - [7] dba,y ; io -*/ void bCPU::op_mvn() { -uint32 src, dest; -uint8 sb, db; - db = op_read(); //2 - sb = op_read(); //3 - regs.db = db; - regs.a.w--; - dest = (db << 16) | regs.y.w; - src = (sb << 16) | regs.x.w; - rd.l = op_read(OPMODE_LONG, src); //4 - op_write(OPMODE_LONG, dest, rd.l); //5 - if(regs.p.x) { - regs.x.l++; - regs.y.l++; - } else { - regs.x.w++; - regs.y.w++; - } - if(regs.a.w != 0xffff) { - regs.pc.w -= 3; - } - cpu_io(); //6 - cpu_io(); //7 +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; } -/************************** - *** 0x44: mvp src,dest *** - ************************** -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; dba - [3] pbr,pc+2 ; sba - [4] sba,x ; src data - [5] dba,y ; dest data - [6] dba,y ; io - [7] dba,y ; io -*/ void bCPU::op_mvp() { -uint32 src, dest; -uint8 sb, db; - db = op_read(); //2 - sb = op_read(); //3 - regs.db = db; - regs.a.w--; - dest = (db << 16) | regs.y.w; - src = (sb << 16) | regs.x.w; - rd.l = op_read(OPMODE_LONG, src); //4 - op_write(OPMODE_LONG, dest, rd.l); //5 - if(regs.p.x) { - regs.x.l--; - regs.y.l--; - } else { - regs.x.w--; - regs.y.w--; - } - if(regs.a.w != 0xffff) { - regs.pc.w -= 3; - } - cpu_io(); //6 - cpu_io(); //7 +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; } -/************************ - *** 0x00: brk #const *** - ************************ -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; signature -* [3] 0,s ; pbr [3] - [4] 0,s-1 ; pch - [5] 0,s-2 ; pcl - [6] 0,s-3 ; p - [7] 0,va ; aavl - [8] 0,va+1 ; aavh -*/ void bCPU::op_brk() { -uint16 aavw = (regs.e)?0xfffe:0xffe6; - op_read(); //2 - stack_write(regs.pc.b); //3 - stack_write(regs.pc.h); //4 - stack_write(regs.pc.l); //5 - stack_write(regs.p); //6 - rd.l = op_read(OPMODE_LONG, aavw ); //7 - rd.h = op_read(OPMODE_LONG, aavw + 1); //8 +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; + regs.p.i = 1; + regs.p.d = 0; } -/************************ - *** 0x02: cop #const *** - ************************ -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; signature -* [3] 0,s ; pbr [3] - [4] 0,s-1 ; pch - [5] 0,s-2 ; pcl - [6] 0,s-3 ; p - [7] 0,va ; aavl - [8] 0,va+1 ; aavh -*/ void bCPU::op_cop() { -uint16 aavw = (regs.e)?0xfff4:0xffe4; - op_read(); //2 - stack_write(regs.pc.b); //3 - stack_write(regs.pc.h); //4 - stack_write(regs.pc.l); //5 - stack_write(regs.p); //6 - rd.l = op_read(OPMODE_LONG, aavw ); //7 - rd.h = op_read(OPMODE_LONG, aavw + 1); //8 +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; + regs.p.i = 1; + regs.p.d = 0; } -/***************** - *** 0xdb: stp *** - ***************** -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; io - [3] pbr,pc+1 ; io -*/ void bCPU::op_stp() { +l1: cpu_io(); + status.cpu_state = CPUSTATE_STP; +l2: cpu_io(); regs.pc.w--; - cpustate = CPUSTATE_STP; } -/***************** - *** 0xcb: wai *** - ***************** -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; io - [3] pbr,pc+1 ; io -*/ void bCPU::op_wai() { +l1: cpu_io(); + status.cpu_state = CPUSTATE_WAI; +l2: cpu_io(); regs.pc.w--; - cpustate = CPUSTATE_WAI; } -/***************** - *** 0xfb: xce *** - ***************** -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; io -*/ void bCPU::op_xce() { +l1: + cpu_io(); bool c = regs.p.c; - cpu_io(); //2 regs.p.c = regs.e; regs.e = c; if(regs.e) { - regs.p.m = 1; - regs.p.x = 1; + regs.p |= 0x30; regs.x.h = 0x00; regs.y.h = 0x00; regs.s.h = 0x01; - optbl = optbl_e; - } else { - switch((regs.p >> 4) & 3) { - case 0:optbl = optbl_mx;break; - case 1:optbl = optbl_mX;break; - case 2:optbl = optbl_Mx;break; - case 3:optbl = optbl_MX;break; - } } } -/***************** - *** 0xea: nop *** - ***************** -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; io -*/ -void bCPU::op_nop() { - cpu_io(); //2 -} - -/***************** - *** 0x42: wdm *** - ***************** -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; io -*/ -void bCPU::op_wdm() { - cpu_io(); - regs.pc.w++; -} - -/***************** - *** 0x18: clc *** - ***************** -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; io -*/ void bCPU::op_clc() { +l1: cpu_io(); regs.p.c = 0; } -/***************** - *** 0xd8: cld *** - ***************** -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; io -*/ void bCPU::op_cld() { +l1: cpu_io(); regs.p.d = 0; } -/***************** - *** 0x58: cli *** - ***************** -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; io -*/ void bCPU::op_cli() { +l1: cpu_io(); regs.p.i = 0; } -/***************** - *** 0xb8: clv *** - ***************** -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; io -*/ void bCPU::op_clv() { +l1: cpu_io(); regs.p.v = 0; } -/***************** - *** 0x38: sec *** - ***************** -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; io -*/ void bCPU::op_sec() { +l1: cpu_io(); regs.p.c = 1; } -/***************** - *** 0xf8: sed *** - ***************** -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; io -*/ void bCPU::op_sed() { +l1: cpu_io(); regs.p.d = 1; } -/***************** - *** 0x78: sei *** - ***************** -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; io -*/ void bCPU::op_sei() { +l1: cpu_io(); regs.p.i = 1; } -/************************ - *** 0xc2: rep #const *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; idl - [2a] pbr,pc+1 ; idl -*/ void bCPU::op_rep() { - rd.l = op_read(); //2 - cpu_io(); //2a - regs.p &= ~rd.l; - if(regs.e) { - regs.p |= 0x30; - } else { - switch((regs.p >> 4) & 3) { - case 0:optbl = optbl_mx;break; - case 1:optbl = optbl_mX;break; - case 2:optbl = optbl_Mx;break; - case 3:optbl = optbl_MX;break; - } - } -} - -/************************ - *** 0xe2: sep #const *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; idl - [2a] pbr,pc+1 ; idl -*/ -void bCPU::op_sep() { - rd.l = op_read(); //2 - cpu_io(); //2a - regs.p |= rd.l; - if(regs.e) { - regs.p |= 0x30; - } else { - switch((regs.p >> 4) & 3) { - case 0:optbl = optbl_mx;break; - case 1:optbl = optbl_mX;break; - case 2:optbl = optbl_Mx;break; - case 3:optbl = optbl_MX;break; - } - } +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; } } -/***************** - *** 0xaa: tax *** - ***************** -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; io -*/ -void bCPU::op_taxb() { - cpu_io(); //2 - regs.x.l = regs.a.l; - regs.p.n = !!(regs.x.l & 0x80); - regs.p.z = (regs.x.l == 0); +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; + } } -void bCPU::op_taxw() { - cpu_io(); //2 - regs.x.w = regs.a.w; - regs.p.n = !!(regs.x.w & 0x8000); - regs.p.z = (regs.x.w == 0); +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); + } } -/***************** - *** 0xa8: tay *** - ***************** -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; io -*/ -void bCPU::op_tayb() { - cpu_io(); //2 - regs.y.l = regs.a.l; - regs.p.n = !!(regs.y.l & 0x80); - regs.p.z = (regs.y.l == 0); +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); + } } -void bCPU::op_tayw() { - cpu_io(); //2 - regs.y.w = regs.a.w; - regs.p.n = !!(regs.y.w & 0x8000); - regs.p.z = (regs.y.w == 0); +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); + } +} + +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); + } +} + +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); + } +} + +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); + } } -/***************** - *** 0x5b: tcd *** - ***************** -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; io -*/ void bCPU::op_tcd() { - cpu_io(); //2 +l1: + cpu_io(); regs.d.w = regs.a.w; regs.p.n = !!(regs.d.w & 0x8000); regs.p.z = (regs.d.w == 0); } -/***************** - *** 0x1b: tcs *** - ***************** -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; io -*/ void bCPU::op_tcs() { - cpu_io(); //2 +l1: + cpu_io(); regs.s.w = regs.a.w; - if(regs.e) { - regs.s.h = 0x01; - } + if(regs.e)regs.s.h = 0x01; } -/***************** - *** 0x7b: tdc *** - ***************** -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; io -*/ void bCPU::op_tdc() { - cpu_io(); //2 +l1: + cpu_io(); regs.a.w = regs.d.w; regs.p.n = !!(regs.a.w & 0x8000); regs.p.z = (regs.a.w == 0); } -/***************** - *** 0x3b: tsc *** - ***************** -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; io -*/ void bCPU::op_tsc() { - cpu_io(); //2 +l1: + cpu_io(); regs.a.w = regs.s.w; if(regs.e) { regs.p.n = !!(regs.a.l & 0x80); @@ -1423,128 +323,229 @@ void bCPU::op_tsc() { } } -/***************** - *** 0xba: tsx *** - ***************** -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; io -*/ -void bCPU::op_tsxb() { - cpu_io(); //2 - regs.x.l = regs.s.l; - regs.p.n = !!(regs.x.l & 0x80); - regs.p.z = (regs.x.l == 0); +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); + } } -void bCPU::op_tsxw() { - cpu_io(); //2 - regs.x.w = regs.s.w; - regs.p.n = !!(regs.x.w & 0x8000); - regs.p.z = (regs.x.w == 0); +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); + } } -/***************** - *** 0x8a: txa *** - ***************** -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; io -*/ -void bCPU::op_txab() { - cpu_io(); //2 - regs.a.l = regs.x.l; - regs.p.n = !!(regs.a.l & 0x80); - regs.p.z = (regs.a.l == 0); +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); } -void bCPU::op_txaw() { - cpu_io(); //2 - regs.a.w = regs.x.w; +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); +} + +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); +} + +void bCPU::op_phd() { +l1: + cpu_io(); + if(0)goto l3; +l2: + stack_write(regs. d.h); +l3: + stack_write(regs. d.l); +} + +void bCPU::op_phb() { +l1: + cpu_io(); +l2: + stack_write(regs.db); +} + +void bCPU::op_phk() { +l1: + cpu_io(); +l2: + stack_write(regs.pc.b); +} + +void bCPU::op_php() { +l1: + cpu_io(); +l2: + stack_write(regs.p); +} + +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; + } +l4: + regs.a.h = stack_read(); regs.p.n = !!(regs.a.w & 0x8000); regs.p.z = (regs.a.w == 0); } -/***************** - *** 0x9a: txs *** - ***************** -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; io -*/ -void bCPU::op_txsb() { - cpu_io(); //2 - regs.s.l = regs.x.l; - regs.p.n = !!(regs.s.l & 0x80); - regs.p.z = (regs.s.l == 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; + } +l4: + regs.x.h = stack_read(); + regs.p.n = !!(regs.x.w & 0x8000); + regs.p.z = (regs.x.w == 0); } -void bCPU::op_txsw() { - cpu_io(); //2 - regs.s.w = regs.x.w; - regs.p.n = !!(regs.s.w & 0x8000); - regs.p.z = (regs.s.w == 0); -} - -/***************** - *** 0x9b: txy *** - ***************** -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; io -*/ -void bCPU::op_txyb() { - cpu_io(); //2 - regs.y.l = regs.x.l; - regs.p.n = !!(regs.y.l & 0x80); - regs.p.z = (regs.y.l == 0); -} - -void bCPU::op_txyw() { - cpu_io(); //2 - regs.y.w = regs.x.w; +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; + } +l4: + regs.y.h = stack_read(); regs.p.n = !!(regs.y.w & 0x8000); regs.p.z = (regs.y.w == 0); } -/***************** - *** 0x98: tya *** - ***************** -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; io -*/ -void bCPU::op_tyab() { - cpu_io(); //2 - regs.a.l = regs.y.l; - regs.p.n = !!(regs.a.l & 0x80); - regs.p.z = (regs.a.l == 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; + } +l4: + regs. d.h = stack_read(); + regs.p.n = !!(regs. d.w & 0x8000); + regs.p.z = (regs. d.w == 0); } -void bCPU::op_tyaw() { - cpu_io(); //2 - regs.a.w = regs.y.w; - regs.p.n = !!(regs.a.w & 0x8000); - regs.p.z = (regs.a.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); } -/***************** - *** 0xbb: tyx *** - ***************** -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; io -*/ -void bCPU::op_tyxb() { - cpu_io(); //2 - regs.x.l = regs.y.l; - regs.p.n = !!(regs.x.l & 0x80); - regs.p.z = (regs.x.l == 0); +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; + } } -void bCPU::op_tyxw() { - cpu_io(); //2 - regs.x.w = regs.y.w; - regs.p.n = !!(regs.x.w & 0x8000); - regs.p.z = (regs.x.w == 0); +void bCPU::op_pea() { +l1: + aa.l = op_read(); +l2: + aa.h = op_read(); +l3: + stack_write(aa.h); +l4: + stack_write(aa.l); } + +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); +} + +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); +} + diff --git a/src/cpu/bcpu/bcpu_op_ora.cpp b/src/cpu/bcpu/bcpu_op_ora.cpp deleted file mode 100644 index 33e86b90..00000000 --- a/src/cpu/bcpu/bcpu_op_ora.cpp +++ /dev/null @@ -1,444 +0,0 @@ -inline void bCPU::flags_ora_b() { - regs.p.n = !!(regs.a.l & 0x80); - regs.p.z = (regs.a.l == 0); -} - -inline void bCPU::flags_ora_w() { - regs.p.n = !!(regs.a.w & 0x8000); - regs.p.z = (regs.a.w == 0); -} - -/************************ - *** 0x09: ora #const *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; idl - [2a] pbr,pc+2 ; idh [1] -*/ -void bCPU::op_ora_constb() { - regs.a.l |= op_read(); //2 - flags_ora_b(); -} - -void bCPU::op_ora_constw() { - regs.a.l |= op_read(); //2 - regs.a.h |= op_read(); //2a - flags_ora_w(); -} - -/********************** - *** 0x0d: ora addr *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [4 ] dbr,aa ; data low - [4a] dbr,aa+1 ; data high [1] -*/ -void bCPU::op_ora_addrb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - regs.a.l |= op_read(OPMODE_DBR, aa.w); //4 - flags_ora_b(); -} - -void bCPU::op_ora_addrw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - regs.a.l |= op_read(OPMODE_DBR, aa.w); //4 - regs.a.h |= op_read(OPMODE_DBR, aa.w + 1); //4a - flags_ora_w(); -} - -/************************ - *** 0x1d: ora addr,x *** - ************************ -cycles: - [1 ] pbr,pc ; operora - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [3a] dbr,aah,aal+xl ; io [4] - [4 ] dbr,aa+x ; data low - [4a] dbr,aa+x+1 ; data high [1] -*/ -void bCPU::op_ora_addrxb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_c4(aa.w, aa.w + regs.x.w); //3a - regs.a.l |= op_read(OPMODE_DBR, aa.w + regs.x.w); //4 - flags_ora_b(); -} - -void bCPU::op_ora_addrxw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_c4(aa.w, aa.w + regs.x.w); //3a - regs.a.l |= op_read(OPMODE_DBR, aa.w + regs.x.w); //4 - regs.a.h |= op_read(OPMODE_DBR, aa.w + regs.x.w + 1); //4a - flags_ora_w(); -} - -/******************** - *** 0x05: ora dp *** - ******************** -cycles: - [1 ] pbr,pc ; operora - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; data low - [3a] 0,d+dp+1 ; data high [1] -*/ -void bCPU::op_ora_dpb() { - dp = op_read(); //2 - cpu_c2(); //2a - regs.a.l |= op_read(OPMODE_DP, dp); //3 - flags_ora_b(); -} - -void bCPU::op_ora_dpw() { - dp = op_read(); //2 - cpu_c2(); //2a - regs.a.l |= op_read(OPMODE_DP, dp); //3 - regs.a.h |= op_read(OPMODE_DP, dp + 1); //3a - flags_ora_w(); -} - -/********************** - *** 0x12: ora (dp) *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; aal - [4 ] 0,d+dp+1 ; aah - [5 ] dbr,aa ; data low - [5a] dbr,aa+1 ; data high [1] -*/ -void bCPU::op_ora_idpb() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - regs.a.l |= op_read(OPMODE_DBR, aa.w); //5 - flags_ora_b(); -} - -void bCPU::op_ora_idpw() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - regs.a.l |= op_read(OPMODE_DBR, aa.w); //5 - regs.a.h |= op_read(OPMODE_DBR, aa.w + 1); //5 - flags_ora_w(); -} - -/********************** - *** 0x07: ora [dp] *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; aal - [4 ] 0,d+dp+1 ; aah - [5 ] 0,d+dp+2 ; aab - [6 ] aab,aa ; data low - [6a] aab,aa+1 ; data high [1] -*/ -void bCPU::op_ora_ildpb() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - aa.b = op_read(OPMODE_DP, dp + 2); //5 - regs.a.l |= op_read(OPMODE_LONG, aa.d); //6 - flags_ora_b(); -} - -void bCPU::op_ora_ildpw() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - aa.b = op_read(OPMODE_DP, dp + 2); //5 - regs.a.l |= op_read(OPMODE_LONG, aa.d); //6 - regs.a.h |= op_read(OPMODE_LONG, aa.d + 1); //6a - flags_ora_w(); -} - -/********************** - *** 0x0f: ora long *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [4 ] pbr,pc+3 ; aab - [5 ] aab,aa ; data low - [5a] aab,aa+1 ; data high -*/ -void bCPU::op_ora_longb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - aa.b = op_read(); //4 - regs.a.l |= op_read(OPMODE_LONG, aa.d); //5 - flags_ora_b(); -} - -void bCPU::op_ora_longw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - aa.b = op_read(); //4 - regs.a.l |= op_read(OPMODE_LONG, aa.d); //5 - regs.a.h |= op_read(OPMODE_LONG, aa.d + 1); //5a - flags_ora_w(); -} - -/************************ - *** 0x1f: ora long,x *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [4 ] pbr,pc+3 ; aab - [5 ] aab,aa+x ; data low - [5a] aab,aa+x+1 ; data high -*/ -void bCPU::op_ora_longxb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - aa.b = op_read(); //4 - regs.a.l |= op_read(OPMODE_LONG, aa.d + regs.x.w); //5 - flags_ora_b(); -} - -void bCPU::op_ora_longxw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - aa.b = op_read(); //4 - regs.a.l |= op_read(OPMODE_LONG, aa.d + regs.x.w); //5 - regs.a.h |= op_read(OPMODE_LONG, aa.d + regs.x.w + 1); //5a - flags_ora_w(); -} - -/************************ - *** 0x19: ora addr,y *** - ************************ -cycles: - [1 ] pbr,pc ; operora - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [3a] dbr,aah,aal+yl ; io [4] - [4 ] dbr,aa+y ; data low - [4a] dbr,aa+y+1 ; data high [1] -*/ -void bCPU::op_ora_addryb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_c4(aa.w, aa.w + regs.y.w); //3a - regs.a.l |= op_read(OPMODE_DBR, aa.w + regs.y.w); //4 - flags_ora_b(); -} - -void bCPU::op_ora_addryw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_c4(aa.w, aa.w + regs.y.w); //3a - regs.a.l |= op_read(OPMODE_DBR, aa.w + regs.y.w); //4 - regs.a.h |= op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //4a - flags_ora_w(); -} - -/********************** - *** 0x15: ora dp,x *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io - [3 ] pbr,pc+1 ; io - [4 ] 0,d+dp+x ; data low - [4a] 0,d+dp+x+1 ; data high -*/ -void bCPU::op_ora_dpxb() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - regs.a.l |= op_read(OPMODE_DP, dp + regs.x.w); //4 - flags_ora_b(); -} - -void bCPU::op_ora_dpxw() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - regs.a.l |= op_read(OPMODE_DP, dp + regs.x.w); //4 - regs.a.h |= op_read(OPMODE_DP, dp + regs.x.w + 1); //4a - flags_ora_w(); -} - -/************************ - *** 0x01: ora (dp,x) *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] pbr,pc+1 ; io - [4 ] 0,d+dp+x ; aal - [5 ] 0,d+dp+x+1 ; aah - [6 ] dbr,aa ; data low - [6a] dbr,aa+1 ; data high [1] -*/ -void bCPU::op_ora_idpxb() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - aa.l = op_read(OPMODE_DP, dp + regs.x.w); //4 - aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //5 - regs.a.l |= op_read(OPMODE_DBR, aa.w); //6 - flags_ora_b(); -} - -void bCPU::op_ora_idpxw() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - aa.l = op_read(OPMODE_DP, dp + regs.x.w); //4 - aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //5 - regs.a.l |= op_read(OPMODE_DBR, aa.w); //6 - regs.a.h |= op_read(OPMODE_DBR, aa.w + 1); //6a - flags_ora_w(); -} - -/************************ - *** 0x11: ora (dp),y *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; aal - [4 ] 0,d+dp+1 ; aah - [4a] dbr,aah,aal+yl ; io [4] - [5 ] dbr,aa+y ; data low - [5a] dbr,aa+y+1 ; data high [1] -*/ -void bCPU::op_ora_idpyb() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - cpu_c4(aa.w, aa.w + regs.y.w); //4a - regs.a.l |= op_read(OPMODE_DBR, aa.w + regs.y.w); //5 - flags_ora_b(); -} - -void bCPU::op_ora_idpyw() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - cpu_c4(aa.w, aa.w + regs.y.w); //4a - regs.a.l |= op_read(OPMODE_DBR, aa.w + regs.y.w); //5 - regs.a.h |= op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //5a - flags_ora_w(); -} - -/************************ - *** 0x17: ora [dp],y *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; aal - [4 ] 0,d+dp+1 ; aah - [5 ] 0,d+dp+2 ; aab - [6 ] aab,aa+y ; data low - [6a] aab,aa+y+1 ; data high [1] -*/ -void bCPU::op_ora_ildpyb() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - aa.b = op_read(OPMODE_DP, dp + 2); //5 - regs.a.l |= op_read(OPMODE_LONG, aa.d + regs.y.w); //6 - flags_ora_b(); -} - -void bCPU::op_ora_ildpyw() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - aa.b = op_read(OPMODE_DP, dp + 2); //5 - regs.a.l |= op_read(OPMODE_LONG, aa.d + regs.y.w); //6 - regs.a.h |= op_read(OPMODE_LONG, aa.d + regs.y.w + 1); //6a - flags_ora_w(); -} - -/********************** - *** 0x03: ora sr,s *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; sp - [3 ] pbr,pc+1 ; io - [4 ] 0,s+sp ; data low - [4a] 0,s+sp+1 ; data high [1] -*/ -void bCPU::op_ora_srb() { - sp = op_read(); //2 - cpu_io(); //3 - regs.a.l |= op_read(OPMODE_SP, sp); //4 - flags_ora_b(); -} - -void bCPU::op_ora_srw() { - sp = op_read(); //2 - cpu_io(); //3 - regs.a.l |= op_read(OPMODE_SP, sp); //4 - regs.a.h |= op_read(OPMODE_SP, sp + 1); //4a - flags_ora_w(); -} - -/************************** - *** 0x13: ora (sr,s),y *** - ************************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; sp - [3 ] pbr,pc+1 ; io - [4 ] 0,s+sp ; aal - [5 ] 0,s+sp+1 ; aah - [6 ] 0,s+sp+1 ; io - [7 ] dbr,aa+y ; data low - [7a] dbr,aa+y+1 ; data high [1] -*/ -void bCPU::op_ora_isryb() { - sp = op_read(); //2 - cpu_io(); //3 - aa.l = op_read(OPMODE_SP, sp); //4 - aa.h = op_read(OPMODE_SP, sp + 1); //5 - cpu_io(); //6 - regs.a.l |= op_read(OPMODE_DBR, aa.w + regs.y.w); //7 - flags_ora_b(); -} - -void bCPU::op_ora_isryw() { - sp = op_read(); //2 - cpu_io(); //3 - aa.l = op_read(OPMODE_SP, sp); //4 - aa.h = op_read(OPMODE_SP, sp + 1); //5 - cpu_io(); //6 - regs.a.l |= op_read(OPMODE_DBR, aa.w + regs.y.w); //7 - regs.a.h |= op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //7a - flags_ora_w(); -} diff --git a/src/cpu/bcpu/bcpu_op_pc.cpp b/src/cpu/bcpu/bcpu_op_pc.cpp index 2ec8b225..c17a7df6 100644 --- a/src/cpu/bcpu/bcpu_op_pc.cpp +++ b/src/cpu/bcpu/bcpu_op_pc.cpp @@ -1,441 +1,310 @@ -/********************** - *** 0x4c: jmp addr *** - ********************** -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; new pcl - [3] pbr,pc+2 ; new pch -*/ +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; + } +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; + } +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; + } +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; + } +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; + } +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; + } +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; + } +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; + } +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; + } +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; +} + void bCPU::op_jmp_addr() { - rd.l = op_read(); //2 - rd.h = op_read(); //3 +l1: + rd.l = op_read(); +l2: + rd.h = op_read(); regs.pc.w = rd.w; } -/********************** - *** 0x5c: jmp long *** - ********************** -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; new pcl - [3] pbr,pc+2 ; new pch - [4] pbr,pc+3 ; new pbr -*/ void bCPU::op_jmp_long() { - rd.l = op_read(); //2 - rd.h = op_read(); //3 - rd.b = op_read(); //4 - regs.pc.d = rd.d; +l1: + rd.l = op_read(); +l2: + rd.h = op_read(); +l3: + rd.b = op_read(); + regs.pc.d = rd.d & 0xffffff; } -/************************ - *** 0x6c: jmp (addr) *** - ************************ -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; aal - [3] pbr,pc+2 ; aah - [4] 0,aa ; new pcl - [5] 0,aa+1 ; new pch -*/ void bCPU::op_jmp_iaddr() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - rd.l = op_read(OPMODE_ADDR, aa.w); //4 - rd.h = op_read(OPMODE_ADDR, aa.w + 1); //5 +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; } -/************************** - *** 0x7c: jmp (addr,x) *** - ************************** -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; aal - [3] pbr,pc+2 ; aah - [4] pbr,pc+2 ; io - [5] pbr,aa+x ; new pcl - [6] pbr,aa+x+1 ; new pch -*/ void bCPU::op_jmp_iaddrx() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_io(); //4 - rd.l = op_read(OPMODE_PBR, aa.w + regs.x.w); //5 - rd.h = op_read(OPMODE_PBR, aa.w + regs.x.w + 1); //6 +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; } -/************************ - *** 0xdc: jmp [addr] *** - ************************ -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; aal - [3] pbr,pc+2 ; aah - [4] 0,aa ; new pcl - [5] 0,aa+1 ; new pch - [6] 0,aa+2 ; new pbr -*/ void bCPU::op_jmp_iladdr() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - rd.l = op_read(OPMODE_ADDR, aa.w); //4 - rd.h = op_read(OPMODE_ADDR, aa.w + 1); //5 - rd.b = op_read(OPMODE_ADDR, aa.w + 2); //6 - regs.pc.d = rd.d; +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; } -/********************** - *** 0x20: jsr addr *** - ********************** -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; new pcl - [3] pbr,pc+2 ; new pch - [4] pbr,pc+2 ; io - [5] 0,s ; pch - [6] 0,s-1 ; pcl -*/ void bCPU::op_jsr_addr() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_io(); //4 +l1: + aa.l = op_read(); +l2: + aa.h = op_read(); +l3: + cpu_io(); +l4: regs.pc.w--; - stack_write(regs.pc.h); //5 - stack_write(regs.pc.l); //6 + stack_write(regs.pc.h); +l5: + stack_write(regs.pc.l); regs.pc.w = aa.w; } -/********************** - *** 0x22: jsr long *** - ********************** -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; new pcl - [3] pbr,pc+2 ; new pch - [4] 0,s ; pbr - [5] 0,s ; io - [6] pbr,pc+3 ; new pbr - [7] 0,s-1 ; pch - [8] 0,s-2 ; pcl -*/ void bCPU::op_jsr_long() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - stack_write(regs.pc.b); //4 - cpu_io(); //5 - aa.b = op_read(); //6 +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); //7 - stack_write(regs.pc.l); //8 - regs.pc.d = aa.d; + stack_write(regs.pc.h); +l7: + stack_write(regs.pc.l); + regs.pc.d = aa.d & 0xffffff; } -/************************** - *** 0xfc: jsr (addr,x) *** - ************************** -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; aal - [3] 0,s ; pch - [4] 0,s-1 ; pcl - [5] pbr,pc+2 ; aah - [6] pbr,pc+2 ; io - [7] pbr,aa+x ; new pcl - [8] pbr,aa+x+1 ; new pch -*/ void bCPU::op_jsr_iaddrx() { - aa.l = op_read(); //2 - stack_write(regs.pc.h); //3 - stack_write(regs.pc.l); //4 - aa.h = op_read(); //5 - cpu_io(); //6 - rd.l = op_read(OPMODE_PBR, aa.w + regs.x.w); //7 - rd.h = op_read(OPMODE_PBR, aa.w + regs.x.w + 1); //8 +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; } -/***************** - *** 0x40: rti *** - ***************** -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; io - [3] pbr,pc+1 ; io - [4] 0,s+1 ; p - [5] 0,s+2 ; new pcl - [6] 0,s+3 ; new pch - [7] 0,s+4 ; pbr [7] -*/ -void bCPU::op_rtie() { - cpu_io(); //2 - cpu_io(); //3 - regs.p = stack_read(); //4 - rd.l = stack_read(); //5 - rd.h = stack_read(); //6 +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; } - regs.pc.w = rd.w; +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_rtin() { - cpu_io(); //2 - cpu_io(); //3 - regs.p = stack_read(); //4 - rd.l = stack_read(); //5 - rd.h = stack_read(); //6 - rd.b = stack_read(); //7 - if(regs.p.x) { - regs.x.h = 0x00; - regs.y.h = 0x00; - } - regs.pc.d = rd.d; - - switch((regs.p >> 4) & 3) { - case 0:optbl = optbl_mx;break; - case 1:optbl = optbl_mX;break; - case 2:optbl = optbl_Mx;break; - case 3:optbl = optbl_MX;break; - } -} - -/***************** - *** 0x60: rts *** - ***************** -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; io - [3] pbr,pc+1 ; io - [4] 0,s+1 ; pcl - [5] 0,s+2 ; pch - [6] 0,s+2 ; io -*/ void bCPU::op_rts() { - cpu_io(); //2 - cpu_io(); //3 - rd.l = stack_read(); //4 - rd.h = stack_read(); //5 - cpu_io(); //6 +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++; } -/***************** - *** 0x6b: rtl *** - ***************** -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; io - [3] pbr,pc+1 ; io - [4] 0,s+1 ; pcl - [5] 0,s+2 ; pch - [6] 0,s+3 ; pbr -*/ void bCPU::op_rtl() { - cpu_io(); //2 - cpu_io(); //3 - rd.l = stack_read(); //4 - rd.h = stack_read(); //5 - rd.b = stack_read(); //6 - regs.pc.d = rd.d; +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++; } -/********************** - *** 0x80: bra near *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; offset - [2a] pbr,pc+1 ; io [5] - [2b] pbr,pc+1 ; io [6] -*/ -void bCPU::op_bra() { -uint16 r; - rd.l = op_read(); //2 - cpu_io(); //2a - r = regs.pc + (int8)rd.l; - cpu_c6(r); //2b - regs.pc.w = r; -} - -/********************* - *** 0x82: brl far *** - ********************* -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; offset low - [3] pbr,pc+2 ; offset high - [4] pbr,pc+2 ; io -*/ -void bCPU::op_brl() { -uint16 r; - rd.l = op_read(); //2 - rd.h = op_read(); //3 - cpu_io(); //4 - r = regs.pc + (int16)rd.w; - regs.pc.w = r; -} - -/********************** - *** 0x90: bcc near *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; offset - [2a] pbr,pc+1 ; io [5] - [2b] pbr,pc+1 ; io [6] -*/ -void bCPU::op_bcc() { -uint16 r; - rd.l = op_read(); //2 - if(!regs.p.c) { - cpu_io(); //2a - r = regs.pc + (int8)rd.l; - cpu_c6(r); //2b - regs.pc.w = r; - } -} - -/********************** - *** 0xb0: bcs near *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; offset - [2a] pbr,pc+1 ; io [5] - [2b] pbr,pc+1 ; io [6] -*/ -void bCPU::op_bcs() { -uint16 r; - rd.l = op_read(); //2 - if(regs.p.c) { - cpu_io(); //2a - r = regs.pc + (int8)rd.l; - cpu_c6(r); //2b - regs.pc.w = r; - } -} - -/********************** - *** 0xd0: bne near *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; offset - [2a] pbr,pc+1 ; io [5] - [2b] pbr,pc+1 ; io [6] -*/ -void bCPU::op_bne() { -uint16 r; - rd.l = op_read(); //2 - if(!regs.p.z) { - cpu_io(); //2a - r = regs.pc + (int8)rd.l; - cpu_c6(r); //2b - regs.pc.w = r; - } -} - -/********************** - *** 0xf0: beq near *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; offset - [2a] pbr,pc+1 ; io [5] - [2b] pbr,pc+1 ; io [6] -*/ -void bCPU::op_beq() { -uint16 r; - rd.l = op_read(); //2 - if(regs.p.z) { - cpu_io(); //2a - r = regs.pc + (int8)rd.l; - cpu_c6(r); //2b - regs.pc.w = r; - } -} - -/********************** - *** 0x10: bpl near *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; offset - [2a] pbr,pc+1 ; io [5] - [2b] pbr,pc+1 ; io [6] -*/ -void bCPU::op_bpl() { -uint16 r; - rd.l = op_read(); //2 - if(!regs.p.n) { - cpu_io(); //2a - r = regs.pc + (int8)rd.l; - cpu_c6(r); //2b - regs.pc.w = r; - } -} - -/********************** - *** 0x30: bmi near *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; offset - [2a] pbr,pc+1 ; io [5] - [2b] pbr,pc+1 ; io [6] -*/ -void bCPU::op_bmi() { -uint16 r; - rd.l = op_read(); //2 - if(regs.p.n) { - cpu_io(); //2a - r = regs.pc + (int8)rd.l; - cpu_c6(r); //2b - regs.pc.w = r; - } -} - -/********************** - *** 0x50: bvc near *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; offset - [2a] pbr,pc+1 ; io [5] - [2b] pbr,pc+1 ; io [6] -*/ -void bCPU::op_bvc() { -uint16 r; - rd.l = op_read(); //2 - if(!regs.p.v) { - cpu_io(); //2a - r = regs.pc + (int8)rd.l; - cpu_c6(r); //2b - regs.pc.w = r; - } -} - -/********************** - *** 0x70: bvs near *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; offset - [2a] pbr,pc+1 ; io [5] - [2b] pbr,pc+1 ; io [6] -*/ -void bCPU::op_bvs() { -uint16 r; - rd.l = op_read(); //2 - if(regs.p.v) { - cpu_io(); //2a - r = regs.pc + (int8)rd.l; - cpu_c6(r); //2b - regs.pc.w = r; - } -} diff --git a/src/cpu/bcpu/bcpu_op_read.cpp b/src/cpu/bcpu/bcpu_op_read.cpp new file mode 100644 index 00000000..d670a879 --- /dev/null +++ b/src/cpu/bcpu/bcpu_op_read.cpp @@ -0,0 +1,1913 @@ +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +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(); +} + +void bCPU::op_bit_const() { +l1: + rd.l = op_read(); + if(regs.p.m) { + regs.p.z = ((rd.l & regs.a.l) == 0); + return; + } +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 new file mode 100644 index 00000000..6c4af89a --- /dev/null +++ b/src/cpu/bcpu/bcpu_op_rmw.cpp @@ -0,0 +1,740 @@ +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); + } +} + +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); + } +} + +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); + } +} + +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); + } +} + +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); + } +} + +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); + } +} + +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); + } +} + +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); + } +} + +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); + } +} + +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); + } +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + diff --git a/src/cpu/bcpu/bcpu_op_sbc.cpp b/src/cpu/bcpu/bcpu_op_sbc.cpp deleted file mode 100644 index 012a7ff5..00000000 --- a/src/cpu/bcpu/bcpu_op_sbc.cpp +++ /dev/null @@ -1,464 +0,0 @@ -inline void bCPU::flags_sbc_b() { -int32 r = regs.a.l - rd.l - !regs.p.c; -//bcd - if(regs.p.d) { - if(((r ) & 15) > 9)r -= 6; - if(((r >> 4) & 15) > 9)r -= 6 << 4; - } - regs.p.n = !!(r & 0x80); - regs.p.v = !!((regs.a.l ^ rd.l) & (regs.a.l ^ r) & 0x80); - regs.p.z = ((byte)r == 0); - regs.p.c = (r >= 0); - regs.a.l = r; -} - -inline void bCPU::flags_sbc_w() { -int32 r = regs.a.w - rd.w - !regs.p.c; -//bcd - if(regs.p.d) { - if(((r ) & 15) > 9)r -= 6; - if(((r >> 4) & 15) > 9)r -= 6 << 4; - if(((r >> 8) & 15) > 9)r -= 6 << 8; - if(((r >> 12) & 15) > 9)r -= 6 << 12; - } - regs.p.n = !!(r & 0x8000); - regs.p.v = !!((regs.a.w ^ rd.w) & (regs.a.w ^ r) & 0x8000); - regs.p.z = ((word)r == 0); - regs.p.c = (r >= 0); - regs.a.w = r; -} - -/************************ - *** 0xe9: sbc #const *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; idl - [2a] pbr,pc+2 ; idh [1] -*/ -void bCPU::op_sbc_constb() { - rd.l = op_read(); //2 - flags_sbc_b(); -} - -void bCPU::op_sbc_constw() { - rd.l = op_read(); //2 - rd.h = op_read(); //2a - flags_sbc_w(); -} - -/********************** - *** 0xed: sbc addr *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [4 ] dbr,aa ; data low - [4a] dbr,aa+1 ; data high [1] -*/ -void bCPU::op_sbc_addrb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - rd.l = op_read(OPMODE_DBR, aa.w); //4 - flags_sbc_b(); -} - -void bCPU::op_sbc_addrw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - rd.l = op_read(OPMODE_DBR, aa.w); //4 - rd.h = op_read(OPMODE_DBR, aa.w + 1); //4a - flags_sbc_w(); -} - -/************************ - *** 0xfd: sbc addr,x *** - ************************ -cycles: - [1 ] pbr,pc ; opersbc - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [3a] dbr,aah,aal+xl ; io [4] - [4 ] dbr,aa+x ; data low - [4a] dbr,aa+x+1 ; data high [1] -*/ -void bCPU::op_sbc_addrxb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_c4(aa.w, aa.w + regs.x.w); //3a - rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //4 - flags_sbc_b(); -} - -void bCPU::op_sbc_addrxw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_c4(aa.w, aa.w + regs.x.w); //3a - rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //4 - rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); //4a - flags_sbc_w(); -} - -/******************** - *** 0xe5: sbc dp *** - ******************** -cycles: - [1 ] pbr,pc ; opersbc - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; data low - [3a] 0,d+dp+1 ; data high [1] -*/ -void bCPU::op_sbc_dpb() { - dp = op_read(); //2 - cpu_c2(); //2a - rd.l = op_read(OPMODE_DP, dp); //3 - flags_sbc_b(); -} - -void bCPU::op_sbc_dpw() { - dp = op_read(); //2 - cpu_c2(); //2a - rd.l = op_read(OPMODE_DP, dp); //3 - rd.h = op_read(OPMODE_DP, dp + 1); //3a - flags_sbc_w(); -} - -/********************** - *** 0xf2: sbc (dp) *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; aal - [4 ] 0,d+dp+1 ; aah - [5 ] dbr,aa ; data low - [5a] dbr,aa+1 ; data high [1] -*/ -void bCPU::op_sbc_idpb() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - rd.l = op_read(OPMODE_DBR, aa.w); //5 - flags_sbc_b(); -} - -void bCPU::op_sbc_idpw() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - rd.l = op_read(OPMODE_DBR, aa.w); //5 - rd.h = op_read(OPMODE_DBR, aa.w + 1); //5 - flags_sbc_w(); -} - -/********************** - *** 0xe7: sbc [dp] *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; aal - [4 ] 0,d+dp+1 ; aah - [5 ] 0,d+dp+2 ; aab - [6 ] aab,aa ; data low - [6a] aab,aa+1 ; data high [1] -*/ -void bCPU::op_sbc_ildpb() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - aa.b = op_read(OPMODE_DP, dp + 2); //5 - rd.l = op_read(OPMODE_LONG, aa.d); //6 - flags_sbc_b(); -} - -void bCPU::op_sbc_ildpw() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - aa.b = op_read(OPMODE_DP, dp + 2); //5 - rd.l = op_read(OPMODE_LONG, aa.d); //6 - rd.h = op_read(OPMODE_LONG, aa.d + 1); //6a - flags_sbc_w(); -} - -/********************** - *** 0xef: sbc long *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [4 ] pbr,pc+3 ; aab - [5 ] aab,aa ; data low - [5a] aab,aa+1 ; data high -*/ -void bCPU::op_sbc_longb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - aa.b = op_read(); //4 - rd.l = op_read(OPMODE_LONG, aa.d); //5 - flags_sbc_b(); -} - -void bCPU::op_sbc_longw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - aa.b = op_read(); //4 - rd.l = op_read(OPMODE_LONG, aa.d); //5 - rd.h = op_read(OPMODE_LONG, aa.d + 1); //5a - flags_sbc_w(); -} - -/************************ - *** 0xff: sbc long,x *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [4 ] pbr,pc+3 ; aab - [5 ] aab,aa+x ; data low - [5a] aab,aa+x+1 ; data high -*/ -void bCPU::op_sbc_longxb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - aa.b = op_read(); //4 - rd.l = op_read(OPMODE_LONG, aa.d + regs.x.w); //5 - flags_sbc_b(); -} - -void bCPU::op_sbc_longxw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - aa.b = op_read(); //4 - rd.l = op_read(OPMODE_LONG, aa.d + regs.x.w); //5 - rd.h = op_read(OPMODE_LONG, aa.d + regs.x.w + 1); //5a - flags_sbc_w(); -} - -/************************ - *** 0xf9: sbc addr,y *** - ************************ -cycles: - [1 ] pbr,pc ; opersbc - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [3a] dbr,aah,aal+yl ; io [4] - [4 ] dbr,aa+y ; data low - [4a] dbr,aa+y+1 ; data high [1] -*/ -void bCPU::op_sbc_addryb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_c4(aa.w, aa.w + regs.y.w); //3a - rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //4 - flags_sbc_b(); -} - -void bCPU::op_sbc_addryw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_c4(aa.w, aa.w + regs.y.w); //3a - rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //4 - rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //4a - flags_sbc_w(); -} - -/********************** - *** 0xf5: sbc dp,x *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io - [3 ] pbr,pc+1 ; io - [4 ] 0,d+dp+x ; data low - [4a] 0,d+dp+x+1 ; data high -*/ -void bCPU::op_sbc_dpxb() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4 - flags_sbc_b(); -} - -void bCPU::op_sbc_dpxw() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4 - rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //4a - flags_sbc_w(); -} - -/************************ - *** 0xe1: sbc (dp,x) *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] pbr,pc+1 ; io - [4 ] 0,d+dp+x ; aal - [5 ] 0,d+dp+x+1 ; aah - [6 ] dbr,aa ; data low - [6a] dbr,aa+1 ; data high [1] -*/ -void bCPU::op_sbc_idpxb() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - aa.l = op_read(OPMODE_DP, dp + regs.x.w); //4 - aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //5 - rd.l = op_read(OPMODE_DBR, aa.w); //6 - flags_sbc_b(); -} - -void bCPU::op_sbc_idpxw() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - aa.l = op_read(OPMODE_DP, dp + regs.x.w); //4 - aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //5 - rd.l = op_read(OPMODE_DBR, aa.w); //6 - rd.h = op_read(OPMODE_DBR, aa.w + 1); //6a - flags_sbc_w(); -} - -/************************ - *** 0xf1: sbc (dp),y *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; aal - [4 ] 0,d+dp+1 ; aah - [4a] dbr,aah,aal+yl ; io [4] - [5 ] dbr,aa+y ; data low - [5a] dbr,aa+y+1 ; data high [1] -*/ -void bCPU::op_sbc_idpyb() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - cpu_c4(aa.w, aa.w + regs.y.w); //4a - rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //5 - flags_sbc_b(); -} - -void bCPU::op_sbc_idpyw() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - cpu_c4(aa.w, aa.w + regs.y.w); //4a - rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //5 - rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //5a - flags_sbc_w(); -} - -/************************ - *** 0xf7: sbc [dp],y *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; aal - [4 ] 0,d+dp+1 ; aah - [5 ] 0,d+dp+2 ; aab - [6 ] aab,aa+y ; data low - [6a] aab,aa+y+1 ; data high [1] -*/ -void bCPU::op_sbc_ildpyb() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - aa.b = op_read(OPMODE_DP, dp + 2); //5 - rd.l = op_read(OPMODE_LONG, aa.d + regs.y.w); //6 - flags_sbc_b(); -} - -void bCPU::op_sbc_ildpyw() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - aa.b = op_read(OPMODE_DP, dp + 2); //5 - rd.l = op_read(OPMODE_LONG, aa.d + regs.y.w); //6 - rd.h = op_read(OPMODE_LONG, aa.d + regs.y.w + 1); //6a - flags_sbc_w(); -} - -/********************** - *** 0xe3: sbc sr,s *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; sp - [3 ] pbr,pc+1 ; io - [4 ] 0,s+sp ; data low - [4a] 0,s+sp+1 ; data high [1] -*/ -void bCPU::op_sbc_srb() { - sp = op_read(); //2 - cpu_io(); //3 - rd.l = op_read(OPMODE_SP, sp); //4 - flags_sbc_b(); -} - -void bCPU::op_sbc_srw() { - sp = op_read(); //2 - cpu_io(); //3 - rd.l = op_read(OPMODE_SP, sp); //4 - rd.h = op_read(OPMODE_SP, sp + 1); //4a - flags_sbc_w(); -} - -/************************** - *** 0xf3: sbc (sr,s),y *** - ************************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; sp - [3 ] pbr,pc+1 ; io - [4 ] 0,s+sp ; aal - [5 ] 0,s+sp+1 ; aah - [6 ] 0,s+sp+1 ; io - [7 ] dbr,aa+y ; data low - [7a] dbr,aa+y+1 ; data high [1] -*/ -void bCPU::op_sbc_isryb() { - sp = op_read(); //2 - cpu_io(); //3 - aa.l = op_read(OPMODE_SP, sp); //4 - aa.h = op_read(OPMODE_SP, sp + 1); //5 - cpu_io(); //6 - rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //7 - flags_sbc_b(); -} - -void bCPU::op_sbc_isryw() { - sp = op_read(); //2 - cpu_io(); //3 - aa.l = op_read(OPMODE_SP, sp); //4 - aa.h = op_read(OPMODE_SP, sp + 1); //5 - cpu_io(); //6 - rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //7 - rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //7a - flags_sbc_w(); -} diff --git a/src/cpu/bcpu/bcpu_op_shift.cpp b/src/cpu/bcpu/bcpu_op_shift.cpp deleted file mode 100644 index 23171da3..00000000 --- a/src/cpu/bcpu/bcpu_op_shift.cpp +++ /dev/null @@ -1,779 +0,0 @@ -/***************** - *** 0x0a: asl *** - ***************** -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; io -*/ -void bCPU::op_aslb() { - cpu_io(); //2 - 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); -} - -void bCPU::op_aslw() { - cpu_io(); //2 - 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); -} - -/********************** - *** 0x0e: asl addr *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [4 ] dbr,aa ; data low - [4a] dbr,aa+1 ; data high [1] - [5 ] dbr,aa+1 ; io - [6a] dbr,aa+1 ; data high [1] - [6 ] dbr,aa ; data low -*/ -void bCPU::op_asl_addrb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - rd.l = op_read(OPMODE_DBR, aa.w); //4 - regs.p.c = !!(rd.l & 0x80); - rd.l <<= 1; - cpu_io(); //5 - op_write(OPMODE_DBR, aa.w, rd.l); //6 - regs.p.n = !!(rd.l & 0x80); - regs.p.z = (rd.l == 0); -} - -void bCPU::op_asl_addrw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - rd.l = op_read(OPMODE_DBR, aa.w); //4 - rd.h = op_read(OPMODE_DBR, aa.w + 1); //4a - regs.p.c = !!(rd.w & 0x8000); - rd.w <<= 1; - cpu_io(); //5 - op_write(OPMODE_DBR, aa.w + 1, rd.h); //6a - op_write(OPMODE_DBR, aa.w, rd.l); //6 - regs.p.n = !!(rd.w & 0x8000); - regs.p.z = (rd.w == 0); -} - -/************************ - *** 0x1e: asl addr,x *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [4 ] dbr,aah,aal+xl ; io - [5 ] dbr,aa+x ; data low - [5a] dbr,aa+x+1 ; data high [1] - [6 ] dbr,aa+x+1 ; io - [7a] dbr,aa+x+1 ; data high [1] - [7 ] dbr,aa+x ; data low -*/ -void bCPU::op_asl_addrxb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_io(); //4 - rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //5 - regs.p.c = !!(rd.l & 0x80); - rd.l <<= 1; - cpu_io(); //6 - op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); //7 - regs.p.n = !!(rd.l & 0x80); - regs.p.z = (rd.l == 0); -} - -void bCPU::op_asl_addrxw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_io(); //4 - rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //5 - rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); //5a - regs.p.c = !!(rd.w & 0x8000); - rd.w <<= 1; - cpu_io(); //6 - op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h); //7a - op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); //7 - regs.p.n = !!(rd.w & 0x8000); - regs.p.z = (rd.w == 0); -} - -/******************** - *** 0x06: asl dp *** - ******************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; data low - [3a] 0,d+dp+1 ; data high [1] - [4 ] 0,d+dp+1 ; io - [5a] 0,d+dp+1 ; data high [1] - [5 ] 0,d+dp ; data low -*/ -void bCPU::op_asl_dpb() { - dp = op_read(); //2 - cpu_c2(); //2a - rd.l = op_read(OPMODE_DP, dp); //3 - regs.p.c = !!(rd.l & 0x80); - rd.l <<= 1; - cpu_io(); //4 - op_write(OPMODE_DP, dp, rd.l); //5 - regs.p.n = !!(rd.l & 0x80); - regs.p.z = (rd.l == 0); -} - -void bCPU::op_asl_dpw() { - dp = op_read(); //2 - cpu_c2(); //2a - rd.l = op_read(OPMODE_DP, dp); //3 - rd.h = op_read(OPMODE_DP, dp + 1); //3a - regs.p.c = !!(rd.w & 0x8000); - rd.w <<= 1; - cpu_io(); //4 - op_write(OPMODE_DP, dp + 1, rd.h); //5a - op_write(OPMODE_DP, dp, rd.l); //5 - regs.p.n = !!(rd.w & 0x8000); - regs.p.z = (rd.w == 0); -} - -/********************** - *** 0x16: asl dp,x *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] pbr,pc+1 ; io - [4 ] 0,d+dp+x ; data low - [4a] 0,d+dp+x+1 ; data high [1] - [5 ] 0,d+dp+x+1 ; io - [6a] 0,d+dp+x+1 ; data high [1] - [6 ] 0,d+dp+x ; data low -*/ -void bCPU::op_asl_dpxb() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4 - regs.p.c = !!(rd.l & 0x80); - rd.l <<= 1; - cpu_io(); //5 - op_write(OPMODE_DP, dp + regs.x.w, rd.l); //6 - regs.p.n = !!(rd.l & 0x80); - regs.p.z = (rd.l == 0); -} - -void bCPU::op_asl_dpxw() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4 - rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //4a - regs.p.c = !!(rd.w & 0x8000); - rd.w <<= 1; - cpu_io(); //5 - op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h); //6a - op_write(OPMODE_DP, dp + regs.x.w, rd.l); //6 - regs.p.n = !!(rd.w & 0x8000); - regs.p.z = (rd.w == 0); -} - -/***************** - *** 0x4a: lsr *** - ***************** -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; io -*/ -void bCPU::op_lsrb() { - cpu_io(); //2 - 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); -} - -void bCPU::op_lsrw() { - cpu_io(); //2 - 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); -} - -/********************** - *** 0x4e: lsr addr *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [4 ] dbr,aa ; data low - [4a] dbr,aa+1 ; data high [1] - [5 ] dbr,aa+1 ; io - [6a] dbr,aa+1 ; data high [1] - [6 ] dbr,aa ; data low -*/ -void bCPU::op_lsr_addrb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - rd.l = op_read(OPMODE_DBR, aa.w); //4 - regs.p.c = rd.l & 1; - rd.l >>= 1; - cpu_io(); //5 - op_write(OPMODE_DBR, aa.w, rd.l); //6 - regs.p.n = !!(rd.l & 0x80); - regs.p.z = (rd.l == 0); -} - -void bCPU::op_lsr_addrw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - rd.l = op_read(OPMODE_DBR, aa.w); //4 - rd.h = op_read(OPMODE_DBR, aa.w + 1); //4a - regs.p.c = rd.w & 1; - rd.w >>= 1; - cpu_io(); //5 - op_write(OPMODE_DBR, aa.w + 1, rd.h); //6a - op_write(OPMODE_DBR, aa.w, rd.l); //6 - regs.p.n = !!(rd.w & 0x8000); - regs.p.z = (rd.w == 0); -} - -/************************ - *** 0x5e: lsr addr,x *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [4 ] dbr,aah,aal+xl ; io - [5 ] dbr,aa+x ; data low - [5a] dbr,aa+x+1 ; data high [1] - [6 ] dbr,aa+x+1 ; io - [7a] dbr,aa+x+1 ; data high [1] - [7 ] dbr,aa+x ; data low -*/ -void bCPU::op_lsr_addrxb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_io(); //4 - rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //5 - regs.p.c = rd.l & 1; - rd.l >>= 1; - cpu_io(); //6 - op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); //7 - regs.p.n = !!(rd.l & 0x80); - regs.p.z = (rd.l == 0); -} - -void bCPU::op_lsr_addrxw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_io(); //4 - rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //5 - rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); //5a - regs.p.c = rd.w & 1; - rd.w >>= 1; - cpu_io(); //6 - op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h); //7a - op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); //7 - regs.p.n = !!(rd.w & 0x8000); - regs.p.z = (rd.w == 0); -} - -/******************** - *** 0x46: lsr dp *** - ******************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; data low - [3a] 0,d+dp+1 ; data high [1] - [4 ] 0,d+dp+1 ; io - [5a] 0,d+dp+1 ; data high [1] - [5 ] 0,d+dp ; data low -*/ -void bCPU::op_lsr_dpb() { - dp = op_read(); //2 - cpu_c2(); //2a - rd.l = op_read(OPMODE_DP, dp); //3 - regs.p.c = rd.l & 1; - rd.l >>= 1; - cpu_io(); //4 - op_write(OPMODE_DP, dp, rd.l); //5 - regs.p.n = !!(rd.l & 0x80); - regs.p.z = (rd.l == 0); -} - -void bCPU::op_lsr_dpw() { - dp = op_read(); //2 - cpu_c2(); //2a - rd.l = op_read(OPMODE_DP, dp); //3 - rd.h = op_read(OPMODE_DP, dp + 1); //3a - regs.p.c = rd.w & 1; - rd.w >>= 1; - cpu_io(); //4 - op_write(OPMODE_DP, dp + 1, rd.h); //5a - op_write(OPMODE_DP, dp, rd.l); //5 - regs.p.n = !!(rd.w & 0x8000); - regs.p.z = (rd.w == 0); -} - -/********************** - *** 0x56: lsr dp,x *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] pbr,pc+1 ; io - [4 ] 0,d+dp+x ; data low - [4a] 0,d+dp+x+1 ; data high [1] - [5 ] 0,d+dp+x+1 ; io - [6a] 0,d+dp+x+1 ; data high [1] - [6 ] 0,d+dp+x ; data low -*/ -void bCPU::op_lsr_dpxb() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4 - regs.p.c = rd.l & 1; - rd.l >>= 1; - cpu_io(); //5 - op_write(OPMODE_DP, dp + regs.x.w, rd.l); //6 - regs.p.n = !!(rd.l & 0x80); - regs.p.z = (rd.l == 0); -} - -void bCPU::op_lsr_dpxw() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4 - rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //4a - regs.p.c = rd.w & 1; - rd.w >>= 1; - cpu_io(); //5 - op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h); //6a - op_write(OPMODE_DP, dp + regs.x.w, rd.l); //6 - regs.p.n = !!(rd.w & 0x8000); - regs.p.z = (rd.w == 0); -} - -/***************** - *** 0x2a: rol *** - ***************** -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; io -*/ -void bCPU::op_rolb() { -uint8 c = regs.p.c; - cpu_io(); //2 - 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); -} - -void bCPU::op_rolw() { -uint16 c = regs.p.c; - cpu_io(); //2 - 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); -} - -/********************** - *** 0x2e: rol addr *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [4 ] dbr,aa ; data low - [4a] dbr,aa+1 ; data high [1] - [5 ] dbr,aa+1 ; io - [6a] dbr,aa+1 ; data high [1] - [6 ] dbr,aa ; data low -*/ -void bCPU::op_rol_addrb() { -uint8 c = regs.p.c; - aa.l = op_read(); //2 - aa.h = op_read(); //3 - rd.l = op_read(OPMODE_DBR, aa.w); //4 - regs.p.c = !!(rd.l & 0x80); - rd.l <<= 1; - rd.l |= c; - cpu_io(); //5 - op_write(OPMODE_DBR, aa.w, rd.l); //6 - regs.p.n = !!(rd.l & 0x80); - regs.p.z = (rd.l == 0); -} - -void bCPU::op_rol_addrw() { -uint16 c = regs.p.c; - aa.l = op_read(); //2 - aa.h = op_read(); //3 - rd.l = op_read(OPMODE_DBR, aa.w); //4 - rd.h = op_read(OPMODE_DBR, aa.w + 1); //4a - regs.p.c = !!(rd.w & 0x8000); - rd.w <<= 1; - rd.w |= c; - cpu_io(); //5 - op_write(OPMODE_DBR, aa.w + 1, rd.h); //6a - op_write(OPMODE_DBR, aa.w, rd.l); //6 - regs.p.n = !!(rd.w & 0x8000); - regs.p.z = (rd.w == 0); -} - -/************************ - *** 0x3e: rol addr,x *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [4 ] dbr,aah,aal+xl ; io - [5 ] dbr,aa+x ; data low - [5a] dbr,aa+x+1 ; data high [1] - [6 ] dbr,aa+x+1 ; io - [7a] dbr,aa+x+1 ; data high [1] - [7 ] dbr,aa+x ; data low -*/ -void bCPU::op_rol_addrxb() { -uint8 c = regs.p.c; - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_io(); //4 - rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //5 - regs.p.c = !!(rd.l & 0x80); - rd.l <<= 1; - rd.l |= c; - cpu_io(); //6 - op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); //7 - regs.p.n = !!(rd.l & 0x80); - regs.p.z = (rd.l == 0); -} - -void bCPU::op_rol_addrxw() { -uint16 c = regs.p.c; - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_io(); //4 - rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //5 - rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); //5a - regs.p.c = !!(rd.w & 0x8000); - rd.w <<= 1; - rd.w |= c; - cpu_io(); //6 - op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h); //7a - op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); //7 - regs.p.n = !!(rd.w & 0x8000); - regs.p.z = (rd.w == 0); -} - -/******************** - *** 0x26: rol dp *** - ******************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; data low - [3a] 0,d+dp+1 ; data high [1] - [4 ] 0,d+dp+1 ; io - [5a] 0,d+dp+1 ; data high [1] - [5 ] 0,d+dp ; data low -*/ -void bCPU::op_rol_dpb() { -uint8 c = regs.p.c; - dp = op_read(); //2 - cpu_c2(); //2a - rd.l = op_read(OPMODE_DP, dp); //3 - regs.p.c = !!(rd.l & 0x80); - rd.l <<= 1; - rd.l |= c; - cpu_io(); //4 - op_write(OPMODE_DP, dp, rd.l); //5 - regs.p.n = !!(rd.l & 0x80); - regs.p.z = (rd.l == 0); -} - -void bCPU::op_rol_dpw() { -uint16 c = regs.p.c; - dp = op_read(); //2 - cpu_c2(); //2a - rd.l = op_read(OPMODE_DP, dp); //3 - rd.h = op_read(OPMODE_DP, dp + 1); //3a - regs.p.c = !!(rd.w & 0x8000); - rd.w <<= 1; - rd.w |= c; - cpu_io(); //4 - op_write(OPMODE_DP, dp + 1, rd.h); //5a - op_write(OPMODE_DP, dp, rd.l); //5 - regs.p.n = !!(rd.w & 0x8000); - regs.p.z = (rd.w == 0); -} - -/********************** - *** 0x36: rol dp,x *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] pbr,pc+1 ; io - [4 ] 0,d+dp+x ; data low - [4a] 0,d+dp+x+1 ; data high [1] - [5 ] 0,d+dp+x+1 ; io - [6a] 0,d+dp+x+1 ; data high [1] - [6 ] 0,d+dp+x ; data low -*/ -void bCPU::op_rol_dpxb() { -uint8 c = regs.p.c; - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4 - regs.p.c = !!(rd.l & 0x80); - rd.l <<= 1; - rd.l |= c; - cpu_io(); //5 - op_write(OPMODE_DP, dp + regs.x.w, rd.l); //6 - regs.p.n = !!(rd.l & 0x80); - regs.p.z = (rd.l == 0); -} - -void bCPU::op_rol_dpxw() { -uint16 c = regs.p.c; - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4 - rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //4a - regs.p.c = !!(rd.w & 0x8000); - rd.w <<= 1; - rd.w |= c; - cpu_io(); //5 - op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h); //6a - op_write(OPMODE_DP, dp + regs.x.w, rd.l); //6 - regs.p.n = !!(rd.w & 0x8000); - regs.p.z = (rd.w == 0); -} - -/***************** - *** 0x6a: ror *** - ***************** -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; io -*/ -void bCPU::op_rorb() { -uint8 c = (regs.p.c)?0x80:0; - cpu_io(); //2 - 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); -} - -void bCPU::op_rorw() { -uint16 c = (regs.p.c)?0x8000:0; - cpu_io(); //2 - 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); -} - -/********************** - *** 0x6e: ror addr *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [4 ] dbr,aa ; data low - [4a] dbr,aa+1 ; data high [1] - [5 ] dbr,aa+1 ; io - [6a] dbr,aa+1 ; data high [1] - [6 ] dbr,aa ; data low -*/ -void bCPU::op_ror_addrb() { -uint8 c = (regs.p.c)?0x80:0; - aa.l = op_read(); //2 - aa.h = op_read(); //3 - rd.l = op_read(OPMODE_DBR, aa.w); //4 - regs.p.c = rd.l & 1; - rd.l >>= 1; - rd.l |= c; - cpu_io(); //5 - op_write(OPMODE_DBR, aa.w, rd.l); //6 - regs.p.n = !!(rd.l & 0x80); - regs.p.z = (rd.l == 0); -} - -void bCPU::op_ror_addrw() { -uint16 c = (regs.p.c)?0x8000:0; - aa.l = op_read(); //2 - aa.h = op_read(); //3 - rd.l = op_read(OPMODE_DBR, aa.w); //4 - rd.h = op_read(OPMODE_DBR, aa.w + 1); //4a - regs.p.c = rd.w & 1; - rd.w >>= 1; - rd.w |= c; - cpu_io(); //5 - op_write(OPMODE_DBR, aa.w + 1, rd.h); //6a - op_write(OPMODE_DBR, aa.w, rd.l); //6 - regs.p.n = !!(rd.w & 0x8000); - regs.p.z = (rd.w == 0); -} - -/************************ - *** 0x7e: ror addr,x *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [4 ] dbr,aah,aal+xl ; io - [5 ] dbr,aa+x ; data low - [5a] dbr,aa+x+1 ; data high [1] - [6 ] dbr,aa+x+1 ; io - [7a] dbr,aa+x+1 ; data high [1] - [7 ] dbr,aa+x ; data low -*/ -void bCPU::op_ror_addrxb() { -uint8 c = (regs.p.c)?0x80:0; - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_io(); //4 - rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //5 - regs.p.c = rd.l & 1; - rd.l >>= 1; - rd.l |= c; - cpu_io(); //6 - op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); //7 - regs.p.n = !!(rd.l & 0x80); - regs.p.z = (rd.l == 0); -} - -void bCPU::op_ror_addrxw() { -uint16 c = (regs.p.c)?0x8000:0; - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_io(); //4 - rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //5 - rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); //5a - regs.p.c = rd.w & 1; - rd.w >>= 1; - rd.w |= c; - cpu_io(); //6 - op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h); //7a - op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); //7 - regs.p.n = !!(rd.w & 0x8000); - regs.p.z = (rd.w == 0); -} - -/******************** - *** 0x66: ror dp *** - ******************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; data low - [3a] 0,d+dp+1 ; data high [1] - [4 ] 0,d+dp+1 ; io - [5a] 0,d+dp+1 ; data high [1] - [5 ] 0,d+dp ; data low -*/ -void bCPU::op_ror_dpb() { -uint8 c = (regs.p.c)?0x80:0; - dp = op_read(); //2 - cpu_c2(); //2a - rd.l = op_read(OPMODE_DP, dp); //3 - regs.p.c = rd.l & 1; - rd.l >>= 1; - rd.l |= c; - cpu_io(); //4 - op_write(OPMODE_DP, dp, rd.l); //5 - regs.p.n = !!(rd.l & 0x80); - regs.p.z = (rd.l == 0); -} - -void bCPU::op_ror_dpw() { -uint16 c = (regs.p.c)?0x8000:0; - dp = op_read(); //2 - cpu_c2(); //2a - rd.l = op_read(OPMODE_DP, dp); //3 - rd.h = op_read(OPMODE_DP, dp + 1); //3a - regs.p.c = rd.w & 1; - rd.w >>= 1; - rd.w |= c; - cpu_io(); //4 - op_write(OPMODE_DP, dp + 1, rd.h); //5a - op_write(OPMODE_DP, dp, rd.l); //5 - regs.p.n = !!(rd.w & 0x8000); - regs.p.z = (rd.w == 0); -} - -/********************** - *** 0x76: ror dp,x *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] pbr,pc+1 ; io - [4 ] 0,d+dp+x ; data low - [4a] 0,d+dp+x+1 ; data high [1] - [5 ] 0,d+dp+x+1 ; io - [6a] 0,d+dp+x+1 ; data high [1] - [6 ] 0,d+dp+x ; data low -*/ -void bCPU::op_ror_dpxb() { -uint8 c = (regs.p.c)?0x80:0; - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4 - regs.p.c = rd.l & 1; - rd.l >>= 1; - rd.l |= c; - cpu_io(); //5 - op_write(OPMODE_DP, dp + regs.x.w, rd.l); //6 - regs.p.n = !!(rd.l & 0x80); - regs.p.z = (rd.l == 0); -} - -void bCPU::op_ror_dpxw() { -uint16 c = (regs.p.c)?0x8000:0; - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4 - rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //4a - regs.p.c = rd.w & 1; - rd.w >>= 1; - rd.w |= c; - cpu_io(); //5 - op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h); //6a - op_write(OPMODE_DP, dp + regs.x.w, rd.l); //6 - regs.p.n = !!(rd.w & 0x8000); - regs.p.z = (rd.w == 0); -} diff --git a/src/cpu/bcpu/bcpu_op_sta.cpp b/src/cpu/bcpu/bcpu_op_sta.cpp deleted file mode 100644 index eb88afaf..00000000 --- a/src/cpu/bcpu/bcpu_op_sta.cpp +++ /dev/null @@ -1,387 +0,0 @@ -/********************** - *** 0x8d: sta addr *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [4 ] dbr,aa ; data low - [4a] dbr,aa+1 ; data high [1] -*/ -void bCPU::op_sta_addrb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - op_write(OPMODE_DBR, aa.w, regs.a.l); //4 -} - -void bCPU::op_sta_addrw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - op_write(OPMODE_DBR, aa.w, regs.a.l); //4 - op_write(OPMODE_DBR, aa.w + 1, regs.a.h); //4a -} - -/************************ - *** 0x9d: sta addr,x *** - ************************ -cycles: - [1 ] pbr,pc ; operand - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [3a] dbr,aah,aal+xl ; io [4] - [4 ] dbr,aa+x ; data low - [4a] dbr,aa+x+1 ; data high [1] -*/ -void bCPU::op_sta_addrxb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_c4(aa.w, aa.w + regs.x.w); //3a - op_write(OPMODE_DBR, aa.w + regs.x.w, regs.a.l); //4 -} - -void bCPU::op_sta_addrxw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_c4(aa.w, aa.w + regs.x.w); //3a - op_write(OPMODE_DBR, aa.w + regs.x.w, regs.a.l); //4 - op_write(OPMODE_DBR, aa.w + regs.x.w + 1, regs.a.h); //4a -} - -/******************** - *** 0x85: sta dp *** - ******************** -cycles: - [1 ] pbr,pc ; operand - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; data low - [3a] 0,d+dp+1 ; data high [1] -*/ -void bCPU::op_sta_dpb() { - dp = op_read(); //2 - cpu_c2(); //2a - op_write(OPMODE_DP, dp, regs.a.l); //3 -} - -void bCPU::op_sta_dpw() { - dp = op_read(); //2 - cpu_c2(); //2a - op_write(OPMODE_DP, dp, regs.a.l); //3 - op_write(OPMODE_DP, dp + 1, regs.a.h); //3a -} - -/********************** - *** 0x92: sta (dp) *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; aal - [4 ] 0,d+dp+1 ; aah - [5 ] dbr,aa ; data low - [5a] dbr,aa+1 ; data high [1] -*/ -void bCPU::op_sta_idpb() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - op_write(OPMODE_DBR, aa.w, regs.a.l); //5 -} - -void bCPU::op_sta_idpw() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - op_write(OPMODE_DBR, aa.w, regs.a.l); //5 - op_write(OPMODE_DBR, aa.w + 1, regs.a.h); //5 -} - -/********************** - *** 0x87: sta [dp] *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; aal - [4 ] 0,d+dp+1 ; aah - [5 ] 0,d+dp+2 ; aab - [6 ] aab,aa ; data low - [6a] aab,aa+1 ; data high [1] -*/ -void bCPU::op_sta_ildpb() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - aa.b = op_read(OPMODE_DP, dp + 2); //5 - op_write(OPMODE_LONG, aa.d, regs.a.l); //6 -} - -void bCPU::op_sta_ildpw() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - aa.b = op_read(OPMODE_DP, dp + 2); //5 - op_write(OPMODE_LONG, aa.d, regs.a.l); //6 - op_write(OPMODE_LONG, aa.d + 1, regs.a.h); //6a -} - -/********************** - *** 0x8f: sta long *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [4 ] pbr,pc+3 ; aab - [5 ] aab,aa ; data low - [5a] aab,aa+1 ; data high -*/ -void bCPU::op_sta_longb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - aa.b = op_read(); //4 - op_write(OPMODE_LONG, aa.d, regs.a.l); //5 -} - -void bCPU::op_sta_longw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - aa.b = op_read(); //4 - op_write(OPMODE_LONG, aa.d, regs.a.l); //5 - op_write(OPMODE_LONG, aa.d + 1, regs.a.h); //5a -} - -/************************ - *** 0x9f: sta long,x *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [4 ] pbr,pc+3 ; aab - [5 ] aab,aa+x ; data low - [5a] aab,aa+x+1 ; data high -*/ -void bCPU::op_sta_longxb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - aa.b = op_read(); //4 - op_write(OPMODE_LONG, aa.d + regs.x.w, regs.a.l); //5 -} - -void bCPU::op_sta_longxw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - aa.b = op_read(); //4 - op_write(OPMODE_LONG, aa.d + regs.x.w, regs.a.l); //5 - op_write(OPMODE_LONG, aa.d + regs.x.w + 1, regs.a.h); //5a -} - -/************************ - *** 0x99: sta addr,y *** - ************************ -cycles: - [1 ] pbr,pc ; operand - [2 ] pbr,pc+1 ; aal - [3 ] pbr,pc+2 ; aah - [3a] dbr,aah,aal+yl ; io [4] - [4 ] dbr,aa+y ; data low - [4a] dbr,aa+y+1 ; data high [1] -*/ -void bCPU::op_sta_addryb() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_c4(aa.w, aa.w + regs.y.w); //3a - op_write(OPMODE_DBR, aa.w + regs.y.w, regs.a.l); //4 -} - -void bCPU::op_sta_addryw() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_c4(aa.w, aa.w + regs.y.w); //3a - op_write(OPMODE_DBR, aa.w + regs.y.w, regs.a.l); //4 - op_write(OPMODE_DBR, aa.w + regs.y.w + 1, regs.a.h); //4a -} - -/********************** - *** 0x95: sta dp,x *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io - [3 ] pbr,pc+1 ; io - [4 ] 0,d+dp+x ; data low - [4a] 0,d+dp+x+1 ; data high -*/ -void bCPU::op_sta_dpxb() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - op_write(OPMODE_DP, dp + regs.x.w, regs.a.l); //4 -} - -void bCPU::op_sta_dpxw() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - op_write(OPMODE_DP, dp + regs.x.w, regs.a.l); //4 - op_write(OPMODE_DP, dp + regs.x.w + 1, regs.a.h); //4a -} - -/************************ - *** 0x81: sta (dp,x) *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] pbr,pc+1 ; io - [4 ] 0,d+dp+x ; aal - [5 ] 0,d+dp+x+1 ; aah - [6 ] dbr,aa ; data low - [6a] dbr,aa+1 ; data high [1] -*/ -void bCPU::op_sta_idpxb() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - aa.l = op_read(OPMODE_DP, dp + regs.x.w); //4 - aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //5 - op_write(OPMODE_DBR, aa.w, regs.a.l); //6 -} - -void bCPU::op_sta_idpxw() { - dp = op_read(); //2 - cpu_c2(); //2a - cpu_io(); //3 - aa.l = op_read(OPMODE_DP, dp + regs.x.w); //4 - aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //5 - op_write(OPMODE_DBR, aa.w, regs.a.l); //6 - op_write(OPMODE_DBR, aa.w + 1, regs.a.h); //6a -} - -/************************ - *** 0x91: sta (dp),y *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; aal - [4 ] 0,d+dp+1 ; aah - [4a] dbr,aah,aal+yl ; io [4] - [5 ] dbr,aa+y ; data low - [5a] dbr,aa+y+1 ; data high [1] -*/ -void bCPU::op_sta_idpyb() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - cpu_c4(aa.w, aa.w + regs.y.w); //4a - op_write(OPMODE_DBR, aa.w + regs.y.w, regs.a.l); //5 -} - -void bCPU::op_sta_idpyw() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - cpu_c4(aa.w, aa.w + regs.y.w); //4a - op_write(OPMODE_DBR, aa.w + regs.y.w, regs.a.l); //5 - op_write(OPMODE_DBR, aa.w + regs.y.w + 1, regs.a.h); //5a -} - -/************************ - *** 0x97: sta [dp],y *** - ************************ -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io [2] - [3 ] 0,d+dp ; aal - [4 ] 0,d+dp+1 ; aah - [5 ] 0,d+dp+2 ; aab - [6 ] aab,aa+y ; data low - [6a] aab,aa+y+1 ; data high [1] -*/ -void bCPU::op_sta_ildpyb() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - aa.b = op_read(OPMODE_DP, dp + 2); //5 - op_write(OPMODE_LONG, aa.d + regs.y.w, regs.a.l); //6 -} - -void bCPU::op_sta_ildpyw() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - aa.b = op_read(OPMODE_DP, dp + 2); //5 - op_write(OPMODE_LONG, aa.d + regs.y.w, regs.a.l); //6 - op_write(OPMODE_LONG, aa.d + regs.y.w + 1, regs.a.h); //6a -} - -/********************** - *** 0x83: sta sr,s *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; sp - [3 ] pbr,pc+1 ; io - [4 ] 0,s+sp ; data low - [4a] 0,s+sp+1 ; data high [1] -*/ -void bCPU::op_sta_srb() { - sp = op_read(); //2 - cpu_io(); //3 - op_write(OPMODE_SP, sp, regs.a.l); //4 -} - -void bCPU::op_sta_srw() { - sp = op_read(); //2 - cpu_io(); //3 - op_write(OPMODE_SP, sp, regs.a.l); //4 - op_write(OPMODE_SP, sp + 1, regs.a.h); //4a -} - -/************************** - *** 0x93: sta (sr,s),y *** - ************************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; sp - [3 ] pbr,pc+1 ; io - [4 ] 0,s+sp ; aal - [5 ] 0,s+sp+1 ; aah - [6 ] 0,s+sp+1 ; io - [7 ] dbr,aa+y ; data low - [7a] dbr,aa+y+1 ; data high [1] -*/ -void bCPU::op_sta_isryb() { - sp = op_read(); //2 - cpu_io(); //3 - aa.l = op_read(OPMODE_SP, sp); //4 - aa.h = op_read(OPMODE_SP, sp + 1); //5 - cpu_io(); //6 - op_write(OPMODE_DBR, aa.w + regs.y.w, regs.a.l); //7 -} - -void bCPU::op_sta_isryw() { - sp = op_read(); //2 - cpu_io(); //3 - aa.l = op_read(OPMODE_SP, sp); //4 - aa.h = op_read(OPMODE_SP, sp + 1); //5 - cpu_io(); //6 - op_write(OPMODE_DBR, aa.w + regs.y.w, regs.a.l); //7 - op_write(OPMODE_DBR, aa.w + regs.y.w + 1, regs.a.h); //7a -} diff --git a/src/cpu/bcpu/bcpu_op_stack.cpp b/src/cpu/bcpu/bcpu_op_stack.cpp deleted file mode 100644 index bb741e84..00000000 --- a/src/cpu/bcpu/bcpu_op_stack.cpp +++ /dev/null @@ -1,317 +0,0 @@ -/***************** - *** 0x48: pha *** - ***************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; io - [3a] 0,s ; reg high [1] - [3 ] 0,s-1 ; reg low -*/ -void bCPU::op_phab() { - cpu_io(); //2 - stack_write(regs.a.l); //3 -} - -void bCPU::op_phaw() { - cpu_io(); //2 - stack_write(regs.a.h); //3a - stack_write(regs.a.l); //3 -} - -/***************** - *** 0x8b: phb *** - ***************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; io - [3 ] 0,s-1 ; dbr -*/ -void bCPU::op_phb() { - cpu_io(); //2 - stack_write(regs.db); //3 -} - -/***************** - *** 0x0b: phd *** - ***************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; io - [3a] 0,s ; reg high - [3 ] 0,s-1 ; reg low -*/ -void bCPU::op_phd() { - cpu_io(); //2 - stack_write(regs.d.h); //3a - stack_write(regs.d.l); //3 -} - -/***************** - *** 0x4b: phk *** - ***************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; io - [3 ] 0,s-1 ; pcb -*/ -void bCPU::op_phk() { - cpu_io(); //2 - stack_write(regs.pc.b); //3 -} - -/***************** - *** 0x08: php *** - ***************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; io - [3 ] 0,s-1 ; reg low -*/ -void bCPU::op_php() { - cpu_io(); //2 - stack_write(regs.p); //3 -} - -/***************** - *** 0xda: phx *** - ***************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; io - [3a] 0,s ; reg high [1] - [3 ] 0,s-1 ; reg low -*/ -void bCPU::op_phxb() { - cpu_io(); //2 - stack_write(regs.x.l); //3 -} - -void bCPU::op_phxw() { - cpu_io(); //2 - stack_write(regs.x.h); //3a - stack_write(regs.x.l); //3 -} - -/***************** - *** 0x5a: phy *** - ***************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; io - [3a] 0,s ; reg high [1] - [3 ] 0,s-1 ; reg low -*/ -void bCPU::op_phyb() { - cpu_io(); //2 - stack_write(regs.y.l); //3 -} - -void bCPU::op_phyw() { - cpu_io(); //2 - stack_write(regs.y.h); //3a - stack_write(regs.y.l); //3 -} - -/***************** - *** 0x68: pla *** - ***************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; io - [3 ] pbr,pc+1 ; io - [4 ] 0,s+1 ; reg low - [4a] 0,s+2 ; reg high [1] -*/ -void bCPU::op_plab() { - cpu_io(); //2 - cpu_io(); //3 - regs.a.l = stack_read(); //4 - regs.p.n = !!(regs.a.l & 0x80); - regs.p.z = (regs.a.l == 0); -} - -void bCPU::op_plaw() { - cpu_io(); //2 - cpu_io(); //3 - regs.a.l = stack_read(); //4 - regs.a.h = stack_read(); //4a - regs.p.n = !!(regs.a.w & 0x8000); - regs.p.z = (regs.a.w == 0); -} - -/***************** - *** 0xab: plb *** - ***************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; io - [3 ] pbr,pc+1 ; io - [4 ] 0,s+1 ; reg low -*/ -void bCPU::op_plb() { - cpu_io(); //2 - cpu_io(); //3 - regs.db = stack_read(); //4 - regs.p.n = !!(regs.db & 0x80); - regs.p.z = (regs.db == 0); -} - -/***************** - *** 0x2b: pld *** - ***************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; io - [3 ] pbr,pc+1 ; io - [4 ] 0,s+1 ; reg low - [4a] 0,s+2 ; reg high -*/ -void bCPU::op_pld() { - cpu_io(); //2 - cpu_io(); //3 - regs.d.l = stack_read(); //4 - regs.d.h = stack_read(); //4a - regs.p.n = !!(regs.d.w & 0x8000); - regs.p.z = (regs.d.w == 0); -} - -/***************** - *** 0x28: plp *** - ***************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; io - [3 ] pbr,pc+1 ; io - [4 ] 0,s+1 ; reg low -*/ -void bCPU::op_plp() { - cpu_io(); //2 - cpu_io(); //3 - regs.p = stack_read(); //4 - if(regs.e) { - regs.p |= 0x30; - } else { - switch((regs.p >> 4) & 3) { - case 0:optbl = optbl_mx;break; - case 1:optbl = optbl_mX;break; - case 2:optbl = optbl_Mx;break; - case 3:optbl = optbl_MX;break; - } - } - if(regs.p.x) { - regs.x.h = 0x00; - regs.y.h = 0x00; - } -} - -/***************** - *** 0xfa: plx *** - ***************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; io - [3 ] pbr,pc+1 ; io - [4 ] 0,s+1 ; reg low - [4a] 0,s+2 ; reg high [1] -*/ -void bCPU::op_plxb() { - cpu_io(); //2 - cpu_io(); //3 - regs.x.l = stack_read(); //4 - regs.p.n = !!(regs.x.l & 0x80); - regs.p.z = (regs.x.l == 0); -} - -void bCPU::op_plxw() { - cpu_io(); //2 - cpu_io(); //3 - regs.x.l = stack_read(); //4 - regs.x.h = stack_read(); //4a - regs.p.n = !!(regs.x.w & 0x8000); - regs.p.z = (regs.x.w == 0); -} - -/***************** - *** 0x7a: ply *** - ***************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; io - [3 ] pbr,pc+1 ; io - [4 ] 0,s+1 ; reg low - [4a] 0,s+2 ; reg high [1] -*/ -void bCPU::op_plyb() { - cpu_io(); //2 - cpu_io(); //3 - regs.y.l = stack_read(); //4 - regs.p.n = !!(regs.y.l & 0x80); - regs.p.z = (regs.y.l == 0); -} - -void bCPU::op_plyw() { - cpu_io(); //2 - cpu_io(); //3 - regs.y.l = stack_read(); //4 - regs.y.h = stack_read(); //4a - regs.p.n = !!(regs.y.w & 0x8000); - regs.p.z = (regs.y.w == 0); -} - -/********************** - *** 0xf4: pea addr *** - ********************** -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; aal - [3] pbr,pc+2 ; aah - [4] 0,s ; aah - [5] 0,s-1 ; aal -*/ -void bCPU::op_pea() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - stack_write(aa.h); //4 - stack_write(aa.l); //5 -} - -/********************** - *** 0xd4: pei (dp) *** - ********************** -cycles: - [1 ] pbr,pc ; opcode - [2 ] pbr,pc+1 ; dp - [2a] pbr,pc+1 ; io - [3 ] 0,d+dp ; aal - [4 ] 0,d+dp+1 ; aah - [5 ] 0,s ; aah - [6 ] 0,s-1 ; aal -*/ -void bCPU::op_pei() { - dp = op_read(); //2 - cpu_c2(); //2a - aa.l = op_read(OPMODE_DP, dp); //3 - aa.h = op_read(OPMODE_DP, dp + 1); //4 - stack_write(aa.h); //5 - stack_write(aa.l); //6 -} - -/********************** - *** 0x62: per addr *** - ********************** -cycles: - [1] pbr,pc ; opcode - [2] pbr,pc+1 ; offset low - [3] pbr,pc+2 ; offset high - [4] pbr,pc+2 ; io - [5] 0,s ; pch+offset - [6] 0,s-1 ; pcl+offset -*/ -void bCPU::op_per() { - aa.l = op_read(); //2 - aa.h = op_read(); //3 - cpu_io(); //4 - rd.w = regs.pc.d + (int16)aa.w; - stack_write(rd.h); //5 - stack_write(rd.l); //6 -} diff --git a/src/cpu/bcpu/bcpu_op_write.cpp b/src/cpu/bcpu/bcpu_op_write.cpp new file mode 100644 index 00000000..8a294337 --- /dev/null +++ b/src/cpu/bcpu/bcpu_op_write.cpp @@ -0,0 +1,340 @@ +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + diff --git a/src/cpu/bcpu/bcpu_opfn.cpp b/src/cpu/bcpu/bcpu_opfn.cpp new file mode 100644 index 00000000..b6f13563 --- /dev/null +++ b/src/cpu/bcpu/bcpu_opfn.cpp @@ -0,0 +1,295 @@ +//op_read +inline void bCPU::op_adc_b() { +int32 r = regs.a.l + rd.l + regs.p.c; +//bcd + if(regs.p.d) { + if(((r ) & 15) > 9)r += 6; + if(((r >> 4) & 15) > 9)r += 6 << 4; + } + regs.p.n = !!(r & 0x80); + regs.p.v = !!(~(regs.a.l ^ rd.l) & (regs.a.l ^ r) & 0x80); + regs.p.z = ((uint8)r == 0); + regs.p.c = (r > 0xff); + regs.a.l = r; +} + +inline void bCPU::op_adc_w() { +int32 r = regs.a.w + rd.w + regs.p.c; +//bcd + if(regs.p.d) { + if(((r ) & 15) > 9)r += 6; + if(((r >> 4) & 15) > 9)r += 6 << 4; + if(((r >> 8) & 15) > 9)r += 6 << 8; + if(((r >> 12) & 15) > 9)r += 6 << 12; + } + regs.p.n = !!(r & 0x8000); + regs.p.v = !!(~(regs.a.w ^ rd.w) & (regs.a.w ^ r) & 0x8000); + regs.p.z = ((uint16)r == 0); + regs.p.c = (r > 0xffff); + regs.a.w = r; +} + +inline void bCPU::op_and_b() { + regs.a.l &= rd.l; + regs.p.n = !!(regs.a.l & 0x80); + regs.p.z = (regs.a.l == 0); +} + +inline void bCPU::op_and_w() { + regs.a.w &= rd.w; + regs.p.n = !!(regs.a.w & 0x8000); + regs.p.z = (regs.a.w == 0); +} + +inline void bCPU::op_bit_b() { + regs.p.n = !!(rd.l & 0x80); + regs.p.v = !!(rd.l & 0x40); + regs.p.z = ((rd.l & regs.a.l) == 0); +} + +inline void bCPU::op_bit_w() { + regs.p.n = !!(rd.w & 0x8000); + regs.p.v = !!(rd.w & 0x4000); + regs.p.z = ((rd.w & regs.a.w) == 0); +} + +inline void bCPU::op_cmp_b() { +int32 r = regs.a.l - rd.l; + regs.p.n = !!(r & 0x80); + regs.p.z = ((uint8)r == 0); + regs.p.c = (r >= 0); +} + +inline void bCPU::op_cmp_w() { +int32 r = regs.a.w - rd.w; + regs.p.n = !!(r & 0x8000); + regs.p.z = ((uint16)r == 0); + regs.p.c = (r >= 0); +} + +inline void bCPU::op_cpx_b() { +int32 r = regs.x.l - rd.l; + regs.p.n = !!(r & 0x80); + regs.p.z = ((uint8)r == 0); + regs.p.c = (r >= 0); +} + +inline void bCPU::op_cpx_w() { +int32 r = regs.x.w - rd.w; + regs.p.n = !!(r & 0x8000); + regs.p.z = ((uint16)r == 0); + regs.p.c = (r >= 0); +} + +inline void bCPU::op_cpy_b() { +int32 r = regs.y.l - rd.l; + regs.p.n = !!(r & 0x80); + regs.p.z = ((uint8)r == 0); + regs.p.c = (r >= 0); +} + +inline void bCPU::op_cpy_w() { +int32 r = regs.y.w - rd.w; + regs.p.n = !!(r & 0x8000); + regs.p.z = ((uint16)r == 0); + regs.p.c = (r >= 0); +} + +inline void bCPU::op_eor_b() { + regs.a.l ^= rd.l; + regs.p.n = !!(regs.a.l & 0x80); + regs.p.z = (regs.a.l == 0); +} + +inline void bCPU::op_eor_w() { + regs.a.w ^= rd.w; + regs.p.n = !!(regs.a.w & 0x8000); + regs.p.z = (regs.a.w == 0); +} + +inline void bCPU::op_lda_b() { + regs.a.l = rd.l; + regs.p.n = !!(regs.a.l & 0x80); + regs.p.z = (regs.a.l == 0); +} + +inline void bCPU::op_lda_w() { + regs.a.w = rd.w; + regs.p.n = !!(regs.a.w & 0x8000); + regs.p.z = (regs.a.w == 0); +} + +inline void bCPU::op_ldx_b() { + regs.x.l = rd.l; + regs.p.n = !!(regs.x.l & 0x80); + regs.p.z = (regs.x.l == 0); +} + +inline void bCPU::op_ldx_w() { + regs.x.w = rd.w; + regs.p.n = !!(regs.x.w & 0x8000); + regs.p.z = (regs.x.w == 0); +} + +inline void bCPU::op_ldy_b() { + regs.y.l = rd.l; + regs.p.n = !!(regs.y.l & 0x80); + regs.p.z = (regs.y.l == 0); +} + +inline void bCPU::op_ldy_w() { + regs.y.w = rd.w; + regs.p.n = !!(regs.y.w & 0x8000); + regs.p.z = (regs.y.w == 0); +} + +inline void bCPU::op_ora_b() { + regs.a.l |= rd.l; + regs.p.n = !!(regs.a.l & 0x80); + regs.p.z = (regs.a.l == 0); +} + +inline void bCPU::op_ora_w() { + regs.a.w |= rd.w; + regs.p.n = !!(regs.a.w & 0x8000); + regs.p.z = (regs.a.w == 0); +} + +inline void bCPU::op_sbc_b() { +int32 r = regs.a.l - rd.l - !regs.p.c; +//bcd + if(regs.p.d) { + if(((r ) & 15) > 9)r -= 6; + if(((r >> 4) & 15) > 9)r -= 6 << 4; + } + regs.p.n = !!(r & 0x80); + regs.p.v = !!((regs.a.l ^ rd.l) & (regs.a.l ^ r) & 0x80); + regs.p.z = ((byte)r == 0); + regs.p.c = (r >= 0); + regs.a.l = r; +} + +inline void bCPU::op_sbc_w() { +int32 r = regs.a.w - rd.w - !regs.p.c; +//bcd + if(regs.p.d) { + if(((r ) & 15) > 9)r -= 6; + if(((r >> 4) & 15) > 9)r -= 6 << 4; + if(((r >> 8) & 15) > 9)r -= 6 << 8; + if(((r >> 12) & 15) > 9)r -= 6 << 12; + } + regs.p.n = !!(r & 0x8000); + regs.p.v = !!((regs.a.w ^ rd.w) & (regs.a.w ^ r) & 0x8000); + regs.p.z = ((word)r == 0); + regs.p.c = (r >= 0); + regs.a.w = r; +} + +//op_rmw +inline void bCPU::op_inc_b() { + rd.l++; + regs.p.n = !!(rd.l & 0x80); + regs.p.z = (rd.l == 0); +} + +inline void bCPU::op_inc_w() { + rd.w++; + regs.p.n = !!(rd.w & 0x8000); + regs.p.z = (rd.w == 0); +} + +inline void bCPU::op_dec_b() { + rd.l--; + regs.p.n = !!(rd.l & 0x80); + regs.p.z = (rd.l == 0); +} + +inline void bCPU::op_dec_w() { + rd.w--; + regs.p.n = !!(rd.w & 0x8000); + regs.p.z = (rd.w == 0); +} + +inline void bCPU::op_asl_b() { + regs.p.c = !!(rd.l & 0x80); + rd.l <<= 1; + regs.p.n = !!(rd.l & 0x80); + regs.p.z = (rd.l == 0); +} + +inline void bCPU::op_asl_w() { + regs.p.c = !!(rd.w & 0x8000); + rd.w <<= 1; + regs.p.n = !!(rd.w & 0x8000); + regs.p.z = (rd.w == 0); +} + +inline void bCPU::op_lsr_b() { + regs.p.c = rd.l & 1; + rd.l >>= 1; + regs.p.n = !!(rd.l & 0x80); + regs.p.z = (rd.l == 0); +} + +inline void bCPU::op_lsr_w() { + regs.p.c = rd.w & 1; + rd.w >>= 1; + regs.p.n = !!(rd.w & 0x8000); + regs.p.z = (rd.w == 0); +} + +inline void bCPU::op_rol_b() { +uint16 c = regs.p.c; + regs.p.c = !!(rd.l & 0x80); + rd.l <<= 1; + rd.l |= c; + regs.p.n = !!(rd.l & 0x80); + regs.p.z = (rd.l == 0); +} + +inline void bCPU::op_rol_w() { +uint16 c = regs.p.c; + regs.p.c = !!(rd.w & 0x8000); + rd.w <<= 1; + rd.w |= c; + regs.p.n = !!(rd.w & 0x8000); + regs.p.z = (rd.w == 0); +} + +inline void bCPU::op_ror_b() { +uint16 c = (regs.p.c)?0x80:0; + regs.p.c = rd.l & 1; + rd.l >>= 1; + rd.l |= c; + regs.p.n = !!(rd.l & 0x80); + regs.p.z = (rd.l == 0); +} + +inline void bCPU::op_ror_w() { +uint16 c = (regs.p.c)?0x8000:0; + regs.p.c = rd.w & 1; + rd.w >>= 1; + rd.w |= c; + regs.p.n = !!(rd.w & 0x8000); + regs.p.z = (rd.w == 0); +} + +inline void bCPU::op_trb_b() { + regs.p.z = ((rd.l & regs.a.l) == 0); + rd.l &= ~regs.a.l; +} + +inline void bCPU::op_trb_w() { + regs.p.z = ((rd.w & regs.a.w) == 0); + rd.w &= ~regs.a.w; +} + +inline void bCPU::op_tsb_b() { + regs.p.z = ((rd.l & regs.a.l) == 0); + rd.l |= regs.a.l; +} + +inline void bCPU::op_tsb_w() { + regs.p.z = ((rd.w & regs.a.w) == 0); + rd.w |= regs.a.w; +} diff --git a/src/cpu/bcpu/bcpu_optable.cpp b/src/cpu/bcpu/bcpu_optable.cpp new file mode 100644 index 00000000..253f75b9 --- /dev/null +++ b/src/cpu/bcpu/bcpu_optable.cpp @@ -0,0 +1,256 @@ +optbl[0x69] = &bCPU::op_adc_const; +optbl[0x29] = &bCPU::op_and_const; +optbl[0xc9] = &bCPU::op_cmp_const; +optbl[0xe0] = &bCPU::op_cpx_const; +optbl[0xc0] = &bCPU::op_cpy_const; +optbl[0x49] = &bCPU::op_eor_const; +optbl[0xa9] = &bCPU::op_lda_const; +optbl[0xa2] = &bCPU::op_ldx_const; +optbl[0xa0] = &bCPU::op_ldy_const; +optbl[0x09] = &bCPU::op_ora_const; +optbl[0xe9] = &bCPU::op_sbc_const; +optbl[0x6d] = &bCPU::op_adc_addr; +optbl[0x2d] = &bCPU::op_and_addr; +optbl[0x2c] = &bCPU::op_bit_addr; +optbl[0xcd] = &bCPU::op_cmp_addr; +optbl[0xec] = &bCPU::op_cpx_addr; +optbl[0xcc] = &bCPU::op_cpy_addr; +optbl[0x4d] = &bCPU::op_eor_addr; +optbl[0xad] = &bCPU::op_lda_addr; +optbl[0xae] = &bCPU::op_ldx_addr; +optbl[0xac] = &bCPU::op_ldy_addr; +optbl[0x0d] = &bCPU::op_ora_addr; +optbl[0xed] = &bCPU::op_sbc_addr; +optbl[0x7d] = &bCPU::op_adc_addrx; +optbl[0x3d] = &bCPU::op_and_addrx; +optbl[0x3c] = &bCPU::op_bit_addrx; +optbl[0xdd] = &bCPU::op_cmp_addrx; +optbl[0x5d] = &bCPU::op_eor_addrx; +optbl[0xbd] = &bCPU::op_lda_addrx; +optbl[0xbc] = &bCPU::op_ldy_addrx; +optbl[0x1d] = &bCPU::op_ora_addrx; +optbl[0xfd] = &bCPU::op_sbc_addrx; +optbl[0x79] = &bCPU::op_adc_addry; +optbl[0x39] = &bCPU::op_and_addry; +optbl[0xd9] = &bCPU::op_cmp_addry; +optbl[0x59] = &bCPU::op_eor_addry; +optbl[0xb9] = &bCPU::op_lda_addry; +optbl[0xbe] = &bCPU::op_ldx_addry; +optbl[0x19] = &bCPU::op_ora_addry; +optbl[0xf9] = &bCPU::op_sbc_addry; +optbl[0x6f] = &bCPU::op_adc_long; +optbl[0x2f] = &bCPU::op_and_long; +optbl[0xcf] = &bCPU::op_cmp_long; +optbl[0x4f] = &bCPU::op_eor_long; +optbl[0xaf] = &bCPU::op_lda_long; +optbl[0x0f] = &bCPU::op_ora_long; +optbl[0xef] = &bCPU::op_sbc_long; +optbl[0x7f] = &bCPU::op_adc_longx; +optbl[0x3f] = &bCPU::op_and_longx; +optbl[0xdf] = &bCPU::op_cmp_longx; +optbl[0x5f] = &bCPU::op_eor_longx; +optbl[0xbf] = &bCPU::op_lda_longx; +optbl[0x1f] = &bCPU::op_ora_longx; +optbl[0xff] = &bCPU::op_sbc_longx; +optbl[0x65] = &bCPU::op_adc_dp; +optbl[0x25] = &bCPU::op_and_dp; +optbl[0x24] = &bCPU::op_bit_dp; +optbl[0xc5] = &bCPU::op_cmp_dp; +optbl[0xe4] = &bCPU::op_cpx_dp; +optbl[0xc4] = &bCPU::op_cpy_dp; +optbl[0x45] = &bCPU::op_eor_dp; +optbl[0xa5] = &bCPU::op_lda_dp; +optbl[0xa6] = &bCPU::op_ldx_dp; +optbl[0xa4] = &bCPU::op_ldy_dp; +optbl[0x05] = &bCPU::op_ora_dp; +optbl[0xe5] = &bCPU::op_sbc_dp; +optbl[0x75] = &bCPU::op_adc_dpx; +optbl[0x35] = &bCPU::op_and_dpx; +optbl[0x34] = &bCPU::op_bit_dpx; +optbl[0xd5] = &bCPU::op_cmp_dpx; +optbl[0x55] = &bCPU::op_eor_dpx; +optbl[0xb5] = &bCPU::op_lda_dpx; +optbl[0xb4] = &bCPU::op_ldy_dpx; +optbl[0x15] = &bCPU::op_ora_dpx; +optbl[0xf5] = &bCPU::op_sbc_dpx; +optbl[0xb6] = &bCPU::op_ldx_dpy; +optbl[0x72] = &bCPU::op_adc_idp; +optbl[0x32] = &bCPU::op_and_idp; +optbl[0xd2] = &bCPU::op_cmp_idp; +optbl[0x52] = &bCPU::op_eor_idp; +optbl[0xb2] = &bCPU::op_lda_idp; +optbl[0x12] = &bCPU::op_ora_idp; +optbl[0xf2] = &bCPU::op_sbc_idp; +optbl[0x61] = &bCPU::op_adc_idpx; +optbl[0x21] = &bCPU::op_and_idpx; +optbl[0xc1] = &bCPU::op_cmp_idpx; +optbl[0x41] = &bCPU::op_eor_idpx; +optbl[0xa1] = &bCPU::op_lda_idpx; +optbl[0x01] = &bCPU::op_ora_idpx; +optbl[0xe1] = &bCPU::op_sbc_idpx; +optbl[0x71] = &bCPU::op_adc_idpy; +optbl[0x31] = &bCPU::op_and_idpy; +optbl[0xd1] = &bCPU::op_cmp_idpy; +optbl[0x51] = &bCPU::op_eor_idpy; +optbl[0xb1] = &bCPU::op_lda_idpy; +optbl[0x11] = &bCPU::op_ora_idpy; +optbl[0xf1] = &bCPU::op_sbc_idpy; +optbl[0x67] = &bCPU::op_adc_ildp; +optbl[0x27] = &bCPU::op_and_ildp; +optbl[0xc7] = &bCPU::op_cmp_ildp; +optbl[0x47] = &bCPU::op_eor_ildp; +optbl[0xa7] = &bCPU::op_lda_ildp; +optbl[0x07] = &bCPU::op_ora_ildp; +optbl[0xe7] = &bCPU::op_sbc_ildp; +optbl[0x77] = &bCPU::op_adc_ildpy; +optbl[0x37] = &bCPU::op_and_ildpy; +optbl[0xd7] = &bCPU::op_cmp_ildpy; +optbl[0x57] = &bCPU::op_eor_ildpy; +optbl[0xb7] = &bCPU::op_lda_ildpy; +optbl[0x17] = &bCPU::op_ora_ildpy; +optbl[0xf7] = &bCPU::op_sbc_ildpy; +optbl[0x63] = &bCPU::op_adc_sr; +optbl[0x23] = &bCPU::op_and_sr; +optbl[0xc3] = &bCPU::op_cmp_sr; +optbl[0x43] = &bCPU::op_eor_sr; +optbl[0xa3] = &bCPU::op_lda_sr; +optbl[0x03] = &bCPU::op_ora_sr; +optbl[0xe3] = &bCPU::op_sbc_sr; +optbl[0x73] = &bCPU::op_adc_isry; +optbl[0x33] = &bCPU::op_and_isry; +optbl[0xd3] = &bCPU::op_cmp_isry; +optbl[0x53] = &bCPU::op_eor_isry; +optbl[0xb3] = &bCPU::op_lda_isry; +optbl[0x13] = &bCPU::op_ora_isry; +optbl[0xf3] = &bCPU::op_sbc_isry; +optbl[0x89] = &bCPU::op_bit_const; +optbl[0x1a] = &bCPU::op_inc; +optbl[0xe8] = &bCPU::op_inx; +optbl[0xc8] = &bCPU::op_iny; +optbl[0x3a] = &bCPU::op_dec; +optbl[0xca] = &bCPU::op_dex; +optbl[0x88] = &bCPU::op_dey; +optbl[0x0a] = &bCPU::op_asl; +optbl[0x4a] = &bCPU::op_lsr; +optbl[0x2a] = &bCPU::op_rol; +optbl[0x6a] = &bCPU::op_ror; +optbl[0xee] = &bCPU::op_inc_addr; +optbl[0xce] = &bCPU::op_dec_addr; +optbl[0x0e] = &bCPU::op_asl_addr; +optbl[0x4e] = &bCPU::op_lsr_addr; +optbl[0x2e] = &bCPU::op_rol_addr; +optbl[0x6e] = &bCPU::op_ror_addr; +optbl[0x1c] = &bCPU::op_trb_addr; +optbl[0x0c] = &bCPU::op_tsb_addr; +optbl[0xfe] = &bCPU::op_inc_addrx; +optbl[0xde] = &bCPU::op_dec_addrx; +optbl[0x1e] = &bCPU::op_asl_addrx; +optbl[0x5e] = &bCPU::op_lsr_addrx; +optbl[0x3e] = &bCPU::op_rol_addrx; +optbl[0x7e] = &bCPU::op_ror_addrx; +optbl[0xe6] = &bCPU::op_inc_dp; +optbl[0xc6] = &bCPU::op_dec_dp; +optbl[0x06] = &bCPU::op_asl_dp; +optbl[0x46] = &bCPU::op_lsr_dp; +optbl[0x26] = &bCPU::op_rol_dp; +optbl[0x66] = &bCPU::op_ror_dp; +optbl[0x14] = &bCPU::op_trb_dp; +optbl[0x04] = &bCPU::op_tsb_dp; +optbl[0xf6] = &bCPU::op_inc_dpx; +optbl[0xd6] = &bCPU::op_dec_dpx; +optbl[0x16] = &bCPU::op_asl_dpx; +optbl[0x56] = &bCPU::op_lsr_dpx; +optbl[0x36] = &bCPU::op_rol_dpx; +optbl[0x76] = &bCPU::op_ror_dpx; +optbl[0x8d] = &bCPU::op_sta_addr; +optbl[0x8e] = &bCPU::op_stx_addr; +optbl[0x8c] = &bCPU::op_sty_addr; +optbl[0x9c] = &bCPU::op_stz_addr; +optbl[0x9d] = &bCPU::op_sta_addrx; +optbl[0x9e] = &bCPU::op_stz_addrx; +optbl[0x99] = &bCPU::op_sta_addry; +optbl[0x8f] = &bCPU::op_sta_long; +optbl[0x9f] = &bCPU::op_sta_longx; +optbl[0x85] = &bCPU::op_sta_dp; +optbl[0x86] = &bCPU::op_stx_dp; +optbl[0x84] = &bCPU::op_sty_dp; +optbl[0x64] = &bCPU::op_stz_dp; +optbl[0x95] = &bCPU::op_sta_dpx; +optbl[0x94] = &bCPU::op_sty_dpx; +optbl[0x74] = &bCPU::op_stz_dpx; +optbl[0x96] = &bCPU::op_stx_dpy; +optbl[0x92] = &bCPU::op_sta_idp; +optbl[0x87] = &bCPU::op_sta_ildp; +optbl[0x81] = &bCPU::op_sta_idpx; +optbl[0x91] = &bCPU::op_sta_idpy; +optbl[0x97] = &bCPU::op_sta_ildpy; +optbl[0x83] = &bCPU::op_sta_sr; +optbl[0x93] = &bCPU::op_sta_isry; +optbl[0x80] = &bCPU::op_bra; +optbl[0x90] = &bCPU::op_bcc; +optbl[0xb0] = &bCPU::op_bcs; +optbl[0xd0] = &bCPU::op_bne; +optbl[0xf0] = &bCPU::op_beq; +optbl[0x10] = &bCPU::op_bpl; +optbl[0x30] = &bCPU::op_bmi; +optbl[0x50] = &bCPU::op_bvc; +optbl[0x70] = &bCPU::op_bvs; +optbl[0x82] = &bCPU::op_brl; +optbl[0x4c] = &bCPU::op_jmp_addr; +optbl[0x5c] = &bCPU::op_jmp_long; +optbl[0x6c] = &bCPU::op_jmp_iaddr; +optbl[0x7c] = &bCPU::op_jmp_iaddrx; +optbl[0xdc] = &bCPU::op_jmp_iladdr; +optbl[0x20] = &bCPU::op_jsr_addr; +optbl[0x22] = &bCPU::op_jsr_long; +optbl[0xfc] = &bCPU::op_jsr_iaddrx; +optbl[0x40] = &bCPU::op_rti; +optbl[0x60] = &bCPU::op_rts; +optbl[0x6b] = &bCPU::op_rtl; +optbl[0xea] = &bCPU::op_nop; +optbl[0x42] = &bCPU::op_wdm; +optbl[0xeb] = &bCPU::op_xba; +optbl[0x54] = &bCPU::op_mvn; +optbl[0x44] = &bCPU::op_mvp; +optbl[0x00] = &bCPU::op_brk; +optbl[0x02] = &bCPU::op_cop; +optbl[0xdb] = &bCPU::op_stp; +optbl[0xcb] = &bCPU::op_wai; +optbl[0xfb] = &bCPU::op_xce; +optbl[0x18] = &bCPU::op_clc; +optbl[0xd8] = &bCPU::op_cld; +optbl[0x58] = &bCPU::op_cli; +optbl[0xb8] = &bCPU::op_clv; +optbl[0x38] = &bCPU::op_sec; +optbl[0xf8] = &bCPU::op_sed; +optbl[0x78] = &bCPU::op_sei; +optbl[0xc2] = &bCPU::op_rep; +optbl[0xe2] = &bCPU::op_sep; +optbl[0xaa] = &bCPU::op_tax; +optbl[0xa8] = &bCPU::op_tay; +optbl[0x8a] = &bCPU::op_txa; +optbl[0x9b] = &bCPU::op_txy; +optbl[0x98] = &bCPU::op_tya; +optbl[0xbb] = &bCPU::op_tyx; +optbl[0x5b] = &bCPU::op_tcd; +optbl[0x1b] = &bCPU::op_tcs; +optbl[0x7b] = &bCPU::op_tdc; +optbl[0x3b] = &bCPU::op_tsc; +optbl[0xba] = &bCPU::op_tsx; +optbl[0x9a] = &bCPU::op_txs; +optbl[0x48] = &bCPU::op_pha; +optbl[0xda] = &bCPU::op_phx; +optbl[0x5a] = &bCPU::op_phy; +optbl[0x0b] = &bCPU::op_phd; +optbl[0x8b] = &bCPU::op_phb; +optbl[0x4b] = &bCPU::op_phk; +optbl[0x08] = &bCPU::op_php; +optbl[0x68] = &bCPU::op_pla; +optbl[0xfa] = &bCPU::op_plx; +optbl[0x7a] = &bCPU::op_ply; +optbl[0x2b] = &bCPU::op_pld; +optbl[0xab] = &bCPU::op_plb; +optbl[0x28] = &bCPU::op_plp; +optbl[0xf4] = &bCPU::op_pea; +optbl[0xd4] = &bCPU::op_pei; +optbl[0x62] = &bCPU::op_per; diff --git a/src/cpu/bcpu/bcpu_timing.cpp b/src/cpu/bcpu/bcpu_timing.cpp new file mode 100644 index 00000000..3e9cd83e --- /dev/null +++ b/src/cpu/bcpu/bcpu_timing.cpp @@ -0,0 +1,141 @@ +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; } + +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; } + +//all scanlines are 1364 cycles long, except scanline 240 +//on non-interlace odd-frames, which is 1360 cycles long. +//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. +// +//cycles per frame: +// 263 * 1364 = 358732 +// 262 * 1364 = 357368 +// 262 * 1364 - 4 = 357364 +void bCPU::inc_vcounter() { + time.v++; + if(time.v >= time.frame_lines) { + time.v = 0; + time.interlace_field ^= 1; + + if(time.interlace == true && time.interlace_field == 0) { + time.frame_lines = 263; + } else { + time.frame_lines = 262; + } + } + + time.hc = 0; + time.dma_counter = time.line_cycles & 6; + if(time.v == 240 && time.interlace == false && time.interlace_field == 1) { + time.line_cycles = 1360; + } else { + time.line_cycles = 1364; + } + time.dram_refreshed = false; +} + +//all dots are 4 cycles long, except dots 322 and 326. dots 322 and 326 +//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 } +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]; + } + } +} + +void bCPU::dram_refresh() { + time.dram_refreshed = true; + add_cycles(40); + if(time.v != 240 || time.interlace != false || time.interlace_field != 1) { + //alternate between 534 and 538 every scanline except 240ni1 + time.dram_refresh_pos ^= 12; + } +} + +void bCPU::add_cycles(int cycles) { + cycles >>= 1; + while(cycles--) { + apusync.cycles += apusync.apu_freq << 1; + apu_sync(); + time.hc += 2; + + if(time.hc >= time.line_cycles) { + inc_vcounter(); + if(time.v == 0) { + frame(); + ppu->frame(); + } + scanline(); + ppu->scanline(); + } + + if(time.dram_refreshed == false && time.hc >= time.dram_refresh_pos) { + dram_refresh(); + } + + if(hdma_test() == true) { + hdma_run(); + } + } +} + +void bCPU::time_reset() { +//initial latch values for $213c/$213d +//[x]0035 : [y]0000 (53.0 -> 212) [lda $2137] +//[x]0038 : [y]0000 (56.5 -> 226) [nop : lda $2137] + time.v = 0; + time.hc = 186; + +//upon SNES reset, start at scanline 0 non-interlace + time.interlace = false; + 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; + } +} diff --git a/src/cpu/bcpu/bcpu_timing.h b/src/cpu/bcpu/bcpu_timing.h new file mode 100644 index 00000000..76a91a15 --- /dev/null +++ b/src/cpu/bcpu/bcpu_timing.h @@ -0,0 +1,38 @@ +struct { + uint16 v, hc; + + bool interlace, interlace_field, overscan; + uint16 line_cycles, frame_lines; + + bool dram_refreshed; + uint16 dram_refresh_pos; + + uint8 dma_counter; +}time; + +inline uint16 vcounter(); +inline uint16 hcounter(); +inline uint16 hcycles(); +inline bool interlace(); +inline bool interlace_field(); +inline bool overscan(); + +inline void set_interlace(bool r); +inline void set_overscan (bool r); + +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 new file mode 100644 index 00000000..ca22a068 --- /dev/null +++ b/src/cpu/bcpu/bcpugen.cpp @@ -0,0 +1,168 @@ +#include "../../lib/libbase.h" +#include "../../lib/libstring.h" +#include "../../lib/libstring.cpp" + +FILE *fp, *fph, *fpt; + +string data, line, part, subpart; +string output_table, output_header, output_op; + +int op_count; +struct _op_list { +string name; +string arg; +}op_list[64]; + +int line_num; + +void clear_op_list() { + op_count = 0; + for(int i=0;i<64;i++) { + strcpy(op_list[i].name, ""); + for(int l=0;l<8;l++) { + strcpy(op_list[i].arg[l], ""); + } + } +} + +void gen_header() { +int i = line_num, l, n, z; +char t[4096]; + clear_op_list(); + while(1) { + z = op_count++; + strcpy(part, line[i]); + strrtrim(part, "),"); + strrtrim(part, ") {"); + split(subpart, "(", part); + strcpy(op_list[z].name, subpart[0]); + split(part, ", ", subpart[1]); + for(l=0;l= count(line))break; + + gen_header(); + gen_op(); + gen_final(); + } + + fclose(fp); +} + +int main() { + fph = fopen("bcpu_op.h", "wb"); + fpt = fopen("bcpu_optable.cpp", "wb"); + + generate("bcpu_op_read.cpp", "op_read.b"); + generate("bcpu_op_rmw.cpp", "op_rmw.b"); + generate("bcpu_op_write.cpp", "op_write.b"); + generate("bcpu_op_pc.cpp", "op_pc.b"); + generate("bcpu_op_misc.cpp", "op_misc.b"); + + fclose(fph); + fclose(fpt); + + return 0; +} diff --git a/src/cpu/bcpu/bcpugen.exe b/src/cpu/bcpu/bcpugen.exe new file mode 100644 index 00000000..2f635841 Binary files /dev/null and b/src/cpu/bcpu/bcpugen.exe differ diff --git a/src/cpu/bcpu/cc.bat b/src/cpu/bcpu/cc.bat new file mode 100644 index 00000000..67f52823 --- /dev/null +++ b/src/cpu/bcpu/cc.bat @@ -0,0 +1,3 @@ +cl /ML /O2 bcpugen.cpp +@pause +@del *.obj \ No newline at end of file diff --git a/src/cpu/bcpu/clean.bat b/src/cpu/bcpu/clean.bat new file mode 100644 index 00000000..fc33f918 --- /dev/null +++ b/src/cpu/bcpu/clean.bat @@ -0,0 +1,8 @@ +@del *.exe +@del bcpu_op_misc.cpp +@del bcpu_op_pc.cpp +@del bcpu_op_read.cpp +@del bcpu_op_rmw.cpp +@del bcpu_op_write.cpp +@del bcpu_optable.cpp +@del bcpu_op.h diff --git a/src/cpu/bcpu/op_misc.b b/src/cpu/bcpu/op_misc.b new file mode 100644 index 00000000..2c115c32 --- /dev/null +++ b/src/cpu/bcpu/op_misc.b @@ -0,0 +1,252 @@ +nop(0xea) { +1:cpu_io(); +} + +wdm(0x42) { +1:cpu_io(); + regs.pc.w++; +} + +xba(0xeb) { +1:cpu_io(); +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); +} + +mvn(0x54, ++), +mvp(0x44, --) { +1:dp = op_read(); +2:sp = op_read(); +3:regs.db = dp; + rd.l = op_read(OPMODE_LONG, (sp << 16) | regs.x.w); +4:op_write(OPMODE_LONG, (dp << 16) | regs.y.w, rd.l); +5:cpu_io(); + if(regs.p.x) { regs.x.l$1; regs.y.l$1; } + else { regs.x.w$1; regs.y.w$1; } +6:cpu_io(); + if(regs.a.w--)regs.pc.w -= 3; +} + +brk(0x00, 0xfffe, 0xffff, 0xffe6, 0xffe7), +cop(0x02, 0xfff4, 0xfff5, 0xffe4, 0xffe5) { +1:op_read(); + if(regs.e)skip; +2:stack_write(regs.pc.b); +3:stack_write(regs.pc.h); +4:stack_write(regs.pc.l); +5:stack_write(regs.p); +6:rd.l = op_read(OPMODE_LONG, (regs.e)?$1:$3); +7:rd.h = op_read(OPMODE_LONG, (regs.e)?$2:$4); + regs.pc.b = 0x00; + regs.pc.w = rd.w; + regs.p.i = 1; + regs.p.d = 0; +} + +stp(0xdb) { +1:cpu_io(); + status.cpu_state = CPUSTATE_STP; +2:cpu_io(); + regs.pc.w--; +} + +wai(0xcb) { +1:cpu_io(); + status.cpu_state = CPUSTATE_WAI; +2:cpu_io(); + regs.pc.w--; +} + +xce(0xfb) { +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; + } +} + +clc(0x18, regs.p.c = 0), +cld(0xd8, regs.p.d = 0), +cli(0x58, regs.p.i = 0), +clv(0xb8, regs.p.v = 0), +sec(0x38, regs.p.c = 1), +sed(0xf8, regs.p.d = 1), +sei(0x78, regs.p.i = 1) { +1:cpu_io(); + $1; +} + +rep(0xc2, &=~), +sep(0xe2, |=) { +1:rd.l = op_read(); +2:cpu_io(); + regs.p $1 rd.l; + if(regs.e)regs.p |= 0x30; + if(regs.p.x) { + regs.x.h = 0x00; + regs.y.h = 0x00; + } +} + +tax(0xaa, regs.p.x, x, a), +tay(0xa8, regs.p.x, y, a), +txa(0x8a, regs.p.m, a, x), +txy(0x9b, regs.p.x, y, x), +tya(0x98, regs.p.m, a, y), +tyx(0xbb, regs.p.x, x, y) { +1:cpu_io(); + if($1) { + regs.$2.l = regs.$3.l; + regs.p.n = !!(regs.$2.l & 0x80); + regs.p.z = (regs.$2.l == 0); + } else { + regs.$2.w = regs.$3.w; + regs.p.n = !!(regs.$2.w & 0x8000); + regs.p.z = (regs.$2.w == 0); + } +} + +tcd(0x5b) { +1:cpu_io(); + regs.d.w = regs.a.w; + regs.p.n = !!(regs.d.w & 0x8000); + regs.p.z = (regs.d.w == 0); +} + +tcs(0x1b) { +1:cpu_io(); + regs.s.w = regs.a.w; + if(regs.e)regs.s.h = 0x01; +} + +tdc(0x7b) { +1:cpu_io(); + regs.a.w = regs.d.w; + regs.p.n = !!(regs.a.w & 0x8000); + regs.p.z = (regs.a.w == 0); +} + +tsc(0x3b) { +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); + } +} + +tsx(0xba) { +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); + } +} + +txs(0x9a) { +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); + } +} + +pha(0x48, regs.p.m, a), +phx(0xda, regs.p.x, x), +phy(0x5a, regs.p.x, y), +phd(0x0b, 0, d) { +1:cpu_io(); + if($1)skip; +2:stack_write(regs.$2.h); +3:stack_write(regs.$2.l); +} + +phb(0x8b, regs.db), +phk(0x4b, regs.pc.b), +php(0x08, regs.p) { +1:cpu_io(); +2:stack_write($1); +} + +pla(0x68, regs.p.m, a), +plx(0xfa, regs.p.x, x), +ply(0x7a, regs.p.x, y), +pld(0x2b, 0, d) { +1:cpu_io(); +2:cpu_io(); +3:regs.$2.l = stack_read(); + if($1) { + regs.p.n = !!(regs.$2.l & 0x80); + regs.p.z = (regs.$2.l == 0); + end; + } +4:regs.$2.h = stack_read(); + regs.p.n = !!(regs.$2.w & 0x8000); + regs.p.z = (regs.$2.w == 0); +} + +plb(0xab) { +1:cpu_io(); +2:cpu_io(); +3:regs.db = stack_read(); + regs.p.n = !!(regs.db & 0x80); + regs.p.z = (regs.db == 0); +} + +plp(0x28) { +1:cpu_io(); +2:cpu_io(); +3:regs.p = stack_read(); + if(regs.e)regs.p |= 0x30; + if(regs.p.x) { + regs.x.h = 0x00; + regs.y.h = 0x00; + } +} + +pea(0xf4) { +1:aa.l = op_read(); +2:aa.h = op_read(); +3:stack_write(aa.h); +4:stack_write(aa.l); +} + +pei(0xd4) { +1:dp = op_read(); +2:cpu_c2(); +3:aa.l = op_read(OPMODE_DP, dp); +4:aa.h = op_read(OPMODE_DP, dp + 1); +5:stack_write(aa.h); +6:stack_write(aa.l); +} + +per(0x62) { +1:aa.l = op_read(); +2:aa.h = op_read(); +3:cpu_io(); + rd.w = regs.pc.d + (int16)aa.w; +4:stack_write(rd.h); +5:stack_write(rd.l); +} diff --git a/src/cpu/bcpu/op_pc.b b/src/cpu/bcpu/op_pc.b new file mode 100644 index 00000000..c24ff5b5 --- /dev/null +++ b/src/cpu/bcpu/op_pc.b @@ -0,0 +1,137 @@ +bra(0x80, 1), +bcc(0x90, !regs.p.c), +bcs(0xb0, regs.p.c), +bne(0xd0, !regs.p.z), +beq(0xf0, regs.p.z), +bpl(0x10, !regs.p.n), +bmi(0x30, regs.p.n), +bvc(0x50, !regs.p.v), +bvs(0x70, regs.p.v) { +1:rd.l = op_read(); + if($1) { + aa.w = regs.pc.d + (int8)rd.l; + regs.pc.w = aa.w; + } else { + end; + } +2:cpu_c6(aa.w); +3:cpu_io(); +} + +brl(0x82) { +1:rd.l = op_read(); +2:rd.h = op_read(); +3:cpu_io(); + regs.pc.w = regs.pc.d + (int16)rd.w; +} + +jmp_addr(0x4c) { +1:rd.l = op_read(); +2:rd.h = op_read(); + regs.pc.w = rd.w; +} + +jmp_long(0x5c) { +1:rd.l = op_read(); +2:rd.h = op_read(); +3:rd.b = op_read(); + regs.pc.d = rd.d & 0xffffff; +} + +jmp_iaddr(0x6c) { +1:aa.l = op_read(); +2:aa.h = op_read(); +3:rd.l = op_read(OPMODE_ADDR, aa.w); +4:rd.h = op_read(OPMODE_ADDR, aa.w + 1); + regs.pc.w = rd.w; +} + +jmp_iaddrx(0x7c) { +1:aa.l = op_read(); +2:aa.h = op_read(); +3:cpu_io(); +4:rd.l = op_read(OPMODE_PBR, aa.w + regs.x.w); +5:rd.h = op_read(OPMODE_PBR, aa.w + regs.x.w + 1); + regs.pc.w = rd.w; +} + +jmp_iladdr(0xdc) { +1:aa.l = op_read(); +2:aa.h = op_read(); +3:rd.l = op_read(OPMODE_ADDR, aa.w); +4:rd.h = op_read(OPMODE_ADDR, aa.w + 1); +5:rd.b = op_read(OPMODE_ADDR, aa.w + 2); + regs.pc.d = rd.d & 0xffffff; +} + +jsr_addr(0x20) { +1:aa.l = op_read(); +2:aa.h = op_read(); +3:cpu_io(); +4:regs.pc.w--; + stack_write(regs.pc.h); +5:stack_write(regs.pc.l); + regs.pc.w = aa.w; +} + +jsr_long(0x22) { +1:aa.l = op_read(); +2:aa.h = op_read(); +3:stack_write(regs.pc.b); +4:cpu_io(); +5:aa.b = op_read(); +6:regs.pc.w--; + stack_write(regs.pc.h); +7:stack_write(regs.pc.l); + regs.pc.d = aa.d & 0xffffff; +} + +jsr_iaddrx(0xfc) { +1:aa.l = op_read(); +2:stack_write(regs.pc.h); +3:stack_write(regs.pc.l); +4:aa.h = op_read(); +5:cpu_io(); +6:rd.l = op_read(OPMODE_PBR, aa.w + regs.x.w); +7:rd.h = op_read(OPMODE_PBR, aa.w + regs.x.w + 1); + regs.pc.w = rd.w; +} + +rti(0x40) { +1:cpu_io(); +2:cpu_io(); +3:regs.p = stack_read(); + if(regs.e)regs.p |= 0x30; + if(regs.p.x) { + regs.x.h = 0x00; + regs.y.h = 0x00; + } +4:rd.l = stack_read(); +5:rd.h = stack_read(); + if(regs.e) { + regs.pc.w = rd.w; + end; + } +6:rd.b = stack_read(); + regs.pc.d = rd.d & 0xffffff; +} + +rts(0x60) { +1:cpu_io(); +2:cpu_io(); +3:rd.l = stack_read(); +4:rd.h = stack_read(); +5:cpu_io(); + regs.pc.w = rd.w; + regs.pc.w++; +} + +rtl(0x6b) { +1:cpu_io(); +2:cpu_io(); +3:rd.l = stack_read(); +4:rd.h = stack_read(); +5:rd.b = stack_read(); + regs.pc.d = rd.d & 0xffffff; + regs.pc.w++; +} diff --git a/src/cpu/bcpu/op_read.b b/src/cpu/bcpu/op_read.b new file mode 100644 index 00000000..fb384d71 --- /dev/null +++ b/src/cpu/bcpu/op_read.b @@ -0,0 +1,283 @@ +adc_const(0x69, adc, regs.p.m), +and_const(0x29, and, regs.p.m), +cmp_const(0xc9, cmp, regs.p.m), +cpx_const(0xe0, cpx, regs.p.x), +cpy_const(0xc0, cpy, regs.p.x), +eor_const(0x49, eor, regs.p.m), +lda_const(0xa9, lda, regs.p.m), +ldx_const(0xa2, ldx, regs.p.x), +ldy_const(0xa0, ldy, regs.p.x), +ora_const(0x09, ora, regs.p.m), +sbc_const(0xe9, sbc, regs.p.m) { +1:rd.l = op_read(); + if($2) { op_$1_b(); end; } +2:rd.h = op_read(); + op_$1_w(); +} + +adc_addr(0x6d, adc, regs.p.m), +and_addr(0x2d, and, regs.p.m), +bit_addr(0x2c, bit, regs.p.m), +cmp_addr(0xcd, cmp, regs.p.m), +cpx_addr(0xec, cpx, regs.p.x), +cpy_addr(0xcc, cpy, regs.p.x), +eor_addr(0x4d, eor, regs.p.m), +lda_addr(0xad, lda, regs.p.m), +ldx_addr(0xae, ldx, regs.p.x), +ldy_addr(0xac, ldy, regs.p.x), +ora_addr(0x0d, ora, regs.p.m), +sbc_addr(0xed, sbc, regs.p.m) { +1:aa.l = op_read(); +2:aa.h = op_read(); +3:rd.l = op_read(OPMODE_DBR, aa.w); + if($2) { op_$1_b(); end; } +4:rd.h = op_read(OPMODE_DBR, aa.w + 1); + op_$1_w(); +} + +adc_addrx(0x7d, adc, regs.p.m), +and_addrx(0x3d, and, regs.p.m), +bit_addrx(0x3c, bit, regs.p.m), +cmp_addrx(0xdd, cmp, regs.p.m), +eor_addrx(0x5d, eor, regs.p.m), +lda_addrx(0xbd, lda, regs.p.m), +ldy_addrx(0xbc, ldy, regs.p.x), +ora_addrx(0x1d, ora, regs.p.m), +sbc_addrx(0xfd, sbc, regs.p.m) { +1:aa.l = op_read(); +2:aa.h = op_read(); +3:cpu_c4(aa.w, aa.w + regs.x.w); +4:rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); + if($2) { op_$1_b(); end; } +5:rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); + op_$1_w(); +} + +adc_addry(0x79, adc, regs.p.m), +and_addry(0x39, and, regs.p.m), +cmp_addry(0xd9, cmp, regs.p.m), +eor_addry(0x59, eor, regs.p.m), +lda_addry(0xb9, lda, regs.p.m), +ldx_addry(0xbe, ldx, regs.p.x), +ora_addry(0x19, ora, regs.p.m), +sbc_addry(0xf9, sbc, regs.p.m) { +1:aa.l = op_read(); +2:aa.h = op_read(); +3:cpu_c4(aa.w, aa.w + regs.y.w); +4:rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); + if($2) { op_$1_b(); end; } +5:rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); + op_$1_w(); +} + +adc_long(0x6f, adc, regs.p.m), +and_long(0x2f, and, regs.p.m), +cmp_long(0xcf, cmp, regs.p.m), +eor_long(0x4f, eor, regs.p.m), +lda_long(0xaf, lda, regs.p.m), +ora_long(0x0f, ora, regs.p.m), +sbc_long(0xef, sbc, regs.p.m) { +1:aa.l = op_read(); +2:aa.h = op_read(); +3:aa.b = op_read(); +4:rd.l = op_read(OPMODE_LONG, aa.d); + if($2) { op_$1_b(); end; } +5:rd.h = op_read(OPMODE_LONG, aa.d + 1); + op_$1_w(); +} + +adc_longx(0x7f, adc, regs.p.m), +and_longx(0x3f, and, regs.p.m), +cmp_longx(0xdf, cmp, regs.p.m), +eor_longx(0x5f, eor, regs.p.m), +lda_longx(0xbf, lda, regs.p.m), +ora_longx(0x1f, ora, regs.p.m), +sbc_longx(0xff, sbc, regs.p.m) { +1:aa.l = op_read(); +2:aa.h = op_read(); +3:aa.b = op_read(); +4:rd.l = op_read(OPMODE_LONG, aa.d + regs.x.w); + if($2) { op_$1_b(); end; } +5:rd.h = op_read(OPMODE_LONG, aa.d + regs.x.w + 1); + op_$1_w(); +} + +adc_dp(0x65, adc, regs.p.m), +and_dp(0x25, and, regs.p.m), +bit_dp(0x24, bit, regs.p.m), +cmp_dp(0xc5, cmp, regs.p.m), +cpx_dp(0xe4, cpx, regs.p.x), +cpy_dp(0xc4, cpy, regs.p.x), +eor_dp(0x45, eor, regs.p.m), +lda_dp(0xa5, lda, regs.p.m), +ldx_dp(0xa6, ldx, regs.p.x), +ldy_dp(0xa4, ldy, regs.p.x), +ora_dp(0x05, ora, regs.p.m), +sbc_dp(0xe5, sbc, regs.p.m) { +1:dp = op_read(); +2:cpu_c2(); +3:rd.l = op_read(OPMODE_DP, dp); + if($2) { op_$1_b(); end; } +4:rd.h = op_read(OPMODE_DP, dp + 1); + op_$1_w(); +} + +adc_dpx(0x75, adc, regs.p.m), +and_dpx(0x35, and, regs.p.m), +bit_dpx(0x34, bit, regs.p.m), +cmp_dpx(0xd5, cmp, regs.p.m), +eor_dpx(0x55, eor, regs.p.m), +lda_dpx(0xb5, lda, regs.p.m), +ldy_dpx(0xb4, ldy, regs.p.x), +ora_dpx(0x15, ora, regs.p.m), +sbc_dpx(0xf5, sbc, regs.p.m) { +1:dp = op_read(); +2:cpu_c2(); +3:cpu_io(); +4:rd.l = op_read(OPMODE_DP, dp + regs.x.w); + if($2) { op_$1_b(); end; } +5:rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); + op_$1_w(); +} + +ldx_dpy(0xb6, ldx, regs.p.x) { +1:dp = op_read(); +2:cpu_c2(); +3:cpu_io(); +4:rd.l = op_read(OPMODE_DP, dp + regs.y.w); + if($2) { op_$1_b(); end; } +5:rd.h = op_read(OPMODE_DP, dp + regs.y.w + 1); + op_$1_w(); +} + +adc_idp(0x72, adc, regs.p.m), +and_idp(0x32, and, regs.p.m), +cmp_idp(0xd2, cmp, regs.p.m), +eor_idp(0x52, eor, regs.p.m), +lda_idp(0xb2, lda, regs.p.m), +ora_idp(0x12, ora, regs.p.m), +sbc_idp(0xf2, sbc, regs.p.m) { +1:dp = op_read(); +2:cpu_c2(); +3:aa.l = op_read(OPMODE_DP, dp); +4:aa.h = op_read(OPMODE_DP, dp + 1); +5:rd.l = op_read(OPMODE_DBR, aa.w); + if($2) { op_$1_b(); end; } +6:rd.h = op_read(OPMODE_DBR, aa.w + 1); + op_$1_w(); +} + +adc_idpx(0x61, adc, regs.p.m), +and_idpx(0x21, and, regs.p.m), +cmp_idpx(0xc1, cmp, regs.p.m), +eor_idpx(0x41, eor, regs.p.m), +lda_idpx(0xa1, lda, regs.p.m), +ora_idpx(0x01, ora, regs.p.m), +sbc_idpx(0xe1, sbc, regs.p.m) { +1:dp = op_read(); +2:cpu_c2(); +3:cpu_io(); +4:aa.l = op_read(OPMODE_DP, dp + regs.x.w); +5:aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); +6:rd.l = op_read(OPMODE_DBR, aa.w); + if($2) { op_$1_b(); end; } +7:rd.h = op_read(OPMODE_DBR, aa.w + 1); + op_$1_w(); +} + +adc_idpy(0x71, adc, regs.p.m), +and_idpy(0x31, and, regs.p.m), +cmp_idpy(0xd1, cmp, regs.p.m), +eor_idpy(0x51, eor, regs.p.m), +lda_idpy(0xb1, lda, regs.p.m), +ora_idpy(0x11, ora, regs.p.m), +sbc_idpy(0xf1, sbc, regs.p.m) { +1:dp = op_read(); +2:cpu_c2(); +3:aa.l = op_read(OPMODE_DP, dp); +4:aa.h = op_read(OPMODE_DP, dp + 1); +5:cpu_c4(aa.w, aa.w + regs.y.w); +6:rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); + if($2) { op_$1_b(); end; } +7:rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); + op_$1_w(); +} + +adc_ildp(0x67, adc, regs.p.m), +and_ildp(0x27, and, regs.p.m), +cmp_ildp(0xc7, cmp, regs.p.m), +eor_ildp(0x47, eor, regs.p.m), +lda_ildp(0xa7, lda, regs.p.m), +ora_ildp(0x07, ora, regs.p.m), +sbc_ildp(0xe7, sbc, regs.p.m) { +1:dp = op_read(); +2:cpu_c2(); +3:aa.l = op_read(OPMODE_DP, dp); +4:aa.h = op_read(OPMODE_DP, dp + 1); +5:aa.b = op_read(OPMODE_DP, dp + 2); +6:rd.l = op_read(OPMODE_LONG, aa.d); + if($2) { op_$1_b(); end; } +7:rd.h = op_read(OPMODE_LONG, aa.d + 1); + op_$1_w(); +} + +adc_ildpy(0x77, adc, regs.p.m), +and_ildpy(0x37, and, regs.p.m), +cmp_ildpy(0xd7, cmp, regs.p.m), +eor_ildpy(0x57, eor, regs.p.m), +lda_ildpy(0xb7, lda, regs.p.m), +ora_ildpy(0x17, ora, regs.p.m), +sbc_ildpy(0xf7, sbc, regs.p.m) { +1:dp = op_read(); +2:cpu_c2(); +3:aa.l = op_read(OPMODE_DP, dp); +4:aa.h = op_read(OPMODE_DP, dp + 1); +5:aa.b = op_read(OPMODE_DP, dp + 2); +6:rd.l = op_read(OPMODE_LONG, aa.d + regs.y.w); + if($2) { op_$1_b(); end; } +7:rd.h = op_read(OPMODE_LONG, aa.d + regs.y.w + 1); + op_$1_w(); +} + +adc_sr(0x63, adc, regs.p.m), +and_sr(0x23, and, regs.p.m), +cmp_sr(0xc3, cmp, regs.p.m), +eor_sr(0x43, eor, regs.p.m), +lda_sr(0xa3, lda, regs.p.m), +ora_sr(0x03, ora, regs.p.m), +sbc_sr(0xe3, sbc, regs.p.m) { +1:sp = op_read(); +2:cpu_io(); +3:rd.l = op_read(OPMODE_SP, sp); + if($2) { op_$1_b(); end; } +4:rd.h = op_read(OPMODE_SP, sp + 1); + op_$1_w(); +} + +adc_isry(0x73, adc), +and_isry(0x33, and), +cmp_isry(0xd3, cmp), +eor_isry(0x53, eor), +lda_isry(0xb3, lda), +ora_isry(0x13, ora), +sbc_isry(0xf3, sbc) { +1:sp = op_read(); +2:cpu_io(); +3:aa.l = op_read(OPMODE_SP, sp); +4:aa.h = op_read(OPMODE_SP, sp + 1); +5:cpu_io(); +6:rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); + if(regs.p.m) { op_$1_b(); end; } +7:rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); + op_$1_w(); +} + +bit_const(0x89) { +1:rd.l = op_read(); + if(regs.p.m) { + regs.p.z = ((rd.l & regs.a.l) == 0); + end; + } +2:rd.h = op_read(); + regs.p.z = ((rd.w & regs.a.w) == 0); +} diff --git a/src/cpu/bcpu/op_rmw.b b/src/cpu/bcpu/op_rmw.b new file mode 100644 index 00000000..2fff41b2 --- /dev/null +++ b/src/cpu/bcpu/op_rmw.b @@ -0,0 +1,175 @@ +inc(0x1a, regs.p.m, a), +inx(0xe8, regs.p.x, x), +iny(0xc8, regs.p.x, y) { +1:cpu_io(); + if($1) { + regs.$2.l++; + regs.p.n = !!(regs.$2.l & 0x80); + regs.p.z = (regs.$2.l == 0); + } else { + regs.$2.w++; + regs.p.n = !!(regs.$2.w & 0x8000); + regs.p.z = (regs.$2.w == 0); + } +} + +dec(0x3a, regs.p.m, a), +dex(0xca, regs.p.x, x), +dey(0x88, regs.p.x, y) { +1:cpu_io(); + if($1) { + regs.$2.l--; + regs.p.n = !!(regs.$2.l & 0x80); + regs.p.z = (regs.$2.l == 0); + } else { + regs.$2.w--; + regs.p.n = !!(regs.$2.w & 0x8000); + regs.p.z = (regs.$2.w == 0); + } +} + +asl(0x0a) { +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); + } +} + +lsr(0x4a) { +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); + } +} + +rol(0x2a) { +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); + } +} + +ror(0x6a) { +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); + } +} + +inc_addr(0xee, inc), +dec_addr(0xce, dec), +asl_addr(0x0e, asl), +lsr_addr(0x4e, lsr), +rol_addr(0x2e, rol), +ror_addr(0x6e, ror), +trb_addr(0x1c, trb), +tsb_addr(0x0c, tsb) { +1:aa.l = op_read(); +2:aa.h = op_read(); +3:rd.l = op_read(OPMODE_DBR, aa.w); + if(regs.p.m)skip; +4:rd.h = op_read(OPMODE_DBR, aa.w + 1); +5:cpu_io(); + if(regs.p.m) { op_$1_b(); skip; } + else op_$1_w(); +6:op_write(OPMODE_DBR, aa.w + 1, rd.h); +7:op_write(OPMODE_DBR, aa.w, rd.l); +} + +inc_addrx(0xfe, inc), +dec_addrx(0xde, dec), +asl_addrx(0x1e, asl), +lsr_addrx(0x5e, lsr), +rol_addrx(0x3e, rol), +ror_addrx(0x7e, ror) { +1:aa.l = op_read(); +2:aa.h = op_read(); +3:cpu_io(); +4:rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); + if(regs.p.m)skip; +5:rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); +6:cpu_io(); + if(regs.p.m) { op_$1_b(); skip; } + else op_$1_w(); +7:op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h); +8:op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); +} + +inc_dp(0xe6, inc), +dec_dp(0xc6, dec), +asl_dp(0x06, asl), +lsr_dp(0x46, lsr), +rol_dp(0x26, rol), +ror_dp(0x66, ror), +trb_dp(0x14, trb), +tsb_dp(0x04, tsb) { +1:dp = op_read(); +2:cpu_c2(); +3:rd.l = op_read(OPMODE_DP, dp); + if(regs.p.m)skip; +4:rd.h = op_read(OPMODE_DP, dp + 1); +5:cpu_io(); + if(regs.p.m) { op_$1_b(); skip; } + else op_$1_w(); +6:op_write(OPMODE_DP, dp + 1, rd.h); +7:op_write(OPMODE_DP, dp, rd.l); +} + +inc_dpx(0xf6, inc), +dec_dpx(0xd6, dec), +asl_dpx(0x16, asl), +lsr_dpx(0x56, lsr), +rol_dpx(0x36, rol), +ror_dpx(0x76, ror) { +1:dp = op_read(); +2:cpu_c2(); +3:cpu_io(); +4:rd.l = op_read(OPMODE_DP, dp + regs.x.w); + if(regs.p.m)skip; +5:rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); +6:cpu_io(); + if(regs.p.m) { op_$1_b(); skip; } + else op_$1_w(); +7:op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h); +8:op_write(OPMODE_DP, dp + regs.x.w, rd.l); +} diff --git a/src/cpu/bcpu/op_write.b b/src/cpu/bcpu/op_write.b new file mode 100644 index 00000000..e1ba5c14 --- /dev/null +++ b/src/cpu/bcpu/op_write.b @@ -0,0 +1,151 @@ +sta_addr(0x8d, regs.p.m, regs.a.w), +stx_addr(0x8e, regs.p.x, regs.x.w), +sty_addr(0x8c, regs.p.x, regs.y.w), +stz_addr(0x9c, regs.p.m, 0x0000) { +1:aa.l = op_read(); +2:aa.h = op_read(); +3:op_write(OPMODE_DBR, aa.w, $2); + if($1)end; +4:op_write(OPMODE_DBR, aa.w + 1, $2 >> 8); +} + +sta_addrx(0x9d, regs.p.m, regs.a.w), +stz_addrx(0x9e, regs.p.m, 0x0000) { +1:aa.l = op_read(); +2:aa.h = op_read(); +3:cpu_c4(aa.w, aa.w + regs.x.w); +4:op_write(OPMODE_DBR, aa.w + regs.x.w, $2); + if($1)end; +5:op_write(OPMODE_DBR, aa.w + regs.x.w + 1, $2 >> 8); +} + +sta_addry(0x99) { +1:aa.l = op_read(); +2:aa.h = op_read(); +3:cpu_c4(aa.w, aa.w + regs.y.w); +4:op_write(OPMODE_DBR, aa.w + regs.y.w, regs.a.l); + if(regs.p.m)end; +5:op_write(OPMODE_DBR, aa.w + regs.y.w + 1, regs.a.h); +} + +sta_long(0x8f) { +1:aa.l = op_read(); +2:aa.h = op_read(); +3:aa.b = op_read(); +4:op_write(OPMODE_LONG, aa.d, regs.a.l); + if(regs.p.m)end; +5:op_write(OPMODE_LONG, aa.d + 1, regs.a.h); +} + +sta_longx(0x9f) { +1:aa.l = op_read(); +2:aa.h = op_read(); +3:aa.b = op_read(); +4:op_write(OPMODE_LONG, aa.d + regs.x.w, regs.a.l); + if(regs.p.m)end; +5:op_write(OPMODE_LONG, aa.d + regs.x.w + 1, regs.a.h); +} + +sta_dp(0x85, regs.p.m, regs.a.w), +stx_dp(0x86, regs.p.x, regs.x.w), +sty_dp(0x84, regs.p.x, regs.y.w), +stz_dp(0x64, regs.p.m, 0x0000) { +1:dp = op_read(); +2:cpu_c2(); +3:op_write(OPMODE_DP, dp, $2); + if($1)end; +4:op_write(OPMODE_DP, dp + 1, $2 >> 8); +} + +sta_dpx(0x95, regs.p.m, regs.a.w), +sty_dpx(0x94, regs.p.x, regs.y.w), +stz_dpx(0x74, regs.p.m, 0x0000) { +1:dp = op_read(); +2:cpu_c2(); +3:cpu_io(); +4:op_write(OPMODE_DP, dp + regs.x.w, $2); + if($1)end; +5:op_write(OPMODE_DP, dp + regs.x.w + 1, $2 >> 8); +} + +stx_dpy(0x96) { +1:dp = op_read(); +2:cpu_c2(); +3:cpu_io(); +4:op_write(OPMODE_DP, dp + regs.y.w, regs.x.l); + if(regs.p.x)end; +5:op_write(OPMODE_DP, dp + regs.y.w + 1, regs.x.h); +} + +sta_idp(0x92) { +1:dp = op_read(); +2:cpu_c2(); +3:aa.l = op_read(OPMODE_DP, dp); +4:aa.h = op_read(OPMODE_DP, dp + 1); +5:op_write(OPMODE_DBR, aa.w, regs.a.l); + if(regs.p.m)end; +6:op_write(OPMODE_DBR, aa.w + 1, regs.a.h); +} + +sta_ildp(0x87) { +1:dp = op_read(); +2:cpu_c2(); +3:aa.l = op_read(OPMODE_DP, dp); +4:aa.h = op_read(OPMODE_DP, dp + 1); +5:aa.b = op_read(OPMODE_DP, dp + 2); +6:op_write(OPMODE_LONG, aa.d, regs.a.l); + if(regs.p.m)end; +7:op_write(OPMODE_LONG, aa.d + 1, regs.a.h); +} + +sta_idpx(0x81) { +1:dp = op_read(); +2:cpu_c2(); +3:cpu_io(); +4:aa.l = op_read(OPMODE_DP, dp + regs.x.w); +5:aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); +6:op_write(OPMODE_DBR, aa.w, regs.a.l); + if(regs.p.m)end; +7:op_write(OPMODE_DBR, aa.w + 1, regs.a.h); +} + +sta_idpy(0x91) { +1:dp = op_read(); +2:cpu_c2(); +3:aa.l = op_read(OPMODE_DP, dp); +4:aa.h = op_read(OPMODE_DP, dp + 1); +5:cpu_c4(aa.w, aa.w + regs.y.w); +6:op_write(OPMODE_DBR, aa.w + regs.y.w, regs.a.l); + if(regs.p.m)end; +7:op_write(OPMODE_DBR, aa.w + regs.y.w + 1, regs.a.h); +} + +sta_ildpy(0x97) { +1:dp = op_read(); +2:cpu_c2(); +3:aa.l = op_read(OPMODE_DP, dp); +4:aa.h = op_read(OPMODE_DP, dp + 1); +5:aa.b = op_read(OPMODE_DP, dp + 2); +6:op_write(OPMODE_LONG, aa.d + regs.y.w, regs.a.l); + if(regs.p.m)end; +7:op_write(OPMODE_LONG, aa.d + regs.y.w + 1, regs.a.h); +} + +sta_sr(0x83) { +1:sp = op_read(); +2:cpu_io(); +3:op_write(OPMODE_SP, sp, regs.a.l); + if(regs.p.m)end; +4:op_write(OPMODE_SP, sp + 1, regs.a.h); +} + +sta_isry(0x93) { +1:sp = op_read(); +2:cpu_io(); +3:aa.l = op_read(OPMODE_SP, sp); +4:aa.h = op_read(OPMODE_SP, sp + 1); +5:cpu_io(); +6:op_write(OPMODE_DBR, aa.w + regs.y.w, regs.a.l); + if(regs.p.m)end; +7:op_write(OPMODE_DBR, aa.w + regs.y.w + 1, regs.a.h); +} diff --git a/src/cpu/bcpu/srtc.cpp b/src/cpu/bcpu/srtc.cpp new file mode 100644 index 00000000..d1c1281d --- /dev/null +++ b/src/cpu/bcpu/srtc.cpp @@ -0,0 +1,158 @@ +/* + S-RTC chip emulation + Used by Hudson Soft in Dai Kaijuu Monogatari II and Far East of Eden Zero. + Currently, only the former is supported by bsnes. + + Original S-RTC emulation code via John Weidman/SNES9x + Rewritten for compatibility with bsnes via byuu + + The S-RTC is a real-time clock chip that was added to the above two carts + to allow the games to maintain the current time, even when the game was not + powered on. Thus allowing special events at certain times, and on certain + dates. Hudson Soft called this the PLG (Player's Life Gameplay System). + + This chip is a special case to the term 'emulation' itself. + There are a few different ways to go about emulating this chip, and each + result in a different style of emulation. + + The first is to simply return the current PC system time when the S-RTC is + read from. This emulates the original S-RTC in the sense that it always + returns the true current time, ignoring the speed that the SNES itself is + running at. The downside to this method is that you lose the ability to set + the time to whatever you choose inside the game itself. It will always return + the true time, regardless. This can be overcome by changing the PC system time, + which actually adds a greater degree of control over event timing, very useful + for emulation. It also has a timeshifting flaw discussed below. + + The second is to run the S-RTC relative to the SNES speed. This means that + if the emulator is sped up (via fast forward key, frameskipping, etc), or + slowed down (via slowdown key, system bottlenecking, etc); the time increments + slower, thus ~60 frames on the SNES equal one second. Without this, timeshifting + will occur between the S-RTC and the real SNES. + + The third and final method is to save a copy of the local system time when the + S-RTC is initially set, and compare the current system time against this value + when setting the S-RTC time. This overcomes the first methods' shortcoming of + not allowing the player to set the time in-game, however a new problem arises. + You now have to save the time when the RTC was initially set to both savestates + and to save-game data. This would require an extra file, or the breaking of + perhaps the only standard format (.srm savegame backups) in the entire SNES + emulation scene. You also give up the control of being able to override the + RTC clock at will via the PC system time outside of emulation. + The first method has another advantage over the third: Dai Kaijuu Monogatari II + only allows dates in the range of the years 1996-2199. The first method gets + around this limitation. But who knows, maybe it will break something in the + game if the date exceeds 2199... I guess we'll worry about that in two hundred + years from now. + + For my implementation, I chose to go with the first method. Both for simplicity + and because I did not wish to create a new method for saving the system time + whenever the RTC is set. +*/ + +void bCPU::srtc_set_time() { +time_t rawtime; +tm *t; + ::time(&rawtime); + t = localtime(&rawtime); + +//see srtc.h for format of srtc.data[] + srtc.data[0] = t->tm_sec % 10; + srtc.data[1] = t->tm_sec / 10; + srtc.data[2] = t->tm_min % 10; + srtc.data[3] = t->tm_min / 10; + srtc.data[4] = t->tm_hour % 10; + srtc.data[5] = t->tm_hour / 10; + srtc.data[6] = t->tm_mday % 10; + srtc.data[7] = t->tm_mday / 10; + srtc.data[8] = t->tm_mon + 1; + srtc.data[9] = t->tm_year % 10; + srtc.data[10] = (t->tm_year / 10) % 10; + srtc.data[11] = 9 + (t->tm_year / 100); + srtc.data[12] = t->tm_wday; +} + +void bCPU::srtc_power() { + memset(&srtc, 0, sizeof(srtc)); + reset(); +} + +void bCPU::srtc_reset() { + srtc.index = -1; + srtc.mode = SRTC_READ; +} + +//Please see notes above about the implementation of the S-RTC +//Writes are stored the srtc.data[] array, but they are ignored +//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) { + data &= 0x0f; //only the low four bits are used + + if(data >= 0x0d) { + switch(data) { + case 0x0d: + srtc.mode = SRTC_READ; + srtc.index = -1; + break; + case 0x0e: + srtc.mode = SRTC_COMMAND; + break; + case 0x0f: + //unknown behaviour + break; + } + return; + } + + if(srtc.mode == SRTC_WRITE) { + if(srtc.index >= 0 && srtc.index < MAX_SRTC_INDEX) { + srtc.data[srtc.index++] = data; + + if(srtc.index == MAX_SRTC_INDEX) { + //all S-RTC data has been loaded by program + srtc.data[srtc.index++] = 0x00; //day_of_week + } + } + } else if(srtc.mode == SRTC_COMMAND) { + switch(data) { + case SRTC_COMMAND_CLEAR: + memset(srtc.data, 0, MAX_SRTC_INDEX + 1); + srtc.index = -1; + srtc.mode = SRTC_READY; + break; + case SRTC_COMMAND_WRITE: + srtc.index = 0; + srtc.mode = SRTC_WRITE; + break; + default: + //unknown behaviour + srtc.mode = SRTC_READY; + break; + } + } else { + if(srtc.mode == SRTC_READ) { + //ignore writes while in read mode + } else if(srtc.mode == SRTC_READY) { + //unknown behaviour + } + } +} + +uint8 bCPU::srtc_read() { + if(srtc.mode == SRTC_READ) { + if(srtc.index < 0) { + srtc_set_time(); + srtc.index++; + return 0x0f; //send start message + } else if(srtc.index > MAX_SRTC_INDEX) { + srtc.index = -1; + return 0x0f; //send finished message + } else { + return srtc.data[srtc.index++]; + } + } else { + return 0x00; + } +} diff --git a/src/cpu/bcpu/srtc.h b/src/cpu/bcpu/srtc.h new file mode 100644 index 00000000..4a828e3f --- /dev/null +++ b/src/cpu/bcpu/srtc.h @@ -0,0 +1,48 @@ +void srtc_set_time(); +void srtc_power(); +void srtc_reset(); +void srtc_write(uint8 data); +uint8 srtc_read(); + +#define MAX_SRTC_INDEX 0x0c + +enum { + SRTC_READ = 0, + SRTC_WRITE, + SRTC_COMMAND, + SRTC_READY +}; + +enum { + SRTC_COMMAND_WRITE = 0, + SRTC_COMMAND_CLEAR = 4 +}; + +#define DAYTICKS (60*60*24) +#define HOURTICKS (60*60) +#define MINUTETICKS (60) + +/****************************** +[srtc.data structure] +Index Description Range +----- ----------- ----- + 0 Seconds low 0-9 + 1 Seconds high 0-5 + 2 Minutes low 0-9 + 3 Minutes high 0-5 + 4 Hour low 0-9 + 5 Hour high 0-2 + 6 Day low 0-9 + 7 Day high 0-3 + 8 Month 1-12 + 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, ...) +******************************/ + +struct { + int8 index; + uint8 mode; + uint8 data[MAX_SRTC_INDEX + 1]; +}srtc; diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 9ecbf73f..92777167 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -2,20 +2,34 @@ class CPU { public: +//timing + virtual uint16 vcounter() = 0; + virtual uint16 hcounter() = 0; + virtual uint16 hcycles() = 0; + virtual bool interlace() = 0; + virtual bool interlace_field() = 0; + virtual bool overscan() = 0; + + virtual void set_interlace(bool r) = 0; + virtual void set_overscan (bool r) = 0; + MMIO *mmio; CPURegs regs; + virtual uint8 port_read (uint8 port) = 0; + virtual void port_write(uint8 port, uint8 value) = 0; + enum { FLAG_N = 0x80, FLAG_V = 0x40, FLAG_M = 0x20, FLAG_X = 0x10, FLAG_D = 0x08, FLAG_I = 0x04, FLAG_Z = 0x02, FLAG_C = 0x01 }; - virtual uint8 pio_status() = 0; - virtual void run() = 0; - virtual void scanline() = 0; - virtual void frame() = 0; - virtual void power() = 0; - virtual void reset() = 0; + virtual uint8 pio_status() = 0; + virtual void run() = 0; + virtual void scanline() = 0; + virtual void frame() = 0; + virtual void power() = 0; + virtual void reset() = 0; //opcode disassembler enum { diff --git a/src/cpu/cpuregs.h b/src/cpu/cpuregs.h index 6725fe2a..215ef2eb 100644 --- a/src/cpu/cpuregs.h +++ b/src/cpu/cpuregs.h @@ -2,32 +2,35 @@ class CPURegFlags { private: template class bit { public: - uint8 b; - inline operator bool() { return (b & B); } - inline operator = (bool i) { (i) ? b |= B : b &= ~B; return (b & B); } - inline operator & (bool i) { if(i)b &= ~B; return (b & B); } - inline operator | (bool i) { if(i)b |= B; return (b & B); } - inline operator ^ (bool i) { if(i)b ^= B; return (b & B); } + uint8 _b; + inline operator bool() { return (_b & B); } + inline bool operator = (bool i) { (i) ? _b |= B : _b &= ~B; return (_b & B); } + inline bool operator & (bool i) { if(i)_b &= ~B; return (_b & B); } + inline bool operator &= (bool i) { if(i)_b &= ~B; return (_b & B); } + inline bool operator | (bool i) { if(i)_b |= B; return (_b & B); } + inline bool operator |= (bool i) { if(i)_b |= B; return (_b & B); } + inline bool operator ^ (bool i) { if(i)_b ^= B; return (_b & B); } + inline bool operator ^= (bool i) { if(i)_b ^= B; return (_b & B); } }; public: union { - uint8 b; + uint8 _b; bit<0x80> n; bit<0x40> v; - bit<0x20> m; - bit<0x10> x; + bit<0x20> m, p; + bit<0x10> x, b; bit<0x08> d; bit<0x04> i; bit<0x02> z; bit<0x01> c; }; - CPURegFlags() { b = 0; } - inline operator uint8() { return b; } - inline unsigned operator = (uint8 i) { b = i; return b; } - inline unsigned operator &= (uint8 i) { b &= i; return b; } - inline unsigned operator |= (uint8 i) { b |= i; return b; } - inline unsigned operator ^= (uint8 i) { b ^= i; return b; } + CPURegFlags() { _b = 0; } + inline operator uint8() { return _b; } + inline unsigned operator = (uint8 i) { _b = i; return _b; } + inline unsigned operator &= (uint8 i) { _b &= i; return _b; } + inline unsigned operator |= (uint8 i) { _b |= i; return _b; } + inline unsigned operator ^= (uint8 i) { _b ^= i; return _b; } }; class CPUReg16 { diff --git a/src/cpu/dcpu.cpp b/src/cpu/dcpu.cpp index 240bcaab..26137d2d 100644 --- a/src/cpu/dcpu.cpp +++ b/src/cpu/dcpu.cpp @@ -378,7 +378,7 @@ uint8 op, op0, op1, op2; strcat(s, " "); sprintf(t, "A:%0.4x X:%0.4x Y:%0.4x S:%0.4x D:%0.4x DB:%0.2x ", - regs.a.w, regs.x.w, regs.y.w, regs.s.w, regs.d, regs.db); + regs.a.w, regs.x.w, regs.y.w, regs.s.w, regs.d.w, regs.db); strcat(s, t); if(regs.e) { sprintf(t, "%c%c%c%c%c%c%c%c", diff --git a/src/interface.h b/src/interface.h index d4e45224..0a6cedca 100644 --- a/src/interface.h +++ b/src/interface.h @@ -1,9 +1,5 @@ #include "reader/reader.h" -#include "clock/clock.h" -#include "clock/bclock/bclock.h" -extern Clock *clock; - #include "memory/memory.h" #include "memory/bmemory/bmemory.h" extern MMIO mmio_unmapped; @@ -13,6 +9,11 @@ extern MemBus *mem_bus; #include "cpu/bcpu/bcpu.h" extern CPU *cpu; +#include "apu/apu.h" +#include "apu/bapu/bapu.h" +#include "apu/bapuskip/bapuskip.h" +extern APU *apu; + #include "ppu/ppu.h" #include "ppu/bppu/bppu.h" extern PPU *ppu; @@ -21,9 +22,9 @@ extern PPU *ppu; extern SNES *snes; #ifdef INTERFACE_MAIN - Clock *clock; - MemBus *mem_bus; - CPU *cpu; - PPU *ppu; - SNES *snes; + MemBus *mem_bus; + CPU *cpu; + APU *apu; + PPU *ppu; + SNES *snes; #endif diff --git a/src/lib/libconfig.cpp b/src/lib/libconfig.cpp index 5fb4cf31..247ea6f2 100644 --- a/src/lib/libconfig.cpp +++ b/src/lib/libconfig.cpp @@ -1,18 +1,29 @@ #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 (is_string == true) ? (*strsource != strdef) : (*source != def); + 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, ""); is_string = false; source = 0; strsource = 0; def = 0; - strdef = ""; type = 0; - name = ""; } void config::add(uint32 *variable, char *name, uint32 def, uint32 type) { @@ -21,13 +32,12 @@ int n; n = item_count; item[n] = new config_item(); - + strcpy(item[n]->name, name); item[n]->is_string = false; - item[n]->name = name; - item[n]->source = variable; item[n]->def = def; - item[n]->type = type; + item[n]->source = variable; *item[n]->source = item[n]->def; + item[n]->type = type; item_count++; } @@ -38,18 +48,19 @@ int n; n = item_count; item[n] = new config_item(); - item[n]->is_string = true; - item[n]->name = name; - item[n]->strsource = variable; - item[n]->strdef = def; - *item[n]->strsource = item[n]->strdef; + strcpy(item[n]->name, name); + item[n]->is_string = true; + strcpy(item[n]->strdef, def); + item[n]->strsource = variable; + strcpy(*item[n]->strsource, item[n]->strdef); + item[n]->type = type; item_count++; } uint32 config::find(char *name) { for(int i=0;iname == name) { + if(!strcmp(item[i]->name, name)) { return i; } } @@ -66,7 +77,7 @@ string &config::strget(char *name) { int i = find(name); if(i == null) { static string not_found; - not_found = ""; + strcmp(not_found, ""); return not_found; } return *item[i]->strsource; @@ -81,7 +92,7 @@ int i = find(name); void config::set(char *name, char *value) { int i = find(name); if(i == null)return; - *item[i]->strsource = value; + strcpy(*item[i]->strsource, value); } void config::load(char *fn) { @@ -90,14 +101,14 @@ char *buffer; int i, fsize; uint32 l; fp = fopen(fn, "rb"); -/* file doesn't exist yet, do nothing */ +//file doesn't exist yet, do nothing if(!fp)return; fseek(fp, 0, SEEK_END); fsize = ftell(fp); fseek(fp, 0, SEEK_SET); -/* blank file, do nothing */ +//blank file, do nothing if(fsize == 0) { fclose(fp); return; @@ -108,7 +119,7 @@ uint32 l; fclose(fp); buffer[fsize] = 0; - data = buffer; + strcpy(data, buffer); free(buffer); replace(data, "\r\n", "\n"); qreplace(data, "\t", " "); @@ -118,29 +129,31 @@ uint32 l; for(i=0;isource = 1; - } else if(part[1] == "false" || part[1] == "no" || part[1] == "off" || part[1] == "disabled") { + } else if(!strcmp(part[1], "false") || !strcmp(part[1], "no") || + !strcmp(part[1], "off") || !strcmp(part[1], "disabled")) { *item[l]->source = 0; } else if(item[l]->type == HEX) { - *item[l]->source = strhex(part[1]); + *item[l]->source = strhex(*part[1] + 2); //skip 0x prefix } else { /* fall back on DEC */ *item[l]->source = strdec(part[1]); } @@ -149,38 +162,38 @@ uint32 l; } } -/* create a text string from config item[i] to be output via config->save() */ +//create a text string from config item[i] to be output via config->save() void config::set_newline(int i) { char t[16]; if(item[i]->is_string == true) { - newline = item[i]->name; - newline += " = \""; - newline += *item[i]->strsource; - newline += "\""; + strcpy(newline, item[i]->name); + strcat(newline, " = \""); + strcat(newline, *item[i]->strsource); + strcat(newline, "\""); } else { - newline = item[i]->name; - newline += " = "; + strcpy(newline, item[i]->name); + strcat(newline, " = "); switch(item[i]->type) { case TRUEFALSE: - newline += (*item[i]->source)?"true":"false"; + strcat(newline, (*item[i]->source)?"true":"false"); break; case YESNO: - newline += (*item[i]->source)?"yes":"no"; + strcat(newline, (*item[i]->source)?"yes":"no"); break; case ONOFF: - newline += (*item[i]->source)?"on":"off"; + strcat(newline, (*item[i]->source)?"on":"off"); break; case ENABLED: - newline += (*item[i]->source)?"enabled":"disabled"; + strcat(newline, (*item[i]->source)?"enabled":"disabled"); break; case HEX: - sprintf(t, "%x", *item[i]->source); - newline += t; + sprintf(t, "0x%0.2x", *item[i]->source); + strcat(newline, t); break; case DEC: default: sprintf(t, "%d", *item[i]->source); - newline += t; + strcat(newline, t); break; } } @@ -206,21 +219,21 @@ bool blank = false; } else { buffer = (char*)malloc(fsize + 1); fread(buffer, 1, fsize, fp); - fclose(fp); buffer[fsize] = 0; - data = buffer; + strcpy(data, buffer); free(buffer); } + fclose(fp); } fp = fopen(fn, "wb"); -/* no write access? */ +//no write access? if(!fp)return; -/* list of config items. if the item is set in the - existing config file, then don't test it to see - if it needs to be written again later on */ +//list of config items. if the item is set in the +//existing config file, then don't test it to see +//if it needs to be written again later on memset(set, 0, item_count); if(blank == false) { @@ -237,9 +250,9 @@ bool blank = false; strset(line[i], strqpos(line[i], "#"), 0); } - /* this line is empty, restore the old line and continue */ + //this line is empty, restore the old line and continue if(strlen(line[i]) == 0) { - line[i] = oldline[i]; + strcpy(line[i], oldline[i]); continue; } @@ -247,44 +260,44 @@ bool blank = false; l = find(*part[0]); if(l == null) { - /* invalid item name, restore the old line and continue */ - line[i] = oldline[i]; + //invalid item name, restore the old line and continue + strcpy(line[i], oldline[i]); continue; } set[l] = 1; set_newline(l); - /* copy the user comment from the old config file, if it exists */ + //copy the user comment from the old config file, if it exists if(strqpos(oldline[i], "#") != null) { - newline += " "; - newline += *oldline[i] + strqpos(oldline[i], "#"); + strcat(newline, " "); + strcat(newline, *oldline[i] + strqpos(oldline[i], "#")); } - line[i] = newline; + strcpy(line[i], newline); } - /* write out the old config file + changes first */ + //write out the old config file + changes first 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 */ + //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); lines_written++; diff --git a/src/lib/libconfig.h b/src/lib/libconfig.h index dfe4674b..57373799 100644 --- a/src/lib/libconfig.h +++ b/src/lib/libconfig.h @@ -1,5 +1,5 @@ /* - libconfig : version 0.01 ~byuu + libconfig : version 0.02 ~byuu */ #ifndef __LIBCONFIG diff --git a/src/lib/libstring.cpp b/src/lib/libstring.cpp index effc189c..97e66b71 100644 --- a/src/lib/libstring.cpp +++ b/src/lib/libstring.cpp @@ -247,10 +247,10 @@ int ssl = strlen(str), ksl = strlen(key); /* does not work on type char* because function increases string length */ void strquote(_string &str) { static string t; - t = "\""; - t += str; - t += "\""; - str = t; + strcpy(t, "\""); + strcat(t, str); + strcat(t, "\""); + strcpy(str, t); } bool strunquote(char *str) { diff --git a/src/lib/libstring.h b/src/lib/libstring.h index fd924a94..b41ff4dd 100644 --- a/src/lib/libstring.h +++ b/src/lib/libstring.h @@ -1,5 +1,5 @@ /* - libstring : version 0.04 ~byuu + libstring : version 0.05 ~byuu */ #ifndef __LIBSTRING @@ -49,34 +49,29 @@ class _string { public: char *s; uint32 size; - -/* * */ inline char* operator*() { return s; } -/* = */ +#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 s; } @@ -91,33 +86,29 @@ 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 -/* * */ 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); } @@ -128,9 +119,7 @@ uint32 count, listcount; ~string(); }; -// -// = -// +#ifdef __LIBSTRING_OVERLOADS inline _string& _string::operator=(char *cpy) { strcpy(*this, cpy); return *this; @@ -157,9 +146,6 @@ inline string& string::operator=(string &cpy) { return *this; } -// -// += -// inline _string& _string::operator+=(char *cat) { strcat(*this, cat); return *this; @@ -186,9 +172,6 @@ inline string& string::operator+=(string &cat) { return *this; } -// -// -= -// inline _string& _string::operator-=(char *cut) { strrtrim(*this, cut); return *this; @@ -215,9 +198,6 @@ inline string& string::operator-=(string &cut) { return *this; } -// -// == -// inline bool _string::operator==(char *cmp) { if(!strcmp(*this, cmp))return true; return false; @@ -244,9 +224,6 @@ inline bool string::operator==(string &cmp) { return false; } -// -// != -// inline bool _string::operator!=(char *cmp) { if(!strcmp(*this, cmp))return false; return true; @@ -272,5 +249,6 @@ inline bool string::operator!=(string &cmp) { if(!strcmp(str(0), cmp.str(0)))return false; return true; } +#endif //__LIBSTRING_OVERLOADS -#endif +#endif //__LIBSTRING diff --git a/src/lib/libstring_sprintf.cpp b/src/lib/libstring_sprintf.cpp index ab86833d..d1c0ab40 100644 --- a/src/lib/libstring_sprintf.cpp +++ b/src/lib/libstring_sprintf.cpp @@ -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= size)resize(index + 1); - if(index > sizelimit)return __null; + if(index > sizelimit)return array[size - 1]; return array[index]; } }; diff --git a/src/memory/bmemory/bcart_exhirom.cpp b/src/memory/bmemory/bcart_exhirom.cpp new file mode 100644 index 00000000..86a85943 --- /dev/null +++ b/src/memory/bmemory/bcart_exhirom.cpp @@ -0,0 +1,108 @@ +void bCartExHiROM::write_protect(bool r) { write_protected = r; } + +uint8 bCartExHiROM::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 &= 0x3fffff; + addr += 0x400000; + } else if(b <= 0x7f) { + addr &= 0x3fffff; + addr += 0x400000; + } else if(b <= 0xbf) { + addr &= 0x3fffff; + } else { + addr &= 0x3fffff; + } + + if(addr < rom_size)return rom[addr]; + return 0x00; +} + +void bCartExHiROM::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 &= 0x3fffff; + addr += 0x400000; + } else if(b <= 0x7f) { + addr &= 0x3fffff; + addr += 0x400000; + } else if(b <= 0xbf) { + addr &= 0x3fffff; + } else { + addr &= 0x3fffff; + } + + if(addr < rom_size)rom[addr] = value; +} + +void bCartExHiROM::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_exhirom.h b/src/memory/bmemory/bcart_exhirom.h new file mode 100644 index 00000000..63b48660 --- /dev/null +++ b/src/memory/bmemory/bcart_exhirom.h @@ -0,0 +1,14 @@ +class bCartExHiROM : 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); + + bCartExHiROM() : write_protected(true) {} +}; diff --git a/src/memory/bmemory/bcart_hirom.cpp b/src/memory/bmemory/bcart_hirom.cpp new file mode 100644 index 00000000..3bbc9e53 --- /dev/null +++ b/src/memory/bmemory/bcart_hirom.cpp @@ -0,0 +1,86 @@ +void bCartHiROM::write_protect(bool r) { write_protected = r; } + +uint8 bCartHiROM::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 + } + } + + addr &= 0x3fffff; + if(addr < rom_size)return rom[addr]; + + return 0x00; +} + +void bCartHiROM::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; + addr &= 0x3fffff; + if(addr < rom_size)rom[addr] = value; +} + +void bCartHiROM::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_hirom.h b/src/memory/bmemory/bcart_hirom.h new file mode 100644 index 00000000..cccce628 --- /dev/null +++ b/src/memory/bmemory/bcart_hirom.h @@ -0,0 +1,14 @@ +class bCartHiROM : 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); + + bCartHiROM() : write_protected(true) {} +}; diff --git a/src/memory/bmemory/bcart_lorom.cpp b/src/memory/bmemory/bcart_lorom.cpp new file mode 100644 index 00000000..85ea74d7 --- /dev/null +++ b/src/memory/bmemory/bcart_lorom.cpp @@ -0,0 +1,104 @@ +void bCartLoROM::write_protect(bool r) { write_protected = r; } + +uint8 bCartLoROM::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(w & 0x8000) { + b &= 0x7f; + b %= 0x60; + addr = (b << 15) | (addr & 0x7fff); + } else { + b &= 0x7f; + b %= 0x60; + if(b == 0x00)b = 0x60; + addr = (((b << 15) | (addr & 0x7fff)) - 0x8000); + } + if(addr < rom_size)return rom[addr]; + + return 0x00; +} + +void bCartLoROM::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(w & 0x8000) { + b &= 0x7f; + b %= 0x60; + addr = (b << 15) | (addr & 0x7fff); + } else { + b &= 0x7f; + b %= 0x60; + if(b == 0x00)b = 0x60; + addr = (((b << 15) | (addr & 0x7fff)) - 0x8000); + } + if(addr < rom_size)rom[addr] = value; +} + +void bCartLoROM::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_lorom.h b/src/memory/bmemory/bcart_lorom.h new file mode 100644 index 00000000..cf279308 --- /dev/null +++ b/src/memory/bmemory/bcart_lorom.h @@ -0,0 +1,14 @@ +class bCartLoROM : 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); + + bCartLoROM() : write_protected(true) {} +}; diff --git a/src/memory/bmemory/bmemory.cpp b/src/memory/bmemory/bmemory.cpp index 9d4b1827..66cde60b 100644 --- a/src/memory/bmemory/bmemory.cpp +++ b/src/memory/bmemory/bmemory.cpp @@ -1,147 +1,32 @@ #include "../../base.h" +#include "bcart_lorom.cpp" +#include "bcart_hirom.cpp" +#include "bcart_exhirom.cpp" -uint8 bROM::read(uint32 addr) { -uint32 b, w; - addr &= 0xffffff; - b = (addr >> 16); - w = (addr & 0xffff); +bool bMemBus::load_cart(Reader *rf) { +uint32 cksum, icksum, index; +char cart_title[24]; +uint8 mapper; + if(rom_loaded == true)return false; -/* 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_data[addr]; - } else { - return 0x00; //no SRAM available - } - } else { - return 0x00; //unmapped - } - } + rf->read(&rom); -/* SRAM Region B */ - if(b >= 0x70 && b <= 0x7d) { - if(sram_size) { - addr = (addr & 0xffffff) - 0x700000; - addr &= (sram_size - 1); - return sram_data[addr]; - } else { - return 0x00; //no SRAM available - } - } + rom_size = rf->size(); - switch(mapper) { - case LOROM: - if(w & 0x8000) { - b &= 0x7f; - b %= 0x60; - addr = (b << 15) | (addr & 0x7fff); - } else { - b &= 0x7f; - b %= 0x60; - if(b == 0x00)b = 0x60; - addr = (((b << 15) | (addr & 0x7fff)) - 0x8000); - } - if(addr < size)return data[addr]; - break; - case HIROM: - addr &= 0x3fffff; - if(addr < size)return data[addr]; - break; - } - return 0x00; -} + if(rom_size < 32768)return false; -void bROM::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_data[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_data[addr] = value; - } else { - return; //no SRAM available - } - } - -/* Block write attempts to ROM by default, debugger can override this */ - if(write_protection == true)return; - - switch(mapper) { - case LOROM: - if(w & 0x8000) { - b &= 0x7f; - b %= 0x60; - addr = (b << 15) | (addr & 0x7fff); - } else { - b &= 0x7f; - b %= 0x60; - if(b == 0x00)b = 0x60; - addr = (((b << 15) | (addr & 0x7fff)) - 0x8000); - } - if(addr < size)data[addr] = value; - break; - case HIROM: - addr &= 0x3fffff; - if(addr < size)data[addr] = value; - break; - } -} - -void bROM::load_sram(Reader *rf) { - if(rom_loaded == false)return; - - rf->read(&sram_data, sram_size); -} - -void bROM::save_sram(Writer *wf) { - if(rom_loaded == false)return; - if(!sram_size)return; - - wf->write(sram_data, sram_size); -} - -void bROM::load_rom(Reader *rf) { -uint16 cksum, icksum, index; -char cart_title[24]; - if(rom_loaded == true)return; - - rf->read(&data); - - size = rf->size(); - if(size < 65536) { - mapper = LOROM; - strcpy(cart_title, ""); + if(rom_size >= 0x410000) { + mapper = EXHIROM; goto end; } - cksum = data[0xffdc] | (data[0xffdd] << 8); - icksum = data[0xffde] | (data[0xffdf] << 8); + if(rom_size < 65536) { + mapper = LOROM; + goto end; + } + + cksum = rom[0xffdc] | (rom[0xffdd] << 8); + icksum = rom[0xffde] | (rom[0xffdf] << 8); if(cksum + icksum == 0xffff) { mapper = HIROM; } else { @@ -149,13 +34,15 @@ char cart_title[24]; } end: - if(size >= 32768) { - memcpy(cart_title, (char*)data + ((mapper == LOROM)?0x7fc0:0xffc0), 21); - } else *cart_title = 0; + switch(mapper) { + case LOROM: index = 0x007fc0;break; + case HIROM: index = 0x00ffc0;break; + case EXHIROM:index = 0x40ffc0;break; + } + memcpy(cart_title, (char*)rom + index, 21); cart_title[21] = 0; - index = (mapper == HIROM)?0x8000:0x0000; - switch(data[index + 0x7fd8] & 7) { + switch(rom[index + 0x18] & 7) { case 0:sram_size = 0; break; case 1:sram_size = 2 * 1024;break; case 2:sram_size = 4 * 1024;break; @@ -166,45 +53,73 @@ end: case 7:sram_size = 128 * 1024;break; } - dprintf("Image Name : \"%s\"", cart_title); - dprintf("Image Type : %s", (mapper == LOROM)?"LoROM":"HiROM"); - 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", - data[index + 0x7ffc] | (data[index + 0x7ffd] << 8), //Reset - data[index + 0x7fea] | (data[index + 0x7feb] << 8), //NMI - data[index + 0x7fee] | (data[index + 0x7fef] << 8), //IRQ - data[index + 0x7fe6] | (data[index + 0x7fe7] << 8), //BRK[n] - data[index + 0x7fe4] | (data[index + 0x7fe5] << 8), //COP[n] - data[index + 0x7ffe] | (data[index + 0x7fff] << 8), //BRK[e] - data[index + 0x7ff4] | (data[index + 0x7ff5] << 8) //COP[e] + dprintf("* Image Name : \"%s\"", cart_title); + 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", + rom[index + 0x3c] | (rom[index + 0x3d] << 8), //Reset + rom[index + 0x2a] | (rom[index + 0x2b] << 8), //NMI + rom[index + 0x2e] | (rom[index + 0x2f] << 8), //IRQ + rom[index + 0x26] | (rom[index + 0x27] << 8), //BRK[n] + rom[index + 0x24] | (rom[index + 0x25] << 8), //COP[n] + rom[index + 0x3e] | (rom[index + 0x3f] << 8), //BRK[e] + rom[index + 0x34] | (rom[index + 0x35] << 8) //COP[e] ); dprintf(""); +CartInfo ci; + ci.rom = rom; + ci.sram = sram; + ci.rom_size = rom_size; + ci.sram_size = sram_size; + + switch(mapper) { + case LOROM: cart = new bCartLoROM(); break; + case HIROM: cart = new bCartHiROM(); break; + case EXHIROM:cart = new bCartExHiROM();break; + default:return false; + } + + cart->set_cartinfo(&ci); rom_loaded = true; + return true; } -void bROM::unload() { +bool bMemBus::load_sram(Reader *rf) { + if(rom_loaded == false || sram_size == 0)return false; + rf->read(&sram, sram_size); + +CartInfo ci; + ci.rom = rom; + ci.sram = sram; + ci.rom_size = rom_size; + ci.sram_size = sram_size; + cart->set_cartinfo(&ci); + + return true; +} + +bool bMemBus::save_sram(Writer *wf) { + if(rom_loaded == false || sram_size == 0)return false; + wf->write(sram, sram_size); + return true; +} + +void bMemBus::unload_cart() { if(rom_loaded == false)return; - if(data)memfree(data, "bROM::data"); - if(sram_data)memfree(sram_data, "bROM::sram_data"); + if(rom) free(rom); + if(sram)free(sram); + delete(cart); rom_loaded = false; } -void bROM::write_protect(bool yn) { - write_protection = yn; -} - -bROM::bROM() { - sram_size = 0; - sram_data = 0; - write_protection = true; - - rom_loaded = false; -} - -bROM::~bROM() { +void bMemBus::get_cartinfo(CartInfo *ci) { + ci->rom = rom; + ci->sram = sram; + ci->rom_size = rom_size; + ci->sram_size = sram_size; } /*********************** @@ -235,10 +150,10 @@ uint32 b, w, r; } else if(w <= 0x5fff) { r = mmio[w - 0x2000]->read(w); } else { - r = rom->read(addr); + r = cart->read(addr); } } else if(b <= 0x7d) { - r = rom->read(addr); + r = cart->read(addr); } else if(b <= 0x7f) { r = wram[addr & 0x01ffff]; } else if(b <= 0xbf) { @@ -247,10 +162,10 @@ uint32 b, w, r; } else if(w <= 0x5fff) { r = mmio[w - 0x2000]->read(w); } else { - r = rom->read(addr); + r = cart->read(addr); } } else { - r = rom->read(addr); + r = cart->read(addr); } snes->notify(SNES::MEM_READ, addr, r); @@ -269,10 +184,10 @@ uint32 b, w; } else if(w <= 0x5fff) { mmio[w - 0x2000]->write(w, value); } else { - rom->write(addr, value); + cart->write(addr, value); } } else if(b <= 0x7d) { - rom->write(addr, value); + cart->write(addr, value); } else if(b <= 0x7f) { wram[addr & 0x01ffff] = value; } else if(b <= 0xbf) { @@ -281,10 +196,10 @@ uint32 b, w; } else if(w <= 0x5fff) { mmio[w - 0x2000]->write(w, value); } else { - rom->write(addr, value); + cart->write(addr, value); } } else { - rom->write(addr, value); + cart->write(addr, value); } snes->notify(SNES::MEM_WRITE, addr, value); @@ -300,14 +215,11 @@ void bMemBus::reset() { } bMemBus::bMemBus() { - rom = new bROM(); - - wram = (byte*)memalloc(0x020000, "bMemBus::wram"); + wram = (byte*)malloc(0x020000); memset(wram, 0, 0x020000); + rom_loaded = false; } bMemBus::~bMemBus() { - delete(rom); - - if(wram)memfree(wram, "bMemBus::wram"); + if(wram)free(wram); } diff --git a/src/memory/bmemory/bmemory.h b/src/memory/bmemory/bmemory.h index fc89a116..ae9831f9 100644 --- a/src/memory/bmemory/bmemory.h +++ b/src/memory/bmemory/bmemory.h @@ -1,31 +1,24 @@ -class bROM : public ROM { -private: -bool write_protection; -bool rom_loaded; - -public: -enum { LOROM = 0, HIROM = 1 }; -uint8 *data, *sram_data; -uint8 mapper; -uint32 size, sram_size; - void load_rom(Reader *rf); - void load_sram(Reader *rf); - void save_sram(Writer *wf); - void unload(); - uint8 read (uint32 addr); - void write(uint32 addr, byte value); - void write_protect(bool yn); - - bROM(); - ~bROM(); -}; +#include "bcart_lorom.h" +#include "bcart_hirom.h" +#include "bcart_exhirom.h" class bMemBus : public MemBus { public: -byte *wram; +uint8 *rom, *sram, *wram; +uint32 rom_size, sram_size; + +bool rom_loaded; +enum { LOROM = 0x20, HIROM = 0x21, EXHIROM = 0x25 }; + uint8 read (uint32 addr); void write(uint32 addr, byte value); + bool load_cart(Reader *rf); + bool load_sram(Reader *rf); + bool save_sram(Writer *wf); + void unload_cart(); + void get_cartinfo(CartInfo *ci); + void power(); void reset(); diff --git a/src/memory/memory.h b/src/memory/memory.h index 48bed7d6..9c7a10b5 100644 --- a/src/memory/memory.h +++ b/src/memory/memory.h @@ -9,13 +9,15 @@ enum { WRAP_NONE = 0, WRAP_BANK = 1, WRAP_PAGE = 2 }; virtual void write_long(uint32 addr, uint32 value, uint8 wrap = WRAP_NONE); }; -class ROM : public Memory { +typedef struct { +uint8 *rom, *sram; +uint32 rom_size, sram_size; +}CartInfo; + +class Cart : public Memory { public: - virtual void load_rom(Reader *rf) = 0; - virtual void load_sram(Reader *rf) = 0; - virtual void save_sram(Writer *wf) = 0; - virtual void unload() = 0; - virtual void write_protect(bool yn) = 0; + virtual void write_protect(bool r) = 0; + virtual void set_cartinfo(CartInfo *ci) = 0; }; class MMIO : public Memory { @@ -26,13 +28,19 @@ public: class MemBus : public Memory { public: -ROM *rom; +Cart *cart; MMIO *mmio[0x4000]; bool fastROM; virtual void flush_mmio_mappers(); virtual bool set_mmio_mapper(uint16 addr, MMIO *mapper); virtual uint8 speed(uint32 addr); + virtual bool load_cart(Reader *rf) = 0; + virtual bool load_sram(Reader *rf) = 0; + virtual bool save_sram(Writer *wf) = 0; + virtual void unload_cart() = 0; + virtual void get_cartinfo(CartInfo *ci) = 0; + virtual void power() = 0; virtual void reset() = 0; diff --git a/src/ppu/bppu/bppu.cpp b/src/ppu/bppu/bppu.cpp index 1e61bbf9..44868895 100644 --- a/src/ppu/bppu/bppu.cpp +++ b/src/ppu/bppu/bppu.cpp @@ -1,21 +1,39 @@ #include "../../base.h" #include "bppu_mmio.cpp" - -#ifdef _BPPU_OLDRENDER -#include "bppu_old_render.cpp" -#else #include "bppu_render.cpp" -#endif void bPPU::run() {} void bPPU::scanline() { - _y = clock->vcounter(); + _y = cpu->vcounter(); _screen_width = (regs.bg_mode == 5 || regs.bg_mode == 6)?512:256; - _interlace = clock->interlace(); - _interlace_field = clock->interlace_field(); + _interlace = cpu->interlace(); + _interlace_field = cpu->interlace_field(); - if(_y > 0 && _y < clock->visible_scanlines()) { + if(_y == 0) { + //RTO flag reset + regs.time_over = false; + regs.range_over = false; + } + + if(_y == 1) { + //OAM FirstSprite priority set + if(regs.oam_priority == true) { + regs.oam_firstsprite = (regs.oam_addr & 0xfe) >> 1; + } else { + regs.oam_firstsprite = 0; + } + } + + if(_y == (cpu->overscan()?239:224) && regs.display_disabled == false) { + //OAM address reset + regs.oam_addr = ((regs.oam_addrh << 8) | regs.oam_addrl) << 1; + } + +//only allow frameskip setting to ignore actual rendering; not RTO, etc. + if(settings.frameskip_pos != 0)return; + + if(_y > 0 && _y < (cpu->overscan()?239:224)) { if(regs.bg_mode == 5 || regs.bg_mode == 6) { output->hires = true; output->line[_y].hires = true; @@ -29,6 +47,16 @@ void bPPU::scanline() { } void bPPU::frame() { + if(settings.frameskip_changed == true) { + settings.frameskip_changed = false; + settings.frameskip_pos = 0; + } else { + settings.frameskip_pos++; + settings.frameskip_pos %= (settings.frameskip + 1); + } + + if(settings.frameskip_pos != 0)return; + snes->notify(SNES::RENDER_FRAME); output->hires = false; output->interlace = false; @@ -38,6 +66,11 @@ void bPPU::frame() { } } +void bPPU::set_frameskip(int fs) { + settings.frameskip = fs; + settings.frameskip_changed = true; +} + void bPPU::power() { memset(vram, 0, 65536); memset(oam, 0, 544); @@ -49,6 +82,8 @@ void bPPU::reset() { memset(output->buffer, 0, 512 * 478 * 2); frame(); + memset(sprite_list, 0, sizeof(sprite_list)); + //$2100 regs.display_disabled = 0; regs.display_brightness = 0; @@ -59,10 +94,12 @@ void bPPU::reset() { regs.oam_tdaddr = 0x0000; //$2102-$2103 - regs.oam_addrl = 0x00; - regs.oam_addrh = 0x00; - regs.oam_addr = 0x0000; - regs.oam_latchdata = 0x00; + regs.oam_addrl = 0x00; + regs.oam_addrh = 0x00; + regs.oam_addr = 0x0000; + regs.oam_latchdata = 0x00; + regs.oam_priority = false; + regs.oam_firstsprite = 0x00; //$2105 regs.bg_tilesize[BG1] = 0; @@ -226,6 +263,11 @@ void bPPU::reset() { //$2139-$213a regs.vram_readbuffer = 0x0000; +//$213e + regs.time_over = false; + regs.range_over = false; + + update_sprite_list_sizes(); clear_tiledata_cache(); } @@ -252,6 +294,7 @@ uint8 r; void bPPU::oam_write(uint16 addr, uint8 value) { if(addr >= 0x0200)addr = 0x0200 | (addr & 31); oam[addr] = value; + update_sprite_list(addr); snes->notify(SNES::OAM_WRITE, addr, value); } @@ -268,6 +311,10 @@ void bPPU::cgram_write(uint16 addr, uint8 value) { } bPPU::bPPU() { + settings.frameskip = 0; + settings.frameskip_pos = 0; + settings.frameskip_changed = false; + mmio = new bPPUMMIO(this); vram = (uint8*)memalloc(65536, "bPPU::vram"); @@ -301,9 +348,9 @@ uint16 *ptr; if(l == 0) { r = g = b = 0; } else if(l == 15); else { - r = (double)r * m; - g = (double)g * m; - b = (double)b * m; + r = (uint8)((double)r * m); + g = (uint8)((double)g * m); + b = (uint8)((double)b * m); } *ptr++ = (r) | (g << 5) | (b << 10); } diff --git a/src/ppu/bppu/bppu.h b/src/ppu/bppu/bppu.h index f89d7493..6a30848b 100644 --- a/src/ppu/bppu/bppu.h +++ b/src/ppu/bppu/bppu.h @@ -1,5 +1,3 @@ -//#define _BPPU_OLDRENDER - class bPPU; class bPPUMMIO : public MMIO { @@ -17,6 +15,21 @@ uint8 *vram, *oam, *cgram; 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 }; +struct sprite_item { + uint8 width, height; + uint16 x, y; + uint8 character; + bool use_nameselect; + bool vflip, hflip; + uint8 palette; + uint8 priority; +}sprite_list[128]; + +struct { + int32 frameskip, frameskip_pos; + bool frameskip_changed; +}settings; + struct { //$2100 bool display_disabled; @@ -31,6 +44,8 @@ struct { uint8 oam_addrl, oam_addrh; uint16 oam_addr; uint8 oam_latchdata; + bool oam_priority; + uint8 oam_firstsprite; //$2105 bool bg_tilesize[4]; @@ -118,6 +133,10 @@ struct { //$2139-$213a uint16 vram_readbuffer; + +//$213e + bool time_over, range_over; + uint16 oam_itemcount, oam_tilecount; }regs; uint8 vram_read (uint16 addr); void vram_write (uint16 addr, uint8 value); @@ -126,6 +145,9 @@ struct { uint8 cgram_read (uint16 addr); void cgram_write(uint16 addr, uint8 value); + void get_sprite_size(int i, bool size); + void update_sprite_list(uint16 addr); + void update_sprite_list_sizes(); uint16 get_vram_address(); void mmio_w2100(uint8 value); //INIDISP @@ -197,22 +219,20 @@ struct { /* PPU render functions */ -#ifdef _BPPU_OLDRENDER -#include "bppu_old_render.h" -#else #include "bppu_render.h" -#endif uint16 *light_table; uint16 *mosaic_table[16]; void render_line(); + void update_oam_status(); /* Required functions */ void run(); void scanline(); void frame(); void power(); void reset(); + void set_frameskip(int fs); bPPU(); ~bPPU(); diff --git a/src/ppu/bppu/bppu_mmio.cpp b/src/ppu/bppu/bppu_mmio.cpp index 6b58b0ce..2f81b8ea 100644 --- a/src/ppu/bppu/bppu_mmio.cpp +++ b/src/ppu/bppu/bppu_mmio.cpp @@ -1,6 +1,6 @@ void bPPU::latch_counters() { - regs.hcounter = clock->hcounter(); - regs.vcounter = clock->vcounter(); + regs.hcounter = cpu->hcounter(); + regs.vcounter = cpu->vcounter(); regs.counters_latched = true; } @@ -27,6 +27,7 @@ void bPPU::mmio_w2101(uint8 value) { regs.oam_basesize = (value >> 5) & 7; regs.oam_nameselect = (value >> 3) & 3; regs.oam_tdaddr = (value & 3) << 14; + update_sprite_list_sizes(); } //OAMADDL @@ -37,8 +38,9 @@ void bPPU::mmio_w2102(uint8 value) { //OAMADDH void bPPU::mmio_w2103(uint8 value) { - regs.oam_addrh = value & 1; - regs.oam_addr = ((regs.oam_addrh << 8) | regs.oam_addrl) << 1; + regs.oam_priority = !!(value & 0x80); + regs.oam_addrh = value & 1; + regs.oam_addr = ((regs.oam_addrh << 8) | regs.oam_addrl) << 1; } //OAMDATA @@ -168,11 +170,17 @@ void bPPU::mmio_w2115(uint8 value) { //VMADDL void bPPU::mmio_w2116(uint8 value) { regs.vram_addr = (regs.vram_addr & 0xff00) | value; +uint16 addr = get_vram_address(); + regs.vram_readbuffer = vram_read(addr); + regs.vram_readbuffer |= vram_read(addr + 1) << 8; } //VMADDH void bPPU::mmio_w2117(uint8 value) { regs.vram_addr = (value << 8) | (regs.vram_addr & 0x00ff); +uint16 addr = get_vram_address(); + regs.vram_readbuffer = vram_read(addr); + regs.vram_readbuffer |= vram_read(addr + 1) << 8; } //VMDATAL @@ -388,8 +396,8 @@ void bPPU::mmio_w2133(uint8 value) { regs.oam_halve = !!(value & 0x02); regs.interlace = !!(value & 0x01); - clock->enable_overscan(regs.overscan); - clock->enable_interlace(regs.interlace); + cpu->set_overscan(regs.overscan); + cpu->set_interlace(regs.interlace); } //MPYL @@ -487,6 +495,8 @@ uint16 r = regs.vcounter; //STAT77 uint8 bPPU::mmio_r213e() { uint8 r = 0x00; + r |= (regs.time_over) ?0x80:0x00; + r |= (regs.range_over)?0x40:0x00; r |= 0x01; //PPU1 version number return r; } @@ -497,7 +507,7 @@ uint8 r = 0x00; regs.latch_hcounter = 0; regs.latch_vcounter = 0; - r |= clock->interlace_field() << 7; + r |= cpu->interlace_field() << 7; if(!(cpu->pio_status() & 0x80)) { r |= 1 << 6; } else if(regs.counters_latched == true) { @@ -510,7 +520,7 @@ uint8 r = 0x00; } uint8 bPPUMMIO::read(uint32 addr) { - clock->sync(); +//cpu->sync(); switch(addr) { case 0x2134:return ppu->mmio_r2134(); //MPYL case 0x2135:return ppu->mmio_r2135(); //MPYM @@ -524,36 +534,12 @@ uint8 bPPUMMIO::read(uint32 addr) { case 0x213d:return ppu->mmio_r213d(); //OPVCT case 0x213e:return ppu->mmio_r213e(); //STAT77 case 0x213f:return ppu->mmio_r213f(); //STAT78 - - case 0x2140:case 0x2141:case 0x2142:case 0x2143: - static uint8 t = 0, counter = 0; - uint8 x, port = (addr & 3); - if(rand() & 1) { - x = rand() & 7; - if(x == 0) { - if(!(port & 1))t = cpu->regs.a; - else t = cpu->regs.a >> 8; - } - else if(x == 1) { - if(!(port & 1))t = cpu->regs.x; - else t = cpu->regs.x >> 8; - } - else if(x == 2) { - if(!(port & 1))t = cpu->regs.y; - else t = cpu->regs.y >> 8; - } - else if(x == 3)t = 0xaa; - else if(x == 4)t = 0xbb; - else if(x == 5)t = 0xcc; - else { t = counter++; } - } - return t; } return 0x00; } void bPPUMMIO::write(uint32 addr, uint8 value) { - clock->sync(); +//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_old_render.cpp b/src/ppu/bppu/bppu_old_render.cpp deleted file mode 100644 index 9bdc3cf6..00000000 --- a/src/ppu/bppu/bppu_old_render.cpp +++ /dev/null @@ -1,133 +0,0 @@ -#include "bppu_old_render_cache.cpp" -#include "bppu_old_render_windows.cpp" -#include "bppu_old_render_main.cpp" -#include "bppu_old_render_mode7.cpp" - -namespace bPPURenderTables { -enum { BG1 = 0, BG2 = 1, BG3 = 2, BG4 = 3, OAM = 4, BACK = 5 }; - uint8 lookup_mode0[12] = { - BG4, BG3, OAM, BG4, BG3, OAM, BG2, BG1, OAM, BG2, BG1, OAM - }; - uint8 lookup_mode1_pri0[10] = { - BG3, OAM, BG3, OAM, BG2, BG1, OAM, BG2, BG1, OAM - }; - uint8 lookup_mode1_pri1[10] = { - BG3, OAM, OAM, BG2, BG1, OAM, BG2, BG1, OAM, BG3 - }; - uint8 lookup_mode2[8] = { - OAM, OAM, BG2, BG1, OAM, BG2, BG1, OAM - }; - uint8 lookup_mode3[8] = { - OAM, OAM, BG2, BG1, OAM, BG2, BG1, OAM - }; - uint8 lookup_mode4[8] = { - OAM, OAM, BG2, BG1, OAM, BG2, BG1, OAM - }; - uint8 lookup_mode5[8] = { - OAM, OAM, BG2, BG1, OAM, BG2, BG1, OAM - }; - uint8 lookup_mode6[6] = { - OAM, OAM, BG1, OAM, BG1, OAM - }; - uint8 lookup_mode7[5] = { - OAM, BG1, OAM, OAM, OAM - }; - uint8 lookup_mode7_extbg[6] = { - BG2, OAM, OAM, BG2, OAM, OAM - }; -}; - -void bPPU::render_line_mode0() { - render_line_bg (7, 10, COLORDEPTH_4, BG1); - render_line_bg (6, 9, COLORDEPTH_4, BG2); - render_line_bg (1, 4, COLORDEPTH_4, BG3); - render_line_bg (0, 3, COLORDEPTH_4, BG4); - render_line_oam(2, 5, 8, 11); - set_layer_pixels(12, bPPURenderTables::lookup_mode0); -} - -void bPPU::render_line_mode1() { - switch(regs.bg3_priority) { - case 0: - render_line_bg (5, 8, COLORDEPTH_16, BG1); - render_line_bg (4, 7, COLORDEPTH_16, BG2); - render_line_bg (0, 2, COLORDEPTH_4, BG3); - render_line_oam(1, 3, 6, 9); - set_layer_pixels(10, bPPURenderTables::lookup_mode1_pri0); - break; - case 1: - render_line_bg (4, 7, COLORDEPTH_16, BG1); - render_line_bg (3, 6, COLORDEPTH_16, BG2); - render_line_bg (0, 9, COLORDEPTH_4, BG3); - render_line_oam(1, 2, 5, 8); - set_layer_pixels(10, bPPURenderTables::lookup_mode1_pri1); - break; - } -} - -void bPPU::render_line_mode2() { - render_line_bg (3, 6, COLORDEPTH_16, BG1); - render_line_bg (2, 5, COLORDEPTH_16, BG2); - render_line_oam(0, 1, 4, 7); - set_layer_pixels(8, bPPURenderTables::lookup_mode2); -} - -void bPPU::render_line_mode3() { - render_line_bg (3, 6, COLORDEPTH_256, BG1); - render_line_bg (2, 5, COLORDEPTH_16, BG2); - render_line_oam(0, 1, 4, 7); - set_layer_pixels(8, bPPURenderTables::lookup_mode3); -} - -void bPPU::render_line_mode4() { - render_line_bg (3, 6, COLORDEPTH_256, BG1); - render_line_bg (2, 5, COLORDEPTH_4, BG2); - render_line_oam(0, 1, 4, 7); - set_layer_pixels(8, bPPURenderTables::lookup_mode4); -} - -void bPPU::render_line_mode5() { - render_line_bg (3, 6, COLORDEPTH_16, BG1); - render_line_bg (2, 5, COLORDEPTH_4, BG2); - render_line_oam(0, 1, 4, 7); - set_layer_pixels(8, bPPURenderTables::lookup_mode5); -} - -void bPPU::render_line_mode6() { - render_line_bg (2, 4, COLORDEPTH_16, BG1); - render_line_oam(0, 1, 3, 5); - set_layer_pixels(8, bPPURenderTables::lookup_mode6); -} - -void bPPU::render_line_mode7() { - if(regs.mode7_extbg == false) { - render_line_m7 (1, 0, 0); //bg2 priorities are ignored - render_line_oam(0, 2, 3, 4); - set_layer_pixels(5, bPPURenderTables::lookup_mode7); - } else { - render_line_m7 (0, 0, 3); //bg1 priority is ignored - render_line_oam(1, 2, 4, 5); - set_layer_pixels(6, bPPURenderTables::lookup_mode7_extbg); - } -} - -void bPPU::render_line() { - if(regs.display_disabled == true) { - memset(output->buffer + (_y << 1) * 512, 0, 2048); - return; - } - - clear_layer_cache(); - clear_pixel_cache(); - switch(regs.bg_mode) { - case 0:render_line_mode0();break; - case 1:render_line_mode1();break; - case 2:render_line_mode2();break; - case 3:render_line_mode3();break; - case 4:render_line_mode4();break; - case 5:render_line_mode5();break; - case 6:render_line_mode6();break; - case 7:render_line_mode7();break; - } - render_line_to_output(); -} diff --git a/src/ppu/bppu/bppu_old_render.h b/src/ppu/bppu/bppu_old_render.h deleted file mode 100644 index 128b54ec..00000000 --- a/src/ppu/bppu/bppu_old_render.h +++ /dev/null @@ -1,70 +0,0 @@ -//bppu_render.cpp -void render_line_mode0(); -void render_line_mode1(); -void render_line_mode2(); -void render_line_mode3(); -void render_line_mode4(); -void render_line_mode5(); -void render_line_mode6(); -void render_line_mode7(); - -//bppu_render_cache.cpp -enum { BLENDTYPE_BACK = 0, BLENDTYPE_MAIN = 1, BLENDTYPE_SUB = 2, BLENDTYPE_COMBINE = 3 }; -enum { COLORDEPTH_4 = 0, COLORDEPTH_16 = 1, COLORDEPTH_256 = 2 }; -enum { TILE_2BIT = 0, TILE_4BIT = 1, TILE_8BIT = 2 }; - -struct { - uint8 color_main, color_sub; - uint8 src_main, src_sub; - uint8 blend_type; -}pixel_cache[512]; -uint8 layer_cache[512 * 12]; - -uint8 *bg_tiledata[3]; -uint8 *bg_tiledata_state[3]; - -void clear_pixel_cache(void); -void clear_layer_cache(void); -void init_tiledata_cache(void); -void clear_tiledata_cache(void); - -//bppu_render_windows.cpp -enum { WINDOWMASK_OR = 0, WINDOWMASK_AND = 1, WINDOWMASK_XOR = 2, WINDOWMASK_XNOR = 3 }; - -bool windows_not_obstructing(uint8 layer, uint8 bg, uint16 x); -bool color_windows_not_obstructing(uint16 x, uint8 color_mask_type); - -//bppu_render_main.cpp -enum { - SH_2 = 1, SH_4 = 2, SH_8 = 3, SH_16 = 4, - SH_32 = 5, SH_64 = 6, SH_128 = 7, SH_256 = 8, - SH_512 = 9, SH_1024 = 10, SH_2048 = 11, SH_4096 = 12 -}; -enum { COLORMODE_ADD = 0, COLORMODE_SUB = 1 }; -enum { PPU_MAIN = 0, PPU_SUB = 1 }; -enum { OAM_PRI_NONE = 4 }; -uint8 oam_line_pal[512], oam_line_pri[512]; - -struct { - byte num; - byte width, height; - word x, y; - word character; - byte v_flip, h_flip; - byte palette; - byte priority; -}current_sprite; - -void render_line_to_output(); -inline uint16 addsub_pixels(uint8 x, uint8 cdest_index, uint8 cdest_bg, uint8 csrc_index, uint8 csrc_bg); -inline uint16 addsub_pixel(uint8 x, uint8 cdest_index, uint8 cdest_bg); -void render_bg_tile(uint8 color_depth, uint8 bg, uint16 tile_num); -void set_pixel(uint8 bg, uint16 x, uint8 pal_index); -void set_layer_pixels(uint8 layer_count, uint8 *layer_bg_lookup); -void set_sprite_attributes(uint8 sprite_num); -void render_oam_sprite(void); -void render_line_oam(uint8 layer_pos_pri0, uint8 layer_pos_pri1, uint8 layer_pos_pri2, uint8 layer_pos_pri3); -void render_line_bg(uint8 layer_pos_pri0, uint8 layer_pos_pri1, uint8 color_depth, uint8 bg); - -//bppu_render_mode7.cpp -void render_line_m7(uint8 layer_pos_bg1, uint8 layer_pos_bg2_pri0, uint8 layer_pos_bg2_pri1); diff --git a/src/ppu/bppu/bppu_old_render_cache.cpp b/src/ppu/bppu/bppu_old_render_cache.cpp deleted file mode 100644 index 508aed97..00000000 --- a/src/ppu/bppu/bppu_old_render_cache.cpp +++ /dev/null @@ -1,33 +0,0 @@ -//this should be reset once every scanline -void bPPU::clear_pixel_cache(void) { - for(int i=0;i<512;i++) { - pixel_cache[i].color_main = 0; - pixel_cache[i].color_sub = 0; - pixel_cache[i].src_main = BACK; - pixel_cache[i].src_sub = BACK; - pixel_cache[i].blend_type = BLENDTYPE_BACK; - } -} - -//this should be reset once every scanline -void bPPU::clear_layer_cache(void) { - memset(&layer_cache, 0, 512 * 12); -} - -void bPPU::init_tiledata_cache(void) { - bg_tiledata[TILE_2BIT] = (uint8*)malloc(262144); - bg_tiledata[TILE_4BIT] = (uint8*)malloc(131072); - bg_tiledata[TILE_8BIT] = (uint8*)malloc( 65536); - bg_tiledata_state[TILE_2BIT] = (uint8*)malloc( 4096); - bg_tiledata_state[TILE_4BIT] = (uint8*)malloc( 2048); - bg_tiledata_state[TILE_8BIT] = (uint8*)malloc( 1024); -} - -void bPPU::clear_tiledata_cache(void) { - memset(bg_tiledata[TILE_2BIT], 0, 262144); - memset(bg_tiledata[TILE_4BIT], 0, 131072); - memset(bg_tiledata[TILE_4BIT], 0, 65536); - memset(bg_tiledata_state[TILE_2BIT], 0, 4096); - memset(bg_tiledata_state[TILE_4BIT], 0, 2048); - memset(bg_tiledata_state[TILE_8BIT], 0, 1024); -} diff --git a/src/ppu/bppu/bppu_old_render_main.cpp b/src/ppu/bppu/bppu_old_render_main.cpp deleted file mode 100644 index e7ae5c4a..00000000 --- a/src/ppu/bppu/bppu_old_render_main.cpp +++ /dev/null @@ -1,696 +0,0 @@ -#define set_layer_pixel(__x, __c) layer_cache[(__x) * 12 + layer_pos] = __c -#define pal_pixel(__i) (*((uint16*)cgram + __i)) - -namespace bPPUAddSubTables { - uint8 adjust_buffer_full[96] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31 - }; - uint8 adjust_buffer_half[96] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63 - }; -}; - -inline uint16 bPPU::addsub_pixels(uint8 x, uint8 cdest_index, uint8 cdest_bg, uint8 csrc_index, uint8 csrc_bg) { -int r, g, b; -uint16 cdest = pal_pixel(cdest_index); -uint16 csrc = pal_pixel(csrc_index); -uint16 res; -//oam palettes 0-3 are not affected by color add/sub - if(cdest_bg == OAM) { - if(cdest_index < 192) { - return cdest; - } - } - switch(regs.color_mode) { - case COLORMODE_ADD: - if(regs.bg_color_enabled[cdest_bg] == true && regs.color_halve == true) { - r = *(bPPUAddSubTables::adjust_buffer_half + 32 + ( ((cdest ) & 31) + ((csrc ) & 31) )) >> 1; - g = *(bPPUAddSubTables::adjust_buffer_half + 32 + ( ((cdest >> 5) & 31) + ((csrc >> 5) & 31) )) >> 1; - b = *(bPPUAddSubTables::adjust_buffer_half + 32 + ( ((cdest >> 10) & 31) + ((csrc >> 10) & 31) )) >> 1; - } else { - r = *(bPPUAddSubTables::adjust_buffer_full + 32 + ( ((cdest ) & 31) + ((csrc ) & 31) )); - g = *(bPPUAddSubTables::adjust_buffer_full + 32 + ( ((cdest >> 5) & 31) + ((csrc >> 5) & 31) )); - b = *(bPPUAddSubTables::adjust_buffer_full + 32 + ( ((cdest >> 10) & 31) + ((csrc >> 10) & 31) )); - } - break; - case COLORMODE_SUB: - if(regs.bg_color_enabled[cdest_bg] == true && regs.color_halve == true) { - r = *(bPPUAddSubTables::adjust_buffer_half + 32 + ( ((cdest ) & 31) + ((csrc ) & 31) )) >> 1; - g = *(bPPUAddSubTables::adjust_buffer_half + 32 + ( ((cdest >> 5) & 31) + ((csrc >> 5) & 31) )) >> 1; - b = *(bPPUAddSubTables::adjust_buffer_half + 32 + ( ((cdest >> 10) & 31) + ((csrc >> 10) & 31) )) >> 1; - } else { - r = *(bPPUAddSubTables::adjust_buffer_full + 32 + ( ((cdest ) & 31) - ((csrc ) & 31) )); - g = *(bPPUAddSubTables::adjust_buffer_full + 32 + ( ((cdest >> 5) & 31) - ((csrc >> 5) & 31) )); - b = *(bPPUAddSubTables::adjust_buffer_full + 32 + ( ((cdest >> 10) & 31) - ((csrc >> 10) & 31) )); - } - break; - } - return ((r) | (g << 5) | (b << 10)); -} - -inline uint16 bPPU::addsub_pixel(uint8 x, uint8 cdest_index, uint8 cdest_bg) { -int r, g, b; -uint16 cdest = pal_pixel(cdest_index); -uint16 csrc = (regs.color_r) | (regs.color_g << 5) | (regs.color_b << 10); -uint16 res; -//only oam palettes 4-7 are affected by color add/sub - if(cdest_bg == OAM) { - if(cdest_index < 192) { - return cdest; - } - } - switch(regs.color_mode) { - case COLORMODE_ADD: - if(regs.bg_color_enabled[cdest_bg] == true && regs.color_halve == true && regs.addsub_mode == 0) { - r = *(bPPUAddSubTables::adjust_buffer_half + 32 + ( ((cdest ) & 31) + ((csrc ) & 31) )) >> 1; - g = *(bPPUAddSubTables::adjust_buffer_half + 32 + ( ((cdest >> 5) & 31) + ((csrc >> 5) & 31) )) >> 1; - b = *(bPPUAddSubTables::adjust_buffer_half + 32 + ( ((cdest >> 10) & 31) + ((csrc >> 10) & 31) )) >> 1; - } else { - r = *(bPPUAddSubTables::adjust_buffer_full + 32 + ( ((cdest ) & 31) + ((csrc ) & 31) )); - g = *(bPPUAddSubTables::adjust_buffer_full + 32 + ( ((cdest >> 5) & 31) + ((csrc >> 5) & 31) )); - b = *(bPPUAddSubTables::adjust_buffer_full + 32 + ( ((cdest >> 10) & 31) + ((csrc >> 10) & 31) )); - } - break; - case COLORMODE_SUB: - if(regs.bg_color_enabled[cdest_bg] == true && regs.color_halve == true && regs.addsub_mode == 0) { - r = *(bPPUAddSubTables::adjust_buffer_half + 32 + ( ((cdest ) & 31) + ((csrc ) & 31) )) >> 1; - g = *(bPPUAddSubTables::adjust_buffer_half + 32 + ( ((cdest >> 5) & 31) + ((csrc >> 5) & 31) )) >> 1; - b = *(bPPUAddSubTables::adjust_buffer_half + 32 + ( ((cdest >> 10) & 31) + ((csrc >> 10) & 31) )) >> 1; - } else { - r = *(bPPUAddSubTables::adjust_buffer_full + 32 + ( ((cdest ) & 31) - ((csrc ) & 31) )); - g = *(bPPUAddSubTables::adjust_buffer_full + 32 + ( ((cdest >> 5) & 31) - ((csrc >> 5) & 31) )); - b = *(bPPUAddSubTables::adjust_buffer_full + 32 + ( ((cdest >> 10) & 31) - ((csrc >> 10) & 31) )); - } - break; - } - return ((r) | (g << 5) | (b << 10)); -} - -#define render_bg_tile_line_4(__m) \ - col = 0; \ - if(d0 & __m)col += 1; \ - if(d1 & __m)col += 2; \ - *dest++ = col -#define render_bg_tile_line_16(__m) \ - col = 0; \ - if(d0 & __m)col += 1; \ - if(d1 & __m)col += 2; \ - if(d2 & __m)col += 4; \ - if(d3 & __m)col += 8; \ - *dest++ = col -#define render_bg_tile_line_256(__m) \ - col = 0; \ - if(d0 & __m)col += 1; \ - if(d1 & __m)col += 2; \ - if(d2 & __m)col += 4; \ - if(d3 & __m)col += 8; \ - if(d4 & __m)col += 16; \ - if(d5 & __m)col += 32; \ - if(d6 & __m)col += 64; \ - if(d7 & __m)col += 128; \ - *dest++ = col - -void bPPU::render_bg_tile(uint8 color_depth, uint8 bg, uint16 tile_num) { -uint8 mask, d0, d1, d2, d3, d4, d5, d6, d7, col; -int x, y; -uint32 pos; -uint8 *dest; - switch(color_depth) { - case COLORDEPTH_4: - dest = (uint8*)bg_tiledata[TILE_2BIT] + tile_num * 64; - pos = tile_num * 16; - y = 8; - while(y--) { - d0 = vram[pos ]; - d1 = vram[pos + 1]; - render_bg_tile_line_4(0x80); - render_bg_tile_line_4(0x40); - render_bg_tile_line_4(0x20); - render_bg_tile_line_4(0x10); - render_bg_tile_line_4(0x08); - render_bg_tile_line_4(0x04); - render_bg_tile_line_4(0x02); - render_bg_tile_line_4(0x01); - pos += 2; - } - bg_tiledata_state[TILE_2BIT][tile_num] = 0; - break; - case COLORDEPTH_16: - dest = (uint8*)bg_tiledata[TILE_4BIT] + tile_num * 64; - pos = tile_num * 32; - y = 8; - while(y--) { - d0 = vram[pos ]; - d1 = vram[pos + 1]; - d2 = vram[pos + 16]; - d3 = vram[pos + 17]; - render_bg_tile_line_16(0x80); - render_bg_tile_line_16(0x40); - render_bg_tile_line_16(0x20); - render_bg_tile_line_16(0x10); - render_bg_tile_line_16(0x08); - render_bg_tile_line_16(0x04); - render_bg_tile_line_16(0x02); - render_bg_tile_line_16(0x01); - pos += 2; - } - bg_tiledata_state[TILE_4BIT][tile_num] = 0; - break; - case COLORDEPTH_256: - dest = (uint8*)bg_tiledata[TILE_8BIT] + tile_num * 64; - pos = tile_num * 64; - y = 8; - while(y--) { - d0 = vram[pos ]; - d1 = vram[pos + 1]; - d2 = vram[pos + 16]; - d3 = vram[pos + 17]; - d4 = vram[pos + 32]; - d5 = vram[pos + 33]; - d6 = vram[pos + 48]; - d7 = vram[pos + 49]; - render_bg_tile_line_256(0x80); - render_bg_tile_line_256(0x40); - render_bg_tile_line_256(0x20); - render_bg_tile_line_256(0x10); - render_bg_tile_line_256(0x08); - render_bg_tile_line_256(0x04); - render_bg_tile_line_256(0x02); - render_bg_tile_line_256(0x01); - pos += 2; - } - bg_tiledata_state[TILE_8BIT][tile_num] = 0; - break; - } -} - -void bPPU::render_line_to_output() { -int x, x1; -uint16 *ptr, *ltable; -uint16 c, cx, cy; -uint16 screen_width; -uint16 v, vline_pos = clock->vcounter(); - v = vline_pos; - screen_width = (output->line[v].hires)?512:256; - - if(output->line[v].interlace == false) { - ptr = (uint16*)output->buffer + ((vline_pos << 1)) * 512; - } else { - ptr = (uint16*)output->buffer + ((vline_pos << 1) + clock->interlace_field()) * 512; - } - ltable = (uint16*)light_table + (regs.display_brightness * 65536); - - for(x=x1=0;x= 192)) { - if(regs.bg_color_enabled[pixel_cache[x].src_main] == true) { - pixel_cache[x].blend_type = BLENDTYPE_COMBINE; - } - } - } - } -} - -void bPPU::set_layer_pixels(uint8 layer_count, uint8 *layer_bg_lookup) { -int layer, x = 0, x1; -uint8 pal; -uint16 width = (regs.bg_mode == 5 || regs.bg_mode == 6)?512:256; - do { - layer = 0; - x1 = x * 12; - do { - pal = layer_cache[x1 + layer]; - if(pal) { - set_pixel(layer_bg_lookup[layer], x, pal); - } - layer++; - } while(layer < layer_count); - x++; - } while(x < width); -} - -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(void) { -uint16 pos, col, chr, tiledata_inc; -uint8 d0, d1, d2, d3, pal_index; -int x, y, z, x1, mx, mask, p; -int tile_width; -int vline_pos = clock->vcounter(); -int snes_width = (regs.bg_mode == 5 || regs.bg_mode == 6)?512:256; - if(regs.bg_enabled[OAM] == false && regs.bgsub_enabled[OAM] == false)return; - - tile_width = current_sprite.width >> SH_8; //e.x. 16x16 sprite = 2x2 tiles - - if(clock->interlace() == true && (regs.bg_mode == 5 || regs.bg_mode == 6)) { - y = (vline_pos << SH_2) + clock->interlace_field(); - } else { - y = vline_pos; - } - - x = current_sprite.x; - if(snes_width == 512) { - x <<= SH_2; - } - - if(current_sprite.v_flip) { - y = ((current_sprite.height - 1) - (vline_pos - current_sprite.y)); - } else { - y = (vline_pos - current_sprite.y); - } - y &= 255; - if(regs.oam_halve == true) { - y <<= 1; - y += clock->interlace_field(); - } - - chr = current_sprite.character; - tiledata_inc = (chr & 0x100)?(regs.oam_nameselect << 13):0; - chr += (y >> SH_8) << SH_16; - pal_index = (current_sprite.palette << SH_16); - for(x1=0;x1> z; - } - x &= 511; - if(x < snes_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(snes_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++; - if(snes_width == 512) { - x++; - } - } - } -} - -void bPPU::render_line_oam(uint8 layer_pos_pri0, uint8 layer_pos_pri1, uint8 layer_pos_pri2, uint8 layer_pos_pri3) { -int i, s; -int vline_pos = clock->vcounter(); -int snes_width = (regs.bg_mode == 5 || regs.bg_mode == 6)?512:256; -uint8 layer_pos; - if(regs.bg_enabled[OAM] != true && regs.bgsub_enabled[OAM] != true)return; - - memset(oam_line_pri, OAM_PRI_NONE, 512); - for(s=0;s<128;s++) { - set_sprite_attributes(s); - if(regs.oam_halve == false) { - if(vline_pos >= current_sprite.y && vline_pos < (current_sprite.y + current_sprite.height)) { - render_oam_sprite(); - } else if((current_sprite.y + current_sprite.height) >= 256 && vline_pos < ((current_sprite.y + current_sprite.height) & 255)) { - render_oam_sprite(); - } - } else { - if(vline_pos >= current_sprite.y && vline_pos < (current_sprite.y + (current_sprite.height >> 1))) { - render_oam_sprite(); - } else if((current_sprite.y + current_sprite.height) >= 256 && vline_pos < ((current_sprite.y + (current_sprite.height >> 1)) & 255)) { - render_oam_sprite(); - } - } - } - - for(i=0;ivcounter(); -uint16 t, base_xpos, base_pos, pos, ppos = 0; -uint16 col; -uint8 *src, *bg_td, *bg_td_state, *tile_ptr; -uint8 tiledata_size; -uint8 tile_size, tile_width, tile_height, tile_x; -uint8 mask, pal_index, pal_size; -uint16 tile_num, screen_width, screen_height, screen_width_mask, screen_height_mask, map_index; -uint16 *mtable; -uint8 layer_pos; -uint16 opt_valid_bit, voffset, hoffset, vscroll, hscroll; - if(regs.bg_enabled[bg] == false && regs.bgsub_enabled[bg] == false)return; - - if (bg == BG1)opt_valid_bit = 0x2000; - else if(bg == BG2)opt_valid_bit = 0x4000; - else opt_valid_bit = 0x0000; - - switch(color_depth) { - case COLORDEPTH_4: - pal_size = 4; - tiledata_size = SH_16; - break; - case COLORDEPTH_16: - pal_size = 16; - tiledata_size = SH_32; - break; - case COLORDEPTH_256: - pal_size = 256; - tiledata_size = SH_64; - break; - } - bg_td = (byte*)bg_tiledata[color_depth]; - bg_td_state = (byte*)bg_tiledata_state[color_depth]; - - screen_width = snes_width; - screen_height = snes_width; //this is correct -- ppu tilemap is based around 256x256, etc. - tile_size = (regs.bg_tilesize[bg])?SH_16:SH_8; - tile_width = tile_size; - tile_height = tile_size; - - if(clock->interlace() == true && (regs.bg_mode == 5 || regs.bg_mode == 6)) { - screen_y = (vline_pos << SH_2) + clock->interlace_field(); - } else { - screen_y = vline_pos; - } - -//Modes 5 and 6 seem to force 16-width tiles due to having twice the resolution. -//The tile size attribute in $2105 has no effect on tile width. - if(regs.bg_mode == 5 || regs.bg_mode == 6) { - tile_width = SH_16; - } - - if(tile_size == SH_16) { - screen_width <<= SH_2; - screen_height <<= SH_2; - } - - if(regs.bg_scsize[bg] & 0x01)screen_width <<= SH_2; - if(regs.bg_scsize[bg] & 0x02)screen_height <<= SH_2; - - screen_width_mask = screen_width - 1; - screen_height_mask = screen_height - 1; - - if(snes_width == 512) { - hscroll = (regs.bg_hofs[bg] << SH_2) & screen_width_mask; - } else { - hscroll = regs.bg_hofs[bg] & screen_width_mask; - } - bg_x = hscroll; - - if(snes_width == 512 && clock->interlace() == true) { - vscroll = (regs.bg_vofs[bg] << SH_2) & screen_height_mask; - } else { - vscroll = regs.bg_vofs[bg] & screen_height_mask; - } - bg_y = (screen_y + vscroll) & screen_height_mask; - - if(regs.mosaic_enabled[bg] == true) { - mtable = (uint16*)mosaic_table[regs.mosaic_size]; - } else { - mtable = (uint16*)mosaic_table[0]; - } - mosaic_x = mtable[bg_x]; - mosaic_y = mtable[bg_y]; - - for(screen_x=0;screen_x> SH_16); - } else { - tile_x = (mtable[screen_x + (hscroll & 7)] >> SH_8); - } - hoffset = hscroll; - voffset = vscroll; - if(tile_x != 0) { - tile_x = (tile_x - 1) & 31; - if(regs.bg_mode == 4) { - pos = regs.bg_scaddr[BG3] + (tile_x << SH_2); - t = *((uint16*)vram + (pos >> SH_2)); - if(t & opt_valid_bit) { - if(!(t & 0x8000)) { - hoffset = ((t & 0x1ff8) | (hscroll & 7)) & screen_width_mask; - } else { - voffset = (t & 0x1fff) & screen_height_mask; - } - } - } else { - pos = regs.bg_scaddr[BG3] + (tile_x << SH_2); - t = *((uint16*)vram + (pos >> SH_2)); - if(t & opt_valid_bit) { - hoffset = ((t & 0x1ff8) | (hscroll & 7)) & screen_width_mask; - } - pos = regs.bg_scaddr[BG3] + 64 + (tile_x << SH_2); - t = *((uint16*)vram + (pos >> SH_2)); - if(t & opt_valid_bit) { - voffset = (t & 0x1fff) & screen_height_mask; - } - } - } - mosaic_x = mtable[(screen_x + hoffset) & screen_width_mask ]; - mosaic_y = mtable[(screen_y + voffset) & screen_height_mask]; - } - - switch(regs.bg_scsize[bg]) { - case 0: - map_index = 0; - break; - case 1: - map_index = ((mosaic_x >> tile_size) >> SH_32) << SH_2048; - break; - case 2: - map_index = ((mosaic_y >> tile_size) >> SH_32) << SH_2048; - break; - case 3: - map_index = ((mosaic_x >> tile_size) >> SH_32) << SH_2048 | - ((mosaic_y >> tile_size) >> SH_32) << SH_4096; - break; - } - - base_xpos = ((mosaic_x >> SH_8) & 31); - base_pos = (((mosaic_y >> tile_height) & 31) << SH_32) + ((mosaic_x >> tile_width) & 31); - pos = regs.bg_scaddr[bg] + map_index + (base_pos << SH_2); - t = *((uint16*)vram + (pos >> SH_2)); - mirror_y = (t & 0x8000)?1:0; - mirror_x = (t & 0x4000)?1:0; - - if((t & 0x2000) == 0) { - layer_pos = layer_pos_pri0; - } else { - layer_pos = layer_pos_pri1; - } - - tile_num = t & 0x03ff; - if(tile_width == SH_16) { - if(((mosaic_x & 15) >= 8 && !mirror_x) || - ((mosaic_x & 15) < 8 && mirror_x))tile_num++; - tile_num &= 0x03ff; - } - if(tile_height == SH_16) { - if(((mosaic_y & 15) >= 8 && !mirror_y) || - ((mosaic_y & 15) < 8 && mirror_y))tile_num += 16; - tile_num &= 0x03ff; - } - tile_num += (regs.bg_tdaddr[bg] >> tiledata_size); - - if(bg_td_state[tile_num] == 1) { - render_bg_tile(color_depth, bg, tile_num); - } - - pal_index = ((t >> 10) & 7) * pal_size; - - if(mirror_y) { ypos = (7 - (mosaic_y & 7)); } - else { ypos = ( (mosaic_y & 7)); } - -//loop while we are rendering from the same tile, as there's no need to do all of the above work -//unless we have rendered all of the visible tile, taking mosaic into account. - tile_ptr = (uint8*)bg_td + (tile_num << SH_64) + (ypos << SH_8); - while(1) { - if(mirror_x) { xpos = (7 - (mosaic_x & 7)); } - else { xpos = ( (mosaic_x & 7)); } - col = *(tile_ptr + xpos); - if(col) { - set_layer_pixel(screen_x, col + pal_index); - } - - bg_x++; - bg_x &= screen_width_mask; - mosaic_x = mtable[bg_x]; - - if(base_xpos != ((mosaic_x >> SH_8) & 31))break; - screen_x++; - if(screen_x >= snes_width)break; - } - } -} diff --git a/src/ppu/bppu/bppu_old_render_mode7.cpp b/src/ppu/bppu/bppu_old_render_mode7.cpp deleted file mode 100644 index 823eb555..00000000 --- a/src/ppu/bppu/bppu_old_render_mode7.cpp +++ /dev/null @@ -1,110 +0,0 @@ -#define CLIP_10BIT_SIGNED(x) \ - ((x) & ((1 << 10) - 1)) + (((((x) & (1 << 13)) ^ (1 << 13)) - (1 << 13)) >> 3) - -#define CAST_WORDTOINT(x) \ - (int)(((x & 0x8000)?(x | 0xffff0000):(x & 0x00007fff))) - -void bPPU::render_line_m7(uint8 layer_pos_bg1, uint8 layer_pos_bg2_pri0, uint8 layer_pos_bg2_pri1) { -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, priority; -uint8 layer_pos; - hoffset = (CAST_WORDTOINT(regs.bg_hofs[BG1]) << 7) >> 7; - voffset = (CAST_WORDTOINT(regs.bg_vofs[BG1]) << 7) >> 7; - - centerx = (CAST_WORDTOINT(regs.m7x) << 7) >> 7; - centery = (CAST_WORDTOINT(regs.m7y) << 7) >> 7; - - if(regs.mode7_vflip == true) { - yy = 223 - clock->vcounter(); - } else { - yy = clock->vcounter(); - } - yy += CLIP_10BIT_SIGNED(voffset - centery); - - m7b = CAST_WORDTOINT(regs.m7b) * yy + (centerx << 8); - m7d = CAST_WORDTOINT(regs.m7d) * yy + (centery << 8); - - step_m7a = CAST_WORDTOINT(regs.m7a); - step_m7c = CAST_WORDTOINT(regs.m7c); - - xx = CLIP_10BIT_SIGNED(hoffset - centerx); - - m7a = CAST_WORDTOINT(regs.m7a) * xx; - m7c = CAST_WORDTOINT(regs.m7c) * xx; - - for(x=0;x<256;x++) { - px = ((m7a + m7b) >> 8); - py = ((m7c + m7d) >> 8); - - switch(regs.mode7_repeat) { - case 0: //screen repitition outside of screen area - case 1: //same as case 0 - px &= 1023; - py &= 1023; - tx = ((px >> SH_8) & 127); - ty = ((py >> SH_8) & 127); - tile = vram[(ty * 128 + tx) << 1]; - palette = vram[(((tile << SH_64) + ((py & 7) << SH_8) + (px & 7)) << 1) + 1]; - break; - case 2: //character 0 repetition outside of screen area - if(px < 0 || px > 1023 || py < 0 || py > 1023) { - tx = 0; - ty = 0; - } else { - px &= 1023; - py &= 1023; - tx = ((px >> SH_8) & 127); - ty = ((py >> SH_8) & 127); - } - tile = vram[(ty * 128 + tx) << 1]; - palette = vram[(((tile << SH_64) + ((py & 7) << SH_8) + (px & 7)) << 1) + 1]; - break; - case 3: //palette color 0 outside of screen area - if(px < 0 || px > 1023 || py < 0 || py > 1023) { - palette = 0; - } else { - px &= 1023; - py &= 1023; - tx = ((px >> SH_8) & 127); - ty = ((py >> SH_8) & 127); - tile = vram[(ty * 128 + tx) << 1]; - palette = vram[(((tile << SH_64) + ((py & 7) << SH_8) + (px & 7)) << 1) + 1]; - } - break; - } - - if(regs.mode7_extbg == false) { - if(palette) { - layer_pos = layer_pos_bg1; - if(regs.mode7_hflip == true) { - set_layer_pixel(255 - x, palette); - } else { - set_layer_pixel(x, palette); - } - } - } else { - priority = (palette >> 7); - palette &= 0x7f; - if(palette) { - if(priority == 0) { - layer_pos = layer_pos_bg2_pri0; - } else { - layer_pos = layer_pos_bg2_pri1; - } - if(regs.mode7_hflip == true) { - set_layer_pixel(255 - x, palette); - } else { - set_layer_pixel(x, palette); - } - } - } - - m7a += step_m7a; - m7c += step_m7c; - } -} diff --git a/src/ppu/bppu/bppu_old_render_windows.cpp b/src/ppu/bppu/bppu_old_render_windows.cpp deleted file mode 100644 index cc0cc5e4..00000000 --- a/src/ppu/bppu/bppu_old_render_windows.cpp +++ /dev/null @@ -1,159 +0,0 @@ -bool bPPU::windows_not_obstructing(uint8 layer, uint8 bg, uint16 x) { -uint8 w1_mask, w2_mask; //1 = masked, 0 = not masked -uint16 window1_left, window1_right, window2_left, window2_right; - if(layer == PPU_MAIN) { - if(regs.bg_window_enabled[bg] == false)return true; - } else if(layer == PPU_SUB) { - if(regs.bgsub_window_enabled[bg] == false)return true; - } - - window1_left = regs.window1_left; - window1_right = regs.window1_right; - window2_left = regs.window2_left; - window2_right = regs.window2_right; - - if(regs.bg_mode == 5 || regs.bg_mode == 6) { - window1_left <<= 1; - window1_right <<= 1; - window2_left <<= 1; - window2_right <<= 1; - } - - if(regs.bg_window1_enabled[bg] == true && regs.bg_window2_enabled[bg] == false) { - if(regs.bg_window1_invert[bg] == false) { - if(x >= window1_left && x <= window1_right)return false; - return true; - } else { - if(x < window1_left || x > window1_right)return false; - return true; - } - } else if(regs.bg_window2_enabled[bg] == true && regs.bg_window1_enabled[bg] == false) { - if(regs.bg_window2_invert[bg] == false) { - if(x >= window2_left && x <= window2_right)return false; - return true; - } else { - if(x < window2_left || x > window2_right)return false; - return true; - } - } else if(regs.bg_window1_enabled[bg] == true && regs.bg_window2_enabled[bg] == true) { - if(regs.bg_window1_invert[bg] == false) { - if(x >= window1_left && x <= window1_right)w1_mask = 1; - else w1_mask = 0; - } else { - if(x < window1_left || x > window1_right)w1_mask = 1; - else w1_mask = 0; - } - - if(regs.bg_window2_invert[bg] == false) { - if(x >= window2_left && x <= window2_right)w2_mask = 1; - else w2_mask = 0; - } else { - if(x < window2_left || x > window2_right)w2_mask = 1; - else w2_mask = 0; - } - - switch(regs.bg_window_mask[bg]) { - case WINDOWMASK_OR: - if((w1_mask | w2_mask) == 1)return false; - return true; - case WINDOWMASK_AND: - if((w1_mask & w2_mask) == 1)return false; - return true; - case WINDOWMASK_XOR: - if((w1_mask ^ w2_mask) == 1)return false; - return true; - case WINDOWMASK_XNOR: - if((w1_mask ^ w2_mask) == 0)return false; - return true; - } - } - return true; -} - -bool bPPU::color_windows_not_obstructing(uint16 x, uint8 color_mask_type) { -uint8 w1_mask, w2_mask; //1 = masked, 0 = not masked -uint8 color_mask; -bool r; -uint16 window1_left, window1_right, window2_left, window2_right; - if(color_mask_type == PPU_MAIN) { - color_mask = regs.color_mask; - } else { - color_mask = regs.colorsub_mask; - } - - if(color_mask == 0)return false; - if(color_mask == 3)return true; - - window1_left = regs.window1_left; - window1_right = regs.window1_right; - window2_left = regs.window2_left; - window2_right = regs.window2_right; - - if(regs.bg_mode == 5 || regs.bg_mode == 6) { - window1_left <<= 1; - window1_right <<= 1; - window2_left <<= 1; - window2_right <<= 1; - } - - if(regs.color_window1_enabled == false && regs.color_window2_enabled == false) { - r = true; - } else if(regs.color_window1_enabled == true && regs.color_window2_enabled == false) { - if(regs.color_window1_invert == false) { - if(x >= window1_left && x <= window1_right)r = false; - else r = true; - } else { - if(x < window1_left || x > window1_right)r = false; - else r = true; - } - } else if(regs.color_window1_enabled == false && regs.color_window2_enabled == true) { - if(regs.color_window2_invert == false) { - if(x >= window2_left && x <= window2_right)r = false; - else r = true; - } else { - if(x < window2_left || x > window2_right)r = false; - else r = true; - } - } else if(regs.color_window1_enabled == true && regs.color_window2_enabled == true) { - if(regs.color_window1_invert == false) { - if(x >= window1_left && x <= window1_right)w1_mask = 1; - else w1_mask = 0; - } else { - if(x < window1_left || x > window1_right)w1_mask = 1; - else w1_mask = 0; - } - - if(regs.color_window2_invert == false) { - if(x >= window2_left && x <= window2_right)w2_mask = 1; - else w2_mask = 0; - } else { - if(x < window2_left || x > window2_right)w2_mask = 1; - else w2_mask = 0; - } - - switch(regs.color_window_mask) { - case WINDOWMASK_OR: - if((w1_mask | w2_mask) == 1)r = false; - else r = true; - break; - case WINDOWMASK_AND: - if((w1_mask & w2_mask) == 1)r = false; - else r = true; - break; - case WINDOWMASK_XOR: - if((w1_mask ^ w2_mask) == 1)r = false; - else r = true; - break; - case WINDOWMASK_XNOR: - if((w1_mask ^ w2_mask) == 0)r = false; - else r = true; - break; - } - } - - if(color_mask == 2) { - r = (r == true)?false:true; - } - - return r; -} diff --git a/src/ppu/bppu/bppu_render.h b/src/ppu/bppu/bppu_render.h index cfaafba7..89ebdb10 100644 --- a/src/ppu/bppu/bppu_render.h +++ b/src/ppu/bppu/bppu_render.h @@ -49,21 +49,20 @@ void build_color_window_tables(); void render_line_bg(uint8 bg, uint8 color_depth, uint8 pri0_pos, uint8 pri1_pos); //bppu_render_oam.cpp -struct { - byte num; - byte width, height; - word x, y; - word character; - byte v_flip, h_flip; - byte palette; - byte priority; -}current_sprite; +sprite_item *spr; + +uint8 oam_itemlist[32]; +struct oam_tileitem { + uint16 x, y, pri, pal, tile; + bool hflip; +}oam_tilelist[34]; enum { OAM_PRI_NONE = 4 }; uint8 oam_line_pal[512], oam_line_pri[512]; -void set_sprite_attributes(uint8 sprite_num); -void render_oam_sprite(); +bool is_sprite_on_scanline(); +void load_oam_tiles(); +void render_oam_tile(int tile_num); void render_line_oam(uint8 pri0_pos, uint8 pri1_pos, uint8 pri2_pos, uint8 pri3_pos); //bppu_render_mode7.cpp diff --git a/src/ppu/bppu/bppu_render_bg.cpp b/src/ppu/bppu/bppu_render_bg.cpp index a131b09c..d0b52853 100644 --- a/src/ppu/bppu/bppu_render_bg.cpp +++ b/src/ppu/bppu/bppu_render_bg.cpp @@ -111,6 +111,8 @@ uint8 *wt_main = main_windowtable[bg]; uint8 *wt_sub = sub_windowtable[bg]; build_window_tables(bg); for(screen_x=0;screen_x<_screen_width;screen_x++) { + //offset-per-tile mode. horizontal OPT is buggy, so it is disabled + //vertical OPT seems to be working OK... if(regs.bg_mode == 2 || regs.bg_mode == 4 || regs.bg_mode == 6) { if(regs.bg_mode == 6) { tile_x = (mtable[screen_x + (hscroll & 15)] >> 4); diff --git a/src/ppu/bppu/bppu_render_oam.cpp b/src/ppu/bppu/bppu_render_oam.cpp index b487604b..be44c52f 100644 --- a/src/ppu/bppu/bppu_render_oam.cpp +++ b/src/ppu/bppu/bppu_render_oam.cpp @@ -1,86 +1,131 @@ -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 +void bPPU::get_sprite_size(int i, bool size) { 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; } + if(!size) { sprite_list[i].width = 8; sprite_list[i].height = 8; } + else { sprite_list[i].width = 16; sprite_list[i].height = 16; } break; case 1: - if(!size) { current_sprite.width = 8; current_sprite.height = 8; } - else { current_sprite.width = 32; current_sprite.height = 32; } + if(!size) { sprite_list[i].width = 8; sprite_list[i].height = 8; } + else { sprite_list[i].width = 32; sprite_list[i].height = 32; } break; case 2: - if(!size) { current_sprite.width = 8; current_sprite.height = 8; } - else { current_sprite.width = 64; current_sprite.height = 64; } + if(!size) { sprite_list[i].width = 8; sprite_list[i].height = 8; } + else { sprite_list[i].width = 64; sprite_list[i].height = 64; } break; case 3: - if(!size) { current_sprite.width = 16; current_sprite.height = 16; } - else { current_sprite.width = 32; current_sprite.height = 32; } + if(!size) { sprite_list[i].width = 16; sprite_list[i].height = 16; } + else { sprite_list[i].width = 32; sprite_list[i].height = 32; } break; case 4: - if(!size) { current_sprite.width = 16; current_sprite.height = 16; } - else { current_sprite.width = 64; current_sprite.height = 64; } + if(!size) { sprite_list[i].width = 16; sprite_list[i].height = 16; } + else { sprite_list[i].width = 64; sprite_list[i].height = 64; } break; case 5: - if(!size) { current_sprite.width = 32; current_sprite.height = 32; } - else { current_sprite.width = 64; current_sprite.height = 64; } + if(!size) { sprite_list[i].width = 32; sprite_list[i].height = 32; } + else { sprite_list[i].width = 64; sprite_list[i].height = 64; } break; case 6: - if(!size) { current_sprite.width = 16; current_sprite.height = 32; } - else { current_sprite.width = 32; current_sprite.height = 64; } + if(!size) { sprite_list[i].width = 16; sprite_list[i].height = 32; } + else { sprite_list[i].width = 32; sprite_list[i].height = 64; } break; case 7: - if(!size) { current_sprite.width = 16; current_sprite.height = 32; } - else { current_sprite.width = 32; current_sprite.height = 32; } + if(!size) { sprite_list[i].width = 16; sprite_list[i].height = 32; } + else { sprite_list[i].width = 32; sprite_list[i].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; - tile_width = current_sprite.width >> 3; //e.x. 16x16 sprite = 2x2 tiles - - if(_interlace == true && _screen_width == 512) { - y = (_y << 1) + _interlace_field; +//called whenever OAM memory is written to +void bPPU::update_sprite_list(uint16 addr) { +int i, z; +uint16 width, height; + if(addr < 0x0200) { + i = addr >> 2; + switch(addr & 3) { + case 0: + sprite_list[i].x = (sprite_list[i].x & 0x0100) | oam[addr]; + break; + case 1: + sprite_list[i].y = oam[addr] + 1; + break; + case 2: + sprite_list[i].character = oam[addr]; + break; + case 3: + sprite_list[i].vflip = !!(oam[addr] & 0x80); + sprite_list[i].hflip = !!(oam[addr] & 0x40); + sprite_list[i].priority = (oam[addr] >> 4) & 3; + sprite_list[i].palette = (oam[addr] >> 1) & 7; + sprite_list[i].use_nameselect = oam[addr] & 1; + break; + } } else { - y = _y; + addr &= 0x001f; + z = oam[0x0200 + addr]; + i = addr << 2; + sprite_list[i ].x = ((z & 0x01)?0x0100:0x0000) + (sprite_list[i ].x & 0xff); + sprite_list[i + 1].x = ((z & 0x04)?0x0100:0x0000) + (sprite_list[i + 1].x & 0xff); + sprite_list[i + 2].x = ((z & 0x10)?0x0100:0x0000) + (sprite_list[i + 2].x & 0xff); + sprite_list[i + 3].x = ((z & 0x40)?0x0100:0x0000) + (sprite_list[i + 3].x & 0xff); + get_sprite_size(i, !!(z & 0x02)); + get_sprite_size(i + 1, !!(z & 0x08)); + get_sprite_size(i + 2, !!(z & 0x20)); + get_sprite_size(i + 3, !!(z & 0x80)); } +} - x = current_sprite.x; - if(_screen_width == 512) { - x <<= 1; +//called when sprite sizes are changed via $2101 write +void bPPU::update_sprite_list_sizes() { +int i, z; +uint16 addr = 0x0200; + for(i=0;i<128;i+=4) { + z = oam[addr++]; + get_sprite_size(i, !!(z & 0x02)); + get_sprite_size(i + 1, !!(z & 0x08)); + get_sprite_size(i + 2, !!(z & 0x20)); + get_sprite_size(i + 3, !!(z & 0x80)); } +} - if(current_sprite.v_flip) { - y = ((current_sprite.height - 1) - (_y - current_sprite.y)); +bool bPPU::is_sprite_on_scanline() { +//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(spr->x > 256 && (spr->x + spr->width) < 512 && _screen_width != 512)return false; + + if(regs.oam_halve == false) { + if(_y >= spr->y && _y < (spr->y + spr->height)) { + return true; + } else if((spr->y + spr->height) >= 256 && _y < ((spr->y + spr->height) & 255)) { + return true; + } } else { - y = (_y - current_sprite.y); + if(_y >= spr->y && _y < (spr->y + (spr->height >> 1))) { + return true; + } else if((spr->y + (spr->height >> 1)) >= 256 && _y < ((spr->y + (spr->height >> 1)) & 255)) { + return true; + } } + + return false; +} + +void bPPU::load_oam_tiles() { +uint16 tile_width; + tile_width = spr->width >> 3; + +int x, y, chr, nameselect_index; + x = spr->x; + if(_screen_width == 512)x <<= 1; + x &= 511; + + if(spr->vflip) { + y = ((spr->height - 1) - (_y - spr->y)); + } else { + y = (_y - spr->y); + } +//todo: double-check code below. seems that interlace_field +//should be added to hires 512x448 sprites as well, and not +//just when oam_halve is enabled... if(regs.oam_halve == true) { y <<= 1; if(_interlace == true && _screen_width == 512) { @@ -89,81 +134,114 @@ int tile_width; } y &= 255; - chr = current_sprite.character; - tiledata_inc = (chr & 0x100)?(regs.oam_nameselect << 13):0; + chr = spr->character; + if(spr->use_nameselect == true) { + chr += 256; + nameselect_index = regs.oam_nameselect << 13; + } else { + nameselect_index = 0x0000; + } 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; - } - } + +int i, n, mx, pos, z; + for(i=0;i= 257 && (z + 7) < 512 && _screen_width != 512)continue; + + if(regs.oam_tilecount++ > 34)break; + n = regs.oam_tilecount - 1; + oam_tilelist[n].x = z; + oam_tilelist[n].y = y; + oam_tilelist[n].pri = spr->priority; + oam_tilelist[n].pal = (spr->palette << 4) + 128; + oam_tilelist[n].hflip = spr->hflip; + + if(oam_tilelist[n].hflip) { + mx = (tile_width - 1) - i; + } else { + mx = i; + } + pos = regs.oam_tdaddr + ((chr + mx) << 5) + ((y & 7) << 1) + nameselect_index; + oam_tilelist[n].tile = (pos >> 5) & 0x07ff; + } +} + +void bPPU::render_oam_tile(int tile_num) { +uint8 *oam_td, *oam_td_state, *tile_ptr; +oam_tileitem *t = &oam_tilelist[tile_num]; + oam_td = (uint8*)bg_tiledata[COLORDEPTH_16]; + oam_td_state = (uint8*)bg_tiledata_state[COLORDEPTH_16]; + + if(oam_td_state[t->tile] == 1) { + render_bg_tile(COLORDEPTH_16, t->tile); + } + +int x, sx, col; + sx = t->x; +//tile_ptr = tiledata + (tile * (8_width * 8_height)) + ((y & 7_height_mask) * 8_width); + tile_ptr = (uint8*)oam_td + (t->tile << 6) + ((t->y & 7) << 3); + for(x=0;x<8;x++) { + sx &= 511; + if(sx < _screen_width) { + col = *(tile_ptr + ((t->hflip)?7-x:x)); + if(col) { + col += t->pal; + oam_line_pal[sx] = col; + oam_line_pri[sx] = t->pri; + if(_screen_width == 512) { + oam_line_pal[sx + 1] = col; + oam_line_pri[sx + 1] = t->pri; } } - x += (_screen_width == 512)?2:1; } + sx += (_screen_width == 512)?2:1; } } void bPPU::render_line_oam(uint8 pri0_pos, uint8 pri1_pos, uint8 pri2_pos, uint8 pri3_pos) { -int s; +int s, x; bool _bg_enabled = regs.bg_enabled[OAM]; bool _bgsub_enabled = regs.bgsub_enabled[OAM]; - if(_bg_enabled == false && _bgsub_enabled == false)return; 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); + + memset(oam_itemlist, 0xff, 32); for(s=0;s<128;s++) { - set_sprite_attributes(s); - 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) >= 256 && _y < ((current_sprite.y + (current_sprite.height >> 1)) & 255)) { - render_oam_sprite(); - } - } + spr = &sprite_list[(s + regs.oam_firstsprite) & 127]; + if(is_sprite_on_scanline() == false)continue; + if(regs.oam_itemcount++ > 32)break; + oam_itemlist[regs.oam_itemcount - 1] = (s + regs.oam_firstsprite) & 127; } + for(s=0;s<34;s++)oam_tilelist[s].tile = 0xffff; + + for(s=31;s>=0;s--) { + if(oam_itemlist[s] == 0xff)continue; + spr = &sprite_list[oam_itemlist[s]]; + load_oam_tiles(); + } + + for(s=0;s<34;s++) { + if(oam_tilelist[s].tile == 0xffff)continue; + render_oam_tile(s); + } + + regs.time_over |= (regs.oam_tilecount > 34); + regs.range_over |= (regs.oam_itemcount > 32); + + if(_bg_enabled == false && _bgsub_enabled == false)return; int _pri; - for(int x=0;x<_screen_width;x++) { + for(x=0;x<_screen_width;x++) { if(oam_line_pri[x] == OAM_PRI_NONE)continue; switch(oam_line_pri[x]) { diff --git a/src/ppu/bppu/old_bppu_render_oam.cpp b/src/ppu/bppu/old_bppu_render_oam.cpp new file mode 100644 index 00000000..c6060e19 --- /dev/null +++ b/src/ppu/bppu/old_bppu_render_oam.cpp @@ -0,0 +1,230 @@ +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/ppu/ppu.cpp b/src/ppu/ppu.cpp index 8f9ff5b5..3f7a90ce 100644 --- a/src/ppu/ppu.cpp +++ b/src/ppu/ppu.cpp @@ -15,6 +15,8 @@ PPUOutput::~PPUOutput() { if(buffer)memfree(buffer, "PPUOutput::buffer"); } +void PPU::set_frameskip(int fs) {} + PPU::PPU() { mmio = &mmio_unmapped; output = new PPUOutput(); diff --git a/src/ppu/ppu.h b/src/ppu/ppu.h index 4aeefdff..f4c20eca 100644 --- a/src/ppu/ppu.h +++ b/src/ppu/ppu.h @@ -28,6 +28,7 @@ MMIO *mmio; virtual void frame() = 0; virtual void power() = 0; virtual void reset() = 0; + virtual void set_frameskip(int fs); PPU(); ~PPU(); diff --git a/src/sdl/Makefile b/src/sdl/Makefile new file mode 100644 index 00000000..eba1c93b --- /dev/null +++ b/src/sdl/Makefile @@ -0,0 +1,81 @@ +CC = c++ +CFLAGS = -O2 +OBJS = sdlmain.o \ + libstring.o libconfig.o \ + reader.o \ + memory.o bmemory.o \ + cpu.o bcpu.o \ + apu.o bapu.o bapuskip.o \ + ppu.o bppu.o \ + snes.o + +all: $(OBJS) + $(CC) $(CFLAGS) $(OBJS) `sdl11-config --cflags --libs` -o bsnes_sdl + +clean: + rm *.o + +#################### +### sdl-specific ### +#################### +sdlmain.o: *.cpp *.h + $(CC) $(CFLAGS) -c sdlmain.cpp `sdl11-config --cflags` + +################# +### libraries ### +################# +libstring.o: ../lib/*.cpp ../lib/*.h + $(CC) $(CFLAGS) -c ../lib/libstring.cpp +libconfig.o: ../lib/*.cpp ../lib/*.h + $(CC) $(CFLAGS) -c ../lib/libconfig.cpp + +############## +### memory ### +############## +memory.o: ../memory/memory.cpp ../memory/memory.h + $(CC) $(CFLAGS) -c ../memory/memory.cpp + +bmemory.o: ../memory/bmemory/* + $(CC) $(CFLAGS) -c ../memory/bmemory/bmemory.cpp + +########### +### cpu ### +########### +cpu.o: ../cpu/*.cpp ../cpu/*.h + $(CC) $(CFLAGS) -c ../cpu/cpu.cpp + +bcpu.o: ../cpu/bcpu/* + $(CC) $(CFLAGS) -c ../cpu/bcpu/bcpu.cpp + +########### +### apu ### +########### +apu.o: ../apu/* + $(CC) $(CFLAGS) -c ../apu/apu.cpp + +bapu.o: ../apu/bapu/* + $(CC) $(CFLAGS) -c ../apu/bapu/bapu.cpp + +bapuskip.o: ../apu/bapuskip/* + $(CC) $(CFLAGS) -c ../apu/bapuskip/bapuskip.cpp + +########### +### ppu ### +########### +ppu.o: ../ppu/*.cpp ../ppu/*.h + $(CC) $(CFLAGS) -c ../ppu/ppu.cpp + +bppu.o: ../ppu/bppu/* + $(CC) $(CFLAGS) -c ../ppu/bppu/bppu.cpp + +############## +### reader ### +############## +reader.o: ../reader/reader.cpp ../reader/reader.h + $(CC) $(CFLAGS) -c ../reader/reader.cpp + +############ +### snes ### +############ +snes.o: ../snes/*.cpp ../snes/*.h + $(CC) $(CFLAGS) -c ../snes/snes.cpp diff --git a/src/sdl/Makefile.win32 b/src/sdl/Makefile.win32 new file mode 100644 index 00000000..fee7b835 --- /dev/null +++ b/src/sdl/Makefile.win32 @@ -0,0 +1,82 @@ +CC = cl +CFLAGS = /nologo /O2 /Ogityb2 /Gr /Gs +OBJS = sdlmain.obj \ + libstring.obj libconfig.obj \ + reader.obj \ + memory.obj bmemory.obj \ + cpu.obj bcpu.obj \ + apu.obj bapu.obj bapuskip.obj \ + ppu.obj bppu.obj \ + snes.obj +LIBS = kernel32.lib user32.lib gdi32.lib sdlmain.lib sdl.lib + +all: $(OBJS) + $(CC) /Febsnes_sdl.exe $(CFLAGS) $(OBJS) $(LIBS) + +clean: + del *.obj + +#################### +### sdl-specific ### +#################### +sdlmain.obj: *.cpp *.h + $(CC) $(CFLAGS) /c sdlmain.cpp + +################# +### libraries ### +################# +libstring.obj: ../lib/*.cpp ../lib/*.h + $(CC) $(CFLAGS) /c ../lib/libstring.cpp +libconfig.obj: ../lib/*.cpp ../lib/*.h + $(CC) $(CFLAGS) /c ../lib/libconfig.cpp + +############## +### memory ### +############## +memory.obj: ../memory/memory.cpp ../memory/memory.h + $(CC) $(CFLAGS) /c ../memory/memory.cpp + +bmemory.obj: ../memory/bmemory/* + $(CC) $(CFLAGS) /c ../memory/bmemory/bmemory.cpp + +########### +### cpu ### +########### +cpu.obj: ../cpu/*.cpp ../cpu/*.h + $(CC) $(CFLAGS) /c ../cpu/cpu.cpp + +bcpu.obj: ../cpu/bcpu/* + $(CC) $(CFLAGS) /c ../cpu/bcpu/bcpu.cpp + +########### +### apu ### +########### +apu.obj: ../apu/* + $(CC) $(CFLAGS) /c ../apu/apu.cpp + +bapu.obj: ../apu/bapu/* + $(CC) $(CFLAGS) /c ../apu/bapu/bapu.cpp + +bapuskip.obj: ../apu/bapuskip/* + $(CC) $(CFLAGS) /c ../apu/bapuskip/bapuskip.cpp + +########### +### ppu ### +########### +ppu.obj: ../ppu/*.cpp ../ppu/*.h + $(CC) $(CFLAGS) /c ../ppu/ppu.cpp + +bppu.obj: ../ppu/bppu/* + $(CC) $(CFLAGS) /c ../ppu/bppu/bppu.cpp + +############## +### reader ### +############## +reader.obj: ../reader/reader.cpp ../reader/reader.h + $(CC) $(CFLAGS) /c ../reader/reader.cpp + +############ +### snes ### +############ +snes.obj: ../snes/*.cpp ../snes/*.h + $(CC) $(CFLAGS) /c ../snes/snes.cpp diff --git a/src/sdl/bsnes.cpp b/src/sdl/bsnes.cpp new file mode 100644 index 00000000..50336b7a --- /dev/null +++ b/src/sdl/bsnes.cpp @@ -0,0 +1,90 @@ +void bSNES::set_status(uint32 new_status) { run_status = new_status; } +uint32 bSNES::get_status() { return run_status; } + +void bSNES::snes_run() { + if(!rom_image->loaded())return; + + switch(run_status) { + case RUN: + while(update_frame == false) { + run(); + } + update_frame = false; + render(); + return; + case STOP: + break; + } +} + +void bSNES::render_frame() {} + +/*********************** + *** Input functions *** + ***********************/ + +//It would appear that keystate does not need to be free'd +//after calling SDL_GetKeyState... doing so causes libSDL +//to throw error messages about a bad free call to stdout... +void bSNES::poll_input() { +uint8 *keystate = SDL_GetKeyState(0); + joypad1.up = keystate[cfg.input.joypad1.up]; + joypad1.down = keystate[cfg.input.joypad1.down]; + joypad1.left = keystate[cfg.input.joypad1.left]; + joypad1.right = keystate[cfg.input.joypad1.right]; + joypad1.select = keystate[cfg.input.joypad1.select]; + joypad1.start = keystate[cfg.input.joypad1.start]; + joypad1.y = keystate[cfg.input.joypad1.y]; + joypad1.b = keystate[cfg.input.joypad1.b]; + joypad1.x = keystate[cfg.input.joypad1.x]; + joypad1.a = keystate[cfg.input.joypad1.a]; + joypad1.l = keystate[cfg.input.joypad1.l]; + joypad1.r = keystate[cfg.input.joypad1.r]; + +//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; + if(joypad1.left)joypad1.right = 0; +} + +bool bSNES::get_input_status(uint8 device, uint8 button) { + switch(device) { + case DEV_JOYPAD1: + switch(button) { + case JOYPAD_UP: return joypad1.up; + case JOYPAD_DOWN: return joypad1.down; + case JOYPAD_LEFT: return joypad1.left; + case JOYPAD_RIGHT: return joypad1.right; + case JOYPAD_A: return joypad1.a; + case JOYPAD_B: return joypad1.b; + case JOYPAD_X: return joypad1.x; + case JOYPAD_Y: return joypad1.y; + case JOYPAD_L: return joypad1.l; + case JOYPAD_R: return joypad1.r; + case JOYPAD_SELECT:return joypad1.select; + case JOYPAD_START: return joypad1.start; + } + break; + } + return 0; +} + +bJoypad::bJoypad() { + up = down = left = right = false; + a = b = x = y = false; + l = r = select = start = false; +} + +void bSNES::notify(uint32 message, uint32 param1, uint32 param2) { + switch(message) { + case RENDER_FRAME: + update_frame = true; + break; + } +} + +bSNES::bSNES() { + run_status = STOP; + update_frame = false; +} diff --git a/src/sdl/bsnes.h b/src/sdl/bsnes.h new file mode 100644 index 00000000..472df4e5 --- /dev/null +++ b/src/sdl/bsnes.h @@ -0,0 +1,30 @@ +class bJoypad { +public: +bool up, down, left, right; +bool a, b, x, y; +bool l, r, select, start; + bJoypad(); +}; + +class bSNES : public SNES { +private: +uint32 run_status; +bool update_frame; +bJoypad joypad1, joypad2; + +public: +enum { STOP = 0, RUN }; + void set_status(uint32 new_status); + uint32 get_status(); + void snes_run(); + void render_frame(); + +//input functions + void poll_input(); + bool get_input_status(uint8 device, uint8 button); + + void notify(uint32 message, uint32 param1 = 0, uint32 param2 = 0); + bSNES(); +}; + +bSNES *bsnes; diff --git a/src/sdl/bsnes_sdl.cfg b/src/sdl/bsnes_sdl.cfg new file mode 100644 index 00000000..3e9cb767 --- /dev/null +++ b/src/sdl/bsnes_sdl.cfg @@ -0,0 +1,18 @@ +apu.enabled = true +video.fullscreen = false +video.display_width = 256 +video.display_height = 223 +video.output_width = 256 +video.output_height = 223 +input.joypad1.up = 0x111 +input.joypad1.down = 0x112 +input.joypad1.left = 0x114 +input.joypad1.right = 0x113 +input.joypad1.a = 0x78 +input.joypad1.b = 0x7a +input.joypad1.x = 0x73 +input.joypad1.y = 0x61 +input.joypad1.l = 0x64 +input.joypad1.r = 0x63 +input.joypad1.select = 0x12f +input.joypad1.start = 0x0d diff --git a/src/sdl/cc.bat b/src/sdl/cc.bat new file mode 100644 index 00000000..413eb640 --- /dev/null +++ b/src/sdl/cc.bat @@ -0,0 +1,3 @@ +@nmake /NOLOGO /f Makefile.win32 +@move bsnes_sdl.exe ../../bsnes_sdl.exe>nul +@pause \ No newline at end of file diff --git a/src/sdl/clean.bat b/src/sdl/clean.bat new file mode 100644 index 00000000..81715981 --- /dev/null +++ b/src/sdl/clean.bat @@ -0,0 +1 @@ +@nmake /NOLOGO /f Makefile.win32 clean diff --git a/src/sdl/config.cpp b/src/sdl/config.cpp new file mode 100644 index 00000000..62177565 --- /dev/null +++ b/src/sdl/config.cpp @@ -0,0 +1,47 @@ +#define __config_add(name, def, type) add(&name, #name, def, type) + +class Config : public config { +public: + +struct { + uint32 enabled; +}apu; + +struct { + uint32 fullscreen; + uint32 display_width, display_height; + uint32 output_width, output_height; +}video; + +struct { + struct { + uint32 up, down, left, right; + uint32 a, b, x, y, l, r; + uint32 select, start; + }joypad1; +}input; + + Config() { + __config_add(apu.enabled, true, TRUEFALSE); + + __config_add(video.fullscreen, false, TRUEFALSE); + __config_add(video.display_width, 256, DEC); + __config_add(video.display_height, 223, DEC); + __config_add(video.output_width, 256, DEC); + __config_add(video.output_height, 223, DEC); + + __config_add(input.joypad1.up, SDLK_UP, HEX); + __config_add(input.joypad1.down, SDLK_DOWN, HEX); + __config_add(input.joypad1.left, SDLK_LEFT, HEX); + __config_add(input.joypad1.right, SDLK_RIGHT, HEX); + __config_add(input.joypad1.a, SDLK_x, HEX); + __config_add(input.joypad1.b, SDLK_z, HEX); + __config_add(input.joypad1.x, SDLK_s, HEX); + __config_add(input.joypad1.y, SDLK_a, HEX); + __config_add(input.joypad1.l, SDLK_d, HEX); + __config_add(input.joypad1.r, SDLK_c, HEX); + __config_add(input.joypad1.select, SDLK_RSHIFT, HEX); + __config_add(input.joypad1.start, SDLK_RETURN, HEX); + } + +}cfg; diff --git a/src/sdl/render.cpp b/src/sdl/render.cpp new file mode 100644 index 00000000..69b9ebec --- /dev/null +++ b/src/sdl/render.cpp @@ -0,0 +1,110 @@ +uint8 color_curve_table[32]; +uint32 color_lookup_table[65536]; + +void update_color_lookup_table() { +int i, r, g, b, c; + for(i=0,c=0;i<16;i++) { + color_curve_table[i] = c; + c = c + i + 1; + } + for(;i<31;i++) { + color_curve_table[i] = c; + c += 8; + } + color_curve_table[i] = 0xff; + +int color_depth = 16; + if(color_depth == 15) { + for(i=0;i<65536;i++) { + r = (i ) & 31; + g = (i >> 5) & 31; + b = (i >> 10) & 31; + r = color_curve_table[r] >> 3; + g = color_curve_table[g] >> 3; + b = color_curve_table[b] >> 3; + color_lookup_table[i] = (r << 10) | (g << 5) | (b); + } + } else if(color_depth == 16) { + for(i=0;i<65536;i++) { + r = (i ) & 31; + g = (i >> 5) & 31; + b = (i >> 10) & 31; + r = color_curve_table[r] >> 3; + g = color_curve_table[g] >> 2; + b = color_curve_table[b] >> 3; + color_lookup_table[i] = (r << 11) | (g << 5) | (b); + } + } else if(color_depth == 32) { + for(i=0;i<65536;i++) { + r = (i ) & 31; + g = (i >> 5) & 31; + b = (i >> 10) & 31; + r = color_curve_table[r]; + g = color_curve_table[g]; + b = color_curve_table[b]; + color_lookup_table[i] = (r << 16) | (g << 8) | (b); + } + } else { + alert("Error: Unsupported color depth [%d]", color_depth); + } +} + +void render16() { +uint16 *src, *dest; +uint32 pitch; +int x, y; + pitch = (backbuffer->pitch >> 1) - 256; + src = (uint16*)ppu->output->buffer + (1 << 10); + dest = (uint16*)backbuffer->pixels; + for(y=0;y<223;y++) { + for(x=0;x<256;x++) { + *dest++ = color_lookup_table[*src]; + src += 2; + } + dest += pitch; + src += 512; + } +} + +void render32() { +uint16 *src; +uint32 *dest, pitch; +int x, y; + pitch = (screen->pitch >> 2) - 256; + src = (uint16*)ppu->output->buffer + (1 << 10); + dest = (uint32*)screen->pixels; + for(y=0;y<223;y++) { + for(x=0;x<256;x++) { + *dest++ = color_lookup_table[*src]; + src += 2; + } + dest += pitch; + src += 512; + } +} + +void render() { + if(SDL_MUSTLOCK(screen)) { + SDL_LockSurface(screen); + } + if(SDL_MUSTLOCK(backbuffer)) { + SDL_LockSurface(backbuffer); + } + + render16(); + +//documentation says not to use this, but it's rather ridiculous that a graphics +//library wouldn't support simple image scaling... so let's use it anyway and see +//what happens... + SDL_SoftStretch(backbuffer, &screen_info.rs, screen, &screen_info.rd); +//SDL_BlitSurface(backbuffer, &screen_info.rs, screen, &screen_info.rd); + + if(SDL_MUSTLOCK(backbuffer)) { + SDL_UnlockSurface(backbuffer); + } + if(SDL_MUSTLOCK(screen)) { + SDL_UnlockSurface(screen); + } + + SDL_UpdateRect(screen, screen_info.rd.x, screen_info.rd.y, screen_info.rd.w, screen_info.rd.h); +} diff --git a/src/sdl/rom.cpp b/src/sdl/rom.cpp new file mode 100644 index 00000000..7df0f250 --- /dev/null +++ b/src/sdl/rom.cpp @@ -0,0 +1,99 @@ +class ROMImage { +private: +char rom_fn[4096]; +char sram_fn[4096]; +bool file_loaded; + +public: + bool loaded(); + bool load(); + void unload(); + void select(char *fn); + ROMImage(); + ~ROMImage(); +}; + +bool ROMImage::loaded() { + return file_loaded; +} + +bool ROMImage::load() { + if(file_loaded == true)return false; + + dprintf("* Loading \"%s\"...", rom_fn); + +FileReader *rf = new FileReader(); + if(!rf->open(FileReader::TYPE_ROM, rom_fn)) { + alert("Error loading image file [%s]!", rom_fn); + return false; + } + mem_bus->load_cart(static_cast(rf)); + rf->close(); + +CartInfo ci; + mem_bus->get_cartinfo(&ci); + if(ci.sram_size != 0) { + rf->open(FileReader::TYPE_SRAM, sram_fn); + mem_bus->load_sram(static_cast(rf)); + rf->close(); + } + + delete(rf); + + file_loaded = true; + return true; +} + +void ROMImage::unload() { + if(file_loaded == false)return; + +FileWriter *wf; +CartInfo ci; + mem_bus->get_cartinfo(&ci); + if(ci.sram_size != 0) { + wf = new FileWriter(); + wf->open(sram_fn); + mem_bus->save_sram(static_cast(wf)); + wf->close(); + delete(wf); + } + + file_loaded = false; + + mem_bus->unload_cart(); +} + +void ROMImage::select(char *fn) { +int i; + if(file_loaded == true)return; + +/* Remove quotes */ + if(fn[0] == '\"') { + strcpy(rom_fn, fn + 1); + rom_fn[strlen(rom_fn) - 1] = 0; + } else { + strcpy(rom_fn, fn); + } + + for(i=strlen(rom_fn)-1;i>=0;i--) { + if(rom_fn[i] == '.')break; + } + + strcpy(sram_fn, rom_fn); + if(rom_fn[i] == '.')sram_fn[i] = 0; + strcat(sram_fn, ".srm"); +} + +ROMImage::ROMImage() { + *rom_fn = 0; + *sram_fn = 0; + file_loaded = false; +} + +ROMImage::~ROMImage() { + if(file_loaded == true) { + unload(); + } +} + +ROMImage *rom_image; diff --git a/src/sdl/sdlmain.cpp b/src/sdl/sdlmain.cpp new file mode 100644 index 00000000..1648d9b1 --- /dev/null +++ b/src/sdl/sdlmain.cpp @@ -0,0 +1,181 @@ +#define _WIN32_ + +#define INTERFACE_MAIN +#define BSNES_VERSION "0.010" +#define BSNES_TITLE "bsnes/SDL v" BSNES_VERSION +#include "sdlmain.h" +#include "../base.h" + +#ifdef _WIN32_ +HWND hwnd; +#endif + +#include "config.cpp" +#include "bsnes.h" +#include "rom.cpp" +#include "render.cpp" +#include "bsnes.cpp" + +void *memalloc(uint32 size, char *name, ...) { + return (void*)malloc(size); +} + +void memfree(void *mem, char *name, ...) { + free(mem); +} + +void alert(char *s, ...) { +char str[4096]; +va_list args; + va_start(args, s); + vsprintf(str, s, args); + va_end(args); +#ifdef _WIN32_ + MessageBox(0, str, "bsnes", MB_OK); +#else + fprintf(stdout, "%s\r\n", str); +#endif +} + +void dprintf(char *s, ...) { +char str[4096]; +va_list args; + va_start(args, s); + vsprintf(str, s, args); + va_end(args); + fprintf(stdout, "%s\r\n", str); +} + +void init_snes() { + mem_bus = new bMemBus(); + cpu = new bCPU(); + if(cfg.apu.enabled) { + apu = new bAPU(); + } else { + apu = new bAPUSkip(); + } + ppu = new bPPU(); + snes = new bSNES(); + bsnes = static_cast(snes); +} + +void term_snes() { + if(mem_bus) { delete(mem_bus); mem_bus = 0; } + if(cpu) { delete(cpu); cpu = 0; } + if(apu) { delete(apu); apu = 0; } + if(ppu) { delete(ppu); ppu = 0; } + if(snes) { delete(snes); snes = 0; } +} + +void center_window() { +#ifdef _WIN32_ +RECT rc; +int x, y; + GetWindowRect(hwnd, &rc); + x = (GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left)) >> 1; + y = (GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top)) >> 1; + SetWindowPos(hwnd, HWND_TOPMOST, x, y, 0, 0, SWP_NOSIZE); +#endif +} + +void set_window_info() { +//SDL won't draw anything if you blit an image that's larger than +//the display mode/window, even if you use the SoftStretch blit and +//clip the source + dest rectangles properly... + if(cfg.video.display_width < cfg.video.output_width) { + cfg.video.display_width = cfg.video.output_width; + } + if(cfg.video.display_height < cfg.video.output_height) { + cfg.video.display_height = cfg.video.output_height; + } + + screen_info.rd.x = (cfg.video.display_width - cfg.video.output_width ) >> 1; + screen_info.rd.y = (cfg.video.display_height - cfg.video.output_height) >> 1; + screen_info.rd.w = cfg.video.output_width; + screen_info.rd.h = cfg.video.output_height; + + screen_info.rs.x = 0; + screen_info.rs.y = 0; + screen_info.rs.w = 256; + screen_info.rs.h = 223; +} + +#ifdef _WIN32_ +int __stdcall WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow) { +int argc = __argc; +char **argv = __argv; +#else +int main(int argc, char *argv[]) { +#endif + +SDL_Event event; + + if(argc < 2) { + alert("Usage: bsnes_sdl "); + return 0; + } + + cfg.load("bsnes_sdl.cfg"); + + rom_image = new ROMImage(); + init_snes(); + + rom_image->select(argv[1]); + rom_image->load(); + snes->power(); + + if(rom_image->loaded() == false) { + alert("Failed to load image. Usage: bsnes_sdl "); + goto _end; + } + + SDL_Init(SDL_INIT_VIDEO); + atexit(SDL_Quit); + set_window_info(); + screen = SDL_SetVideoMode(cfg.video.display_width, cfg.video.display_height, 16, + SDL_SWSURFACE | ((cfg.video.fullscreen)?SDL_FULLSCREEN:0)); + if(!screen) { + alert("Failed to initialize SDL"); + goto _end; + } + backbuffer = SDL_CreateRGBSurface(SDL_SWSURFACE, 256, 223, 16, 0xf800, 0x07e0, 0x001f, 0x0000); + + SDL_WM_SetCaption(BSNES_TITLE, 0); +#ifdef _WIN32_ + hwnd = FindWindow(0, BSNES_TITLE); +#endif + center_window(); + + update_color_lookup_table(); + bsnes->set_status(bSNES::RUN); + +int cursor_status; + while(1) { + bsnes->snes_run(); + while(SDL_PollEvent(&event)) { + switch(event.type) { + case SDL_KEYUP: + switch(event.key.keysym.sym) { + case SDLK_ESCAPE: + goto _end; + case SDLK_F10: //toggle cursor display + cursor_status = (SDL_ShowCursor(SDL_QUERY) == SDL_ENABLE)?SDL_DISABLE:SDL_ENABLE; + SDL_ShowCursor(cursor_status); + break; + case SDLK_F11: //only supported on X11 + SDL_WM_ToggleFullScreen(screen); + break; + } + break; + case SDL_QUIT: + goto _end; + } + } + } + +_end: + cfg.save("bsnes_sdl.cfg"); + term_snes(); + + return 0; +} diff --git a/src/sdl/sdlmain.h b/src/sdl/sdlmain.h new file mode 100644 index 00000000..d86de697 --- /dev/null +++ b/src/sdl/sdlmain.h @@ -0,0 +1,17 @@ +#ifdef _WIN32_ +#include +#include +#else +#include "SDL.h" +#endif + +#include "../lib/libbase.h" +#include "../lib/libvector.h" +#include "../lib/libstring.h" +#include "../lib/libconfig.h" + +SDL_Surface *screen, *backbuffer; + +struct { +SDL_Rect rs, rd; +}screen_info; diff --git a/src/sdl/sdlrun.bat b/src/sdl/sdlrun.bat new file mode 100644 index 00000000..2aaf95ea --- /dev/null +++ b/src/sdl/sdlrun.bat @@ -0,0 +1 @@ +c:\root\bsnes_g2\bsnes_sdl.exe c:\root\bsnes_testrom\zelda_us.smc \ No newline at end of file diff --git a/src/snes/snes.cpp b/src/snes/snes.cpp index a5510833..9ba56f14 100644 --- a/src/snes/snes.cpp +++ b/src/snes/snes.cpp @@ -1,22 +1,28 @@ #include "../base.h" void SNES::run() { - clock->run(); + cpu->run(); } void SNES::power() { - clock->power(); cpu->power(); + apu->power(); ppu->power(); +//clock->power(); mem_bus->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<=0x2143;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); +//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); @@ -24,9 +30,10 @@ int i; } void SNES::reset() { - clock->reset(); cpu->reset(); + apu->reset(); ppu->reset(); +//clock->reset(); mem_bus->reset(); } diff --git a/src/snes/snes.h b/src/snes/snes.h index aeff4b21..b66abed2 100644 --- a/src/snes/snes.h +++ b/src/snes/snes.h @@ -4,7 +4,7 @@ bool is_debugger_enabled; public: //system functions - virtual void run(); + void run(); virtual void render_frame() = 0; virtual void power(); virtual void reset(); @@ -29,11 +29,13 @@ enum { enum { NO_ACTION = 0, RENDER_FRAME, - CPU_EXEC_OPCODE, - MEM_READ, MEM_WRITE, - VRAM_READ, VRAM_WRITE, - OAM_READ, OAM_WRITE, - CGRAM_READ, CGRAM_WRITE, + CPU_EXEC_OPCODE_BEGIN, CPU_EXEC_OPCODE_END, + APU_EXEC_OPCODE_BEGIN, APU_EXEC_OPCODE_END, + MEM_READ, MEM_WRITE, + SPCRAM_READ, SPCRAM_WRITE, + VRAM_READ, VRAM_WRITE, + OAM_READ, OAM_WRITE, + CGRAM_READ, CGRAM_WRITE, }; virtual void notify(uint32 message, uint32 param1 = 0, uint32 param2 = 0); virtual void debugger_enable(); diff --git a/src/win/Makefile b/src/win/Makefile index 40414f21..ceb050d9 100644 --- a/src/win/Makefile +++ b/src/win/Makefile @@ -2,16 +2,17 @@ CC = cl CFLAGS = /nologo /O2 /Ogityb2 /Gr /Gs OBJS = winmain.obj \ libstring.obj libconfig.obj \ - clock.obj bclock.obj \ - memory.obj bmemory.obj \ reader.obj \ + memory.obj bmemory.obj \ cpu.obj bcpu.obj \ + apu.obj bapu.obj bapuskip.obj \ ppu.obj bppu.obj \ snes.obj LIBS = kernel32.lib user32.lib gdi32.lib comdlg32.lib ddraw.lib dxguid.lib all: $(OBJS) - $(CC) /Febsnes_g2.exe $(CFLAGS) $(OBJS) $(LIBS) + rc /r /fobsnes.res bsnes.rc + $(CC) /Febsnes.exe $(CFLAGS) $(OBJS) bsnes.res $(LIBS) clean: del *.obj @@ -30,15 +31,6 @@ libstring.obj: ../lib/*.cpp ../lib/*.h libconfig.obj: ../lib/*.cpp ../lib/*.h $(CC) $(CFLAGS) /c ../lib/libconfig.cpp -############# -### clock ### -############# -clock.obj: ../clock/*.cpp ../clock/*.h - $(CC) $(CFLAGS) /c ../clock/clock.cpp - -bclock.obj: ../clock/bclock/* - $(CC) $(CFLAGS) /c ../clock/bclock/bclock.cpp - ############## ### memory ### ############## @@ -57,6 +49,18 @@ cpu.obj: ../cpu/*.cpp ../cpu/*.h bcpu.obj: ../cpu/bcpu/* $(CC) $(CFLAGS) /c ../cpu/bcpu/bcpu.cpp +########### +### apu ### +########### +apu.obj: ../apu/* + $(CC) $(CFLAGS) /c ../apu/apu.cpp + +bapu.obj: ../apu/bapu/* + $(CC) $(CFLAGS) /c ../apu/bapu/bapu.cpp + +bapuskip.obj: ../apu/bapuskip/* + $(CC) $(CFLAGS) /c ../apu/bapuskip/bapuskip.cpp + ########### ### ppu ### ########### diff --git a/src/win/bsnes.cpp b/src/win/bsnes.cpp index 91738a51..c8063fed 100644 --- a/src/win/bsnes.cpp +++ b/src/win/bsnes.cpp @@ -6,6 +6,7 @@ uint8 cpu_op; case STOP: w_console->is_running(false); w_console->update_status(); + w_memory->refresh(); break; case RUNTOCPUSTEP: status.cpu_ran = false; @@ -21,6 +22,9 @@ uint8 cpu_op; run_status = RUNTOCPUSTEP; } break; + case RUNTOAPUSTEP: + status.apu_ran = false; + break; } } @@ -28,60 +32,73 @@ uint32 bSNES::get_status() { return run_status; } -void bSNES::run() { +void bSNES::snes_run() { if(!rom_image->loaded())return; switch(run_status) { case RUN: while(update_frame == false) { - clock->run(); + run(); } update_frame = false; return; case STOP: break; case RUNONCE: - clock->run(); + run(); set_status(STOP); break; case RUNTOSIGNAL: - clock->run(); + run(); if(w_bp->hit() == true) { set_status(STOP); - disassemble_cpu_op(); + disassemble_bp_op(); } break; case RUNTOFRAME: - clock->run(); + run(); if(update_frame == true) { update_frame = false; + set_status(STOP); + disassemble_apu_op(); + disassemble_cpu_op(); + } else if(w_bp->hit() == true) { + set_status(STOP); + disassemble_bp_op(); + } + return; + case RUNTOCPUSTEP: + run(); + if(status.cpu_ran == true) { + set_status(STOP); + } else if(w_bp->hit() == true) { + set_status(STOP); + disassemble_bp_op(); + } + break; + case RUNTOCPUPROCEED: + run(); + if(status.cpu_stop_pos == cpu->regs.pc) { set_status(STOP); disassemble_cpu_op(); } else if(w_bp->hit() == true) { set_status(STOP); - disassemble_cpu_op(); - } - return; - case RUNTOCPUSTEP: - clock->run(); - if(status.cpu_ran == true || w_bp->hit() == true) { - set_status(STOP); - } - break; - case RUNTOCPUPROCEED: - clock->run(); - if(status.cpu_stop_pos == cpu->regs.pc || w_bp->hit() == true) { - set_status(STOP); - disassemble_cpu_op(); + disassemble_bp_op(); } break; case RUNTOCPUTRACE: - clock->run(); + run(); if(status.cpu_trace_pos >= status.cpu_trace_stop) { set_status(STOP); disassemble_cpu_op(); } break; + case RUNTOAPUSTEP: + run(); + if(status.apu_ran == true || w_bp->hit() == true) { + set_status(STOP); + } + break; } } @@ -92,22 +109,26 @@ void bSNES::render_frame() { /*********************** *** Input functions *** ***********************/ -#define KeyState(key) ((GetAsyncKeyState(key) & 0x8000)?1:0) void bSNES::poll_input() { /* Only capture input when main window has focus */ if(GetForegroundWindow() == w_main->hwnd) { - joypad1.up = KeyState(VK_UP); - joypad1.down = KeyState(VK_DOWN); - joypad1.left = KeyState(VK_LEFT); - joypad1.right = KeyState(VK_RIGHT); - joypad1.select = KeyState(VK_LSHIFT) | KeyState(VK_RSHIFT); - joypad1.start = KeyState(VK_RETURN); - joypad1.y = KeyState('A'); - joypad1.b = KeyState('Z'); - joypad1.x = KeyState('S'); - joypad1.a = KeyState('X'); - joypad1.l = KeyState('D'); - joypad1.r = KeyState('C'); + joypad1.up = KeyDown(cfg.input.joypad1.up); + joypad1.down = KeyDown(cfg.input.joypad1.down); + joypad1.left = KeyDown(cfg.input.joypad1.left); + joypad1.right = KeyDown(cfg.input.joypad1.right); + joypad1.select = KeyDown(cfg.input.joypad1.select); + joypad1.start = KeyDown(cfg.input.joypad1.start); + joypad1.y = KeyDown(cfg.input.joypad1.y); + joypad1.b = KeyDown(cfg.input.joypad1.b); + joypad1.x = KeyDown(cfg.input.joypad1.x); + joypad1.a = KeyDown(cfg.input.joypad1.a); + joypad1.l = KeyDown(cfg.input.joypad1.l); + joypad1.r = KeyDown(cfg.input.joypad1.r); + } else { + joypad1.up = joypad1.down = joypad1.left = joypad1.right = + joypad1.select = joypad1.start = + joypad1.y = joypad1.b = joypad1.x = joypad1.a = + joypad1.l = joypad1.r = 0; } //Check for debugger-based key locks @@ -175,7 +196,7 @@ uint8 r = 0x00; a = addr & 0xffff; if((bank >= 0x00 && bank <= 0x3f) || (bank >= 0x80 && bank <= 0xbf)) { - /* Don't let the debugger poll MMIO ports */ + //don't let the debugger poll MMIO ports if(a >= 0x2000 && a <= 0x5fff) { r = 0x00; } else { @@ -185,6 +206,10 @@ uint8 r = 0x00; r = mem_bus->read(addr); } break; + case SPCRAM: + addr &= 0xffff; + r = apu->spcram_read(addr); + break; case VRAM: addr &= 0xffff; r = ppu->vram_read(addr); @@ -207,9 +232,13 @@ void bSNES::write(uint8 type, uint32 addr, uint8 value) { switch(type) { case DRAM: addr &= 0xffffff; - mem_bus->rom->write_protect(false); + mem_bus->cart->write_protect(false); mem_bus->write(addr, value); - mem_bus->rom->write_protect(true); + mem_bus->cart->write_protect(true); + break; + case SPCRAM: + addr &= 0xffff; + apu->spcram_write(addr, value); break; case VRAM: addr &= 0xffff; @@ -228,7 +257,7 @@ void bSNES::write(uint8 type, uint32 addr, uint8 value) { } void bSNES::notify(uint32 message, uint32 param1, uint32 param2) { -/* system messages */ +//system messages switch(message) { case RENDER_FRAME: update_frame = true; @@ -236,17 +265,27 @@ void bSNES::notify(uint32 message, uint32 param1, uint32 param2) { break; } -/* debugging messages */ +//debugging messages if(is_debugger_enabled == false)return; switch(message) { - case CPU_EXEC_OPCODE: + case CPU_EXEC_OPCODE_BEGIN: + break; + case CPU_EXEC_OPCODE_END: status.cpu_ran = true; status.cpu_trace_pos++; w_bp->test(message, cpu->regs.pc.d, 0); disassemble_cpu_op(); break; + case APU_EXEC_OPCODE_BEGIN: + break; + case APU_EXEC_OPCODE_END: + status.apu_ran = true; + w_bp->test(message, apu->regs.pc, 0); + disassemble_apu_op(); + break; case MEM_READ: + case SPCRAM_READ: case VRAM_READ: case OAM_READ: case CGRAM_READ: @@ -255,14 +294,15 @@ void bSNES::notify(uint32 message, uint32 param1, uint32 param2) { } break; case MEM_WRITE: + case SPCRAM_WRITE: case VRAM_WRITE: case OAM_WRITE: case CGRAM_WRITE: if(debug_command == false) { w_bp->test(message, param1, param2); } - /* this needs to be called after the breakpoint test, - as it will access read() and clear debug_command */ + //this needs to be called after the breakpoint test, + //as it will access read() and clear debug_command w_memory->refresh(message, param1); break; } @@ -270,16 +310,34 @@ void bSNES::notify(uint32 message, uint32 param1, uint32 param2) { void bSNES::disassemble_cpu_op() { char t[512]; -/* don't disassemble opcodes when no ROM is loaded */ +//don't disassemble opcodes when no ROM is loaded if(is_debugger_activated == false)return; -/* don't disassemble opcodes that won't be printed to console/traced to log anyway */ +//don't disassemble opcodes that won't be printed to console/traced to log anyway if(!w_console->can_write(Console::CPU_MESSAGE) && !w_console->tracing_enabled)return; cpu->disassemble_opcode(t); w_console->write(t, Console::CPU_MESSAGE); } +void bSNES::disassemble_apu_op() { +char t[512]; + if(is_debugger_activated == false)return; + + if(!w_console->can_write(Console::APU_MESSAGE) && !w_console->tracing_enabled)return; + + apu->disassemble_opcode(t); + w_console->write(t, Console::APU_MESSAGE); +} + +void bSNES::disassemble_bp_op() { + if(w_bp->bp[w_bp->bp_hit_num].source == SPCRAM) { + disassemble_apu_op(); + } else { + disassemble_cpu_op(); + } +} + bool bSNES::debugger_enabled() { return is_debugger_enabled; } @@ -319,6 +377,7 @@ void bSNES::debugger_update() { w_console->update_status(); w_bp->refresh(); w_memory->refresh(); + disassemble_apu_op(); disassemble_cpu_op(); } diff --git a/src/win/bsnes.h b/src/win/bsnes.h index bcb23c0b..049e0400 100644 --- a/src/win/bsnes.h +++ b/src/win/bsnes.h @@ -31,12 +31,13 @@ enum { RUNTOFRAME, RUNTOCPUSTEP, RUNTOCPUPROCEED, - RUNTOCPUTRACE + RUNTOCPUTRACE, + RUNTOAPUSTEP }; -enum { DRAM = 0, VRAM = 1, OAM = 2, CGRAM = 3 }; +enum { DRAM = 0, SPCRAM = 1, VRAM = 2, OAM = 3, CGRAM = 4 }; void set_status(uint32 new_status); uint32 get_status(); - void run(); + void snes_run(); void render_frame(); //input functions @@ -47,12 +48,14 @@ enum { DRAM = 0, VRAM = 1, OAM = 2, CGRAM = 3 }; struct { uint32 cpu_stop_pos; uint32 cpu_trace_pos, cpu_trace_stop; - bool cpu_ran; + bool cpu_ran, apu_ran; }status; uint8 read (uint8 type, uint32 addr); void write(uint8 type, uint32 addr, uint8 value); void notify(uint32 message, uint32 param1 = 0, uint32 param2 = 0); void disassemble_cpu_op(); + void disassemble_apu_op(); + void disassemble_bp_op(); //whether or not the user requests the debugger open bool debugger_enabled(); diff --git a/src/win/bsnes.ico b/src/win/bsnes.ico new file mode 100644 index 00000000..a396add1 Binary files /dev/null and b/src/win/bsnes.ico differ diff --git a/src/win/bsnes.lnk b/src/win/bsnes.lnk new file mode 100644 index 00000000..e83cb0a0 Binary files /dev/null and b/src/win/bsnes.lnk differ diff --git a/src/win/bsnes.rc b/src/win/bsnes.rc new file mode 100644 index 00000000..08f24c00 --- /dev/null +++ b/src/win/bsnes.rc @@ -0,0 +1,5 @@ +#define IDB_SNES_CONTROLLER 100 +#define IDI_APP_ICON 101 + +IDB_SNES_CONTROLLER BITMAP DISCARDABLE "snes_controller.bmp" +IDI_APP_ICON ICON DISCARDABLE "bsnes.ico" diff --git a/src/win/bsnes.res b/src/win/bsnes.res new file mode 100644 index 00000000..412d6082 Binary files /dev/null and b/src/win/bsnes.res differ diff --git a/src/win/bsnes_g2.lnk b/src/win/bsnes_g2.lnk deleted file mode 100644 index 3dd9544d..00000000 Binary files a/src/win/bsnes_g2.lnk and /dev/null differ diff --git a/src/win/cc.bat b/src/win/cc.bat index dbf5d9cb..ec67d554 100644 --- a/src/win/cc.bat +++ b/src/win/cc.bat @@ -1,3 +1,3 @@ @nmake /NOLOGO -@move bsnes_g2.exe ../../bsnes_g2.exe>nul +@move bsnes.exe ../../bsnes.exe>nul @pause \ No newline at end of file diff --git a/src/win/config.cpp b/src/win/config.cpp index 79a0f1c5..9520d449 100644 --- a/src/win/config.cpp +++ b/src/win/config.cpp @@ -3,6 +3,10 @@ class Config : public config { public: +struct { + uint32 enabled; +}apu; + struct { uint32 mode; uint32 use_vram; @@ -10,15 +14,39 @@ struct { uint32 vblank; }video; +struct { + struct { + uint32 up, down, left, right; + uint32 a, b, x, y, l, r; + uint32 select, start; + }joypad1; +}input; + struct { uint32 show_fps; }gui; Config() { + __config_add(apu.enabled, true, TRUEFALSE); + __config_add(video.mode, 1, DEC); __config_add(video.use_vram, true, TRUEFALSE); __config_add(video.color_curve, true, ENABLED); __config_add(video.vblank, false, TRUEFALSE); - __config_add(gui.show_fps, true, TRUEFALSE); + + __config_add(input.joypad1.up, VK_UP, HEX); + __config_add(input.joypad1.down, VK_DOWN, HEX); + __config_add(input.joypad1.left, VK_LEFT, HEX); + __config_add(input.joypad1.right, VK_RIGHT, HEX); + __config_add(input.joypad1.a, 'X', HEX); + __config_add(input.joypad1.b, 'Z', HEX); + __config_add(input.joypad1.x, 'S', HEX); + __config_add(input.joypad1.y, 'A', HEX); + __config_add(input.joypad1.l, 'D', HEX); + __config_add(input.joypad1.r, 'C', HEX); + __config_add(input.joypad1.select, VK_SHIFT, HEX); + __config_add(input.joypad1.start, VK_RETURN, HEX); + + __config_add(gui.show_fps, true, TRUEFALSE); } }cfg; diff --git a/src/win/dd_renderer.cpp b/src/win/dd_renderer.cpp index 6d3d2618..4aace022 100644 --- a/src/win/dd_renderer.cpp +++ b/src/win/dd_renderer.cpp @@ -235,7 +235,7 @@ int rx, ry; lpddsb->Restore(); } - if(cfg.gui.show_fps == false)return; + if(cfg.gui.show_fps == false || bsnes->get_status() == bSNES::STOP)return; uint32 fps; char s[256], t[256]; fps_timer->tick(); diff --git a/src/win/dd_renderer16.cpp b/src/win/dd_renderer16.cpp index 00fa4b2b..0f50abb5 100644 --- a/src/win/dd_renderer16.cpp +++ b/src/win/dd_renderer16.cpp @@ -8,9 +8,9 @@ int x, y; pitch = (ddsd.lPitch >> 1) - 256; int overscan_adjust = 0; - if(clock->overscan() == true) { - src += 8 << 10; - overscan_adjust = 8; + if(cpu->overscan() == true) { + src += 7 << 10; + overscan_adjust = 7; } for(y=1+overscan_adjust;y<224+overscan_adjust;y++) { @@ -34,9 +34,9 @@ int x, y; pitch = (ddsd.lPitch >> 1) - 256; int overscan_adjust = 0; - if(clock->overscan() == true) { - src += 8 << 10; - overscan_adjust = 16; + if(cpu->overscan() == true) { + src += 7 << 10; + overscan_adjust = 14; } for(y=2+overscan_adjust;y<448+overscan_adjust;y++) { @@ -62,9 +62,9 @@ int x, y; pitch = (ddsd.lPitch >> 1) - 512; int overscan_adjust = 0; - if(clock->overscan() == true) { - src += 8 << 10; - overscan_adjust = 8; + if(cpu->overscan() == true) { + src += 7 << 10; + overscan_adjust = 7; } for(y=1+overscan_adjust;y<224+overscan_adjust;y++) { @@ -96,9 +96,9 @@ int x, y; pitch = (ddsd.lPitch >> 1) - 512; int overscan_adjust = 0; - if(clock->overscan() == true) { - src += 8 << 10; - overscan_adjust = 16; + if(cpu->overscan() == true) { + src += 7 << 10; + overscan_adjust = 14; } for(y=2+overscan_adjust;y<448+overscan_adjust;y++) { diff --git a/src/win/dd_renderer32.cpp b/src/win/dd_renderer32.cpp index 9a097583..6b4893ea 100644 --- a/src/win/dd_renderer32.cpp +++ b/src/win/dd_renderer32.cpp @@ -8,9 +8,9 @@ int x, y; pitch = (ddsd.lPitch >> 2) - 256; int overscan_adjust = 0; - if(clock->overscan() == true) { - src += 8 << 10; - overscan_adjust = 8; + if(cpu->overscan() == true) { + src += 7 << 10; + overscan_adjust = 7; } for(y=1+overscan_adjust;y<224+overscan_adjust;y++) { @@ -34,9 +34,9 @@ int x, y; pitch = (ddsd.lPitch >> 2) - 256; int overscan_adjust = 0; - if(clock->overscan() == true) { - src += 8 << 10; - overscan_adjust = 16; + if(cpu->overscan() == true) { + src += 7 << 10; + overscan_adjust = 14; } for(y=2+overscan_adjust;y<448+overscan_adjust;y++) { @@ -62,9 +62,9 @@ int x, y; pitch = (ddsd.lPitch >> 2) - 512; int overscan_adjust = 0; - if(clock->overscan() == true) { - src += 8 << 10; - overscan_adjust = 8; + if(cpu->overscan() == true) { + src += 7 << 10; + overscan_adjust = 7; } for(y=1+overscan_adjust;y<224+overscan_adjust;y++) { @@ -96,9 +96,9 @@ int x, y; pitch = (ddsd.lPitch >> 2) - 512; int overscan_adjust = 0; - if(clock->overscan() == true) { - src += 8 << 10; - overscan_adjust = 16; + if(cpu->overscan() == true) { + src += 7 << 10; + overscan_adjust = 14; } for(y=2+overscan_adjust;y<448+overscan_adjust;y++) { diff --git a/src/win/lib.cpp b/src/win/lib.cpp index 03e21d53..5f54aff3 100644 --- a/src/win/lib.cpp +++ b/src/win/lib.cpp @@ -60,10 +60,10 @@ va_list args; void dprintf(char *s, ...) { char str[4096]; va_list args; + if(!w_console)return; + if(!w_console->can_write(Console::DEBUG_MESSAGE))return; va_start(args, s); vsprintf(str, s, args); va_end(args); - if(w_console) { - w_console->write(str, Console::DEBUG_MESSAGE); - } + w_console->write(str, Console::DEBUG_MESSAGE); } diff --git a/src/win/rom.cpp b/src/win/rom.cpp index 7e700d59..282be928 100644 --- a/src/win/rom.cpp +++ b/src/win/rom.cpp @@ -20,19 +20,23 @@ bool ROMImage::loaded() { bool ROMImage::load() { if(file_loaded == true)return false; - dprintf("* Loading [%s]...", rom_fn); + dprintf("* Loading \"%s\"...", rom_fn); FileReader *rf = new FileReader(); if(!rf->open(FileReader::TYPE_ROM, rom_fn)) { alert("Error loading image file [%s]!", rom_fn); return false; } - mem_bus->rom->load_rom(static_cast(rf)); + mem_bus->load_cart(static_cast(rf)); rf->close(); - rf->open(FileReader::TYPE_SRAM, sram_fn); - mem_bus->rom->load_sram(static_cast(rf)); - rf->close(); +CartInfo ci; + mem_bus->get_cartinfo(&ci); + if(ci.sram_size != 0) { + rf->open(FileReader::TYPE_SRAM, sram_fn); + mem_bus->load_sram(static_cast(rf)); + rf->close(); + } delete(rf); @@ -44,19 +48,25 @@ FileReader *rf = new FileReader(); void ROMImage::unload() { if(file_loaded == false)return; -FileWriter *wf = new FileWriter(); - wf->open(sram_fn); - mem_bus->rom->save_sram(static_cast(wf)); - wf->close(); - delete(wf); +FileWriter *wf; +CartInfo ci; + mem_bus->get_cartinfo(&ci); + if(ci.sram_size != 0) { + wf = new FileWriter(); + wf->open(sram_fn); + mem_bus->save_sram(static_cast(wf)); + wf->close(); + delete(wf); + } file_loaded = false; bsnes->debugger_deactivate(); - mem_bus->rom->unload(); + mem_bus->unload_cart(); } void ROMImage::select(char *fn) { +int i; if(file_loaded == true)return; /* Remove quotes */ @@ -67,7 +77,7 @@ void ROMImage::select(char *fn) { strcpy(rom_fn, fn); } - for(int i=strlen(rom_fn)-1;i>=0;i--) { + for(i=strlen(rom_fn)-1;i>=0;i--) { if(rom_fn[i] == '.')break; } diff --git a/src/win/snes_controller.bmp b/src/win/snes_controller.bmp new file mode 100644 index 00000000..90b6265e Binary files /dev/null and b/src/win/snes_controller.bmp differ diff --git a/src/win/ui.cpp b/src/win/ui.cpp index b1fa2ff6..5969c8d2 100644 --- a/src/win/ui.cpp +++ b/src/win/ui.cpp @@ -1,11 +1,15 @@ HFONT hFont, hMonofont; +HBRUSH hbr_backbrush; #include "dd_renderer.cpp" +#include "uictl_editex.cpp" #include "ui_window.cpp" #include "ui_main.cpp" #include "ui_console.cpp" #include "ui_bp.cpp" #include "ui_memory.cpp" +#include "ui_inputconfig.cpp" +#include "ui_about.cpp" void CreateFonts() { HDC hdc; @@ -22,18 +26,24 @@ long height; } void CreateWindows() { - CreateWindowMain(); - CreateWindowConsole(); - CreateWindowBreakpoint(); - CreateWindowMemory(); + LoadLibrary("riched20.dll"); + hbr_backbrush = CreateSolidBrush(RGB(32, 32, 32)); + w_main->create(); + w_console->create(); + w_bp->create(); + w_memory->create(); + w_inputconfig->create(); + w_about->create(); } void init_ui0() { - dd_renderer = new DDRenderer(); - w_main = new MainWindow(); - w_console = new Console(); - w_bp = new BreakpointEditor(); - w_memory = new MemoryEditor(); + dd_renderer = new DDRenderer(); + w_main = new MainWindow(); + w_console = new Console(); + w_bp = new BreakpointEditor(); + w_memory = new MemoryEditor(); + w_inputconfig = new InputConfig(); + w_about = new AboutWindow(); } void init_ui1() { diff --git a/src/win/ui.h b/src/win/ui.h index 41d27037..eda78049 100644 --- a/src/win/ui.h +++ b/src/win/ui.h @@ -1,3 +1,5 @@ +#define KeyDown(key) ((GetAsyncKeyState(key) & 0x8000)?1:0) + enum { VIDEOMODE_256x224w = 0, VIDEOMODE_512x448w, @@ -31,7 +33,10 @@ enum { MENU_SETTINGS_VBLANK, MENU_SETTINGS_COLORCURVE, MENU_SETTINGS_SHOWFPS, - MENU_SETTINGS_DEBUGGER + MENU_SETTINGS_APUENABLED, + MENU_SETTINGS_INPUTCFG_JOYPAD1, + MENU_SETTINGS_DEBUGGER, + MENU_MISC_ABOUT }; enum { @@ -118,14 +123,13 @@ enum { MEMORYEDITOR_FSOURCE, MEMORYEDITOR_FEXPORT, - MEMORYEDITOR_UP40, - MEMORYEDITOR_DOWN40, - MEMORYEDITOR_UP400, - MEMORYEDITOR_DOWN400, - MEMORYEDITOR_UP4000, - MEMORYEDITOR_DOWN4000, - MEMORYEDITOR_UP40000, - MEMORYEDITOR_DOWN40000 + MEMORYEDITOR_UPDATE, + MEMORYEDITOR_AUTOUPDATE +}; + +enum { + ABOUT_STATIC = 100, + ABOUT_OK }; class Window { @@ -156,6 +160,7 @@ class MainWindow : public Window { public: uint8 frameskip; int width, height; + void create(); void to_fullscreen(); void to_windowed(); void set_frameskip(uint8 fs); @@ -163,23 +168,22 @@ int width, height; void set_video_mode(uint8 mode); void menu_load(); void menu_unload(); +}*w_main = 0; - MainWindow(); -}; - -MainWindow *w_main; - -#define CONSOLE_LINES 256 +#define CONSOLE_LINES 240 class Console : public Window { private: bool _is_running; //used to swap "Run"/"Stop" text on console window + public: bool ctl_disabled[100]; +bool outputcpu, outputapu, outputdbg; enum { DEBUG_MESSAGE = 0, CPU_MESSAGE, APU_MESSAGE }; enum { REGTYPE_CPU = 0, REGTYPE_APU }; -char output_line[CONSOLE_LINES][512]; -char output_data[CONSOLE_LINES * 512]; +char output_line[CONSOLE_LINES][128]; +uint8 output_linecol[CONSOLE_LINES]; +char output_data[CONSOLE_LINES * 128]; FILE *log_fp; bool tracing_enabled; @@ -189,8 +193,9 @@ struct { bool l, r, select, start; }joypad_lock; + void create(); + long wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam); void clear(); - void create_controls(); void update_status(); void set_reg_list_type(uint8 list_type); bool can_write(uint32 message_type); @@ -198,15 +203,13 @@ struct { void is_running(bool n); //API access to _is_running Console(); -}; - -Console *w_console; +}*w_console = 0; class BreakpointEditor : public Window { public: bool ctl_disabled[100]; -enum { DRAM = 0, VRAM = 1, OAM = 2, CGRAM = 3 }; +enum { DRAM = 0, SPCRAM = 1, VRAM = 2, OAM = 3, CGRAM = 4 }; enum { FLAG_NONE = 0, FLAG_R = 1, FLAG_W = 2, FLAG_X = 4, FLAG_V = 8 }; struct { uint32 addr; @@ -216,29 +219,54 @@ struct { uint32 hit_count; bool set; }bp[16]; -bool bp_enabled, bp_hit; +bool bp_enabled, bp_hit; +//indicates which breakpoint was hit, used to tell whether to disassemble +//a cpu or apu opcode once the emulation status is set to stop. +uint8 bp_hit_num; void clear(); - void create_controls(); + void create(); bool hit(); void test(uint32 message, uint32 addr, uint32 value); void refresh(); BreakpointEditor(); -}; - -BreakpointEditor *w_bp; +}*w_bp = 0; class MemoryEditor : public Window { public: bool ctl_disabled[100]; -enum { MODE_DRAM = 0, MODE_ROM, MODE_SRAM, MODE_VRAM, MODE_OAM, MODE_CGRAM }; +enum { MODE_DRAM = 0, MODE_ROM, MODE_SRAM, MODE_SPCRAM, MODE_VRAM, MODE_OAM, MODE_CGRAM }; uint32 edit_mode, edit_addr, edit_mask; +bool auto_update; //update memory window whenever visible value is written to when true void clear(); - void create_controls(); + void create(); uint8 read_byte(uint32 addr); - void refresh(uint32 type = 0, uint32 addr = 0); + void write_byte(uint32 addr, uint8 value); + void refresh(uint32 type = null, uint32 addr = 0); void export(uint32 type); -}; +}*w_memory = 0; -MemoryEditor *w_memory; +class InputConfig : public Window { +public: +enum { + JOYPAD1 = 0 +}; +enum { + ID_COMMAND = 100 +}; +int config_type, config_pos; +bool polling; + long wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam); + void update_polling(int key); + void update_command(); + void set_text(char *str); + void begin_config(int type); + void create(); +}*w_inputconfig = 0; + +class AboutWindow : public Window { +public: + long wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam); + void create(); +}*w_about = 0; diff --git a/src/win/ui_about.cpp b/src/win/ui_about.cpp new file mode 100644 index 00000000..7d8b9f74 --- /dev/null +++ b/src/win/ui_about.cpp @@ -0,0 +1,53 @@ +long AboutWindow::wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { + switch(msg) { + case WM_COMMAND: + switch(LOWORD(wparam)) { + case ABOUT_OK: + w_about->hide(); + break; + } + break; + case WM_CLOSE: + w_about->hide(); + return TRUE; + } + return DefWindowProc(hwnd, msg, wparam, lparam); +} + +long __stdcall wndproc_aboutwindow(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { + return w_about->wndproc(hwnd, msg, wparam, lparam); +} + +void AboutWindow::create() { +WNDCLASS wc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hbrBackground = (HBRUSH)COLOR_WINDOW; + wc.hCursor = LoadCursor(0, IDC_ARROW); + wc.hIcon = LoadIcon(0, IDI_APPLICATION); + wc.hInstance = GetModuleHandle(0); + wc.lpfnWndProc = wndproc_aboutwindow; + wc.lpszClassName = "bsnes_aboutwindow"; + wc.lpszMenuName = 0; + wc.style = CS_HREDRAW | CS_VREDRAW; + RegisterClass(&wc); + + hwnd = CreateWindow("bsnes_aboutwindow", "About bsnes...", + WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, + 0, 0, 275, 55, 0, 0, wc.hInstance, 0); + resize(275, 55); + center(); + + CreateWindowEx(WS_EX_STATICEDGE, "STATIC", "", WS_CHILD | WS_VISIBLE, + 5, 5, 200, 45, hwnd, (HMENU)ABOUT_STATIC, wc.hInstance, 0); + SetDlgItemText(hwnd, ABOUT_STATIC, "" + " bsnes -- Version " BSNES_VERSION "\r\n" + " Written by: byuu\r\n" + " http://byuu.org/" + ); + CreateWindow("BUTTON", "OK", WS_CHILD | WS_VISIBLE, + 210, 5, 60, 20, hwnd, (HMENU)ABOUT_OK, wc.hInstance, 0); + + SendDlgItemMessage(hwnd, ABOUT_STATIC, WM_SETFONT, (WPARAM)hFont, TRUE); + SendDlgItemMessage(hwnd, ABOUT_OK, WM_SETFONT, (WPARAM)hFont, TRUE); +} diff --git a/src/win/ui_bp.cpp b/src/win/ui_bp.cpp index 0a367035..af88494e 100644 --- a/src/win/ui_bp.cpp +++ b/src/win/ui_bp.cpp @@ -1,4 +1,5 @@ bool BreakpointEditor::hit() { +//breakpoints are disabled when BP window is closed if(visible == false)return false; if(bp_hit == true) { @@ -17,7 +18,7 @@ int i; if(bp[i].set == false)continue; switch(message) { - case SNES::CPU_EXEC_OPCODE: + case SNES::CPU_EXEC_OPCODE_END: if(!(bp[i].flags & FLAG_X))continue; if(bp[i].source != DRAM)continue; if(bp[i].addr != addr)continue; @@ -26,13 +27,24 @@ int i; bp_hit = true; w_bp->refresh(); break; + case SNES::APU_EXEC_OPCODE_END: + 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); + bp[i].hit_count++; + bp_hit = true; + w_bp->refresh(); + break; case SNES::MEM_READ: + case SNES::SPCRAM_READ: case SNES::VRAM_READ: case SNES::OAM_READ: case SNES::CGRAM_READ: if(!(bp[i].flags & FLAG_R))continue; if(bp[i].addr != addr)continue; if(message == SNES::MEM_READ && bp[i].source == DRAM); + else if(message == SNES::SPCRAM_READ && bp[i].source == SPCRAM); else if(message == SNES::VRAM_READ && bp[i].source == VRAM); else if(message == SNES::OAM_READ && bp[i].source == OAM); else if(message == SNES::CGRAM_READ && bp[i].source == CGRAM); @@ -46,12 +58,14 @@ int i; w_bp->refresh(); break; case SNES::MEM_WRITE: + case SNES::SPCRAM_WRITE: case SNES::VRAM_WRITE: case SNES::OAM_WRITE: case SNES::CGRAM_WRITE: if(!(bp[i].flags & FLAG_W))continue; if(bp[i].addr != addr)continue; if(message == SNES::MEM_WRITE && bp[i].source == DRAM); + else if(message == SNES::SPCRAM_WRITE && bp[i].source == SPCRAM); else if(message == SNES::VRAM_WRITE && bp[i].source == VRAM); else if(message == SNES::OAM_WRITE && bp[i].source == OAM); else if(message == SNES::CGRAM_WRITE && bp[i].source == CGRAM); @@ -65,13 +79,24 @@ int i; w_bp->refresh(); break; } + if(bp_hit == true) { + bp_hit_num = i; + } } } long __stdcall wndproc_bp(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { char t[256]; uint32 n, addr; +HDC hdc; switch(msg) { + case WM_CTLCOLORSTATIC: + if((HWND)lparam != GetDlgItem(hwnd, BREAKPOINT_LIST))break; + hdc = (HDC)wparam; + SetTextColor(hdc, RGB(255, 255, 255)); + SetBkColor(hdc, RGB(0, 0, 0)); + SetBkMode(hdc, TRANSPARENT); + return (long)hbr_backbrush; case WM_COMMAND: switch(LOWORD(wparam)) { case BREAKPOINT_SET: @@ -136,32 +161,6 @@ uint32 n, addr; return DefWindowProc(hwnd, msg, wparam, lparam); } -void CreateWindowBreakpoint() { -WNDCLASS wc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hbrBackground = (HBRUSH)COLOR_WINDOW; - wc.hCursor = LoadCursor(0, IDC_ARROW); - wc.hIcon = LoadIcon(0, IDI_APPLICATION); - wc.hInstance = GetModuleHandle(0); - wc.lpfnWndProc = wndproc_bp; - wc.lpszClassName = "bsnes_breakpoint"; - wc.lpszMenuName = 0; - wc.style = CS_HREDRAW | CS_VREDRAW; - RegisterClass(&wc); - - w_bp->hwnd = CreateWindow("bsnes_breakpoint", "bsnes breakpoint editor", - WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, - 0, 0, 395, 245, - 0, 0, GetModuleHandle(0), 0); - - w_bp->resize(395, 245); - w_bp->to_left(); - w_bp->to_bottom(w_console->hwnd); - - w_bp->create_controls(); -} - void BreakpointEditor::clear() { SetDlgItemText(hwnd, BREAKPOINT_LIST, ""); } @@ -175,11 +174,12 @@ char s[256 * 16], t[256], source[256], v[16]; for(int i=0;i<16;i++) { if(bp[i].set == true) { switch(bp[i].source) { - case DRAM: strcpy(source, "DRAM ");break; - case VRAM: strcpy(source, "VRAM ");break; - case OAM: strcpy(source, "OAM ");break; - case CGRAM:strcpy(source, "CGRAM ");break; - default: strcpy(source, "??????");break; + case DRAM: strcpy(source, "DRAM ");break; + case SPCRAM:strcpy(source, "SPCRAM");break; + case VRAM: strcpy(source, "VRAM ");break; + case OAM: strcpy(source, "OAM ");break; + case CGRAM: strcpy(source, "CGRAM ");break; + default: strcpy(source, "??????");break; } if(bp[i].flags & FLAG_V)sprintf(v, "%0.2x", bp[i].value); else strcpy(v, "--"); @@ -197,7 +197,29 @@ char s[256 * 16], t[256], source[256], v[16]; SetDlgItemText(hwnd, BREAKPOINT_LIST, s); } -void BreakpointEditor::create_controls() { +void BreakpointEditor::create() { +WNDCLASS wc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hbrBackground = (HBRUSH)COLOR_WINDOW; + wc.hCursor = LoadCursor(0, IDC_ARROW); + wc.hIcon = LoadIcon(0, IDI_APPLICATION); + wc.hInstance = GetModuleHandle(0); + wc.lpfnWndProc = wndproc_bp; + wc.lpszClassName = "bsnes_breakpoint"; + wc.lpszMenuName = 0; + wc.style = CS_HREDRAW | CS_VREDRAW; + RegisterClass(&wc); + + hwnd = CreateWindow("bsnes_breakpoint", "bsnes Breakpoint Editor", + WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, + 0, 0, 395, 245, + 0, 0, GetModuleHandle(0), 0); + + resize(395, 245); + to_left(); + to_bottom(w_console->hwnd); + CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_READONLY, 5, 5, 260, 235, hwnd, (HMENU)BREAKPOINT_LIST, GetModuleHandle(0), 0); @@ -243,6 +265,7 @@ void BreakpointEditor::create_controls() { CreateWindow("COMBOBOX", "", WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST | CBS_HASSTRINGS, 305, 75, 85, 200, hwnd, (HMENU)BREAKPOINT_SOURCE, GetModuleHandle(0), 0); SendDlgItemMessage(hwnd, BREAKPOINT_SOURCE, CB_ADDSTRING, 0, (LPARAM)"DRAM"); + SendDlgItemMessage(hwnd, BREAKPOINT_SOURCE, CB_ADDSTRING, 0, (LPARAM)"SPCRAM"); SendDlgItemMessage(hwnd, BREAKPOINT_SOURCE, CB_ADDSTRING, 0, (LPARAM)"VRAM"); SendDlgItemMessage(hwnd, BREAKPOINT_SOURCE, CB_ADDSTRING, 0, (LPARAM)"OAM"); SendDlgItemMessage(hwnd, BREAKPOINT_SOURCE, CB_ADDSTRING, 0, (LPARAM)"CGRAM"); @@ -254,7 +277,7 @@ void BreakpointEditor::create_controls() { 330, 100, 60, 20, hwnd, (HMENU)BREAKPOINT_CLEAR, GetModuleHandle(0), 0); CreateWindow("BUTTON", "Enable Breakpoints", WS_CHILD | WS_VISIBLE | BS_CHECKBOX, - 270, 160, 120, 15, hwnd, (HMENU)BREAKPOINT_ENABLE, GetModuleHandle(0), 0); + 270, 163, 120, 15, hwnd, (HMENU)BREAKPOINT_ENABLE, GetModuleHandle(0), 0); SendDlgItemMessage(hwnd, BREAKPOINT_ENABLE, BM_SETCHECK, (WPARAM)true, 0); CreateWindow("BUTTON", "Clear All Breakpoints", WS_CHILD | WS_VISIBLE, 270, 180, 120, 20, hwnd, (HMENU)BREAKPOINT_CLEARALL, GetModuleHandle(0), 0); diff --git a/src/win/ui_console.cpp b/src/win/ui_console.cpp index b5afdc19..eb2a8f68 100644 --- a/src/win/ui_console.cpp +++ b/src/win/ui_console.cpp @@ -7,11 +7,19 @@ SendDlgItemMessage(hwnd, CONSOLE_CFGLOCK##l##, BM_SETCHECK, (WPARAM)true, 0); \ } -long __stdcall wndproc_console(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { +long Console::wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { char t[256]; int i, pos; uint32 addr, len, value; +HDC hdc; switch(msg) { + case WM_CTLCOLORSTATIC: + if((HWND)lparam != GetDlgItem(hwnd, CONSOLE_STATUS))break; + hdc = (HDC)wparam; + SetTextColor(hdc, RGB(255, 255, 255)); + SetBkColor(hdc, RGB(0, 0, 0)); + SetBkMode(hdc, TRANSPARENT); + return (long)hbr_backbrush; case WM_COMMAND: switch(LOWORD(wparam)) { case CONSOLE_CPUSTEP: @@ -46,17 +54,23 @@ uint32 addr, len, value; for(i=0;iwrite(bSNES::DRAM, (addr & 0xff0000) | ((addr + i) & 0xffff), 0xea); } - cpu->regs.pc.w += len; +// cpu->regs.pc.w += len; bsnes->disassemble_cpu_op(); } break; + case CONSOLE_APUSTEP: + if(bsnes->get_status() == bSNES::STOP) { + bsnes->set_status(bSNES::RUNTOAPUSTEP); + } + break; case CONSOLE_SYSRUN: if(bsnes->get_status() == bSNES::STOP) { - w_console->is_running(true); + is_running(true); bsnes->set_status(bSNES::RUNTOSIGNAL); } else { - w_console->is_running(false); + is_running(false); bsnes->set_status(bSNES::STOP); + bsnes->disassemble_apu_op(); bsnes->disassemble_cpu_op(); } break; @@ -65,16 +79,31 @@ uint32 addr, len, value; bsnes->set_status(bSNES::RUNTOFRAME); } break; + case CONSOLE_CFGOUTPUTCPU: + outputcpu ^= 1; + SendDlgItemMessage(hwnd, CONSOLE_CFGOUTPUTCPU, BM_SETCHECK, (WPARAM)outputcpu, 0); + break; + case CONSOLE_CFGOUTPUTAPU: + outputapu ^= 1; + SendDlgItemMessage(hwnd, CONSOLE_CFGOUTPUTAPU, BM_SETCHECK, (WPARAM)outputapu, 0); + break; + case CONSOLE_CFGOUTPUTDBG: + outputdbg ^= 1; + SendDlgItemMessage(hwnd, CONSOLE_CFGOUTPUTDBG, BM_SETCHECK, (WPARAM)outputdbg, 0); + break; case CONSOLE_CFGTRACE: - if(w_console->tracing_enabled == false) { - w_console->tracing_enabled = true; - w_console->log_fp = fopen("trace.log", "wb"); + if(tracing_enabled == false) { + write("* Tracing enabled"); + tracing_enabled = true; + log_fp = fopen("trace.log", "wb"); + bsnes->disassemble_apu_op(); bsnes->disassemble_cpu_op(); SendDlgItemMessage(hwnd, CONSOLE_CFGTRACE, BM_SETCHECK, (WPARAM)true, 0); } else { - w_console->tracing_enabled = false; - fclose(w_console->log_fp); + tracing_enabled = false; + fclose(log_fp); SendDlgItemMessage(hwnd, CONSOLE_CFGTRACE, BM_SETCHECK, (WPARAM)false, 0); + write("* Tracing disabled"); } break; case CONSOLE_CFGREGSET: @@ -94,9 +123,8 @@ uint32 addr, len, value; case 7:cpu->regs.e = value;break; case 8:cpu->regs.pc.d = value;break; } - /* these bits can *never* be clear in emulation mode */ + //these bits can never be clear in emulation mode if(cpu->regs.e)cpu->regs.p |= 0x30; - /* disassemble current opcode again to reflect new register values */ bsnes->disassemble_cpu_op(); } else { //Set APU register } @@ -115,12 +143,9 @@ uint32 addr, len, value; case CONSOLE_CFGLOCKSTART: __console_joypad_lock(start, START); break; } break; -/* Usually, bsnes will catch the close request here, and replace it - with a hide command instead. */ case WM_CLOSE: bsnes->debugger_disable(); return 0; -/* Just in case something sends a DestroyWindow command to bsnes... */ case WM_DESTROY: alert("Error: bsnes debugging console window has been destroyed!\n" "The emulator will still run, but it must be restarted before\n" @@ -132,15 +157,26 @@ uint32 addr, len, value; return DefWindowProc(hwnd, msg, wparam, lparam); } +long __stdcall wndproc_console(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { + return w_console->wndproc(hwnd, msg, wparam, lparam); +} + void Console::clear() { +static uint8 linecol[4] = { 0, 0, 0 }; for(int i=0;iget_status()) { @@ -154,30 +190,58 @@ bool Console::can_write(uint32 message_type) { } void Console::write(char *s, uint32 message_type) { -char t[512]; +char t[128]; +bool blank_line; if(tracing_enabled == true) { - fprintf(log_fp, "%s\r\n", s); + if (message_type == Console::CPU_MESSAGE && outputcpu == false); + else if(message_type == Console::APU_MESSAGE && outputapu == false); + else if(message_type == Console::DEBUG_MESSAGE && outputdbg == false); + else fprintf(log_fp, "%s\r\n", s); } if(!can_write(message_type)) { return; } - for(int i=0;i= 80) { + memcpy(t, s, 80); + } else { + blank_line = (sl == 0); + strcpy(t, s); + memset(t + sl, 0x20, 80 - sl); + } + t[80] = 0; +//only allow ascii characters. other characters will force the +//font to change to one that supports non-ascii characters, +//which will break the line highlighting and alignment of text + for(int i=0;i<80;i++) { + if(t[i] & 0x80)t[i] = '?'; + } + + for(i=0;ihwnd = CreateWindow("bsnes_console", "bsnes debug console", - WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, - 0, 0, 850, 355, - 0, 0, GetModuleHandle(0), 0); - - w_console->resize(850, 355); - w_console->to_left(); - w_console->to_bottom(); - - w_console->create_controls(); -} - void Console::update_status() { -char s[4096], t[256]; +char s[4096], t[512]; +static uint8 linecol[4] = { 1, 2, 3 }; if(rom_image->loaded() == false)return; strcpy(s, ""); sprintf(t, "V:%3d H:%3d HC:%4d I:%d IF:%d O:%d", - clock->vcounter(), clock->hcounter(), clock->hcycles(), - clock->interlace(), clock->interlace_field(), clock->overscan()); + cpu->vcounter(), cpu->hcounter(), cpu->hcycles(), + cpu->interlace(), cpu->interlace_field(), cpu->overscan()); strcat(s, t); + if(cfg.apu.enabled) { + sprintf(t, " -- CPU[$%0.2x,$%0.2x,$%0.2x,$%0.2x]<>APU[$%0.2x,$%0.2x,$%0.2x,$%0.2x]", + cpu->port_read(0), cpu->port_read(1), cpu->port_read(2), cpu->port_read(3), + apu->port_read(0), apu->port_read(1), apu->port_read(2), apu->port_read(3) + ); + strcat(s, t); + } SetDlgItemText(hwnd, CONSOLE_STATUS, s); } @@ -248,84 +294,114 @@ void Console::set_reg_list_type(uint8 list_type) { } } -void Console::create_controls() { +void Console::create() { +WNDCLASS wc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hbrBackground = (HBRUSH)COLOR_WINDOW; + wc.hCursor = LoadCursor(0, IDC_ARROW); + wc.hIcon = LoadIcon(0, IDI_APPLICATION); + wc.hInstance = GetModuleHandle(0); + wc.lpfnWndProc = wndproc_console; + wc.lpszClassName = "bsnes_console"; + wc.lpszMenuName = 0; + wc.style = CS_HREDRAW | CS_VREDRAW; + RegisterClass(&wc); + + hwnd = CreateWindow("bsnes_console", "bsnes Debug Console", + WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, + 0, 0, 847, 354, + 0, 0, GetModuleHandle(0), 0); + + resize(847, 354); + to_left(); + to_bottom(); + int x, y; - CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", - WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_MULTILINE | ES_READONLY, - 5, 5, 585, 290, + CreateWindowEx(WS_EX_CLIENTEDGE, RICHEDIT_CLASS, "", WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_MULTILINE | ES_READONLY, + 5, 5, 582, 285, hwnd, (HMENU)CONSOLE_OUTPUT, GetModuleHandle(0), 0); - CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", - WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_READONLY, 5, 300, 585, 50, + editex_setbackcolor(GetDlgItem(hwnd, CONSOLE_OUTPUT), RGB(32, 32, 32)); + CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_READONLY, + 5, 290, 582, 59, hwnd, (HMENU)CONSOLE_STATUS, GetModuleHandle(0), 0); - x = 595; + x = 592; + y = 5; CreateWindow("BUTTON", "cpu (wdc 65c816)", WS_CHILD | WS_VISIBLE | BS_GROUPBOX, - x, 5, 250, 60, hwnd, (HMENU)CONSOLE_CPUGROUP, GetModuleHandle(0), 0); - CreateWindow("BUTTON", "Step", WS_CHILD | WS_VISIBLE, x + 5, 20, 80, 20, hwnd, (HMENU)CONSOLE_CPUSTEP, GetModuleHandle(0), 0); - CreateWindow("BUTTON", "Proceed", WS_CHILD | WS_VISIBLE, x + 85, 20, 80, 20, hwnd, (HMENU)CONSOLE_CPUPROCEED, GetModuleHandle(0), 0); - CreateWindow("BUTTON", "Skip", WS_CHILD | WS_VISIBLE, x + 165, 20, 80, 20, hwnd, (HMENU)CONSOLE_CPUSKIP, GetModuleHandle(0), 0); + x, y, 250, 60, hwnd, (HMENU)CONSOLE_CPUGROUP, GetModuleHandle(0), 0); + CreateWindow("BUTTON", "Step", WS_CHILD | WS_VISIBLE, x + 5, y + 15, 80, 20, hwnd, (HMENU)CONSOLE_CPUSTEP, GetModuleHandle(0), 0); + CreateWindow("BUTTON", "Proceed", WS_CHILD | WS_VISIBLE, x + 85, y + 15, 80, 20, hwnd, (HMENU)CONSOLE_CPUPROCEED, GetModuleHandle(0), 0); + CreateWindow("BUTTON", "Skip", WS_CHILD | WS_VISIBLE, x + 165, y + 15, 80, 20, hwnd, (HMENU)CONSOLE_CPUSKIP, GetModuleHandle(0), 0); CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "0", WS_CHILD | WS_VISIBLE, - x + 5, 40, 80, 20, hwnd, (HMENU)CONSOLE_CPUTRACENUM, GetModuleHandle(0), 0); - CreateWindow("BUTTON", "Trace", WS_CHILD | WS_VISIBLE, x + 85, 40, 80, 20, hwnd, (HMENU)CONSOLE_CPUTRACE, GetModuleHandle(0), 0); - CreateWindow("BUTTON", "Disable", WS_CHILD | WS_VISIBLE, x + 165, 40, 80, 20, hwnd, (HMENU)CONSOLE_CPUDISABLE, GetModuleHandle(0), 0); + x + 5, y + 35, 80, 20, hwnd, (HMENU)CONSOLE_CPUTRACENUM, GetModuleHandle(0), 0); + CreateWindow("BUTTON", "Trace", WS_CHILD | WS_VISIBLE, x + 85, y + 35, 80, 20, hwnd, (HMENU)CONSOLE_CPUTRACE, GetModuleHandle(0), 0); + CreateWindow("BUTTON", "Disable", WS_CHILD | WS_VISIBLE, x + 165, y + 35, 80, 20, hwnd, (HMENU)CONSOLE_CPUDISABLE, GetModuleHandle(0), 0); - CreateWindow("BUTTON", "apu (sony spc700)", WS_CHILD | WS_VISIBLE | WS_DISABLED | BS_GROUPBOX, - x, 70, 250, 60, hwnd, (HMENU)CONSOLE_APUGROUP, GetModuleHandle(0), 0); - CreateWindow("BUTTON", "Step", WS_CHILD | WS_VISIBLE | WS_DISABLED, x + 5, 85, 80, 20, hwnd, (HMENU)CONSOLE_APUSTEP, GetModuleHandle(0), 0); - CreateWindow("BUTTON", "Proceed", WS_CHILD | WS_VISIBLE | WS_DISABLED, x + 85, 85, 80, 20, hwnd, (HMENU)CONSOLE_APUPROCEED, GetModuleHandle(0), 0); - CreateWindow("BUTTON", "Skip", WS_CHILD | WS_VISIBLE | WS_DISABLED, x + 165, 85, 80, 20, hwnd, (HMENU)CONSOLE_APUSKIP, GetModuleHandle(0), 0); + y += 66; + CreateWindow("BUTTON", "apu (sony spc700)", WS_CHILD | WS_VISIBLE | BS_GROUPBOX, + x, y, 250, 60, hwnd, (HMENU)CONSOLE_APUGROUP, GetModuleHandle(0), 0); + CreateWindow("BUTTON", "Step", WS_CHILD | WS_VISIBLE, x + 5, y + 15, 80, 20, hwnd, (HMENU)CONSOLE_APUSTEP, GetModuleHandle(0), 0); + CreateWindow("BUTTON", "Proceed", WS_CHILD | WS_VISIBLE | WS_DISABLED, x + 85, y + 15, 80, 20, hwnd, (HMENU)CONSOLE_APUPROCEED, GetModuleHandle(0), 0); + CreateWindow("BUTTON", "Skip", WS_CHILD | WS_VISIBLE | WS_DISABLED, x + 165, y + 15, 80, 20, hwnd, (HMENU)CONSOLE_APUSKIP, GetModuleHandle(0), 0); CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "0", WS_CHILD | WS_VISIBLE | WS_DISABLED, - x + 5, 105, 80, 20, hwnd, (HMENU)CONSOLE_APUTRACENUM, GetModuleHandle(0), 0); - CreateWindow("BUTTON", "Trace", WS_CHILD | WS_VISIBLE | WS_DISABLED, x + 85, 105, 80, 20, hwnd, (HMENU)CONSOLE_APUTRACE, GetModuleHandle(0), 0); - CreateWindow("BUTTON", "Disable", WS_CHILD | WS_VISIBLE | WS_DISABLED, x + 165, 105, 80, 20, hwnd, (HMENU)CONSOLE_APUDISABLE, GetModuleHandle(0), 0); + x + 5, y + 35, 80, 20, hwnd, (HMENU)CONSOLE_APUTRACENUM, GetModuleHandle(0), 0); + CreateWindow("BUTTON", "Trace", WS_CHILD | WS_VISIBLE | WS_DISABLED, x + 85, y + 35, 80, 20, hwnd, (HMENU)CONSOLE_APUTRACE, GetModuleHandle(0), 0); + CreateWindow("BUTTON", "Disable", WS_CHILD | WS_VISIBLE | WS_DISABLED, x + 165, y + 35, 80, 20, hwnd, (HMENU)CONSOLE_APUDISABLE, GetModuleHandle(0), 0); - CreateWindow("BUTTON", "System", WS_CHILD | WS_VISIBLE | BS_GROUPBOX, x, 135, 250, 40, hwnd, (HMENU)CONSOLE_SYSGROUP, GetModuleHandle(0), 0); - CreateWindow("BUTTON", "Run", WS_CHILD | WS_VISIBLE, x + 5, 150, 80, 20, hwnd, (HMENU)CONSOLE_SYSRUN, GetModuleHandle(0), 0); - CreateWindow("BUTTON", "To Frame", WS_CHILD | WS_VISIBLE, x + 85, 150, 80, 20, hwnd, (HMENU)CONSOLE_SYSRUNTOFRAME, GetModuleHandle(0), 0); - CreateWindow("BUTTON", "To NMI", WS_CHILD | WS_VISIBLE | WS_DISABLED, x + 165, 150, 80, 20, hwnd, (HMENU)CONSOLE_SYSRUNTONMI, GetModuleHandle(0), 0); + y += 66; + CreateWindow("BUTTON", "System", WS_CHILD | WS_VISIBLE | BS_GROUPBOX, x, y, 250, 40, hwnd, (HMENU)CONSOLE_SYSGROUP, GetModuleHandle(0), 0); + CreateWindow("BUTTON", "Run", WS_CHILD | WS_VISIBLE, x + 5, y + 15, 80, 20, hwnd, (HMENU)CONSOLE_SYSRUN, GetModuleHandle(0), 0); + CreateWindow("BUTTON", "To Frame", WS_CHILD | WS_VISIBLE, x + 85, y + 15, 80, 20, hwnd, (HMENU)CONSOLE_SYSRUNTOFRAME, GetModuleHandle(0), 0); + CreateWindow("BUTTON", "To NMI", WS_CHILD | WS_VISIBLE | WS_DISABLED, x + 165, y + 15, 80, 20, hwnd, (HMENU)CONSOLE_SYSRUNTONMI, GetModuleHandle(0), 0); - CreateWindow("BUTTON", "Settings", WS_CHILD | WS_VISIBLE | BS_GROUPBOX, x, 180, 250, 170, hwnd, (HMENU)CONSOLE_CFGGROUP, GetModuleHandle(0), 0); - CreateWindow("BUTTON", "Output CPU instructions to console", WS_CHILD | WS_VISIBLE | WS_DISABLED | BS_CHECKBOX, - x + 5, 195, 240, 15, hwnd, (HMENU)CONSOLE_CFGOUTPUTCPU, GetModuleHandle(0), 0); - CreateWindow("BUTTON", "Output APU instructions to console", WS_CHILD | WS_VISIBLE | WS_DISABLED | BS_CHECKBOX, - x + 5, 210, 240, 15, hwnd, (HMENU)CONSOLE_CFGOUTPUTAPU, GetModuleHandle(0), 0); - CreateWindow("BUTTON", "Output debug messages to console", WS_CHILD | WS_VISIBLE | WS_DISABLED | BS_CHECKBOX, - x + 5, 225, 240, 15, hwnd, (HMENU)CONSOLE_CFGOUTPUTDBG, GetModuleHandle(0), 0); + y += 46; + CreateWindow("BUTTON", "Settings", WS_CHILD | WS_VISIBLE | BS_GROUPBOX, x, y, 250, 166, hwnd, (HMENU)CONSOLE_CFGGROUP, GetModuleHandle(0), 0); + CreateWindow("BUTTON", "Output CPU instructions to console", WS_CHILD | WS_VISIBLE | BS_CHECKBOX, + x + 5, y + 15, 240, 15, hwnd, (HMENU)CONSOLE_CFGOUTPUTCPU, GetModuleHandle(0), 0); + CreateWindow("BUTTON", "Output APU instructions to console", WS_CHILD | WS_VISIBLE | BS_CHECKBOX, + x + 5, y + 30, 240, 15, hwnd, (HMENU)CONSOLE_CFGOUTPUTAPU, GetModuleHandle(0), 0); + CreateWindow("BUTTON", "Output debug messages to console", WS_CHILD | WS_VISIBLE | BS_CHECKBOX, + x + 5, y + 45, 240, 15, hwnd, (HMENU)CONSOLE_CFGOUTPUTDBG, GetModuleHandle(0), 0); CreateWindow("BUTTON", "Trace console output to file", WS_CHILD | WS_VISIBLE | BS_CHECKBOX, - x + 5, 240, 240, 15, hwnd, (HMENU)CONSOLE_CFGTRACE, GetModuleHandle(0), 0); + x + 5, y + 60, 240, 15, hwnd, (HMENU)CONSOLE_CFGTRACE, GetModuleHandle(0), 0); + + y += 77; CreateWindow("COMBOBOX", "", WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST | CBS_HASSTRINGS, - x + 5, 260, 60, 200, hwnd, (HMENU)CONSOLE_CFGREGTYPE, GetModuleHandle(0), 0); + x + 5, y, 60, 200, hwnd, (HMENU)CONSOLE_CFGREGTYPE, GetModuleHandle(0), 0); CreateWindow("COMBOBOX", "", WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST | CBS_HASSTRINGS, - x + 65, 260, 60, 200, hwnd, (HMENU)CONSOLE_CFGREGNUM, GetModuleHandle(0), 0); + x + 65, y, 60, 200, hwnd, (HMENU)CONSOLE_CFGREGNUM, GetModuleHandle(0), 0); CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "0", WS_CHILD | WS_VISIBLE, - x + 125, 260, 60, 21, hwnd, (HMENU)CONSOLE_CFGREGVAL, GetModuleHandle(0), 0); + x + 125, y, 60, 21, hwnd, (HMENU)CONSOLE_CFGREGVAL, GetModuleHandle(0), 0); CreateWindow("BUTTON", "Set Reg", WS_CHILD | WS_VISIBLE, - x + 185, 260, 60, 21, hwnd, (HMENU)CONSOLE_CFGREGSET, GetModuleHandle(0), 0); - CreateWindow("STATIC", "Lock Joypad Button(s) Down:", WS_CHILD | WS_VISIBLE, x + 5, 285, 240, 15, hwnd, (HMENU)CONSOLE_CFGLOCK, GetModuleHandle(0), 0); + x + 185, y, 60, 21, hwnd, (HMENU)CONSOLE_CFGREGSET, GetModuleHandle(0), 0); + + y += 24; + CreateWindow("STATIC", "Lock Joypad Button(s) Down:", WS_CHILD | WS_VISIBLE, x + 5, y, 240, 15, hwnd, (HMENU)CONSOLE_CFGLOCK, GetModuleHandle(0), 0); CreateWindow("BUTTON", "Up", WS_CHILD | WS_VISIBLE | BS_CHECKBOX, - x + 5, 300, 60, 15, hwnd, (HMENU)CONSOLE_CFGLOCKUP, GetModuleHandle(0), 0); + x + 5, y + 15, 60, 15, hwnd, (HMENU)CONSOLE_CFGLOCKUP, GetModuleHandle(0), 0); CreateWindow("BUTTON", "Down", WS_CHILD | WS_VISIBLE | BS_CHECKBOX, - x + 65, 300, 60, 15, hwnd, (HMENU)CONSOLE_CFGLOCKDOWN, GetModuleHandle(0), 0); + x + 65, y + 15, 60, 15, hwnd, (HMENU)CONSOLE_CFGLOCKDOWN, GetModuleHandle(0), 0); CreateWindow("BUTTON", "Left", WS_CHILD | WS_VISIBLE | BS_CHECKBOX, - x + 125, 300, 60, 15, hwnd, (HMENU)CONSOLE_CFGLOCKLEFT, GetModuleHandle(0), 0); + x + 125, y + 15, 60, 15, hwnd, (HMENU)CONSOLE_CFGLOCKLEFT, GetModuleHandle(0), 0); CreateWindow("BUTTON", "Right", WS_CHILD | WS_VISIBLE | BS_CHECKBOX, - x + 185, 300, 60, 15, hwnd, (HMENU)CONSOLE_CFGLOCKRIGHT, GetModuleHandle(0), 0); + x + 185, y + 15, 60, 15, hwnd, (HMENU)CONSOLE_CFGLOCKRIGHT, GetModuleHandle(0), 0); CreateWindow("BUTTON", "A", WS_CHILD | WS_VISIBLE | BS_CHECKBOX, - x + 5, 315, 60, 15, hwnd, (HMENU)CONSOLE_CFGLOCKA, GetModuleHandle(0), 0); + x + 5, y + 30, 60, 15, hwnd, (HMENU)CONSOLE_CFGLOCKA, GetModuleHandle(0), 0); CreateWindow("BUTTON", "B", WS_CHILD | WS_VISIBLE | BS_CHECKBOX, - x + 65, 315, 60, 15, hwnd, (HMENU)CONSOLE_CFGLOCKB, GetModuleHandle(0), 0); + x + 65, y + 30, 60, 15, hwnd, (HMENU)CONSOLE_CFGLOCKB, GetModuleHandle(0), 0); CreateWindow("BUTTON", "X", WS_CHILD | WS_VISIBLE | BS_CHECKBOX, - x + 125, 315, 60, 15, hwnd, (HMENU)CONSOLE_CFGLOCKX, GetModuleHandle(0), 0); + x + 125, y + 30, 60, 15, hwnd, (HMENU)CONSOLE_CFGLOCKX, GetModuleHandle(0), 0); CreateWindow("BUTTON", "Y", WS_CHILD | WS_VISIBLE | BS_CHECKBOX, - x + 185, 315, 60, 15, hwnd, (HMENU)CONSOLE_CFGLOCKY, GetModuleHandle(0), 0); + x + 185, y + 30, 60, 15, hwnd, (HMENU)CONSOLE_CFGLOCKY, GetModuleHandle(0), 0); CreateWindow("BUTTON", "L", WS_CHILD | WS_VISIBLE | BS_CHECKBOX, - x + 5, 330, 60, 15, hwnd, (HMENU)CONSOLE_CFGLOCKL, GetModuleHandle(0), 0); + x + 5, y + 45, 60, 15, hwnd, (HMENU)CONSOLE_CFGLOCKL, GetModuleHandle(0), 0); CreateWindow("BUTTON", "R", WS_CHILD | WS_VISIBLE | BS_CHECKBOX, - x + 65, 330, 60, 15, hwnd, (HMENU)CONSOLE_CFGLOCKR, GetModuleHandle(0), 0); + x + 65, y + 45, 60, 15, hwnd, (HMENU)CONSOLE_CFGLOCKR, GetModuleHandle(0), 0); CreateWindow("BUTTON", "Select", WS_CHILD | WS_VISIBLE | BS_CHECKBOX, - x + 125, 330, 60, 15, hwnd, (HMENU)CONSOLE_CFGLOCKSELECT, GetModuleHandle(0), 0); + x + 125, y + 45, 60, 15, hwnd, (HMENU)CONSOLE_CFGLOCKSELECT, GetModuleHandle(0), 0); CreateWindow("BUTTON", "Start", WS_CHILD | WS_VISIBLE | BS_CHECKBOX, - x + 185, 330, 60, 15, hwnd, (HMENU)CONSOLE_CFGLOCKSTART, GetModuleHandle(0), 0); + x + 185, y + 45, 60, 15, hwnd, (HMENU)CONSOLE_CFGLOCKSTART, GetModuleHandle(0), 0); SendDlgItemMessage(hwnd, CONSOLE_OUTPUT, WM_SETFONT, (WPARAM)hMonofont, TRUE); SendDlgItemMessage(hwnd, CONSOLE_STATUS, WM_SETFONT, (WPARAM)hMonofont, TRUE); @@ -374,7 +450,11 @@ int x, y; SendDlgItemMessage(hwnd, CONSOLE_CFGLOCKSELECT, WM_SETFONT, (WPARAM)hFont, TRUE); SendDlgItemMessage(hwnd, CONSOLE_CFGLOCKSTART, WM_SETFONT, (WPARAM)hFont, TRUE); + outputcpu = true; + outputapu = true; + outputdbg = true; SendDlgItemMessage(hwnd, CONSOLE_CFGOUTPUTCPU, BM_SETCHECK, (WPARAM)true, 0); + SendDlgItemMessage(hwnd, CONSOLE_CFGOUTPUTAPU, BM_SETCHECK, (WPARAM)true, 0); SendDlgItemMessage(hwnd, CONSOLE_CFGOUTPUTDBG, BM_SETCHECK, (WPARAM)true, 0); SendDlgItemMessage(hwnd, CONSOLE_CFGREGTYPE, CB_ADDSTRING, 0, (LPARAM)"CPU"); @@ -396,10 +476,10 @@ Console::Console() { for(int i=0;iwndproc(hwnd, msg, wparam, lparam); +} + +void InputConfig::update_polling(int key) { +bool end_config = false; + if(polling == false)return; + + switch(config_type) { + case JOYPAD1: + switch(config_pos) { + case 0:cfg.input.joypad1.up = key;break; + case 1:cfg.input.joypad1.down = key;break; + case 2:cfg.input.joypad1.left = key;break; + case 3:cfg.input.joypad1.right = key;break; + case 4:cfg.input.joypad1.select = key;break; + case 5:cfg.input.joypad1.start = key;break; + case 6:cfg.input.joypad1.x = key;break; + case 7:cfg.input.joypad1.y = key;break; + case 8:cfg.input.joypad1.a = key;break; + case 9:cfg.input.joypad1.b = key;break; + case 10:cfg.input.joypad1.l = key;break; + case 11:cfg.input.joypad1.r = key;break; + case 12:end_config = true;break; + } + config_pos++; + } + if(end_config == true) { + polling = false; + hide(); + return; + } + update_command(); +} + +void InputConfig::update_command() { + switch(config_type) { + case JOYPAD1: + switch(config_pos) { + case 0:set_text("Press key for Up..."); break; + case 1:set_text("Press key for Down..."); break; + case 2:set_text("Press key for Left..."); break; + case 3:set_text("Press key for Right..."); break; + case 4:set_text("Press key for Select...");break; + case 5:set_text("Press key for Start..."); break; + case 6:set_text("Press key for X..."); break; + case 7:set_text("Press key for Y..."); break; + case 8:set_text("Press key for A..."); break; + case 9:set_text("Press key for B..."); break; + case 10:set_text("Press key for L..."); break; + case 11:set_text("Press key for R..."); break; + case 12:set_text("Configuration complete. Press any key to close window...");break; + } + break; + } +} + +void InputConfig::begin_config(int type) { + if(visible == true) { + center(); + SetFocus(hwnd); + return; + } + config_type = type; + config_pos = 0; + switch(config_type) { + case JOYPAD1: + SetWindowText(hwnd, "bsnes Input Configuration : Joypad1"); + break; + default: + return; + } + polling = true; + update_command(); + center(); + show(); +} + +void InputConfig::set_text(char *str) { + SetDlgItemText(hwnd, ID_COMMAND, str); +} + +void InputConfig::create() { +WNDCLASS wc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hbrBackground = (HBRUSH)COLOR_WINDOW; + wc.hCursor = LoadCursor(0, IDC_ARROW); + wc.hIcon = LoadIcon(0, IDI_APPLICATION); + wc.hInstance = GetModuleHandle(0); + wc.lpfnWndProc = wndproc_inputconfig; + wc.lpszClassName = "bsnes_inputconfig"; + wc.lpszMenuName = 0; + wc.style = CS_HREDRAW | CS_VREDRAW; + RegisterClass(&wc); + + hwnd = CreateWindow("bsnes_inputconfig", "bsnes input configuration", + WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, + 0, 0, 410, 230, + 0, 0, GetModuleHandle(0), 0); + + resize(410, 230); + center(); + + CreateWindow("STATIC", "", WS_CHILD | WS_VISIBLE, 5, 5, 350, 15, hwnd, (HMENU)ID_COMMAND, GetModuleHandle(0), 0); + + SendDlgItemMessage(hwnd, ID_COMMAND, WM_SETFONT, (WPARAM)hFont, 0); + SendDlgItemMessage(hwnd, 120, WM_SETFONT, (WPARAM)hFont, 0); +} diff --git a/src/win/ui_main.cpp b/src/win/ui_main.cpp index dfd8b6a1..efa883c6 100644 --- a/src/win/ui_main.cpp +++ b/src/win/ui_main.cpp @@ -11,7 +11,7 @@ void MainWindow::set_frameskip(uint8 fs) { CheckMenuItem(w_main->hmenu, MENU_SETTINGS_FRAMESKIP_9, MF_UNCHECKED); CheckMenuItem(w_main->hmenu, MENU_SETTINGS_FRAMESKIP_OFF + fs, MF_CHECKED); - clock->set_frameskip(fs); + ppu->set_frameskip(fs); w_main->frameskip = fs; } @@ -212,6 +212,13 @@ long __stdcall wndproc_main(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { SetWindowText(w_main->hwnd, BSNES_TITLE); CheckMenuItem(w_main->hmenu, MENU_SETTINGS_SHOWFPS, (cfg.gui.show_fps)?MF_CHECKED:MF_UNCHECKED); break; + case MENU_SETTINGS_APUENABLED: + cfg.apu.enabled ^= 1; + CheckMenuItem(w_main->hmenu, MENU_SETTINGS_APUENABLED, (cfg.apu.enabled)?MF_CHECKED:MF_UNCHECKED); + break; + case MENU_SETTINGS_INPUTCFG_JOYPAD1: + w_inputconfig->begin_config(InputConfig::JOYPAD1); + break; case MENU_SETTINGS_DEBUGGER: if(bsnes->debugger_enabled() == true) { bsnes->debugger_disable(); @@ -220,6 +227,11 @@ long __stdcall wndproc_main(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { w_main->set_video_mode(VIDEOMODE_256x224w); } break; + case MENU_MISC_ABOUT: + w_about->center(); + w_about->show(); + SetFocus(w_about->hwnd); + break; } break; case WM_DESTROY: @@ -232,13 +244,13 @@ long __stdcall wndproc_main(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { return DefWindowProc(hwnd, msg, wparam, lparam); } -void CreateWindowMain() { +void MainWindow::create() { WNDCLASS wc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hbrBackground = CreateSolidBrush(RGB(0, 0, 0)); wc.hCursor = LoadCursor(0, IDC_ARROW); - wc.hIcon = LoadIcon(0, IDI_APPLICATION); + wc.hIcon = LoadIcon(GetModuleHandle(0), MAKEINTRESOURCE(101)); wc.hInstance = GetModuleHandle(0); wc.lpfnWndProc = wndproc_main; wc.lpszClassName = "bsnes"; @@ -246,13 +258,13 @@ WNDCLASS wc; wc.style = CS_HREDRAW | CS_VREDRAW; RegisterClass(&wc); - w_main->hwnd = CreateWindowEx(0, "bsnes", "bsnes v" BSNES_VERSION " ~byuu", + hwnd = CreateWindowEx(0, "bsnes", BSNES_TITLE, WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, 0, 0, 512, 446, 0, 0, GetModuleHandle(0), 0); HMENU hsubmenu, hbranchmenu; - w_main->hmenu = CreateMenu(); + hmenu = CreateMenu(); hsubmenu = CreatePopupMenu(); AppendMenu(hsubmenu, MF_STRING, MENU_FILE_LOAD, "&Load ROM"); @@ -262,7 +274,7 @@ HMENU hsubmenu, hbranchmenu; AppendMenu(hsubmenu, MF_STRING, MENU_FILE_POWER, "&Power (Hard Reset)"); AppendMenu(hsubmenu, MF_SEPARATOR, 0, ""); AppendMenu(hsubmenu, MF_STRING, MENU_FILE_EXIT, "E&xit"); - AppendMenu(w_main->hmenu, MF_STRING | MF_POPUP, (unsigned int)hsubmenu, "&File"); + AppendMenu(hmenu, MF_STRING | MF_POPUP, (unsigned int)hsubmenu, "&File"); hsubmenu = CreatePopupMenu(); @@ -292,16 +304,23 @@ HMENU hsubmenu, hbranchmenu; AppendMenu(hsubmenu, MF_STRING, MENU_SETTINGS_VBLANK, "&Wait for Vertical Retrace"); AppendMenu(hsubmenu, MF_STRING, MENU_SETTINGS_COLORCURVE, "Use &Color Curve"); AppendMenu(hsubmenu, MF_STRING, MENU_SETTINGS_SHOWFPS, "&Show FPS"); + AppendMenu(hsubmenu, MF_STRING, MENU_SETTINGS_APUENABLED, "&Enable APU"); + + hbranchmenu = CreatePopupMenu(); + AppendMenu(hbranchmenu, MF_STRING, MENU_SETTINGS_INPUTCFG_JOYPAD1, "Joypad 1"); + AppendMenu(hsubmenu, MF_STRING | MF_POPUP, (unsigned int)hbranchmenu, "&Configure Input Devices"); AppendMenu(hsubmenu, MF_SEPARATOR, 0, ""); AppendMenu(hsubmenu, MF_STRING, MENU_SETTINGS_DEBUGGER, "&Debugger"); - AppendMenu(w_main->hmenu, MF_STRING | MF_POPUP, (unsigned int)hsubmenu, "&Settings"); + AppendMenu(hmenu, MF_STRING | MF_POPUP, (unsigned int)hsubmenu, "&Settings"); - CheckMenuItem(w_main->hmenu, MENU_SETTINGS_USEVRAM, (cfg.video.use_vram)?MF_CHECKED:MF_UNCHECKED); - CheckMenuItem(w_main->hmenu, MENU_SETTINGS_VBLANK, (cfg.video.vblank)?MF_CHECKED:MF_UNCHECKED); - CheckMenuItem(w_main->hmenu, MENU_SETTINGS_COLORCURVE, (cfg.video.color_curve)?MF_CHECKED:MF_UNCHECKED); - CheckMenuItem(w_main->hmenu, MENU_SETTINGS_SHOWFPS, (cfg.gui.show_fps)?MF_CHECKED:MF_UNCHECKED); -} + hsubmenu = CreatePopupMenu(); + AppendMenu(hsubmenu, MF_STRING, MENU_MISC_ABOUT, "&About..."); + AppendMenu(hmenu, MF_STRING | MF_POPUP, (unsigned int)hsubmenu, "&Misc"); -MainWindow::MainWindow() { + CheckMenuItem(hmenu, MENU_SETTINGS_USEVRAM, (cfg.video.use_vram)?MF_CHECKED:MF_UNCHECKED); + CheckMenuItem(hmenu, MENU_SETTINGS_VBLANK, (cfg.video.vblank)?MF_CHECKED:MF_UNCHECKED); + CheckMenuItem(hmenu, MENU_SETTINGS_COLORCURVE, (cfg.video.color_curve)?MF_CHECKED:MF_UNCHECKED); + CheckMenuItem(hmenu, MENU_SETTINGS_SHOWFPS, (cfg.gui.show_fps)?MF_CHECKED:MF_UNCHECKED); + CheckMenuItem(hmenu, MENU_SETTINGS_APUENABLED, (cfg.apu.enabled)?MF_CHECKED:MF_UNCHECKED); } diff --git a/src/win/ui_memory.cpp b/src/win/ui_memory.cpp index 651b0215..380d9fef 100644 --- a/src/win/ui_memory.cpp +++ b/src/win/ui_memory.cpp @@ -1,7 +1,101 @@ +WNDPROC wndproc_oldmemoryeditbox; + +long __stdcall wndproc_memoryeditbox(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { +int pos, len, xpos, ypos, t, z, read; + switch(msg) { + case WM_KEYDOWN: + pos = SendMessage(hwnd, EM_GETSEL, 0, 0); + pos = LOWORD(pos); + ypos = pos / 57; + xpos = pos % 57; + + if(wparam == VK_UP) { + if(ypos != 0)break; + w_memory->edit_addr -= 16; + w_memory->edit_addr &= w_memory->edit_mask; + w_memory->refresh(); + SendMessage(hwnd, EM_SETSEL, pos, pos); + break; + } + + if(wparam == VK_DOWN) { + if(ypos != 15)break; + w_memory->edit_addr += 16; + w_memory->edit_addr &= w_memory->edit_mask; + w_memory->refresh(); + SendMessage(hwnd, EM_SETSEL, pos, pos); + break; + } + + if(wparam == VK_PRIOR) { + if(KeyDown(VK_CONTROL))len = 65536; + else if(KeyDown(VK_SHIFT))len = 4096; + else len = 256; + w_memory->edit_addr -= len; + w_memory->edit_addr &= w_memory->edit_mask; + w_memory->refresh(); + SendMessage(hwnd, EM_SETSEL, pos, pos); + break; + } + + if(wparam == VK_NEXT) { + if(KeyDown(VK_CONTROL))len = 65536; + else if(KeyDown(VK_SHIFT))len = 4096; + else len = 256; + w_memory->edit_addr += len; + w_memory->edit_addr &= w_memory->edit_mask; + w_memory->refresh(); + SendMessage(hwnd, EM_SETSEL, pos, pos); + break; + } + + if(xpos < 8)break; + xpos -= 8; + t = xpos % 3; + xpos /= 3; + if(xpos > 15)break; + + if(wparam >= '0' && wparam <= '9')read = wparam - '0'; + else if(wparam >= 'A' && wparam <= 'F')read = wparam - 'A' + 0x0a; + else if(wparam >= 'a' && wparam <= 'f')read = wparam - 'a' + 0x0a; + else break; + + z = w_memory->read_byte(w_memory->edit_addr + ypos * 16 + xpos); + if(t == 0) { + z = (read << 4) | (z & 0x0f); + pos++; + } else { + z = (z & 0xf0) | (read); + if(xpos == 15) { //go to new line + if(ypos == 15) { //so long as we aren't on the last one + pos++; + } else { + pos += 11; + } + } else { //go to next byte + pos += 2; + } + } + w_memory->write_byte(w_memory->edit_addr + ypos * 16 + xpos, z); + w_memory->refresh(); + SendMessage(hwnd, EM_SETSEL, pos, pos); + break; + } + return wndproc_oldmemoryeditbox(hwnd, msg, wparam, lparam); +} + long __stdcall wndproc_memoryeditor(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { char t[256]; uint32 addr, value, pos; +HDC hdc; switch(msg) { + case WM_CTLCOLORSTATIC: + if((HWND)lparam != GetDlgItem(hwnd, MEMORYEDITOR_VIEW))break; + hdc = (HDC)wparam; + SetTextColor(hdc, RGB(255, 255, 255)); + SetBkColor(hdc, RGB(0, 0, 0)); + SetBkMode(hdc, TRANSPARENT); + return (long)hbr_backbrush; case WM_COMMAND: switch(LOWORD(wparam)) { case MEMORYEDITOR_MODE: @@ -20,14 +114,18 @@ uint32 addr, value, pos; w_memory->edit_addr = 0x700000; w_memory->edit_mask = 0xffffff; } else if(pos == 3) { - w_memory->edit_mode = MemoryEditor::MODE_VRAM; + w_memory->edit_mode = MemoryEditor::MODE_SPCRAM; w_memory->edit_addr = 0x0000; w_memory->edit_mask = 0xffff; } else if(pos == 4) { + w_memory->edit_mode = MemoryEditor::MODE_VRAM; + w_memory->edit_addr = 0x0000; + w_memory->edit_mask = 0xffff; + } else if(pos == 5) { w_memory->edit_mode = MemoryEditor::MODE_OAM; w_memory->edit_addr = 0x0000; w_memory->edit_mask = 0x03ff; - } else if(pos == 5) { + } else if(pos == 6) { w_memory->edit_mode = MemoryEditor::MODE_CGRAM; w_memory->edit_addr = 0x0000; w_memory->edit_mask = 0x01ff; @@ -47,54 +145,26 @@ uint32 addr, value, pos; GetDlgItemText(hwnd, MEMORYEDITOR_VALUE, t, 255); value = strhex(t) & 0xff; switch(w_memory->edit_mode) { - case MemoryEditor::MODE_DRAM: bsnes->write(bSNES::DRAM, addr, value);break; - case MemoryEditor::MODE_VRAM: bsnes->write(bSNES::VRAM, addr, value);break; - case MemoryEditor::MODE_OAM: bsnes->write(bSNES::OAM, addr, value);break; - case MemoryEditor::MODE_CGRAM:bsnes->write(bSNES::CGRAM, addr, value);break; + case MemoryEditor::MODE_DRAM: bsnes->write(bSNES::DRAM, addr, value);break; + case MemoryEditor::MODE_SPCRAM:bsnes->write(bSNES::SPCRAM, addr, value);break; + case MemoryEditor::MODE_VRAM: bsnes->write(bSNES::VRAM, addr, value);break; + case MemoryEditor::MODE_OAM: bsnes->write(bSNES::OAM, addr, value);break; + case MemoryEditor::MODE_CGRAM: bsnes->write(bSNES::CGRAM, addr, value);break; } break; case MEMORYEDITOR_FEXPORT: pos = SendDlgItemMessage(hwnd, MEMORYEDITOR_FSOURCE, CB_GETCURSEL, 0, 0); w_memory->export(pos); break; - case MEMORYEDITOR_UP40: - w_memory->edit_addr -= 0x40; - w_memory->edit_addr &= w_memory->edit_mask; - w_memory->refresh(); + case MEMORYEDITOR_AUTOUPDATE: + if(w_memory->auto_update == false) { + w_memory->auto_update = true; + } else { + w_memory->auto_update = false; + } + SendDlgItemMessage(hwnd, MEMORYEDITOR_AUTOUPDATE, BM_SETCHECK, (WPARAM)w_memory->auto_update, 0); break; - case MEMORYEDITOR_DOWN40: - w_memory->edit_addr += 0x40; - w_memory->edit_addr &= w_memory->edit_mask; - w_memory->refresh(); - break; - case MEMORYEDITOR_UP400: - w_memory->edit_addr -= 0x400; - w_memory->edit_addr &= w_memory->edit_mask; - w_memory->refresh(); - break; - case MEMORYEDITOR_DOWN400: - w_memory->edit_addr += 0x400; - w_memory->edit_addr &= w_memory->edit_mask; - w_memory->refresh(); - break; - case MEMORYEDITOR_UP4000: - w_memory->edit_addr -= 0x4000; - w_memory->edit_addr &= w_memory->edit_mask; - w_memory->refresh(); - break; - case MEMORYEDITOR_DOWN4000: - w_memory->edit_addr += 0x4000; - w_memory->edit_addr &= w_memory->edit_mask; - w_memory->refresh(); - break; - case MEMORYEDITOR_UP40000: - w_memory->edit_addr -= 0x40000; - w_memory->edit_addr &= w_memory->edit_mask; - w_memory->refresh(); - break; - case MEMORYEDITOR_DOWN40000: - w_memory->edit_addr += 0x40000; - w_memory->edit_addr &= w_memory->edit_mask; + case MEMORYEDITOR_UPDATE: w_memory->refresh(); break; } @@ -116,32 +186,6 @@ uint32 addr, value, pos; return DefWindowProc(hwnd, msg, wparam, lparam); } -void CreateWindowMemory() { -WNDCLASS wc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hbrBackground = (HBRUSH)COLOR_WINDOW; - wc.hCursor = LoadCursor(0, IDC_ARROW); - wc.hIcon = LoadIcon(0, IDI_APPLICATION); - wc.hInstance = GetModuleHandle(0); - wc.lpfnWndProc = wndproc_memoryeditor; - wc.lpszClassName = "bsnes_memoryeditor"; - wc.lpszMenuName = 0; - wc.style = CS_HREDRAW | CS_VREDRAW; - RegisterClass(&wc); - - w_memory->hwnd = CreateWindow("bsnes_memoryeditor", "bsnes memory editor", - WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, - 0, 0, 500, 245, - 0, 0, GetModuleHandle(0), 0); - - w_memory->resize(500, 245); - w_memory->to_left(w_bp->hwnd); - w_memory->to_bottom(w_console->hwnd); - - w_memory->create_controls(); -} - void MemoryEditor::export(uint32 type) { FILE *fp; int i, x; @@ -160,46 +204,65 @@ int i, x; fputc(x, fp); } fclose(fp); - } else if(type == 2) { //VRAM + } else if(type == 2) { //SPCRAM + fp = fopen("spcram.bin", "wb"); + for(i=0x0000;i<=0xffff;i++) { + x = bsnes->read(bSNES::SPCRAM, i); + fputc(x, fp); + } + fclose(fp); + } else if(type == 3) { //VRAM fp = fopen("vram.bin", "wb"); for(i=0x0000;i<=0xffff;i++) { x = bsnes->read(bSNES::VRAM, i); fputc(x, fp); } fclose(fp); - } else if(type == 3) { //OAM + } else if(type == 4) { //OAM fp = fopen("oam.bin", "wb"); for(i=0x0000;i<=0x021f;i++) { x = bsnes->read(bSNES::OAM, i); fputc(x, fp); } fclose(fp); - } else if(type == 4) { //CGRAM + } else if(type == 5) { //CGRAM fp = fopen("cgram.bin", "wb"); for(i=0x0000;i<=0x01ff;i++) { x = bsnes->read(bSNES::CGRAM, i); fputc(x, fp); } fclose(fp); - } else if(type == 5) { //All + } else if(type == 6) { //All export(0); export(1); export(2); export(3); export(4); + export(5); } } uint8 MemoryEditor::read_byte(uint32 addr) { switch(edit_mode) { - case MODE_DRAM: return bsnes->read(bSNES::DRAM, addr); - case MODE_VRAM: return bsnes->read(bSNES::VRAM, addr); - case MODE_OAM: return bsnes->read(bSNES::OAM, addr); - case MODE_CGRAM:return bsnes->read(bSNES::CGRAM, addr); + case MODE_DRAM: return bsnes->read(bSNES::DRAM, addr); + case MODE_SPCRAM:return bsnes->read(bSNES::SPCRAM, addr); + case MODE_VRAM: return bsnes->read(bSNES::VRAM, addr); + case MODE_OAM: return bsnes->read(bSNES::OAM, addr); + case MODE_CGRAM: return bsnes->read(bSNES::CGRAM, addr); } return 0x00; } +void MemoryEditor::write_byte(uint32 addr, uint8 value) { + switch(edit_mode) { + case MODE_DRAM: bsnes->write(bSNES::DRAM, addr, value);break; + case MODE_SPCRAM:bsnes->write(bSNES::SPCRAM, addr, value);break; + case MODE_VRAM: bsnes->write(bSNES::VRAM, addr, value);break; + case MODE_OAM: bsnes->write(bSNES::OAM, addr, value);break; + case MODE_CGRAM: bsnes->write(bSNES::CGRAM, addr, value);break; + } +} + void MemoryEditor::clear() { SetDlgItemText(hwnd, MEMORYEDITOR_VIEW, ""); } @@ -210,18 +273,25 @@ int x, y; if(rom_image->loaded() == false)return; if(visible == false)return; - if(type == SNES::MEM_WRITE) { - if(edit_mode != MODE_DRAM)return; - if(addr < edit_addr || addr >= edit_addr + 256)return; - } else if(type == SNES::VRAM_WRITE) { - if(edit_mode != MODE_VRAM)return; - if(addr < edit_addr || addr >= edit_addr + 256)return; - } else if(type == SNES::OAM_WRITE) { - if(edit_mode != MODE_OAM)return; - if(addr < edit_addr || addr >= edit_addr + 256)return; - } else if(type == SNES::CGRAM_WRITE) { - if(edit_mode != MODE_CGRAM)return; - if(addr < edit_addr || addr >= edit_addr + 256)return; + if(type != null) { + if(auto_update == false && bsnes->get_status() != bSNES::STOP)return; + + if(type == SNES::MEM_WRITE) { + if(edit_mode != MODE_DRAM)return; + if(addr < edit_addr || addr >= edit_addr + 256)return; + } else if(type == SNES::SPCRAM_WRITE) { + if(edit_mode != MODE_SPCRAM)return; + if(addr < edit_addr || addr >= edit_addr + 256)return; + } else if(type == SNES::VRAM_WRITE) { + if(edit_mode != MODE_VRAM)return; + if(addr < edit_addr || addr >= edit_addr + 256)return; + } else if(type == SNES::OAM_WRITE) { + if(edit_mode != MODE_OAM)return; + if(addr < edit_addr || addr >= edit_addr + 256)return; + } else if(type == SNES::CGRAM_WRITE) { + if(edit_mode != MODE_CGRAM)return; + if(addr < edit_addr || addr >= edit_addr + 256)return; + } } strcpy(s, ""); @@ -238,9 +308,33 @@ int x, y; SetDlgItemText(hwnd, MEMORYEDITOR_VIEW, s); } -void MemoryEditor::create_controls() { +void MemoryEditor::create() { +WNDCLASS wc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hbrBackground = (HBRUSH)COLOR_WINDOW; + wc.hCursor = LoadCursor(0, IDC_ARROW); + wc.hIcon = LoadIcon(0, IDI_APPLICATION); + wc.hInstance = GetModuleHandle(0); + wc.lpfnWndProc = wndproc_memoryeditor; + wc.lpszClassName = "bsnes_memoryeditor"; + wc.lpszMenuName = 0; + wc.style = CS_HREDRAW | CS_VREDRAW; + RegisterClass(&wc); + + hwnd = CreateWindow("bsnes_memoryeditor", "bsnes Memory Editor", + WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, + 0, 0, 500, 245, + 0, 0, GetModuleHandle(0), 0); + + resize(500, 245); + to_left(w_bp->hwnd); + to_bottom(w_console->hwnd); + CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_READONLY, 5, 5, 395, 235, hwnd, (HMENU)MEMORYEDITOR_VIEW, GetModuleHandle(0), 0); + wndproc_oldmemoryeditbox = (WNDPROC)GetWindowLong(GetDlgItem(hwnd, MEMORYEDITOR_VIEW), GWL_WNDPROC); + SetWindowLong(GetDlgItem(hwnd, MEMORYEDITOR_VIEW), GWL_WNDPROC, (long)wndproc_memoryeditbox); CreateWindow("COMBOBOX", "", WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST | CBS_HASSTRINGS, 405, 5, 90, 200, hwnd, (HMENU)MEMORYEDITOR_MODE, GetModuleHandle(0), 0); @@ -263,45 +357,28 @@ void MemoryEditor::create_controls() { CreateWindow("BUTTON", "Export...", WS_CHILD | WS_VISIBLE, 405, 131, 90, 20, hwnd, (HMENU)MEMORYEDITOR_FEXPORT, GetModuleHandle(0), 0); - CreateWindow("BUTTON", "-40", WS_CHILD | WS_VISIBLE, - 405, 160, 45, 20, hwnd, (HMENU)MEMORYEDITOR_UP40, GetModuleHandle(0), 0); - CreateWindow("BUTTON", "+40", WS_CHILD | WS_VISIBLE, - 450, 160, 45, 20, hwnd, (HMENU)MEMORYEDITOR_DOWN40, GetModuleHandle(0), 0); - CreateWindow("BUTTON", "-400", WS_CHILD | WS_VISIBLE, - 405, 180, 45, 20, hwnd, (HMENU)MEMORYEDITOR_UP400, GetModuleHandle(0), 0); - CreateWindow("BUTTON", "+400", WS_CHILD | WS_VISIBLE, - 450, 180, 45, 20, hwnd, (HMENU)MEMORYEDITOR_DOWN400, GetModuleHandle(0), 0); - CreateWindow("BUTTON", "-4000", WS_CHILD | WS_VISIBLE, - 405, 200, 45, 20, hwnd, (HMENU)MEMORYEDITOR_UP4000, GetModuleHandle(0), 0); - CreateWindow("BUTTON", "+4000", WS_CHILD | WS_VISIBLE, - 450, 200, 45, 20, hwnd, (HMENU)MEMORYEDITOR_DOWN4000, GetModuleHandle(0), 0); - CreateWindow("BUTTON", "-40000", WS_CHILD | WS_VISIBLE, - 405, 220, 45, 20, hwnd, (HMENU)MEMORYEDITOR_UP40000, GetModuleHandle(0), 0); - CreateWindow("BUTTON", "+40000", WS_CHILD | WS_VISIBLE, - 450, 220, 45, 20, hwnd, (HMENU)MEMORYEDITOR_DOWN40000, GetModuleHandle(0), 0); + CreateWindow("BUTTON", "Auto Update", WS_CHILD | WS_VISIBLE | BS_CHECKBOX, + 405, 203, 90, 15, hwnd, (HMENU)MEMORYEDITOR_AUTOUPDATE, GetModuleHandle(0), 0); + CreateWindow("BUTTON", "Update", WS_CHILD | WS_VISIBLE, + 405, 220, 90, 20, hwnd, (HMENU)MEMORYEDITOR_UPDATE, GetModuleHandle(0), 0); - SendDlgItemMessage(hwnd, MEMORYEDITOR_VIEW, WM_SETFONT, (WPARAM)hMonofont, 0); - SendDlgItemMessage(hwnd, MEMORYEDITOR_MODE, WM_SETFONT, (WPARAM)hFont, 0); - SendDlgItemMessage(hwnd, MEMORYEDITOR_GOTOADDR, WM_SETFONT, (WPARAM)hMonofont, 0); - SendDlgItemMessage(hwnd, MEMORYEDITOR_GOTO, WM_SETFONT, (WPARAM)hFont, 0); - SendDlgItemMessage(hwnd, MEMORYEDITOR_STATIC1, WM_SETFONT, (WPARAM)hFont, 0); - SendDlgItemMessage(hwnd, MEMORYEDITOR_OFFSET, WM_SETFONT, (WPARAM)hMonofont, 0); - SendDlgItemMessage(hwnd, MEMORYEDITOR_VALUE, WM_SETFONT, (WPARAM)hMonofont, 0); - SendDlgItemMessage(hwnd, MEMORYEDITOR_EDIT, WM_SETFONT, (WPARAM)hFont, 0); - SendDlgItemMessage(hwnd, MEMORYEDITOR_FSOURCE, WM_SETFONT, (WPARAM)hFont, 0); - SendDlgItemMessage(hwnd, MEMORYEDITOR_FEXPORT, WM_SETFONT, (WPARAM)hFont, 0); - SendDlgItemMessage(hwnd, MEMORYEDITOR_UP40, WM_SETFONT, (WPARAM)hFont, 0); - SendDlgItemMessage(hwnd, MEMORYEDITOR_DOWN40, WM_SETFONT, (WPARAM)hFont, 0); - SendDlgItemMessage(hwnd, MEMORYEDITOR_UP400, WM_SETFONT, (WPARAM)hFont, 0); - SendDlgItemMessage(hwnd, MEMORYEDITOR_DOWN400, WM_SETFONT, (WPARAM)hFont, 0); - SendDlgItemMessage(hwnd, MEMORYEDITOR_UP4000, WM_SETFONT, (WPARAM)hFont, 0); - SendDlgItemMessage(hwnd, MEMORYEDITOR_DOWN4000, WM_SETFONT, (WPARAM)hFont, 0); - SendDlgItemMessage(hwnd, MEMORYEDITOR_UP40000, WM_SETFONT, (WPARAM)hFont, 0); - SendDlgItemMessage(hwnd, MEMORYEDITOR_DOWN40000, WM_SETFONT, (WPARAM)hFont, 0); + SendDlgItemMessage(hwnd, MEMORYEDITOR_VIEW, WM_SETFONT, (WPARAM)hMonofont, 0); + SendDlgItemMessage(hwnd, MEMORYEDITOR_MODE, WM_SETFONT, (WPARAM)hFont, 0); + SendDlgItemMessage(hwnd, MEMORYEDITOR_GOTOADDR, WM_SETFONT, (WPARAM)hMonofont, 0); + SendDlgItemMessage(hwnd, MEMORYEDITOR_GOTO, WM_SETFONT, (WPARAM)hFont, 0); + SendDlgItemMessage(hwnd, MEMORYEDITOR_STATIC1, WM_SETFONT, (WPARAM)hFont, 0); + SendDlgItemMessage(hwnd, MEMORYEDITOR_OFFSET, WM_SETFONT, (WPARAM)hMonofont, 0); + SendDlgItemMessage(hwnd, MEMORYEDITOR_VALUE, WM_SETFONT, (WPARAM)hMonofont, 0); + SendDlgItemMessage(hwnd, MEMORYEDITOR_EDIT, WM_SETFONT, (WPARAM)hFont, 0); + SendDlgItemMessage(hwnd, MEMORYEDITOR_FSOURCE, WM_SETFONT, (WPARAM)hFont, 0); + SendDlgItemMessage(hwnd, MEMORYEDITOR_FEXPORT, WM_SETFONT, (WPARAM)hFont, 0); + SendDlgItemMessage(hwnd, MEMORYEDITOR_AUTOUPDATE, WM_SETFONT, (WPARAM)hFont, 0); + SendDlgItemMessage(hwnd, MEMORYEDITOR_UPDATE, WM_SETFONT, (WPARAM)hFont, 0); SendDlgItemMessage(hwnd, MEMORYEDITOR_MODE, CB_ADDSTRING, 0, (LPARAM)"DRAM"); SendDlgItemMessage(hwnd, MEMORYEDITOR_MODE, CB_ADDSTRING, 0, (LPARAM)"ROM"); SendDlgItemMessage(hwnd, MEMORYEDITOR_MODE, CB_ADDSTRING, 0, (LPARAM)"SRAM"); + SendDlgItemMessage(hwnd, MEMORYEDITOR_MODE, CB_ADDSTRING, 0, (LPARAM)"SPCRAM"); SendDlgItemMessage(hwnd, MEMORYEDITOR_MODE, CB_ADDSTRING, 0, (LPARAM)"VRAM"); SendDlgItemMessage(hwnd, MEMORYEDITOR_MODE, CB_ADDSTRING, 0, (LPARAM)"OAM"); SendDlgItemMessage(hwnd, MEMORYEDITOR_MODE, CB_ADDSTRING, 0, (LPARAM)"CGRAM"); @@ -309,6 +386,7 @@ void MemoryEditor::create_controls() { SendDlgItemMessage(hwnd, MEMORYEDITOR_FSOURCE, CB_ADDSTRING, 0, (LPARAM)"DRAM"); SendDlgItemMessage(hwnd, MEMORYEDITOR_FSOURCE, CB_ADDSTRING, 0, (LPARAM)"SRAM"); + SendDlgItemMessage(hwnd, MEMORYEDITOR_FSOURCE, CB_ADDSTRING, 0, (LPARAM)"SPCRAM"); SendDlgItemMessage(hwnd, MEMORYEDITOR_FSOURCE, CB_ADDSTRING, 0, (LPARAM)"VRAM"); SendDlgItemMessage(hwnd, MEMORYEDITOR_FSOURCE, CB_ADDSTRING, 0, (LPARAM)"OAM"); SendDlgItemMessage(hwnd, MEMORYEDITOR_FSOURCE, CB_ADDSTRING, 0, (LPARAM)"CGRAM"); @@ -324,4 +402,6 @@ uint32 style; style = GetWindowLong(h, GWL_STYLE); if(style & WS_DISABLED)ctl_disabled[i] = true; } + + auto_update = false; } diff --git a/src/win/ui_window.cpp b/src/win/ui_window.cpp index 1696d73c..14695fe2 100644 --- a/src/win/ui_window.cpp +++ b/src/win/ui_window.cpp @@ -80,6 +80,7 @@ int width, height; void Window::show() { int style; + visible = true; style = GetWindowLong(hwnd, GWL_STYLE); if(style & WS_VISIBLE)return; ShowWindow(hwnd, SW_NORMAL); @@ -87,6 +88,7 @@ int style; void Window::hide() { int style; + visible = false; style = GetWindowLong(hwnd, GWL_STYLE); if(!(style & WS_VISIBLE))return; ShowWindow(hwnd, SW_HIDE); diff --git a/src/win/uictl_editex.cpp b/src/win/uictl_editex.cpp new file mode 100644 index 00000000..e05dd5a9 --- /dev/null +++ b/src/win/uictl_editex.cpp @@ -0,0 +1,75 @@ +void editex_setbackcolor(HWND hwnd, COLORREF color) { + SendMessage(hwnd, EM_SETBKGNDCOLOR, 0, color); +} + +/* + This command attempts to apply line color highlighting + to a RichEdit 2.0 control. It tries to set the colors + of blank lines, CPU message lines, APU message lines, + and debug message lines to differing colors to aid in + readability. It expects the input variable char *str + to be in a special format where every line is exactly + 80 characters long. This is so that setting the + background color of the line covers the entire width + of the window. + + It auto-detects what type of message each line is by + assuming formatting information returned by + cpu->disassemble_op(n) and apu->disassemble_op(n). +*/ +enum { EDITEX_NOALIGN = 0, EDITEX_ALIGNTOP, EDITEX_ALIGNBOTTOM }; +void editex_settext(HWND hwnd, char *str, uint8 *linecol, uint8 align) { +char *t; +int sl, lines; + SetWindowText(hwnd, str); + if(!strcmp(str, ""))return; + + sl = strlen(str); + lines = (sl + 1) / 80; + +CHARFORMAT2 cf; +CHARRANGE cr; + memset(&cf, 0, sizeof(cf)); + cf.cbSize = sizeof(cf); + cf.dwMask = CFM_COLOR | CFM_BACKCOLOR; + cf.crTextColor = RGB(255, 255, 255); + +int pos = 0; + for(int i=0;i(snes); } void term_snes() { - if(clock) { delete(clock); clock = 0; } +//if(clock) { delete(clock); clock = 0; } if(mem_bus) { delete(mem_bus); mem_bus = 0; } if(cpu) { delete(cpu); cpu = 0; } + if(apu) { delete(apu); apu = 0; } if(ppu) { delete(ppu); ppu = 0; } if(snes) { delete(snes); snes = 0; } } @@ -39,9 +45,9 @@ void term_snes() { void get_config_fn(string &str) { char *t = (char*)malloc(4096); _getcwd(t, 4095); - str = t; + strcpy(str, t); free(t); - str += "\\bsnes.cfg"; + strcat(str, "\\bsnes.cfg"); } int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { @@ -58,13 +64,14 @@ string cfg_fn; init_snes(); init_ui1(); - if(lpCmdLine) { - if(*lpCmdLine) { - rom_image->select(lpCmdLine); - rom_image->load(); - snes->power(); - bsnes->debugger_update(); - } +int argc = __argc; +char **argv = __argv; + + if(argc >= 2) { + rom_image->select(argv[1]); + rom_image->load(); + snes->power(); + bsnes->debugger_update(); } while(1) { @@ -73,7 +80,7 @@ string cfg_fn; TranslateMessage(&msg); DispatchMessage(&msg); } - bsnes->run(); + bsnes->snes_run(); } cfg.save(cfg_fn); diff --git a/src/win/winmain.h b/src/win/winmain.h index f990b93c..2784204e 100644 --- a/src/win/winmain.h +++ b/src/win/winmain.h @@ -2,6 +2,7 @@ //#define WIN32_LEAN_AND_MEAN #include #include +#include #include "../lib/libbase.h" #include "../lib/libvector.h" #include "../lib/libstring.h"