From 9ecf86a80af8b723b31074cf557dc61efc850c69 Mon Sep 17 00:00:00 2001 From: nattthebear Date: Sat, 10 Jun 2017 07:21:29 -0400 Subject: [PATCH] Revert the following commits, from newest to oldest, which all hacked around cothread savestates: a60be7d2c9818229a0dcff0dbccf15f31015ca2a a7b6a9af4d4c049dbcd775f05f8539f86456e5e9 57b1df8487e3102b2e81c75fb96640cb1da430a4 9119e4f4ea7661b555125f8d6023efda8f6ed704 b2c0910376657208acb325953fbb2dbd4957d5e1 587270cad2ec96eaeec0ae60e4247c31a0a06a2e 74c26d9b117d3bdc78f5e5247909c9a05dee2a98 5e3d6555b02b1d6a6b61d8aeb3617e256697cd01 451f786660744835be868c7fca91ef3fc33db687 --- libsnes/bsnes/snes/alt/cpu/cpu.cpp | 27 +- .../bsnes/snes/alt/ppu-compatibility/ppu.cpp | 43 +- .../bsnes/snes/alt/ppu-compatibility/ppu.hpp | 158 +- .../alt/ppu-compatibility/serialization.cpp | 416 ++- .../bsnes/snes/chip/hitachidsp/hitachidsp.cpp | 161 +- libsnes/bsnes/snes/chip/sa1/sa1.cpp | 29 +- libsnes/bsnes/snes/cpu/core/opcode_misc.cpp | 16 +- libsnes/bsnes/snes/cpu/core/registers.hpp | 7 +- libsnes/bsnes/snes/cpu/core/serialization.cpp | 4 - libsnes/bsnes/snes/cpu/cpu.cpp | 362 +- libsnes/bsnes/snes/smp/core/core.cpp | 543 ++- libsnes/bsnes/snes/smp/core/core.hpp | 190 +- libsnes/bsnes/snes/smp/core/memory.hpp | 12 +- libsnes/bsnes/snes/smp/core/opcodes.cpp | 4 - libsnes/bsnes/snes/smp/core/serialization.cpp | 54 +- libsnes/bsnes/snes/smp/core/uop.cpp | 3151 ----------------- libsnes/bsnes/snes/smp/memory/memory.cpp | 6 +- libsnes/bsnes/snes/smp/smp.cpp | 32 +- libsnes/bsnes/snes/smp/smp.hpp | 123 +- libsnes/bsnes/snes/smp/timing/timing.cpp | 130 +- 20 files changed, 1100 insertions(+), 4368 deletions(-) delete mode 100644 libsnes/bsnes/snes/smp/core/uop.cpp diff --git a/libsnes/bsnes/snes/alt/cpu/cpu.cpp b/libsnes/bsnes/snes/alt/cpu/cpu.cpp index 49958d39b0..9b67166be0 100644 --- a/libsnes/bsnes/snes/alt/cpu/cpu.cpp +++ b/libsnes/bsnes/snes/alt/cpu/cpu.cpp @@ -60,24 +60,19 @@ void CPU::enter() { scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); } - if (regs.hang == HangType::Wait) this->op_wai(); - else if (regs.hang == HangType::Stop) this->op_stp(); - else - { - if(status.nmi_pending) { - status.nmi_pending = false; - regs.vector = (regs.e == false ? 0xffea : 0xfffa); - op_irq(); - } + if(status.nmi_pending) { + status.nmi_pending = false; + regs.vector = (regs.e == false ? 0xffea : 0xfffa); + op_irq(); + } - if(status.irq_pending) { - status.irq_pending = false; - regs.vector = (regs.e == false ? 0xffee : 0xfffe); - op_irq(); - } + if(status.irq_pending) { + status.irq_pending = false; + regs.vector = (regs.e == false ? 0xffee : 0xfffe); + op_irq(); + } - op_step(); - } + op_step(); } } diff --git a/libsnes/bsnes/snes/alt/ppu-compatibility/ppu.cpp b/libsnes/bsnes/snes/alt/ppu-compatibility/ppu.cpp index 3e6d2dfaa6..f0c9df6073 100644 --- a/libsnes/bsnes/snes/alt/ppu-compatibility/ppu.cpp +++ b/libsnes/bsnes/snes/alt/ppu-compatibility/ppu.cpp @@ -16,10 +16,7 @@ void PPU::step(unsigned clocks) { void PPU::synchronize_cpu() { if(CPU::Threaded == true) { - if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) - co_switch(cpu.thread); - else if(clock >= 0 && scheduler.sync == Scheduler::SynchronizeMode::All) - interface()->message("PPU had to advance nondeterministically!"); + if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(cpu.thread); } else { while(clock >= 0) cpu.enter(); } @@ -28,33 +25,15 @@ void PPU::synchronize_cpu() { void PPU::Enter() { ppu.enter(); } void PPU::enter() { - while(true) { - if(scheduler.sync == Scheduler::SynchronizeMode::CPU) { - synchronize_cpu(); // when in CPU sync mode, always switch back to CPU as soon as possible - } + while(true) { if(scheduler.sync == Scheduler::SynchronizeMode::All) { scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); - } - - switch(uindex) - { - case 0: enter1(); break; - case 1: enter2(); break; - case 2: enter3(); break; - case 3: enter4(); break; - } - uindex++; - uindex &= 3; - } -} - -void PPU::enter1() { + } + //H = 0 (initialize) scanline(); add_clocks(10); -} - -void PPU::enter2() { + //H = 10 (cache mode7 registers + OAM address reset) cache.m7_hofs = regs.m7_hofs; cache.m7_vofs = regs.m7_vofs; @@ -71,15 +50,11 @@ void PPU::enter2() { } } add_clocks(502); -} - -void PPU::enter3() { + //H = 512 (render) render_scanline(); add_clocks(640); -} - -void PPU::enter4() { + //H = 1152 (cache OBSEL) if(cache.oam_basesize != regs.oam_basesize) { cache.oam_basesize = regs.oam_basesize; @@ -88,6 +63,8 @@ void PPU::enter4() { cache.oam_nameselect = regs.oam_nameselect; cache.oam_tdaddr = regs.oam_tdaddr; add_clocks(lineclocks() - 1152); //seek to start of next scanline + + } } void PPU::add_clocks(unsigned clocks) { @@ -372,8 +349,6 @@ void PPU::reset() { create(Enter, system.cpu_frequency()); PPUcounter::reset(); memset(surface, 0, 512 * 512 * sizeof(uint32)); - - uindex = 0; //zero 01-dec-2012 - gotta reset these sometime, somewhere memset(oam_itemlist, 0, sizeof(oam_itemlist)); diff --git a/libsnes/bsnes/snes/alt/ppu-compatibility/ppu.hpp b/libsnes/bsnes/snes/alt/ppu-compatibility/ppu.hpp index 9036d4f5fd..9cbfbabf12 100644 --- a/libsnes/bsnes/snes/alt/ppu-compatibility/ppu.hpp +++ b/libsnes/bsnes/snes/alt/ppu-compatibility/ppu.hpp @@ -1,84 +1,78 @@ -class PPU : public Processor, public PPUcounter { -public: - uint8* vram; //[128 * 1024] - uint8* oam; //[544] - uint8* cgram; //[512] - - enum : bool { Threaded = true }; - alwaysinline void step(unsigned clocks); - alwaysinline void synchronize_cpu(); - - #include "memory/memory.hpp" - #include "mmio/mmio.hpp" - #include "render/render.hpp" +class PPU : public Processor, public PPUcounter { +public: + uint8* vram; //[128 * 1024] + uint8* oam; //[544] + uint8* cgram; //[512] - int uindex; - - uint32 *surface; - uint32 *output; - - uint8 ppu1_version; - uint8 ppu2_version; - - static void Enter(); - void add_clocks(unsigned clocks); - - uint8 region; - unsigned line; - - enum { NTSC = 0, PAL = 1 }; - enum { BG1 = 0, BG2 = 1, BG3 = 2, BG4 = 3, OAM = 4, BACK = 5, COL = 5 }; - enum { SC_32x32 = 0, SC_64x32 = 1, SC_32x64 = 2, SC_64x64 = 3 }; - - struct { - bool interlace; - bool overscan; - } display; - - struct { - //$2101 - uint8 oam_basesize; - uint8 oam_nameselect; - uint16 oam_tdaddr; - - //$210d-$210e - uint16 m7_hofs, m7_vofs; - - //$211b-$2120 - uint16 m7a, m7b, m7c, m7d, m7x, m7y; - } cache; - - alwaysinline bool interlace() const { return display.interlace; } - alwaysinline bool overscan() const { return display.overscan; } - alwaysinline bool hires() const { return (regs.pseudo_hires || regs.bg_mode == 5 || regs.bg_mode == 6); } - - uint16 mosaic_table[16][4096]; - void render_line(); - - void update_oam_status(); - //required functions - void scanline(); - void render_scanline(); - void frame(); + enum : bool { Threaded = true }; + alwaysinline void step(unsigned clocks); + alwaysinline void synchronize_cpu(); + + #include "memory/memory.hpp" + #include "mmio/mmio.hpp" + #include "render/render.hpp" + + uint32 *surface; + uint32 *output; + + uint8 ppu1_version; + uint8 ppu2_version; + + static void Enter(); + void add_clocks(unsigned clocks); + + uint8 region; + unsigned line; + + enum { NTSC = 0, PAL = 1 }; + enum { BG1 = 0, BG2 = 1, BG3 = 2, BG4 = 3, OAM = 4, BACK = 5, COL = 5 }; + enum { SC_32x32 = 0, SC_64x32 = 1, SC_32x64 = 2, SC_64x64 = 3 }; + + struct { + bool interlace; + bool overscan; + } display; + + struct { + //$2101 + uint8 oam_basesize; + uint8 oam_nameselect; + uint16 oam_tdaddr; + + //$210d-$210e + uint16 m7_hofs, m7_vofs; + + //$211b-$2120 + uint16 m7a, m7b, m7c, m7d, m7x, m7y; + } cache; + + alwaysinline bool interlace() const { return display.interlace; } + alwaysinline bool overscan() const { return display.overscan; } + alwaysinline bool hires() const { return (regs.pseudo_hires || regs.bg_mode == 5 || regs.bg_mode == 6); } + + uint16 mosaic_table[16][4096]; + void render_line(); + + void update_oam_status(); + //required functions + void scanline(); + void render_scanline(); + void frame(); void enter(); - void enter1(); - void enter2(); - void enter3(); - void enter4(); - void enable(); - void power(); - void reset(); - - bool layer_enabled[5][4]; - void layer_enable(unsigned layer, unsigned priority, bool enable); - unsigned frameskip; - unsigned framecounter; - void set_frameskip(unsigned frameskip); - - void serialize(serializer&); - void initialize(); - PPU(); - ~PPU(); -}; - -extern PPU ppu; + void enable(); + void power(); + void reset(); + + bool layer_enabled[5][4]; + void layer_enable(unsigned layer, unsigned priority, bool enable); + unsigned frameskip; + unsigned framecounter; + void set_frameskip(unsigned frameskip); + + void serialize(serializer&); + void initialize(); + PPU(); + ~PPU(); +}; + +extern PPU ppu; diff --git a/libsnes/bsnes/snes/alt/ppu-compatibility/serialization.cpp b/libsnes/bsnes/snes/alt/ppu-compatibility/serialization.cpp index 28df9b1e95..c83896400e 100644 --- a/libsnes/bsnes/snes/alt/ppu-compatibility/serialization.cpp +++ b/libsnes/bsnes/snes/alt/ppu-compatibility/serialization.cpp @@ -1,210 +1,208 @@ -#ifdef PPU_CPP - -void PPUcounter::serialize(serializer &s) { - s.integer(status.interlace); - s.integer(status.field); - s.integer(status.vcounter); - s.integer(status.hcounter); - - s.array(history.field); - s.array(history.vcounter); - s.array(history.hcounter); - s.integer(history.index); -} - -void PPU::serialize(serializer &s) { - Processor::serialize(s); - PPUcounter::serialize(s); - - s.array(vram,128 * 1024); - s.array(oam,544); - s.array(cgram,512); - - s.integer(ppu1_version); - s.integer(ppu2_version); - - s.integer(region); - s.integer(line); - - s.integer(display.interlace); - s.integer(display.overscan); - - s.integer(cache.oam_basesize); - s.integer(cache.oam_nameselect); - s.integer(cache.oam_tdaddr); - - s.integer(regs.ppu1_mdr); - s.integer(regs.ppu2_mdr); - for(unsigned n = 0; n < 4; n++) s.integer(regs.bg_y[n]); - - s.integer(regs.ioamaddr); - s.integer(regs.icgramaddr); - - s.integer(regs.display_disabled); - s.integer(regs.display_brightness); - - s.integer(regs.oam_basesize); - s.integer(regs.oam_nameselect); - s.integer(regs.oam_tdaddr); - - s.integer(regs.oam_baseaddr); - s.integer(regs.oam_addr); - s.integer(regs.oam_priority); - s.integer(regs.oam_firstsprite); - - s.integer(regs.oam_latchdata); - - for(unsigned n = 0; n < 4; n++) s.integer(regs.bg_tilesize[n]); - s.integer(regs.bg3_priority); - s.integer(regs.bg_mode); - - s.integer(regs.mosaic_size); - for(unsigned n = 0; n < 4; n++) s.integer(regs.mosaic_enabled[n]); - s.integer(regs.mosaic_countdown); - - for(unsigned n = 0; n < 4; n++) s.integer(regs.bg_scaddr[n]); - for(unsigned n = 0; n < 4; n++) s.integer(regs.bg_scsize[n]); - - for(unsigned n = 0; n < 4; n++) s.integer(regs.bg_tdaddr[n]); - - s.integer(regs.bg_ofslatch); - s.integer(regs.m7_hofs); - s.integer(regs.m7_vofs); - for(unsigned n = 0; n < 4; n++) s.integer(regs.bg_hofs[n]); - for(unsigned n = 0; n < 4; n++) s.integer(regs.bg_vofs[n]); - - s.integer(regs.vram_incmode); - s.integer(regs.vram_mapping); - s.integer(regs.vram_incsize); - - s.integer(regs.vram_addr); - - s.integer(regs.mode7_repeat); - s.integer(regs.mode7_vflip); - s.integer(regs.mode7_hflip); - - s.integer(regs.m7_latch); - s.integer(regs.m7a); - s.integer(regs.m7b); - s.integer(regs.m7c); - s.integer(regs.m7d); - s.integer(regs.m7x); - s.integer(regs.m7y); - - s.integer(regs.cgram_addr); - - s.integer(regs.cgram_latchdata); - - for(unsigned n = 0; n < 6; n++) s.integer(regs.window1_enabled[n]); - for(unsigned n = 0; n < 6; n++) s.integer(regs.window1_invert [n]); - for(unsigned n = 0; n < 6; n++) s.integer(regs.window2_enabled[n]); - for(unsigned n = 0; n < 6; n++) s.integer(regs.window2_invert [n]); - - s.integer(regs.window1_left); - s.integer(regs.window1_right); - s.integer(regs.window2_left); - s.integer(regs.window2_right); - - for(unsigned n = 0; n < 6; n++) s.integer(regs.window_mask[n]); - for(unsigned n = 0; n < 5; n++) s.integer(regs.bg_enabled[n]); - for(unsigned n = 0; n < 5; n++) s.integer(regs.bgsub_enabled[n]); - for(unsigned n = 0; n < 5; n++) s.integer(regs.window_enabled[n]); - for(unsigned n = 0; n < 5; n++) s.integer(regs.sub_window_enabled[n]); - - s.integer(regs.color_mask); - s.integer(regs.colorsub_mask); - s.integer(regs.addsub_mode); - s.integer(regs.direct_color); - - s.integer(regs.color_mode); - s.integer(regs.color_halve); - for(unsigned n = 0; n < 6; n++) s.integer(regs.color_enabled[n]); - - s.integer(regs.color_r); - s.integer(regs.color_g); - s.integer(regs.color_b); - s.integer(regs.color_rgb); - - s.integer(regs.mode7_extbg); - s.integer(regs.pseudo_hires); - s.integer(regs.overscan); - s.integer(regs.scanlines); - s.integer(regs.oam_interlace); - s.integer(regs.interlace); - - s.integer(regs.hcounter); - s.integer(regs.vcounter); - s.integer(regs.latch_hcounter); - s.integer(regs.latch_vcounter); - s.integer(regs.counters_latched); - - s.integer(regs.vram_readbuffer); - - s.integer(regs.time_over); - s.integer(regs.range_over); - s.integer(regs.oam_itemcount); - s.integer(regs.oam_tilecount); - - for(unsigned n = 0; n < 256; n++) { - s.integer(pixel_cache[n].src_main); - s.integer(pixel_cache[n].src_sub); - s.integer(pixel_cache[n].bg_main); - s.integer(pixel_cache[n].bg_sub); - s.integer(pixel_cache[n].ce_main); - s.integer(pixel_cache[n].ce_sub); - s.integer(pixel_cache[n].pri_main); - s.integer(pixel_cache[n].pri_sub); - } - - //zero TODO - only on load - //better to just take a small speed hit than store all of bg_tiledata[3][] ... - flush_tiledata_cache(); - - for(unsigned n = 0; n < 6; n++) { - s.array(window[n].main, 256); - s.array(window[n].sub, 256); - } - - for(unsigned n = 0; n < 4; n++) { - s.integer(bg_info[n].tw); - s.integer(bg_info[n].th); - s.integer(bg_info[n].mx); - s.integer(bg_info[n].my); - s.integer(bg_info[n].scx); - s.integer(bg_info[n].scy); - } - - for(unsigned n = 0; n < 128; n++) { - s.integer(sprite_list[n].width); - s.integer(sprite_list[n].height); - s.integer(sprite_list[n].x); - s.integer(sprite_list[n].y); - s.integer(sprite_list[n].character); - s.integer(sprite_list[n].use_nameselect); - s.integer(sprite_list[n].vflip); - s.integer(sprite_list[n].hflip); - s.integer(sprite_list[n].palette); - s.integer(sprite_list[n].priority); - s.integer(sprite_list[n].size); - } - s.integer(sprite_list_valid); - s.integer(active_sprite); - - s.array(oam_itemlist, 32); - - for(unsigned n = 0; n < 34; n++) { - s.integer(oam_tilelist[n].x); - s.integer(oam_tilelist[n].y); - s.integer(oam_tilelist[n].pri); - s.integer(oam_tilelist[n].pal); - s.integer(oam_tilelist[n].tile); - s.integer(oam_tilelist[n].hflip); - } - - s.array(oam_line_pal, 256); - s.array(oam_line_pri, 256); +#ifdef PPU_CPP - s.integer(uindex); -} - -#endif +void PPUcounter::serialize(serializer &s) { + s.integer(status.interlace); + s.integer(status.field); + s.integer(status.vcounter); + s.integer(status.hcounter); + + s.array(history.field); + s.array(history.vcounter); + s.array(history.hcounter); + s.integer(history.index); +} + +void PPU::serialize(serializer &s) { + Processor::serialize(s); + PPUcounter::serialize(s); + + s.array(vram,128 * 1024); + s.array(oam,544); + s.array(cgram,512); + + s.integer(ppu1_version); + s.integer(ppu2_version); + + s.integer(region); + s.integer(line); + + s.integer(display.interlace); + s.integer(display.overscan); + + s.integer(cache.oam_basesize); + s.integer(cache.oam_nameselect); + s.integer(cache.oam_tdaddr); + + s.integer(regs.ppu1_mdr); + s.integer(regs.ppu2_mdr); + for(unsigned n = 0; n < 4; n++) s.integer(regs.bg_y[n]); + + s.integer(regs.ioamaddr); + s.integer(regs.icgramaddr); + + s.integer(regs.display_disabled); + s.integer(regs.display_brightness); + + s.integer(regs.oam_basesize); + s.integer(regs.oam_nameselect); + s.integer(regs.oam_tdaddr); + + s.integer(regs.oam_baseaddr); + s.integer(regs.oam_addr); + s.integer(regs.oam_priority); + s.integer(regs.oam_firstsprite); + + s.integer(regs.oam_latchdata); + + for(unsigned n = 0; n < 4; n++) s.integer(regs.bg_tilesize[n]); + s.integer(regs.bg3_priority); + s.integer(regs.bg_mode); + + s.integer(regs.mosaic_size); + for(unsigned n = 0; n < 4; n++) s.integer(regs.mosaic_enabled[n]); + s.integer(regs.mosaic_countdown); + + for(unsigned n = 0; n < 4; n++) s.integer(regs.bg_scaddr[n]); + for(unsigned n = 0; n < 4; n++) s.integer(regs.bg_scsize[n]); + + for(unsigned n = 0; n < 4; n++) s.integer(regs.bg_tdaddr[n]); + + s.integer(regs.bg_ofslatch); + s.integer(regs.m7_hofs); + s.integer(regs.m7_vofs); + for(unsigned n = 0; n < 4; n++) s.integer(regs.bg_hofs[n]); + for(unsigned n = 0; n < 4; n++) s.integer(regs.bg_vofs[n]); + + s.integer(regs.vram_incmode); + s.integer(regs.vram_mapping); + s.integer(regs.vram_incsize); + + s.integer(regs.vram_addr); + + s.integer(regs.mode7_repeat); + s.integer(regs.mode7_vflip); + s.integer(regs.mode7_hflip); + + s.integer(regs.m7_latch); + s.integer(regs.m7a); + s.integer(regs.m7b); + s.integer(regs.m7c); + s.integer(regs.m7d); + s.integer(regs.m7x); + s.integer(regs.m7y); + + s.integer(regs.cgram_addr); + + s.integer(regs.cgram_latchdata); + + for(unsigned n = 0; n < 6; n++) s.integer(regs.window1_enabled[n]); + for(unsigned n = 0; n < 6; n++) s.integer(regs.window1_invert [n]); + for(unsigned n = 0; n < 6; n++) s.integer(regs.window2_enabled[n]); + for(unsigned n = 0; n < 6; n++) s.integer(regs.window2_invert [n]); + + s.integer(regs.window1_left); + s.integer(regs.window1_right); + s.integer(regs.window2_left); + s.integer(regs.window2_right); + + for(unsigned n = 0; n < 6; n++) s.integer(regs.window_mask[n]); + for(unsigned n = 0; n < 5; n++) s.integer(regs.bg_enabled[n]); + for(unsigned n = 0; n < 5; n++) s.integer(regs.bgsub_enabled[n]); + for(unsigned n = 0; n < 5; n++) s.integer(regs.window_enabled[n]); + for(unsigned n = 0; n < 5; n++) s.integer(regs.sub_window_enabled[n]); + + s.integer(regs.color_mask); + s.integer(regs.colorsub_mask); + s.integer(regs.addsub_mode); + s.integer(regs.direct_color); + + s.integer(regs.color_mode); + s.integer(regs.color_halve); + for(unsigned n = 0; n < 6; n++) s.integer(regs.color_enabled[n]); + + s.integer(regs.color_r); + s.integer(regs.color_g); + s.integer(regs.color_b); + s.integer(regs.color_rgb); + + s.integer(regs.mode7_extbg); + s.integer(regs.pseudo_hires); + s.integer(regs.overscan); + s.integer(regs.scanlines); + s.integer(regs.oam_interlace); + s.integer(regs.interlace); + + s.integer(regs.hcounter); + s.integer(regs.vcounter); + s.integer(regs.latch_hcounter); + s.integer(regs.latch_vcounter); + s.integer(regs.counters_latched); + + s.integer(regs.vram_readbuffer); + + s.integer(regs.time_over); + s.integer(regs.range_over); + s.integer(regs.oam_itemcount); + s.integer(regs.oam_tilecount); + + for(unsigned n = 0; n < 256; n++) { + s.integer(pixel_cache[n].src_main); + s.integer(pixel_cache[n].src_sub); + s.integer(pixel_cache[n].bg_main); + s.integer(pixel_cache[n].bg_sub); + s.integer(pixel_cache[n].ce_main); + s.integer(pixel_cache[n].ce_sub); + s.integer(pixel_cache[n].pri_main); + s.integer(pixel_cache[n].pri_sub); + } + + //zero TODO - only on load + //better to just take a small speed hit than store all of bg_tiledata[3][] ... + flush_tiledata_cache(); + + for(unsigned n = 0; n < 6; n++) { + s.array(window[n].main, 256); + s.array(window[n].sub, 256); + } + + for(unsigned n = 0; n < 4; n++) { + s.integer(bg_info[n].tw); + s.integer(bg_info[n].th); + s.integer(bg_info[n].mx); + s.integer(bg_info[n].my); + s.integer(bg_info[n].scx); + s.integer(bg_info[n].scy); + } + + for(unsigned n = 0; n < 128; n++) { + s.integer(sprite_list[n].width); + s.integer(sprite_list[n].height); + s.integer(sprite_list[n].x); + s.integer(sprite_list[n].y); + s.integer(sprite_list[n].character); + s.integer(sprite_list[n].use_nameselect); + s.integer(sprite_list[n].vflip); + s.integer(sprite_list[n].hflip); + s.integer(sprite_list[n].palette); + s.integer(sprite_list[n].priority); + s.integer(sprite_list[n].size); + } + s.integer(sprite_list_valid); + s.integer(active_sprite); + + s.array(oam_itemlist, 32); + + for(unsigned n = 0; n < 34; n++) { + s.integer(oam_tilelist[n].x); + s.integer(oam_tilelist[n].y); + s.integer(oam_tilelist[n].pri); + s.integer(oam_tilelist[n].pal); + s.integer(oam_tilelist[n].tile); + s.integer(oam_tilelist[n].hflip); + } + + s.array(oam_line_pal, 256); + s.array(oam_line_pri, 256); +} + +#endif diff --git a/libsnes/bsnes/snes/chip/hitachidsp/hitachidsp.cpp b/libsnes/bsnes/snes/chip/hitachidsp/hitachidsp.cpp index 698f1e15e8..e1fe56bcf9 100644 --- a/libsnes/bsnes/snes/chip/hitachidsp/hitachidsp.cpp +++ b/libsnes/bsnes/snes/chip/hitachidsp/hitachidsp.cpp @@ -1,87 +1,82 @@ -#include - -#define HITACHIDSP_CPP -namespace SNES { - -#include "memory.cpp" -#include "opcodes.cpp" -#include "registers.cpp" -#include "serialization.cpp" -HitachiDSP hitachidsp; - -//zero 01-sep-2014 - dont clobber these when reconstructing! -unsigned HitachiDSP::frequency; -uint24 HitachiDSP::dataROM[1024]; - -void HitachiDSP::Enter() { hitachidsp.enter(); } - -void HitachiDSP::enter() { +#include + +#define HITACHIDSP_CPP +namespace SNES { + +#include "memory.cpp" +#include "opcodes.cpp" +#include "registers.cpp" +#include "serialization.cpp" +HitachiDSP hitachidsp; + +//zero 01-sep-2014 - dont clobber these when reconstructing! +unsigned HitachiDSP::frequency; +uint24 HitachiDSP::dataROM[1024]; + +void HitachiDSP::Enter() { hitachidsp.enter(); } + +void HitachiDSP::enter() { while(true) { - // exit requested due to savestate - if(scheduler.sync == Scheduler::SynchronizeMode::All) { - scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); + if(scheduler.sync == Scheduler::SynchronizeMode::All) { + scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); } - // if we bail out due to savestating, the first thing we'll try afterwards is synchronize_cpu() again - synchronize_cpu(); - - switch(state) { - case State::Idle: - step(1); - break; - case State::DMA: - for(unsigned n = 0; n < regs.dma_length; n++) { - bus.write(regs.dma_target + n, bus.read(regs.dma_source + n)); - step(2); - } - state = State::Idle; - break; - case State::Execute: - unsigned offset = regs.program_offset + regs.pc * 2; - opcode = bus_read(offset + 0) << 0; - opcode |= bus_read(offset + 1) << 8; - regs.pc = (regs.pc & 0xffff00) | ((regs.pc + 1) & 0x0000ff); - exec(); - step(1); - break; - } + switch(state) { + case State::Idle: + step(1); + break; + case State::DMA: + for(unsigned n = 0; n < regs.dma_length; n++) { + bus.write(regs.dma_target + n, bus.read(regs.dma_source + n)); + step(2); + } + state = State::Idle; + break; + case State::Execute: + unsigned offset = regs.program_offset + regs.pc * 2; + opcode = bus_read(offset + 0) << 0; + opcode |= bus_read(offset + 1) << 8; + regs.pc = (regs.pc & 0xffff00) | ((regs.pc + 1) & 0x0000ff); + exec(); + step(1); + break; + } - // this call is gone, but it's the first thing we try at the top of the loop AFTER we bail out - //synchronize_cpu(); - } -} - -void HitachiDSP::init() { -} - -void HitachiDSP::load() { -} - -void HitachiDSP::unload() { -} - -void HitachiDSP::power() { -} - -void HitachiDSP::reset() { - create(HitachiDSP::Enter, frequency); - state = State::Idle; - - regs.n = 0; - regs.z = 0; - regs.c = 0; - - regs.dma_source = 0x000000; - regs.dma_length = 0x0000; - regs.dma_target = 0x000000; - regs.r1f48 = 0x00; - regs.program_offset = 0x000000; - regs.r1f4c = 0x00; - regs.page_number = 0x0000; - regs.program_counter = 0x00; - regs.r1f50 = 0x33; - regs.r1f51 = 0x00; - regs.r1f52 = 0x01; -} - -} + synchronize_cpu(); + } +} + +void HitachiDSP::init() { +} + +void HitachiDSP::load() { +} + +void HitachiDSP::unload() { +} + +void HitachiDSP::power() { +} + +void HitachiDSP::reset() { + create(HitachiDSP::Enter, frequency); + state = State::Idle; + + regs.n = 0; + regs.z = 0; + regs.c = 0; + + regs.dma_source = 0x000000; + regs.dma_length = 0x0000; + regs.dma_target = 0x000000; + regs.r1f48 = 0x00; + regs.program_offset = 0x000000; + regs.r1f4c = 0x00; + regs.page_number = 0x0000; + regs.program_counter = 0x00; + regs.r1f50 = 0x33; + regs.r1f51 = 0x00; + regs.r1f52 = 0x01; +} + +} diff --git a/libsnes/bsnes/snes/chip/sa1/sa1.cpp b/libsnes/bsnes/snes/chip/sa1/sa1.cpp index a8edc92c0e..71c6310a09 100644 --- a/libsnes/bsnes/snes/chip/sa1/sa1.cpp +++ b/libsnes/bsnes/snes/chip/sa1/sa1.cpp @@ -19,25 +19,20 @@ void SA1::enter() { scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); } - if (regs.hang == HangType::Wait) this->op_wai(); - else if (regs.hang == HangType::Stop) this->op_stp(); - else - { - if(mmio.sa1_rdyb || mmio.sa1_resb) { - //SA-1 co-processor is asleep - tick(); - synchronize_cpu(); - continue; - } + if(mmio.sa1_rdyb || mmio.sa1_resb) { + //SA-1 co-processor is asleep + tick(); + synchronize_cpu(); + continue; + } - if(status.interrupt_pending) { - status.interrupt_pending = false; - op_irq(); - continue; - } + if(status.interrupt_pending) { + status.interrupt_pending = false; + op_irq(); + continue; + } - (this->*opcode_table[op_readpc()])(); - } + (this->*opcode_table[op_readpc()])(); } } diff --git a/libsnes/bsnes/snes/cpu/core/opcode_misc.cpp b/libsnes/bsnes/snes/cpu/core/opcode_misc.cpp index 6d2b72fae7..8087fe66e1 100644 --- a/libsnes/bsnes/snes/cpu/core/opcode_misc.cpp +++ b/libsnes/bsnes/snes/cpu/core/opcode_misc.cpp @@ -72,28 +72,16 @@ L rd.h = op_readlong(vectorN + 1); } void CPUcore::op_stp() { - if(regs.hang == HangType::Stop) - goto SKIP; - regs.hang = HangType::Stop; while(regs.wai = true) { L op_io(); - scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); -SKIP: ; - } - regs.hang = HangType::None; + } } void CPUcore::op_wai() { - if (regs.hang == HangType::Wait) - goto SKIP; regs.wai = true; - regs.hang = HangType::Wait; while(regs.wai) { L op_io(); - scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); - SKIP: ; - } - regs.hang = HangType::None; + } op_io(); } diff --git a/libsnes/bsnes/snes/cpu/core/registers.hpp b/libsnes/bsnes/snes/cpu/core/registers.hpp index 46fea03208..adcf797fd8 100644 --- a/libsnes/bsnes/snes/cpu/core/registers.hpp +++ b/libsnes/bsnes/snes/cpu/core/registers.hpp @@ -1,5 +1,3 @@ -enum class HangType: unsigned { None, Wait, Stop }; - struct flag_t { bool n, v, m, x, d, i, z, c; @@ -75,14 +73,11 @@ struct regs_t { bool irq; //IRQ pin (0 = low, 1 = trigger) bool wai; //raised during wai, cleared after interrupt triggered - uint8 mdr; //memory data register uint16 vector; //interrupt vector address - HangType hang; - regs_t(): - a(r[0]), x(r[1]), y(r[2]), z(r[3]), s(r[4]), d(r[5]), db(0), e(false), irq(false), wai(false), mdr(0), vector(0), hang(HangType::None) { + a(r[0]), x(r[1]), y(r[2]), z(r[3]), s(r[4]), d(r[5]), db(0), e(false), irq(false), wai(false), mdr(0), vector(0) { z = 0; } }; diff --git a/libsnes/bsnes/snes/cpu/core/serialization.cpp b/libsnes/bsnes/snes/cpu/core/serialization.cpp index 629fb6fe71..81753e9684 100644 --- a/libsnes/bsnes/snes/cpu/core/serialization.cpp +++ b/libsnes/bsnes/snes/cpu/core/serialization.cpp @@ -26,10 +26,6 @@ void CPUcore::core_serialize(serializer &s) { s.integer(regs.mdr); s.integer(regs.vector); - unsigned junk = (unsigned)regs.hang; - s.integer(junk); - regs.hang = (HangType)junk; - s.integer(aa.d); s.integer(rd.d); s.integer(sp); diff --git a/libsnes/bsnes/snes/cpu/cpu.cpp b/libsnes/bsnes/snes/cpu/cpu.cpp index 398ac0e7dd..f58a33dd0b 100644 --- a/libsnes/bsnes/snes/cpu/cpu.cpp +++ b/libsnes/bsnes/snes/cpu/cpu.cpp @@ -1,184 +1,180 @@ -#include - -#define CPU_CPP -namespace SNES { - -CPU cpu; - -#include "serialization.cpp" -#include "dma/dma.cpp" -#include "memory/memory.cpp" -#include "mmio/mmio.cpp" -#include "timing/timing.cpp" - -void CPU::step(unsigned clocks) { - smp.clock -= clocks * (uint64)smp.frequency; - ppu.clock -= clocks; - for(unsigned i = 0; i < coprocessors.size(); i++) { - Processor &chip = *coprocessors[i]; - chip.clock -= clocks * (uint64)chip.frequency; - } - input.port1->clock -= clocks * (uint64)input.port1->frequency; - input.port2->clock -= clocks * (uint64)input.port2->frequency; - synchronize_controllers(); -} - -void CPU::synchronize_smp() { - if(SMP::Threaded == true) { - if(smp.clock < 0) co_switch(smp.thread); - } else { - while(smp.clock < 0) smp.enter(); - } -} - -void CPU::synchronize_ppu() { - if(PPU::Threaded == true) { - if(ppu.clock < 0) co_switch(ppu.thread); - } else { - while(ppu.clock < 0) ppu.enter(); - } -} - -void CPU::synchronize_coprocessors() { - for(unsigned i = 0; i < coprocessors.size(); i++) { - Processor &chip = *coprocessors[i]; - if(chip.clock < 0) co_switch(chip.thread); - } -} - -void CPU::synchronize_controllers() { - if(input.port1->clock < 0) co_switch(input.port1->thread); - if(input.port2->clock < 0) co_switch(input.port2->thread); -} - -void CPU::Enter() { cpu.enter(); } - -void CPU::enter() { - while(true) { +#include + +#define CPU_CPP +namespace SNES { + +CPU cpu; + +#include "serialization.cpp" +#include "dma/dma.cpp" +#include "memory/memory.cpp" +#include "mmio/mmio.cpp" +#include "timing/timing.cpp" + +void CPU::step(unsigned clocks) { + smp.clock -= clocks * (uint64)smp.frequency; + ppu.clock -= clocks; + for(unsigned i = 0; i < coprocessors.size(); i++) { + Processor &chip = *coprocessors[i]; + chip.clock -= clocks * (uint64)chip.frequency; + } + input.port1->clock -= clocks * (uint64)input.port1->frequency; + input.port2->clock -= clocks * (uint64)input.port2->frequency; + synchronize_controllers(); +} + +void CPU::synchronize_smp() { + if(SMP::Threaded == true) { + if(smp.clock < 0) co_switch(smp.thread); + } else { + while(smp.clock < 0) smp.enter(); + } +} + +void CPU::synchronize_ppu() { + if(PPU::Threaded == true) { + if(ppu.clock < 0) co_switch(ppu.thread); + } else { + while(ppu.clock < 0) ppu.enter(); + } +} + +void CPU::synchronize_coprocessors() { + for(unsigned i = 0; i < coprocessors.size(); i++) { + Processor &chip = *coprocessors[i]; + if(chip.clock < 0) co_switch(chip.thread); + } +} + +void CPU::synchronize_controllers() { + if(input.port1->clock < 0) co_switch(input.port1->thread); + if(input.port2->clock < 0) co_switch(input.port2->thread); +} + +void CPU::Enter() { cpu.enter(); } + +void CPU::enter() { + while(true) { if(scheduler.sync == Scheduler::SynchronizeMode::CPU) { - // we can only stop if there's enough time for at least one more event - // on both the PPU and the SMP - if (smp.clock < 0 && ppu.clock < 0) { - scheduler.sync = Scheduler::SynchronizeMode::All; - scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); - } - } - - if(status.interrupt_pending) { - status.interrupt_pending = false; - if(status.nmi_pending) { - status.nmi_pending = false; - regs.vector = (regs.e == false ? 0xffea : 0xfffa); - op_irq(); - debugger.op_nmi(); - } else if(status.irq_pending) { - status.irq_pending = false; - regs.vector = (regs.e == false ? 0xffee : 0xfffe); - op_irq(); - debugger.op_irq(); - } else if(status.reset_pending) { - status.reset_pending = false; - add_clocks(186); - regs.pc.l = bus.read(0xfffc); - regs.pc.h = bus.read(0xfffd); - } - } - - op_step(); - } -} - -void CPU::op_step() { - debugger.op_exec(regs.pc.d); - - if (interface()->wanttrace & TRACE_CPU_MASK) - { - char tmp[512]; - disassemble_opcode(tmp, regs.pc.d); - tmp[511] = 0; - interface()->cpuTrace(TRACE_CPU, tmp); - } - - (this->*opcode_table[op_readpcfirst()])(); -} - -void CPU::enable() { - function read = { &CPU::mmio_read, (CPU*)&cpu }; - function write = { &CPU::mmio_write, (CPU*)&cpu }; - - bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x2140, 0x2183, read, write); - bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x2140, 0x2183, read, write); - - bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x4016, 0x4017, read, write); - bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x4016, 0x4017, read, write); - - bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x4200, 0x421f, read, write); - bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x4200, 0x421f, read, write); - - bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x4300, 0x437f, read, write); - bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x4300, 0x437f, read, write); - - read = [](unsigned addr) { cdlInfo.set(eCDLog_AddrType_WRAM, addr); return cpu.wram[addr]; }; - write = [](unsigned addr, uint8 data) { cpu.wram[addr] = data; }; - - bus.map(Bus::MapMode::Linear, 0x00, 0x3f, 0x0000, 0x1fff, read, write, 0x000000, 0x002000); - bus.map(Bus::MapMode::Linear, 0x80, 0xbf, 0x0000, 0x1fff, read, write, 0x000000, 0x002000); - bus.map(Bus::MapMode::Linear, 0x7e, 0x7f, 0x0000, 0xffff, read, write); -} - -void CPU::power() { - cpu_version = config.cpu.version; - for(int i=0;i<128*1024;i++) wram[i] = random(config.cpu.wram_init_value); - - regs.a = regs.x = regs.y = 0x0000; - regs.s = 0x01ff; - - mmio_power(); - dma_power(); - timing_power(); - - //zero 01-dec-2012 - //gotta clear these to something, sometime - aa.d = rd.d = sp = dp = 0; -} - -void CPU::reset() { - create(Enter, system.cpu_frequency()); - coprocessors.reset(); - PPUcounter::reset(); - - //note: some registers are not fully reset by SNES - regs.pc = 0x000000; - regs.x.h = 0x00; - regs.y.h = 0x00; - regs.s.h = 0x01; - regs.d = 0x0000; - regs.db = 0x00; - regs.p = 0x34; - regs.e = 1; - regs.mdr = 0x00; - regs.wai = false; - regs.vector = 0xfffc; //reset vector address - update_table(); - - mmio_reset(); - dma_reset(); - timing_reset(); -} - -CPU::CPU() - : wram(nullptr) -{ - PPUcounter::scanline = { &CPU::scanline, this }; -} - -CPU::~CPU() { - interface()->freeSharedMemory(wram); -} - -void CPU::initialize() -{ - wram = (uint8*)interface()->allocSharedMemory("WRAM",128 * 1024); -} - -} + scheduler.sync = Scheduler::SynchronizeMode::All; + scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); + } + + if(status.interrupt_pending) { + status.interrupt_pending = false; + if(status.nmi_pending) { + status.nmi_pending = false; + regs.vector = (regs.e == false ? 0xffea : 0xfffa); + op_irq(); + debugger.op_nmi(); + } else if(status.irq_pending) { + status.irq_pending = false; + regs.vector = (regs.e == false ? 0xffee : 0xfffe); + op_irq(); + debugger.op_irq(); + } else if(status.reset_pending) { + status.reset_pending = false; + add_clocks(186); + regs.pc.l = bus.read(0xfffc); + regs.pc.h = bus.read(0xfffd); + } + } + + op_step(); + } +} + +void CPU::op_step() { + debugger.op_exec(regs.pc.d); + + if (interface()->wanttrace & TRACE_CPU_MASK) + { + char tmp[512]; + disassemble_opcode(tmp, regs.pc.d); + tmp[511] = 0; + interface()->cpuTrace(TRACE_CPU, tmp); + } + + (this->*opcode_table[op_readpcfirst()])(); +} + +void CPU::enable() { + function read = { &CPU::mmio_read, (CPU*)&cpu }; + function write = { &CPU::mmio_write, (CPU*)&cpu }; + + bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x2140, 0x2183, read, write); + bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x2140, 0x2183, read, write); + + bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x4016, 0x4017, read, write); + bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x4016, 0x4017, read, write); + + bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x4200, 0x421f, read, write); + bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x4200, 0x421f, read, write); + + bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x4300, 0x437f, read, write); + bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x4300, 0x437f, read, write); + + read = [](unsigned addr) { cdlInfo.set(eCDLog_AddrType_WRAM, addr); return cpu.wram[addr]; }; + write = [](unsigned addr, uint8 data) { cpu.wram[addr] = data; }; + + bus.map(Bus::MapMode::Linear, 0x00, 0x3f, 0x0000, 0x1fff, read, write, 0x000000, 0x002000); + bus.map(Bus::MapMode::Linear, 0x80, 0xbf, 0x0000, 0x1fff, read, write, 0x000000, 0x002000); + bus.map(Bus::MapMode::Linear, 0x7e, 0x7f, 0x0000, 0xffff, read, write); +} + +void CPU::power() { + cpu_version = config.cpu.version; + for(int i=0;i<128*1024;i++) wram[i] = random(config.cpu.wram_init_value); + + regs.a = regs.x = regs.y = 0x0000; + regs.s = 0x01ff; + + mmio_power(); + dma_power(); + timing_power(); + + //zero 01-dec-2012 + //gotta clear these to something, sometime + aa.d = rd.d = sp = dp = 0; +} + +void CPU::reset() { + create(Enter, system.cpu_frequency()); + coprocessors.reset(); + PPUcounter::reset(); + + //note: some registers are not fully reset by SNES + regs.pc = 0x000000; + regs.x.h = 0x00; + regs.y.h = 0x00; + regs.s.h = 0x01; + regs.d = 0x0000; + regs.db = 0x00; + regs.p = 0x34; + regs.e = 1; + regs.mdr = 0x00; + regs.wai = false; + regs.vector = 0xfffc; //reset vector address + update_table(); + + mmio_reset(); + dma_reset(); + timing_reset(); +} + +CPU::CPU() + : wram(nullptr) +{ + PPUcounter::scanline = { &CPU::scanline, this }; +} + +CPU::~CPU() { + interface()->freeSharedMemory(wram); +} + +void CPU::initialize() +{ + wram = (uint8*)interface()->allocSharedMemory("WRAM",128 * 1024); +} + +} diff --git a/libsnes/bsnes/snes/smp/core/core.cpp b/libsnes/bsnes/snes/smp/core/core.cpp index 915efa3ad4..690612ae00 100644 --- a/libsnes/bsnes/snes/smp/core/core.cpp +++ b/libsnes/bsnes/snes/smp/core/core.cpp @@ -1,275 +1,272 @@ -#include - -#define SMPCORE_CPP -namespace SNES { - -#include "algorithms.cpp" -//#include "opcodes.cpp" -#include "disassembler.cpp" -#include "serialization.cpp" +#include -#include "uop.cpp" +#define SMPCORE_CPP +namespace SNES { -/* -void SMPcore::op_step() { - switch(opcode = op_readpc()) { - case 0x00: return op_nop(); - case 0x01: return op_jst(); - case 0x02: return op_set_bit(); - case 0x03: return op_branch_bit(); - case 0x04: return op_read_dp<&SMPcore::op_or>(regs.a); - case 0x05: return op_read_addr<&SMPcore::op_or>(regs.a); - case 0x06: return op_read_ix<&SMPcore::op_or>(); - case 0x07: return op_read_idpx<&SMPcore::op_or>(); - case 0x08: return op_read_const<&SMPcore::op_or>(regs.a); - case 0x09: return op_write_dp_dp<&SMPcore::op_or>(); - case 0x0a: return op_set_addr_bit(); - case 0x0b: return op_adjust_dp<&SMPcore::op_asl>(); - case 0x0c: return op_adjust_addr<&SMPcore::op_asl>(); - case 0x0d: return op_push(regs.p); - case 0x0e: return op_test_addr(1); - case 0x0f: return op_brk(); - case 0x10: return op_branch(regs.p.n == 0); - case 0x11: return op_jst(); - case 0x12: return op_set_bit(); - case 0x13: return op_branch_bit(); - case 0x14: return op_read_dpi<&SMPcore::op_or>(regs.a, regs.x); - case 0x15: return op_read_addri<&SMPcore::op_or>(regs.x); - case 0x16: return op_read_addri<&SMPcore::op_or>(regs.y); - case 0x17: return op_read_idpy<&SMPcore::op_or>(); - case 0x18: return op_write_dp_const<&SMPcore::op_or>(); - case 0x19: return op_write_ix_iy<&SMPcore::op_or>(); - case 0x1a: return op_adjust_dpw(-1); - case 0x1b: return op_adjust_dpx<&SMPcore::op_asl>(); - case 0x1c: return op_adjust<&SMPcore::op_asl>(regs.a); - case 0x1d: return op_adjust<&SMPcore::op_dec>(regs.x); - case 0x1e: return op_read_addr<&SMPcore::op_cmp>(regs.x); - case 0x1f: return op_jmp_iaddrx(); - case 0x20: return op_set_flag(regs.p.p, 0); - case 0x21: return op_jst(); - case 0x22: return op_set_bit(); - case 0x23: return op_branch_bit(); - case 0x24: return op_read_dp<&SMPcore::op_and>(regs.a); - case 0x25: return op_read_addr<&SMPcore::op_and>(regs.a); - case 0x26: return op_read_ix<&SMPcore::op_and>(); - case 0x27: return op_read_idpx<&SMPcore::op_and>(); - case 0x28: return op_read_const<&SMPcore::op_and>(regs.a); - case 0x29: return op_write_dp_dp<&SMPcore::op_and>(); - case 0x2a: return op_set_addr_bit(); - case 0x2b: return op_adjust_dp<&SMPcore::op_rol>(); - case 0x2c: return op_adjust_addr<&SMPcore::op_rol>(); - case 0x2d: return op_push(regs.a); - case 0x2e: return op_bne_dp(); - case 0x2f: return op_branch(true); - case 0x30: return op_branch(regs.p.n == 1); - case 0x31: return op_jst(); - case 0x32: return op_set_bit(); - case 0x33: return op_branch_bit(); - case 0x34: return op_read_dpi<&SMPcore::op_and>(regs.a, regs.x); - case 0x35: return op_read_addri<&SMPcore::op_and>(regs.x); - case 0x36: return op_read_addri<&SMPcore::op_and>(regs.y); - case 0x37: return op_read_idpy<&SMPcore::op_and>(); - case 0x38: return op_write_dp_const<&SMPcore::op_and>(); - case 0x39: return op_write_ix_iy<&SMPcore::op_and>(); - case 0x3a: return op_adjust_dpw(+1); - case 0x3b: return op_adjust_dpx<&SMPcore::op_rol>(); - case 0x3c: return op_adjust<&SMPcore::op_rol>(regs.a); - case 0x3d: return op_adjust<&SMPcore::op_inc>(regs.x); - case 0x3e: return op_read_dp<&SMPcore::op_cmp>(regs.x); - case 0x3f: return op_jsr_addr(); - case 0x40: return op_set_flag(regs.p.p, 1); - case 0x41: return op_jst(); - case 0x42: return op_set_bit(); - case 0x43: return op_branch_bit(); - case 0x44: return op_read_dp<&SMPcore::op_eor>(regs.a); - case 0x45: return op_read_addr<&SMPcore::op_eor>(regs.a); - case 0x46: return op_read_ix<&SMPcore::op_eor>(); - case 0x47: return op_read_idpx<&SMPcore::op_eor>(); - case 0x48: return op_read_const<&SMPcore::op_eor>(regs.a); - case 0x49: return op_write_dp_dp<&SMPcore::op_eor>(); - case 0x4a: return op_set_addr_bit(); - case 0x4b: return op_adjust_dp<&SMPcore::op_lsr>(); - case 0x4c: return op_adjust_addr<&SMPcore::op_lsr>(); - case 0x4d: return op_push(regs.x); - case 0x4e: return op_test_addr(0); - case 0x4f: return op_jsp_dp(); - case 0x50: return op_branch(regs.p.v == 0); - case 0x51: return op_jst(); - case 0x52: return op_set_bit(); - case 0x53: return op_branch_bit(); - case 0x54: return op_read_dpi<&SMPcore::op_eor>(regs.a, regs.x); - case 0x55: return op_read_addri<&SMPcore::op_eor>(regs.x); - case 0x56: return op_read_addri<&SMPcore::op_eor>(regs.y); - case 0x57: return op_read_idpy<&SMPcore::op_eor>(); - case 0x58: return op_write_dp_const<&SMPcore::op_eor>(); - case 0x59: return op_write_ix_iy<&SMPcore::op_eor>(); - case 0x5a: return op_read_dpw<&SMPcore::op_cpw>(); - case 0x5b: return op_adjust_dpx<&SMPcore::op_lsr>(); - case 0x5c: return op_adjust<&SMPcore::op_lsr>(regs.a); - case 0x5d: return op_transfer(regs.a, regs.x); - case 0x5e: return op_read_addr<&SMPcore::op_cmp>(regs.y); - case 0x5f: return op_jmp_addr(); - case 0x60: return op_set_flag(regs.p.c, 0); - case 0x61: return op_jst(); - case 0x62: return op_set_bit(); - case 0x63: return op_branch_bit(); - case 0x64: return op_read_dp<&SMPcore::op_cmp>(regs.a); - case 0x65: return op_read_addr<&SMPcore::op_cmp>(regs.a); - case 0x66: return op_read_ix<&SMPcore::op_cmp>(); - case 0x67: return op_read_idpx<&SMPcore::op_cmp>(); - case 0x68: return op_read_const<&SMPcore::op_cmp>(regs.a); - case 0x69: return op_write_dp_dp<&SMPcore::op_cmp>(); - case 0x6a: return op_set_addr_bit(); - case 0x6b: return op_adjust_dp<&SMPcore::op_ror>(); - case 0x6c: return op_adjust_addr<&SMPcore::op_ror>(); - case 0x6d: return op_push(regs.y); - case 0x6e: return op_bne_dpdec(); - case 0x6f: return op_rts(); - case 0x70: return op_branch(regs.p.v == 1); - case 0x71: return op_jst(); - case 0x72: return op_set_bit(); - case 0x73: return op_branch_bit(); - case 0x74: return op_read_dpi<&SMPcore::op_cmp>(regs.a, regs.x); - case 0x75: return op_read_addri<&SMPcore::op_cmp>(regs.x); - case 0x76: return op_read_addri<&SMPcore::op_cmp>(regs.y); - case 0x77: return op_read_idpy<&SMPcore::op_cmp>(); - case 0x78: return op_write_dp_const<&SMPcore::op_cmp>(); - case 0x79: return op_write_ix_iy<&SMPcore::op_cmp>(); - case 0x7a: return op_read_dpw<&SMPcore::op_adw>(); - case 0x7b: return op_adjust_dpx<&SMPcore::op_ror>(); - case 0x7c: return op_adjust<&SMPcore::op_ror>(regs.a); - case 0x7d: return op_transfer(regs.x, regs.a); - case 0x7e: return op_read_dp<&SMPcore::op_cmp>(regs.y); - case 0x7f: return op_rti(); - case 0x80: return op_set_flag(regs.p.c, 1); - case 0x81: return op_jst(); - case 0x82: return op_set_bit(); - case 0x83: return op_branch_bit(); - case 0x84: return op_read_dp<&SMPcore::op_adc>(regs.a); - case 0x85: return op_read_addr<&SMPcore::op_adc>(regs.a); - case 0x86: return op_read_ix<&SMPcore::op_adc>(); - case 0x87: return op_read_idpx<&SMPcore::op_adc>(); - case 0x88: return op_read_const<&SMPcore::op_adc>(regs.a); - case 0x89: return op_write_dp_dp<&SMPcore::op_adc>(); - case 0x8a: return op_set_addr_bit(); - case 0x8b: return op_adjust_dp<&SMPcore::op_dec>(); - case 0x8c: return op_adjust_addr<&SMPcore::op_dec>(); - case 0x8d: return op_read_const<&SMPcore::op_ld>(regs.y); - case 0x8e: return op_plp(); - case 0x8f: return op_write_dp_const<&SMPcore::op_st>(); - case 0x90: return op_branch(regs.p.c == 0); - case 0x91: return op_jst(); - case 0x92: return op_set_bit(); - case 0x93: return op_branch_bit(); - case 0x94: return op_read_dpi<&SMPcore::op_adc>(regs.a, regs.x); - case 0x95: return op_read_addri<&SMPcore::op_adc>(regs.x); - case 0x96: return op_read_addri<&SMPcore::op_adc>(regs.y); - case 0x97: return op_read_idpy<&SMPcore::op_adc>(); - case 0x98: return op_write_dp_const<&SMPcore::op_adc>(); - case 0x99: return op_write_ix_iy<&SMPcore::op_adc>(); - case 0x9a: return op_read_dpw<&SMPcore::op_sbw>(); - case 0x9b: return op_adjust_dpx<&SMPcore::op_dec>(); - case 0x9c: return op_adjust<&SMPcore::op_dec>(regs.a); - case 0x9d: return op_transfer(regs.s, regs.x); - case 0x9e: return op_div_ya_x(); - case 0x9f: return op_xcn(); - case 0xa0: return op_set_flag(regs.p.i, 1); - case 0xa1: return op_jst(); - case 0xa2: return op_set_bit(); - case 0xa3: return op_branch_bit(); - case 0xa4: return op_read_dp<&SMPcore::op_sbc>(regs.a); - case 0xa5: return op_read_addr<&SMPcore::op_sbc>(regs.a); - case 0xa6: return op_read_ix<&SMPcore::op_sbc>(); - case 0xa7: return op_read_idpx<&SMPcore::op_sbc>(); - case 0xa8: return op_read_const<&SMPcore::op_sbc>(regs.a); - case 0xa9: return op_write_dp_dp<&SMPcore::op_sbc>(); - case 0xaa: return op_set_addr_bit(); - case 0xab: return op_adjust_dp<&SMPcore::op_inc>(); - case 0xac: return op_adjust_addr<&SMPcore::op_inc>(); - case 0xad: return op_read_const<&SMPcore::op_cmp>(regs.y); - case 0xae: return op_pull(regs.a); - case 0xaf: return op_sta_ixinc(); - case 0xb0: return op_branch(regs.p.c == 1); - case 0xb1: return op_jst(); - case 0xb2: return op_set_bit(); - case 0xb3: return op_branch_bit(); - case 0xb4: return op_read_dpi<&SMPcore::op_sbc>(regs.a, regs.x); - case 0xb5: return op_read_addri<&SMPcore::op_sbc>(regs.x); - case 0xb6: return op_read_addri<&SMPcore::op_sbc>(regs.y); - case 0xb7: return op_read_idpy<&SMPcore::op_sbc>(); - case 0xb8: return op_write_dp_const<&SMPcore::op_sbc>(); - case 0xb9: return op_write_ix_iy<&SMPcore::op_sbc>(); - case 0xba: return op_read_dpw<&SMPcore::op_ldw>(); - case 0xbb: return op_adjust_dpx<&SMPcore::op_inc>(); - case 0xbc: return op_adjust<&SMPcore::op_inc>(regs.a); - case 0xbd: return op_transfer(regs.x, regs.s); - case 0xbe: return op_das(); - case 0xbf: return op_lda_ixinc(); - case 0xc0: return op_set_flag(regs.p.i, 0); - case 0xc1: return op_jst(); - case 0xc2: return op_set_bit(); - case 0xc3: return op_branch_bit(); - case 0xc4: return op_write_dp(regs.a); - case 0xc5: return op_write_addr(regs.a); - case 0xc6: return op_sta_ix(); - case 0xc7: return op_sta_idpx(); - case 0xc8: return op_read_const<&SMPcore::op_cmp>(regs.x); - case 0xc9: return op_write_addr(regs.x); - case 0xca: return op_set_addr_bit(); - case 0xcb: return op_write_dp(regs.y); - case 0xcc: return op_write_addr(regs.y); - case 0xcd: return op_read_const<&SMPcore::op_ld>(regs.x); - case 0xce: return op_pull(regs.x); - case 0xcf: return op_mul_ya(); - case 0xd0: return op_branch(regs.p.z == 0); - case 0xd1: return op_jst(); - case 0xd2: return op_set_bit(); - case 0xd3: return op_branch_bit(); - case 0xd4: return op_write_dpi(regs.a, regs.x); - case 0xd5: return op_write_addri(regs.x); - case 0xd6: return op_write_addri(regs.y); - case 0xd7: return op_sta_idpy(); - case 0xd8: return op_write_dp(regs.x); - case 0xd9: return op_write_dpi(regs.x, regs.y); - case 0xda: return op_stw_dp(); - case 0xdb: return op_write_dpi(regs.y, regs.x); - case 0xdc: return op_adjust<&SMPcore::op_dec>(regs.y); - case 0xdd: return op_transfer(regs.y, regs.a); - case 0xde: return op_bne_dpx(); - case 0xdf: return op_daa(); - case 0xe0: return op_clv(); - case 0xe1: return op_jst(); - case 0xe2: return op_set_bit(); - case 0xe3: return op_branch_bit(); - case 0xe4: return op_read_dp<&SMPcore::op_ld>(regs.a); - case 0xe5: return op_read_addr<&SMPcore::op_ld>(regs.a); - case 0xe6: return op_read_ix<&SMPcore::op_ld>(); - case 0xe7: return op_read_idpx<&SMPcore::op_ld>(); - case 0xe8: return op_read_const<&SMPcore::op_ld>(regs.a); - case 0xe9: return op_read_addr<&SMPcore::op_ld>(regs.x); - case 0xea: return op_set_addr_bit(); - case 0xeb: return op_read_dp<&SMPcore::op_ld>(regs.y); - case 0xec: return op_read_addr<&SMPcore::op_ld>(regs.y); - case 0xed: return op_cmc(); - case 0xee: return op_pull(regs.y); - case 0xef: return op_wait(); - case 0xf0: return op_branch(regs.p.z == 1); - case 0xf1: return op_jst(); - case 0xf2: return op_set_bit(); - case 0xf3: return op_branch_bit(); - case 0xf4: return op_read_dpi<&SMPcore::op_ld>(regs.a, regs.x); - case 0xf5: return op_read_addri<&SMPcore::op_ld>(regs.x); - case 0xf6: return op_read_addri<&SMPcore::op_ld>(regs.y); - case 0xf7: return op_read_idpy<&SMPcore::op_ld>(); - case 0xf8: return op_read_dp<&SMPcore::op_ld>(regs.x); - case 0xf9: return op_read_dpi<&SMPcore::op_ld>(regs.x, regs.y); - case 0xfa: return op_write_dp_dp<&SMPcore::op_st>(); - case 0xfb: return op_read_dpi<&SMPcore::op_ld>(regs.y, regs.x); - case 0xfc: return op_adjust<&SMPcore::op_inc>(regs.y); - case 0xfd: return op_transfer(regs.a, regs.y); - case 0xfe: return op_bne_ydec(); - case 0xff: return op_wait(); - } -} -*/ -} +#include "algorithms.cpp" +#include "opcodes.cpp" +#include "disassembler.cpp" +#include "serialization.cpp" + +void SMPcore::op_step() { + switch(opcode = op_readpc()) { + case 0x00: return op_nop(); + case 0x01: return op_jst(); + case 0x02: return op_set_bit(); + case 0x03: return op_branch_bit(); + case 0x04: return op_read_dp<&SMPcore::op_or>(regs.a); + case 0x05: return op_read_addr<&SMPcore::op_or>(regs.a); + case 0x06: return op_read_ix<&SMPcore::op_or>(); + case 0x07: return op_read_idpx<&SMPcore::op_or>(); + case 0x08: return op_read_const<&SMPcore::op_or>(regs.a); + case 0x09: return op_write_dp_dp<&SMPcore::op_or>(); + case 0x0a: return op_set_addr_bit(); + case 0x0b: return op_adjust_dp<&SMPcore::op_asl>(); + case 0x0c: return op_adjust_addr<&SMPcore::op_asl>(); + case 0x0d: return op_push(regs.p); + case 0x0e: return op_test_addr(1); + case 0x0f: return op_brk(); + case 0x10: return op_branch(regs.p.n == 0); + case 0x11: return op_jst(); + case 0x12: return op_set_bit(); + case 0x13: return op_branch_bit(); + case 0x14: return op_read_dpi<&SMPcore::op_or>(regs.a, regs.x); + case 0x15: return op_read_addri<&SMPcore::op_or>(regs.x); + case 0x16: return op_read_addri<&SMPcore::op_or>(regs.y); + case 0x17: return op_read_idpy<&SMPcore::op_or>(); + case 0x18: return op_write_dp_const<&SMPcore::op_or>(); + case 0x19: return op_write_ix_iy<&SMPcore::op_or>(); + case 0x1a: return op_adjust_dpw(-1); + case 0x1b: return op_adjust_dpx<&SMPcore::op_asl>(); + case 0x1c: return op_adjust<&SMPcore::op_asl>(regs.a); + case 0x1d: return op_adjust<&SMPcore::op_dec>(regs.x); + case 0x1e: return op_read_addr<&SMPcore::op_cmp>(regs.x); + case 0x1f: return op_jmp_iaddrx(); + case 0x20: return op_set_flag(regs.p.p, 0); + case 0x21: return op_jst(); + case 0x22: return op_set_bit(); + case 0x23: return op_branch_bit(); + case 0x24: return op_read_dp<&SMPcore::op_and>(regs.a); + case 0x25: return op_read_addr<&SMPcore::op_and>(regs.a); + case 0x26: return op_read_ix<&SMPcore::op_and>(); + case 0x27: return op_read_idpx<&SMPcore::op_and>(); + case 0x28: return op_read_const<&SMPcore::op_and>(regs.a); + case 0x29: return op_write_dp_dp<&SMPcore::op_and>(); + case 0x2a: return op_set_addr_bit(); + case 0x2b: return op_adjust_dp<&SMPcore::op_rol>(); + case 0x2c: return op_adjust_addr<&SMPcore::op_rol>(); + case 0x2d: return op_push(regs.a); + case 0x2e: return op_bne_dp(); + case 0x2f: return op_branch(true); + case 0x30: return op_branch(regs.p.n == 1); + case 0x31: return op_jst(); + case 0x32: return op_set_bit(); + case 0x33: return op_branch_bit(); + case 0x34: return op_read_dpi<&SMPcore::op_and>(regs.a, regs.x); + case 0x35: return op_read_addri<&SMPcore::op_and>(regs.x); + case 0x36: return op_read_addri<&SMPcore::op_and>(regs.y); + case 0x37: return op_read_idpy<&SMPcore::op_and>(); + case 0x38: return op_write_dp_const<&SMPcore::op_and>(); + case 0x39: return op_write_ix_iy<&SMPcore::op_and>(); + case 0x3a: return op_adjust_dpw(+1); + case 0x3b: return op_adjust_dpx<&SMPcore::op_rol>(); + case 0x3c: return op_adjust<&SMPcore::op_rol>(regs.a); + case 0x3d: return op_adjust<&SMPcore::op_inc>(regs.x); + case 0x3e: return op_read_dp<&SMPcore::op_cmp>(regs.x); + case 0x3f: return op_jsr_addr(); + case 0x40: return op_set_flag(regs.p.p, 1); + case 0x41: return op_jst(); + case 0x42: return op_set_bit(); + case 0x43: return op_branch_bit(); + case 0x44: return op_read_dp<&SMPcore::op_eor>(regs.a); + case 0x45: return op_read_addr<&SMPcore::op_eor>(regs.a); + case 0x46: return op_read_ix<&SMPcore::op_eor>(); + case 0x47: return op_read_idpx<&SMPcore::op_eor>(); + case 0x48: return op_read_const<&SMPcore::op_eor>(regs.a); + case 0x49: return op_write_dp_dp<&SMPcore::op_eor>(); + case 0x4a: return op_set_addr_bit(); + case 0x4b: return op_adjust_dp<&SMPcore::op_lsr>(); + case 0x4c: return op_adjust_addr<&SMPcore::op_lsr>(); + case 0x4d: return op_push(regs.x); + case 0x4e: return op_test_addr(0); + case 0x4f: return op_jsp_dp(); + case 0x50: return op_branch(regs.p.v == 0); + case 0x51: return op_jst(); + case 0x52: return op_set_bit(); + case 0x53: return op_branch_bit(); + case 0x54: return op_read_dpi<&SMPcore::op_eor>(regs.a, regs.x); + case 0x55: return op_read_addri<&SMPcore::op_eor>(regs.x); + case 0x56: return op_read_addri<&SMPcore::op_eor>(regs.y); + case 0x57: return op_read_idpy<&SMPcore::op_eor>(); + case 0x58: return op_write_dp_const<&SMPcore::op_eor>(); + case 0x59: return op_write_ix_iy<&SMPcore::op_eor>(); + case 0x5a: return op_read_dpw<&SMPcore::op_cpw>(); + case 0x5b: return op_adjust_dpx<&SMPcore::op_lsr>(); + case 0x5c: return op_adjust<&SMPcore::op_lsr>(regs.a); + case 0x5d: return op_transfer(regs.a, regs.x); + case 0x5e: return op_read_addr<&SMPcore::op_cmp>(regs.y); + case 0x5f: return op_jmp_addr(); + case 0x60: return op_set_flag(regs.p.c, 0); + case 0x61: return op_jst(); + case 0x62: return op_set_bit(); + case 0x63: return op_branch_bit(); + case 0x64: return op_read_dp<&SMPcore::op_cmp>(regs.a); + case 0x65: return op_read_addr<&SMPcore::op_cmp>(regs.a); + case 0x66: return op_read_ix<&SMPcore::op_cmp>(); + case 0x67: return op_read_idpx<&SMPcore::op_cmp>(); + case 0x68: return op_read_const<&SMPcore::op_cmp>(regs.a); + case 0x69: return op_write_dp_dp<&SMPcore::op_cmp>(); + case 0x6a: return op_set_addr_bit(); + case 0x6b: return op_adjust_dp<&SMPcore::op_ror>(); + case 0x6c: return op_adjust_addr<&SMPcore::op_ror>(); + case 0x6d: return op_push(regs.y); + case 0x6e: return op_bne_dpdec(); + case 0x6f: return op_rts(); + case 0x70: return op_branch(regs.p.v == 1); + case 0x71: return op_jst(); + case 0x72: return op_set_bit(); + case 0x73: return op_branch_bit(); + case 0x74: return op_read_dpi<&SMPcore::op_cmp>(regs.a, regs.x); + case 0x75: return op_read_addri<&SMPcore::op_cmp>(regs.x); + case 0x76: return op_read_addri<&SMPcore::op_cmp>(regs.y); + case 0x77: return op_read_idpy<&SMPcore::op_cmp>(); + case 0x78: return op_write_dp_const<&SMPcore::op_cmp>(); + case 0x79: return op_write_ix_iy<&SMPcore::op_cmp>(); + case 0x7a: return op_read_dpw<&SMPcore::op_adw>(); + case 0x7b: return op_adjust_dpx<&SMPcore::op_ror>(); + case 0x7c: return op_adjust<&SMPcore::op_ror>(regs.a); + case 0x7d: return op_transfer(regs.x, regs.a); + case 0x7e: return op_read_dp<&SMPcore::op_cmp>(regs.y); + case 0x7f: return op_rti(); + case 0x80: return op_set_flag(regs.p.c, 1); + case 0x81: return op_jst(); + case 0x82: return op_set_bit(); + case 0x83: return op_branch_bit(); + case 0x84: return op_read_dp<&SMPcore::op_adc>(regs.a); + case 0x85: return op_read_addr<&SMPcore::op_adc>(regs.a); + case 0x86: return op_read_ix<&SMPcore::op_adc>(); + case 0x87: return op_read_idpx<&SMPcore::op_adc>(); + case 0x88: return op_read_const<&SMPcore::op_adc>(regs.a); + case 0x89: return op_write_dp_dp<&SMPcore::op_adc>(); + case 0x8a: return op_set_addr_bit(); + case 0x8b: return op_adjust_dp<&SMPcore::op_dec>(); + case 0x8c: return op_adjust_addr<&SMPcore::op_dec>(); + case 0x8d: return op_read_const<&SMPcore::op_ld>(regs.y); + case 0x8e: return op_plp(); + case 0x8f: return op_write_dp_const<&SMPcore::op_st>(); + case 0x90: return op_branch(regs.p.c == 0); + case 0x91: return op_jst(); + case 0x92: return op_set_bit(); + case 0x93: return op_branch_bit(); + case 0x94: return op_read_dpi<&SMPcore::op_adc>(regs.a, regs.x); + case 0x95: return op_read_addri<&SMPcore::op_adc>(regs.x); + case 0x96: return op_read_addri<&SMPcore::op_adc>(regs.y); + case 0x97: return op_read_idpy<&SMPcore::op_adc>(); + case 0x98: return op_write_dp_const<&SMPcore::op_adc>(); + case 0x99: return op_write_ix_iy<&SMPcore::op_adc>(); + case 0x9a: return op_read_dpw<&SMPcore::op_sbw>(); + case 0x9b: return op_adjust_dpx<&SMPcore::op_dec>(); + case 0x9c: return op_adjust<&SMPcore::op_dec>(regs.a); + case 0x9d: return op_transfer(regs.s, regs.x); + case 0x9e: return op_div_ya_x(); + case 0x9f: return op_xcn(); + case 0xa0: return op_set_flag(regs.p.i, 1); + case 0xa1: return op_jst(); + case 0xa2: return op_set_bit(); + case 0xa3: return op_branch_bit(); + case 0xa4: return op_read_dp<&SMPcore::op_sbc>(regs.a); + case 0xa5: return op_read_addr<&SMPcore::op_sbc>(regs.a); + case 0xa6: return op_read_ix<&SMPcore::op_sbc>(); + case 0xa7: return op_read_idpx<&SMPcore::op_sbc>(); + case 0xa8: return op_read_const<&SMPcore::op_sbc>(regs.a); + case 0xa9: return op_write_dp_dp<&SMPcore::op_sbc>(); + case 0xaa: return op_set_addr_bit(); + case 0xab: return op_adjust_dp<&SMPcore::op_inc>(); + case 0xac: return op_adjust_addr<&SMPcore::op_inc>(); + case 0xad: return op_read_const<&SMPcore::op_cmp>(regs.y); + case 0xae: return op_pull(regs.a); + case 0xaf: return op_sta_ixinc(); + case 0xb0: return op_branch(regs.p.c == 1); + case 0xb1: return op_jst(); + case 0xb2: return op_set_bit(); + case 0xb3: return op_branch_bit(); + case 0xb4: return op_read_dpi<&SMPcore::op_sbc>(regs.a, regs.x); + case 0xb5: return op_read_addri<&SMPcore::op_sbc>(regs.x); + case 0xb6: return op_read_addri<&SMPcore::op_sbc>(regs.y); + case 0xb7: return op_read_idpy<&SMPcore::op_sbc>(); + case 0xb8: return op_write_dp_const<&SMPcore::op_sbc>(); + case 0xb9: return op_write_ix_iy<&SMPcore::op_sbc>(); + case 0xba: return op_read_dpw<&SMPcore::op_ldw>(); + case 0xbb: return op_adjust_dpx<&SMPcore::op_inc>(); + case 0xbc: return op_adjust<&SMPcore::op_inc>(regs.a); + case 0xbd: return op_transfer(regs.x, regs.s); + case 0xbe: return op_das(); + case 0xbf: return op_lda_ixinc(); + case 0xc0: return op_set_flag(regs.p.i, 0); + case 0xc1: return op_jst(); + case 0xc2: return op_set_bit(); + case 0xc3: return op_branch_bit(); + case 0xc4: return op_write_dp(regs.a); + case 0xc5: return op_write_addr(regs.a); + case 0xc6: return op_sta_ix(); + case 0xc7: return op_sta_idpx(); + case 0xc8: return op_read_const<&SMPcore::op_cmp>(regs.x); + case 0xc9: return op_write_addr(regs.x); + case 0xca: return op_set_addr_bit(); + case 0xcb: return op_write_dp(regs.y); + case 0xcc: return op_write_addr(regs.y); + case 0xcd: return op_read_const<&SMPcore::op_ld>(regs.x); + case 0xce: return op_pull(regs.x); + case 0xcf: return op_mul_ya(); + case 0xd0: return op_branch(regs.p.z == 0); + case 0xd1: return op_jst(); + case 0xd2: return op_set_bit(); + case 0xd3: return op_branch_bit(); + case 0xd4: return op_write_dpi(regs.a, regs.x); + case 0xd5: return op_write_addri(regs.x); + case 0xd6: return op_write_addri(regs.y); + case 0xd7: return op_sta_idpy(); + case 0xd8: return op_write_dp(regs.x); + case 0xd9: return op_write_dpi(regs.x, regs.y); + case 0xda: return op_stw_dp(); + case 0xdb: return op_write_dpi(regs.y, regs.x); + case 0xdc: return op_adjust<&SMPcore::op_dec>(regs.y); + case 0xdd: return op_transfer(regs.y, regs.a); + case 0xde: return op_bne_dpx(); + case 0xdf: return op_daa(); + case 0xe0: return op_clv(); + case 0xe1: return op_jst(); + case 0xe2: return op_set_bit(); + case 0xe3: return op_branch_bit(); + case 0xe4: return op_read_dp<&SMPcore::op_ld>(regs.a); + case 0xe5: return op_read_addr<&SMPcore::op_ld>(regs.a); + case 0xe6: return op_read_ix<&SMPcore::op_ld>(); + case 0xe7: return op_read_idpx<&SMPcore::op_ld>(); + case 0xe8: return op_read_const<&SMPcore::op_ld>(regs.a); + case 0xe9: return op_read_addr<&SMPcore::op_ld>(regs.x); + case 0xea: return op_set_addr_bit(); + case 0xeb: return op_read_dp<&SMPcore::op_ld>(regs.y); + case 0xec: return op_read_addr<&SMPcore::op_ld>(regs.y); + case 0xed: return op_cmc(); + case 0xee: return op_pull(regs.y); + case 0xef: return op_wait(); + case 0xf0: return op_branch(regs.p.z == 1); + case 0xf1: return op_jst(); + case 0xf2: return op_set_bit(); + case 0xf3: return op_branch_bit(); + case 0xf4: return op_read_dpi<&SMPcore::op_ld>(regs.a, regs.x); + case 0xf5: return op_read_addri<&SMPcore::op_ld>(regs.x); + case 0xf6: return op_read_addri<&SMPcore::op_ld>(regs.y); + case 0xf7: return op_read_idpy<&SMPcore::op_ld>(); + case 0xf8: return op_read_dp<&SMPcore::op_ld>(regs.x); + case 0xf9: return op_read_dpi<&SMPcore::op_ld>(regs.x, regs.y); + case 0xfa: return op_write_dp_dp<&SMPcore::op_st>(); + case 0xfb: return op_read_dpi<&SMPcore::op_ld>(regs.y, regs.x); + case 0xfc: return op_adjust<&SMPcore::op_inc>(regs.y); + case 0xfd: return op_transfer(regs.a, regs.y); + case 0xfe: return op_bne_ydec(); + case 0xff: return op_wait(); + } +} + +} diff --git a/libsnes/bsnes/snes/smp/core/core.hpp b/libsnes/bsnes/snes/smp/core/core.hpp index 0b3da3f330..3c0532b36a 100644 --- a/libsnes/bsnes/snes/smp/core/core.hpp +++ b/libsnes/bsnes/snes/smp/core/core.hpp @@ -1,98 +1,96 @@ -struct SMPcore { - virtual void op_io() = 0; - virtual uint8 op_read(uint16 addr, eCDLog_Flags flags = eCDLog_Flags_CPUData) = 0; - virtual void op_write(uint16 addr, uint8 data) = 0; - void op_step(); - - #include "registers.hpp" - #include "memory.hpp" - - regs_t regs; - word_t dp, sp, rd, wr, bit, ya; +struct SMPcore { + virtual void op_io() = 0; + virtual uint8 op_read(uint16 addr, eCDLog_Flags flags = eCDLog_Flags_CPUData) = 0; + virtual void op_write(uint16 addr, uint8 data) = 0; + void op_step(); + + #include "registers.hpp" + #include "memory.hpp" + + regs_t regs; + word_t dp, sp, rd, wr, bit, ya; uint8 opcode; - int uindex; - - void core_serialize(serializer&); - string disassemble_opcode(uint16 addr); - -protected: - uint8 op_adc(uint8, uint8); - uint8 op_and(uint8, uint8); - uint8 op_asl(uint8); - uint8 op_cmp(uint8, uint8); - uint8 op_dec(uint8); - uint8 op_eor(uint8, uint8); - uint8 op_inc(uint8); - uint8 op_ld (uint8, uint8); - uint8 op_lsr(uint8); - uint8 op_or (uint8, uint8); - uint8 op_rol(uint8); - uint8 op_ror(uint8); - uint8 op_sbc(uint8, uint8); - uint8 op_st (uint8, uint8); - uint16 op_adw(uint16, uint16); - uint16 op_cpw(uint16, uint16); - uint16 op_ldw(uint16, uint16); - uint16 op_sbw(uint16, uint16); - - template void op_adjust(uint8&); - template void op_adjust_addr(); - template void op_adjust_dp(); - void op_adjust_dpw(signed); - template void op_adjust_dpx(); - void op_branch(bool); - void op_branch_bit(); - void op_pull(uint8&); - void op_push(uint8); - template void op_read_addr(uint8&); - template void op_read_addri(uint8&); - template void op_read_const(uint8&); - template void op_read_dp(uint8&); - template void op_read_dpi(uint8&, uint8&); - template void op_read_dpw(); - template void op_read_idpx(); - template void op_read_idpy(); - template void op_read_ix(); - void op_set_addr_bit(); - void op_set_bit(); - void op_set_flag(bool&, bool); - void op_test_addr(bool); - void op_transfer(uint8&, uint8&); - void op_write_addr(uint8&); - void op_write_addri(uint8&); - void op_write_dp(uint8&); - void op_write_dpi(uint8&, uint8&); - template void op_write_dp_const(); - template void op_write_dp_dp(); - template void op_write_ix_iy(); - - void op_bne_dp(); - void op_bne_dpdec(); - void op_bne_dpx(); - void op_bne_ydec(); - void op_brk(); - void op_clv(); - void op_cmc(); - void op_daa(); - void op_das(); - void op_div_ya_x(); - void op_jmp_addr(); - void op_jmp_iaddrx(); - void op_jsp_dp(); - void op_jsr_addr(); - void op_jst(); - void op_lda_ixinc(); - void op_mul_ya(); - void op_nop(); - void op_plp(); - void op_rti(); - void op_rts(); - void op_sta_idpx(); - void op_sta_idpy(); - void op_sta_ix(); - void op_sta_ixinc(); - void op_stw_dp(); - void op_wait(); - void op_xcn(); -}; + void core_serialize(serializer&); + string disassemble_opcode(uint16 addr); + +protected: + uint8 op_adc(uint8, uint8); + uint8 op_and(uint8, uint8); + uint8 op_asl(uint8); + uint8 op_cmp(uint8, uint8); + uint8 op_dec(uint8); + uint8 op_eor(uint8, uint8); + uint8 op_inc(uint8); + uint8 op_ld (uint8, uint8); + uint8 op_lsr(uint8); + uint8 op_or (uint8, uint8); + uint8 op_rol(uint8); + uint8 op_ror(uint8); + uint8 op_sbc(uint8, uint8); + uint8 op_st (uint8, uint8); + uint16 op_adw(uint16, uint16); + uint16 op_cpw(uint16, uint16); + uint16 op_ldw(uint16, uint16); + uint16 op_sbw(uint16, uint16); + + template void op_adjust(uint8&); + template void op_adjust_addr(); + template void op_adjust_dp(); + void op_adjust_dpw(signed); + template void op_adjust_dpx(); + void op_branch(bool); + void op_branch_bit(); + void op_pull(uint8&); + void op_push(uint8); + template void op_read_addr(uint8&); + template void op_read_addri(uint8&); + template void op_read_const(uint8&); + template void op_read_dp(uint8&); + template void op_read_dpi(uint8&, uint8&); + template void op_read_dpw(); + template void op_read_idpx(); + template void op_read_idpy(); + template void op_read_ix(); + void op_set_addr_bit(); + void op_set_bit(); + void op_set_flag(bool&, bool); + void op_test_addr(bool); + void op_transfer(uint8&, uint8&); + void op_write_addr(uint8&); + void op_write_addri(uint8&); + void op_write_dp(uint8&); + void op_write_dpi(uint8&, uint8&); + template void op_write_dp_const(); + template void op_write_dp_dp(); + template void op_write_ix_iy(); + + void op_bne_dp(); + void op_bne_dpdec(); + void op_bne_dpx(); + void op_bne_ydec(); + void op_brk(); + void op_clv(); + void op_cmc(); + void op_daa(); + void op_das(); + void op_div_ya_x(); + void op_jmp_addr(); + void op_jmp_iaddrx(); + void op_jsp_dp(); + void op_jsr_addr(); + void op_jst(); + void op_lda_ixinc(); + void op_mul_ya(); + void op_nop(); + void op_plp(); + void op_rti(); + void op_rts(); + void op_sta_idpx(); + void op_sta_idpy(); + void op_sta_ix(); + void op_sta_ixinc(); + void op_stw_dp(); + void op_wait(); + void op_xcn(); +}; diff --git a/libsnes/bsnes/snes/smp/core/memory.hpp b/libsnes/bsnes/snes/smp/core/memory.hpp index ac33f22232..73e6d8a29b 100644 --- a/libsnes/bsnes/snes/smp/core/memory.hpp +++ b/libsnes/bsnes/snes/smp/core/memory.hpp @@ -20,10 +20,10 @@ alwaysinline uint8 op_readdp(uint8 addr) { alwaysinline void op_writedp(uint8 addr, uint8 data) { return op_write((regs.p.p << 8) + addr, data); -} - -alwaysinline void op_next() { - opcode = op_readpcfirst(); - uindex = -1; -} +} + +alwaysinline void op_next() { + opcode = op_readpcfirst(); + uindex = -1; +} diff --git a/libsnes/bsnes/snes/smp/core/opcodes.cpp b/libsnes/bsnes/snes/smp/core/opcodes.cpp index 703dda93e3..95b9844f66 100644 --- a/libsnes/bsnes/snes/smp/core/opcodes.cpp +++ b/libsnes/bsnes/snes/smp/core/opcodes.cpp @@ -540,10 +540,6 @@ void SMPcore::op_stw_dp() { void SMPcore::op_wait() { while(true) { - if(scheduler.sync == Scheduler::SynchronizeMode::All) { - regs.pc--; // repeat this opcode on next run - scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); - } op_io(); op_io(); } diff --git a/libsnes/bsnes/snes/smp/core/serialization.cpp b/libsnes/bsnes/snes/smp/core/serialization.cpp index 03a8d33639..24d0ca78cc 100644 --- a/libsnes/bsnes/snes/smp/core/serialization.cpp +++ b/libsnes/bsnes/snes/smp/core/serialization.cpp @@ -1,29 +1,27 @@ -#ifdef SMPCORE_CPP - -void SMPcore::core_serialize(serializer &s) { - s.integer(regs.pc); - s.integer(regs.a); - s.integer(regs.x); - s.integer(regs.y); - s.integer(regs.s); - s.integer(regs.p.n); - s.integer(regs.p.v); - s.integer(regs.p.p); - s.integer(regs.p.b); - s.integer(regs.p.h); - s.integer(regs.p.i); - s.integer(regs.p.z); - s.integer(regs.p.c); - - s.integer(opcode); - s.integer(dp.w); - s.integer(sp.w); - s.integer(rd.w); - s.integer(wr.w); - s.integer(bit.w); - s.integer(ya.w); +#ifdef SMPCORE_CPP - s.integer(uindex); -} - -#endif +void SMPcore::core_serialize(serializer &s) { + s.integer(regs.pc); + s.integer(regs.a); + s.integer(regs.x); + s.integer(regs.y); + s.integer(regs.s); + s.integer(regs.p.n); + s.integer(regs.p.v); + s.integer(regs.p.p); + s.integer(regs.p.b); + s.integer(regs.p.h); + s.integer(regs.p.i); + s.integer(regs.p.z); + s.integer(regs.p.c); + + s.integer(opcode); + s.integer(dp.w); + s.integer(sp.w); + s.integer(rd.w); + s.integer(wr.w); + s.integer(bit.w); + s.integer(ya.w); +} + +#endif diff --git a/libsnes/bsnes/snes/smp/core/uop.cpp b/libsnes/bsnes/snes/smp/core/uop.cpp deleted file mode 100644 index def4ca5d67..0000000000 --- a/libsnes/bsnes/snes/smp/core/uop.cpp +++ /dev/null @@ -1,3151 +0,0 @@ -const int uoptable[256][16] = { - -// case 0x00: return op_nop(); -// void SMPcore::op_nop() { -{ - 1, // op_io(); - 2, // //!!NEXT -}, -// case 0x01: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x02: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0x03: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x04: return op_read_dp<&SMPcore::op_or>(regs.a); -// void SMPcore::op_read_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 17, // regs.a = op_or(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x05: return op_read_addr<&SMPcore::op_or>(regs.a); -// void SMPcore::op_read_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 17, // regs.a = op_or(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x06: return op_read_ix<&SMPcore::op_or>(); -// void SMPcore::op_read_ix() { -{ - 1, // op_io(); - 21, // rd = op_readdp(regs.x); - 17, // regs.a = op_or(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x07: return op_read_idpx<&SMPcore::op_or>(); -// void SMPcore::op_read_idpx() { -{ - 22, // dp = op_readpc() + regs.x; - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 25, // rd = op_read(sp); - 17, // regs.a = op_or(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x08: return op_read_const<&SMPcore::op_or>(regs.a); -// void SMPcore::op_read_const(uint8 &r) { -{ - 13, // rd = op_readpc(); - 17, // regs.a = op_or(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x09: return op_write_dp_dp<&SMPcore::op_or>(); -// void SMPcore::op_write_dp_dp() { -{ - 26, // sp = op_readpc(); - 27, // rd = op_readdp(sp); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 29, // wr = op_or(wr, rd); - 30, // op_writedp(dp, wr); - 2, // //!!NEXT -}, -// case 0x0a: return op_set_addr_bit(); -// void SMPcore::op_set_addr_bit() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 31, // bit = dp >> 13; - 32, // dp &= 0x1fff; - 20, // rd = op_read(dp); - 1, // op_io(); - 33, // regs.p.c |= (rd & (1 << bit)) ^ 0; - 2, // //!!NEXT -}, -// case 0x0b: return op_adjust_dp<&SMPcore::op_asl>(); -// void SMPcore::op_adjust_dp() { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 34, // rd = op_asl(rd); - 35, // op_writedp(dp, rd); - 2, // //!!NEXT -}, -// case 0x0c: return op_adjust_addr<&SMPcore::op_asl>(); -// void SMPcore::op_adjust_addr() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 34, // rd = op_asl(rd); - 36, // op_write(dp, rd); - 2, // //!!NEXT -}, -// case 0x0d: return op_push(regs.p); -// void SMPcore::op_push(uint8 r) { -{ - 1, // op_io(); - 1, // op_io(); - 37, // op_writesp(regs.p); - 2, // //!!NEXT -}, -// case 0x0e: return op_test_addr(1); -// void SMPcore::op_test_addr(bool set) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 38, // regs.p.n = (regs.a - rd) & 0x80; - 39, // regs.p.z = (regs.a - rd) == 0; - 40, // op_read(dp); - 41, // op_write(dp, rd | regs.a); - 2, // //!!NEXT -}, -// case 0x0f: return op_brk(); -// void SMPcore::op_brk() { -{ - 42, // rd.l = op_read(0xffde); - 43, // rd.h = op_read(0xffdf); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 37, // op_writesp(regs.p); - 8, // regs.pc = rd; - 44, // regs.p.b = 1; - 45, // regs.p.i = 0; - 2, // //!!NEXT -}, -// case 0x10: return op_branch(regs.p.n == 0); -// void SMPcore::op_branch(bool condition) { -{ - 13, // rd = op_readpc(); - 46, // if(regs.p.n != 0) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x11: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x12: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0x13: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x14: return op_read_dpi<&SMPcore::op_or>(regs.a, regs.x); -// void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 17, // regs.a = op_or(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x15: return op_read_addri<&SMPcore::op_or>(regs.x); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 48, // rd = op_read(dp + regs.x); - 17, // regs.a = op_or(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x16: return op_read_addri<&SMPcore::op_or>(regs.y); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 49, // rd = op_read(dp + regs.y); - 17, // regs.a = op_or(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x17: return op_read_idpy<&SMPcore::op_or>(); -// void SMPcore::op_read_idpy() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 50, // rd = op_read(sp + regs.y); - 17, // regs.a = op_or(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x18: return op_write_dp_const<&SMPcore::op_or>(); -// void SMPcore::op_write_dp_const() { -{ - 13, // rd = op_readpc(); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 29, // wr = op_or(wr, rd); - 30, // op_writedp(dp, wr); - 2, // //!!NEXT -}, -// case 0x19: return op_write_ix_iy<&SMPcore::op_or>(); -// void SMPcore::op_write_ix_iy() { -{ - 1, // op_io(); - 51, // rd = op_readdp(regs.y); - 52, // wr = op_readdp(regs.x); - 29, // wr = op_or(wr, rd); - 53, // op_writedp(regs.x, wr); - 2, // //!!NEXT -}, -// case 0x1a: return op_adjust_dpw(-1); -// void SMPcore::op_adjust_dpw(signed n) { -{ - 9, // dp = op_readpc(); - 54, // rd.w = op_readdp(dp) - 1; - 55, // op_writedp(dp++, rd.l); - 56, // rd.h += op_readdp(dp); - 57, // op_writedp(dp++, rd.h); - 58, // regs.p.n = rd & 0x8000; - 59, // regs.p.z = rd == 0; - 2, // //!!NEXT -}, -// case 0x1b: return op_adjust_dpx<&SMPcore::op_asl>(); -// void SMPcore::op_adjust_dpx() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 34, // rd = op_asl(rd); - 60, // op_writedp(dp + regs.x, rd); - 2, // //!!NEXT -}, -// case 0x1c: return op_adjust<&SMPcore::op_asl>(regs.a); -// void SMPcore::op_adjust(uint8 &r) { -{ - 1, // op_io(); - 61, // regs.a = op_asl(regs.a); - 2, // //!!NEXT -}, -// case 0x1d: return op_adjust<&SMPcore::op_dec>(regs.x); -// void SMPcore::op_adjust(uint8 &r) { -{ - 1, // op_io(); - 62, // regs.x = op_dec(regs.x); - 2, // //!!NEXT -}, -// case 0x1e: return op_read_addr<&SMPcore::op_cmp>(regs.x); -// void SMPcore::op_read_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 63, // regs.x = op_cmp(regs.x, rd); - 2, // //!!NEXT -}, -// case 0x1f: return op_jmp_iaddrx(); -// void SMPcore::op_jmp_iaddrx() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 64, // dp += regs.x; - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x20: return op_set_flag(regs.p.p, 0); -// void SMPcore::op_set_flag(bool &flag, bool data) { -{ - 1, // op_io(); - 65, // regs.p.p = 0; - 2, // //!!NEXT -}, -// case 0x21: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x22: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0x23: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x24: return op_read_dp<&SMPcore::op_and>(regs.a); -// void SMPcore::op_read_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 66, // regs.a = op_and(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x25: return op_read_addr<&SMPcore::op_and>(regs.a); -// void SMPcore::op_read_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 66, // regs.a = op_and(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x26: return op_read_ix<&SMPcore::op_and>(); -// void SMPcore::op_read_ix() { -{ - 1, // op_io(); - 21, // rd = op_readdp(regs.x); - 66, // regs.a = op_and(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x27: return op_read_idpx<&SMPcore::op_and>(); -// void SMPcore::op_read_idpx() { -{ - 22, // dp = op_readpc() + regs.x; - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 25, // rd = op_read(sp); - 66, // regs.a = op_and(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x28: return op_read_const<&SMPcore::op_and>(regs.a); -// void SMPcore::op_read_const(uint8 &r) { -{ - 13, // rd = op_readpc(); - 66, // regs.a = op_and(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x29: return op_write_dp_dp<&SMPcore::op_and>(); -// void SMPcore::op_write_dp_dp() { -{ - 26, // sp = op_readpc(); - 27, // rd = op_readdp(sp); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 67, // wr = op_and(wr, rd); - 30, // op_writedp(dp, wr); - 2, // //!!NEXT -}, -// case 0x2a: return op_set_addr_bit(); -// void SMPcore::op_set_addr_bit() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 31, // bit = dp >> 13; - 32, // dp &= 0x1fff; - 20, // rd = op_read(dp); - 1, // op_io(); - 68, // regs.p.c |= (rd & (1 << bit)) ^ 1; - 2, // //!!NEXT -}, -// case 0x2b: return op_adjust_dp<&SMPcore::op_rol>(); -// void SMPcore::op_adjust_dp() { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 69, // rd = op_rol(rd); - 35, // op_writedp(dp, rd); - 2, // //!!NEXT -}, -// case 0x2c: return op_adjust_addr<&SMPcore::op_rol>(); -// void SMPcore::op_adjust_addr() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 69, // rd = op_rol(rd); - 36, // op_write(dp, rd); - 2, // //!!NEXT -}, -// case 0x2d: return op_push(regs.a); -// void SMPcore::op_push(uint8 r) { -{ - 1, // op_io(); - 1, // op_io(); - 70, // op_writesp(regs.a); - 2, // //!!NEXT -}, -// case 0x2e: return op_bne_dp(); -// void SMPcore::op_bne_dp() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 71, // if(regs.a == sp) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x2f: return op_branch(true); -// void SMPcore::op_branch(bool condition) { -{ - 13, // rd = op_readpc(); - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x30: return op_branch(regs.p.n == 1); -// void SMPcore::op_branch(bool condition) { -{ - 13, // rd = op_readpc(); - 72, // if(regs.p.n != 1) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x31: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x32: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0x33: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x34: return op_read_dpi<&SMPcore::op_and>(regs.a, regs.x); -// void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 66, // regs.a = op_and(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x35: return op_read_addri<&SMPcore::op_and>(regs.x); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 48, // rd = op_read(dp + regs.x); - 66, // regs.a = op_and(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x36: return op_read_addri<&SMPcore::op_and>(regs.y); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 49, // rd = op_read(dp + regs.y); - 66, // regs.a = op_and(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x37: return op_read_idpy<&SMPcore::op_and>(); -// void SMPcore::op_read_idpy() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 50, // rd = op_read(sp + regs.y); - 66, // regs.a = op_and(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x38: return op_write_dp_const<&SMPcore::op_and>(); -// void SMPcore::op_write_dp_const() { -{ - 13, // rd = op_readpc(); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 67, // wr = op_and(wr, rd); - 30, // op_writedp(dp, wr); - 2, // //!!NEXT -}, -// case 0x39: return op_write_ix_iy<&SMPcore::op_and>(); -// void SMPcore::op_write_ix_iy() { -{ - 1, // op_io(); - 51, // rd = op_readdp(regs.y); - 52, // wr = op_readdp(regs.x); - 67, // wr = op_and(wr, rd); - 53, // op_writedp(regs.x, wr); - 2, // //!!NEXT -}, -// case 0x3a: return op_adjust_dpw(+1); -// void SMPcore::op_adjust_dpw(signed n) { -{ - 9, // dp = op_readpc(); - 73, // rd.w = op_readdp(dp) + 1; - 55, // op_writedp(dp++, rd.l); - 56, // rd.h += op_readdp(dp); - 57, // op_writedp(dp++, rd.h); - 58, // regs.p.n = rd & 0x8000; - 59, // regs.p.z = rd == 0; - 2, // //!!NEXT -}, -// case 0x3b: return op_adjust_dpx<&SMPcore::op_rol>(); -// void SMPcore::op_adjust_dpx() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 69, // rd = op_rol(rd); - 60, // op_writedp(dp + regs.x, rd); - 2, // //!!NEXT -}, -// case 0x3c: return op_adjust<&SMPcore::op_rol>(regs.a); -// void SMPcore::op_adjust(uint8 &r) { -{ - 1, // op_io(); - 74, // regs.a = op_rol(regs.a); - 2, // //!!NEXT -}, -// case 0x3d: return op_adjust<&SMPcore::op_inc>(regs.x); -// void SMPcore::op_adjust(uint8 &r) { -{ - 1, // op_io(); - 75, // regs.x = op_inc(regs.x); - 2, // //!!NEXT -}, -// case 0x3e: return op_read_dp<&SMPcore::op_cmp>(regs.x); -// void SMPcore::op_read_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 63, // regs.x = op_cmp(regs.x, rd); - 2, // //!!NEXT -}, -// case 0x3f: return op_jsr_addr(); -// void SMPcore::op_jsr_addr() { -{ - 76, // rd.l = op_readpc(); - 77, // rd.h = op_readpc(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x40: return op_set_flag(regs.p.p, 1); -// void SMPcore::op_set_flag(bool &flag, bool data) { -{ - 1, // op_io(); - 78, // regs.p.p = 1; - 2, // //!!NEXT -}, -// case 0x41: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x42: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0x43: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x44: return op_read_dp<&SMPcore::op_eor>(regs.a); -// void SMPcore::op_read_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 79, // regs.a = op_eor(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x45: return op_read_addr<&SMPcore::op_eor>(regs.a); -// void SMPcore::op_read_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 79, // regs.a = op_eor(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x46: return op_read_ix<&SMPcore::op_eor>(); -// void SMPcore::op_read_ix() { -{ - 1, // op_io(); - 21, // rd = op_readdp(regs.x); - 79, // regs.a = op_eor(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x47: return op_read_idpx<&SMPcore::op_eor>(); -// void SMPcore::op_read_idpx() { -{ - 22, // dp = op_readpc() + regs.x; - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 25, // rd = op_read(sp); - 79, // regs.a = op_eor(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x48: return op_read_const<&SMPcore::op_eor>(regs.a); -// void SMPcore::op_read_const(uint8 &r) { -{ - 13, // rd = op_readpc(); - 79, // regs.a = op_eor(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x49: return op_write_dp_dp<&SMPcore::op_eor>(); -// void SMPcore::op_write_dp_dp() { -{ - 26, // sp = op_readpc(); - 27, // rd = op_readdp(sp); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 80, // wr = op_eor(wr, rd); - 30, // op_writedp(dp, wr); - 2, // //!!NEXT -}, -// case 0x4a: return op_set_addr_bit(); -// void SMPcore::op_set_addr_bit() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 31, // bit = dp >> 13; - 32, // dp &= 0x1fff; - 20, // rd = op_read(dp); - 81, // regs.p.c &= (rd & (1 << bit)) ^ 0; - 2, // //!!NEXT -}, -// case 0x4b: return op_adjust_dp<&SMPcore::op_lsr>(); -// void SMPcore::op_adjust_dp() { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 82, // rd = op_lsr(rd); - 35, // op_writedp(dp, rd); - 2, // //!!NEXT -}, -// case 0x4c: return op_adjust_addr<&SMPcore::op_lsr>(); -// void SMPcore::op_adjust_addr() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 82, // rd = op_lsr(rd); - 36, // op_write(dp, rd); - 2, // //!!NEXT -}, -// case 0x4d: return op_push(regs.x); -// void SMPcore::op_push(uint8 r) { -{ - 1, // op_io(); - 1, // op_io(); - 83, // op_writesp(regs.x); - 2, // //!!NEXT -}, -// case 0x4e: return op_test_addr(0); -// void SMPcore::op_test_addr(bool set) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 38, // regs.p.n = (regs.a - rd) & 0x80; - 39, // regs.p.z = (regs.a - rd) == 0; - 40, // op_read(dp); - 84, // op_write(dp, rd & ~regs.a); - 2, // //!!NEXT -}, -// case 0x4f: return op_jsp_dp(); -// void SMPcore::op_jsp_dp() { -{ - 13, // rd = op_readpc(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 85, // regs.pc = 0xff00 | rd; - 2, // //!!NEXT -}, -// case 0x50: return op_branch(regs.p.v == 0); -// void SMPcore::op_branch(bool condition) { -{ - 13, // rd = op_readpc(); - 86, // if(regs.p.v != 0) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x51: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x52: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0x53: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x54: return op_read_dpi<&SMPcore::op_eor>(regs.a, regs.x); -// void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 79, // regs.a = op_eor(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x55: return op_read_addri<&SMPcore::op_eor>(regs.x); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 48, // rd = op_read(dp + regs.x); - 79, // regs.a = op_eor(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x56: return op_read_addri<&SMPcore::op_eor>(regs.y); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 49, // rd = op_read(dp + regs.y); - 79, // regs.a = op_eor(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x57: return op_read_idpy<&SMPcore::op_eor>(); -// void SMPcore::op_read_idpy() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 50, // rd = op_read(sp + regs.y); - 79, // regs.a = op_eor(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x58: return op_write_dp_const<&SMPcore::op_eor>(); -// void SMPcore::op_write_dp_const() { -{ - 13, // rd = op_readpc(); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 80, // wr = op_eor(wr, rd); - 30, // op_writedp(dp, wr); - 2, // //!!NEXT -}, -// case 0x59: return op_write_ix_iy<&SMPcore::op_eor>(); -// void SMPcore::op_write_ix_iy() { -{ - 1, // op_io(); - 51, // rd = op_readdp(regs.y); - 52, // wr = op_readdp(regs.x); - 80, // wr = op_eor(wr, rd); - 53, // op_writedp(regs.x, wr); - 2, // //!!NEXT -}, -// case 0x5a: return op_read_dpw<&SMPcore::op_cpw>(); -// void SMPcore::op_read_dpw() { -{ - 9, // dp = op_readpc(); - 87, // rd.l = op_readdp(dp++); - 88, // rd.h = op_readdp(dp++); - 89, // regs.ya = op_cpw(regs.ya, rd); - 2, // //!!NEXT -}, -// case 0x5b: return op_adjust_dpx<&SMPcore::op_lsr>(); -// void SMPcore::op_adjust_dpx() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 82, // rd = op_lsr(rd); - 60, // op_writedp(dp + regs.x, rd); - 2, // //!!NEXT -}, -// case 0x5c: return op_adjust<&SMPcore::op_lsr>(regs.a); -// void SMPcore::op_adjust(uint8 &r) { -{ - 1, // op_io(); - 90, // regs.a = op_lsr(regs.a); - 2, // //!!NEXT -}, -// case 0x5d: return op_transfer(regs.a, regs.x); -// void SMPcore::op_transfer(uint8 &from, uint8 &to) { -{ - 1, // op_io(); - 91, // regs.x = regs.a; - 92, // regs.p.n = (regs.x & 0x80); - 93, // regs.p.z = (regs.x == 0); - 2, // //!!NEXT -}, -// case 0x5e: return op_read_addr<&SMPcore::op_cmp>(regs.y); -// void SMPcore::op_read_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 94, // regs.y = op_cmp(regs.y, rd); - 2, // //!!NEXT -}, -// case 0x5f: return op_jmp_addr(); -// void SMPcore::op_jmp_addr() { -{ - 76, // rd.l = op_readpc(); - 77, // rd.h = op_readpc(); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x60: return op_set_flag(regs.p.c, 0); -// void SMPcore::op_set_flag(bool &flag, bool data) { -{ - 1, // op_io(); - 95, // regs.p.c = 0; - 2, // //!!NEXT -}, -// case 0x61: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x62: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0x63: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x64: return op_read_dp<&SMPcore::op_cmp>(regs.a); -// void SMPcore::op_read_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 96, // regs.a = op_cmp(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x65: return op_read_addr<&SMPcore::op_cmp>(regs.a); -// void SMPcore::op_read_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 96, // regs.a = op_cmp(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x66: return op_read_ix<&SMPcore::op_cmp>(); -// void SMPcore::op_read_ix() { -{ - 1, // op_io(); - 21, // rd = op_readdp(regs.x); - 96, // regs.a = op_cmp(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x67: return op_read_idpx<&SMPcore::op_cmp>(); -// void SMPcore::op_read_idpx() { -{ - 22, // dp = op_readpc() + regs.x; - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 25, // rd = op_read(sp); - 96, // regs.a = op_cmp(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x68: return op_read_const<&SMPcore::op_cmp>(regs.a); -// void SMPcore::op_read_const(uint8 &r) { -{ - 13, // rd = op_readpc(); - 96, // regs.a = op_cmp(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x69: return op_write_dp_dp<&SMPcore::op_cmp>(); -// void SMPcore::op_write_dp_dp() { -{ - 26, // sp = op_readpc(); - 27, // rd = op_readdp(sp); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 97, // wr = op_cmp(wr, rd); - 1, // op_io(); - 2, // //!!NEXT -}, -// case 0x6a: return op_set_addr_bit(); -// void SMPcore::op_set_addr_bit() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 31, // bit = dp >> 13; - 32, // dp &= 0x1fff; - 20, // rd = op_read(dp); - 98, // regs.p.c &= (rd & (1 << bit)) ^ 1; - 2, // //!!NEXT -}, -// case 0x6b: return op_adjust_dp<&SMPcore::op_ror>(); -// void SMPcore::op_adjust_dp() { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 99, // rd = op_ror(rd); - 35, // op_writedp(dp, rd); - 2, // //!!NEXT -}, -// case 0x6c: return op_adjust_addr<&SMPcore::op_ror>(); -// void SMPcore::op_adjust_addr() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 99, // rd = op_ror(rd); - 36, // op_write(dp, rd); - 2, // //!!NEXT -}, -// case 0x6d: return op_push(regs.y); -// void SMPcore::op_push(uint8 r) { -{ - 1, // op_io(); - 1, // op_io(); - 100, // op_writesp(regs.y); - 2, // //!!NEXT -}, -// case 0x6e: return op_bne_dpdec(); -// void SMPcore::op_bne_dpdec() { -{ - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 101, // op_writedp(dp, --wr); - 13, // rd = op_readpc(); - 102, // if(wr == 0) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x6f: return op_rts(); -// void SMPcore::op_rts() { -{ - 103, // rd.l = op_readsp(); - 104, // rd.h = op_readsp(); - 1, // op_io(); - 1, // op_io(); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x70: return op_branch(regs.p.v == 1); -// void SMPcore::op_branch(bool condition) { -{ - 13, // rd = op_readpc(); - 105, // if(regs.p.v != 1) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x71: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x72: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0x73: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x74: return op_read_dpi<&SMPcore::op_cmp>(regs.a, regs.x); -// void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 96, // regs.a = op_cmp(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x75: return op_read_addri<&SMPcore::op_cmp>(regs.x); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 48, // rd = op_read(dp + regs.x); - 96, // regs.a = op_cmp(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x76: return op_read_addri<&SMPcore::op_cmp>(regs.y); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 49, // rd = op_read(dp + regs.y); - 96, // regs.a = op_cmp(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x77: return op_read_idpy<&SMPcore::op_cmp>(); -// void SMPcore::op_read_idpy() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 50, // rd = op_read(sp + regs.y); - 96, // regs.a = op_cmp(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x78: return op_write_dp_const<&SMPcore::op_cmp>(); -// void SMPcore::op_write_dp_const() { -{ - 13, // rd = op_readpc(); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 97, // wr = op_cmp(wr, rd); - 1, // op_io(); - 2, // //!!NEXT -}, -// case 0x79: return op_write_ix_iy<&SMPcore::op_cmp>(); -// void SMPcore::op_write_ix_iy() { -{ - 1, // op_io(); - 51, // rd = op_readdp(regs.y); - 52, // wr = op_readdp(regs.x); - 97, // wr = op_cmp(wr, rd); - 1, // op_io(); - 2, // //!!NEXT -}, -// case 0x7a: return op_read_dpw<&SMPcore::op_adw>(); -// void SMPcore::op_read_dpw() { -{ - 9, // dp = op_readpc(); - 87, // rd.l = op_readdp(dp++); - 1, // op_io(); - 88, // rd.h = op_readdp(dp++); - 106, // regs.ya = op_adw(regs.ya, rd); - 2, // //!!NEXT -}, -// case 0x7b: return op_adjust_dpx<&SMPcore::op_ror>(); -// void SMPcore::op_adjust_dpx() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 99, // rd = op_ror(rd); - 60, // op_writedp(dp + regs.x, rd); - 2, // //!!NEXT -}, -// case 0x7c: return op_adjust<&SMPcore::op_ror>(regs.a); -// void SMPcore::op_adjust(uint8 &r) { -{ - 1, // op_io(); - 107, // regs.a = op_ror(regs.a); - 2, // //!!NEXT -}, -// case 0x7d: return op_transfer(regs.x, regs.a); -// void SMPcore::op_transfer(uint8 &from, uint8 &to) { -{ - 1, // op_io(); - 108, // regs.a = regs.x; - 109, // regs.p.n = (regs.a & 0x80); - 110, // regs.p.z = (regs.a == 0); - 2, // //!!NEXT -}, -// case 0x7e: return op_read_dp<&SMPcore::op_cmp>(regs.y); -// void SMPcore::op_read_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 94, // regs.y = op_cmp(regs.y, rd); - 2, // //!!NEXT -}, -// case 0x7f: return op_rti(); -// void SMPcore::op_rti() { -{ - 111, // regs.p = op_readsp(); - 103, // rd.l = op_readsp(); - 104, // rd.h = op_readsp(); - 1, // op_io(); - 1, // op_io(); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x80: return op_set_flag(regs.p.c, 1); -// void SMPcore::op_set_flag(bool &flag, bool data) { -{ - 1, // op_io(); - 112, // regs.p.c = 1; - 2, // //!!NEXT -}, -// case 0x81: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x82: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0x83: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x84: return op_read_dp<&SMPcore::op_adc>(regs.a); -// void SMPcore::op_read_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 113, // regs.a = op_adc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x85: return op_read_addr<&SMPcore::op_adc>(regs.a); -// void SMPcore::op_read_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 113, // regs.a = op_adc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x86: return op_read_ix<&SMPcore::op_adc>(); -// void SMPcore::op_read_ix() { -{ - 1, // op_io(); - 21, // rd = op_readdp(regs.x); - 113, // regs.a = op_adc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x87: return op_read_idpx<&SMPcore::op_adc>(); -// void SMPcore::op_read_idpx() { -{ - 22, // dp = op_readpc() + regs.x; - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 25, // rd = op_read(sp); - 113, // regs.a = op_adc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x88: return op_read_const<&SMPcore::op_adc>(regs.a); -// void SMPcore::op_read_const(uint8 &r) { -{ - 13, // rd = op_readpc(); - 113, // regs.a = op_adc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x89: return op_write_dp_dp<&SMPcore::op_adc>(); -// void SMPcore::op_write_dp_dp() { -{ - 26, // sp = op_readpc(); - 27, // rd = op_readdp(sp); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 114, // wr = op_adc(wr, rd); - 30, // op_writedp(dp, wr); - 2, // //!!NEXT -}, -// case 0x8a: return op_set_addr_bit(); -// void SMPcore::op_set_addr_bit() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 31, // bit = dp >> 13; - 32, // dp &= 0x1fff; - 20, // rd = op_read(dp); - 1, // op_io(); - 115, // regs.p.c ^= (bool)(rd & (1 << bit)); - 2, // //!!NEXT -}, -// case 0x8b: return op_adjust_dp<&SMPcore::op_dec>(); -// void SMPcore::op_adjust_dp() { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 116, // rd = op_dec(rd); - 35, // op_writedp(dp, rd); - 2, // //!!NEXT -}, -// case 0x8c: return op_adjust_addr<&SMPcore::op_dec>(); -// void SMPcore::op_adjust_addr() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 116, // rd = op_dec(rd); - 36, // op_write(dp, rd); - 2, // //!!NEXT -}, -// case 0x8d: return op_read_const<&SMPcore::op_ld>(regs.y); -// void SMPcore::op_read_const(uint8 &r) { -{ - 13, // rd = op_readpc(); - 117, // regs.y = op_ld(regs.y, rd); - 2, // //!!NEXT -}, -// case 0x8e: return op_plp(); -// void SMPcore::op_plp() { -{ - 1, // op_io(); - 1, // op_io(); - 111, // regs.p = op_readsp(); - 2, // //!!NEXT -}, -// case 0x8f: return op_write_dp_const<&SMPcore::op_st>(); -// void SMPcore::op_write_dp_const() { -{ - 13, // rd = op_readpc(); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 118, // wr = op_st(wr, rd); - 30, // op_writedp(dp, wr); - 2, // //!!NEXT -}, -// case 0x90: return op_branch(regs.p.c == 0); -// void SMPcore::op_branch(bool condition) { -{ - 13, // rd = op_readpc(); - 119, // if(regs.p.c != 0) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x91: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0x92: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0x93: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0x94: return op_read_dpi<&SMPcore::op_adc>(regs.a, regs.x); -// void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 113, // regs.a = op_adc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x95: return op_read_addri<&SMPcore::op_adc>(regs.x); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 48, // rd = op_read(dp + regs.x); - 113, // regs.a = op_adc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x96: return op_read_addri<&SMPcore::op_adc>(regs.y); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 49, // rd = op_read(dp + regs.y); - 113, // regs.a = op_adc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x97: return op_read_idpy<&SMPcore::op_adc>(); -// void SMPcore::op_read_idpy() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 50, // rd = op_read(sp + regs.y); - 113, // regs.a = op_adc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0x98: return op_write_dp_const<&SMPcore::op_adc>(); -// void SMPcore::op_write_dp_const() { -{ - 13, // rd = op_readpc(); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 114, // wr = op_adc(wr, rd); - 30, // op_writedp(dp, wr); - 2, // //!!NEXT -}, -// case 0x99: return op_write_ix_iy<&SMPcore::op_adc>(); -// void SMPcore::op_write_ix_iy() { -{ - 1, // op_io(); - 51, // rd = op_readdp(regs.y); - 52, // wr = op_readdp(regs.x); - 114, // wr = op_adc(wr, rd); - 53, // op_writedp(regs.x, wr); - 2, // //!!NEXT -}, -// case 0x9a: return op_read_dpw<&SMPcore::op_sbw>(); -// void SMPcore::op_read_dpw() { -{ - 9, // dp = op_readpc(); - 87, // rd.l = op_readdp(dp++); - 1, // op_io(); - 88, // rd.h = op_readdp(dp++); - 120, // regs.ya = op_sbw(regs.ya, rd); - 2, // //!!NEXT -}, -// case 0x9b: return op_adjust_dpx<&SMPcore::op_dec>(); -// void SMPcore::op_adjust_dpx() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 116, // rd = op_dec(rd); - 60, // op_writedp(dp + regs.x, rd); - 2, // //!!NEXT -}, -// case 0x9c: return op_adjust<&SMPcore::op_dec>(regs.a); -// void SMPcore::op_adjust(uint8 &r) { -{ - 1, // op_io(); - 121, // regs.a = op_dec(regs.a); - 2, // //!!NEXT -}, -// case 0x9d: return op_transfer(regs.s, regs.x); -// void SMPcore::op_transfer(uint8 &from, uint8 &to) { -{ - 1, // op_io(); - 122, // regs.x = regs.s; - 92, // regs.p.n = (regs.x & 0x80); - 93, // regs.p.z = (regs.x == 0); - 2, // //!!NEXT -}, -// case 0x9e: return op_div_ya_x(); -// void SMPcore::op_div_ya_x() { -{ - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - //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 S-SMP 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); - 123, // //!!MULTI0 - 2, // //!!NEXT -}, -// case 0x9f: return op_xcn(); -// void SMPcore::op_xcn() { -{ - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 124, // regs.a = (regs.a >> 4) | (regs.a << 4); - 125, // regs.p.n = regs.a & 0x80; - 126, // regs.p.z = regs.a == 0; - 2, // //!!NEXT -}, -// case 0xa0: return op_set_flag(regs.p.i, 1); -// void SMPcore::op_set_flag(bool &flag, bool data) { -{ - 1, // op_io(); - 1, // op_io(); - 127, // regs.p.i = 1; - 2, // //!!NEXT -}, -// case 0xa1: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0xa2: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0xa3: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0xa4: return op_read_dp<&SMPcore::op_sbc>(regs.a); -// void SMPcore::op_read_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 128, // regs.a = op_sbc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xa5: return op_read_addr<&SMPcore::op_sbc>(regs.a); -// void SMPcore::op_read_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 128, // regs.a = op_sbc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xa6: return op_read_ix<&SMPcore::op_sbc>(); -// void SMPcore::op_read_ix() { -{ - 1, // op_io(); - 21, // rd = op_readdp(regs.x); - 128, // regs.a = op_sbc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xa7: return op_read_idpx<&SMPcore::op_sbc>(); -// void SMPcore::op_read_idpx() { -{ - 22, // dp = op_readpc() + regs.x; - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 25, // rd = op_read(sp); - 128, // regs.a = op_sbc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xa8: return op_read_const<&SMPcore::op_sbc>(regs.a); -// void SMPcore::op_read_const(uint8 &r) { -{ - 13, // rd = op_readpc(); - 128, // regs.a = op_sbc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xa9: return op_write_dp_dp<&SMPcore::op_sbc>(); -// void SMPcore::op_write_dp_dp() { -{ - 26, // sp = op_readpc(); - 27, // rd = op_readdp(sp); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 129, // wr = op_sbc(wr, rd); - 30, // op_writedp(dp, wr); - 2, // //!!NEXT -}, -// case 0xaa: return op_set_addr_bit(); -// void SMPcore::op_set_addr_bit() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 31, // bit = dp >> 13; - 32, // dp &= 0x1fff; - 20, // rd = op_read(dp); - 130, // regs.p.c = (rd & (1 << bit)); - 2, // //!!NEXT -}, -// case 0xab: return op_adjust_dp<&SMPcore::op_inc>(); -// void SMPcore::op_adjust_dp() { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 131, // rd = op_inc(rd); - 35, // op_writedp(dp, rd); - 2, // //!!NEXT -}, -// case 0xac: return op_adjust_addr<&SMPcore::op_inc>(); -// void SMPcore::op_adjust_addr() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 131, // rd = op_inc(rd); - 36, // op_write(dp, rd); - 2, // //!!NEXT -}, -// case 0xad: return op_read_const<&SMPcore::op_cmp>(regs.y); -// void SMPcore::op_read_const(uint8 &r) { -{ - 13, // rd = op_readpc(); - 94, // regs.y = op_cmp(regs.y, rd); - 2, // //!!NEXT -}, -// case 0xae: return op_pull(regs.a); -// void SMPcore::op_pull(uint8 &r) { -{ - 1, // op_io(); - 1, // op_io(); - 132, // regs.a = op_readsp(); - 2, // //!!NEXT -}, -// case 0xaf: return op_sta_ixinc(); -// void SMPcore::op_sta_ixinc() { -{ - 1, // op_io(); - 1, // op_io(); - 133, // op_writedp(regs.x++, regs.a); - 2, // //!!NEXT -}, -// case 0xb0: return op_branch(regs.p.c == 1); -// void SMPcore::op_branch(bool condition) { -{ - 13, // rd = op_readpc(); - 134, // if(regs.p.c != 1) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0xb1: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0xb2: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0xb3: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0xb4: return op_read_dpi<&SMPcore::op_sbc>(regs.a, regs.x); -// void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 128, // regs.a = op_sbc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xb5: return op_read_addri<&SMPcore::op_sbc>(regs.x); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 48, // rd = op_read(dp + regs.x); - 128, // regs.a = op_sbc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xb6: return op_read_addri<&SMPcore::op_sbc>(regs.y); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 49, // rd = op_read(dp + regs.y); - 128, // regs.a = op_sbc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xb7: return op_read_idpy<&SMPcore::op_sbc>(); -// void SMPcore::op_read_idpy() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 50, // rd = op_read(sp + regs.y); - 128, // regs.a = op_sbc(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xb8: return op_write_dp_const<&SMPcore::op_sbc>(); -// void SMPcore::op_write_dp_const() { -{ - 13, // rd = op_readpc(); - 9, // dp = op_readpc(); - 28, // wr = op_readdp(dp); - 129, // wr = op_sbc(wr, rd); - 30, // op_writedp(dp, wr); - 2, // //!!NEXT -}, -// case 0xb9: return op_write_ix_iy<&SMPcore::op_sbc>(); -// void SMPcore::op_write_ix_iy() { -{ - 1, // op_io(); - 51, // rd = op_readdp(regs.y); - 52, // wr = op_readdp(regs.x); - 129, // wr = op_sbc(wr, rd); - 53, // op_writedp(regs.x, wr); - 2, // //!!NEXT -}, -// case 0xba: return op_read_dpw<&SMPcore::op_ldw>(); -// void SMPcore::op_read_dpw() { -{ - 9, // dp = op_readpc(); - 87, // rd.l = op_readdp(dp++); - 1, // op_io(); - 88, // rd.h = op_readdp(dp++); - 135, // regs.ya = op_ldw(regs.ya, rd); - 2, // //!!NEXT -}, -// case 0xbb: return op_adjust_dpx<&SMPcore::op_inc>(); -// void SMPcore::op_adjust_dpx() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 131, // rd = op_inc(rd); - 60, // op_writedp(dp + regs.x, rd); - 2, // //!!NEXT -}, -// case 0xbc: return op_adjust<&SMPcore::op_inc>(regs.a); -// void SMPcore::op_adjust(uint8 &r) { -{ - 1, // op_io(); - 136, // regs.a = op_inc(regs.a); - 2, // //!!NEXT -}, -// case 0xbd: return op_transfer(regs.x, regs.s); -// void SMPcore::op_transfer(uint8 &from, uint8 &to) { -{ - 1, // op_io(); - 137, // regs.s = regs.x; - 2, // //!!NEXT -}, -// case 0xbe: return op_das(); -// void SMPcore::op_das() { -{ - 1, // op_io(); - 1, // op_io(); - //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); - 138, // //!!MULTI1 - 2, // //!!NEXT -}, -// case 0xbf: return op_lda_ixinc(); -// void SMPcore::op_lda_ixinc() { -{ - 1, // op_io(); - 139, // regs.a = op_readdp(regs.x++); - 1, // op_io(); - 125, // regs.p.n = regs.a & 0x80; - 126, // regs.p.z = regs.a == 0; - 2, // //!!NEXT -}, -// case 0xc0: return op_set_flag(regs.p.i, 0); -// void SMPcore::op_set_flag(bool &flag, bool data) { -{ - 1, // op_io(); - 1, // op_io(); - 45, // regs.p.i = 0; - 2, // //!!NEXT -}, -// case 0xc1: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0xc2: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0xc3: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0xc4: return op_write_dp(regs.a); -// void SMPcore::op_write_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 140, // op_readdp(dp); - 141, // op_writedp(dp, regs.a); - 2, // //!!NEXT -}, -// case 0xc5: return op_write_addr(regs.a); -// void SMPcore::op_write_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 40, // op_read(dp); - 142, // op_write(dp, regs.a); - 2, // //!!NEXT -}, -// case 0xc6: return op_sta_ix(); -// void SMPcore::op_sta_ix() { -{ - 1, // op_io(); - 143, // op_readdp(regs.x); - 144, // op_writedp(regs.x, regs.a); - 2, // //!!NEXT -}, -// case 0xc7: return op_sta_idpx(); -// void SMPcore::op_sta_idpx() { -{ - 145, // sp = op_readpc() + regs.x; - 1, // op_io(); - 146, // dp.l = op_readdp(sp++); - 147, // dp.h = op_readdp(sp++); - 40, // op_read(dp); - 142, // op_write(dp, regs.a); - 2, // //!!NEXT -}, -// case 0xc8: return op_read_const<&SMPcore::op_cmp>(regs.x); -// void SMPcore::op_read_const(uint8 &r) { -{ - 13, // rd = op_readpc(); - 63, // regs.x = op_cmp(regs.x, rd); - 2, // //!!NEXT -}, -// case 0xc9: return op_write_addr(regs.x); -// void SMPcore::op_write_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 40, // op_read(dp); - 148, // op_write(dp, regs.x); - 2, // //!!NEXT -}, -// case 0xca: return op_set_addr_bit(); -// void SMPcore::op_set_addr_bit() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 31, // bit = dp >> 13; - 32, // dp &= 0x1fff; - 20, // rd = op_read(dp); - 1, // op_io(); - 149, // rd = (rd & ~(1 << bit)) | (regs.p.c << bit); - 36, // op_write(dp, rd); - 2, // //!!NEXT -}, -// case 0xcb: return op_write_dp(regs.y); -// void SMPcore::op_write_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 140, // op_readdp(dp); - 150, // op_writedp(dp, regs.y); - 2, // //!!NEXT -}, -// case 0xcc: return op_write_addr(regs.y); -// void SMPcore::op_write_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 40, // op_read(dp); - 151, // op_write(dp, regs.y); - 2, // //!!NEXT -}, -// case 0xcd: return op_read_const<&SMPcore::op_ld>(regs.x); -// void SMPcore::op_read_const(uint8 &r) { -{ - 13, // rd = op_readpc(); - 152, // regs.x = op_ld(regs.x, rd); - 2, // //!!NEXT -}, -// case 0xce: return op_pull(regs.x); -// void SMPcore::op_pull(uint8 &r) { -{ - 1, // op_io(); - 1, // op_io(); - 153, // regs.x = op_readsp(); - 2, // //!!NEXT -}, -// case 0xcf: return op_mul_ya(); -// void SMPcore::op_mul_ya() { -{ - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - //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); - 154, // //!!MULTI2 - 2, // //!!NEXT -}, -// case 0xd0: return op_branch(regs.p.z == 0); -// void SMPcore::op_branch(bool condition) { -{ - 13, // rd = op_readpc(); - 155, // if(regs.p.z != 0) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0xd1: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0xd2: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0xd3: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0xd4: return op_write_dpi(regs.a, regs.x); -// void SMPcore::op_write_dpi(uint8 &r, uint8 &i) { -{ - 22, // dp = op_readpc() + regs.x; - 1, // op_io(); - 140, // op_readdp(dp); - 141, // op_writedp(dp, regs.a); - 2, // //!!NEXT -}, -// case 0xd5: return op_write_addri(regs.x); -// void SMPcore::op_write_addri(uint8 &i) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 64, // dp += regs.x; - 40, // op_read(dp); - 142, // op_write(dp, regs.a); - 2, // //!!NEXT -}, -// case 0xd6: return op_write_addri(regs.y); -// void SMPcore::op_write_addri(uint8 &i) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 156, // dp += regs.y; - 40, // op_read(dp); - 142, // op_write(dp, regs.a); - 2, // //!!NEXT -}, -// case 0xd7: return op_sta_idpy(); -// void SMPcore::op_sta_idpy() { -{ - 26, // sp = op_readpc(); - 146, // dp.l = op_readdp(sp++); - 147, // dp.h = op_readdp(sp++); - 1, // op_io(); - 156, // dp += regs.y; - 40, // op_read(dp); - 142, // op_write(dp, regs.a); - 2, // //!!NEXT -}, -// case 0xd8: return op_write_dp(regs.x); -// void SMPcore::op_write_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 140, // op_readdp(dp); - 157, // op_writedp(dp, regs.x); - 2, // //!!NEXT -}, -// case 0xd9: return op_write_dpi(regs.x, regs.y); -// void SMPcore::op_write_dpi(uint8 &r, uint8 &i) { -{ - 158, // dp = op_readpc() + regs.y; - 1, // op_io(); - 140, // op_readdp(dp); - 157, // op_writedp(dp, regs.x); - 2, // //!!NEXT -}, -// case 0xda: return op_stw_dp(); -// void SMPcore::op_stw_dp() { -{ - 9, // dp = op_readpc(); - 140, // op_readdp(dp); - 159, // op_writedp(dp++, regs.a); - 160, // op_writedp(dp++, regs.y); - 2, // //!!NEXT -}, -// case 0xdb: return op_write_dpi(regs.y, regs.x); -// void SMPcore::op_write_dpi(uint8 &r, uint8 &i) { -{ - 22, // dp = op_readpc() + regs.x; - 1, // op_io(); - 140, // op_readdp(dp); - 150, // op_writedp(dp, regs.y); - 2, // //!!NEXT -}, -// case 0xdc: return op_adjust<&SMPcore::op_dec>(regs.y); -// void SMPcore::op_adjust(uint8 &r) { -{ - 1, // op_io(); - 161, // regs.y = op_dec(regs.y); - 2, // //!!NEXT -}, -// case 0xdd: return op_transfer(regs.y, regs.a); -// void SMPcore::op_transfer(uint8 &from, uint8 &to) { -{ - 1, // op_io(); - 162, // regs.a = regs.y; - 109, // regs.p.n = (regs.a & 0x80); - 110, // regs.p.z = (regs.a == 0); - 2, // //!!NEXT -}, -// case 0xde: return op_bne_dpx(); -// void SMPcore::op_bne_dpx() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 163, // sp = op_readdp(dp + regs.x); - 13, // rd = op_readpc(); - 1, // op_io(); - 71, // if(regs.a == sp) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0xdf: return op_daa(); -// void SMPcore::op_daa() { -{ - 1, // op_io(); - 1, // op_io(); - //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); - 164, // //!!MULTI3 - 2, // //!!NEXT -}, -// case 0xe0: return op_clv(); -// void SMPcore::op_clv() { -{ - 1, // op_io(); - 165, // regs.p.v = 0; - 166, // regs.p.h = 0; - 2, // //!!NEXT -}, -// case 0xe1: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0xe2: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0xe3: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0xe4: return op_read_dp<&SMPcore::op_ld>(regs.a); -// void SMPcore::op_read_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 167, // regs.a = op_ld(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xe5: return op_read_addr<&SMPcore::op_ld>(regs.a); -// void SMPcore::op_read_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 167, // regs.a = op_ld(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xe6: return op_read_ix<&SMPcore::op_ld>(); -// void SMPcore::op_read_ix() { -{ - 1, // op_io(); - 21, // rd = op_readdp(regs.x); - 167, // regs.a = op_ld(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xe7: return op_read_idpx<&SMPcore::op_ld>(); -// void SMPcore::op_read_idpx() { -{ - 22, // dp = op_readpc() + regs.x; - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 25, // rd = op_read(sp); - 167, // regs.a = op_ld(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xe8: return op_read_const<&SMPcore::op_ld>(regs.a); -// void SMPcore::op_read_const(uint8 &r) { -{ - 13, // rd = op_readpc(); - 167, // regs.a = op_ld(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xe9: return op_read_addr<&SMPcore::op_ld>(regs.x); -// void SMPcore::op_read_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 152, // regs.x = op_ld(regs.x, rd); - 2, // //!!NEXT -}, -// case 0xea: return op_set_addr_bit(); -// void SMPcore::op_set_addr_bit() { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 31, // bit = dp >> 13; - 32, // dp &= 0x1fff; - 20, // rd = op_read(dp); - 168, // rd ^= 1 << bit; - 36, // op_write(dp, rd); - 2, // //!!NEXT -}, -// case 0xeb: return op_read_dp<&SMPcore::op_ld>(regs.y); -// void SMPcore::op_read_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 117, // regs.y = op_ld(regs.y, rd); - 2, // //!!NEXT -}, -// case 0xec: return op_read_addr<&SMPcore::op_ld>(regs.y); -// void SMPcore::op_read_addr(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 20, // rd = op_read(dp); - 117, // regs.y = op_ld(regs.y, rd); - 2, // //!!NEXT -}, -// case 0xed: return op_cmc(); -// void SMPcore::op_cmc() { -{ - 1, // op_io(); - 1, // op_io(); - 169, // regs.p.c = !regs.p.c; - 2, // //!!NEXT -}, -// case 0xee: return op_pull(regs.y); -// void SMPcore::op_pull(uint8 &r) { -{ - 1, // op_io(); - 1, // op_io(); - 170, // regs.y = op_readsp(); - 2, // //!!NEXT -}, -// case 0xef: return op_wait(); -// void SMPcore::op_wait() { -{ - 1, // op_io(); - 1, // op_io(); - 171, // //!!REPEAT -}, -// case 0xf0: return op_branch(regs.p.z == 1); -// void SMPcore::op_branch(bool condition) { -{ - 13, // rd = op_readpc(); - 172, // if(regs.p.z != 1) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0xf1: return op_jst(); -// void SMPcore::op_jst() { -{ - 3, // dp = 0xffde - ((opcode >> 4) << 1); - 4, // rd.l = op_read(dp++); - 5, // rd.h = op_read(dp++); - 1, // op_io(); - 1, // op_io(); - 1, // op_io(); - 6, // op_writesp(regs.pc.h); - 7, // op_writesp(regs.pc.l); - 8, // regs.pc = rd; - 2, // //!!NEXT -}, -// case 0xf2: return op_set_bit(); -// void SMPcore::op_set_bit() { -{ - 9, // dp = op_readpc(); - 10, // rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - 11, // op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - 2, // //!!NEXT -}, -// case 0xf3: return op_branch_bit(); -// void SMPcore::op_branch_bit() { -{ - 9, // dp = op_readpc(); - 12, // sp = op_readdp(dp); - 13, // rd = op_readpc(); - 1, // op_io(); - 14, // if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0xf4: return op_read_dpi<&SMPcore::op_ld>(regs.a, regs.x); -// void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 167, // regs.a = op_ld(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xf5: return op_read_addri<&SMPcore::op_ld>(regs.x); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 48, // rd = op_read(dp + regs.x); - 167, // regs.a = op_ld(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xf6: return op_read_addri<&SMPcore::op_ld>(regs.y); -// void SMPcore::op_read_addri(uint8 &r) { -{ - 18, // dp.l = op_readpc(); - 19, // dp.h = op_readpc(); - 1, // op_io(); - 49, // rd = op_read(dp + regs.y); - 167, // regs.a = op_ld(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xf7: return op_read_idpy<&SMPcore::op_ld>(); -// void SMPcore::op_read_idpy() { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 23, // sp.l = op_readdp(dp++); - 24, // sp.h = op_readdp(dp++); - 50, // rd = op_read(sp + regs.y); - 167, // regs.a = op_ld(regs.a, rd); - 2, // //!!NEXT -}, -// case 0xf8: return op_read_dp<&SMPcore::op_ld>(regs.x); -// void SMPcore::op_read_dp(uint8 &r) { -{ - 9, // dp = op_readpc(); - 16, // rd = op_readdp(dp); - 152, // regs.x = op_ld(regs.x, rd); - 2, // //!!NEXT -}, -// case 0xf9: return op_read_dpi<&SMPcore::op_ld>(regs.x, regs.y); -// void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 173, // rd = op_readdp(dp + regs.y); - 152, // regs.x = op_ld(regs.x, rd); - 2, // //!!NEXT -}, -// case 0xfa: return op_write_dp_dp<&SMPcore::op_st>(); -// void SMPcore::op_write_dp_dp() { -{ - 26, // sp = op_readpc(); - 27, // rd = op_readdp(sp); - 9, // dp = op_readpc(); - 118, // wr = op_st(wr, rd); - 30, // op_writedp(dp, wr); - 2, // //!!NEXT -}, -// case 0xfb: return op_read_dpi<&SMPcore::op_ld>(regs.y, regs.x); -// void SMPcore::op_read_dpi(uint8 &r, uint8 &i) { -{ - 9, // dp = op_readpc(); - 1, // op_io(); - 47, // rd = op_readdp(dp + regs.x); - 117, // regs.y = op_ld(regs.y, rd); - 2, // //!!NEXT -}, -// case 0xfc: return op_adjust<&SMPcore::op_inc>(regs.y); -// void SMPcore::op_adjust(uint8 &r) { -{ - 1, // op_io(); - 174, // regs.y = op_inc(regs.y); - 2, // //!!NEXT -}, -// case 0xfd: return op_transfer(regs.a, regs.y); -// void SMPcore::op_transfer(uint8 &from, uint8 &to) { -{ - 1, // op_io(); - 175, // regs.y = regs.a; - 176, // regs.p.n = (regs.y & 0x80); - 177, // regs.p.z = (regs.y == 0); - 2, // //!!NEXT -}, -// case 0xfe: return op_bne_ydec(); -// void SMPcore::op_bne_ydec() { -{ - 13, // rd = op_readpc(); - 1, // op_io(); - 1, // op_io(); - 178, // if(--regs.y == 0) return; - 1, // op_io(); - 1, // op_io(); - 15, // regs.pc += (int8)rd; - 2, // //!!NEXT -}, -// case 0xff: return op_wait(); -// void SMPcore::op_wait() { -{ - 1, // op_io(); - 1, // op_io(); - 171, // //!!REPEAT -}, - -}; // const int uoptable[][] = { - - - - -void SMPcore::op_step() -{ - switch (uoptable[opcode][uindex]) - { - case 1: - op_io(); - break; - case 2: - op_next();//!!NEXT - break; - case 3: - dp = 0xffde - ((opcode >> 4) << 1); - break; - case 4: - rd.l = op_read(dp++); - break; - case 5: - rd.h = op_read(dp++); - break; - case 6: - op_writesp(regs.pc.h); - break; - case 7: - op_writesp(regs.pc.l); - break; - case 8: - regs.pc = rd; - break; - case 9: - dp = op_readpc(); - break; - case 10: - rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - break; - case 11: - op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); - break; - case 12: - sp = op_readdp(dp); - break; - case 13: - rd = op_readpc(); - break; - case 14: - if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) op_next(); - break; - case 15: - regs.pc += (int8)rd; - break; - case 16: - rd = op_readdp(dp); - break; - case 17: - regs.a = op_or(regs.a, rd); - break; - case 18: - dp.l = op_readpc(); - break; - case 19: - dp.h = op_readpc(); - break; - case 20: - rd = op_read(dp); - break; - case 21: - rd = op_readdp(regs.x); - break; - case 22: - dp = op_readpc() + regs.x; - break; - case 23: - sp.l = op_readdp(dp++); - break; - case 24: - sp.h = op_readdp(dp++); - break; - case 25: - rd = op_read(sp); - break; - case 26: - sp = op_readpc(); - break; - case 27: - rd = op_readdp(sp); - break; - case 28: - wr = op_readdp(dp); - break; - case 29: - wr = op_or(wr, rd); - break; - case 30: - op_writedp(dp, wr); - break; - case 31: - bit = dp >> 13; - break; - case 32: - dp &= 0x1fff; - break; - case 33: - regs.p.c |= (rd & (1 << bit)) ^ 0; - break; - case 34: - rd = op_asl(rd); - break; - case 35: - op_writedp(dp, rd); - break; - case 36: - op_write(dp, rd); - break; - case 37: - op_writesp(regs.p); - break; - case 38: - regs.p.n = (regs.a - rd) & 0x80; - break; - case 39: - regs.p.z = (regs.a - rd) == 0; - break; - case 40: - op_read(dp); - break; - case 41: - op_write(dp, rd | regs.a); - break; - case 42: - rd.l = op_read(0xffde); - break; - case 43: - rd.h = op_read(0xffdf); - break; - case 44: - regs.p.b = 1; - break; - case 45: - regs.p.i = 0; - break; - case 46: - if(regs.p.n != 0) op_next(); - break; - case 47: - rd = op_readdp(dp + regs.x); - break; - case 48: - rd = op_read(dp + regs.x); - break; - case 49: - rd = op_read(dp + regs.y); - break; - case 50: - rd = op_read(sp + regs.y); - break; - case 51: - rd = op_readdp(regs.y); - break; - case 52: - wr = op_readdp(regs.x); - break; - case 53: - op_writedp(regs.x, wr); - break; - case 54: - rd.w = op_readdp(dp) - 1; - break; - case 55: - op_writedp(dp++, rd.l); - break; - case 56: - rd.h += op_readdp(dp); - break; - case 57: - op_writedp(dp++, rd.h); - break; - case 58: - regs.p.n = rd & 0x8000; - break; - case 59: - regs.p.z = rd == 0; - break; - case 60: - op_writedp(dp + regs.x, rd); - break; - case 61: - regs.a = op_asl(regs.a); - break; - case 62: - regs.x = op_dec(regs.x); - break; - case 63: - regs.x = op_cmp(regs.x, rd); - break; - case 64: - dp += regs.x; - break; - case 65: - regs.p.p = 0; - break; - case 66: - regs.a = op_and(regs.a, rd); - break; - case 67: - wr = op_and(wr, rd); - break; - case 68: - regs.p.c |= (rd & (1 << bit)) ^ 1; - break; - case 69: - rd = op_rol(rd); - break; - case 70: - op_writesp(regs.a); - break; - case 71: - if(regs.a == sp) op_next(); - break; - case 72: - if(regs.p.n != 1) op_next(); - break; - case 73: - rd.w = op_readdp(dp) + 1; - break; - case 74: - regs.a = op_rol(regs.a); - break; - case 75: - regs.x = op_inc(regs.x); - break; - case 76: - rd.l = op_readpc(); - break; - case 77: - rd.h = op_readpc(); - break; - case 78: - regs.p.p = 1; - break; - case 79: - regs.a = op_eor(regs.a, rd); - break; - case 80: - wr = op_eor(wr, rd); - break; - case 81: - regs.p.c &= (rd & (1 << bit)) ^ 0; - break; - case 82: - rd = op_lsr(rd); - break; - case 83: - op_writesp(regs.x); - break; - case 84: - op_write(dp, rd & ~regs.a); - break; - case 85: - regs.pc = 0xff00 | rd; - break; - case 86: - if(regs.p.v != 0) op_next(); - break; - case 87: - rd.l = op_readdp(dp++); - break; - case 88: - rd.h = op_readdp(dp++); - break; - case 89: - regs.ya = op_cpw(regs.ya, rd); - break; - case 90: - regs.a = op_lsr(regs.a); - break; - case 91: - regs.x = regs.a; - break; - case 92: - regs.p.n = (regs.x & 0x80); - break; - case 93: - regs.p.z = (regs.x == 0); - break; - case 94: - regs.y = op_cmp(regs.y, rd); - break; - case 95: - regs.p.c = 0; - break; - case 96: - regs.a = op_cmp(regs.a, rd); - break; - case 97: - wr = op_cmp(wr, rd); - break; - case 98: - regs.p.c &= (rd & (1 << bit)) ^ 1; - break; - case 99: - rd = op_ror(rd); - break; - case 100: - op_writesp(regs.y); - break; - case 101: - op_writedp(dp, --wr); - break; - case 102: - if(wr == 0) op_next(); - break; - case 103: - rd.l = op_readsp(); - break; - case 104: - rd.h = op_readsp(); - break; - case 105: - if(regs.p.v != 1) op_next(); - break; - case 106: - regs.ya = op_adw(regs.ya, rd); - break; - case 107: - regs.a = op_ror(regs.a); - break; - case 108: - regs.a = regs.x; - break; - case 109: - regs.p.n = (regs.a & 0x80); - break; - case 110: - regs.p.z = (regs.a == 0); - break; - case 111: - regs.p = op_readsp(); - break; - case 112: - regs.p.c = 1; - break; - case 113: - regs.a = op_adc(regs.a, rd); - break; - case 114: - wr = op_adc(wr, rd); - break; - case 115: - regs.p.c ^= (bool)(rd & (1 << bit)); - break; - case 116: - rd = op_dec(rd); - break; - case 117: - regs.y = op_ld(regs.y, rd); - break; - case 118: - wr = op_st(wr, rd); - break; - case 119: - if(regs.p.c != 0) op_next(); - break; - case 120: - regs.ya = op_sbw(regs.ya, rd); - break; - case 121: - regs.a = op_dec(regs.a); - break; - case 122: - regs.x = regs.s; - break; - case 123: - //!!MULTI0 - 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 S-SMP 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); - break; - case 124: - regs.a = (regs.a >> 4) | (regs.a << 4); - break; - case 125: - regs.p.n = regs.a & 0x80; - break; - case 126: - regs.p.z = regs.a == 0; - break; - case 127: - regs.p.i = 1; - break; - case 128: - regs.a = op_sbc(regs.a, rd); - break; - case 129: - wr = op_sbc(wr, rd); - break; - case 130: - regs.p.c = (rd & (1 << bit)); - break; - case 131: - rd = op_inc(rd); - break; - case 132: - regs.a = op_readsp(); - break; - case 133: - op_writedp(regs.x++, regs.a); - break; - case 134: - if(regs.p.c != 1) op_next(); - break; - case 135: - regs.ya = op_ldw(regs.ya, rd); - break; - case 136: - regs.a = op_inc(regs.a); - break; - case 137: - regs.s = regs.x; - break; - case 138: - //!!MULTI1 - 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); - break; - case 139: - regs.a = op_readdp(regs.x++); - break; - case 140: - op_readdp(dp); - break; - case 141: - op_writedp(dp, regs.a); - break; - case 142: - op_write(dp, regs.a); - break; - case 143: - op_readdp(regs.x); - break; - case 144: - op_writedp(regs.x, regs.a); - break; - case 145: - sp = op_readpc() + regs.x; - break; - case 146: - dp.l = op_readdp(sp++); - break; - case 147: - dp.h = op_readdp(sp++); - break; - case 148: - op_write(dp, regs.x); - break; - case 149: - rd = (rd & ~(1 << bit)) | (regs.p.c << bit); - break; - case 150: - op_writedp(dp, regs.y); - break; - case 151: - op_write(dp, regs.y); - break; - case 152: - regs.x = op_ld(regs.x, rd); - break; - case 153: - regs.x = op_readsp(); - break; - case 154: - //!!MULTI2 - 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); - break; - case 155: - if(regs.p.z != 0) op_next(); - break; - case 156: - dp += regs.y; - break; - case 157: - op_writedp(dp, regs.x); - break; - case 158: - dp = op_readpc() + regs.y; - break; - case 159: - op_writedp(dp++, regs.a); - break; - case 160: - op_writedp(dp++, regs.y); - break; - case 161: - regs.y = op_dec(regs.y); - break; - case 162: - regs.a = regs.y; - break; - case 163: - sp = op_readdp(dp + regs.x); - break; - case 164: - //!!MULTI3 - 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); - break; - case 165: - regs.p.v = 0; - break; - case 166: - regs.p.h = 0; - break; - case 167: - regs.a = op_ld(regs.a, rd); - break; - case 168: - rd ^= 1 << bit; - break; - case 169: - regs.p.c = !regs.p.c; - break; - case 170: - regs.y = op_readsp(); - break; - case 171: - uindex = -1; //!!REPEAT - break; - case 172: - if(regs.p.z != 1) op_next(); - break; - case 173: - rd = op_readdp(dp + regs.y); - break; - case 174: - regs.y = op_inc(regs.y); - break; - case 175: - regs.y = regs.a; - break; - case 176: - regs.p.n = (regs.y & 0x80); - break; - case 177: - regs.p.z = (regs.y == 0); - break; - case 178: - if(--regs.y == 0) op_next(); - break; - } - uindex++; -} diff --git a/libsnes/bsnes/snes/smp/memory/memory.cpp b/libsnes/bsnes/snes/smp/memory/memory.cpp index 7a53df5df1..b46dc45802 100644 --- a/libsnes/bsnes/snes/smp/memory/memory.cpp +++ b/libsnes/bsnes/snes/smp/memory/memory.cpp @@ -40,7 +40,7 @@ uint8 SMP::op_busread(uint16 addr) { case 0xf5: //CPUIO1 case 0xf6: //CPUIO2 case 0xf7: //CPUIO3 - synchronize_cpu_force(); + synchronize_cpu(); return cpu.port_read(addr); case 0xf8: //RAM0 @@ -99,7 +99,7 @@ void SMP::op_buswrite(uint16 addr, uint8 data) { if(data & 0x30) { //one-time clearing of APU port read registers, //emulated by simulating CPU writes of 0x00 - synchronize_cpu_force(); + synchronize_cpu(); if(data & 0x20) { cpu.port_write(2, 0x00); cpu.port_write(3, 0x00); @@ -143,7 +143,7 @@ void SMP::op_buswrite(uint16 addr, uint8 data) { case 0xf5: //CPUIO1 case 0xf6: //CPUIO2 case 0xf7: //CPUIO3 - synchronize_cpu_force(); + synchronize_cpu(); port_write(addr, data); break; diff --git a/libsnes/bsnes/snes/smp/smp.cpp b/libsnes/bsnes/snes/smp/smp.cpp index 92e4d72621..b15b211f5d 100644 --- a/libsnes/bsnes/snes/smp/smp.cpp +++ b/libsnes/bsnes/snes/smp/smp.cpp @@ -16,23 +16,12 @@ void SMP::step(unsigned clocks) { } void SMP::synchronize_cpu() { - if(CPU::Threaded == true) { + if(CPU::Threaded == true) { if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(cpu.thread); } else { while(clock >= 0) cpu.enter(); } -} - -void SMP::synchronize_cpu_force() { - if(CPU::Threaded == true) { - if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) - co_switch(cpu.thread); - else if(clock >= 0 && scheduler.sync == Scheduler::SynchronizeMode::All) - interface()->message("SMP had to advance nondeterministically!"); - } else { - while(clock >= 0) cpu.enter(); - } -} +} void SMP::synchronize_dsp() { if(DSP::Threaded == true) { @@ -45,17 +34,10 @@ void SMP::synchronize_dsp() { void SMP::Enter() { smp.enter(); } void SMP::enter() { - while(true) { - // see comment in timing.cpp - if(clock > +(768 * 24 * (int64)24000000)) - synchronize_cpu(); - - if(scheduler.sync == Scheduler::SynchronizeMode::CPU) { - synchronize_cpu(); // when in CPU sync mode, always switch back to CPU as soon as possible - } + while(true) { if(scheduler.sync == Scheduler::SynchronizeMode::All) { scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); - } + } debugger.op_exec(regs.pc); if(interface()->wanttrace & TRACE_SMP_MASK) @@ -81,11 +63,7 @@ void SMP::power() { void SMP::reset() { create(Enter, system.apu_frequency()); - regs.pc = 0xffc0; - // exact value doesn't matter much, so long as "fetch" is next - opcode = 0; // NOP - uindex = 1; // fetch phase - + regs.pc = 0xffc0; regs.a = 0x00; regs.x = 0x00; regs.y = 0x00; diff --git a/libsnes/bsnes/snes/smp/smp.hpp b/libsnes/bsnes/snes/smp/smp.hpp index da1d56ec16..70edf66974 100644 --- a/libsnes/bsnes/snes/smp/smp.hpp +++ b/libsnes/bsnes/snes/smp/smp.hpp @@ -1,63 +1,62 @@ -struct SMP : public Processor, public SMPcore { - static const uint8 iplrom[64]; - uint8* apuram; //[64 * 1024]; - - enum : bool { Threaded = true }; - alwaysinline void step(unsigned clocks); +struct SMP : public Processor, public SMPcore { + static const uint8 iplrom[64]; + uint8* apuram; //[64 * 1024]; + + enum : bool { Threaded = true }; + alwaysinline void step(unsigned clocks); alwaysinline void synchronize_cpu(); - alwaysinline void synchronize_cpu_force(); - alwaysinline void synchronize_dsp(); - - uint8 port_read(uint2 port) const; - void port_write(uint2 port, uint8 data); - - void enter(); - void power(); - void reset(); - - void serialize(serializer&); - SMP(); - ~SMP(); - void initialize(); - -privileged: - #include "memory/memory.hpp" - #include "timing/timing.hpp" - - struct { - //timing - unsigned clock_counter; - unsigned dsp_counter; - unsigned timer_step; - - //$00f0 - uint8 clock_speed; - uint8 timer_speed; - bool timers_enable; - bool ram_disable; - bool ram_writable; - bool timers_disable; - - //$00f1 - bool iplrom_enable; - - //$00f2 - uint8 dsp_addr; - - //$00f8,$00f9 - uint8 ram00f8; - uint8 ram00f9; - } status; - - static void Enter(); - - friend class SMPcore; - - struct Debugger { - hook op_exec; - hook op_read; - hook op_write; - } debugger; -}; - -extern SMP smp; + alwaysinline void synchronize_dsp(); + + uint8 port_read(uint2 port) const; + void port_write(uint2 port, uint8 data); + + void enter(); + void power(); + void reset(); + + void serialize(serializer&); + SMP(); + ~SMP(); + void initialize(); + +privileged: + #include "memory/memory.hpp" + #include "timing/timing.hpp" + + struct { + //timing + unsigned clock_counter; + unsigned dsp_counter; + unsigned timer_step; + + //$00f0 + uint8 clock_speed; + uint8 timer_speed; + bool timers_enable; + bool ram_disable; + bool ram_writable; + bool timers_disable; + + //$00f1 + bool iplrom_enable; + + //$00f2 + uint8 dsp_addr; + + //$00f8,$00f9 + uint8 ram00f8; + uint8 ram00f9; + } status; + + static void Enter(); + + friend class SMPcore; + + struct Debugger { + hook op_exec; + hook op_read; + hook op_write; + } debugger; +}; + +extern SMP smp; diff --git a/libsnes/bsnes/snes/smp/timing/timing.cpp b/libsnes/bsnes/snes/smp/timing/timing.cpp index 419d6c5c20..286c733dd0 100644 --- a/libsnes/bsnes/snes/smp/timing/timing.cpp +++ b/libsnes/bsnes/snes/smp/timing/timing.cpp @@ -1,72 +1,62 @@ -#ifdef SMP_CPP - -void SMP::add_clocks(unsigned clocks) { - step(clocks); - synchronize_dsp(); - +#ifdef SMP_CPP + +void SMP::add_clocks(unsigned clocks) { + step(clocks); + synchronize_dsp(); + #if defined(DEBUGGER) - #error -DDEBUGGER SMP runtosave() correctness not checked - synchronize_cpu(); - #else - //forcefully sync S-SMP to S-CPU in case chips are not communicating + synchronize_cpu(); + #else + //forcefully sync S-SMP to S-CPU in case chips are not communicating //sync if S-SMP is more than 24 samples ahead of S-CPU -/* -our new smp design guarantees that there is at most one required synchronize_cpu() per uop, -inside an op_busread() or op_buswrite(). this extra synchronize can cause problems if we -swap out of the SMP at the beginning of a uop with an add_clocks() call when there is an -important op_busread() / op_buswrite() later on. the SMP will need to finish that uop in -order to reach a savable state, but it might never get to do so until it's too late (ie, -scheduler.sync == Scheduler.SynchronizeMode::All). so we remove this call and instead -do catchup sync in the main Enter() loop. -*/ - //if(clock > +(768 * 24 * (int64)24000000)) synchronize_cpu(); - #endif -} - -void SMP::cycle_edge() { - timer0.tick(); - timer1.tick(); - timer2.tick(); - - //TEST register S-SMP speed control - //24 clocks have already been added for this cycle at this point - switch(status.clock_speed) { - case 0: break; //100% speed - case 1: add_clocks(24); break; // 50% speed - case 2: while(true) add_clocks(24); // 0% speed -- locks S-SMP - case 3: add_clocks(24 * 9); break; // 10% speed - } -} - -template -void SMP::Timer::tick() { - //stage 0 increment - stage0_ticks += smp.status.timer_step; - if(stage0_ticks < timer_frequency) return; - stage0_ticks -= timer_frequency; - - //stage 1 increment - stage1_ticks ^= 1; - synchronize_stage1(); -} - -template -void SMP::Timer::synchronize_stage1() { - bool new_line = stage1_ticks; - if(smp.status.timers_enable == false) new_line = false; - if(smp.status.timers_disable == true) new_line = false; - - bool old_line = current_line; - current_line = new_line; - if(old_line != 1 || new_line != 0) return; //only pulse on 1->0 transition - - //stage 2 increment - if(enable == false) return; - if(++stage2_ticks != target) return; - - //stage 3 increment - stage2_ticks = 0; - stage3_ticks++; -} - -#endif + if(clock > +(768 * 24 * (int64)24000000)) synchronize_cpu(); + #endif +} + +void SMP::cycle_edge() { + timer0.tick(); + timer1.tick(); + timer2.tick(); + + //TEST register S-SMP speed control + //24 clocks have already been added for this cycle at this point + switch(status.clock_speed) { + case 0: break; //100% speed + case 1: add_clocks(24); break; // 50% speed + case 2: while(true) add_clocks(24); // 0% speed -- locks S-SMP + case 3: add_clocks(24 * 9); break; // 10% speed + } +} + +template +void SMP::Timer::tick() { + //stage 0 increment + stage0_ticks += smp.status.timer_step; + if(stage0_ticks < timer_frequency) return; + stage0_ticks -= timer_frequency; + + //stage 1 increment + stage1_ticks ^= 1; + synchronize_stage1(); +} + +template +void SMP::Timer::synchronize_stage1() { + bool new_line = stage1_ticks; + if(smp.status.timers_enable == false) new_line = false; + if(smp.status.timers_disable == true) new_line = false; + + bool old_line = current_line; + current_line = new_line; + if(old_line != 1 || new_line != 0) return; //only pulse on 1->0 transition + + //stage 2 increment + if(enable == false) return; + if(++stage2_ticks != target) return; + + //stage 3 increment + stage2_ticks = 0; + stage3_ticks++; +} + +#endif