From 397b9c45054834d93801713b74e5e734cd688262 Mon Sep 17 00:00:00 2001 From: byuu Date: Sun, 2 Oct 2005 00:38:34 +0000 Subject: [PATCH] Update to bsnes v012 release. Changelog: - Added S-DSP emulation - Added sound output support via DirectSound -- no sound buffering though, so sound is muted by default - Added option to record raw sound output to WAV files - Added multiple color adjustment filters to the video output - Added mode3/4 direct color support - Added mode7 direct color and mosaic support - Greatly improved mode7 rendering algorithm thanks to anomie - Fixed mode7 screen repitition and EXTBG effects - Greatly increased accuracy of NMI and IRQ timing, and emulated many newly discovered hardware quirks involving the two - A few speed improvements courtesy of Nach for profiling the code for me I'm now looking for assistance with sound buffering. Specifically, I need help modifying the DirectSound code to allow the emulator to be ran between 50%-400% normal speed, while keeping the sound output relatively good. If you have experience with this and can help, please get in touch with me (setsunakun0 at hotmail dot com). --- bsnes.cfg | 106 +++-- bsnes.exe | Bin 630784 -> 630784 bytes license.txt | 2 +- src/apu/apu.cpp | 1 + src/apu/apu.h | 4 +- src/apu/bapu/bapu.cpp | 15 +- src/apu/bapu/bapu.h | 3 +- src/apu/bapu/bapugen.exe | Bin 53248 -> 0 bytes src/apu/bapuskip/bapuskip.h | 4 + src/apu/iplrom.h | 9 +- src/base.h | 9 +- src/chip/sdd1/sdd1.cpp | 9 + src/chip/sdd1/sdd1.h | 1 + src/chip/srtc/srtc.cpp | 8 + src/chip/srtc/srtc.h | 10 +- src/config/config.cpp | 28 ++ src/config/config.h | 15 + src/cpu/bcpu/bcpu.cpp | 191 ++------- src/cpu/bcpu/bcpu.h | 25 +- src/cpu/bcpu/bcpu_dma.cpp | 10 +- src/cpu/bcpu/bcpu_exec.cpp | 25 +- src/cpu/bcpu/bcpu_int.cpp | 70 ++++ src/cpu/bcpu/bcpu_mmio.cpp | 123 +++--- src/cpu/bcpu/bcpu_op.h | 2 +- src/cpu/bcpu/bcpu_op_misc.cpp | 55 ++- src/cpu/bcpu/bcpu_op_pc.cpp | 67 ++- src/cpu/bcpu/bcpu_op_read.cpp | 252 ++++++++++++ src/cpu/bcpu/bcpu_op_rmw.cpp | 38 ++ src/cpu/bcpu/bcpu_op_write.cpp | 48 +++ src/cpu/bcpu/bcpu_optable.cpp | 2 +- src/cpu/bcpu/bcpu_timing.cpp | 251 ++++++++++-- src/cpu/bcpu/bcpu_timing.h | 40 +- src/cpu/bcpu/bcpugen.cpp | 7 +- src/cpu/bcpu/bcpugen.exe | Bin 53248 -> 0 bytes src/cpu/bcpu/op_misc.b | 82 ++-- src/cpu/bcpu/op_pc.b | 52 ++- src/cpu/bcpu/op_read.b | 102 +++-- src/cpu/bcpu/op_rmw.b | 30 +- src/cpu/bcpu/op_write.b | 90 +++-- src/cpu/cpu.cpp | 1 + src/cpu/cpu.h | 7 +- src/dsp/bdsp/bdsp.cpp | 583 +++++++++++++++++++++++++++ src/dsp/bdsp/bdsp.h | 176 ++++++++ src/dsp/bdsp/bdsp_tables.cpp | 73 ++++ src/dsp/dsp.h | 9 + src/interface.h | 11 + src/lib/libbase.h | 2 + src/lib/libconfig.cpp | 352 ++++++---------- src/lib/libconfig.h | 113 ++++-- src/memory/bmemory/bcart_exhirom.h | 2 +- src/memory/bmemory/bcart_exlorom.h | 2 +- src/memory/bmemory/bcart_hirom.h | 2 +- src/memory/bmemory/bcart_lorom.h | 2 +- src/memory/bmemory/bmemory.cpp | 111 ++--- src/memory/bmemory/bmemory.h | 12 +- src/memory/memory.cpp | 66 +-- src/memory/memory.h | 45 ++- src/ppu/bppu/bppu.cpp | 66 +-- src/ppu/bppu/bppu.h | 15 +- src/ppu/bppu/bppu_mmio.cpp | 9 +- src/ppu/bppu/bppu_render.cpp | 19 +- src/ppu/bppu/bppu_render.h | 25 +- src/ppu/bppu/bppu_render_addsub.cpp | 21 +- src/ppu/bppu/bppu_render_bg.cpp | 74 ++-- src/ppu/bppu/bppu_render_line.cpp | 45 ++- src/ppu/bppu/bppu_render_mode7.cpp | 184 +++++---- src/ppu/bppu/bppu_render_oam.cpp | 5 +- src/ppu/bppu/snes9x_render_mode7.cpp | 148 +++++++ src/ppu/ppu.cpp | 24 +- src/ppu/ppu.h | 36 +- src/sdl/Makefile | 7 + src/sdl/Makefile.win32 | 7 + src/sdl/bsnes.cpp | 31 +- src/sdl/bsnes.h | 6 +- src/sdl/bsnes_sdl.cfg | 18 - src/sdl/cc.bat | 1 - src/sdl/config.cpp | 73 ++-- src/sdl/render.cpp | 114 ++---- src/sdl/sdlmain.cpp | 77 ++-- src/sdl/sdlmain.h | 4 +- src/sdl/sdlrun.bat | 2 +- src/snes/snes.cpp | 67 ++- src/snes/snes.h | 51 ++- src/snes/snes_audio.cpp | 145 +++++++ src/snes/snes_audio.h | 22 + src/snes/snes_input.cpp | 0 src/snes/snes_input.h | 21 + src/snes/snes_video.cpp | 385 ++++++++++++++++++ src/snes/snes_video.h | 72 ++++ src/snes/snes_video_ex.cpp | 106 +++++ src/win/Makefile | 11 +- src/win/bsnes.cpp | 49 +-- src/win/bsnes.h | 6 +- src/win/bsnes.lnk | Bin 1292 -> 1267 bytes src/win/bsnes.res | Bin 244452 -> 0 bytes src/win/config.cpp | 84 ++-- src/win/dd_renderer.cpp | 132 ++---- src/win/dd_renderer.h | 23 +- src/win/dd_renderer16.cpp | 146 +++---- src/win/ds_sound.cpp | 77 ++++ src/win/ds_sound.h | 30 ++ src/win/ui.cpp | 5 +- src/win/ui.h | 9 +- src/win/ui_console.cpp | 2 +- src/win/ui_inputconfig.cpp | 24 +- src/win/ui_main.cpp | 108 +++-- src/win/winmain.cpp | 63 ++- 107 files changed, 4295 insertions(+), 1709 deletions(-) delete mode 100644 src/apu/bapu/bapugen.exe create mode 100644 src/config/config.cpp create mode 100644 src/config/config.h create mode 100644 src/cpu/bcpu/bcpu_int.cpp delete mode 100644 src/cpu/bcpu/bcpugen.exe create mode 100644 src/dsp/bdsp/bdsp.cpp create mode 100644 src/dsp/bdsp/bdsp.h create mode 100644 src/dsp/bdsp/bdsp_tables.cpp create mode 100644 src/dsp/dsp.h create mode 100644 src/ppu/bppu/snes9x_render_mode7.cpp delete mode 100644 src/sdl/bsnes_sdl.cfg create mode 100644 src/snes/snes_audio.cpp create mode 100644 src/snes/snes_audio.h create mode 100644 src/snes/snes_input.cpp create mode 100644 src/snes/snes_input.h create mode 100644 src/snes/snes_video.cpp create mode 100644 src/snes/snes_video.h create mode 100644 src/snes/snes_video_ex.cpp delete mode 100644 src/win/bsnes.res create mode 100644 src/win/ds_sound.cpp create mode 100644 src/win/ds_sound.h diff --git a/bsnes.cfg b/bsnes.cfg index 2e683772..8bb84202 100644 --- a/bsnes.cfg +++ b/bsnes.cfg @@ -1,57 +1,87 @@ -#[bsnes v0.009 configuration file] +# Applies contrast adjust filter to video output when enabled +# Works by lowering the brightness of darker colors, +# while leaving brighter colors alone; thus reducing saturation +# (default = true) +snes.video_color_curve = true -#[apu enable] -apu.enabled = true +# Selects color adjustment filter for video output +# 0 = Normal (no filter, rgb555) +# 1 = Grayscale mode (l5) +# 2 = VGA mode (rgb332) +# 3 = Genesis mode (rgb333) +# (default = 0) +snes.video_color_adjust_mode = 0 -#[video mode] -# 0: 256x224w -# 1: 512x448w -# 2: 960x720w -# 3: 640x480f -# 4: 1024x768f +# Mutes SNES audio output when enabled +# (default = true) +snes.mute = true + +# Video mode +# 0 = 256x224w +# 1 = 512x448w +# 2 = 960x720w +# 3 = 640x480f +# 4 = 1024x768f +# (default = 1) video.mode = 1 -#[video memory type] -# true: video ram (VRAM) -# false: system ram (SRAM) -# -# VRAM results in the image being stretched in hardware, -# which is generally much faster, and automatically adds -# bilinear filtering (if the card supports it). -# -# However, some video cards end up taking a major speed -# loss when this option is enabled. It is also the only -# way to guarantee that the output image will not be -# filtered. +# Use Video RAM instead of System RAM +# (default = true) video.use_vram = true -#[color curve] -# gives a more NTSC TV-style feel to the color palette -# by darkening the image contrast. -video.color_curve = enabled - -#[show fps] -# true: show fps in titlebar -# false: do not show fps in titlebar -gui.show_fps = true - -#[wait for vertical retrace] +# Wait for vertical retrace when updating screen +# (default = false) video.vblank = false -#[joypad 1 configuration] -# Key numbers are standard windows VK_* keys. -# Unfortunately, I don't have a table of common -# key mappings to list here... use GUI joypad -# configuration utility to edit these. +# Show framerate in window title +# (default = true) +gui.show_fps = false + +# Joypad1 up +# (default = 0x26) input.joypad1.up = 0x26 + +# Joypad1 down +# (default = 0x28) input.joypad1.down = 0x28 + +# Joypad1 left +# (default = 0x25) input.joypad1.left = 0x25 + +# Joypad1 right +# (default = 0x27) input.joypad1.right = 0x27 + +# Joypad1 A +# (default = 0x58) input.joypad1.a = 0x58 + +# Joypad1 B +# (default = 0x5a) input.joypad1.b = 0x5a + +# Joypad1 X +# (default = 0x53) input.joypad1.x = 0x53 + +# Joypad1 Y +# (default = 0x41) input.joypad1.y = 0x41 + +# Joypad1 L +# (default = 0x44) input.joypad1.l = 0x44 + +# Joypad1 R +# (default = 0x43) input.joypad1.r = 0x43 + +# Joypad1 select +# (default = 0x10) input.joypad1.select = 0x10 -input.joypad1.start = 0x0d + +# Joypad1 start +# (default = 0xd) +input.joypad1.start = 0xd + diff --git a/bsnes.exe b/bsnes.exe index 6081d3214eb335c5a3fa60a91904ff78130a0313..2a1747eccef33ba03dfc927f2d7972a7dc2eab4e 100644 GIT binary patch literal 630784 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 z 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

HVxRh9NcU{-LsmP+P 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 CF)9E6 literal 630784 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𗱍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 lCnxWDU^Uaread(status.dsp_addr & 0x7f); break; case 0xf4: //CPUIO0 case 0xf5: //CPUIO1 @@ -111,7 +111,7 @@ void bAPU::spcram_write(uint16 addr, uint8 value) { case 0xf3: //DSPDATA //0x80-0xff is a read-only mirror of 0x00-0x7f if(status.dsp_addr < 0x80) { - dsp_regs[status.dsp_addr & 0x7f] = value; + dsp->write(status.dsp_addr & 0x7f, value); } break; case 0xf4: //CPUIO0 @@ -209,6 +209,14 @@ void bAPU::stack_write(uint8 value) { regs.sp--; } +uint8 *bAPU::get_spcram_handle() { + if(!spcram) { + alert("bAPU::get_spcram_handle() -- spcram uninitialized"); + } + + return spcram; +} + void bAPU::run() { exec_cycle(); } @@ -247,15 +255,12 @@ void bAPU::reset() { t0.stage3_ticks = 0; t1.stage3_ticks = 0; t2.stage3_ticks = 0; - - memset(dsp_regs, 0, 128); } bAPU::bAPU() { init_op_table(); spcram = (uint8*)malloc(65536); - memcpy(iplrom, spc700_iplrom, 64); t0.cycle_frequency = 128; //1.024mhz / 8khz = 128 t1.cycle_frequency = 128; //1.024mhz / 8khz = 128 diff --git a/src/apu/bapu/bapu.h b/src/apu/bapu/bapu.h index b09d4338..065f9972 100644 --- a/src/apu/bapu/bapu.h +++ b/src/apu/bapu/bapu.h @@ -29,12 +29,13 @@ struct { bAPUTimer t0, t1, t2; -uint8 *spcram, iplrom[64], dsp_regs[128]; +uint8 *spcram; inline uint8 spcram_read (uint16 addr); inline void spcram_write(uint16 addr, uint8 value); inline uint8 port_read (uint8 port); inline void port_write(uint8 port, uint8 value); + inline uint8 *get_spcram_handle(); inline void run(); inline uint32 cycles_executed(); inline void power(); diff --git a/src/apu/bapu/bapugen.exe b/src/apu/bapu/bapugen.exe deleted file mode 100644 index 4f0e81b9abaa8f9b9db75aaa94c59338ff3fe3fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53248 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 AasU7T diff --git a/src/apu/bapuskip/bapuskip.h b/src/apu/bapuskip/bapuskip.h index 9d907c23..63b1da50 100644 --- a/src/apu/bapuskip/bapuskip.h +++ b/src/apu/bapuskip/bapuskip.h @@ -1,4 +1,7 @@ class bAPUSkip : public APU { +private: +uint8 spcram[65536]; + public: struct _apu_port { @@ -26,6 +29,7 @@ enum { uint8 port_read (uint8 port); void port_write (uint8 port, uint8 value); + uint8 *get_spcram_handle() { return spcram; } void run(); uint32 cycles_executed() { return 12 * 24; } void power(); diff --git a/src/apu/iplrom.h b/src/apu/iplrom.h index 84cb6441..9fcf4d38 100644 --- a/src/apu/iplrom.h +++ b/src/apu/iplrom.h @@ -3,12 +3,8 @@ //allow writing to the IPLROM, all writes are //instead mapped to the extended SPC700 RAM region, //accessible when $f1 bit 7 is clear. -//If you use this buffer directly, make sure not -//to write to it, as this will break other APU -//implementations that attempt to use this buffer. -#ifdef _APU_IPLROM -const uint8 spc700_iplrom[64] = { +const uint8 APU::iplrom[64] = { /*ffc0*/ 0xcd, 0xef, //mov x,#$ef /*ffc2*/ 0xbd, //mov sp,x /*ffc3*/ 0xe8, 0x00, //mov a,#$00 @@ -43,6 +39,3 @@ const uint8 spc700_iplrom[64] = { /*fffb*/ 0x1f, 0x00, 0x00, //jmp ($0000+x) /*fffe*/ 0xc0, 0xff //---reset vector location ($ffc0) }; -#else -extern const uint8 spc700_iplrom[64]; -#endif diff --git a/src/base.h b/src/base.h index bbb683fb..783fa03f 100644 --- a/src/base.h +++ b/src/base.h @@ -1,5 +1,8 @@ #include #include "lib/libbase.h" +#include "lib/libvector.h" +#include "lib/libstring.h" +#include "lib/libconfig.h" #if defined(_WIN32) #define _WIN32_ @@ -11,12 +14,6 @@ #error "unknown architecture" #endif -//structs -typedef struct { -uint8 *data; -uint32 size; -}lfile; - //platform-specific global functions void *memalloc(uint32 size, char *name = 0, ...); void memfree(void *mem, char *name = 0, ...); diff --git a/src/chip/sdd1/sdd1.cpp b/src/chip/sdd1/sdd1.cpp index b26d0e3f..c26694bb 100644 --- a/src/chip/sdd1/sdd1.cpp +++ b/src/chip/sdd1/sdd1.cpp @@ -1,6 +1,15 @@ #include "../../base.h" #include "sdd1emu.cpp" +void SDD1::init() { +} + +void SDD1::enable() { + for(int i=0x4800;i<=0x4807;i++) { + mem_bus->set_mmio_mapper(i, mmio); + } +} + void SDD1::power() { reset(); } diff --git a/src/chip/sdd1/sdd1.h b/src/chip/sdd1/sdd1.h index d8cba35b..6bb4af8f 100644 --- a/src/chip/sdd1/sdd1.h +++ b/src/chip/sdd1/sdd1.h @@ -21,6 +21,7 @@ struct { bool dma_active; }sdd1; void init(); + void enable(); void power(); void reset(); uint32 offset(uint32 addr); diff --git a/src/chip/srtc/srtc.cpp b/src/chip/srtc/srtc.cpp index 3601ecd9..590037ab 100644 --- a/src/chip/srtc/srtc.cpp +++ b/src/chip/srtc/srtc.cpp @@ -74,6 +74,14 @@ tm *t; srtc.data[12] = t->tm_wday; } +void SRTC::init() { +} + +void SRTC::enable() { + mem_bus->set_mmio_mapper(0x2800, mmio); + mem_bus->set_mmio_mapper(0x2801, mmio); +} + void SRTC::power() { memset(&srtc, 0, sizeof(srtc)); reset(); diff --git a/src/chip/srtc/srtc.h b/src/chip/srtc/srtc.h index 8f0ef48b..532a1f1e 100644 --- a/src/chip/srtc/srtc.h +++ b/src/chip/srtc/srtc.h @@ -41,11 +41,13 @@ Index Description Range 12 Day of week 0-6 (0=Sunday, ...) ******************************/ struct { - int8 index; - uint8 mode; - uint8 data[MAX_SRTC_INDEX + 1]; -}srtc; + int8 index; + uint8 mode; + uint8 data[MAX_SRTC_INDEX + 1]; +} srtc; void set_time(); + void init(); + void enable(); void power(); void reset(); void write(uint8 data); diff --git a/src/config/config.cpp b/src/config/config.cpp new file mode 100644 index 00000000..a3d82316 --- /dev/null +++ b/src/config/config.cpp @@ -0,0 +1,28 @@ +Config config_file; + +namespace config { + +SNES::VideoColorAdjust SNES::video_color_curve(&config_file, "snes.video_color_curve", + "Applies contrast adjust filter to video output when enabled\n" + "Works by lowering the brightness of darker colors,\n" + "while leaving brighter colors alone; thus reducing saturation", + true, Setting::TRUE_FALSE); + +SNES::VideoColorAdjust SNES::video_color_adjust_mode(&config_file, "snes.video_color_adjust_mode", + "Selects color adjustment filter for video output\n" + " 0 = Normal (no filter, rgb555)\n" + " 1 = Grayscale mode (l5)\n" + " 2 = VGA mode (rgb332)\n" + " 3 = Genesis mode (rgb333)", + 0, Setting::DEC); + +void SNES::VideoColorAdjust::set(uint32 _data) { + data = _data; + ::snes->update_color_lookup_table(); +} + +Setting SNES::mute(&config_file, "snes.mute", + "Mutes SNES audio output when enabled", + true, Setting::TRUE_FALSE); + +}; diff --git a/src/config/config.h b/src/config/config.h new file mode 100644 index 00000000..9933d6c8 --- /dev/null +++ b/src/config/config.h @@ -0,0 +1,15 @@ +extern Config config_file; + +namespace config { + +extern struct SNES { + static class VideoColorAdjust : public Setting { + public: + void set(uint32 _data); + SettingOperators(VideoColorAdjust); + } video_color_curve, video_color_adjust_mode; + + static Setting mute; +} snes; + +}; diff --git a/src/cpu/bcpu/bcpu.cpp b/src/cpu/bcpu/bcpu.cpp index 33ea3b4c..295b1f2e 100644 --- a/src/cpu/bcpu/bcpu.cpp +++ b/src/cpu/bcpu/bcpu.cpp @@ -13,152 +13,26 @@ #include "bcpu_timing.cpp" -uint8 bCPU::pio_status() { - return status.pio; -} +#include "bcpu_int.cpp" -/*********** - *** IRQ *** - *********** -cycles: - [1] pbr,pc ; io/opcode - [2] pbr,pc ; io - [3] 0,s ; pbr - [4] 0,s-1 ; pch - [5] 0,s-2 ; pcl - [6] 0,s-3 ; p - [7] 0,va ; aavl - [8] 0,va+1 ; aavh -*/ -void bCPU::irq(uint16 addr) { - if(status.cpu_state == CPUSTATE_WAI) { - status.cpu_state = CPUSTATE_RUN; - regs.pc.w++; - } - -//GTE documentation is incorrect, first cycle -//is a memory read fetch from PBR:PC - add_cycles(mem_bus->speed(regs.pc.d)); - add_cycles(6); - stack_write(regs.pc.b); - stack_write(regs.pc.h); - stack_write(regs.pc.l); - stack_write(regs.p); - rd.l = op_read(OPMODE_ADDR, addr); - rd.h = op_read(OPMODE_ADDR, addr + 1); - - regs.pc.b = 0x00; - regs.pc.w = rd.w; - regs.p.i = 1; - regs.p.d = 0; - -//let debugger know the new IRQ opcode address - snes->notify(SNES::CPU_EXEC_OPCODE_END); -} - -//vcounter range verified on real hardware, -//HDMA runs on the very first scanline of vblank -bool bCPU::hdma_test() { - if(status.hdma_triggered == false) { - if(vcounter() <= (overscan()?239:224) && hcounter() >= 278) { - status.hdma_triggered = true; - return true; - } - } - return false; -} - -//NMI range: V==225/240,H>=12 ; V>225/240 -bool bCPU::nmi_test() { - if(status.nmi_exec == true)return false; - -//[status.cycle_count index] -// 6->12 -// 8->14 -int hc = status.cycle_count + 6; - if(vcounter() == ((overscan()?239:224) + 1) && hcycles() < hc) { - //dprintf("* miss at %3d,%4d,%3x : %d x=%0.4x", vcounter(), hcycles(), hcounter(), status.cycle_count, regs.x.w); - } - - if( - (vcounter() == ((overscan()?239:224) + 1) && hcycles() >= hc) || - (vcounter() > ((overscan()?239:224) + 1)) - ) { - //dprintf("* %3d,%4d,%3x : %d x=%0.4x", vcounter(), hcycles(), hcounter(), status.cycle_count, regs.x.w); - status.nmi_exec = true; - return status.nmi_enabled; - } - - return false; -} - -bool bCPU::irq_test() { -int vpos, hpos; - if(regs.p.i)return false; //no interrupt can occur with I flag set - if(status.irq_read == true)return false; //same as above - if(status.virq_enabled == false && status.hirq_enabled == false)return false; - -//if irq_exec is true, then an IRQ occurred already. -//IRQs will continue to fire until $4211 is read from, or -//$4200 is written to, where irq_exec is set back to false. - if(status.irq_exec == true) { - return true; - } - -//calculate V/H positions required for IRQ to trigger - vpos = status.virq_pos; - hpos = (status.hirq_enabled) ? status.hirq_pos : 0; - -//positions that can never be latched -//region_scanlines() = 262/NTSC, 312/PAL -//PAL results are unverified on hardware - if(vpos == 240 && hpos == 339 && interlace() == false && interlace_field() == 1)return false; - if(vpos == (region_scanlines() - 1) && hpos == 339 && interlace() == false)return false; - if(vpos == region_scanlines() && interlace() == false)return false; - if(vpos == region_scanlines() && hpos == 339)return false; - if(vpos > region_scanlines())return false; - if(hpos > 339)return false; - - if(hpos == 0) { - hpos = status.cycle_count + 14; - } else { - hpos <<= 2; - hpos += status.cycle_count + 18; - //it should be OK to use the current line cycles/frame lines, - //as the IRQ will only trigger on the correct scanline anyway... - if(hpos >= time.line_cycles) { - hpos -= time.line_cycles; - vpos++; - if(vpos >= time.frame_lines) { - vpos = 0; - } - } - } - - if(status.virq_enabled == true && vcounter() != vpos)return false; - - if(hcycles() >= hpos) { - status.irq_exec = true; - return true; - } - - return false; -} +uint8 bCPU::pio_status() { return status.pio; } void bCPU::run() { switch(status.cpu_state) { case CPUSTATE_DMA: dma_run(); break; - case CPUSTATE_RUN: case CPUSTATE_WAI: + case CPUSTATE_RUN: if(status.cycle_pos == 0) { //interrupts only trigger on opcode edges - if(nmi_test() == true) { + if(time.nmi_pending == true) { + time.nmi_pending = false; irq(0xffea); break; } - if(irq_test() == true) { + if(time.irq_pending == true) { + time.irq_pending = false; irq(0xffee); break; } @@ -184,19 +58,14 @@ void bCPU::scanline() { //connected status bit. status.joypad1_read_pos = 16; } - - if(status.virq_enabled == false) { - status.irq_read = false; - } } void bCPU::frame() { hdma_initialize(); - status.nmi_read = false; - status.nmi_exec = false; - - status.irq_read = false; + time.nmi_read = 1; + time.nmi_line = 1; + time.nmi_transition = 0; } void bCPU::power() { @@ -234,12 +103,6 @@ void bCPU::reset() { status.hdma_triggered = false; - status.nmi_read = false; - status.nmi_exec = false; - - status.irq_read = false; - status.irq_exec = false; - apu_port[0] = 0x00; apu_port[1] = 0x00; apu_port[2] = 0x00; @@ -258,43 +121,52 @@ void bCPU::port_write(uint8 port, uint8 value) { void bCPU::cpu_c2() { if(regs.d.l != 0x00) { - status.cycle_count = 6; - add_cycles(6); + cpu_io(); } } void bCPU::cpu_c4(uint16 x, uint16 y) { if(!regs.p.x && (x & 0xff00) != (y & 0xff00)) { - status.cycle_count = 6; - add_cycles(6); + cpu_io(); } } void bCPU::cpu_c6(uint16 addr) { if(regs.e && (regs.pc.w & 0xff00) != (addr & 0xff00)) { - status.cycle_count = 6; - add_cycles(6); + cpu_io(); } } +/* The next 3 functions control bus timing for the CPU. + * cpu_io is an I/O cycle, and always 6 clock cycles long. + * mem_read / mem_write indicate memory access bus cycle, + * they are either 6, 8, or 12 bus cycles long, depending + * both on location and the $420d.1 FastROM enable bit. + */ + void bCPU::cpu_io() { + if(status.is_last_cycle)last_cycle_exec(); + status.cycle_count = 6; add_cycles(6); } uint8 bCPU::mem_read(uint32 addr) { + if(status.is_last_cycle)last_cycle_exec(); + status.cycle_count = mem_bus->speed(addr); - add_cycles(2); + add_cycles(status.cycle_count - 4); regs.mdr = mem_bus->read(addr); - add_cycles(status.cycle_count - 2); + add_cycles(4); return regs.mdr; } void bCPU::mem_write(uint32 addr, uint8 value) { + if(status.is_last_cycle)last_cycle_exec(); + status.cycle_count = mem_bus->speed(addr); - add_cycles(6); + add_cycles(status.cycle_count); mem_bus->write(addr, value); - add_cycles(status.cycle_count - 6); } uint32 bCPU::op_addr(uint8 mode, uint32 addr) { @@ -306,12 +178,11 @@ uint32 bCPU::op_addr(uint8 mode, uint32 addr) { addr &= 0xffffff; break; case OPMODE_DBR: - addr &= 0xffffff; - addr = (regs.db << 16) + addr; + addr = ((regs.db << 16) + addr) & 0xffffff; break; case OPMODE_PBR: addr &= 0xffff; - addr = (regs.pc.b << 16) | addr; + addr = (regs.pc.b << 16) + addr; break; case OPMODE_DP: addr &= 0xffff; diff --git a/src/cpu/bcpu/bcpu.h b/src/cpu/bcpu/bcpu.h index 121b5fca..d593b288 100644 --- a/src/cpu/bcpu/bcpu.h +++ b/src/cpu/bcpu/bcpu.h @@ -10,8 +10,7 @@ bCPU *cpu; class bCPU : public CPU { private: -typedef void (bCPU::*op)(); -op optbl[256]; +void (bCPU::*optbl[256])(); enum { NTSC = 0, PAL = 1 }; uint8 region; @@ -53,20 +52,13 @@ struct { uint8 opcode; uint32 cycles_executed; +//set by last_cycle(), cleared by last_cycle_exec() + bool is_last_cycle; + uint8 dma_state; uint32 dma_cycle_count; bool hdma_triggered; -//used by $4210 read bit 7 - bool nmi_read; -//used by NMI test, set when NMI executed this frame - bool nmi_exec; - -//IRQ is level-sensitive, so $4211 must be read to -//prevent multiple interrupts from occurring - bool irq_read; -//this is used to return $4211 bit 7 - bool irq_exec; //$4207-$420a uint16 virq_trigger, hirq_trigger; @@ -98,7 +90,7 @@ struct { //$4214-$4216 uint16 r4214; uint16 r4216; -}status; +} status; struct { uint32 read_index; //set to 0 at beginning of DMA/HDMA @@ -136,12 +128,13 @@ struct { bool hdma_repeat; uint16 hdma_iaddr; bool hdma_active; -}channel[8]; +} channel[8]; inline bool hdma_test(); + + inline void irq(uint16 addr); inline bool nmi_test(); inline bool irq_test(); - inline void irq(uint16 addr); inline uint8 pio_status(); inline void run(); @@ -225,6 +218,8 @@ struct { enum { CYCLE_OPREAD = 0, CYCLE_READ, CYCLE_WRITE, CYCLE_IO }; inline void exec_cycle(); + inline void last_cycle(); + inline void last_cycle_exec(); inline void cycle_edge(); inline bool in_opcode(); diff --git a/src/cpu/bcpu/bcpu_dma.cpp b/src/cpu/bcpu/bcpu_dma.cpp index 7388358e..61a6b12f 100644 --- a/src/cpu/bcpu/bcpu_dma.cpp +++ b/src/cpu/bcpu/bcpu_dma.cpp @@ -113,11 +113,11 @@ uint16 index; void bCPU::hdma_run() { int l, xferlen; uint8 x, active_channels = 0; -static hdma_xferlen[8] = { 1, 2, 2, 4, 4, 4, 2, 4 }; +static uint8 hdma_xferlen[8] = { 1, 2, 2, 4, 4, 4, 2, 4 }; for(int i=0;i<8;i++) { if(channel[i].hdma_active == false)continue; -// add_cycles(8); + add_cycles(8); active_channels++; if(channel[i].hdma_line_counter == 0) { @@ -140,7 +140,7 @@ static hdma_xferlen[8] = { 1, 2, 2, 4, 4, 4, 2, 4 }; if(channel[i].hdma_indirect == true) { channel[i].hdma_iaddr = mem_bus->read(hdma_addr(i)); channel[i].hdma_iaddr |= mem_bus->read(hdma_addr(i)) << 8; -// add_cycles(16); + add_cycles(16); } } @@ -157,12 +157,12 @@ static hdma_xferlen[8] = { 1, 2, 2, 4, 4, 4, 2, 4 }; } hdma_write(i, l, x); -// add_cycles(8); + add_cycles(8); } } if(active_channels != 0) { -// add_cycles(18); + add_cycles(18); } } diff --git a/src/cpu/bcpu/bcpu_exec.cpp b/src/cpu/bcpu/bcpu_exec.cpp index 6e861392..0cef3fae 100644 --- a/src/cpu/bcpu/bcpu_exec.cpp +++ b/src/cpu/bcpu/bcpu_exec.cpp @@ -1,4 +1,15 @@ -inline void bCPU::cycle_edge() { +void bCPU::last_cycle() { + status.is_last_cycle = true; +} + +void bCPU::last_cycle_exec() { + status.is_last_cycle = false; + + time.nmi_pending = nmi_test(); + time.irq_pending = irq_test(); +} + +void bCPU::cycle_edge() { int c, n, z; if(status.dma_state != DMASTATE_STOP) { switch(status.dma_state) { @@ -36,15 +47,17 @@ int c, n, z; } void bCPU::exec_cycle() { +//on first cycle? if(status.cycle_pos == 0) { snes->notify(SNES::CPU_EXEC_OPCODE_BEGIN); status.opcode = op_read(); status.cycle_pos = 1; - } else { - (this->*optbl[status.opcode])(); - if(status.cycle_pos == 0) { - snes->notify(SNES::CPU_EXEC_OPCODE_END); - } + return; + } + + (this->*optbl[status.opcode])(); + if(status.cycle_pos == 0) { + snes->notify(SNES::CPU_EXEC_OPCODE_END); } } diff --git a/src/cpu/bcpu/bcpu_int.cpp b/src/cpu/bcpu/bcpu_int.cpp new file mode 100644 index 00000000..5a4eb1a8 --- /dev/null +++ b/src/cpu/bcpu/bcpu_int.cpp @@ -0,0 +1,70 @@ +/* +[IRQ cycles] + [1] pbr,pc ; opcode + [2] pbr,pc ; io + [3] 0,s ; pbr + [4] 0,s-1 ; pch + [5] 0,s-2 ; pcl + [6] 0,s-3 ; p + [7] 0,va ; aavl + [8] 0,va+1 ; aavh +*/ +void bCPU::irq(uint16 addr) { +//WDC documentation is incorrect, first cycle +//is a memory read fetch from PBR:PC + add_cycles(mem_bus->speed(regs.pc.d)); + add_cycles(6); + stack_write(regs.pc.b); + stack_write(regs.pc.h); + stack_write(regs.pc.l); + stack_write(regs.p); + rd.l = op_read(OPMODE_ADDR, addr); + rd.h = op_read(OPMODE_ADDR, addr + 1); + + regs.pc.b = 0x00; + regs.pc.w = rd.w; + regs.p.i = 1; + regs.p.d = 0; + +//let debugger know the new IRQ opcode address + snes->notify(SNES::CPU_EXEC_OPCODE_END); +} + +bool bCPU::nmi_test() { + if(time.nmi_transition == 0)return false; + time.nmi_transition = 0; + + if(status.cpu_state == CPUSTATE_WAI) { + status.cpu_state = CPUSTATE_RUN; + } + + return true; +} + +bool bCPU::irq_test() { + if(time.irq_transition == 1)goto _true; + + if(time.irq_read == 0) { + if(time.irq_line == 1 && (irq_trigger_pos_match(0) || irq_trigger_pos_match(2))) { + return false; + } + goto _true; + } + + if(time.irq_line == 0) { + time.irq_line = 1; + goto _true; + } + + return false; + +_true: + time.irq_transition = 0; + + if(status.cpu_state == CPUSTATE_WAI) { + status.cpu_state = CPUSTATE_RUN; + } + + if(regs.p.i)return false; + return true; +} diff --git a/src/cpu/bcpu/bcpu_mmio.cpp b/src/cpu/bcpu/bcpu_mmio.cpp index e36680b2..fa23536a 100644 --- a/src/cpu/bcpu/bcpu_mmio.cpp +++ b/src/cpu/bcpu/bcpu_mmio.cpp @@ -42,18 +42,17 @@ uint8 r; } //JOYSER0 -/* - The joypad contains a small bit shifter that has 16 bits. - Reading from 4016 reads one bit from this buffer, then moves - the buffer left one, and adds a '1' to the rightmost bit. - Writing a one to $4016 will fill the buffer with the current - joypad button states, and lock the bit shifter at position - zero. All reads will be the first buffer state, or 'B'. - A zero must be written back to $4016 to unlock the buffer, - so that reads will increment the bit shifting position. -*/ //7-2 = MDR //1-0 = Joypad serial data +/* The joypad contains a small bit shifter that has 16 bits. + * Reading from 4016 reads one bit from this buffer, then moves + * the buffer left one, and adds a '1' to the rightmost bit. + * Writing a one to $4016 will fill the buffer with the current + * joypad button states, and lock the bit shifter at position + * zero. All reads will be the first buffer state, or 'B'. + * A zero must be written back to $4016 to unlock the buffer, + * so that reads will increment the bit shifting position. + */ uint8 bCPU::mmio_r4016() { uint8 r; r = regs.mdr & 0xfc; @@ -96,44 +95,19 @@ uint8 r; } //RDNMI -/* $4210 bit 7 (NMI triggered bit) is set at: - * V=225/240,HC>=2, - * V>225 - * The bit is only set once per NMI trigger, so - * subsequent reads return this bit as being clear. - * There is but one exception: if the $4210 read - * occurs at *exactly* V=225/240,HC==2, then $4210 - * bit 7 will be set, and the next read will also - * have this bit set. - */ //7 = NMI acknowledge //6-4 = MDR //3-0 = CPU (5a22) version uint8 bCPU::mmio_r4210() { -uint8 r; -uint16 v, h, hc, vs; - r = regs.mdr & 0x70; +uint8 r; + r = regs.mdr & 0x70; + r |= uint8(!time.nmi_read) << 7; - v = vcounter(); - h = hcounter(); - hc = hcycles(); - vs = (overscan()?239:224); - - if(status.nmi_read == false) { - if( - (v == (vs + 1) && hc >= 2) || - (v > (vs + 1)) - ) { - r |= 0x80; - - //test for special case where NMI read not raised - if(v != (vs + 1) || hc != 2) { - status.nmi_read = true; - } - } + if(!nmi_trigger_pos_match(0) && !nmi_trigger_pos_match(2)) { + time.nmi_read = 1; } - r |= 0x02; //cpu version number + r |= (cpu_version & 0x0f); return r; } @@ -142,10 +116,15 @@ uint16 v, h, hc, vs; //6-0 = MDR uint8 bCPU::mmio_r4211() { uint8 r; - r = regs.mdr & 0x7f; - if(status.irq_exec == true)r |= 0x80; - status.irq_exec = false; - status.irq_read = true; + r = regs.mdr & 0x7f; + r |= uint8(!time.irq_read) << 7; + + if(!irq_trigger_pos_match(0) && !irq_trigger_pos_match(2)) { + time.irq_read = 1; + time.irq_line = 1; + time.irq_transition = 0; + } + return r; } @@ -155,23 +134,20 @@ uint8 r; //5-1 = MDR //0 = joypad ready uint8 bCPU::mmio_r4212() { -uint8 r; -uint16 v, h, hc, vs; +uint8 r; r = regs.mdr & 0x3e; - v = vcounter(); - h = hcounter(); - hc = hcycles(); - vs = (overscan()?239:224); +uint16 vs = overscan() ? 240 : 225; //auto joypad polling - if(v >= (vs + 1) && v <= (vs + 3))r |= 0x01; + if(time.v >= vs && time.v <= (vs + 2))r |= 0x01; //hblank - if(hc <= 2 || hc >= 1096)r |= 0x40; + if(time.hc <= 2 || time.hc >= 1096)r |= 0x40; //vblank - if(v >= (vs + 1))r |= 0x80; + if(time.v >= vs)r |= 0x80; + return r; } @@ -291,9 +267,7 @@ uint8 bCPU::mmio_r43xb(uint8 i) { } uint8 bCPUMMIO::read(uint32 addr) { -uint8 i; -//cpu->sync(); - +uint i; //APU if(addr >= 0x2140 && addr <= 0x217f) { return apu->port_read(addr & 3); @@ -337,6 +311,8 @@ uint8 i; case 0x4218:return cpu->mmio_r4218(); //JOY1L case 0x4219:return cpu->mmio_r4219(); //JOY1H case 0x421a:case 0x421b:case 0x421c:case 0x421d:case 0x421e:case 0x421f:return 0x00; +case 0x4000:dprintf("* 4000 read at %3d,%4d <%d>", cpu->time.v, cpu->time.hc, cpu->status.cycle_count);break; +case 0x4200:dprintf("* 4200 read at %3d,%4d", cpu->time.v, cpu->time.hc);break; } return cpu->regs.mdr; @@ -383,14 +359,20 @@ void bCPU::mmio_w4200(uint8 value) { status.hirq_enabled = !!(value & 0x10); status.auto_joypad_poll = !!(value & 0x01); - if(status.nmi_enabled == false) { - status.nmi_read = false; + if(time.nmi_read == 0) { + if(time.nmi_line == 1 && !status.nmi_enabled == 0) { + time.nmi_transition = 1; + } + time.nmi_line = !status.nmi_enabled; } - status.irq_exec = false; - if(status.virq_enabled == true || status.hirq_enabled == true) { - status.irq_read = false; + if(status.virq_enabled == false && status.hirq_enabled == false) { + time.irq_line = 1; + time.irq_read = 1; + time.irq_transition = 0; } + + update_interrupts(); } //WRIO @@ -424,32 +406,32 @@ void bCPU::mmio_w4205(uint8 value) { //WRDIVB void bCPU::mmio_w4206(uint8 value) { status.div_b = value; - status.r4214 = (status.div_b)?status.div_a / status.div_b : 0xffff; - status.r4216 = (status.div_b)?status.div_a % status.div_b : status.div_a; + status.r4214 = (status.div_b) ? status.div_a / status.div_b : 0xffff; + status.r4216 = (status.div_b) ? status.div_a % status.div_b : status.div_a; } //HTIMEL void bCPU::mmio_w4207(uint8 value) { status.hirq_pos = (status.hirq_pos & 0xff00) | value; - status.irq_read = false; + update_interrupts(); } //HTIMEH void bCPU::mmio_w4208(uint8 value) { status.hirq_pos = (status.hirq_pos & 0x00ff) | (value << 8); - status.irq_read = false; + update_interrupts(); } //VTIMEL void bCPU::mmio_w4209(uint8 value) { status.virq_pos = (status.virq_pos & 0xff00) | value; - status.irq_read = false; + update_interrupts(); } //VTIMEH void bCPU::mmio_w420a(uint8 value) { status.virq_pos = (status.virq_pos & 0x00ff) | (value << 8); - status.irq_read = false; + update_interrupts(); } //DMAEN @@ -479,7 +461,7 @@ void bCPU::mmio_w420c(uint8 value) { //MEMSEL void bCPU::mmio_w420d(uint8 value) { - mem_bus->fastROM = value & 1; + mem_bus->set_speed(value & 1); } //DMAPx @@ -549,8 +531,6 @@ void bCPU::mmio_w43xb(uint8 value, uint8 i) { void bCPUMMIO::write(uint32 addr, uint8 value) { uint8 i; -//cpu->sync(); - //APU if(addr >= 0x2140 && addr <= 0x217f) { cpu->port_write(addr & 3, value); @@ -600,6 +580,7 @@ uint8 i; case 0x420b:cpu->mmio_w420b(value);return; //DMAEN case 0x420c:cpu->mmio_w420c(value);return; //HDMAEN case 0x420d:cpu->mmio_w420d(value);return; //MEMSEL +case 0x4000:dprintf("* 4000 write at %3d,%4d", cpu->time.v, cpu->time.hc);break; } } diff --git a/src/cpu/bcpu/bcpu_op.h b/src/cpu/bcpu/bcpu_op.h index 63b88b2d..1b3f44f6 100644 --- a/src/cpu/bcpu/bcpu_op.h +++ b/src/cpu/bcpu/bcpu_op.h @@ -186,7 +186,6 @@ void op_sta_idpy(); void op_sta_ildpy(); void op_sta_sr(); void op_sta_isry(); -void op_bra(); void op_bcc(); void op_bcs(); void op_bne(); @@ -195,6 +194,7 @@ void op_bpl(); void op_bmi(); void op_bvc(); void op_bvs(); +void op_bra(); void op_brl(); void op_jmp_addr(); void op_jmp_long(); diff --git a/src/cpu/bcpu/bcpu_op_misc.cpp b/src/cpu/bcpu/bcpu_op_misc.cpp index 9b6fe3af..ff08ae50 100644 --- a/src/cpu/bcpu/bcpu_op_misc.cpp +++ b/src/cpu/bcpu/bcpu_op_misc.cpp @@ -1,6 +1,7 @@ void bCPU::op_nop() { switch(status.cycle_pos++) { case 1: + last_cycle(); cpu_io(); status.cycle_pos = 0; break; @@ -10,6 +11,7 @@ void bCPU::op_nop() { void bCPU::op_wdm() { switch(status.cycle_pos++) { case 1: + last_cycle(); op_read(); status.cycle_pos = 0; break; @@ -22,6 +24,7 @@ void bCPU::op_xba() { cpu_io(); break; case 2: + last_cycle(); cpu_io(); regs.a.l ^= regs.a.h; regs.a.h ^= regs.a.l; @@ -54,6 +57,7 @@ void bCPU::op_mvn() { else { regs.x.w++; regs.y.w++; } break; case 6: + last_cycle(); cpu_io(); if(regs.a.w--)regs.pc.w -= 3; status.cycle_pos = 0; @@ -82,6 +86,7 @@ void bCPU::op_mvp() { else { regs.x.w--; regs.y.w--; } break; case 6: + last_cycle(); cpu_io(); if(regs.a.w--)regs.pc.w -= 3; status.cycle_pos = 0; @@ -111,6 +116,7 @@ void bCPU::op_brk() { rd.l = op_read(OPMODE_LONG, (regs.e)?0xfffe:0xffe6); break; case 7: + last_cycle(); rd.h = op_read(OPMODE_LONG, (regs.e)?0xffff:0xffe7); regs.pc.b = 0x00; regs.pc.w = rd.w; @@ -143,6 +149,7 @@ void bCPU::op_cop() { rd.l = op_read(OPMODE_LONG, (regs.e)?0xfff4:0xffe4); break; case 7: + last_cycle(); rd.h = op_read(OPMODE_LONG, (regs.e)?0xfff5:0xffe5); regs.pc.b = 0x00; regs.pc.w = rd.w; @@ -160,6 +167,7 @@ void bCPU::op_stp() { status.cpu_state = CPUSTATE_STP; break; case 2: + last_cycle(); cpu_io(); regs.pc.w--; status.cycle_pos = 0; @@ -174,8 +182,11 @@ void bCPU::op_wai() { status.cpu_state = CPUSTATE_WAI; break; case 2: + last_cycle(); cpu_io(); - regs.pc.w--; + if(status.cpu_state == CPUSTATE_WAI) { + regs.pc.w--; + } status.cycle_pos = 0; break; } @@ -184,6 +195,7 @@ void bCPU::op_wai() { void bCPU::op_xce() { switch(status.cycle_pos++) { case 1: + last_cycle(); cpu_io(); bool c = regs.p.c; regs.p.c = regs.e; @@ -202,6 +214,7 @@ void bCPU::op_xce() { void bCPU::op_clc() { switch(status.cycle_pos++) { case 1: + last_cycle(); cpu_io(); regs.p.c = 0; status.cycle_pos = 0; @@ -212,6 +225,7 @@ void bCPU::op_clc() { void bCPU::op_cld() { switch(status.cycle_pos++) { case 1: + last_cycle(); cpu_io(); regs.p.d = 0; status.cycle_pos = 0; @@ -222,6 +236,7 @@ void bCPU::op_cld() { void bCPU::op_cli() { switch(status.cycle_pos++) { case 1: + last_cycle(); cpu_io(); regs.p.i = 0; status.cycle_pos = 0; @@ -232,6 +247,7 @@ void bCPU::op_cli() { void bCPU::op_clv() { switch(status.cycle_pos++) { case 1: + last_cycle(); cpu_io(); regs.p.v = 0; status.cycle_pos = 0; @@ -242,6 +258,7 @@ void bCPU::op_clv() { void bCPU::op_sec() { switch(status.cycle_pos++) { case 1: + last_cycle(); cpu_io(); regs.p.c = 1; status.cycle_pos = 0; @@ -252,6 +269,7 @@ void bCPU::op_sec() { void bCPU::op_sed() { switch(status.cycle_pos++) { case 1: + last_cycle(); cpu_io(); regs.p.d = 1; status.cycle_pos = 0; @@ -262,6 +280,7 @@ void bCPU::op_sed() { void bCPU::op_sei() { switch(status.cycle_pos++) { case 1: + last_cycle(); cpu_io(); regs.p.i = 1; status.cycle_pos = 0; @@ -275,6 +294,7 @@ void bCPU::op_rep() { rd.l = op_read(); break; case 2: + last_cycle(); cpu_io(); regs.p &=~ rd.l; if(regs.e)regs.p |= 0x30; @@ -293,6 +313,7 @@ void bCPU::op_sep() { rd.l = op_read(); break; case 2: + last_cycle(); cpu_io(); regs.p |= rd.l; if(regs.e)regs.p |= 0x30; @@ -308,6 +329,7 @@ void bCPU::op_sep() { void bCPU::op_tax() { switch(status.cycle_pos++) { case 1: + last_cycle(); cpu_io(); if(regs.p.x) { regs.x.l = regs.a.l; @@ -326,6 +348,7 @@ void bCPU::op_tax() { void bCPU::op_tay() { switch(status.cycle_pos++) { case 1: + last_cycle(); cpu_io(); if(regs.p.x) { regs.y.l = regs.a.l; @@ -344,6 +367,7 @@ void bCPU::op_tay() { void bCPU::op_txa() { switch(status.cycle_pos++) { case 1: + last_cycle(); cpu_io(); if(regs.p.m) { regs.a.l = regs.x.l; @@ -362,6 +386,7 @@ void bCPU::op_txa() { void bCPU::op_txy() { switch(status.cycle_pos++) { case 1: + last_cycle(); cpu_io(); if(regs.p.x) { regs.y.l = regs.x.l; @@ -380,6 +405,7 @@ void bCPU::op_txy() { void bCPU::op_tya() { switch(status.cycle_pos++) { case 1: + last_cycle(); cpu_io(); if(regs.p.m) { regs.a.l = regs.y.l; @@ -398,6 +424,7 @@ void bCPU::op_tya() { void bCPU::op_tyx() { switch(status.cycle_pos++) { case 1: + last_cycle(); cpu_io(); if(regs.p.x) { regs.x.l = regs.y.l; @@ -416,6 +443,7 @@ void bCPU::op_tyx() { void bCPU::op_tcd() { switch(status.cycle_pos++) { case 1: + last_cycle(); cpu_io(); regs.d.w = regs.a.w; regs.p.n = !!(regs.d.w & 0x8000); @@ -428,6 +456,7 @@ void bCPU::op_tcd() { void bCPU::op_tcs() { switch(status.cycle_pos++) { case 1: + last_cycle(); cpu_io(); regs.s.w = regs.a.w; if(regs.e)regs.s.h = 0x01; @@ -439,6 +468,7 @@ void bCPU::op_tcs() { void bCPU::op_tdc() { switch(status.cycle_pos++) { case 1: + last_cycle(); cpu_io(); regs.a.w = regs.d.w; regs.p.n = !!(regs.a.w & 0x8000); @@ -451,6 +481,7 @@ void bCPU::op_tdc() { void bCPU::op_tsc() { switch(status.cycle_pos++) { case 1: + last_cycle(); cpu_io(); regs.a.w = regs.s.w; if(regs.e) { @@ -468,6 +499,7 @@ void bCPU::op_tsc() { void bCPU::op_tsx() { switch(status.cycle_pos++) { case 1: + last_cycle(); cpu_io(); if(regs.p.x) { regs.x.l = regs.s.l; @@ -486,6 +518,7 @@ void bCPU::op_tsx() { void bCPU::op_txs() { switch(status.cycle_pos++) { case 1: + last_cycle(); cpu_io(); if(regs.e) { regs.s.l = regs.x.l; @@ -511,6 +544,7 @@ void bCPU::op_pha() { stack_write(regs.a.h); break; case 3: + last_cycle(); stack_write(regs.a.l); status.cycle_pos = 0; break; @@ -527,6 +561,7 @@ void bCPU::op_phx() { stack_write(regs.x.h); break; case 3: + last_cycle(); stack_write(regs.x.l); status.cycle_pos = 0; break; @@ -543,6 +578,7 @@ void bCPU::op_phy() { stack_write(regs.y.h); break; case 3: + last_cycle(); stack_write(regs.y.l); status.cycle_pos = 0; break; @@ -559,6 +595,7 @@ void bCPU::op_phd() { stack_write(regs. d.h); break; case 3: + last_cycle(); stack_write(regs. d.l); status.cycle_pos = 0; break; @@ -571,6 +608,7 @@ void bCPU::op_phb() { cpu_io(); break; case 2: + last_cycle(); stack_write(regs.db); status.cycle_pos = 0; break; @@ -583,6 +621,7 @@ void bCPU::op_phk() { cpu_io(); break; case 2: + last_cycle(); stack_write(regs.pc.b); status.cycle_pos = 0; break; @@ -595,6 +634,7 @@ void bCPU::op_php() { cpu_io(); break; case 2: + last_cycle(); stack_write(regs.p); status.cycle_pos = 0; break; @@ -610,6 +650,7 @@ void bCPU::op_pla() { cpu_io(); break; case 3: + if(regs.p.m)last_cycle(); regs.a.l = stack_read(); if(regs.p.m) { regs.p.n = !!(regs.a.l & 0x80); @@ -618,6 +659,7 @@ void bCPU::op_pla() { } break; case 4: + last_cycle(); regs.a.h = stack_read(); regs.p.n = !!(regs.a.w & 0x8000); regs.p.z = (regs.a.w == 0); @@ -635,6 +677,7 @@ void bCPU::op_plx() { cpu_io(); break; case 3: + if(regs.p.x)last_cycle(); regs.x.l = stack_read(); if(regs.p.x) { regs.p.n = !!(regs.x.l & 0x80); @@ -643,6 +686,7 @@ void bCPU::op_plx() { } break; case 4: + last_cycle(); regs.x.h = stack_read(); regs.p.n = !!(regs.x.w & 0x8000); regs.p.z = (regs.x.w == 0); @@ -660,6 +704,7 @@ void bCPU::op_ply() { cpu_io(); break; case 3: + if(regs.p.x)last_cycle(); regs.y.l = stack_read(); if(regs.p.x) { regs.p.n = !!(regs.y.l & 0x80); @@ -668,6 +713,7 @@ void bCPU::op_ply() { } break; case 4: + last_cycle(); regs.y.h = stack_read(); regs.p.n = !!(regs.y.w & 0x8000); regs.p.z = (regs.y.w == 0); @@ -685,6 +731,7 @@ void bCPU::op_pld() { cpu_io(); break; case 3: + if(0)last_cycle(); regs. d.l = stack_read(); if(0) { regs.p.n = !!(regs. d.l & 0x80); @@ -693,6 +740,7 @@ void bCPU::op_pld() { } break; case 4: + last_cycle(); regs. d.h = stack_read(); regs.p.n = !!(regs. d.w & 0x8000); regs.p.z = (regs. d.w == 0); @@ -710,6 +758,7 @@ void bCPU::op_plb() { cpu_io(); break; case 3: + last_cycle(); regs.db = stack_read(); regs.p.n = !!(regs.db & 0x80); regs.p.z = (regs.db == 0); @@ -727,6 +776,7 @@ void bCPU::op_plp() { cpu_io(); break; case 3: + last_cycle(); regs.p = stack_read(); if(regs.e)regs.p |= 0x30; if(regs.p.x) { @@ -750,6 +800,7 @@ void bCPU::op_pea() { stack_write(aa.h); break; case 4: + last_cycle(); stack_write(aa.l); status.cycle_pos = 0; break; @@ -774,6 +825,7 @@ void bCPU::op_pei() { stack_write(aa.h); break; case 6: + last_cycle(); stack_write(aa.l); status.cycle_pos = 0; break; @@ -796,6 +848,7 @@ void bCPU::op_per() { stack_write(rd.h); break; case 5: + last_cycle(); stack_write(rd.l); status.cycle_pos = 0; break; diff --git a/src/cpu/bcpu/bcpu_op_pc.cpp b/src/cpu/bcpu/bcpu_op_pc.cpp index 94a23447..b02d9dc8 100644 --- a/src/cpu/bcpu/bcpu_op_pc.cpp +++ b/src/cpu/bcpu/bcpu_op_pc.cpp @@ -1,27 +1,7 @@ -void bCPU::op_bra() { - switch(status.cycle_pos++) { - case 1: - rd.l = op_read(); - if(1) { - aa.w = regs.pc.d + (int8)rd.l; - regs.pc.w = aa.w; - } else { - status.cycle_pos = 0; - } - break; - case 2: - cpu_c6(aa.w); - break; - case 3: - cpu_io(); - status.cycle_pos = 0; - break; - } -} - void bCPU::op_bcc() { switch(status.cycle_pos++) { case 1: + if(!!regs.p.c)last_cycle(); rd.l = op_read(); if(!regs.p.c) { aa.w = regs.pc.d + (int8)rd.l; @@ -34,6 +14,7 @@ void bCPU::op_bcc() { cpu_c6(aa.w); break; case 3: + last_cycle(); cpu_io(); status.cycle_pos = 0; break; @@ -43,6 +24,7 @@ void bCPU::op_bcc() { void bCPU::op_bcs() { switch(status.cycle_pos++) { case 1: + if(!regs.p.c)last_cycle(); rd.l = op_read(); if(regs.p.c) { aa.w = regs.pc.d + (int8)rd.l; @@ -55,6 +37,7 @@ void bCPU::op_bcs() { cpu_c6(aa.w); break; case 3: + last_cycle(); cpu_io(); status.cycle_pos = 0; break; @@ -64,6 +47,7 @@ void bCPU::op_bcs() { void bCPU::op_bne() { switch(status.cycle_pos++) { case 1: + if(!!regs.p.z)last_cycle(); rd.l = op_read(); if(!regs.p.z) { aa.w = regs.pc.d + (int8)rd.l; @@ -76,6 +60,7 @@ void bCPU::op_bne() { cpu_c6(aa.w); break; case 3: + last_cycle(); cpu_io(); status.cycle_pos = 0; break; @@ -85,6 +70,7 @@ void bCPU::op_bne() { void bCPU::op_beq() { switch(status.cycle_pos++) { case 1: + if(!regs.p.z)last_cycle(); rd.l = op_read(); if(regs.p.z) { aa.w = regs.pc.d + (int8)rd.l; @@ -97,6 +83,7 @@ void bCPU::op_beq() { cpu_c6(aa.w); break; case 3: + last_cycle(); cpu_io(); status.cycle_pos = 0; break; @@ -106,6 +93,7 @@ void bCPU::op_beq() { void bCPU::op_bpl() { switch(status.cycle_pos++) { case 1: + if(!!regs.p.n)last_cycle(); rd.l = op_read(); if(!regs.p.n) { aa.w = regs.pc.d + (int8)rd.l; @@ -118,6 +106,7 @@ void bCPU::op_bpl() { cpu_c6(aa.w); break; case 3: + last_cycle(); cpu_io(); status.cycle_pos = 0; break; @@ -127,6 +116,7 @@ void bCPU::op_bpl() { void bCPU::op_bmi() { switch(status.cycle_pos++) { case 1: + if(!regs.p.n)last_cycle(); rd.l = op_read(); if(regs.p.n) { aa.w = regs.pc.d + (int8)rd.l; @@ -139,6 +129,7 @@ void bCPU::op_bmi() { cpu_c6(aa.w); break; case 3: + last_cycle(); cpu_io(); status.cycle_pos = 0; break; @@ -148,6 +139,7 @@ void bCPU::op_bmi() { void bCPU::op_bvc() { switch(status.cycle_pos++) { case 1: + if(!!regs.p.v)last_cycle(); rd.l = op_read(); if(!regs.p.v) { aa.w = regs.pc.d + (int8)rd.l; @@ -160,6 +152,7 @@ void bCPU::op_bvc() { cpu_c6(aa.w); break; case 3: + last_cycle(); cpu_io(); status.cycle_pos = 0; break; @@ -169,6 +162,7 @@ void bCPU::op_bvc() { void bCPU::op_bvs() { switch(status.cycle_pos++) { case 1: + if(!regs.p.v)last_cycle(); rd.l = op_read(); if(regs.p.v) { aa.w = regs.pc.d + (int8)rd.l; @@ -181,6 +175,25 @@ void bCPU::op_bvs() { cpu_c6(aa.w); break; case 3: + last_cycle(); + cpu_io(); + status.cycle_pos = 0; + break; + } +} + +void bCPU::op_bra() { + switch(status.cycle_pos++) { + case 1: + rd.l = op_read(); + aa.w = regs.pc.d + (int8)rd.l; + regs.pc.w = aa.w; + break; + case 2: + cpu_c6(aa.w); + break; + case 3: + last_cycle(); cpu_io(); status.cycle_pos = 0; break; @@ -196,6 +209,7 @@ void bCPU::op_brl() { rd.h = op_read(); break; case 3: + last_cycle(); cpu_io(); regs.pc.w = regs.pc.d + (int16)rd.w; status.cycle_pos = 0; @@ -209,6 +223,7 @@ void bCPU::op_jmp_addr() { rd.l = op_read(); break; case 2: + last_cycle(); rd.h = op_read(); regs.pc.w = rd.w; status.cycle_pos = 0; @@ -225,6 +240,7 @@ void bCPU::op_jmp_long() { rd.h = op_read(); break; case 3: + last_cycle(); rd.b = op_read(); regs.pc.d = rd.d & 0xffffff; status.cycle_pos = 0; @@ -244,6 +260,7 @@ void bCPU::op_jmp_iaddr() { rd.l = op_read(OPMODE_ADDR, aa.w); break; case 4: + last_cycle(); rd.h = op_read(OPMODE_ADDR, aa.w + 1); regs.pc.w = rd.w; status.cycle_pos = 0; @@ -266,6 +283,7 @@ void bCPU::op_jmp_iaddrx() { rd.l = op_read(OPMODE_PBR, aa.w + regs.x.w); break; case 5: + last_cycle(); rd.h = op_read(OPMODE_PBR, aa.w + regs.x.w + 1); regs.pc.w = rd.w; status.cycle_pos = 0; @@ -288,6 +306,7 @@ void bCPU::op_jmp_iladdr() { rd.h = op_read(OPMODE_ADDR, aa.w + 1); break; case 5: + last_cycle(); rd.b = op_read(OPMODE_ADDR, aa.w + 2); regs.pc.d = rd.d & 0xffffff; status.cycle_pos = 0; @@ -311,6 +330,7 @@ void bCPU::op_jsr_addr() { stack_write(regs.pc.h); break; case 5: + last_cycle(); stack_write(regs.pc.l); regs.pc.w = aa.w; status.cycle_pos = 0; @@ -340,6 +360,7 @@ void bCPU::op_jsr_long() { stack_write(regs.pc.h); break; case 7: + last_cycle(); stack_write(regs.pc.l); regs.pc.d = aa.d & 0xffffff; status.cycle_pos = 0; @@ -368,6 +389,7 @@ void bCPU::op_jsr_iaddrx() { rd.l = op_read(OPMODE_PBR, aa.w + regs.x.w); break; case 7: + last_cycle(); rd.h = op_read(OPMODE_PBR, aa.w + regs.x.w + 1); regs.pc.w = rd.w; status.cycle_pos = 0; @@ -402,6 +424,7 @@ void bCPU::op_rti() { } break; case 6: + last_cycle(); rd.b = stack_read(); regs.pc.d = rd.d & 0xffffff; status.cycle_pos = 0; @@ -424,6 +447,7 @@ void bCPU::op_rts() { rd.h = stack_read(); break; case 5: + last_cycle(); cpu_io(); regs.pc.w = rd.w; regs.pc.w++; @@ -447,6 +471,7 @@ void bCPU::op_rtl() { rd.h = stack_read(); break; case 5: + last_cycle(); rd.b = stack_read(); regs.pc.d = rd.d & 0xffffff; regs.pc.w++; diff --git a/src/cpu/bcpu/bcpu_op_read.cpp b/src/cpu/bcpu/bcpu_op_read.cpp index 8274a2dd..d905520c 100644 --- a/src/cpu/bcpu/bcpu_op_read.cpp +++ b/src/cpu/bcpu/bcpu_op_read.cpp @@ -1,10 +1,12 @@ void bCPU::op_adc_const() { switch(status.cycle_pos++) { case 1: + if(regs.p.m)last_cycle(); rd.l = op_read(); if(regs.p.m) { op_adc_b(); status.cycle_pos = 0; } break; case 2: + last_cycle(); rd.h = op_read(); op_adc_w(); status.cycle_pos = 0; @@ -15,10 +17,12 @@ void bCPU::op_adc_const() { void bCPU::op_and_const() { switch(status.cycle_pos++) { case 1: + if(regs.p.m)last_cycle(); rd.l = op_read(); if(regs.p.m) { op_and_b(); status.cycle_pos = 0; } break; case 2: + last_cycle(); rd.h = op_read(); op_and_w(); status.cycle_pos = 0; @@ -29,10 +33,12 @@ void bCPU::op_and_const() { void bCPU::op_cmp_const() { switch(status.cycle_pos++) { case 1: + if(regs.p.m)last_cycle(); rd.l = op_read(); if(regs.p.m) { op_cmp_b(); status.cycle_pos = 0; } break; case 2: + last_cycle(); rd.h = op_read(); op_cmp_w(); status.cycle_pos = 0; @@ -43,10 +49,12 @@ void bCPU::op_cmp_const() { void bCPU::op_cpx_const() { switch(status.cycle_pos++) { case 1: + if(regs.p.x)last_cycle(); rd.l = op_read(); if(regs.p.x) { op_cpx_b(); status.cycle_pos = 0; } break; case 2: + last_cycle(); rd.h = op_read(); op_cpx_w(); status.cycle_pos = 0; @@ -57,10 +65,12 @@ void bCPU::op_cpx_const() { void bCPU::op_cpy_const() { switch(status.cycle_pos++) { case 1: + if(regs.p.x)last_cycle(); rd.l = op_read(); if(regs.p.x) { op_cpy_b(); status.cycle_pos = 0; } break; case 2: + last_cycle(); rd.h = op_read(); op_cpy_w(); status.cycle_pos = 0; @@ -71,10 +81,12 @@ void bCPU::op_cpy_const() { void bCPU::op_eor_const() { switch(status.cycle_pos++) { case 1: + if(regs.p.m)last_cycle(); rd.l = op_read(); if(regs.p.m) { op_eor_b(); status.cycle_pos = 0; } break; case 2: + last_cycle(); rd.h = op_read(); op_eor_w(); status.cycle_pos = 0; @@ -85,10 +97,12 @@ void bCPU::op_eor_const() { void bCPU::op_lda_const() { switch(status.cycle_pos++) { case 1: + if(regs.p.m)last_cycle(); rd.l = op_read(); if(regs.p.m) { op_lda_b(); status.cycle_pos = 0; } break; case 2: + last_cycle(); rd.h = op_read(); op_lda_w(); status.cycle_pos = 0; @@ -99,10 +113,12 @@ void bCPU::op_lda_const() { void bCPU::op_ldx_const() { switch(status.cycle_pos++) { case 1: + if(regs.p.x)last_cycle(); rd.l = op_read(); if(regs.p.x) { op_ldx_b(); status.cycle_pos = 0; } break; case 2: + last_cycle(); rd.h = op_read(); op_ldx_w(); status.cycle_pos = 0; @@ -113,10 +129,12 @@ void bCPU::op_ldx_const() { void bCPU::op_ldy_const() { switch(status.cycle_pos++) { case 1: + if(regs.p.x)last_cycle(); rd.l = op_read(); if(regs.p.x) { op_ldy_b(); status.cycle_pos = 0; } break; case 2: + last_cycle(); rd.h = op_read(); op_ldy_w(); status.cycle_pos = 0; @@ -127,10 +145,12 @@ void bCPU::op_ldy_const() { void bCPU::op_ora_const() { switch(status.cycle_pos++) { case 1: + if(regs.p.m)last_cycle(); rd.l = op_read(); if(regs.p.m) { op_ora_b(); status.cycle_pos = 0; } break; case 2: + last_cycle(); rd.h = op_read(); op_ora_w(); status.cycle_pos = 0; @@ -141,10 +161,12 @@ void bCPU::op_ora_const() { void bCPU::op_sbc_const() { switch(status.cycle_pos++) { case 1: + if(regs.p.m)last_cycle(); rd.l = op_read(); if(regs.p.m) { op_sbc_b(); status.cycle_pos = 0; } break; case 2: + last_cycle(); rd.h = op_read(); op_sbc_w(); status.cycle_pos = 0; @@ -161,10 +183,12 @@ void bCPU::op_adc_addr() { aa.h = op_read(); break; case 3: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w); if(regs.p.m) { op_adc_b(); status.cycle_pos = 0; } break; case 4: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + 1); op_adc_w(); status.cycle_pos = 0; @@ -181,10 +205,12 @@ void bCPU::op_and_addr() { aa.h = op_read(); break; case 3: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w); if(regs.p.m) { op_and_b(); status.cycle_pos = 0; } break; case 4: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + 1); op_and_w(); status.cycle_pos = 0; @@ -201,10 +227,12 @@ void bCPU::op_bit_addr() { aa.h = op_read(); break; case 3: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w); if(regs.p.m) { op_bit_b(); status.cycle_pos = 0; } break; case 4: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + 1); op_bit_w(); status.cycle_pos = 0; @@ -221,10 +249,12 @@ void bCPU::op_cmp_addr() { aa.h = op_read(); break; case 3: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w); if(regs.p.m) { op_cmp_b(); status.cycle_pos = 0; } break; case 4: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + 1); op_cmp_w(); status.cycle_pos = 0; @@ -241,10 +271,12 @@ void bCPU::op_cpx_addr() { aa.h = op_read(); break; case 3: + if(regs.p.x)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w); if(regs.p.x) { op_cpx_b(); status.cycle_pos = 0; } break; case 4: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + 1); op_cpx_w(); status.cycle_pos = 0; @@ -261,10 +293,12 @@ void bCPU::op_cpy_addr() { aa.h = op_read(); break; case 3: + if(regs.p.x)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w); if(regs.p.x) { op_cpy_b(); status.cycle_pos = 0; } break; case 4: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + 1); op_cpy_w(); status.cycle_pos = 0; @@ -281,10 +315,12 @@ void bCPU::op_eor_addr() { aa.h = op_read(); break; case 3: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w); if(regs.p.m) { op_eor_b(); status.cycle_pos = 0; } break; case 4: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + 1); op_eor_w(); status.cycle_pos = 0; @@ -301,10 +337,12 @@ void bCPU::op_lda_addr() { aa.h = op_read(); break; case 3: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w); if(regs.p.m) { op_lda_b(); status.cycle_pos = 0; } break; case 4: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + 1); op_lda_w(); status.cycle_pos = 0; @@ -321,10 +359,12 @@ void bCPU::op_ldx_addr() { aa.h = op_read(); break; case 3: + if(regs.p.x)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w); if(regs.p.x) { op_ldx_b(); status.cycle_pos = 0; } break; case 4: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + 1); op_ldx_w(); status.cycle_pos = 0; @@ -341,10 +381,12 @@ void bCPU::op_ldy_addr() { aa.h = op_read(); break; case 3: + if(regs.p.x)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w); if(regs.p.x) { op_ldy_b(); status.cycle_pos = 0; } break; case 4: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + 1); op_ldy_w(); status.cycle_pos = 0; @@ -361,10 +403,12 @@ void bCPU::op_ora_addr() { aa.h = op_read(); break; case 3: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w); if(regs.p.m) { op_ora_b(); status.cycle_pos = 0; } break; case 4: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + 1); op_ora_w(); status.cycle_pos = 0; @@ -381,10 +425,12 @@ void bCPU::op_sbc_addr() { aa.h = op_read(); break; case 3: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w); if(regs.p.m) { op_sbc_b(); status.cycle_pos = 0; } break; case 4: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + 1); op_sbc_w(); status.cycle_pos = 0; @@ -404,10 +450,12 @@ void bCPU::op_adc_addrx() { cpu_c4(aa.w, aa.w + regs.x.w); break; case 4: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); if(regs.p.m) { op_adc_b(); status.cycle_pos = 0; } break; case 5: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); op_adc_w(); status.cycle_pos = 0; @@ -427,10 +475,12 @@ void bCPU::op_and_addrx() { cpu_c4(aa.w, aa.w + regs.x.w); break; case 4: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); if(regs.p.m) { op_and_b(); status.cycle_pos = 0; } break; case 5: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); op_and_w(); status.cycle_pos = 0; @@ -450,10 +500,12 @@ void bCPU::op_bit_addrx() { cpu_c4(aa.w, aa.w + regs.x.w); break; case 4: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); if(regs.p.m) { op_bit_b(); status.cycle_pos = 0; } break; case 5: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); op_bit_w(); status.cycle_pos = 0; @@ -473,10 +525,12 @@ void bCPU::op_cmp_addrx() { cpu_c4(aa.w, aa.w + regs.x.w); break; case 4: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); if(regs.p.m) { op_cmp_b(); status.cycle_pos = 0; } break; case 5: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); op_cmp_w(); status.cycle_pos = 0; @@ -496,10 +550,12 @@ void bCPU::op_eor_addrx() { cpu_c4(aa.w, aa.w + regs.x.w); break; case 4: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); if(regs.p.m) { op_eor_b(); status.cycle_pos = 0; } break; case 5: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); op_eor_w(); status.cycle_pos = 0; @@ -519,10 +575,12 @@ void bCPU::op_lda_addrx() { cpu_c4(aa.w, aa.w + regs.x.w); break; case 4: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); if(regs.p.m) { op_lda_b(); status.cycle_pos = 0; } break; case 5: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); op_lda_w(); status.cycle_pos = 0; @@ -542,10 +600,12 @@ void bCPU::op_ldy_addrx() { cpu_c4(aa.w, aa.w + regs.x.w); break; case 4: + if(regs.p.x)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); if(regs.p.x) { op_ldy_b(); status.cycle_pos = 0; } break; case 5: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); op_ldy_w(); status.cycle_pos = 0; @@ -565,10 +625,12 @@ void bCPU::op_ora_addrx() { cpu_c4(aa.w, aa.w + regs.x.w); break; case 4: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); if(regs.p.m) { op_ora_b(); status.cycle_pos = 0; } break; case 5: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); op_ora_w(); status.cycle_pos = 0; @@ -588,10 +650,12 @@ void bCPU::op_sbc_addrx() { cpu_c4(aa.w, aa.w + regs.x.w); break; case 4: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); if(regs.p.m) { op_sbc_b(); status.cycle_pos = 0; } break; case 5: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); op_sbc_w(); status.cycle_pos = 0; @@ -611,10 +675,12 @@ void bCPU::op_adc_addry() { cpu_c4(aa.w, aa.w + regs.y.w); break; case 4: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); if(regs.p.m) { op_adc_b(); status.cycle_pos = 0; } break; case 5: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); op_adc_w(); status.cycle_pos = 0; @@ -634,10 +700,12 @@ void bCPU::op_and_addry() { cpu_c4(aa.w, aa.w + regs.y.w); break; case 4: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); if(regs.p.m) { op_and_b(); status.cycle_pos = 0; } break; case 5: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); op_and_w(); status.cycle_pos = 0; @@ -657,10 +725,12 @@ void bCPU::op_cmp_addry() { cpu_c4(aa.w, aa.w + regs.y.w); break; case 4: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); if(regs.p.m) { op_cmp_b(); status.cycle_pos = 0; } break; case 5: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); op_cmp_w(); status.cycle_pos = 0; @@ -680,10 +750,12 @@ void bCPU::op_eor_addry() { cpu_c4(aa.w, aa.w + regs.y.w); break; case 4: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); if(regs.p.m) { op_eor_b(); status.cycle_pos = 0; } break; case 5: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); op_eor_w(); status.cycle_pos = 0; @@ -703,10 +775,12 @@ void bCPU::op_lda_addry() { cpu_c4(aa.w, aa.w + regs.y.w); break; case 4: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); if(regs.p.m) { op_lda_b(); status.cycle_pos = 0; } break; case 5: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); op_lda_w(); status.cycle_pos = 0; @@ -726,10 +800,12 @@ void bCPU::op_ldx_addry() { cpu_c4(aa.w, aa.w + regs.y.w); break; case 4: + if(regs.p.x)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); if(regs.p.x) { op_ldx_b(); status.cycle_pos = 0; } break; case 5: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); op_ldx_w(); status.cycle_pos = 0; @@ -749,10 +825,12 @@ void bCPU::op_ora_addry() { cpu_c4(aa.w, aa.w + regs.y.w); break; case 4: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); if(regs.p.m) { op_ora_b(); status.cycle_pos = 0; } break; case 5: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); op_ora_w(); status.cycle_pos = 0; @@ -772,10 +850,12 @@ void bCPU::op_sbc_addry() { cpu_c4(aa.w, aa.w + regs.y.w); break; case 4: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); if(regs.p.m) { op_sbc_b(); status.cycle_pos = 0; } break; case 5: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); op_sbc_w(); status.cycle_pos = 0; @@ -795,10 +875,12 @@ void bCPU::op_adc_long() { aa.b = op_read(); break; case 4: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_LONG, aa.d); if(regs.p.m) { op_adc_b(); status.cycle_pos = 0; } break; case 5: + last_cycle(); rd.h = op_read(OPMODE_LONG, aa.d + 1); op_adc_w(); status.cycle_pos = 0; @@ -818,10 +900,12 @@ void bCPU::op_and_long() { aa.b = op_read(); break; case 4: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_LONG, aa.d); if(regs.p.m) { op_and_b(); status.cycle_pos = 0; } break; case 5: + last_cycle(); rd.h = op_read(OPMODE_LONG, aa.d + 1); op_and_w(); status.cycle_pos = 0; @@ -841,10 +925,12 @@ void bCPU::op_cmp_long() { aa.b = op_read(); break; case 4: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_LONG, aa.d); if(regs.p.m) { op_cmp_b(); status.cycle_pos = 0; } break; case 5: + last_cycle(); rd.h = op_read(OPMODE_LONG, aa.d + 1); op_cmp_w(); status.cycle_pos = 0; @@ -864,10 +950,12 @@ void bCPU::op_eor_long() { aa.b = op_read(); break; case 4: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_LONG, aa.d); if(regs.p.m) { op_eor_b(); status.cycle_pos = 0; } break; case 5: + last_cycle(); rd.h = op_read(OPMODE_LONG, aa.d + 1); op_eor_w(); status.cycle_pos = 0; @@ -887,10 +975,12 @@ void bCPU::op_lda_long() { aa.b = op_read(); break; case 4: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_LONG, aa.d); if(regs.p.m) { op_lda_b(); status.cycle_pos = 0; } break; case 5: + last_cycle(); rd.h = op_read(OPMODE_LONG, aa.d + 1); op_lda_w(); status.cycle_pos = 0; @@ -910,10 +1000,12 @@ void bCPU::op_ora_long() { aa.b = op_read(); break; case 4: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_LONG, aa.d); if(regs.p.m) { op_ora_b(); status.cycle_pos = 0; } break; case 5: + last_cycle(); rd.h = op_read(OPMODE_LONG, aa.d + 1); op_ora_w(); status.cycle_pos = 0; @@ -933,10 +1025,12 @@ void bCPU::op_sbc_long() { aa.b = op_read(); break; case 4: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_LONG, aa.d); if(regs.p.m) { op_sbc_b(); status.cycle_pos = 0; } break; case 5: + last_cycle(); rd.h = op_read(OPMODE_LONG, aa.d + 1); op_sbc_w(); status.cycle_pos = 0; @@ -956,10 +1050,12 @@ void bCPU::op_adc_longx() { aa.b = op_read(); break; case 4: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_LONG, aa.d + regs.x.w); if(regs.p.m) { op_adc_b(); status.cycle_pos = 0; } break; case 5: + last_cycle(); rd.h = op_read(OPMODE_LONG, aa.d + regs.x.w + 1); op_adc_w(); status.cycle_pos = 0; @@ -979,10 +1075,12 @@ void bCPU::op_and_longx() { aa.b = op_read(); break; case 4: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_LONG, aa.d + regs.x.w); if(regs.p.m) { op_and_b(); status.cycle_pos = 0; } break; case 5: + last_cycle(); rd.h = op_read(OPMODE_LONG, aa.d + regs.x.w + 1); op_and_w(); status.cycle_pos = 0; @@ -1002,10 +1100,12 @@ void bCPU::op_cmp_longx() { aa.b = op_read(); break; case 4: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_LONG, aa.d + regs.x.w); if(regs.p.m) { op_cmp_b(); status.cycle_pos = 0; } break; case 5: + last_cycle(); rd.h = op_read(OPMODE_LONG, aa.d + regs.x.w + 1); op_cmp_w(); status.cycle_pos = 0; @@ -1025,10 +1125,12 @@ void bCPU::op_eor_longx() { aa.b = op_read(); break; case 4: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_LONG, aa.d + regs.x.w); if(regs.p.m) { op_eor_b(); status.cycle_pos = 0; } break; case 5: + last_cycle(); rd.h = op_read(OPMODE_LONG, aa.d + regs.x.w + 1); op_eor_w(); status.cycle_pos = 0; @@ -1048,10 +1150,12 @@ void bCPU::op_lda_longx() { aa.b = op_read(); break; case 4: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_LONG, aa.d + regs.x.w); if(regs.p.m) { op_lda_b(); status.cycle_pos = 0; } break; case 5: + last_cycle(); rd.h = op_read(OPMODE_LONG, aa.d + regs.x.w + 1); op_lda_w(); status.cycle_pos = 0; @@ -1071,10 +1175,12 @@ void bCPU::op_ora_longx() { aa.b = op_read(); break; case 4: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_LONG, aa.d + regs.x.w); if(regs.p.m) { op_ora_b(); status.cycle_pos = 0; } break; case 5: + last_cycle(); rd.h = op_read(OPMODE_LONG, aa.d + regs.x.w + 1); op_ora_w(); status.cycle_pos = 0; @@ -1094,10 +1200,12 @@ void bCPU::op_sbc_longx() { aa.b = op_read(); break; case 4: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_LONG, aa.d + regs.x.w); if(regs.p.m) { op_sbc_b(); status.cycle_pos = 0; } break; case 5: + last_cycle(); rd.h = op_read(OPMODE_LONG, aa.d + regs.x.w + 1); op_sbc_w(); status.cycle_pos = 0; @@ -1114,10 +1222,12 @@ void bCPU::op_adc_dp() { cpu_c2(); break; case 3: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DP, dp); if(regs.p.m) { op_adc_b(); status.cycle_pos = 0; } break; case 4: + last_cycle(); rd.h = op_read(OPMODE_DP, dp + 1); op_adc_w(); status.cycle_pos = 0; @@ -1134,10 +1244,12 @@ void bCPU::op_and_dp() { cpu_c2(); break; case 3: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DP, dp); if(regs.p.m) { op_and_b(); status.cycle_pos = 0; } break; case 4: + last_cycle(); rd.h = op_read(OPMODE_DP, dp + 1); op_and_w(); status.cycle_pos = 0; @@ -1154,10 +1266,12 @@ void bCPU::op_bit_dp() { cpu_c2(); break; case 3: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DP, dp); if(regs.p.m) { op_bit_b(); status.cycle_pos = 0; } break; case 4: + last_cycle(); rd.h = op_read(OPMODE_DP, dp + 1); op_bit_w(); status.cycle_pos = 0; @@ -1174,10 +1288,12 @@ void bCPU::op_cmp_dp() { cpu_c2(); break; case 3: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DP, dp); if(regs.p.m) { op_cmp_b(); status.cycle_pos = 0; } break; case 4: + last_cycle(); rd.h = op_read(OPMODE_DP, dp + 1); op_cmp_w(); status.cycle_pos = 0; @@ -1194,10 +1310,12 @@ void bCPU::op_cpx_dp() { cpu_c2(); break; case 3: + if(regs.p.x)last_cycle(); rd.l = op_read(OPMODE_DP, dp); if(regs.p.x) { op_cpx_b(); status.cycle_pos = 0; } break; case 4: + last_cycle(); rd.h = op_read(OPMODE_DP, dp + 1); op_cpx_w(); status.cycle_pos = 0; @@ -1214,10 +1332,12 @@ void bCPU::op_cpy_dp() { cpu_c2(); break; case 3: + if(regs.p.x)last_cycle(); rd.l = op_read(OPMODE_DP, dp); if(regs.p.x) { op_cpy_b(); status.cycle_pos = 0; } break; case 4: + last_cycle(); rd.h = op_read(OPMODE_DP, dp + 1); op_cpy_w(); status.cycle_pos = 0; @@ -1234,10 +1354,12 @@ void bCPU::op_eor_dp() { cpu_c2(); break; case 3: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DP, dp); if(regs.p.m) { op_eor_b(); status.cycle_pos = 0; } break; case 4: + last_cycle(); rd.h = op_read(OPMODE_DP, dp + 1); op_eor_w(); status.cycle_pos = 0; @@ -1254,10 +1376,12 @@ void bCPU::op_lda_dp() { cpu_c2(); break; case 3: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DP, dp); if(regs.p.m) { op_lda_b(); status.cycle_pos = 0; } break; case 4: + last_cycle(); rd.h = op_read(OPMODE_DP, dp + 1); op_lda_w(); status.cycle_pos = 0; @@ -1274,10 +1398,12 @@ void bCPU::op_ldx_dp() { cpu_c2(); break; case 3: + if(regs.p.x)last_cycle(); rd.l = op_read(OPMODE_DP, dp); if(regs.p.x) { op_ldx_b(); status.cycle_pos = 0; } break; case 4: + last_cycle(); rd.h = op_read(OPMODE_DP, dp + 1); op_ldx_w(); status.cycle_pos = 0; @@ -1294,10 +1420,12 @@ void bCPU::op_ldy_dp() { cpu_c2(); break; case 3: + if(regs.p.x)last_cycle(); rd.l = op_read(OPMODE_DP, dp); if(regs.p.x) { op_ldy_b(); status.cycle_pos = 0; } break; case 4: + last_cycle(); rd.h = op_read(OPMODE_DP, dp + 1); op_ldy_w(); status.cycle_pos = 0; @@ -1314,10 +1442,12 @@ void bCPU::op_ora_dp() { cpu_c2(); break; case 3: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DP, dp); if(regs.p.m) { op_ora_b(); status.cycle_pos = 0; } break; case 4: + last_cycle(); rd.h = op_read(OPMODE_DP, dp + 1); op_ora_w(); status.cycle_pos = 0; @@ -1334,10 +1464,12 @@ void bCPU::op_sbc_dp() { cpu_c2(); break; case 3: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DP, dp); if(regs.p.m) { op_sbc_b(); status.cycle_pos = 0; } break; case 4: + last_cycle(); rd.h = op_read(OPMODE_DP, dp + 1); op_sbc_w(); status.cycle_pos = 0; @@ -1357,10 +1489,12 @@ void bCPU::op_adc_dpx() { cpu_io(); break; case 4: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DP, dp + regs.x.w); if(regs.p.m) { op_adc_b(); status.cycle_pos = 0; } break; case 5: + last_cycle(); rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); op_adc_w(); status.cycle_pos = 0; @@ -1380,10 +1514,12 @@ void bCPU::op_and_dpx() { cpu_io(); break; case 4: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DP, dp + regs.x.w); if(regs.p.m) { op_and_b(); status.cycle_pos = 0; } break; case 5: + last_cycle(); rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); op_and_w(); status.cycle_pos = 0; @@ -1403,10 +1539,12 @@ void bCPU::op_bit_dpx() { cpu_io(); break; case 4: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DP, dp + regs.x.w); if(regs.p.m) { op_bit_b(); status.cycle_pos = 0; } break; case 5: + last_cycle(); rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); op_bit_w(); status.cycle_pos = 0; @@ -1426,10 +1564,12 @@ void bCPU::op_cmp_dpx() { cpu_io(); break; case 4: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DP, dp + regs.x.w); if(regs.p.m) { op_cmp_b(); status.cycle_pos = 0; } break; case 5: + last_cycle(); rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); op_cmp_w(); status.cycle_pos = 0; @@ -1449,10 +1589,12 @@ void bCPU::op_eor_dpx() { cpu_io(); break; case 4: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DP, dp + regs.x.w); if(regs.p.m) { op_eor_b(); status.cycle_pos = 0; } break; case 5: + last_cycle(); rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); op_eor_w(); status.cycle_pos = 0; @@ -1472,10 +1614,12 @@ void bCPU::op_lda_dpx() { cpu_io(); break; case 4: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DP, dp + regs.x.w); if(regs.p.m) { op_lda_b(); status.cycle_pos = 0; } break; case 5: + last_cycle(); rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); op_lda_w(); status.cycle_pos = 0; @@ -1495,10 +1639,12 @@ void bCPU::op_ldy_dpx() { cpu_io(); break; case 4: + if(regs.p.x)last_cycle(); rd.l = op_read(OPMODE_DP, dp + regs.x.w); if(regs.p.x) { op_ldy_b(); status.cycle_pos = 0; } break; case 5: + last_cycle(); rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); op_ldy_w(); status.cycle_pos = 0; @@ -1518,10 +1664,12 @@ void bCPU::op_ora_dpx() { cpu_io(); break; case 4: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DP, dp + regs.x.w); if(regs.p.m) { op_ora_b(); status.cycle_pos = 0; } break; case 5: + last_cycle(); rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); op_ora_w(); status.cycle_pos = 0; @@ -1541,10 +1689,12 @@ void bCPU::op_sbc_dpx() { cpu_io(); break; case 4: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DP, dp + regs.x.w); if(regs.p.m) { op_sbc_b(); status.cycle_pos = 0; } break; case 5: + last_cycle(); rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); op_sbc_w(); status.cycle_pos = 0; @@ -1564,10 +1714,12 @@ void bCPU::op_ldx_dpy() { cpu_io(); break; case 4: + if(regs.p.x)last_cycle(); rd.l = op_read(OPMODE_DP, dp + regs.y.w); if(regs.p.x) { op_ldx_b(); status.cycle_pos = 0; } break; case 5: + last_cycle(); rd.h = op_read(OPMODE_DP, dp + regs.y.w + 1); op_ldx_w(); status.cycle_pos = 0; @@ -1590,10 +1742,12 @@ void bCPU::op_adc_idp() { aa.h = op_read(OPMODE_DP, dp + 1); break; case 5: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w); if(regs.p.m) { op_adc_b(); status.cycle_pos = 0; } break; case 6: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + 1); op_adc_w(); status.cycle_pos = 0; @@ -1616,10 +1770,12 @@ void bCPU::op_and_idp() { aa.h = op_read(OPMODE_DP, dp + 1); break; case 5: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w); if(regs.p.m) { op_and_b(); status.cycle_pos = 0; } break; case 6: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + 1); op_and_w(); status.cycle_pos = 0; @@ -1642,10 +1798,12 @@ void bCPU::op_cmp_idp() { aa.h = op_read(OPMODE_DP, dp + 1); break; case 5: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w); if(regs.p.m) { op_cmp_b(); status.cycle_pos = 0; } break; case 6: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + 1); op_cmp_w(); status.cycle_pos = 0; @@ -1668,10 +1826,12 @@ void bCPU::op_eor_idp() { aa.h = op_read(OPMODE_DP, dp + 1); break; case 5: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w); if(regs.p.m) { op_eor_b(); status.cycle_pos = 0; } break; case 6: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + 1); op_eor_w(); status.cycle_pos = 0; @@ -1694,10 +1854,12 @@ void bCPU::op_lda_idp() { aa.h = op_read(OPMODE_DP, dp + 1); break; case 5: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w); if(regs.p.m) { op_lda_b(); status.cycle_pos = 0; } break; case 6: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + 1); op_lda_w(); status.cycle_pos = 0; @@ -1720,10 +1882,12 @@ void bCPU::op_ora_idp() { aa.h = op_read(OPMODE_DP, dp + 1); break; case 5: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w); if(regs.p.m) { op_ora_b(); status.cycle_pos = 0; } break; case 6: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + 1); op_ora_w(); status.cycle_pos = 0; @@ -1746,10 +1910,12 @@ void bCPU::op_sbc_idp() { aa.h = op_read(OPMODE_DP, dp + 1); break; case 5: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w); if(regs.p.m) { op_sbc_b(); status.cycle_pos = 0; } break; case 6: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + 1); op_sbc_w(); status.cycle_pos = 0; @@ -1775,10 +1941,12 @@ void bCPU::op_adc_idpx() { aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); break; case 6: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w); if(regs.p.m) { op_adc_b(); status.cycle_pos = 0; } break; case 7: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + 1); op_adc_w(); status.cycle_pos = 0; @@ -1804,10 +1972,12 @@ void bCPU::op_and_idpx() { aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); break; case 6: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w); if(regs.p.m) { op_and_b(); status.cycle_pos = 0; } break; case 7: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + 1); op_and_w(); status.cycle_pos = 0; @@ -1833,10 +2003,12 @@ void bCPU::op_cmp_idpx() { aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); break; case 6: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w); if(regs.p.m) { op_cmp_b(); status.cycle_pos = 0; } break; case 7: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + 1); op_cmp_w(); status.cycle_pos = 0; @@ -1862,10 +2034,12 @@ void bCPU::op_eor_idpx() { aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); break; case 6: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w); if(regs.p.m) { op_eor_b(); status.cycle_pos = 0; } break; case 7: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + 1); op_eor_w(); status.cycle_pos = 0; @@ -1891,10 +2065,12 @@ void bCPU::op_lda_idpx() { aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); break; case 6: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w); if(regs.p.m) { op_lda_b(); status.cycle_pos = 0; } break; case 7: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + 1); op_lda_w(); status.cycle_pos = 0; @@ -1920,10 +2096,12 @@ void bCPU::op_ora_idpx() { aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); break; case 6: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w); if(regs.p.m) { op_ora_b(); status.cycle_pos = 0; } break; case 7: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + 1); op_ora_w(); status.cycle_pos = 0; @@ -1949,10 +2127,12 @@ void bCPU::op_sbc_idpx() { aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); break; case 6: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w); if(regs.p.m) { op_sbc_b(); status.cycle_pos = 0; } break; case 7: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + 1); op_sbc_w(); status.cycle_pos = 0; @@ -1978,10 +2158,12 @@ void bCPU::op_adc_idpy() { cpu_c4(aa.w, aa.w + regs.y.w); break; case 6: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); if(regs.p.m) { op_adc_b(); status.cycle_pos = 0; } break; case 7: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); op_adc_w(); status.cycle_pos = 0; @@ -2007,10 +2189,12 @@ void bCPU::op_and_idpy() { cpu_c4(aa.w, aa.w + regs.y.w); break; case 6: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); if(regs.p.m) { op_and_b(); status.cycle_pos = 0; } break; case 7: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); op_and_w(); status.cycle_pos = 0; @@ -2036,10 +2220,12 @@ void bCPU::op_cmp_idpy() { cpu_c4(aa.w, aa.w + regs.y.w); break; case 6: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); if(regs.p.m) { op_cmp_b(); status.cycle_pos = 0; } break; case 7: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); op_cmp_w(); status.cycle_pos = 0; @@ -2065,10 +2251,12 @@ void bCPU::op_eor_idpy() { cpu_c4(aa.w, aa.w + regs.y.w); break; case 6: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); if(regs.p.m) { op_eor_b(); status.cycle_pos = 0; } break; case 7: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); op_eor_w(); status.cycle_pos = 0; @@ -2094,10 +2282,12 @@ void bCPU::op_lda_idpy() { cpu_c4(aa.w, aa.w + regs.y.w); break; case 6: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); if(regs.p.m) { op_lda_b(); status.cycle_pos = 0; } break; case 7: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); op_lda_w(); status.cycle_pos = 0; @@ -2123,10 +2313,12 @@ void bCPU::op_ora_idpy() { cpu_c4(aa.w, aa.w + regs.y.w); break; case 6: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); if(regs.p.m) { op_ora_b(); status.cycle_pos = 0; } break; case 7: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); op_ora_w(); status.cycle_pos = 0; @@ -2152,10 +2344,12 @@ void bCPU::op_sbc_idpy() { cpu_c4(aa.w, aa.w + regs.y.w); break; case 6: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); if(regs.p.m) { op_sbc_b(); status.cycle_pos = 0; } break; case 7: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); op_sbc_w(); status.cycle_pos = 0; @@ -2181,10 +2375,12 @@ void bCPU::op_adc_ildp() { aa.b = op_read(OPMODE_DP, dp + 2); break; case 6: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_LONG, aa.d); if(regs.p.m) { op_adc_b(); status.cycle_pos = 0; } break; case 7: + last_cycle(); rd.h = op_read(OPMODE_LONG, aa.d + 1); op_adc_w(); status.cycle_pos = 0; @@ -2210,10 +2406,12 @@ void bCPU::op_and_ildp() { aa.b = op_read(OPMODE_DP, dp + 2); break; case 6: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_LONG, aa.d); if(regs.p.m) { op_and_b(); status.cycle_pos = 0; } break; case 7: + last_cycle(); rd.h = op_read(OPMODE_LONG, aa.d + 1); op_and_w(); status.cycle_pos = 0; @@ -2239,10 +2437,12 @@ void bCPU::op_cmp_ildp() { aa.b = op_read(OPMODE_DP, dp + 2); break; case 6: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_LONG, aa.d); if(regs.p.m) { op_cmp_b(); status.cycle_pos = 0; } break; case 7: + last_cycle(); rd.h = op_read(OPMODE_LONG, aa.d + 1); op_cmp_w(); status.cycle_pos = 0; @@ -2268,10 +2468,12 @@ void bCPU::op_eor_ildp() { aa.b = op_read(OPMODE_DP, dp + 2); break; case 6: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_LONG, aa.d); if(regs.p.m) { op_eor_b(); status.cycle_pos = 0; } break; case 7: + last_cycle(); rd.h = op_read(OPMODE_LONG, aa.d + 1); op_eor_w(); status.cycle_pos = 0; @@ -2297,10 +2499,12 @@ void bCPU::op_lda_ildp() { aa.b = op_read(OPMODE_DP, dp + 2); break; case 6: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_LONG, aa.d); if(regs.p.m) { op_lda_b(); status.cycle_pos = 0; } break; case 7: + last_cycle(); rd.h = op_read(OPMODE_LONG, aa.d + 1); op_lda_w(); status.cycle_pos = 0; @@ -2326,10 +2530,12 @@ void bCPU::op_ora_ildp() { aa.b = op_read(OPMODE_DP, dp + 2); break; case 6: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_LONG, aa.d); if(regs.p.m) { op_ora_b(); status.cycle_pos = 0; } break; case 7: + last_cycle(); rd.h = op_read(OPMODE_LONG, aa.d + 1); op_ora_w(); status.cycle_pos = 0; @@ -2355,10 +2561,12 @@ void bCPU::op_sbc_ildp() { aa.b = op_read(OPMODE_DP, dp + 2); break; case 6: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_LONG, aa.d); if(regs.p.m) { op_sbc_b(); status.cycle_pos = 0; } break; case 7: + last_cycle(); rd.h = op_read(OPMODE_LONG, aa.d + 1); op_sbc_w(); status.cycle_pos = 0; @@ -2384,10 +2592,12 @@ void bCPU::op_adc_ildpy() { aa.b = op_read(OPMODE_DP, dp + 2); break; case 6: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_LONG, aa.d + regs.y.w); if(regs.p.m) { op_adc_b(); status.cycle_pos = 0; } break; case 7: + last_cycle(); rd.h = op_read(OPMODE_LONG, aa.d + regs.y.w + 1); op_adc_w(); status.cycle_pos = 0; @@ -2413,10 +2623,12 @@ void bCPU::op_and_ildpy() { aa.b = op_read(OPMODE_DP, dp + 2); break; case 6: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_LONG, aa.d + regs.y.w); if(regs.p.m) { op_and_b(); status.cycle_pos = 0; } break; case 7: + last_cycle(); rd.h = op_read(OPMODE_LONG, aa.d + regs.y.w + 1); op_and_w(); status.cycle_pos = 0; @@ -2442,10 +2654,12 @@ void bCPU::op_cmp_ildpy() { aa.b = op_read(OPMODE_DP, dp + 2); break; case 6: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_LONG, aa.d + regs.y.w); if(regs.p.m) { op_cmp_b(); status.cycle_pos = 0; } break; case 7: + last_cycle(); rd.h = op_read(OPMODE_LONG, aa.d + regs.y.w + 1); op_cmp_w(); status.cycle_pos = 0; @@ -2471,10 +2685,12 @@ void bCPU::op_eor_ildpy() { aa.b = op_read(OPMODE_DP, dp + 2); break; case 6: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_LONG, aa.d + regs.y.w); if(regs.p.m) { op_eor_b(); status.cycle_pos = 0; } break; case 7: + last_cycle(); rd.h = op_read(OPMODE_LONG, aa.d + regs.y.w + 1); op_eor_w(); status.cycle_pos = 0; @@ -2500,10 +2716,12 @@ void bCPU::op_lda_ildpy() { aa.b = op_read(OPMODE_DP, dp + 2); break; case 6: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_LONG, aa.d + regs.y.w); if(regs.p.m) { op_lda_b(); status.cycle_pos = 0; } break; case 7: + last_cycle(); rd.h = op_read(OPMODE_LONG, aa.d + regs.y.w + 1); op_lda_w(); status.cycle_pos = 0; @@ -2529,10 +2747,12 @@ void bCPU::op_ora_ildpy() { aa.b = op_read(OPMODE_DP, dp + 2); break; case 6: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_LONG, aa.d + regs.y.w); if(regs.p.m) { op_ora_b(); status.cycle_pos = 0; } break; case 7: + last_cycle(); rd.h = op_read(OPMODE_LONG, aa.d + regs.y.w + 1); op_ora_w(); status.cycle_pos = 0; @@ -2558,10 +2778,12 @@ void bCPU::op_sbc_ildpy() { aa.b = op_read(OPMODE_DP, dp + 2); break; case 6: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_LONG, aa.d + regs.y.w); if(regs.p.m) { op_sbc_b(); status.cycle_pos = 0; } break; case 7: + last_cycle(); rd.h = op_read(OPMODE_LONG, aa.d + regs.y.w + 1); op_sbc_w(); status.cycle_pos = 0; @@ -2578,10 +2800,12 @@ void bCPU::op_adc_sr() { cpu_io(); break; case 3: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_SP, sp); if(regs.p.m) { op_adc_b(); status.cycle_pos = 0; } break; case 4: + last_cycle(); rd.h = op_read(OPMODE_SP, sp + 1); op_adc_w(); status.cycle_pos = 0; @@ -2598,10 +2822,12 @@ void bCPU::op_and_sr() { cpu_io(); break; case 3: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_SP, sp); if(regs.p.m) { op_and_b(); status.cycle_pos = 0; } break; case 4: + last_cycle(); rd.h = op_read(OPMODE_SP, sp + 1); op_and_w(); status.cycle_pos = 0; @@ -2618,10 +2844,12 @@ void bCPU::op_cmp_sr() { cpu_io(); break; case 3: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_SP, sp); if(regs.p.m) { op_cmp_b(); status.cycle_pos = 0; } break; case 4: + last_cycle(); rd.h = op_read(OPMODE_SP, sp + 1); op_cmp_w(); status.cycle_pos = 0; @@ -2638,10 +2866,12 @@ void bCPU::op_eor_sr() { cpu_io(); break; case 3: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_SP, sp); if(regs.p.m) { op_eor_b(); status.cycle_pos = 0; } break; case 4: + last_cycle(); rd.h = op_read(OPMODE_SP, sp + 1); op_eor_w(); status.cycle_pos = 0; @@ -2658,10 +2888,12 @@ void bCPU::op_lda_sr() { cpu_io(); break; case 3: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_SP, sp); if(regs.p.m) { op_lda_b(); status.cycle_pos = 0; } break; case 4: + last_cycle(); rd.h = op_read(OPMODE_SP, sp + 1); op_lda_w(); status.cycle_pos = 0; @@ -2678,10 +2910,12 @@ void bCPU::op_ora_sr() { cpu_io(); break; case 3: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_SP, sp); if(regs.p.m) { op_ora_b(); status.cycle_pos = 0; } break; case 4: + last_cycle(); rd.h = op_read(OPMODE_SP, sp + 1); op_ora_w(); status.cycle_pos = 0; @@ -2698,10 +2932,12 @@ void bCPU::op_sbc_sr() { cpu_io(); break; case 3: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_SP, sp); if(regs.p.m) { op_sbc_b(); status.cycle_pos = 0; } break; case 4: + last_cycle(); rd.h = op_read(OPMODE_SP, sp + 1); op_sbc_w(); status.cycle_pos = 0; @@ -2727,10 +2963,12 @@ void bCPU::op_adc_isry() { cpu_io(); break; case 6: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); if(regs.p.m) { op_adc_b(); status.cycle_pos = 0; } break; case 7: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); op_adc_w(); status.cycle_pos = 0; @@ -2756,10 +2994,12 @@ void bCPU::op_and_isry() { cpu_io(); break; case 6: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); if(regs.p.m) { op_and_b(); status.cycle_pos = 0; } break; case 7: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); op_and_w(); status.cycle_pos = 0; @@ -2785,10 +3025,12 @@ void bCPU::op_cmp_isry() { cpu_io(); break; case 6: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); if(regs.p.m) { op_cmp_b(); status.cycle_pos = 0; } break; case 7: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); op_cmp_w(); status.cycle_pos = 0; @@ -2814,10 +3056,12 @@ void bCPU::op_eor_isry() { cpu_io(); break; case 6: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); if(regs.p.m) { op_eor_b(); status.cycle_pos = 0; } break; case 7: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); op_eor_w(); status.cycle_pos = 0; @@ -2843,10 +3087,12 @@ void bCPU::op_lda_isry() { cpu_io(); break; case 6: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); if(regs.p.m) { op_lda_b(); status.cycle_pos = 0; } break; case 7: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); op_lda_w(); status.cycle_pos = 0; @@ -2872,10 +3118,12 @@ void bCPU::op_ora_isry() { cpu_io(); break; case 6: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); if(regs.p.m) { op_ora_b(); status.cycle_pos = 0; } break; case 7: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); op_ora_w(); status.cycle_pos = 0; @@ -2901,10 +3149,12 @@ void bCPU::op_sbc_isry() { cpu_io(); break; case 6: + if(regs.p.m)last_cycle(); rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); if(regs.p.m) { op_sbc_b(); status.cycle_pos = 0; } break; case 7: + last_cycle(); rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); op_sbc_w(); status.cycle_pos = 0; @@ -2915,6 +3165,7 @@ void bCPU::op_sbc_isry() { void bCPU::op_bit_const() { switch(status.cycle_pos++) { case 1: + if(regs.p.m)last_cycle(); rd.l = op_read(); if(regs.p.m) { regs.p.z = ((rd.l & regs.a.l) == 0); @@ -2922,6 +3173,7 @@ void bCPU::op_bit_const() { } break; case 2: + last_cycle(); rd.h = op_read(); regs.p.z = ((rd.w & regs.a.w) == 0); status.cycle_pos = 0; diff --git a/src/cpu/bcpu/bcpu_op_rmw.cpp b/src/cpu/bcpu/bcpu_op_rmw.cpp index 8d716c91..41f0939c 100644 --- a/src/cpu/bcpu/bcpu_op_rmw.cpp +++ b/src/cpu/bcpu/bcpu_op_rmw.cpp @@ -1,6 +1,7 @@ void bCPU::op_inc() { switch(status.cycle_pos++) { case 1: + last_cycle(); cpu_io(); if(regs.p.m) { regs.a.l++; @@ -19,6 +20,7 @@ void bCPU::op_inc() { void bCPU::op_inx() { switch(status.cycle_pos++) { case 1: + last_cycle(); cpu_io(); if(regs.p.x) { regs.x.l++; @@ -37,6 +39,7 @@ void bCPU::op_inx() { void bCPU::op_iny() { switch(status.cycle_pos++) { case 1: + last_cycle(); cpu_io(); if(regs.p.x) { regs.y.l++; @@ -55,6 +58,7 @@ void bCPU::op_iny() { void bCPU::op_dec() { switch(status.cycle_pos++) { case 1: + last_cycle(); cpu_io(); if(regs.p.m) { regs.a.l--; @@ -73,6 +77,7 @@ void bCPU::op_dec() { void bCPU::op_dex() { switch(status.cycle_pos++) { case 1: + last_cycle(); cpu_io(); if(regs.p.x) { regs.x.l--; @@ -91,6 +96,7 @@ void bCPU::op_dex() { void bCPU::op_dey() { switch(status.cycle_pos++) { case 1: + last_cycle(); cpu_io(); if(regs.p.x) { regs.y.l--; @@ -109,6 +115,7 @@ void bCPU::op_dey() { void bCPU::op_asl() { switch(status.cycle_pos++) { case 1: + last_cycle(); cpu_io(); if(regs.p.m) { regs.p.c = !!(regs.a.l & 0x80); @@ -129,6 +136,7 @@ void bCPU::op_asl() { void bCPU::op_lsr() { switch(status.cycle_pos++) { case 1: + last_cycle(); cpu_io(); if(regs.p.m) { regs.p.c = regs.a.l & 1; @@ -149,6 +157,7 @@ void bCPU::op_lsr() { void bCPU::op_rol() { switch(status.cycle_pos++) { case 1: + last_cycle(); cpu_io(); uint16 c = regs.p.c; if(regs.p.m) { @@ -172,6 +181,7 @@ void bCPU::op_rol() { void bCPU::op_ror() { switch(status.cycle_pos++) { case 1: + last_cycle(); cpu_io(); uint16 c; if(regs.p.m) { @@ -218,6 +228,7 @@ void bCPU::op_inc_addr() { op_write(OPMODE_DBR, aa.w + 1, rd.h); break; case 7: + last_cycle(); op_write(OPMODE_DBR, aa.w, rd.l); status.cycle_pos = 0; break; @@ -248,6 +259,7 @@ void bCPU::op_dec_addr() { op_write(OPMODE_DBR, aa.w + 1, rd.h); break; case 7: + last_cycle(); op_write(OPMODE_DBR, aa.w, rd.l); status.cycle_pos = 0; break; @@ -278,6 +290,7 @@ void bCPU::op_asl_addr() { op_write(OPMODE_DBR, aa.w + 1, rd.h); break; case 7: + last_cycle(); op_write(OPMODE_DBR, aa.w, rd.l); status.cycle_pos = 0; break; @@ -308,6 +321,7 @@ void bCPU::op_lsr_addr() { op_write(OPMODE_DBR, aa.w + 1, rd.h); break; case 7: + last_cycle(); op_write(OPMODE_DBR, aa.w, rd.l); status.cycle_pos = 0; break; @@ -338,6 +352,7 @@ void bCPU::op_rol_addr() { op_write(OPMODE_DBR, aa.w + 1, rd.h); break; case 7: + last_cycle(); op_write(OPMODE_DBR, aa.w, rd.l); status.cycle_pos = 0; break; @@ -368,6 +383,7 @@ void bCPU::op_ror_addr() { op_write(OPMODE_DBR, aa.w + 1, rd.h); break; case 7: + last_cycle(); op_write(OPMODE_DBR, aa.w, rd.l); status.cycle_pos = 0; break; @@ -398,6 +414,7 @@ void bCPU::op_trb_addr() { op_write(OPMODE_DBR, aa.w + 1, rd.h); break; case 7: + last_cycle(); op_write(OPMODE_DBR, aa.w, rd.l); status.cycle_pos = 0; break; @@ -428,6 +445,7 @@ void bCPU::op_tsb_addr() { op_write(OPMODE_DBR, aa.w + 1, rd.h); break; case 7: + last_cycle(); op_write(OPMODE_DBR, aa.w, rd.l); status.cycle_pos = 0; break; @@ -461,6 +479,7 @@ void bCPU::op_inc_addrx() { op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h); break; case 8: + last_cycle(); op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); status.cycle_pos = 0; break; @@ -494,6 +513,7 @@ void bCPU::op_dec_addrx() { op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h); break; case 8: + last_cycle(); op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); status.cycle_pos = 0; break; @@ -527,6 +547,7 @@ void bCPU::op_asl_addrx() { op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h); break; case 8: + last_cycle(); op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); status.cycle_pos = 0; break; @@ -560,6 +581,7 @@ void bCPU::op_lsr_addrx() { op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h); break; case 8: + last_cycle(); op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); status.cycle_pos = 0; break; @@ -593,6 +615,7 @@ void bCPU::op_rol_addrx() { op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h); break; case 8: + last_cycle(); op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); status.cycle_pos = 0; break; @@ -626,6 +649,7 @@ void bCPU::op_ror_addrx() { op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h); break; case 8: + last_cycle(); op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); status.cycle_pos = 0; break; @@ -656,6 +680,7 @@ void bCPU::op_inc_dp() { op_write(OPMODE_DP, dp + 1, rd.h); break; case 7: + last_cycle(); op_write(OPMODE_DP, dp, rd.l); status.cycle_pos = 0; break; @@ -686,6 +711,7 @@ void bCPU::op_dec_dp() { op_write(OPMODE_DP, dp + 1, rd.h); break; case 7: + last_cycle(); op_write(OPMODE_DP, dp, rd.l); status.cycle_pos = 0; break; @@ -716,6 +742,7 @@ void bCPU::op_asl_dp() { op_write(OPMODE_DP, dp + 1, rd.h); break; case 7: + last_cycle(); op_write(OPMODE_DP, dp, rd.l); status.cycle_pos = 0; break; @@ -746,6 +773,7 @@ void bCPU::op_lsr_dp() { op_write(OPMODE_DP, dp + 1, rd.h); break; case 7: + last_cycle(); op_write(OPMODE_DP, dp, rd.l); status.cycle_pos = 0; break; @@ -776,6 +804,7 @@ void bCPU::op_rol_dp() { op_write(OPMODE_DP, dp + 1, rd.h); break; case 7: + last_cycle(); op_write(OPMODE_DP, dp, rd.l); status.cycle_pos = 0; break; @@ -806,6 +835,7 @@ void bCPU::op_ror_dp() { op_write(OPMODE_DP, dp + 1, rd.h); break; case 7: + last_cycle(); op_write(OPMODE_DP, dp, rd.l); status.cycle_pos = 0; break; @@ -836,6 +866,7 @@ void bCPU::op_trb_dp() { op_write(OPMODE_DP, dp + 1, rd.h); break; case 7: + last_cycle(); op_write(OPMODE_DP, dp, rd.l); status.cycle_pos = 0; break; @@ -866,6 +897,7 @@ void bCPU::op_tsb_dp() { op_write(OPMODE_DP, dp + 1, rd.h); break; case 7: + last_cycle(); op_write(OPMODE_DP, dp, rd.l); status.cycle_pos = 0; break; @@ -899,6 +931,7 @@ void bCPU::op_inc_dpx() { op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h); break; case 8: + last_cycle(); op_write(OPMODE_DP, dp + regs.x.w, rd.l); status.cycle_pos = 0; break; @@ -932,6 +965,7 @@ void bCPU::op_dec_dpx() { op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h); break; case 8: + last_cycle(); op_write(OPMODE_DP, dp + regs.x.w, rd.l); status.cycle_pos = 0; break; @@ -965,6 +999,7 @@ void bCPU::op_asl_dpx() { op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h); break; case 8: + last_cycle(); op_write(OPMODE_DP, dp + regs.x.w, rd.l); status.cycle_pos = 0; break; @@ -998,6 +1033,7 @@ void bCPU::op_lsr_dpx() { op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h); break; case 8: + last_cycle(); op_write(OPMODE_DP, dp + regs.x.w, rd.l); status.cycle_pos = 0; break; @@ -1031,6 +1067,7 @@ void bCPU::op_rol_dpx() { op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h); break; case 8: + last_cycle(); op_write(OPMODE_DP, dp + regs.x.w, rd.l); status.cycle_pos = 0; break; @@ -1064,6 +1101,7 @@ void bCPU::op_ror_dpx() { op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h); break; case 8: + last_cycle(); op_write(OPMODE_DP, dp + regs.x.w, rd.l); status.cycle_pos = 0; break; diff --git a/src/cpu/bcpu/bcpu_op_write.cpp b/src/cpu/bcpu/bcpu_op_write.cpp index 6bff82ad..42d218a6 100644 --- a/src/cpu/bcpu/bcpu_op_write.cpp +++ b/src/cpu/bcpu/bcpu_op_write.cpp @@ -7,10 +7,12 @@ void bCPU::op_sta_addr() { aa.h = op_read(); break; case 3: + if(regs.p.m)last_cycle(); op_write(OPMODE_DBR, aa.w, regs.a.w); if(regs.p.m)status.cycle_pos = 0; break; case 4: + last_cycle(); op_write(OPMODE_DBR, aa.w + 1, regs.a.w >> 8); status.cycle_pos = 0; break; @@ -26,10 +28,12 @@ void bCPU::op_stx_addr() { aa.h = op_read(); break; case 3: + if(regs.p.x)last_cycle(); op_write(OPMODE_DBR, aa.w, regs.x.w); if(regs.p.x)status.cycle_pos = 0; break; case 4: + last_cycle(); op_write(OPMODE_DBR, aa.w + 1, regs.x.w >> 8); status.cycle_pos = 0; break; @@ -45,10 +49,12 @@ void bCPU::op_sty_addr() { aa.h = op_read(); break; case 3: + if(regs.p.x)last_cycle(); op_write(OPMODE_DBR, aa.w, regs.y.w); if(regs.p.x)status.cycle_pos = 0; break; case 4: + last_cycle(); op_write(OPMODE_DBR, aa.w + 1, regs.y.w >> 8); status.cycle_pos = 0; break; @@ -64,10 +70,12 @@ void bCPU::op_stz_addr() { aa.h = op_read(); break; case 3: + if(regs.p.m)last_cycle(); op_write(OPMODE_DBR, aa.w, 0x0000); if(regs.p.m)status.cycle_pos = 0; break; case 4: + last_cycle(); op_write(OPMODE_DBR, aa.w + 1, 0x0000 >> 8); status.cycle_pos = 0; break; @@ -86,10 +94,12 @@ void bCPU::op_sta_addrx() { cpu_c4(aa.w, aa.w + regs.x.w); break; case 4: + if(regs.p.m)last_cycle(); op_write(OPMODE_DBR, aa.w + regs.x.w, regs.a.w); if(regs.p.m)status.cycle_pos = 0; break; case 5: + last_cycle(); op_write(OPMODE_DBR, aa.w + regs.x.w + 1, regs.a.w >> 8); status.cycle_pos = 0; break; @@ -108,10 +118,12 @@ void bCPU::op_stz_addrx() { cpu_c4(aa.w, aa.w + regs.x.w); break; case 4: + if(regs.p.m)last_cycle(); op_write(OPMODE_DBR, aa.w + regs.x.w, 0x0000); if(regs.p.m)status.cycle_pos = 0; break; case 5: + last_cycle(); op_write(OPMODE_DBR, aa.w + regs.x.w + 1, 0x0000 >> 8); status.cycle_pos = 0; break; @@ -130,10 +142,12 @@ void bCPU::op_sta_addry() { cpu_c4(aa.w, aa.w + regs.y.w); break; case 4: + if(regs.p.m)last_cycle(); op_write(OPMODE_DBR, aa.w + regs.y.w, regs.a.l); if(regs.p.m)status.cycle_pos = 0; break; case 5: + last_cycle(); op_write(OPMODE_DBR, aa.w + regs.y.w + 1, regs.a.h); status.cycle_pos = 0; break; @@ -152,10 +166,12 @@ void bCPU::op_sta_long() { aa.b = op_read(); break; case 4: + if(regs.p.m)last_cycle(); op_write(OPMODE_LONG, aa.d, regs.a.l); if(regs.p.m)status.cycle_pos = 0; break; case 5: + last_cycle(); op_write(OPMODE_LONG, aa.d + 1, regs.a.h); status.cycle_pos = 0; break; @@ -174,10 +190,12 @@ void bCPU::op_sta_longx() { aa.b = op_read(); break; case 4: + if(regs.p.m)last_cycle(); op_write(OPMODE_LONG, aa.d + regs.x.w, regs.a.l); if(regs.p.m)status.cycle_pos = 0; break; case 5: + last_cycle(); op_write(OPMODE_LONG, aa.d + regs.x.w + 1, regs.a.h); status.cycle_pos = 0; break; @@ -193,10 +211,12 @@ void bCPU::op_sta_dp() { cpu_c2(); break; case 3: + if(regs.p.m)last_cycle(); op_write(OPMODE_DP, dp, regs.a.w); if(regs.p.m)status.cycle_pos = 0; break; case 4: + last_cycle(); op_write(OPMODE_DP, dp + 1, regs.a.w >> 8); status.cycle_pos = 0; break; @@ -212,10 +232,12 @@ void bCPU::op_stx_dp() { cpu_c2(); break; case 3: + if(regs.p.x)last_cycle(); op_write(OPMODE_DP, dp, regs.x.w); if(regs.p.x)status.cycle_pos = 0; break; case 4: + last_cycle(); op_write(OPMODE_DP, dp + 1, regs.x.w >> 8); status.cycle_pos = 0; break; @@ -231,10 +253,12 @@ void bCPU::op_sty_dp() { cpu_c2(); break; case 3: + if(regs.p.x)last_cycle(); op_write(OPMODE_DP, dp, regs.y.w); if(regs.p.x)status.cycle_pos = 0; break; case 4: + last_cycle(); op_write(OPMODE_DP, dp + 1, regs.y.w >> 8); status.cycle_pos = 0; break; @@ -250,10 +274,12 @@ void bCPU::op_stz_dp() { cpu_c2(); break; case 3: + if(regs.p.m)last_cycle(); op_write(OPMODE_DP, dp, 0x0000); if(regs.p.m)status.cycle_pos = 0; break; case 4: + last_cycle(); op_write(OPMODE_DP, dp + 1, 0x0000 >> 8); status.cycle_pos = 0; break; @@ -272,10 +298,12 @@ void bCPU::op_sta_dpx() { cpu_io(); break; case 4: + if(regs.p.m)last_cycle(); op_write(OPMODE_DP, dp + regs.x.w, regs.a.w); if(regs.p.m)status.cycle_pos = 0; break; case 5: + last_cycle(); op_write(OPMODE_DP, dp + regs.x.w + 1, regs.a.w >> 8); status.cycle_pos = 0; break; @@ -294,10 +322,12 @@ void bCPU::op_sty_dpx() { cpu_io(); break; case 4: + if(regs.p.x)last_cycle(); op_write(OPMODE_DP, dp + regs.x.w, regs.y.w); if(regs.p.x)status.cycle_pos = 0; break; case 5: + last_cycle(); op_write(OPMODE_DP, dp + regs.x.w + 1, regs.y.w >> 8); status.cycle_pos = 0; break; @@ -316,10 +346,12 @@ void bCPU::op_stz_dpx() { cpu_io(); break; case 4: + if(regs.p.m)last_cycle(); op_write(OPMODE_DP, dp + regs.x.w, 0x0000); if(regs.p.m)status.cycle_pos = 0; break; case 5: + last_cycle(); op_write(OPMODE_DP, dp + regs.x.w + 1, 0x0000 >> 8); status.cycle_pos = 0; break; @@ -338,10 +370,12 @@ void bCPU::op_stx_dpy() { cpu_io(); break; case 4: + if(regs.p.x)last_cycle(); op_write(OPMODE_DP, dp + regs.y.w, regs.x.l); if(regs.p.x)status.cycle_pos = 0; break; case 5: + last_cycle(); op_write(OPMODE_DP, dp + regs.y.w + 1, regs.x.h); status.cycle_pos = 0; break; @@ -363,10 +397,12 @@ void bCPU::op_sta_idp() { aa.h = op_read(OPMODE_DP, dp + 1); break; case 5: + if(regs.p.m)last_cycle(); op_write(OPMODE_DBR, aa.w, regs.a.l); if(regs.p.m)status.cycle_pos = 0; break; case 6: + last_cycle(); op_write(OPMODE_DBR, aa.w + 1, regs.a.h); status.cycle_pos = 0; break; @@ -391,10 +427,12 @@ void bCPU::op_sta_ildp() { aa.b = op_read(OPMODE_DP, dp + 2); break; case 6: + if(regs.p.m)last_cycle(); op_write(OPMODE_LONG, aa.d, regs.a.l); if(regs.p.m)status.cycle_pos = 0; break; case 7: + last_cycle(); op_write(OPMODE_LONG, aa.d + 1, regs.a.h); status.cycle_pos = 0; break; @@ -419,10 +457,12 @@ void bCPU::op_sta_idpx() { aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); break; case 6: + if(regs.p.m)last_cycle(); op_write(OPMODE_DBR, aa.w, regs.a.l); if(regs.p.m)status.cycle_pos = 0; break; case 7: + last_cycle(); op_write(OPMODE_DBR, aa.w + 1, regs.a.h); status.cycle_pos = 0; break; @@ -447,10 +487,12 @@ void bCPU::op_sta_idpy() { cpu_c4(aa.w, aa.w + regs.y.w); break; case 6: + if(regs.p.m)last_cycle(); op_write(OPMODE_DBR, aa.w + regs.y.w, regs.a.l); if(regs.p.m)status.cycle_pos = 0; break; case 7: + last_cycle(); op_write(OPMODE_DBR, aa.w + regs.y.w + 1, regs.a.h); status.cycle_pos = 0; break; @@ -475,10 +517,12 @@ void bCPU::op_sta_ildpy() { aa.b = op_read(OPMODE_DP, dp + 2); break; case 6: + if(regs.p.m)last_cycle(); op_write(OPMODE_LONG, aa.d + regs.y.w, regs.a.l); if(regs.p.m)status.cycle_pos = 0; break; case 7: + last_cycle(); op_write(OPMODE_LONG, aa.d + regs.y.w + 1, regs.a.h); status.cycle_pos = 0; break; @@ -494,10 +538,12 @@ void bCPU::op_sta_sr() { cpu_io(); break; case 3: + if(regs.p.m)last_cycle(); op_write(OPMODE_SP, sp, regs.a.l); if(regs.p.m)status.cycle_pos = 0; break; case 4: + last_cycle(); op_write(OPMODE_SP, sp + 1, regs.a.h); status.cycle_pos = 0; break; @@ -522,10 +568,12 @@ void bCPU::op_sta_isry() { cpu_io(); break; case 6: + if(regs.p.m)last_cycle(); op_write(OPMODE_DBR, aa.w + regs.y.w, regs.a.l); if(regs.p.m)status.cycle_pos = 0; break; case 7: + last_cycle(); op_write(OPMODE_DBR, aa.w + regs.y.w + 1, regs.a.h); status.cycle_pos = 0; break; diff --git a/src/cpu/bcpu/bcpu_optable.cpp b/src/cpu/bcpu/bcpu_optable.cpp index 253f75b9..4041724c 100644 --- a/src/cpu/bcpu/bcpu_optable.cpp +++ b/src/cpu/bcpu/bcpu_optable.cpp @@ -186,7 +186,6 @@ optbl[0x91] = &bCPU::op_sta_idpy; optbl[0x97] = &bCPU::op_sta_ildpy; optbl[0x83] = &bCPU::op_sta_sr; optbl[0x93] = &bCPU::op_sta_isry; -optbl[0x80] = &bCPU::op_bra; optbl[0x90] = &bCPU::op_bcc; optbl[0xb0] = &bCPU::op_bcs; optbl[0xd0] = &bCPU::op_bne; @@ -195,6 +194,7 @@ optbl[0x10] = &bCPU::op_bpl; optbl[0x30] = &bCPU::op_bmi; optbl[0x50] = &bCPU::op_bvc; optbl[0x70] = &bCPU::op_bvs; +optbl[0x80] = &bCPU::op_bra; optbl[0x82] = &bCPU::op_brl; optbl[0x4c] = &bCPU::op_jmp_addr; optbl[0x5c] = &bCPU::op_jmp_long; diff --git a/src/cpu/bcpu/bcpu_timing.cpp b/src/cpu/bcpu/bcpu_timing.cpp index d5e10792..e25535c3 100644 --- a/src/cpu/bcpu/bcpu_timing.cpp +++ b/src/cpu/bcpu/bcpu_timing.cpp @@ -25,19 +25,158 @@ * 4 cycles short? */ -uint16 bCPU::vcounter() { return time.v; } -uint16 bCPU::hcounter() { return get_hcounter(); } -uint16 bCPU::hcycles() { return time.hc; } +uint16 bCPU::vcounter() { return time.v; } +uint16 bCPU::hcounter() { return get_hcounter(); } +uint16 bCPU::hcycles() { return time.hc; } + bool bCPU::interlace() { return time.interlace; } bool bCPU::interlace_field() { return time.interlace_field; } bool bCPU::overscan() { return time.overscan; } uint16 bCPU::region_scanlines() { return time.region_scanlines; } -void bCPU::set_interlace(bool r) { time.interlace = r; } -void bCPU::set_overscan(bool r) { time.overscan = r; } +void bCPU::set_interlace(bool r) { time.interlace = r; update_interrupts(); } +void bCPU::set_overscan (bool r) { time.overscan = r; update_interrupts(); } uint8 bCPU::dma_counter() { return (time.dma_counter + time.hc) & 6; } +bool bCPU::nmi_trigger_pos_match(uint32 offset) { +uint16 v = overscan() ? 240 : 225; +uint16 hc = 2 + offset; + return (time.v == v && time.hc == hc); +} + +bool bCPU::irq_trigger_pos_match(uint32 offset) { +uint16 v = status.virq_pos; +uint16 hc = (status.hirq_enabled) ? status.hirq_pos : 0; + +//positions that can never be latched +//region_scanlines() = 262/NTSC, 312/PAL +//PAL results are unverified on hardware + if(v == 240 && hc == 339 && interlace() == false && interlace_field() == 1)return false; + if(v == (region_scanlines() - 1) && hc == 339 && interlace() == false)return false; + if(v == region_scanlines() && interlace() == false)return false; + if(v == region_scanlines() && hc == 339)return false; + if(v > region_scanlines())return false; + if(hc > 339)return false; + + hc = (hc != 0) ? ((hc << 2) + 14) : 10; + hc += offset; + if(hc >= time.line_cycles) { + hc -= time.line_cycles; + if(++v >= time.frame_lines) { + v = 0; + } + } + + if((status.virq_enabled == true && time.v == v) || status.virq_enabled == false) { + return (time.hc == hc); + } + + return false; +} + +void bCPU::update_nmi() { + if(time.v == (overscan() ? 240 : 225)) { + time.nmi_read_trigger_pos = 2; + time.nmi_line_trigger_pos = 6; + } else { + time.nmi_read_trigger_pos = -64; + time.nmi_line_trigger_pos = -64; + } +} + +void bCPU::update_irq() { +int vpos = status.virq_pos; +int hpos = (status.hirq_enabled) ? status.hirq_pos : 0; + +//positions that can never be latched +//region_scanlines() = 262/NTSC, 312/PAL +//PAL results are unverified on hardware + if(vpos == 240 && hpos == 339 && interlace() == false && interlace_field() == 1)goto _nolatch; + if(vpos == (region_scanlines() - 1) && hpos == 339 && interlace() == false)goto _nolatch; + if(vpos == region_scanlines() && interlace() == false)goto _nolatch; + if(vpos == region_scanlines() && hpos == 339)goto _nolatch; + if(vpos > region_scanlines())goto _nolatch; + if(hpos > 339)goto _nolatch; + + hpos = (hpos != 0) ? ((hpos << 2) + 14) : 10; + if(hpos >= time.line_cycles) { + hpos -= time.line_cycles; + if(++vpos >= time.frame_lines) { + vpos = 0; + } + } + + if((status.virq_enabled == true && time.v == vpos) || status.virq_enabled == false) { + time.irq_read_trigger_pos = hpos; + } else { + time.irq_read_trigger_pos = -64; + } + + hpos += 4; + if(hpos >= time.line_cycles) { + hpos -= time.line_cycles; + if(++vpos >= time.frame_lines) { + vpos = 0; + } + } + + if((status.virq_enabled == true && time.v == vpos) || status.virq_enabled == false) { + time.irq_line_trigger_pos = hpos; + } else { + time.irq_line_trigger_pos = -64; + } + + return; + +_nolatch: + time.irq_read_trigger_pos = -64; + time.irq_line_trigger_pos = -64; +} + +void bCPU::update_interrupts() { + update_nmi(); + update_irq(); +} + +void bCPU::poll_interrupts(int cycles) { +int16 hc, hc_end; + if(time.hc == 0) { + hc = -1; + hc_end = cycles; + } else { + hc = time.hc; + hc_end = time.hc + cycles; + } + + if(hc < time.nmi_read_trigger_pos && time.nmi_read_trigger_pos <= hc_end) { + //nmi_read can go low even with NMI interrupts disabled in $4200.d7 + time.nmi_read = 0; + } + + if(hc < time.nmi_line_trigger_pos && time.nmi_line_trigger_pos <= hc_end) { + if(status.nmi_enabled == true) { + if(time.nmi_line == 1) { + time.nmi_transition = 1; + } + time.nmi_line = 0; + } + } + + if(hc < time.irq_read_trigger_pos && time.irq_read_trigger_pos <= hc_end) { + if(status.virq_enabled == true || status.hirq_enabled == true) { + time.irq_read = 0; + } + } + + if(hc < time.irq_line_trigger_pos && time.irq_line_trigger_pos <= hc_end) { + if(status.virq_enabled == true || status.hirq_enabled == true) { + time.irq_line = 0; + time.irq_transition = 1; + } + } +} + //all scanlines are 1364 cycles long, except scanline 240 //on non-interlace odd-frames, which is 1360 cycles long. //[NTSC] @@ -68,7 +207,6 @@ void bCPU::inc_vcounter() { } } - time.hc = 0; time.dma_counter = time.line_cycles & 6; if(time.v == 240 && time.interlace == false && time.interlace_field == 1) { time.line_cycles = 1360; @@ -76,6 +214,8 @@ void bCPU::inc_vcounter() { time.line_cycles = 1364; } time.dram_refreshed = false; + + update_interrupts(); } //all dots are 4 cycles long, except dots 323 and 327. dots 323 and 327 @@ -93,16 +233,6 @@ uint16 bCPU::get_hcounter() { return (time.hc - ((time.hc > 1292) << 1) - ((time.hc > 1310) << 1)) >> 2; } -void bCPU::dram_refresh() { - time.dram_refreshed = true; - add_cycles(40); - if(time.v != 240 || time.interlace != false || time.interlace_field != 1) { - //alternate between 534 and 538 every scanline except 240ni1 - //in reality, this is probably based on frame cycle length... - time.dram_refresh_pos ^= 12; - } -} - uint32 bCPU::cycles_executed() { uint32 r = status.cycles_executed; status.cycles_executed = 0; @@ -112,28 +242,73 @@ uint32 r = status.cycles_executed; void bCPU::add_cycles(int cycles) { status.cycles_executed += cycles; - cycles >>= 1; - while(cycles--) { - time.hc += 2; + poll_interrupts(cycles); - if(time.hc >= time.line_cycles) { - inc_vcounter(); - if(time.v == 0) { - frame(); - ppu->frame(); - } - scanline(); - ppu->scanline(); + if(time.hc + cycles >= time.line_cycles) { + cycles = (time.hc + cycles) - time.line_cycles; + time.hc = 0; + + inc_vcounter(); + poll_interrupts(cycles); + + if(time.v == 0) { + frame(); + ppu->frame(); + snes->frame(); } - if(time.dram_refreshed == false && time.hc >= time.dram_refresh_pos) { - dram_refresh(); - } + scanline(); + ppu->scanline(); +// ppu->render_scanline(); + snes->scanline(); + time.line_rendered = false; + } - if(hdma_test() == true) { - hdma_run(); + if(time.line_rendered == false) { + //rendering should start at H=22, but due to inaccurate + //timing, and due to using a scanline-based renderer, use + //a higher value to allow more games to run properly... + //H=48 fixes off-by-one HDMA effects with FF6's battles + if(time.hc + cycles >= (48 * 4)) { + cycles = (time.hc + cycles) - (48 * 4); + time.hc = (48 * 4); + time.line_rendered = true; + ppu->render_scanline(); } } + + if(time.dram_refreshed == false) { + if(time.hc + cycles >= time.dram_refresh_pos) { + time.dram_refreshed = true; + status.cycles_executed += 40; + cycles = (time.hc + cycles) - time.dram_refresh_pos; + time.hc = time.dram_refresh_pos + 40; + + if(cpu_version == 2) { + if(time.v != 240 || time.interlace != false || time.interlace_field != 1) { + if(time.dram_refresh_pos == 534) { + time.dram_refresh_pos = 538; + } else { + time.dram_refresh_pos = 534; + } + } + } + } + } + + if(status.hdma_triggered == false) { + //vcounter range verified on hardware + if(time.v <= (overscan() ? 239 : 224)) { + if(time.hc + cycles >= 1112) { //278 * 4 = 1112 + cycles = (time.hc + cycles) - 1112; + time.hc = 1112; + status.hdma_triggered = true; + hdma_run(); + } + } + } + + time.hc += cycles; } void bCPU::time_reset() { @@ -150,10 +325,20 @@ void bCPU::time_reset() { time.line_cycles = 1364; time.dram_refreshed = false; - time.dram_refresh_pos = 538; + time.dram_refresh_pos = (cpu_version == 2) ? 538 : 530; time.dma_counter = 0; + time.nmi_pending = false; + time.irq_pending = false; + time.nmi_line = time.nmi_read = 1; + time.irq_line = time.irq_read = 1; + + time.nmi_transition = 0; + time.irq_transition = 0; + + update_interrupts(); + switch(region) { case NTSC: time.region_scanlines = 262; diff --git a/src/cpu/bcpu/bcpu_timing.h b/src/cpu/bcpu/bcpu_timing.h index c6fd4dd6..42a15158 100644 --- a/src/cpu/bcpu/bcpu_timing.h +++ b/src/cpu/bcpu/bcpu_timing.h @@ -4,13 +4,42 @@ struct { bool interlace, interlace_field, overscan; uint16 line_cycles, frame_lines; + bool line_rendered; + bool dram_refreshed; uint16 dram_refresh_pos; uint8 dma_counter; uint16 region_scanlines; -}time; + +//nmi_pending, irq_pending are used by last_cycle() +//nmi_line = /NMI, nmi_read = $4210.7 +//irq_line = /IRQ, irq_read = $4211.7 + bool nmi_pending, nmi_line, nmi_read; + bool irq_pending, irq_line, irq_read; + +//NMI is edge-sensitive, meaning it triggers when /NMI +//transitions from high to low. This value is set to 1 +//when that happens, and cleared after the nmi_test() +//routine acknowledges it and invokes the NMI interrupt + bool nmi_transition; + +//IRQ is level-sensitive, so it does not need to keep +//track of transitions from high to low. IRQs will +//continue to fire as long as /IRQ stays low. +//However, if a write to $4200 forces IRQs high at the +//exact same clock cycle that /IRQ goes low, the /IRQ +//will still occur. Hence the need for this variable. + bool irq_transition; + +//position is relative to time.hc, set at start of each scanline +//-64 means no trigger point on this scanline +//$4210/$4211 status bits get set before /NMI and /IRQ go low, +//hence the need for two variables for each. + int32 nmi_read_trigger_pos, nmi_line_trigger_pos; + int32 irq_read_trigger_pos, irq_line_trigger_pos; +} time; inline uint16 vcounter(); inline uint16 hcounter(); @@ -20,6 +49,14 @@ inline bool interlace_field(); inline bool overscan(); inline uint16 region_scanlines(); +inline bool nmi_trigger_pos_match(uint32 offset); +inline bool irq_trigger_pos_match(uint32 offset); + +inline void update_nmi(); +inline void update_irq(); +inline void update_interrupts(); +inline void poll_interrupts(int cycles); + inline void set_interlace(bool r); inline void set_overscan (bool r); @@ -27,6 +64,5 @@ inline uint8 dma_counter(); inline void inc_vcounter(); inline uint16 get_hcounter(); -inline void dram_refresh(); inline void add_cycles(int cycles); inline void time_reset(); diff --git a/src/cpu/bcpu/bcpugen.cpp b/src/cpu/bcpu/bcpugen.cpp index 9f49452f..d5406c9a 100644 --- a/src/cpu/bcpu/bcpugen.cpp +++ b/src/cpu/bcpu/bcpugen.cpp @@ -53,7 +53,6 @@ char t[4096]; void update_line(int i, int n) { char t[4096]; - sprintf(t, "goto l%d;", n + 2); replace(line[i], "end;", "status.cycle_pos = 0;"); replace(line[i], "skip;", "status.cycle_pos++;"); } @@ -88,7 +87,11 @@ char t[4096]; i++; } - if(!strcmp(line[i], "}"))strcat(output_op, " status.cycle_pos = 0;\r\n"); + + if(!strcmp(line[i], "}")) { + strcat(output_op, " status.cycle_pos = 0;\r\n"); + } + strcat(output_op, " break;\r\n"); } strcat(output_op, " }\r\n}"); diff --git a/src/cpu/bcpu/bcpugen.exe b/src/cpu/bcpu/bcpugen.exe deleted file mode 100644 index db34eb920d8555e4bf7874e1624e9a7ef073ab13..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53248 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 1; @@ -59,7 +63,8 @@ lsr(0x4a) { } rol(0x2a) { -1:cpu_io(); +1:last_cycle(); + cpu_io(); uint16 c = regs.p.c; if(regs.p.m) { regs.p.c = !!(regs.a.l & 0x80); @@ -77,7 +82,8 @@ rol(0x2a) { } ror(0x6a) { -1:cpu_io(); +1:last_cycle(); + cpu_io(); uint16 c; if(regs.p.m) { c = (regs.p.c)?0x80:0; @@ -113,7 +119,8 @@ tsb_addr(0x0c, tsb) { if(regs.p.m) { op_$1_b(); skip; } else op_$1_w(); 6:op_write(OPMODE_DBR, aa.w + 1, rd.h); -7:op_write(OPMODE_DBR, aa.w, rd.l); +7:last_cycle(); + op_write(OPMODE_DBR, aa.w, rd.l); } inc_addrx(0xfe, inc), @@ -132,7 +139,8 @@ ror_addrx(0x7e, ror) { if(regs.p.m) { op_$1_b(); skip; } else op_$1_w(); 7:op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h); -8:op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); +8:last_cycle(); + op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); } inc_dp(0xe6, inc), @@ -152,7 +160,8 @@ tsb_dp(0x04, tsb) { if(regs.p.m) { op_$1_b(); skip; } else op_$1_w(); 6:op_write(OPMODE_DP, dp + 1, rd.h); -7:op_write(OPMODE_DP, dp, rd.l); +7:last_cycle(); + op_write(OPMODE_DP, dp, rd.l); } inc_dpx(0xf6, inc), @@ -171,5 +180,6 @@ ror_dpx(0x76, ror) { if(regs.p.m) { op_$1_b(); skip; } else op_$1_w(); 7:op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h); -8:op_write(OPMODE_DP, dp + regs.x.w, rd.l); +8:last_cycle(); + op_write(OPMODE_DP, dp + regs.x.w, rd.l); } diff --git a/src/cpu/bcpu/op_write.b b/src/cpu/bcpu/op_write.b index e1ba5c14..527e1505 100644 --- a/src/cpu/bcpu/op_write.b +++ b/src/cpu/bcpu/op_write.b @@ -4,9 +4,11 @@ sty_addr(0x8c, regs.p.x, regs.y.w), stz_addr(0x9c, regs.p.m, 0x0000) { 1:aa.l = op_read(); 2:aa.h = op_read(); -3:op_write(OPMODE_DBR, aa.w, $2); +3:if($1)last_cycle(); + op_write(OPMODE_DBR, aa.w, $2); if($1)end; -4:op_write(OPMODE_DBR, aa.w + 1, $2 >> 8); +4:last_cycle(); + op_write(OPMODE_DBR, aa.w + 1, $2 >> 8); } sta_addrx(0x9d, regs.p.m, regs.a.w), @@ -14,36 +16,44 @@ stz_addrx(0x9e, regs.p.m, 0x0000) { 1:aa.l = op_read(); 2:aa.h = op_read(); 3:cpu_c4(aa.w, aa.w + regs.x.w); -4:op_write(OPMODE_DBR, aa.w + regs.x.w, $2); +4:if($1)last_cycle(); + op_write(OPMODE_DBR, aa.w + regs.x.w, $2); if($1)end; -5:op_write(OPMODE_DBR, aa.w + regs.x.w + 1, $2 >> 8); +5:last_cycle(); + op_write(OPMODE_DBR, aa.w + regs.x.w + 1, $2 >> 8); } sta_addry(0x99) { 1:aa.l = op_read(); 2:aa.h = op_read(); 3:cpu_c4(aa.w, aa.w + regs.y.w); -4:op_write(OPMODE_DBR, aa.w + regs.y.w, regs.a.l); +4:if(regs.p.m)last_cycle(); + op_write(OPMODE_DBR, aa.w + regs.y.w, regs.a.l); if(regs.p.m)end; -5:op_write(OPMODE_DBR, aa.w + regs.y.w + 1, regs.a.h); +5:last_cycle(); + op_write(OPMODE_DBR, aa.w + regs.y.w + 1, regs.a.h); } sta_long(0x8f) { 1:aa.l = op_read(); 2:aa.h = op_read(); 3:aa.b = op_read(); -4:op_write(OPMODE_LONG, aa.d, regs.a.l); +4:if(regs.p.m)last_cycle(); + op_write(OPMODE_LONG, aa.d, regs.a.l); if(regs.p.m)end; -5:op_write(OPMODE_LONG, aa.d + 1, regs.a.h); +5:last_cycle(); + op_write(OPMODE_LONG, aa.d + 1, regs.a.h); } sta_longx(0x9f) { 1:aa.l = op_read(); 2:aa.h = op_read(); 3:aa.b = op_read(); -4:op_write(OPMODE_LONG, aa.d + regs.x.w, regs.a.l); +4:if(regs.p.m)last_cycle(); + op_write(OPMODE_LONG, aa.d + regs.x.w, regs.a.l); if(regs.p.m)end; -5:op_write(OPMODE_LONG, aa.d + regs.x.w + 1, regs.a.h); +5:last_cycle(); + op_write(OPMODE_LONG, aa.d + regs.x.w + 1, regs.a.h); } sta_dp(0x85, regs.p.m, regs.a.w), @@ -52,9 +62,11 @@ sty_dp(0x84, regs.p.x, regs.y.w), stz_dp(0x64, regs.p.m, 0x0000) { 1:dp = op_read(); 2:cpu_c2(); -3:op_write(OPMODE_DP, dp, $2); +3:if($1)last_cycle(); + op_write(OPMODE_DP, dp, $2); if($1)end; -4:op_write(OPMODE_DP, dp + 1, $2 >> 8); +4:last_cycle(); + op_write(OPMODE_DP, dp + 1, $2 >> 8); } sta_dpx(0x95, regs.p.m, regs.a.w), @@ -63,18 +75,22 @@ stz_dpx(0x74, regs.p.m, 0x0000) { 1:dp = op_read(); 2:cpu_c2(); 3:cpu_io(); -4:op_write(OPMODE_DP, dp + regs.x.w, $2); +4:if($1)last_cycle(); + op_write(OPMODE_DP, dp + regs.x.w, $2); if($1)end; -5:op_write(OPMODE_DP, dp + regs.x.w + 1, $2 >> 8); +5:last_cycle(); + op_write(OPMODE_DP, dp + regs.x.w + 1, $2 >> 8); } stx_dpy(0x96) { 1:dp = op_read(); 2:cpu_c2(); 3:cpu_io(); -4:op_write(OPMODE_DP, dp + regs.y.w, regs.x.l); +4:if(regs.p.x)last_cycle(); + op_write(OPMODE_DP, dp + regs.y.w, regs.x.l); if(regs.p.x)end; -5:op_write(OPMODE_DP, dp + regs.y.w + 1, regs.x.h); +5:last_cycle(); + op_write(OPMODE_DP, dp + regs.y.w + 1, regs.x.h); } sta_idp(0x92) { @@ -82,9 +98,11 @@ sta_idp(0x92) { 2:cpu_c2(); 3:aa.l = op_read(OPMODE_DP, dp); 4:aa.h = op_read(OPMODE_DP, dp + 1); -5:op_write(OPMODE_DBR, aa.w, regs.a.l); +5:if(regs.p.m)last_cycle(); + op_write(OPMODE_DBR, aa.w, regs.a.l); if(regs.p.m)end; -6:op_write(OPMODE_DBR, aa.w + 1, regs.a.h); +6:last_cycle(); + op_write(OPMODE_DBR, aa.w + 1, regs.a.h); } sta_ildp(0x87) { @@ -93,9 +111,11 @@ sta_ildp(0x87) { 3:aa.l = op_read(OPMODE_DP, dp); 4:aa.h = op_read(OPMODE_DP, dp + 1); 5:aa.b = op_read(OPMODE_DP, dp + 2); -6:op_write(OPMODE_LONG, aa.d, regs.a.l); +6:if(regs.p.m)last_cycle(); + op_write(OPMODE_LONG, aa.d, regs.a.l); if(regs.p.m)end; -7:op_write(OPMODE_LONG, aa.d + 1, regs.a.h); +7:last_cycle(); + op_write(OPMODE_LONG, aa.d + 1, regs.a.h); } sta_idpx(0x81) { @@ -104,9 +124,11 @@ sta_idpx(0x81) { 3:cpu_io(); 4:aa.l = op_read(OPMODE_DP, dp + regs.x.w); 5:aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); -6:op_write(OPMODE_DBR, aa.w, regs.a.l); +6:if(regs.p.m)last_cycle(); + op_write(OPMODE_DBR, aa.w, regs.a.l); if(regs.p.m)end; -7:op_write(OPMODE_DBR, aa.w + 1, regs.a.h); +7:last_cycle(); + op_write(OPMODE_DBR, aa.w + 1, regs.a.h); } sta_idpy(0x91) { @@ -115,9 +137,11 @@ sta_idpy(0x91) { 3:aa.l = op_read(OPMODE_DP, dp); 4:aa.h = op_read(OPMODE_DP, dp + 1); 5:cpu_c4(aa.w, aa.w + regs.y.w); -6:op_write(OPMODE_DBR, aa.w + regs.y.w, regs.a.l); +6:if(regs.p.m)last_cycle(); + op_write(OPMODE_DBR, aa.w + regs.y.w, regs.a.l); if(regs.p.m)end; -7:op_write(OPMODE_DBR, aa.w + regs.y.w + 1, regs.a.h); +7:last_cycle(); + op_write(OPMODE_DBR, aa.w + regs.y.w + 1, regs.a.h); } sta_ildpy(0x97) { @@ -126,17 +150,21 @@ sta_ildpy(0x97) { 3:aa.l = op_read(OPMODE_DP, dp); 4:aa.h = op_read(OPMODE_DP, dp + 1); 5:aa.b = op_read(OPMODE_DP, dp + 2); -6:op_write(OPMODE_LONG, aa.d + regs.y.w, regs.a.l); +6:if(regs.p.m)last_cycle(); + op_write(OPMODE_LONG, aa.d + regs.y.w, regs.a.l); if(regs.p.m)end; -7:op_write(OPMODE_LONG, aa.d + regs.y.w + 1, regs.a.h); +7:last_cycle(); + op_write(OPMODE_LONG, aa.d + regs.y.w + 1, regs.a.h); } sta_sr(0x83) { 1:sp = op_read(); 2:cpu_io(); -3:op_write(OPMODE_SP, sp, regs.a.l); +3:if(regs.p.m)last_cycle(); + op_write(OPMODE_SP, sp, regs.a.l); if(regs.p.m)end; -4:op_write(OPMODE_SP, sp + 1, regs.a.h); +4:last_cycle(); + op_write(OPMODE_SP, sp + 1, regs.a.h); } sta_isry(0x93) { @@ -145,7 +173,9 @@ sta_isry(0x93) { 3:aa.l = op_read(OPMODE_SP, sp); 4:aa.h = op_read(OPMODE_SP, sp + 1); 5:cpu_io(); -6:op_write(OPMODE_DBR, aa.w + regs.y.w, regs.a.l); +6:if(regs.p.m)last_cycle(); + op_write(OPMODE_DBR, aa.w + regs.y.w, regs.a.l); if(regs.p.m)end; -7:op_write(OPMODE_DBR, aa.w + regs.y.w + 1, regs.a.h); +7:last_cycle(); + op_write(OPMODE_DBR, aa.w + regs.y.w + 1, regs.a.h); } diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 6c43bc68..2bec94aa 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -2,5 +2,6 @@ #include "dcpu.cpp" CPU::CPU() { + cpu_version = 2; mmio = &mmio_unmapped; } diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 9d1a01f5..f249338c 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -2,6 +2,12 @@ class CPU { public: +//CPU version number +//* 1 and 2 are known +//* reported by $4210 +//* affects DRAM refresh behavior +uint8 cpu_version; + //timing virtual uint16 vcounter() = 0; virtual uint16 hcounter() = 0; @@ -9,7 +15,6 @@ public: virtual bool interlace() = 0; virtual bool interlace_field() = 0; virtual bool overscan() = 0; - virtual void set_interlace(bool r) = 0; virtual void set_overscan (bool r) = 0; diff --git a/src/dsp/bdsp/bdsp.cpp b/src/dsp/bdsp/bdsp.cpp new file mode 100644 index 00000000..abd1e944 --- /dev/null +++ b/src/dsp/bdsp/bdsp.cpp @@ -0,0 +1,583 @@ +#include "../../base.h" +#include "bdsp_tables.cpp" + +uint8 bDSP::read_8 (uint16 addr) { return (spcram[addr]); } +uint16 bDSP::read_16 (uint16 addr) { return (spcram[(addr + 1) & 0xffff] << 8) + (spcram[addr]); } +void bDSP::write_8 (uint16 addr, uint8 data) { spcram[addr] = data; } +void bDSP::write_16(uint16 addr, uint16 data) { spcram[addr++] = data; spcram[addr] = data >> 8; } + +uint8 bDSP::read(uint8 addr) { +int i, v, n; + addr &= 127; + v = addr >> 4; + n = addr & 15; + + switch(addr) { + case 0x00:case 0x10:case 0x20:case 0x30: + case 0x40:case 0x50:case 0x60:case 0x70: + return voice[v].VOLL; + case 0x01:case 0x11:case 0x21:case 0x31: + case 0x41:case 0x51:case 0x61:case 0x71: + return voice[v].VOLR; + case 0x02:case 0x12:case 0x22:case 0x32: + case 0x42:case 0x52:case 0x62:case 0x72: + return voice[v].PITCH >> 8; + case 0x03:case 0x13:case 0x23:case 0x33: + case 0x43:case 0x53:case 0x63:case 0x73: + return voice[v].PITCH; + case 0x04:case 0x14:case 0x24:case 0x34: + case 0x44:case 0x54:case 0x64:case 0x74: + return voice[v].SRCN; + case 0x05:case 0x15:case 0x25:case 0x35: + case 0x45:case 0x55:case 0x65:case 0x75: + return voice[v].ADSR1; + case 0x06:case 0x16:case 0x26:case 0x36: + case 0x46:case 0x56:case 0x66:case 0x76: + return voice[v].ADSR2; + case 0x07:case 0x17:case 0x27:case 0x37: + case 0x47:case 0x57:case 0x67:case 0x77: + return voice[v].GAIN; + case 0x08:case 0x18:case 0x28:case 0x38: + case 0x48:case 0x58:case 0x68:case 0x78: + return voice[v].ENVX; + case 0x09:case 0x19:case 0x29:case 0x39: + case 0x49:case 0x59:case 0x69:case 0x79: + return voice[v].OUTX; + + case 0x0f:case 0x1f:case 0x2f:case 0x3f: + case 0x4f:case 0x5f:case 0x6f:case 0x7f: + return status.FIR[v]; + + case 0x0c:return status.MVOLL; + case 0x1c:return status.MVOLR; + case 0x2c:return status.EVOLL; + case 0x3c:return status.EVOLR; + case 0x4c:return status.KON; + case 0x5c:return status.KOFF; + case 0x6c:return status.FLG; + case 0x7c:return status.ENDX; + + case 0x0d:return status.EFB; + case 0x2d:return status.PMON; + case 0x3d:return status.NON; + case 0x4d:return status.EON; + case 0x5d:return status.DIR; + case 0x6d:return status.ESA; + case 0x7d:return status.EDL; + } + + return dspram[addr]; +} + +void bDSP::write(uint8 addr, uint8 data) { +int i, v, n; +//0x80-0xff is a read-only mirror of 0x00-0x7f + if(addr & 0x80)return; + + v = addr >> 4; + n = addr & 15; + + switch(addr) { + case 0x00:case 0x10:case 0x20:case 0x30: + case 0x40:case 0x50:case 0x60:case 0x70: + voice[v].VOLL = data; + break; + case 0x01:case 0x11:case 0x21:case 0x31: + case 0x41:case 0x51:case 0x61:case 0x71: + voice[v].VOLR = data; + break; + case 0x02:case 0x12:case 0x22:case 0x32: + case 0x42:case 0x52:case 0x62:case 0x72: + voice[v].PITCH &= 0xff00; + voice[v].PITCH |= data; + break; + case 0x03:case 0x13:case 0x23:case 0x33: + case 0x43:case 0x53:case 0x63:case 0x73: + voice[v].PITCH &= 0x00ff; + voice[v].PITCH |= data << 8; + break; + case 0x04:case 0x14:case 0x24:case 0x34: + case 0x44:case 0x54:case 0x64:case 0x74: + //voice[v].SRCN = data; + //below is anomie's code, but TRAC says writing SRCN doesn't affect anything until a + //BRR-with-end block is encountered, where it loads the loop address from the new SRCN + if(voice[v].SRCN != data) { + voice[v].SRCN = data; + voice[v].brr_ptr = read_16((status.DIR << 8) + (voice[v].SRCN << 2) + ((voice[v].brr_looped)?2:0)); + voice[v].brr_index = 0; + } + break; + case 0x05:case 0x15:case 0x25:case 0x35: + case 0x45:case 0x55:case 0x65:case 0x75: + voice[v].ADSR1 = data; + voice[v].AdjustEnvelope(); + break; + case 0x06:case 0x16:case 0x26:case 0x36: + case 0x46:case 0x56:case 0x66:case 0x76: + voice[v].ADSR2 = data; + //sustain_level = 0-7, 7 is a special case handled by ATTACK envx mode + voice[v].env_sustain = (voice[v].ADSR_sus_level() + 1) << 8; + voice[v].AdjustEnvelope(); + break; + case 0x07:case 0x17:case 0x27:case 0x37: + case 0x47:case 0x57:case 0x67:case 0x77: + voice[v].GAIN = data; + voice[v].AdjustEnvelope(); + break; + case 0x08:case 0x18:case 0x28:case 0x38: + case 0x48:case 0x58:case 0x68:case 0x78: + voice[v].ENVX = data; + break; + case 0x09:case 0x19:case 0x29:case 0x39: + case 0x49:case 0x59:case 0x69:case 0x79: + voice[v].OUTX = data; + break; + + case 0x0f:case 0x1f:case 0x2f:case 0x3f: + case 0x4f:case 0x5f:case 0x6f:case 0x7f: + status.FIR[v] = data; + break; + + case 0x0c:status.MVOLL = data;break; + case 0x1c:status.MVOLR = data;break; + case 0x2c:status.EVOLL = data;break; + case 0x3c:status.EVOLR = data;break; + + case 0x4c: + status.KON = data; + status.kon = data; + status.key_flag = true; + break; + + case 0x5c: + status.KOFF = data; + status.key_flag = true; + break; + + case 0x6c: + status.FLG = data; + status.key_flag = true; + status.noise_rate = RateTable[data & 0x1f]; + break; + + case 0x7c: + //read-only register, writes clear all bits of ENDX + status.ENDX = 0; + break; + + case 0x0d:status.EFB = data;break; + case 0x2d:status.PMON = data;break; + case 0x3d:status.NON = data;break; + case 0x4d:status.EON = data;break; + case 0x5d:status.DIR = data;break; + case 0x6d:status.ESA = data;break; + + case 0x7d: + status.EDL = data; + status.echo_size = (data & 0x0f) << 11; + break; + } + + dspram[addr] = data; +} + +void bDSP::power() { +int v; + spcram = apu->get_spcram_handle(); + memset(dspram, 0x00, 128); + + for(v=0;v<8;v++) { + voice[v].VOLL = 0; + voice[v].VOLR = 0; + voice[v].PITCH = 0; + voice[v].SRCN = 0; + voice[v].ADSR1 = 0; + voice[v].ADSR2 = 0; + voice[v].GAIN = 0; + + status.FIR[v] = 0; + } + + status.MVOLL = status.MVOLR = 0; + status.EVOLL = status.EVOLR = 0; + status.ENDX = 0; + status.EFB = 0; + status.PMON = 0; + status.NON = 0; + status.EON = 0; + status.DIR = 0; + status.ESA = 0; + status.EDL = 0; + + status.echo_size = 0; + status.echo_target = 0; + + reset(); +} + +void bDSP::reset() { +int v; + status.KON = 0x00; + status.KOFF = 0x00; + status.FLG |= 0xe0; + + status.kon = 0x00; + status.key_flag = false; + + status.noise_ctr = 0; + status.noise_rate = 0; + status.noise_sample = 0x4000; + + status.echo_index = 0; + status.fir_buffer_index = 0; + + for(v=0;v<8;v++) { + voice[v].ENVX = 0; + voice[v].OUTX = 0; + + voice[v].pitch_ctr = 0; + + voice[v].brr_index = 0; + voice[v].brr_ptr = read_16((status.DIR << 8) + (voice[v].SRCN << 2)); + voice[v].brr_looped = false; + voice[v].brr_data[0] = 0; + voice[v].brr_data[1] = 0; + voice[v].brr_data[2] = 0; + voice[v].brr_data[3] = 0; + voice[v].brr_data_index = 0; + + voice[v].envx = 0; + voice[v].env_ctr = 0; + voice[v].env_rate = 0; + voice[v].env_state = SILENCE; + voice[v].env_mode = DIRECT; + + status.fir_buffer[0][v] = 0; + status.fir_buffer[1][v] = 0; + } + + dsp_counter = 0; +} + +int32 bDSP::clamp(int32 bits, int32 x) { +int32 b = 1 << (bits - 1); + if(x > (b - 1)) { + return (b - 1); + } else if(x < -b) { + return -b; + } else { + return x; + } +} + +int32 bDSP::clip(int32 bits, int32 x) { +int32 b = 1 << (bits - 1); + if(x & b) { + return x | ~(b - 1); + } else { + return x & (b - 1); + } +} + +uint32 bDSP::run() { +int v, d; +uint8 pmon; +int32 sample; +int32 msamplel, msampler; +int32 esamplel, esampler; +int32 fir_samplel, fir_sampler; + pmon = status.PMON & ~status.NON & ~1; + + if(!(dsp_counter++ & 1) && status.key_flag) { + for(v=0;v<8;v++) { + if(status.soft_reset()) { + if(voice[v].env_state != SILENCE) { + voice[v].env_state = SILENCE; + voice[v].AdjustEnvelope(); + } + } else if(status.KOFF & (1 << v)) { + if(voice[v].env_state != SILENCE && voice[v].env_state != RELEASE) { + voice[v].env_state = RELEASE; + voice[v].AdjustEnvelope(); + } + } else if(status.kon & (1 << v)) { + voice[v].brr_ptr = read_16((status.DIR << 8) + (voice[v].SRCN << 2)); + voice[v].brr_index = -9; + voice[v].brr_looped = false; + voice[v].brr_data[0] = 0; + voice[v].brr_data[1] = 0; + voice[v].brr_data[2] = 0; + voice[v].brr_data[3] = 0; + voice[v].envx = 0; + voice[v].env_state = ATTACK; + voice[v].AdjustEnvelope(); + } + } + status.ENDX &= ~status.kon; + status.kon = 0; + status.key_flag = false; + } + +//update noise + status.noise_ctr += status.noise_rate; + if(status.noise_ctr >= 0x7800) { + status.noise_ctr -= 0x7800; + status.noise_sample = (status.noise_sample >> 1) | + (((status.noise_sample << 14) ^ (status.noise_sample << 13)) & 0x4000); + } + + msamplel = msampler = 0; + esamplel = esampler = 0; + + for(v=0;v<8;v++) { + if(voice[v].brr_index < -1) { + voice[v].brr_index++; + voice[v].OUTX = voice[v].outx = 0; + voice[v].ENVX = 0; + continue; + } + + if(voice[v].brr_index >= 0) { + if(pmon & (1 << v)) { + voice[v].pitch_ctr += (voice[v].pitch_rate() * (voice[v - 1].outx + 0x8000)) >> 15; + } else { + voice[v].pitch_ctr += voice[v].pitch_rate(); + } + } else { + voice[v].pitch_ctr = 0x3000; + voice[v].brr_index = 0; + } + + //decode BRR samples + while(voice[v].pitch_ctr >= 0) { + voice[v].pitch_ctr -= 0x1000; + + voice[v].brr_data_index++; + voice[v].brr_data_index &= 3; + + if(voice[v].brr_index == 0) { + voice[v].brr_header = read_8(voice[v].brr_ptr); + + if(voice[v].brr_header_flags() & BRR_END) { + status.ENDX |= (1 << v); + } + + if(voice[v].brr_header_flags() == BRR_END) { + voice[v].env_state = SILENCE; + voice[v].AdjustEnvelope(); + } + } + +#define S(x) voice[v].brr_data[(voice[v].brr_data_index + (x)) & 3] + if(voice[v].env_state != SILENCE) { + sample = read_8(voice[v].brr_ptr + 1 + (voice[v].brr_index >> 1)); + if(voice[v].brr_index & 1) { + sample = clip(4, sample); + } else { + sample = clip(4, sample >> 4); + } + + if(voice[v].brr_header_shift() <= 12) { + sample = (sample << voice[v].brr_header_shift() >> 1); + } else { + sample &= ~0x7ff; + } + + switch(voice[v].brr_header_filter()) { + case 0: //direct + break; + case 1: //15/16 + sample += S(-1) + ((-S(-1)) >> 4); + break; + case 2: //61/32 - 15/16 + sample += (S(-1) << 1) + ((-((S(-1) << 1) + S(-1))) >> 5) + - S(-2) + (S(-2) >> 4); + break; + case 3: //115/64 - 13/16 + sample += (S(-1) << 1) + ((-(S(-1) + (S(-1) << 2) + (S(-1) << 3))) >> 6) + - S(-2) + (((S(-2) << 1) + S(-2)) >> 4); + break; + } + + S(0) = sample = clip(15, clamp(16, sample)); + } else { + S(0) = sample = 0; + } + + if(++voice[v].brr_index > 15) { + voice[v].brr_index = 0; + if(voice[v].brr_header_flags() & BRR_END) { + voice[v].brr_ptr = read_16((status.DIR << 8) + (voice[v].SRCN << 2) + 2); + voice[v].brr_looped = true; + } else { + voice[v].brr_ptr += 9; + } + } + } + + //volume envelope adjust + voice[v].env_ctr += voice[v].env_rate; + + if(voice[v].env_ctr >= 0x7800) { + voice[v].env_ctr -= 0x7800; + switch(voice[v].env_mode) { + case DIRECT: + voice[v].env_rate = 0; + break; + case LINEAR_DEC: + voice[v].envx -= 32; + if(voice[v].envx <= 0) { + voice[v].envx = 0; + voice[v].env_rate = 0; + voice[v].env_mode = DIRECT; + } + break; + case LINEAR_INC: + voice[v].envx += 32; + if(voice[v].envx >= 0x7ff) { + voice[v].envx = 0x7ff; + voice[v].env_rate = 0; + voice[v].env_mode = DIRECT; + if(voice[v].ADSR_enabled() && voice[v].env_state == ATTACK) { + voice[v].env_state = ((voice[v].env_sustain == 0x800) ? SUSTAIN : DECAY); + voice[v].AdjustEnvelope(); + } + } + break; + case EXP_DEC: + //multiply by 255/256ths + voice[v].envx -= ((voice[v].envx - 1) >> 8) + 1; + if(voice[v].ADSR_enabled() && voice[v].env_state == DECAY && voice[v].envx <= voice[v].env_sustain) { + voice[v].env_state = SUSTAIN; + voice[v].AdjustEnvelope(); + } else if(voice[v].envx <= 0) { + voice[v].envx = 0; + voice[v].env_rate = 0; + voice[v].env_mode = DIRECT; + } + break; + case BENT_INC: + if(voice[v].envx < 0x600) { + voice[v].envx += 32; + } else { + voice[v].envx += 8; + + if(voice[v].envx >= 0x7ff) { + voice[v].envx = 0x7ff; + voice[v].env_rate = 0; + voice[v].env_mode = DIRECT; + } + } + break; + case FAST_ATTACK: + voice[v].envx += 0x400; + if(voice[v].envx >= 0x7ff) { + voice[v].envx = 0x7ff; + + //attack raises to max. envx, if sustain is also set to max. envx, skip decay phase + voice[v].env_state = ((voice[v].env_sustain == 0x800) ? SUSTAIN : DECAY); + voice[v].AdjustEnvelope(); + } + break; + case RELEASE_DEC: + voice[v].envx -= 8; + if(voice[v].envx <= 0) { + voice[v].env_state = SILENCE; + voice[v].AdjustEnvelope(); + } + break; + } + } + + voice[v].ENVX = voice[v].envx >> 4; + + //gaussian interpolation / noise + if(status.NON & (1 << v)) { + sample = status.noise_sample; + } else { + d = voice[v].pitch_ctr >> 4; //-256 <= sample <= -1 + sample = ((GaussTable[ -1-d] * S(-3)) >> 11); + sample += ((GaussTable[255-d] * S(-2)) >> 11); + sample += ((GaussTable[512+d] * S(-1)) >> 11); + sample = clip (15, sample); + sample += ((GaussTable[256+d] * S( 0)) >> 11); + sample = clamp(15, sample); + } +#undef S + + //envelope / volume adjust + sample = (sample * voice[v].envx) >> 11; + voice[v].outx = sample << 1; + voice[v].OUTX = sample >> 7; + + if(!status.mute()) { + msamplel += ((sample * voice[v].VOLL) >> 7) << 1; + msampler += ((sample * voice[v].VOLR) >> 7) << 1; + } + + if((status.EON & (1 << v)) && status.echo_write()) { + esamplel += ((sample * voice[v].VOLL) >> 7) << 1; + esampler += ((sample * voice[v].VOLR) >> 7) << 1; + } + } + +//echo (FIR) adjust +#define F(c,x) status.fir_buffer[c][(status.fir_buffer_index+(x)) & 7] + status.fir_buffer_index++; + F(0,0) = read_16((status.ESA << 8) + status.echo_index); + F(1,0) = read_16((status.ESA << 8) + status.echo_index + 2); + + fir_samplel = (F(0,-0) * status.FIR[7] + + F(0,-1) * status.FIR[6] + + F(0,-2) * status.FIR[5] + + F(0,-3) * status.FIR[4] + + F(0,-4) * status.FIR[3] + + F(0,-5) * status.FIR[2] + + F(0,-6) * status.FIR[1] + + F(0,-7) * status.FIR[0]); + + fir_sampler = (F(1,-0) * status.FIR[7] + + F(1,-1) * status.FIR[6] + + F(1,-2) * status.FIR[5] + + F(1,-3) * status.FIR[4] + + F(1,-4) * status.FIR[3] + + F(1,-5) * status.FIR[2] + + F(1,-6) * status.FIR[1] + + F(1,-7) * status.FIR[0]); +#undef F + +//update echo buffer + if(status.echo_write()) { + esamplel += (fir_samplel * status.EFB) >> 14; + esampler += (fir_sampler * status.EFB) >> 14; + + esamplel = clamp(16, esamplel); + esampler = clamp(16, esampler); + + write_16((status.ESA << 8) + status.echo_index, esamplel); + write_16((status.ESA << 8) + status.echo_index + 2, esampler); + } + + status.echo_index += 4; + if(status.echo_index >= status.echo_target) { + status.echo_index = 0; + status.echo_target = status.echo_size; + } + +//main output adjust + if(!status.mute()) { + msamplel = (msamplel * status.MVOLL) >> 7; + msampler = (msampler * status.MVOLR) >> 7; + + msamplel += (fir_samplel * status.EVOLL) >> 14; + msampler += (fir_sampler * status.EVOLR) >> 14; + + msamplel = clamp(16, msamplel); + msampler = clamp(16, msampler); + } + + return (uint32)(((uint16)msamplel) | ((uint16)msampler << 16)); +} + +bDSP::bDSP() {} +bDSP::~bDSP() {} diff --git a/src/dsp/bdsp/bdsp.h b/src/dsp/bdsp/bdsp.h new file mode 100644 index 00000000..40eb6849 --- /dev/null +++ b/src/dsp/bdsp/bdsp.h @@ -0,0 +1,176 @@ +class bDSP : public DSP { +private: +uint8 dspram[128]; +uint8 *spcram; + +uint32 dsp_counter; + +enum { + BRR_END = 1, + BRR_LOOP = 2 +}; + +uint8 read_8 (uint16 addr); +uint16 read_16 (uint16 addr); +void write_8 (uint16 addr, uint8 data); +void write_16(uint16 addr, uint16 data); + +public: +static const uint16 RateTable[32]; +static const int16 GaussTable[512]; + +enum EnvelopeStates { + ATTACK, + DECAY, + SUSTAIN, + RELEASE, + SILENCE +}; + +enum EnvelopeModes { + DIRECT, + LINEAR_DEC, + EXP_DEC, + LINEAR_INC, + BENT_INC, + + FAST_ATTACK, + RELEASE_DEC +}; + +private: +struct Status { +//$0c,$1c + int8 MVOLL, MVOLR; +//$2c,$3c + int8 EVOLL, EVOLR; +//$4c,$5c + uint8 KON, KOFF; +//$6c + uint8 FLG; +//$7c + uint8 ENDX; +//$0d + int8 EFB; +//$2d,$3d,$4d + uint8 PMON, NON, EON; +//$5d + uint8 DIR; +//$6d,$7d + uint8 ESA, EDL; + +//$xf + int8 FIR[8]; + +//internal variables + uint8 kon; + bool key_flag; + + int16 noise_ctr, noise_rate; + uint16 noise_sample; + + uint16 echo_index, echo_size, echo_target; + int16 fir_buffer[2][8]; + uint8 fir_buffer_index; + +//functions + bool soft_reset() { return !!(FLG & 0x80); } + bool mute() { return !!(FLG & 0x40); } + bool echo_write() { return !(FLG & 0x20); } +} status; + +struct Voice { +//$x0-$x1 + int8 VOLL, VOLR; +//$x2-$x3 + int16 PITCH; +//$x4 + uint8 SRCN; +//$x5-$x7 + uint8 ADSR1, ADSR2, GAIN; +//$x8-$x9 + uint8 ENVX, OUTX; + +//internal variables + int16 pitch_ctr; + + int8 brr_index; + uint16 brr_ptr; + uint8 brr_header; + bool brr_looped; + + int16 brr_data[4]; + uint8 brr_data_index; + + int16 envx; + uint16 env_ctr, env_rate, env_sustain; + enum EnvelopeStates env_state; + enum EnvelopeModes env_mode; + + int16 outx; + +//functions + int16 pitch_rate() { return PITCH & 0x3fff; } + + uint8 brr_header_shift() { return brr_header >> 4; } + uint8 brr_header_filter() { return (brr_header >> 2) & 3; } + uint8 brr_header_flags() { return brr_header & 3; } + + bool ADSR_enabled() { return !!(ADSR1 & 0x80); } + uint8 ADSR_decay() { return (ADSR1 >> 4) & 7; } + uint8 ADSR_attack() { return ADSR1 & 15; } + uint8 ADSR_sus_level() { return ADSR2 >> 5; } + uint8 ADSR_sus_rate() { return ADSR2 & 31; } + + void AdjustEnvelope() { + if(env_state == SILENCE) { + env_mode = DIRECT; + env_rate = 0; + envx = 0; + } else if(env_state == RELEASE) { + env_mode = RELEASE_DEC; + env_rate = 0x7800; + } else if(ADSR_enabled()) { + switch(env_state) { + case ATTACK: + env_rate = RateTable[(ADSR_attack() << 1) + 1]; + env_mode = (env_rate == 0x7800) ? FAST_ATTACK : LINEAR_INC; + break; + case DECAY: + env_rate = RateTable[(ADSR_decay() << 1) + 0x10]; + env_mode = EXP_DEC; + break; + case SUSTAIN: + env_rate = RateTable[ADSR_sus_rate()]; + env_mode = (env_rate == 0) ? DIRECT : EXP_DEC; + break; + } + } else if(GAIN & 0x80) { + switch(GAIN & 0x60) { + case 0x00:env_mode = LINEAR_DEC; break; + case 0x20:env_mode = EXP_DEC; break; + case 0x40:env_mode = LINEAR_INC; break; + case 0x60:env_mode = BENT_INC; break; + } + env_rate = RateTable[GAIN & 0x1f]; + } else { + env_mode = DIRECT; + env_rate = 0; + envx = (GAIN & 0x7f) << 4; + } + } +} voice[8]; + + int32 clamp(int32 bits, int32 x); + int32 clip (int32 bits, int32 x); +public: + uint8 read (uint8 addr); + void write(uint8 addr, uint8 data); + + void power(); + void reset(); + uint32 run(); + + bDSP(); + ~bDSP(); +}; diff --git a/src/dsp/bdsp/bdsp_tables.cpp b/src/dsp/bdsp/bdsp_tables.cpp new file mode 100644 index 00000000..27e12904 --- /dev/null +++ b/src/dsp/bdsp/bdsp_tables.cpp @@ -0,0 +1,73 @@ +const uint16 bDSP::RateTable[32] = { + 0x0000, 0x000F, 0x0014, 0x0018, 0x001E, 0x0028, 0x0030, 0x003C, + 0x0050, 0x0060, 0x0078, 0x00A0, 0x00C0, 0x00F0, 0x0140, 0x0180, + 0x01E0, 0x0280, 0x0300, 0x03C0, 0x0500, 0x0600, 0x0780, 0x0A00, + 0x0C00, 0x0F00, 0x1400, 0x1800, 0x1E00, 0x2800, 0x3C00, 0x7800 +}; + +const int16 bDSP::GaussTable[512] = { + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, + 0x001, 0x001, 0x001, 0x002, 0x002, 0x002, 0x002, 0x002, + 0x002, 0x002, 0x003, 0x003, 0x003, 0x003, 0x003, 0x004, + 0x004, 0x004, 0x004, 0x004, 0x005, 0x005, 0x005, 0x005, + 0x006, 0x006, 0x006, 0x006, 0x007, 0x007, 0x007, 0x008, + 0x008, 0x008, 0x009, 0x009, 0x009, 0x00A, 0x00A, 0x00A, + 0x00B, 0x00B, 0x00B, 0x00C, 0x00C, 0x00D, 0x00D, 0x00E, + 0x00E, 0x00F, 0x00F, 0x00F, 0x010, 0x010, 0x011, 0x011, + 0x012, 0x013, 0x013, 0x014, 0x014, 0x015, 0x015, 0x016, + 0x017, 0x017, 0x018, 0x018, 0x019, 0x01A, 0x01B, 0x01B, + 0x01C, 0x01D, 0x01D, 0x01E, 0x01F, 0x020, 0x020, 0x021, + 0x022, 0x023, 0x024, 0x024, 0x025, 0x026, 0x027, 0x028, + 0x029, 0x02A, 0x02B, 0x02C, 0x02D, 0x02E, 0x02F, 0x030, + 0x031, 0x032, 0x033, 0x034, 0x035, 0x036, 0x037, 0x038, + 0x03A, 0x03B, 0x03C, 0x03D, 0x03E, 0x040, 0x041, 0x042, + 0x043, 0x045, 0x046, 0x047, 0x049, 0x04A, 0x04C, 0x04D, + 0x04E, 0x050, 0x051, 0x053, 0x054, 0x056, 0x057, 0x059, + 0x05A, 0x05C, 0x05E, 0x05F, 0x061, 0x063, 0x064, 0x066, + 0x068, 0x06A, 0x06B, 0x06D, 0x06F, 0x071, 0x073, 0x075, + 0x076, 0x078, 0x07A, 0x07C, 0x07E, 0x080, 0x082, 0x084, + 0x086, 0x089, 0x08B, 0x08D, 0x08F, 0x091, 0x093, 0x096, + 0x098, 0x09A, 0x09C, 0x09F, 0x0A1, 0x0A3, 0x0A6, 0x0A8, + 0x0AB, 0x0AD, 0x0AF, 0x0B2, 0x0B4, 0x0B7, 0x0BA, 0x0BC, + 0x0BF, 0x0C1, 0x0C4, 0x0C7, 0x0C9, 0x0CC, 0x0CF, 0x0D2, + 0x0D4, 0x0D7, 0x0DA, 0x0DD, 0x0E0, 0x0E3, 0x0E6, 0x0E9, + 0x0EC, 0x0EF, 0x0F2, 0x0F5, 0x0F8, 0x0FB, 0x0FE, 0x101, + 0x104, 0x107, 0x10B, 0x10E, 0x111, 0x114, 0x118, 0x11B, + 0x11E, 0x122, 0x125, 0x129, 0x12C, 0x130, 0x133, 0x137, + 0x13A, 0x13E, 0x141, 0x145, 0x148, 0x14C, 0x150, 0x153, + 0x157, 0x15B, 0x15F, 0x162, 0x166, 0x16A, 0x16E, 0x172, + 0x176, 0x17A, 0x17D, 0x181, 0x185, 0x189, 0x18D, 0x191, + 0x195, 0x19A, 0x19E, 0x1A2, 0x1A6, 0x1AA, 0x1AE, 0x1B2, + 0x1B7, 0x1BB, 0x1BF, 0x1C3, 0x1C8, 0x1CC, 0x1D0, 0x1D5, + 0x1D9, 0x1DD, 0x1E2, 0x1E6, 0x1EB, 0x1EF, 0x1F3, 0x1F8, + 0x1FC, 0x201, 0x205, 0x20A, 0x20F, 0x213, 0x218, 0x21C, + 0x221, 0x226, 0x22A, 0x22F, 0x233, 0x238, 0x23D, 0x241, + 0x246, 0x24B, 0x250, 0x254, 0x259, 0x25E, 0x263, 0x267, + 0x26C, 0x271, 0x276, 0x27B, 0x280, 0x284, 0x289, 0x28E, + 0x293, 0x298, 0x29D, 0x2A2, 0x2A6, 0x2AB, 0x2B0, 0x2B5, + 0x2BA, 0x2BF, 0x2C4, 0x2C9, 0x2CE, 0x2D3, 0x2D8, 0x2DC, + 0x2E1, 0x2E6, 0x2EB, 0x2F0, 0x2F5, 0x2FA, 0x2FF, 0x304, + 0x309, 0x30E, 0x313, 0x318, 0x31D, 0x322, 0x326, 0x32B, + 0x330, 0x335, 0x33A, 0x33F, 0x344, 0x349, 0x34E, 0x353, + 0x357, 0x35C, 0x361, 0x366, 0x36B, 0x370, 0x374, 0x379, + 0x37E, 0x383, 0x388, 0x38C, 0x391, 0x396, 0x39B, 0x39F, + 0x3A4, 0x3A9, 0x3AD, 0x3B2, 0x3B7, 0x3BB, 0x3C0, 0x3C5, + 0x3C9, 0x3CE, 0x3D2, 0x3D7, 0x3DC, 0x3E0, 0x3E5, 0x3E9, + 0x3ED, 0x3F2, 0x3F6, 0x3FB, 0x3FF, 0x403, 0x408, 0x40C, + 0x410, 0x415, 0x419, 0x41D, 0x421, 0x425, 0x42A, 0x42E, + 0x432, 0x436, 0x43A, 0x43E, 0x442, 0x446, 0x44A, 0x44E, + 0x452, 0x455, 0x459, 0x45D, 0x461, 0x465, 0x468, 0x46C, + 0x470, 0x473, 0x477, 0x47A, 0x47E, 0x481, 0x485, 0x488, + 0x48C, 0x48F, 0x492, 0x496, 0x499, 0x49C, 0x49F, 0x4A2, + 0x4A6, 0x4A9, 0x4AC, 0x4AF, 0x4B2, 0x4B5, 0x4B7, 0x4BA, + 0x4BD, 0x4C0, 0x4C3, 0x4C5, 0x4C8, 0x4CB, 0x4CD, 0x4D0, + 0x4D2, 0x4D5, 0x4D7, 0x4D9, 0x4DC, 0x4DE, 0x4E0, 0x4E3, + 0x4E5, 0x4E7, 0x4E9, 0x4EB, 0x4ED, 0x4EF, 0x4F1, 0x4F3, + 0x4F5, 0x4F6, 0x4F8, 0x4FA, 0x4FB, 0x4FD, 0x4FF, 0x500, + 0x502, 0x503, 0x504, 0x506, 0x507, 0x508, 0x50A, 0x50B, + 0x50C, 0x50D, 0x50E, 0x50F, 0x510, 0x511, 0x511, 0x512, + 0x513, 0x514, 0x514, 0x515, 0x516, 0x516, 0x517, 0x517, + 0x517, 0x518, 0x518, 0x518, 0x518, 0x518, 0x519, 0x519 +}; diff --git a/src/dsp/dsp.h b/src/dsp/dsp.h new file mode 100644 index 00000000..af495adb --- /dev/null +++ b/src/dsp/dsp.h @@ -0,0 +1,9 @@ +class DSP { +public: + virtual uint8 read (uint8 addr) = 0; + virtual void write(uint8 addr, uint8 data) = 0; + + virtual void power() = 0; + virtual void reset() = 0; + virtual uint32 run() = 0; +}; diff --git a/src/interface.h b/src/interface.h index ca3281a7..829a5f6f 100644 --- a/src/interface.h +++ b/src/interface.h @@ -1,3 +1,6 @@ +#define BSNES_VERSION "0.012" +#define BSNES_TITLE "bsnes v" BSNES_VERSION + #include "reader/reader.h" #include "memory/memory.h" @@ -14,6 +17,10 @@ extern CPU *cpu; #include "apu/bapuskip/bapuskip.h" extern APU *apu; +#include "dsp/dsp.h" +#include "dsp/bdsp/bdsp.h" +extern DSP *dsp; + #include "ppu/ppu.h" #include "ppu/bppu/bppu.h" extern PPU *ppu; @@ -26,10 +33,14 @@ extern SNES *snes; extern SRTC *srtc; extern SDD1 *sdd1; +#include "config/config.h" + #ifdef INTERFACE_MAIN +#include "config/config.cpp" MemBus *mem_bus; CPU *cpu; APU *apu; + DSP *dsp; PPU *ppu; SNES *snes; diff --git a/src/lib/libbase.h b/src/lib/libbase.h index 55648c03..b203d073 100644 --- a/src/lib/libbase.h +++ b/src/lib/libbase.h @@ -18,6 +18,8 @@ #define FALSE 0 #endif +#define zerofree(__n) if(__n) { free(__n); __n = 0; } + typedef unsigned int uint; typedef unsigned char byte; diff --git a/src/lib/libconfig.cpp b/src/lib/libconfig.cpp index f4d43221..949e7c47 100644 --- a/src/lib/libconfig.cpp +++ b/src/lib/libconfig.cpp @@ -1,273 +1,161 @@ #include "libbase.h" #include "libconfig.h" -config_item::config_item() { - strcpy(name, ""); - strcpy(strdef, ""); - is_string = false; - source = 0; - strsource = 0; - def = 0; - type = 0; +void Setting::toggle() { + data ^= 1; + set(data); } -void config::add(uint32 *variable, char *name, uint32 def, uint32 type) { -int n; - if(item_count >= 4096)return; - n = item_count; - - item[n] = new config_item(); - strcpy(item[n]->name, name); - item[n]->is_string = false; - item[n]->def = def; - item[n]->source = variable; - *item[n]->source = item[n]->def; - item[n]->type = type; - - item_count++; +uint Setting::get() { + return data; } -void config::add(string *variable, char *name, char *def, uint32 type) { -int n; - if(item_count >= 4096)return; - n = item_count; +void Setting::set(uint _data) { +printf("%s %d\n", name, _data); + data = _data; - item[n] = new config_item(); - strcpy(item[n]->name, name); - item[n]->is_string = true; - strcpy(item[n]->strdef, def); - item[n]->strsource = variable; - strcpy(*item[n]->strsource, item[n]->strdef); - item[n]->type = type; - - item_count++; -} - -uint32 config::find(char *name) { - for(int i=0;iname, name)) { - return i; - } + if(type != DEC && type != HEX) { + //data is a boolean type + data &= 1; } - return null; } -void config::load(char *fn) { +Setting::Setting(Config *_parent, char *_name, char *_desc, uint _data, uint _type) { +int s; + if(_parent) { + _parent->add(this); + } + + s = strlen(_name); + name = (char*)malloc(s + 1); + strcpy(name, _name); + + if(_desc) { + s = strlen(_desc); + desc = (char*)malloc(s + 1); + strcpy(desc, _desc); + } else { + desc = (char*)malloc(1); + *desc = 0; + } + + data = _data; + def = _data; + type = _type; +} + +void Config::add(Setting *setting) { + list[list_count++] = setting; +} + +uint Config::string_to_uint(uint type, char *input) { + if(!strcmp(input, "true") || + !strcmp(input, "enabled") || + !strcmp(input, "on") || + !strcmp(input, "yes") + ) { + return (uint)true; + } + + if(!strcmp(input, "false") || + !strcmp(input, "disabled") || + !strcmp(input, "off") || + !strcmp(input, "no") + ) { + return (uint)false; + } + + if(!strbegin(input, "0x")) { + return strhex(input + 2); + } + + return strdec(input); +} + +char *Config::uint_to_string(uint type, uint input) { +static char output[512]; + switch(type) { + case Setting::TRUE_FALSE: + sprintf(output, "%s", (input & 1)?"true":"false"); + break; + case Setting::ENABLED_DISABLED: + sprintf(output, "%s", (input & 1)?"enabled":"disabled"); + break; + case Setting::ON_OFF: + sprintf(output, "%s", (input & 1)?"on":"off"); + break; + case Setting::YES_NO: + sprintf(output, "%s", (input & 1)?"yes":"no"); + break; + case Setting::DEC: + sprintf(output, "%d", input); + break; + case Setting::HEX: + sprintf(output, "0x%x", input); + break; + } + + return output; +} + +bool Config::load(char *fn) { FILE *fp; -char *buffer; -int i, fsize; -uint32 l; fp = fopen(fn, "rb"); -//file doesn't exist yet, do nothing - if(!fp)return; + if(!fp)return false; +//load the config file into memory fseek(fp, 0, SEEK_END); - fsize = ftell(fp); +int fsize = ftell(fp); fseek(fp, 0, SEEK_SET); - -//blank file, do nothing - if(fsize == 0) { - fclose(fp); - return; - } - - buffer = (char*)malloc(fsize + 1); +char *buffer = (char*)malloc(fsize + 1); fread(buffer, 1, fsize, fp); fclose(fp); - buffer[fsize] = 0; - + *(buffer + fsize) = 0; strcpy(data, buffer); free(buffer); - replace(data, "\r\n", "\n"); - qreplace(data, "\t", " "); +//split the file into lines + replace(data, "\r\n", "\n"); + qreplace(data, "\t", ""); + qreplace(data, " ", ""); split(line, "\n", data); - for(i=0;isource = 1; - } else if(!strcmp(part[1], "false") || !strcmp(part[1], "no") || - !strcmp(part[1], "off") || !strcmp(part[1], "disabled")) { - *item[l]->source = 0; - } else if(item[l]->type == HEX) { - *item[l]->source = strhex(strptr(part[1]) + 2); //skip 0x prefix - } else { /* fall back on DEC */ - *item[l]->source = strdec(part[1]); - } + split(part, "=", line[i]); + for(int l=0;lname, part[0])) { + list[l]->set(string_to_uint(list[l]->type, strptr(part[1]))); } } } -} -void config::load(substring &fn) { load(strptr(fn)); } -//create a text string from config item[i] to be output via config->save() -void config::set_newline(int i) { -char t[16]; - if(item[i]->is_string == true) { - strcpy(newline, item[i]->name); - strcat(newline, " = \""); - strcat(newline, *item[i]->strsource); - strcat(newline, "\""); - } else { - strcpy(newline, item[i]->name); - strcat(newline, " = "); - switch(item[i]->type) { - case TRUEFALSE: - strcat(newline, (*item[i]->source)?"true":"false"); - break; - case YESNO: - strcat(newline, (*item[i]->source)?"yes":"no"); - break; - case ONOFF: - strcat(newline, (*item[i]->source)?"on":"off"); - break; - case ENABLED: - strcat(newline, (*item[i]->source)?"enabled":"disabled"); - break; - case HEX: - sprintf(t, "0x%0.2x", *item[i]->source); - strcat(newline, t); - break; - case DEC: - default: - sprintf(t, "%d", *item[i]->source); - strcat(newline, t); - break; - } - } + return true; } +bool Config::load(substring &fn) { return load(strptr(fn)); } -void config::save(char *fn) { +bool Config::save(char *fn) { FILE *fp; -int i, fsize; -uint32 l; -char *buffer; -uint8 set[4096]; -bool blank = false; - fp = fopen(fn, "rb"); - if(!fp) { - blank = true; - } else { - fseek(fp, 0, SEEK_END); - fsize = ftell(fp); - fseek(fp, 0, SEEK_SET); - - if(fsize == 0) { - blank = true; - } else { - buffer = (char*)malloc(fsize + 1); - fread(buffer, 1, fsize, fp); - buffer[fsize] = 0; - - strcpy(data, buffer); - free(buffer); - } - fclose(fp); - } - fp = fopen(fn, "wb"); -//no write access? - if(!fp)return; + if(!fp)return false; -//list of config items. if the item is set in the -//existing config file, then don't test it to see -//if it needs to be written again later on - memset(set, 0, item_count); - - if(blank == false) { + for(int i=0;idesc); replace(data, "\r\n", "\n"); - qreplace(data, "\t", " "); - - split(line, "\n", data); - split(oldline, "\n", data); - - for(i=0;itype, list[i]->def)); + fprintf(fp, "%s = %s\r\n\r\n", list[i]->name, uint_to_string(list[i]->type, list[i]->data)); } -int lines_written; - for(i=lines_written=0;i t.set(0); +#define SettingOperators(__name) \ + inline __name &operator=(const bool _data) { set((uint)_data); return *this; } \ + inline __name &operator=(const uint _data) { set(_data); return *this; } \ + inline __name &operator=(const uint8 _data) { set(_data); return *this; } \ + inline __name &operator=(const uint16 _data) { set(_data); return *this; } \ + inline __name &operator=(const uint32 _data) { set(_data); return *this; } \ + inline __name &operator=(const int _data) { set(_data); return *this; } \ + inline __name &operator=(const int8 _data) { set(_data); return *this; } \ + inline __name &operator=(const int16 _data) { set(_data); return *this; } \ + inline __name &operator=(const int32 _data) { set(_data); return *this; } \ + void toggle() { data ^= 1; set(data); } \ + __name(Config *_parent, char *_name, char *_desc = 0, uint _data = 0, uint _type = Setting::DEC) : \ + Setting(_parent, _name, _desc, _data, _type) {} + +class Setting { + friend class Config; + +protected: +uint data, type, def; -class config { -private: -uint32 item_count; -config_item *item[4096]; -string data, line, oldline, newline, part; public: enum { - TRUEFALSE = 0, - YESNO = 1, - ONOFF = 2, - ENABLED = 3, - DEC = 4, - HEX = 5, - STR = 6 + TRUE_FALSE, + ENABLED_DISABLED, + ON_OFF, + YES_NO, + BOOL, + DEC, + HEX }; - void add(uint32 *variable, char *name, uint32 def, uint32 type = DEC); - void add(string *variable, char *name, char *def, uint32 type = STR); - uint32 find(char *name); - void load(char *fn); - void load(substring &fn); - void save(char *fn); - void save(substring &fn); - void set_newline(int i); +char *name, *desc; + virtual void toggle(); + virtual uint get(); + virtual void set(uint _data); - config(); - ~config(); + Setting(Config *_parent, char *_name, char *_desc = 0, uint _data = 0, uint _type = DEC); + + inline operator bool() { return (bool)get(); } + inline operator uint() { return get(); } + inline operator uint8() { return get(); } + inline operator uint16() { return get(); } + inline operator uint32() { return get(); } + inline operator int() { return get(); } + inline operator int8() { return get(); } + inline operator int16() { return get(); } + inline operator int32() { return get(); } + + inline Setting &operator=(const bool _data) { set((uint)_data); return *this; } + inline Setting &operator=(const uint _data) { set(_data); return *this; } + inline Setting &operator=(const uint8 _data) { set(_data); return *this; } + inline Setting &operator=(const uint16 _data) { set(_data); return *this; } + inline Setting &operator=(const uint32 _data) { set(_data); return *this; } + inline Setting &operator=(const int _data) { set(_data); return *this; } + inline Setting &operator=(const int8 _data) { set(_data); return *this; } + inline Setting &operator=(const int16 _data) { set(_data); return *this; } + inline Setting &operator=(const int32 _data) { set(_data); return *this; } +}; + +class Config { +protected: +vector list; +uint list_count; + +string data, line, part, subpart; + +uint string_to_uint(uint type, char *input); +char *uint_to_string(uint type, uint input); + +public: + void add(Setting *setting); + bool load(char *fn); + bool load(substring &fn); + bool save(char *fn); + bool save(substring &fn); + Config(); }; #endif diff --git a/src/memory/bmemory/bcart_exhirom.h b/src/memory/bmemory/bcart_exhirom.h index 63b48660..d6b9b34f 100644 --- a/src/memory/bmemory/bcart_exhirom.h +++ b/src/memory/bmemory/bcart_exhirom.h @@ -6,7 +6,7 @@ public: uint8 *rom, *sram; uint32 rom_size, sram_size; uint8 read (uint32 addr); - void write(uint32 addr, byte value); + void write(uint32 addr, uint8 value); void write_protect(bool r); void set_cartinfo(CartInfo *ci); diff --git a/src/memory/bmemory/bcart_exlorom.h b/src/memory/bmemory/bcart_exlorom.h index a3996a05..c51018d4 100644 --- a/src/memory/bmemory/bcart_exlorom.h +++ b/src/memory/bmemory/bcart_exlorom.h @@ -6,7 +6,7 @@ public: uint8 *rom, *sram; uint32 rom_size, sram_size; uint8 read (uint32 addr); - void write(uint32 addr, byte value); + void write(uint32 addr, uint8 value); void write_protect(bool r); void set_cartinfo(CartInfo *ci); diff --git a/src/memory/bmemory/bcart_hirom.h b/src/memory/bmemory/bcart_hirom.h index f8eba666..02631437 100644 --- a/src/memory/bmemory/bcart_hirom.h +++ b/src/memory/bmemory/bcart_hirom.h @@ -7,7 +7,7 @@ public: uint8 *rom, *sram; uint32 rom_size, sram_size; uint8 read (uint32 addr); - void write(uint32 addr, byte value); + void write(uint32 addr, uint8 value); void write_protect(bool r); void set_cartinfo(CartInfo *ci); diff --git a/src/memory/bmemory/bcart_lorom.h b/src/memory/bmemory/bcart_lorom.h index 8fdd058c..b456bee3 100644 --- a/src/memory/bmemory/bcart_lorom.h +++ b/src/memory/bmemory/bcart_lorom.h @@ -7,7 +7,7 @@ public: uint8 *rom, *sram; uint32 rom_size, sram_size; uint8 read (uint32 addr); - void write(uint32 addr, byte value); + void write(uint32 addr, uint8 value); void write_protect(bool r); void set_cartinfo(CartInfo *ci); diff --git a/src/memory/bmemory/bmemory.cpp b/src/memory/bmemory/bmemory.cpp index 08a7ebf4..010459a3 100644 --- a/src/memory/bmemory/bmemory.cpp +++ b/src/memory/bmemory/bmemory.cpp @@ -171,33 +171,39 @@ void bMemBus::get_cartinfo(CartInfo *ci) { ***************************************/ uint8 bMemBus::read(uint32 addr) { -uint32 b, w, r; - addr &= 0xffffff; - b = (addr >> 16); - w = (addr & 0xffff); +static uint32 r; + switch(addr & 0xc00000) { + case 0x400000: + if((addr & 0xfe0000) == 0x7e0000) { + r = wram[addr & 0x01ffff]; + break; + } + //fallthrough + case 0xc00000: + r = cart->read(addr); + break; - if(b <= 0x3f) { - if(w <= 0x1fff) { - r = wram[w]; - } else if(w <= 0x5fff) { - r = mmio[w - 0x2000]->read(w); - } else { +//case 0x000000: +//case 0x800000: + default: + switch(addr & 0x00e000) { + case 0x0000: + r = wram[addr & 0x1fff]; + break; + case 0x2000: + case 0x4000: + r = mmio[(addr - 0x2000) & 0x3fff]->read(addr & 0x7fff); + break; +// case 0x6000: +// case 0x8000: +// case 0xa000: +// case 0xc000: +// case 0xe000: + default: r = cart->read(addr); + break; } - } else if(b <= 0x7d) { - r = cart->read(addr); - } else if(b <= 0x7f) { - r = wram[addr & 0x01ffff]; - } else if(b <= 0xbf) { - if(w <= 0x1fff) { - r = wram[w]; - } else if(w <= 0x5fff) { - r = mmio[w - 0x2000]->read(w); - } else { - r = cart->read(addr); - } - } else { - r = cart->read(addr); + break; } snes->notify(SNES::MEM_READ, addr, r); @@ -205,33 +211,38 @@ uint32 b, w, r; } void bMemBus::write(uint32 addr, uint8 value) { -uint32 b, w; - addr &= 0xffffff; - b = (addr >> 16); - w = (addr & 0xffff); + switch(addr & 0xc00000) { + case 0x400000: + if((addr & 0xfe0000) == 0x7e0000) { + wram[addr & 0x01ffff] = value; + break; + } + //fallthrough + case 0xc00000: + cart->write(addr, value); + break; - if(b <= 0x3f) { - if(w <= 0x1fff) { - wram[w] = value; - } else if(w <= 0x5fff) { - mmio[w - 0x2000]->write(w, value); - } else { +//case 0x000000: +//case 0x800000: + default: + switch(addr & 0x00e000) { + case 0x0000: + wram[addr & 0x1fff] = value; + break; + case 0x2000: + case 0x4000: + mmio[(addr - 0x2000) & 0x3fff]->write(addr & 0x7fff, value); + break; +// case 0x6000: +// case 0x8000: +// case 0xa000: +// case 0xc000: +// case 0xe000: + default: cart->write(addr, value); + break; } - } else if(b <= 0x7d) { - cart->write(addr, value); - } else if(b <= 0x7f) { - wram[addr & 0x01ffff] = value; - } else if(b <= 0xbf) { - if(w <= 0x1fff) { - wram[w] = value; - } else if(w <= 0x5fff) { - mmio[w - 0x2000]->write(w, value); - } else { - cart->write(addr, value); - } - } else { - cart->write(addr, value); + break; } snes->notify(SNES::MEM_WRITE, addr, value); @@ -243,7 +254,7 @@ void bMemBus::power() { } void bMemBus::reset() { - fastROM = false; + set_speed(false); } bMemBus::bMemBus() { @@ -253,5 +264,5 @@ bMemBus::bMemBus() { } bMemBus::~bMemBus() { - if(wram)free(wram); + zerofree(wram); } diff --git a/src/memory/bmemory/bmemory.h b/src/memory/bmemory/bmemory.h index 5c633d9e..992ac956 100644 --- a/src/memory/bmemory/bmemory.h +++ b/src/memory/bmemory/bmemory.h @@ -18,13 +18,13 @@ bool rom_loaded; enum { LOROM = 0x20, HIROM = 0x21, EXLOROM = 0x22, EXHIROM = 0x25 }; uint8 read (uint32 addr); - void write(uint32 addr, byte value); + void write(uint32 addr, uint8 value); - bool load_cart(Reader *rf); - bool load_sram(Reader *rf); - bool save_sram(Writer *wf); - void unload_cart(); - void get_cartinfo(CartInfo *ci); + bool load_cart(Reader *rf); + bool load_sram(Reader *rf); + bool save_sram(Writer *wf); + void unload_cart(); + void get_cartinfo(CartInfo *ci); void power(); void reset(); diff --git a/src/memory/memory.cpp b/src/memory/memory.cpp index 4308c031..ed894abd 100644 --- a/src/memory/memory.cpp +++ b/src/memory/memory.cpp @@ -1,6 +1,6 @@ #include "../base.h" -uint16 Memory::read_word(uint32 addr, uint8 wrap) { +uint16 Memory::read_word(uint32 addr, uint wrap) { uint16 r; switch(wrap) { case WRAP_NONE: @@ -19,24 +19,24 @@ uint16 r; return r; } -void Memory::write_word(uint32 addr, uint16 value, uint8 wrap) { +void Memory::write_word(uint32 addr, uint16 data, uint wrap) { switch(wrap) { case WRAP_NONE: - write(addr, value); - write(addr + 1, value >> 8); + write(addr, data); + write(addr + 1, data >> 8); return; case WRAP_BANK: - write(addr, value); - write((addr & 0xff0000) | ((addr + 1) & 0xffff), value >> 8); + write(addr, data); + write((addr & 0xff0000) | ((addr + 1) & 0xffff), data >> 8); return; case WRAP_PAGE: - write(addr, value); - write((addr & 0xffff00) | ((addr + 1) & 0xff), value >> 8); + write(addr, data); + write((addr & 0xffff00) | ((addr + 1) & 0xff), data >> 8); return; } } -uint32 Memory::read_long(uint32 addr, uint8 wrap) { +uint32 Memory::read_long(uint32 addr, uint wrap) { uint32 r; switch(wrap) { case WRAP_NONE: @@ -58,22 +58,22 @@ uint32 r; return r; } -void Memory::write_long(uint32 addr, uint32 value, uint8 wrap) { +void Memory::write_long(uint32 addr, uint32 data, uint wrap) { switch(wrap) { case WRAP_NONE: - write(addr, value); - write(addr + 1, value >> 8); - write(addr + 2, value >> 16); + write(addr, data); + write(addr + 1, data >> 8); + write(addr + 2, data >> 16); return; case WRAP_BANK: - write(addr, value); - write((addr & 0xff0000) | ((addr + 1) & 0xffff), value >> 8); - write((addr & 0xff0000) | ((addr + 2) & 0xffff), value >> 16); + write(addr, data); + write((addr & 0xff0000) | ((addr + 1) & 0xffff), data >> 8); + write((addr & 0xff0000) | ((addr + 2) & 0xffff), data >> 16); return; case WRAP_PAGE: - write(addr, value); - write((addr & 0xffff00) | ((addr + 1) & 0xff), value >> 8); - write((addr & 0xffff00) | ((addr + 2) & 0xff), value >> 16); + write(addr, data); + write((addr & 0xffff00) | ((addr + 1) & 0xff), data >> 8); + write((addr & 0xffff00) | ((addr + 2) & 0xff), data >> 16); return; } } @@ -82,16 +82,30 @@ MMIO mmio_unmapped; uint8 MMIO::read (uint32 addr) { return cpu->regs.mdr; } void MMIO::write(uint32 addr, uint8 value) {} -uint8 MemBus::speed(uint32 addr) { +uint8 MemBus::calc_speed(uint32 addr, bool fast) { if((addr & 0xc00000) == 0x400000)return 8; - if((addr & 0x808000) == 0x808000)return fastROM?6:8; - if((addr & 0xc00000) == 0xc00000)return fastROM?6:8; + if((addr & 0x808000) == 0x808000)return fast?6:8; + if((addr & 0xc00000) == 0xc00000)return fast?6:8; if((addr & 0xe000) == 0x2000)return 6; if((addr & 0xfe00) == 0x4000)return 12; if((addr & 0xe000) == 0x4000)return 6; return 8; } +uint8 MemBus::speed(uint32 addr) { + return speed_table[addr >> 9]; +} + +void MemBus::set_speed(bool fast) { + fastROM = fast; + + if(fastROM) { + speed_table = (uint8*)speed_table_fastrom; + } else { + speed_table = (uint8*)speed_table_slowrom; + } +} + void MemBus::flush_mmio_mappers() { for(int i=0;i<0x4000;i++) { mmio[i] = &mmio_unmapped; @@ -99,7 +113,7 @@ void MemBus::flush_mmio_mappers() { } bool MemBus::set_mmio_mapper(uint16 addr, MMIO *mapper) { -/* out of range? */ +//out of range? if(addr < 0x2000 || addr >= 0x6000)return false; mmio[(addr - 0x2000) & 0x3fff] = mapper; @@ -110,6 +124,12 @@ MemBus::MemBus() { int i; fastROM = false; flush_mmio_mappers(); + + for(i=0;i<32768;i++) { + speed_table_slowrom[i] = calc_speed(i << 9, false); + speed_table_fastrom[i] = calc_speed(i << 9, true); + } + speed_table = (uint8*)speed_table_slowrom; } MemBus::~MemBus() {} diff --git a/src/memory/memory.h b/src/memory/memory.h index 9c7a10b5..01424c13 100644 --- a/src/memory/memory.h +++ b/src/memory/memory.h @@ -1,18 +1,18 @@ class Memory { public: enum { WRAP_NONE = 0, WRAP_BANK = 1, WRAP_PAGE = 2 }; - virtual uint8 read (uint32 addr) = 0; - virtual void write(uint32 addr, uint8 value) = 0; - virtual uint16 read_word (uint32 addr, uint8 wrap = WRAP_NONE); - virtual void write_word(uint32 addr, uint16 value, uint8 wrap = WRAP_NONE); - virtual uint32 read_long (uint32 addr, uint8 wrap = WRAP_NONE); - virtual void write_long(uint32 addr, uint32 value, uint8 wrap = WRAP_NONE); + virtual uint8 read (uint32 addr) = 0; + virtual void write (uint32 addr, uint8 data) = 0; + virtual uint16 read_word (uint32 addr, uint wrap = WRAP_NONE); + virtual void write_word(uint32 addr, uint16 data, uint wrap = WRAP_NONE); + virtual uint32 read_long (uint32 addr, uint wrap = WRAP_NONE); + virtual void write_long(uint32 addr, uint32 data, uint wrap = WRAP_NONE); }; typedef struct { -uint8 *rom, *sram; -uint32 rom_size, sram_size; -}CartInfo; + uint8 *rom, *sram; + uint32 rom_size, sram_size; +} CartInfo; class Cart : public Memory { public: @@ -31,15 +31,26 @@ public: Cart *cart; MMIO *mmio[0x4000]; bool fastROM; - virtual void flush_mmio_mappers(); - virtual bool set_mmio_mapper(uint16 addr, MMIO *mapper); - virtual uint8 speed(uint32 addr); + void flush_mmio_mappers(); + bool set_mmio_mapper(uint16 addr, MMIO *mapper); - virtual bool load_cart(Reader *rf) = 0; - virtual bool load_sram(Reader *rf) = 0; - virtual bool save_sram(Writer *wf) = 0; - virtual void unload_cart() = 0; - virtual void get_cartinfo(CartInfo *ci) = 0; +private: +//0x1000000 / 512 = 32768 +//512 = 0x200, smallest block of a different-speed memory range +//ex. $4000-$41ff = 512 +uint8 *speed_table, + speed_table_slowrom[32768], + speed_table_fastrom[32768]; + inline uint8 calc_speed(uint32 addr, bool fast); +public: + uint8 speed(uint32 addr); + void set_speed(bool fast); + + virtual bool load_cart(Reader *rf) = 0; + virtual bool load_sram(Reader *rf) = 0; + virtual bool save_sram(Writer *wf) = 0; + virtual void unload_cart() = 0; + virtual void get_cartinfo(CartInfo *ci) = 0; virtual void power() = 0; virtual void reset() = 0; diff --git a/src/ppu/bppu/bppu.cpp b/src/ppu/bppu/bppu.cpp index 43ee573d..cc276a06 100644 --- a/src/ppu/bppu/bppu.cpp +++ b/src/ppu/bppu/bppu.cpp @@ -6,7 +6,7 @@ void bPPU::run() {} void bPPU::scanline() { _y = cpu->vcounter(); - _screen_width = (regs.bg_mode == 5 || regs.bg_mode == 6)?512:256; + _screen_width = (regs.bg_mode == 5 || regs.bg_mode == 6) ? 512 : 256; _interlace = cpu->interlace(); _interlace_field = cpu->interlace_field(); @@ -25,27 +25,23 @@ void bPPU::scanline() { } } - if(_y == (cpu->overscan()?239:224) && regs.display_disabled == false) { + if(_y == (cpu->overscan() ? 239 : 224) && regs.display_disabled == false) { //OAM address reset regs.oam_addr = ((regs.oam_addrh << 8) | regs.oam_addrl) << 1; } +} +void bPPU::render_scanline() { //only allow frameskip setting to ignore actual rendering; not RTO, etc. if(settings.frameskip_pos != 0)return; - if(_y > 0 && _y < (cpu->overscan()?239:224)) { - if(regs.bg_mode == 5 || regs.bg_mode == 6) { - output->hires = true; - output->line[_y].hires = true; - } - if(_interlace == true) { - output->interlace = true; - output->line[_y].interlace = true; - } + if(_y > 0 && _y < (cpu->overscan() ? 239 : 224)) { render_line(); } } +bool bPPU::render_frame() { return (settings.frameskip_pos == 0); } + void bPPU::frame() { if(settings.frameskip_changed == true) { settings.frameskip_changed = false; @@ -58,12 +54,6 @@ void bPPU::frame() { if(settings.frameskip_pos != 0)return; snes->notify(SNES::RENDER_FRAME); - output->hires = false; - output->interlace = false; - for(int i=0;i<239;i++) { - output->line[i].hires = false; - output->line[i].interlace = false; - } } void bPPU::set_frameskip(int fs) { @@ -82,7 +72,6 @@ void bPPU::power() { } void bPPU::reset() { - memset(output->buffer, 0, 512 * 478 * 2); frame(); memset(sprite_list, 0, sizeof(sprite_list)); @@ -335,9 +324,9 @@ bPPU::bPPU() { mmio = new bPPUMMIO(this); - vram = (uint8*)memalloc(65536, "bPPU::vram"); - oam = (uint8*)memalloc( 544, "bPPU::oam"); - cgram = (uint8*)memalloc( 512, "bPPU::cgram"); + vram = (uint8*)malloc(65536); + oam = (uint8*)malloc( 544); + cgram = (uint8*)malloc( 512); memset(vram, 0, 65536); memset(oam, 0, 544); memset(cgram, 0, 512); @@ -346,7 +335,7 @@ bPPU::bPPU() { int i, l; uint8 r, g, b; -float m; +double m; uint16 *ptr; for(l=0;l<16;l++) { mosaic_table[l] = (uint16*)malloc(4096 * 2); @@ -358,7 +347,7 @@ uint16 *ptr; light_table = (uint16*)malloc(16 * 32768 * 2); ptr = (uint16*)light_table; for(l=0;l<16;l++) { - m = (float)l / 15.0; + m = (double)l / 15.0; for(i=0;i<32768;i++) { r = (i ) & 31; g = (i >> 5) & 31; @@ -366,9 +355,9 @@ uint16 *ptr; if(l == 0) { r = g = b = 0; } else if(l == 15); else { - r = (uint8)((float)r * m); - g = (uint8)((float)g * m); - b = (uint8)((float)b * m); + r = (uint8)((double)r * m); + g = (uint8)((double)g * m); + b = (uint8)((double)b * m); } *ptr++ = (r) | (g << 5) | (b << 10); } @@ -378,30 +367,15 @@ uint16 *ptr; bPPU::~bPPU() { delete(mmio); - if(vram) { - free(vram); - vram = 0; - } - if(oam) { - free(oam); - oam = 0; - } - if(cgram) { - free(cgram); - cgram = 0; - } + zerofree(vram); + zerofree(oam); + zerofree(cgram); for(int i=0;i<16;i++) { - if(mosaic_table[i]) { - free(mosaic_table[i]); - mosaic_table[i] = 0; - } + zerofree(mosaic_table[i]); } - if(light_table) { - memfree(light_table); - light_table = 0; - } + zerofree(light_table); } bPPUMMIO::bPPUMMIO(bPPU *_ppu) { diff --git a/src/ppu/bppu/bppu.h b/src/ppu/bppu/bppu.h index 36c7740c..c403df54 100644 --- a/src/ppu/bppu/bppu.h +++ b/src/ppu/bppu/bppu.h @@ -25,12 +25,12 @@ struct sprite_item { bool vflip, hflip; uint8 palette; uint8 priority; -}sprite_list[128]; +} sprite_list[128]; struct { int32 frameskip, frameskip_pos; bool frameskip_changed; -}settings; +} settings; struct { //open bus support @@ -119,6 +119,7 @@ struct { //$2130 uint8 color_mask, colorsub_mask; bool addsub_mode; + bool direct_color; //$2131 bool color_mode, color_halve; @@ -145,7 +146,7 @@ struct { //$213e bool time_over, range_over; uint16 oam_itemcount, oam_tilecount; -}regs; +} regs; uint8 vram_read (uint16 addr); void vram_write (uint16 addr, uint8 value); uint8 oam_read (uint16 addr); @@ -225,7 +226,7 @@ struct { void latch_counters(); -/* PPU render functions */ +//PPU render functions #include "bppu_render.h" @@ -234,13 +235,17 @@ uint16 *mosaic_table[16]; void render_line(); void update_oam_status(); -/* Required functions */ +//required functions void run(); void scanline(); + void render_scanline(); void frame(); void power(); void reset(); void set_frameskip(int fs); + bool render_frame(); + + bool scanline_is_hires() { return (regs.bg_mode == 5 || regs.bg_mode == 6); } bPPU(); ~bPPU(); diff --git a/src/ppu/bppu/bppu_mmio.cpp b/src/ppu/bppu/bppu_mmio.cpp index c0dfdfd0..916e465a 100644 --- a/src/ppu/bppu/bppu_mmio.cpp +++ b/src/ppu/bppu/bppu_mmio.cpp @@ -393,6 +393,7 @@ void bPPU::mmio_w2130(uint8 value) { regs.color_mask = (value >> 6) & 3; regs.colorsub_mask = (value >> 4) & 3; regs.addsub_mode = !!(value & 0x02); + regs.direct_color = !!(value & 0x01); } //CGADDSUB @@ -538,9 +539,9 @@ uint8 bPPU::mmio_r213d() { //STAT77 uint8 bPPU::mmio_r213e() { uint8 r = 0x00; - r |= (regs.time_over) ?0x80:0x00; - r |= (regs.range_over)?0x40:0x00; - r |= 0x01; //PPU1 version number + r |= (regs.time_over) ? 0x80 : 0x00; + r |= (regs.range_over) ? 0x40 : 0x00; + r |= (ppu1_version & 0x0f); regs.ppu1_mdr = r; return regs.ppu1_mdr; } @@ -560,7 +561,7 @@ uint8 r = 0x00; } r |= (regs.ppu2_mdr & 0x20); r |= (region << 4); //0 = NTSC, 1 = PAL - r |= 0x03; //PPU2 version number + r |= (ppu2_version & 0x0f); regs.ppu2_mdr = r; return regs.ppu2_mdr; } diff --git a/src/ppu/bppu/bppu_render.cpp b/src/ppu/bppu/bppu_render.cpp index 52f25a6c..131d8d59 100644 --- a/src/ppu/bppu/bppu_render.cpp +++ b/src/ppu/bppu/bppu_render.cpp @@ -104,32 +104,30 @@ Mode7: -> 1, 2, 3, 4, 5 OAM0, BG1n, OAM1, OAM2, OAM3 -*** -This appears to be incorrect, possibly should be... +Mode 7 EXTBG: -> + 1, 2, 3, 4, 5, 6, 7 BG2B, OAM0, BG1n, OAM1, BG2A, OAM2, OAM3 -*** -Mode 7 (extbg): -> - 1, 2, 3, 4, 5, 6 - BG2B, OAM0, OAM1, BG2A, OAM2, OAM3 */ inline void bPPU::render_line_mode7() { if(regs.mode7_extbg == false) { - render_line_mode7(2, 0, 0); //bg2 priorities are ignored + render_line_mode7(BG1, 2, 2); render_line_oam(1, 3, 4, 5); } else { - render_line_mode7(0, 1, 4); //bg1 priority is ignored - render_line_oam(2, 3, 5, 6); + render_line_mode7(BG1, 3, 3); + render_line_mode7(BG2, 1, 5); + render_line_oam(2, 4, 6, 7); } } void bPPU::render_line() { if(regs.display_disabled == true) { - memset(output->buffer + (_y << 10), 0, 2048); + memset(snes->get_ppu_output_handle(), 0, 1024); return; } clear_pixel_cache(); build_color_window_tables(); + switch(regs.bg_mode) { case 0:render_line_mode0();break; case 1:render_line_mode1();break; @@ -140,5 +138,6 @@ void bPPU::render_line() { case 6:render_line_mode6();break; case 7:render_line_mode7();break; } + render_line_output(); } diff --git a/src/ppu/bppu/bppu_render.h b/src/ppu/bppu/bppu_render.h index 89ebdb10..cc6f4229 100644 --- a/src/ppu/bppu/bppu_render.h +++ b/src/ppu/bppu/bppu_render.h @@ -18,15 +18,17 @@ enum { TILE_2BIT = 0, TILE_4BIT = 1, TILE_8BIT = 2 }; enum { PC_BG1 = 0x80, PC_BG2 = 0x81, PC_BG3 = 0x82, PC_BG4 = 0x83, PC_OAM = 0x84, PC_BACK = 0x00 }; struct _pixel { -//palette # index for main/subscreen pixels -//0 = transparent / use palette color # 0 -uint8 src_main, src_sub; +//bgr555 color data for main/subscreen pixels: 0x0000 = transparent / use palette color # 0 +//needs to be bgr555 instead of palette index for direct color mode ($2130 bit 0) to work +uint16 src_main, src_sub; //indicates source of palette # for main/subscreen (BG1-4, OAM, or back) -uint8 bg_main, bg_sub; +uint8 bg_main, bg_sub; +//true when bg_main == OAM && palette index >= 192, disables color add/sub effects +uint8 color_exempt; //priority level of src_n. to set src_n, //the priority of the pixel must be >pri_n -uint8 pri_main, pri_sub; -}pixel_cache[512]; +uint8 pri_main, pri_sub; +} pixel_cache[512]; uint8 *bg_tiledata[3]; uint8 *bg_tiledata_state[3]; @@ -55,7 +57,7 @@ uint8 oam_itemlist[32]; struct oam_tileitem { uint16 x, y, pri, pal, tile; bool hflip; -}oam_tilelist[34]; +} oam_tilelist[34]; enum { OAM_PRI_NONE = 4 }; uint8 oam_line_pal[512], oam_line_pri[512]; @@ -66,15 +68,16 @@ void render_oam_tile(int tile_num); void render_line_oam(uint8 pri0_pos, uint8 pri1_pos, uint8 pri2_pos, uint8 pri3_pos); //bppu_render_mode7.cpp -void render_line_mode7(uint8 bg1_pri, uint8 bg2b_pri, uint8 bg2a_pri); +void render_line_mode7(uint8 bg, uint8 pri0_pos, uint8 pri1_pos); //bppu_render_addsub.cpp -inline uint16 addsub_pixels(int cdest_index, int cdest_bg, int csrc_index, int csrc_bg); -inline uint16 addsub_pixel(int cdest_index, int cdest_bg); +inline uint16 addsub_pixels(uint32 cdest, uint32 csrc); +inline uint16 addsub_pixel (uint32 cdest); //bppu_render_line.cpp enum { BLENDTYPE_BACK = 0, BLENDTYPE_MAIN = 1, BLENDTYPE_SUB = 2, BLENDTYPE_COMBINE = 3 }; -inline uint16 get_palette(int index); +inline uint16 get_palette(uint8 index); +inline uint16 get_direct_color(uint8 p, uint8 t); inline uint16 get_pixel(int x); inline void render_line_output(); diff --git a/src/ppu/bppu/bppu_render_addsub.cpp b/src/ppu/bppu/bppu_render_addsub.cpp index fa727483..43bea198 100644 --- a/src/ppu/bppu/bppu_render_addsub.cpp +++ b/src/ppu/bppu/bppu_render_addsub.cpp @@ -1,15 +1,6 @@ -inline uint16 bPPU::addsub_pixels(int cdest_index, int cdest_bg, int csrc_index, int csrc_bg) { +inline uint16 bPPU::addsub_pixels(uint32 cdest, uint32 csrc) { int r, g, b; -uint32 cdest = get_palette(cdest_index); -uint32 csrc = get_palette(csrc_index); uint16 res; -//oam palettes 0-3 are not affected by color add/sub - if(cdest_bg == OAM) { - if(cdest_index < 192) { - return cdest; - } - } - switch(regs.color_mode) { case 0: //COLORMODE_ADD: if(regs.color_halve == true) { @@ -53,18 +44,10 @@ uint16 res; return 0x0000; //prevent annoying warning message } -inline uint16 bPPU::addsub_pixel(int cdest_index, int cdest_bg) { +inline uint16 bPPU::addsub_pixel(uint32 cdest) { int r, g, b; -uint32 cdest = get_palette(cdest_index); uint32 csrc = (regs.color_r) | (regs.color_g << 5) | (regs.color_b << 10); uint16 res; -//only oam palettes 4-7 are affected by color add/sub - if(cdest_bg == OAM) { - if(cdest_index < 192) { - return cdest; - } - } - switch(regs.color_mode) { case 0: //COLORMODE_ADD: if(regs.color_halve == true && regs.addsub_mode == 0) { diff --git a/src/ppu/bppu/bppu_render_bg.cpp b/src/ppu/bppu/bppu_render_bg.cpp index cad885ae..7379d277 100644 --- a/src/ppu/bppu/bppu_render_bg.cpp +++ b/src/ppu/bppu/bppu_render_bg.cpp @@ -3,7 +3,7 @@ void bPPU::render_line_bg(uint8 bg, uint8 color_depth, uint8 pri0_pos, uint8 pri return; } -int x; +int x; int _scaddr = regs.bg_scaddr[bg]; int _tdaddr = regs.bg_tdaddr[bg]; bool _bg_enabled = regs.bg_enabled[bg]; @@ -25,17 +25,7 @@ uint16 opt_valid_bit; //offset-per-tile valid flag bit //entry point. This allows all 256 palette colors //to be used, instead of just the first 32. //entry = bg * 32, where 32 is from 8 * 4 -uint8 bgpal_index; - if(regs.bg_mode == 0) { - switch(bg) { - case BG1:bgpal_index = 0;break; - case BG2:bgpal_index = 32;break; - case BG3:bgpal_index = 64;break; - case BG4:bgpal_index = 96;break; - } - } else { - bgpal_index = 0; - } +uint8 bgpal_index = (regs.bg_mode == 0) ? (bg << 5) : 0; uint8 pal_size, tiledata_size; switch(color_depth) { @@ -114,36 +104,43 @@ int mosaic_x, mosaic_y; } else { mtable = (uint16*)mosaic_table[0]; } + mosaic_x = mtable[bg_x]; mosaic_y = mtable[bg_y]; uint8 tile_x; uint16 t, base_xpos, base_pos, pos; uint16 tile_num; -int mirror_x, mirror_y; -uint8 pal_index; +int mirror_x, mirror_y; +uint8 pal_index, pal_num; uint8 *tile_ptr; int xpos, ypos; uint16 map_index, hoffset, voffset, col; + build_window_tables(bg); uint8 *wt_main = main_windowtable[bg]; uint8 *wt_sub = sub_windowtable[bg]; - build_window_tables(bg); - for(screen_x=0;screen_x<_screen_width;screen_x++) { - //offset-per-tile mode. horizontal OPT is buggy, so it is disabled - //vertical OPT seems to be working OK... + + screen_x = 0; + do { //for(screen_x=0;screen_x<_screen_width;screen_x++) { if(regs.bg_mode == 2 || regs.bg_mode == 4 || regs.bg_mode == 6) { if(regs.bg_mode == 6) { + //hires adjust tile_x = (mtable[screen_x + (hscroll & 15)] >> 4); } else { tile_x = (mtable[screen_x + (hscroll & 7)] >> 3); } + hoffset = hscroll; voffset = vscroll; + + //tile 0 is unaffected by OPT mode... if(tile_x != 0) { - tile_x = (tile_x - 1) & 31; + //multiply by two to index into 16-bit table entries + tile_x = ((tile_x - 1) & 31) << 1; + if(regs.bg_mode == 4) { - pos = regs.bg_scaddr[BG3] + (tile_x << 1); + pos = regs.bg_scaddr[BG3] + tile_x; t = *((uint16*)vram + (pos >> 1)); if(t & opt_valid_bit) { if(!(t & 0x8000)) { @@ -153,18 +150,19 @@ uint8 *wt_sub = sub_windowtable[bg]; } } } else { - pos = regs.bg_scaddr[BG3] + (tile_x << 1); + pos = regs.bg_scaddr[BG3] + tile_x; t = *((uint16*)vram + (pos >> 1)); if(t & opt_valid_bit) { hoffset = ((t & 0x1ff8) | (hscroll & 7)) & screen_width_mask; } - pos = regs.bg_scaddr[BG3] + 64 + (tile_x << 1); + pos = regs.bg_scaddr[BG3] + 64 + tile_x; t = *((uint16*)vram + (pos >> 1)); if(t & opt_valid_bit) { voffset = (t & 0x1fff) & screen_height_mask; } } } + mosaic_x = mtable[(screen_x + hoffset) & screen_width_mask ]; mosaic_y = mtable[(screen_y + voffset) & screen_height_mask]; } @@ -189,30 +187,36 @@ uint8 *wt_sub = sub_windowtable[bg]; base_pos = (((mosaic_y >> tile_height) & 31) << 5) + ((mosaic_x >> tile_width) & 31); pos = _scaddr + map_index + (base_pos << 1); t = *((uint16*)vram + (pos >> 1)); - mirror_y = (t & 0x8000)?1:0; - mirror_x = (t & 0x4000)?1:0; + mirror_y = !!(t & 0x8000); + mirror_x = !!(t & 0x4000); int _pri; _pri = (t & 0x2000) ? pri1_pos : pri0_pos; tile_num = t & 0x03ff; + + //16x16 horizontal tile mirroring if(tile_width == 4) { if(((mosaic_x & 15) >= 8 && !mirror_x) || ((mosaic_x & 15) < 8 && mirror_x))tile_num++; tile_num &= 0x03ff; } + + //16x16 vertical tile mirroring if(tile_height == 4) { if(((mosaic_y & 15) >= 8 && !mirror_y) || ((mosaic_y & 15) < 8 && mirror_y))tile_num += 16; tile_num &= 0x03ff; } + tile_num += (_tdaddr >> tiledata_size); if(bg_td_state[tile_num] == 1) { render_bg_tile(color_depth, tile_num); } - pal_index = ((t >> 10) & 7) * pal_size + bgpal_index; + pal_num = ((t >> 10) & 7); + pal_index = pal_num * pal_size + bgpal_index; if(mirror_y) { ypos = (7 - (mosaic_y & 7)); } else { ypos = ( (mosaic_y & 7)); } @@ -220,23 +224,30 @@ int _pri; //loop while we are rendering from the same tile, as there's no need to do all of the above work //unless we have rendered all of the visible tile, taking mosaic into account. tile_ptr = (uint8*)bg_td + (tile_num << 6) + (ypos << 3); - while(1) { + do { if(mirror_x) { xpos = (7 - (mosaic_x & 7)); } else { xpos = ( (mosaic_x & 7)); } col = *(tile_ptr + xpos); if(col && main_colorwindowtable[screen_x]) { + if(regs.direct_color == true && bg == BG1 && (regs.bg_mode == 3 || regs.bg_mode == 4)) { + col = get_direct_color(pal_num, col); + } else { + col = get_palette(col + pal_index); + } + if(_bg_enabled == true && !wt_main[screen_x]) { if(pixel_cache[screen_x].pri_main < _pri) { pixel_cache[screen_x].pri_main = _pri; pixel_cache[screen_x].bg_main = 0x80 | bg; - pixel_cache[screen_x].src_main = col + pal_index; + pixel_cache[screen_x].src_main = col; + pixel_cache[screen_x].color_exempt = false; } } if(_bgsub_enabled == true && !wt_sub[screen_x]) { if(pixel_cache[screen_x].pri_sub < _pri) { pixel_cache[screen_x].pri_sub = _pri; pixel_cache[screen_x].bg_sub = 0x80 | bg; - pixel_cache[screen_x].src_sub = col + pal_index; + pixel_cache[screen_x].src_sub = col; } } } @@ -246,8 +257,7 @@ int _pri; mosaic_x = mtable[bg_x]; if(base_xpos != ((mosaic_x >> 3) & 31))break; - screen_x++; - if(screen_x >= _screen_width)break; - } - } + if(++screen_x >= _screen_width)break; + } while(1); + } while(++screen_x < _screen_width); } diff --git a/src/ppu/bppu/bppu_render_line.cpp b/src/ppu/bppu/bppu_render_line.cpp index ee83802d..7b657c07 100644 --- a/src/ppu/bppu/bppu_render_line.cpp +++ b/src/ppu/bppu/bppu_render_line.cpp @@ -1,36 +1,45 @@ -inline uint16 bPPU::get_palette(int index) { +inline uint16 bPPU::get_palette(uint8 index) { return *((uint16*)cgram + index); } +inline uint16 bPPU::get_direct_color(uint8 p, uint8 t) { +//p = 00000bgr +//t = BBGGGRRR +//r = 0BBb00GGGg0RRRr0 + return ((t & 7) << 2) | ((p & 1) << 1) | + (((t >> 3) & 7) << 7) | (((p >> 1) & 1) << 6) | + ((t >> 6) << 13) | ((p >> 2) << 12); +} + inline uint16 bPPU::get_pixel(int x) { _pixel *p = &pixel_cache[x]; -uint16 _r; +uint16 _r, src_back = get_palette(0); if(p->bg_main && p->bg_sub) { - if(regs.bg_color_enabled[p->bg_main & 0x7f] && sub_colorwindowtable[x]) { + if(p->color_exempt == false && regs.bg_color_enabled[p->bg_main & 0x7f] && sub_colorwindowtable[x]) { if(regs.addsub_mode) { - _r = addsub_pixels(p->src_main, p->bg_main & 0x7f, p->src_sub, p->bg_sub & 0x7f); + _r = addsub_pixels(p->src_main, p->src_sub); } else { - _r = addsub_pixel(p->src_main, p->bg_main & 0x7f); + _r = addsub_pixel(p->src_main); } } else { - _r = get_palette(p->src_main); + _r = p->src_main; } } else if(p->bg_main) { - if(regs.bg_color_enabled[p->bg_main & 0x7f] && sub_colorwindowtable[x]) { - _r = addsub_pixel(p->src_main, p->bg_main & 0x7f); + if(p->color_exempt == false && regs.bg_color_enabled[p->bg_main & 0x7f] && sub_colorwindowtable[x]) { + _r = addsub_pixel(p->src_main); } else { - _r = get_palette(p->src_main); + _r = p->src_main; } } else if(p->bg_sub) { if(regs.bg_color_enabled[BACK]) { if(sub_colorwindowtable[x]) { if(regs.addsub_mode) { - _r = addsub_pixels(0, BACK, p->src_sub, p->bg_sub & 0x7f); + _r = addsub_pixels(src_back, p->src_sub); } else { - _r = addsub_pixel(0, BACK); + _r = addsub_pixel(src_back); } } else { - _r = get_palette(0); + _r = src_back; } } else { _r = 0x0000; @@ -38,9 +47,9 @@ uint16 _r; } else { if(main_colorwindowtable[x]) { if(regs.bg_color_enabled[BACK] && sub_colorwindowtable[x]) { - _r = addsub_pixel(0, BACK); + _r = addsub_pixel(src_back); } else { - _r = get_palette(0); + _r = src_back; } } else { _r = 0x0000; @@ -53,10 +62,7 @@ inline void bPPU::render_line_output() { int x; uint16 _r; uint16 *ptr; - ptr = (uint16*)output->buffer + (_y << 10); - if(_interlace == true) { - ptr += _interlace_field << 9; - } + ptr = (uint16*)snes->get_ppu_output_handle(); uint16 *ltable; ltable = (uint16*)light_table + (regs.display_brightness << 15); @@ -64,8 +70,7 @@ uint16 *ltable; if(_screen_width == 256) { for(x=0;x<256;x++) { _r = get_pixel(x); - *ptr = *(ltable + _r); - ptr += 2; + *ptr++ = *(ltable + _r); } } else { for(x=0;x<512;x++) { diff --git a/src/ppu/bppu/bppu_render_mode7.cpp b/src/ppu/bppu/bppu_render_mode7.cpp index 8ed29b5b..1671f6c5 100644 --- a/src/ppu/bppu/bppu_render_mode7.cpp +++ b/src/ppu/bppu/bppu_render_mode7.cpp @@ -1,62 +1,72 @@ -#define CLIP_10BIT_SIGNED(x) \ - ((x) & ((1 << 10) - 1)) + (((((x) & (1 << 13)) ^ (1 << 13)) - (1 << 13)) >> 3) +/* + bsnes mode7 renderer -#define CAST_WORDTOINT(x) \ - (int32)(((x & 0x8000) ? (x | 0xffff0000) : (x & 0x00007fff))) + base algorithm written by anomie + bsnes implementation written by byuu + + supports mode 7 + extbg + rotate + zoom + direct color + scrolling + m7sel + windowing + mosaic + does not support pseudo-hires + interlace support is automatic via main rendering routine +*/ + +//13-bit sign extend +//--s---vvvvvvvvvv -> ssssssvvvvvvvvvv +#define CLIP(x) ( ((x) & 0x2000) ? ( (x) | ~0x03ff) : ((x) & 0x03ff) ) +//#define CLIP(x) ( ((x) & 0x03ff) | (((x) & 0x2000) ? -0x0400 : 0) ) + +void bPPU::render_line_mode7(uint8 bg, uint8 pri0_pos, uint8 pri1_pos) { + if(regs.bg_enabled[bg] == false && regs.bgsub_enabled[bg] == false)return; + +int32 x, y; +int32 a, b, c, d, cx, cy; +int32 hofs, vofs; -void bPPU::render_line_mode7(uint8 bg1_pri, uint8 bg2b_pri, uint8 bg2a_pri) { -int32 x; -int32 step_m7a, step_m7c, m7a, m7b, m7c, m7d; -int32 hoffset, voffset; -int32 centerx, centery; -int32 xx, yy; int32 px, py; int32 tx, ty, tile, palette; -uint8 layer_pos; - hoffset = ((int32)regs.m7_hofs << 19) >> 19; - voffset = ((int32)regs.m7_vofs << 19) >> 19; + a = int32(int16(regs.m7a)); + b = int32(int16(regs.m7b)); + c = int32(int16(regs.m7c)); + d = int32(int16(regs.m7d)); - centerx = ((int32)regs.m7x << 19) >> 19; - centery = ((int32)regs.m7y << 19) >> 19; + cx = (int32(regs.m7x) << 19) >> 19; + cy = (int32(regs.m7y) << 19) >> 19; + hofs = (int32(regs.m7_hofs) << 19) >> 19; + vofs = (int32(regs.m7_vofs + 1) << 19) >> 19; + +int _pri, _x; +bool _bg_enabled = regs.bg_enabled[bg]; +bool _bgsub_enabled = regs.bgsub_enabled[bg]; + + build_window_tables(bg); +uint8 *wt_main = main_windowtable[bg]; +uint8 *wt_sub = sub_windowtable[bg]; if(regs.mode7_vflip == true) { - yy = 255 - _y; + y = 255 - _y; } else { - yy = _y; - } - yy += CLIP_10BIT_SIGNED(voffset - centery); - - m7b = CAST_WORDTOINT(regs.m7b) * yy + (centerx << 8); - m7d = CAST_WORDTOINT(regs.m7d) * yy + (centery << 8); - - step_m7a = CAST_WORDTOINT(regs.m7a); - step_m7c = CAST_WORDTOINT(regs.m7c); - - xx = CLIP_10BIT_SIGNED(hoffset - centerx); - - m7a = CAST_WORDTOINT(regs.m7a) * xx; - m7c = CAST_WORDTOINT(regs.m7c) * xx; - -int _pri, _x, _bg; -bool _bg_enabled, _bgsub_enabled; - if(regs.mode7_extbg == false) { - _pri = bg1_pri; - _bg = BG1; - _bg_enabled = regs.bg_enabled[BG1]; - _bgsub_enabled = regs.bgsub_enabled[BG1]; - } else { - _bg = BG2; - _bg_enabled = regs.bg_enabled[BG2]; - _bgsub_enabled = regs.bgsub_enabled[BG2]; + y = _y; } -uint8 *wt_main = main_windowtable[_bg]; -uint8 *wt_sub = sub_windowtable[_bg]; - build_window_tables(_bg); +uint16 *mtable_x, *mtable_y; + if(bg == BG1) { + mtable_x = (uint16*)mosaic_table[(regs.mosaic_enabled[BG1] == true) ? regs.mosaic_size : 0]; + mtable_y = (uint16*)mosaic_table[(regs.mosaic_enabled[BG1] == true) ? regs.mosaic_size : 0]; + } else { //bg == BG2 + //Mode7 EXTBG BG2 uses BG1 mosaic enable to control vertical mosaic, + //and BG2 mosaic enable to control horizontal mosaic... + mtable_x = (uint16*)mosaic_table[(regs.mosaic_enabled[BG2] == true) ? regs.mosaic_size : 0]; + mtable_y = (uint16*)mosaic_table[(regs.mosaic_enabled[BG1] == true) ? regs.mosaic_size : 0]; + } +int32 psx = ((a * CLIP(hofs - cx)) & ~63) + ((b * CLIP(vofs - cy)) & ~63) + ((b * mtable_y[y]) & ~63) + (cx << 8); +int32 psy = ((c * CLIP(hofs - cx)) & ~63) + ((d * CLIP(vofs - cy)) & ~63) + ((d * mtable_y[y]) & ~63) + (cy << 8); for(x=0;x<256;x++) { - px = ((m7a + m7b) >> 8); - py = ((m7c + m7d) >> 8); + px = psx + (a * mtable_x[x]); + py = psy + (c * mtable_x[x]); + + //mask floating-point bits (low 8 bits) + px >>= 8; + py >>= 8; switch(regs.mode7_repeat) { case 0: //screen repitition outside of screen area @@ -68,20 +78,7 @@ uint8 *wt_sub = sub_windowtable[_bg]; tile = vram[(ty * 128 + tx) << 1]; palette = vram[(((tile << 6) + ((py & 7) << 3) + (px & 7)) << 1) + 1]; break; - case 2: //character 0 repetition outside of screen area - if(px < 0 || px > 1023 || py < 0 || py > 1023) { - tx = 0; - ty = 0; - } else { - px &= 1023; - py &= 1023; - tx = ((px >> 3) & 127); - ty = ((py >> 3) & 127); - } - tile = vram[(ty * 128 + tx) << 1]; - palette = vram[(((tile << 6) + ((py & 7) << 3) + (px & 7)) << 1) + 1]; - break; - case 3: //palette color 0 outside of screen area + case 2: //palette color 0 outside of screen area if(px < 0 || px > 1023 || py < 0 || py > 1023) { palette = 0; } else { @@ -93,46 +90,61 @@ uint8 *wt_sub = sub_windowtable[_bg]; palette = vram[(((tile << 6) + ((py & 7) << 3) + (px & 7)) << 1) + 1]; } break; + case 3: //character 0 repetition outside of screen area + if(px < 0 || px > 1023 || py < 0 || py > 1023) { + tile = 0; + } else { + px &= 1023; + py &= 1023; + tx = ((px >> 3) & 127); + ty = ((py >> 3) & 127); + tile = vram[(ty * 128 + tx) << 1]; + } + palette = vram[(((tile << 6) + ((py & 7) << 3) + (px & 7)) << 1) + 1]; + break; } - if(!palette)goto _end_setpixel; - - if(regs.mode7_extbg == false) { - //_pri set at top of function, as it is static - if(regs.mode7_hflip == true) { - _x = 255 - x; - } else { - _x = x; - } + if(bg == BG1) { + _pri = pri0_pos; } else { - _pri = (palette >> 7) ? bg2a_pri : bg2b_pri; + _pri = (palette >> 7) ? pri1_pos : pri0_pos; palette &= 0x7f; - if(regs.mode7_hflip == true) { - _x = 255 - x; - } else { - _x = x; - } + } + + if(!palette)continue; + + if(regs.mode7_hflip == true) { + _x = 255 - x; + } else { + _x = x; } if(main_colorwindowtable[_x]) { - if(_bg_enabled == true && !wt_main[_x]) { + uint32 col; + if(regs.direct_color == true && bg == BG1) { + //direct color mode does not apply to bg2, as it is only 128 colors... + col = get_direct_color(0, palette); + } else { + col = get_palette(palette); + } + + if(regs.bg_enabled[bg] == true && !wt_main[_x]) { if(pixel_cache[_x].pri_main < _pri) { pixel_cache[_x].pri_main = _pri; - pixel_cache[_x].bg_main = 0x80 | _bg; - pixel_cache[_x].src_main = palette; + pixel_cache[_x].bg_main = 0x80 | bg; + pixel_cache[_x].src_main = col; + pixel_cache[_x].color_exempt = false; } } - if(_bgsub_enabled == true && !wt_sub[_x]) { + if(regs.bgsub_enabled[bg] == true && !wt_sub[_x]) { if(pixel_cache[_x].pri_sub < _pri) { pixel_cache[_x].pri_sub = _pri; - pixel_cache[_x].bg_sub = 0x80 | _bg; - pixel_cache[_x].src_sub = palette; + pixel_cache[_x].bg_sub = 0x80 | bg; + pixel_cache[_x].src_sub = col; } } } - -_end_setpixel: - m7a += step_m7a; - m7c += step_m7c; } } + +#undef CLIP diff --git a/src/ppu/bppu/bppu_render_oam.cpp b/src/ppu/bppu/bppu_render_oam.cpp index be44c52f..54d7f1a8 100644 --- a/src/ppu/bppu/bppu_render_oam.cpp +++ b/src/ppu/bppu/bppu_render_oam.cpp @@ -256,14 +256,15 @@ int _pri; if(pixel_cache[x].pri_main < _pri) { pixel_cache[x].pri_main = _pri; pixel_cache[x].bg_main = PC_OAM; - pixel_cache[x].src_main = oam_line_pal[x]; + pixel_cache[x].src_main = get_palette(oam_line_pal[x]); + pixel_cache[x].color_exempt = (oam_line_pal[x] < 192); } } if(_bgsub_enabled == true && !wt_sub[x]) { if(pixel_cache[x].pri_sub < _pri) { pixel_cache[x].pri_sub = _pri; pixel_cache[x].bg_sub = PC_OAM; - pixel_cache[x].src_sub = oam_line_pal[x]; + pixel_cache[x].src_sub = get_palette(oam_line_pal[x]); } } } diff --git a/src/ppu/bppu/snes9x_render_mode7.cpp b/src/ppu/bppu/snes9x_render_mode7.cpp new file mode 100644 index 00000000..572a414f --- /dev/null +++ b/src/ppu/bppu/snes9x_render_mode7.cpp @@ -0,0 +1,148 @@ +#define CLIP_10BIT_SIGNED(x) \ + ((x) & ((1 << 10) - 1)) + (((((x) & (1 << 13)) ^ (1 << 13)) - (1 << 13)) >> 3) + +#define CAST_WORDTOINT(x) \ + (int32)((((x) & 0x8000) ? ((x) | 0xffff0000) : ((x) & 0x00007fff))) + +void bPPU::render_line_mode7(uint8 bg, uint8 pri0_pos, uint8 pri1_pos) { +int32 x; +int32 step_m7a, step_m7c, m7a, m7b, m7c, m7d; +int32 hoffset, voffset; +int32 centerx, centery; +int32 xx, yy; +int32 px, py; +int32 tx, ty, tile, palette; +uint8 layer_pos; + if(regs.bg_enabled[bg] == false && regs.bgsub_enabled[bg] == false)return; + +uint16 *mtable_x, *mtable_y; + if(bg == BG1) { + mtable_x = (uint16*)mosaic_table[(regs.mosaic_enabled[BG1] == true) ? regs.mosaic_size : 0]; + mtable_y = (uint16*)mosaic_table[(regs.mosaic_enabled[BG1] == true) ? regs.mosaic_size : 0]; + } else { //bg == BG2 + //Mode7 EXTBG BG2 uses BG1 mosaic enable to control vertical mosaic, + //and BG2 mosaic enable to control horizontal mosaic... + mtable_x = (uint16*)mosaic_table[(regs.mosaic_enabled[BG2] == true) ? regs.mosaic_size : 0]; + mtable_y = (uint16*)mosaic_table[(regs.mosaic_enabled[BG1] == true) ? regs.mosaic_size : 0]; + } + + hoffset = ((int32)regs.m7_hofs << 19) >> 19; + voffset = ((int32)regs.m7_vofs << 19) >> 19; + + centerx = ((int32)regs.m7x << 19) >> 19; + centery = ((int32)regs.m7y << 19) >> 19; + + if(regs.mode7_vflip == true) { + yy = 255 - _y; + } else { + yy = _y; + } + yy = mtable_y[yy]; + yy += CLIP_10BIT_SIGNED(voffset - centery); + + m7b = CAST_WORDTOINT(regs.m7b) * yy + (centerx << 8); + m7d = CAST_WORDTOINT(regs.m7d) * yy + (centery << 8); + + step_m7a = CAST_WORDTOINT(regs.m7a); + step_m7c = CAST_WORDTOINT(regs.m7c); + + xx = CLIP_10BIT_SIGNED(hoffset - centerx); + + m7a = CAST_WORDTOINT(regs.m7a) * xx; + m7c = CAST_WORDTOINT(regs.m7c) * xx; + +int _pri, _x; +bool _bg_enabled, _bgsub_enabled; + _bg_enabled = regs.bg_enabled[bg]; + _bgsub_enabled = regs.bgsub_enabled[bg]; + + build_window_tables(bg); +uint8 *wt_main = main_windowtable[bg]; +uint8 *wt_sub = sub_windowtable[bg]; + + for(x=0;x<256;x++) { + px = ((m7a + step_m7a * mtable_x[x] + m7b) >> 8); + py = ((m7c + step_m7c * mtable_x[x] + m7d) >> 8); + + switch(regs.mode7_repeat) { + case 0: //screen repitition outside of screen area + case 1: //same as case 0 + px &= 1023; + py &= 1023; + tx = ((px >> 3) & 127); + ty = ((py >> 3) & 127); + tile = vram[(ty * 128 + tx) << 1]; + palette = vram[(((tile << 6) + ((py & 7) << 3) + (px & 7)) << 1) + 1]; + break; + case 2: //palette color 0 outside of screen area + if(px < 0 || px > 1023 || py < 0 || py > 1023) { + palette = 0; + } else { + px &= 1023; + py &= 1023; + tx = ((px >> 3) & 127); + ty = ((py >> 3) & 127); + tile = vram[(ty * 128 + tx) << 1]; + palette = vram[(((tile << 6) + ((py & 7) << 3) + (px & 7)) << 1) + 1]; + } + break; + case 3: //character 0 repetition outside of screen area + if(px < 0 || px > 1023 || py < 0 || py > 1023) { + tx = 0; + ty = 0; + } else { + px &= 1023; + py &= 1023; + tx = ((px >> 3) & 127); + ty = ((py >> 3) & 127); + } + tile = vram[(ty * 128 + tx) << 1]; + palette = vram[(((tile << 6) + ((py & 7) << 3) + (px & 7)) << 1) + 1]; + break; + } + + if(bg == BG1) { + _pri = pri0_pos; + } else { + _pri = (palette >> 7) ? pri1_pos : pri0_pos; + palette &= 0x7f; + } + + if(!palette)continue; + + if(regs.mode7_hflip == true) { + _x = 255 - x; + } else { + _x = x; + } + + if(main_colorwindowtable[_x]) { + uint32 col; + if(regs.direct_color == true && bg == BG1) { + //direct color mode does not apply to bg2 as it is only 128 colors... + col = get_direct_color(0, palette); + } else { + col = get_palette(palette); + } + + if(regs.bg_enabled[bg] == true && !wt_main[_x]) { + if(pixel_cache[_x].pri_main < _pri) { + pixel_cache[_x].pri_main = _pri; + pixel_cache[_x].bg_main = 0x80 | bg; + pixel_cache[_x].src_main = col; + pixel_cache[_x].color_exempt = false; + } + } + if(regs.bgsub_enabled[bg] == true && !wt_sub[_x]) { + if(pixel_cache[_x].pri_sub < _pri) { + pixel_cache[_x].pri_sub = _pri; + pixel_cache[_x].bg_sub = 0x80 | bg; + pixel_cache[_x].src_sub = col; + } + } + } + } +} + +#undef CLIP_10BIT_SIGNED +#undef CAST_WORDTOINT diff --git a/src/ppu/ppu.cpp b/src/ppu/ppu.cpp index 3f7a90ce..224bd621 100644 --- a/src/ppu/ppu.cpp +++ b/src/ppu/ppu.cpp @@ -1,27 +1,17 @@ #include "../base.h" -PPUOutput::PPUOutput() { - buffer = (uint16*)memalloc(512 * 478 * 2, "PPUOutput::buffer"); - memset(buffer, 0, 512 * 478 * 2); - hires = false; - interlace = false; - for(int i=0;i<239;i++) { - line[i].hires = false; - line[i].interlace = false; - } -} - -PPUOutput::~PPUOutput() { - if(buffer)memfree(buffer, "PPUOutput::buffer"); +void PPU::get_scanline_info(scanline_info *info) { + info->hires = scanline_is_hires(); + info->interlace = cpu->interlace(); } void PPU::set_frameskip(int fs) {} +bool PPU::render_frame() { return true; } PPU::PPU() { + ppu1_version = 1; + ppu2_version = 3; mmio = &mmio_unmapped; - output = new PPUOutput(); } -PPU::~PPU() { - if(output)delete(output); -} +PPU::~PPU() {} diff --git a/src/ppu/ppu.h b/src/ppu/ppu.h index f4c20eca..f2997aea 100644 --- a/src/ppu/ppu.h +++ b/src/ppu/ppu.h @@ -1,19 +1,25 @@ -class PPUOutput { -public: -bool hires, interlace; -struct { -bool hires, interlace; -}line[239]; -uint16 *buffer; - PPUOutput(); - ~PPUOutput(); -}; - class PPU { public: -int _y; -PPUOutput *output; -MMIO *mmio; +//PPU1 version number +//* 1 is known +//* reported by $213e +uint8 ppu1_version; + +//PPU2 version number +//* 1 and 3 are known +//* reported by $213f +uint8 ppu2_version; + +int _y; +MMIO *mmio; + +struct scanline_info { + bool hires; + bool interlace; +}; + virtual bool scanline_is_hires() = 0; + virtual void get_scanline_info(scanline_info *info); + virtual uint8 vram_read (uint16 addr) = 0; virtual void vram_write (uint16 addr, uint8 value) = 0; virtual uint8 oam_read (uint16 addr) = 0; @@ -25,10 +31,12 @@ MMIO *mmio; virtual void run() = 0; virtual void scanline() = 0; + virtual void render_scanline() = 0; virtual void frame() = 0; virtual void power() = 0; virtual void reset() = 0; virtual void set_frameskip(int fs); + virtual bool render_frame(); PPU(); ~PPU(); diff --git a/src/sdl/Makefile b/src/sdl/Makefile index 7d81aeb3..0275a371 100644 --- a/src/sdl/Makefile +++ b/src/sdl/Makefile @@ -6,6 +6,7 @@ OBJS = sdlmain.o \ memory.o bmemory.o \ cpu.o bcpu.o \ apu.o bapu.o bapuskip.o \ + bdsp.o \ ppu.o bppu.o \ snes.o \ srtc.o sdd1.o @@ -60,6 +61,12 @@ bapu.o: ../apu/bapu/* bapuskip.o: ../apu/bapuskip/* $(CC) $(CFLAGS) -c ../apu/bapuskip/bapuskip.cpp +########### +### dsp ### +########### +bdsp.o: ../dsp/bdsp/* + $(CC) $(CFLAGS) -c ../dsp/bdsp/bdsp.cpp + ########### ### ppu ### ########### diff --git a/src/sdl/Makefile.win32 b/src/sdl/Makefile.win32 index 53c00b32..fb3b12fb 100644 --- a/src/sdl/Makefile.win32 +++ b/src/sdl/Makefile.win32 @@ -6,6 +6,7 @@ OBJS = sdlmain.obj \ memory.obj bmemory.obj \ cpu.obj bcpu.obj \ apu.obj bapu.obj bapuskip.obj \ + bdsp.obj \ ppu.obj bppu.obj \ snes.obj \ srtc.obj sdd1.obj @@ -61,6 +62,12 @@ bapu.obj: ../apu/bapu/* bapuskip.obj: ../apu/bapuskip/* $(CC) $(CFLAGS) /c ../apu/bapuskip/bapuskip.cpp +########### +### dsp ### +########### +bdsp.obj: ../dsp/bdsp/* + $(CC) $(CFLAGS) /c ../dsp/bdsp/bdsp.cpp + ########### ### ppu ### ########### diff --git a/src/sdl/bsnes.cpp b/src/sdl/bsnes.cpp index 50336b7a..054b3243 100644 --- a/src/sdl/bsnes.cpp +++ b/src/sdl/bsnes.cpp @@ -1,13 +1,13 @@ void bSNES::set_status(uint32 new_status) { run_status = new_status; } uint32 bSNES::get_status() { return run_status; } -void bSNES::snes_run() { +void bSNES::run() { if(!rom_image->loaded())return; switch(run_status) { case RUN: while(update_frame == false) { - run(); + SNES::run(); } update_frame = false; render(); @@ -17,7 +17,8 @@ void bSNES::snes_run() { } } -void bSNES::render_frame() {} +void bSNES::video_run() { render(); } +void bSNES::sound_run() {} /*********************** *** Input functions *** @@ -28,18 +29,18 @@ void bSNES::render_frame() {} //to throw error messages about a bad free call to stdout... void bSNES::poll_input() { uint8 *keystate = SDL_GetKeyState(0); - joypad1.up = keystate[cfg.input.joypad1.up]; - joypad1.down = keystate[cfg.input.joypad1.down]; - joypad1.left = keystate[cfg.input.joypad1.left]; - joypad1.right = keystate[cfg.input.joypad1.right]; - joypad1.select = keystate[cfg.input.joypad1.select]; - joypad1.start = keystate[cfg.input.joypad1.start]; - joypad1.y = keystate[cfg.input.joypad1.y]; - joypad1.b = keystate[cfg.input.joypad1.b]; - joypad1.x = keystate[cfg.input.joypad1.x]; - joypad1.a = keystate[cfg.input.joypad1.a]; - joypad1.l = keystate[cfg.input.joypad1.l]; - joypad1.r = keystate[cfg.input.joypad1.r]; + joypad1.up = keystate[(int)config::input.joypad1.up]; + joypad1.down = keystate[(int)config::input.joypad1.down]; + joypad1.left = keystate[(int)config::input.joypad1.left]; + joypad1.right = keystate[(int)config::input.joypad1.right]; + joypad1.select = keystate[(int)config::input.joypad1.select]; + joypad1.start = keystate[(int)config::input.joypad1.start]; + joypad1.y = keystate[(int)config::input.joypad1.y]; + joypad1.b = keystate[(int)config::input.joypad1.b]; + joypad1.x = keystate[(int)config::input.joypad1.x]; + joypad1.a = keystate[(int)config::input.joypad1.a]; + joypad1.l = keystate[(int)config::input.joypad1.l]; + joypad1.r = keystate[(int)config::input.joypad1.r]; //It's impossible to hold both up+down, or left+right down //at the same time on a directional pad; and besides, allowing diff --git a/src/sdl/bsnes.h b/src/sdl/bsnes.h index 472df4e5..dfefc6e1 100644 --- a/src/sdl/bsnes.h +++ b/src/sdl/bsnes.h @@ -14,10 +14,12 @@ bJoypad joypad1, joypad2; public: enum { STOP = 0, RUN }; + void run(); + void video_run(); + void sound_run(); + void set_status(uint32 new_status); uint32 get_status(); - void snes_run(); - void render_frame(); //input functions void poll_input(); diff --git a/src/sdl/bsnes_sdl.cfg b/src/sdl/bsnes_sdl.cfg deleted file mode 100644 index 3e9cb767..00000000 --- a/src/sdl/bsnes_sdl.cfg +++ /dev/null @@ -1,18 +0,0 @@ -apu.enabled = true -video.fullscreen = false -video.display_width = 256 -video.display_height = 223 -video.output_width = 256 -video.output_height = 223 -input.joypad1.up = 0x111 -input.joypad1.down = 0x112 -input.joypad1.left = 0x114 -input.joypad1.right = 0x113 -input.joypad1.a = 0x78 -input.joypad1.b = 0x7a -input.joypad1.x = 0x73 -input.joypad1.y = 0x61 -input.joypad1.l = 0x64 -input.joypad1.r = 0x63 -input.joypad1.select = 0x12f -input.joypad1.start = 0x0d diff --git a/src/sdl/cc.bat b/src/sdl/cc.bat index 413eb640..cc1ab957 100644 --- a/src/sdl/cc.bat +++ b/src/sdl/cc.bat @@ -1,3 +1,2 @@ @nmake /NOLOGO /f Makefile.win32 -@move bsnes_sdl.exe ../../bsnes_sdl.exe>nul @pause \ No newline at end of file diff --git a/src/sdl/config.cpp b/src/sdl/config.cpp index 62177565..163d3646 100644 --- a/src/sdl/config.cpp +++ b/src/sdl/config.cpp @@ -1,47 +1,32 @@ -#define __config_add(name, def, type) add(&name, #name, def, type) +namespace config { -class Config : public config { -public: +struct Video { + static Setting fullscreen; + static Setting display_width, display_height; + static Setting output_width, output_height; +} video; +Setting Video::fullscreen(&config_file, "video.fullscreen", "Enable fullscreen mode at startup", false, Setting::TRUE_FALSE); +Setting Video::display_width (&config_file, "video.display_width", "Window / Fullscreen width", 320, Setting::DEC); +Setting Video::display_height(&config_file, "video.display_height", "Window / Fullscreen height", 240, Setting::DEC); +Setting Video::output_width (&config_file, "video.output_width", "SNES video output width", 256, Setting::DEC); +Setting Video::output_height (&config_file, "video.output_height", "SNES video output height", 223, Setting::DEC); -struct { - uint32 enabled; -}apu; +struct Input { + struct Joypad { + static Setting up, down, left, right, a, b, x, y, l, r, select, start; + } joypad1; +} input; +Setting Input::Joypad::up (&config_file, "input.joypad1.up", "Joypad1 up", SDLK_UP, Setting::HEX); +Setting Input::Joypad::down (&config_file, "input.joypad1.down", "Joypad1 down", SDLK_DOWN, Setting::HEX); +Setting Input::Joypad::left (&config_file, "input.joypad1.left", "Joypad1 left", SDLK_LEFT, Setting::HEX); +Setting Input::Joypad::right (&config_file, "input.joypad1.right", "Joypad1 right", SDLK_RIGHT, Setting::HEX); +Setting Input::Joypad::a (&config_file, "input.joypad1.a", "Joypad1 A", SDLK_x, Setting::HEX); +Setting Input::Joypad::b (&config_file, "input.joypad1.b", "Joypad1 B", SDLK_z, Setting::HEX); +Setting Input::Joypad::x (&config_file, "input.joypad1.x", "Joypad1 X", SDLK_s, Setting::HEX); +Setting Input::Joypad::y (&config_file, "input.joypad1.y", "Joypad1 Y", SDLK_a, Setting::HEX); +Setting Input::Joypad::l (&config_file, "input.joypad1.l", "Joypad1 L", SDLK_d, Setting::HEX); +Setting Input::Joypad::r (&config_file, "input.joypad1.r", "Joypad1 R", SDLK_c, Setting::HEX); +Setting Input::Joypad::select(&config_file, "input.joypad1.select", "Joypad1 select", SDLK_RSHIFT, Setting::HEX); +Setting Input::Joypad::start (&config_file, "input.joypad1.start", "Joypad1 start", SDLK_RETURN, Setting::HEX); -struct { - uint32 fullscreen; - uint32 display_width, display_height; - uint32 output_width, output_height; -}video; - -struct { - struct { - uint32 up, down, left, right; - uint32 a, b, x, y, l, r; - uint32 select, start; - }joypad1; -}input; - - Config() { - __config_add(apu.enabled, true, TRUEFALSE); - - __config_add(video.fullscreen, false, TRUEFALSE); - __config_add(video.display_width, 256, DEC); - __config_add(video.display_height, 223, DEC); - __config_add(video.output_width, 256, DEC); - __config_add(video.output_height, 223, DEC); - - __config_add(input.joypad1.up, SDLK_UP, HEX); - __config_add(input.joypad1.down, SDLK_DOWN, HEX); - __config_add(input.joypad1.left, SDLK_LEFT, HEX); - __config_add(input.joypad1.right, SDLK_RIGHT, HEX); - __config_add(input.joypad1.a, SDLK_x, HEX); - __config_add(input.joypad1.b, SDLK_z, HEX); - __config_add(input.joypad1.x, SDLK_s, HEX); - __config_add(input.joypad1.y, SDLK_a, HEX); - __config_add(input.joypad1.l, SDLK_d, HEX); - __config_add(input.joypad1.r, SDLK_c, HEX); - __config_add(input.joypad1.select, SDLK_RSHIFT, HEX); - __config_add(input.joypad1.start, SDLK_RETURN, HEX); - } - -}cfg; +}; diff --git a/src/sdl/render.cpp b/src/sdl/render.cpp index 69b9ebec..38d4da84 100644 --- a/src/sdl/render.cpp +++ b/src/sdl/render.cpp @@ -1,87 +1,49 @@ -uint8 color_curve_table[32]; -uint32 color_lookup_table[65536]; - -void update_color_lookup_table() { -int i, r, g, b, c; - for(i=0,c=0;i<16;i++) { - color_curve_table[i] = c; - c = c + i + 1; - } - for(;i<31;i++) { - color_curve_table[i] = c; - c += 8; - } - color_curve_table[i] = 0xff; - -int color_depth = 16; - if(color_depth == 15) { - for(i=0;i<65536;i++) { - r = (i ) & 31; - g = (i >> 5) & 31; - b = (i >> 10) & 31; - r = color_curve_table[r] >> 3; - g = color_curve_table[g] >> 3; - b = color_curve_table[b] >> 3; - color_lookup_table[i] = (r << 10) | (g << 5) | (b); - } - } else if(color_depth == 16) { - for(i=0;i<65536;i++) { - r = (i ) & 31; - g = (i >> 5) & 31; - b = (i >> 10) & 31; - r = color_curve_table[r] >> 3; - g = color_curve_table[g] >> 2; - b = color_curve_table[b] >> 3; - color_lookup_table[i] = (r << 11) | (g << 5) | (b); - } - } else if(color_depth == 32) { - for(i=0;i<65536;i++) { - r = (i ) & 31; - g = (i >> 5) & 31; - b = (i >> 10) & 31; - r = color_curve_table[r]; - g = color_curve_table[g]; - b = color_curve_table[b]; - color_lookup_table[i] = (r << 16) | (g << 8) | (b); - } - } else { - alert("Error: Unsupported color depth [%d]", color_depth); - } -} - void render16() { -uint16 *src, *dest; +uint16 *dest, *src; uint32 pitch; int x, y; - pitch = (backbuffer->pitch >> 1) - 256; - src = (uint16*)ppu->output->buffer + (1 << 10); + +SNES::video_info vi; + snes->get_video_info(&vi); + + pitch = (backbuffer->pitch >> 1); dest = (uint16*)backbuffer->pixels; - for(y=0;y<223;y++) { - for(x=0;x<256;x++) { - *dest++ = color_lookup_table[*src]; - src += 2; + src = (uint16*)vi.data; + + if(vi.width == 256 && vi.height == 224) { + for(y=0;y<224;y++) { + memcpy(dest, src, 512); + dest += pitch; + src += 256; + } + } else if(vi.width == 512 && vi.height == 224) { + for(y=0;y<224;y++) { + memcpy(dest, src, 1024); + dest += pitch; + src += 512; + } + } else if(vi.width == 256 && vi.height == 448) { + for(y=0;y<448;y++) { + memcpy(dest, src, 512); + dest += pitch; + src += 256; + } + } else if(vi.width == 512 && vi.height == 448) { + for(y=0;y<448;y++) { + memcpy(dest, src, 1024); + dest += pitch; + src += 512; } - dest += pitch; - src += 512; } + + + screen_info.rs.x = 0; + screen_info.rs.y = (vi.height == 224) ? 1 : 2; + screen_info.rs.w = vi.width; + screen_info.rs.h = (vi.height == 224) ? 223 : 446; } -void render32() { -uint16 *src; -uint32 *dest, pitch; -int x, y; - pitch = (screen->pitch >> 2) - 256; - src = (uint16*)ppu->output->buffer + (1 << 10); - dest = (uint32*)screen->pixels; - for(y=0;y<223;y++) { - for(x=0;x<256;x++) { - *dest++ = color_lookup_table[*src]; - src += 2; - } - dest += pitch; - src += 512; - } -} +void render32() {} void render() { if(SDL_MUSTLOCK(screen)) { diff --git a/src/sdl/sdlmain.cpp b/src/sdl/sdlmain.cpp index e4f8f270..76d69354 100644 --- a/src/sdl/sdlmain.cpp +++ b/src/sdl/sdlmain.cpp @@ -1,14 +1,13 @@ #define INTERFACE_MAIN -#define BSNES_VERSION "0.011" -#define BSNES_TITLE "bsnes/SDL v" BSNES_VERSION #include "../base.h" #include "sdlmain.h" +#include "config.cpp" + #ifdef _WIN32_ HWND hwnd; #endif -#include "config.cpp" #include "bsnes.h" #include "rom.cpp" #include "render.cpp" @@ -47,24 +46,31 @@ va_list args; void init_snes() { mem_bus = new bMemBus(); cpu = new bCPU(); - if(cfg.apu.enabled) { - apu = new bAPU(); - } else { - apu = new bAPUSkip(); - } + apu = new bAPU(); + dsp = new bDSP(); ppu = new bPPU(); snes = new bSNES(); bsnes = static_cast(snes); snes->init(); + +//TODO: add sound support and remove this, +//this is used with linux/bsd and mkfifo to +//play audio in real-time while sound output +//isn't available. + snes->log_audio_enable("output.wav"); + + snes->set_playback_buffer_size(2000); } void term_snes() { - if(mem_bus) { delete(mem_bus); mem_bus = 0; } - if(cpu) { delete(cpu); cpu = 0; } - if(apu) { delete(apu); apu = 0; } - if(ppu) { delete(ppu); ppu = 0; } - if(snes) { delete(snes); snes = 0; } + snes->term(); + + if(mem_bus) { delete(static_cast(mem_bus)); mem_bus = 0; } + if(cpu) { delete(static_cast (cpu)); cpu = 0; } + if(apu) { delete(static_cast (apu)); apu = 0; } + if(ppu) { delete(static_cast (ppu)); ppu = 0; } + if(snes) { delete(static_cast (snes)); snes = 0; } } void center_window() { @@ -82,22 +88,17 @@ void set_window_info() { //SDL won't draw anything if you blit an image that's larger than //the display mode/window, even if you use the SoftStretch blit and //clip the source + dest rectangles properly... - if(cfg.video.display_width < cfg.video.output_width) { - cfg.video.display_width = cfg.video.output_width; + if((int)config::video.display_width < (int)config::video.output_width) { + config::video.display_width = config::video.output_width; } - if(cfg.video.display_height < cfg.video.output_height) { - cfg.video.display_height = cfg.video.output_height; + if((int)config::video.display_height < (int)config::video.output_height) { + config::video.display_height = config::video.output_height; } - screen_info.rd.x = (cfg.video.display_width - cfg.video.output_width ) >> 1; - screen_info.rd.y = (cfg.video.display_height - cfg.video.output_height) >> 1; - screen_info.rd.w = cfg.video.output_width; - screen_info.rd.h = cfg.video.output_height; - - screen_info.rs.x = 0; - screen_info.rs.y = 0; - screen_info.rs.w = 256; - screen_info.rs.h = 223; + screen_info.rd.x = ((int)config::video.display_width - (int)config::video.output_width ) >> 1; + screen_info.rd.y = ((int)config::video.display_height - (int)config::video.output_height) >> 1; + screen_info.rd.w = config::video.output_width; + screen_info.rd.h = config::video.output_height; } #ifdef _WIN32_ @@ -115,14 +116,13 @@ SDL_Event event; return 0; } - cfg.load("bsnes_sdl.cfg"); + config_file.load("bsnes_sdl.cfg"); rom_image = new ROMImage(); init_snes(); rom_image->select(argv[1]); rom_image->load(); - snes->power(); if(rom_image->loaded() == false) { alert("Failed to load image. Usage: bsnes_sdl "); @@ -132,13 +132,11 @@ SDL_Event event; SDL_Init(SDL_INIT_VIDEO); atexit(SDL_Quit); set_window_info(); - screen = SDL_SetVideoMode(cfg.video.display_width, cfg.video.display_height, 16, - SDL_SWSURFACE | ((cfg.video.fullscreen)?SDL_FULLSCREEN:0)); - if(!screen) { - alert("Failed to initialize SDL"); - goto _end; - } - backbuffer = SDL_CreateRGBSurface(SDL_SWSURFACE, 256, 223, 16, 0xf800, 0x07e0, 0x001f, 0x0000); + screen = SDL_SetVideoMode(config::video.display_width, config::video.display_height, 16, + SDL_SWSURFACE | ((config::video.fullscreen)?SDL_FULLSCREEN:0)); + if(!screen) { alert("Failed to initialize SDL"); goto _end; } + backbuffer = SDL_CreateRGBSurface(SDL_SWSURFACE, 512, 448, 16, 0xf800, 0x07e0, 0x001f, 0x0000); + if(!backbuffer) { alert("Failed to initialize SDL"); goto _end; } SDL_WM_SetCaption(BSNES_TITLE, 0); #ifdef _WIN32_ @@ -146,18 +144,21 @@ SDL_Event event; #endif center_window(); - update_color_lookup_table(); + snes->power(); bsnes->set_status(bSNES::RUN); int cursor_status; while(1) { - bsnes->snes_run(); + bsnes->run(); while(SDL_PollEvent(&event)) { switch(event.type) { case SDL_KEYUP: switch(event.key.keysym.sym) { case SDLK_ESCAPE: goto _end; + case SDLK_BACKSPACE: + snes->capture_screenshot(); + break; case SDLK_F10: //toggle cursor display cursor_status = (SDL_ShowCursor(SDL_QUERY) == SDL_ENABLE)?SDL_DISABLE:SDL_ENABLE; SDL_ShowCursor(cursor_status); @@ -174,7 +175,7 @@ int cursor_status; } _end: - cfg.save("bsnes_sdl.cfg"); + config_file.save("bsnes_sdl.cfg"); term_snes(); return 0; diff --git a/src/sdl/sdlmain.h b/src/sdl/sdlmain.h index d86de697..1ed322fb 100644 --- a/src/sdl/sdlmain.h +++ b/src/sdl/sdlmain.h @@ -13,5 +13,5 @@ SDL_Surface *screen, *backbuffer; struct { -SDL_Rect rs, rd; -}screen_info; + SDL_Rect rs, rd; +} screen_info; diff --git a/src/sdl/sdlrun.bat b/src/sdl/sdlrun.bat index 2aaf95ea..d397c2f2 100644 --- a/src/sdl/sdlrun.bat +++ b/src/sdl/sdlrun.bat @@ -1 +1 @@ -c:\root\bsnes_g2\bsnes_sdl.exe c:\root\bsnes_testrom\zelda_us.smc \ No newline at end of file +bsnes_sdl c:\root\bsnes_testrom\zelda_us.smc \ No newline at end of file diff --git a/src/snes/snes.cpp b/src/snes/snes.cpp index d80cffe8..b9564c7e 100644 --- a/src/snes/snes.cpp +++ b/src/snes/snes.cpp @@ -1,24 +1,48 @@ #include "../base.h" +#include "snes_video.cpp" +#include "snes_audio.cpp" +#include "snes_input.cpp" + void SNES::run() { -uint32 cycles; +uint32 cycles, r; if(apusync.cycles < 0) { cpu->run(); apusync.cycles += apusync.apu_multbl[cpu->cycles_executed()]; } else { apu->run(); - apusync.cycles -= apusync.cpu_multbl[apu->cycles_executed()]; + cycles = apu->cycles_executed(); + apusync.dsp += cycles; + apusync.cycles -= apusync.cpu_multbl[cycles]; + + //1024000(SPC700) / 32000(DSP) = 32spc/dsp ticks + //24576000(Sound clock crystal) / 32000(DSP) = 768crystal/dsp ticks + while(apusync.dsp >= 768) { + apusync.dsp -= 768; + audio_update(dsp->run()); + } } } void SNES::init() { srtc = new SRTC(); sdd1 = new SDD1(); + + srtc->init(); + sdd1->init(); + + video_init(); + audio_init(); +} + +void SNES::term() { + audio_term(); } void SNES::power() { cpu->power(); apu->power(); + dsp->power(); ppu->power(); mem_bus->power(); @@ -30,16 +54,19 @@ int i; for(i=0x2100;i<=0x213f;i++)mem_bus->set_mmio_mapper(i, ppu->mmio); for(i=0x2140;i<=0x217f;i++)mem_bus->set_mmio_mapper(i, cpu->mmio); for(i=0x2180;i<=0x2183;i++)mem_bus->set_mmio_mapper(i, cpu->mmio); -//S-RTC - mem_bus->set_mmio_mapper(0x2800, srtc->mmio); - mem_bus->set_mmio_mapper(0x2801, srtc->mmio); //input +mem_bus->set_mmio_mapper(0x4000, cpu->mmio); //test -- remove this mem_bus->set_mmio_mapper(0x4016, cpu->mmio); mem_bus->set_mmio_mapper(0x4017, cpu->mmio); for(i=0x4200;i<=0x421f;i++)mem_bus->set_mmio_mapper(i, cpu->mmio); for(i=0x4300;i<=0x437f;i++)mem_bus->set_mmio_mapper(i, cpu->mmio); -//S-DD1 - for(i=0x4800;i<=0x4807;i++)mem_bus->set_mmio_mapper(i, sdd1->mmio); + + srtc->enable(); + sdd1->enable(); + + memset(video.data, 0, 512 * 448 * sizeof(uint32)); + memset(video.ppu_data, 0, 512 * 480 * sizeof(uint16)); + video_update(); } void SNES::reset() { @@ -47,13 +74,30 @@ void SNES::reset() { cpu->reset(); apu->reset(); + dsp->reset(); ppu->reset(); mem_bus->reset(); srtc->reset(); sdd1->reset(); + + memset(video.data, 0, 512 * 448 * sizeof(uint32)); + memset(video.ppu_data, 0, 512 * 480 * sizeof(uint16)); + video_update(); } +void SNES::frame() { + video_update(); +} + +void SNES::scanline() { + video_scanline(); +} + +/**************** + *** PAL/NTSC *** + ****************/ + void SNES::set_region(uint8 new_region) { if(new_region == NTSC) { snes_region = NTSC; @@ -68,6 +112,10 @@ void SNES::set_region(uint8 new_region) { uint8 SNES::region() { return snes_region; } +/************** + *** Timing *** + **************/ + void SNES::update_timing() { apusync.cycles = 0; if(snes_region == NTSC) { @@ -87,6 +135,7 @@ int i; /*************************** *** Debugging functions *** ***************************/ + void SNES::notify(uint32 message, uint32 param1, uint32 param2) {} void SNES::debugger_enable() { @@ -102,8 +151,10 @@ bool SNES::debugger_enabled() { } SNES::SNES() { - is_debugger_enabled = true; + is_debugger_enabled = false; snes_region = NTSC; update_timing(); + + dsp_buffer.data = 0; } diff --git a/src/snes/snes.h b/src/snes/snes.h index a5e1699f..4524c304 100644 --- a/src/snes/snes.h +++ b/src/snes/snes.h @@ -6,10 +6,12 @@ uint8 snes_region; //APU synchronization struct { -int32 cpu_freq, apu_freq; -int32 cpu_multbl[1024], apu_multbl[1024]; -int32 cycles; -}apusync; + int32 cpu_freq, apu_freq; + int32 cpu_multbl[1024], apu_multbl[1024]; + int32 cycles; + + int32 dsp; +} apusync; void update_timing(); @@ -17,29 +19,22 @@ public: enum { NTSC = 0, PAL = 1 }; //system functions - void run(); - virtual void render_frame() = 0; - virtual void init(); - virtual void power(); - virtual void reset(); - virtual uint8 region(); - virtual void set_region(uint8 new_region); + virtual void run(); + virtual void init(); + virtual void term(); + virtual void power(); + virtual void reset(); -//input functions -enum { - DEV_JOYPAD1 = 0, - DEV_JOYPAD2 = 1 -}; -enum { - JOYPAD_B = 0, JOYPAD_Y = 1, - JOYPAD_SELECT = 2, JOYPAD_START = 3, - JOYPAD_UP = 4, JOYPAD_DOWN = 5, - JOYPAD_LEFT = 6, JOYPAD_RIGHT = 7, - JOYPAD_A = 8, JOYPAD_X = 9, - JOYPAD_L = 10, JOYPAD_R = 11 -}; - virtual void poll_input() = 0; - virtual bool get_input_status(uint8 device, uint8 button) = 0; + virtual void frame(); + virtual void scanline(); + +//PAL/NTSC + uint8 region(); + void set_region(uint8 new_region); + +#include "snes_video.h" +#include "snes_audio.h" +#include "snes_input.h" //debugging functions enum { @@ -53,10 +48,12 @@ enum { OAM_READ, OAM_WRITE, CGRAM_READ, CGRAM_WRITE, }; - virtual void notify(uint32 message, uint32 param1 = 0, uint32 param2 = 0); virtual void debugger_enable(); virtual void debugger_disable(); virtual bool debugger_enabled(); +//message functions + virtual void notify(uint32 message, uint32 param1 = 0, uint32 param2 = 0); + SNES(); }; diff --git a/src/snes/snes_audio.cpp b/src/snes/snes_audio.cpp new file mode 100644 index 00000000..5f10e603 --- /dev/null +++ b/src/snes/snes_audio.cpp @@ -0,0 +1,145 @@ +void SNES::set_playback_buffer_size(uint32 buffer_size) { + if(dsp_buffer.data) { + free(dsp_buffer.data); + dsp_buffer.data = 0; + } + +//* 2 is for left/right channel data + dsp_buffer.data = (uint16*)malloc(buffer_size * sizeof(uint16) * 2); + memset(dsp_buffer.data, 0, buffer_size * sizeof(uint16) * 2); + + dsp_buffer.size = buffer_size; + dsp_buffer.pos = 0; +} + +uint32 SNES::get_playback_buffer_pos() { + return dsp_buffer.pos; +} + +uint16 *SNES::get_playback_buffer() { + return dsp_buffer.data; +} + +void SNES::audio_update(uint32 data) { + if(pcmfp) { + fputc(data, pcmfp); + fputc(data >> 8, pcmfp); + fputc(data >> 16, pcmfp); + fputc(data >> 24, pcmfp); + } + + if((bool)config::snes.mute == true)data = 0x0000; + + dsp_buffer.data[dsp_buffer.pos++] = (data) & 0xffff; + dsp_buffer.data[dsp_buffer.pos++] = (data >> 16) & 0xffff; + dsp_buffer.pos %= dsp_buffer.size; + + sound_run(); +} + +void SNES::log_audio_enable(const char *fn) { +char tfn[256]; +int i; + if(pcmfp)log_audio_disable(); + + if(!fn) { + for(i=0;i<=999;i++) { + sprintf(tfn, "audio%0.3d.wav", i); + pcmfp = fopen(tfn, "rb"); + if(!pcmfp)break; + fclose(pcmfp); + pcmfp = 0; + } + if(i >= 1000)return; + } else { + strcpy(tfn, fn); + } + + pcmfp = fopen(tfn, "wb"); + if(!pcmfp)return; + +//header + fwrite("RIFF", 1, 4, pcmfp); +//file size + fputc(0, pcmfp); + fputc(0, pcmfp); + fputc(0, pcmfp); + fputc(0, pcmfp); +//format + fwrite("WAVE", 1, 4, pcmfp); + fwrite("fmt ", 1, 4, pcmfp); +//fmt size + fputc(0x12, pcmfp); + fputc(0x00, pcmfp); + fputc(0x00, pcmfp); + fputc(0x00, pcmfp); +//fmt type (PCM) + fputc(1, pcmfp); + fputc(0, pcmfp); +//channels + fputc(2, pcmfp); + fputc(0, pcmfp); +//sample rate (32000hz) + fputc(0x00, pcmfp); + fputc(0x7d, pcmfp); + fputc(0x00, pcmfp); + fputc(0x00, pcmfp); +//byte rate (32000 * 2 * (16 / 8) + fputc(0x00, pcmfp); + fputc(0xf4, pcmfp); + fputc(0x01, pcmfp); + fputc(0x00, pcmfp); +//block align (bytes per sample) (4) + fputc(4, pcmfp); + fputc(0, pcmfp); +//??? + fputc(0x10, pcmfp); + fputc(0x00, pcmfp); + fputc(0x00, pcmfp); + fputc(0x00, pcmfp); + fwrite("fact", 1, 4, pcmfp); + fputc(0x04, pcmfp); + fputc(0x00, pcmfp); + fputc(0x00, pcmfp); + fputc(0x00, pcmfp); + fputc(0x0b, pcmfp); + fputc(0xf4, pcmfp); + fputc(0x01, pcmfp); + fputc(0x00, pcmfp); +//data + fwrite("data", 1, 4, pcmfp); +//data size + fputc(0, pcmfp); + fputc(0, pcmfp); + fputc(0, pcmfp); + fputc(0, pcmfp); +} + +void SNES::log_audio_disable() { + if(pcmfp) { + int fsize, t; + fseek(pcmfp, 0, SEEK_END); + fsize = ftell(pcmfp); + fseek(pcmfp, 4, SEEK_SET); + t = fsize - 2; + fputc(t, pcmfp); + fputc(t >> 8, pcmfp); + fputc(t >> 16, pcmfp); + fputc(t >> 24, pcmfp); + fseek(pcmfp, 0x36, SEEK_SET); + t = fsize - 0x3a; + fputc(t, pcmfp); + fputc(t >> 8, pcmfp); + fputc(t >> 16, pcmfp); + fputc(t >> 24, pcmfp); + fclose(pcmfp); + pcmfp = 0; + } +} + +void SNES::audio_init() { +} + +void SNES::audio_term() { + log_audio_disable(); +} diff --git a/src/snes/snes_audio.h b/src/snes/snes_audio.h new file mode 100644 index 00000000..4ba04c88 --- /dev/null +++ b/src/snes/snes_audio.h @@ -0,0 +1,22 @@ +struct { + uint16 *data; + uint32 size, pos; +} dsp_buffer; + +FILE *pcmfp; + +//buffer_size is in samples + void set_playback_buffer_size(uint32 buffer_size); + uint32 get_playback_buffer_pos(); + uint16 *get_playback_buffer(); + +//if a filename is not specified, one will be generated +//automatically ("audio%0.3d.wav") + void log_audio_enable(const char *fn = 0); + void log_audio_disable(); + + void audio_update(uint32 data); + void audio_init(); + void audio_term(); + + virtual void sound_run() = 0; diff --git a/src/snes/snes_input.cpp b/src/snes/snes_input.cpp new file mode 100644 index 00000000..e69de29b diff --git a/src/snes/snes_input.h b/src/snes/snes_input.h new file mode 100644 index 00000000..73fe859f --- /dev/null +++ b/src/snes/snes_input.h @@ -0,0 +1,21 @@ +enum { + DEV_JOYPAD1 = 0, + DEV_JOYPAD2 = 1 +}; + +enum { + JOYPAD_B = 0, JOYPAD_Y = 1, + JOYPAD_SELECT = 2, JOYPAD_START = 3, + JOYPAD_UP = 4, JOYPAD_DOWN = 5, + JOYPAD_LEFT = 6, JOYPAD_RIGHT = 7, + JOYPAD_A = 8, JOYPAD_X = 9, + JOYPAD_L = 10, JOYPAD_R = 11 +}; + +//The CPU calls poll_input() when the main interface should check the +//status of all joypad buttons and cache the results... + virtual void poll_input() = 0; + +//...and then the CPU calls get_input_status() whenever it needs one +//of the cached button values to be returned for emulation purposes. + virtual bool get_input_status(uint8 device, uint8 button) = 0; diff --git a/src/snes/snes_video.cpp b/src/snes/snes_video.cpp new file mode 100644 index 00000000..b273bf6a --- /dev/null +++ b/src/snes/snes_video.cpp @@ -0,0 +1,385 @@ +#include "snes_video_ex.cpp" + +const uint8 SNES::color_curve_table[32] = { + 0x00, 0x01, 0x03, 0x06, 0x0a, 0x0f, 0x15, 0x1c, + 0x24, 0x2d, 0x37, 0x42, 0x4e, 0x5b, 0x69, 0x78, + 0x88, 0x90, 0x98, 0xa0, 0xa8, 0xb0, 0xb8, 0xc0, + 0xc8, 0xd0, 0xd8, 0xe0, 0xe8, 0xf0, 0xf8, 0xff +}; + +void SNES::update_color_lookup_table() { +int i, l, r, g, b; +double lr = 0.2126, lg = 0.7152, lb = 0.0722; //luminance + switch(video.depth) { + case 15: //rgb565 + for(i=0;i<32768;i++) { + r = (i ) & 31; + g = (i >> 5) & 31; + b = (i >> 10) & 31; + + if((bool)config::snes.video_color_curve == true) { + r = color_curve_table[r] >> 3; + g = color_curve_table[g] >> 3; + b = color_curve_table[b] >> 3; + } + + if((int)config::snes.video_color_adjust_mode == VCA_GRAYSCALE) { + r = (r << 3) | (r >> 2); + g = (g << 3) | (g >> 2); + b = (b << 3) | (b >> 2); + + l = int((double)r * lr) + ((double)g * lg) + ((double)b * lb); + if(l < 0)l = 0; + if(l > 255)l = 255; + r = g = b = l; + + r >>= 3; + g >>= 3; + b >>= 3; + } else if((int)config::snes.video_color_adjust_mode == VCA_VGA) { + //rgb555->rgb332 + r >>= 2; + g >>= 2; + b >>= 3; + + r = (r << 2) | (r >> 1); + g = (g << 2) | (g >> 1); + b = (b << 3) | (b << 1) | (b >> 1); + } else if((int)config::snes.video_color_adjust_mode == VCA_GENESIS) { + //rgb555->rgb333 + r >>= 2; + g >>= 2; + b >>= 2; + + r = (r << 2) | (r >> 1); + g = (g << 2) | (g >> 1); + b = (b << 2) | (b >> 1); + } + + color_lookup_table[i] = (r << 10) | (g << 5) | (b); + } + break; + case 16: //rgb565 + for(i=0;i<32768;i++) { + r = (i ) & 31; + g = (i >> 5) & 31; + b = (i >> 10) & 31; + + if((bool)config::snes.video_color_curve == true) { + r = color_curve_table[r] >> 3; + g = color_curve_table[g] >> 2; + b = color_curve_table[b] >> 3; + } else { + g = (g << 1) | (g >> 4); + } + + if((int)config::snes.video_color_adjust_mode == VCA_GRAYSCALE) { + r = (r << 3) | (r >> 2); + g = (g << 2) | (g >> 4); + b = (b << 3) | (b >> 2); + + l = int((double)r * lr) + ((double)g * lg) + ((double)b * lb); + if(l < 0)l = 0; + if(l > 255)l = 255; + r = g = b = l; + + r >>= 3; + g >>= 2; + b >>= 3; + } else if((int)config::snes.video_color_adjust_mode == VCA_VGA) { + //rgb565->rgb332 + r >>= 2; + g >>= 3; + b >>= 3; + + r = (r << 2) | (r >> 1); + g = (g << 3) | (g); + b = (b << 3) | (b << 1) | (b >> 1); + } else if((int)config::snes.video_color_adjust_mode == VCA_GENESIS) { + //rgb565->rgb333 + r >>= 2; + g >>= 3; + b >>= 2; + + r = (r << 2) | (r >> 1); + g = (g << 3) | (g); + b = (b << 2) | (b >> 1); + } + + color_lookup_table[i] = (r << 11) | (g << 5) | (b); + } + break; + default: + alert("Error: SNES::update_color_lookup_table() -- color depth %d not supported", video.depth); + break; + } +} + +void SNES::set_video_format(uint8 mode, uint8 depth) { +//only make changes at the start of a new frame + video.format_changed = true; + + video_changed.mode = mode; + video_changed.depth = depth; +} + +//internal function called at the start of the frame +//after SNES::set_video_format() is called +void SNES::update_video_format() { + video.mode = video_changed.mode; + video.depth = video_changed.depth; + + update_color_lookup_table(); + video.format_changed = false; +} + +void SNES::get_video_info(video_info *info) { + info->data = video.data; + info->mode = video.mode; + + switch(video.mode) { + case VM_256x224: + info->width = 256; + info->height = 224; + break; + case VM_512x224: + info->width = 512; + info->height = 224; + break; + case VM_256x448: + info->width = 256; + info->height = 448; + break; + case VM_512x448: + info->width = 512; + info->height = 448; + break; + case VM_VARIABLE: + if(video.frame_hires == false) { + info->width = 256; + } else { + info->width = 512; + } + + if(video.frame_interlace == false) { + info->height = 224; + } else { + info->height = 448; + } + + break; + } +} + +void SNES::video_update_256x224(uint16 *src) { +int x, y; +uint16 *dest; + dest = video.data; + + for(y=0;y<224;y++) { + if(video_frame[y].hires == false) { + for(x=0;x<256;x++) { + *dest++ = color_lookup_table[*src++]; + } + src += 768; + } else { + for(x=0;x<256;x++) { + *dest++ = color_lookup_table[*src]; + src += 2; + } + src += 512; + } + } +} + +void SNES::video_update_512x224(uint16 *src) { +int x, y; +uint16 *dest; + dest = video.data; + + for(y=0;y<224;y++) { + if(video_frame[y].hires == false) { + for(x=0;x<256;x++) { + *dest++ = color_lookup_table[*src]; + *dest++ = color_lookup_table[*src++]; + } + src += 768; + } else { + for(x=0;x<512;x++) { + *dest++ = color_lookup_table[*src++]; + } + src += 512; + } + } +} + +void SNES::video_update_256x448(uint16 *src) { +int x, y; +uint16 *dest; +bool field = !cpu->interlace_field(); + dest = video.data; + + for(y=0;y<224;y++) { + if(video_frame[y].interlace == false) { + if(video_frame[y].hires == false) { + for(x=0;x<512;x++) { + *dest++ = color_lookup_table[*(src + (uint8)x)]; + } + src += 1024; + } else { + for(x=0;x<512;x++) { + *dest++ = color_lookup_table[*(src + ((x & 255) << 1))]; + } + src += 1024; + } + } else { + if(field) { + dest += 256; + src += 512; + } + + if(video_frame[y].hires == false) { + for(x=0;x<256;x++) { + *dest++ = color_lookup_table[*src++]; + } + src += 256; + } else { + for(x=0;x<256;x++) { + *dest++ = color_lookup_table[*src]; + src += 2; + } + } + + if(!field) { + dest += 256; + src += 512; + } + } + } +} + +void SNES::video_update_512x448(uint16 *src) { +int x, y; +uint16 *dest; +bool field = !cpu->interlace_field(); + dest = video.data; + + for(y=0;y<224;y++) { + if(video_frame[y].interlace == false) { + if(video_frame[y].hires == false) { + for(x=0;x<512;x++) { + *dest++ = color_lookup_table[*(src + (uint8)x)]; + *dest++ = color_lookup_table[*(src + (uint8)x)]; + } + src += 1024; + } else { + for(x=0;x<1024;x++) { + *dest++ = color_lookup_table[*(src + (x & 511))]; + } + src += 1024; + } + } else { + if(field) { + dest += 512; + src += 512; + } + + if(video_frame[y].hires == false) { + for(x=0;x<256;x++) { + *dest++ = color_lookup_table[*(src + x)]; + *dest++ = color_lookup_table[*(src + x)]; + } + src += 512; + } else { + for(x=0;x<512;x++) { + *dest++ = color_lookup_table[*src++]; + } + } + + if(!field) { + dest += 512; + src += 512; + } + } + } +} + +void SNES::video_update() { + if(!ppu->render_frame())return; + + if(video.format_changed == true) { + update_video_format(); + } + +uint16 *src = (uint16*)video.ppu_data + ((int(cpu->overscan()) << 3) * 1024); + switch(video.mode) { + case VM_256x224:video_update_256x224(src);break; + case VM_512x224:video_update_512x224(src);break; + case VM_256x448:video_update_256x448(src);break; + case VM_512x448:video_update_512x448(src);break; + case VM_VARIABLE: + switch(int(video.frame_hires) | (int(video.frame_interlace) << 1)) { + case 0:video_update_256x224(src);break; + case 1:video_update_512x224(src);break; + case 2:video_update_256x448(src);break; + case 3:video_update_512x448(src);break; + } + break; + } + +//SNES::capture_screenshot() was called by emulation interface + if(flag_output_screenshot == true) { + output_screenshot(); + flag_output_screenshot = false; + } + + video_run(); + + video.frame_hires = false; + video.frame_interlace = false; +} + +void SNES::video_scanline() { +int y = cpu->vcounter(); +int o = int(cpu->overscan()) << 3; + if(y <= (0 + o) || y >= (224 + o))return; + y -= o; + +PPU::scanline_info si; + ppu->get_scanline_info(&si); + + video_frame[y].hires = si.hires; + video_frame[y].interlace = si.interlace; + + video.frame_hires |= si.hires; + video.frame_interlace |= si.interlace; +} + +uint16 *SNES::get_ppu_output_handle() { + return (uint16*)(video.ppu_data + + (cpu->vcounter() * 1024) + + ((cpu->interlace() && cpu->interlace_field())?512:0)); +} + +void SNES::video_init() { +int i, c; + video.format_changed = false; + + video.data = (uint16*)malloc(512 * 448 * sizeof(uint32)); + video.ppu_data = (uint16*)malloc(512 * 480 * sizeof(uint16)); + memset(video.data, 0, 512 * 448 * sizeof(uint32)); + memset(video.ppu_data, 0, 512 * 480 * sizeof(uint16)); + + for(i=0;i<224;i++) { + video_frame[i].hires = false; + video_frame[i].interlace = false; + } + + video.frame_hires = false; + video.frame_interlace = false; + + set_video_format(VM_VARIABLE, 16); + update_video_format(); + + flag_output_screenshot = false; +} diff --git a/src/snes/snes_video.h b/src/snes/snes_video.h new file mode 100644 index 00000000..df89b25d --- /dev/null +++ b/src/snes/snes_video.h @@ -0,0 +1,72 @@ +enum { + VM_256x224, //video data will be scaled to 256x224 + VM_512x224, //.. + VM_256x448, //.. + VM_512x448, //.. + VM_VARIABLE //video data can be 256x224 - 512x448 +}; + +enum { + VMF_NORMAL = 0, + VMF_HIRES = 1, + VMF_INTERLACE = 2, + VMF_HINTERLACE = 3 +}; + +//video color adjustment +//via config::snes.video_color_adjust_mode +enum { + VCA_NORMAL = 0, + VCA_GRAYSCALE = 1, + VCA_VGA = 2, + VCA_GENESIS = 3 +}; + +static const uint8 color_curve_table[32]; +uint32 color_lookup_table[32768]; + +struct { + uint16 *data, *ppu_data; + uint8 mode; + uint8 depth; + + bool frame_hires, frame_interlace; + + bool format_changed; +} video, video_changed; + +struct { + bool hires, interlace; +} video_frame[224]; + +struct video_info { + uint16 *data; + uint8 mode; + uint32 width, height; +}; + +//public functions + void capture_screenshot(); + void update_color_lookup_table(); + + virtual void set_video_format(uint8 mode, uint8 depth); + virtual void get_video_info(video_info *info); + virtual void video_run() = 0; + +//private functions + uint16 *get_ppu_output_handle(); //used by PPU only +private: +//when a screenshot is requested, wait until the frame +//has finished rendering, so we can tell the image size +bool flag_output_screenshot; + uint16 to_rgb555(uint32 color); + void output_screenshot(); + void update_video_format(); + void video_update_256x224(uint16 *src); + void video_update_512x224(uint16 *src); + void video_update_256x448(uint16 *src); + void video_update_512x448(uint16 *src); + void video_update(); + void video_scanline(); + void video_init(); +public: diff --git a/src/snes/snes_video_ex.cpp b/src/snes/snes_video_ex.cpp new file mode 100644 index 00000000..7a899f72 --- /dev/null +++ b/src/snes/snes_video_ex.cpp @@ -0,0 +1,106 @@ +void SNES::capture_screenshot() { + flag_output_screenshot = true; +} + +//used to convert pixel data to write to rgb555 format +//bitmap image via SNES::output_screenshot() function +uint16 SNES::to_rgb555(uint32 color) { + if(video.depth == 15) { + //rgb555 + return color & 0x7fff; + } + + if(video.depth == 16) { + //rgb565->rgb555 + return ((color >> 1) & 0x7fe0) | (color & 0x001f); + } + + if(video.depth == 24 || video.depth == 32) { + //rgb888->rgb555 + return ((color >> 9) & 0x7c00) | ((color >> 6) & 0x03e0) | ((color >> 3) & 0x001f); + } + +//unsupported color depth + return color; +} + +void SNES::output_screenshot() { +FILE *fp; +char fn[256]; +int i; +//get a file name that doesn't exit... + for(i=0;i<=999;i++) { + sprintf(fn, "image%0.3d.bmp", i); + fp = fopen(fn, "rb"); + if(!fp)break; + fclose(fp); + fp = 0; + } + if(i >= 1000)return; + + fp = fopen(fn, "wb"); + if(!fp)return; + +video_info vi; + get_video_info(&vi); +int width, height; + width = vi.width; + height = (vi.height == 224) ? 223 : 446; +int32 fsize; + fsize = 0x36 + (width * height * sizeof(uint16)); + +//header + fputc('B', fp); + fputc('M', fp); +//file size + fputc(fsize, fp); + fputc(fsize >> 8, fp); + fputc(fsize >> 16, fp); + fputc(fsize >> 24, fp); +//??? + fputc(0, fp); + fputc(0, fp); + fputc(0, fp); + fputc(0, fp); +//start of data + fputc(0x36, fp); + fputc(0x00, fp); + fputc(0x00, fp); + fputc(0x00, fp); +//remaining header size + fputc(0x28, fp); + fputc(0x00, fp); + fputc(0x00, fp); + fputc(0x00, fp); +//width + fputc(width, fp); + fputc(width >> 8, fp); + fputc(width >> 16, fp); + fputc(width >> 24, fp); +//height + fputc(height, fp); + fputc(height >> 8, fp); + fputc(height >> 16, fp); + fputc(height >> 24, fp); +//format + fputc(0x01, fp); + fputc(0x00, fp); +//bpp + fputc(16, fp); + fputc( 0, fp); +//??? + for(i=0;i<24;i++) { fputc(0, fp); } + +int x, y; +uint16 c; + for(y=height;y>=1;y--) { + for(x=0;x> 8, fp); + } + } + + fclose(fp); + fp = 0; +} diff --git a/src/win/Makefile b/src/win/Makefile index eb4de871..c0dc7955 100644 --- a/src/win/Makefile +++ b/src/win/Makefile @@ -6,10 +6,11 @@ OBJS = winmain.obj \ memory.obj bmemory.obj \ cpu.obj bcpu.obj \ apu.obj bapu.obj bapuskip.obj \ + bdsp.obj \ ppu.obj bppu.obj \ snes.obj \ srtc.obj sdd1.obj -LIBS = kernel32.lib user32.lib gdi32.lib comdlg32.lib ddraw.lib dxguid.lib +LIBS = kernel32.lib user32.lib gdi32.lib comdlg32.lib ddraw.lib dsound.lib dxguid.lib all: $(OBJS) rc /r /fobsnes.res bsnes.rc @@ -21,7 +22,7 @@ clean: ###################### ### win32-specific ### ###################### -winmain.obj: *.cpp *.h +winmain.obj: *.cpp *.h ../config/* $(CC) $(CFLAGS) /c winmain.cpp ################# @@ -62,6 +63,12 @@ bapu.obj: ../apu/bapu/* bapuskip.obj: ../apu/bapuskip/* $(CC) $(CFLAGS) /c ../apu/bapuskip/bapuskip.cpp +########### +### dsp ### +########### +bdsp.obj: ../dsp/bdsp/* + $(CC) $(CFLAGS) /c ../dsp/bdsp/bdsp.cpp + ########### ### ppu ### ########### diff --git a/src/win/bsnes.cpp b/src/win/bsnes.cpp index ee5a828f..9bddbd74 100644 --- a/src/win/bsnes.cpp +++ b/src/win/bsnes.cpp @@ -43,31 +43,31 @@ uint32 bSNES::get_status() { return run_status; } -void bSNES::snes_run() { +void bSNES::run() { if(!rom_image->loaded())return; switch(run_status) { case RUN: while(update_frame == false) { - run(); + SNES::run(); } update_frame = false; return; case STOP: break; case RUNONCE: - run(); + SNES::run(); set_status(STOP); break; case RUNTOSIGNAL: - run(); + SNES::run(); if(w_bp->hit() == true) { set_status(STOP); disassemble_bp_op(); } break; case RUNTOFRAME: - run(); + SNES::run(); if(update_frame == true) { update_frame = false; set_status(STOP); @@ -79,7 +79,7 @@ void bSNES::snes_run() { } return; case RUNTOCPUSTEP: - run(); + SNES::run(); if(status.cpu_ran == true) { set_status(STOP); } else if(w_bp->hit() == true) { @@ -88,7 +88,7 @@ void bSNES::snes_run() { } break; case RUNTOCPUPROCEED: - run(); + SNES::run(); if(cpu->in_opcode() == false && status.cpu_stop_pos == cpu->regs.pc.d) { set_status(STOP); disassemble_cpu_op(); @@ -98,14 +98,14 @@ void bSNES::snes_run() { } break; case RUNTOCPUTRACE: - run(); + SNES::run(); if(status.cpu_trace_pos >= status.cpu_trace_stop) { set_status(STOP); disassemble_cpu_op(); } break; case RUNTOAPUSTEP: - run(); + SNES::run(); if(status.apu_ran == true || w_bp->hit() == true) { set_status(STOP); } @@ -113,28 +113,32 @@ void bSNES::snes_run() { } } -void bSNES::render_frame() { +void bSNES::video_run() { dd_renderer->update(); } +void bSNES::sound_run() { + ds_sound->run(); +} + /*********************** *** Input functions *** ***********************/ void bSNES::poll_input() { //only capture input when main window has focus if(GetForegroundWindow() == w_main->hwnd) { - joypad1.up = KeyDown(cfg.input.joypad1.up); - joypad1.down = KeyDown(cfg.input.joypad1.down); - joypad1.left = KeyDown(cfg.input.joypad1.left); - joypad1.right = KeyDown(cfg.input.joypad1.right); - joypad1.select = KeyDown(cfg.input.joypad1.select); - joypad1.start = KeyDown(cfg.input.joypad1.start); - joypad1.y = KeyDown(cfg.input.joypad1.y); - joypad1.b = KeyDown(cfg.input.joypad1.b); - joypad1.x = KeyDown(cfg.input.joypad1.x); - joypad1.a = KeyDown(cfg.input.joypad1.a); - joypad1.l = KeyDown(cfg.input.joypad1.l); - joypad1.r = KeyDown(cfg.input.joypad1.r); + joypad1.up = KeyDown(config::input.joypad1.up); + joypad1.down = KeyDown(config::input.joypad1.down); + joypad1.left = KeyDown(config::input.joypad1.left); + joypad1.right = KeyDown(config::input.joypad1.right); + joypad1.select = KeyDown(config::input.joypad1.select); + joypad1.start = KeyDown(config::input.joypad1.start); + joypad1.y = KeyDown(config::input.joypad1.y); + joypad1.b = KeyDown(config::input.joypad1.b); + joypad1.x = KeyDown(config::input.joypad1.x); + joypad1.a = KeyDown(config::input.joypad1.a); + joypad1.l = KeyDown(config::input.joypad1.l); + joypad1.r = KeyDown(config::input.joypad1.r); } else { joypad1.up = joypad1.down = joypad1.left = joypad1.right = joypad1.select = joypad1.start = @@ -272,7 +276,6 @@ void bSNES::notify(uint32 message, uint32 param1, uint32 param2) { switch(message) { case RENDER_FRAME: update_frame = true; - render_frame(); break; } diff --git a/src/win/bsnes.h b/src/win/bsnes.h index 049e0400..41165c76 100644 --- a/src/win/bsnes.h +++ b/src/win/bsnes.h @@ -35,10 +35,12 @@ enum { RUNTOAPUSTEP }; enum { DRAM = 0, SPCRAM = 1, VRAM = 2, OAM = 3, CGRAM = 4 }; + void run(); + void video_run(); + void sound_run(); + void set_status(uint32 new_status); uint32 get_status(); - void snes_run(); - void render_frame(); //input functions void poll_input(); diff --git a/src/win/bsnes.lnk b/src/win/bsnes.lnk index e83cb0a0933e6b14f67f88d06f30be7ebe83294c..ce73821edf28a2decde76ca9652d3ef48295ff8d 100644 GIT binary patch delta 275 zcmeC-`ph{&#&E&E!_wi0jxsVRygcj&rd4FX{12QAAixMF5yb6@zJB#q#taG~K(Qi* zd>||VvP2ln7!1LxW*9{*6JSUx&Py$3P-0+aU}1Q_4pPg zfL2)B7zHLzV3cNuSSAHxvx3=^k1?9^0$mAFte0AmI$4nE+GGVL&dJZ244~>`CJQi% KZZ>8EBvBH}VCD2ga3D&jJzI4X`HASfaVE(i!H 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 diff --git a/src/win/config.cpp b/src/win/config.cpp index 9520d449..8f2427ca 100644 --- a/src/win/config.cpp +++ b/src/win/config.cpp @@ -1,52 +1,40 @@ -#define __config_add(name, def, type) add(&name, #name, def, type) +namespace config { -class Config : public config { -public: +struct Video { + static Setting mode, use_vram, vblank; +} video; +Setting Video::mode(&config_file, "video.mode", + "Video mode\n" + " 0 = 256x224w\n" + " 1 = 512x448w\n" + " 2 = 960x720w\n" + " 3 = 640x480f\n" + " 4 = 1024x768f", + 1, Setting::DEC); +Setting Video::use_vram(&config_file, "video.use_vram", "Use Video RAM instead of System RAM", true, Setting::TRUE_FALSE); +Setting Video::vblank(&config_file, "video.vblank", "Wait for vertical retrace when updating screen", false, Setting::TRUE_FALSE); -struct { - uint32 enabled; -}apu; +struct GUI { + static Setting show_fps; +} gui; +Setting GUI::show_fps(&config_file, "gui.show_fps", "Show framerate in window title", true, Setting::TRUE_FALSE); -struct { - uint32 mode; - uint32 use_vram; - uint32 color_curve; - uint32 vblank; -}video; +struct Input { + struct Joypad { + static Setting up, down, left, right, a, b, x, y, l, r, select, start; + } joypad1; +} input; +Setting Input::Joypad::up (&config_file, "input.joypad1.up", "Joypad1 up", VK_UP, Setting::HEX); +Setting Input::Joypad::down (&config_file, "input.joypad1.down", "Joypad1 down", VK_DOWN, Setting::HEX); +Setting Input::Joypad::left (&config_file, "input.joypad1.left", "Joypad1 left", VK_LEFT, Setting::HEX); +Setting Input::Joypad::right (&config_file, "input.joypad1.right", "Joypad1 right", VK_RIGHT, Setting::HEX); +Setting Input::Joypad::a (&config_file, "input.joypad1.a", "Joypad1 A", 'X', Setting::HEX); +Setting Input::Joypad::b (&config_file, "input.joypad1.b", "Joypad1 B", 'Z', Setting::HEX); +Setting Input::Joypad::x (&config_file, "input.joypad1.x", "Joypad1 X", 'S', Setting::HEX); +Setting Input::Joypad::y (&config_file, "input.joypad1.y", "Joypad1 Y", 'A', Setting::HEX); +Setting Input::Joypad::l (&config_file, "input.joypad1.l", "Joypad1 L", 'D', Setting::HEX); +Setting Input::Joypad::r (&config_file, "input.joypad1.r", "Joypad1 R", 'C', Setting::HEX); +Setting Input::Joypad::select(&config_file, "input.joypad1.select", "Joypad1 select", VK_SHIFT, Setting::HEX); +Setting Input::Joypad::start (&config_file, "input.joypad1.start", "Joypad1 start", VK_RETURN, Setting::HEX); -struct { - struct { - uint32 up, down, left, right; - uint32 a, b, x, y, l, r; - uint32 select, start; - }joypad1; -}input; - -struct { - uint32 show_fps; -}gui; - - Config() { - __config_add(apu.enabled, true, TRUEFALSE); - - __config_add(video.mode, 1, DEC); - __config_add(video.use_vram, true, TRUEFALSE); - __config_add(video.color_curve, true, ENABLED); - __config_add(video.vblank, false, TRUEFALSE); - - __config_add(input.joypad1.up, VK_UP, HEX); - __config_add(input.joypad1.down, VK_DOWN, HEX); - __config_add(input.joypad1.left, VK_LEFT, HEX); - __config_add(input.joypad1.right, VK_RIGHT, HEX); - __config_add(input.joypad1.a, 'X', HEX); - __config_add(input.joypad1.b, 'Z', HEX); - __config_add(input.joypad1.x, 'S', HEX); - __config_add(input.joypad1.y, 'A', HEX); - __config_add(input.joypad1.l, 'D', HEX); - __config_add(input.joypad1.r, 'C', HEX); - __config_add(input.joypad1.select, VK_SHIFT, HEX); - __config_add(input.joypad1.start, VK_RETURN, HEX); - - __config_add(gui.show_fps, true, TRUEFALSE); - } -}cfg; +}; diff --git a/src/win/dd_renderer.cpp b/src/win/dd_renderer.cpp index 1c2484ec..0e6d88ec 100644 --- a/src/win/dd_renderer.cpp +++ b/src/win/dd_renderer.cpp @@ -4,68 +4,6 @@ DDRenderer::DDRenderer() { lpdds = 0; lpddsb = 0; lpddc = 0; - -int i, c; - for(i=0,c=0;i<16;i++) { - color_curve_table[i] = c; - c = c + i + 1; - } - for(;i<31;i++) { - color_curve_table[i] = c; - c += 8; - } - color_curve_table[i] = 0xff; -} - -void DDRenderer::update_color_lookup_table() { -int i, r, g, b; - lpddsb->GetSurfaceDesc(&ddsd); - color_depth = ddsd.ddpfPixelFormat.dwRGBBitCount; - if(color_depth == 15) { - for(i=0;i<32768;i++) { - r = (i ) & 31; - g = (i >> 5) & 31; - b = (i >> 10) & 31; - if(cfg.video.color_curve) { - r = color_curve_table[r] >> 3; - g = color_curve_table[g] >> 3; - b = color_curve_table[b] >> 3; - } - color_lookup_table[i] = (r << 10) | (g << 5) | (b); - } - } else if(color_depth == 16) { - for(i=0;i<32768;i++) { - r = (i ) & 31; - g = (i >> 5) & 31; - b = (i >> 10) & 31; - if(cfg.video.color_curve) { - r = color_curve_table[r] >> 3; - g = color_curve_table[g] >> 2; - b = color_curve_table[b] >> 3; - } else { - g = (g << 1) | (g >> 4); - } - color_lookup_table[i] = (r << 11) | (g << 5) | (b); - } - } else if(color_depth == 32) { - for(i=0;i<32768;i++) { - r = (i ) & 31; - g = (i >> 5) & 31; - b = (i >> 10) & 31; - if(cfg.video.color_curve) { - r = color_curve_table[r]; - g = color_curve_table[g]; - b = color_curve_table[b]; - } else { - r = (r << 3) | (r >> 2); - g = (g << 3) | (g >> 2); - b = (b << 3) | (b >> 2); - } - color_lookup_table[i] = (r << 16) | (g << 8) | (b); - } - } else { - alert("Error: Unsupported color depth [%d]", color_depth); - } } void DDRenderer::set_window(HWND hwnd_handle) { hwnd = hwnd_handle; } @@ -76,25 +14,24 @@ void DDRenderer::set_window(HWND hwnd_handle) { hwnd = hwnd_handle; } handles conversion from 16bpp->32bpp in hardware. This only works when both the source and dest buffers are in VRAM, though. - The SNES resolution is 256x224. The top scanline is never drawn, so - 256x223 is used. Hires mode doubles the screen width, and hires+interlace - double the screen height, making the resolution 512x446. + The SNES resolution is 256x224. Hires mode doubles the screen width, and + hires+interlace double the screen height, making the resolution 512x448. There is one more problem, however. On some video cards, when blitting - from video memory from 256x223->512x446, a bilinear filter is applied by + from video memory from 256x224->512x448, a bilinear filter is applied by the video card, and sometimes this filter tries to read past the source video memory to get interpolation data. This results in a line of garble on the right and bottom edges of the screen. Therefore, an additional 4 pixels in each direction is added to the backbuffer. - The backbuffer is thusly 512+4 * 476+4 + The backbuffer is thusly 512+4 * 480+4 */ void DDRenderer::create_backbuffer() { -int color_depth; +int depth; lpdds->GetSurfaceDesc(&ddsd); - color_depth = ddsd.ddpfPixelFormat.dwRGBBitCount; - if(color_depth == 15 || color_depth == 16) { + depth = ddsd.ddpfPixelFormat.dwRGBBitCount; + if(depth == 15 || depth == 16) { goto try_native_backbuffer; } else { - if(cfg.video.use_vram == false) { + if((int)config::video.use_vram == false) { goto try_native_backbuffer; } } @@ -103,14 +40,14 @@ int color_depth; ddsd.dwSize = sizeof(DDSURFACEDESC); ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; - if(cfg.video.use_vram) { + if(config::video.use_vram) { ddsd.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY; } else { ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; } ddsd.dwWidth = 512 + 4; - ddsd.dwHeight = 476 + 4; + ddsd.dwHeight = 480 + 4; ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT); ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB; @@ -126,14 +63,14 @@ try_native_backbuffer: ddsd.dwSize = sizeof(DDSURFACEDESC); ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; - if(cfg.video.use_vram) { + if(config::video.use_vram) { ddsd.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY; } else { ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; } ddsd.dwWidth = 512 + 4; - ddsd.dwHeight = 476 + 4; + ddsd.dwHeight = 480 + 4; lpdd->CreateSurface(&ddsd, &lpddsb, 0); @@ -147,6 +84,9 @@ DDBLTFX fx; fx.dwSize = sizeof(DDBLTFX); fx.dwFillColor = 0x00000000; lpddsb->Blt(0, 0, 0, DDBLT_WAIT | DDBLT_COLORFILL, &fx); + + lpddsb->GetSurfaceDesc(&ddsd); + color_depth = ddsd.ddpfPixelFormat.dwRGBBitCount; } void DDRenderer::to_windowed() { @@ -166,7 +106,6 @@ void DDRenderer::to_windowed() { lpdds->SetClipper(lpddc); create_backbuffer(); - update_color_lookup_table(); redraw(); } @@ -195,14 +134,13 @@ void DDRenderer::to_fullscreen(int _width, int _height) { lpdds->SetClipper(lpddc); create_backbuffer(); - update_color_lookup_table(); redraw(); } void DDRenderer::set_source_window() { - SetRect(&lpddrc, 0, 0, - (ppu->output->hires == false)?256:512, - (ppu->output->interlace == false)?223:446); +//skip first scanline +int i = (vi.height == 224) ? 1 : 2; + SetRect(&lpddrc, 0, i, vi.width, vi.height); } void DDRenderer::redraw() { @@ -226,7 +164,7 @@ int rx, ry; break; } } - if(cfg.video.vblank) { + if(config::video.vblank) { lpdd->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, 0); } hr = lpdds->Blt(&rd, lpddsb, &lpddrc, DDBLT_WAIT, 0); @@ -235,7 +173,7 @@ int rx, ry; lpddsb->Restore(); } - if(cfg.gui.show_fps == false || bsnes->get_status() == bSNES::STOP)return; + if((int)config::gui.show_fps == false || bsnes->get_status() == bSNES::STOP)return; uint32 fps; char s[256], t[256]; fps_timer->tick(); @@ -262,24 +200,22 @@ HRESULT hr; if(hr != DD_OK)return; set_source_window(); - if(ppu->output->hires == false) { - if(ppu->output->interlace == false) { - update16_256x224(); - } else { - update16_256x448(); - } - } else { - if(ppu->output->interlace == false) { - update16_512x224(); - } else { - update16_512x448(); - } + + if (vi.width == 256 && vi.height == 224) { + update16_256x224(); + } else if(vi.width == 512 && vi.height == 224) { + update16_512x224(); + } else if(vi.width == 256 && vi.height == 448) { + update16_256x448(); + } else if(vi.width == 512 && vi.height == 448) { + update16_512x448(); } lpddsb->Unlock(0); } -#include "dd_renderer32.cpp" +//#include "dd_renderer32.cpp" +/* void DDRenderer::update32() { HRESULT hr; hr = lpddsb->Lock(0, &ddsd, DDLOCK_WAIT, 0); @@ -302,17 +238,21 @@ HRESULT hr; lpddsb->Unlock(0); } +*/ void DDRenderer::update() { + snes->get_video_info(&vi); + switch(color_depth) { case 15: case 16: update16(); break; case 32: - update32(); + //update32(); break; } + redraw(); } diff --git a/src/win/dd_renderer.h b/src/win/dd_renderer.h index 3a9c8f5d..b98127ec 100644 --- a/src/win/dd_renderer.h +++ b/src/win/dd_renderer.h @@ -1,4 +1,5 @@ #include + class DDRenderer { public: LPDIRECTDRAW lpdd; @@ -9,11 +10,10 @@ DDSURFACEDESC ddsd; DDSCAPS ddscaps; RECT lpddrc; HWND hwnd; -bool fullscreen; -int width, height; //used for fullscreen mode clipping only -uint8 color_depth; -uint8 color_curve_table[32]; -uint32 color_lookup_table[32768]; +bool fullscreen; +int width, height; //used for fullscreen mode clipping only +uint8 color_depth; +SNES::video_info vi; //initialized each frame at start of update() void set_window(HWND hwnd_handle); void create_backbuffer(); void to_windowed(); @@ -21,18 +21,17 @@ uint32 color_lookup_table[32768]; void set_source_window(); void redraw(); inline void update16_256x224(); - inline void update16_256x448(); inline void update16_512x224(); + inline void update16_256x448(); inline void update16_512x448(); void update16(); - inline void update32_256x224(); - inline void update32_256x448(); - inline void update32_512x224(); - inline void update32_512x448(); - void update32(); +//inline void update32_256x224(); +//inline void update32_512x224(); +//inline void update32_256x448(); +//inline void update32_512x448(); +//void update32(); void update(); void destroy(); - void update_color_lookup_table(); DDRenderer(); }; diff --git a/src/win/dd_renderer16.cpp b/src/win/dd_renderer16.cpp index 0f50abb5..6a4fef80 100644 --- a/src/win/dd_renderer16.cpp +++ b/src/win/dd_renderer16.cpp @@ -1,123 +1,79 @@ inline void DDRenderer::update16_256x224() { -uint16 *src; -uint16 *dest; +uint16 *src, *dest; uint32 pitch; int x, y; - src = (uint16*)ppu->output->buffer + (1 << 10); - dest = (uint16*)ddsd.lpSurface; - pitch = (ddsd.lPitch >> 1) - 256; + dest = (uint16*)ddsd.lpSurface; + src = (uint16*)vi.data; -int overscan_adjust = 0; - if(cpu->overscan() == true) { - src += 7 << 10; - overscan_adjust = 7; +#ifdef USE_X86_ASM + pitch = (ddsd.lPitch) - 512; + __asm { + mov edi,dest + mov esi,src + mov edx,224 + ly: + mov ecx,32 + lx: + movsd + movsd + movsd + movsd + loopnz lx + add edi,pitch + dec edx + jnz ly } +#else + pitch = (ddsd.lPitch >> 1); + for(y=0;y<224;y++) { + memcpy(dest, src, 512); + dest += pitch; + src += 256; + } +#endif +} - for(y=1+overscan_adjust;y<224+overscan_adjust;y++) { - x = 256; - while(x--) { - *dest++ = color_lookup_table[*src]; - src += 2; - } +inline void DDRenderer::update16_512x224() { +uint16 *src, *dest; +uint32 pitch; +int x, y; + pitch = (ddsd.lPitch >> 1); + dest = (uint16*)ddsd.lpSurface; + src = (uint16*)vi.data; + + for(y=0;y<224;y++) { + memcpy(dest, src, 1024); dest += pitch; src += 512; } } inline void DDRenderer::update16_256x448() { -uint16 *src; -uint16 *dest; +uint16 *src, *dest; uint32 pitch; int x, y; - src = (uint16*)ppu->output->buffer + (1 << 10); + pitch = (ddsd.lPitch >> 1); dest = (uint16*)ddsd.lpSurface; - pitch = (ddsd.lPitch >> 1) - 256; + src = (uint16*)vi.data; -int overscan_adjust = 0; - if(cpu->overscan() == true) { - src += 7 << 10; - overscan_adjust = 14; - } - - for(y=2+overscan_adjust;y<448+overscan_adjust;y++) { - x = 256; - while(x--) { - *dest++ = color_lookup_table[*src]; - src += 2; - } + for(y=0;y<448;y++) { + memcpy(dest, src, 512); dest += pitch; - if(ppu->output->line[y >> 1].interlace == false) { - src += (y & 1)?512:-512; - } - } -} - -inline void DDRenderer::update16_512x224() { -uint16 *src; -uint16 *dest; -uint32 pitch; -int x, y; - src = (uint16*)ppu->output->buffer + (1 << 10); - dest = (uint16*)ddsd.lpSurface; - pitch = (ddsd.lPitch >> 1) - 512; - -int overscan_adjust = 0; - if(cpu->overscan() == true) { - src += 7 << 10; - overscan_adjust = 7; - } - - for(y=1+overscan_adjust;y<224+overscan_adjust;y++) { - if(ppu->output->line[y].hires == true) { - x = 512; - while(x--) { - *dest++ = color_lookup_table[*src++]; - } - } else { - x = 256; - while(x--) { - *dest++ = color_lookup_table[*src]; - *dest++ = color_lookup_table[*src]; - src += 2; - } - } - dest += pitch; - src += 512; + src += 256; } } inline void DDRenderer::update16_512x448() { -uint16 *src; -uint16 *dest; +uint16 *src, *dest; uint32 pitch; int x, y; - src = (uint16*)ppu->output->buffer + (1 << 10); + pitch = (ddsd.lPitch >> 1); dest = (uint16*)ddsd.lpSurface; - pitch = (ddsd.lPitch >> 1) - 512; + src = (uint16*)vi.data; -int overscan_adjust = 0; - if(cpu->overscan() == true) { - src += 7 << 10; - overscan_adjust = 14; - } - - for(y=2+overscan_adjust;y<448+overscan_adjust;y++) { - if(ppu->output->line[y >> 1].hires == true) { - x = 512; - while(x--) { - *dest++ = color_lookup_table[*src++]; - } - } else { - x = 256; - while(x--) { - *dest++ = color_lookup_table[*src]; - *dest++ = color_lookup_table[*src]; - src += 2; - } - } + for(y=0;y<448;y++) { + memcpy(dest, src, 1024); dest += pitch; - if(ppu->output->line[y >> 1].interlace == false) { - src += (y & 1)?512:-512; - } + src += 512; } } diff --git a/src/win/ds_sound.cpp b/src/win/ds_sound.cpp new file mode 100644 index 00000000..ab6862e8 --- /dev/null +++ b/src/win/ds_sound.cpp @@ -0,0 +1,77 @@ +DSSound::DSSound() { + data.buffer = 0; + data.lpos = data.lsample = data.lbuffer = 0; +} + +void DSSound::run() { + if(snes->get_playback_buffer_pos() != 0)return; + +uint32 pos, status; + +//dsb_b[0]->SetFrequency(22050); + +//do { +// dsb_b[0]->GetStatus(&status); +//} while(status & DSBSTATUS_PLAYING); + + dsb_b[0]->Lock(0, DSP_BUFFER_SIZE * 4, &dslb, &dslbs, 0, 0, 0); + memcpy(dslb, snes->get_playback_buffer(), DSP_BUFFER_SIZE * 4); + dsb_b[0]->Unlock(dslb, dslbs, 0, 0); + + dsb_b[0]->SetCurrentPosition(0); + +//has the buffer stopped (possibly due to running too fast)? + dsb_b[0]->GetStatus(&status); + if(!(status & DSBSTATUS_PLAYING)) { + dsb_b[0]->Play(0, 0, 0); + } +} + +void DSSound::init() { + DirectSoundCreate(0, &ds, 0); + ds->SetCooperativeLevel(w_main->hwnd, DSSCL_PRIORITY); + + memset(&dsbd, 0, sizeof(dsbd)); + dsbd.dwSize = sizeof(dsbd); + dsbd.dwFlags = DSBCAPS_PRIMARYBUFFER; + dsbd.dwBufferBytes = 0; + dsbd.lpwfxFormat = 0; + ds->CreateSoundBuffer(&dsbd, &dsb_p, 0); + + memset(&wfx, 0, sizeof(wfx)); + wfx.wFormatTag = WAVE_FORMAT_PCM; + wfx.nChannels = 2; + wfx.nSamplesPerSec = 32000; + wfx.wBitsPerSample = 16; + wfx.nBlockAlign = wfx.wBitsPerSample / 8 * wfx.nChannels; + wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; + dsb_p->SetFormat(&wfx); + + sample_size = (16 / 8) * 2; + buffer_size = DSP_BUFFER_SIZE * sample_size; + buffer_pos = 0; + + dsb_b = new LPDIRECTSOUNDBUFFER[1]; + memset(&dsbd, 0, sizeof(dsbd)); + dsbd.dwSize = sizeof(dsbd); + dsbd.dwFlags = DSBCAPS_CTRLFREQUENCY | DSBCAPS_GLOBALFOCUS; + dsbd.dwBufferBytes = buffer_size; + dsbd.guid3DAlgorithm = GUID_NULL; + dsbd.lpwfxFormat = &wfx; + ds->CreateSoundBuffer(&dsbd, &dsb_b[0], 0); + ds->CreateSoundBuffer(&dsbd, &dsb_b[1], 0); + dsb_b[0]->SetFrequency(32000); + dsb_b[1]->SetFrequency(32000); + + dsb_b[0]->Lock(0, buffer_size, &dslb, &dslbs, 0, 0, 0); + memset(dslb, 0, buffer_size); + dsb_b[0]->Unlock(dslb, dslbs, 0, 0); + + dsb_b[1]->Lock(0, buffer_size, &dslb, &dslbs, 0, 0, 0); + memset(dslb, 0, buffer_size); + dsb_b[1]->Unlock(dslb, dslbs, 0, 0); + + dsb_b[0]->Play(0, 0, 0); + + buffer_pos = 0; +} diff --git a/src/win/ds_sound.h b/src/win/ds_sound.h new file mode 100644 index 00000000..d580facb --- /dev/null +++ b/src/win/ds_sound.h @@ -0,0 +1,30 @@ +#include + +class DSSound { +public: +LPDIRECTSOUND ds; +LPDIRECTSOUNDBUFFER dsb_p, *dsb_b; +DSBUFFERDESC dsbd; +WAVEFORMATEX wfx; +uint32 sample_size; +uint32 buffer_size; +uint32 buffer_pos; + +void *dslb; +uint32 dslbs; + +public: + void run(); + void init(); + + DSSound(); +}; + +struct { + uint32 *buffer; + uint32 lpos; + uint32 lsample; + bool lbuffer; +} data; + +DSSound *ds_sound; diff --git a/src/win/ui.cpp b/src/win/ui.cpp index 5969c8d2..46ae9c34 100644 --- a/src/win/ui.cpp +++ b/src/win/ui.cpp @@ -2,6 +2,7 @@ HFONT hFont, hMonofont; HBRUSH hbr_backbrush; #include "dd_renderer.cpp" +#include "ds_sound.cpp" #include "uictl_editex.cpp" #include "ui_window.cpp" #include "ui_main.cpp" @@ -38,6 +39,7 @@ void CreateWindows() { void init_ui0() { dd_renderer = new DDRenderer(); + ds_sound = new DSSound(); w_main = new MainWindow(); w_console = new Console(); w_bp = new BreakpointEditor(); @@ -52,9 +54,10 @@ void init_ui1() { SetFocus(w_main->hwnd); dd_renderer->set_window(w_main->hwnd); dd_renderer->to_windowed(); + ds_sound->init(); w_main->show_menu(); - w_main->set_video_mode(cfg.video.mode); + w_main->set_video_mode(config::video.mode); w_main->set_frameskip(0); bsnes->debugger_deactivate(); diff --git a/src/win/ui.h b/src/win/ui.h index 8d207ca4..0ece67b8 100644 --- a/src/win/ui.h +++ b/src/win/ui.h @@ -29,14 +29,19 @@ enum { MENU_SETTINGS_VIDEOMODE_960x720w, MENU_SETTINGS_VIDEOMODE_640x480f, MENU_SETTINGS_VIDEOMODE_1024x768f, + MENU_SETTINGS_COLORADJUST_COLORCURVE, + MENU_SETTINGS_COLORADJUST_NORMAL, + MENU_SETTINGS_COLORADJUST_GRAYSCALE, + MENU_SETTINGS_COLORADJUST_VGA, + MENU_SETTINGS_COLORADJUST_GENESIS, MENU_SETTINGS_USEVRAM, MENU_SETTINGS_VBLANK, - MENU_SETTINGS_COLORCURVE, MENU_SETTINGS_SHOWFPS, - MENU_SETTINGS_APUENABLED, + MENU_SETTINGS_MUTE, MENU_SETTINGS_INPUTCFG_JOYPAD1, MENU_SETTINGS_DEBUGGER, MENU_MISC_SCREENSHOT, + MENU_MISC_LOGAUDIO, MENU_MISC_ABOUT }; diff --git a/src/win/ui_console.cpp b/src/win/ui_console.cpp index dcd1c059..52cf61fc 100644 --- a/src/win/ui_console.cpp +++ b/src/win/ui_console.cpp @@ -284,7 +284,7 @@ static uint8 linecol[4] = { 1, 2, 3 }; cpu->vcounter(), cpu->hcounter(), cpu->hcycles(), cpu->interlace(), cpu->interlace_field(), cpu->overscan()); strcat(s, t); - if(cfg.apu.enabled) { + if(1) { //config::apu.enabled sprintf(t, " -- CPU[$%0.2x,$%0.2x,$%0.2x,$%0.2x]<>APU[$%0.2x,$%0.2x,$%0.2x,$%0.2x]", cpu->port_read(0), cpu->port_read(1), cpu->port_read(2), cpu->port_read(3), apu->port_read(0), apu->port_read(1), apu->port_read(2), apu->port_read(3) diff --git a/src/win/ui_inputconfig.cpp b/src/win/ui_inputconfig.cpp index e5d5a732..258603b6 100644 --- a/src/win/ui_inputconfig.cpp +++ b/src/win/ui_inputconfig.cpp @@ -38,18 +38,18 @@ bool end_config = false; switch(config_type) { case JOYPAD1: switch(config_pos) { - case 0:cfg.input.joypad1.up = key;break; - case 1:cfg.input.joypad1.down = key;break; - case 2:cfg.input.joypad1.left = key;break; - case 3:cfg.input.joypad1.right = key;break; - case 4:cfg.input.joypad1.select = key;break; - case 5:cfg.input.joypad1.start = key;break; - case 6:cfg.input.joypad1.x = key;break; - case 7:cfg.input.joypad1.y = key;break; - case 8:cfg.input.joypad1.a = key;break; - case 9:cfg.input.joypad1.b = key;break; - case 10:cfg.input.joypad1.l = key;break; - case 11:cfg.input.joypad1.r = key;break; + case 0:config::input.joypad1.up = key;break; + case 1:config::input.joypad1.down = key;break; + case 2:config::input.joypad1.left = key;break; + case 3:config::input.joypad1.right = key;break; + case 4:config::input.joypad1.select = key;break; + case 5:config::input.joypad1.start = key;break; + case 6:config::input.joypad1.x = key;break; + case 7:config::input.joypad1.y = key;break; + case 8:config::input.joypad1.a = key;break; + case 9:config::input.joypad1.b = key;break; + case 10:config::input.joypad1.l = key;break; + case 11:config::input.joypad1.r = key;break; case 12:end_config = true;break; } config_pos++; diff --git a/src/win/ui_main.cpp b/src/win/ui_main.cpp index 855670bf..2b2c863b 100644 --- a/src/win/ui_main.cpp +++ b/src/win/ui_main.cpp @@ -95,7 +95,7 @@ void MainWindow::set_video_mode(uint8 mode) { break; } - cfg.video.mode = mode; + config::video.mode = mode; show(); } @@ -107,8 +107,8 @@ char t[4096]; ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = hwnd; - ofn.lpstrFilter = "SNES ROM Images (*.smc;*.swc;*.fig;*.ufo;*.gd3;*.078)\0" - "*.smc;*.swc;*.fig;*.ufo;*.gd3;*.078\0" + ofn.lpstrFilter = "SNES ROM Images (*.smc;*.sfc;*.swc;*.fig;*.ufo;*.gd3;*.078)\0" + "*.smc;*.sfc;*.swc;*.fig;*.ufo;*.gd3;*.078\0" "All Files (*.*)\0" "*.*\0"; ofn.lpstrFile = t; @@ -133,6 +133,7 @@ void MainWindow::menu_unload() { long __stdcall wndproc_main(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { time_t timeout; +int i; switch(msg) { case WM_KEYDOWN: if(wparam == VK_ESCAPE) { @@ -145,7 +146,7 @@ time_t timeout; } break; case WM_COMMAND: -//below code fails becahse it is triggered after snes->poll_input()... +//below code fails because it is triggered after snes->poll_input()... //unsure how to fix this... // timeout = time(NULL); // while(difftime(time(NULL), timeout) < 5) { @@ -201,28 +202,39 @@ time_t timeout; case MENU_SETTINGS_VIDEOMODE_1024x768f: w_main->set_video_mode(VIDEOMODE_1024x768f); break; + case MENU_SETTINGS_COLORADJUST_COLORCURVE: + config::snes.video_color_curve.toggle(); + CheckMenuItem(w_main->hmenu, MENU_SETTINGS_COLORADJUST_COLORCURVE, + (config::snes.video_color_curve)?MF_CHECKED:MF_UNCHECKED); + break; + case MENU_SETTINGS_COLORADJUST_NORMAL: + case MENU_SETTINGS_COLORADJUST_GRAYSCALE: + case MENU_SETTINGS_COLORADJUST_VGA: + case MENU_SETTINGS_COLORADJUST_GENESIS: + i = LOWORD(wparam) - MENU_SETTINGS_COLORADJUST_NORMAL; + config::snes.video_color_adjust_mode = i; + CheckMenuItem(w_main->hmenu, MENU_SETTINGS_COLORADJUST_NORMAL, (i == 0)?MF_CHECKED:MF_UNCHECKED); + CheckMenuItem(w_main->hmenu, MENU_SETTINGS_COLORADJUST_GRAYSCALE, (i == 1)?MF_CHECKED:MF_UNCHECKED); + CheckMenuItem(w_main->hmenu, MENU_SETTINGS_COLORADJUST_VGA, (i == 2)?MF_CHECKED:MF_UNCHECKED); + CheckMenuItem(w_main->hmenu, MENU_SETTINGS_COLORADJUST_GENESIS, (i == 3)?MF_CHECKED:MF_UNCHECKED); + break; case MENU_SETTINGS_USEVRAM: - cfg.video.use_vram ^= 1; - w_main->set_video_mode(cfg.video.mode); - CheckMenuItem(w_main->hmenu, MENU_SETTINGS_USEVRAM, (cfg.video.use_vram)?MF_CHECKED:MF_UNCHECKED); + config::video.use_vram.toggle(); + w_main->set_video_mode(config::video.mode); + CheckMenuItem(w_main->hmenu, MENU_SETTINGS_USEVRAM, (config::video.use_vram)?MF_CHECKED:MF_UNCHECKED); break; case MENU_SETTINGS_VBLANK: - cfg.video.vblank ^= 1; - CheckMenuItem(w_main->hmenu, MENU_SETTINGS_VBLANK, (cfg.video.vblank)?MF_CHECKED:MF_UNCHECKED); - break; - case MENU_SETTINGS_COLORCURVE: - cfg.video.color_curve ^= 1; - dd_renderer->update_color_lookup_table(); - CheckMenuItem(w_main->hmenu, MENU_SETTINGS_COLORCURVE, (cfg.video.color_curve)?MF_CHECKED:MF_UNCHECKED); + config::video.vblank.toggle(); + CheckMenuItem(w_main->hmenu, MENU_SETTINGS_VBLANK, (config::video.vblank)?MF_CHECKED:MF_UNCHECKED); break; case MENU_SETTINGS_SHOWFPS: - cfg.gui.show_fps ^= 1; + config::gui.show_fps.toggle(); SetWindowText(w_main->hwnd, BSNES_TITLE); - CheckMenuItem(w_main->hmenu, MENU_SETTINGS_SHOWFPS, (cfg.gui.show_fps)?MF_CHECKED:MF_UNCHECKED); + CheckMenuItem(w_main->hmenu, MENU_SETTINGS_SHOWFPS, (config::gui.show_fps)?MF_CHECKED:MF_UNCHECKED); break; - case MENU_SETTINGS_APUENABLED: - cfg.apu.enabled ^= 1; - CheckMenuItem(w_main->hmenu, MENU_SETTINGS_APUENABLED, (cfg.apu.enabled)?MF_CHECKED:MF_UNCHECKED); + case MENU_SETTINGS_MUTE: + config::snes.mute.toggle(); + CheckMenuItem(w_main->hmenu, MENU_SETTINGS_MUTE, (config::snes.mute)?MF_CHECKED:MF_UNCHECKED); break; case MENU_SETTINGS_INPUTCFG_JOYPAD1: w_inputconfig->begin_config(InputConfig::JOYPAD1); @@ -236,6 +248,17 @@ time_t timeout; } break; case MENU_MISC_SCREENSHOT: + snes->capture_screenshot(); + break; + case MENU_MISC_LOGAUDIO: + i = CheckMenuItem(w_main->hmenu, MENU_MISC_LOGAUDIO, 0); + if(i == MF_UNCHECKED) { + CheckMenuItem(w_main->hmenu, MENU_MISC_LOGAUDIO, MF_CHECKED); + snes->log_audio_enable(); + } else { + CheckMenuItem(w_main->hmenu, MENU_MISC_LOGAUDIO, MF_UNCHECKED); + snes->log_audio_disable(); + } break; case MENU_MISC_ABOUT: w_about->center(); @@ -256,6 +279,7 @@ time_t timeout; void MainWindow::create() { WNDCLASS wc; +int i; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hbrBackground = CreateSolidBrush(RGB(0, 0, 0)); @@ -303,18 +327,26 @@ HMENU hsubmenu, hbranchmenu; AppendMenu(hsubmenu, MF_STRING | MF_POPUP, (unsigned int)hbranchmenu, "&Frameskip"); hbranchmenu = CreatePopupMenu(); - AppendMenu(hbranchmenu, MF_STRING, MENU_SETTINGS_VIDEOMODE_256x224w, "256x224 Windowed [16:15]"); - AppendMenu(hbranchmenu, MF_STRING, MENU_SETTINGS_VIDEOMODE_512x448w, "512x448 Windowed [16:15]"); - AppendMenu(hbranchmenu, MF_STRING, MENU_SETTINGS_VIDEOMODE_960x720w, "960x720 Windowed [4:3]"); - AppendMenu(hbranchmenu, MF_STRING, MENU_SETTINGS_VIDEOMODE_640x480f, "640x480 Fullscreen [16:15]"); - AppendMenu(hbranchmenu, MF_STRING, MENU_SETTINGS_VIDEOMODE_1024x768f, "1024x768 Fullscreen [4:3]"); + AppendMenu(hbranchmenu, MF_STRING, MENU_SETTINGS_VIDEOMODE_256x224w, "256x224 Windowed (16:15)"); + AppendMenu(hbranchmenu, MF_STRING, MENU_SETTINGS_VIDEOMODE_512x448w, "512x448 Windowed (16:15)"); + AppendMenu(hbranchmenu, MF_STRING, MENU_SETTINGS_VIDEOMODE_960x720w, "960x720 Windowed (4:3)"); + AppendMenu(hbranchmenu, MF_STRING, MENU_SETTINGS_VIDEOMODE_640x480f, "640x480 Fullscreen (16:15)"); + AppendMenu(hbranchmenu, MF_STRING, MENU_SETTINGS_VIDEOMODE_1024x768f, "1024x768 Fullscreen (4:3)"); AppendMenu(hsubmenu, MF_STRING | MF_POPUP, (unsigned int)hbranchmenu, "&Video Mode"); - AppendMenu(hsubmenu, MF_STRING, MENU_SETTINGS_USEVRAM, "Use &Video Memory Surface"); - AppendMenu(hsubmenu, MF_STRING, MENU_SETTINGS_VBLANK, "&Wait for Vertical Retrace"); - AppendMenu(hsubmenu, MF_STRING, MENU_SETTINGS_COLORCURVE, "Use &Color Curve"); - AppendMenu(hsubmenu, MF_STRING, MENU_SETTINGS_SHOWFPS, "&Show FPS"); - AppendMenu(hsubmenu, MF_STRING, MENU_SETTINGS_APUENABLED, "&Enable APU"); + hbranchmenu = CreatePopupMenu(); + AppendMenu(hbranchmenu, MF_STRING, MENU_SETTINGS_COLORADJUST_COLORCURVE, "Use &Color Curve"); + AppendMenu(hbranchmenu, MF_SEPARATOR, 0, ""); + AppendMenu(hbranchmenu, MF_STRING, MENU_SETTINGS_COLORADJUST_NORMAL, "Normal (RGB555)"); + AppendMenu(hbranchmenu, MF_STRING, MENU_SETTINGS_COLORADJUST_GRAYSCALE, "Grayscale Mode (L5)"); + AppendMenu(hbranchmenu, MF_STRING, MENU_SETTINGS_COLORADJUST_VGA, "VGA Mode (RGB332)"); + AppendMenu(hbranchmenu, MF_STRING, MENU_SETTINGS_COLORADJUST_GENESIS, "Genesis Mode (RGB333)"); + AppendMenu(hsubmenu, MF_STRING | MF_POPUP, (unsigned int)hbranchmenu, "&Color Adjust"); + + AppendMenu(hsubmenu, MF_STRING, MENU_SETTINGS_USEVRAM, "Use &Video Memory Surface"); + AppendMenu(hsubmenu, MF_STRING, MENU_SETTINGS_VBLANK, "&Wait For Vertical Retrace"); + AppendMenu(hsubmenu, MF_STRING, MENU_SETTINGS_SHOWFPS, "&Show FPS"); + AppendMenu(hsubmenu, MF_STRING, MENU_SETTINGS_MUTE, "&Mute Sound Output"); hbranchmenu = CreatePopupMenu(); AppendMenu(hbranchmenu, MF_STRING, MENU_SETTINGS_INPUTCFG_JOYPAD1, "Joypad 1"); @@ -325,14 +357,20 @@ HMENU hsubmenu, hbranchmenu; AppendMenu(hmenu, MF_STRING | MF_POPUP, (unsigned int)hsubmenu, "&Settings"); hsubmenu = CreatePopupMenu(); - AppendMenu(hsubmenu, MF_STRING | MF_GRAYED, MENU_MISC_SCREENSHOT, "&Capture Screenshot"); + AppendMenu(hsubmenu, MF_STRING, MENU_MISC_SCREENSHOT, "&Capture Screenshot"); + AppendMenu(hsubmenu, MF_STRING, MENU_MISC_LOGAUDIO, "&Log Audio Data"); AppendMenu(hsubmenu, MF_SEPARATOR, 0, ""); AppendMenu(hsubmenu, MF_STRING, MENU_MISC_ABOUT, "&About..."); AppendMenu(hmenu, MF_STRING | MF_POPUP, (unsigned int)hsubmenu, "&Misc"); - CheckMenuItem(hmenu, MENU_SETTINGS_USEVRAM, (cfg.video.use_vram)?MF_CHECKED:MF_UNCHECKED); - CheckMenuItem(hmenu, MENU_SETTINGS_VBLANK, (cfg.video.vblank)?MF_CHECKED:MF_UNCHECKED); - CheckMenuItem(hmenu, MENU_SETTINGS_COLORCURVE, (cfg.video.color_curve)?MF_CHECKED:MF_UNCHECKED); - CheckMenuItem(hmenu, MENU_SETTINGS_SHOWFPS, (cfg.gui.show_fps)?MF_CHECKED:MF_UNCHECKED); - CheckMenuItem(hmenu, MENU_SETTINGS_APUENABLED, (cfg.apu.enabled)?MF_CHECKED:MF_UNCHECKED); + CheckMenuItem(hmenu, MENU_SETTINGS_USEVRAM, (config::video.use_vram)?MF_CHECKED:MF_UNCHECKED); + CheckMenuItem(hmenu, MENU_SETTINGS_VBLANK, (config::video.vblank)?MF_CHECKED:MF_UNCHECKED); + CheckMenuItem(hmenu, MENU_SETTINGS_COLORADJUST_COLORCURVE, (config::snes.video_color_curve)?MF_CHECKED:MF_UNCHECKED); + i = config::snes.video_color_adjust_mode; + CheckMenuItem(hmenu, MENU_SETTINGS_COLORADJUST_NORMAL, (i == 0)?MF_CHECKED:MF_UNCHECKED); + CheckMenuItem(hmenu, MENU_SETTINGS_COLORADJUST_GRAYSCALE, (i == 1)?MF_CHECKED:MF_UNCHECKED); + CheckMenuItem(hmenu, MENU_SETTINGS_COLORADJUST_VGA, (i == 2)?MF_CHECKED:MF_UNCHECKED); + CheckMenuItem(hmenu, MENU_SETTINGS_COLORADJUST_GENESIS, (i == 3)?MF_CHECKED:MF_UNCHECKED); + CheckMenuItem(hmenu, MENU_SETTINGS_SHOWFPS, (config::gui.show_fps)?MF_CHECKED:MF_UNCHECKED); + CheckMenuItem(hmenu, MENU_SETTINGS_MUTE, (config::snes.mute) ?MF_CHECKED:MF_UNCHECKED); } diff --git a/src/win/winmain.cpp b/src/win/winmain.cpp index 0d50ac7d..9ae050a4 100644 --- a/src/win/winmain.cpp +++ b/src/win/winmain.cpp @@ -1,14 +1,19 @@ #define INTERFACE_MAIN -#define BSNES_VERSION "0.011" -#define BSNES_TITLE "bsnes v" BSNES_VERSION + +//requires visual c++ +#define USE_X86_ASM + #include "winmain.h" #include "../base.h" #include "config.cpp" +#define DSP_BUFFER_SIZE 8000 + #include "bsnes.h" #include "ui.h" #include "dd_renderer.h" +#include "ds_sound.h" #include "timer.cpp" fpstimer *fps_timer; @@ -20,28 +25,47 @@ fpstimer *fps_timer; #include "ui.cpp" void init_snes() { -//clock = new bClock(); mem_bus = new bMemBus(); cpu = new bCPU(); - if(cfg.apu.enabled) { - apu = new bAPU(); - } else { - apu = new bAPUSkip(); - } +cpu->cpu_version = 1; + apu = new bAPU(); + dsp = new bDSP(); ppu = new bPPU(); snes = new bSNES(); bsnes = static_cast(snes); snes->init(); + snes->set_playback_buffer_size(DSP_BUFFER_SIZE); } void term_snes() { -//if(clock) { delete(clock); clock = 0; } - if(mem_bus) { delete(mem_bus); mem_bus = 0; } - if(cpu) { delete(cpu); cpu = 0; } - if(apu) { delete(apu); apu = 0; } - if(ppu) { delete(ppu); ppu = 0; } - if(snes) { delete(snes); snes = 0; } + snes->term(); + +//static casting is neccesary to call derived class deconstructor... + if(mem_bus) { + delete(static_cast(mem_bus)); + mem_bus = 0; + } + if(cpu) { + delete(static_cast(cpu)); + cpu = 0; + } + if(apu) { + delete(static_cast(apu)); + apu = 0; + } + if(dsp) { + delete(static_cast(dsp)); + dsp = 0; + } + if(ppu) { + delete(static_cast(ppu)); + ppu = 0; + } + if(snes) { + delete(static_cast(snes)); + snes = 0; + } } void get_config_fn(string &str) { @@ -56,7 +80,7 @@ int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdL MSG msg; string cfg_fn; get_config_fn(cfg_fn); - cfg.load(cfg_fn); + config_file.load(cfg_fn); meminit(); fps_timer = new fpstimer(); fps_timer->start(); @@ -77,15 +101,16 @@ char **argv = __argv; } while(1) { - if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) { - if(msg.message == WM_QUIT)break; + while(PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) { + if(msg.message == WM_QUIT)goto _end; TranslateMessage(&msg); DispatchMessage(&msg); } - bsnes->snes_run(); + bsnes->run(); } - cfg.save(cfg_fn); +_end: + config_file.save(cfg_fn); delete(rom_image); term_snes(); memterm();