summaryrefslogtreecommitdiff
path: root/plugins/gme
diff options
context:
space:
mode:
authorGravatar waker <wakeroid@gmail.com>2012-05-13 20:04:04 +0200
committerGravatar waker <wakeroid@gmail.com>2012-05-13 20:04:04 +0200
commitcf275f4e1f3c256788186d11f788249dc3b45ddd (patch)
tree672a2521e5f5fda6821c34afa680f999746de5df /plugins/gme
parentf4f70d6a0e9158b28add0260a337344d8126213d (diff)
removed gme 0.5.2 and 0.5.5 sources
Diffstat (limited to 'plugins/gme')
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/Makefile.am3
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/changes.txt218
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/demo/Wave_Writer.cpp182
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/demo/Wave_Writer.h73
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/demo/basics.c57
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/demo/cpp_basics.cpp67
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/demo/features.c149
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/design.txt194
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme.txt464
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Ay_Apu.cpp395
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Ay_Apu.h107
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Ay_Cpu.cpp1665
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Ay_Cpu.h92
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Ay_Emu.cpp404
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Ay_Emu.h70
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Blip_Buffer.cpp446
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Blip_Buffer.h485
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Classic_Emu.cpp184
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Classic_Emu.h127
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Data_Reader.cpp315
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Data_Reader.h151
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Dual_Resampler.cpp131
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Dual_Resampler.h50
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Effects_Buffer.cpp529
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Effects_Buffer.h86
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Fir_Resampler.cpp199
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Fir_Resampler.h171
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Gb_Apu.cpp306
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Gb_Apu.h90
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Gb_Cpu.cpp1056
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Gb_Cpu.h93
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Gb_Oscs.cpp336
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Gb_Oscs.h83
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Gbs_Emu.cpp288
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Gbs_Emu.h88
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Gme_File.cpp216
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Gme_File.h145
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Gym_Emu.cpp379
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Gym_Emu.h82
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Hes_Apu.cpp315
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Hes_Apu.h66
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Hes_Cpu.cpp1303
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Hes_Cpu.h125
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Hes_Emu.cpp529
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Hes_Emu.h94
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Kss_Cpu.cpp1706
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Kss_Cpu.h124
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Kss_Emu.cpp414
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Kss_Emu.h96
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Kss_Scc_Apu.cpp97
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Kss_Scc_Apu.h106
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/M3u_Playlist.cpp426
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/M3u_Playlist.h67
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Makefile.am66
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Multi_Buffer.cpp232
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Multi_Buffer.h156
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Music_Emu.cpp410
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Music_Emu.h211
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Nes_Apu.cpp391
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Nes_Apu.h179
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Nes_Cpu.cpp1084
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Nes_Cpu.h114
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Nes_Fme7_Apu.cpp121
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Nes_Fme7_Apu.h131
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Nes_Namco_Apu.cpp145
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Nes_Namco_Apu.h102
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Nes_Oscs.cpp551
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Nes_Oscs.h147
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Nes_Vrc6_Apu.cpp215
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Nes_Vrc6_Apu.h95
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Nsf_Emu.cpp557
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Nsf_Emu.h106
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Nsfe_Emu.cpp330
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Nsfe_Emu.h68
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Sap_Apu.cpp334
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Sap_Apu.h77
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Sap_Cpu.cpp1011
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Sap_Cpu.h83
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Sap_Emu.cpp442
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Sap_Emu.h69
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Sms_Apu.cpp330
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Sms_Apu.h75
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Sms_Oscs.h49
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Snes_Spc.cpp489
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Snes_Spc.h121
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Spc_Cpu.cpp1062
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Spc_Cpu.h57
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Spc_Dsp.cpp666
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Spc_Dsp.h152
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Spc_Emu.cpp326
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Spc_Emu.h77
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Vgm_Emu.cpp412
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Vgm_Emu.h84
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Vgm_Emu_Impl.cpp314
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Vgm_Emu_Impl.h71
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Ym2413_Emu.cpp21
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Ym2413_Emu.h33
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Ym2612_Emu.cpp1319
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Ym2612_Emu.h38
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/blargg_common.h179
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/blargg_config.h30
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/blargg_endian.h158
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/blargg_source.h78
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/gb_cpu_io.h72
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/gme.cpp256
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/gme.h222
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/hes_cpu_io.h101
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/nes_cpu_io.h83
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/sap_cpu_io.h26
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/license.txt504
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/player/Audio_Scope.cpp198
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/player/Audio_Scope.h36
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/player/Music_Player.cpp231
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/player/Music_Player.h69
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/player/player.cpp213
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/readme.txt205
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/test.m3u2
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/test.nsfbin749 -> 0 bytes
-rw-r--r--plugins/gme/game-music-emu-0.5.5/changes.txt225
-rw-r--r--plugins/gme/game-music-emu-0.5.5/design.txt194
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme.txt464
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Ay_Apu.cpp395
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Ay_Apu.h107
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Ay_Cpu.cpp1665
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Ay_Cpu.h92
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Ay_Emu.cpp410
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Ay_Emu.h70
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Blip_Buffer.cpp446
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Blip_Buffer.cpp.orig446
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Blip_Buffer.h488
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Blip_Buffer.h.orig488
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Classic_Emu.cpp184
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Classic_Emu.h127
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Data_Reader.cpp315
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Data_Reader.h151
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Dual_Resampler.cpp133
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Dual_Resampler.h50
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Effects_Buffer.cpp529
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Effects_Buffer.h86
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Fir_Resampler.cpp199
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Fir_Resampler.h171
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Gb_Apu.cpp306
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Gb_Apu.h90
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Gb_Cpu.cpp1056
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Gb_Cpu.h93
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Gb_Oscs.cpp336
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Gb_Oscs.h83
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Gbs_Emu.cpp289
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Gbs_Emu.h88
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Gme_File.cpp216
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Gme_File.h159
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Gym_Emu.cpp380
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Gym_Emu.h82
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Hes_Apu.cpp315
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Hes_Apu.h66
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Hes_Cpu.cpp1303
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Hes_Cpu.h124
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Hes_Emu.cpp531
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Hes_Emu.h94
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Kss_Cpu.cpp1706
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Kss_Cpu.h124
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Kss_Emu.cpp416
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Kss_Emu.h96
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Kss_Scc_Apu.cpp97
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Kss_Scc_Apu.h106
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/M3u_Playlist.cpp426
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/M3u_Playlist.h67
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Multi_Buffer.cpp232
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Multi_Buffer.h158
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Music_Emu.cpp410
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Music_Emu.h211
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Nes_Apu.cpp391
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Nes_Apu.h179
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Nes_Cpu.cpp1084
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Nes_Cpu.h114
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Nes_Fme7_Apu.cpp121
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Nes_Fme7_Apu.h131
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Nes_Namco_Apu.cpp145
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Nes_Namco_Apu.h102
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Nes_Oscs.cpp551
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Nes_Oscs.h147
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Nes_Vrc6_Apu.cpp215
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Nes_Vrc6_Apu.h95
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Nsf_Emu.cpp559
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Nsf_Emu.h106
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Nsfe_Emu.cpp332
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Nsfe_Emu.h68
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Sap_Apu.cpp334
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Sap_Apu.h77
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Sap_Cpu.cpp1011
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Sap_Cpu.h83
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Sap_Emu.cpp444
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Sap_Emu.h69
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Sms_Apu.cpp330
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Sms_Apu.h75
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Sms_Oscs.h49
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Snes_Spc.cpp489
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Snes_Spc.h121
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Spc_Cpu.cpp1062
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Spc_Cpu.h57
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Spc_Dsp.cpp666
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Spc_Dsp.h152
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Spc_Emu.cpp328
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Spc_Emu.h77
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Vgm_Emu.cpp416
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Vgm_Emu.h84
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Vgm_Emu_Impl.cpp314
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Vgm_Emu_Impl.h71
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Ym2413_Emu.cpp21
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Ym2413_Emu.h33
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Ym2612_Emu.cpp1319
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/Ym2612_Emu.h38
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/blargg_common.h175
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/blargg_config.h29
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/blargg_endian.h158
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/blargg_source.h78
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/gb_cpu_io.h72
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/gme.cpp367
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/gme.h254
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/gme_types.h15
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/gme_types.h.in23
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/hes_cpu_io.h101
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/nes_cpu_io.h83
-rw-r--r--plugins/gme/game-music-emu-0.5.5/gme/sap_cpu_io.h26
-rw-r--r--plugins/gme/game-music-emu-0.5.5/license.txt504
-rw-r--r--plugins/gme/game-music-emu-0.5.5/player/Audio_Scope.cpp198
-rw-r--r--plugins/gme/game-music-emu-0.5.5/player/Audio_Scope.h36
-rw-r--r--plugins/gme/game-music-emu-0.5.5/player/Music_Player.cpp231
-rw-r--r--plugins/gme/game-music-emu-0.5.5/player/Music_Player.h69
-rw-r--r--plugins/gme/game-music-emu-0.5.5/player/player.cpp213
-rw-r--r--plugins/gme/game-music-emu-0.5.5/readme.txt218
231 files changed, 0 insertions, 63435 deletions
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/Makefile.am b/plugins/gme/Game_Music_Emu-0.5.2/Makefile.am
deleted file mode 100644
index 49e0b8b8..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/Makefile.am
+++ /dev/null
@@ -1,3 +0,0 @@
-EXTRA_DIST = changes.txt design.txt gme.txt license.txt readme.txt
-
-
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/changes.txt b/plugins/gme/Game_Music_Emu-0.5.2/changes.txt
deleted file mode 100644
index 0405b590..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/changes.txt
+++ /dev/null
@@ -1,218 +0,0 @@
-Game_Music_Emu Change Log
--------------------------
-
-Game_Music_Emu 0.5.2
---------------------
-- *TONS* of changes and improvements. You should re-read the new header
-files and documentation as the changes will allow you to simplify your
-code a lot (it might even be simpler to just rewrite it). Existing code
-should continue to work without changes in most cases (see Deprecated
-features in gme.txt).
-
-- New file formats: AY, HES, KSS, SAP, NSFE
-
-- All-new comprehensive C interface (also usable from C++). Simplifies
-many things, especially file loading, and brings everything together in
-one header file (gme.h).
-
-- Information tags and track names and times can be accessed for all
-game music formats
-
-- New features supported by all emulators: end of track fading,
-automatic silence detection, adjustable song tempo, seek to new time in
-track
-
-- Updated mini player example to support track names and times, echo,
-tempo, and channel muting, and added visual waveform display
-
-- Improved configuration to use blargg_config.h, which you can modify
-and keep when you update to a newer libary version. Includes flag for
-library to automatically handle gzipped files using zlib (so you don't
-need to use Gzip_File_Reader anymore).
-
-- GBS: Fixed wave channel to not reset waveform when APU is powered off
-(affected Garfield). Also improved invalid bank selection (affected Game
-& Watch and others).
-
-- VGM: Added support for alternate noise shifter register
-configurations, used by other systems like the BBC Micro.
-
-- SPC: Removed IPL ROM dump from emulator, as none of the SPC files I
-scanned needed it, and an SPC file can include a copy if necessary. Also
-re-enabled supposed clamping in gaussian interpolation between the third
-and fourth lookups, though I don't know whether it matters
-
-- Added Music_Emu::load_mem() to use music data already in memory
-(without copying it)
-
-- Added Music_Emu::warning(), which reports minor problems when loading
-and playing a music file
-
-- Added Music_Emu::set_gain() for uniform adjustment of gain. Can only
-be set during initialization, so not useful as a general volume control.
-
-- Added custom operator new to ensure that no exceptions are thrown in
-the library (I'd use std::nothrow if it were part of pre-ISO (ARM) C++)
-
-- Added BLIP_BUFFER_FAST flag to blargg_config.h to use a lower quality
-bandlimited synthesis in "classic" emulators, which might help
-performance on ancient processors (measure first!). Don't use this
-unless absolutely necessary, as quality suffers.
-
-- Improved performance a bit for x86 platforms
-
-- Text files now in DOS newline format so they will open in Notepad
-properly
-
-- Removed requirement that file header structures not have any padding
-added to the end
-
-- Fixed common bug in all CPU emulators where negative program counter
-could crash emulator (occurred during a negative branch from the
-beginning of memory). Also fixed related bug in Z80 emulator for
-IX/IY+displacement mode.
-
-- Eliminated all warnings when compiling on gcc 4.0. The following
-generates no diagnostics:
-
- gcc -S gme/*.cpp -o /dev/null -ansi -fno-gnu-keywords
- -fno-nonansi-builtins -pedantic -W -Wabi -Wall -Wcast-align
- -Wcast-qual -Wchar-subscripts -Wdisabled-optimization -Werror
- -Winline -Wlong-long -Wmultichar -Winvalid-offsetof
- -Wnon-virtual-dtor -Woverloaded-virtual -Wparentheses
- -Wpointer-arith -Wredundant-decls -Wreorder -Wsign-compare
- -Wsign-promo -Wunknown-pragmas -Wwrite-strings
-
-
-Game_Music_Emu 0.3.0
---------------------
-- Added more demos, including music player using the SDL multimedia
-library for sound, and improved documentation
-
-- All: Improved interface to emulators to allow simpler setup and
-loading. Instead of various init() functions, all now support
-set_sample_rate( long rate ) and load( const char* file_path ).
-
-- All: Removed error return from start_track() and play(), and added
-error_count() to get the total number of emulation errors since the
-track was last started. See demos for examples of new usage.
-
-- All: Fixed mute_voices() muting to be preserved after loading files
-and starting tracks, instead of being cleared as it was whenever a track
-was started
-
-- VGM: Rewrote Vgm_Emu to support Sega Genesis/Mega Drive FM sound at
-any sample rate with optional FM oversampling, support for alternate
-YM2612 sound cores, and support for optional YM2413
-
-- VGM: Added tempo control, useful for slowing 60Hz NTSC Sega Genesis
-music to 50Hz PAL
-
-- VGM: Removed Vgm_Emu::track_data(), since I realized that this
-information is already present in the VGM header (oops!)
-
-- GYM: Changed Gym_Emu::track_length() operation (see Gym_Emu.h)
-
-- NSF: Added support for Sunsoft FME-7 sound chip used by Gimmick
-soundtrack
-
-- NSF: Fixed Namco 106 problems with Final Lap and others
-
-- Moved library sources to gme/ directory to reduce clutter, and merged
-boost/ functionality into blargg_common.h
-
-- Added Gzip_File_Reader for transparently using gzipped files
-
-
-Game_Music_Emu 0.2.4
---------------------
-- Created a discussion forum for problems and feedback:
-http://groups-beta.google.com/group/blargg-sound-libs
-
-- Changed error return value of Blip_Buffer::sample_rate() (also for
-Stereo_Buffer, Effects_Buffer, etc.) to blargg_err_t (defined in
-blargg_common.h), to make error reporting consistent with other
-functions. This means the "no error" return value is the opposite of
-what it was before, which will break current code which checks the error
-return value:
-
- // current code (broken)
- if ( !buf.sample_rate( samples_per_sec ) )
- out_of_memory();
-
- // quick-and-dirty fix (just remove the ! operation)
- if ( buf.sample_rate( samples_per_sec ) )
- out_of_memory();
-
- // proper fix
- blargg_err_t error = buf.sample_rate( samples_per_sec );
- if ( error )
- report_error( error );
-
-- Implemented workaround for MSVC++ 6 compiler limitations, allowing it
-to work on that compiler again
-
-- Added sample clamping to avoid wrap-around at high volumes, allowing
-higher volume with little distortion
-
-- Added to-do list and design notes
-
-- Added Music_Emu::skip( long sample_count ) to skip ahead in current
-track
-
-- Added Gym_Emu::track_length() and Vgm_Emu::track_length() for
-determining the length of non-looped GYM and VGM files
-
-- Partially implemented DMC non-linearity when its value is directly set
-using $4011, which reduces previously over-emphasized "popping" of
-percussion on some games (TMNT II in particular)
-
-- Fixed Fir_Resampler, used for SPC and GYM playback (was incorrectly
-using abs() instead of fabs()...argh)
-
-- Fixed SPC emulation bugs: eliminated clicks in Plok! soundtrack and
-now stops sample slightly earlier than the end, as the SNES does. Fixed
-a totally broken CPU addressing mode.
-
-- Fixed Konami VRC6 saw wave (was very broken before). Now VRC6 music
-sounds decent
-
-- Fixed a minor GBS emulation bug
-
-- Fixed GYM loop point bug when track was restarted before loop point
-had been reached
-
-- Made default GBS frequency equalization less muffled
-
-- Added pseudo-surround effect removal for SPC files
-
-- Added Music_Emu::voice_names() which returns names for each voice.
-
-- Added BLARGG_SOURCE_BEGIN which allows custom compiler options to be
-easily set for library sources
-
-- Changed assignment of expansion sound chips in Nsf_Emu to be spread
-more evenly when using Effects_Buffer
-
-- Changed 'size_t' values in Blip_Buffer interface to 'long'
-
-- Changed demo to generate a WAVE sound file rather than an AIFF file
-
-
-Game_Music_Emu 0.2.0
---------------------
-- Redid framework and rewrote/cleaned up emulators
-
-- Changed licensing to GNU Lesser General Public License (LGPL)
-
-- Added Sega Genesis GYM and Super Nintendo SPC emulators
-
-- Added Namco-106 and Konami VRC6 sound chip support to NSF emulator
-
-- Eliminated use of static mutable data in emulators, allowing
-multi-instance safety
-
-
-Game_Music_Emu 0.1.0
---------------------
-- First release
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/demo/Wave_Writer.cpp b/plugins/gme/Game_Music_Emu-0.5.2/demo/Wave_Writer.cpp
deleted file mode 100644
index ec40959d..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/demo/Wave_Writer.cpp
+++ /dev/null
@@ -1,182 +0,0 @@
-// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
-
-#include "Wave_Writer.h"
-
-#include <assert.h>
-#include <stdlib.h>
-
-/* Copyright (C) 2003-2006 by Shay Green. Permission is hereby granted, free
-of charge, to any person obtaining a copy of this software and associated
-documentation files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use, copy, modify,
-merge, publish, distribute, sublicense, and/or sell copies of the Software, and
-to permit persons to whom the Software is furnished to do so, subject to the
-following conditions: The above copyright notice and this permission notice
-shall be included in all copies or substantial portions of the Software. THE
-SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
-INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
-PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-
-const int header_size = 0x2C;
-
-static void exit_with_error( const char* str )
-{
- printf( "Error: %s\n", str ); getchar();
- exit( EXIT_FAILURE );
-}
-
-Wave_Writer::Wave_Writer( long sample_rate, const char* filename )
-{
- sample_count_ = 0;
- rate = sample_rate;
- buf_pos = header_size;
- chan_count = 1;
-
- buf = (unsigned char*) malloc( buf_size * sizeof *buf );
- if ( !buf )
- exit_with_error( "Out of memory" );
-
- file = fopen( filename, "wb" );
- if ( !file )
- exit_with_error( "Couldn't open WAVE file for writing" );
-
- setvbuf( file, 0, _IOFBF, 32 * 1024L );
-}
-
-void Wave_Writer::flush()
-{
- if ( buf_pos && !fwrite( buf, buf_pos, 1, file ) )
- exit_with_error( "Couldn't write WAVE data" );
- buf_pos = 0;
-}
-
-void Wave_Writer::write( const sample_t* in, long remain, int skip )
-{
- sample_count_ += remain;
- while ( remain )
- {
- if ( buf_pos >= buf_size )
- flush();
-
- long n = (buf_size - buf_pos) / sizeof (sample_t);
- if ( n > remain )
- n = remain;
- remain -= n;
-
- // convert to lsb first format
- unsigned char* p = &buf [buf_pos];
- while ( n-- )
- {
- int s = *in;
- in += skip;
- *p++ = (unsigned char) s;
- *p++ = (unsigned char) (s >> 8);
- }
-
- buf_pos = p - buf;
- assert( buf_pos <= buf_size );
- }
-}
-
-
-void Wave_Writer::write( const float* in, long remain, int skip )
-{
- sample_count_ += remain;
- while ( remain )
- {
- if ( buf_pos >= buf_size )
- flush();
-
- long n = (buf_size - buf_pos) / sizeof (sample_t);
- if ( n > remain )
- n = remain;
- remain -= n;
-
- // convert to lsb first format
- unsigned char* p = &buf [buf_pos];
- while ( n-- )
- {
- long s = (long) (*in * 0x7FFF);
- in += skip;
- if ( (short) s != s )
- s = 0x7FFF - (s >> 24); // clamp to 16 bits
- *p++ = (unsigned char) s;
- *p++ = (unsigned char) (s >> 8);
- }
-
- buf_pos = p - buf;
- assert( buf_pos <= buf_size );
- }
-}
-
-void Wave_Writer::close()
-{
- if ( file )
- {
- flush();
-
- // generate header
- long ds = sample_count_ * sizeof (sample_t);
- long rs = header_size - 8 + ds;
- int frame_size = chan_count * sizeof (sample_t);
- long bps = rate * frame_size;
- unsigned char header [header_size] =
- {
- 'R','I','F','F',
- rs,rs>>8, // length of rest of file
- rs>>16,rs>>24,
- 'W','A','V','E',
- 'f','m','t',' ',
- 0x10,0,0,0, // size of fmt chunk
- 1,0, // uncompressed format
- chan_count,0, // channel count
- rate,rate >> 8, // sample rate
- rate>>16,rate>>24,
- bps,bps>>8, // bytes per second
- bps>>16,bps>>24,
- frame_size,0, // bytes per sample frame
- 16,0, // bits per sample
- 'd','a','t','a',
- ds,ds>>8,ds>>16,ds>>24// size of sample data
- // ... // sample data
- };
-
- // write header
- fseek( file, 0, SEEK_SET );
- fwrite( header, sizeof header, 1, file );
-
- fclose( file );
- file = 0;
- free( buf );
- }
-}
-
-Wave_Writer::~Wave_Writer()
-{
- close();
-}
-
-// C interface
-
-static Wave_Writer* ww;
-
-void wave_open( long sample_rate, const char* filename )
-{
- ww = new Wave_Writer( sample_rate, filename );
- assert( ww );
-}
-
-void wave_enable_stereo() { ww->enable_stereo(); }
-
-long wave_sample_count() { return ww->sample_count(); }
-
-void wave_write( const short* buf, long count ) { ww->write( buf, count ); }
-
-void wave_close()
-{
- delete ww;
- ww = 0;
-}
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/demo/Wave_Writer.h b/plugins/gme/Game_Music_Emu-0.5.2/demo/Wave_Writer.h
deleted file mode 100644
index da08cc2a..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/demo/Wave_Writer.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/* WAVE sound file writer for recording 16-bit output during program development */
-
-#ifndef WAVE_WRITER_H
-#define WAVE_WRITER_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/* C interface */
-void wave_open( long sample_rate, const char* filename );
-void wave_enable_stereo( void );
-void wave_write( const short* buf, long count );
-long wave_sample_count( void );
-void wave_close( void );
-
-#ifdef __cplusplus
- }
-#endif
-
-#ifdef __cplusplus
-#include <stddef.h>
-#include <stdio.h>
-
-/* C++ interface */
-class Wave_Writer {
-public:
- typedef short sample_t;
-
- // Create sound file with given sample rate (in Hz) and filename.
- // Exits program if there's an error.
- Wave_Writer( long sample_rate, char const* filename = "out.wav" );
-
- // Enable stereo output
- void enable_stereo();
-
- // Append 'count' samples to file. Use every 'skip'th source sample; allows
- // one channel of stereo sample pairs to be written by specifying a skip of 2.
- void write( const sample_t*, long count, int skip = 1 );
-
- // Append 'count' floating-point samples to file. Use every 'skip'th source sample;
- // allows one channel of stereo sample pairs to be written by specifying a skip of 2.
- void write( const float*, long count, int skip = 1 );
-
- // Number of samples written so far
- long sample_count() const;
-
- // Finish writing sound file and close it
- void close();
-
- ~Wave_Writer();
-public:
- // Deprecated
- void stereo( bool b ) { chan_count = b ? 2 : 1; }
-private:
- enum { buf_size = 32768 * 2 };
- unsigned char* buf;
- FILE* file;
- long sample_count_;
- long rate;
- long buf_pos;
- int chan_count;
-
- void flush();
-};
-
-inline void Wave_Writer::enable_stereo() { chan_count = 2; }
-
-inline long Wave_Writer::sample_count() const { return sample_count_; }
-
-#endif
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/demo/basics.c b/plugins/gme/Game_Music_Emu-0.5.2/demo/basics.c
deleted file mode 100644
index 55178251..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/demo/basics.c
+++ /dev/null
@@ -1,57 +0,0 @@
-/* C example that opens a game music file and records 10 seconds to "out.wav" */
-
-static char filename [] = "test.nsf"; /* opens this file (can be any music type) */
-
-#include "gme/gme.h"
-
-#include "Wave_Writer.h" /* wave_ functions for writing sound file */
-#include <stdlib.h>
-#include <stdio.h>
-
-void handle_error( const char* str );
-
-int main()
-{
- long sample_rate = 44100; /* number of samples per second */
- int track = 0; /* index of track to play (0 = first) */
-
- /* Open music file in new emulator */
- Music_Emu* emu;
- handle_error( gme_open_file( filename, &emu, sample_rate ) );
-
- /* Start track */
- handle_error( gme_start_track( emu, track ) );
-
- /* Begin writing to wave file */
- wave_open( sample_rate, "out.wav" );
- wave_enable_stereo();
-
- /* Record 10 seconds of track */
- while ( gme_tell( emu ) < 10 * 1000L )
- {
- /* Sample buffer */
- #define buf_size 1024 /* can be any multiple of 2 */
- short buf [buf_size];
-
- /* Fill sample buffer */
- handle_error( gme_play( emu, buf_size, buf ) );
-
- /* Write samples to wave file */
- wave_write( buf, buf_size );
- }
-
- /* Cleanup */
- gme_delete( emu );
- wave_close();
-
- return 0;
-}
-
-void handle_error( const char* str )
-{
- if ( str )
- {
- printf( "Error: %s\n", str ); getchar();
- exit( EXIT_FAILURE );
- }
-}
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/demo/cpp_basics.cpp b/plugins/gme/Game_Music_Emu-0.5.2/demo/cpp_basics.cpp
deleted file mode 100644
index 53fab418..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/demo/cpp_basics.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-// C++ example that opens a game music file and records 10 seconds to "out.wav"
-
-static char filename [] = "test.nsf"; /* opens this file (can be any music type) */
-
-#include "gme/Music_Emu.h"
-
-#include "Wave_Writer.h"
-#include <stdlib.h>
-#include <stdio.h>
-
-void handle_error( const char* str );
-
-int main()
-{
- long sample_rate = 44100; // number of samples per second
- int track = 0; // index of track to play (0 = first)
-
- // Determine file type
- gme_type_t file_type;
- handle_error( gme_identify_file( filename, &file_type ) );
- if ( !file_type )
- handle_error( "Unsupported music type" );
-
- // Create emulator and set sample rate
- Music_Emu* emu = file_type->new_emu();
- if ( !emu )
- handle_error( "Out of memory" );
- handle_error( emu->set_sample_rate( sample_rate ) );
-
- // Load music file into emulator
- handle_error( emu->load_file( filename ) );
-
- // Start track
- handle_error( emu->start_track( track ) );
-
- // Begin writing to wave file
- Wave_Writer wave( sample_rate, "out.wav" );
- wave.enable_stereo();
-
- // Record 10 seconds of track
- while ( emu->tell() < 10 * 1000L )
- {
- // Sample buffer
- const long size = 1024; // can be any multiple of 2
- short buf [size];
-
- // Fill buffer
- handle_error( emu->play( size, buf ) );
-
- // Write samples to wave file
- wave.write( buf, size );
- }
-
- // Cleanup
- delete emu;
-
- return 0;
-}
-
-void handle_error( const char* str )
-{
- if ( str )
- {
- printf( "Error: %s\n", str ); getchar();
- exit( EXIT_FAILURE );
- }
-}
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/demo/features.c b/plugins/gme/Game_Music_Emu-0.5.2/demo/features.c
deleted file mode 100644
index 96a9a8a9..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/demo/features.c
+++ /dev/null
@@ -1,149 +0,0 @@
-/* C example that opens any music file type, opens an m3u playlist if present,
-prints its info and voice names, customizes the sound, and fades a track out.
-Records to "out.wav". */
-
-static char filename [] = "test.nsf"; /* opens this file (can be any music type) */
-static char playlist [] = "test.m3u"; /* uses this playlist, if present*/
-
-#include "gme/gme.h"
-
-#include "Wave_Writer.h" /* wave_ functions for writing sound file */
-#include <stdlib.h>
-#include <stdio.h>
-
-void handle_error( const char* );
-
-/* Example of loading from memory, which would be useful if using a zip file or
-other custom format. In this example it's silly because we could just use
-gme_load( &emu, sample_rate, path, 0 ). */
-Music_Emu* load_file( const char* path, long sample_rate )
-{
- Music_Emu* emu;
- char* data;
- long size;
-
- /* Read file data into memory. You might read the data from a zip file or
- other compressed format. */
- FILE* in = fopen( path, "rb" );
- if ( !in )
- handle_error( "Couldn't open file" );
- fseek( in, 0, SEEK_END );
- size = ftell( in );
- rewind( in );
-
- data = malloc( size );
- if ( !data )
- handle_error( "Out of memory" );
- if ( fread( data, size, 1, in ) <= 0 )
- handle_error( "Read error" );
- fclose( in );
-
- handle_error( gme_open_data( data, size, &emu, sample_rate ) );
- free( data ); /* a copy is made of the data */
- return emu;
-}
-
-/* Print any warning for most recent emulator action (load, start_track, play) */
-void print_warning( Music_Emu* emu )
-{
- const char* warning = gme_warning( emu );
- if ( warning )
- printf( "**** Warning: %s\n\n", warning );
-}
-
-static char my_data [] = "Our cleanup function was called";
-
-/* Example cleanup function automatically called when emulator is deleted. */
-static void my_cleanup( void* my_data )
-{
- printf( "\n%s\n", (char*) my_data );
-}
-
-int main()
-{
- long sample_rate = 44100;
- int track = 0; /* index of track to play (0 = first) */
- int i;
-
- /* Load file into emulator */
- Music_Emu* emu = load_file( filename, sample_rate );
- print_warning( emu );
-
- /* Register cleanup function and confirmation string as data */
- gme_set_user_data( emu, my_data );
- gme_set_user_cleanup( emu, my_cleanup );
-
- /* Load .m3u playlist file. All tracks are assumed to use current file.
- We ignore error here in case there is no m3u file present. */
- gme_load_m3u( emu, playlist );
- print_warning( emu );
-
- /* Get and print main info for track */
- {
- track_info_t info;
- handle_error( gme_track_info( emu, &info, track ) );
- printf( "System : %s\n", info.system );
- printf( "Game : %s\n", info.game );
- printf( "Author : %s\n", info.author );
- printf( "Copyright: %s\n", info.copyright );
- printf( "Comment : %s\n", info.comment );
- printf( "Dumper : %s\n", info.dumper );
- printf( "Tracks : %d\n", (int) info.track_count );
- printf( "\n" );
- printf( "Track : %d\n", (int) track + 1 );
- printf( "Name : %s\n", info.song );
- printf( "Length : %ld:%02ld",
- (long) info.length / 1000 / 60, (long) info.length / 1000 % 60 );
- if ( info.loop_length != 0 )
- printf( " (endless)" );
- printf( "\n\n" );
- }
-
- /* Print voice names */
- for ( i = 0; i < gme_voice_count( emu ); i++ )
- printf( "Voice %d: %s\n", i, gme_voice_names( emu ) [i] );
-
- /* Add some stereo enhancement */
- gme_set_stereo_depth( emu, 0.20 );
-
- /* Adjust equalizer for crisp, bassy sound */
- {
- gme_equalizer_t eq;
- eq.treble = 0.0;
- eq.bass = 20;
- gme_set_equalizer( emu, &eq );
- }
-
- /* Start track and begin fade at 10 seconds */
- handle_error( gme_start_track( emu, track ) );
- print_warning( emu );
- gme_set_fade( emu, 10 * 1000L );
-
- /* Record track until it ends */
- wave_open( sample_rate, "out.wav" );
- wave_enable_stereo();
- while ( !gme_track_ended( emu ) )
- {
- #define buf_size 1024
- short buf [buf_size];
- handle_error( gme_play( emu, buf_size, buf ) );
- print_warning( emu );
- wave_write( buf, buf_size );
- }
-
- /* Cleanup */
- gme_delete( emu );
- wave_close();
-
- getchar();
- return 0;
-}
-
-void handle_error( const char* str )
-{
- if ( str )
- {
- printf( "Error: %s\n", str ); getchar();
- exit( EXIT_FAILURE );
- }
-}
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/design.txt b/plugins/gme/Game_Music_Emu-0.5.2/design.txt
deleted file mode 100644
index 8c8c65b1..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/design.txt
+++ /dev/null
@@ -1,194 +0,0 @@
-Game_Music_Emu 0.5.2 Design
----------------------------
-This might be slightly out-of-date at times, but will be a big help in
-understanding the library implementation.
-
-
-Architecture
-------------
-The library is essentially a bunch of independent game music file
-emulators unified with a common interface.
-
-Gme_File and Music_Emu provide a common interface to the emulators. The
-virtual functions are protected rather than public to allow pre- and
-post-processing of arguments and data in one place. This allows the
-emulator classes to assume that everything is set up properly when
-starting a track and playing samples.
-
-All file input is done with the Data_Reader interface. Many derived
-classes are present, for the usual disk-based file and block of memory,
-to specialized adaptors for things like reading a subset of data or
-combining a block of memory with a Data_Reader to the remaining data.
-This makes the library much more flexible with regard to the source of
-game music file data. I still added a specialized load_mem() function to
-have the emulator keep a pointer to data already read in memory, for
-those formats whose files can be absolutely huge (GYM, some VGMs). This
-is important if for some reason the caller must load the data ahead of
-time, but doesn't want the emulator needlessly making a copy.
-
-Since silence checking and fading are relatively complex, they are kept
-separate from basic file loading and track information, which are
-handled in the base class Gme_File. My original intent was to use
-Gme_File as the common base class for full emulators and track
-information-only readers, but implementing the C interface was much
-simpler if both derived from Music_Emu. User C++ code can still benefit
-from static checking by using Gme_File where only track information will
-be accessed.
-
-Each emulator generally has three components: main emulator, CPU
-emulator, and sound chip emulator(s). Each component has minimal
-coupling, so use in a full emulator or stand alone is fairly easy. This
-modularity really helps reduce complexity. Blip_Buffer helps a lot with
-simplifying the APU interfaces and implementation.
-
-The "classic" emulators derive from Classic_Emu, which handles
-Blip_Buffer filling and multiple channels. It uses Multi_Buffer for
-output, allowing you to derive a custom buffer that could output each
-voice to a separate sound channel and do different processing on each.
-At some point I'm going to implement a better Effects_Buffer that allows
-individual control of every channel.
-
-In implementing the C interface, I wanted a way to specify an emulator
-type that didn't require linking in all the emulators. For each emulator
-type there is a global object with pointers to functions to create the
-emulator or a track information reader. The emulator type is thus a
-pointer to this, which conveniently allows for a NULL value. The user
-referencing this emulator type object is what ultimately links the
-emulator in (unless new Foo_Emu is used in C++, of course). This type
-also serves as a useful substitute for RTTI on older C++ compilers.
-
-Addendum: I have since added gme_type_list(), which causes all listed
-emulators to be linked in. To avoid this, I make the list itself
-editable in blargg_config.h. Having a built-in list allows
-gme_load_file() to take a path and give back an emulator with the file
-loaded, which is extremely useful for new users.
-
-
-Interface conventions
-----------------------
-If a function retains a pointer to or replaces the value of an object
-passed, it takes a pointer so that it will be clear in the caller's
-source code that care is required.
-
-Multi-word names have an underscore '_' separator between individual
-words.
-
-Functions are named with lowercase words. Functions which perform an
-action with side-effects are named with a verb phrase (i.e. load, move,
-run). Functions which return the value of a piece of state are named
-using a noun phrase (i.e. loaded, moved, running).
-
-Classes are named with capitalized words. Only the first letter of an
-acronym is capitalized. Class names are nouns, sometimes suggestive of
-what they do (i.e. File_Scanner).
-
-Structure, enumeration, and typedefs to these and built-in types are
-named using lowercase words with a _t suffix.
-
-Macros are named with all-uppercase words.
-
-Internal names which can't be hidden due to technical reasons have an
-underscore '_' suffix.
-
-
-Managing Complexity
--------------------
-Complexity has been a factor in most library decisions. Many features
-have been passed by due to the complexity they would add. Once
-complexity goes past a certain level, it mentally grasping the library
-in its entirety, at which point more defects will occur and be hard to
-find.
-
-I chose 16-bit signed samples because it seems to be the most common
-format. Supporting multiple formats would add too much complexity to be
-worth it. Other formats can be obtained via conversion.
-
-I've kept interfaces fairly lean, leaving many possible features
-untapped but easy to add if necessary. For example the classic emulators
-could have volume and frequency equalization adjusted separately for
-each channel, since they each have an associated Blip_Synth.
-
-Source files of 400 lines or less seem to be the best size to limit
-complexity. In a few cases there is no reasonable way to split longer
-files, or there is benefit from having the source together in one file.
-
-
-Preventing Bugs
----------------
-I've done many things to reduce the opportunity for defects. A general
-principle is to write code so that defects will be as visible as
-possible. I've used several techniques to achieve this.
-
-I put assertions at key points where defects seem likely or where
-corruption due to a defect is likely to be visible. I've also put
-assertions where violations of the interface are likely. In emulators
-where I am unsure of exact hardware operation in a particular case, I
-output a debug-only message noting that this has occurred; many times I
-haven't implemented a hardware feature because nothing uses it. I've
-made code brittle where there is no clear reason flexibility; code
-written to handle every possibility sacrifices quality and reliability
-to handle vaguely defined situations.
-
-
-Flexibility through indirection
--------------------------------
-I've tried to allow the most flexibility of modules by using indirection
-to allow extension by the user. This keeps each module simpler and more
-focused on its unique task.
-
-The classic emulators use Multi_Buffer, which potentially allows a
-separate Blip_Buffer for each channel. This keeps emulators free of
-typical code to allow output in mono, stereo, panning, etc.
-
-All emulators use a reader object to access file data, allowing it to be
-stored in a regular file, compressed archive, memory, or generated
-on-the-fly. Again, the library can be kept free of the particulars of
-file access and changes required to support new formats.
-
-
-Emulators in general
---------------------
-When I wrote the first NES sound emulator, I stored most of the state in
-an emulator-specific format, with significant redundancy. In the
-register write function I decoded everything into named variables. I
-became tired of the verbosity and wanted to more closely model the
-hardware, so I moved to a style of storing the last written value to
-each register, along with as little other state as possible, mostly the
-internal hardware registers. While this involves slightly more
-recalculation, in most cases the emulation code is of comparable size.
-It also makes state save/restore (for use in a full emulator) much
-simpler. Finally, it makes debugging easier since the hardware registers
-used in emulation are obvious.
-
-
-CPU Cores
----------
-I've spent lots of time coming up with techniques to optimize the CPU
-cores. Some of the most important: execute multiple instructions during
-an emulation call, keep state in local variables to allow register
-assignment, optimize state representation for most common instructions,
-defer status flag calculation until actually needed, read program code
-directly without a call to the memory read function, always pre-fetch
-the operand byte before decoding instruction, and emulate instructions
-using common blocks of code.
-
-I've successfully used Nes_Cpu in a fairly complete NES emulator, and
-I'd like to make all the CPU emulators suitable for use in emulators. It
-seems a waste for them to be used only for the small amount of emulation
-necessary for game music files.
-
-I debugged the CPU cores by writing a test shell that ran them in
-parallel with other CPU cores and compared all memory accesses and
-processor states at each step. This provided good value at little cost.
-
-The CPU mapping page size is adjustable to allow the best tradeoff
-between memory/cache usage and handler granularity. The interface allows
-code to be somewhat independent of the page size.
-
-I optimize program memory accesses to direct reads rather than calls to
-the memory read function. My assumption is that it would be difficult to
-get useful code out of hardware I/O addresses, so no software will
-intentionally execute out of I/O space. Since the page size can be
-changed easily, most program memory mapping schemes can be accommodated.
-This greatly reduces memory access function calls.
-
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme.txt b/plugins/gme/Game_Music_Emu-0.5.2/gme.txt
deleted file mode 100644
index 2c963d8e..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme.txt
+++ /dev/null
@@ -1,464 +0,0 @@
-Game_Music_Emu 0.5.2
---------------------
-Author : Shay Green <gblargg@gmail.com>
-Website: http://www.slack.net/~ant/libs/
-Forum : http://groups.google.com/group/blargg-sound-libs
-License: GNU Lesser General Public License (LGPL)
-
-Contents
---------
-* Overview
-* C and C++ interfaces
-* Function reference
-* Error handling
-* Emulator types
-* M3U playlist support
-* Information fields
-* Track length
-* Loading file data
-* Sound parameters
-* VGM/GYM YM2413 & YM2612 FM sound
-* Modular construction
-* Obscure features
-* Solving problems
-* Deprecated features
-* Thanks
-
-
-Overview
---------
-This library can open game music files, play tracks, and read game and
-track information tags. To play a game music file, do the following:
-
-* Open the file with gme_open_file()
-* Start a track with gme_start_track();
-* Generate samples as needed with gme_play()
-* Play samples through speaker using your operating system
-* Delete emulator when done with gme_delete()
-
-Your code must arrange for the generated samples to be played through
-the computer's speaker using whatever method your operating system
-requires.
-
-There are many additional features available; you can:
-
-* Determine of the type of a music file without opening it with
-gme_identify_*()
-* Load just the file's information tags with gme_info_only
-* Load from a block of memory rather than a file with gme_load_data()
-* Arrange for a fade-out at a particular time with gme_set_fade
-* Find when a track has ended with gme_track_ended()
-* Seek to a new time in the track with gme_seek()
-* Load an extended m3u playlist with gme_load_m3u()
-* Get a list of the voices (channels) and mute them individually with
-gme_voice_names() and gme_mute_voice()
-* Change the playback tempo without affecting pitch with gme_set_tempo()
-* Adjust treble/bass equalization with gme_set_equalizer()
-* Associate your own data with an emulator and later get it back with
-gme_set_user_data()
-* Register a function of yours to be called back when the emulator is
-deleted with gme_set_user_cleanup()
-
-Refer to gme.h for a comprehensive summary of features.
-
-
-C and C++ interfaces
---------------------
-While the library is written in C++, an extensive C interface is
-provided in gme.h. This C interface will be referred to throughout this
-documentation unless a feature is only available in the full C++
-interface. All C interface functions and other names have the gme_
-prefix, so you can recognize a C++-only feature by the lack of gme_ in
-the names used (contact me if you'd like a feature added to the C
-interface). If you're building a shared library, I highly recommend
-sticking to the C interface only, because it will be more stable between
-releases of the library than the C++ interface. Finally, the C and C++
-interfaces can be freely mixed without problems. Compare demo/basics.c
-with demo/cpp_basics.cpp to see how the C and C++ interfaces translate
-between each other.
-
-
-Function reference
-------------------
-Read the following header files for a complete reference to functions
-and features. The second group of header files can only be used in C++.
-
-blargg_config.h Library configuration
-gme.h C interface (also usable from C++)
-
-Gme_File.h File loading and track information
-Music_Emu.h Track playback and adjustments
-Data_Reader.h Custom data readers
-Effects_Buffer.h Sound buffer with adjustable stereo echo and panning
-M3u_Playlist.h M3U playlist support
-Gbs_Emu.h GBS equalizer settings
-Nsf_Emu.h NSF equalizer settings
-Spc_Emu.h SPC surround disable
-Vgm_Emu.h VGM oversampling disable and custom buffer query
-
-
-Error handling
---------------
-Functions which can fail have a return type of gme_err_t (blargg_err_t
-in the C++ interfaces), which is a pointer to an error string (const
-char*). If a function is successful it returns NULL. Errors that you can
-easily avoid are checked with debug assertions; gme_err_t return values
-are only used for genuine run-time errors that can't be easily predicted
-in advance (out of memory, I/O errors, incompatible file data). Your
-code should check all error values.
-
-To improve usability for C programmers, C++ programmers unfamiliar with
-exceptions, and compatibility with older C++ compilers, the library does
-*not* throw any C++ exceptions and uses malloc() instead of the standard
-operator new. This means that you *must* check for NULL when creating a
-library object with the new operator.
-
-When loading a music file in the wrong emulator or trying to load a
-non-music file, gme_wrong_file_type is returned. You can check for this
-error in C++ like this:
-
- gme_err_t err = gme_open_file( path, &emu );
- if ( err == gme_wrong_file_type )
- ...
-
-To check for minor problems, call gme_warning() to get a string
-describing the last warning. Your player should allow the user some way
-of knowing when this is the case, since these minor errors could affect
-playback. Without this information the user can't solve problems as
-well. When playing a track, gme_warning() returns minor playback-related
-problems (major playback problems end the track immediately and set the
-warning string).
-
-
-Emulator types
---------------
-The library includes several game music emulators that each support a
-different file type. Each is identified by a gme_type_t constant defined
-in gme.h, for example gme_nsf_emu is for the NSF emulator. If you use
-gme_open_file() or gme_open_data(), the library does the work of
-determining the file type and creating an appropriate emulator. If you
-want more control over this process, read on.
-
-There are two basic ways to identify a game music file's type: look at
-its file extension, or read the header data. The library includes
-functions to help with both methods. The first is preferable because it
-is fast and the most common way to identify files. Sometimes the
-extension is lost or wrong, so the header must be read.
-
-Use gme_identify_extension() to find the correct game music type based
-on a filename. To identify a file based on its extension and header
-contents, use gme_identify_file(). If you read the header data yourself,
-use gme_identify_header().
-
-If you want to remove support for some music types to reduce your
-executable size, edit GME_TYPE_LIST in blargg_config.h. For example, to
-support just NSF and GBS, use this:
-
- #define GME_TYPE_LIST gme_nsf_type, gme_gbs_type
-
-
-M3U playlist support
---------------------
-The library supports playlists in an extended m3u format with
-gme_load_m3u() to give track names and times to multi-song formats: AY,
-GBS, HES, KSS, NSF, NSFE, and SAP. Some aspects of the file format
-itself is not well-defined so some m3u files won't work properly
-(particularly those provided with KSS files). Only m3u files referencing
-a single file are supported; your code must handle m3u files covering
-more than one game music file, though it can use the built-in m3u
-parsing provided by the library.
-
-
-Information fields
-------------------
-Support is provided for the various text fields and length information
-in a file with gme_track_info(). If you just need track information for
-a file (for example, building a playlist), use gme_new_info() in place
-of gme_new_emu(), load the file normally, then you can access the track
-count and info, but nothing else.
-
- M3U VGM GYM SPC SAP NSFE NSF AY GBS HES KSS
- -------------------------------------------------------
-Track Count | * * * * * * * * *
- |
-System | * * * * * * * * * *
- |
-Game | * * * * * * *
- |
-Song | * * * * * * *
- |
-Author | * * * * * * * *
- |
-Copyright | * * * * * * * *
- |
-Comment | * * * *
- |
-Dumper | * * * *
- |
-Length | * * * * * *
- |
-Intro Length| * * *
- |
-Loop Length | * * *
-
-As listed above, the HES and KSS file formats don't include a track
-count, and tracks are often scattered over the 0-255 range, so an m3u
-playlist for these is a must.
-
-Unavailable text fields are set to an empty string and times to -1. Your
-code should be prepared for any combination of available and unavailable
-fields, as a particular music file might not use all of the supported
-fields listed above.
-
-Currently text fields are truncated to 255 characters. Obscure fields of
-some formats are not currently decoded; contact me if you want one
-added.
-
-
-Track length
-------------
-The library leaves it up to you as to when to stop playing a track. You
-can ask for available length information and then tell the library what
-time it should start fading the track with gme_set_fade(). By default it
-also continually checks for 6 or more seconds of silence to mark the end
-of a track. Here is a reasonable algorithm you can use to decide how
-long to play a track:
-
-* If the track length is > 0, use it
-* If the loop length > 0, play for intro + loop * 2
-* Otherwise, default to 2.5 minutes (150000 msec)
-
-If you want to play a track longer than normal, be sure the loop length
-isn't zero. See Music_Player.cpp around line 145 for example code.
-
-By default, the library skips silence at the beginning of a track. It
-also continually checks for the end of a non-looping track by watching
-for 6 seconds of unbroken silence. When doing this is scans *ahead* by
-several seconds so it can report the end of the track after only one
-second of silence has actually played. This feature can be disabled with
-gme_ignore_silence().
-
-
-Loading file data
------------------
-The library allows file data to be loaded in many different ways. All
-load functions return an error which you should check. The following
-examples assume these variables:
-
- Music_Emu* emu;
- gme_err_t error;
-
-If you're letting the library determine a file's type, you can use
-either gme_open_file() or gme_open_data():
-
- error = gme_open_file( pathname, &emu );
- error = gme_open_data( pointer, size, &emu );
-
-If you're manually determining file type and using used gme_new_emu() to
-create an emulator, you can use the following methods of loading:
-
-* From a block of memory:
-
- error = gme_load_data( emu, pointer, size );
-
-* Have library call your function to read data:
-
- gme_err_t my_read( void* my_data, void* out, long count )
- {
- // code that reads 'count' bytes into 'out' buffer
- // and return 0 if no error
- }
-
- error = gme_load_custom( emu, my_read, file_size, my_data );
-
-* If you must load the file data into memory yourself, you can have the
-library use your data directly *without* making a copy. If you do this,
-you must not free the data until you're done playing the file.
-
- error = emu->load_mem( pointer, size );
-
-* If you've already read the first bytes of a file (perhaps to determine
-the file type) and want to avoid seeking back to the beginning for
-performance reasons, use Remaining_Reader:
-
- Std_File_Reader in;
- error = in.open( file_path );
-
- char header [4];
- error = in.read( &header, sizeof header );
- ...
-
- Remaining_Reader rem( &header, sizeof header, &in );
- error = emu->load( rem );
-
-If you merely need access to a file's header after loading, use the
-emulator-specific header() functions, after casting the Music_Emu
-pointer to the specific emulator's type. This example examines the
-chip_flags field of the header if it's an NSF file:
-
- if ( music_emu->type() == gme_nsf_type )
- {
- Nsf_Emu* nsf_emu = (Nsf_Emu*) music_emu;
- if ( nsf_emu->header().chip_flags & 0x01 )
- ...
- }
-
-Contact me if you want more information about loading files.
-
-
-Sound parameters
-----------------
-All emulators support an arbitrary output sampling rate. A rate of 44100
-Hz should work well on most systems. Since band-limited synthesis is
-used, a sampling rate above 48000 Hz is not necessary and will actually
-reduce sound quality and performance.
-
-All emulators also support adjustable gain, mainly for the purpose of
-getting consistent volume between different music formats and avoiding
-excessive modulation. The gain can only be set *before* setting the
-emulator's sampling rate, so it's not useful as a general volume
-control. The default gains of emulators are set so that they give
-generally similar volumes, though some soundtracks are significantly
-louder or quieter than normal.
-
-Some emulators support adjustable treble and bass frequency equalization
-(AY, GBS, HES, KSS, NSF, NSFE, SAP, VGM) using set_equalizer().
-Parameters are specified using gme_equalizer_t eq = { treble_dB,
-bass_freq }. Treble_dB sets the treble level (in dB), where 0.0 dB gives
-normal treble; -200.0 dB is quite muffled, and 5.0 dB emphasizes treble
-for an extra crisp sound. Bass_freq sets the frequency where bass
-response starts to diminish; 15 Hz is normal, 0 Hz gives maximum bass,
-and 15000 Hz removes all bass. For example, the following makes the
-sound extra-crisp but lacking bass:
-
- gme_equalizer_t eq = { 5.0, 1000 };
- gme_set_equalizer( music_emu, &eq );
-
-Each emulator's equalization defaults to approximate the particular
-console's sound quality; this default can be determined by calling
-equalizer() just after creating the emulator. The Music_Emu::tv_eq
-profile gives sound as if coming from a TV speaker, and some emulators
-include other profiles for different versions of the system. For
-example, to use Famicom sound equalization with the NSF emulator, do the
-following:
-
- music_emu->set_equalizer( Nsf_Emu::famicom_eq );
-
-
-VGM/GYM YM2413 & YM2612 FM sound
---------------------------------
-The library plays Sega Genesis/Mega Drive music using a YM2612 FM sound
-chip emulator based on the Gens project. Because this has some
-inaccuracies, other YM2612 emulators can be used in its place by
-re-implementing the interface in YM2612_Emu.h. Available on my website
-is a modified version of MAME's YM2612 emulator, which sounds better in
-some ways and whose author is still making improvements.
-
-VGM music files using the YM2413 FM sound chip are also supported, but a
-YM2413 emulator isn't included with the library due to technical
-reasons. I have put one of the available YM2413 emulators on my website
-that can be used directly.
-
-
-Modular construction
---------------------
-The library is made of many fairly independent modules. If you're using
-only one music file emulator, you can eliminate many of the library
-sources from your program. Refer to the files list in readme.txt to get
-a general idea of what can be removed, and be sure to edit GME_TYPE_LIST
-(see "Emulator types" above). Post to the forum if you'd like me to put
-together a smaller version for a particular use, as this only takes me a
-few minutes to do.
-
-If you want to use one of the individual sound chip emulators (or CPU
-cores) in your own console emulator, first check the libraries page on
-my website since I have released several of them as stand alone
-libraries with included documentation and examples on their use. If you
-don't find it as a standalone library, contact me and I'll consider
-separating it.
-
-The "classic" sound chips use my Blip_Buffer library, which greatly
-simplifies their implementation and efficiently handles band-limited
-synthesis. It is also available as a stand alone library with
-documentation and many examples.
-
-
-Obscure features
-----------------
-The library's flexibility allows many possibilities. Contact me if you
-want help implementing ideas or removing limitations.
-
-* Uses no global/static variables, allowing multiple instances of any
-emulator. This is useful in a music player if you want to allow
-simultaneous recording or scanning of other tracks while one is already
-playing. This will also be useful if your platform disallows global
-data.
-
-* Emulators that support a custom sound buffer can have *every* voice
-routed to a different Blip_Buffer, allowing custom processing on each
-voice. For example you could record a Game Boy track as a 4-channel
-sound file.
-
-* Defining BLIP_BUFFER_FAST uses lower quality, less-multiply-intensive
-synthesis on "classic" emulators, which might help on some really old
-processors. This significantly lowers sound quality and prevents treble
-equalization. Try this if your platform's processor isn't fast enough
-for normal quality. Even on my ten-year-old 400 MHz Mac, this reduces
-processor usage at most by about 0.6% (from 4% to 3.4%), hardly worth
-the quality loss.
-
-
-Solving problems
-----------------
-If you're having problems, try the following:
-
-* If you're getting garbled sound, try this simple siren generator in
-place of your call to play(). This will quickly tell whether the problem
-is in the library or in your code.
-
- static void play_siren( long count, short* out )
- {
- static double a, a2;
- while ( count-- )
- *out++ = 0x2000 * sin( a += .1 + .05*sin( a2+=.00005 ) );
- }
-
-* Enable debugging support in your environment. This enables assertions
-and other run-time checks.
-
-* Turn the compiler's optimizer is off. Sometimes an optimizer generates
-bad code.
-
-* If multiple threads are being used, ensure that only one at a time is
-accessing a given set of objects from the library. This library is not
-in general thread-safe, though independent objects can be used in
-separate threads.
-
-* If all else fails, see if the demos work.
-
-
-Deprecated features
--------------------
-The following functions and other features have been deprecated and will
-be removed in a future release of the library. Alternatives to the
-deprecated features are listed to the right.
-
-Music_Emu::error_count() warning()
-load( header, reader ) see "Loading file data" above
-Spc_Emu::trailer() track_info()
-Spc_Emu::trailer_size()
-Gym_Emu::track_length() track_info()
-Vgm_Emu::gd3_data() track_info()
-Nsfe_Emu::disable_playlist() clear_playlist()
-
-
-Thanks
-------
-Big thanks to Chris Moeller (kode54) for help with library testing and
-feedback, for maintaining the Foobar2000 plugin foo_gep based on it, and
-for original work on openspc++ that was used when developing Spc_Emu.
-Brad Martin's excellent OpenSPC SNES DSP emulator worked well from the
-start. Also thanks to Richard Bannister, Mahendra Tallur, Shazz,
-nenolod, theHobbit, Johan Samuelsson, and nes6502 for testing, using,
-and giving feedback for the library in their respective game music
-players.
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Ay_Apu.cpp b/plugins/gme/Game_Music_Emu-0.5.2/gme/Ay_Apu.cpp
deleted file mode 100644
index 9dc5bb28..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Ay_Apu.cpp
+++ /dev/null
@@ -1,395 +0,0 @@
-// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
-
-#include "Ay_Apu.h"
-
-/* Copyright (C) 2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-// Emulation inaccuracies:
-// * Noise isn't run when not in use
-// * Changes to envelope and noise periods are delayed until next reload
-// * Super-sonic tone should attenuate output to about 60%, not 50%
-
-// Tones above this frequency are treated as disabled tone at half volume.
-// Power of two is more efficient (avoids division).
-unsigned const inaudible_freq = 16384;
-
-int const period_factor = 16;
-
-static byte const amp_table [16] =
-{
-#define ENTRY( n ) byte (n * Ay_Apu::amp_range + 0.5)
- // With channels tied together and 1K resistor to ground (as datasheet recommends),
- // output nearly matches logarithmic curve as claimed. Approx. 1.5 dB per step.
- ENTRY(0.000000),ENTRY(0.007813),ENTRY(0.011049),ENTRY(0.015625),
- ENTRY(0.022097),ENTRY(0.031250),ENTRY(0.044194),ENTRY(0.062500),
- ENTRY(0.088388),ENTRY(0.125000),ENTRY(0.176777),ENTRY(0.250000),
- ENTRY(0.353553),ENTRY(0.500000),ENTRY(0.707107),ENTRY(1.000000),
-
- /*
- // Measured from an AY-3-8910A chip with date code 8611.
-
- // Direct voltages without any load (very linear)
- ENTRY(0.000000),ENTRY(0.046237),ENTRY(0.064516),ENTRY(0.089785),
- ENTRY(0.124731),ENTRY(0.173118),ENTRY(0.225806),ENTRY(0.329032),
- ENTRY(0.360215),ENTRY(0.494624),ENTRY(0.594624),ENTRY(0.672043),
- ENTRY(0.766129),ENTRY(0.841935),ENTRY(0.926882),ENTRY(1.000000),
- // With only some load
- ENTRY(0.000000),ENTRY(0.011940),ENTRY(0.017413),ENTRY(0.024876),
- ENTRY(0.036318),ENTRY(0.054229),ENTRY(0.072637),ENTRY(0.122388),
- ENTRY(0.174129),ENTRY(0.239303),ENTRY(0.323881),ENTRY(0.410945),
- ENTRY(0.527363),ENTRY(0.651741),ENTRY(0.832338),ENTRY(1.000000),
- */
-#undef ENTRY
-};
-
-static byte const modes [8] =
-{
-#define MODE( a0,a1, b0,b1, c0,c1 ) \
- (a0 | a1<<1 | b0<<2 | b1<<3 | c0<<4 | c1<<5)
- MODE( 1,0, 1,0, 1,0 ),
- MODE( 1,0, 0,0, 0,0 ),
- MODE( 1,0, 0,1, 1,0 ),
- MODE( 1,0, 1,1, 1,1 ),
- MODE( 0,1, 0,1, 0,1 ),
- MODE( 0,1, 1,1, 1,1 ),
- MODE( 0,1, 1,0, 0,1 ),
- MODE( 0,1, 0,0, 0,0 ),
-};
-
-Ay_Apu::Ay_Apu()
-{
- // build full table of the upper 8 envelope waveforms
- for ( int m = 8; m--; )
- {
- byte* out = env.modes [m];
- int flags = modes [m];
- for ( int x = 3; --x >= 0; )
- {
- int amp = flags & 1;
- int end = flags >> 1 & 1;
- int step = end - amp;
- amp *= 15;
- for ( int y = 16; --y >= 0; )
- {
- *out++ = amp_table [amp];
- amp += step;
- }
- flags >>= 2;
- }
- }
-
- output( 0 );
- volume( 1.0 );
- reset();
-}
-
-void Ay_Apu::reset()
-{
- last_time = 0;
- noise.delay = 0;
- noise.lfsr = 1;
-
- osc_t* osc = &oscs [osc_count];
- do
- {
- osc--;
- osc->period = period_factor;
- osc->delay = 0;
- osc->last_amp = 0;
- osc->phase = 0;
- }
- while ( osc != oscs );
-
- for ( int i = sizeof regs; --i >= 0; )
- regs [i] = 0;
- regs [7] = 0xFF;
- write_data_( 13, 0 );
-}
-
-void Ay_Apu::write_data_( int addr, int data )
-{
- assert( (unsigned) addr < reg_count );
-
- if ( (unsigned) addr >= 14 )
- {
- #ifdef dprintf
- dprintf( "Wrote to I/O port %02X\n", (int) addr );
- #endif
- }
-
- // envelope mode
- if ( addr == 13 )
- {
- if ( !(data & 8) ) // convert modes 0-7 to proper equivalents
- data = (data & 4) ? 15 : 9;
- env.wave = env.modes [data - 7];
- env.pos = -48;
- env.delay = 0; // will get set to envelope period in run_until()
- }
- regs [addr] = data;
-
- // handle period changes accurately
- int i = addr >> 1;
- if ( i < osc_count )
- {
- blip_time_t period = (regs [i * 2 + 1] & 0x0F) * (0x100L * period_factor) +
- regs [i * 2] * period_factor;
- if ( !period )
- period = period_factor;
-
- // adjust time of next timer expiration based on change in period
- osc_t& osc = oscs [i];
- if ( (osc.delay += period - osc.period) < 0 )
- osc.delay = 0;
- osc.period = period;
- }
-
- // TODO: same as above for envelope timer, and it also has a divide by two after it
-}
-
-int const noise_off = 0x08;
-int const tone_off = 0x01;
-
-void Ay_Apu::run_until( blip_time_t final_end_time )
-{
- require( final_end_time >= last_time );
-
- // noise period and initial values
- blip_time_t const noise_period_factor = period_factor * 2; // verified
- blip_time_t noise_period = (regs [6] & 0x1F) * noise_period_factor;
- if ( !noise_period )
- noise_period = noise_period_factor;
- blip_time_t const old_noise_delay = noise.delay;
- blargg_ulong const old_noise_lfsr = noise.lfsr;
-
- // envelope period
- blip_time_t const env_period_factor = period_factor * 2; // verified
- blip_time_t env_period = (regs [12] * 0x100L + regs [11]) * env_period_factor;
- if ( !env_period )
- env_period = env_period_factor; // same as period 1 on my AY chip
- if ( !env.delay )
- env.delay = env_period;
-
- // run each osc separately
- for ( int index = 0; index < osc_count; index++ )
- {
- osc_t* const osc = &oscs [index];
- int osc_mode = regs [7] >> index;
-
- // output
- Blip_Buffer* const osc_output = osc->output;
- if ( !osc_output )
- continue;
- osc_output->set_modified();
-
- // period
- int half_vol = 0;
- blip_time_t inaudible_period = (blargg_ulong) (osc_output->clock_rate() +
- inaudible_freq) / (inaudible_freq * 2);
- if ( osc->period <= inaudible_period && !(osc_mode & tone_off) )
- {
- half_vol = 1; // Actually around 60%, but 50% is close enough
- osc_mode |= tone_off;
- }
-
- // envelope
- blip_time_t start_time = last_time;
- blip_time_t end_time = final_end_time;
- int const vol_mode = regs [0x08 + index];
- int volume = amp_table [vol_mode & 0x0F] >> half_vol;
- int osc_env_pos = env.pos;
- if ( vol_mode & 0x10 )
- {
- volume = env.wave [osc_env_pos] >> half_vol;
- // use envelope only if it's a repeating wave or a ramp that hasn't finished
- if ( !(regs [13] & 1) || osc_env_pos < -32 )
- {
- end_time = start_time + env.delay;
- if ( end_time >= final_end_time )
- end_time = final_end_time;
-
- //if ( !(regs [12] | regs [11]) )
- // dprintf( "Used envelope period 0\n" );
- }
- else if ( !volume )
- {
- osc_mode = noise_off | tone_off;
- }
- }
- else if ( !volume )
- {
- osc_mode = noise_off | tone_off;
- }
-
- // tone time
- blip_time_t const period = osc->period;
- blip_time_t time = start_time + osc->delay;
- if ( osc_mode & tone_off ) // maintain tone's phase when off
- {
- blargg_long count = (final_end_time - time + period - 1) / period;
- time += count * period;
- osc->phase ^= count & 1;
- }
-
- // noise time
- blip_time_t ntime = final_end_time;
- blargg_ulong noise_lfsr = 1;
- if ( !(osc_mode & noise_off) )
- {
- ntime = start_time + old_noise_delay;
- noise_lfsr = old_noise_lfsr;
- //if ( (regs [6] & 0x1F) == 0 )
- // dprintf( "Used noise period 0\n" );
- }
-
- // The following efficiently handles several cases (least demanding first):
- // * Tone, noise, and envelope disabled, where channel acts as 4-bit DAC
- // * Just tone or just noise, envelope disabled
- // * Envelope controlling tone and/or noise
- // * Tone and noise disabled, envelope enabled with high frequency
- // * Tone and noise together
- // * Tone and noise together with envelope
-
- // This loop only runs one iteration if envelope is disabled. If envelope
- // is being used as a waveform (tone and noise disabled), this loop will
- // still be reasonably efficient since the bulk of it will be skipped.
- while ( 1 )
- {
- // current amplitude
- int amp = 0;
- if ( (osc_mode | osc->phase) & 1 & (osc_mode >> 3 | noise_lfsr) )
- amp = volume;
- {
- int delta = amp - osc->last_amp;
- if ( delta )
- {
- osc->last_amp = amp;
- synth_.offset( start_time, delta, osc_output );
- }
- }
-
- // Run wave and noise interleved with each catching up to the other.
- // If one or both are disabled, their "current time" will be past end time,
- // so there will be no significant performance hit.
- if ( ntime < end_time || time < end_time )
- {
- // Since amplitude was updated above, delta will always be +/- volume,
- // so we can avoid using last_amp every time to calculate the delta.
- int delta = amp * 2 - volume;
- int delta_non_zero = delta != 0;
- int phase = osc->phase | (osc_mode & tone_off); assert( tone_off == 0x01 );
- do
- {
- // run noise
- blip_time_t end = end_time;
- if ( end_time > time ) end = time;
- if ( phase & delta_non_zero )
- {
- while ( ntime <= end ) // must advance *past* time to avoid hang
- {
- int changed = noise_lfsr + 1;
- noise_lfsr = (-(noise_lfsr & 1) & 0x12000) ^ (noise_lfsr >> 1);
- if ( changed & 2 )
- {
- delta = -delta;
- synth_.offset( ntime, delta, osc_output );
- }
- ntime += noise_period;
- }
- }
- else
- {
- // 20 or more noise periods on average for some music
- blargg_long remain = end - ntime;
- blargg_long count = remain / noise_period;
- if ( remain >= 0 )
- ntime += noise_period + count * noise_period;
- }
-
- // run tone
- end = end_time;
- if ( end_time > ntime ) end = ntime;
- if ( noise_lfsr & delta_non_zero )
- {
- while ( time < end )
- {
- delta = -delta;
- synth_.offset( time, delta, osc_output );
- time += period;
- //phase ^= 1;
- }
- //assert( phase == (delta > 0) );
- phase = unsigned (-delta) >> (CHAR_BIT * sizeof (unsigned) - 1);
- // (delta > 0)
- }
- else
- {
- // loop usually runs less than once
- //SUB_CASE_COUNTER( (time < end) * (end - time + period - 1) / period );
-
- while ( time < end )
- {
- time += period;
- phase ^= 1;
- }
- }
- }
- while ( time < end_time || ntime < end_time );
-
- osc->last_amp = (delta + volume) >> 1;
- if ( !(osc_mode & tone_off) )
- osc->phase = phase;
- }
-
- if ( end_time >= final_end_time )
- break; // breaks first time when envelope is disabled
-
- // next envelope step
- if ( ++osc_env_pos >= 0 )
- osc_env_pos -= 32;
- volume = env.wave [osc_env_pos] >> half_vol;
-
- start_time = end_time;
- end_time += env_period;
- if ( end_time > final_end_time )
- end_time = final_end_time;
- }
- osc->delay = time - final_end_time;
-
- if ( !(osc_mode & noise_off) )
- {
- noise.delay = ntime - final_end_time;
- noise.lfsr = noise_lfsr;
- }
- }
-
- // TODO: optimized saw wave envelope?
-
- // maintain envelope phase
- blip_time_t remain = final_end_time - last_time - env.delay;
- if ( remain >= 0 )
- {
- blargg_long count = (remain + env_period) / env_period;
- env.pos += count;
- if ( env.pos >= 0 )
- env.pos = (env.pos & 31) - 32;
- remain -= count * env_period;
- assert( -remain <= env_period );
- }
- env.delay = -remain;
- assert( env.delay > 0 );
- assert( env.pos < 0 );
-
- last_time = final_end_time;
-}
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Ay_Apu.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/Ay_Apu.h
deleted file mode 100644
index 31956939..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Ay_Apu.h
+++ /dev/null
@@ -1,107 +0,0 @@
-// AY-3-8910 sound chip emulator
-
-// Game_Music_Emu 0.5.2
-#ifndef AY_APU_H
-#define AY_APU_H
-
-#include "blargg_common.h"
-#include "Blip_Buffer.h"
-
-class Ay_Apu {
-public:
- // Set buffer to generate all sound into, or disable sound if NULL
- void output( Blip_Buffer* );
-
- // Reset sound chip
- void reset();
-
- // Write to register at specified time
- enum { reg_count = 16 };
- void write( blip_time_t time, int addr, int data );
-
- // Run sound to specified time, end current time frame, then start a new
- // time frame at time 0. Time frames have no effect on emulation and each
- // can be whatever length is convenient.
- void end_frame( blip_time_t length );
-
-// Additional features
-
- // Set sound output of specific oscillator to buffer, where index is
- // 0, 1, or 2. If buffer is NULL, the specified oscillator is muted.
- enum { osc_count = 3 };
- void osc_output( int index, Blip_Buffer* );
-
- // Set overall volume (default is 1.0)
- void volume( double );
-
- // Set treble equalization (see documentation)
- void treble_eq( blip_eq_t const& );
-
-public:
- Ay_Apu();
- typedef unsigned char byte;
-private:
- struct osc_t
- {
- blip_time_t period;
- blip_time_t delay;
- short last_amp;
- short phase;
- Blip_Buffer* output;
- } oscs [osc_count];
- blip_time_t last_time;
- byte latch;
- byte regs [reg_count];
-
- struct {
- blip_time_t delay;
- blargg_ulong lfsr;
- } noise;
-
- struct {
- blip_time_t delay;
- byte const* wave;
- int pos;
- byte modes [8] [48]; // values already passed through volume table
- } env;
-
- void run_until( blip_time_t );
- void write_data_( int addr, int data );
-public:
- enum { amp_range = 255 };
- Blip_Synth<blip_good_quality,1> synth_;
-};
-
-inline void Ay_Apu::volume( double v ) { synth_.volume( 0.7 / osc_count / amp_range * v ); }
-
-inline void Ay_Apu::treble_eq( blip_eq_t const& eq ) { synth_.treble_eq( eq ); }
-
-inline void Ay_Apu::write( blip_time_t time, int addr, int data )
-{
- run_until( time );
- write_data_( addr, data );
-}
-
-inline void Ay_Apu::osc_output( int i, Blip_Buffer* buf )
-{
- assert( (unsigned) i < osc_count );
- oscs [i].output = buf;
-}
-
-inline void Ay_Apu::output( Blip_Buffer* buf )
-{
- osc_output( 0, buf );
- osc_output( 1, buf );
- osc_output( 2, buf );
-}
-
-inline void Ay_Apu::end_frame( blip_time_t time )
-{
- if ( time > last_time )
- run_until( time );
-
- assert( last_time >= time );
- last_time -= time;
-}
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Ay_Cpu.cpp b/plugins/gme/Game_Music_Emu-0.5.2/gme/Ay_Cpu.cpp
deleted file mode 100644
index 6ff7156b..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Ay_Cpu.cpp
+++ /dev/null
@@ -1,1665 +0,0 @@
-// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
-
-/*
-Last validated with zexall 2006.11.21 5:26 PM
-* Doesn't implement the R register or immediate interrupt after EI.
-* Address wrap-around isn't completely correct, but is prevented from crashing emulator.
-*/
-
-#include "Ay_Cpu.h"
-
-#include "blargg_endian.h"
-#include <string.h>
-
-//#include "z80_cpu_log.h"
-
-/* Copyright (C) 2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#define SYNC_TIME() (void) (s.time = s_time)
-#define RELOAD_TIME() (void) (s_time = s.time)
-
-// Callbacks to emulator
-
-#define CPU_OUT( cpu, addr, data, TIME )\
- ay_cpu_out( cpu, TIME, addr, data )
-
-#define CPU_IN( cpu, addr, TIME )\
- ay_cpu_in( cpu, addr )
-
-#include "blargg_source.h"
-
-// flags, named with hex value for clarity
-int const S80 = 0x80;
-int const Z40 = 0x40;
-int const F20 = 0x20;
-int const H10 = 0x10;
-int const F08 = 0x08;
-int const V04 = 0x04;
-int const P04 = 0x04;
-int const N02 = 0x02;
-int const C01 = 0x01;
-
-#define SZ28P( n ) szpc [n]
-#define SZ28PC( n ) szpc [n]
-#define SZ28C( n ) (szpc [n] & ~P04)
-#define SZ28( n ) SZ28C( n )
-
-#define SET_R( n ) (void) (r.r = n)
-#define GET_R() (r.r)
-
-Ay_Cpu::Ay_Cpu()
-{
- state = &state_;
- for ( int i = 0x100; --i >= 0; )
- {
- int even = 1;
- for ( int p = i; p; p >>= 1 )
- even ^= p;
- int n = (i & (S80 | F20 | F08)) | ((even & 1) * P04);
- szpc [i] = n;
- szpc [i + 0x100] = n | C01;
- }
- szpc [0x000] |= Z40;
- szpc [0x100] |= Z40;
-}
-
-void Ay_Cpu::reset( void* m )
-{
- mem = (uint8_t*) m;
-
- check( state == &state_ );
- state = &state_;
- state_.time = 0;
- state_.base = 0;
- end_time_ = 0;
-
- memset( &r, 0, sizeof r );
-}
-
-#define TIME (s_time + s.base)
-#define READ_PROG( addr ) (mem [addr])
-#define INSTR( offset ) READ_PROG( pc + (offset) )
-#define GET_ADDR() GET_LE16( &READ_PROG( pc ) )
-#define READ( addr ) READ_PROG( addr )
-#define WRITE( addr, data ) (void) (READ_PROG( addr ) = data)
-#define READ_WORD( addr ) GET_LE16( &READ_PROG( addr ) )
-#define WRITE_WORD( addr, data ) SET_LE16( &READ_PROG( addr ), data )
-#define IN( addr ) CPU_IN( this, addr, TIME )
-#define OUT( addr, data ) CPU_OUT( this, addr, data, TIME )
-
-#if BLARGG_BIG_ENDIAN
- #define R8( n, offset ) ((r8_ - offset) [n])
-#elif BLARGG_LITTLE_ENDIAN
- #define R8( n, offset ) ((r8_ - offset) [(n) ^ 1])
-#else
- #error "Byte order of CPU must be known"
-#endif
-
-//#define R16( n, shift, offset ) (r16_ [((n) >> shift) - (offset >> shift)])
-
-// help compiler see that it can just adjust stack offset, saving an extra instruction
-#define R16( n, shift, offset )\
- (*(uint16_t*) ((char*) r16_ - (offset >> (shift - 1)) + ((n) >> (shift - 1))))
-
-#define CASE5( a, b, c, d, e ) case 0x##a:case 0x##b:case 0x##c:case 0x##d:case 0x##e
-#define CASE6( a, b, c, d, e, f ) CASE5( a, b, c, d, e ): case 0x##f
-#define CASE7( a, b, c, d, e, f, g ) CASE6( a, b, c, d, e, f ): case 0x##g
-#define CASE8( a, b, c, d, e, f, g, h ) CASE7( a, b, c, d, e, f, g ): case 0x##h
-
-// high four bits are $ED time - 8, low four bits are $DD/$FD time - 8
-static byte const ed_dd_timing [0x100] = {
-//0 1 2 3 4 5 6 7 8 9 A B C D E F
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x06,0x0C,0x02,0x00,0x00,0x03,0x00,0x00,0x07,0x0C,0x02,0x00,0x00,0x03,0x00,
-0x00,0x00,0x00,0x00,0x0F,0x0F,0x0B,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x10,0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x10,
-0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x10,0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x10,
-0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0xA0,0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0xA0,
-0x4B,0x4B,0x7B,0xCB,0x0B,0x6B,0x00,0x0B,0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00,
-0x80,0x80,0x80,0x80,0x00,0x00,0x0B,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x0B,0x00,
-0xD0,0xD0,0xD0,0xD0,0x00,0x00,0x0B,0x00,0xD0,0xD0,0xD0,0xD0,0x00,0x00,0x0B,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x06,0x00,0x0F,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,
-};
-
-// even on x86, using short and unsigned char was slower
-typedef int fint16;
-typedef unsigned fuint16;
-typedef unsigned fuint8;
-
-bool Ay_Cpu::run( cpu_time_t end_time )
-{
- set_end_time( end_time );
- state_t s = this->state_;
- this->state = &s;
- bool warning = false;
-
- typedef BOOST::int8_t int8_t;
-
- union {
- regs_t rg;
- pairs_t rp;
- uint8_t r8_ [8]; // indexed
- uint16_t r16_ [4];
- };
- rg = this->r.b;
-
- cpu_time_t s_time = s.time;
- uint8_t* const mem = this->mem; // cache
- fuint16 pc = r.pc;
- fuint16 sp = r.sp;
- fuint16 ix = r.ix; // TODO: keep in memory for direct access?
- fuint16 iy = r.iy;
- int flags = r.b.flags;
-
- goto loop;
-jr_not_taken:
- s_time -= 5;
- goto loop;
-call_not_taken:
- s_time -= 7;
-jp_not_taken:
- pc += 2;
-loop:
-
- check( (unsigned long) pc < 0x10000 );
- check( (unsigned long) sp < 0x10000 );
- check( (unsigned) flags < 0x100 );
- check( (unsigned) ix < 0x10000 );
- check( (unsigned) iy < 0x10000 );
-
- fuint8 opcode;
- opcode = READ_PROG( pc );
- pc++;
-
- static byte const base_timing [0x100] = {
- // 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 4,10, 7, 6, 4, 4, 7, 4, 4,11, 7, 6, 4, 4, 7, 4, // 0
- 13,10, 7, 6, 4, 4, 7, 4,12,11, 7, 6, 4, 4, 7, 4, // 1
- 12,10,16, 6, 4, 4, 7, 4,12,11,16, 6, 4, 4, 7, 4, // 2
- 12,10,13, 6,11,11,10, 4,12,11,13, 6, 4, 4, 7, 4, // 3
- 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 4
- 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 5
- 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 6
- 7, 7, 7, 7, 7, 7, 4, 7, 4, 4, 4, 4, 4, 4, 7, 4, // 7
- 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 8
- 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 9
- 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // A
- 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // B
- 11,10,10,10,17,11, 7,11,11,10,10, 8,17,17, 7,11, // C
- 11,10,10,11,17,11, 7,11,11, 4,10,11,17, 8, 7,11, // D
- 11,10,10,19,17,11, 7,11,11, 4,10, 4,17, 8, 7,11, // E
- 11,10,10, 4,17,11, 7,11,11, 6,10, 4,17, 8, 7,11, // F
- };
-
- fuint16 data;
- data = base_timing [opcode];
- if ( (s_time += data) >= 0 )
- goto possibly_out_of_time;
-almost_out_of_time:
-
- data = READ_PROG( pc );
-
- #ifdef Z80_CPU_LOG_H
- //log_opcode( opcode, READ_PROG( pc ) );
- z80_log_regs( rg.a, rp.bc, rp.de, rp.hl, sp, ix, iy );
- z80_cpu_log( "new", pc - 1, opcode, READ_PROG( pc ),
- READ_PROG( pc + 1 ), READ_PROG( pc + 2 ) );
- #endif
-
- switch ( opcode )
- {
-possibly_out_of_time:
- if ( s_time < (int) data )
- goto almost_out_of_time;
- s_time -= data;
- goto out_of_time;
-
-// Common
-
- case 0x00: // NOP
- CASE7( 40, 49, 52, 5B, 64, 6D, 7F ): // LD B,B etc.
- goto loop;
-
- case 0x08:{// EX AF,AF'
- int temp = r.alt.b.a;
- r.alt.b.a = rg.a;
- rg.a = temp;
-
- temp = r.alt.b.flags;
- r.alt.b.flags = flags;
- flags = temp;
- goto loop;
- }
-
- case 0xD3: // OUT (imm),A
- pc++;
- OUT( data + rg.a * 0x100, rg.a );
- goto loop;
-
- case 0x2E: // LD L,imm
- pc++;
- rg.l = data;
- goto loop;
-
- case 0x3E: // LD A,imm
- pc++;
- rg.a = data;
- goto loop;
-
- case 0x3A:{// LD A,(addr)
- fuint16 addr = GET_ADDR();
- pc += 2;
- rg.a = READ( addr );
- goto loop;
- }
-
-// Conditional
-
-#define ZERO (flags & Z40)
-#define CARRY (flags & C01)
-#define EVEN (flags & P04)
-#define MINUS (flags & S80)
-
-// JR
-#define JR( cond ) {\
- int disp = (BOOST::int8_t) data;\
- pc++;\
- if ( !(cond) )\
- goto jr_not_taken;\
- pc += disp;\
- goto loop;\
-}
-
- case 0x20: JR( !ZERO ) // JR NZ,disp
- case 0x28: JR( ZERO ) // JR Z,disp
- case 0x30: JR( !CARRY ) // JR NC,disp
- case 0x38: JR( CARRY ) // JR C,disp
- case 0x18: JR( true ) // JR disp
-
- case 0x10:{// DJNZ disp
- int temp = rg.b - 1;
- rg.b = temp;
- JR( temp )
- }
-
-// JP
-#define JP( cond ) if ( !(cond) ) goto jp_not_taken; pc = GET_ADDR(); goto loop;
-
- case 0xC2: JP( !ZERO ) // JP NZ,addr
- case 0xCA: JP( ZERO ) // JP Z,addr
- case 0xD2: JP( !CARRY ) // JP NC,addr
- case 0xDA: JP( CARRY ) // JP C,addr
- case 0xE2: JP( !EVEN ) // JP PO,addr
- case 0xEA: JP( EVEN ) // JP PE,addr
- case 0xF2: JP( !MINUS ) // JP P,addr
- case 0xFA: JP( MINUS ) // JP M,addr
-
- case 0xC3: // JP addr
- pc = GET_ADDR();
- goto loop;
-
- case 0xE9: // JP HL
- pc = rp.hl;
- goto loop;
-
-// RET
-#define RET( cond ) if ( cond ) goto ret_taken; s_time -= 6; goto loop;
-
- case 0xC0: RET( !ZERO ) // RET NZ
- case 0xC8: RET( ZERO ) // RET Z
- case 0xD0: RET( !CARRY ) // RET NC
- case 0xD8: RET( CARRY ) // RET C
- case 0xE0: RET( !EVEN ) // RET PO
- case 0xE8: RET( EVEN ) // RET PE
- case 0xF0: RET( !MINUS ) // RET P
- case 0xF8: RET( MINUS ) // RET M
-
- case 0xC9: // RET
- ret_taken:
- pc = READ_WORD( sp );
- sp = uint16_t (sp + 2);
- goto loop;
-
-// CALL
-#define CALL( cond ) if ( cond ) goto call_taken; goto call_not_taken;
-
- case 0xC4: CALL( !ZERO ) // CALL NZ,addr
- case 0xCC: CALL( ZERO ) // CALL Z,addr
- case 0xD4: CALL( !CARRY ) // CALL NC,addr
- case 0xDC: CALL( CARRY ) // CALL C,addr
- case 0xE4: CALL( !EVEN ) // CALL PO,addr
- case 0xEC: CALL( EVEN ) // CALL PE,addr
- case 0xF4: CALL( !MINUS ) // CALL P,addr
- case 0xFC: CALL( MINUS ) // CALL M,addr
-
- case 0xCD:{// CALL addr
- call_taken:
- fuint16 addr = pc + 2;
- pc = GET_ADDR();
- sp = uint16_t (sp - 2);
- WRITE_WORD( sp, addr );
- goto loop;
- }
-
- case 0xFF: // RST
- if ( (pc - 1) > 0xFFFF )
- {
- pc = uint16_t (pc - 1);
- s_time -= 11;
- goto loop;
- }
- CASE7( C7, CF, D7, DF, E7, EF, F7 ):
- data = pc;
- pc = opcode & 0x38;
- goto push_data;
-
-// PUSH/POP
- case 0xF5: // PUSH AF
- data = rg.a * 0x100u + flags;
- goto push_data;
-
- case 0xC5: // PUSH BC
- case 0xD5: // PUSH DE
- case 0xE5: // PUSH HL
- data = R16( opcode, 4, 0xC5 );
- push_data:
- sp = uint16_t (sp - 2);
- WRITE_WORD( sp, data );
- goto loop;
-
- case 0xF1: // POP AF
- flags = READ( sp );
- rg.a = READ( sp + 1 );
- sp = uint16_t (sp + 2);
- goto loop;
-
- case 0xC1: // POP BC
- case 0xD1: // POP DE
- case 0xE1: // POP HL
- R16( opcode, 4, 0xC1 ) = READ_WORD( sp );
- sp = uint16_t (sp + 2);
- goto loop;
-
-// ADC/ADD/SBC/SUB
- case 0x96: // SUB (HL)
- case 0x86: // ADD (HL)
- flags &= ~C01;
- case 0x9E: // SBC (HL)
- case 0x8E: // ADC (HL)
- data = READ( rp.hl );
- goto adc_data;
-
- case 0xD6: // SUB A,imm
- case 0xC6: // ADD imm
- flags &= ~C01;
- case 0xDE: // SBC A,imm
- case 0xCE: // ADC imm
- pc++;
- goto adc_data;
-
- CASE7( 90, 91, 92, 93, 94, 95, 97 ): // SUB r
- CASE7( 80, 81, 82, 83, 84, 85, 87 ): // ADD r
- flags &= ~C01;
- CASE7( 98, 99, 9A, 9B, 9C, 9D, 9F ): // SBC r
- CASE7( 88, 89, 8A, 8B, 8C, 8D, 8F ): // ADC r
- data = R8( opcode & 7, 0 );
- adc_data: {
- int result = data + (flags & C01);
- data ^= rg.a;
- flags = opcode >> 3 & N02; // bit 4 is set in subtract opcodes
- if ( flags )
- result = -result;
- result += rg.a;
- data ^= result;
- flags |=(data & H10) |
- ((data - -0x80) >> 6 & V04) |
- SZ28C( result & 0x1FF );
- rg.a = result;
- goto loop;
- }
-
-// CP
- case 0xBE: // CP (HL)
- data = READ( rp.hl );
- goto cp_data;
-
- case 0xFE: // CP imm
- pc++;
- goto cp_data;
-
- CASE7( B8, B9, BA, BB, BC, BD, BF ): // CP r
- data = R8( opcode, 0xB8 );
- cp_data: {
- int result = rg.a - data;
- flags = N02 | (data & (F20 | F08)) | (result >> 8 & C01);
- data ^= rg.a;
- flags |=(((result ^ rg.a) & data) >> 5 & V04) |
- (((data & H10) ^ result) & (S80 | H10));
- if ( (uint8_t) result )
- goto loop;
- flags |= Z40;
- goto loop;
- }
-
-// ADD HL,rp
-
- case 0x39: // ADD HL,SP
- data = sp;
- goto add_hl_data;
-
- case 0x09: // ADD HL,BC
- case 0x19: // ADD HL,DE
- case 0x29: // ADD HL,HL
- data = R16( opcode, 4, 0x09 );
- add_hl_data: {
- blargg_ulong sum = rp.hl + data;
- data ^= rp.hl;
- rp.hl = sum;
- flags = (flags & (S80 | Z40 | V04)) |
- (sum >> 16) |
- (sum >> 8 & (F20 | F08)) |
- ((data ^ sum) >> 8 & H10);
- goto loop;
- }
-
- case 0x27:{// DAA
- int a = rg.a;
- if ( a > 0x99 )
- flags |= C01;
-
- int adjust = 0x60 & -(flags & C01);
-
- if ( flags & H10 || (a & 0x0F) > 9 )
- adjust |= 0x06;
-
- if ( flags & N02 )
- adjust = -adjust;
- a += adjust;
-
- flags = (flags & (C01 | N02)) |
- ((rg.a ^ a) & H10) |
- SZ28P( (uint8_t) a );
- rg.a = a;
- goto loop;
- }
- /*
- case 0x27:{// DAA
- // more optimized, but probably not worth the obscurity
- int f = (rg.a + (0xFF - 0x99)) >> 8 | flags; // (a > 0x99 ? C01 : 0) | flags
- int adjust = 0x60 & -(f & C01); // f & C01 ? 0x60 : 0
-
- if ( (((rg.a + (0x0F - 9)) ^ rg.a) | f) & H10 ) // flags & H10 || (rg.a & 0x0F) > 9
- adjust |= 0x06;
-
- if ( f & N02 )
- adjust = -adjust;
- int a = rg.a + adjust;
-
- flags = (f & (N02 | C01)) | ((rg.a ^ a) & H10) | SZ28P( (uint8_t) a );
- rg.a = a;
- goto loop;
- }
- */
-
-// INC/DEC
- case 0x34: // INC (HL)
- data = READ( rp.hl ) + 1;
- WRITE( rp.hl, data );
- goto inc_set_flags;
-
- CASE7( 04, 0C, 14, 1C, 24, 2C, 3C ): // INC r
- data = ++R8( opcode >> 3, 0 );
- inc_set_flags:
- flags = (flags & C01) |
- (((data & 0x0F) - 1) & H10) |
- SZ28( (uint8_t) data );
- if ( data != 0x80 )
- goto loop;
- flags |= V04;
- goto loop;
-
- case 0x35: // DEC (HL)
- data = READ( rp.hl ) - 1;
- WRITE( rp.hl, data );
- goto dec_set_flags;
-
- CASE7( 05, 0D, 15, 1D, 25, 2D, 3D ): // DEC r
- data = --R8( opcode >> 3, 0 );
- dec_set_flags:
- flags = (flags & C01) | N02 |
- (((data & 0x0F) + 1) & H10) |
- SZ28( (uint8_t) data );
- if ( data != 0x7F )
- goto loop;
- flags |= V04;
- goto loop;
-
- case 0x03: // INC BC
- case 0x13: // INC DE
- case 0x23: // INC HL
- R16( opcode, 4, 0x03 )++;
- goto loop;
-
- case 0x33: // INC SP
- sp = uint16_t (sp + 1);
- goto loop;
-
- case 0x0B: // DEC BC
- case 0x1B: // DEC DE
- case 0x2B: // DEC HL
- R16( opcode, 4, 0x0B )--;
- goto loop;
-
- case 0x3B: // DEC SP
- sp = uint16_t (sp - 1);
- goto loop;
-
-// AND
- case 0xA6: // AND (HL)
- data = READ( rp.hl );
- goto and_data;
-
- case 0xE6: // AND imm
- pc++;
- goto and_data;
-
- CASE7( A0, A1, A2, A3, A4, A5, A7 ): // AND r
- data = R8( opcode, 0xA0 );
- and_data:
- rg.a &= data;
- flags = SZ28P( rg.a ) | H10;
- goto loop;
-
-// OR
- case 0xB6: // OR (HL)
- data = READ( rp.hl );
- goto or_data;
-
- case 0xF6: // OR imm
- pc++;
- goto or_data;
-
- CASE7( B0, B1, B2, B3, B4, B5, B7 ): // OR r
- data = R8( opcode, 0xB0 );
- or_data:
- rg.a |= data;
- flags = SZ28P( rg.a );
- goto loop;
-
-// XOR
- case 0xAE: // XOR (HL)
- data = READ( rp.hl );
- goto xor_data;
-
- case 0xEE: // XOR imm
- pc++;
- goto xor_data;
-
- CASE7( A8, A9, AA, AB, AC, AD, AF ): // XOR r
- data = R8( opcode, 0xA8 );
- xor_data:
- rg.a ^= data;
- flags = SZ28P( rg.a );
- goto loop;
-
-// LD
- CASE7( 70, 71, 72, 73, 74, 75, 77 ): // LD (HL),r
- WRITE( rp.hl, R8( opcode, 0x70 ) );
- goto loop;
-
- CASE6( 41, 42, 43, 44, 45, 47 ): // LD B,r
- CASE6( 48, 4A, 4B, 4C, 4D, 4F ): // LD C,r
- CASE6( 50, 51, 53, 54, 55, 57 ): // LD D,r
- CASE6( 58, 59, 5A, 5C, 5D, 5F ): // LD E,r
- CASE6( 60, 61, 62, 63, 65, 67 ): // LD H,r
- CASE6( 68, 69, 6A, 6B, 6C, 6F ): // LD L,r
- CASE6( 78, 79, 7A, 7B, 7C, 7D ): // LD A,r
- R8( opcode >> 3 & 7, 0 ) = R8( opcode & 7, 0 );
- goto loop;
-
- CASE5( 06, 0E, 16, 1E, 26 ): // LD r,imm
- R8( opcode >> 3, 0 ) = data;
- pc++;
- goto loop;
-
- case 0x36: // LD (HL),imm
- pc++;
- WRITE( rp.hl, data );
- goto loop;
-
- CASE7( 46, 4E, 56, 5E, 66, 6E, 7E ): // LD r,(HL)
- R8( opcode >> 3, 8 ) = READ( rp.hl );
- goto loop;
-
- case 0x01: // LD rp,imm
- case 0x11:
- case 0x21:
- R16( opcode, 4, 0x01 ) = GET_ADDR();
- pc += 2;
- goto loop;
-
- case 0x31: // LD sp,imm
- sp = GET_ADDR();
- pc += 2;
- goto loop;
-
- case 0x2A:{// LD HL,(addr)
- fuint16 addr = GET_ADDR();
- pc += 2;
- rp.hl = READ_WORD( addr );
- goto loop;
- }
-
- case 0x32:{// LD (addr),A
- fuint16 addr = GET_ADDR();
- pc += 2;
- WRITE( addr, rg.a );
- goto loop;
- }
-
- case 0x22:{// LD (addr),HL
- fuint16 addr = GET_ADDR();
- pc += 2;
- WRITE_WORD( addr, rp.hl );
- goto loop;
- }
-
- case 0x02: // LD (BC),A
- case 0x12: // LD (DE),A
- WRITE( R16( opcode, 4, 0x02 ), rg.a );
- goto loop;
-
- case 0x0A: // LD A,(BC)
- case 0x1A: // LD A,(DE)
- rg.a = READ( R16( opcode, 4, 0x0A ) );
- goto loop;
-
- case 0xF9: // LD SP,HL
- sp = rp.hl;
- goto loop;
-
-// Rotate
-
- case 0x07:{// RLCA
- fuint16 temp = rg.a;
- temp = (temp << 1) | (temp >> 7);
- flags = (flags & (S80 | Z40 | P04)) |
- (temp & (F20 | F08 | C01));
- rg.a = temp;
- goto loop;
- }
-
- case 0x0F:{// RRCA
- fuint16 temp = rg.a;
- flags = (flags & (S80 | Z40 | P04)) |
- (temp & C01);
- temp = (temp << 7) | (temp >> 1);
- flags |= temp & (F20 | F08);
- rg.a = temp;
- goto loop;
- }
-
- case 0x17:{// RLA
- blargg_ulong temp = (rg.a << 1) | (flags & C01);
- flags = (flags & (S80 | Z40 | P04)) |
- (temp & (F20 | F08)) |
- (temp >> 8);
- rg.a = temp;
- goto loop;
- }
-
- case 0x1F:{// RRA
- fuint16 temp = (flags << 7) | (rg.a >> 1);
- flags = (flags & (S80 | Z40 | P04)) |
- (temp & (F20 | F08)) |
- (rg.a & C01);
- rg.a = temp;
- goto loop;
- }
-
-// Misc
- case 0x2F:{// CPL
- fuint16 temp = ~rg.a;
- flags = (flags & (S80 | Z40 | P04 | C01)) |
- (temp & (F20 | F08)) |
- (H10 | N02);
- rg.a = temp;
- goto loop;
- }
-
- case 0x3F:{// CCF
- flags = ((flags & (S80 | Z40 | P04 | C01)) ^ C01) |
- (flags << 4 & H10) |
- (rg.a & (F20 | F08));
- goto loop;
- }
-
- case 0x37: // SCF
- flags = (flags & (S80 | Z40 | P04)) | C01 |
- (rg.a & (F20 | F08));
- goto loop;
-
- case 0xDB: // IN A,(imm)
- pc++;
- rg.a = IN( data + rg.a * 0x100 );
- goto loop;
-
- case 0xE3:{// EX (SP),HL
- fuint16 temp = READ_WORD( sp );
- WRITE_WORD( sp, rp.hl );
- rp.hl = temp;
- goto loop;
- }
-
- case 0xEB:{// EX DE,HL
- fuint16 temp = rp.hl;
- rp.hl = rp.de;
- rp.de = temp;
- goto loop;
- }
-
- case 0xD9:{// EXX DE,HL
- fuint16 temp = r.alt.w.bc;
- r.alt.w.bc = rp.bc;
- rp.bc = temp;
-
- temp = r.alt.w.de;
- r.alt.w.de = rp.de;
- rp.de = temp;
-
- temp = r.alt.w.hl;
- r.alt.w.hl = rp.hl;
- rp.hl = temp;
- goto loop;
- }
-
- case 0xF3: // DI
- r.iff1 = 0;
- r.iff2 = 0;
- goto loop;
-
- case 0xFB: // EI
- r.iff1 = 1;
- r.iff2 = 1;
- // TODO: delayed effect
- goto loop;
-
- case 0x76: // HALT
- goto halt;
-
-//////////////////////////////////////// CB prefix
- {
- case 0xCB:
- unsigned data2;
- data2 = INSTR( 1 );
- pc++;
- switch ( data )
- {
-
- // Rotate left
-
- #define RLC( read, write ) {\
- fuint8 result = read;\
- result = uint8_t (result << 1) | (result >> 7);\
- flags = SZ28P( result ) | (result & C01);\
- write;\
- goto loop;\
- }
-
- case 0x06: // RLC (HL)
- s_time += 7;
- data = rp.hl;
- rlc_data_addr:
- RLC( READ( data ), WRITE( data, result ) )
-
- CASE7( 00, 01, 02, 03, 04, 05, 07 ):{// RLC r
- uint8_t& reg = R8( data, 0 );
- RLC( reg, reg = result )
- }
-
- #define RL( read, write ) {\
- fuint16 result = (read << 1) | (flags & C01);\
- flags = SZ28PC( result );\
- write;\
- goto loop;\
- }
-
- case 0x16: // RL (HL)
- s_time += 7;
- data = rp.hl;
- rl_data_addr:
- RL( READ( data ), WRITE( data, result ) )
-
- CASE7( 10, 11, 12, 13, 14, 15, 17 ):{// RL r
- uint8_t& reg = R8( data, 0x10 );
- RL( reg, reg = result )
- }
-
- #define SLA( read, add, write ) {\
- fuint16 result = (read << 1) | add;\
- flags = SZ28PC( result );\
- write;\
- goto loop;\
- }
-
- case 0x26: // SLA (HL)
- s_time += 7;
- data = rp.hl;
- sla_data_addr:
- SLA( READ( data ), 0, WRITE( data, result ) )
-
- CASE7( 20, 21, 22, 23, 24, 25, 27 ):{// SLA r
- uint8_t& reg = R8( data, 0x20 );
- SLA( reg, 0, reg = result )
- }
-
- case 0x36: // SLL (HL)
- s_time += 7;
- data = rp.hl;
- sll_data_addr:
- SLA( READ( data ), 1, WRITE( data, result ) )
-
- CASE7( 30, 31, 32, 33, 34, 35, 37 ):{// SLL r
- uint8_t& reg = R8( data, 0x30 );
- SLA( reg, 1, reg = result )
- }
-
- // Rotate right
-
- #define RRC( read, write ) {\
- fuint8 result = read;\
- flags = result & C01;\
- result = uint8_t (result << 7) | (result >> 1);\
- flags |= SZ28P( result );\
- write;\
- goto loop;\
- }
-
- case 0x0E: // RRC (HL)
- s_time += 7;
- data = rp.hl;
- rrc_data_addr:
- RRC( READ( data ), WRITE( data, result ) )
-
- CASE7( 08, 09, 0A, 0B, 0C, 0D, 0F ):{// RRC r
- uint8_t& reg = R8( data, 0x08 );
- RRC( reg, reg = result )
- }
-
- #define RR( read, write ) {\
- fuint8 result = read;\
- fuint8 temp = result & C01;\
- result = uint8_t (flags << 7) | (result >> 1);\
- flags = SZ28P( result ) | temp;\
- write;\
- goto loop;\
- }
-
- case 0x1E: // RR (HL)
- s_time += 7;
- data = rp.hl;
- rr_data_addr:
- RR( READ( data ), WRITE( data, result ) )
-
- CASE7( 18, 19, 1A, 1B, 1C, 1D, 1F ):{// RR r
- uint8_t& reg = R8( data, 0x18 );
- RR( reg, reg = result )
- }
-
- #define SRA( read, write ) {\
- fuint8 result = read;\
- flags = result & C01;\
- result = (result & 0x80) | (result >> 1);\
- flags |= SZ28P( result );\
- write;\
- goto loop;\
- }
-
- case 0x2E: // SRA (HL)
- data = rp.hl;
- s_time += 7;
- sra_data_addr:
- SRA( READ( data ), WRITE( data, result ) )
-
- CASE7( 28, 29, 2A, 2B, 2C, 2D, 2F ):{// SRA r
- uint8_t& reg = R8( data, 0x28 );
- SRA( reg, reg = result )
- }
-
- #define SRL( read, write ) {\
- fuint8 result = read;\
- flags = result & C01;\
- result >>= 1;\
- flags |= SZ28P( result );\
- write;\
- goto loop;\
- }
-
- case 0x3E: // SRL (HL)
- s_time += 7;
- data = rp.hl;
- srl_data_addr:
- SRL( READ( data ), WRITE( data, result ) )
-
- CASE7( 38, 39, 3A, 3B, 3C, 3D, 3F ):{// SRL r
- uint8_t& reg = R8( data, 0x38 );
- SRL( reg, reg = result )
- }
-
- // BIT
- {
- unsigned temp;
- CASE8( 46, 4E, 56, 5E, 66, 6E, 76, 7E ): // BIT b,(HL)
- s_time += 4;
- temp = READ( rp.hl );
- flags &= C01;
- goto bit_temp;
- CASE7( 40, 41, 42, 43, 44, 45, 47 ): // BIT 0,r
- CASE7( 48, 49, 4A, 4B, 4C, 4D, 4F ): // BIT 1,r
- CASE7( 50, 51, 52, 53, 54, 55, 57 ): // BIT 2,r
- CASE7( 58, 59, 5A, 5B, 5C, 5D, 5F ): // BIT 3,r
- CASE7( 60, 61, 62, 63, 64, 65, 67 ): // BIT 4,r
- CASE7( 68, 69, 6A, 6B, 6C, 6D, 6F ): // BIT 5,r
- CASE7( 70, 71, 72, 73, 74, 75, 77 ): // BIT 6,r
- CASE7( 78, 79, 7A, 7B, 7C, 7D, 7F ): // BIT 7,r
- temp = R8( data & 7, 0 );
- flags = (flags & C01) | (temp & (F20 | F08));
- bit_temp:
- int masked = temp & 1 << (data >> 3 & 7);
- flags |=(masked & S80) | H10 |
- ((masked - 1) >> 8 & (Z40 | P04));
- goto loop;
- }
-
- // SET/RES
- CASE8( 86, 8E, 96, 9E, A6, AE, B6, BE ): // RES b,(HL)
- CASE8( C6, CE, D6, DE, E6, EE, F6, FE ):{// SET b,(HL)
- s_time += 7;
- int temp = READ( rp.hl );
- int bit = 1 << (data >> 3 & 7);
- temp |= bit; // SET
- if ( !(data & 0x40) )
- temp ^= bit; // RES
- WRITE( rp.hl, temp );
- goto loop;
- }
-
- CASE7( C0, C1, C2, C3, C4, C5, C7 ): // SET 0,r
- CASE7( C8, C9, CA, CB, CC, CD, CF ): // SET 1,r
- CASE7( D0, D1, D2, D3, D4, D5, D7 ): // SET 2,r
- CASE7( D8, D9, DA, DB, DC, DD, DF ): // SET 3,r
- CASE7( E0, E1, E2, E3, E4, E5, E7 ): // SET 4,r
- CASE7( E8, E9, EA, EB, EC, ED, EF ): // SET 5,r
- CASE7( F0, F1, F2, F3, F4, F5, F7 ): // SET 6,r
- CASE7( F8, F9, FA, FB, FC, FD, FF ): // SET 7,r
- R8( data & 7, 0 ) |= 1 << (data >> 3 & 7);
- goto loop;
-
- CASE7( 80, 81, 82, 83, 84, 85, 87 ): // RES 0,r
- CASE7( 88, 89, 8A, 8B, 8C, 8D, 8F ): // RES 1,r
- CASE7( 90, 91, 92, 93, 94, 95, 97 ): // RES 2,r
- CASE7( 98, 99, 9A, 9B, 9C, 9D, 9F ): // RES 3,r
- CASE7( A0, A1, A2, A3, A4, A5, A7 ): // RES 4,r
- CASE7( A8, A9, AA, AB, AC, AD, AF ): // RES 5,r
- CASE7( B0, B1, B2, B3, B4, B5, B7 ): // RES 6,r
- CASE7( B8, B9, BA, BB, BC, BD, BF ): // RES 7,r
- R8( data & 7, 0 ) &= ~(1 << (data >> 3 & 7));
- goto loop;
- }
- assert( false );
- }
-
-//////////////////////////////////////// ED prefix
- {
- case 0xED:
- pc++;
- s_time += ed_dd_timing [data] >> 4;
- switch ( data )
- {
- {
- blargg_ulong temp;
- case 0x72: // SBC HL,SP
- case 0x7A: // ADC HL,SP
- temp = sp;
- if ( 0 )
- case 0x42: // SBC HL,BC
- case 0x52: // SBC HL,DE
- case 0x62: // SBC HL,HL
- case 0x4A: // ADC HL,BC
- case 0x5A: // ADC HL,DE
- case 0x6A: // ADC HL,HL
- temp = R16( data >> 3 & 6, 1, 0 );
- blargg_ulong sum = temp + (flags & C01);
- flags = ~data >> 2 & N02;
- if ( flags )
- sum = -sum;
- sum += rp.hl;
- temp ^= rp.hl;
- temp ^= sum;
- flags |=(sum >> 16 & C01) |
- (temp >> 8 & H10) |
- (sum >> 8 & (S80 | F20 | F08)) |
- ((temp - -0x8000) >> 14 & V04);
- rp.hl = sum;
- if ( (uint16_t) sum )
- goto loop;
- flags |= Z40;
- goto loop;
- }
-
- CASE8( 40, 48, 50, 58, 60, 68, 70, 78 ):{// IN r,(C)
- int temp = IN( rp.bc );
- R8( data >> 3, 8 ) = temp;
- flags = (flags & C01) | SZ28P( temp );
- goto loop;
- }
-
- case 0x71: // OUT (C),0
- rg.flags = 0;
- CASE7( 41, 49, 51, 59, 61, 69, 79 ): // OUT (C),r
- OUT( rp.bc, R8( data >> 3, 8 ) );
- goto loop;
-
- {
- unsigned temp;
- case 0x73: // LD (ADDR),SP
- temp = sp;
- if ( 0 )
- case 0x43: // LD (ADDR),BC
- case 0x53: // LD (ADDR),DE
- temp = R16( data, 4, 0x43 );
- fuint16 addr = GET_ADDR();
- pc += 2;
- WRITE_WORD( addr, temp );
- goto loop;
- }
-
- case 0x4B: // LD BC,(ADDR)
- case 0x5B:{// LD DE,(ADDR)
- fuint16 addr = GET_ADDR();
- pc += 2;
- R16( data, 4, 0x4B ) = READ_WORD( addr );
- goto loop;
- }
-
- case 0x7B:{// LD SP,(ADDR)
- fuint16 addr = GET_ADDR();
- pc += 2;
- sp = READ_WORD( addr );
- goto loop;
- }
-
- case 0x67:{// RRD
- fuint8 temp = READ( rp.hl );
- WRITE( rp.hl, (rg.a << 4) | (temp >> 4) );
- temp = (rg.a & 0xF0) | (temp & 0x0F);
- flags = (flags & C01) | SZ28P( temp );
- rg.a = temp;
- goto loop;
- }
-
- case 0x6F:{// RLD
- fuint8 temp = READ( rp.hl );
- WRITE( rp.hl, (temp << 4) | (rg.a & 0x0F) );
- temp = (rg.a & 0xF0) | (temp >> 4);
- flags = (flags & C01) | SZ28P( temp );
- rg.a = temp;
- goto loop;
- }
-
- CASE8( 44, 4C, 54, 5C, 64, 6C, 74, 7C ): // NEG
- opcode = 0x10; // flag to do SBC instead of ADC
- flags &= ~C01;
- data = rg.a;
- rg.a = 0;
- goto adc_data;
-
- {
- int inc;
- case 0xA9: // CPD
- case 0xB9: // CPDR
- inc = -1;
- if ( 0 )
- case 0xA1: // CPI
- case 0xB1: // CPIR
- inc = +1;
- fuint16 addr = rp.hl;
- rp.hl = addr + inc;
- int temp = READ( addr );
-
- int result = rg.a - temp;
- flags = (flags & C01) | N02 |
- ((((temp ^ rg.a) & H10) ^ result) & (S80 | H10));
-
- if ( !(uint8_t) result ) flags |= Z40;
- result -= (flags & H10) >> 4;
- flags |= result & F08;
- flags |= result << 4 & F20;
- if ( !--rp.bc )
- goto loop;
-
- flags |= V04;
- if ( flags & Z40 || data < 0xB0 )
- goto loop;
-
- pc -= 2;
- s_time += 5;
- goto loop;
- }
-
- {
- int inc;
- case 0xA8: // LDD
- case 0xB8: // LDDR
- inc = -1;
- if ( 0 )
- case 0xA0: // LDI
- case 0xB0: // LDIR
- inc = +1;
- fuint16 addr = rp.hl;
- rp.hl = addr + inc;
- int temp = READ( addr );
-
- addr = rp.de;
- rp.de = addr + inc;
- WRITE( addr, temp );
-
- temp += rg.a;
- flags = (flags & (S80 | Z40 | C01)) |
- (temp & F08) | (temp << 4 & F20);
- if ( !--rp.bc )
- goto loop;
-
- flags |= V04;
- if ( data < 0xB0 )
- goto loop;
-
- pc -= 2;
- s_time += 5;
- goto loop;
- }
-
- {
- int inc;
- case 0xAB: // OUTD
- case 0xBB: // OTDR
- inc = -1;
- if ( 0 )
- case 0xA3: // OUTI
- case 0xB3: // OTIR
- inc = +1;
- fuint16 addr = rp.hl;
- rp.hl = addr + inc;
- int temp = READ( addr );
-
- int b = --rg.b;
- flags = (temp >> 6 & N02) | SZ28( b );
- if ( b && data >= 0xB0 )
- {
- pc -= 2;
- s_time += 5;
- }
-
- OUT( rp.bc, temp );
- goto loop;
- }
-
- {
- int inc;
- case 0xAA: // IND
- case 0xBA: // INDR
- inc = -1;
- if ( 0 )
- case 0xA2: // INI
- case 0xB2: // INIR
- inc = +1;
-
- fuint16 addr = rp.hl;
- rp.hl = addr + inc;
-
- int temp = IN( rp.bc );
-
- int b = --rg.b;
- flags = (temp >> 6 & N02) | SZ28( b );
- if ( b && data >= 0xB0 )
- {
- pc -= 2;
- s_time += 5;
- }
-
- WRITE( addr, temp );
- goto loop;
- }
-
- case 0x47: // LD I,A
- r.i = rg.a;
- goto loop;
-
- case 0x4F: // LD R,A
- SET_R( rg.a );
- dprintf( "LD R,A not supported\n" );
- warning = true;
- goto loop;
-
- case 0x57: // LD A,I
- rg.a = r.i;
- goto ld_ai_common;
-
- case 0x5F: // LD A,R
- rg.a = GET_R();
- dprintf( "LD A,R not supported\n" );
- warning = true;
- ld_ai_common:
- flags = (flags & C01) | SZ28( rg.a ) | (r.iff2 << 2 & V04);
- goto loop;
-
- CASE8( 45, 4D, 55, 5D, 65, 6D, 75, 7D ): // RETI/RETN
- r.iff1 = r.iff2;
- goto ret_taken;
-
- case 0x46: case 0x4E: case 0x66: case 0x6E: // IM 0
- r.im = 0;
- goto loop;
-
- case 0x56: case 0x76: // IM 1
- r.im = 1;
- goto loop;
-
- case 0x5E: case 0x7E: // IM 2
- r.im = 2;
- goto loop;
-
- default:
- dprintf( "Opcode $ED $%02X not supported\n", data );
- warning = true;
- goto loop;
- }
- assert( false );
- }
-
-//////////////////////////////////////// DD/FD prefix
- {
- fuint16 ixy;
- case 0xDD:
- ixy = ix;
- goto ix_prefix;
- case 0xFD:
- ixy = iy;
- ix_prefix:
- pc++;
- unsigned data2 = READ_PROG( pc );
- s_time += ed_dd_timing [data] & 0x0F;
- switch ( data )
- {
- // TODO: more efficient way of avoid negative address
- #define IXY_DISP( ixy, disp ) uint16_t ((ixy) + (disp))
-
- #define SET_IXY( in ) if ( opcode == 0xDD ) ix = in; else iy = in;
-
- // ADD/ADC/SUB/SBC
-
- case 0x96: // SUB (IXY+disp)
- case 0x86: // ADD (IXY+disp)
- flags &= ~C01;
- case 0x9E: // SBC (IXY+disp)
- case 0x8E: // ADC (IXY+disp)
- pc++;
- opcode = data;
- data = READ( IXY_DISP( ixy, (int8_t) data2 ) );
- goto adc_data;
-
- case 0x94: // SUB HXY
- case 0x84: // ADD HXY
- flags &= ~C01;
- case 0x9C: // SBC HXY
- case 0x8C: // ADC HXY
- opcode = data;
- data = ixy >> 8;
- goto adc_data;
-
- case 0x95: // SUB LXY
- case 0x85: // ADD LXY
- flags &= ~C01;
- case 0x9D: // SBC LXY
- case 0x8D: // ADC LXY
- opcode = data;
- data = (uint8_t) ixy;
- goto adc_data;
-
- {
- unsigned temp;
- case 0x39: // ADD IXY,SP
- temp = sp;
- goto add_ixy_data;
-
- case 0x29: // ADD IXY,HL
- temp = ixy;
- goto add_ixy_data;
-
- case 0x09: // ADD IXY,BC
- case 0x19: // ADD IXY,DE
- temp = R16( data, 4, 0x09 );
- add_ixy_data: {
- blargg_ulong sum = ixy + temp;
- temp ^= ixy;
- ixy = (uint16_t) sum;
- flags = (flags & (S80 | Z40 | V04)) |
- (sum >> 16) |
- (sum >> 8 & (F20 | F08)) |
- ((temp ^ sum) >> 8 & H10);
- goto set_ixy;
- }
- }
-
- // AND
- case 0xA6: // AND (IXY+disp)
- pc++;
- data = READ( IXY_DISP( ixy, (int8_t) data2 ) );
- goto and_data;
-
- case 0xA4: // AND HXY
- data = ixy >> 8;
- goto and_data;
-
- case 0xA5: // AND LXY
- data = (uint8_t) ixy;
- goto and_data;
-
- // OR
- case 0xB6: // OR (IXY+disp)
- pc++;
- data = READ( IXY_DISP( ixy, (int8_t) data2 ) );
- goto or_data;
-
- case 0xB4: // OR HXY
- data = ixy >> 8;
- goto or_data;
-
- case 0xB5: // OR LXY
- data = (uint8_t) ixy;
- goto or_data;
-
- // XOR
- case 0xAE: // XOR (IXY+disp)
- pc++;
- data = READ( IXY_DISP( ixy, (int8_t) data2 ) );
- goto xor_data;
-
- case 0xAC: // XOR HXY
- data = ixy >> 8;
- goto xor_data;
-
- case 0xAD: // XOR LXY
- data = (uint8_t) ixy;
- goto xor_data;
-
- // CP
- case 0xBE: // CP (IXY+disp)
- pc++;
- data = READ( IXY_DISP( ixy, (int8_t) data2 ) );
- goto cp_data;
-
- case 0xBC: // CP HXY
- data = ixy >> 8;
- goto cp_data;
-
- case 0xBD: // CP LXY
- data = (uint8_t) ixy;
- goto cp_data;
-
- // LD
- CASE7( 70, 71, 72, 73, 74, 75, 77 ): // LD (IXY+disp),r
- data = R8( data, 0x70 );
- if ( 0 )
- case 0x36: // LD (IXY+disp),imm
- pc++, data = READ_PROG( pc );
- pc++;
- WRITE( IXY_DISP( ixy, (int8_t) data2 ), data );
- goto loop;
-
- CASE5( 44, 4C, 54, 5C, 7C ): // LD r,HXY
- R8( data >> 3, 8 ) = ixy >> 8;
- goto loop;
-
- case 0x64: // LD HXY,HXY
- case 0x6D: // LD LXY,LXY
- goto loop;
-
- CASE5( 45, 4D, 55, 5D, 7D ): // LD r,LXY
- R8( data >> 3, 8 ) = ixy;
- goto loop;
-
- CASE7( 46, 4E, 56, 5E, 66, 6E, 7E ): // LD r,(IXY+disp)
- pc++;
- R8( data >> 3, 8 ) = READ( IXY_DISP( ixy, (int8_t) data2 ) );
- goto loop;
-
- case 0x26: // LD HXY,imm
- pc++;
- goto ld_hxy_data;
-
- case 0x65: // LD HXY,LXY
- data2 = (uint8_t) ixy;
- goto ld_hxy_data;
-
- CASE5( 60, 61, 62, 63, 67 ): // LD HXY,r
- data2 = R8( data, 0x60 );
- ld_hxy_data:
- ixy = (uint8_t) ixy | (data2 << 8);
- goto set_ixy;
-
- case 0x2E: // LD LXY,imm
- pc++;
- goto ld_lxy_data;
-
- case 0x6C: // LD LXY,HXY
- data2 = ixy >> 8;
- goto ld_lxy_data;
-
- CASE5( 68, 69, 6A, 6B, 6F ): // LD LXY,r
- data2 = R8( data, 0x68 );
- ld_lxy_data:
- ixy = (ixy & 0xFF00) | data2;
- set_ixy:
- if ( opcode == 0xDD )
- {
- ix = ixy;
- goto loop;
- }
- iy = ixy;
- goto loop;
-
- case 0xF9: // LD SP,IXY
- sp = ixy;
- goto loop;
-
- case 0x22:{// LD (ADDR),IXY
- fuint16 addr = GET_ADDR();
- pc += 2;
- WRITE_WORD( addr, ixy );
- goto loop;
- }
-
- case 0x21: // LD IXY,imm
- ixy = GET_ADDR();
- pc += 2;
- goto set_ixy;
-
- case 0x2A:{// LD IXY,(addr)
- fuint16 addr = GET_ADDR();
- ixy = READ_WORD( addr );
- pc += 2;
- goto set_ixy;
- }
-
- // DD/FD CB prefix
- case 0xCB: {
- data = IXY_DISP( ixy, (int8_t) data2 );
- pc++;
- data2 = READ_PROG( pc );
- pc++;
- switch ( data2 )
- {
- case 0x06: goto rlc_data_addr; // RLC (IXY)
- case 0x16: goto rl_data_addr; // RL (IXY)
- case 0x26: goto sla_data_addr; // SLA (IXY)
- case 0x36: goto sll_data_addr; // SLL (IXY)
- case 0x0E: goto rrc_data_addr; // RRC (IXY)
- case 0x1E: goto rr_data_addr; // RR (IXY)
- case 0x2E: goto sra_data_addr; // SRA (IXY)
- case 0x3E: goto srl_data_addr; // SRL (IXY)
-
- CASE8( 46, 4E, 56, 5E, 66, 6E, 76, 7E ):{// BIT b,(IXY+disp)
- fuint8 temp = READ( data );
- int masked = temp & 1 << (data2 >> 3 & 7);
- flags = (flags & C01) | H10 |
- (masked & S80) |
- ((masked - 1) >> 8 & (Z40 | P04));
- goto loop;
- }
-
- CASE8( 86, 8E, 96, 9E, A6, AE, B6, BE ): // RES b,(IXY+disp)
- CASE8( C6, CE, D6, DE, E6, EE, F6, FE ):{// SET b,(IXY+disp)
- int temp = READ( data );
- int bit = 1 << (data2 >> 3 & 7);
- temp |= bit; // SET
- if ( !(data2 & 0x40) )
- temp ^= bit; // RES
- WRITE( data, temp );
- goto loop;
- }
-
- default:
- dprintf( "Opcode $%02X $CB $%02X not supported\n", opcode, data2 );
- warning = true;
- goto loop;
- }
- assert( false );
- }
-
- // INC/DEC
- case 0x23: // INC IXY
- ixy = uint16_t (ixy + 1);
- goto set_ixy;
-
- case 0x2B: // DEC IXY
- ixy = uint16_t (ixy - 1);
- goto set_ixy;
-
- case 0x34: // INC (IXY+disp)
- ixy = IXY_DISP( ixy, (int8_t) data2 );
- pc++;
- data = READ( ixy ) + 1;
- WRITE( ixy, data );
- goto inc_set_flags;
-
- case 0x35: // DEC (IXY+disp)
- ixy = IXY_DISP( ixy, (int8_t) data2 );
- pc++;
- data = READ( ixy ) - 1;
- WRITE( ixy, data );
- goto dec_set_flags;
-
- case 0x24: // INC HXY
- ixy = uint16_t (ixy + 0x100);
- data = ixy >> 8;
- goto inc_xy_common;
-
- case 0x2C: // INC LXY
- data = uint8_t (ixy + 1);
- ixy = (ixy & 0xFF00) | data;
- inc_xy_common:
- if ( opcode == 0xDD )
- {
- ix = ixy;
- goto inc_set_flags;
- }
- iy = ixy;
- goto inc_set_flags;
-
- case 0x25: // DEC HXY
- ixy = uint16_t (ixy - 0x100);
- data = ixy >> 8;
- goto dec_xy_common;
-
- case 0x2D: // DEC LXY
- data = uint8_t (ixy - 1);
- ixy = (ixy & 0xFF00) | data;
- dec_xy_common:
- if ( opcode == 0xDD )
- {
- ix = ixy;
- goto dec_set_flags;
- }
- iy = ixy;
- goto dec_set_flags;
-
- // PUSH/POP
- case 0xE5: // PUSH IXY
- data = ixy;
- goto push_data;
-
- case 0xE1:{// POP IXY
- ixy = READ_WORD( sp );
- sp = uint16_t (sp + 2);
- goto set_ixy;
- }
-
- // Misc
-
- case 0xE9: // JP (IXY)
- pc = ixy;
- goto loop;
-
- case 0xE3:{// EX (SP),IXY
- fuint16 temp = READ_WORD( sp );
- WRITE_WORD( sp, ixy );
- ixy = temp;
- goto set_ixy;
- }
-
- default:
- dprintf( "Unnecessary DD/FD prefix encountered\n" );
- warning = true;
- pc--;
- goto loop;
- }
- assert( false );
- }
-
- }
- dprintf( "Unhandled main opcode: $%02X\n", opcode );
- assert( false );
-
-halt:
- s_time &= 3; // increment by multiple of 4
-out_of_time:
- pc--;
-
- s.time = s_time;
- rg.flags = flags;
- r.ix = ix;
- r.iy = iy;
- r.sp = sp;
- r.pc = pc;
- this->r.b = rg;
- this->state_ = s;
- this->state = &this->state_;
-
- return warning;
-}
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Ay_Cpu.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/Ay_Cpu.h
deleted file mode 100644
index 07241d5e..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Ay_Cpu.h
+++ /dev/null
@@ -1,92 +0,0 @@
-// Z80 CPU emulator
-
-// Game_Music_Emu 0.5.2
-#ifndef AY_CPU_H
-#define AY_CPU_H
-
-#include "blargg_endian.h"
-
-typedef blargg_long cpu_time_t;
-
-// must be defined by caller
-void ay_cpu_out( class Ay_Cpu*, cpu_time_t, unsigned addr, int data );
-int ay_cpu_in( class Ay_Cpu*, unsigned addr );
-
-class Ay_Cpu {
-public:
- // Clear all registers and keep pointer to 64K memory passed in
- void reset( void* mem_64k );
-
- // Run until specified time is reached. Returns true if suspicious/unsupported
- // instruction was encountered at any point during run.
- bool run( cpu_time_t end_time );
-
- // Time of beginning of next instruction
- cpu_time_t time() const { return state->time + state->base; }
-
- // Alter current time. Not supported during run() call.
- void set_time( cpu_time_t t ) { state->time = t - state->base; }
- void adjust_time( int delta ) { state->time += delta; }
-
- typedef BOOST::uint8_t uint8_t;
- typedef BOOST::uint16_t uint16_t;
-
- #if BLARGG_BIG_ENDIAN
- struct regs_t { uint8_t b, c, d, e, h, l, flags, a; };
- #else
- struct regs_t { uint8_t c, b, e, d, l, h, a, flags; };
- #endif
- BOOST_STATIC_ASSERT( sizeof (regs_t) == 8 );
-
- struct pairs_t { uint16_t bc, de, hl, fa; };
-
- // Registers are not updated until run() returns
- struct registers_t {
- uint16_t pc;
- uint16_t sp;
- uint16_t ix;
- uint16_t iy;
- union {
- regs_t b; // b.b, b.c, b.d, b.e, b.h, b.l, b.flags, b.a
- pairs_t w; // w.bc, w.de, w.hl. w.fa
- };
- union {
- regs_t b;
- pairs_t w;
- } alt;
- uint8_t iff1;
- uint8_t iff2;
- uint8_t r;
- uint8_t i;
- uint8_t im;
- };
- //registers_t r; (below for efficiency)
-
- // can read this far past end of memory
- enum { cpu_padding = 0x100 };
-
-public:
- Ay_Cpu();
-private:
- uint8_t szpc [0x200];
- uint8_t* mem;
- cpu_time_t end_time_;
- struct state_t {
- cpu_time_t base;
- cpu_time_t time;
- };
- state_t* state; // points to state_ or a local copy within run()
- state_t state_;
- void set_end_time( cpu_time_t t );
-public:
- registers_t r;
-};
-
-inline void Ay_Cpu::set_end_time( cpu_time_t t )
-{
- cpu_time_t delta = state->base - t;
- state->base = t;
- state->time += delta;
-}
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Ay_Emu.cpp b/plugins/gme/Game_Music_Emu-0.5.2/gme/Ay_Emu.cpp
deleted file mode 100644
index bdc82e9e..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Ay_Emu.cpp
+++ /dev/null
@@ -1,404 +0,0 @@
-// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
-
-#include "Ay_Emu.h"
-
-#include "blargg_endian.h"
-#include <string.h>
-
-/* Copyright (C) 2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-long const spectrum_clock = 3546900;
-long const cpc_clock = 2000000;
-
-unsigned const ram_start = 0x4000;
-int const osc_count = Ay_Apu::osc_count + 1;
-
-Ay_Emu::Ay_Emu()
-{
- beeper_output = 0;
- set_type( gme_ay_type );
-
- static const char* const names [osc_count] = {
- "Wave 1", "Wave 2", "Wave 3", "Beeper"
- };
- set_voice_names( names );
-
- static int const types [osc_count] = {
- wave_type | 0, wave_type | 1, wave_type | 2, mixed_type | 0
- };
- set_voice_types( types );
- set_silence_lookahead( 6 );
-}
-
-Ay_Emu::~Ay_Emu() { }
-
-// Track info
-
-static byte const* get_data( Ay_Emu::file_t const& file, byte const* ptr, int min_size )
-{
- long pos = ptr - (byte const*) file.header;
- long file_size = file.end - (byte const*) file.header;
- assert( (unsigned long) pos <= (unsigned long) file_size - 2 );
- int offset = (BOOST::int16_t) get_be16( ptr );
- if ( !offset || blargg_ulong (pos + offset) > blargg_ulong (file_size - min_size) )
- return 0;
- return ptr + offset;
-}
-
-static blargg_err_t parse_header( byte const* in, long size, Ay_Emu::file_t* out )
-{
- typedef Ay_Emu::header_t header_t;
- out->header = (header_t const*) in;
- out->end = in + size;
-
- if ( size < Ay_Emu::header_size )
- return gme_wrong_file_type;
-
- header_t const& h = *(header_t const*) in;
- if ( memcmp( h.tag, "ZXAYEMUL", 8 ) )
- return gme_wrong_file_type;
-
- out->tracks = get_data( *out, h.track_info, (h.max_track + 1) * 4 );
- if ( !out->tracks )
- return "Missing track data";
-
- return 0;
-}
-
-static void copy_ay_fields( Ay_Emu::file_t const& file, track_info_t* out, int track )
-{
- Gme_File::copy_field_( out->song, (char const*) get_data( file, file.tracks + track * 4, 1 ) );
- byte const* track_info = get_data( file, file.tracks + track * 4 + 2, 6 );
- if ( track_info )
- out->length = get_be16( track_info + 4 ) * (1000L / 50); // frames to msec
-
- Gme_File::copy_field_( out->author, (char const*) get_data( file, file.header->author, 1 ) );
- Gme_File::copy_field_( out->comment, (char const*) get_data( file, file.header->comment, 1 ) );
-}
-
-blargg_err_t Ay_Emu::track_info_( track_info_t* out, int track ) const
-{
- copy_ay_fields( file, out, track );
- return 0;
-}
-
-struct Ay_File : Gme_Info_
-{
- Ay_Emu::file_t file;
-
- Ay_File() { set_type( gme_ay_type ); }
-
- blargg_err_t load_mem_( byte const* begin, long size )
- {
- RETURN_ERR( parse_header( begin, size, &file ) );
- set_track_count( file.header->max_track + 1 );
- return 0;
- }
-
- blargg_err_t track_info_( track_info_t* out, int track ) const
- {
- copy_ay_fields( file, out, track );
- return 0;
- }
-};
-
-static Music_Emu* new_ay_emu () { return BLARGG_NEW Ay_Emu ; }
-static Music_Emu* new_ay_file() { return BLARGG_NEW Ay_File; }
-
-gme_type_t_ const gme_ay_type [1] = { "ZX Spectrum", 0, &new_ay_emu, &new_ay_file, "AY", 1 };
-
-// Setup
-
-blargg_err_t Ay_Emu::load_mem_( byte const* in, long size )
-{
- assert( offsetof (header_t,track_info [2]) == header_size );
-
- RETURN_ERR( parse_header( in, size, &file ) );
- set_track_count( file.header->max_track + 1 );
-
- if ( file.header->vers > 2 )
- set_warning( "Unknown file version" );
-
- set_voice_count( osc_count );
- apu.volume( gain() );
-
- return setup_buffer( spectrum_clock );
-}
-
-void Ay_Emu::update_eq( blip_eq_t const& eq )
-{
- apu.treble_eq( eq );
-}
-
-void Ay_Emu::set_voice( int i, Blip_Buffer* center, Blip_Buffer*, Blip_Buffer* )
-{
- if ( i >= Ay_Apu::osc_count )
- beeper_output = center;
- else
- apu.osc_output( i, center );
-}
-
-// Emulation
-
-void Ay_Emu::set_tempo_( double t )
-{
- play_period = blip_time_t (clock_rate() / 50 / t);
-}
-
-blargg_err_t Ay_Emu::start_track_( int track )
-{
- RETURN_ERR( Classic_Emu::start_track_( track ) );
-
- memset( mem.ram + 0x0000, 0xC9, 0x100 ); // fill RST vectors with RET
- memset( mem.ram + 0x0100, 0xFF, 0x4000 - 0x100 );
- memset( mem.ram + ram_start, 0x00, sizeof mem.ram - ram_start );
- memset( mem.padding1, 0xFF, sizeof mem.padding1 );
- memset( mem.ram + 0x10000, 0xFF, sizeof mem.ram - 0x10000 );
-
- // locate data blocks
- byte const* const data = get_data( file, file.tracks + track * 4 + 2, 14 );
- if ( !data ) return "File data missing";
-
- byte const* const more_data = get_data( file, data + 10, 6 );
- if ( !more_data ) return "File data missing";
-
- byte const* blocks = get_data( file, data + 12, 8 );
- if ( !blocks ) return "File data missing";
-
- // initial addresses
- cpu::reset( mem.ram );
- r.sp = get_be16( more_data );
- r.b.a = r.b.b = r.b.d = r.b.h = data [8];
- r.b.flags = r.b.c = r.b.e = r.b.l = data [9];
- r.alt.w = r.w;
- r.ix = r.iy = r.w.hl;
-
- unsigned addr = get_be16( blocks );
- if ( !addr ) return "File data missing";
-
- unsigned init = get_be16( more_data + 2 );
- if ( !init )
- init = addr;
-
- // copy blocks into memory
- do
- {
- blocks += 2;
- unsigned len = get_be16( blocks ); blocks += 2;
- if ( addr + len > 0x10000 )
- {
- set_warning( "Bad data block size" );
- len = 0x10000 - addr;
- }
- check( len );
- byte const* in = get_data( file, blocks, 0 ); blocks += 2;
- if ( len > blargg_ulong (file.end - in) )
- {
- set_warning( "Missing file data" );
- len = file.end - in;
- }
- //dprintf( "addr: $%04X, len: $%04X\n", addr, len );
- if ( addr < ram_start && addr >= 0x400 ) // several tracks use low data
- dprintf( "Block addr in ROM\n" );
- memcpy( mem.ram + addr, in, len );
-
- if ( file.end - blocks < 8 )
- {
- set_warning( "Missing file data" );
- break;
- }
- }
- while ( (addr = get_be16( blocks )) != 0 );
-
- // copy and configure driver
- static byte const passive [] = {
- 0xF3, // DI
- 0xCD, 0, 0, // CALL init
- 0xED, 0x5E, // LOOP: IM 2
- 0xFB, // EI
- 0x76, // HALT
- 0x18, 0xFA // JR LOOP
- };
- static byte const active [] = {
- 0xF3, // DI
- 0xCD, 0, 0, // CALL init
- 0xED, 0x56, // LOOP: IM 1
- 0xFB, // EI
- 0x76, // HALT
- 0xCD, 0, 0, // CALL play
- 0x18, 0xF7 // JR LOOP
- };
- memcpy( mem.ram, passive, sizeof passive );
- unsigned play_addr = get_be16( more_data + 4 );
- //dprintf( "Play: $%04X\n", play_addr );
- if ( play_addr )
- {
- memcpy( mem.ram, active, sizeof active );
- mem.ram [ 9] = play_addr;
- mem.ram [10] = play_addr >> 8;
- }
- mem.ram [2] = init;
- mem.ram [3] = init >> 8;
-
- mem.ram [0x38] = 0xFB; // Put EI at interrupt vector (followed by RET)
-
- memcpy( mem.ram + 0x10000, mem.ram, 0x80 ); // some code wraps around (ugh)
-
- beeper_delta = int (apu.amp_range * 0.65);
- last_beeper = 0;
- apu.reset();
- next_play = play_period;
-
- // start at spectrum speed
- change_clock_rate( spectrum_clock );
- set_tempo( tempo() );
-
- spectrum_mode = false;
- cpc_mode = false;
- cpc_latch = 0;
-
- return 0;
-}
-
-// Emulation
-
-void Ay_Emu::cpu_out_misc( cpu_time_t time, unsigned addr, int data )
-{
- if ( !cpc_mode )
- {
- switch ( addr & 0xFEFF )
- {
- case 0xFEFD:
- spectrum_mode = true;
- apu_addr = data & 0x0F;
- return;
-
- case 0xBEFD:
- spectrum_mode = true;
- apu.write( time, apu_addr, data );
- return;
- }
- }
-
- if ( !spectrum_mode )
- {
- switch ( addr >> 8 )
- {
- case 0xF6:
- switch ( data & 0xC0 )
- {
- case 0xC0:
- apu_addr = cpc_latch & 0x0F;
- goto enable_cpc;
-
- case 0x80:
- apu.write( time, apu_addr, cpc_latch );
- goto enable_cpc;
- }
- break;
-
- case 0xF4:
- cpc_latch = data;
- goto enable_cpc;
- }
- }
-
- dprintf( "Unmapped OUT: $%04X <- $%02X\n", addr, data );
- return;
-
-enable_cpc:
- if ( !cpc_mode )
- {
- cpc_mode = true;
- change_clock_rate( cpc_clock );
- set_tempo( tempo() );
- }
-}
-
-void ay_cpu_out( Ay_Cpu* cpu, cpu_time_t time, unsigned addr, int data )
-{
- Ay_Emu& emu = STATIC_CAST(Ay_Emu&,*cpu);
-
- if ( (addr & 0xFF) == 0xFE && !emu.cpc_mode )
- {
- int delta = emu.beeper_delta;
- data &= 0x10;
- if ( emu.last_beeper != data )
- {
- emu.last_beeper = data;
- emu.beeper_delta = -delta;
- emu.spectrum_mode = true;
- if ( emu.beeper_output )
- emu.apu.synth_.offset( time, delta, emu.beeper_output );
- }
- }
- else
- {
- emu.cpu_out_misc( time, addr, data );
- }
-}
-
-int ay_cpu_in( Ay_Cpu*, unsigned addr )
-{
- // keyboard read and other things
- if ( (addr & 0xFF) == 0xFE )
- return 0xFF; // other values break some beeper tunes
-
- dprintf( "Unmapped IN : $%04X\n", addr );
- return 0xFF;
-}
-
-blargg_err_t Ay_Emu::run_clocks( blip_time_t& duration, int )
-{
- set_time( 0 );
- if ( !(spectrum_mode | cpc_mode) )
- duration /= 2; // until mode is set, leave room for halved clock rate
-
- while ( time() < duration )
- {
- cpu::run( min( duration, (blip_time_t) next_play ) );
-
- if ( time() >= next_play )
- {
- next_play += play_period;
-
- if ( r.iff1 )
- {
- if ( mem.ram [r.pc] == 0x76 )
- r.pc++;
-
- r.iff1 = r.iff2 = 0;
-
- mem.ram [--r.sp] = uint8_t (r.pc >> 8);
- mem.ram [--r.sp] = uint8_t (r.pc);
- r.pc = 0x38;
- cpu::adjust_time( 12 );
- if ( r.im == 2 )
- {
- cpu::adjust_time( 6 );
- unsigned addr = r.i * 0x100u + 0xFF;
- r.pc = mem.ram [(addr + 1) & 0xFFFF] * 0x100u + mem.ram [addr];
- }
- }
- }
- }
- duration = time();
- next_play -= duration;
- check( next_play >= 0 );
- adjust_time( -duration );
-
- apu.end_frame( duration );
-
- return 0;
-}
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Ay_Emu.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/Ay_Emu.h
deleted file mode 100644
index ba8445d3..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Ay_Emu.h
+++ /dev/null
@@ -1,70 +0,0 @@
-// Sinclair Spectrum AY music file emulator
-
-// Game_Music_Emu 0.5.2
-#ifndef AY_EMU_H
-#define AY_EMU_H
-
-#include "Classic_Emu.h"
-#include "Ay_Apu.h"
-#include "Ay_Cpu.h"
-
-class Ay_Emu : private Ay_Cpu, public Classic_Emu {
- typedef Ay_Cpu cpu;
-public:
- // AY file header
- enum { header_size = 0x14 };
- struct header_t
- {
- byte tag [8];
- byte vers;
- byte player;
- byte unused [2];
- byte author [2];
- byte comment [2];
- byte max_track;
- byte first_track;
- byte track_info [2];
- };
-
- static gme_type_t static_type() { return gme_ay_type; }
-public:
- Ay_Emu();
- ~Ay_Emu();
- struct file_t {
- header_t const* header;
- byte const* end;
- byte const* tracks;
- };
-protected:
- blargg_err_t track_info_( track_info_t*, int track ) const;
- blargg_err_t load_mem_( byte const*, long );
- blargg_err_t start_track_( int );
- blargg_err_t run_clocks( blip_time_t&, int );
- void set_tempo_( double );
- void set_voice( int, Blip_Buffer*, Blip_Buffer*, Blip_Buffer* );
- void update_eq( blip_eq_t const& );
-private:
- file_t file;
-
- unsigned play_addr;
- cpu_time_t play_period;
- cpu_time_t next_play;
- Blip_Buffer* beeper_output;
- int beeper_delta;
- int last_beeper;
- int apu_addr;
- int cpc_latch;
- bool spectrum_mode;
- bool cpc_mode;
-
- // large items
- struct {
- byte padding1 [0x100];
- byte ram [0x10000 + 0x100];
- } mem;
- Ay_Apu apu;
- friend void ay_cpu_out( Ay_Cpu*, cpu_time_t, unsigned addr, int data );
- void cpu_out_misc( cpu_time_t, unsigned addr, int data );
-};
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Blip_Buffer.cpp b/plugins/gme/Game_Music_Emu-0.5.2/gme/Blip_Buffer.cpp
deleted file mode 100644
index 07e9d658..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Blip_Buffer.cpp
+++ /dev/null
@@ -1,446 +0,0 @@
-// Blip_Buffer 0.4.1. http://www.slack.net/~ant/
-
-#include "Blip_Buffer.h"
-#include "blargg_common.h"
-#include <assert.h>
-#include <limits.h>
-#include <string.h>
-#include <stdlib.h>
-#include <math.h>
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#ifdef BLARGG_ENABLE_OPTIMIZER
- #include BLARGG_ENABLE_OPTIMIZER
-#endif
-
-int const silent_buf_size = 1; // size used for Silent_Blip_Buffer
-
-Blip_Buffer::Blip_Buffer()
-{
- factor_ = 0x7fffffff;
- offset_ = 0;
- buffer_ = 0;
- buffer_size_ = 0;
- sample_rate_ = 0;
- reader_accum_ = 0;
- bass_shift_ = 0;
- clock_rate_ = 0;
- bass_freq_ = 16;
- length_ = 0;
-
- // assumptions code makes about implementation-defined features
- #ifndef NDEBUG
- // right shift of negative value preserves sign
- buf_t_ i = -0x7FFFFFFE;
- assert( (i >> 1) == -0x3FFFFFFF );
-
- // casting to short truncates to 16 bits and sign-extends
- i = 0x18000;
- assert( (short) i == -0x8000 );
- #endif
-}
-
-Blip_Buffer::~Blip_Buffer()
-{
- if ( buffer_size_ != silent_buf_size )
- free( buffer_ );
-}
-
-Silent_Blip_Buffer::Silent_Blip_Buffer()
-{
- factor_ = 0;
- buffer_ = buf;
- buffer_size_ = silent_buf_size;
- memset( buf, 0, sizeof buf ); // in case machine takes exception for signed overflow
-}
-
-void Blip_Buffer::clear( int entire_buffer )
-{
- offset_ = 0;
- reader_accum_ = 0;
- modified_ = 0;
- if ( buffer_ )
- {
- long count = (entire_buffer ? buffer_size_ : samples_avail());
- memset( buffer_, 0, (count + blip_buffer_extra_) * sizeof (buf_t_) );
- }
-}
-
-Blip_Buffer::blargg_err_t Blip_Buffer::set_sample_rate( long new_rate, int msec )
-{
- if ( buffer_size_ == silent_buf_size )
- {
- assert( 0 );
- return "Internal (tried to resize Silent_Blip_Buffer)";
- }
-
- // start with maximum length that resampled time can represent
- long new_size = (ULONG_MAX >> BLIP_BUFFER_ACCURACY) - blip_buffer_extra_ - 64;
- if ( msec != blip_max_length )
- {
- long s = (new_rate * (msec + 1) + 999) / 1000;
- if ( s < new_size )
- new_size = s;
- else
- assert( 0 ); // fails if requested buffer length exceeds limit
- }
-
- if ( buffer_size_ != new_size )
- {
- void* p = realloc( buffer_, (new_size + blip_buffer_extra_) * sizeof *buffer_ );
- if ( !p )
- return "Out of memory";
- buffer_ = (buf_t_*) p;
- }
-
- buffer_size_ = new_size;
- assert( buffer_size_ != silent_buf_size );
-
- // update things based on the sample rate
- sample_rate_ = new_rate;
- length_ = new_size * 1000 / new_rate - 1;
- if ( msec )
- assert( length_ == msec ); // ensure length is same as that passed in
- if ( clock_rate_ )
- clock_rate( clock_rate_ );
- bass_freq( bass_freq_ );
-
- clear();
-
- return 0; // success
-}
-
-blip_resampled_time_t Blip_Buffer::clock_rate_factor( long rate ) const
-{
- double ratio = (double) sample_rate_ / rate;
- blip_long factor = (blip_long) floor( ratio * (1L << BLIP_BUFFER_ACCURACY) + 0.5 );
- assert( factor > 0 || !sample_rate_ ); // fails if clock/output ratio is too large
- return (blip_resampled_time_t) factor;
-}
-
-void Blip_Buffer::bass_freq( int freq )
-{
- bass_freq_ = freq;
- int shift = 31;
- if ( freq > 0 )
- {
- shift = 13;
- long f = (freq << 16) / sample_rate_;
- while ( (f >>= 1) && --shift ) { }
- }
- bass_shift_ = shift;
-}
-
-void Blip_Buffer::end_frame( blip_time_t t )
-{
- offset_ += t * factor_;
- assert( samples_avail() <= (long) buffer_size_ ); // time outside buffer length
-}
-
-void Blip_Buffer::remove_silence( long count )
-{
- assert( count <= samples_avail() ); // tried to remove more samples than available
- offset_ -= (blip_resampled_time_t) count << BLIP_BUFFER_ACCURACY;
-}
-
-long Blip_Buffer::count_samples( blip_time_t t ) const
-{
- unsigned long last_sample = resampled_time( t ) >> BLIP_BUFFER_ACCURACY;
- unsigned long first_sample = offset_ >> BLIP_BUFFER_ACCURACY;
- return (long) (last_sample - first_sample);
-}
-
-blip_time_t Blip_Buffer::count_clocks( long count ) const
-{
- if ( !factor_ )
- {
- assert( 0 ); // sample rate and clock rates must be set first
- return 0;
- }
-
- if ( count > buffer_size_ )
- count = buffer_size_;
- blip_resampled_time_t time = (blip_resampled_time_t) count << BLIP_BUFFER_ACCURACY;
- return (blip_time_t) ((time - offset_ + factor_ - 1) / factor_);
-}
-
-void Blip_Buffer::remove_samples( long count )
-{
- if ( count )
- {
- remove_silence( count );
-
- // copy remaining samples to beginning and clear old samples
- long remain = samples_avail() + blip_buffer_extra_;
- memmove( buffer_, buffer_ + count, remain * sizeof *buffer_ );
- memset( buffer_ + remain, 0, count * sizeof *buffer_ );
- }
-}
-
-// Blip_Synth_
-
-Blip_Synth_Fast_::Blip_Synth_Fast_()
-{
- buf = 0;
- last_amp = 0;
- delta_factor = 0;
-}
-
-void Blip_Synth_Fast_::volume_unit( double new_unit )
-{
- delta_factor = int (new_unit * (1L << blip_sample_bits) + 0.5);
-}
-
-#if !BLIP_BUFFER_FAST
-
-Blip_Synth_::Blip_Synth_( short* p, int w ) :
- impulses( p ),
- width( w )
-{
- volume_unit_ = 0.0;
- kernel_unit = 0;
- buf = 0;
- last_amp = 0;
- delta_factor = 0;
-}
-
-#undef PI
-#define PI 3.1415926535897932384626433832795029
-
-static void gen_sinc( float* out, int count, double oversample, double treble, double cutoff )
-{
- if ( cutoff >= 0.999 )
- cutoff = 0.999;
-
- if ( treble < -300.0 )
- treble = -300.0;
- if ( treble > 5.0 )
- treble = 5.0;
-
- double const maxh = 4096.0;
- double const rolloff = pow( 10.0, 1.0 / (maxh * 20.0) * treble / (1.0 - cutoff) );
- double const pow_a_n = pow( rolloff, maxh - maxh * cutoff );
- double const to_angle = PI / 2 / maxh / oversample;
- for ( int i = 0; i < count; i++ )
- {
- double angle = ((i - count) * 2 + 1) * to_angle;
- double c = rolloff * cos( (maxh - 1.0) * angle ) - cos( maxh * angle );
- double cos_nc_angle = cos( maxh * cutoff * angle );
- double cos_nc1_angle = cos( (maxh * cutoff - 1.0) * angle );
- double cos_angle = cos( angle );
-
- c = c * pow_a_n - rolloff * cos_nc1_angle + cos_nc_angle;
- double d = 1.0 + rolloff * (rolloff - cos_angle - cos_angle);
- double b = 2.0 - cos_angle - cos_angle;
- double a = 1.0 - cos_angle - cos_nc_angle + cos_nc1_angle;
-
- out [i] = (float) ((a * d + c * b) / (b * d)); // a / b + c / d
- }
-}
-
-void blip_eq_t::generate( float* out, int count ) const
-{
- // lower cutoff freq for narrow kernels with their wider transition band
- // (8 points->1.49, 16 points->1.15)
- double oversample = blip_res * 2.25 / count + 0.85;
- double half_rate = sample_rate * 0.5;
- if ( cutoff_freq )
- oversample = half_rate / cutoff_freq;
- double cutoff = rolloff_freq * oversample / half_rate;
-
- gen_sinc( out, count, blip_res * oversample, treble, cutoff );
-
- // apply (half of) hamming window
- double to_fraction = PI / (count - 1);
- for ( int i = count; i--; )
- out [i] *= 0.54f - 0.46f * (float) cos( i * to_fraction );
-}
-
-void Blip_Synth_::adjust_impulse()
-{
- // sum pairs for each phase and add error correction to end of first half
- int const size = impulses_size();
- for ( int p = blip_res; p-- >= blip_res / 2; )
- {
- int p2 = blip_res - 2 - p;
- long error = kernel_unit;
- for ( int i = 1; i < size; i += blip_res )
- {
- error -= impulses [i + p ];
- error -= impulses [i + p2];
- }
- if ( p == p2 )
- error /= 2; // phase = 0.5 impulse uses same half for both sides
- impulses [size - blip_res + p] += (short) error;
- //printf( "error: %ld\n", error );
- }
-
- //for ( int i = blip_res; i--; printf( "\n" ) )
- // for ( int j = 0; j < width / 2; j++ )
- // printf( "%5ld,", impulses [j * blip_res + i + 1] );
-}
-
-void Blip_Synth_::treble_eq( blip_eq_t const& eq )
-{
- float fimpulse [blip_res / 2 * (blip_widest_impulse_ - 1) + blip_res * 2];
-
- int const half_size = blip_res / 2 * (width - 1);
- eq.generate( &fimpulse [blip_res], half_size );
-
- int i;
-
- // need mirror slightly past center for calculation
- for ( i = blip_res; i--; )
- fimpulse [blip_res + half_size + i] = fimpulse [blip_res + half_size - 1 - i];
-
- // starts at 0
- for ( i = 0; i < blip_res; i++ )
- fimpulse [i] = 0.0f;
-
- // find rescale factor
- double total = 0.0;
- for ( i = 0; i < half_size; i++ )
- total += fimpulse [blip_res + i];
-
- //double const base_unit = 44800.0 - 128 * 18; // allows treble up to +0 dB
- //double const base_unit = 37888.0; // allows treble to +5 dB
- double const base_unit = 32768.0; // necessary for blip_unscaled to work
- double rescale = base_unit / 2 / total;
- kernel_unit = (long) base_unit;
-
- // integrate, first difference, rescale, convert to int
- double sum = 0.0;
- double next = 0.0;
- int const impulses_size = this->impulses_size();
- for ( i = 0; i < impulses_size; i++ )
- {
- impulses [i] = (short) floor( (next - sum) * rescale + 0.5 );
- sum += fimpulse [i];
- next += fimpulse [i + blip_res];
- }
- adjust_impulse();
-
- // volume might require rescaling
- double vol = volume_unit_;
- if ( vol )
- {
- volume_unit_ = 0.0;
- volume_unit( vol );
- }
-}
-
-void Blip_Synth_::volume_unit( double new_unit )
-{
- if ( new_unit != volume_unit_ )
- {
- // use default eq if it hasn't been set yet
- if ( !kernel_unit )
- treble_eq( -8.0 );
-
- volume_unit_ = new_unit;
- double factor = new_unit * (1L << blip_sample_bits) / kernel_unit;
-
- if ( factor > 0.0 )
- {
- int shift = 0;
-
- // if unit is really small, might need to attenuate kernel
- while ( factor < 2.0 )
- {
- shift++;
- factor *= 2.0;
- }
-
- if ( shift )
- {
- kernel_unit >>= shift;
- assert( kernel_unit > 0 ); // fails if volume unit is too low
-
- // keep values positive to avoid round-towards-zero of sign-preserving
- // right shift for negative values
- long offset = 0x8000 + (1 << (shift - 1));
- long offset2 = 0x8000 >> shift;
- for ( int i = impulses_size(); i--; )
- impulses [i] = (short) (((impulses [i] + offset) >> shift) - offset2);
- adjust_impulse();
- }
- }
- delta_factor = (int) floor( factor + 0.5 );
- //printf( "delta_factor: %d, kernel_unit: %d\n", delta_factor, kernel_unit );
- }
-}
-#endif
-
-long Blip_Buffer::read_samples( blip_sample_t* BLIP_RESTRICT out, long max_samples, int stereo )
-{
- long count = samples_avail();
- if ( count > max_samples )
- count = max_samples;
-
- if ( count )
- {
- int const bass = BLIP_READER_BASS( *this );
- BLIP_READER_BEGIN( reader, *this );
-
- if ( !stereo )
- {
- for ( blip_long n = count; n; --n )
- {
- blip_long s = BLIP_READER_READ( reader );
- if ( (blip_sample_t) s != s )
- s = 0x7FFF - (s >> 24);
- *out++ = (blip_sample_t) s;
- BLIP_READER_NEXT( reader, bass );
- }
- }
- else
- {
- for ( blip_long n = count; n; --n )
- {
- blip_long s = BLIP_READER_READ( reader );
- if ( (blip_sample_t) s != s )
- s = 0x7FFF - (s >> 24);
- *out = (blip_sample_t) s;
- out += 2;
- BLIP_READER_NEXT( reader, bass );
- }
- }
- BLIP_READER_END( reader, *this );
-
- remove_samples( count );
- }
- return count;
-}
-
-void Blip_Buffer::mix_samples( blip_sample_t const* in, long count )
-{
- if ( buffer_size_ == silent_buf_size )
- {
- assert( 0 );
- return;
- }
-
- buf_t_* out = buffer_ + (offset_ >> BLIP_BUFFER_ACCURACY) + blip_widest_impulse_ / 2;
-
- int const sample_shift = blip_sample_bits - 16;
- int prev = 0;
- while ( count-- )
- {
- blip_long s = (blip_long) *in++ << sample_shift;
- *out += s - prev;
- prev = s;
- ++out;
- }
- *out -= prev;
-}
-
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Blip_Buffer.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/Blip_Buffer.h
deleted file mode 100644
index 73341b8c..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Blip_Buffer.h
+++ /dev/null
@@ -1,485 +0,0 @@
-// Band-limited sound synthesis buffer
-
-// Blip_Buffer 0.4.1
-#ifndef BLIP_BUFFER_H
-#define BLIP_BUFFER_H
-
-// internal
-#include <limits.h>
-#include <stdint.h>
-typedef int32_t blip_long;
-typedef uint32_t blip_ulong;
-
-// Time unit at source clock rate
-typedef blip_long blip_time_t;
-
-// Output samples are 16-bit signed, with a range of -32768 to 32767
-typedef short blip_sample_t;
-enum { blip_sample_max = 32767 };
-
-class Blip_Buffer {
-public:
- typedef const char* blargg_err_t;
-
- // Set output sample rate and buffer length in milliseconds (1/1000 sec, defaults
- // to 1/4 second), then clear buffer. Returns NULL on success, otherwise if there
- // isn't enough memory, returns error without affecting current buffer setup.
- blargg_err_t set_sample_rate( long samples_per_sec, int msec_length = 1000 / 4 );
-
- // Set number of source time units per second
- void clock_rate( long );
-
- // End current time frame of specified duration and make its samples available
- // (along with any still-unread samples) for reading with read_samples(). Begins
- // a new time frame at the end of the current frame.
- void end_frame( blip_time_t time );
-
- // Read at most 'max_samples' out of buffer into 'dest', removing them from from
- // the buffer. Returns number of samples actually read and removed. If stereo is
- // true, increments 'dest' one extra time after writing each sample, to allow
- // easy interleving of two channels into a stereo output buffer.
- long read_samples( blip_sample_t* dest, long max_samples, int stereo = 0 );
-
-// Additional optional features
-
- // Current output sample rate
- long sample_rate() const;
-
- // Length of buffer, in milliseconds
- int length() const;
-
- // Number of source time units per second
- long clock_rate() const;
-
- // Set frequency high-pass filter frequency, where higher values reduce bass more
- void bass_freq( int frequency );
-
- // Number of samples delay from synthesis to samples read out
- int output_latency() const;
-
- // Remove all available samples and clear buffer to silence. If 'entire_buffer' is
- // false, just clears out any samples waiting rather than the entire buffer.
- void clear( int entire_buffer = 1 );
-
- // Number of samples available for reading with read_samples()
- long samples_avail() const;
-
- // Remove 'count' samples from those waiting to be read
- void remove_samples( long count );
-
-// Experimental features
-
- // Count number of clocks needed until 'count' samples will be available.
- // If buffer can't even hold 'count' samples, returns number of clocks until
- // buffer becomes full.
- blip_time_t count_clocks( long count ) const;
-
- // Number of raw samples that can be mixed within frame of specified duration.
- long count_samples( blip_time_t duration ) const;
-
- // Mix 'count' samples from 'buf' into buffer.
- void mix_samples( blip_sample_t const* buf, long count );
-
- // not documented yet
- void set_modified() { modified_ = 1; }
- int clear_modified() { int b = modified_; modified_ = 0; return b; }
- typedef blip_ulong blip_resampled_time_t;
- void remove_silence( long count );
- blip_resampled_time_t resampled_duration( int t ) const { return t * factor_; }
- blip_resampled_time_t resampled_time( blip_time_t t ) const { return t * factor_ + offset_; }
- blip_resampled_time_t clock_rate_factor( long clock_rate ) const;
-public:
- Blip_Buffer();
- ~Blip_Buffer();
-
- // Deprecated
- typedef blip_resampled_time_t resampled_time_t;
- blargg_err_t sample_rate( long r ) { return set_sample_rate( r ); }
- blargg_err_t sample_rate( long r, int msec ) { return set_sample_rate( r, msec ); }
-private:
- // noncopyable
- Blip_Buffer( const Blip_Buffer& );
- Blip_Buffer& operator = ( const Blip_Buffer& );
-public:
- typedef blip_time_t buf_t_;
- blip_ulong factor_;
- blip_resampled_time_t offset_;
- buf_t_* buffer_;
- blip_long buffer_size_;
- blip_long reader_accum_;
- int bass_shift_;
-private:
- long sample_rate_;
- long clock_rate_;
- int bass_freq_;
- int length_;
- int modified_;
- friend class Blip_Reader;
-};
-
-#ifdef HAVE_CONFIG_H
- #include "config.h"
-#endif
-
-// Number of bits in resample ratio fraction. Higher values give a more accurate ratio
-// but reduce maximum buffer size.
-#ifndef BLIP_BUFFER_ACCURACY
- #define BLIP_BUFFER_ACCURACY 16
-#endif
-
-// Number bits in phase offset. Fewer than 6 bits (64 phase offsets) results in
-// noticeable broadband noise when synthesizing high frequency square waves.
-// Affects size of Blip_Synth objects since they store the waveform directly.
-#ifndef BLIP_PHASE_BITS
- #if BLIP_BUFFER_FAST
- #define BLIP_PHASE_BITS 8
- #else
- #define BLIP_PHASE_BITS 6
- #endif
-#endif
-
- // Internal
- typedef blip_ulong blip_resampled_time_t;
- int const blip_widest_impulse_ = 16;
- int const blip_buffer_extra_ = blip_widest_impulse_ + 2;
- int const blip_res = 1 << BLIP_PHASE_BITS;
- class blip_eq_t;
-
- class Blip_Synth_Fast_ {
- public:
- Blip_Buffer* buf;
- int last_amp;
- int delta_factor;
-
- void volume_unit( double );
- Blip_Synth_Fast_();
- void treble_eq( blip_eq_t const& ) { }
- };
-
- class Blip_Synth_ {
- public:
- Blip_Buffer* buf;
- int last_amp;
- int delta_factor;
-
- void volume_unit( double );
- Blip_Synth_( short* impulses, int width );
- void treble_eq( blip_eq_t const& );
- private:
- double volume_unit_;
- short* const impulses;
- int const width;
- blip_long kernel_unit;
- int impulses_size() const { return blip_res / 2 * width + 1; }
- void adjust_impulse();
- };
-
-// Quality level. Start with blip_good_quality.
-const int blip_med_quality = 8;
-const int blip_good_quality = 12;
-const int blip_high_quality = 16;
-
-// Range specifies the greatest expected change in amplitude. Calculate it
-// by finding the difference between the maximum and minimum expected
-// amplitudes (max - min).
-template<int quality,int range>
-class Blip_Synth {
-public:
- // Set overall volume of waveform
- void volume( double v ) { impl.volume_unit( v * (1.0 / (range < 0 ? -range : range)) ); }
-
- // Configure low-pass filter (see blip_buffer.txt)
- void treble_eq( blip_eq_t const& eq ) { impl.treble_eq( eq ); }
-
- // Get/set Blip_Buffer used for output
- Blip_Buffer* output() const { return impl.buf; }
- void output( Blip_Buffer* b ) { impl.buf = b; impl.last_amp = 0; }
-
- // Update amplitude of waveform at given time. Using this requires a separate
- // Blip_Synth for each waveform.
- void update( blip_time_t time, int amplitude );
-
-// Low-level interface
-
- // Add an amplitude transition of specified delta, optionally into specified buffer
- // rather than the one set with output(). Delta can be positive or negative.
- // The actual change in amplitude is delta * (volume / range)
- void offset( blip_time_t, int delta, Blip_Buffer* ) const;
- void offset( blip_time_t t, int delta ) const { offset( t, delta, impl.buf ); }
-
- // Works directly in terms of fractional output samples. Contact author for more info.
- void offset_resampled( blip_resampled_time_t, int delta, Blip_Buffer* ) const;
-
- // Same as offset(), except code is inlined for higher performance
- void offset_inline( blip_time_t t, int delta, Blip_Buffer* buf ) const {
- offset_resampled( t * buf->factor_ + buf->offset_, delta, buf );
- }
- void offset_inline( blip_time_t t, int delta ) const {
- offset_resampled( t * impl.buf->factor_ + impl.buf->offset_, delta, impl.buf );
- }
-
-private:
-#if BLIP_BUFFER_FAST
- Blip_Synth_Fast_ impl;
-#else
- Blip_Synth_ impl;
- typedef short imp_t;
- imp_t impulses [blip_res * (quality / 2) + 1];
-public:
- Blip_Synth() : impl( impulses, quality ) { }
-#endif
-};
-
-// Low-pass equalization parameters
-class blip_eq_t {
-public:
- // Logarithmic rolloff to treble dB at half sampling rate. Negative values reduce
- // treble, small positive values (0 to 5.0) increase treble.
- blip_eq_t( double treble_db = 0 );
-
- // See blip_buffer.txt
- blip_eq_t( double treble, long rolloff_freq, long sample_rate, long cutoff_freq = 0 );
-
-private:
- double treble;
- long rolloff_freq;
- long sample_rate;
- long cutoff_freq;
- void generate( float* out, int count ) const;
- friend class Blip_Synth_;
-};
-
-int const blip_sample_bits = 30;
-
-// Dummy Blip_Buffer to direct sound output to, for easy muting without
-// having to stop sound code.
-class Silent_Blip_Buffer : public Blip_Buffer {
- buf_t_ buf [blip_buffer_extra_ + 1];
-public:
- // The following cannot be used (an assertion will fail if attempted):
- blargg_err_t set_sample_rate( long samples_per_sec, int msec_length );
- blip_time_t count_clocks( long count ) const;
- void mix_samples( blip_sample_t const* buf, long count );
-
- Silent_Blip_Buffer();
-};
-
- #if defined (__GNUC__) || _MSC_VER >= 1100
- #define BLIP_RESTRICT __restrict
- #else
- #define BLIP_RESTRICT
- #endif
-
-// Optimized reading from Blip_Buffer, for use in custom sample output
-
-// Begin reading from buffer. Name should be unique to the current block.
-#define BLIP_READER_BEGIN( name, blip_buffer ) \
- const Blip_Buffer::buf_t_* BLIP_RESTRICT name##_reader_buf = (blip_buffer).buffer_;\
- blip_long name##_reader_accum = (blip_buffer).reader_accum_
-
-// Get value to pass to BLIP_READER_NEXT()
-#define BLIP_READER_BASS( blip_buffer ) ((blip_buffer).bass_shift_)
-
-// Constant value to use instead of BLIP_READER_BASS(), for slightly more optimal
-// code at the cost of having no bass control
-int const blip_reader_default_bass = 9;
-
-// Current sample
-#define BLIP_READER_READ( name ) (name##_reader_accum >> (blip_sample_bits - 16))
-
-// Current raw sample in full internal resolution
-#define BLIP_READER_READ_RAW( name ) (name##_reader_accum)
-
-// Advance to next sample
-#define BLIP_READER_NEXT( name, bass ) \
- (void) (name##_reader_accum += *name##_reader_buf++ - (name##_reader_accum >> (bass)))
-
-// End reading samples from buffer. The number of samples read must now be removed
-// using Blip_Buffer::remove_samples().
-#define BLIP_READER_END( name, blip_buffer ) \
- (void) ((blip_buffer).reader_accum_ = name##_reader_accum)
-
-
-// Compatibility with older version
-const long blip_unscaled = 65535;
-const int blip_low_quality = blip_med_quality;
-const int blip_best_quality = blip_high_quality;
-
-// Deprecated; use BLIP_READER macros as follows:
-// Blip_Reader r; r.begin( buf ); -> BLIP_READER_BEGIN( r, buf );
-// int bass = r.begin( buf ) -> BLIP_READER_BEGIN( r, buf ); int bass = BLIP_READER_BASS( buf );
-// r.read() -> BLIP_READER_READ( r )
-// r.read_raw() -> BLIP_READER_READ_RAW( r )
-// r.next( bass ) -> BLIP_READER_NEXT( r, bass )
-// r.next() -> BLIP_READER_NEXT( r, blip_reader_default_bass )
-// r.end( buf ) -> BLIP_READER_END( r, buf )
-class Blip_Reader {
-public:
- int begin( Blip_Buffer& );
- blip_long read() const { return accum >> (blip_sample_bits - 16); }
- blip_long read_raw() const { return accum; }
- void next( int bass_shift = 9 ) { accum += *buf++ - (accum >> bass_shift); }
- void end( Blip_Buffer& b ) { b.reader_accum_ = accum; }
-
-private:
- const Blip_Buffer::buf_t_* buf;
- blip_long accum;
-};
-
-// End of public interface
-
-#include <assert.h>
-
-template<int quality,int range>
-inline void Blip_Synth<quality,range>::offset_resampled( blip_resampled_time_t time,
- int delta, Blip_Buffer* blip_buf ) const
-{
- // Fails if time is beyond end of Blip_Buffer, due to a bug in caller code or the
- // need for a longer buffer as set by set_sample_rate().
- assert( (blip_long) (time >> BLIP_BUFFER_ACCURACY) < blip_buf->buffer_size_ );
- delta *= impl.delta_factor;
- blip_long* BLIP_RESTRICT buf = blip_buf->buffer_ + (time >> BLIP_BUFFER_ACCURACY);
- int phase = (int) (time >> (BLIP_BUFFER_ACCURACY - BLIP_PHASE_BITS) & (blip_res - 1));
-
-#if BLIP_BUFFER_FAST
- blip_long left = buf [0] + delta;
-
- // Kind of crappy, but doing shift after multiply results in overflow.
- // Alternate way of delaying multiply by delta_factor results in worse
- // sub-sample resolution.
- blip_long right = (delta >> BLIP_PHASE_BITS) * phase;
- left -= right;
- right += buf [1];
-
- buf [0] = left;
- buf [1] = right;
-#else
-
- int const fwd = (blip_widest_impulse_ - quality) / 2;
- int const rev = fwd + quality - 2;
- int const mid = quality / 2 - 1;
-
- imp_t const* BLIP_RESTRICT imp = impulses + blip_res - phase;
-
- #if defined (_M_IX86) || defined (_M_IA64) || defined (__i486__) || \
- defined (__x86_64__) || defined (__ia64__) || defined (__i386__)
-
- // straight forward implementation resulted in better code on GCC for x86
-
- #define ADD_IMP( out, in ) \
- buf [out] += (blip_long) imp [blip_res * (in)] * delta
-
- #define BLIP_FWD( i ) {\
- ADD_IMP( fwd + i, i );\
- ADD_IMP( fwd + 1 + i, i + 1 );\
- }
- #define BLIP_REV( r ) {\
- ADD_IMP( rev - r, r + 1 );\
- ADD_IMP( rev + 1 - r, r );\
- }
-
- BLIP_FWD( 0 )
- if ( quality > 8 ) BLIP_FWD( 2 )
- if ( quality > 12 ) BLIP_FWD( 4 )
- {
- ADD_IMP( fwd + mid - 1, mid - 1 );
- ADD_IMP( fwd + mid , mid );
- imp = impulses + phase;
- }
- if ( quality > 12 ) BLIP_REV( 6 )
- if ( quality > 8 ) BLIP_REV( 4 )
- BLIP_REV( 2 )
-
- ADD_IMP( rev , 1 );
- ADD_IMP( rev + 1, 0 );
-
- #else
-
- // for RISC processors, help compiler by reading ahead of writes
-
- #define BLIP_FWD( i ) {\
- blip_long t0 = i0 * delta + buf [fwd + i];\
- blip_long t1 = imp [blip_res * (i + 1)] * delta + buf [fwd + 1 + i];\
- i0 = imp [blip_res * (i + 2)];\
- buf [fwd + i] = t0;\
- buf [fwd + 1 + i] = t1;\
- }
- #define BLIP_REV( r ) {\
- blip_long t0 = i0 * delta + buf [rev - r];\
- blip_long t1 = imp [blip_res * r] * delta + buf [rev + 1 - r];\
- i0 = imp [blip_res * (r - 1)];\
- buf [rev - r] = t0;\
- buf [rev + 1 - r] = t1;\
- }
-
- blip_long i0 = *imp;
- BLIP_FWD( 0 )
- if ( quality > 8 ) BLIP_FWD( 2 )
- if ( quality > 12 ) BLIP_FWD( 4 )
- {
- blip_long t0 = i0 * delta + buf [fwd + mid - 1];
- blip_long t1 = imp [blip_res * mid] * delta + buf [fwd + mid ];
- imp = impulses + phase;
- i0 = imp [blip_res * mid];
- buf [fwd + mid - 1] = t0;
- buf [fwd + mid ] = t1;
- }
- if ( quality > 12 ) BLIP_REV( 6 )
- if ( quality > 8 ) BLIP_REV( 4 )
- BLIP_REV( 2 )
-
- blip_long t0 = i0 * delta + buf [rev ];
- blip_long t1 = *imp * delta + buf [rev + 1];
- buf [rev ] = t0;
- buf [rev + 1] = t1;
- #endif
-
-#endif
-}
-
-#undef BLIP_FWD
-#undef BLIP_REV
-
-template<int quality,int range>
-#if BLIP_BUFFER_FAST
- inline
-#endif
-void Blip_Synth<quality,range>::offset( blip_time_t t, int delta, Blip_Buffer* buf ) const
-{
- offset_resampled( t * buf->factor_ + buf->offset_, delta, buf );
-}
-
-template<int quality,int range>
-#if BLIP_BUFFER_FAST
- inline
-#endif
-void Blip_Synth<quality,range>::update( blip_time_t t, int amp )
-{
- int delta = amp - impl.last_amp;
- impl.last_amp = amp;
- offset_resampled( t * impl.buf->factor_ + impl.buf->offset_, delta, impl.buf );
-}
-
-inline blip_eq_t::blip_eq_t( double t ) :
- treble( t ), rolloff_freq( 0 ), sample_rate( 44100 ), cutoff_freq( 0 ) { }
-inline blip_eq_t::blip_eq_t( double t, long rf, long sr, long cf ) :
- treble( t ), rolloff_freq( rf ), sample_rate( sr ), cutoff_freq( cf ) { }
-
-inline int Blip_Buffer::length() const { return length_; }
-inline long Blip_Buffer::samples_avail() const { return (long) (offset_ >> BLIP_BUFFER_ACCURACY); }
-inline long Blip_Buffer::sample_rate() const { return sample_rate_; }
-inline int Blip_Buffer::output_latency() const { return blip_widest_impulse_ / 2; }
-inline long Blip_Buffer::clock_rate() const { return clock_rate_; }
-inline void Blip_Buffer::clock_rate( long cps ) { factor_ = clock_rate_factor( clock_rate_ = cps ); }
-
-inline int Blip_Reader::begin( Blip_Buffer& blip_buf )
-{
- buf = blip_buf.buffer_;
- accum = blip_buf.reader_accum_;
- return blip_buf.bass_shift_;
-}
-
-int const blip_max_length = 0;
-int const blip_default_length = 250;
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Classic_Emu.cpp b/plugins/gme/Game_Music_Emu-0.5.2/gme/Classic_Emu.cpp
deleted file mode 100644
index 063444fe..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Classic_Emu.cpp
+++ /dev/null
@@ -1,184 +0,0 @@
-// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
-
-#include "Classic_Emu.h"
-
-#include "Multi_Buffer.h"
-#include <string.h>
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-Classic_Emu::Classic_Emu()
-{
- buf = 0;
- stereo_buffer = 0;
- voice_types = 0;
-
- // avoid inconsistency in our duplicated constants
- assert( (int) wave_type == (int) Multi_Buffer::wave_type );
- assert( (int) noise_type == (int) Multi_Buffer::noise_type );
- assert( (int) mixed_type == (int) Multi_Buffer::mixed_type );
-}
-
-Classic_Emu::~Classic_Emu()
-{
- delete stereo_buffer;
-}
-
-void Classic_Emu::set_equalizer_( equalizer_t const& eq )
-{
- Music_Emu::set_equalizer_( eq );
- update_eq( eq.treble );
- if ( buf )
- buf->bass_freq( equalizer().bass );
-}
-
-blargg_err_t Classic_Emu::set_sample_rate_( long rate )
-{
- if ( !buf )
- {
- if ( !stereo_buffer )
- CHECK_ALLOC( stereo_buffer = BLARGG_NEW Stereo_Buffer );
- buf = stereo_buffer;
- }
- return buf->set_sample_rate( rate, 1000 / 20 );
-}
-
-void Classic_Emu::mute_voices_( int mask )
-{
- Music_Emu::mute_voices_( mask );
- for ( int i = voice_count(); i--; )
- {
- if ( mask & (1 << i) )
- {
- set_voice( i, 0, 0, 0 );
- }
- else
- {
- Multi_Buffer::channel_t ch = buf->channel( i, (voice_types ? voice_types [i] : 0) );
- assert( (ch.center && ch.left && ch.right) ||
- (!ch.center && !ch.left && !ch.right) ); // all or nothing
- set_voice( i, ch.center, ch.left, ch.right );
- }
- }
-}
-
-void Classic_Emu::change_clock_rate( long rate )
-{
- clock_rate_ = rate;
- buf->clock_rate( rate );
-}
-
-blargg_err_t Classic_Emu::setup_buffer( long rate )
-{
- change_clock_rate( rate );
- RETURN_ERR( buf->set_channel_count( voice_count() ) );
- set_equalizer( equalizer() );
- buf_changed_count = buf->channels_changed_count();
- return 0;
-}
-
-blargg_err_t Classic_Emu::start_track_( int track )
-{
- RETURN_ERR( Music_Emu::start_track_( track ) );
- buf->clear();
- return 0;
-}
-
-blargg_err_t Classic_Emu::play_( long count, sample_t* out )
-{
- long remain = count;
- while ( remain )
- {
- remain -= buf->read_samples( &out [count - remain], remain );
- if ( remain )
- {
- if ( buf_changed_count != buf->channels_changed_count() )
- {
- buf_changed_count = buf->channels_changed_count();
- remute_voices();
- }
- int msec = buf->length();
- blip_time_t clocks_emulated = (blargg_long) msec * clock_rate_ / 1000;
- RETURN_ERR( run_clocks( clocks_emulated, msec ) );
- assert( clocks_emulated );
- buf->end_frame( clocks_emulated );
- }
- }
- return 0;
-}
-
-// Rom_Data
-
-blargg_err_t Rom_Data_::load_rom_data_( Data_Reader& in,
- int header_size, void* header_out, int fill, long pad_size )
-{
- long file_offset = pad_size - header_size;
-
- rom_addr = 0;
- mask = 0;
- size_ = 0;
- rom.clear();
-
- file_size_ = in.remain();
- if ( file_size_ <= header_size ) // <= because there must be data after header
- return gme_wrong_file_type;
- blargg_err_t err = rom.resize( file_offset + file_size_ + pad_size );
- if ( !err )
- err = in.read( rom.begin() + file_offset, file_size_ );
- if ( err )
- {
- rom.clear();
- return err;
- }
-
- file_size_ -= header_size;
- memcpy( header_out, &rom [file_offset], header_size );
-
- memset( rom.begin() , fill, pad_size );
- memset( rom.end() - pad_size, fill, pad_size );
-
- return 0;
-}
-
-void Rom_Data_::set_addr_( long addr, int unit )
-{
- rom_addr = addr - unit - pad_extra;
-
- long rounded = (addr + file_size_ + unit - 1) / unit * unit;
- if ( rounded <= 0 )
- {
- rounded = 0;
- }
- else
- {
- int shift = 0;
- unsigned long max_addr = (unsigned long) (rounded - 1);
- while ( max_addr >> shift )
- shift++;
- mask = (1L << shift) - 1;
- }
-
- if ( addr < 0 )
- addr = 0;
- size_ = rounded;
- if ( rom.resize( rounded - rom_addr + pad_extra ) ) { } // OK if shrink fails
-
- if ( 0 )
- {
- dprintf( "addr: %X\n", addr );
- dprintf( "file_size: %d\n", file_size_ );
- dprintf( "rounded: %d\n", rounded );
- dprintf( "mask: $%X\n", mask );
- }
-}
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Classic_Emu.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/Classic_Emu.h
deleted file mode 100644
index 8cd822ca..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Classic_Emu.h
+++ /dev/null
@@ -1,127 +0,0 @@
-// Common aspects of emulators which use Blip_Buffer for sound output
-
-// Game_Music_Emu 0.5.2
-#ifndef CLASSIC_EMU_H
-#define CLASSIC_EMU_H
-
-#include "blargg_common.h"
-#include "Blip_Buffer.h"
-#include "Music_Emu.h"
-
-class Classic_Emu : public Music_Emu {
-public:
- Classic_Emu();
- ~Classic_Emu();
- void set_buffer( Multi_Buffer* );
-protected:
- // Services
- enum { wave_type = 0x100, noise_type = 0x200, mixed_type = wave_type | noise_type };
- void set_voice_types( int const* t ) { voice_types = t; }
- blargg_err_t setup_buffer( long clock_rate );
- long clock_rate() const { return clock_rate_; }
- void change_clock_rate( long ); // experimental
-
- // Overridable
- virtual void set_voice( int index, Blip_Buffer* center,
- Blip_Buffer* left, Blip_Buffer* right ) = 0;
- virtual void update_eq( blip_eq_t const& ) = 0;
- virtual blargg_err_t start_track_( int track ) = 0;
- virtual blargg_err_t run_clocks( blip_time_t& time_io, int msec ) = 0;
-protected:
- blargg_err_t set_sample_rate_( long sample_rate );
- void mute_voices_( int );
- void set_equalizer_( equalizer_t const& );
- blargg_err_t play_( long, sample_t* );
-private:
- Multi_Buffer* buf;
- Multi_Buffer* stereo_buffer; // NULL if using custom buffer
- long clock_rate_;
- unsigned buf_changed_count;
- int const* voice_types;
-};
-
-inline void Classic_Emu::set_buffer( Multi_Buffer* new_buf )
-{
- assert( !buf && new_buf );
- buf = new_buf;
-}
-
-// ROM data handler, used by several Classic_Emu derivitives. Loads file data
-// with padding on both sides, allowing direct use in bank mapping. The main purpose
-// is to allow all file data to be loaded with only one read() call (for efficiency).
-
-class Rom_Data_ {
-public:
- typedef unsigned char byte;
-protected:
- enum { pad_extra = 8 };
- blargg_vector<byte> rom;
- long file_size_;
- blargg_long rom_addr;
- blargg_long mask;
- blargg_long size_; // TODO: eliminate
-
- blargg_err_t load_rom_data_( Data_Reader& in, int header_size, void* header_out,
- int fill, long pad_size );
- void set_addr_( long addr, int unit );
-};
-
-template<int unit>
-class Rom_Data : public Rom_Data_ {
- enum { pad_size = unit + pad_extra };
-public:
- // Load file data, using already-loaded header 'h' if not NULL. Copy header
- // from loaded file data into *out and fill unmapped bytes with 'fill'.
- blargg_err_t load( Data_Reader& in, int header_size, void* header_out, int fill )
- {
- return load_rom_data_( in, header_size, header_out, fill, pad_size );
- }
-
- // Size of file data read in (excluding header)
- long file_size() const { return file_size_; }
-
- // Pointer to beginning of file data
- byte* begin() const { return rom.begin() + pad_size; }
-
- // Set address that file data should start at
- void set_addr( long addr ) { set_addr_( addr, unit ); }
-
- // Free data
- void clear() { rom.clear(); }
-
- // Size of data + start addr, rounded to a multiple of unit
- long size() const { return size_; }
-
- // Pointer to unmapped page filled with same value
- byte* unmapped() { return rom.begin(); }
-
- // Mask address to nearest power of two greater than size()
- blargg_long mask_addr( blargg_long addr ) const
- {
- #ifdef check
- check( addr <= mask );
- #endif
- return addr & mask;
- }
-
- // Pointer to page starting at addr. Returns unmapped() if outside data.
- byte* at_addr( blargg_long addr )
- {
- blargg_ulong offset = mask_addr( addr ) - rom_addr;
- if ( offset > blargg_ulong (rom.size() - pad_size) )
- offset = 0; // unmapped
- return &rom [offset];
- }
-};
-
-#ifndef GME_APU_HOOK
- #define GME_APU_HOOK( emu, addr, data ) ((void) 0)
-#endif
-
-#ifndef GME_FRAME_HOOK
- #define GME_FRAME_HOOK( emu ) ((void) 0)
-#else
- #define GME_FRAME_HOOK_DEFINED 1
-#endif
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Data_Reader.cpp b/plugins/gme/Game_Music_Emu-0.5.2/gme/Data_Reader.cpp
deleted file mode 100644
index 5bbfbf55..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Data_Reader.cpp
+++ /dev/null
@@ -1,315 +0,0 @@
-// File_Extractor 0.4.0. http://www.slack.net/~ant/
-
-#include "Data_Reader.h"
-
-#include "blargg_endian.h"
-#include <assert.h>
-#include <string.h>
-#include <stdio.h>
-
-/* Copyright (C) 2005-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-const char Data_Reader::eof_error [] = "Unexpected end of file";
-
-blargg_err_t Data_Reader::read( void* p, long s )
-{
- long result = read_avail( p, s );
- if ( result != s )
- {
- if ( result >= 0 && result < s )
- return eof_error;
-
- return "Read error";
- }
-
- return 0;
-}
-
-blargg_err_t Data_Reader::skip( long count )
-{
- char buf [512];
- while ( count )
- {
- long n = sizeof buf;
- if ( n > count )
- n = count;
- count -= n;
- RETURN_ERR( read( buf, n ) );
- }
- return 0;
-}
-
-long File_Reader::remain() const { return size() - tell(); }
-
-blargg_err_t File_Reader::skip( long n )
-{
- assert( n >= 0 );
- if ( !n )
- return 0;
- return seek( tell() + n );
-}
-
-// Subset_Reader
-
-Subset_Reader::Subset_Reader( Data_Reader* dr, long size )
-{
- in = dr;
- remain_ = dr->remain();
- if ( remain_ > size )
- remain_ = size;
-}
-
-long Subset_Reader::remain() const { return remain_; }
-
-long Subset_Reader::read_avail( void* p, long s )
-{
- if ( s > remain_ )
- s = remain_;
- remain_ -= s;
- return in->read_avail( p, s );
-}
-
-// Remaining_Reader
-
-Remaining_Reader::Remaining_Reader( void const* h, long size, Data_Reader* r )
-{
- header = (char const*) h;
- header_end = header + size;
- in = r;
-}
-
-long Remaining_Reader::remain() const { return header_end - header + in->remain(); }
-
-long Remaining_Reader::read_first( void* out, long count )
-{
- long first = header_end - header;
- if ( first )
- {
- if ( first > count )
- first = count;
- void const* old = header;
- header += first;
- memcpy( out, old, first );
- }
- return first;
-}
-
-long Remaining_Reader::read_avail( void* out, long count )
-{
- long first = read_first( out, count );
- long second = count - first;
- if ( second )
- {
- second = in->read_avail( (char*) out + first, second );
- if ( second <= 0 )
- return second;
- }
- return first + second;
-}
-
-blargg_err_t Remaining_Reader::read( void* out, long count )
-{
- long first = read_first( out, count );
- long second = count - first;
- if ( !second )
- return 0;
- return in->read( (char*) out + first, second );
-}
-
-// Mem_File_Reader
-
-Mem_File_Reader::Mem_File_Reader( const void* p, long s ) :
- begin( (const char*) p ),
- size_( s )
-{
- pos = 0;
-}
-
-long Mem_File_Reader::size() const { return size_; }
-
-long Mem_File_Reader::read_avail( void* p, long s )
-{
- long r = remain();
- if ( s > r )
- s = r;
- memcpy( p, begin + pos, s );
- pos += s;
- return s;
-}
-
-long Mem_File_Reader::tell() const { return pos; }
-
-blargg_err_t Mem_File_Reader::seek( long n )
-{
- if ( n > size_ )
- return eof_error;
- pos = n;
- return 0;
-}
-
-// Callback_Reader
-
-Callback_Reader::Callback_Reader( callback_t c, long size, void* d ) :
- callback( c ),
- data( d )
-{
- remain_ = size;
-}
-
-long Callback_Reader::remain() const { return remain_; }
-
-long Callback_Reader::read_avail( void* out, long count )
-{
- if ( count > remain_ )
- count = remain_;
- if ( Callback_Reader::read( out, count ) )
- count = -1;
- return count;
-}
-
-blargg_err_t Callback_Reader::read( void* out, long count )
-{
- if ( count > remain_ )
- return eof_error;
- return callback( data, out, count );
-}
-
-// Std_File_Reader
-
-Std_File_Reader::Std_File_Reader() : file_( 0 ) { }
-
-Std_File_Reader::~Std_File_Reader() { close(); }
-
-blargg_err_t Std_File_Reader::open( const char* path )
-{
- file_ = fopen( path, "rb" );
- if ( !file_ )
- return "Couldn't open file";
- return 0;
-}
-
-long Std_File_Reader::size() const
-{
- long pos = tell();
- fseek( (FILE*) file_, 0, SEEK_END );
- long result = tell();
- fseek( (FILE*) file_, pos, SEEK_SET );
- return result;
-}
-
-long Std_File_Reader::read_avail( void* p, long s )
-{
- return fread( p, 1, s, (FILE*) file_ );
-}
-
-blargg_err_t Std_File_Reader::read( void* p, long s )
-{
- if ( s == (long) fread( p, 1, s, (FILE*) file_ ) )
- return 0;
- if ( feof( (FILE*) file_ ) )
- return eof_error;
- return "Couldn't read from file";
-}
-
-long Std_File_Reader::tell() const { return ftell( (FILE*) file_ ); }
-
-blargg_err_t Std_File_Reader::seek( long n )
-{
- if ( !fseek( (FILE*) file_, n, SEEK_SET ) )
- return 0;
- if ( n > size() )
- return eof_error;
- return "Error seeking in file";
-}
-
-void Std_File_Reader::close()
-{
- if ( file_ )
- {
- fclose( (FILE*) file_ );
- file_ = 0;
- }
-}
-
-// Gzip_File_Reader
-
-#ifdef HAVE_ZLIB_H
-
-#include "zlib.h"
-
-static const char* get_gzip_eof( const char* path, long* eof )
-{
- FILE* file = fopen( path, "rb" );
- if ( !file )
- return "Couldn't open file";
-
- unsigned char buf [4];
- if ( fread( buf, 2, 1, file ) > 0 && buf [0] == 0x1F && buf [1] == 0x8B )
- {
- fseek( file, -4, SEEK_END );
- fread( buf, 4, 1, file );
- *eof = get_le32( buf );
- }
- else
- {
- fseek( file, 0, SEEK_END );
- *eof = ftell( file );
- }
- const char* err = (ferror( file ) || feof( file )) ? "Couldn't get file size" : 0;
- fclose( file );
- return err;
-}
-
-Gzip_File_Reader::Gzip_File_Reader() : file_( 0 ) { }
-
-Gzip_File_Reader::~Gzip_File_Reader() { close(); }
-
-blargg_err_t Gzip_File_Reader::open( const char* path )
-{
- close();
-
- RETURN_ERR( get_gzip_eof( path, &size_ ) );
-
- file_ = gzopen( path, "rb" );
- if ( !file_ )
- return "Couldn't open file";
-
- return 0;
-}
-
-long Gzip_File_Reader::size() const { return size_; }
-
-long Gzip_File_Reader::read_avail( void* p, long s ) { return gzread( file_, p, s ); }
-
-long Gzip_File_Reader::tell() const { return gztell( file_ ); }
-
-blargg_err_t Gzip_File_Reader::seek( long n )
-{
- if ( gzseek( file_, n, SEEK_SET ) >= 0 )
- return 0;
- if ( n > size_ )
- return eof_error;
- return "Error seeking in file";
-}
-
-void Gzip_File_Reader::close()
-{
- if ( file_ )
- {
- gzclose( file_ );
- file_ = 0;
- }
-}
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Data_Reader.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/Data_Reader.h
deleted file mode 100644
index 00b53b9e..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Data_Reader.h
+++ /dev/null
@@ -1,151 +0,0 @@
-// Data reader interface for uniform access
-
-// File_Extractor 0.4.0
-#ifndef DATA_READER_H
-#define DATA_READER_H
-
-#include "blargg_common.h"
-
-// Supports reading and finding out how many bytes are remaining
-class Data_Reader {
-public:
- virtual ~Data_Reader() { }
-
- static const char eof_error []; // returned by read() when request goes beyond end
-
- // Read at most count bytes and return number actually read, or <= 0 if error
- virtual long read_avail( void*, long n ) = 0;
-
- // Read exactly count bytes and return error if they couldn't be read
- virtual blargg_err_t read( void*, long count );
-
- // Number of bytes remaining until end of file
- virtual long remain() const = 0;
-
- // Read and discard count bytes
- virtual blargg_err_t skip( long count );
-
-public:
- Data_Reader() { }
- typedef blargg_err_t error_t; // deprecated
-private:
- // noncopyable
- Data_Reader( const Data_Reader& );
- Data_Reader& operator = ( const Data_Reader& );
-};
-
-// Supports seeking in addition to Data_Reader operations
-class File_Reader : public Data_Reader {
-public:
- // Size of file
- virtual long size() const = 0;
-
- // Current position in file
- virtual long tell() const = 0;
-
- // Go to new position
- virtual blargg_err_t seek( long ) = 0;
-
- long remain() const;
- blargg_err_t skip( long n );
-};
-
-// Disk file reader
-class Std_File_Reader : public File_Reader {
-public:
- blargg_err_t open( const char* path );
- void close();
-
-public:
- Std_File_Reader();
- ~Std_File_Reader();
- long size() const;
- blargg_err_t read( void*, long );
- long read_avail( void*, long );
- long tell() const;
- blargg_err_t seek( long );
-private:
- void* file_;
-};
-
-// Treats range of memory as a file
-class Mem_File_Reader : public File_Reader {
-public:
- Mem_File_Reader( const void*, long size );
-
-public:
- long size() const;
- long read_avail( void*, long );
- long tell() const;
- blargg_err_t seek( long );
-private:
- const char* const begin;
- const long size_;
- long pos;
-};
-
-// Makes it look like there are only count bytes remaining
-class Subset_Reader : public Data_Reader {
-public:
- Subset_Reader( Data_Reader*, long count );
-
-public:
- long remain() const;
- long read_avail( void*, long );
-private:
- Data_Reader* in;
- long remain_;
-};
-
-// Joins already-read header and remaining data into original file (to avoid seeking)
-class Remaining_Reader : public Data_Reader {
-public:
- Remaining_Reader( void const* header, long size, Data_Reader* );
-
-public:
- long remain() const;
- long read_avail( void*, long );
- blargg_err_t read( void*, long );
-private:
- char const* header;
- char const* header_end;
- Data_Reader* in;
- long read_first( void* out, long count );
-};
-
-// Invokes callback function to read data. Size of data must be specified in advance.
-class Callback_Reader : public Data_Reader {
-public:
- typedef const char* (*callback_t)( void* data, void* out, long count );
- Callback_Reader( callback_t, long size, void* data = 0 );
-public:
- long read_avail( void*, long );
- blargg_err_t read( void*, long );
- long remain() const;
-private:
- callback_t const callback;
- void* const data;
- long remain_;
-};
-
-#ifdef HAVE_ZLIB_H
-// Gzip compressed file reader
-class Gzip_File_Reader : public File_Reader {
-public:
- blargg_err_t open( const char* path );
- void close();
-
-public:
- Gzip_File_Reader();
- ~Gzip_File_Reader();
- long size() const;
- long read_avail( void*, long );
- long tell() const;
- blargg_err_t seek( long );
-private:
- void* file_;
- long size_;
-};
-#endif
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Dual_Resampler.cpp b/plugins/gme/Game_Music_Emu-0.5.2/gme/Dual_Resampler.cpp
deleted file mode 100644
index 8644517c..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Dual_Resampler.cpp
+++ /dev/null
@@ -1,131 +0,0 @@
-// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
-
-#include "Dual_Resampler.h"
-
-#include <stdlib.h>
-#include <string.h>
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-unsigned const resampler_extra = 256;
-
-Dual_Resampler::Dual_Resampler() { }
-
-Dual_Resampler::~Dual_Resampler() { }
-
-blargg_err_t Dual_Resampler::reset( int pairs )
-{
- // expand allocations a bit
- RETURN_ERR( sample_buf.resize( (pairs + (pairs >> 2)) * 2 ) );
- resize( pairs );
- resampler_size = oversamples_per_frame + (oversamples_per_frame >> 2);
- return resampler.buffer_size( resampler_size );
-}
-
-void Dual_Resampler::resize( int pairs )
-{
- int new_sample_buf_size = pairs * 2;
- if ( sample_buf_size != new_sample_buf_size )
- {
- if ( (unsigned) new_sample_buf_size > sample_buf.size() )
- {
- check( false );
- return;
- }
- sample_buf_size = new_sample_buf_size;
- oversamples_per_frame = int (pairs * resampler.ratio()) * 2 + 2;
- clear();
- }
-}
-
-void Dual_Resampler::play_frame_( Blip_Buffer& blip_buf, dsample_t* out )
-{
- long pair_count = sample_buf_size >> 1;
- blip_time_t blip_time = blip_buf.count_clocks( pair_count );
- int sample_count = oversamples_per_frame - resampler.written();
-
- int new_count = play_frame( blip_time, sample_count, resampler.buffer() );
- assert( new_count < resampler_size );
-
- blip_buf.end_frame( blip_time );
- assert( blip_buf.samples_avail() == pair_count );
-
- resampler.write( new_count );
-
- long count = resampler.read( sample_buf.begin(), sample_buf_size );
- assert( count == (long) sample_buf_size );
-
- mix_samples( blip_buf, out );
- blip_buf.remove_samples( pair_count );
-}
-
-void Dual_Resampler::dual_play( long count, dsample_t* out, Blip_Buffer& blip_buf )
-{
- // empty extra buffer
- long remain = sample_buf_size - buf_pos;
- if ( remain )
- {
- if ( remain > count )
- remain = count;
- count -= remain;
- memcpy( out, &sample_buf [buf_pos], remain * sizeof *out );
- out += remain;
- buf_pos += remain;
- }
-
- // entire frames
- while ( count >= (long) sample_buf_size )
- {
- play_frame_( blip_buf, out );
- out += sample_buf_size;
- count -= sample_buf_size;
- }
-
- // extra
- if ( count )
- {
- play_frame_( blip_buf, sample_buf.begin() );
- buf_pos = count;
- memcpy( out, sample_buf.begin(), count * sizeof *out );
- out += count;
- }
-}
-
-void Dual_Resampler::mix_samples( Blip_Buffer& blip_buf, dsample_t* out )
-{
- Blip_Reader sn;
- int bass = sn.begin( blip_buf );
- const dsample_t* in = sample_buf.begin();
-
- for ( int n = sample_buf_size >> 1; n--; )
- {
- int s = sn.read();
- blargg_long l = (blargg_long) in [0] * 2 + s;
- if ( (BOOST::int16_t) l != l )
- l = 0x7FFF - (l >> 24);
-
- sn.next( bass );
- blargg_long r = (blargg_long) in [1] * 2 + s;
- if ( (BOOST::int16_t) r != r )
- r = 0x7FFF - (r >> 24);
-
- in += 2;
- out [0] = l;
- out [1] = r;
- out += 2;
- }
-
- sn.end( blip_buf );
-}
-
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Dual_Resampler.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/Dual_Resampler.h
deleted file mode 100644
index 61beb8a0..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Dual_Resampler.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Combination of Fir_Resampler and Blip_Buffer mixing. Used by Sega FM emulators.
-
-// Game_Music_Emu 0.5.2
-#ifndef DUAL_RESAMPLER_H
-#define DUAL_RESAMPLER_H
-
-#include "Fir_Resampler.h"
-#include "Blip_Buffer.h"
-
-class Dual_Resampler {
-public:
- Dual_Resampler();
- virtual ~Dual_Resampler();
-
- typedef short dsample_t;
-
- double setup( double oversample, double rolloff, double gain );
- blargg_err_t reset( int max_pairs );
- void resize( int pairs_per_frame );
- void clear();
-
- void dual_play( long count, dsample_t* out, Blip_Buffer& );
-
-protected:
- virtual int play_frame( blip_time_t, int pcm_count, dsample_t* pcm_out ) = 0;
-private:
-
- blargg_vector<dsample_t> sample_buf;
- int sample_buf_size;
- int oversamples_per_frame;
- int buf_pos;
- int resampler_size;
-
- Fir_Resampler<12> resampler;
- void mix_samples( Blip_Buffer&, dsample_t* );
- void play_frame_( Blip_Buffer&, dsample_t* );
-};
-
-inline double Dual_Resampler::setup( double oversample, double rolloff, double gain )
-{
- return resampler.time_ratio( oversample, rolloff, gain * 0.5 );
-}
-
-inline void Dual_Resampler::clear()
-{
- buf_pos = sample_buf_size;
- resampler.clear();
-}
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Effects_Buffer.cpp b/plugins/gme/Game_Music_Emu-0.5.2/gme/Effects_Buffer.cpp
deleted file mode 100644
index 730f8e94..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Effects_Buffer.cpp
+++ /dev/null
@@ -1,529 +0,0 @@
-// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
-
-#include "Effects_Buffer.h"
-
-#include <string.h>
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-#ifdef BLARGG_ENABLE_OPTIMIZER
- #include BLARGG_ENABLE_OPTIMIZER
-#endif
-
-typedef blargg_long fixed_t;
-
-#define TO_FIXED( f ) fixed_t ((f) * (1L << 15) + 0.5)
-#define FMUL( x, y ) (((x) * (y)) >> 15)
-
-const unsigned echo_size = 4096;
-const unsigned echo_mask = echo_size - 1;
-BOOST_STATIC_ASSERT( (echo_size & echo_mask) == 0 ); // must be power of 2
-
-const unsigned reverb_size = 8192 * 2;
-const unsigned reverb_mask = reverb_size - 1;
-BOOST_STATIC_ASSERT( (reverb_size & reverb_mask) == 0 ); // must be power of 2
-
-Effects_Buffer::config_t::config_t()
-{
- pan_1 = -0.15f;
- pan_2 = 0.15f;
- reverb_delay = 88.0f;
- reverb_level = 0.12f;
- echo_delay = 61.0f;
- echo_level = 0.10f;
- delay_variance = 18.0f;
- effects_enabled = false;
-}
-
-void Effects_Buffer::set_depth( double d )
-{
- float f = (float) d;
- config_t c;
- c.pan_1 = -0.6f * f;
- c.pan_2 = 0.6f * f;
- c.reverb_delay = 880 * 0.1f;
- c.echo_delay = 610 * 0.1f;
- if ( f > 0.5 )
- f = 0.5; // TODO: more linear reduction of extreme reverb/echo
- c.reverb_level = 0.5f * f;
- c.echo_level = 0.30f * f;
- c.delay_variance = 180 * 0.1f;
- c.effects_enabled = (d > 0.0f);
- config( c );
-}
-
-Effects_Buffer::Effects_Buffer( bool center_only ) : Multi_Buffer( 2 )
-{
- buf_count = center_only ? max_buf_count - 4 : max_buf_count;
-
- echo_pos = 0;
- reverb_pos = 0;
-
- stereo_remain = 0;
- effect_remain = 0;
- effects_enabled = false;
- set_depth( 0 );
-}
-
-Effects_Buffer::~Effects_Buffer() { }
-
-blargg_err_t Effects_Buffer::set_sample_rate( long rate, int msec )
-{
- if ( !echo_buf.size() )
- RETURN_ERR( echo_buf.resize( echo_size ) );
-
- if ( !reverb_buf.size() )
- RETURN_ERR( reverb_buf.resize( reverb_size ) );
-
- for ( int i = 0; i < buf_count; i++ )
- RETURN_ERR( bufs [i].set_sample_rate( rate, msec ) );
-
- config( config_ );
- clear();
-
- return Multi_Buffer::set_sample_rate( bufs [0].sample_rate(), bufs [0].length() );
-}
-
-void Effects_Buffer::clock_rate( long rate )
-{
- for ( int i = 0; i < buf_count; i++ )
- bufs [i].clock_rate( rate );
-}
-
-void Effects_Buffer::bass_freq( int freq )
-{
- for ( int i = 0; i < buf_count; i++ )
- bufs [i].bass_freq( freq );
-}
-
-void Effects_Buffer::clear()
-{
- stereo_remain = 0;
- effect_remain = 0;
- if ( echo_buf.size() )
- memset( &echo_buf [0], 0, echo_size * sizeof echo_buf [0] );
-
- if ( reverb_buf.size() )
- memset( &reverb_buf [0], 0, reverb_size * sizeof reverb_buf [0] );
-
- for ( int i = 0; i < buf_count; i++ )
- bufs [i].clear();
-}
-
-inline int pin_range( int n, int max, int min = 0 )
-{
- if ( n < min )
- return min;
- if ( n > max )
- return max;
- return n;
-}
-
-void Effects_Buffer::config( const config_t& cfg )
-{
- channels_changed();
-
- // clear echo and reverb buffers
- if ( !config_.effects_enabled && cfg.effects_enabled && echo_buf.size() )
- {
- memset( &echo_buf [0], 0, echo_size * sizeof echo_buf [0] );
- memset( &reverb_buf [0], 0, reverb_size * sizeof reverb_buf [0] );
- }
-
- config_ = cfg;
-
- if ( config_.effects_enabled )
- {
- // convert to internal format
-
- chans.pan_1_levels [0] = TO_FIXED( 1 ) - TO_FIXED( config_.pan_1 );
- chans.pan_1_levels [1] = TO_FIXED( 2 ) - chans.pan_1_levels [0];
-
- chans.pan_2_levels [0] = TO_FIXED( 1 ) - TO_FIXED( config_.pan_2 );
- chans.pan_2_levels [1] = TO_FIXED( 2 ) - chans.pan_2_levels [0];
-
- chans.reverb_level = TO_FIXED( config_.reverb_level );
- chans.echo_level = TO_FIXED( config_.echo_level );
-
- int delay_offset = int (1.0 / 2000 * config_.delay_variance * sample_rate());
-
- int reverb_sample_delay = int (1.0 / 1000 * config_.reverb_delay * sample_rate());
- chans.reverb_delay_l = pin_range( reverb_size -
- (reverb_sample_delay - delay_offset) * 2, reverb_size - 2, 0 );
- chans.reverb_delay_r = pin_range( reverb_size + 1 -
- (reverb_sample_delay + delay_offset) * 2, reverb_size - 1, 1 );
-
- int echo_sample_delay = int (1.0 / 1000 * config_.echo_delay * sample_rate());
- chans.echo_delay_l = pin_range( echo_size - 1 - (echo_sample_delay - delay_offset),
- echo_size - 1 );
- chans.echo_delay_r = pin_range( echo_size - 1 - (echo_sample_delay + delay_offset),
- echo_size - 1 );
-
- chan_types [0].center = &bufs [0];
- chan_types [0].left = &bufs [3];
- chan_types [0].right = &bufs [4];
-
- chan_types [1].center = &bufs [1];
- chan_types [1].left = &bufs [3];
- chan_types [1].right = &bufs [4];
-
- chan_types [2].center = &bufs [2];
- chan_types [2].left = &bufs [5];
- chan_types [2].right = &bufs [6];
- assert( 2 < chan_types_count );
- }
- else
- {
- // set up outputs
- for ( unsigned i = 0; i < chan_types_count; i++ )
- {
- channel_t& c = chan_types [i];
- c.center = &bufs [0];
- c.left = &bufs [1];
- c.right = &bufs [2];
- }
- }
-
- if ( buf_count < max_buf_count )
- {
- for ( int i = 0; i < chan_types_count; i++ )
- {
- channel_t& c = chan_types [i];
- c.left = c.center;
- c.right = c.center;
- }
- }
-}
-
-Effects_Buffer::channel_t Effects_Buffer::channel( int i, int type )
-{
- int out = 2;
- if ( !type )
- {
- out = i % 5;
- if ( out > 2 )
- out = 2;
- }
- else if ( !(type & noise_type) && (type & type_index_mask) % 3 != 0 )
- {
- out = type & 1;
- }
- return chan_types [out];
-}
-
-void Effects_Buffer::end_frame( blip_time_t clock_count )
-{
- int bufs_used = 0;
- for ( int i = 0; i < buf_count; i++ )
- {
- bufs_used |= bufs [i].clear_modified() << i;
- bufs [i].end_frame( clock_count );
- }
-
- int stereo_mask = (config_.effects_enabled ? 0x78 : 0x06);
- if ( (bufs_used & stereo_mask) && buf_count == max_buf_count )
- stereo_remain = bufs [0].samples_avail() + bufs [0].output_latency();
-
- if ( effects_enabled || config_.effects_enabled )
- effect_remain = bufs [0].samples_avail() + bufs [0].output_latency();
-
- effects_enabled = config_.effects_enabled;
-}
-
-long Effects_Buffer::samples_avail() const
-{
- return bufs [0].samples_avail() * 2;
-}
-
-long Effects_Buffer::read_samples( blip_sample_t* out, long total_samples )
-{
- require( total_samples % 2 == 0 ); // count must be even
-
- long remain = bufs [0].samples_avail();
- if ( remain > (total_samples >> 1) )
- remain = (total_samples >> 1);
- total_samples = remain;
- while ( remain )
- {
- int active_bufs = buf_count;
- long count = remain;
-
- // optimizing mixing to skip any channels which had nothing added
- if ( effect_remain )
- {
- if ( count > effect_remain )
- count = effect_remain;
-
- if ( stereo_remain )
- {
- mix_enhanced( out, count );
- }
- else
- {
- mix_mono_enhanced( out, count );
- active_bufs = 3;
- }
- }
- else if ( stereo_remain )
- {
- mix_stereo( out, count );
- active_bufs = 3;
- }
- else
- {
- mix_mono( out, count );
- active_bufs = 1;
- }
-
- out += count * 2;
- remain -= count;
-
- stereo_remain -= count;
- if ( stereo_remain < 0 )
- stereo_remain = 0;
-
- effect_remain -= count;
- if ( effect_remain < 0 )
- effect_remain = 0;
-
- for ( int i = 0; i < buf_count; i++ )
- {
- if ( i < active_bufs )
- bufs [i].remove_samples( count );
- else
- bufs [i].remove_silence( count ); // keep time synchronized
- }
- }
-
- return total_samples * 2;
-}
-
-void Effects_Buffer::mix_mono( blip_sample_t* out_, blargg_long count )
-{
- blip_sample_t* BLIP_RESTRICT out = out_;
- int const bass = BLIP_READER_BASS( bufs [0] );
- BLIP_READER_BEGIN( c, bufs [0] );
-
- // unrolled loop
- for ( blargg_long n = count >> 1; n; --n )
- {
- blargg_long cs0 = BLIP_READER_READ( c );
- BLIP_READER_NEXT( c, bass );
-
- blargg_long cs1 = BLIP_READER_READ( c );
- BLIP_READER_NEXT( c, bass );
-
- if ( (BOOST::int16_t) cs0 != cs0 )
- cs0 = 0x7FFF - (cs0 >> 24);
- ((BOOST::uint32_t*) out) [0] = ((BOOST::uint16_t) cs0) | (cs0 << 16);
-
- if ( (BOOST::int16_t) cs1 != cs1 )
- cs1 = 0x7FFF - (cs1 >> 24);
- ((BOOST::uint32_t*) out) [1] = ((BOOST::uint16_t) cs1) | (cs1 << 16);
- out += 4;
- }
-
- if ( count & 1 )
- {
- int s = BLIP_READER_READ( c );
- BLIP_READER_NEXT( c, bass );
- out [0] = s;
- out [1] = s;
- if ( (BOOST::int16_t) s != s )
- {
- s = 0x7FFF - (s >> 24);
- out [0] = s;
- out [1] = s;
- }
- }
-
- BLIP_READER_END( c, bufs [0] );
-}
-
-void Effects_Buffer::mix_stereo( blip_sample_t* out_, blargg_long count )
-{
- blip_sample_t* BLIP_RESTRICT out = out_;
- int const bass = BLIP_READER_BASS( bufs [0] );
- BLIP_READER_BEGIN( c, bufs [0] );
- BLIP_READER_BEGIN( l, bufs [1] );
- BLIP_READER_BEGIN( r, bufs [2] );
-
- while ( count-- )
- {
- int cs = BLIP_READER_READ( c );
- BLIP_READER_NEXT( c, bass );
- int left = cs + BLIP_READER_READ( l );
- int right = cs + BLIP_READER_READ( r );
- BLIP_READER_NEXT( l, bass );
- BLIP_READER_NEXT( r, bass );
-
- if ( (BOOST::int16_t) left != left )
- left = 0x7FFF - (left >> 24);
-
- out [0] = left;
- out [1] = right;
-
- out += 2;
-
- if ( (BOOST::int16_t) right != right )
- out [-1] = 0x7FFF - (right >> 24);
- }
-
- BLIP_READER_END( r, bufs [2] );
- BLIP_READER_END( l, bufs [1] );
- BLIP_READER_END( c, bufs [0] );
-}
-
-void Effects_Buffer::mix_mono_enhanced( blip_sample_t* out_, blargg_long count )
-{
- blip_sample_t* BLIP_RESTRICT out = out_;
- int const bass = BLIP_READER_BASS( bufs [2] );
- BLIP_READER_BEGIN( center, bufs [2] );
- BLIP_READER_BEGIN( sq1, bufs [0] );
- BLIP_READER_BEGIN( sq2, bufs [1] );
-
- blip_sample_t* const reverb_buf = this->reverb_buf.begin();
- blip_sample_t* const echo_buf = this->echo_buf.begin();
- int echo_pos = this->echo_pos;
- int reverb_pos = this->reverb_pos;
-
- while ( count-- )
- {
- int sum1_s = BLIP_READER_READ( sq1 );
- int sum2_s = BLIP_READER_READ( sq2 );
-
- BLIP_READER_NEXT( sq1, bass );
- BLIP_READER_NEXT( sq2, bass );
-
- int new_reverb_l = FMUL( sum1_s, chans.pan_1_levels [0] ) +
- FMUL( sum2_s, chans.pan_2_levels [0] ) +
- reverb_buf [(reverb_pos + chans.reverb_delay_l) & reverb_mask];
-
- int new_reverb_r = FMUL( sum1_s, chans.pan_1_levels [1] ) +
- FMUL( sum2_s, chans.pan_2_levels [1] ) +
- reverb_buf [(reverb_pos + chans.reverb_delay_r) & reverb_mask];
-
- fixed_t reverb_level = chans.reverb_level;
- reverb_buf [reverb_pos] = (blip_sample_t) FMUL( new_reverb_l, reverb_level );
- reverb_buf [reverb_pos + 1] = (blip_sample_t) FMUL( new_reverb_r, reverb_level );
- reverb_pos = (reverb_pos + 2) & reverb_mask;
-
- int sum3_s = BLIP_READER_READ( center );
- BLIP_READER_NEXT( center, bass );
-
- int left = new_reverb_l + sum3_s + FMUL( chans.echo_level,
- echo_buf [(echo_pos + chans.echo_delay_l) & echo_mask] );
- int right = new_reverb_r + sum3_s + FMUL( chans.echo_level,
- echo_buf [(echo_pos + chans.echo_delay_r) & echo_mask] );
-
- echo_buf [echo_pos] = sum3_s;
- echo_pos = (echo_pos + 1) & echo_mask;
-
- if ( (BOOST::int16_t) left != left )
- left = 0x7FFF - (left >> 24);
-
- out [0] = left;
- out [1] = right;
-
- out += 2;
-
- if ( (BOOST::int16_t) right != right )
- out [-1] = 0x7FFF - (right >> 24);
- }
- this->reverb_pos = reverb_pos;
- this->echo_pos = echo_pos;
-
- BLIP_READER_END( sq1, bufs [0] );
- BLIP_READER_END( sq2, bufs [1] );
- BLIP_READER_END( center, bufs [2] );
-}
-
-void Effects_Buffer::mix_enhanced( blip_sample_t* out_, blargg_long count )
-{
- blip_sample_t* BLIP_RESTRICT out = out_;
- int const bass = BLIP_READER_BASS( bufs [2] );
- BLIP_READER_BEGIN( center, bufs [2] );
- BLIP_READER_BEGIN( l1, bufs [3] );
- BLIP_READER_BEGIN( r1, bufs [4] );
- BLIP_READER_BEGIN( l2, bufs [5] );
- BLIP_READER_BEGIN( r2, bufs [6] );
- BLIP_READER_BEGIN( sq1, bufs [0] );
- BLIP_READER_BEGIN( sq2, bufs [1] );
-
- blip_sample_t* const reverb_buf = this->reverb_buf.begin();
- blip_sample_t* const echo_buf = this->echo_buf.begin();
- int echo_pos = this->echo_pos;
- int reverb_pos = this->reverb_pos;
-
- while ( count-- )
- {
- int sum1_s = BLIP_READER_READ( sq1 );
- int sum2_s = BLIP_READER_READ( sq2 );
-
- BLIP_READER_NEXT( sq1, bass );
- BLIP_READER_NEXT( sq2, bass );
-
- int new_reverb_l = FMUL( sum1_s, chans.pan_1_levels [0] ) +
- FMUL( sum2_s, chans.pan_2_levels [0] ) + BLIP_READER_READ( l1 ) +
- reverb_buf [(reverb_pos + chans.reverb_delay_l) & reverb_mask];
-
- int new_reverb_r = FMUL( sum1_s, chans.pan_1_levels [1] ) +
- FMUL( sum2_s, chans.pan_2_levels [1] ) + BLIP_READER_READ( r1 ) +
- reverb_buf [(reverb_pos + chans.reverb_delay_r) & reverb_mask];
-
- BLIP_READER_NEXT( l1, bass );
- BLIP_READER_NEXT( r1, bass );
-
- fixed_t reverb_level = chans.reverb_level;
- reverb_buf [reverb_pos] = (blip_sample_t) FMUL( new_reverb_l, reverb_level );
- reverb_buf [reverb_pos + 1] = (blip_sample_t) FMUL( new_reverb_r, reverb_level );
- reverb_pos = (reverb_pos + 2) & reverb_mask;
-
- int sum3_s = BLIP_READER_READ( center );
- BLIP_READER_NEXT( center, bass );
-
- int left = new_reverb_l + sum3_s + BLIP_READER_READ( l2 ) + FMUL( chans.echo_level,
- echo_buf [(echo_pos + chans.echo_delay_l) & echo_mask] );
- int right = new_reverb_r + sum3_s + BLIP_READER_READ( r2 ) + FMUL( chans.echo_level,
- echo_buf [(echo_pos + chans.echo_delay_r) & echo_mask] );
-
- BLIP_READER_NEXT( l2, bass );
- BLIP_READER_NEXT( r2, bass );
-
- echo_buf [echo_pos] = sum3_s;
- echo_pos = (echo_pos + 1) & echo_mask;
-
- if ( (BOOST::int16_t) left != left )
- left = 0x7FFF - (left >> 24);
-
- out [0] = left;
- out [1] = right;
-
- out += 2;
-
- if ( (BOOST::int16_t) right != right )
- out [-1] = 0x7FFF - (right >> 24);
- }
- this->reverb_pos = reverb_pos;
- this->echo_pos = echo_pos;
-
- BLIP_READER_END( l1, bufs [3] );
- BLIP_READER_END( r1, bufs [4] );
- BLIP_READER_END( l2, bufs [5] );
- BLIP_READER_END( r2, bufs [6] );
- BLIP_READER_END( sq1, bufs [0] );
- BLIP_READER_END( sq2, bufs [1] );
- BLIP_READER_END( center, bufs [2] );
-}
-
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Effects_Buffer.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/Effects_Buffer.h
deleted file mode 100644
index eb0aa67a..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Effects_Buffer.h
+++ /dev/null
@@ -1,86 +0,0 @@
-// Multi-channel effects buffer with panning, echo and reverb
-
-// Game_Music_Emu 0.5.2
-#ifndef EFFECTS_BUFFER_H
-#define EFFECTS_BUFFER_H
-
-#include "Multi_Buffer.h"
-
-// Effects_Buffer uses several buffers and outputs stereo sample pairs.
-class Effects_Buffer : public Multi_Buffer {
-public:
- // If center_only is true, only center buffers are created and
- // less memory is used.
- Effects_Buffer( bool center_only = false );
-
- // Channel Effect Center Pan
- // ---------------------------------
- // 0,5 reverb pan_1
- // 1,6 reverb pan_2
- // 2,7 echo -
- // 3 echo -
- // 4 echo -
-
- // Channel configuration
- struct config_t {
- double pan_1; // -1.0 = left, 0.0 = center, 1.0 = right
- double pan_2;
- double echo_delay; // msec
- double echo_level; // 0.0 to 1.0
- double reverb_delay; // msec
- double delay_variance; // difference between left/right delays (msec)
- double reverb_level; // 0.0 to 1.0
- bool effects_enabled; // if false, use optimized simple mixer
- config_t();
- };
-
- // Set configuration of buffer
- virtual void config( const config_t& );
- void set_depth( double );
-
-public:
- ~Effects_Buffer();
- blargg_err_t set_sample_rate( long samples_per_sec, int msec = blip_default_length );
- void clock_rate( long );
- void bass_freq( int );
- void clear();
- channel_t channel( int, int );
- void end_frame( blip_time_t );
- long read_samples( blip_sample_t*, long );
- long samples_avail() const;
-private:
- typedef long fixed_t;
-
- enum { max_buf_count = 7 };
- Blip_Buffer bufs [max_buf_count];
- enum { chan_types_count = 3 };
- channel_t chan_types [3];
- config_t config_;
- long stereo_remain;
- long effect_remain;
- int buf_count;
- bool effects_enabled;
-
- blargg_vector<blip_sample_t> reverb_buf;
- blargg_vector<blip_sample_t> echo_buf;
- int reverb_pos;
- int echo_pos;
-
- struct {
- fixed_t pan_1_levels [2];
- fixed_t pan_2_levels [2];
- int echo_delay_l;
- int echo_delay_r;
- fixed_t echo_level;
- int reverb_delay_l;
- int reverb_delay_r;
- fixed_t reverb_level;
- } chans;
-
- void mix_mono( blip_sample_t*, blargg_long );
- void mix_stereo( blip_sample_t*, blargg_long );
- void mix_enhanced( blip_sample_t*, blargg_long );
- void mix_mono_enhanced( blip_sample_t*, blargg_long );
-};
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Fir_Resampler.cpp b/plugins/gme/Game_Music_Emu-0.5.2/gme/Fir_Resampler.cpp
deleted file mode 100644
index 4e0a4631..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Fir_Resampler.cpp
+++ /dev/null
@@ -1,199 +0,0 @@
-// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
-
-#include "Fir_Resampler.h"
-
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <math.h>
-
-/* Copyright (C) 2004-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-#undef PI
-#define PI 3.1415926535897932384626433832795029
-
-static void gen_sinc( double rolloff, int width, double offset, double spacing, double scale,
- int count, short* out )
-{
- double const maxh = 256;
- double const step = PI / maxh * spacing;
- double const to_w = maxh * 2 / width;
- double const pow_a_n = pow( rolloff, maxh );
- scale /= maxh * 2;
-
- double angle = (count / 2 - 1 + offset) * -step;
- while ( count-- )
- {
- *out++ = 0;
- double w = angle * to_w;
- if ( fabs( w ) < PI )
- {
- double rolloff_cos_a = rolloff * cos( angle );
- double num = 1 - rolloff_cos_a -
- pow_a_n * cos( maxh * angle ) +
- pow_a_n * rolloff * cos( (maxh - 1) * angle );
- double den = 1 - rolloff_cos_a - rolloff_cos_a + rolloff * rolloff;
- double sinc = scale * num / den - scale;
-
- out [-1] = (short) (cos( w ) * sinc + sinc);
- }
- angle += step;
- }
-}
-
-Fir_Resampler_::Fir_Resampler_( int width, sample_t* impulses_ ) :
- width_( width ),
- write_offset( width * stereo - stereo ),
- impulses( impulses_ )
-{
- write_pos = 0;
- res = 1;
- imp_phase = 0;
- skip_bits = 0;
- step = stereo;
- ratio_ = 1.0;
-}
-
-Fir_Resampler_::~Fir_Resampler_() { }
-
-void Fir_Resampler_::clear()
-{
- imp_phase = 0;
- if ( buf.size() )
- {
- write_pos = &buf [write_offset];
- memset( buf.begin(), 0, write_offset * sizeof buf [0] );
- }
-}
-
-blargg_err_t Fir_Resampler_::buffer_size( int new_size )
-{
- RETURN_ERR( buf.resize( new_size + write_offset ) );
- clear();
- return 0;
-}
-
-double Fir_Resampler_::time_ratio( double new_factor, double rolloff, double gain )
-{
- ratio_ = new_factor;
-
- double fstep = 0.0;
- {
- double least_error = 2;
- double pos = 0;
- res = -1;
- for ( int r = 1; r <= max_res; r++ )
- {
- pos += ratio_;
- double nearest = floor( pos + 0.5 );
- double error = fabs( pos - nearest );
- if ( error < least_error )
- {
- res = r;
- fstep = nearest / res;
- least_error = error;
- }
- }
- }
-
- skip_bits = 0;
-
- step = stereo * (int) floor( fstep );
-
- ratio_ = fstep;
- fstep = fmod( fstep, 1.0 );
-
- double filter = (ratio_ < 1.0) ? 1.0 : 1.0 / ratio_;
- double pos = 0.0;
- input_per_cycle = 0;
- for ( int i = 0; i < res; i++ )
- {
- gen_sinc( rolloff, int (width_ * filter + 1) & ~1, pos, filter,
- double (0x7FFF * gain * filter),
- (int) width_, impulses + i * width_ );
-
- pos += fstep;
- input_per_cycle += step;
- if ( pos >= 0.9999999 )
- {
- pos -= 1.0;
- skip_bits |= 1 << i;
- input_per_cycle++;
- }
- }
-
- clear();
-
- return ratio_;
-}
-
-int Fir_Resampler_::input_needed( blargg_long output_count ) const
-{
- blargg_long input_count = 0;
-
- unsigned long skip = skip_bits >> imp_phase;
- int remain = res - imp_phase;
- while ( (output_count -= 2) > 0 )
- {
- input_count += step + (skip & 1) * stereo;
- skip >>= 1;
- if ( !--remain )
- {
- skip = skip_bits;
- remain = res;
- }
- output_count -= 2;
- }
-
- long input_extra = input_count - (write_pos - &buf [(width_ - 1) * stereo]);
- if ( input_extra < 0 )
- input_extra = 0;
- return input_extra;
-}
-
-int Fir_Resampler_::avail_( blargg_long input_count ) const
-{
- int cycle_count = input_count / input_per_cycle;
- int output_count = cycle_count * res * stereo;
- input_count -= cycle_count * input_per_cycle;
-
- blargg_ulong skip = skip_bits >> imp_phase;
- int remain = res - imp_phase;
- while ( input_count >= 0 )
- {
- input_count -= step + (skip & 1) * stereo;
- skip >>= 1;
- if ( !--remain )
- {
- skip = skip_bits;
- remain = res;
- }
- output_count += 2;
- }
- return output_count;
-}
-
-int Fir_Resampler_::skip_input( long count )
-{
- int remain = write_pos - buf.begin();
- int max_count = remain - width_ * stereo;
- if ( count > max_count )
- count = max_count;
-
- remain -= count;
- write_pos = &buf [remain];
- memmove( buf.begin(), &buf [count], remain * sizeof buf [0] );
-
- return count;
-}
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Fir_Resampler.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/Fir_Resampler.h
deleted file mode 100644
index 339dfce3..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Fir_Resampler.h
+++ /dev/null
@@ -1,171 +0,0 @@
-// Finite impulse response (FIR) resampler with adjustable FIR size
-
-// Game_Music_Emu 0.5.2
-#ifndef FIR_RESAMPLER_H
-#define FIR_RESAMPLER_H
-
-#include "blargg_common.h"
-#include <string.h>
-
-class Fir_Resampler_ {
-public:
-
- // Use Fir_Resampler<width> (below)
-
- // Set input/output resampling ratio and optionally low-pass rolloff and gain.
- // Returns actual ratio used (rounded to internal precision).
- double time_ratio( double factor, double rolloff = 0.999, double gain = 1.0 );
-
- // Current input/output ratio
- double ratio() const { return ratio_; }
-
-// Input
-
- typedef short sample_t;
-
- // Resize and clear input buffer
- blargg_err_t buffer_size( int );
-
- // Clear input buffer. At least two output samples will be available after
- // two input samples are written.
- void clear();
-
- // Number of input samples that can be written
- int max_write() const { return buf.end() - write_pos; }
-
- // Pointer to place to write input samples
- sample_t* buffer() { return write_pos; }
-
- // Notify resampler that 'count' input samples have been written
- void write( long count );
-
- // Number of input samples in buffer
- int written() const { return write_pos - &buf [write_offset]; }
-
- // Skip 'count' input samples. Returns number of samples actually skipped.
- int skip_input( long count );
-
-// Output
-
- // Number of extra input samples needed until 'count' output samples are available
- int input_needed( blargg_long count ) const;
-
- // Number of output samples available
- int avail() const { return avail_( write_pos - &buf [width_ * stereo] ); }
-
-public:
- ~Fir_Resampler_();
-protected:
- enum { stereo = 2 };
- enum { max_res = 32 };
- blargg_vector<sample_t> buf;
- sample_t* write_pos;
- int res;
- int imp_phase;
- int const width_;
- int const write_offset;
- blargg_ulong skip_bits;
- int step;
- int input_per_cycle;
- double ratio_;
- sample_t* impulses;
-
- Fir_Resampler_( int width, sample_t* );
- int avail_( blargg_long input_count ) const;
-};
-
-// Width is number of points in FIR. Must be even and 4 or more. More points give
-// better quality and rolloff effectiveness, and take longer to calculate.
-template<int width>
-class Fir_Resampler : public Fir_Resampler_ {
- BOOST_STATIC_ASSERT( width >= 4 && width % 2 == 0 );
- short impulses [max_res] [width];
-public:
- Fir_Resampler() : Fir_Resampler_( width, impulses [0] ) { }
-
- // Read at most 'count' samples. Returns number of samples actually read.
- typedef short sample_t;
- int read( sample_t* out, blargg_long count );
-};
-
-// End of public interface
-
-inline void Fir_Resampler_::write( long count )
-{
- write_pos += count;
- assert( write_pos <= buf.end() );
-}
-
-template<int width>
-int Fir_Resampler<width>::read( sample_t* out_begin, blargg_long count )
-{
- sample_t* out = out_begin;
- const sample_t* in = buf.begin();
- sample_t* end_pos = write_pos;
- blargg_ulong skip = skip_bits >> imp_phase;
- sample_t const* imp = impulses [imp_phase];
- int remain = res - imp_phase;
- int const step = this->step;
-
- count >>= 1;
-
- if ( end_pos - in >= width * stereo )
- {
- end_pos -= width * stereo;
- do
- {
- count--;
-
- // accumulate in extended precision
- blargg_long l = 0;
- blargg_long r = 0;
-
- const sample_t* i = in;
- if ( count < 0 )
- break;
-
- for ( int n = width / 2; n; --n )
- {
- int pt0 = imp [0];
- l += pt0 * i [0];
- r += pt0 * i [1];
- int pt1 = imp [1];
- imp += 2;
- l += pt1 * i [2];
- r += pt1 * i [3];
- i += 4;
- }
-
- remain--;
-
- l >>= 15;
- r >>= 15;
-
- in += (skip * stereo) & stereo;
- skip >>= 1;
- in += step;
-
- if ( !remain )
- {
- imp = impulses [0];
- skip = skip_bits;
- remain = res;
- }
-
- out [0] = (sample_t) l;
- out [1] = (sample_t) r;
- out += 2;
- }
- while ( in <= end_pos );
- }
-
- imp_phase = res - remain;
-
- int left = write_pos - in;
- write_pos = &buf [left];
- memmove( buf.begin(), in, left * sizeof *in );
-
- return out - out_begin;
-}
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Gb_Apu.cpp b/plugins/gme/Game_Music_Emu-0.5.2/gme/Gb_Apu.cpp
deleted file mode 100644
index 932ebb83..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Gb_Apu.cpp
+++ /dev/null
@@ -1,306 +0,0 @@
-// Gb_Snd_Emu 0.1.5. http://www.slack.net/~ant/
-
-#include "Gb_Apu.h"
-
-#include <string.h>
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-unsigned const vol_reg = 0xFF24;
-unsigned const status_reg = 0xFF26;
-
-Gb_Apu::Gb_Apu()
-{
- square1.synth = &square_synth;
- square2.synth = &square_synth;
- wave.synth = &other_synth;
- noise.synth = &other_synth;
-
- oscs [0] = &square1;
- oscs [1] = &square2;
- oscs [2] = &wave;
- oscs [3] = &noise;
-
- for ( int i = 0; i < osc_count; i++ )
- {
- Gb_Osc& osc = *oscs [i];
- osc.regs = &regs [i * 5];
- osc.output = 0;
- osc.outputs [0] = 0;
- osc.outputs [1] = 0;
- osc.outputs [2] = 0;
- osc.outputs [3] = 0;
- }
-
- set_tempo( 1.0 );
- volume( 1.0 );
- reset();
-}
-
-void Gb_Apu::treble_eq( const blip_eq_t& eq )
-{
- square_synth.treble_eq( eq );
- other_synth.treble_eq( eq );
-}
-
-void Gb_Apu::osc_output( int index, Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right )
-{
- require( (unsigned) index < osc_count );
- require( (center && left && right) || (!center && !left && !right) );
- Gb_Osc& osc = *oscs [index];
- osc.outputs [1] = right;
- osc.outputs [2] = left;
- osc.outputs [3] = center;
- osc.output = osc.outputs [osc.output_select];
-}
-
-void Gb_Apu::output( Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right )
-{
- for ( int i = 0; i < osc_count; i++ )
- osc_output( i, center, left, right );
-}
-
-void Gb_Apu::update_volume()
-{
- // TODO: doesn't handle differing left/right global volume (support would
- // require modification to all oscillator code)
- int data = regs [vol_reg - start_addr];
- double vol = (max( data & 7, data >> 4 & 7 ) + 1) * volume_unit;
- square_synth.volume( vol );
- other_synth.volume( vol );
-}
-
-static unsigned char const powerup_regs [0x20] = {
- 0x80,0x3F,0x00,0xFF,0xBF, // square 1
- 0xFF,0x3F,0x00,0xFF,0xBF, // square 2
- 0x7F,0xFF,0x9F,0xFF,0xBF, // wave
- 0xFF,0xFF,0x00,0x00,0xBF, // noise
- 0x00, // left/right enables
- 0x77, // master volume
- 0x80, // power
- 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
-};
-
-void Gb_Apu::set_tempo( double t )
-{
- frame_period = 4194304 / 256; // 256 Hz
- if ( t != 1.0 )
- frame_period = blip_time_t (frame_period / t);
-}
-
-void Gb_Apu::reset()
-{
- next_frame_time = 0;
- last_time = 0;
- frame_count = 0;
-
- square1.reset();
- square2.reset();
- wave.reset();
- noise.reset();
- noise.bits = 1;
- wave.wave_pos = 0;
-
- // avoid click at beginning
- regs [vol_reg - start_addr] = 0x77;
- update_volume();
-
- regs [status_reg - start_addr] = 0x01; // force power
- write_register( 0, status_reg, 0x00 );
-
- static unsigned char const initial_wave [] = {
- 0x84,0x40,0x43,0xAA,0x2D,0x78,0x92,0x3C, // wave table
- 0x60,0x59,0x59,0xB0,0x34,0xB8,0x2E,0xDA
- };
- memcpy( wave.wave, initial_wave, sizeof wave.wave );
-}
-
-void Gb_Apu::run_until( blip_time_t end_time )
-{
- require( end_time >= last_time ); // end_time must not be before previous time
- if ( end_time == last_time )
- return;
-
- while ( true )
- {
- blip_time_t time = next_frame_time;
- if ( time > end_time )
- time = end_time;
-
- // run oscillators
- for ( int i = 0; i < osc_count; ++i )
- {
- Gb_Osc& osc = *oscs [i];
- if ( osc.output )
- {
- osc.output->set_modified(); // TODO: misses optimization opportunities?
- int playing = false;
- if ( osc.enabled && osc.volume &&
- (!(osc.regs [4] & osc.len_enabled_mask) || osc.length) )
- playing = -1;
- switch ( i )
- {
- case 0: square1.run( last_time, time, playing ); break;
- case 1: square2.run( last_time, time, playing ); break;
- case 2: wave .run( last_time, time, playing ); break;
- case 3: noise .run( last_time, time, playing ); break;
- }
- }
- }
- last_time = time;
-
- if ( time == end_time )
- break;
-
- next_frame_time += frame_period;
-
- // 256 Hz actions
- square1.clock_length();
- square2.clock_length();
- wave.clock_length();
- noise.clock_length();
-
- frame_count = (frame_count + 1) & 3;
- if ( frame_count == 0 )
- {
- // 64 Hz actions
- square1.clock_envelope();
- square2.clock_envelope();
- noise.clock_envelope();
- }
-
- if ( frame_count & 1 )
- square1.clock_sweep(); // 128 Hz action
- }
-}
-
-void Gb_Apu::end_frame( blip_time_t end_time )
-{
- if ( end_time > last_time )
- run_until( end_time );
-
- assert( next_frame_time >= end_time );
- next_frame_time -= end_time;
-
- assert( last_time >= end_time );
- last_time -= end_time;
-}
-
-void Gb_Apu::write_register( blip_time_t time, unsigned addr, int data )
-{
- require( (unsigned) data < 0x100 );
-
- int reg = addr - start_addr;
- if ( (unsigned) reg >= register_count )
- return;
-
- run_until( time );
-
- int old_reg = regs [reg];
- regs [reg] = data;
-
- if ( addr < vol_reg )
- {
- write_osc( reg / 5, reg, data );
- }
- else if ( addr == vol_reg && data != old_reg ) // global volume
- {
- // return all oscs to 0
- for ( int i = 0; i < osc_count; i++ )
- {
- Gb_Osc& osc = *oscs [i];
- int amp = osc.last_amp;
- osc.last_amp = 0;
- if ( amp && osc.enabled && osc.output )
- other_synth.offset( time, -amp, osc.output );
- }
-
- if ( wave.outputs [3] )
- other_synth.offset( time, 30, wave.outputs [3] );
-
- update_volume();
-
- if ( wave.outputs [3] )
- other_synth.offset( time, -30, wave.outputs [3] );
-
- // oscs will update with new amplitude when next run
- }
- else if ( addr == 0xFF25 || addr == status_reg )
- {
- int mask = (regs [status_reg - start_addr] & 0x80) ? ~0 : 0;
- int flags = regs [0xFF25 - start_addr] & mask;
-
- // left/right assignments
- for ( int i = 0; i < osc_count; i++ )
- {
- Gb_Osc& osc = *oscs [i];
- osc.enabled &= mask;
- int bits = flags >> i;
- Blip_Buffer* old_output = osc.output;
- osc.output_select = (bits >> 3 & 2) | (bits & 1);
- osc.output = osc.outputs [osc.output_select];
- if ( osc.output != old_output )
- {
- int amp = osc.last_amp;
- osc.last_amp = 0;
- if ( amp && old_output )
- other_synth.offset( time, -amp, old_output );
- }
- }
-
- if ( addr == status_reg && data != old_reg )
- {
- if ( !(data & 0x80) )
- {
- for ( unsigned i = 0; i < sizeof powerup_regs; i++ )
- {
- if ( i != status_reg - start_addr )
- write_register( time, i + start_addr, powerup_regs [i] );
- }
- }
- else
- {
- //dprintf( "APU powered on\n" );
- }
- }
- }
- else if ( addr >= 0xFF30 )
- {
- int index = (addr & 0x0F) * 2;
- wave.wave [index] = data >> 4;
- wave.wave [index + 1] = data & 0x0F;
- }
-}
-
-int Gb_Apu::read_register( blip_time_t time, unsigned addr )
-{
- run_until( time );
-
- int index = addr - start_addr;
- require( (unsigned) index < register_count );
- int data = regs [index];
-
- if ( addr == status_reg )
- {
- data = (data & 0x80) | 0x70;
- for ( int i = 0; i < osc_count; i++ )
- {
- const Gb_Osc& osc = *oscs [i];
- if ( osc.enabled && (osc.length || !(osc.regs [4] & osc.len_enabled_mask)) )
- data |= 1 << i;
- }
- }
-
- return data;
-}
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Gb_Apu.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/Gb_Apu.h
deleted file mode 100644
index e74ebc55..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Gb_Apu.h
+++ /dev/null
@@ -1,90 +0,0 @@
-// Nintendo Game Boy PAPU sound chip emulator
-
-// Gb_Snd_Emu 0.1.5
-#ifndef GB_APU_H
-#define GB_APU_H
-
-#include "Gb_Oscs.h"
-
-class Gb_Apu {
-public:
-
- // Set overall volume of all oscillators, where 1.0 is full volume
- void volume( double );
-
- // Set treble equalization
- void treble_eq( const blip_eq_t& );
-
- // Outputs can be assigned to a single buffer for mono output, or to three
- // buffers for stereo output (using Stereo_Buffer to do the mixing).
-
- // Assign all oscillator outputs to specified buffer(s). If buffer
- // is NULL, silences all oscillators.
- void output( Blip_Buffer* mono );
- void output( Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right );
-
- // Assign single oscillator output to buffer(s). Valid indicies are 0 to 3,
- // which refer to Square 1, Square 2, Wave, and Noise. If buffer is NULL,
- // silences oscillator.
- enum { osc_count = 4 };
- void osc_output( int index, Blip_Buffer* mono );
- void osc_output( int index, Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right );
-
- // Reset oscillators and internal state
- void reset();
-
- // Reads and writes at addr must satisfy start_addr <= addr <= end_addr
- enum { start_addr = 0xFF10 };
- enum { end_addr = 0xFF3F };
- enum { register_count = end_addr - start_addr + 1 };
-
- // Write 'data' to address at specified time
- void write_register( blip_time_t, unsigned addr, int data );
-
- // Read from address at specified time
- int read_register( blip_time_t, unsigned addr );
-
- // Run all oscillators up to specified time, end current time frame, then
- // start a new frame at time 0.
- void end_frame( blip_time_t );
-
- void set_tempo( double );
-
-public:
- Gb_Apu();
-private:
- // noncopyable
- Gb_Apu( const Gb_Apu& );
- Gb_Apu& operator = ( const Gb_Apu& );
-
- Gb_Osc* oscs [osc_count];
- blip_time_t next_frame_time;
- blip_time_t last_time;
- blip_time_t frame_period;
- double volume_unit;
- int frame_count;
-
- Gb_Square square1;
- Gb_Square square2;
- Gb_Wave wave;
- Gb_Noise noise;
- BOOST::uint8_t regs [register_count];
- Gb_Square::Synth square_synth; // used by squares
- Gb_Wave::Synth other_synth; // used by wave and noise
-
- void update_volume();
- void run_until( blip_time_t );
- void write_osc( int index, int reg, int data );
-};
-
-inline void Gb_Apu::output( Blip_Buffer* b ) { output( b, b, b ); }
-
-inline void Gb_Apu::osc_output( int i, Blip_Buffer* b ) { osc_output( i, b, b, b ); }
-
-inline void Gb_Apu::volume( double vol )
-{
- volume_unit = 0.60 / osc_count / 15 /*steps*/ / 2 /*?*/ / 8 /*master vol range*/ * vol;
- update_volume();
-}
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Gb_Cpu.cpp b/plugins/gme/Game_Music_Emu-0.5.2/gme/Gb_Cpu.cpp
deleted file mode 100644
index b1f22bd9..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Gb_Cpu.cpp
+++ /dev/null
@@ -1,1056 +0,0 @@
-// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
-
-#include "Gb_Cpu.h"
-
-#include <string.h>
-
-//#include "gb_cpu_log.h"
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "gb_cpu_io.h"
-
-#include "blargg_source.h"
-
-// Common instructions:
-//
-// 365880 FA LD A,IND16
-// 355863 20 JR NZ
-// 313655 21 LD HL,IMM
-// 274580 28 JR Z
-// 252878 FE CMP IMM
-// 230541 7E LD A,(HL)
-// 226209 2A LD A,(HL+)
-// 217467 CD CALL
-// 212034 C9 RET
-// 208376 CB CB prefix
-//
-// 27486 CB 7E BIT 7,(HL)
-// 15925 CB 76 BIT 6,(HL)
-// 13035 CB 19 RR C
-// 11557 CB 7F BIT 7,A
-// 10898 CB 37 SWAP A
-// 10208 CB 66 BIT 4,(HL)
-
-#if BLARGG_NONPORTABLE
- #define PAGE_OFFSET( addr ) (addr)
-#else
- #define PAGE_OFFSET( addr ) ((addr) & (page_size - 1))
-#endif
-
-inline void Gb_Cpu::set_code_page( int i, uint8_t* p )
-{
- state->code_map [i] = p - PAGE_OFFSET( i * (blargg_long) page_size );
-}
-
-void Gb_Cpu::reset( void* unmapped )
-{
- check( state == &state_ );
- state = &state_;
-
- state_.remain = 0;
-
- for ( int i = 0; i < page_count + 1; i++ )
- set_code_page( i, (uint8_t*) unmapped );
-
- memset( &r, 0, sizeof r );
- //interrupts_enabled = false;
-
- blargg_verify_byte_order();
-}
-
-void Gb_Cpu::map_code( gb_addr_t start, unsigned size, void* data )
-{
- // address range must begin and end on page boundaries
- require( start % page_size == 0 );
- require( size % page_size == 0 );
-
- unsigned first_page = start / page_size;
- for ( unsigned i = size / page_size; i--; )
- set_code_page( first_page + i, (uint8_t*) data + i * page_size );
-}
-
-#define READ( addr ) CPU_READ( this, (addr), s.remain )
-#define WRITE( addr, data ) {CPU_WRITE( this, (addr), (data), s.remain );}
-#define READ_FAST( addr, out ) CPU_READ_FAST( this, (addr), s.remain, out )
-#define READ_PROG( addr ) (s.code_map [(addr) >> page_shift] [PAGE_OFFSET( addr )])
-
-unsigned const z_flag = 0x80;
-unsigned const n_flag = 0x40;
-unsigned const h_flag = 0x20;
-unsigned const c_flag = 0x10;
-
-bool Gb_Cpu::run( blargg_long cycle_count )
-{
- state_.remain = blargg_ulong (cycle_count + clocks_per_instr) / clocks_per_instr;
- state_t s;
- this->state = &s;
- memcpy( &s, &this->state_, sizeof s );
-
- typedef BOOST::uint16_t uint16_t;
-
-#if BLARGG_BIG_ENDIAN
- #define R8( n ) (r8_ [n])
-#elif BLARGG_LITTLE_ENDIAN
- #define R8( n ) (r8_ [(n) ^ 1])
-#else
- #error "Byte order of CPU must be known"
-#endif
-
- union {
- core_regs_t rg; // individual registers
-
- struct {
- BOOST::uint16_t bc, de, hl, unused; // pairs
- } rp;
-
- uint8_t r8_ [8]; // indexed registers (use R8 macro due to endian dependence)
- BOOST::uint16_t r16 [4]; // indexed pairs
- };
- BOOST_STATIC_ASSERT( sizeof rg == 8 && sizeof rp == 8 );
-
- rg = r;
- unsigned pc = r.pc;
- unsigned sp = r.sp;
- unsigned flags = r.flags;
-
-loop:
-
- check( (unsigned long) pc < 0x10000 );
- check( (unsigned long) sp < 0x10000 );
- check( (flags & ~0xF0) == 0 );
-
- uint8_t const* instr = s.code_map [pc >> page_shift];
- unsigned op;
-
- // TODO: eliminate this special case
- #if BLARGG_NONPORTABLE
- op = instr [pc];
- pc++;
- instr += pc;
- #else
- instr += PAGE_OFFSET( pc );
- op = *instr++;
- pc++;
- #endif
-
-#define GET_ADDR() GET_LE16( instr )
-
- if ( !--s.remain )
- goto stop;
-
- unsigned data;
- data = *instr;
-
- #ifdef GB_CPU_LOG_H
- gb_cpu_log( "new", pc - 1, op, data, instr [1] );
- #endif
-
- switch ( op )
- {
-
-// TODO: more efficient way to handle negative branch that wraps PC around
-#define BRANCH( cond )\
-{\
- pc++;\
- int offset = (BOOST::int8_t) data;\
- if ( !(cond) ) goto loop;\
- pc = uint16_t (pc + offset);\
- goto loop;\
-}
-
-// Most Common
-
- case 0x20: // JR NZ
- BRANCH( !(flags & z_flag) )
-
- case 0x21: // LD HL,IMM (common)
- rp.hl = GET_ADDR();
- pc += 2;
- goto loop;
-
- case 0x28: // JR Z
- BRANCH( flags & z_flag )
-
- {
- unsigned temp;
- case 0xF0: // LD A,(0xFF00+imm)
- temp = data | 0xFF00;
- pc++;
- goto ld_a_ind_comm;
-
- case 0xF2: // LD A,(0xFF00+C)
- temp = rg.c | 0xFF00;
- goto ld_a_ind_comm;
-
- case 0x0A: // LD A,(BC)
- temp = rp.bc;
- goto ld_a_ind_comm;
-
- case 0x3A: // LD A,(HL-)
- temp = rp.hl;
- rp.hl = temp - 1;
- goto ld_a_ind_comm;
-
- case 0x1A: // LD A,(DE)
- temp = rp.de;
- goto ld_a_ind_comm;
-
- case 0x2A: // LD A,(HL+) (common)
- temp = rp.hl;
- rp.hl = temp + 1;
- goto ld_a_ind_comm;
-
- case 0xFA: // LD A,IND16 (common)
- temp = GET_ADDR();
- pc += 2;
- ld_a_ind_comm:
- READ_FAST( temp, rg.a );
- goto loop;
- }
-
- case 0xBE: // CMP (HL)
- data = READ( rp.hl );
- goto cmp_comm;
-
- case 0xB8: // CMP B
- case 0xB9: // CMP C
- case 0xBA: // CMP D
- case 0xBB: // CMP E
- case 0xBC: // CMP H
- case 0xBD: // CMP L
- data = R8( op & 7 );
- goto cmp_comm;
-
- case 0xFE: // CMP IMM
- pc++;
- cmp_comm:
- op = rg.a;
- data = op - data;
- sub_set_flags:
- flags = ((op & 15) - (data & 15)) & h_flag;
- flags |= (data >> 4) & c_flag;
- flags |= n_flag;
- if ( data & 0xFF )
- goto loop;
- flags |= z_flag;
- goto loop;
-
- case 0x46: // LD B,(HL)
- case 0x4E: // LD C,(HL)
- case 0x56: // LD D,(HL)
- case 0x5E: // LD E,(HL)
- case 0x66: // LD H,(HL)
- case 0x6E: // LD L,(HL)
- case 0x7E:{// LD A,(HL)
- unsigned addr = rp.hl;
- READ_FAST( addr, R8( (op >> 3) & 7 ) );
- goto loop;
- }
-
- case 0xC4: // CNZ (next-most-common)
- pc += 2;
- if ( flags & z_flag )
- goto loop;
- call:
- pc -= 2;
- case 0xCD: // CALL (most-common)
- data = pc + 2;
- pc = GET_ADDR();
- push:
- sp = (sp - 1) & 0xFFFF;
- WRITE( sp, data >> 8 );
- sp = (sp - 1) & 0xFFFF;
- WRITE( sp, data & 0xFF );
- goto loop;
-
- case 0xC8: // RNZ (next-most-common)
- if ( !(flags & z_flag) )
- goto loop;
- case 0xC9: // RET (most common)
- ret:
- pc = READ( sp );
- pc += 0x100 * READ( sp + 1 );
- sp = (sp + 2) & 0xFFFF;
- goto loop;
-
- case 0x00: // NOP
- case 0x40: // LD B,B
- case 0x49: // LD C,C
- case 0x52: // LD D,D
- case 0x5B: // LD E,E
- case 0x64: // LD H,H
- case 0x6D: // LD L,L
- case 0x7F: // LD A,A
- goto loop;
-
-// CB Instructions
-
- case 0xCB:
- pc++;
- // now data is the opcode
- switch ( data ) {
-
- {
- int temp;
- case 0x46: // BIT b,(HL)
- case 0x4E:
- case 0x56:
- case 0x5E:
- case 0x66:
- case 0x6E:
- case 0x76:
- case 0x7E:
- {
- unsigned addr = rp.hl;
- READ_FAST( addr, temp );
- goto bit_comm;
- }
-
- case 0x40: case 0x41: case 0x42: case 0x43: // BIT b,r
- case 0x44: case 0x45: case 0x47: case 0x48:
- case 0x49: case 0x4A: case 0x4B: case 0x4C:
- case 0x4D: case 0x4F: case 0x50: case 0x51:
- case 0x52: case 0x53: case 0x54: case 0x55:
- case 0x57: case 0x58: case 0x59: case 0x5A:
- case 0x5B: case 0x5C: case 0x5D: case 0x5F:
- case 0x60: case 0x61: case 0x62: case 0x63:
- case 0x64: case 0x65: case 0x67: case 0x68:
- case 0x69: case 0x6A: case 0x6B: case 0x6C:
- case 0x6D: case 0x6F: case 0x70: case 0x71:
- case 0x72: case 0x73: case 0x74: case 0x75:
- case 0x77: case 0x78: case 0x79: case 0x7A:
- case 0x7B: case 0x7C: case 0x7D: case 0x7F:
- temp = R8( data & 7 );
- bit_comm:
- int bit = (~data >> 3) & 7;
- flags &= ~n_flag;
- flags |= h_flag | z_flag;
- flags ^= (temp << bit) & z_flag;
- goto loop;
- }
-
- case 0x86: // RES b,(HL)
- case 0x8E:
- case 0x96:
- case 0x9E:
- case 0xA6:
- case 0xAE:
- case 0xB6:
- case 0xBE:
- case 0xC6: // SET b,(HL)
- case 0xCE:
- case 0xD6:
- case 0xDE:
- case 0xE6:
- case 0xEE:
- case 0xF6:
- case 0xFE: {
- int temp = READ( rp.hl );
- int bit = 1 << ((data >> 3) & 7);
- temp &= ~bit;
- if ( !(data & 0x40) )
- bit = 0;
- WRITE( rp.hl, temp | bit );
- goto loop;
- }
-
- case 0xC0: case 0xC1: case 0xC2: case 0xC3: // SET b,r
- case 0xC4: case 0xC5: case 0xC7: case 0xC8:
- case 0xC9: case 0xCA: case 0xCB: case 0xCC:
- case 0xCD: case 0xCF: case 0xD0: case 0xD1:
- case 0xD2: case 0xD3: case 0xD4: case 0xD5:
- case 0xD7: case 0xD8: case 0xD9: case 0xDA:
- case 0xDB: case 0xDC: case 0xDD: case 0xDF:
- case 0xE0: case 0xE1: case 0xE2: case 0xE3:
- case 0xE4: case 0xE5: case 0xE7: case 0xE8:
- case 0xE9: case 0xEA: case 0xEB: case 0xEC:
- case 0xED: case 0xEF: case 0xF0: case 0xF1:
- case 0xF2: case 0xF3: case 0xF4: case 0xF5:
- case 0xF7: case 0xF8: case 0xF9: case 0xFA:
- case 0xFB: case 0xFC: case 0xFD: case 0xFF:
- R8( data & 7 ) |= 1 << ((data >> 3) & 7);
- goto loop;
-
- case 0x80: case 0x81: case 0x82: case 0x83: // RES b,r
- case 0x84: case 0x85: case 0x87: case 0x88:
- case 0x89: case 0x8A: case 0x8B: case 0x8C:
- case 0x8D: case 0x8F: case 0x90: case 0x91:
- case 0x92: case 0x93: case 0x94: case 0x95:
- case 0x97: case 0x98: case 0x99: case 0x9A:
- case 0x9B: case 0x9C: case 0x9D: case 0x9F:
- case 0xA0: case 0xA1: case 0xA2: case 0xA3:
- case 0xA4: case 0xA5: case 0xA7: case 0xA8:
- case 0xA9: case 0xAA: case 0xAB: case 0xAC:
- case 0xAD: case 0xAF: case 0xB0: case 0xB1:
- case 0xB2: case 0xB3: case 0xB4: case 0xB5:
- case 0xB7: case 0xB8: case 0xB9: case 0xBA:
- case 0xBB: case 0xBC: case 0xBD: case 0xBF:
- R8( data & 7 ) &= ~(1 << ((data >> 3) & 7));
- goto loop;
-
- {
- int temp;
- case 0x36: // SWAP (HL)
- temp = READ( rp.hl );
- goto swap_comm;
-
- case 0x30: // SWAP B
- case 0x31: // SWAP C
- case 0x32: // SWAP D
- case 0x33: // SWAP E
- case 0x34: // SWAP H
- case 0x35: // SWAP L
- case 0x37: // SWAP A
- temp = R8( data & 7 );
- swap_comm:
- op = (temp >> 4) | (temp << 4);
- flags = 0;
- goto shift_comm;
- }
-
-// Shift/Rotate
-
- case 0x06: // RLC (HL)
- case 0x16: // RL (HL)
- case 0x26: // SLA (HL)
- op = READ( rp.hl );
- goto rl_comm;
-
- case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x27: // SLA A
- case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x07: // RLC A
- case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x17: // RL A
- op = R8( data & 7 );
- goto rl_comm;
-
- case 0x3E: // SRL (HL)
- data += 0x10; // bump up to 0x4n to avoid preserving sign bit
- case 0x1E: // RR (HL)
- case 0x0E: // RRC (HL)
- case 0x2E: // SRA (HL)
- op = READ( rp.hl );
- goto rr_comm;
-
- case 0x38: case 0x39: case 0x3A: case 0x3B: case 0x3C: case 0x3D: case 0x3F: // SRL A
- data += 0x10; // bump up to 0x4n
- case 0x18: case 0x19: case 0x1A: case 0x1B: case 0x1C: case 0x1D: case 0x1F: // RR A
- case 0x08: case 0x09: case 0x0A: case 0x0B: case 0x0C: case 0x0D: case 0x0F: // RRC A
- case 0x28: case 0x29: case 0x2A: case 0x2B: case 0x2C: case 0x2D: case 0x2F: // SRA A
- op = R8( data & 7 );
- goto rr_comm;
-
- } // CB op
- assert( false ); // unhandled CB op
-
- case 0x07: // RLCA
- case 0x17: // RLA
- data = op;
- op = rg.a;
- rl_comm:
- op <<= 1;
- op |= ((data & flags) >> 4) & 1; // RL and carry is set
- flags = (op >> 4) & c_flag; // C = bit shifted out
- if ( data < 0x10 ) // RLC
- op |= op >> 8;
- // SLA doesn't fill lower bit
- goto shift_comm;
-
- case 0x0F: // RRCA
- case 0x1F: // RRA
- data = op;
- op = rg.a;
- rr_comm:
- op |= (data & flags) << 4; // RR and carry is set
- flags = (op << 4) & c_flag; // C = bit shifted out
- if ( data < 0x10 ) // RRC
- op |= op << 8;
- op >>= 1;
- if ( data & 0x20 ) // SRA propagates sign bit
- op |= (op << 1) & 0x80;
- shift_comm:
- data &= 7;
- if ( !(op & 0xFF) )
- flags |= z_flag;
- if ( data == 6 )
- goto write_hl_op_ff;
- R8( data ) = op;
- goto loop;
-
-// Load
-
- case 0x70: // LD (HL),B
- case 0x71: // LD (HL),C
- case 0x72: // LD (HL),D
- case 0x73: // LD (HL),E
- case 0x74: // LD (HL),H
- case 0x75: // LD (HL),L
- case 0x77: // LD (HL),A
- op = R8( op & 7 );
- write_hl_op_ff:
- WRITE( rp.hl, op & 0xFF );
- goto loop;
-
- case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x47: // LD r,r
- case 0x48: case 0x4A: case 0x4B: case 0x4C: case 0x4D: case 0x4F:
- case 0x50: case 0x51: case 0x53: case 0x54: case 0x55: case 0x57:
- case 0x58: case 0x59: case 0x5A: case 0x5C: case 0x5D: case 0x5F:
- case 0x60: case 0x61: case 0x62: case 0x63: case 0x65: case 0x67:
- case 0x68: case 0x69: case 0x6A: case 0x6B: case 0x6C: case 0x6F:
- case 0x78: case 0x79: case 0x7A: case 0x7B: case 0x7C: case 0x7D:
- R8( (op >> 3) & 7 ) = R8( op & 7 );
- goto loop;
-
- case 0x08: // LD IND16,SP
- data = GET_ADDR();
- pc += 2;
- WRITE( data, sp&0xFF );
- data++;
- WRITE( data, sp >> 8 );
- goto loop;
-
- case 0xF9: // LD SP,HL
- sp = rp.hl;
- goto loop;
-
- case 0x31: // LD SP,IMM
- sp = GET_ADDR();
- pc += 2;
- goto loop;
-
- case 0x01: // LD BC,IMM
- case 0x11: // LD DE,IMM
- r16 [op >> 4] = GET_ADDR();
- pc += 2;
- goto loop;
-
- {
- unsigned temp;
- case 0xE0: // LD (0xFF00+imm),A
- temp = data | 0xFF00;
- pc++;
- goto write_data_rg_a;
-
- case 0xE2: // LD (0xFF00+C),A
- temp = rg.c | 0xFF00;
- goto write_data_rg_a;
-
- case 0x32: // LD (HL-),A
- temp = rp.hl;
- rp.hl = temp - 1;
- goto write_data_rg_a;
-
- case 0x02: // LD (BC),A
- temp = rp.bc;
- goto write_data_rg_a;
-
- case 0x12: // LD (DE),A
- temp = rp.de;
- goto write_data_rg_a;
-
- case 0x22: // LD (HL+),A
- temp = rp.hl;
- rp.hl = temp + 1;
- goto write_data_rg_a;
-
- case 0xEA: // LD IND16,A (common)
- temp = GET_ADDR();
- pc += 2;
- write_data_rg_a:
- WRITE( temp, rg.a );
- goto loop;
- }
-
- case 0x06: // LD B,IMM
- rg.b = data;
- pc++;
- goto loop;
-
- case 0x0E: // LD C,IMM
- rg.c = data;
- pc++;
- goto loop;
-
- case 0x16: // LD D,IMM
- rg.d = data;
- pc++;
- goto loop;
-
- case 0x1E: // LD E,IMM
- rg.e = data;
- pc++;
- goto loop;
-
- case 0x26: // LD H,IMM
- rg.h = data;
- pc++;
- goto loop;
-
- case 0x2E: // LD L,IMM
- rg.l = data;
- pc++;
- goto loop;
-
- case 0x36: // LD (HL),IMM
- WRITE( rp.hl, data );
- pc++;
- goto loop;
-
- case 0x3E: // LD A,IMM
- rg.a = data;
- pc++;
- goto loop;
-
-// Increment/Decrement
-
- case 0x03: // INC BC
- case 0x13: // INC DE
- case 0x23: // INC HL
- r16 [op >> 4]++;
- goto loop;
-
- case 0x33: // INC SP
- sp = (sp + 1) & 0xFFFF;
- goto loop;
-
- case 0x0B: // DEC BC
- case 0x1B: // DEC DE
- case 0x2B: // DEC HL
- r16 [op >> 4]--;
- goto loop;
-
- case 0x3B: // DEC SP
- sp = (sp - 1) & 0xFFFF;
- goto loop;
-
- case 0x34: // INC (HL)
- op = rp.hl;
- data = READ( op );
- data++;
- WRITE( op, data & 0xFF );
- goto inc_comm;
-
- case 0x04: // INC B
- case 0x0C: // INC C (common)
- case 0x14: // INC D
- case 0x1C: // INC E
- case 0x24: // INC H
- case 0x2C: // INC L
- case 0x3C: // INC A
- op = (op >> 3) & 7;
- R8( op ) = data = R8( op ) + 1;
- inc_comm:
- flags = (flags & c_flag) | (((data & 15) - 1) & h_flag) | ((data >> 1) & z_flag);
- goto loop;
-
- case 0x35: // DEC (HL)
- op = rp.hl;
- data = READ( op );
- data--;
- WRITE( op, data & 0xFF );
- goto dec_comm;
-
- case 0x05: // DEC B
- case 0x0D: // DEC C
- case 0x15: // DEC D
- case 0x1D: // DEC E
- case 0x25: // DEC H
- case 0x2D: // DEC L
- case 0x3D: // DEC A
- op = (op >> 3) & 7;
- data = R8( op ) - 1;
- R8( op ) = data;
- dec_comm:
- flags = (flags & c_flag) | n_flag | (((data & 15) + 0x31) & h_flag);
- if ( data & 0xFF )
- goto loop;
- flags |= z_flag;
- goto loop;
-
-// Add 16-bit
-
- {
- blargg_ulong temp; // need more than 16 bits for carry
- unsigned prev;
-
- case 0xF8: // LD HL,SP+imm
- temp = BOOST::int8_t (data); // sign-extend to 16 bits
- pc++;
- flags = 0;
- temp += sp;
- prev = sp;
- goto add_16_hl;
-
- case 0xE8: // ADD SP,IMM
- temp = BOOST::int8_t (data); // sign-extend to 16 bits
- pc++;
- flags = 0;
- temp += sp;
- prev = sp;
- sp = temp & 0xFFFF;
- goto add_16_comm;
-
- case 0x39: // ADD HL,SP
- temp = sp;
- goto add_hl_comm;
-
- case 0x09: // ADD HL,BC
- case 0x19: // ADD HL,DE
- case 0x29: // ADD HL,HL
- temp = r16 [op >> 4];
- add_hl_comm:
- prev = rp.hl;
- temp += prev;
- flags &= z_flag;
- add_16_hl:
- rp.hl = temp;
- add_16_comm:
- flags |= (temp >> 12) & c_flag;
- flags |= (((temp & 0x0FFF) - (prev & 0x0FFF)) >> 7) & h_flag;
- goto loop;
- }
-
- case 0x86: // ADD (HL)
- data = READ( rp.hl );
- goto add_comm;
-
- case 0x80: // ADD B
- case 0x81: // ADD C
- case 0x82: // ADD D
- case 0x83: // ADD E
- case 0x84: // ADD H
- case 0x85: // ADD L
- case 0x87: // ADD A
- data = R8( op & 7 );
- goto add_comm;
-
- case 0xC6: // ADD IMM
- pc++;
- add_comm:
- flags = rg.a;
- data += flags;
- flags = ((data & 15) - (flags & 15)) & h_flag;
- flags |= (data >> 4) & c_flag;
- rg.a = data;
- if ( data & 0xFF )
- goto loop;
- flags |= z_flag;
- goto loop;
-
-// Add/Subtract
-
- case 0x8E: // ADC (HL)
- data = READ( rp.hl );
- goto adc_comm;
-
- case 0x88: // ADC B
- case 0x89: // ADC C
- case 0x8A: // ADC D
- case 0x8B: // ADC E
- case 0x8C: // ADC H
- case 0x8D: // ADC L
- case 0x8F: // ADC A
- data = R8( op & 7 );
- goto adc_comm;
-
- case 0xCE: // ADC IMM
- pc++;
- adc_comm:
- data += (flags >> 4) & 1;
- data &= 0xFF; // to do: does carry get set when sum + carry = 0x100?
- goto add_comm;
-
- case 0x96: // SUB (HL)
- data = READ( rp.hl );
- goto sub_comm;
-
- case 0x90: // SUB B
- case 0x91: // SUB C
- case 0x92: // SUB D
- case 0x93: // SUB E
- case 0x94: // SUB H
- case 0x95: // SUB L
- case 0x97: // SUB A
- data = R8( op & 7 );
- goto sub_comm;
-
- case 0xD6: // SUB IMM
- pc++;
- sub_comm:
- op = rg.a;
- data = op - data;
- rg.a = data;
- goto sub_set_flags;
-
- case 0x9E: // SBC (HL)
- data = READ( rp.hl );
- goto sbc_comm;
-
- case 0x98: // SBC B
- case 0x99: // SBC C
- case 0x9A: // SBC D
- case 0x9B: // SBC E
- case 0x9C: // SBC H
- case 0x9D: // SBC L
- case 0x9F: // SBC A
- data = R8( op & 7 );
- goto sbc_comm;
-
- case 0xDE: // SBC IMM
- pc++;
- sbc_comm:
- data += (flags >> 4) & 1;
- data &= 0xFF; // to do: does carry get set when sum + carry = 0x100?
- goto sub_comm;
-
-// Logical
-
- case 0xA0: // AND B
- case 0xA1: // AND C
- case 0xA2: // AND D
- case 0xA3: // AND E
- case 0xA4: // AND H
- case 0xA5: // AND L
- data = R8( op & 7 );
- goto and_comm;
-
- case 0xA6: // AND (HL)
- data = READ( rp.hl );
- pc--;
- case 0xE6: // AND IMM
- pc++;
- and_comm:
- rg.a &= data;
- case 0xA7: // AND A
- flags = h_flag | (((rg.a - 1) >> 1) & z_flag);
- goto loop;
-
- case 0xB0: // OR B
- case 0xB1: // OR C
- case 0xB2: // OR D
- case 0xB3: // OR E
- case 0xB4: // OR H
- case 0xB5: // OR L
- data = R8( op & 7 );
- goto or_comm;
-
- case 0xB6: // OR (HL)
- data = READ( rp.hl );
- pc--;
- case 0xF6: // OR IMM
- pc++;
- or_comm:
- rg.a |= data;
- case 0xB7: // OR A
- flags = ((rg.a - 1) >> 1) & z_flag;
- goto loop;
-
- case 0xA8: // XOR B
- case 0xA9: // XOR C
- case 0xAA: // XOR D
- case 0xAB: // XOR E
- case 0xAC: // XOR H
- case 0xAD: // XOR L
- data = R8( op & 7 );
- goto xor_comm;
-
- case 0xAE: // XOR (HL)
- data = READ( rp.hl );
- pc--;
- case 0xEE: // XOR IMM
- pc++;
- xor_comm:
- data ^= rg.a;
- rg.a = data;
- data--;
- flags = (data >> 1) & z_flag;
- goto loop;
-
- case 0xAF: // XOR A
- rg.a = 0;
- flags = z_flag;
- goto loop;
-
-// Stack
-
- case 0xF1: // POP FA
- case 0xC1: // POP BC
- case 0xD1: // POP DE
- case 0xE1: // POP HL (common)
- data = READ( sp );
- r16 [(op >> 4) & 3] = data + 0x100 * READ( sp + 1 );
- sp = (sp + 2) & 0xFFFF;
- if ( op != 0xF1 )
- goto loop;
- flags = rg.flags & 0xF0;
- goto loop;
-
- case 0xC5: // PUSH BC
- data = rp.bc;
- goto push;
-
- case 0xD5: // PUSH DE
- data = rp.de;
- goto push;
-
- case 0xE5: // PUSH HL
- data = rp.hl;
- goto push;
-
- case 0xF5: // PUSH FA
- data = (flags << 8) | rg.a;
- goto push;
-
-// Flow control
-
- case 0xFF:
- if ( pc == idle_addr + 1 )
- goto stop;
- case 0xC7: case 0xCF: case 0xD7: case 0xDF: // RST
- case 0xE7: case 0xEF: case 0xF7:
- data = pc;
- pc = (op & 0x38) + rst_base;
- goto push;
-
- case 0xCC: // CZ
- pc += 2;
- if ( flags & z_flag )
- goto call;
- goto loop;
-
- case 0xD4: // CNC
- pc += 2;
- if ( !(flags & c_flag) )
- goto call;
- goto loop;
-
- case 0xDC: // CC
- pc += 2;
- if ( flags & c_flag )
- goto call;
- goto loop;
-
- case 0xD9: // RETI
- //interrupts_enabled = 1;
- goto ret;
-
- case 0xC0: // RZ
- if ( !(flags & z_flag) )
- goto ret;
- goto loop;
-
- case 0xD0: // RNC
- if ( !(flags & c_flag) )
- goto ret;
- goto loop;
-
- case 0xD8: // RC
- if ( flags & c_flag )
- goto ret;
- goto loop;
-
- case 0x18: // JR
- BRANCH( true )
-
- case 0x30: // JR NC
- BRANCH( !(flags & c_flag) )
-
- case 0x38: // JR C
- BRANCH( flags & c_flag )
-
- case 0xE9: // JP_HL
- pc = rp.hl;
- goto loop;
-
- case 0xC3: // JP (next-most-common)
- pc = GET_ADDR();
- goto loop;
-
- case 0xC2: // JP NZ
- pc += 2;
- if ( !(flags & z_flag) )
- goto jp_taken;
- goto loop;
-
- case 0xCA: // JP Z (most common)
- pc += 2;
- if ( !(flags & z_flag) )
- goto loop;
- jp_taken:
- pc -= 2;
- pc = GET_ADDR();
- goto loop;
-
- case 0xD2: // JP NC
- pc += 2;
- if ( !(flags & c_flag) )
- goto jp_taken;
- goto loop;
-
- case 0xDA: // JP C
- pc += 2;
- if ( flags & c_flag )
- goto jp_taken;
- goto loop;
-
-// Flags
-
- case 0x2F: // CPL
- rg.a = ~rg.a;
- flags |= n_flag | h_flag;
- goto loop;
-
- case 0x3F: // CCF
- flags = (flags ^ c_flag) & ~(n_flag | h_flag);
- goto loop;
-
- case 0x37: // SCF
- flags = (flags | c_flag) & ~(n_flag | h_flag);
- goto loop;
-
- case 0xF3: // DI
- //interrupts_enabled = 0;
- goto loop;
-
- case 0xFB: // EI
- //interrupts_enabled = 1;
- goto loop;
-
-// Special
-
- case 0xDD: case 0xD3: case 0xDB: case 0xE3: case 0xE4: // ?
- case 0xEB: case 0xEC: case 0xF4: case 0xFD: case 0xFC:
- case 0x10: // STOP
- case 0x27: // DAA (I'll have to implement this eventually...)
- case 0xBF:
- case 0xED: // Z80 prefix
- case 0x76: // HALT
- s.remain++;
- goto stop;
- }
-
- // If this fails then the case above is missing an opcode
- assert( false );
-
-stop:
- pc--;
-
- // copy state back
- STATIC_CAST(core_regs_t&,r) = rg;
- r.pc = pc;
- r.sp = sp;
- r.flags = flags;
-
- this->state = &state_;
- memcpy( &this->state_, &s, sizeof this->state_ );
-
- return s.remain > 0;
-}
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Gb_Cpu.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/Gb_Cpu.h
deleted file mode 100644
index 953fbaf5..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Gb_Cpu.h
+++ /dev/null
@@ -1,93 +0,0 @@
-// Nintendo Game Boy CPU emulator
-// Treats every instruction as taking 4 cycles
-
-// Game_Music_Emu 0.5.2
-#ifndef GB_CPU_H
-#define GB_CPU_H
-
-#include "blargg_common.h"
-#include "blargg_endian.h"
-
-typedef unsigned gb_addr_t; // 16-bit CPU address
-
-class Gb_Cpu {
- enum { clocks_per_instr = 4 };
-public:
- typedef BOOST::uint8_t uint8_t;
-
- // Clear registers and map all pages to unmapped
- void reset( void* unmapped = 0 );
-
- // Map code memory (memory accessed via the program counter). Start and size
- // must be multiple of page_size.
- enum { page_size = 0x2000 };
- void map_code( gb_addr_t start, unsigned size, void* code );
-
- uint8_t* get_code( gb_addr_t );
-
- // Push a byte on the stack
- void push_byte( int );
-
- // Game Boy Z80 registers. *Not* kept updated during a call to run().
- struct core_regs_t {
- #if BLARGG_BIG_ENDIAN
- uint8_t b, c, d, e, h, l, flags, a;
- #else
- uint8_t c, b, e, d, l, h, a, flags;
- #endif
- };
-
- struct registers_t : core_regs_t {
- long pc; // more than 16 bits to allow overflow detection
- BOOST::uint16_t sp;
- };
- registers_t r;
-
- // Interrupt enable flag set by EI and cleared by DI
- //bool interrupts_enabled; // unused
-
- // Base address for RST vectors (normally 0)
- gb_addr_t rst_base;
-
- // If CPU executes opcode 0xFF at this address, it treats as illegal instruction
- enum { idle_addr = 0xF00D };
-
- // Run CPU for at least 'count' cycles and return false, or return true if
- // illegal instruction is encountered.
- bool run( blargg_long count );
-
- // Number of clock cycles remaining for most recent run() call
- blargg_long remain() const { return state->remain * clocks_per_instr; }
-
- // Can read this many bytes past end of a page
- enum { cpu_padding = 8 };
-
-public:
- Gb_Cpu() : rst_base( 0 ) { state = &state_; }
- enum { page_shift = 13 };
- enum { page_count = 0x10000 >> page_shift };
-private:
- // noncopyable
- Gb_Cpu( const Gb_Cpu& );
- Gb_Cpu& operator = ( const Gb_Cpu& );
-
- struct state_t {
- uint8_t* code_map [page_count + 1];
- blargg_long remain;
- };
- state_t* state; // points to state_ or a local copy within run()
- state_t state_;
-
- void set_code_page( int, uint8_t* );
-};
-
-inline BOOST::uint8_t* Gb_Cpu::get_code( gb_addr_t addr )
-{
- return state->code_map [addr >> page_shift] + addr
- #if !BLARGG_NONPORTABLE
- % (unsigned) page_size
- #endif
- ;
-}
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Gb_Oscs.cpp b/plugins/gme/Game_Music_Emu-0.5.2/gme/Gb_Oscs.cpp
deleted file mode 100644
index 735653fa..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Gb_Oscs.cpp
+++ /dev/null
@@ -1,336 +0,0 @@
-// Gb_Snd_Emu 0.1.5. http://www.slack.net/~ant/
-
-#include "Gb_Apu.h"
-
-#include <string.h>
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-// Gb_Osc
-
-void Gb_Osc::reset()
-{
- delay = 0;
- last_amp = 0;
- length = 0;
- output_select = 3;
- output = outputs [output_select];
-}
-
-void Gb_Osc::clock_length()
-{
- if ( (regs [4] & len_enabled_mask) && length )
- length--;
-}
-
-// Gb_Env
-
-void Gb_Env::clock_envelope()
-{
- if ( env_delay && !--env_delay )
- {
- env_delay = regs [2] & 7;
- int v = volume - 1 + (regs [2] >> 2 & 2);
- if ( (unsigned) v < 15 )
- volume = v;
- }
-}
-
-bool Gb_Env::write_register( int reg, int data )
-{
- switch ( reg )
- {
- case 1:
- length = 64 - (regs [1] & 0x3F);
- break;
-
- case 2:
- if ( !(data >> 4) )
- enabled = false;
- break;
-
- case 4:
- if ( data & trigger )
- {
- env_delay = regs [2] & 7;
- volume = regs [2] >> 4;
- enabled = true;
- if ( length == 0 )
- length = 64;
- return true;
- }
- }
- return false;
-}
-
-// Gb_Square
-
-void Gb_Square::reset()
-{
- phase = 0;
- sweep_freq = 0;
- sweep_delay = 0;
- Gb_Env::reset();
-}
-
-void Gb_Square::clock_sweep()
-{
- int sweep_period = (regs [0] & period_mask) >> 4;
- if ( sweep_period && sweep_delay && !--sweep_delay )
- {
- sweep_delay = sweep_period;
- regs [3] = sweep_freq & 0xFF;
- regs [4] = (regs [4] & ~0x07) | (sweep_freq >> 8 & 0x07);
-
- int offset = sweep_freq >> (regs [0] & shift_mask);
- if ( regs [0] & 0x08 )
- offset = -offset;
- sweep_freq += offset;
-
- if ( sweep_freq < 0 )
- {
- sweep_freq = 0;
- }
- else if ( sweep_freq >= 2048 )
- {
- sweep_delay = 0; // don't modify channel frequency any further
- sweep_freq = 2048; // silence sound immediately
- }
- }
-}
-
-void Gb_Square::run( blip_time_t time, blip_time_t end_time, int playing )
-{
- if ( sweep_freq == 2048 )
- playing = false;
-
- static unsigned char const table [4] = { 1, 2, 4, 6 };
- int const duty = table [regs [1] >> 6];
- int amp = volume & playing;
- if ( phase >= duty )
- amp = -amp;
-
- int frequency = this->frequency();
- if ( unsigned (frequency - 1) > 2040 ) // frequency < 1 || frequency > 2041
- {
- // really high frequency results in DC at half volume
- amp = volume >> 1;
- playing = false;
- }
-
- {
- int delta = amp - last_amp;
- if ( delta )
- {
- last_amp = amp;
- synth->offset( time, delta, output );
- }
- }
-
- time += delay;
- if ( !playing )
- time = end_time;
-
- if ( time < end_time )
- {
- int const period = (2048 - frequency) * 4;
- Blip_Buffer* const output = this->output;
- int phase = this->phase;
- int delta = amp * 2;
- do
- {
- phase = (phase + 1) & 7;
- if ( phase == 0 || phase == duty )
- {
- delta = -delta;
- synth->offset_inline( time, delta, output );
- }
- time += period;
- }
- while ( time < end_time );
-
- this->phase = phase;
- last_amp = delta >> 1;
- }
- delay = time - end_time;
-}
-
-// Gb_Noise
-
-void Gb_Noise::run( blip_time_t time, blip_time_t end_time, int playing )
-{
- int amp = volume & playing;
- int tap = 13 - (regs [3] & 8);
- if ( bits >> tap & 2 )
- amp = -amp;
-
- {
- int delta = amp - last_amp;
- if ( delta )
- {
- last_amp = amp;
- synth->offset( time, delta, output );
- }
- }
-
- time += delay;
- if ( !playing )
- time = end_time;
-
- if ( time < end_time )
- {
- static unsigned char const table [8] = { 8, 16, 32, 48, 64, 80, 96, 112 };
- int period = table [regs [3] & 7] << (regs [3] >> 4);
-
- // keep parallel resampled time to eliminate time conversion in the loop
- Blip_Buffer* const output = this->output;
- const blip_resampled_time_t resampled_period =
- output->resampled_duration( period );
- blip_resampled_time_t resampled_time = output->resampled_time( time );
- unsigned bits = this->bits;
- int delta = amp * 2;
-
- do
- {
- unsigned changed = (bits >> tap) + 1;
- time += period;
- bits <<= 1;
- if ( changed & 2 )
- {
- delta = -delta;
- bits |= 1;
- synth->offset_resampled( resampled_time, delta, output );
- }
- resampled_time += resampled_period;
- }
- while ( time < end_time );
-
- this->bits = bits;
- last_amp = delta >> 1;
- }
- delay = time - end_time;
-}
-
-// Gb_Wave
-
-inline void Gb_Wave::write_register( int reg, int data )
-{
- switch ( reg )
- {
- case 0:
- if ( !(data & 0x80) )
- enabled = false;
- break;
-
- case 1:
- length = 256 - regs [1];
- break;
-
- case 2:
- volume = data >> 5 & 3;
- break;
-
- case 4:
- if ( data & trigger & regs [0] )
- {
- wave_pos = 0;
- enabled = true;
- if ( length == 0 )
- length = 256;
- }
- }
-}
-
-void Gb_Wave::run( blip_time_t time, blip_time_t end_time, int playing )
-{
- int volume_shift = (volume - 1) & 7; // volume = 0 causes shift = 7
- int frequency;
- {
- int amp = (wave [wave_pos] >> volume_shift & playing) * 2;
-
- frequency = this->frequency();
- if ( unsigned (frequency - 1) > 2044 ) // frequency < 1 || frequency > 2045
- {
- amp = 30 >> volume_shift & playing;
- playing = false;
- }
-
- int delta = amp - last_amp;
- if ( delta )
- {
- last_amp = amp;
- synth->offset( time, delta, output );
- }
- }
-
- time += delay;
- if ( !playing )
- time = end_time;
-
- if ( time < end_time )
- {
- Blip_Buffer* const output = this->output;
- int const period = (2048 - frequency) * 2;
- int wave_pos = (this->wave_pos + 1) & (wave_size - 1);
-
- do
- {
- int amp = (wave [wave_pos] >> volume_shift) * 2;
- wave_pos = (wave_pos + 1) & (wave_size - 1);
- int delta = amp - last_amp;
- if ( delta )
- {
- last_amp = amp;
- synth->offset_inline( time, delta, output );
- }
- time += period;
- }
- while ( time < end_time );
-
- this->wave_pos = (wave_pos - 1) & (wave_size - 1);
- }
- delay = time - end_time;
-}
-
-// Gb_Apu::write_osc
-
-void Gb_Apu::write_osc( int index, int reg, int data )
-{
- reg -= index * 5;
- Gb_Square* sq = &square2;
- switch ( index )
- {
- case 0:
- sq = &square1;
- case 1:
- if ( sq->write_register( reg, data ) && index == 0 )
- {
- square1.sweep_freq = square1.frequency();
- if ( (regs [0] & sq->period_mask) && (regs [0] & sq->shift_mask) )
- {
- square1.sweep_delay = 1; // cause sweep to recalculate now
- square1.clock_sweep();
- }
- }
- break;
-
- case 2:
- wave.write_register( reg, data );
- break;
-
- case 3:
- if ( noise.write_register( reg, data ) )
- noise.bits = 0x7FFF;
- }
-}
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Gb_Oscs.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/Gb_Oscs.h
deleted file mode 100644
index d7f88ea1..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Gb_Oscs.h
+++ /dev/null
@@ -1,83 +0,0 @@
-// Private oscillators used by Gb_Apu
-
-// Gb_Snd_Emu 0.1.5
-#ifndef GB_OSCS_H
-#define GB_OSCS_H
-
-#include "blargg_common.h"
-#include "Blip_Buffer.h"
-
-struct Gb_Osc
-{
- enum { trigger = 0x80 };
- enum { len_enabled_mask = 0x40 };
-
- Blip_Buffer* outputs [4]; // NULL, right, left, center
- Blip_Buffer* output;
- int output_select;
- BOOST::uint8_t* regs; // osc's 5 registers
-
- int delay;
- int last_amp;
- int volume;
- int length;
- int enabled;
-
- void reset();
- void clock_length();
- int frequency() const { return (regs [4] & 7) * 0x100 + regs [3]; }
-};
-
-struct Gb_Env : Gb_Osc
-{
- int env_delay;
-
- void reset();
- void clock_envelope();
- bool write_register( int, int );
-};
-
-struct Gb_Square : Gb_Env
-{
- enum { period_mask = 0x70 };
- enum { shift_mask = 0x07 };
-
- typedef Blip_Synth<blip_good_quality,1> Synth;
- Synth const* synth;
- int sweep_delay;
- int sweep_freq;
- int phase;
-
- void reset();
- void clock_sweep();
- void run( blip_time_t, blip_time_t, int playing );
-};
-
-struct Gb_Noise : Gb_Env
-{
- typedef Blip_Synth<blip_med_quality,1> Synth;
- Synth const* synth;
- unsigned bits;
-
- void run( blip_time_t, blip_time_t, int playing );
-};
-
-struct Gb_Wave : Gb_Osc
-{
- typedef Blip_Synth<blip_med_quality,1> Synth;
- Synth const* synth;
- int wave_pos;
- enum { wave_size = 32 };
- BOOST::uint8_t wave [wave_size];
-
- void write_register( int, int );
- void run( blip_time_t, blip_time_t, int playing );
-};
-
-inline void Gb_Env::reset()
-{
- env_delay = 0;
- Gb_Osc::reset();
-}
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Gbs_Emu.cpp b/plugins/gme/Game_Music_Emu-0.5.2/gme/Gbs_Emu.cpp
deleted file mode 100644
index 30a147e5..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Gbs_Emu.cpp
+++ /dev/null
@@ -1,288 +0,0 @@
-// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
-
-#include "Gbs_Emu.h"
-
-#include "blargg_endian.h"
-#include <string.h>
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-Gbs_Emu::equalizer_t const Gbs_Emu::handheld_eq = { -47.0, 2000 };
-Gbs_Emu::equalizer_t const Gbs_Emu::headphones_eq = { 0.0, 300 };
-
-Gbs_Emu::Gbs_Emu()
-{
- set_type( gme_gbs_type );
-
- static const char* const names [Gb_Apu::osc_count] = {
- "Square 1", "Square 2", "Wave", "Noise"
- };
- set_voice_names( names );
-
- static int const types [Gb_Apu::osc_count] = {
- wave_type | 1, wave_type | 2, wave_type | 0, mixed_type | 0
- };
- set_voice_types( types );
-
- set_silence_lookahead( 6 );
- set_max_initial_silence( 21 );
- set_gain( 1.2 );
-
- static equalizer_t const eq = { -1.0, 120 };
- set_equalizer( eq );
-}
-
-Gbs_Emu::~Gbs_Emu() { }
-
-void Gbs_Emu::unload()
-{
- rom.clear();
- Music_Emu::unload();
-}
-
-// Track info
-
-static void copy_gbs_fields( Gbs_Emu::header_t const& h, track_info_t* out )
-{
- GME_COPY_FIELD( h, out, game );
- GME_COPY_FIELD( h, out, author );
- GME_COPY_FIELD( h, out, copyright );
-}
-
-blargg_err_t Gbs_Emu::track_info_( track_info_t* out, int ) const
-{
- copy_gbs_fields( header_, out );
- return 0;
-}
-
-static blargg_err_t check_gbs_header( void const* header )
-{
- if ( memcmp( header, "GBS", 3 ) )
- return gme_wrong_file_type;
- return 0;
-}
-
-struct Gbs_File : Gme_Info_
-{
- Gbs_Emu::header_t h;
-
- Gbs_File() { set_type( gme_gbs_type ); }
-
- blargg_err_t load_( Data_Reader& in )
- {
- blargg_err_t err = in.read( &h, Gbs_Emu::header_size );
- if ( err )
- return (err == in.eof_error ? gme_wrong_file_type : err);
-
- set_track_count( h.track_count );
- return check_gbs_header( &h );
- }
-
- blargg_err_t track_info_( track_info_t* out, int ) const
- {
- copy_gbs_fields( h, out );
- return 0;
- }
-};
-
-static Music_Emu* new_gbs_emu () { return BLARGG_NEW Gbs_Emu ; }
-static Music_Emu* new_gbs_file() { return BLARGG_NEW Gbs_File; }
-
-gme_type_t_ const gme_gbs_type [1] = { "Game Boy", 0, &new_gbs_emu, &new_gbs_file, "GBS", 1 };
-
-// Setup
-
-blargg_err_t Gbs_Emu::load_( Data_Reader& in )
-{
- assert( offsetof (header_t,copyright [32]) == header_size );
- RETURN_ERR( rom.load( in, header_size, &header_, 0 ) );
-
- set_track_count( header_.track_count );
- RETURN_ERR( check_gbs_header( &header_ ) );
-
- if ( header_.vers != 1 )
- set_warning( "Unknown file version" );
-
- if ( header_.timer_mode & 0x78 )
- set_warning( "Invalid timer mode" );
-
- unsigned load_addr = get_le16( header_.load_addr );
- if ( (header_.load_addr [1] | header_.init_addr [1] | header_.play_addr [1]) > 0x7F ||
- load_addr < 0x400 )
- set_warning( "Invalid load/init/play address" );
-
- set_voice_count( Gb_Apu::osc_count );
-
- apu.volume( gain() );
-
- return setup_buffer( 4194304 );
-}
-
-void Gbs_Emu::update_eq( blip_eq_t const& eq )
-{
- apu.treble_eq( eq );
-}
-
-void Gbs_Emu::set_voice( int i, Blip_Buffer* c, Blip_Buffer* l, Blip_Buffer* r )
-{
- apu.osc_output( i, c, l, r );
-}
-
-// Emulation
-
-// see gb_cpu_io.h for read/write functions
-
-void Gbs_Emu::set_bank( int n )
-{
- blargg_long addr = rom.mask_addr( n * (blargg_long) bank_size );
- if ( addr == 0 && rom.size() > bank_size )
- {
- // TODO: what is the correct behavior? Current Game & Watch Gallery
- // rip requires that this have no effect or set to bank 1.
- //dprintf( "Selected ROM bank 0\n" );
- return;
- //n = 1;
- }
- cpu::map_code( bank_size, bank_size, rom.at_addr( addr ) );
-}
-
-void Gbs_Emu::update_timer()
-{
- if ( header_.timer_mode & 0x04 )
- {
- static byte const rates [4] = { 10, 4, 6, 8 };
- int shift = rates [ram [hi_page + 7] & 3] - (header_.timer_mode >> 7);
- play_period = (256L - ram [hi_page + 6]) << shift;
- }
- else
- {
- play_period = 70224; // 59.73 Hz
- }
- if ( tempo() != 1.0 )
- play_period = blip_time_t (play_period / tempo());
-}
-
-static BOOST::uint8_t const sound_data [Gb_Apu::register_count] = {
- 0x80, 0xBF, 0x00, 0x00, 0xBF, // square 1
- 0x00, 0x3F, 0x00, 0x00, 0xBF, // square 2
- 0x7F, 0xFF, 0x9F, 0x00, 0xBF, // wave
- 0x00, 0xFF, 0x00, 0x00, 0xBF, // noise
- 0x77, 0xF3, 0xF1, // vin/volume, status, power mode
- 0, 0, 0, 0, 0, 0, 0, 0, 0, // unused
- 0xAC, 0xDD, 0xDA, 0x48, 0x36, 0x02, 0xCF, 0x16, // waveform data
- 0x2C, 0x04, 0xE5, 0x2C, 0xAC, 0xDD, 0xDA, 0x48
-};
-
-void Gbs_Emu::cpu_jsr( gb_addr_t addr )
-{
- check( cpu::r.sp == get_le16( header_.stack_ptr ) );
- cpu::r.pc = addr;
- cpu_write( --cpu::r.sp, idle_addr >> 8 );
- cpu_write( --cpu::r.sp, idle_addr&0xFF );
-}
-
-void Gbs_Emu::set_tempo_( double t )
-{
- apu.set_tempo( t );
- update_timer();
-}
-
-blargg_err_t Gbs_Emu::start_track_( int track )
-{
- RETURN_ERR( Classic_Emu::start_track_( track ) );
-
- memset( ram, 0, 0x4000 );
- memset( ram + 0x4000, 0xFF, 0x1F80 );
- memset( ram + 0x5F80, 0, sizeof ram - 0x5F80 );
- ram [hi_page] = 0; // joypad reads back as 0
-
- apu.reset();
- for ( int i = 0; i < (int) sizeof sound_data; i++ )
- apu.write_register( 0, i + apu.start_addr, sound_data [i] );
-
- cpu::reset( rom.unmapped() );
-
- unsigned load_addr = get_le16( header_.load_addr );
- cpu::rst_base = load_addr;
- rom.set_addr( load_addr );
-
- cpu::map_code( ram_addr, 0x10000 - ram_addr, ram );
- cpu::map_code( 0, bank_size, rom.at_addr( 0 ) );
- set_bank( rom.size() > bank_size );
-
- ram [hi_page + 6] = header_.timer_modulo;
- ram [hi_page + 7] = header_.timer_mode;
- update_timer();
- next_play = play_period;
-
- cpu::r.a = track;
- cpu::r.pc = idle_addr;
- cpu::r.sp = get_le16( header_.stack_ptr );
- cpu_time = 0;
- cpu_jsr( get_le16( header_.init_addr ) );
-
- return 0;
-}
-
-blargg_err_t Gbs_Emu::run_clocks( blip_time_t& duration, int )
-{
- cpu_time = 0;
- while ( cpu_time < duration )
- {
- long count = duration - cpu_time;
- cpu_time = duration;
- bool result = cpu::run( count );
- cpu_time -= cpu::remain();
-
- if ( result )
- {
- if ( cpu::r.pc == idle_addr )
- {
- if ( next_play > duration )
- {
- cpu_time = duration;
- break;
- }
-
- if ( cpu_time < next_play )
- cpu_time = next_play;
- next_play += play_period;
- cpu_jsr( get_le16( header_.play_addr ) );
- GME_FRAME_HOOK( this );
- // TODO: handle timer rates different than 60 Hz
- }
- else if ( cpu::r.pc > 0xFFFF )
- {
- dprintf( "PC wrapped around\n" );
- cpu::r.pc &= 0xFFFF;
- }
- else
- {
- set_warning( "Emulation error (illegal/unsupported instruction)" );
- dprintf( "Bad opcode $%.2x at $%.4x\n",
- (int) *cpu::get_code( cpu::r.pc ), (int) cpu::r.pc );
- cpu::r.pc = (cpu::r.pc + 1) & 0xFFFF;
- cpu_time += 6;
- }
- }
- }
-
- duration = cpu_time;
- next_play -= cpu_time;
- if ( next_play < 0 ) // could go negative if routine is taking too long to return
- next_play = 0;
- apu.end_frame( cpu_time );
-
- return 0;
-}
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Gbs_Emu.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/Gbs_Emu.h
deleted file mode 100644
index 93fe691e..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Gbs_Emu.h
+++ /dev/null
@@ -1,88 +0,0 @@
-// Nintendo Game Boy GBS music file emulator
-
-// Game_Music_Emu 0.5.2
-#ifndef GBS_EMU_H
-#define GBS_EMU_H
-
-#include "Classic_Emu.h"
-#include "Gb_Apu.h"
-#include "Gb_Cpu.h"
-
-class Gbs_Emu : private Gb_Cpu, public Classic_Emu {
- typedef Gb_Cpu cpu;
-public:
- // Equalizer profiles for Game Boy Color speaker and headphones
- static equalizer_t const handheld_eq;
- static equalizer_t const headphones_eq;
-
- // GBS file header
- enum { header_size = 112 };
- struct header_t
- {
- char tag [3];
- byte vers;
- byte track_count;
- byte first_track;
- byte load_addr [2];
- byte init_addr [2];
- byte play_addr [2];
- byte stack_ptr [2];
- byte timer_modulo;
- byte timer_mode;
- char game [32];
- char author [32];
- char copyright [32];
- };
-
- // Header for currently loaded file
- header_t const& header() const { return header_; }
-
- static gme_type_t static_type() { return gme_gbs_type; }
-
-public:
- // deprecated
- Music_Emu::load;
- blargg_err_t load( header_t const& h, Data_Reader& in ) // use Remaining_Reader
- { return load_remaining_( &h, sizeof h, in ); }
-
-public:
- Gbs_Emu();
- ~Gbs_Emu();
-protected:
- blargg_err_t track_info_( track_info_t*, int track ) const;
- blargg_err_t load_( Data_Reader& );
- blargg_err_t start_track_( int );
- blargg_err_t run_clocks( blip_time_t&, int );
- void set_tempo_( double );
- void set_voice( int, Blip_Buffer*, Blip_Buffer*, Blip_Buffer* );
- void update_eq( blip_eq_t const& );
- void unload();
-private:
- // rom
- enum { bank_size = 0x4000 };
- Rom_Data<bank_size> rom;
- void set_bank( int );
-
- // timer
- blip_time_t cpu_time;
- blip_time_t play_period;
- blip_time_t next_play;
- void update_timer();
-
- header_t header_;
- void cpu_jsr( gb_addr_t );
-
-public: private: friend class Gb_Cpu;
- blip_time_t clock() const { return cpu_time - cpu::remain(); }
-
- enum { joypad_addr = 0xFF00 };
- enum { ram_addr = 0xA000 };
- enum { hi_page = 0xFF00 - ram_addr };
- byte ram [0x4000 + 0x2000 + Gb_Cpu::cpu_padding];
- Gb_Apu apu;
-
- int cpu_read( gb_addr_t );
- void cpu_write( gb_addr_t, int );
-};
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Gme_File.cpp b/plugins/gme/Game_Music_Emu-0.5.2/gme/Gme_File.cpp
deleted file mode 100644
index 6821c3a5..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Gme_File.cpp
+++ /dev/null
@@ -1,216 +0,0 @@
-// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
-
-#include "Gme_File.h"
-
-#include "blargg_endian.h"
-#include <string.h>
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-const char gme_wrong_file_type [] = "Wrong file type for this emulator";
-
-void Gme_File::clear_playlist()
-{
- playlist.clear();
- clear_playlist_();
- track_count_ = raw_track_count_;
-}
-
-void Gme_File::unload()
-{
- clear_playlist(); // *before* clearing track count
- track_count_ = 0;
- raw_track_count_ = 0;
- file_data.clear();
-}
-
-Gme_File::Gme_File()
-{
- type_ = 0;
- user_data_ = 0;
- user_cleanup_ = 0;
- unload(); // clears fields
- blargg_verify_byte_order(); // used by most emulator types, so save them the trouble
-}
-
-Gme_File::~Gme_File()
-{
- if ( user_cleanup_ )
- user_cleanup_( user_data_ );
-}
-
-blargg_err_t Gme_File::load_mem_( byte const* data, long size )
-{
- require( data != file_data.begin() ); // load_mem_() or load_() must be overridden
- Mem_File_Reader in( data, size );
- return load_( in );
-}
-
-blargg_err_t Gme_File::load_( Data_Reader& in )
-{
- RETURN_ERR( file_data.resize( in.remain() ) );
- RETURN_ERR( in.read( file_data.begin(), file_data.size() ) );
- return load_mem_( file_data.begin(), file_data.size() );
-}
-
-// public load functions call this at beginning
-void Gme_File::pre_load() { unload(); }
-
-void Gme_File::post_load_() { }
-
-// public load functions call this at end
-blargg_err_t Gme_File::post_load( blargg_err_t err )
-{
- if ( !track_count() )
- set_track_count( type()->track_count );
- if ( !err )
- post_load_();
- else
- unload();
-
- return err;
-}
-
-// Public load functions
-
-blargg_err_t Gme_File::load_mem( void const* in, long size )
-{
- pre_load();
- return post_load( load_mem_( (byte const*) in, size ) );
-}
-
-blargg_err_t Gme_File::load( Data_Reader& in )
-{
- pre_load();
- return post_load( load_( in ) );
-}
-
-blargg_err_t Gme_File::load_file( const char* path )
-{
- pre_load();
- GME_FILE_READER in;
- RETURN_ERR( in.open( path ) );
- return post_load( load_( in ) );
-}
-
-blargg_err_t Gme_File::load_remaining_( void const* h, long s, Data_Reader& in )
-{
- Remaining_Reader rem( h, s, &in );
- return load( rem );
-}
-
-// Track info
-
-void Gme_File::copy_field_( char* out, const char* in, int in_size )
-{
- if ( !in || !*in )
- return;
-
- // remove spaces/junk from beginning
- while ( in_size && unsigned (*in - 1) <= ' ' - 1 )
- {
- in++;
- in_size--;
- }
-
- // truncate
- if ( in_size > max_field_ )
- in_size = max_field_;
-
- // find terminator
- int len = 0;
- while ( len < in_size && in [len] )
- len++;
-
- // remove spaces/junk from end
- while ( len && unsigned (in [len - 1]) <= ' ' )
- len--;
-
- // copy
- out [len] = 0;
- memcpy( out, in, len );
-
- // strip out stupid fields that should have been left blank
- if ( !strcmp( out, "?" ) || !strcmp( out, "<?>" ) || !strcmp( out, "< ? >" ) )
- out [0] = 0;
-}
-
-void Gme_File::copy_field_( char* out, const char* in )
-{
- copy_field_( out, in, max_field_ );
-}
-
-blargg_err_t Gme_File::remap_track_( int* track_io ) const
-{
- if ( (unsigned) *track_io >= (unsigned) track_count() )
- return "Invalid track";
-
- if ( (unsigned) *track_io < (unsigned) playlist.size() )
- {
- M3u_Playlist::entry_t const& e = playlist [*track_io];
- *track_io = 0;
- if ( e.track >= 0 )
- {
- *track_io = e.track;
- if ( !(type_->flags_ & 0x02) )
- *track_io -= e.decimal_track;
- }
- if ( *track_io >= raw_track_count_ )
- return "Invalid track in m3u playlist";
- }
- else
- {
- check( !playlist.size() );
- }
- return 0;
-}
-
-blargg_err_t Gme_File::track_info( track_info_t* out, int track ) const
-{
- out->track_count = track_count();
- out->length = -1;
- out->loop_length = -1;
- out->intro_length = -1;
- out->song [0] = 0;
-
- out->game [0] = 0;
- out->author [0] = 0;
- out->copyright [0] = 0;
- out->comment [0] = 0;
- out->dumper [0] = 0;
- out->system [0] = 0;
-
- copy_field_( out->system, type()->system );
-
- int remapped = track;
- RETURN_ERR( remap_track_( &remapped ) );
- RETURN_ERR( track_info_( out, remapped ) );
-
- // override with m3u info
- if ( playlist.size() )
- {
- M3u_Playlist::info_t const& i = playlist.info();
- copy_field_( out->game , i.title );
- copy_field_( out->author, i.engineer );
- copy_field_( out->author, i.composer );
- copy_field_( out->dumper, i.ripping );
-
- M3u_Playlist::entry_t const& e = playlist [track];
- copy_field_( out->song, e.name );
- if ( e.length >= 0 ) out->length = e.length * 1000L;
- if ( e.intro >= 0 ) out->intro_length = e.intro * 1000L;
- if ( e.loop >= 0 ) out->loop_length = e.loop * 1000L;
- }
- return 0;
-}
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Gme_File.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/Gme_File.h
deleted file mode 100644
index a535633b..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Gme_File.h
+++ /dev/null
@@ -1,145 +0,0 @@
-// Common interface to game music file loading and information
-
-// Game_Music_Emu 0.5.2
-#ifndef GME_FILE_H
-#define GME_FILE_H
-
-#include "gme.h"
-#include "blargg_common.h"
-#include "Data_Reader.h"
-#include "M3u_Playlist.h"
-
-// Error returned if file is wrong type
-//extern const char gme_wrong_file_type []; // declared in gme.h
-
-struct Gme_File {
-public:
-// File loading
-
- // Each loads game music data from a file and returns an error if
- // file is wrong type or is seriously corrupt. They also set warning
- // string for minor problems.
-
- // Load from file on disk
- blargg_err_t load_file( const char* path );
-
- // Load from custom data source (see Data_Reader.h)
- blargg_err_t load( Data_Reader& );
-
- // Load from file already read into memory. Keeps pointer to data, so you
- // must not free it until you're done with the file.
- blargg_err_t load_mem( void const* data, long size );
-
- // Load an m3u playlist. Must be done after loading main music file.
- blargg_err_t load_m3u( const char* path );
- blargg_err_t load_m3u( Data_Reader& in );
-
- // Clears any loaded m3u playlist and any internal playlist that the music
- // format supports (NSFE for example).
- void clear_playlist();
-
-// Informational
-
- // Type of emulator. For example if this returns gme_nsfe_type, this object
- // is an NSFE emulator, and you can cast to an Nsfe_Emu* if necessary.
- gme_type_t type() const;
-
- // Most recent warning string, or NULL if none. Clears current warning after
- // returning.
- const char* warning();
-
- // Number of tracks or 0 if no file has been loaded
- int track_count() const;
-
- // Get information for a track (length, name, author, etc.)
- // See gme.h for definition of struct track_info_t.
- blargg_err_t track_info( track_info_t* out, int track ) const;
-
-// User data/cleanup
-
- // Set/get pointer to data you want to associate with this emulator.
- // You can use this for whatever you want.
- void set_user_data( void* p ) { user_data_ = p; }
- void* user_data() const { return user_data_; }
-
- // Register cleanup function to be called when deleting emulator, or NULL to
- // clear it. Passes user_data to cleanup function.
- void set_user_cleanup( gme_user_cleanup_t func ) { user_cleanup_ = func; }
-
-public:
- // deprecated
- int error_count() const; // use warning()
-public:
- Gme_File();
- virtual ~Gme_File();
- BLARGG_DISABLE_NOTHROW
- typedef BOOST::uint8_t byte;
-protected:
- // Services
- void set_track_count( int n ) { track_count_ = raw_track_count_ = n; }
- void set_warning( const char* s ) { warning_ = s; }
- void set_type( gme_type_t t ) { type_ = t; }
- blargg_err_t load_remaining_( void const* header, long header_size, Data_Reader& remaining );
-
- // Overridable
- virtual void unload(); // called before loading file and if loading fails
- virtual blargg_err_t load_( Data_Reader& ); // default loads then calls load_mem_()
- virtual blargg_err_t load_mem_( byte const* data, long size ); // use data in memory
- virtual blargg_err_t track_info_( track_info_t* out, int track ) const = 0;
- virtual void pre_load();
- virtual void post_load_();
- virtual void clear_playlist_() { }
-
-public:
- blargg_err_t remap_track_( int* track_io ) const; // need by Music_Emu
-private:
- // noncopyable
- Gme_File( const Gme_File& );
- Gme_File& operator = ( const Gme_File& );
-
- gme_type_t type_;
- int track_count_;
- int raw_track_count_;
- const char* warning_;
- void* user_data_;
- gme_user_cleanup_t user_cleanup_;
- M3u_Playlist playlist;
- char playlist_warning [64];
- blargg_vector<byte> file_data; // only if loaded into memory using default load
-
- blargg_err_t load_m3u_( blargg_err_t );
- blargg_err_t post_load( blargg_err_t err );
-public:
- // track_info field copying
- enum { max_field_ = 255 };
- static void copy_field_( char* out, const char* in );
- static void copy_field_( char* out, const char* in, int len );
-};
-
-Music_Emu* gme_new_( Music_Emu*, long sample_rate );
-
-#define GME_COPY_FIELD( in, out, name ) \
- { Gme_File::copy_field_( out->name, in.name, sizeof in.name ); }
-
-#ifndef GME_FILE_READER
- #ifdef HAVE_ZLIB_H
- #define GME_FILE_READER Gzip_File_Reader
- #else
- #define GME_FILE_READER Std_File_Reader
- #endif
-#elif defined (GME_FILE_READER_INCLUDE)
- #include GME_FILE_READER_INCLUDE
-#endif
-
-inline gme_type_t Gme_File::type() const { return type_; }
-inline int Gme_File::error_count() const { return warning_ != 0; }
-inline int Gme_File::track_count() const { return track_count_; }
-
-inline const char* Gme_File::warning()
-{
- const char* s = warning_;
- warning_ = 0;
- return s;
-}
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Gym_Emu.cpp b/plugins/gme/Game_Music_Emu-0.5.2/gme/Gym_Emu.cpp
deleted file mode 100644
index 499a9ca2..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Gym_Emu.cpp
+++ /dev/null
@@ -1,379 +0,0 @@
-// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
-
-#include "Gym_Emu.h"
-
-#include "blargg_endian.h"
-#include <string.h>
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-double const min_tempo = 0.25;
-double const oversample_factor = 5 / 3.0;
-double const fm_gain = 3.0;
-
-const long base_clock = 53700300;
-const long clock_rate = base_clock / 15;
-
-Gym_Emu::Gym_Emu()
-{
- data = 0;
- pos = 0;
- set_type( gme_gym_type );
-
- static const char* const names [] = {
- "FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6", "PCM", "PSG"
- };
- set_voice_names( names );
- set_silence_lookahead( 1 ); // tracks should already be trimmed
-}
-
-Gym_Emu::~Gym_Emu() { }
-
-// Track info
-
-static void get_gym_info( Gym_Emu::header_t const& h, long length, track_info_t* out )
-{
- if ( !memcmp( h.tag, "GYMX", 4 ) )
- {
- length = length * 50 / 3; // 1000 / 60
- long loop = get_le32( h.loop_start );
- if ( loop )
- {
- out->intro_length = loop * 50 / 3;
- out->loop_length = length - out->intro_length;
- }
- else
- {
- out->length = length;
- out->intro_length = length; // make it clear that track is no longer than length
- out->loop_length = 0;
- }
-
- // more stupidity where the field should have been left
- if ( strcmp( h.song, "Unknown Song" ) )
- GME_COPY_FIELD( h, out, song );
-
- if ( strcmp( h.game, "Unknown Game" ) )
- GME_COPY_FIELD( h, out, game );
-
- if ( strcmp( h.copyright, "Unknown Publisher" ) )
- GME_COPY_FIELD( h, out, copyright );
-
- if ( strcmp( h.dumper, "Unknown Person" ) )
- GME_COPY_FIELD( h, out, dumper );
-
- if ( strcmp( h.comment, "Header added by YMAMP" ) )
- GME_COPY_FIELD( h, out, comment );
- }
-}
-
-blargg_err_t Gym_Emu::track_info_( track_info_t* out, int ) const
-{
- get_gym_info( header_, track_length(), out );
- return 0;
-}
-
-static long gym_track_length( byte const* p, byte const* end )
-{
- long time = 0;
- while ( p < end )
- {
- switch ( *p++ )
- {
- case 0:
- time++;
- break;
-
- case 1:
- case 2:
- p += 2;
- break;
-
- case 3:
- p += 1;
- break;
- }
- }
- return time;
-}
-
-long Gym_Emu::track_length() const { return gym_track_length( data, data_end ); }
-
-static blargg_err_t check_header( byte const* in, long size, int* data_offset = 0 )
-{
- if ( size < 4 )
- return gme_wrong_file_type;
-
- if ( memcmp( in, "GYMX", 4 ) == 0 )
- {
- if ( size < Gym_Emu::header_size + 1 )
- return gme_wrong_file_type;
-
- if ( memcmp( ((Gym_Emu::header_t const*) in)->packed, "\0\0\0\0", 4 ) != 0 )
- return "Packed GYM file not supported";
-
- if ( data_offset )
- *data_offset = Gym_Emu::header_size;
- }
- else if ( *in > 3 )
- {
- return gme_wrong_file_type;
- }
-
- return 0;
-}
-
-struct Gym_File : Gme_Info_
-{
- byte const* file_begin;
- byte const* file_end;
- int data_offset;
-
- Gym_File() { set_type( gme_gym_type ); }
-
- blargg_err_t load_mem_( byte const* in, long size )
- {
- file_begin = in;
- file_end = in + size;
- data_offset = 0;
- return check_header( in, size, &data_offset );
- }
-
- blargg_err_t track_info_( track_info_t* out, int ) const
- {
- long length = gym_track_length( &file_begin [data_offset], file_end );
- get_gym_info( *(Gym_Emu::header_t const*) file_begin, length, out );
- return 0;
- }
-};
-
-static Music_Emu* new_gym_emu () { return BLARGG_NEW Gym_Emu ; }
-static Music_Emu* new_gym_file() { return BLARGG_NEW Gym_File; }
-
-gme_type_t_ const gme_gym_type [1] = { "Sega Genesis", 1, &new_gym_emu, &new_gym_file, "GYM", 0 };
-
-// Setup
-
-blargg_err_t Gym_Emu::set_sample_rate_( long sample_rate )
-{
- blip_eq_t eq( -32, 8000, sample_rate );
- apu.treble_eq( eq );
- dac_synth.treble_eq( eq );
- apu.volume( 0.135 * fm_gain * gain() );
- dac_synth.volume( 0.125 / 256 * fm_gain * gain() );
- double factor = Dual_Resampler::setup( oversample_factor, 0.990, fm_gain * gain() );
- fm_sample_rate = sample_rate * factor;
-
- RETURN_ERR( blip_buf.set_sample_rate( sample_rate, int (1000 / 60.0 / min_tempo) ) );
- blip_buf.clock_rate( clock_rate );
-
- RETURN_ERR( fm.set_rate( fm_sample_rate, base_clock / 7.0 ) );
- RETURN_ERR( Dual_Resampler::reset( long (1.0 / 60 / min_tempo * sample_rate) ) );
-
- return 0;
-}
-
-void Gym_Emu::set_tempo_( double t )
-{
- if ( t < min_tempo )
- {
- set_tempo( min_tempo );
- return;
- }
-
- if ( blip_buf.sample_rate() )
- {
- clocks_per_frame = long (clock_rate / 60 / tempo());
- Dual_Resampler::resize( long (sample_rate() / (60.0 * tempo())) );
- }
-}
-
-void Gym_Emu::mute_voices_( int mask )
-{
- Music_Emu::mute_voices_( mask );
- fm.mute_voices( mask );
- dac_muted = (mask & 0x40) != 0;
- apu.output( (mask & 0x80) ? 0 : &blip_buf );
-}
-
-blargg_err_t Gym_Emu::load_mem_( byte const* in, long size )
-{
- assert( offsetof (header_t,packed [4]) == header_size );
- int offset = 0;
- RETURN_ERR( check_header( in, size, &offset ) );
- set_voice_count( 8 );
-
- data = in + offset;
- data_end = in + size;
- loop_begin = 0;
-
- if ( offset )
- header_ = *(header_t const*) in;
- else
- memset( &header_, 0, sizeof header_ );
-
- return 0;
-}
-
-// Emulation
-
-blargg_err_t Gym_Emu::start_track_( int track )
-{
- RETURN_ERR( Music_Emu::start_track_( track ) );
-
- pos = data;
- loop_remain = get_le32( header_.loop_start );
-
- prev_dac_count = 0;
- dac_enabled = false;
- dac_amp = -1;
-
- fm.reset();
- apu.reset();
- blip_buf.clear();
- Dual_Resampler::clear();
- return 0;
-}
-
-void Gym_Emu::run_dac( int dac_count )
-{
- // Guess beginning and end of sample and adjust rate and buffer position accordingly.
-
- // count dac samples in next frame
- int next_dac_count = 0;
- const byte* p = this->pos;
- int cmd;
- while ( (cmd = *p++) != 0 )
- {
- int data = *p++;
- if ( cmd <= 2 )
- ++p;
- if ( cmd == 1 && data == 0x2A )
- next_dac_count++;
- }
-
- // detect beginning and end of sample
- int rate_count = dac_count;
- int start = 0;
- if ( !prev_dac_count && next_dac_count && dac_count < next_dac_count )
- {
- rate_count = next_dac_count;
- start = next_dac_count - dac_count;
- }
- else if ( prev_dac_count && !next_dac_count && dac_count < prev_dac_count )
- {
- rate_count = prev_dac_count;
- }
-
- // Evenly space samples within buffer section being used
- blip_resampled_time_t period = blip_buf.resampled_duration( clocks_per_frame ) / rate_count;
-
- blip_resampled_time_t time = blip_buf.resampled_time( 0 ) +
- period * start + (period >> 1);
-
- int dac_amp = this->dac_amp;
- if ( dac_amp < 0 )
- dac_amp = dac_buf [0];
-
- for ( int i = 0; i < dac_count; i++ )
- {
- int delta = dac_buf [i] - dac_amp;
- dac_amp += delta;
- dac_synth.offset_resampled( time, delta, &blip_buf );
- time += period;
- }
- this->dac_amp = dac_amp;
-}
-
-void Gym_Emu::parse_frame()
-{
- int dac_count = 0;
- const byte* pos = this->pos;
-
- if ( loop_remain && !--loop_remain )
- loop_begin = pos; // find loop on first time through sequence
-
- int cmd;
- while ( (cmd = *pos++) != 0 )
- {
- int data = *pos++;
- if ( cmd == 1 )
- {
- int data2 = *pos++;
- if ( data != 0x2A )
- {
- if ( data == 0x2B )
- dac_enabled = (data2 & 0x80) != 0;
-
- fm.write0( data, data2 );
- }
- else if ( dac_count < (int) sizeof dac_buf )
- {
- dac_buf [dac_count] = data2;
- dac_count += dac_enabled;
- }
- }
- else if ( cmd == 2 )
- {
- fm.write1( data, *pos++ );
- }
- else if ( cmd == 3 )
- {
- apu.write_data( 0, data );
- }
- else
- {
- // to do: many GYM streams are full of errors, and error count should
- // reflect cases where music is really having problems
- //log_error();
- --pos; // put data back
- }
- }
-
- // loop
- if ( pos >= data_end )
- {
- check( pos == data_end );
-
- if ( loop_begin )
- pos = loop_begin;
- else
- set_track_ended();
- }
- this->pos = pos;
-
- // dac
- if ( dac_count && !dac_muted )
- run_dac( dac_count );
- prev_dac_count = dac_count;
-}
-
-int Gym_Emu::play_frame( blip_time_t blip_time, int sample_count, sample_t* buf )
-{
- if ( !track_ended() )
- parse_frame();
-
- apu.end_frame( blip_time );
-
- memset( buf, 0, sample_count * sizeof *buf );
- fm.run( sample_count >> 1, buf );
-
- return sample_count;
-}
-
-blargg_err_t Gym_Emu::play_( long count, sample_t* out )
-{
- Dual_Resampler::dual_play( count, out, blip_buf );
- return 0;
-}
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Gym_Emu.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/Gym_Emu.h
deleted file mode 100644
index 05419ea2..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Gym_Emu.h
+++ /dev/null
@@ -1,82 +0,0 @@
-// Sega Genesis/Mega Drive GYM music file emulator
-// Includes with PCM timing recovery to improve sample quality.
-
-// Game_Music_Emu 0.5.2
-#ifndef GYM_EMU_H
-#define GYM_EMU_H
-
-#include "Dual_Resampler.h"
-#include "Ym2612_Emu.h"
-#include "Music_Emu.h"
-#include "Sms_Apu.h"
-
-class Gym_Emu : public Music_Emu, private Dual_Resampler {
-public:
- // GYM file header
- enum { header_size = 428 };
- struct header_t
- {
- char tag [4];
- char song [32];
- char game [32];
- char copyright [32];
- char emulator [32];
- char dumper [32];
- char comment [256];
- byte loop_start [4]; // in 1/60 seconds, 0 if not looped
- byte packed [4];
- };
-
- // Header for currently loaded file
- header_t const& header() const { return header_; }
-
- static gme_type_t static_type() { return gme_gym_type; }
-
-public:
- // deprecated
- Music_Emu::load;
- blargg_err_t load( header_t const& h, Data_Reader& in ) // use Remaining_Reader
- { return load_remaining_( &h, sizeof h, in ); }
- enum { gym_rate = 60 };
- long track_length() const; // use track_info()
-
-public:
- Gym_Emu();
- ~Gym_Emu();
-protected:
- blargg_err_t load_mem_( byte const*, long );
- blargg_err_t track_info_( track_info_t*, int track ) const;
- blargg_err_t set_sample_rate_( long sample_rate );
- blargg_err_t start_track_( int );
- blargg_err_t play_( long count, sample_t* );
- void mute_voices_( int );
- void set_tempo_( double );
- int play_frame( blip_time_t blip_time, int sample_count, sample_t* buf );
-private:
- // sequence data begin, loop begin, current position, end
- const byte* data;
- const byte* loop_begin;
- const byte* pos;
- const byte* data_end;
- blargg_long loop_remain; // frames remaining until loop beginning has been located
- header_t header_;
- double fm_sample_rate;
- blargg_long clocks_per_frame;
- void parse_frame();
-
- // dac (pcm)
- int dac_amp;
- int prev_dac_count;
- bool dac_enabled;
- bool dac_muted;
- void run_dac( int );
-
- // sound
- Blip_Buffer blip_buf;
- Ym2612_Emu fm;
- Blip_Synth<blip_med_quality,1> dac_synth;
- Sms_Apu apu;
- byte dac_buf [1024];
-};
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Hes_Apu.cpp b/plugins/gme/Game_Music_Emu-0.5.2/gme/Hes_Apu.cpp
deleted file mode 100644
index 22389121..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Hes_Apu.cpp
+++ /dev/null
@@ -1,315 +0,0 @@
-// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
-
-#include "Hes_Apu.h"
-
-#include <string.h>
-
-/* Copyright (C) 2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-bool const center_waves = true; // reduces asymmetry and clamping when starting notes
-
-Hes_Apu::Hes_Apu()
-{
- Hes_Osc* osc = &oscs [osc_count];
- do
- {
- osc--;
- osc->outputs [0] = 0;
- osc->outputs [1] = 0;
- osc->chans [0] = 0;
- osc->chans [1] = 0;
- osc->chans [2] = 0;
- }
- while ( osc != oscs );
-
- reset();
-}
-
-void Hes_Apu::reset()
-{
- latch = 0;
- balance = 0xFF;
-
- Hes_Osc* osc = &oscs [osc_count];
- do
- {
- osc--;
- memset( osc, 0, offsetof (Hes_Osc,outputs) );
- osc->noise_lfsr = 1;
- osc->control = 0x40;
- osc->balance = 0xFF;
- }
- while ( osc != oscs );
-}
-
-void Hes_Apu::osc_output( int index, Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right )
-{
- require( (unsigned) index < osc_count );
- oscs [index].chans [0] = center;
- oscs [index].chans [1] = left;
- oscs [index].chans [2] = right;
-
- Hes_Osc* osc = &oscs [osc_count];
- do
- {
- osc--;
- balance_changed( *osc );
- }
- while ( osc != oscs );
-}
-
-void Hes_Osc::run_until( synth_t& synth_, blip_time_t end_time )
-{
- Blip_Buffer* const osc_outputs_0 = outputs [0]; // cache often-used values
- if ( osc_outputs_0 && control & 0x80 )
- {
- int dac = this->dac;
-
- int const volume_0 = volume [0];
- {
- int delta = dac * volume_0 - last_amp [0];
- if ( delta )
- synth_.offset( last_time, delta, osc_outputs_0 );
- osc_outputs_0->set_modified();
- }
-
- Blip_Buffer* const osc_outputs_1 = outputs [1];
- int const volume_1 = volume [1];
- if ( osc_outputs_1 )
- {
- int delta = dac * volume_1 - last_amp [1];
- if ( delta )
- synth_.offset( last_time, delta, osc_outputs_1 );
- osc_outputs_1->set_modified();
- }
-
- blip_time_t time = last_time + delay;
- if ( time < end_time )
- {
- if ( noise & 0x80 )
- {
- if ( volume_0 | volume_1 )
- {
- // noise
- int const period = (32 - (noise & 0x1F)) * 64; // TODO: correct?
- unsigned noise_lfsr = this->noise_lfsr;
- do
- {
- int new_dac = 0x1F & -(noise_lfsr >> 1 & 1);
- // Implemented using "Galios configuration"
- // TODO: find correct LFSR algorithm
- noise_lfsr = (noise_lfsr >> 1) ^ (0xE008 & -(noise_lfsr & 1));
- //noise_lfsr = (noise_lfsr >> 1) ^ (0x6000 & -(noise_lfsr & 1));
- int delta = new_dac - dac;
- if ( delta )
- {
- dac = new_dac;
- synth_.offset( time, delta * volume_0, osc_outputs_0 );
- if ( osc_outputs_1 )
- synth_.offset( time, delta * volume_1, osc_outputs_1 );
- }
- time += period;
- }
- while ( time < end_time );
-
- this->noise_lfsr = noise_lfsr;
- assert( noise_lfsr );
- }
- }
- else if ( !(control & 0x40) )
- {
- // wave
- int phase = (this->phase + 1) & 0x1F; // pre-advance for optimal inner loop
- int period = this->period * 2;
- if ( period >= 14 && (volume_0 | volume_1) )
- {
- do
- {
- int new_dac = wave [phase];
- phase = (phase + 1) & 0x1F;
- int delta = new_dac - dac;
- if ( delta )
- {
- dac = new_dac;
- synth_.offset( time, delta * volume_0, osc_outputs_0 );
- if ( osc_outputs_1 )
- synth_.offset( time, delta * volume_1, osc_outputs_1 );
- }
- time += period;
- }
- while ( time < end_time );
- }
- else
- {
- if ( !period )
- {
- // TODO: Gekisha Boy assumes that period = 0 silences wave
- //period = 0x1000 * 2;
- period = 1;
- //if ( !(volume_0 | volume_1) )
- // dprintf( "Used period 0\n" );
- }
-
- // maintain phase when silent
- blargg_long count = (end_time - time + period - 1) / period;
- phase += count; // phase will be masked below
- time += count * period;
- }
- this->phase = (phase - 1) & 0x1F; // undo pre-advance
- }
- }
- time -= end_time;
- if ( time < 0 )
- time = 0;
- delay = time;
-
- this->dac = dac;
- last_amp [0] = dac * volume_0;
- last_amp [1] = dac * volume_1;
- }
- last_time = end_time;
-}
-
-void Hes_Apu::balance_changed( Hes_Osc& osc )
-{
- static short const log_table [32] = { // ~1.5 db per step
- #define ENTRY( factor ) short (factor * Hes_Osc::amp_range / 31.0 + 0.5)
- ENTRY( 0.000000 ),ENTRY( 0.005524 ),ENTRY( 0.006570 ),ENTRY( 0.007813 ),
- ENTRY( 0.009291 ),ENTRY( 0.011049 ),ENTRY( 0.013139 ),ENTRY( 0.015625 ),
- ENTRY( 0.018581 ),ENTRY( 0.022097 ),ENTRY( 0.026278 ),ENTRY( 0.031250 ),
- ENTRY( 0.037163 ),ENTRY( 0.044194 ),ENTRY( 0.052556 ),ENTRY( 0.062500 ),
- ENTRY( 0.074325 ),ENTRY( 0.088388 ),ENTRY( 0.105112 ),ENTRY( 0.125000 ),
- ENTRY( 0.148651 ),ENTRY( 0.176777 ),ENTRY( 0.210224 ),ENTRY( 0.250000 ),
- ENTRY( 0.297302 ),ENTRY( 0.353553 ),ENTRY( 0.420448 ),ENTRY( 0.500000 ),
- ENTRY( 0.594604 ),ENTRY( 0.707107 ),ENTRY( 0.840896 ),ENTRY( 1.000000 ),
- #undef ENTRY
- };
-
- int vol = (osc.control & 0x1F) - 0x1E * 2;
-
- int left = vol + (osc.balance >> 3 & 0x1E) + (balance >> 3 & 0x1E);
- if ( left < 0 ) left = 0;
-
- int right = vol + (osc.balance << 1 & 0x1E) + (balance << 1 & 0x1E);
- if ( right < 0 ) right = 0;
-
- left = log_table [left ];
- right = log_table [right];
-
- // optimizing for the common case of being centered also allows easy
- // panning using Effects_Buffer
- osc.outputs [0] = osc.chans [0]; // center
- osc.outputs [1] = 0;
- if ( left != right )
- {
- osc.outputs [0] = osc.chans [1]; // left
- osc.outputs [1] = osc.chans [2]; // right
- }
-
- if ( center_waves )
- {
- osc.last_amp [0] += (left - osc.volume [0]) * 16;
- osc.last_amp [1] += (right - osc.volume [1]) * 16;
- }
-
- osc.volume [0] = left;
- osc.volume [1] = right;
-}
-
-void Hes_Apu::write_data( blip_time_t time, int addr, int data )
-{
- if ( addr == 0x800 )
- {
- latch = data & 7;
- }
- else if ( addr == 0x801 )
- {
- if ( balance != data )
- {
- balance = data;
-
- Hes_Osc* osc = &oscs [osc_count];
- do
- {
- osc--;
- osc->run_until( synth, time );
- balance_changed( *oscs );
- }
- while ( osc != oscs );
- }
- }
- else if ( latch < osc_count )
- {
- Hes_Osc& osc = oscs [latch];
- osc.run_until( synth, time );
- switch ( addr )
- {
- case 0x802:
- osc.period = (osc.period & 0xF00) | data;
- break;
-
- case 0x803:
- osc.period = (osc.period & 0x0FF) | ((data & 0x0F) << 8);
- break;
-
- case 0x804:
- if ( osc.control & 0x40 & ~data )
- osc.phase = 0;
- osc.control = data;
- balance_changed( osc );
- break;
-
- case 0x805:
- osc.balance = data;
- balance_changed( osc );
- break;
-
- case 0x806:
- data &= 0x1F;
- if ( !(osc.control & 0x40) )
- {
- osc.wave [osc.phase] = data;
- osc.phase = (osc.phase + 1) & 0x1F;
- }
- else if ( osc.control & 0x80 )
- {
- osc.dac = data;
- }
- break;
-
- case 0x807:
- if ( &osc >= &oscs [4] )
- osc.noise = data;
- break;
-
- case 0x809:
- if ( !(data & 0x80) && (data & 0x03) != 0 )
- dprintf( "HES LFO not supported\n" );
- }
- }
-}
-
-void Hes_Apu::end_frame( blip_time_t end_time )
-{
- Hes_Osc* osc = &oscs [osc_count];
- do
- {
- osc--;
- if ( end_time > osc->last_time )
- osc->run_until( synth, end_time );
- assert( osc->last_time >= end_time );
- osc->last_time -= end_time;
- }
- while ( osc != oscs );
-}
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Hes_Apu.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/Hes_Apu.h
deleted file mode 100644
index ca0c932f..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Hes_Apu.h
+++ /dev/null
@@ -1,66 +0,0 @@
-// Turbo Grafx 16 (PC Engine) PSG sound chip emulator
-
-// Game_Music_Emu 0.5.2
-#ifndef HES_APU_H
-#define HES_APU_H
-
-#include "blargg_common.h"
-#include "Blip_Buffer.h"
-
-struct Hes_Osc
-{
- unsigned char wave [32];
- short volume [2];
- int last_amp [2];
- int delay;
- int period;
- unsigned char noise;
- unsigned char phase;
- unsigned char balance;
- unsigned char dac;
- blip_time_t last_time;
-
- Blip_Buffer* outputs [2];
- Blip_Buffer* chans [3];
- unsigned noise_lfsr;
- unsigned char control;
-
- enum { amp_range = 0x8000 };
- typedef Blip_Synth<blip_med_quality,1> synth_t;
-
- void run_until( synth_t& synth, blip_time_t );
-};
-
-class Hes_Apu {
-public:
- void treble_eq( blip_eq_t const& );
- void volume( double );
-
- enum { osc_count = 6 };
- void osc_output( int index, Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right );
-
- void reset();
-
- enum { start_addr = 0x0800 };
- enum { end_addr = 0x0809 };
- void write_data( blip_time_t, int addr, int data );
-
- void end_frame( blip_time_t );
-
-public:
- Hes_Apu();
-private:
- Hes_Osc oscs [osc_count];
- int latch;
- int balance;
- Hes_Osc::synth_t synth;
-
- void balance_changed( Hes_Osc& );
- void recalc_chans();
-};
-
-inline void Hes_Apu::volume( double v ) { synth.volume( 1.8 / osc_count / Hes_Osc::amp_range * v ); }
-
-inline void Hes_Apu::treble_eq( blip_eq_t const& eq ) { synth.treble_eq( eq ); }
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Hes_Cpu.cpp b/plugins/gme/Game_Music_Emu-0.5.2/gme/Hes_Cpu.cpp
deleted file mode 100644
index 2615a0bb..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Hes_Cpu.cpp
+++ /dev/null
@@ -1,1303 +0,0 @@
-// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
-
-#include "Hes_Cpu.h"
-
-#include "blargg_endian.h"
-
-//#include "hes_cpu_log.h"
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-// TODO: support T flag, including clearing it at appropriate times?
-
-// all zero-page should really use whatever is at page 1, but that would
-// reduce efficiency quite a bit
-int const ram_addr = 0x2000;
-
-#define FLUSH_TIME() (void) (s.time = s_time)
-#define CACHE_TIME() (void) (s_time = s.time)
-
-#include "hes_cpu_io.h"
-
-#include "blargg_source.h"
-
-#if BLARGG_NONPORTABLE
- #define PAGE_OFFSET( addr ) (addr)
-#else
- #define PAGE_OFFSET( addr ) ((addr) & (page_size - 1))
-#endif
-
-// status flags
-int const st_n = 0x80;
-int const st_v = 0x40;
-int const st_t = 0x20;
-int const st_b = 0x10;
-int const st_d = 0x08;
-int const st_i = 0x04;
-int const st_z = 0x02;
-int const st_c = 0x01;
-
-void Hes_Cpu::reset()
-{
- check( state == &state_ );
- state = &state_;
-
- state_.time = 0;
- state_.base = 0;
- irq_time_ = future_hes_time;
- end_time_ = future_hes_time;
-
- r.status = st_i;
- r.sp = 0;
- r.pc = 0;
- r.a = 0;
- r.x = 0;
- r.y = 0;
-
- blargg_verify_byte_order();
-}
-
-void Hes_Cpu::set_mmr( int reg, int bank )
-{
- assert( (unsigned) reg <= page_count ); // allow page past end to be set
- assert( (unsigned) bank < 0x100 );
- mmr [reg] = bank;
- uint8_t const* code = CPU_SET_MMR( this, reg, bank );
- state->code_map [reg] = code - PAGE_OFFSET( reg << page_shift );
-}
-
-#define TIME (s_time + s.base)
-
-#define READ( addr ) CPU_READ( this, (addr), TIME )
-#define WRITE( addr, data ) {CPU_WRITE( this, (addr), (data), TIME );}
-#define READ_LOW( addr ) (ram [int (addr)])
-#define WRITE_LOW( addr, data ) (void) (READ_LOW( addr ) = (data))
-#define READ_PROG( addr ) (s.code_map [(addr) >> page_shift] [PAGE_OFFSET( addr )])
-
-#define SET_SP( v ) (sp = ((v) + 1) | 0x100)
-#define GET_SP() ((sp - 1) & 0xFF)
-#define PUSH( v ) ((sp = (sp - 1) | 0x100), WRITE_LOW( sp, v ))
-
-// even on x86, using short and unsigned char was slower
-typedef int fint16;
-typedef unsigned fuint16;
-typedef unsigned fuint8;
-typedef blargg_long fint32;
-
-bool Hes_Cpu::run( hes_time_t end_time )
-{
- bool illegal_encountered = false;
- set_end_time( end_time );
- state_t s = this->state_;
- this->state = &s;
- // even on x86, using s.time in place of s_time was slower
- fint16 s_time = s.time;
-
- // registers
- fuint16 pc = r.pc;
- fuint8 a = r.a;
- fuint8 x = r.x;
- fuint8 y = r.y;
- fuint16 sp;
- SET_SP( r.sp );
-
- #define IS_NEG (nz & 0x8080)
-
- #define CALC_STATUS( out ) do {\
- out = status & (st_v | st_d | st_i);\
- out |= ((nz >> 8) | nz) & st_n;\
- out |= c >> 8 & st_c;\
- if ( !(nz & 0xFF) ) out |= st_z;\
- } while ( 0 )
-
- #define SET_STATUS( in ) do {\
- status = in & (st_v | st_d | st_i);\
- nz = in << 8;\
- c = nz;\
- nz |= ~in & st_z;\
- } while ( 0 )
-
- fuint8 status;
- fuint16 c; // carry set if (c & 0x100) != 0
- fuint16 nz; // Z set if (nz & 0xFF) == 0, N set if (nz & 0x8080) != 0
- {
- fuint8 temp = r.status;
- SET_STATUS( temp );
- }
-
- goto loop;
-branch_not_taken:
- s_time -= 2;
-loop:
-
- #ifndef NDEBUG
- {
- hes_time_t correct = end_time_;
- if ( !(status & st_i) && correct > irq_time_ )
- correct = irq_time_;
- check( s.base == correct );
- /*
- static long count;
- if ( count == 1844 ) Debugger();
- if ( s.base != correct ) dprintf( "%ld\n", count );
- count++;
- */
- }
- #endif
-
- check( (unsigned) GET_SP() < 0x100 );
- check( (unsigned) a < 0x100 );
- check( (unsigned) x < 0x100 );
-
- uint8_t const* instr = s.code_map [pc >> page_shift];
- fuint8 opcode;
-
- // TODO: eliminate this special case
- #if BLARGG_NONPORTABLE
- opcode = instr [pc];
- pc++;
- instr += pc;
- #else
- instr += PAGE_OFFSET( pc );
- opcode = *instr++;
- pc++;
- #endif
-
- // TODO: each reference lists slightly different timing values, ugh
- static uint8_t const clock_table [256] =
- {// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 1,7,3, 4,6,4,6,7,3,2,2,2,7,5,7,6,// 0
- 4,7,7, 4,6,4,6,7,2,5,2,2,7,5,7,6,// 1
- 7,7,3, 4,4,4,6,7,4,2,2,2,5,5,7,6,// 2
- 4,7,7, 2,4,4,6,7,2,5,2,2,5,5,7,6,// 3
- 7,7,3, 4,8,4,6,7,3,2,2,2,4,5,7,6,// 4
- 4,7,7, 5,2,4,6,7,2,5,3,2,2,5,7,6,// 5
- 7,7,2, 2,4,4,6,7,4,2,2,2,7,5,7,6,// 6
- 4,7,7,17,4,4,6,7,2,5,4,2,7,5,7,6,// 7
- 4,7,2, 7,4,4,4,7,2,2,2,2,5,5,5,6,// 8
- 4,7,7, 8,4,4,4,7,2,5,2,2,5,5,5,6,// 9
- 2,7,2, 7,4,4,4,7,2,2,2,2,5,5,5,6,// A
- 4,7,7, 8,4,4,4,7,2,5,2,2,5,5,5,6,// B
- 2,7,2,17,4,4,6,7,2,2,2,2,5,5,7,6,// C
- 4,7,7,17,2,4,6,7,2,5,3,2,2,5,7,6,// D
- 2,7,2,17,4,4,6,7,2,2,2,2,5,5,7,6,// E
- 4,7,7,17,2,4,6,7,2,5,4,2,2,5,7,6 // F
- }; // 0x00 was 8
-
- fuint16 data;
- data = clock_table [opcode];
- if ( (s_time += data) >= 0 )
- goto possibly_out_of_time;
-almost_out_of_time:
-
- data = *instr;
-
- #ifdef HES_CPU_LOG_H
- log_cpu( "new", pc - 1, opcode, instr [0], instr [1], instr [2],
- instr [3], instr [4], instr [5] );
- //log_opcode( opcode );
- #endif
-
- switch ( opcode )
- {
-possibly_out_of_time:
- if ( s_time < (int) data )
- goto almost_out_of_time;
- s_time -= data;
- goto out_of_time;
-
-// Macros
-
-#define GET_MSB() (instr [1])
-#define ADD_PAGE( out ) (pc++, out = data + 0x100 * GET_MSB());
-#define GET_ADDR() GET_LE16( instr )
-
-// TODO: is the penalty really always added? the original 6502 was much better
-//#define PAGE_CROSS_PENALTY( lsb ) (void) (s_time += (lsb) >> 8)
-#define PAGE_CROSS_PENALTY( lsb )
-
-// Branch
-
-// TODO: more efficient way to handle negative branch that wraps PC around
-#define BRANCH( cond )\
-{\
- fint16 offset = (BOOST::int8_t) data;\
- pc++;\
- if ( !(cond) ) goto branch_not_taken;\
- pc = BOOST::uint16_t (pc + offset);\
- goto loop;\
-}
-
- case 0xF0: // BEQ
- BRANCH( !((uint8_t) nz) );
-
- case 0xD0: // BNE
- BRANCH( (uint8_t) nz );
-
- case 0x10: // BPL
- BRANCH( !IS_NEG );
-
- case 0x90: // BCC
- BRANCH( !(c & 0x100) )
-
- case 0x30: // BMI
- BRANCH( IS_NEG )
-
- case 0x50: // BVC
- BRANCH( !(status & st_v) )
-
- case 0x70: // BVS
- BRANCH( status & st_v )
-
- case 0xB0: // BCS
- BRANCH( c & 0x100 )
-
- case 0x80: // BRA
- branch_taken:
- BRANCH( true );
-
- case 0xFF:
- if ( pc == idle_addr + 1 )
- goto idle_done;
- case 0x0F: // BBRn
- case 0x1F:
- case 0x2F:
- case 0x3F:
- case 0x4F:
- case 0x5F:
- case 0x6F:
- case 0x7F:
- case 0x8F: // BBSn
- case 0x9F:
- case 0xAF:
- case 0xBF:
- case 0xCF:
- case 0xDF:
- case 0xEF: {
- fuint16 t = 0x101 * READ_LOW( data );
- t ^= 0xFF;
- pc++;
- data = GET_MSB();
- BRANCH( t & (1 << (opcode >> 4)) )
- }
-
- case 0x4C: // JMP abs
- pc = GET_ADDR();
- goto loop;
-
- case 0x7C: // JMP (ind+X)
- data += x;
- case 0x6C:{// JMP (ind)
- data += 0x100 * GET_MSB();
- pc = GET_LE16( &READ_PROG( data ) );
- goto loop;
- }
-
-// Subroutine
-
- case 0x44: // BSR
- WRITE_LOW( 0x100 | (sp - 1), pc >> 8 );
- sp = (sp - 2) | 0x100;
- WRITE_LOW( sp, pc );
- goto branch_taken;
-
- case 0x20: { // JSR
- fuint16 temp = pc + 1;
- pc = GET_ADDR();
- WRITE_LOW( 0x100 | (sp - 1), temp >> 8 );
- sp = (sp - 2) | 0x100;
- WRITE_LOW( sp, temp );
- goto loop;
- }
-
- case 0x60: // RTS
- pc = 0x100 * READ_LOW( 0x100 | (sp - 0xFF) );
- pc += 1 + READ_LOW( sp );
- sp = (sp - 0xFE) | 0x100;
- goto loop;
-
- case 0x00: // BRK
- goto handle_brk;
-
-// Common
-
- case 0xBD:{// LDA abs,X
- PAGE_CROSS_PENALTY( data + x );
- fuint16 addr = GET_ADDR() + x;
- pc += 2;
- CPU_READ_FAST( this, addr, TIME, nz );
- a = nz;
- goto loop;
- }
-
- case 0x9D:{// STA abs,X
- fuint16 addr = GET_ADDR() + x;
- pc += 2;
- CPU_WRITE_FAST( this, addr, a, TIME );
- goto loop;
- }
-
- case 0x95: // STA zp,x
- data = uint8_t (data + x);
- case 0x85: // STA zp
- pc++;
- WRITE_LOW( data, a );
- goto loop;
-
- case 0xAE:{// LDX abs
- fuint16 addr = GET_ADDR();
- pc += 2;
- CPU_READ_FAST( this, addr, TIME, nz );
- x = nz;
- goto loop;
- }
-
- case 0xA5: // LDA zp
- a = nz = READ_LOW( data );
- pc++;
- goto loop;
-
-// Load/store
-
- {
- fuint16 addr;
- case 0x91: // STA (ind),Y
- addr = 0x100 * READ_LOW( uint8_t (data + 1) );
- addr += READ_LOW( data ) + y;
- pc++;
- goto sta_ptr;
-
- case 0x81: // STA (ind,X)
- data = uint8_t (data + x);
- case 0x92: // STA (ind)
- addr = 0x100 * READ_LOW( uint8_t (data + 1) );
- addr += READ_LOW( data );
- pc++;
- goto sta_ptr;
-
- case 0x99: // STA abs,Y
- data += y;
- case 0x8D: // STA abs
- addr = data + 0x100 * GET_MSB();
- pc += 2;
- sta_ptr:
- CPU_WRITE_FAST( this, addr, a, TIME );
- goto loop;
- }
-
- {
- fuint16 addr;
- case 0xA1: // LDA (ind,X)
- data = uint8_t (data + x);
- case 0xB2: // LDA (ind)
- addr = 0x100 * READ_LOW( uint8_t (data + 1) );
- addr += READ_LOW( data );
- pc++;
- goto a_nz_read_addr;
-
- case 0xB1:// LDA (ind),Y
- addr = READ_LOW( data ) + y;
- PAGE_CROSS_PENALTY( addr );
- addr += 0x100 * READ_LOW( (uint8_t) (data + 1) );
- pc++;
- goto a_nz_read_addr;
-
- case 0xB9: // LDA abs,Y
- data += y;
- PAGE_CROSS_PENALTY( data );
- case 0xAD: // LDA abs
- addr = data + 0x100 * GET_MSB();
- pc += 2;
- a_nz_read_addr:
- CPU_READ_FAST( this, addr, TIME, nz );
- a = nz;
- goto loop;
- }
-
- case 0xBE:{// LDX abs,y
- PAGE_CROSS_PENALTY( data + y );
- fuint16 addr = GET_ADDR() + y;
- pc += 2;
- FLUSH_TIME();
- x = nz = READ( addr );
- CACHE_TIME();
- goto loop;
- }
-
- case 0xB5: // LDA zp,x
- a = nz = READ_LOW( uint8_t (data + x) );
- pc++;
- goto loop;
-
- case 0xA9: // LDA #imm
- pc++;
- a = data;
- nz = data;
- goto loop;
-
-// Bit operations
-
- case 0x3C: // BIT abs,x
- data += x;
- case 0x2C:{// BIT abs
- fuint16 addr;
- ADD_PAGE( addr );
- FLUSH_TIME();
- nz = READ( addr );
- CACHE_TIME();
- goto bit_common;
- }
- case 0x34: // BIT zp,x
- data = uint8_t (data + x);
- case 0x24: // BIT zp
- data = READ_LOW( data );
- case 0x89: // BIT imm
- nz = data;
- bit_common:
- pc++;
- status &= ~st_v;
- status |= nz & st_v;
- if ( nz & a )
- goto loop; // Z should be clear, and nz must be non-zero if nz & a is
- nz <<= 8; // set Z flag without affecting N flag
- goto loop;
-
- {
- fuint16 addr;
-
- case 0xB3: // TST abs,x
- addr = GET_MSB() + x;
- goto tst_abs;
-
- case 0x93: // TST abs
- addr = GET_MSB();
- tst_abs:
- addr += 0x100 * instr [2];
- pc++;
- FLUSH_TIME();
- nz = READ( addr );
- CACHE_TIME();
- goto tst_common;
- }
-
- case 0xA3: // TST zp,x
- nz = READ_LOW( uint8_t (GET_MSB() + x) );
- goto tst_common;
-
- case 0x83: // TST zp
- nz = READ_LOW( GET_MSB() );
- tst_common:
- pc += 2;
- status &= ~st_v;
- status |= nz & st_v;
- if ( nz & data )
- goto loop; // Z should be clear, and nz must be non-zero if nz & data is
- nz <<= 8; // set Z flag without affecting N flag
- goto loop;
-
- {
- fuint16 addr;
- case 0x0C: // TSB abs
- case 0x1C: // TRB abs
- addr = GET_ADDR();
- pc++;
- goto txb_addr;
-
- // TODO: everyone lists different behaviors for the status flags, ugh
- case 0x04: // TSB zp
- case 0x14: // TRB zp
- addr = data + ram_addr;
- txb_addr:
- FLUSH_TIME();
- nz = a | READ( addr );
- if ( opcode & 0x10 )
- nz ^= a; // bits from a will already be set, so this clears them
- status &= ~st_v;
- status |= nz & st_v;
- pc++;
- WRITE( addr, nz );
- CACHE_TIME();
- goto loop;
- }
-
- case 0x07: // RMBn
- case 0x17:
- case 0x27:
- case 0x37:
- case 0x47:
- case 0x57:
- case 0x67:
- case 0x77:
- pc++;
- READ_LOW( data ) &= ~(1 << (opcode >> 4));
- goto loop;
-
- case 0x87: // SMBn
- case 0x97:
- case 0xA7:
- case 0xB7:
- case 0xC7:
- case 0xD7:
- case 0xE7:
- case 0xF7:
- pc++;
- READ_LOW( data ) |= 1 << ((opcode >> 4) - 8);
- goto loop;
-
-// Load/store
-
- case 0x9E: // STZ abs,x
- data += x;
- case 0x9C: // STZ abs
- ADD_PAGE( data );
- pc++;
- FLUSH_TIME();
- WRITE( data, 0 );
- CACHE_TIME();
- goto loop;
-
- case 0x74: // STZ zp,x
- data = uint8_t (data + x);
- case 0x64: // STZ zp
- pc++;
- WRITE_LOW( data, 0 );
- goto loop;
-
- case 0x94: // STY zp,x
- data = uint8_t (data + x);
- case 0x84: // STY zp
- pc++;
- WRITE_LOW( data, y );
- goto loop;
-
- case 0x96: // STX zp,y
- data = uint8_t (data + y);
- case 0x86: // STX zp
- pc++;
- WRITE_LOW( data, x );
- goto loop;
-
- case 0xB6: // LDX zp,y
- data = uint8_t (data + y);
- case 0xA6: // LDX zp
- data = READ_LOW( data );
- case 0xA2: // LDX #imm
- pc++;
- x = data;
- nz = data;
- goto loop;
-
- case 0xB4: // LDY zp,x
- data = uint8_t (data + x);
- case 0xA4: // LDY zp
- data = READ_LOW( data );
- case 0xA0: // LDY #imm
- pc++;
- y = data;
- nz = data;
- goto loop;
-
- case 0xBC: // LDY abs,X
- data += x;
- PAGE_CROSS_PENALTY( data );
- case 0xAC:{// LDY abs
- fuint16 addr = data + 0x100 * GET_MSB();
- pc += 2;
- FLUSH_TIME();
- y = nz = READ( addr );
- CACHE_TIME();
- goto loop;
- }
-
- {
- fuint8 temp;
- case 0x8C: // STY abs
- temp = y;
- goto store_abs;
-
- case 0x8E: // STX abs
- temp = x;
- store_abs:
- fuint16 addr = GET_ADDR();
- pc += 2;
- FLUSH_TIME();
- WRITE( addr, temp );
- CACHE_TIME();
- goto loop;
- }
-
-// Compare
-
- case 0xEC:{// CPX abs
- fuint16 addr = GET_ADDR();
- pc++;
- FLUSH_TIME();
- data = READ( addr );
- CACHE_TIME();
- goto cpx_data;
- }
-
- case 0xE4: // CPX zp
- data = READ_LOW( data );
- case 0xE0: // CPX #imm
- cpx_data:
- nz = x - data;
- pc++;
- c = ~nz;
- nz &= 0xFF;
- goto loop;
-
- case 0xCC:{// CPY abs
- fuint16 addr = GET_ADDR();
- pc++;
- FLUSH_TIME();
- data = READ( addr );
- CACHE_TIME();
- goto cpy_data;
- }
-
- case 0xC4: // CPY zp
- data = READ_LOW( data );
- case 0xC0: // CPY #imm
- cpy_data:
- nz = y - data;
- pc++;
- c = ~nz;
- nz &= 0xFF;
- goto loop;
-
-// Logical
-
-#define ARITH_ADDR_MODES( op )\
- case op - 0x04: /* (ind,x) */\
- data = uint8_t (data + x);\
- case op + 0x0D: /* (ind) */\
- data = 0x100 * READ_LOW( uint8_t (data + 1) ) + READ_LOW( data );\
- goto ptr##op;\
- case op + 0x0C:{/* (ind),y */\
- fuint16 temp = READ_LOW( data ) + y;\
- PAGE_CROSS_PENALTY( temp );\
- data = temp + 0x100 * READ_LOW( uint8_t (data + 1) );\
- goto ptr##op;\
- }\
- case op + 0x10: /* zp,X */\
- data = uint8_t (data + x);\
- case op + 0x00: /* zp */\
- data = READ_LOW( data );\
- goto imm##op;\
- case op + 0x14: /* abs,Y */\
- data += y;\
- goto ind##op;\
- case op + 0x18: /* abs,X */\
- data += x;\
- ind##op:\
- PAGE_CROSS_PENALTY( data );\
- case op + 0x08: /* abs */\
- ADD_PAGE( data );\
- ptr##op:\
- FLUSH_TIME();\
- data = READ( data );\
- CACHE_TIME();\
- case op + 0x04: /* imm */\
- imm##op:
-
- ARITH_ADDR_MODES( 0xC5 ) // CMP
- nz = a - data;
- pc++;
- c = ~nz;
- nz &= 0xFF;
- goto loop;
-
- ARITH_ADDR_MODES( 0x25 ) // AND
- nz = (a &= data);
- pc++;
- goto loop;
-
- ARITH_ADDR_MODES( 0x45 ) // EOR
- nz = (a ^= data);
- pc++;
- goto loop;
-
- ARITH_ADDR_MODES( 0x05 ) // ORA
- nz = (a |= data);
- pc++;
- goto loop;
-
-// Add/subtract
-
- ARITH_ADDR_MODES( 0xE5 ) // SBC
- data ^= 0xFF;
- goto adc_imm;
-
- ARITH_ADDR_MODES( 0x65 ) // ADC
- adc_imm: {
- if ( status & st_d )
- dprintf( "Decimal mode not supported\n" );
- fint16 carry = c >> 8 & 1;
- fint16 ov = (a ^ 0x80) + carry + (BOOST::int8_t) data; // sign-extend
- status &= ~st_v;
- status |= ov >> 2 & 0x40;
- c = nz = a + data + carry;
- pc++;
- a = (uint8_t) nz;
- goto loop;
- }
-
-// Shift/rotate
-
- case 0x4A: // LSR A
- c = 0;
- case 0x6A: // ROR A
- nz = c >> 1 & 0x80;
- c = a << 8;
- nz |= a >> 1;
- a = nz;
- goto loop;
-
- case 0x0A: // ASL A
- nz = a << 1;
- c = nz;
- a = (uint8_t) nz;
- goto loop;
-
- case 0x2A: { // ROL A
- nz = a << 1;
- fint16 temp = c >> 8 & 1;
- c = nz;
- nz |= temp;
- a = (uint8_t) nz;
- goto loop;
- }
-
- case 0x5E: // LSR abs,X
- data += x;
- case 0x4E: // LSR abs
- c = 0;
- case 0x6E: // ROR abs
- ror_abs: {
- ADD_PAGE( data );
- FLUSH_TIME();
- int temp = READ( data );
- nz = (c >> 1 & 0x80) | (temp >> 1);
- c = temp << 8;
- goto rotate_common;
- }
-
- case 0x3E: // ROL abs,X
- data += x;
- goto rol_abs;
-
- case 0x1E: // ASL abs,X
- data += x;
- case 0x0E: // ASL abs
- c = 0;
- case 0x2E: // ROL abs
- rol_abs:
- ADD_PAGE( data );
- nz = c >> 8 & 1;
- FLUSH_TIME();
- nz |= (c = READ( data ) << 1);
- rotate_common:
- pc++;
- WRITE( data, (uint8_t) nz );
- CACHE_TIME();
- goto loop;
-
- case 0x7E: // ROR abs,X
- data += x;
- goto ror_abs;
-
- case 0x76: // ROR zp,x
- data = uint8_t (data + x);
- goto ror_zp;
-
- case 0x56: // LSR zp,x
- data = uint8_t (data + x);
- case 0x46: // LSR zp
- c = 0;
- case 0x66: // ROR zp
- ror_zp: {
- int temp = READ_LOW( data );
- nz = (c >> 1 & 0x80) | (temp >> 1);
- c = temp << 8;
- goto write_nz_zp;
- }
-
- case 0x36: // ROL zp,x
- data = uint8_t (data + x);
- goto rol_zp;
-
- case 0x16: // ASL zp,x
- data = uint8_t (data + x);
- case 0x06: // ASL zp
- c = 0;
- case 0x26: // ROL zp
- rol_zp:
- nz = c >> 8 & 1;
- nz |= (c = READ_LOW( data ) << 1);
- goto write_nz_zp;
-
-// Increment/decrement
-
-#define INC_DEC_AXY( reg, n ) reg = uint8_t (nz = reg + n); goto loop;
-
- case 0x1A: // INA
- INC_DEC_AXY( a, +1 )
-
- case 0xE8: // INX
- INC_DEC_AXY( x, +1 )
-
- case 0xC8: // INY
- INC_DEC_AXY( y, +1 )
-
- case 0x3A: // DEA
- INC_DEC_AXY( a, -1 )
-
- case 0xCA: // DEX
- INC_DEC_AXY( x, -1 )
-
- case 0x88: // DEY
- INC_DEC_AXY( y, -1 )
-
- case 0xF6: // INC zp,x
- data = uint8_t (data + x);
- case 0xE6: // INC zp
- nz = 1;
- goto add_nz_zp;
-
- case 0xD6: // DEC zp,x
- data = uint8_t (data + x);
- case 0xC6: // DEC zp
- nz = (unsigned) -1;
- add_nz_zp:
- nz += READ_LOW( data );
- write_nz_zp:
- pc++;
- WRITE_LOW( data, nz );
- goto loop;
-
- case 0xFE: // INC abs,x
- data = x + GET_ADDR();
- goto inc_ptr;
-
- case 0xEE: // INC abs
- data = GET_ADDR();
- inc_ptr:
- nz = 1;
- goto inc_common;
-
- case 0xDE: // DEC abs,x
- data = x + GET_ADDR();
- goto dec_ptr;
-
- case 0xCE: // DEC abs
- data = GET_ADDR();
- dec_ptr:
- nz = (unsigned) -1;
- inc_common:
- FLUSH_TIME();
- nz += READ( data );
- pc += 2;
- WRITE( data, (uint8_t) nz );
- CACHE_TIME();
- goto loop;
-
-// Transfer
-
- case 0xA8: // TAY
- y = a;
- nz = a;
- goto loop;
-
- case 0x98: // TYA
- a = y;
- nz = y;
- goto loop;
-
- case 0xAA: // TAX
- x = a;
- nz = a;
- goto loop;
-
- case 0x8A: // TXA
- a = x;
- nz = x;
- goto loop;
-
- case 0x9A: // TXS
- SET_SP( x ); // verified (no flag change)
- goto loop;
-
- case 0xBA: // TSX
- x = nz = GET_SP();
- goto loop;
-
- #define SWAP_REGS( r1, r2 ) {\
- fuint8 t = r1;\
- r1 = r2;\
- r2 = t;\
- goto loop;\
- }
-
- case 0x02: // SXY
- SWAP_REGS( x, y );
-
- case 0x22: // SAX
- SWAP_REGS( a, x );
-
- case 0x42: // SAY
- SWAP_REGS( a, y );
-
- case 0x62: // CLA
- a = 0;
- goto loop;
-
- case 0x82: // CLX
- x = 0;
- goto loop;
-
- case 0xC2: // CLY
- y = 0;
- goto loop;
-
-// Stack
-
- case 0x48: // PHA
- PUSH( a );
- goto loop;
-
- case 0xDA: // PHX
- PUSH( x );
- goto loop;
-
- case 0x5A: // PHY
- PUSH( y );
- goto loop;
-
- case 0x40:{// RTI
- fuint8 temp = READ_LOW( sp );
- pc = READ_LOW( 0x100 | (sp - 0xFF) );
- pc |= READ_LOW( 0x100 | (sp - 0xFE) ) * 0x100;
- sp = (sp - 0xFD) | 0x100;
- data = status;
- SET_STATUS( temp );
- this->r.status = status; // update externally-visible I flag
- if ( (data ^ status) & st_i )
- {
- hes_time_t new_time = end_time_;
- if ( !(status & st_i) && new_time > irq_time_ )
- new_time = irq_time_;
- blargg_long delta = s.base - new_time;
- s.base = new_time;
- s_time += delta;
- }
- goto loop;
- }
-
- #define POP() READ_LOW( sp ); sp = (sp - 0xFF) | 0x100
-
- case 0x68: // PLA
- a = nz = POP();
- goto loop;
-
- case 0xFA: // PLX
- x = nz = POP();
- goto loop;
-
- case 0x7A: // PLY
- y = nz = POP();
- goto loop;
-
- case 0x28:{// PLP
- fuint8 temp = POP();
- fuint8 changed = status ^ temp;
- SET_STATUS( temp );
- if ( !(changed & st_i) )
- goto loop; // I flag didn't change
- if ( status & st_i )
- goto handle_sei;
- goto handle_cli;
- }
- #undef POP
-
- case 0x08: { // PHP
- fuint8 temp;
- CALC_STATUS( temp );
- PUSH( temp | st_b );
- goto loop;
- }
-
-// Flags
-
- case 0x38: // SEC
- c = (unsigned) ~0;
- goto loop;
-
- case 0x18: // CLC
- c = 0;
- goto loop;
-
- case 0xB8: // CLV
- status &= ~st_v;
- goto loop;
-
- case 0xD8: // CLD
- status &= ~st_d;
- goto loop;
-
- case 0xF8: // SED
- status |= st_d;
- goto loop;
-
- case 0x58: // CLI
- if ( !(status & st_i) )
- goto loop;
- status &= ~st_i;
- handle_cli: {
- this->r.status = status; // update externally-visible I flag
- blargg_long delta = s.base - irq_time_;
- if ( delta <= 0 )
- {
- if ( TIME < irq_time_ )
- goto loop;
- goto delayed_cli;
- }
- s.base = irq_time_;
- s_time += delta;
- if ( s_time < 0 )
- goto loop;
-
- if ( delta >= s_time + 1 )
- {
- // delayed irq until after next instruction
- s.base += s_time + 1;
- s_time = -1;
- irq_time_ = s.base; // TODO: remove, as only to satisfy debug check in loop
- goto loop;
- }
- delayed_cli:
- dprintf( "Delayed CLI not supported\n" ); // TODO: implement
- goto loop;
- }
-
- case 0x78: // SEI
- if ( status & st_i )
- goto loop;
- status |= st_i;
- handle_sei: {
- this->r.status = status; // update externally-visible I flag
- blargg_long delta = s.base - end_time_;
- s.base = end_time_;
- s_time += delta;
- if ( s_time < 0 )
- goto loop;
- dprintf( "Delayed SEI not supported\n" ); // TODO: implement
- goto loop;
- }
-
-// Special
-
- case 0x53:{// TAM
- fuint8 const bits = data; // avoid using data across function call
- pc++;
- for ( int i = 0; i < 8; i++ )
- if ( bits & (1 << i) )
- set_mmr( i, a );
- goto loop;
- }
-
- case 0x43:{// TMA
- pc++;
- byte const* in = mmr;
- do
- {
- if ( data & 1 )
- a = *in;
- in++;
- }
- while ( (data >>= 1) != 0 );
- goto loop;
- }
-
- case 0x03: // ST0
- case 0x13: // ST1
- case 0x23:{// ST2
- fuint16 addr = opcode >> 4;
- if ( addr )
- addr++;
- pc++;
- FLUSH_TIME();
- CPU_WRITE_VDP( this, addr, data, TIME );
- CACHE_TIME();
- goto loop;
- }
-
- case 0xEA: // NOP
- goto loop;
-
- case 0x54: // CSL
- dprintf( "CSL not supported\n" );
- illegal_encountered = true;
- goto loop;
-
- case 0xD4: // CSH
- goto loop;
-
- case 0xF4: { // SET
- //fuint16 operand = GET_MSB();
- dprintf( "SET not handled\n" );
- //switch ( data )
- //{
- //}
- illegal_encountered = true;
- goto loop;
- }
-
-// Block transfer
-
- {
- fuint16 in_alt;
- fint16 in_inc;
- fuint16 out_alt;
- fint16 out_inc;
-
- case 0xE3: // TIA
- in_alt = 0;
- goto bxfer_alt;
-
- case 0xF3: // TAI
- in_alt = 1;
- bxfer_alt:
- in_inc = in_alt ^ 1;
- out_alt = in_inc;
- out_inc = in_alt;
- goto bxfer;
-
- case 0xD3: // TIN
- in_inc = 1;
- out_inc = 0;
- goto bxfer_no_alt;
-
- case 0xC3: // TDD
- in_inc = -1;
- out_inc = -1;
- goto bxfer_no_alt;
-
- case 0x73: // TII
- in_inc = 1;
- out_inc = 1;
- bxfer_no_alt:
- in_alt = 0;
- out_alt = 0;
- bxfer:
- fuint16 in = GET_LE16( instr + 0 );
- fuint16 out = GET_LE16( instr + 2 );
- int count = GET_LE16( instr + 4 );
- if ( !count )
- count = 0x10000;
- pc += 6;
- WRITE_LOW( 0x100 | (sp - 1), y );
- WRITE_LOW( 0x100 | (sp - 2), a );
- WRITE_LOW( 0x100 | (sp - 3), x );
- FLUSH_TIME();
- do
- {
- // TODO: reads from $0800-$1400 in I/O page return 0 and don't access I/O
- fuint8 t = READ( in );
- in += in_inc;
- in &= 0xFFFF;
- s.time += 6;
- if ( in_alt )
- in_inc = -in_inc;
- WRITE( out, t );
- out += out_inc;
- out &= 0xFFFF;
- if ( out_alt )
- out_inc = -out_inc;
- }
- while ( --count );
- CACHE_TIME();
- goto loop;
- }
-
-// Illegal
-
- default:
- assert( (unsigned) opcode <= 0xFF );
- dprintf( "Illegal opcode $%02X at $%04X\n", (int) opcode, (int) pc - 1 );
- illegal_encountered = true;
- goto loop;
- }
- assert( false );
-
- int result_;
-handle_brk:
- pc++;
- result_ = 6;
-
-interrupt:
- {
- s_time += 7;
-
- WRITE_LOW( 0x100 | (sp - 1), pc >> 8 );
- WRITE_LOW( 0x100 | (sp - 2), pc );
- pc = GET_LE16( &READ_PROG( 0xFFF0 ) + result_ );
-
- sp = (sp - 3) | 0x100;
- fuint8 temp;
- CALC_STATUS( temp );
- if ( result_ == 6 )
- temp |= st_b;
- WRITE_LOW( sp, temp );
-
- status &= ~st_d;
- status |= st_i;
- this->r.status = status; // update externally-visible I flag
-
- blargg_long delta = s.base - end_time_;
- s.base = end_time_;
- s_time += delta;
- goto loop;
- }
-
-idle_done:
- s_time = 0;
-out_of_time:
- pc--;
- FLUSH_TIME();
- CPU_DONE( this, TIME, result_ );
- CACHE_TIME();
- if ( result_ > 0 )
- goto interrupt;
- if ( s_time < 0 )
- goto loop;
-
- s.time = s_time;
-
- r.pc = pc;
- r.sp = GET_SP();
- r.a = a;
- r.x = x;
- r.y = y;
-
- {
- fuint8 temp;
- CALC_STATUS( temp );
- r.status = temp;
- }
-
- this->state_ = s;
- this->state = &this->state_;
-
- return illegal_encountered;
-}
-
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Hes_Cpu.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/Hes_Cpu.h
deleted file mode 100644
index 437d0908..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Hes_Cpu.h
+++ /dev/null
@@ -1,125 +0,0 @@
-// PC Engine CPU emulator for use with HES music files
-
-// Game_Music_Emu 0.5.2
-#ifndef HES_CPU_H
-#define HES_CPU_H
-
-#include "blargg_common.h"
-#include <limits.h>
-
-typedef blargg_long hes_time_t; // clock cycle count
-typedef unsigned hes_addr_t; // 16-bit address
-enum { future_hes_time = LONG_MAX / 2 + 1 };
-
-class Hes_Cpu {
-public:
- typedef BOOST::uint8_t uint8_t;
-
- void reset();
-
- enum { page_size = 0x2000 };
- enum { page_shift = 13 };
- enum { page_count = 8 };
- void set_mmr( int reg, int bank );
-
- uint8_t const* get_code( hes_addr_t );
-
- uint8_t ram [page_size];
-
- // not kept updated during a call to run()
- struct registers_t {
- BOOST::uint16_t pc;
- uint8_t a;
- uint8_t x;
- uint8_t y;
- uint8_t status;
- uint8_t sp;
- };
- registers_t r;
-
- // page mapping registers
- uint8_t mmr [page_count + 1];
-
- // Set end_time and run CPU from current time. Returns true if any illegal
- // instructions were encountered.
- bool run( hes_time_t end_time );
-
- // Time of beginning of next instruction to be executed
- hes_time_t time() const { return state->time + state->base; }
- void set_time( hes_time_t t ) { state->time = t - state->base; }
- void adjust_time( int delta ) { state->time += delta; }
-
- hes_time_t irq_time() const { return irq_time_; }
- void set_irq_time( hes_time_t );
-
- hes_time_t end_time() const { return end_time_; }
- void set_end_time( hes_time_t );
-
- void end_frame( hes_time_t );
-
- // Attempt to execute instruction here results in CPU advancing time to
- // lesser of irq_time() and end_time() (or end_time() if IRQs are
- // disabled)
- enum { idle_addr = 0x1FFF };
-
- // Can read this many bytes past end of a page
- enum { cpu_padding = 8 };
-
-public:
- Hes_Cpu() { state = &state_; }
- enum { irq_inhibit = 0x04 };
-private:
- // noncopyable
- Hes_Cpu( const Hes_Cpu& );
- Hes_Cpu& operator = ( const Hes_Cpu& );
-
- struct state_t {
- uint8_t const* code_map [page_count + 1];
- hes_time_t base;
- blargg_long time;
- };
- state_t* state; // points to state_ or a local copy within run()
- state_t state_;
- hes_time_t irq_time_;
- hes_time_t end_time_;
-
- void set_code_page( int, void const* );
- inline int update_end_time( hes_time_t end, hes_time_t irq );
-};
-
-inline BOOST::uint8_t const* Hes_Cpu::get_code( hes_addr_t addr )
-{
- return state->code_map [addr >> page_shift] + addr
- #if !BLARGG_NONPORTABLE
- % (unsigned) page_size
- #endif
- ;
-}
-
-inline int Hes_Cpu::update_end_time( hes_time_t t, hes_time_t irq )
-{
- if ( irq < t && !(r.status & irq_inhibit) ) t = irq;
- int delta = state->base - t;
- state->base = t;
- return delta;
-}
-
-inline void Hes_Cpu::set_irq_time( hes_time_t t )
-{
- state->time += update_end_time( end_time_, (irq_time_ = t) );
-}
-
-inline void Hes_Cpu::set_end_time( hes_time_t t )
-{
- state->time += update_end_time( (end_time_ = t), irq_time_ );
-}
-
-inline void Hes_Cpu::end_frame( hes_time_t t )
-{
- assert( state == &state_ );
- state_.base -= t;
- if ( irq_time_ < future_hes_time ) irq_time_ -= t;
- if ( end_time_ < future_hes_time ) end_time_ -= t;
-}
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Hes_Emu.cpp b/plugins/gme/Game_Music_Emu-0.5.2/gme/Hes_Emu.cpp
deleted file mode 100644
index fafb2666..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Hes_Emu.cpp
+++ /dev/null
@@ -1,529 +0,0 @@
-// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
-
-#include "Hes_Emu.h"
-
-#include "blargg_endian.h"
-#include <string.h>
-
-/* Copyright (C) 2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-int const timer_mask = 0x04;
-int const vdp_mask = 0x02;
-int const i_flag_mask = 0x04;
-int const unmapped = 0xFF;
-
-long const period_60hz = 262 * 455L; // scanlines * clocks per scanline
-
-Hes_Emu::Hes_Emu()
-{
- timer.raw_load = 0;
- set_type( gme_hes_type );
-
- static const char* const names [Hes_Apu::osc_count] = {
- "Wave 1", "Wave 2", "Wave 3", "Wave 4", "Multi 1", "Multi 2"
- };
- set_voice_names( names );
-
- static int const types [Hes_Apu::osc_count] = {
- wave_type | 0, wave_type | 1, wave_type | 2, wave_type | 3,
- mixed_type | 0, mixed_type | 1
- };
- set_voice_types( types );
- set_silence_lookahead( 6 );
- set_gain( 1.11 );
-}
-
-Hes_Emu::~Hes_Emu() { }
-
-void Hes_Emu::unload()
-{
- rom.clear();
- Music_Emu::unload();
-}
-
-// Track info
-
-static byte const* copy_field( byte const* in, char* out )
-{
- if ( in )
- {
- int len = 0x20;
- if ( in [0x1F] && !in [0x2F] )
- len = 0x30; // fields are sometimes 16 bytes longer (ugh)
-
- // since text fields are where any data could be, detect non-text
- // and fields with data after zero byte terminator
-
- int i = 0;
- for ( i = 0; i < len && in [i]; i++ )
- if ( ((in [i] + 1) & 0xFF) < ' ' + 1 ) // also treat 0xFF as non-text
- return 0; // non-ASCII found
-
- for ( ; i < len; i++ )
- if ( in [i] )
- return 0; // data after terminator
-
- Gme_File::copy_field_( out, (char const*) in, len );
- in += len;
- }
- return in;
-}
-
-static void copy_hes_fields( byte const* in, track_info_t* out )
-{
- if ( *in >= ' ' )
- {
- in = copy_field( in, out->game );
- in = copy_field( in, out->author );
- in = copy_field( in, out->copyright );
- }
-}
-
-blargg_err_t Hes_Emu::track_info_( track_info_t* out, int ) const
-{
- copy_hes_fields( rom.begin() + 0x20, out );
- return 0;
-}
-
-static blargg_err_t check_hes_header( void const* header )
-{
- if ( memcmp( header, "HESM", 4 ) )
- return gme_wrong_file_type;
- return 0;
-}
-
-struct Hes_File : Gme_Info_
-{
- struct header_t {
- char header [Hes_Emu::header_size];
- char unused [0x20];
- byte fields [0x30 * 3];
- } h;
-
- Hes_File() { set_type( gme_hes_type ); }
-
- blargg_err_t load_( Data_Reader& in )
- {
- assert( offsetof (header_t,fields) == Hes_Emu::header_size + 0x20 );
- blargg_err_t err = in.read( &h, sizeof h );
- if ( err )
- return (err == in.eof_error ? gme_wrong_file_type : err);
- return check_hes_header( &h );
- }
-
- blargg_err_t track_info_( track_info_t* out, int ) const
- {
- copy_hes_fields( h.fields, out );
- return 0;
- }
-};
-
-static Music_Emu* new_hes_emu () { return BLARGG_NEW Hes_Emu ; }
-static Music_Emu* new_hes_file() { return BLARGG_NEW Hes_File; }
-
-gme_type_t_ const gme_hes_type [1] = { "PC Engine", 256, &new_hes_emu, &new_hes_file, "HES", 1 };
-
-// Setup
-
-blargg_err_t Hes_Emu::load_( Data_Reader& in )
-{
- assert( offsetof (header_t,unused [4]) == header_size );
- RETURN_ERR( rom.load( in, header_size, &header_, unmapped ) );
-
- RETURN_ERR( check_hes_header( header_.tag ) );
-
- if ( header_.vers != 0 )
- set_warning( "Unknown file version" );
-
- if ( memcmp( header_.data_tag, "DATA", 4 ) )
- set_warning( "Data header missing" );
-
- if ( memcmp( header_.unused, "\0\0\0\0", 4 ) )
- set_warning( "Unknown header data" );
-
- // File spec supports multiple blocks, but I haven't found any, and
- // many files have bad sizes in the only block, so it's simpler to
- // just try to load the damn data as best as possible.
-
- long addr = get_le32( header_.addr );
- long size = get_le32( header_.size );
- long const rom_max = 0x100000;
- if ( addr & ~(rom_max - 1) )
- {
- set_warning( "Invalid address" );
- addr &= rom_max - 1;
- }
- if ( (unsigned long) (addr + size) > (unsigned long) rom_max )
- set_warning( "Invalid size" );
-
- if ( size != rom.file_size() )
- {
- if ( size <= rom.file_size() - 4 && !memcmp( rom.begin() + size, "DATA", 4 ) )
- set_warning( "Multiple DATA not supported" );
- else if ( size < rom.file_size() )
- set_warning( "Extra file data" );
- else
- set_warning( "Missing file data" );
- }
-
- rom.set_addr( addr );
-
- set_voice_count( apu.osc_count );
-
- apu.volume( gain() );
-
- return setup_buffer( 7159091 );
-}
-
-void Hes_Emu::update_eq( blip_eq_t const& eq )
-{
- apu.treble_eq( eq );
-}
-
-void Hes_Emu::set_voice( int i, Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right )
-{
- apu.osc_output( i, center, left, right );
-}
-
-// Emulation
-
-void Hes_Emu::recalc_timer_load()
-{
- timer.load = timer.raw_load * timer_base + 1;
-}
-
-void Hes_Emu::set_tempo_( double t )
-{
- play_period = hes_time_t (period_60hz / t);
- timer_base = int (1024 / t);
- recalc_timer_load();
-}
-
-blargg_err_t Hes_Emu::start_track_( int track )
-{
- RETURN_ERR( Classic_Emu::start_track_( track ) );
-
- memset( ram, 0, sizeof ram ); // some HES music relies on zero fill
- memset( sgx, 0, sizeof sgx );
-
- apu.reset();
- cpu::reset();
-
- for ( unsigned i = 0; i < sizeof header_.banks; i++ )
- set_mmr( i, header_.banks [i] );
- set_mmr( page_count, 0xFF ); // unmapped beyond end of address space
-
- irq.disables = timer_mask | vdp_mask;
- irq.timer = future_hes_time;
- irq.vdp = future_hes_time;
-
- timer.enabled = false;
- timer.raw_load= 0x80;
- timer.count = timer.load;
- timer.fired = false;
- timer.last_time = 0;
-
- vdp.latch = 0;
- vdp.control = 0;
- vdp.next_vbl = 0;
-
- ram [0x1FF] = (idle_addr - 1) >> 8;
- ram [0x1FE] = (idle_addr - 1) & 0xFF;
- r.sp = 0xFD;
- r.pc = get_le16( header_.init_addr );
- r.a = track;
-
- recalc_timer_load();
- last_frame_hook = 0;
-
- return 0;
-}
-
-// Hardware
-
-void Hes_Emu::cpu_write_vdp( int addr, int data )
-{
- switch ( addr )
- {
- case 0:
- vdp.latch = data & 0x1F;
- break;
-
- case 2:
- if ( vdp.latch == 5 )
- {
- if ( data & 0x04 )
- set_warning( "Scanline interrupt unsupported" );
- run_until( time() );
- vdp.control = data;
- irq_changed();
- }
- else
- {
- dprintf( "VDP not supported: $%02X <- $%02X\n", vdp.latch, data );
- }
- break;
-
- case 3:
- dprintf( "VDP MSB not supported: $%02X <- $%02X\n", vdp.latch, data );
- break;
- }
-}
-
-void Hes_Emu::cpu_write_( hes_addr_t addr, int data )
-{
- if ( unsigned (addr - apu.start_addr) <= apu.end_addr - apu.start_addr )
- {
- GME_APU_HOOK( this, addr - apu.start_addr, data );
- // avoid going way past end when a long block xfer is writing to I/O space
- hes_time_t t = min( time(), end_time() + 8 );
- apu.write_data( t, addr, data );
- return;
- }
-
- hes_time_t time = this->time();
- switch ( addr )
- {
- case 0x0000:
- case 0x0002:
- case 0x0003:
- cpu_write_vdp( addr, data );
- return;
-
- case 0x0C00: {
- run_until( time );
- timer.raw_load = (data & 0x7F) + 1;
- recalc_timer_load();
- timer.count = timer.load;
- break;
- }
-
- case 0x0C01:
- data &= 1;
- if ( timer.enabled == data )
- return;
- run_until( time );
- timer.enabled = data;
- if ( data )
- timer.count = timer.load;
- break;
-
- case 0x1402:
- run_until( time );
- irq.disables = data;
- if ( (data & 0xF8) && (data & 0xF8) != 0xF8 ) // flag questionable values
- dprintf( "Int mask: $%02X\n", data );
- break;
-
- case 0x1403:
- run_until( time );
- if ( timer.enabled )
- timer.count = timer.load;
- timer.fired = false;
- break;
-
-#ifndef NDEBUG
- case 0x1000: // I/O port
- case 0x0402: // palette
- case 0x0403:
- case 0x0404:
- case 0x0405:
- return;
-
- default:
- dprintf( "unmapped write $%04X <- $%02X\n", addr, data );
- return;
-#endif
- }
-
- irq_changed();
-}
-
-int Hes_Emu::cpu_read_( hes_addr_t addr )
-{
- hes_time_t time = this->time();
- addr &= page_size - 1;
- switch ( addr )
- {
- case 0x0000:
- if ( irq.vdp > time )
- return 0;
- irq.vdp = future_hes_time;
- run_until( time );
- irq_changed();
- return 0x20;
-
- case 0x0002:
- case 0x0003:
- dprintf( "VDP read not supported: %d\n", addr );
- return 0;
-
- case 0x0C01:
- //return timer.enabled; // TODO: remove?
- case 0x0C00:
- run_until( time );
- dprintf( "Timer count read\n" );
- return (unsigned) (timer.count - 1) / timer_base;
-
- case 0x1402:
- return irq.disables;
-
- case 0x1403:
- {
- int status = 0;
- if ( irq.timer <= time ) status |= timer_mask;
- if ( irq.vdp <= time ) status |= vdp_mask;
- return status;
- }
-
- #ifndef NDEBUG
- case 0x1000: // I/O port
- case 0x180C: // CD-ROM
- case 0x180D:
- break;
-
- default:
- dprintf( "unmapped read $%04X\n", addr );
- #endif
- }
-
- return unmapped;
-}
-
-// see hes_cpu_io.h for core read/write functions
-
-// Emulation
-
-void Hes_Emu::run_until( hes_time_t present )
-{
- while ( vdp.next_vbl < present )
- vdp.next_vbl += play_period;
-
- hes_time_t elapsed = present - timer.last_time;
- if ( elapsed > 0 )
- {
- if ( timer.enabled )
- {
- timer.count -= elapsed;
- if ( timer.count <= 0 )
- timer.count += timer.load;
- }
- timer.last_time = present;
- }
-}
-
-void Hes_Emu::irq_changed()
-{
- hes_time_t present = time();
-
- if ( irq.timer > present )
- {
- irq.timer = future_hes_time;
- if ( timer.enabled && !timer.fired )
- irq.timer = present + timer.count;
- }
-
- if ( irq.vdp > present )
- {
- irq.vdp = future_hes_time;
- if ( vdp.control & 0x08 )
- irq.vdp = vdp.next_vbl;
- }
-
- hes_time_t time = future_hes_time;
- if ( !(irq.disables & timer_mask) ) time = irq.timer;
- if ( !(irq.disables & vdp_mask) ) time = min( time, irq.vdp );
-
- set_irq_time( time );
-}
-
-int Hes_Emu::cpu_done()
-{
- check( time() >= end_time() ||
- (!(r.status & i_flag_mask) && time() >= irq_time()) );
-
- if ( !(r.status & i_flag_mask) )
- {
- hes_time_t present = time();
-
- if ( irq.timer <= present && !(irq.disables & timer_mask) )
- {
- timer.fired = true;
- irq.timer = future_hes_time;
- irq_changed(); // overkill, but not worth writing custom code
- #if GME_FRAME_HOOK_DEFINED
- {
- unsigned const threshold = period_60hz / 30;
- unsigned long elapsed = present - last_frame_hook;
- if ( elapsed - period_60hz + threshold / 2 < threshold )
- {
- last_frame_hook = present;
- GME_FRAME_HOOK( this );
- }
- }
- #endif
- return 0x0A;
- }
-
- if ( irq.vdp <= present && !(irq.disables & vdp_mask) )
- {
- // work around for bugs with music not acknowledging VDP
- //run_until( present );
- //irq.vdp = future_hes_time;
- //irq_changed();
- #if GME_FRAME_HOOK_DEFINED
- last_frame_hook = present;
- GME_FRAME_HOOK( this );
- #endif
- return 0x08;
- }
- }
- return 0;
-}
-
-static void adjust_time( blargg_long& time, hes_time_t delta )
-{
- if ( time < future_hes_time )
- {
- time -= delta;
- if ( time < 0 )
- time = 0;
- }
-}
-
-blargg_err_t Hes_Emu::run_clocks( blip_time_t& duration_, int )
-{
- blip_time_t const duration = duration_; // cache
-
- if ( cpu::run( duration ) )
- set_warning( "Emulation error (illegal instruction)" );
-
- check( time() >= duration );
- //check( time() - duration < 20 ); // Txx instruction could cause going way over
-
- run_until( duration );
-
- // end time frame
- timer.last_time -= duration;
- vdp.next_vbl -= duration;
- #if GME_FRAME_HOOK_DEFINED
- last_frame_hook -= duration;
- #endif
- cpu::end_frame( duration );
- ::adjust_time( irq.timer, duration );
- ::adjust_time( irq.vdp, duration );
- apu.end_frame( duration );
-
- return 0;
-}
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Hes_Emu.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/Hes_Emu.h
deleted file mode 100644
index 9951eb6a..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Hes_Emu.h
+++ /dev/null
@@ -1,94 +0,0 @@
-// TurboGrafx-16/PC Engine HES music file emulator
-
-// Game_Music_Emu 0.5.2
-#ifndef HES_EMU_H
-#define HES_EMU_H
-
-#include "Classic_Emu.h"
-#include "Hes_Apu.h"
-#include "Hes_Cpu.h"
-
-class Hes_Emu : private Hes_Cpu, public Classic_Emu {
- typedef Hes_Cpu cpu;
-public:
- // HES file header
- enum { header_size = 0x20 };
- struct header_t
- {
- byte tag [4];
- byte vers;
- byte first_track;
- byte init_addr [2];
- byte banks [8];
- byte data_tag [4];
- byte size [4];
- byte addr [4];
- byte unused [4];
- };
-
- // Header for currently loaded file
- header_t const& header() const { return header_; }
-
- static gme_type_t static_type() { return gme_hes_type; }
-
-public:
- Hes_Emu();
- ~Hes_Emu();
-protected:
- blargg_err_t track_info_( track_info_t*, int track ) const;
- blargg_err_t load_( Data_Reader& );
- blargg_err_t start_track_( int );
- blargg_err_t run_clocks( blip_time_t&, int );
- void set_tempo_( double );
- void set_voice( int, Blip_Buffer*, Blip_Buffer*, Blip_Buffer* );
- void update_eq( blip_eq_t const& );
- void unload();
-public: private: friend class Hes_Cpu;
- byte* write_pages [page_count + 1]; // 0 if unmapped or I/O space
-
- int cpu_read_( hes_addr_t );
- int cpu_read( hes_addr_t );
- void cpu_write_( hes_addr_t, int data );
- void cpu_write( hes_addr_t, int );
- void cpu_write_vdp( int addr, int data );
- byte const* cpu_set_mmr( int page, int bank );
- int cpu_done();
-private:
- Rom_Data<page_size> rom;
- header_t header_;
- hes_time_t play_period;
- hes_time_t last_frame_hook;
- int timer_base;
-
- struct {
- hes_time_t last_time;
- blargg_long count;
- blargg_long load;
- int raw_load;
- byte enabled;
- byte fired;
- } timer;
-
- struct {
- hes_time_t next_vbl;
- byte latch;
- byte control;
- } vdp;
-
- struct {
- hes_time_t timer;
- hes_time_t vdp;
- byte disables;
- } irq;
-
- void recalc_timer_load();
-
- // large items
- Hes_Apu apu;
- byte sgx [3 * page_size + cpu_padding];
-
- void irq_changed();
- void run_until( hes_time_t );
-};
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Kss_Cpu.cpp b/plugins/gme/Game_Music_Emu-0.5.2/gme/Kss_Cpu.cpp
deleted file mode 100644
index 37c4a724..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Kss_Cpu.cpp
+++ /dev/null
@@ -1,1706 +0,0 @@
-// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
-
-/*
-Last validated with zexall 2006.11.14 2:19 PM
-* Doesn't implement the R register or immediate interrupt after EI.
-* Address wrap-around isn't completely correct, but is prevented from crashing emulator.
-*/
-
-#include "Kss_Cpu.h"
-
-#include "blargg_endian.h"
-#include <string.h>
-
-//#include "z80_cpu_log.h"
-
-/* Copyright (C) 2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#define SYNC_TIME() (void) (s.time = s_time)
-#define RELOAD_TIME() (void) (s_time = s.time)
-
-// Callbacks to emulator
-
-#define CPU_OUT( cpu, addr, data, time )\
- kss_cpu_out( this, time, addr, data )
-
-#define CPU_IN( cpu, addr, time )\
- kss_cpu_in( this, time, addr )
-
-#define CPU_WRITE( cpu, addr, data, time )\
- (SYNC_TIME(), kss_cpu_write( this, addr, data ))
-
-#include "blargg_source.h"
-
-// flags, named with hex value for clarity
-int const S80 = 0x80;
-int const Z40 = 0x40;
-int const F20 = 0x20;
-int const H10 = 0x10;
-int const F08 = 0x08;
-int const V04 = 0x04;
-int const P04 = 0x04;
-int const N02 = 0x02;
-int const C01 = 0x01;
-
-#define SZ28P( n ) szpc [n]
-#define SZ28PC( n ) szpc [n]
-#define SZ28C( n ) (szpc [n] & ~P04)
-#define SZ28( n ) SZ28C( n )
-
-#define SET_R( n ) (void) (r.r = n)
-#define GET_R() (r.r)
-
-Kss_Cpu::Kss_Cpu()
-{
- state = &state_;
-
- for ( int i = 0x100; --i >= 0; )
- {
- int even = 1;
- for ( int p = i; p; p >>= 1 )
- even ^= p;
- int n = (i & (S80 | F20 | F08)) | ((even & 1) * P04);
- szpc [i] = n;
- szpc [i + 0x100] = n | C01;
- }
- szpc [0x000] |= Z40;
- szpc [0x100] |= Z40;
-}
-
-inline void Kss_Cpu::set_page( int i, void* write, void const* read )
-{
- blargg_long offset = KSS_CPU_PAGE_OFFSET( i * (blargg_long) page_size );
- state->write [i] = (byte *) write - offset;
- state->read [i] = (byte const*) read - offset;
-}
-
-void Kss_Cpu::reset( void* unmapped_write, void const* unmapped_read )
-{
- check( state == &state_ );
- state = &state_;
- state_.time = 0;
- state_.base = 0;
- end_time_ = 0;
-
- for ( int i = 0; i < page_count + 1; i++ )
- set_page( i, unmapped_write, unmapped_read );
-
- memset( &r, 0, sizeof r );
-}
-
-void Kss_Cpu::map_mem( unsigned addr, blargg_ulong size, void* write, void const* read )
-{
- // address range must begin and end on page boundaries
- require( addr % page_size == 0 );
- require( size % page_size == 0 );
-
- unsigned first_page = addr / page_size;
- for ( unsigned i = size / page_size; i--; )
- {
- blargg_long offset = i * (blargg_long) page_size;
- set_page( first_page + i, (byte*) write + offset, (byte const*) read + offset );
- }
-}
-
-#define TIME (s_time + s.base)
-#define RW_MEM( addr, rw ) (s.rw [(addr) >> page_shift] [KSS_CPU_PAGE_OFFSET( addr )])
-#define READ_PROG( addr ) RW_MEM( addr, read )
-#define READ( addr ) READ_PROG( addr )
-//#define WRITE( addr, data ) (void) (RW_MEM( addr, write ) = data)
-#define WRITE( addr, data ) CPU_WRITE( this, addr, data, TIME )
-#define READ_WORD( addr ) GET_LE16( &READ( addr ) )
-#define WRITE_WORD( addr, data ) SET_LE16( &RW_MEM( addr, write ), data )
-#define IN( addr ) CPU_IN( this, addr, TIME )
-#define OUT( addr, data ) CPU_OUT( this, addr, data, TIME )
-
-#if BLARGG_BIG_ENDIAN
- #define R8( n, offset ) ((r8_ - offset) [n])
-#elif BLARGG_LITTLE_ENDIAN
- #define R8( n, offset ) ((r8_ - offset) [(n) ^ 1])
-#else
- #error "Byte order of CPU must be known"
-#endif
-
-//#define R16( n, shift, offset ) (r16_ [((n) >> shift) - (offset >> shift)])
-
-// help compiler see that it can just adjust stack offset, saving an extra instruction
-#define R16( n, shift, offset )\
- (*(uint16_t*) ((char*) r16_ - (offset >> (shift - 1)) + ((n) >> (shift - 1))))
-
-#define CASE5( a, b, c, d, e ) case 0x##a:case 0x##b:case 0x##c:case 0x##d:case 0x##e
-#define CASE6( a, b, c, d, e, f ) CASE5( a, b, c, d, e ): case 0x##f
-#define CASE7( a, b, c, d, e, f, g ) CASE6( a, b, c, d, e, f ): case 0x##g
-#define CASE8( a, b, c, d, e, f, g, h ) CASE7( a, b, c, d, e, f, g ): case 0x##h
-
-// high four bits are $ED time - 8, low four bits are $DD/$FD time - 8
-static byte const ed_dd_timing [0x100] = {
-//0 1 2 3 4 5 6 7 8 9 A B C D E F
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x06,0x0C,0x02,0x00,0x00,0x03,0x00,0x00,0x07,0x0C,0x02,0x00,0x00,0x03,0x00,
-0x00,0x00,0x00,0x00,0x0F,0x0F,0x0B,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x10,0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x10,
-0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x10,0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x10,
-0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0xA0,0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0xA0,
-0x4B,0x4B,0x7B,0xCB,0x0B,0x6B,0x00,0x0B,0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00,
-0x80,0x80,0x80,0x80,0x00,0x00,0x0B,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x0B,0x00,
-0xD0,0xD0,0xD0,0xD0,0x00,0x00,0x0B,0x00,0xD0,0xD0,0xD0,0xD0,0x00,0x00,0x0B,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x06,0x00,0x0F,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,
-};
-
-// even on x86, using short and unsigned char was slower
-typedef int fint16;
-typedef unsigned fuint16;
-typedef unsigned fuint8;
-
-bool Kss_Cpu::run( cpu_time_t end_time )
-{
- set_end_time( end_time );
- state_t s = this->state_;
- this->state = &s;
- bool warning = false;
-
- typedef BOOST::int8_t int8_t;
-
- union {
- regs_t rg;
- pairs_t rp;
- uint8_t r8_ [8]; // indexed
- uint16_t r16_ [4];
- };
- rg = this->r.b;
-
- cpu_time_t s_time = s.time;
- fuint16 pc = r.pc;
- fuint16 sp = r.sp;
- fuint16 ix = r.ix; // TODO: keep in memory for direct access?
- fuint16 iy = r.iy;
- int flags = r.b.flags;
-
- goto loop;
-jr_not_taken:
- s_time -= 5;
- goto loop;
-call_not_taken:
- s_time -= 7;
-jp_not_taken:
- pc += 2;
-loop:
-
- check( (unsigned long) pc < 0x10000 );
- check( (unsigned long) sp < 0x10000 );
- check( (unsigned) flags < 0x100 );
- check( (unsigned) ix < 0x10000 );
- check( (unsigned) iy < 0x10000 );
-
- uint8_t const* instr = s.read [pc >> page_shift];
-#define GET_ADDR() GET_LE16( instr )
-
- fuint8 opcode;
-
- // TODO: eliminate this special case
- #if BLARGG_NONPORTABLE
- opcode = instr [pc];
- pc++;
- instr += pc;
- #else
- instr += KSS_CPU_PAGE_OFFSET( pc );
- opcode = *instr++;
- pc++;
- #endif
-
- static byte const base_timing [0x100] = {
- // 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 4,10, 7, 6, 4, 4, 7, 4, 4,11, 7, 6, 4, 4, 7, 4, // 0
- 13,10, 7, 6, 4, 4, 7, 4,12,11, 7, 6, 4, 4, 7, 4, // 1
- 12,10,16, 6, 4, 4, 7, 4,12,11,16, 6, 4, 4, 7, 4, // 2
- 12,10,13, 6,11,11,10, 4,12,11,13, 6, 4, 4, 7, 4, // 3
- 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 4
- 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 5
- 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 6
- 7, 7, 7, 7, 7, 7, 4, 7, 4, 4, 4, 4, 4, 4, 7, 4, // 7
- 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 8
- 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 9
- 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // A
- 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // B
- 11,10,10,10,17,11, 7,11,11,10,10, 8,17,17, 7,11, // C
- 11,10,10,11,17,11, 7,11,11, 4,10,11,17, 8, 7,11, // D
- 11,10,10,19,17,11, 7,11,11, 4,10, 4,17, 8, 7,11, // E
- 11,10,10, 4,17,11, 7,11,11, 6,10, 4,17, 8, 7,11, // F
- };
-
- fuint16 data;
- data = base_timing [opcode];
- if ( (s_time += data) >= 0 )
- goto possibly_out_of_time;
-almost_out_of_time:
-
- data = READ_PROG( pc );
-
- #ifdef Z80_CPU_LOG_H
- //log_opcode( opcode, READ_PROG( pc ) );
- z80_log_regs( rg.a, rp.bc, rp.de, rp.hl, sp, ix, iy );
- z80_cpu_log( "new", pc - 1, opcode, READ_PROG( pc ),
- READ_PROG( pc + 1 ), READ_PROG( pc + 2 ) );
- #endif
-
- switch ( opcode )
- {
-possibly_out_of_time:
- if ( s_time < (int) data )
- goto almost_out_of_time;
- s_time -= data;
- goto out_of_time;
-
-// Common
-
- case 0x00: // NOP
- CASE7( 40, 49, 52, 5B, 64, 6D, 7F ): // LD B,B etc.
- goto loop;
-
- case 0x08:{// EX AF,AF'
- int temp = r.alt.b.a;
- r.alt.b.a = rg.a;
- rg.a = temp;
-
- temp = r.alt.b.flags;
- r.alt.b.flags = flags;
- flags = temp;
- goto loop;
- }
-
- case 0xD3: // OUT (imm),A
- pc++;
- OUT( data + rg.a * 0x100, rg.a );
- goto loop;
-
- case 0x2E: // LD L,imm
- pc++;
- rg.l = data;
- goto loop;
-
- case 0x3E: // LD A,imm
- pc++;
- rg.a = data;
- goto loop;
-
- case 0x3A:{// LD A,(addr)
- fuint16 addr = GET_ADDR();
- pc += 2;
- rg.a = READ( addr );
- goto loop;
- }
-
-// Conditional
-
-#define ZERO (flags & Z40)
-#define CARRY (flags & C01)
-#define EVEN (flags & P04)
-#define MINUS (flags & S80)
-
-// JR
-// TODO: more efficient way to handle negative branch that wraps PC around
-#define JR( cond ) {\
- int offset = (BOOST::int8_t) data;\
- pc++;\
- if ( !(cond) )\
- goto jr_not_taken;\
- pc = uint16_t (pc + offset);\
- goto loop;\
-}
-
- case 0x20: JR( !ZERO ) // JR NZ,disp
- case 0x28: JR( ZERO ) // JR Z,disp
- case 0x30: JR( !CARRY ) // JR NC,disp
- case 0x38: JR( CARRY ) // JR C,disp
- case 0x18: JR( true ) // JR disp
-
- case 0x10:{// DJNZ disp
- int temp = rg.b - 1;
- rg.b = temp;
- JR( temp )
- }
-
-// JP
-#define JP( cond ) if ( !(cond) ) goto jp_not_taken; pc = GET_ADDR(); goto loop;
-
- case 0xC2: JP( !ZERO ) // JP NZ,addr
- case 0xCA: JP( ZERO ) // JP Z,addr
- case 0xD2: JP( !CARRY ) // JP NC,addr
- case 0xDA: JP( CARRY ) // JP C,addr
- case 0xE2: JP( !EVEN ) // JP PO,addr
- case 0xEA: JP( EVEN ) // JP PE,addr
- case 0xF2: JP( !MINUS ) // JP P,addr
- case 0xFA: JP( MINUS ) // JP M,addr
-
- case 0xC3: // JP addr
- pc = GET_ADDR();
- goto loop;
-
- case 0xE9: // JP HL
- pc = rp.hl;
- goto loop;
-
-// RET
-#define RET( cond ) if ( cond ) goto ret_taken; s_time -= 6; goto loop;
-
- case 0xC0: RET( !ZERO ) // RET NZ
- case 0xC8: RET( ZERO ) // RET Z
- case 0xD0: RET( !CARRY ) // RET NC
- case 0xD8: RET( CARRY ) // RET C
- case 0xE0: RET( !EVEN ) // RET PO
- case 0xE8: RET( EVEN ) // RET PE
- case 0xF0: RET( !MINUS ) // RET P
- case 0xF8: RET( MINUS ) // RET M
-
- case 0xC9: // RET
- ret_taken:
- pc = READ_WORD( sp );
- sp = uint16_t (sp + 2);
- goto loop;
-
-// CALL
-#define CALL( cond ) if ( cond ) goto call_taken; goto call_not_taken;
-
- case 0xC4: CALL( !ZERO ) // CALL NZ,addr
- case 0xCC: CALL( ZERO ) // CALL Z,addr
- case 0xD4: CALL( !CARRY ) // CALL NC,addr
- case 0xDC: CALL( CARRY ) // CALL C,addr
- case 0xE4: CALL( !EVEN ) // CALL PO,addr
- case 0xEC: CALL( EVEN ) // CALL PE,addr
- case 0xF4: CALL( !MINUS ) // CALL P,addr
- case 0xFC: CALL( MINUS ) // CALL M,addr
-
- case 0xCD:{// CALL addr
- call_taken:
- fuint16 addr = pc + 2;
- pc = GET_ADDR();
- sp = uint16_t (sp - 2);
- WRITE_WORD( sp, addr );
- goto loop;
- }
-
- case 0xFF: // RST
- if ( pc > idle_addr )
- goto hit_idle_addr;
- CASE7( C7, CF, D7, DF, E7, EF, F7 ):
- data = pc;
- pc = opcode & 0x38;
- goto push_data;
-
-// PUSH/POP
- case 0xF5: // PUSH AF
- data = rg.a * 0x100u + flags;
- goto push_data;
-
- case 0xC5: // PUSH BC
- case 0xD5: // PUSH DE
- case 0xE5: // PUSH HL
- data = R16( opcode, 4, 0xC5 );
- push_data:
- sp = uint16_t (sp - 2);
- WRITE_WORD( sp, data );
- goto loop;
-
- case 0xF1: // POP AF
- flags = READ( sp );
- rg.a = READ( sp + 1 );
- sp = uint16_t (sp + 2);
- goto loop;
-
- case 0xC1: // POP BC
- case 0xD1: // POP DE
- case 0xE1: // POP HL
- R16( opcode, 4, 0xC1 ) = READ_WORD( sp );
- sp = uint16_t (sp + 2);
- goto loop;
-
-// ADC/ADD/SBC/SUB
- case 0x96: // SUB (HL)
- case 0x86: // ADD (HL)
- flags &= ~C01;
- case 0x9E: // SBC (HL)
- case 0x8E: // ADC (HL)
- data = READ( rp.hl );
- goto adc_data;
-
- case 0xD6: // SUB A,imm
- case 0xC6: // ADD imm
- flags &= ~C01;
- case 0xDE: // SBC A,imm
- case 0xCE: // ADC imm
- pc++;
- goto adc_data;
-
- CASE7( 90, 91, 92, 93, 94, 95, 97 ): // SUB r
- CASE7( 80, 81, 82, 83, 84, 85, 87 ): // ADD r
- flags &= ~C01;
- CASE7( 98, 99, 9A, 9B, 9C, 9D, 9F ): // SBC r
- CASE7( 88, 89, 8A, 8B, 8C, 8D, 8F ): // ADC r
- data = R8( opcode & 7, 0 );
- adc_data: {
- int result = data + (flags & C01);
- data ^= rg.a;
- flags = opcode >> 3 & N02; // bit 4 is set in subtract opcodes
- if ( flags )
- result = -result;
- result += rg.a;
- data ^= result;
- flags |=(data & H10) |
- ((data - -0x80) >> 6 & V04) |
- SZ28C( result & 0x1FF );
- rg.a = result;
- goto loop;
- }
-
-// CP
- case 0xBE: // CP (HL)
- data = READ( rp.hl );
- goto cp_data;
-
- case 0xFE: // CP imm
- pc++;
- goto cp_data;
-
- CASE7( B8, B9, BA, BB, BC, BD, BF ): // CP r
- data = R8( opcode, 0xB8 );
- cp_data: {
- int result = rg.a - data;
- flags = N02 | (data & (F20 | F08)) | (result >> 8 & C01);
- data ^= rg.a;
- flags |=(((result ^ rg.a) & data) >> 5 & V04) |
- (((data & H10) ^ result) & (S80 | H10));
- if ( (uint8_t) result )
- goto loop;
- flags |= Z40;
- goto loop;
- }
-
-// ADD HL,rp
-
- case 0x39: // ADD HL,SP
- data = sp;
- goto add_hl_data;
-
- case 0x09: // ADD HL,BC
- case 0x19: // ADD HL,DE
- case 0x29: // ADD HL,HL
- data = R16( opcode, 4, 0x09 );
- add_hl_data: {
- blargg_ulong sum = rp.hl + data;
- data ^= rp.hl;
- rp.hl = sum;
- flags = (flags & (S80 | Z40 | V04)) |
- (sum >> 16) |
- (sum >> 8 & (F20 | F08)) |
- ((data ^ sum) >> 8 & H10);
- goto loop;
- }
-
- case 0x27:{// DAA
- int a = rg.a;
- if ( a > 0x99 )
- flags |= C01;
-
- int adjust = 0x60 & -(flags & C01);
-
- if ( flags & H10 || (a & 0x0F) > 9 )
- adjust |= 0x06;
-
- if ( flags & N02 )
- adjust = -adjust;
- a += adjust;
-
- flags = (flags & (C01 | N02)) |
- ((rg.a ^ a) & H10) |
- SZ28P( (uint8_t) a );
- rg.a = a;
- goto loop;
- }
- /*
- case 0x27:{// DAA
- // more optimized, but probably not worth the obscurity
- int f = (rg.a + (0xFF - 0x99)) >> 8 | flags; // (a > 0x99 ? C01 : 0) | flags
- int adjust = 0x60 & -(f & C01); // f & C01 ? 0x60 : 0
-
- if ( (((rg.a + (0x0F - 9)) ^ rg.a) | f) & H10 ) // flags & H10 || (rg.a & 0x0F) > 9
- adjust |= 0x06;
-
- if ( f & N02 )
- adjust = -adjust;
- int a = rg.a + adjust;
-
- flags = (f & (N02 | C01)) | ((rg.a ^ a) & H10) | SZ28P( (uint8_t) a );
- rg.a = a;
- goto loop;
- }
- */
-
-// INC/DEC
- case 0x34: // INC (HL)
- data = READ( rp.hl ) + 1;
- WRITE( rp.hl, data );
- goto inc_set_flags;
-
- CASE7( 04, 0C, 14, 1C, 24, 2C, 3C ): // INC r
- data = ++R8( opcode >> 3, 0 );
- inc_set_flags:
- flags = (flags & C01) |
- (((data & 0x0F) - 1) & H10) |
- SZ28( (uint8_t) data );
- if ( data != 0x80 )
- goto loop;
- flags |= V04;
- goto loop;
-
- case 0x35: // DEC (HL)
- data = READ( rp.hl ) - 1;
- WRITE( rp.hl, data );
- goto dec_set_flags;
-
- CASE7( 05, 0D, 15, 1D, 25, 2D, 3D ): // DEC r
- data = --R8( opcode >> 3, 0 );
- dec_set_flags:
- flags = (flags & C01) | N02 |
- (((data & 0x0F) + 1) & H10) |
- SZ28( (uint8_t) data );
- if ( data != 0x7F )
- goto loop;
- flags |= V04;
- goto loop;
-
- case 0x03: // INC BC
- case 0x13: // INC DE
- case 0x23: // INC HL
- R16( opcode, 4, 0x03 )++;
- goto loop;
-
- case 0x33: // INC SP
- sp = uint16_t (sp + 1);
- goto loop;
-
- case 0x0B: // DEC BC
- case 0x1B: // DEC DE
- case 0x2B: // DEC HL
- R16( opcode, 4, 0x0B )--;
- goto loop;
-
- case 0x3B: // DEC SP
- sp = uint16_t (sp - 1);
- goto loop;
-
-// AND
- case 0xA6: // AND (HL)
- data = READ( rp.hl );
- goto and_data;
-
- case 0xE6: // AND imm
- pc++;
- goto and_data;
-
- CASE7( A0, A1, A2, A3, A4, A5, A7 ): // AND r
- data = R8( opcode, 0xA0 );
- and_data:
- rg.a &= data;
- flags = SZ28P( rg.a ) | H10;
- goto loop;
-
-// OR
- case 0xB6: // OR (HL)
- data = READ( rp.hl );
- goto or_data;
-
- case 0xF6: // OR imm
- pc++;
- goto or_data;
-
- CASE7( B0, B1, B2, B3, B4, B5, B7 ): // OR r
- data = R8( opcode, 0xB0 );
- or_data:
- rg.a |= data;
- flags = SZ28P( rg.a );
- goto loop;
-
-// XOR
- case 0xAE: // XOR (HL)
- data = READ( rp.hl );
- goto xor_data;
-
- case 0xEE: // XOR imm
- pc++;
- goto xor_data;
-
- CASE7( A8, A9, AA, AB, AC, AD, AF ): // XOR r
- data = R8( opcode, 0xA8 );
- xor_data:
- rg.a ^= data;
- flags = SZ28P( rg.a );
- goto loop;
-
-// LD
- CASE7( 70, 71, 72, 73, 74, 75, 77 ): // LD (HL),r
- WRITE( rp.hl, R8( opcode, 0x70 ) );
- goto loop;
-
- CASE6( 41, 42, 43, 44, 45, 47 ): // LD B,r
- CASE6( 48, 4A, 4B, 4C, 4D, 4F ): // LD C,r
- CASE6( 50, 51, 53, 54, 55, 57 ): // LD D,r
- CASE6( 58, 59, 5A, 5C, 5D, 5F ): // LD E,r
- CASE6( 60, 61, 62, 63, 65, 67 ): // LD H,r
- CASE6( 68, 69, 6A, 6B, 6C, 6F ): // LD L,r
- CASE6( 78, 79, 7A, 7B, 7C, 7D ): // LD A,r
- R8( opcode >> 3 & 7, 0 ) = R8( opcode & 7, 0 );
- goto loop;
-
- CASE5( 06, 0E, 16, 1E, 26 ): // LD r,imm
- R8( opcode >> 3, 0 ) = data;
- pc++;
- goto loop;
-
- case 0x36: // LD (HL),imm
- pc++;
- WRITE( rp.hl, data );
- goto loop;
-
- CASE7( 46, 4E, 56, 5E, 66, 6E, 7E ): // LD r,(HL)
- R8( opcode >> 3, 8 ) = READ( rp.hl );
- goto loop;
-
- case 0x01: // LD rp,imm
- case 0x11:
- case 0x21:
- R16( opcode, 4, 0x01 ) = GET_ADDR();
- pc += 2;
- goto loop;
-
- case 0x31: // LD sp,imm
- sp = GET_ADDR();
- pc += 2;
- goto loop;
-
- case 0x2A:{// LD HL,(addr)
- fuint16 addr = GET_ADDR();
- pc += 2;
- rp.hl = READ_WORD( addr );
- goto loop;
- }
-
- case 0x32:{// LD (addr),A
- fuint16 addr = GET_ADDR();
- pc += 2;
- WRITE( addr, rg.a );
- goto loop;
- }
-
- case 0x22:{// LD (addr),HL
- fuint16 addr = GET_ADDR();
- pc += 2;
- WRITE_WORD( addr, rp.hl );
- goto loop;
- }
-
- case 0x02: // LD (BC),A
- case 0x12: // LD (DE),A
- WRITE( R16( opcode, 4, 0x02 ), rg.a );
- goto loop;
-
- case 0x0A: // LD A,(BC)
- case 0x1A: // LD A,(DE)
- rg.a = READ( R16( opcode, 4, 0x0A ) );
- goto loop;
-
- case 0xF9: // LD SP,HL
- sp = rp.hl;
- goto loop;
-
-// Rotate
-
- case 0x07:{// RLCA
- fuint16 temp = rg.a;
- temp = (temp << 1) | (temp >> 7);
- flags = (flags & (S80 | Z40 | P04)) |
- (temp & (F20 | F08 | C01));
- rg.a = temp;
- goto loop;
- }
-
- case 0x0F:{// RRCA
- fuint16 temp = rg.a;
- flags = (flags & (S80 | Z40 | P04)) |
- (temp & C01);
- temp = (temp << 7) | (temp >> 1);
- flags |= temp & (F20 | F08);
- rg.a = temp;
- goto loop;
- }
-
- case 0x17:{// RLA
- blargg_ulong temp = (rg.a << 1) | (flags & C01);
- flags = (flags & (S80 | Z40 | P04)) |
- (temp & (F20 | F08)) |
- (temp >> 8);
- rg.a = temp;
- goto loop;
- }
-
- case 0x1F:{// RRA
- fuint16 temp = (flags << 7) | (rg.a >> 1);
- flags = (flags & (S80 | Z40 | P04)) |
- (temp & (F20 | F08)) |
- (rg.a & C01);
- rg.a = temp;
- goto loop;
- }
-
-// Misc
- case 0x2F:{// CPL
- fuint16 temp = ~rg.a;
- flags = (flags & (S80 | Z40 | P04 | C01)) |
- (temp & (F20 | F08)) |
- (H10 | N02);
- rg.a = temp;
- goto loop;
- }
-
- case 0x3F:{// CCF
- flags = ((flags & (S80 | Z40 | P04 | C01)) ^ C01) |
- (flags << 4 & H10) |
- (rg.a & (F20 | F08));
- goto loop;
- }
-
- case 0x37: // SCF
- flags = (flags & (S80 | Z40 | P04)) | C01 |
- (rg.a & (F20 | F08));
- goto loop;
-
- case 0xDB: // IN A,(imm)
- pc++;
- rg.a = IN( data + rg.a * 0x100 );
- goto loop;
-
- case 0xE3:{// EX (SP),HL
- fuint16 temp = READ_WORD( sp );
- WRITE_WORD( sp, rp.hl );
- rp.hl = temp;
- goto loop;
- }
-
- case 0xEB:{// EX DE,HL
- fuint16 temp = rp.hl;
- rp.hl = rp.de;
- rp.de = temp;
- goto loop;
- }
-
- case 0xD9:{// EXX DE,HL
- fuint16 temp = r.alt.w.bc;
- r.alt.w.bc = rp.bc;
- rp.bc = temp;
-
- temp = r.alt.w.de;
- r.alt.w.de = rp.de;
- rp.de = temp;
-
- temp = r.alt.w.hl;
- r.alt.w.hl = rp.hl;
- rp.hl = temp;
- goto loop;
- }
-
- case 0xF3: // DI
- r.iff1 = 0;
- r.iff2 = 0;
- goto loop;
-
- case 0xFB: // EI
- r.iff1 = 1;
- r.iff2 = 1;
- // TODO: delayed effect
- goto loop;
-
- case 0x76: // HALT
- goto halt;
-
-//////////////////////////////////////// CB prefix
- {
- case 0xCB:
- unsigned data2;
- data2 = instr [1];
- pc++;
- switch ( data )
- {
-
- // Rotate left
-
- #define RLC( read, write ) {\
- fuint8 result = read;\
- result = uint8_t (result << 1) | (result >> 7);\
- flags = SZ28P( result ) | (result & C01);\
- write;\
- goto loop;\
- }
-
- case 0x06: // RLC (HL)
- s_time += 7;
- data = rp.hl;
- rlc_data_addr:
- RLC( READ( data ), WRITE( data, result ) )
-
- CASE7( 00, 01, 02, 03, 04, 05, 07 ):{// RLC r
- uint8_t& reg = R8( data, 0 );
- RLC( reg, reg = result )
- }
-
- #define RL( read, write ) {\
- fuint16 result = (read << 1) | (flags & C01);\
- flags = SZ28PC( result );\
- write;\
- goto loop;\
- }
-
- case 0x16: // RL (HL)
- s_time += 7;
- data = rp.hl;
- rl_data_addr:
- RL( READ( data ), WRITE( data, result ) )
-
- CASE7( 10, 11, 12, 13, 14, 15, 17 ):{// RL r
- uint8_t& reg = R8( data, 0x10 );
- RL( reg, reg = result )
- }
-
- #define SLA( read, add, write ) {\
- fuint16 result = (read << 1) | add;\
- flags = SZ28PC( result );\
- write;\
- goto loop;\
- }
-
- case 0x26: // SLA (HL)
- s_time += 7;
- data = rp.hl;
- sla_data_addr:
- SLA( READ( data ), 0, WRITE( data, result ) )
-
- CASE7( 20, 21, 22, 23, 24, 25, 27 ):{// SLA r
- uint8_t& reg = R8( data, 0x20 );
- SLA( reg, 0, reg = result )
- }
-
- case 0x36: // SLL (HL)
- s_time += 7;
- data = rp.hl;
- sll_data_addr:
- SLA( READ( data ), 1, WRITE( data, result ) )
-
- CASE7( 30, 31, 32, 33, 34, 35, 37 ):{// SLL r
- uint8_t& reg = R8( data, 0x30 );
- SLA( reg, 1, reg = result )
- }
-
- // Rotate right
-
- #define RRC( read, write ) {\
- fuint8 result = read;\
- flags = result & C01;\
- result = uint8_t (result << 7) | (result >> 1);\
- flags |= SZ28P( result );\
- write;\
- goto loop;\
- }
-
- case 0x0E: // RRC (HL)
- s_time += 7;
- data = rp.hl;
- rrc_data_addr:
- RRC( READ( data ), WRITE( data, result ) )
-
- CASE7( 08, 09, 0A, 0B, 0C, 0D, 0F ):{// RRC r
- uint8_t& reg = R8( data, 0x08 );
- RRC( reg, reg = result )
- }
-
- #define RR( read, write ) {\
- fuint8 result = read;\
- fuint8 temp = result & C01;\
- result = uint8_t (flags << 7) | (result >> 1);\
- flags = SZ28P( result ) | temp;\
- write;\
- goto loop;\
- }
-
- case 0x1E: // RR (HL)
- s_time += 7;
- data = rp.hl;
- rr_data_addr:
- RR( READ( data ), WRITE( data, result ) )
-
- CASE7( 18, 19, 1A, 1B, 1C, 1D, 1F ):{// RR r
- uint8_t& reg = R8( data, 0x18 );
- RR( reg, reg = result )
- }
-
- #define SRA( read, write ) {\
- fuint8 result = read;\
- flags = result & C01;\
- result = (result & 0x80) | (result >> 1);\
- flags |= SZ28P( result );\
- write;\
- goto loop;\
- }
-
- case 0x2E: // SRA (HL)
- data = rp.hl;
- s_time += 7;
- sra_data_addr:
- SRA( READ( data ), WRITE( data, result ) )
-
- CASE7( 28, 29, 2A, 2B, 2C, 2D, 2F ):{// SRA r
- uint8_t& reg = R8( data, 0x28 );
- SRA( reg, reg = result )
- }
-
- #define SRL( read, write ) {\
- fuint8 result = read;\
- flags = result & C01;\
- result >>= 1;\
- flags |= SZ28P( result );\
- write;\
- goto loop;\
- }
-
- case 0x3E: // SRL (HL)
- s_time += 7;
- data = rp.hl;
- srl_data_addr:
- SRL( READ( data ), WRITE( data, result ) )
-
- CASE7( 38, 39, 3A, 3B, 3C, 3D, 3F ):{// SRL r
- uint8_t& reg = R8( data, 0x38 );
- SRL( reg, reg = result )
- }
-
- // BIT
- {
- unsigned temp;
- CASE8( 46, 4E, 56, 5E, 66, 6E, 76, 7E ): // BIT b,(HL)
- s_time += 4;
- temp = READ( rp.hl );
- flags &= C01;
- goto bit_temp;
- CASE7( 40, 41, 42, 43, 44, 45, 47 ): // BIT 0,r
- CASE7( 48, 49, 4A, 4B, 4C, 4D, 4F ): // BIT 1,r
- CASE7( 50, 51, 52, 53, 54, 55, 57 ): // BIT 2,r
- CASE7( 58, 59, 5A, 5B, 5C, 5D, 5F ): // BIT 3,r
- CASE7( 60, 61, 62, 63, 64, 65, 67 ): // BIT 4,r
- CASE7( 68, 69, 6A, 6B, 6C, 6D, 6F ): // BIT 5,r
- CASE7( 70, 71, 72, 73, 74, 75, 77 ): // BIT 6,r
- CASE7( 78, 79, 7A, 7B, 7C, 7D, 7F ): // BIT 7,r
- temp = R8( data & 7, 0 );
- flags = (flags & C01) | (temp & (F20 | F08));
- bit_temp:
- int masked = temp & 1 << (data >> 3 & 7);
- flags |=(masked & S80) | H10 |
- ((masked - 1) >> 8 & (Z40 | P04));
- goto loop;
- }
-
- // SET/RES
- CASE8( 86, 8E, 96, 9E, A6, AE, B6, BE ): // RES b,(HL)
- CASE8( C6, CE, D6, DE, E6, EE, F6, FE ):{// SET b,(HL)
- s_time += 7;
- int temp = READ( rp.hl );
- int bit = 1 << (data >> 3 & 7);
- temp |= bit; // SET
- if ( !(data & 0x40) )
- temp ^= bit; // RES
- WRITE( rp.hl, temp );
- goto loop;
- }
-
- CASE7( C0, C1, C2, C3, C4, C5, C7 ): // SET 0,r
- CASE7( C8, C9, CA, CB, CC, CD, CF ): // SET 1,r
- CASE7( D0, D1, D2, D3, D4, D5, D7 ): // SET 2,r
- CASE7( D8, D9, DA, DB, DC, DD, DF ): // SET 3,r
- CASE7( E0, E1, E2, E3, E4, E5, E7 ): // SET 4,r
- CASE7( E8, E9, EA, EB, EC, ED, EF ): // SET 5,r
- CASE7( F0, F1, F2, F3, F4, F5, F7 ): // SET 6,r
- CASE7( F8, F9, FA, FB, FC, FD, FF ): // SET 7,r
- R8( data & 7, 0 ) |= 1 << (data >> 3 & 7);
- goto loop;
-
- CASE7( 80, 81, 82, 83, 84, 85, 87 ): // RES 0,r
- CASE7( 88, 89, 8A, 8B, 8C, 8D, 8F ): // RES 1,r
- CASE7( 90, 91, 92, 93, 94, 95, 97 ): // RES 2,r
- CASE7( 98, 99, 9A, 9B, 9C, 9D, 9F ): // RES 3,r
- CASE7( A0, A1, A2, A3, A4, A5, A7 ): // RES 4,r
- CASE7( A8, A9, AA, AB, AC, AD, AF ): // RES 5,r
- CASE7( B0, B1, B2, B3, B4, B5, B7 ): // RES 6,r
- CASE7( B8, B9, BA, BB, BC, BD, BF ): // RES 7,r
- R8( data & 7, 0 ) &= ~(1 << (data >> 3 & 7));
- goto loop;
- }
- assert( false );
- }
-
-#undef GET_ADDR
-#define GET_ADDR() GET_LE16( instr + 1 )
-
-//////////////////////////////////////// ED prefix
- {
- case 0xED:
- pc++;
- s_time += ed_dd_timing [data] >> 4;
- switch ( data )
- {
- {
- blargg_ulong temp;
- case 0x72: // SBC HL,SP
- case 0x7A: // ADC HL,SP
- temp = sp;
- if ( 0 )
- case 0x42: // SBC HL,BC
- case 0x52: // SBC HL,DE
- case 0x62: // SBC HL,HL
- case 0x4A: // ADC HL,BC
- case 0x5A: // ADC HL,DE
- case 0x6A: // ADC HL,HL
- temp = R16( data >> 3 & 6, 1, 0 );
- blargg_ulong sum = temp + (flags & C01);
- flags = ~data >> 2 & N02;
- if ( flags )
- sum = -sum;
- sum += rp.hl;
- temp ^= rp.hl;
- temp ^= sum;
- flags |=(sum >> 16 & C01) |
- (temp >> 8 & H10) |
- (sum >> 8 & (S80 | F20 | F08)) |
- ((temp - -0x8000) >> 14 & V04);
- rp.hl = sum;
- if ( (uint16_t) sum )
- goto loop;
- flags |= Z40;
- goto loop;
- }
-
- CASE8( 40, 48, 50, 58, 60, 68, 70, 78 ):{// IN r,(C)
- int temp = IN( rp.bc );
- R8( data >> 3, 8 ) = temp;
- flags = (flags & C01) | SZ28P( temp );
- goto loop;
- }
-
- case 0x71: // OUT (C),0
- rg.flags = 0;
- CASE7( 41, 49, 51, 59, 61, 69, 79 ): // OUT (C),r
- OUT( rp.bc, R8( data >> 3, 8 ) );
- goto loop;
-
- {
- unsigned temp;
- case 0x73: // LD (ADDR),SP
- temp = sp;
- if ( 0 )
- case 0x43: // LD (ADDR),BC
- case 0x53: // LD (ADDR),DE
- temp = R16( data, 4, 0x43 );
- fuint16 addr = GET_ADDR();
- pc += 2;
- WRITE_WORD( addr, temp );
- goto loop;
- }
-
- case 0x4B: // LD BC,(ADDR)
- case 0x5B:{// LD DE,(ADDR)
- fuint16 addr = GET_ADDR();
- pc += 2;
- R16( data, 4, 0x4B ) = READ_WORD( addr );
- goto loop;
- }
-
- case 0x7B:{// LD SP,(ADDR)
- fuint16 addr = GET_ADDR();
- pc += 2;
- sp = READ_WORD( addr );
- goto loop;
- }
-
- case 0x67:{// RRD
- fuint8 temp = READ( rp.hl );
- WRITE( rp.hl, (rg.a << 4) | (temp >> 4) );
- temp = (rg.a & 0xF0) | (temp & 0x0F);
- flags = (flags & C01) | SZ28P( temp );
- rg.a = temp;
- goto loop;
- }
-
- case 0x6F:{// RLD
- fuint8 temp = READ( rp.hl );
- WRITE( rp.hl, (temp << 4) | (rg.a & 0x0F) );
- temp = (rg.a & 0xF0) | (temp >> 4);
- flags = (flags & C01) | SZ28P( temp );
- rg.a = temp;
- goto loop;
- }
-
- CASE8( 44, 4C, 54, 5C, 64, 6C, 74, 7C ): // NEG
- opcode = 0x10; // flag to do SBC instead of ADC
- flags &= ~C01;
- data = rg.a;
- rg.a = 0;
- goto adc_data;
-
- {
- int inc;
- case 0xA9: // CPD
- case 0xB9: // CPDR
- inc = -1;
- if ( 0 )
- case 0xA1: // CPI
- case 0xB1: // CPIR
- inc = +1;
- fuint16 addr = rp.hl;
- rp.hl = addr + inc;
- int temp = READ( addr );
-
- int result = rg.a - temp;
- flags = (flags & C01) | N02 |
- ((((temp ^ rg.a) & H10) ^ result) & (S80 | H10));
-
- if ( !(uint8_t) result ) flags |= Z40;
- result -= (flags & H10) >> 4;
- flags |= result & F08;
- flags |= result << 4 & F20;
- if ( !--rp.bc )
- goto loop;
-
- flags |= V04;
- if ( flags & Z40 || data < 0xB0 )
- goto loop;
-
- pc -= 2;
- s_time += 5;
- goto loop;
- }
-
- {
- int inc;
- case 0xA8: // LDD
- case 0xB8: // LDDR
- inc = -1;
- if ( 0 )
- case 0xA0: // LDI
- case 0xB0: // LDIR
- inc = +1;
- fuint16 addr = rp.hl;
- rp.hl = addr + inc;
- int temp = READ( addr );
-
- addr = rp.de;
- rp.de = addr + inc;
- WRITE( addr, temp );
-
- temp += rg.a;
- flags = (flags & (S80 | Z40 | C01)) |
- (temp & F08) | (temp << 4 & F20);
- if ( !--rp.bc )
- goto loop;
-
- flags |= V04;
- if ( data < 0xB0 )
- goto loop;
-
- pc -= 2;
- s_time += 5;
- goto loop;
- }
-
- {
- int inc;
- case 0xAB: // OUTD
- case 0xBB: // OTDR
- inc = -1;
- if ( 0 )
- case 0xA3: // OUTI
- case 0xB3: // OTIR
- inc = +1;
- fuint16 addr = rp.hl;
- rp.hl = addr + inc;
- int temp = READ( addr );
-
- int b = --rg.b;
- flags = (temp >> 6 & N02) | SZ28( b );
- if ( b && data >= 0xB0 )
- {
- pc -= 2;
- s_time += 5;
- }
-
- OUT( rp.bc, temp );
- goto loop;
- }
-
- {
- int inc;
- case 0xAA: // IND
- case 0xBA: // INDR
- inc = -1;
- if ( 0 )
- case 0xA2: // INI
- case 0xB2: // INIR
- inc = +1;
-
- fuint16 addr = rp.hl;
- rp.hl = addr + inc;
-
- int temp = IN( rp.bc );
-
- int b = --rg.b;
- flags = (temp >> 6 & N02) | SZ28( b );
- if ( b && data >= 0xB0 )
- {
- pc -= 2;
- s_time += 5;
- }
-
- WRITE( addr, temp );
- goto loop;
- }
-
- case 0x47: // LD I,A
- r.i = rg.a;
- goto loop;
-
- case 0x4F: // LD R,A
- SET_R( rg.a );
- dprintf( "LD R,A not supported\n" );
- warning = true;
- goto loop;
-
- case 0x57: // LD A,I
- rg.a = r.i;
- goto ld_ai_common;
-
- case 0x5F: // LD A,R
- rg.a = GET_R();
- dprintf( "LD A,R not supported\n" );
- warning = true;
- ld_ai_common:
- flags = (flags & C01) | SZ28( rg.a ) | (r.iff2 << 2 & V04);
- goto loop;
-
- CASE8( 45, 4D, 55, 5D, 65, 6D, 75, 7D ): // RETI/RETN
- r.iff1 = r.iff2;
- goto ret_taken;
-
- case 0x46: case 0x4E: case 0x66: case 0x6E: // IM 0
- r.im = 0;
- goto loop;
-
- case 0x56: case 0x76: // IM 1
- r.im = 1;
- goto loop;
-
- case 0x5E: case 0x7E: // IM 2
- r.im = 2;
- goto loop;
-
- default:
- dprintf( "Opcode $ED $%02X not supported\n", data );
- warning = true;
- goto loop;
- }
- assert( false );
- }
-
-//////////////////////////////////////// DD/FD prefix
- {
- fuint16 ixy;
- case 0xDD:
- ixy = ix;
- goto ix_prefix;
- case 0xFD:
- ixy = iy;
- ix_prefix:
- pc++;
- unsigned data2 = READ_PROG( pc );
- s_time += ed_dd_timing [data] & 0x0F;
- switch ( data )
- {
- // TODO: more efficient way of avoid negative address
- // TODO: avoid using this as argument to READ() since it is evaluated twice
- #define IXY_DISP( ixy, disp ) uint16_t ((ixy) + (disp))
-
- #define SET_IXY( in ) if ( opcode == 0xDD ) ix = in; else iy = in;
-
- // ADD/ADC/SUB/SBC
-
- case 0x96: // SUB (IXY+disp)
- case 0x86: // ADD (IXY+disp)
- flags &= ~C01;
- case 0x9E: // SBC (IXY+disp)
- case 0x8E: // ADC (IXY+disp)
- pc++;
- opcode = data;
- data = READ( IXY_DISP( ixy, (int8_t) data2 ) );
- goto adc_data;
-
- case 0x94: // SUB HXY
- case 0x84: // ADD HXY
- flags &= ~C01;
- case 0x9C: // SBC HXY
- case 0x8C: // ADC HXY
- opcode = data;
- data = ixy >> 8;
- goto adc_data;
-
- case 0x95: // SUB LXY
- case 0x85: // ADD LXY
- flags &= ~C01;
- case 0x9D: // SBC LXY
- case 0x8D: // ADC LXY
- opcode = data;
- data = (uint8_t) ixy;
- goto adc_data;
-
- {
- unsigned temp;
- case 0x39: // ADD IXY,SP
- temp = sp;
- goto add_ixy_data;
-
- case 0x29: // ADD IXY,HL
- temp = ixy;
- goto add_ixy_data;
-
- case 0x09: // ADD IXY,BC
- case 0x19: // ADD IXY,DE
- temp = R16( data, 4, 0x09 );
- add_ixy_data: {
- blargg_ulong sum = ixy + temp;
- temp ^= ixy;
- ixy = (uint16_t) sum;
- flags = (flags & (S80 | Z40 | V04)) |
- (sum >> 16) |
- (sum >> 8 & (F20 | F08)) |
- ((temp ^ sum) >> 8 & H10);
- goto set_ixy;
- }
- }
-
- // AND
- case 0xA6: // AND (IXY+disp)
- pc++;
- data = READ( IXY_DISP( ixy, (int8_t) data2 ) );
- goto and_data;
-
- case 0xA4: // AND HXY
- data = ixy >> 8;
- goto and_data;
-
- case 0xA5: // AND LXY
- data = (uint8_t) ixy;
- goto and_data;
-
- // OR
- case 0xB6: // OR (IXY+disp)
- pc++;
- data = READ( IXY_DISP( ixy, (int8_t) data2 ) );
- goto or_data;
-
- case 0xB4: // OR HXY
- data = ixy >> 8;
- goto or_data;
-
- case 0xB5: // OR LXY
- data = (uint8_t) ixy;
- goto or_data;
-
- // XOR
- case 0xAE: // XOR (IXY+disp)
- pc++;
- data = READ( IXY_DISP( ixy, (int8_t) data2 ) );
- goto xor_data;
-
- case 0xAC: // XOR HXY
- data = ixy >> 8;
- goto xor_data;
-
- case 0xAD: // XOR LXY
- data = (uint8_t) ixy;
- goto xor_data;
-
- // CP
- case 0xBE: // CP (IXY+disp)
- pc++;
- data = READ( IXY_DISP( ixy, (int8_t) data2 ) );
- goto cp_data;
-
- case 0xBC: // CP HXY
- data = ixy >> 8;
- goto cp_data;
-
- case 0xBD: // CP LXY
- data = (uint8_t) ixy;
- goto cp_data;
-
- // LD
- CASE7( 70, 71, 72, 73, 74, 75, 77 ): // LD (IXY+disp),r
- data = R8( data, 0x70 );
- if ( 0 )
- case 0x36: // LD (IXY+disp),imm
- pc++, data = READ_PROG( pc );
- pc++;
- WRITE( IXY_DISP( ixy, (int8_t) data2 ), data );
- goto loop;
-
- CASE5( 44, 4C, 54, 5C, 7C ): // LD r,HXY
- R8( data >> 3, 8 ) = ixy >> 8;
- goto loop;
-
- case 0x64: // LD HXY,HXY
- case 0x6D: // LD LXY,LXY
- goto loop;
-
- CASE5( 45, 4D, 55, 5D, 7D ): // LD r,LXY
- R8( data >> 3, 8 ) = ixy;
- goto loop;
-
- CASE7( 46, 4E, 56, 5E, 66, 6E, 7E ): // LD r,(IXY+disp)
- pc++;
- R8( data >> 3, 8 ) = READ( IXY_DISP( ixy, (int8_t) data2 ) );
- goto loop;
-
- case 0x26: // LD HXY,imm
- pc++;
- goto ld_hxy_data;
-
- case 0x65: // LD HXY,LXY
- data2 = (uint8_t) ixy;
- goto ld_hxy_data;
-
- CASE5( 60, 61, 62, 63, 67 ): // LD HXY,r
- data2 = R8( data, 0x60 );
- ld_hxy_data:
- ixy = (uint8_t) ixy | (data2 << 8);
- goto set_ixy;
-
- case 0x2E: // LD LXY,imm
- pc++;
- goto ld_lxy_data;
-
- case 0x6C: // LD LXY,HXY
- data2 = ixy >> 8;
- goto ld_lxy_data;
-
- CASE5( 68, 69, 6A, 6B, 6F ): // LD LXY,r
- data2 = R8( data, 0x68 );
- ld_lxy_data:
- ixy = (ixy & 0xFF00) | data2;
- set_ixy:
- if ( opcode == 0xDD )
- {
- ix = ixy;
- goto loop;
- }
- iy = ixy;
- goto loop;
-
- case 0xF9: // LD SP,IXY
- sp = ixy;
- goto loop;
-
- case 0x22:{// LD (ADDR),IXY
- fuint16 addr = GET_ADDR();
- pc += 2;
- WRITE_WORD( addr, ixy );
- goto loop;
- }
-
- case 0x21: // LD IXY,imm
- ixy = GET_ADDR();
- pc += 2;
- goto set_ixy;
-
- case 0x2A:{// LD IXY,(addr)
- fuint16 addr = GET_ADDR();
- ixy = READ_WORD( addr );
- pc += 2;
- goto set_ixy;
- }
-
- // DD/FD CB prefix
- case 0xCB: {
- data = IXY_DISP( ixy, (int8_t) data2 );
- pc++;
- data2 = READ_PROG( pc );
- pc++;
- switch ( data2 )
- {
- case 0x06: goto rlc_data_addr; // RLC (IXY)
- case 0x16: goto rl_data_addr; // RL (IXY)
- case 0x26: goto sla_data_addr; // SLA (IXY)
- case 0x36: goto sll_data_addr; // SLL (IXY)
- case 0x0E: goto rrc_data_addr; // RRC (IXY)
- case 0x1E: goto rr_data_addr; // RR (IXY)
- case 0x2E: goto sra_data_addr; // SRA (IXY)
- case 0x3E: goto srl_data_addr; // SRL (IXY)
-
- CASE8( 46, 4E, 56, 5E, 66, 6E, 76, 7E ):{// BIT b,(IXY+disp)
- fuint8 temp = READ( data );
- int masked = temp & 1 << (data2 >> 3 & 7);
- flags = (flags & C01) | H10 |
- (masked & S80) |
- ((masked - 1) >> 8 & (Z40 | P04));
- goto loop;
- }
-
- CASE8( 86, 8E, 96, 9E, A6, AE, B6, BE ): // RES b,(IXY+disp)
- CASE8( C6, CE, D6, DE, E6, EE, F6, FE ):{// SET b,(IXY+disp)
- int temp = READ( data );
- int bit = 1 << (data2 >> 3 & 7);
- temp |= bit; // SET
- if ( !(data2 & 0x40) )
- temp ^= bit; // RES
- WRITE( data, temp );
- goto loop;
- }
-
- default:
- dprintf( "Opcode $%02X $CB $%02X not supported\n", opcode, data2 );
- warning = true;
- goto loop;
- }
- assert( false );
- }
-
- // INC/DEC
- case 0x23: // INC IXY
- ixy = uint16_t (ixy + 1);
- goto set_ixy;
-
- case 0x2B: // DEC IXY
- ixy = uint16_t (ixy - 1);
- goto set_ixy;
-
- case 0x34: // INC (IXY+disp)
- ixy = IXY_DISP( ixy, (int8_t) data2 );
- pc++;
- data = READ( ixy ) + 1;
- WRITE( ixy, data );
- goto inc_set_flags;
-
- case 0x35: // DEC (IXY+disp)
- ixy = IXY_DISP( ixy, (int8_t) data2 );
- pc++;
- data = READ( ixy ) - 1;
- WRITE( ixy, data );
- goto dec_set_flags;
-
- case 0x24: // INC HXY
- ixy = uint16_t (ixy + 0x100);
- data = ixy >> 8;
- goto inc_xy_common;
-
- case 0x2C: // INC LXY
- data = uint8_t (ixy + 1);
- ixy = (ixy & 0xFF00) | data;
- inc_xy_common:
- if ( opcode == 0xDD )
- {
- ix = ixy;
- goto inc_set_flags;
- }
- iy = ixy;
- goto inc_set_flags;
-
- case 0x25: // DEC HXY
- ixy = uint16_t (ixy - 0x100);
- data = ixy >> 8;
- goto dec_xy_common;
-
- case 0x2D: // DEC LXY
- data = uint8_t (ixy - 1);
- ixy = (ixy & 0xFF00) | data;
- dec_xy_common:
- if ( opcode == 0xDD )
- {
- ix = ixy;
- goto dec_set_flags;
- }
- iy = ixy;
- goto dec_set_flags;
-
- // PUSH/POP
- case 0xE5: // PUSH IXY
- data = ixy;
- goto push_data;
-
- case 0xE1:{// POP IXY
- ixy = READ_WORD( sp );
- sp = uint16_t (sp + 2);
- goto set_ixy;
- }
-
- // Misc
-
- case 0xE9: // JP (IXY)
- pc = ixy;
- goto loop;
-
- case 0xE3:{// EX (SP),IXY
- fuint16 temp = READ_WORD( sp );
- WRITE_WORD( sp, ixy );
- ixy = temp;
- goto set_ixy;
- }
-
- default:
- dprintf( "Unnecessary DD/FD prefix encountered\n" );
- warning = true;
- pc--;
- goto loop;
- }
- assert( false );
- }
-
- }
- dprintf( "Unhandled main opcode: $%02X\n", opcode );
- assert( false );
-
-hit_idle_addr:
- s_time -= 11;
- goto out_of_time;
-halt:
- s_time &= 3; // increment by multiple of 4
-out_of_time:
- pc--;
-
- s.time = s_time;
- rg.flags = flags;
- r.ix = ix;
- r.iy = iy;
- r.sp = sp;
- r.pc = pc;
- this->r.b = rg;
- this->state_ = s;
- this->state = &this->state_;
-
- return warning;
-}
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Kss_Cpu.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/Kss_Cpu.h
deleted file mode 100644
index 6297d100..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Kss_Cpu.h
+++ /dev/null
@@ -1,124 +0,0 @@
-// Z80 CPU emulator
-
-// Game_Music_Emu 0.5.2
-#ifndef KSS_CPU_H
-#define KSS_CPU_H
-
-#include "blargg_endian.h"
-
-typedef blargg_long cpu_time_t;
-
-// must be defined by caller
-void kss_cpu_out( class Kss_Cpu*, cpu_time_t, unsigned addr, int data );
-int kss_cpu_in( class Kss_Cpu*, cpu_time_t, unsigned addr );
-void kss_cpu_write( class Kss_Cpu*, unsigned addr, int data );
-
-class Kss_Cpu {
-public:
- typedef BOOST::uint8_t uint8_t;
-
- // Clear registers and map all pages to unmapped
- void reset( void* unmapped_write, void const* unmapped_read );
-
- // Map memory. Start and size must be multiple of page_size.
- enum { page_size = 0x2000 };
- void map_mem( unsigned addr, blargg_ulong size, void* write, void const* read );
-
- // Map address to page
- uint8_t* write( unsigned addr );
- uint8_t const* read( unsigned addr );
-
- // Run until specified time is reached. Returns true if suspicious/unsupported
- // instruction was encountered at any point during run.
- bool run( cpu_time_t end_time );
-
- // Time of beginning of next instruction
- cpu_time_t time() const { return state->time + state->base; }
-
- // Alter current time. Not supported during run() call.
- void set_time( cpu_time_t t ) { state->time = t - state->base; }
- void adjust_time( int delta ) { state->time += delta; }
-
- typedef BOOST::uint16_t uint16_t;
-
- #if BLARGG_BIG_ENDIAN
- struct regs_t { uint8_t b, c, d, e, h, l, flags, a; };
- #else
- struct regs_t { uint8_t c, b, e, d, l, h, a, flags; };
- #endif
- BOOST_STATIC_ASSERT( sizeof (regs_t) == 8 );
-
- struct pairs_t { uint16_t bc, de, hl, fa; };
-
- // Registers are not updated until run() returns
- struct registers_t {
- uint16_t pc;
- uint16_t sp;
- uint16_t ix;
- uint16_t iy;
- union {
- regs_t b; // b.b, b.c, b.d, b.e, b.h, b.l, b.flags, b.a
- pairs_t w; // w.bc, w.de, w.hl. w.fa
- };
- union {
- regs_t b;
- pairs_t w;
- } alt;
- uint8_t iff1;
- uint8_t iff2;
- uint8_t r;
- uint8_t i;
- uint8_t im;
- };
- //registers_t r; (below for efficiency)
-
- enum { idle_addr = 0xFFFF };
-
- // can read this far past end of a page
- enum { cpu_padding = 0x100 };
-
-public:
- Kss_Cpu();
- enum { page_shift = 13 };
- enum { page_count = 0x10000 >> page_shift };
-private:
- uint8_t szpc [0x200];
- cpu_time_t end_time_;
- struct state_t {
- uint8_t const* read [page_count + 1];
- uint8_t * write [page_count + 1];
- cpu_time_t base;
- cpu_time_t time;
- };
- state_t* state; // points to state_ or a local copy within run()
- state_t state_;
- void set_end_time( cpu_time_t t );
- void set_page( int i, void* write, void const* read );
-public:
- registers_t r;
-};
-
-#if BLARGG_NONPORTABLE
- #define KSS_CPU_PAGE_OFFSET( addr ) (addr)
-#else
- #define KSS_CPU_PAGE_OFFSET( addr ) ((addr) & (page_size - 1))
-#endif
-
-inline BOOST::uint8_t* Kss_Cpu::write( unsigned addr )
-{
- return state->write [addr >> page_shift] + KSS_CPU_PAGE_OFFSET( addr );
-}
-
-inline BOOST::uint8_t const* Kss_Cpu::read( unsigned addr )
-{
- return state->read [addr >> page_shift] + KSS_CPU_PAGE_OFFSET( addr );
-}
-
-inline void Kss_Cpu::set_end_time( cpu_time_t t )
-{
- cpu_time_t delta = state->base - t;
- state->base = t;
- state->time += delta;
-}
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Kss_Emu.cpp b/plugins/gme/Game_Music_Emu-0.5.2/gme/Kss_Emu.cpp
deleted file mode 100644
index 1b26ef0b..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Kss_Emu.cpp
+++ /dev/null
@@ -1,414 +0,0 @@
-// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
-
-#include "Kss_Emu.h"
-
-#include "blargg_endian.h"
-#include <string.h>
-
-/* Copyright (C) 2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-long const clock_rate = 3579545;
-int const osc_count = Ay_Apu::osc_count + Scc_Apu::osc_count;
-
-Kss_Emu::Kss_Emu()
-{
- sn = 0;
- set_type( gme_kss_type );
- set_silence_lookahead( 6 );
- static const char* const names [osc_count] = {
- "Square 1", "Square 2", "Square 3",
- "Wave 1", "Wave 2", "Wave 3", "Wave 4", "Wave 5"
- };
- set_voice_names( names );
-
- static int const types [osc_count] = {
- wave_type | 0, wave_type | 1, wave_type | 2,
- wave_type | 3, wave_type | 4, wave_type | 5, wave_type | 6, wave_type | 7
- };
- set_voice_types( types );
-
- memset( unmapped_read, 0xFF, sizeof unmapped_read );
-}
-
-Kss_Emu::~Kss_Emu() { unload(); }
-
-void Kss_Emu::unload()
-{
- delete sn;
- sn = 0;
- Classic_Emu::unload();
-}
-
-// Track info
-
-static void copy_kss_fields( Kss_Emu::header_t const& h, track_info_t* out )
-{
- const char* system = "MSX";
- if ( h.device_flags & 0x02 )
- {
- system = "Sega Master System";
- if ( h.device_flags & 0x04 )
- system = "Game Gear";
- }
- Gme_File::copy_field_( out->system, system );
-}
-
-blargg_err_t Kss_Emu::track_info_( track_info_t* out, int ) const
-{
- copy_kss_fields( header_, out );
- return 0;
-}
-
-static blargg_err_t check_kss_header( void const* header )
-{
- if ( memcmp( header, "KSCC", 4 ) && memcmp( header, "KSSX", 4 ) )
- return gme_wrong_file_type;
- return 0;
-}
-
-struct Kss_File : Gme_Info_
-{
- Kss_Emu::header_t header_;
-
- Kss_File() { set_type( gme_kss_type ); }
-
- blargg_err_t load_( Data_Reader& in )
- {
- blargg_err_t err = in.read( &header_, Kss_Emu::header_size );
- if ( err )
- return (err == in.eof_error ? gme_wrong_file_type : err);
- return check_kss_header( &header_ );
- }
-
- blargg_err_t track_info_( track_info_t* out, int ) const
- {
- copy_kss_fields( header_, out );
- return 0;
- }
-};
-
-static Music_Emu* new_kss_emu () { return BLARGG_NEW Kss_Emu ; }
-static Music_Emu* new_kss_file() { return BLARGG_NEW Kss_File; }
-
-gme_type_t_ const gme_kss_type [1] = { "MSX", 256, &new_kss_emu, &new_kss_file, "KSS", 0x03 };
-
-// Setup
-
-void Kss_Emu::update_gain()
-{
- double g = gain() * 1.4;
- if ( scc_accessed )
- g *= 1.5;
- ay.volume( g );
- scc.volume( g );
- if ( sn )
- sn->volume( g );
-}
-
-blargg_err_t Kss_Emu::load_( Data_Reader& in )
-{
- memset( &header_, 0, sizeof header_ );
- assert( offsetof (header_t,device_flags) == header_size - 1 );
- assert( offsetof (ext_header_t,msx_audio_vol) == ext_header_size - 1 );
- RETURN_ERR( rom.load( in, header_size, STATIC_CAST(header_t*,&header_), 0 ) );
-
- RETURN_ERR( check_kss_header( header_.tag ) );
-
- if ( header_.tag [3] == 'C' )
- {
- if ( header_.extra_header )
- {
- header_.extra_header = 0;
- set_warning( "Unknown data in header" );
- }
- if ( header_.device_flags & ~0x0F )
- {
- header_.device_flags &= 0x0F;
- set_warning( "Unknown data in header" );
- }
- }
- else
- {
- ext_header_t& ext = header_;
- memcpy( &ext, rom.begin(), min( (int) ext_header_size, (int) header_.extra_header ) );
- if ( header_.extra_header > 0x10 )
- set_warning( "Unknown data in header" );
- }
-
- if ( header_.device_flags & 0x09 )
- set_warning( "FM sound not supported" );
-
- scc_enabled = 0xC000;
- if ( header_.device_flags & 0x04 )
- scc_enabled = 0;
-
- if ( header_.device_flags & 0x02 && !sn )
- CHECK_ALLOC( sn = BLARGG_NEW( Sms_Apu ) );
-
- set_voice_count( osc_count );
-
- return setup_buffer( ::clock_rate );
-}
-
-void Kss_Emu::update_eq( blip_eq_t const& eq )
-{
- ay.treble_eq( eq );
- scc.treble_eq( eq );
- if ( sn )
- sn->treble_eq( eq );
-}
-
-void Kss_Emu::set_voice( int i, Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right )
-{
- int i2 = i - ay.osc_count;
- if ( i2 >= 0 )
- scc.osc_output( i2, center );
- else
- ay.osc_output( i, center );
- if ( sn && i < sn->osc_count )
- sn->osc_output( i, center, left, right );
-}
-
-// Emulation
-
-void Kss_Emu::set_tempo_( double t )
-{
- blip_time_t period =
- (header_.device_flags & 0x40 ? ::clock_rate / 50 : ::clock_rate / 60);
- play_period = blip_time_t (period / t);
-}
-
-blargg_err_t Kss_Emu::start_track_( int track )
-{
- RETURN_ERR( Classic_Emu::start_track_( track ) );
-
- memset( ram, 0xC9, 0x4000 );
- memset( ram + 0x4000, 0, sizeof ram - 0x4000 );
-
- // copy driver code to lo RAM
- static byte const bios [] = {
- 0xD3, 0xA0, 0xF5, 0x7B, 0xD3, 0xA1, 0xF1, 0xC9, // $0001: WRTPSG
- 0xD3, 0xA0, 0xDB, 0xA2, 0xC9 // $0009: RDPSG
- };
- static byte const vectors [] = {
- 0xC3, 0x01, 0x00, // $0093: WRTPSG vector
- 0xC3, 0x09, 0x00, // $0096: RDPSG vector
- };
- memcpy( ram + 0x01, bios, sizeof bios );
- memcpy( ram + 0x93, vectors, sizeof vectors );
-
- // copy non-banked data into RAM
- unsigned load_addr = get_le16( header_.load_addr );
- long orig_load_size = get_le16( header_.load_size );
- long load_size = min( orig_load_size, rom.file_size() );
- load_size = min( load_size, long (mem_size - load_addr) );
- if ( load_size != orig_load_size )
- set_warning( "Excessive data size" );
- memcpy( ram + load_addr, rom.begin() + header_.extra_header, load_size );
-
- rom.set_addr( -load_size - header_.extra_header );
-
- // check available bank data
- blargg_long const bank_size = this->bank_size();
- int max_banks = (rom.file_size() - load_size + bank_size - 1) / bank_size;
- bank_count = header_.bank_mode & 0x7F;
- if ( bank_count > max_banks )
- {
- bank_count = max_banks;
- set_warning( "Bank data missing" );
- }
- //dprintf( "load_size : $%X\n", load_size );
- //dprintf( "bank_size : $%X\n", bank_size );
- //dprintf( "bank_count: %d (%d claimed)\n", bank_count, header_.bank_mode & 0x7F );
-
- ram [idle_addr] = 0xFF;
- cpu::reset( unmapped_write, unmapped_read );
- cpu::map_mem( 0, mem_size, ram, ram );
-
- ay.reset();
- scc.reset();
- if ( sn )
- sn->reset();
- r.sp = 0xF380;
- ram [--r.sp] = idle_addr >> 8;
- ram [--r.sp] = idle_addr & 0xFF;
- r.b.a = track;
- r.pc = get_le16( header_.init_addr );
- next_play = play_period;
- scc_accessed = false;
- gain_updated = false;
- update_gain();
- ay_latch = 0;
-
- return 0;
-}
-
-void Kss_Emu::set_bank( int logical, int physical )
-{
- unsigned const bank_size = this->bank_size();
-
- unsigned addr = 0x8000;
- if ( logical && bank_size == 8 * 1024 )
- addr = 0xA000;
-
- physical -= header_.first_bank;
- if ( (unsigned) physical >= (unsigned) bank_count )
- {
- byte* data = ram + addr;
- cpu::map_mem( addr, bank_size, data, data );
- }
- else
- {
- long phys = physical * (blargg_long) bank_size;
- for ( unsigned offset = 0; offset < bank_size; offset += page_size )
- cpu::map_mem( addr + offset, page_size,
- unmapped_write, rom.at_addr( phys + offset ) );
- }
-}
-
-void Kss_Emu::cpu_write( unsigned addr, int data )
-{
- data &= 0xFF;
- switch ( addr )
- {
- case 0x9000:
- set_bank( 0, data );
- return;
-
- case 0xB000:
- set_bank( 1, data );
- return;
- }
-
- int scc_addr = (addr & 0xDFFF) ^ 0x9800;
- if ( scc_addr < scc.reg_count )
- {
- scc_accessed = true;
- scc.write( time(), scc_addr, data );
- return;
- }
-
- dprintf( "LD ($%04X),$%02X\n", addr, data );
-}
-
-void kss_cpu_write( Kss_Cpu* cpu, unsigned addr, int data )
-{
- *cpu->write( addr ) = data;
- if ( (addr & STATIC_CAST(Kss_Emu&,*cpu).scc_enabled) == 0x8000 )
- STATIC_CAST(Kss_Emu&,*cpu).cpu_write( addr, data );
-}
-
-void kss_cpu_out( Kss_Cpu* cpu, cpu_time_t time, unsigned addr, int data )
-{
- data &= 0xFF;
- Kss_Emu& emu = STATIC_CAST(Kss_Emu&,*cpu);
- switch ( addr & 0xFF )
- {
- case 0xA0:
- emu.ay_latch = data & 0x0F;
- return;
-
- case 0xA1:
- GME_APU_HOOK( &emu, emu.ay_latch, data );
- emu.ay.write( time, emu.ay_latch, data );
- return;
-
- case 0x06:
- if ( emu.sn && (emu.header_.device_flags & 0x04) )
- {
- emu.sn->write_ggstereo( time, data );
- return;
- }
- break;
-
- case 0x7E:
- case 0x7F:
- if ( emu.sn )
- {
- GME_APU_HOOK( &emu, 16, data );
- emu.sn->write_data( time, data );
- return;
- }
- break;
-
- case 0xFE:
- emu.set_bank( 0, data );
- return;
-
- #ifndef NDEBUG
- case 0xF1: // FM data
- if ( data )
- break; // trap non-zero data
- case 0xF0: // FM addr
- case 0xA8: // PPI
- return;
- #endif
- }
-
- dprintf( "OUT $%04X,$%02X\n", addr, data );
-}
-
-int kss_cpu_in( Kss_Cpu*, cpu_time_t, unsigned addr )
-{
- //Kss_Emu& emu = STATIC_CAST(Kss_Emu&,*cpu);
- //switch ( addr & 0xFF )
- //{
- //}
-
- dprintf( "IN $%04X\n", addr );
- return 0;
-}
-
-// Emulation
-
-blargg_err_t Kss_Emu::run_clocks( blip_time_t& duration, int )
-{
- while ( time() < duration )
- {
- blip_time_t end = min( duration, next_play );
- cpu::run( min( duration, next_play ) );
- if ( r.pc == idle_addr )
- set_time( end );
-
- if ( time() >= next_play )
- {
- next_play += play_period;
- if ( r.pc == idle_addr )
- {
- if ( !gain_updated )
- {
- gain_updated = true;
- if ( scc_accessed )
- update_gain();
- }
-
- ram [--r.sp] = idle_addr >> 8;
- ram [--r.sp] = idle_addr & 0xFF;
- r.pc = get_le16( header_.play_addr );
- GME_FRAME_HOOK( this );
- }
- }
- }
-
- duration = time();
- next_play -= duration;
- check( next_play >= 0 );
- adjust_time( -duration );
- ay.end_frame( duration );
- scc.end_frame( duration );
- if ( sn )
- sn->end_frame( duration );
-
- return 0;
-}
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Kss_Emu.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/Kss_Emu.h
deleted file mode 100644
index 4d8463ab..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Kss_Emu.h
+++ /dev/null
@@ -1,96 +0,0 @@
-// MSX computer KSS music file emulator
-
-// Game_Music_Emu 0.5.2
-#ifndef KSS_EMU_H
-#define KSS_EMU_H
-
-#include "Classic_Emu.h"
-#include "Kss_Scc_Apu.h"
-#include "Kss_Cpu.h"
-#include "Sms_Apu.h"
-#include "Ay_Apu.h"
-
-class Kss_Emu : private Kss_Cpu, public Classic_Emu {
- typedef Kss_Cpu cpu;
-public:
- // KSS file header
- enum { header_size = 0x10 };
- struct header_t
- {
- byte tag [4];
- byte load_addr [2];
- byte load_size [2];
- byte init_addr [2];
- byte play_addr [2];
- byte first_bank;
- byte bank_mode;
- byte extra_header;
- byte device_flags;
- };
-
- enum { ext_header_size = 0x10 };
- struct ext_header_t
- {
- byte data_size [4];
- byte unused [4];
- byte first_track [2];
- byte last_tack [2];
- byte psg_vol;
- byte scc_vol;
- byte msx_music_vol;
- byte msx_audio_vol;
- };
-
- struct composite_header_t : header_t, ext_header_t { };
-
- // Header for currently loaded file
- composite_header_t const& header() const { return header_; }
-
- static gme_type_t static_type() { return gme_kss_type; }
-public:
- Kss_Emu();
- ~Kss_Emu();
-protected:
- blargg_err_t track_info_( track_info_t*, int track ) const;
- blargg_err_t load_( Data_Reader& );
- blargg_err_t start_track_( int );
- blargg_err_t run_clocks( blip_time_t&, int );
- void set_tempo_( double );
- void set_voice( int, Blip_Buffer*, Blip_Buffer*, Blip_Buffer* );
- void update_eq( blip_eq_t const& );
- void unload();
-private:
- Rom_Data<page_size> rom;
- composite_header_t header_;
-
- bool scc_accessed;
- bool gain_updated;
- void update_gain();
-
- unsigned scc_enabled; // 0 or 0xC000
- byte const* bank_data;
- int bank_count;
- void set_bank( int logical, int physical );
- blargg_long bank_size() const { return (16 * 1024L) >> (header_.bank_mode >> 7 & 1); }
-
- blip_time_t play_period;
- blip_time_t next_play;
- int ay_latch;
-
- friend void kss_cpu_out( class Kss_Cpu*, cpu_time_t, unsigned addr, int data );
- friend int kss_cpu_in( class Kss_Cpu*, cpu_time_t, unsigned addr );
- void cpu_write( unsigned addr, int data );
- friend void kss_cpu_write( class Kss_Cpu*, unsigned addr, int data );
-
- // large items
- enum { mem_size = 0x10000 };
- byte ram [mem_size + cpu_padding];
-
- Ay_Apu ay;
- Scc_Apu scc;
- Sms_Apu* sn;
- byte unmapped_read [0x100];
- byte unmapped_write [page_size];
-};
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Kss_Scc_Apu.cpp b/plugins/gme/Game_Music_Emu-0.5.2/gme/Kss_Scc_Apu.cpp
deleted file mode 100644
index 1660ac3d..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Kss_Scc_Apu.cpp
+++ /dev/null
@@ -1,97 +0,0 @@
-// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
-
-#include "Kss_Scc_Apu.h"
-
-/* Copyright (C) 2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-// Tones above this frequency are treated as disabled tone at half volume.
-// Power of two is more efficient (avoids division).
-unsigned const inaudible_freq = 16384;
-
-int const wave_size = 0x20;
-
-void Scc_Apu::run_until( blip_time_t end_time )
-{
- for ( int index = 0; index < osc_count; index++ )
- {
- osc_t& osc = oscs [index];
-
- Blip_Buffer* const output = osc.output;
- if ( !output )
- continue;
- output->set_modified();
-
- blip_time_t period = (regs [0x80 + index * 2 + 1] & 0x0F) * 0x100 +
- regs [0x80 + index * 2] + 1;
- int volume = 0;
- if ( regs [0x8F] & (1 << index) )
- {
- blip_time_t inaudible_period = (blargg_ulong) (output->clock_rate() +
- inaudible_freq * 32) / (inaudible_freq * 16);
- if ( period > inaudible_period )
- volume = (regs [0x8A + index] & 0x0F) * (amp_range / 256 / 15);
- }
-
- BOOST::int8_t const* wave = (BOOST::int8_t*) regs + index * wave_size;
- if ( index == osc_count - 1 )
- wave -= wave_size; // last two oscs share wave
- {
- int amp = wave [osc.phase] * volume;
- int delta = amp - osc.last_amp;
- if ( delta )
- {
- osc.last_amp = amp;
- synth.offset( last_time, delta, output );
- }
- }
-
- blip_time_t time = last_time + osc.delay;
- if ( time < end_time )
- {
- if ( !volume )
- {
- // maintain phase
- blargg_long count = (end_time - time + period - 1) / period;
- osc.phase = (osc.phase + count) & (wave_size - 1);
- time += count * period;
- }
- else
- {
-
- int phase = osc.phase;
- int last_wave = wave [phase];
- phase = (phase + 1) & (wave_size - 1); // pre-advance for optimal inner loop
-
- do
- {
- int amp = wave [phase];
- phase = (phase + 1) & (wave_size - 1);
- int delta = amp - last_wave;
- if ( delta )
- {
- last_wave = amp;
- synth.offset( time, delta * volume, output );
- }
- time += period;
- }
- while ( time < end_time );
-
- osc.phase = phase = (phase - 1) & (wave_size - 1); // undo pre-advance
- osc.last_amp = wave [phase] * volume;
- }
- }
- osc.delay = time - end_time;
- }
- last_time = end_time;
-}
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Kss_Scc_Apu.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/Kss_Scc_Apu.h
deleted file mode 100644
index 03a6a108..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Kss_Scc_Apu.h
+++ /dev/null
@@ -1,106 +0,0 @@
-// Konami SCC sound chip emulator
-
-// Game_Music_Emu 0.5.2
-#ifndef KSS_SCC_APU_H
-#define KSS_SCC_APU_H
-
-#include "blargg_common.h"
-#include "Blip_Buffer.h"
-#include <string.h>
-
-class Scc_Apu {
-public:
- // Set buffer to generate all sound into, or disable sound if NULL
- void output( Blip_Buffer* );
-
- // Reset sound chip
- void reset();
-
- // Write to register at specified time
- enum { reg_count = 0x90 };
- void write( blip_time_t time, int reg, int data );
-
- // Run sound to specified time, end current time frame, then start a new
- // time frame at time 0. Time frames have no effect on emulation and each
- // can be whatever length is convenient.
- void end_frame( blip_time_t length );
-
-// Additional features
-
- // Set sound output of specific oscillator to buffer, where index is
- // 0 to 4. If buffer is NULL, the specified oscillator is muted.
- enum { osc_count = 5 };
- void osc_output( int index, Blip_Buffer* );
-
- // Set overall volume (default is 1.0)
- void volume( double );
-
- // Set treble equalization (see documentation)
- void treble_eq( blip_eq_t const& );
-
-public:
- Scc_Apu();
-private:
- enum { amp_range = 0x8000 };
- struct osc_t
- {
- int delay;
- int phase;
- int last_amp;
- Blip_Buffer* output;
- };
- osc_t oscs [osc_count];
- blip_time_t last_time;
- unsigned char regs [reg_count];
- Blip_Synth<blip_med_quality,1> synth;
-
- void run_until( blip_time_t );
-};
-
-inline void Scc_Apu::volume( double v ) { synth.volume( 0.43 / osc_count / amp_range * v ); }
-
-inline void Scc_Apu::treble_eq( blip_eq_t const& eq ) { synth.treble_eq( eq ); }
-
-inline void Scc_Apu::osc_output( int index, Blip_Buffer* b )
-{
- assert( (unsigned) index < osc_count );
- oscs [index].output = b;
-}
-
-inline void Scc_Apu::write( blip_time_t time, int addr, int data )
-{
- assert( (unsigned) addr < reg_count );
- run_until( time );
- regs [addr] = data;
-}
-
-inline void Scc_Apu::end_frame( blip_time_t end_time )
-{
- if ( end_time > last_time )
- run_until( end_time );
- last_time -= end_time;
- assert( last_time >= 0 );
-}
-
-inline void Scc_Apu::output( Blip_Buffer* buf )
-{
- for ( int i = 0; i < osc_count; i++ )
- oscs [i].output = buf;
-}
-
-inline Scc_Apu::Scc_Apu()
-{
- output( 0 );
-}
-
-inline void Scc_Apu::reset()
-{
- last_time = 0;
-
- for ( int i = 0; i < osc_count; i++ )
- memset( &oscs [i], 0, offsetof (osc_t,output) );
-
- memset( regs, 0, sizeof regs );
-}
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/M3u_Playlist.cpp b/plugins/gme/Game_Music_Emu-0.5.2/gme/M3u_Playlist.cpp
deleted file mode 100644
index 0a1475db..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/M3u_Playlist.cpp
+++ /dev/null
@@ -1,426 +0,0 @@
-// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
-
-#include "M3u_Playlist.h"
-#include "Music_Emu.h"
-
-#include <string.h>
-
-/* Copyright (C) 2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-// gme functions defined here to avoid linking in m3u code unless it's used
-
-blargg_err_t Gme_File::load_m3u_( blargg_err_t err )
-{
- require( raw_track_count_ ); // file must be loaded first
-
- if ( !err )
- {
- if ( playlist.size() )
- track_count_ = playlist.size();
-
- int line = playlist.first_error();
- if ( line )
- {
- // avoid using bloated printf()
- char* out = &playlist_warning [sizeof playlist_warning];
- *--out = 0;
- do {
- *--out = line % 10 + '0';
- } while ( (line /= 10) > 0 );
-
- static const char str [] = "Problem in m3u at line ";
- out -= sizeof str - 1;
- memcpy( out, str, sizeof str - 1 );
- set_warning( out );
- }
- }
- return err;
-}
-
-blargg_err_t Gme_File::load_m3u( const char* path ) { return load_m3u_( playlist.load( path ) ); }
-
-blargg_err_t Gme_File::load_m3u( Data_Reader& in ) { return load_m3u_( playlist.load( in ) ); }
-
-gme_err_t gme_load_m3u( Music_Emu* me, const char* path ) { return me->load_m3u( path ); }
-
-gme_err_t gme_load_m3u_data( Music_Emu* me, const void* data, long size )
-{
- Mem_File_Reader in( data, size );
- return me->load_m3u( in );
-}
-
-
-
-static char* skip_white( char* in )
-{
- while ( *in == ' ' )
- in++;
- return in;
-}
-
-inline unsigned from_dec( unsigned n ) { return n - '0'; }
-
-static char* parse_filename( char* in, M3u_Playlist::entry_t& entry )
-{
- entry.file = in;
- entry.type = "";
- char* out = in;
- while ( 1 )
- {
- int c = *in;
- if ( !c ) break;
- in++;
-
- if ( c == ',' ) // commas in filename
- {
- char* p = skip_white( in );
- if ( *p == '$' || from_dec( *p ) <= 9 )
- {
- in = p;
- break;
- }
- }
-
- if ( c == ':' && in [0] == ':' && in [1] && in [2] != ',' ) // ::type suffix
- {
- entry.type = ++in;
- while ( (c = *in) != 0 && c != ',' )
- in++;
- if ( c == ',' )
- {
- *in++ = 0; // terminate type
- in = skip_white( in );
- }
- break;
- }
-
- if ( c == '\\' ) // \ prefix for special characters
- {
- c = *in;
- if ( !c ) break;
- in++;
- }
- *out++ = (char) c;
- }
- *out = 0; // terminate string
- return in;
-}
-
-static char* next_field( char* in, int* result )
-{
- while ( 1 )
- {
- in = skip_white( in );
-
- if ( !*in )
- break;
-
- if ( *in == ',' )
- {
- in++;
- break;
- }
-
- *result = 1;
- in++;
- }
- return skip_white( in );
-}
-
-static char* parse_int_( char* in, int* out )
-{
- int n = 0;
- while ( 1 )
- {
- unsigned d = from_dec( *in );
- if ( d > 9 )
- break;
- in++;
- n = n * 10 + d;
- *out = n;
- }
- return in;
-}
-
-static char* parse_int( char* in, int* out, int* result )
-{
- return next_field( parse_int_( in, out ), result );
-}
-
-// Returns 16 or greater if not hex
-inline int from_hex_char( int h )
-{
- h -= 0x30;
- if ( (unsigned) h > 9 )
- h = ((h - 0x11) & 0xDF) + 10;
- return h;
-}
-
-static char* parse_track( char* in, M3u_Playlist::entry_t& entry, int* result )
-{
- if ( *in == '$' )
- {
- in++;
- int n = 0;
- while ( 1 )
- {
- int h = from_hex_char( *in );
- if ( h > 15 )
- break;
- in++;
- n = n * 16 + h;
- entry.track = n;
- }
- }
- else
- {
- in = parse_int_( in, &entry.track );
- if ( entry.track >= 0 )
- entry.decimal_track = 1;
- }
- return next_field( in, result );
-}
-
-static char* parse_time_( char* in, int* out )
-{
- *out = -1;
- int n = -1;
- in = parse_int_( in, &n );
- if ( n >= 0 )
- {
- *out = n;
- if ( *in == ':' )
- {
- n = -1;
- in = parse_int_( in + 1, &n );
- if ( n >= 0 )
- *out = *out * 60 + n;
- }
- }
- return in;
-}
-
-static char* parse_time( char* in, int* out, int* result )
-{
- return next_field( parse_time_( in, out ), result );
-}
-
-static char* parse_name( char* in )
-{
- char* out = in;
- while ( 1 )
- {
- int c = *in;
- if ( !c ) break;
- in++;
-
- if ( c == ',' ) // commas in string
- {
- char* p = skip_white( in );
- if ( *p == ',' || *p == '-' || from_dec( *p ) <= 9 )
- {
- in = p;
- break;
- }
- }
-
- if ( c == '\\' ) // \ prefix for special characters
- {
- c = *in;
- if ( !c ) break;
- in++;
- }
- *out++ = (char) c;
- }
- *out = 0; // terminate string
- return in;
-}
-
-static int parse_line( char* in, M3u_Playlist::entry_t& entry )
-{
- int result = 0;
-
- // file
- entry.file = in;
- entry.type = "";
- in = parse_filename( in, entry );
-
- // track
- entry.track = -1;
- entry.decimal_track = 0;
- in = parse_track( in, entry, &result );
-
- // name
- entry.name = in;
- in = parse_name( in );
-
- // time
- entry.length = -1;
- in = parse_time( in, &entry.length, &result );
-
- // loop
- entry.intro = -1;
- entry.loop = -1;
- if ( *in == '-' )
- {
- entry.loop = entry.length;
- in++;
- }
- else
- {
- in = parse_time_( in, &entry.loop );
- if ( entry.loop >= 0 )
- {
- entry.intro = 0;
- if ( *in == '-' ) // trailing '-' means that intro length was specified
- {
- in++;
- entry.intro = entry.loop;
- entry.loop = entry.length - entry.intro;
- }
- }
- }
- in = next_field( in, &result );
-
- // fade
- entry.fade = -1;
- in = parse_time( in, &entry.fade, &result );
-
- // repeat
- entry.repeat = -1;
- in = parse_int( in, &entry.repeat, &result );
-
- return result;
-}
-
-static void parse_comment( char* in, M3u_Playlist::info_t& info, bool first )
-{
- in = skip_white( in + 1 );
- const char* field = in;
- while ( *in && *in != ':' )
- in++;
-
- if ( *in == ':' )
- {
- const char* text = skip_white( in + 1 );
- if ( *text )
- {
- *in = 0;
- if ( !strcmp( "Composer", field ) ) info.composer = text;
- else if ( !strcmp( "Engineer", field ) ) info.engineer = text;
- else if ( !strcmp( "Ripping" , field ) ) info.ripping = text;
- else if ( !strcmp( "Tagging" , field ) ) info.tagging = text;
- else
- text = 0;
- if ( text )
- return;
- *in = ':';
- }
- }
-
- if ( first )
- info.title = field;
-}
-
-blargg_err_t M3u_Playlist::parse_()
-{
- info_.title = "";
- info_.composer = "";
- info_.engineer = "";
- info_.ripping = "";
- info_.tagging = "";
-
- int const CR = 13;
- int const LF = 10;
-
- data.end() [-1] = LF; // terminate input
-
- first_error_ = 0;
- bool first_comment = true;
- int line = 0;
- int count = 0;
- char* in = data.begin();
- while ( in < data.end() )
- {
- // find end of line and terminate it
- line++;
- char* begin = in;
- while ( *in != CR && *in != LF )
- {
- if ( !*in )
- return "Not an m3u playlist";
- in++;
- }
- if ( in [0] == CR && in [1] == LF ) // treat CR,LF as a single line
- *in++ = 0;
- *in++ = 0;
-
- // parse line
- if ( *begin == '#' )
- {
- parse_comment( begin, info_, first_comment );
- first_comment = false;
- }
- else if ( *begin )
- {
- if ( (int) entries.size() <= count )
- RETURN_ERR( entries.resize( count * 2 + 64 ) );
-
- if ( !parse_line( begin, entries [count] ) )
- count++;
- else if ( !first_error_ )
- first_error_ = line;
- first_comment = false;
- }
- }
- if ( count <= 0 )
- return "Not an m3u playlist";
-
- if ( !(info_.composer [0] | info_.engineer [0] | info_.ripping [0] | info_.tagging [0]) )
- info_.title = "";
-
- return entries.resize( count );
-}
-
-blargg_err_t M3u_Playlist::parse()
-{
- blargg_err_t err = parse_();
- if ( err )
- {
- entries.clear();
- data.clear();
- }
- return err;
-}
-
-blargg_err_t M3u_Playlist::load( Data_Reader& in )
-{
- RETURN_ERR( data.resize( in.remain() + 1 ) );
- RETURN_ERR( in.read( data.begin(), data.size() - 1 ) );
- return parse();
-}
-
-blargg_err_t M3u_Playlist::load( const char* path )
-{
- GME_FILE_READER in;
- RETURN_ERR( in.open( path ) );
- return load( in );
-}
-
-blargg_err_t M3u_Playlist::load( void const* in, long size )
-{
- RETURN_ERR( data.resize( size + 1 ) );
- memcpy( data.begin(), in, size );
- return parse();
-}
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/M3u_Playlist.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/M3u_Playlist.h
deleted file mode 100644
index eda0dc89..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/M3u_Playlist.h
+++ /dev/null
@@ -1,67 +0,0 @@
-// M3U playlist file parser, with support for subtrack information
-
-// Game_Music_Emu 0.5.2
-#ifndef M3U_PLAYLIST_H
-#define M3U_PLAYLIST_H
-
-#include "blargg_common.h"
-#include "Data_Reader.h"
-
-class M3u_Playlist {
-public:
- // Load playlist data
- blargg_err_t load( const char* path );
- blargg_err_t load( Data_Reader& in );
- blargg_err_t load( void const* data, long size );
-
- // Line number of first parse error, 0 if no error. Any lines with parse
- // errors are ignored.
- int first_error() const { return first_error_; }
-
- struct info_t
- {
- const char* title;
- const char* composer;
- const char* engineer;
- const char* ripping;
- const char* tagging;
- };
- info_t const& info() const { return info_; }
-
- struct entry_t
- {
- const char* file; // filename without stupid ::TYPE suffix
- const char* type; // if filename has ::TYPE suffix, this will be "TYPE". "" if none.
- const char* name;
- bool decimal_track; // true if track was specified in hex
- // integers are -1 if not present
- int track; // 1-based
- int length; // seconds
- int intro;
- int loop;
- int fade;
- int repeat; // count
- };
- entry_t const& operator [] ( int i ) const { return entries [i]; }
- int size() const { return entries.size(); }
-
- void clear();
-
-private:
- blargg_vector<entry_t> entries;
- blargg_vector<char> data;
- int first_error_;
- info_t info_;
-
- blargg_err_t parse();
- blargg_err_t parse_();
-};
-
-inline void M3u_Playlist::clear()
-{
- first_error_ = 0;
- entries.clear();
- data.clear();
-}
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Makefile.am b/plugins/gme/Game_Music_Emu-0.5.2/gme/Makefile.am
deleted file mode 100644
index d728deea..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Makefile.am
+++ /dev/null
@@ -1,66 +0,0 @@
-noinst_LIBRARIES = libgme.a
-libgme_a_SOURCES = Ay_Apu.cpp Gb_Apu.cpp Hes_Emu.cpp Nes_Fme7_Apu.cpp Sms_Apu.cpp\
-Ay_Cpu.cpp Gb_Cpu.cpp Kss_Cpu.cpp Nes_Namco_Apu.cpp Snes_Spc.cpp\
-Ay_Emu.cpp Gb_Oscs.cpp Kss_Emu.cpp Nes_Oscs.cpp Spc_Cpu.cpp\
-Blip_Buffer.cpp Gbs_Emu.cpp Kss_Scc_Apu.cpp Nes_Vrc6_Apu.cpp Spc_Dsp.cpp\
-Classic_Emu.cpp gme.cpp M3u_Playlist.cpp Nsfe_Emu.cpp Spc_Emu.cpp\
-Data_Reader.cpp Gme_File.cpp Multi_Buffer.cpp Nsf_Emu.cpp Vgm_Emu.cpp\
-Dual_Resampler.cpp Gym_Emu.cpp Music_Emu.cpp Sap_Apu.cpp Vgm_Emu_Impl.cpp\
-Effects_Buffer.cpp Hes_Apu.cpp Nes_Apu.cpp Sap_Cpu.cpp Ym2413_Emu.cpp\
-Fir_Resampler.cpp Hes_Cpu.cpp Nes_Cpu.cpp Sap_Emu.cpp Ym2612_Emu.cpp\
-Ay_Apu.h\
-Ay_Cpu.h\
-Ay_Emu.h\
-blargg_common.h\
-blargg_config.h\
-blargg_endian.h\
-blargg_source.h\
-Blip_Buffer.h\
-Classic_Emu.h\
-Data_Reader.h\
-Dual_Resampler.h\
-Effects_Buffer.h\
-Fir_Resampler.h\
-Gb_Apu.h\
-Gb_Cpu.h\
-gb_cpu_io.h\
-Gb_Oscs.h\
-Gbs_Emu.h\
-Gme_File.h\
-gme.h\
-Gym_Emu.h\
-Hes_Apu.h\
-Hes_Cpu.h\
-hes_cpu_io.h\
-Hes_Emu.h\
-Kss_Cpu.h\
-Kss_Emu.h\
-Kss_Scc_Apu.h\
-M3u_Playlist.h\
-Multi_Buffer.h\
-Music_Emu.h\
-Nes_Apu.h\
-Nes_Cpu.h\
-nes_cpu_io.h\
-Nes_Fme7_Apu.h\
-Nes_Namco_Apu.h\
-Nes_Oscs.h\
-Nes_Vrc6_Apu.h\
-Nsfe_Emu.h\
-Nsf_Emu.h\
-Sap_Apu.h\
-Sap_Cpu.h\
-sap_cpu_io.h\
-Sap_Emu.h\
-Sms_Apu.h\
-Sms_Oscs.h\
-Snes_Spc.h\
-Spc_Cpu.h\
-Spc_Dsp.h\
-Spc_Emu.h\
-Vgm_Emu.h\
-Vgm_Emu_Impl.h\
-Ym2413_Emu.h\
-Ym2612_Emu.h
-
-AM_CPPFLAGS = $(CXXFLAGS) -fPIC
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Multi_Buffer.cpp b/plugins/gme/Game_Music_Emu-0.5.2/gme/Multi_Buffer.cpp
deleted file mode 100644
index ecd8f8ad..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Multi_Buffer.cpp
+++ /dev/null
@@ -1,232 +0,0 @@
-// Blip_Buffer 0.4.1. http://www.slack.net/~ant/
-
-#include "Multi_Buffer.h"
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-#ifdef BLARGG_ENABLE_OPTIMIZER
- #include BLARGG_ENABLE_OPTIMIZER
-#endif
-
-Multi_Buffer::Multi_Buffer( int spf ) : samples_per_frame_( spf )
-{
- length_ = 0;
- sample_rate_ = 0;
- channels_changed_count_ = 1;
-}
-
-blargg_err_t Multi_Buffer::set_channel_count( int ) { return 0; }
-
-// Silent_Buffer
-
-Silent_Buffer::Silent_Buffer() : Multi_Buffer( 1 ) // 0 channels would probably confuse
-{
- // TODO: better to use empty Blip_Buffer so caller never has to check for NULL?
- chan.left = 0;
- chan.center = 0;
- chan.right = 0;
-}
-
-// Mono_Buffer
-
-Mono_Buffer::Mono_Buffer() : Multi_Buffer( 1 )
-{
- chan.center = &buf;
- chan.left = &buf;
- chan.right = &buf;
-}
-
-Mono_Buffer::~Mono_Buffer() { }
-
-blargg_err_t Mono_Buffer::set_sample_rate( long rate, int msec )
-{
- RETURN_ERR( buf.set_sample_rate( rate, msec ) );
- return Multi_Buffer::set_sample_rate( buf.sample_rate(), buf.length() );
-}
-
-// Stereo_Buffer
-
-Stereo_Buffer::Stereo_Buffer() : Multi_Buffer( 2 )
-{
- chan.center = &bufs [0];
- chan.left = &bufs [1];
- chan.right = &bufs [2];
-}
-
-Stereo_Buffer::~Stereo_Buffer() { }
-
-blargg_err_t Stereo_Buffer::set_sample_rate( long rate, int msec )
-{
- for ( int i = 0; i < buf_count; i++ )
- RETURN_ERR( bufs [i].set_sample_rate( rate, msec ) );
- return Multi_Buffer::set_sample_rate( bufs [0].sample_rate(), bufs [0].length() );
-}
-
-void Stereo_Buffer::clock_rate( long rate )
-{
- for ( int i = 0; i < buf_count; i++ )
- bufs [i].clock_rate( rate );
-}
-
-void Stereo_Buffer::bass_freq( int bass )
-{
- for ( unsigned i = 0; i < buf_count; i++ )
- bufs [i].bass_freq( bass );
-}
-
-void Stereo_Buffer::clear()
-{
- stereo_added = 0;
- was_stereo = false;
- for ( int i = 0; i < buf_count; i++ )
- bufs [i].clear();
-}
-
-void Stereo_Buffer::end_frame( blip_time_t clock_count )
-{
- stereo_added = 0;
- for ( unsigned i = 0; i < buf_count; i++ )
- {
- stereo_added |= bufs [i].clear_modified() << i;
- bufs [i].end_frame( clock_count );
- }
-}
-
-long Stereo_Buffer::read_samples( blip_sample_t* out, long count )
-{
- require( !(count & 1) ); // count must be even
- count = (unsigned) count / 2;
-
- long avail = bufs [0].samples_avail();
- if ( count > avail )
- count = avail;
- if ( count )
- {
- int bufs_used = stereo_added | was_stereo;
- //dprintf( "%X\n", bufs_used );
- if ( bufs_used <= 1 )
- {
- mix_mono( out, count );
- bufs [0].remove_samples( count );
- bufs [1].remove_silence( count );
- bufs [2].remove_silence( count );
- }
- else if ( bufs_used & 1 )
- {
- mix_stereo( out, count );
- bufs [0].remove_samples( count );
- bufs [1].remove_samples( count );
- bufs [2].remove_samples( count );
- }
- else
- {
- mix_stereo_no_center( out, count );
- bufs [0].remove_silence( count );
- bufs [1].remove_samples( count );
- bufs [2].remove_samples( count );
- }
-
- // to do: this might miss opportunities for optimization
- if ( !bufs [0].samples_avail() )
- {
- was_stereo = stereo_added;
- stereo_added = 0;
- }
- }
-
- return count * 2;
-}
-
-void Stereo_Buffer::mix_stereo( blip_sample_t* out_, blargg_long count )
-{
- blip_sample_t* BLIP_RESTRICT out = out_;
- int const bass = BLIP_READER_BASS( bufs [1] );
- BLIP_READER_BEGIN( left, bufs [1] );
- BLIP_READER_BEGIN( right, bufs [2] );
- BLIP_READER_BEGIN( center, bufs [0] );
-
- for ( ; count; --count )
- {
- int c = BLIP_READER_READ( center );
- blargg_long l = c + BLIP_READER_READ( left );
- blargg_long r = c + BLIP_READER_READ( right );
- if ( (BOOST::int16_t) l != l )
- l = 0x7FFF - (l >> 24);
-
- BLIP_READER_NEXT( center, bass );
- if ( (BOOST::int16_t) r != r )
- r = 0x7FFF - (r >> 24);
-
- BLIP_READER_NEXT( left, bass );
- BLIP_READER_NEXT( right, bass );
-
- out [0] = l;
- out [1] = r;
- out += 2;
- }
-
- BLIP_READER_END( center, bufs [0] );
- BLIP_READER_END( right, bufs [2] );
- BLIP_READER_END( left, bufs [1] );
-}
-
-void Stereo_Buffer::mix_stereo_no_center( blip_sample_t* out_, blargg_long count )
-{
- blip_sample_t* BLIP_RESTRICT out = out_;
- int const bass = BLIP_READER_BASS( bufs [1] );
- BLIP_READER_BEGIN( left, bufs [1] );
- BLIP_READER_BEGIN( right, bufs [2] );
-
- for ( ; count; --count )
- {
- blargg_long l = BLIP_READER_READ( left );
- if ( (BOOST::int16_t) l != l )
- l = 0x7FFF - (l >> 24);
-
- blargg_long r = BLIP_READER_READ( right );
- if ( (BOOST::int16_t) r != r )
- r = 0x7FFF - (r >> 24);
-
- BLIP_READER_NEXT( left, bass );
- BLIP_READER_NEXT( right, bass );
-
- out [0] = l;
- out [1] = r;
- out += 2;
- }
-
- BLIP_READER_END( right, bufs [2] );
- BLIP_READER_END( left, bufs [1] );
-}
-
-void Stereo_Buffer::mix_mono( blip_sample_t* out_, blargg_long count )
-{
- blip_sample_t* BLIP_RESTRICT out = out_;
- int const bass = BLIP_READER_BASS( bufs [0] );
- BLIP_READER_BEGIN( center, bufs [0] );
-
- for ( ; count; --count )
- {
- blargg_long s = BLIP_READER_READ( center );
- if ( (BOOST::int16_t) s != s )
- s = 0x7FFF - (s >> 24);
-
- BLIP_READER_NEXT( center, bass );
- out [0] = s;
- out [1] = s;
- out += 2;
- }
-
- BLIP_READER_END( center, bufs [0] );
-}
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Multi_Buffer.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/Multi_Buffer.h
deleted file mode 100644
index a39cca1a..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Multi_Buffer.h
+++ /dev/null
@@ -1,156 +0,0 @@
-// Multi-channel sound buffer interface, and basic mono and stereo buffers
-
-// Blip_Buffer 0.4.1
-#ifndef MULTI_BUFFER_H
-#define MULTI_BUFFER_H
-
-#include "blargg_common.h"
-#include "Blip_Buffer.h"
-
-// Interface to one or more Blip_Buffers mapped to one or more channels
-// consisting of left, center, and right buffers.
-class Multi_Buffer {
-public:
- Multi_Buffer( int samples_per_frame );
- virtual ~Multi_Buffer() { }
-
- // Set the number of channels available
- virtual blargg_err_t set_channel_count( int );
-
- // Get indexed channel, from 0 to channel count - 1
- struct channel_t {
- Blip_Buffer* center;
- Blip_Buffer* left;
- Blip_Buffer* right;
- };
- enum { type_index_mask = 0xFF };
- enum { wave_type = 0x100, noise_type = 0x200, mixed_type = wave_type | noise_type };
- virtual channel_t channel( int index, int type ) = 0;
-
- // See Blip_Buffer.h
- virtual blargg_err_t set_sample_rate( long rate, int msec = blip_default_length ) = 0;
- virtual void clock_rate( long ) = 0;
- virtual void bass_freq( int ) = 0;
- virtual void clear() = 0;
- long sample_rate() const;
-
- // Length of buffer, in milliseconds
- int length() const;
-
- // See Blip_Buffer.h
- virtual void end_frame( blip_time_t ) = 0;
-
- // Number of samples per output frame (1 = mono, 2 = stereo)
- int samples_per_frame() const;
-
- // Count of changes to channel configuration. Incremented whenever
- // a change is made to any of the Blip_Buffers for any channel.
- unsigned channels_changed_count() { return channels_changed_count_; }
-
- // See Blip_Buffer.h
- virtual long read_samples( blip_sample_t*, long ) = 0;
- virtual long samples_avail() const = 0;
-
-public:
- BLARGG_DISABLE_NOTHROW
-protected:
- void channels_changed() { channels_changed_count_++; }
-private:
- // noncopyable
- Multi_Buffer( const Multi_Buffer& );
- Multi_Buffer& operator = ( const Multi_Buffer& );
-
- unsigned channels_changed_count_;
- long sample_rate_;
- int length_;
- int const samples_per_frame_;
-};
-
-// Uses a single buffer and outputs mono samples.
-class Mono_Buffer : public Multi_Buffer {
- Blip_Buffer buf;
- channel_t chan;
-public:
- // Buffer used for all channels
- Blip_Buffer* center() { return &buf; }
-
-public:
- Mono_Buffer();
- ~Mono_Buffer();
- blargg_err_t set_sample_rate( long rate, int msec = blip_default_length );
- void clock_rate( long rate ) { buf.clock_rate( rate ); }
- void bass_freq( int freq ) { buf.bass_freq( freq ); }
- void clear() { buf.clear(); }
- long samples_avail() const { return buf.samples_avail(); }
- long read_samples( blip_sample_t* p, long s ) { return buf.read_samples( p, s ); }
- channel_t channel( int, int ) { return chan; }
- void end_frame( blip_time_t t ) { buf.end_frame( t ); }
-};
-
-// Uses three buffers (one for center) and outputs stereo sample pairs.
-class Stereo_Buffer : public Multi_Buffer {
-public:
-
- // Buffers used for all channels
- Blip_Buffer* center() { return &bufs [0]; }
- Blip_Buffer* left() { return &bufs [1]; }
- Blip_Buffer* right() { return &bufs [2]; }
-
-public:
- Stereo_Buffer();
- ~Stereo_Buffer();
- blargg_err_t set_sample_rate( long, int msec = blip_default_length );
- void clock_rate( long );
- void bass_freq( int );
- void clear();
- channel_t channel( int, int ) { return chan; }
- void end_frame( blip_time_t );
-
- long samples_avail() const { return bufs [0].samples_avail() * 2; }
- long read_samples( blip_sample_t*, long );
-
-private:
- enum { buf_count = 3 };
- Blip_Buffer bufs [buf_count];
- channel_t chan;
- int stereo_added;
- int was_stereo;
-
- void mix_stereo_no_center( blip_sample_t*, blargg_long );
- void mix_stereo( blip_sample_t*, blargg_long );
- void mix_mono( blip_sample_t*, blargg_long );
-};
-
-// Silent_Buffer generates no samples, useful where no sound is wanted
-class Silent_Buffer : public Multi_Buffer {
- channel_t chan;
-public:
- Silent_Buffer();
- blargg_err_t set_sample_rate( long rate, int msec = blip_default_length )
- {
- return Multi_Buffer::set_sample_rate( rate, msec );
- }
- void clock_rate( long ) { }
- void bass_freq( int ) { }
- void clear() { }
- channel_t channel( int, int ) { return chan; }
- void end_frame( blip_time_t ) { }
- long samples_avail() const { return 0; }
- long read_samples( blip_sample_t*, long ) { return 0; }
-};
-
-
-inline blargg_err_t Multi_Buffer::set_sample_rate( long rate, int msec )
-{
- sample_rate_ = rate;
- length_ = msec;
- return 0;
-}
-
-inline int Multi_Buffer::samples_per_frame() const { return samples_per_frame_; }
-
-inline long Multi_Buffer::sample_rate() const { return sample_rate_; }
-
-inline int Multi_Buffer::length() const { return length_; }
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Music_Emu.cpp b/plugins/gme/Game_Music_Emu-0.5.2/gme/Music_Emu.cpp
deleted file mode 100644
index 31c7233c..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Music_Emu.cpp
+++ /dev/null
@@ -1,410 +0,0 @@
-// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
-
-#include "Music_Emu.h"
-
-#include "Multi_Buffer.h"
-#include <string.h>
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-int const stereo = 2; // number of channels for stereo
-int const silence_max = 6; // seconds
-int const silence_threshold = 0x10;
-long const fade_block_size = 512;
-int const fade_shift = 8; // fade ends with gain at 1.0 / (1 << fade_shift)
-
-Music_Emu::equalizer_t const Music_Emu::tv_eq = { -8.0, 180 };
-
-void Music_Emu::clear_track_vars()
-{
- current_track_ = -1;
- out_time = 0;
- emu_time = 0;
- emu_track_ended_ = true;
- track_ended_ = true;
- fade_start = LONG_MAX / 2 + 1;
- fade_step = 1;
- silence_time = 0;
- silence_count = 0;
- buf_remain = 0;
- warning(); // clear warning
-}
-
-void Music_Emu::unload()
-{
- voice_count_ = 0;
- clear_track_vars();
- Gme_File::unload();
-}
-
-Music_Emu::Music_Emu()
-{
- effects_buffer = 0;
-
- sample_rate_ = 0;
- mute_mask_ = 0;
- tempo_ = 1.0;
- gain_ = 1.0;
-
- // defaults
- max_initial_silence = 2;
- silence_lookahead = 3;
- ignore_silence_ = false;
- equalizer_.treble = -1.0;
- equalizer_.bass = 60;
-
- static const char* const names [] = {
- "Voice 1", "Voice 2", "Voice 3", "Voice 4",
- "Voice 5", "Voice 6", "Voice 7", "Voice 8"
- };
- set_voice_names( names );
- Music_Emu::unload(); // non-virtual
-}
-
-Music_Emu::~Music_Emu() { delete effects_buffer; }
-
-blargg_err_t Music_Emu::set_sample_rate( long rate )
-{
- require( !sample_rate() ); // sample rate can't be changed once set
- RETURN_ERR( set_sample_rate_( rate ) );
- RETURN_ERR( buf.resize( buf_size ) );
- sample_rate_ = rate;
- return 0;
-}
-
-void Music_Emu::pre_load()
-{
- require( sample_rate() ); // set_sample_rate() must be called before loading a file
- Gme_File::pre_load();
-}
-
-void Music_Emu::set_equalizer( equalizer_t const& eq )
-{
- equalizer_ = eq;
- set_equalizer_( eq );
-}
-
-void Music_Emu::mute_voice( int index, bool mute )
-{
- require( (unsigned) index < (unsigned) voice_count() );
- int bit = 1 << index;
- int mask = mute_mask_ | bit;
- if ( !mute )
- mask ^= bit;
- mute_voices( mask );
-}
-
-void Music_Emu::mute_voices( int mask )
-{
- require( sample_rate() ); // sample rate must be set first
- mute_mask_ = mask;
- mute_voices_( mask );
-}
-
-void Music_Emu::set_tempo( double t )
-{
- require( sample_rate() ); // sample rate must be set first
- double const min = 0.02;
- double const max = 4.00;
- if ( t < min ) t = min;
- if ( t > max ) t = max;
- tempo_ = t;
- set_tempo_( t );
-}
-
-void Music_Emu::post_load_()
-{
- set_tempo( tempo_ );
- remute_voices();
-}
-
-blargg_err_t Music_Emu::start_track( int track )
-{
- clear_track_vars();
-
- int remapped = track;
- RETURN_ERR( remap_track_( &remapped ) );
- current_track_ = track;
- RETURN_ERR( start_track_( remapped ) );
-
- emu_track_ended_ = false;
- track_ended_ = false;
-
- if ( !ignore_silence_ )
- {
- // play until non-silence or end of track
- for ( long end = max_initial_silence * stereo * sample_rate(); emu_time < end; )
- {
- fill_buf();
- if ( buf_remain | (int) emu_track_ended_ )
- break;
- }
-
- emu_time = buf_remain;
- out_time = 0;
- silence_time = 0;
- silence_count = 0;
- }
- return track_ended() ? warning() : 0;
-}
-
-void Music_Emu::end_track_if_error( blargg_err_t err )
-{
- if ( err )
- {
- emu_track_ended_ = true;
- set_warning( err );
- }
-}
-
-// Tell/Seek
-
-blargg_long Music_Emu::msec_to_samples( blargg_long msec ) const
-{
- blargg_long sec = msec / 1000;
- msec -= sec * 1000;
- return (sec * sample_rate() + msec * sample_rate() / 1000) * stereo;
-}
-
-long Music_Emu::tell() const
-{
- blargg_long rate = sample_rate() * stereo;
- blargg_long sec = out_time / rate;
- return sec * 1000 + (out_time - sec * rate) * 1000 / rate;
-}
-
-blargg_err_t Music_Emu::seek( long msec )
-{
- blargg_long time = msec_to_samples( msec );
- if ( time < out_time )
- RETURN_ERR( start_track( current_track_ ) );
- return skip( time - out_time );
-}
-
-blargg_err_t Music_Emu::skip( long count )
-{
- require( current_track() >= 0 ); // start_track() must have been called already
- out_time += count;
-
- // remove from silence and buf first
- {
- long n = min( count, silence_count );
- silence_count -= n;
- count -= n;
-
- n = min( count, buf_remain );
- buf_remain -= n;
- count -= n;
- }
-
- if ( count && !emu_track_ended_ )
- {
- emu_time += count;
- end_track_if_error( skip_( count ) );
- }
-
- if ( !(silence_count | buf_remain) ) // caught up to emulator, so update track ended
- track_ended_ |= emu_track_ended_;
-
- return 0;
-}
-
-blargg_err_t Music_Emu::skip_( long count )
-{
- // for long skip, mute sound
- const long threshold = 30000;
- if ( count > threshold )
- {
- int saved_mute = mute_mask_;
- mute_voices( ~0 );
-
- while ( count > threshold / 2 && !emu_track_ended_ )
- {
- RETURN_ERR( play_( buf_size, buf.begin() ) );
- count -= buf_size;
- }
-
- mute_voices( saved_mute );
- }
-
- while ( count && !emu_track_ended_ )
- {
- long n = buf_size;
- if ( n > count )
- n = count;
- count -= n;
- RETURN_ERR( play_( n, buf.begin() ) );
- }
- return 0;
-}
-
-// Fading
-
-void Music_Emu::set_fade( long start_msec, long length_msec )
-{
- fade_step = sample_rate() * length_msec / (fade_block_size * fade_shift * 1000 / stereo);
- fade_start = msec_to_samples( start_msec );
-}
-
-// unit / pow( 2.0, (double) x / step )
-static int int_log( blargg_long x, int step, int unit )
-{
- int shift = x / step;
- int fraction = (x - shift * step) * unit / step;
- return ((unit - fraction) + (fraction >> 1)) >> shift;
-}
-
-void Music_Emu::handle_fade( long out_count, sample_t* out )
-{
- for ( int i = 0; i < out_count; i += fade_block_size )
- {
- int const shift = 14;
- int const unit = 1 << shift;
- int gain = int_log( (out_time + i - fade_start) / fade_block_size,
- fade_step, unit );
- if ( gain < (unit >> fade_shift) )
- track_ended_ = emu_track_ended_ = true;
-
- sample_t* io = &out [i];
- for ( int count = min( fade_block_size, out_count - i ); count; --count )
- {
- *io = sample_t ((*io * gain) >> shift);
- ++io;
- }
- }
-}
-
-// Silence detection
-
-void Music_Emu::emu_play( long count, sample_t* out )
-{
- check( current_track_ >= 0 );
- emu_time += count;
- if ( current_track_ >= 0 && !emu_track_ended_ )
- end_track_if_error( play_( count, out ) );
- else
- memset( out, 0, count * sizeof *out );
-}
-
-// number of consecutive silent samples at end
-static long count_silence( Music_Emu::sample_t* begin, long size )
-{
- Music_Emu::sample_t first = *begin;
- *begin = silence_threshold; // sentinel
- Music_Emu::sample_t* p = begin + size;
- while ( (unsigned) (*--p + silence_threshold / 2) <= (unsigned) silence_threshold ) { }
- *begin = first;
- return size - (p - begin);
-}
-
-// fill internal buffer and check it for silence
-void Music_Emu::fill_buf()
-{
- assert( !buf_remain );
- if ( !emu_track_ended_ )
- {
- emu_play( buf_size, buf.begin() );
- long silence = count_silence( buf.begin(), buf_size );
- if ( silence < buf_size )
- {
- silence_time = emu_time - silence;
- buf_remain = buf_size;
- return;
- }
- }
- silence_count += buf_size;
-}
-
-blargg_err_t Music_Emu::play( long out_count, sample_t* out )
-{
- if ( track_ended_ )
- {
- memset( out, 0, out_count * sizeof *out );
- }
- else
- {
- require( current_track() >= 0 );
- require( out_count % stereo == 0 );
-
- assert( emu_time >= out_time );
-
- // prints nifty graph of how far ahead we are when searching for silence
- //dprintf( "%*s \n", int ((emu_time - out_time) * 7 / sample_rate()), "*" );
-
- long pos = 0;
- if ( silence_count )
- {
- // during a run of silence, run emulator at >=2x speed so it gets ahead
- long ahead_time = silence_lookahead * (out_time + out_count - silence_time) + silence_time;
- while ( emu_time < ahead_time && !(buf_remain | emu_track_ended_) )
- fill_buf();
-
- // fill with silence
- pos = min( silence_count, out_count );
- memset( out, 0, pos * sizeof *out );
- silence_count -= pos;
-
- if ( emu_time - silence_time > silence_max * stereo * sample_rate() )
- {
- track_ended_ = emu_track_ended_ = true;
- silence_count = 0;
- buf_remain = 0;
- }
- }
-
- if ( buf_remain )
- {
- // empty silence buf
- long n = min( buf_remain, out_count - pos );
- memcpy( &out [pos], buf.begin() + (buf_size - buf_remain), n * sizeof *out );
- buf_remain -= n;
- pos += n;
- }
-
- // generate remaining samples normally
- long remain = out_count - pos;
- if ( remain )
- {
- emu_play( remain, out + pos );
- track_ended_ |= emu_track_ended_;
-
- if ( !ignore_silence_ || out_time > fade_start )
- {
- // check end for a new run of silence
- long silence = count_silence( out + pos, remain );
- if ( silence < remain )
- silence_time = emu_time - silence;
-
- if ( emu_time - silence_time >= buf_size )
- fill_buf(); // cause silence detection on next play()
- }
- }
-
- if ( out_time > fade_start )
- handle_fade( out_count, out );
- }
- out_time += out_count;
- return 0;
-}
-
-// Gme_Info_
-
-blargg_err_t Gme_Info_::set_sample_rate_( long ) { return 0; }
-void Gme_Info_::pre_load() { Gme_File::pre_load(); } // skip Music_Emu
-void Gme_Info_::post_load_() { Gme_File::post_load_(); } // skip Music_Emu
-void Gme_Info_::set_equalizer_( equalizer_t const& ){ check( false ); }
-void Gme_Info_::mute_voices_( int ) { check( false ); }
-void Gme_Info_::set_tempo_( double ) { }
-blargg_err_t Gme_Info_::start_track_( int ) { return "Use full emulator for playback"; }
-blargg_err_t Gme_Info_::play_( long, sample_t* ) { return "Use full emulator for playback"; }
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Music_Emu.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/Music_Emu.h
deleted file mode 100644
index 573403ce..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Music_Emu.h
+++ /dev/null
@@ -1,211 +0,0 @@
-// Common interface to game music file emulators
-
-// Game_Music_Emu 0.5.2
-#ifndef MUSIC_EMU_H
-#define MUSIC_EMU_H
-
-#include "Gme_File.h"
-class Multi_Buffer;
-
-struct Music_Emu : public Gme_File {
-public:
-// Basic functionality (see Gme_File.h for file loading/track info functions)
-
- // Set output sample rate. Must be called only once before loading file.
- blargg_err_t set_sample_rate( long sample_rate );
-
- // Start a track, where 0 is the first track. Also clears warning string.
- blargg_err_t start_track( int );
-
- // Generate 'count' samples info 'buf'. Output is in stereo. Any emulation
- // errors set warning string, and major errors also end track.
- typedef short sample_t;
- blargg_err_t play( long count, sample_t* buf );
-
-// Informational
-
- // Sample rate sound is generated at
- long sample_rate() const;
-
- // Index of current track or -1 if one hasn't been started
- int current_track() const;
-
- // Number of voices used by currently loaded file
- int voice_count() const;
-
- // Names of voices
- const char** voice_names() const;
-
-// Track status/control
-
- // Number of milliseconds (1000 msec = 1 second) played since beginning of track
- long tell() const;
-
- // Seek to new time in track. Seeking backwards or far forward can take a while.
- blargg_err_t seek( long msec );
-
- // Skip n samples
- blargg_err_t skip( long n );
-
- // True if a track has reached its end
- bool track_ended() const;
-
- // Set start time and length of track fade out. Once fade ends track_ended() returns
- // true. Fade time can be changed while track is playing.
- void set_fade( long start_msec, long length_msec = 8000 );
-
- // Disable automatic end-of-track detection and skipping of silence at beginning
- void ignore_silence( bool disable = true );
-
- // Info for current track
- Gme_File::track_info;
- blargg_err_t track_info( track_info_t* out ) const;
-
-// Sound customization
-
- // Adjust song tempo, where 1.0 = normal, 0.5 = half speed, 2.0 = double speed.
- // Track length as returned by track_info() assumes a tempo of 1.0.
- void set_tempo( double );
-
- // Mute/unmute voice i, where voice 0 is first voice
- void mute_voice( int index, bool mute = true );
-
- // Set muting state of all voices at once using a bit mask, where -1 mutes them all,
- // 0 unmutes them all, 0x01 mutes just the first voice, etc.
- void mute_voices( int mask );
-
- // Change overall output amplitude, where 1.0 results in minimal clamping.
- // Must be called before set_sample_rate().
- void set_gain( double );
-
- // Request use of custom multichannel buffer. Only supported by "classic" emulators;
- // on others this has no effect. Should be called only once *before* set_sample_rate().
- virtual void set_buffer( Multi_Buffer* ) { }
-
-// Sound equalization (treble/bass)
-
- // Frequency equalizer parameters (see gme.txt)
- // See gme.h for definition of struct gme_equalizer_t.
- typedef gme_equalizer_t equalizer_t;
-
- // Current frequency equalizater parameters
- equalizer_t const& equalizer() const;
-
- // Set frequency equalizer parameters
- void set_equalizer( equalizer_t const& );
-
- // Equalizer settings for TV speaker
- static equalizer_t const tv_eq;
-
-public:
- Music_Emu();
- ~Music_Emu();
-protected:
- void set_max_initial_silence( int n ) { max_initial_silence = n; }
- void set_silence_lookahead( int n ) { silence_lookahead = n; }
- void set_voice_count( int n ) { voice_count_ = n; }
- void set_voice_names( const char* const* names );
- void set_track_ended() { emu_track_ended_ = true; }
- double gain() const { return gain_; }
- double tempo() const { return tempo_; }
- void remute_voices();
-
- virtual blargg_err_t set_sample_rate_( long sample_rate ) = 0;
- virtual void set_equalizer_( equalizer_t const& ) { };
- virtual void mute_voices_( int mask ) = 0;
- virtual void set_tempo_( double ) = 0;
- virtual blargg_err_t start_track_( int ) = 0; // tempo is set before this
- virtual blargg_err_t play_( long count, sample_t* out ) = 0;
- virtual blargg_err_t skip_( long count );
-protected:
- virtual void unload();
- virtual void pre_load();
- virtual void post_load_();
-private:
- // general
- equalizer_t equalizer_;
- int max_initial_silence;
- const char** voice_names_;
- int voice_count_;
- int mute_mask_;
- double tempo_;
- double gain_;
-
- long sample_rate_;
- blargg_long msec_to_samples( blargg_long msec ) const;
-
- // track-specific
- int current_track_;
- blargg_long out_time; // number of samples played since start of track
- blargg_long emu_time; // number of samples emulator has generated since start of track
- bool emu_track_ended_; // emulator has reached end of track
- volatile bool track_ended_;
- void clear_track_vars();
- void end_track_if_error( blargg_err_t );
-
- // fading
- blargg_long fade_start;
- int fade_step;
- void handle_fade( long count, sample_t* out );
-
- // silence detection
- int silence_lookahead; // speed to run emulator when looking ahead for silence
- bool ignore_silence_;
- long silence_time; // number of samples where most recent silence began
- long silence_count; // number of samples of silence to play before using buf
- long buf_remain; // number of samples left in silence buffer
- enum { buf_size = 2048 };
- blargg_vector<sample_t> buf;
- void fill_buf();
- void emu_play( long count, sample_t* out );
-
- Multi_Buffer* effects_buffer;
- friend Music_Emu* gme_new_emu( gme_type_t, long );
- friend void gme_set_stereo_depth( Music_Emu*, double );
-};
-
-// base class for info-only derivations
-struct Gme_Info_ : Music_Emu
-{
- virtual blargg_err_t set_sample_rate_( long sample_rate );
- virtual void set_equalizer_( equalizer_t const& );
- virtual void mute_voices_( int mask );
- virtual void set_tempo_( double );
- virtual blargg_err_t start_track_( int );
- virtual blargg_err_t play_( long count, sample_t* out );
- virtual void pre_load();
- virtual void post_load_();
-};
-
-inline blargg_err_t Music_Emu::track_info( track_info_t* out ) const
-{
- return track_info( out, current_track_ );
-}
-
-inline long Music_Emu::sample_rate() const { return sample_rate_; }
-inline const char** Music_Emu::voice_names() const { return voice_names_; }
-inline int Music_Emu::voice_count() const { return voice_count_; }
-inline int Music_Emu::current_track() const { return current_track_; }
-inline bool Music_Emu::track_ended() const { return track_ended_; }
-inline const Music_Emu::equalizer_t& Music_Emu::equalizer() const { return equalizer_; }
-
-inline void Music_Emu::set_tempo_( double t ) { tempo_ = t; }
-inline void Music_Emu::remute_voices() { mute_voices( mute_mask_ ); }
-inline void Music_Emu::ignore_silence( bool b ) { ignore_silence_ = b; }
-inline blargg_err_t Music_Emu::start_track_( int ) { return 0; }
-
-inline void Music_Emu::set_voice_names( const char* const* names )
-{
- // Intentional removal of const, so users don't have to remember obscure const in middle
- voice_names_ = (const char**) names;
-}
-
-inline void Music_Emu::mute_voices_( int ) { }
-
-inline void Music_Emu::set_gain( double g )
-{
- assert( !sample_rate() ); // you must set gain before setting sample rate
- gain_ = g;
-}
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Nes_Apu.cpp b/plugins/gme/Game_Music_Emu-0.5.2/gme/Nes_Apu.cpp
deleted file mode 100644
index 8daf5d0e..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Nes_Apu.cpp
+++ /dev/null
@@ -1,391 +0,0 @@
-// Nes_Snd_Emu 0.1.8. http://www.slack.net/~ant/
-
-#include "Nes_Apu.h"
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-int const amp_range = 15;
-
-Nes_Apu::Nes_Apu() :
- square1( &square_synth ),
- square2( &square_synth )
-{
- tempo_ = 1.0;
- dmc.apu = this;
- dmc.prg_reader = NULL;
- irq_notifier_ = NULL;
-
- oscs [0] = &square1;
- oscs [1] = &square2;
- oscs [2] = &triangle;
- oscs [3] = &noise;
- oscs [4] = &dmc;
-
- output( NULL );
- volume( 1.0 );
- reset( false );
-}
-
-void Nes_Apu::treble_eq( const blip_eq_t& eq )
-{
- square_synth.treble_eq( eq );
- triangle.synth.treble_eq( eq );
- noise.synth.treble_eq( eq );
- dmc.synth.treble_eq( eq );
-}
-
-void Nes_Apu::enable_nonlinear( double v )
-{
- dmc.nonlinear = true;
- square_synth.volume( 1.3 * 0.25751258 / 0.742467605 * 0.25 / amp_range * v );
-
- const double tnd = 0.48 / 202 * nonlinear_tnd_gain();
- triangle.synth.volume( 3.0 * tnd );
- noise.synth.volume( 2.0 * tnd );
- dmc.synth.volume( tnd );
-
- square1 .last_amp = 0;
- square2 .last_amp = 0;
- triangle.last_amp = 0;
- noise .last_amp = 0;
- dmc .last_amp = 0;
-}
-
-void Nes_Apu::volume( double v )
-{
- dmc.nonlinear = false;
- square_synth.volume( 0.1128 / amp_range * v );
- triangle.synth.volume( 0.12765 / amp_range * v );
- noise.synth.volume( 0.0741 / amp_range * v );
- dmc.synth.volume( 0.42545 / 127 * v );
-}
-
-void Nes_Apu::output( Blip_Buffer* buffer )
-{
- for ( int i = 0; i < osc_count; i++ )
- osc_output( i, buffer );
-}
-
-void Nes_Apu::set_tempo( double t )
-{
- tempo_ = t;
- frame_period = (dmc.pal_mode ? 8314 : 7458);
- if ( t != 1.0 )
- frame_period = (int) (frame_period / t) & ~1; // must be even
-}
-
-void Nes_Apu::reset( bool pal_mode, int initial_dmc_dac )
-{
- dmc.pal_mode = pal_mode;
- set_tempo( tempo_ );
-
- square1.reset();
- square2.reset();
- triangle.reset();
- noise.reset();
- dmc.reset();
-
- last_time = 0;
- last_dmc_time = 0;
- osc_enables = 0;
- irq_flag = false;
- earliest_irq_ = no_irq;
- frame_delay = 1;
- write_register( 0, 0x4017, 0x00 );
- write_register( 0, 0x4015, 0x00 );
-
- for ( nes_addr_t addr = start_addr; addr <= 0x4013; addr++ )
- write_register( 0, addr, (addr & 3) ? 0x00 : 0x10 );
-
- dmc.dac = initial_dmc_dac;
- if ( !dmc.nonlinear )
- triangle.last_amp = 15;
- if ( !dmc.nonlinear ) // TODO: remove?
- dmc.last_amp = initial_dmc_dac; // prevent output transition
-}
-
-void Nes_Apu::irq_changed()
-{
- nes_time_t new_irq = dmc.next_irq;
- if ( dmc.irq_flag | irq_flag ) {
- new_irq = 0;
- }
- else if ( new_irq > next_irq ) {
- new_irq = next_irq;
- }
-
- if ( new_irq != earliest_irq_ ) {
- earliest_irq_ = new_irq;
- if ( irq_notifier_ )
- irq_notifier_( irq_data );
- }
-}
-
-// frames
-
-void Nes_Apu::run_until( nes_time_t end_time )
-{
- require( end_time >= last_dmc_time );
- if ( end_time > next_dmc_read_time() )
- {
- nes_time_t start = last_dmc_time;
- last_dmc_time = end_time;
- dmc.run( start, end_time );
- }
-}
-
-void Nes_Apu::run_until_( nes_time_t end_time )
-{
- require( end_time >= last_time );
-
- if ( end_time == last_time )
- return;
-
- if ( last_dmc_time < end_time )
- {
- nes_time_t start = last_dmc_time;
- last_dmc_time = end_time;
- dmc.run( start, end_time );
- }
-
- while ( true )
- {
- // earlier of next frame time or end time
- nes_time_t time = last_time + frame_delay;
- if ( time > end_time )
- time = end_time;
- frame_delay -= time - last_time;
-
- // run oscs to present
- square1.run( last_time, time );
- square2.run( last_time, time );
- triangle.run( last_time, time );
- noise.run( last_time, time );
- last_time = time;
-
- if ( time == end_time )
- break; // no more frames to run
-
- // take frame-specific actions
- frame_delay = frame_period;
- switch ( frame++ )
- {
- case 0:
- if ( !(frame_mode & 0xC0) ) {
- next_irq = time + frame_period * 4 + 2;
- irq_flag = true;
- }
- // fall through
- case 2:
- // clock length and sweep on frames 0 and 2
- square1.clock_length( 0x20 );
- square2.clock_length( 0x20 );
- noise.clock_length( 0x20 );
- triangle.clock_length( 0x80 ); // different bit for halt flag on triangle
-
- square1.clock_sweep( -1 );
- square2.clock_sweep( 0 );
-
- // frame 2 is slightly shorter in mode 1
- if ( dmc.pal_mode && frame == 3 )
- frame_delay -= 2;
- break;
-
- case 1:
- // frame 1 is slightly shorter in mode 0
- if ( !dmc.pal_mode )
- frame_delay -= 2;
- break;
-
- case 3:
- frame = 0;
-
- // frame 3 is almost twice as long in mode 1
- if ( frame_mode & 0x80 )
- frame_delay += frame_period - (dmc.pal_mode ? 2 : 6);
- break;
- }
-
- // clock envelopes and linear counter every frame
- triangle.clock_linear_counter();
- square1.clock_envelope();
- square2.clock_envelope();
- noise.clock_envelope();
- }
-}
-
-template<class T>
-inline void zero_apu_osc( T* osc, nes_time_t time )
-{
- Blip_Buffer* output = osc->output;
- int last_amp = osc->last_amp;
- osc->last_amp = 0;
- if ( output && last_amp )
- osc->synth.offset( time, -last_amp, output );
-}
-
-void Nes_Apu::end_frame( nes_time_t end_time )
-{
- if ( end_time > last_time )
- run_until_( end_time );
-
- if ( dmc.nonlinear )
- {
- zero_apu_osc( &square1, last_time );
- zero_apu_osc( &square2, last_time );
- zero_apu_osc( &triangle, last_time );
- zero_apu_osc( &noise, last_time );
- zero_apu_osc( &dmc, last_time );
- }
-
- // make times relative to new frame
- last_time -= end_time;
- require( last_time >= 0 );
-
- last_dmc_time -= end_time;
- require( last_dmc_time >= 0 );
-
- if ( next_irq != no_irq ) {
- next_irq -= end_time;
- check( next_irq >= 0 );
- }
- if ( dmc.next_irq != no_irq ) {
- dmc.next_irq -= end_time;
- check( dmc.next_irq >= 0 );
- }
- if ( earliest_irq_ != no_irq ) {
- earliest_irq_ -= end_time;
- if ( earliest_irq_ < 0 )
- earliest_irq_ = 0;
- }
-}
-
-// registers
-
-static const unsigned char length_table [0x20] = {
- 0x0A, 0xFE, 0x14, 0x02, 0x28, 0x04, 0x50, 0x06,
- 0xA0, 0x08, 0x3C, 0x0A, 0x0E, 0x0C, 0x1A, 0x0E,
- 0x0C, 0x10, 0x18, 0x12, 0x30, 0x14, 0x60, 0x16,
- 0xC0, 0x18, 0x48, 0x1A, 0x10, 0x1C, 0x20, 0x1E
-};
-
-void Nes_Apu::write_register( nes_time_t time, nes_addr_t addr, int data )
-{
- require( addr > 0x20 ); // addr must be actual address (i.e. 0x40xx)
- require( (unsigned) data <= 0xFF );
-
- // Ignore addresses outside range
- if ( unsigned (addr - start_addr) > end_addr - start_addr )
- return;
-
- run_until_( time );
-
- if ( addr < 0x4014 )
- {
- // Write to channel
- int osc_index = (addr - start_addr) >> 2;
- Nes_Osc* osc = oscs [osc_index];
-
- int reg = addr & 3;
- osc->regs [reg] = data;
- osc->reg_written [reg] = true;
-
- if ( osc_index == 4 )
- {
- // handle DMC specially
- dmc.write_register( reg, data );
- }
- else if ( reg == 3 )
- {
- // load length counter
- if ( (osc_enables >> osc_index) & 1 )
- osc->length_counter = length_table [(data >> 3) & 0x1F];
-
- // reset square phase
- if ( osc_index < 2 )
- ((Nes_Square*) osc)->phase = Nes_Square::phase_range - 1;
- }
- }
- else if ( addr == 0x4015 )
- {
- // Channel enables
- for ( int i = osc_count; i--; )
- if ( !((data >> i) & 1) )
- oscs [i]->length_counter = 0;
-
- bool recalc_irq = dmc.irq_flag;
- dmc.irq_flag = false;
-
- int old_enables = osc_enables;
- osc_enables = data;
- if ( !(data & 0x10) ) {
- dmc.next_irq = no_irq;
- recalc_irq = true;
- }
- else if ( !(old_enables & 0x10) ) {
- dmc.start(); // dmc just enabled
- }
-
- if ( recalc_irq )
- irq_changed();
- }
- else if ( addr == 0x4017 )
- {
- // Frame mode
- frame_mode = data;
-
- bool irq_enabled = !(data & 0x40);
- irq_flag &= irq_enabled;
- next_irq = no_irq;
-
- // mode 1
- frame_delay = (frame_delay & 1);
- frame = 0;
-
- if ( !(data & 0x80) )
- {
- // mode 0
- frame = 1;
- frame_delay += frame_period;
- if ( irq_enabled )
- next_irq = time + frame_delay + frame_period * 3 + 1;
- }
-
- irq_changed();
- }
-}
-
-int Nes_Apu::read_status( nes_time_t time )
-{
- run_until_( time - 1 );
-
- int result = (dmc.irq_flag << 7) | (irq_flag << 6);
-
- for ( int i = 0; i < osc_count; i++ )
- if ( oscs [i]->length_counter )
- result |= 1 << i;
-
- run_until_( time );
-
- if ( irq_flag )
- {
- result |= 0x40;
- irq_flag = false;
- irq_changed();
- }
-
- //dprintf( "%6d/%d Read $4015->$%02X\n", frame_delay, frame, result );
-
- return result;
-}
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Nes_Apu.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/Nes_Apu.h
deleted file mode 100644
index dbd8484c..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Nes_Apu.h
+++ /dev/null
@@ -1,179 +0,0 @@
-// NES 2A03 APU sound chip emulator
-
-// Nes_Snd_Emu 0.1.8
-#ifndef NES_APU_H
-#define NES_APU_H
-
-#include "blargg_common.h"
-
-typedef blargg_long nes_time_t; // CPU clock cycle count
-typedef unsigned nes_addr_t; // 16-bit memory address
-
-#include "Nes_Oscs.h"
-
-struct apu_state_t;
-class Nes_Buffer;
-
-class Nes_Apu {
-public:
- // Set buffer to generate all sound into, or disable sound if NULL
- void output( Blip_Buffer* );
-
- // Set memory reader callback used by DMC oscillator to fetch samples.
- // When callback is invoked, 'user_data' is passed unchanged as the
- // first parameter.
- void dmc_reader( int (*callback)( void* user_data, nes_addr_t ), void* user_data = NULL );
-
- // All time values are the number of CPU clock cycles relative to the
- // beginning of the current time frame. Before resetting the CPU clock
- // count, call end_frame( last_cpu_time ).
-
- // Write to register (0x4000-0x4017, except 0x4014 and 0x4016)
- enum { start_addr = 0x4000 };
- enum { end_addr = 0x4017 };
- void write_register( nes_time_t, nes_addr_t, int data );
-
- // Read from status register at 0x4015
- enum { status_addr = 0x4015 };
- int read_status( nes_time_t );
-
- // Run all oscillators up to specified time, end current time frame, then
- // start a new time frame at time 0. Time frames have no effect on emulation
- // and each can be whatever length is convenient.
- void end_frame( nes_time_t );
-
-// Additional optional features (can be ignored without any problem)
-
- // Reset internal frame counter, registers, and all oscillators.
- // Use PAL timing if pal_timing is true, otherwise use NTSC timing.
- // Set the DMC oscillator's initial DAC value to initial_dmc_dac without
- // any audible click.
- void reset( bool pal_mode = false, int initial_dmc_dac = 0 );
-
- // Adjust frame period
- void set_tempo( double );
-
- // Save/load exact emulation state
- void save_state( apu_state_t* out ) const;
- void load_state( apu_state_t const& );
-
- // Set overall volume (default is 1.0)
- void volume( double );
-
- // Set treble equalization (see notes.txt)
- void treble_eq( const blip_eq_t& );
-
- // Set sound output of specific oscillator to buffer. If buffer is NULL,
- // the specified oscillator is muted and emulation accuracy is reduced.
- // The oscillators are indexed as follows: 0) Square 1, 1) Square 2,
- // 2) Triangle, 3) Noise, 4) DMC.
- enum { osc_count = 5 };
- void osc_output( int index, Blip_Buffer* buffer );
-
- // Set IRQ time callback that is invoked when the time of earliest IRQ
- // may have changed, or NULL to disable. When callback is invoked,
- // 'user_data' is passed unchanged as the first parameter.
- void irq_notifier( void (*callback)( void* user_data ), void* user_data = NULL );
-
- // Get time that APU-generated IRQ will occur if no further register reads
- // or writes occur. If IRQ is already pending, returns irq_waiting. If no
- // IRQ will occur, returns no_irq.
- enum { no_irq = LONG_MAX / 2 + 1 };
- enum { irq_waiting = 0 };
- nes_time_t earliest_irq( nes_time_t ) const;
-
- // Count number of DMC reads that would occur if 'run_until( t )' were executed.
- // If last_read is not NULL, set *last_read to the earliest time that
- // 'count_dmc_reads( time )' would result in the same result.
- int count_dmc_reads( nes_time_t t, nes_time_t* last_read = NULL ) const;
-
- // Time when next DMC memory read will occur
- nes_time_t next_dmc_read_time() const;
-
- // Run DMC until specified time, so that any DMC memory reads can be
- // accounted for (i.e. inserting CPU wait states).
- void run_until( nes_time_t );
-
-public:
- Nes_Apu();
- BLARGG_DISABLE_NOTHROW
-private:
- friend class Nes_Nonlinearizer;
- void enable_nonlinear( double volume );
- static double nonlinear_tnd_gain() { return 0.75; }
-private:
- friend struct Nes_Dmc;
-
- // noncopyable
- Nes_Apu( const Nes_Apu& );
- Nes_Apu& operator = ( const Nes_Apu& );
-
- Nes_Osc* oscs [osc_count];
- Nes_Square square1;
- Nes_Square square2;
- Nes_Noise noise;
- Nes_Triangle triangle;
- Nes_Dmc dmc;
-
- double tempo_;
- nes_time_t last_time; // has been run until this time in current frame
- nes_time_t last_dmc_time;
- nes_time_t earliest_irq_;
- nes_time_t next_irq;
- int frame_period;
- int frame_delay; // cycles until frame counter runs next
- int frame; // current frame (0-3)
- int osc_enables;
- int frame_mode;
- bool irq_flag;
- void (*irq_notifier_)( void* user_data );
- void* irq_data;
- Nes_Square::Synth square_synth; // shared by squares
-
- void irq_changed();
- void state_restored();
- void run_until_( nes_time_t );
-
- // TODO: remove
- friend class Nes_Core;
-};
-
-inline void Nes_Apu::osc_output( int osc, Blip_Buffer* buf )
-{
- assert( (unsigned) osc < osc_count );
- oscs [osc]->output = buf;
-}
-
-inline nes_time_t Nes_Apu::earliest_irq( nes_time_t ) const
-{
- return earliest_irq_;
-}
-
-inline void Nes_Apu::dmc_reader( int (*func)( void*, nes_addr_t ), void* user_data )
-{
- dmc.prg_reader_data = user_data;
- dmc.prg_reader = func;
-}
-
-inline void Nes_Apu::irq_notifier( void (*func)( void* user_data ), void* user_data )
-{
- irq_notifier_ = func;
- irq_data = user_data;
-}
-
-inline int Nes_Apu::count_dmc_reads( nes_time_t time, nes_time_t* last_read ) const
-{
- return dmc.count_reads( time, last_read );
-}
-
-inline nes_time_t Nes_Dmc::next_read_time() const
-{
- if ( length_counter == 0 )
- return Nes_Apu::no_irq; // not reading
-
- return apu->last_dmc_time + delay + long (bits_remain - 1) * period;
-}
-
-inline nes_time_t Nes_Apu::next_dmc_read_time() const { return dmc.next_read_time(); }
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Nes_Cpu.cpp b/plugins/gme/Game_Music_Emu-0.5.2/gme/Nes_Cpu.cpp
deleted file mode 100644
index 480b4aa4..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Nes_Cpu.cpp
+++ /dev/null
@@ -1,1084 +0,0 @@
-// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
-
-#include "Nes_Cpu.h"
-
-#include "blargg_endian.h"
-#include <limits.h>
-
-#define BLARGG_CPU_X86 1
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#ifdef BLARGG_ENABLE_OPTIMIZER
- #include BLARGG_ENABLE_OPTIMIZER
-#endif
-
-#define FLUSH_TIME() (void) (s.time = s_time)
-#define CACHE_TIME() (void) (s_time = s.time)
-
-#include "nes_cpu_io.h"
-
-#include "blargg_source.h"
-
-#ifndef CPU_DONE
- #define CPU_DONE( cpu, time, result_out ) { result_out = -1; }
-#endif
-
-#ifndef CPU_READ_PPU
- #define CPU_READ_PPU( cpu, addr, out, time )\
- {\
- FLUSH_TIME();\
- out = CPU_READ( cpu, addr, time );\
- CACHE_TIME();\
- }
-#endif
-
-#if BLARGG_NONPORTABLE
- #define PAGE_OFFSET( addr ) (addr)
-#else
- #define PAGE_OFFSET( addr ) ((addr) & (page_size - 1))
-#endif
-
-inline void Nes_Cpu::set_code_page( int i, void const* p )
-{
- state->code_map [i] = (uint8_t const*) p - PAGE_OFFSET( i * page_size );
-}
-
-int const st_n = 0x80;
-int const st_v = 0x40;
-int const st_r = 0x20;
-int const st_b = 0x10;
-int const st_d = 0x08;
-int const st_i = 0x04;
-int const st_z = 0x02;
-int const st_c = 0x01;
-
-void Nes_Cpu::reset( void const* unmapped_page )
-{
- check( state == &state_ );
- state = &state_;
- r.status = st_i;
- r.sp = 0xFF;
- r.pc = 0;
- r.a = 0;
- r.x = 0;
- r.y = 0;
- state_.time = 0;
- state_.base = 0;
- irq_time_ = future_nes_time;
- end_time_ = future_nes_time;
- error_count_ = 0;
-
- assert( page_size == 0x800 ); // assumes this
- set_code_page( page_count, unmapped_page );
- map_code( 0x2000, 0xE000, unmapped_page, true );
- map_code( 0x0000, 0x2000, low_mem, true );
-
- blargg_verify_byte_order();
-}
-
-void Nes_Cpu::map_code( nes_addr_t start, unsigned size, void const* data, bool mirror )
-{
- // address range must begin and end on page boundaries
- require( start % page_size == 0 );
- require( size % page_size == 0 );
- require( start + size <= 0x10000 );
-
- unsigned page = start / page_size;
- for ( unsigned n = size / page_size; n; --n )
- {
- set_code_page( page++, data );
- if ( !mirror )
- data = (char const*) data + page_size;
- }
-}
-
-#define TIME (s_time + s.base)
-#define READ_LIKELY_PPU( addr, out ) {CPU_READ_PPU( this, (addr), out, TIME );}
-#define READ( addr ) CPU_READ( this, (addr), TIME )
-#define WRITE( addr, data ) {CPU_WRITE( this, (addr), (data), TIME );}
-#define READ_LOW( addr ) (low_mem [int (addr)])
-#define WRITE_LOW( addr, data ) (void) (READ_LOW( addr ) = (data))
-#define READ_PROG( addr ) (s.code_map [(addr) >> page_bits] [PAGE_OFFSET( addr )])
-
-#define SET_SP( v ) (sp = ((v) + 1) | 0x100)
-#define GET_SP() ((sp - 1) & 0xFF)
-#define PUSH( v ) ((sp = (sp - 1) | 0x100), WRITE_LOW( sp, v ))
-
-// even on x86, using short and unsigned char was slower
-typedef int fint16;
-typedef unsigned fuint16;
-typedef unsigned fuint8;
-
-bool Nes_Cpu::run( nes_time_t end_time )
-{
- set_end_time( end_time );
- state_t s = this->state_;
- this->state = &s;
- // even on x86, using s.time in place of s_time was slower
- fint16 s_time = s.time;
-
- // registers
- fuint16 pc = r.pc;
- fuint8 a = r.a;
- fuint8 x = r.x;
- fuint8 y = r.y;
- fuint16 sp;
- SET_SP( r.sp );
-
- // status flags
- #define IS_NEG (nz & 0x8080)
-
- #define CALC_STATUS( out ) do {\
- out = status & (st_v | st_d | st_i);\
- out |= ((nz >> 8) | nz) & st_n;\
- out |= c >> 8 & st_c;\
- if ( !(nz & 0xFF) ) out |= st_z;\
- } while ( 0 )
-
- #define SET_STATUS( in ) do {\
- status = in & (st_v | st_d | st_i);\
- nz = in << 8;\
- c = nz;\
- nz |= ~in & st_z;\
- } while ( 0 )
-
- fuint8 status;
- fuint16 c; // carry set if (c & 0x100) != 0
- fuint16 nz; // Z set if (nz & 0xFF) == 0, N set if (nz & 0x8080) != 0
- {
- fuint8 temp = r.status;
- SET_STATUS( temp );
- }
-
- goto loop;
-dec_clock_loop:
- s_time--;
-loop:
-
- check( (unsigned) GET_SP() < 0x100 );
- check( (unsigned) pc < 0x10000 );
- check( (unsigned) a < 0x100 );
- check( (unsigned) x < 0x100 );
- check( (unsigned) y < 0x100 );
- check( -32768 <= s_time && s_time < 32767 );
-
- uint8_t const* instr = s.code_map [pc >> page_bits];
- fuint8 opcode;
-
- // TODO: eliminate this special case
- #if BLARGG_NONPORTABLE
- opcode = instr [pc];
- pc++;
- instr += pc;
- #else
- instr += PAGE_OFFSET( pc );
- opcode = *instr++;
- pc++;
- #endif
-
- static uint8_t const clock_table [256] =
- {// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0,6,2,8,3,3,5,5,3,2,2,2,4,4,6,6,// 0
- 3,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,// 1
- 6,6,2,8,3,3,5,5,4,2,2,2,4,4,6,6,// 2
- 3,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,// 3
- 6,6,2,8,3,3,5,5,3,2,2,2,3,4,6,6,// 4
- 3,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,// 5
- 6,6,2,8,3,3,5,5,4,2,2,2,5,4,6,6,// 6
- 3,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,// 7
- 2,6,2,6,3,3,3,3,2,2,2,2,4,4,4,4,// 8
- 3,6,2,6,4,4,4,4,2,5,2,5,5,5,5,5,// 9
- 2,6,2,6,3,3,3,3,2,2,2,2,4,4,4,4,// A
- 3,5,2,5,4,4,4,4,2,4,2,4,4,4,4,4,// B
- 2,6,2,8,3,3,5,5,2,2,2,2,4,4,6,6,// C
- 3,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,// D
- 2,6,2,8,3,3,5,5,2,2,2,2,4,4,6,6,// E
- 3,5,0,8,4,4,6,6,2,4,2,7,4,4,7,7 // F
- }; // 0x00 was 7 and 0xF2 was 2
-
- fuint16 data;
-
-#if !BLARGG_CPU_X86
- if ( s_time >= 0 )
- goto out_of_time;
- s_time += clock_table [opcode];
-
- data = *instr;
-
- switch ( opcode )
- {
-#else
-
- data = clock_table [opcode];
- if ( (s_time += data) >= 0 )
- goto possibly_out_of_time;
-almost_out_of_time:
-
- data = *instr;
-
- switch ( opcode )
- {
-possibly_out_of_time:
- if ( s_time < (int) data )
- goto almost_out_of_time;
- s_time -= data;
- goto out_of_time;
-#endif
-
-// Macros
-
-#define GET_MSB() (instr [1])
-#define ADD_PAGE() (pc++, data += 0x100 * GET_MSB())
-#define GET_ADDR() GET_LE16( instr )
-
-#define NO_PAGE_CROSSING( lsb )
-#define HANDLE_PAGE_CROSSING( lsb ) s_time += (lsb) >> 8;
-
-#define INC_DEC_XY( reg, n ) reg = uint8_t (nz = reg + n); goto loop;
-
-#define IND_Y( cross, out ) {\
- fuint16 temp = READ_LOW( data ) + y;\
- out = temp + 0x100 * READ_LOW( uint8_t (data + 1) );\
- cross( temp );\
- }
-
-#define IND_X( out ) {\
- fuint16 temp = data + x;\
- out = 0x100 * READ_LOW( uint8_t (temp + 1) ) + READ_LOW( uint8_t (temp) );\
- }
-
-#define ARITH_ADDR_MODES( op )\
-case op - 0x04: /* (ind,x) */\
- IND_X( data )\
- goto ptr##op;\
-case op + 0x0C: /* (ind),y */\
- IND_Y( HANDLE_PAGE_CROSSING, data )\
- goto ptr##op;\
-case op + 0x10: /* zp,X */\
- data = uint8_t (data + x);\
-case op + 0x00: /* zp */\
- data = READ_LOW( data );\
- goto imm##op;\
-case op + 0x14: /* abs,Y */\
- data += y;\
- goto ind##op;\
-case op + 0x18: /* abs,X */\
- data += x;\
-ind##op:\
- HANDLE_PAGE_CROSSING( data );\
-case op + 0x08: /* abs */\
- ADD_PAGE();\
-ptr##op:\
- FLUSH_TIME();\
- data = READ( data );\
- CACHE_TIME();\
-case op + 0x04: /* imm */\
-imm##op:
-
-// TODO: more efficient way to handle negative branch that wraps PC around
-#define BRANCH( cond )\
-{\
- fint16 offset = (BOOST::int8_t) data;\
- fuint16 extra_clock = (++pc & 0xFF) + offset;\
- if ( !(cond) ) goto dec_clock_loop;\
- pc = BOOST::uint16_t (pc + offset);\
- s_time += extra_clock >> 8 & 1;\
- goto loop;\
-}
-
-// Often-Used
-
- case 0xB5: // LDA zp,x
- a = nz = READ_LOW( uint8_t (data + x) );
- pc++;
- goto loop;
-
- case 0xA5: // LDA zp
- a = nz = READ_LOW( data );
- pc++;
- goto loop;
-
- case 0xD0: // BNE
- BRANCH( (uint8_t) nz );
-
- case 0x20: { // JSR
- fuint16 temp = pc + 1;
- pc = GET_ADDR();
- WRITE_LOW( 0x100 | (sp - 1), temp >> 8 );
- sp = (sp - 2) | 0x100;
- WRITE_LOW( sp, temp );
- goto loop;
- }
-
- case 0x4C: // JMP abs
- pc = GET_ADDR();
- goto loop;
-
- case 0xE8: // INX
- INC_DEC_XY( x, 1 )
-
- case 0x10: // BPL
- BRANCH( !IS_NEG )
-
- ARITH_ADDR_MODES( 0xC5 ) // CMP
- nz = a - data;
- pc++;
- c = ~nz;
- nz &= 0xFF;
- goto loop;
-
- case 0x30: // BMI
- BRANCH( IS_NEG )
-
- case 0xF0: // BEQ
- BRANCH( !(uint8_t) nz );
-
- case 0x95: // STA zp,x
- data = uint8_t (data + x);
- case 0x85: // STA zp
- pc++;
- WRITE_LOW( data, a );
- goto loop;
-
- case 0xC8: // INY
- INC_DEC_XY( y, 1 )
-
- case 0xA8: // TAY
- y = a;
- nz = a;
- goto loop;
-
- case 0x98: // TYA
- a = y;
- nz = y;
- goto loop;
-
- case 0xAD:{// LDA abs
- unsigned addr = GET_ADDR();
- pc += 2;
- READ_LIKELY_PPU( addr, nz );
- a = nz;
- goto loop;
- }
-
- case 0x60: // RTS
- pc = 1 + READ_LOW( sp );
- pc += 0x100 * READ_LOW( 0x100 | (sp - 0xFF) );
- sp = (sp - 0xFE) | 0x100;
- goto loop;
-
- {
- fuint16 addr;
-
- case 0x99: // STA abs,Y
- addr = y + GET_ADDR();
- pc += 2;
- if ( addr <= 0x7FF )
- {
- WRITE_LOW( addr, a );
- goto loop;
- }
- goto sta_ptr;
-
- case 0x8D: // STA abs
- addr = GET_ADDR();
- pc += 2;
- if ( addr <= 0x7FF )
- {
- WRITE_LOW( addr, a );
- goto loop;
- }
- goto sta_ptr;
-
- case 0x9D: // STA abs,X (slightly more common than STA abs)
- addr = x + GET_ADDR();
- pc += 2;
- if ( addr <= 0x7FF )
- {
- WRITE_LOW( addr, a );
- goto loop;
- }
- sta_ptr:
- FLUSH_TIME();
- WRITE( addr, a );
- CACHE_TIME();
- goto loop;
-
- case 0x91: // STA (ind),Y
- IND_Y( NO_PAGE_CROSSING, addr )
- pc++;
- goto sta_ptr;
-
- case 0x81: // STA (ind,X)
- IND_X( addr )
- pc++;
- goto sta_ptr;
-
- }
-
- case 0xA9: // LDA #imm
- pc++;
- a = data;
- nz = data;
- goto loop;
-
- // common read instructions
- {
- fuint16 addr;
-
- case 0xA1: // LDA (ind,X)
- IND_X( addr )
- pc++;
- goto a_nz_read_addr;
-
- case 0xB1:// LDA (ind),Y
- addr = READ_LOW( data ) + y;
- HANDLE_PAGE_CROSSING( addr );
- addr += 0x100 * READ_LOW( (uint8_t) (data + 1) );
- pc++;
- a = nz = READ_PROG( addr );
- if ( (addr ^ 0x8000) <= 0x9FFF )
- goto loop;
- goto a_nz_read_addr;
-
- case 0xB9: // LDA abs,Y
- HANDLE_PAGE_CROSSING( data + y );
- addr = GET_ADDR() + y;
- pc += 2;
- a = nz = READ_PROG( addr );
- if ( (addr ^ 0x8000) <= 0x9FFF )
- goto loop;
- goto a_nz_read_addr;
-
- case 0xBD: // LDA abs,X
- HANDLE_PAGE_CROSSING( data + x );
- addr = GET_ADDR() + x;
- pc += 2;
- a = nz = READ_PROG( addr );
- if ( (addr ^ 0x8000) <= 0x9FFF )
- goto loop;
- a_nz_read_addr:
- FLUSH_TIME();
- a = nz = READ( addr );
- CACHE_TIME();
- goto loop;
-
- }
-
-// Branch
-
- case 0x50: // BVC
- BRANCH( !(status & st_v) )
-
- case 0x70: // BVS
- BRANCH( status & st_v )
-
- case 0xB0: // BCS
- BRANCH( c & 0x100 )
-
- case 0x90: // BCC
- BRANCH( !(c & 0x100) )
-
-// Load/store
-
- case 0x94: // STY zp,x
- data = uint8_t (data + x);
- case 0x84: // STY zp
- pc++;
- WRITE_LOW( data, y );
- goto loop;
-
- case 0x96: // STX zp,y
- data = uint8_t (data + y);
- case 0x86: // STX zp
- pc++;
- WRITE_LOW( data, x );
- goto loop;
-
- case 0xB6: // LDX zp,y
- data = uint8_t (data + y);
- case 0xA6: // LDX zp
- data = READ_LOW( data );
- case 0xA2: // LDX #imm
- pc++;
- x = data;
- nz = data;
- goto loop;
-
- case 0xB4: // LDY zp,x
- data = uint8_t (data + x);
- case 0xA4: // LDY zp
- data = READ_LOW( data );
- case 0xA0: // LDY #imm
- pc++;
- y = data;
- nz = data;
- goto loop;
-
- case 0xBC: // LDY abs,X
- data += x;
- HANDLE_PAGE_CROSSING( data );
- case 0xAC:{// LDY abs
- unsigned addr = data + 0x100 * GET_MSB();
- pc += 2;
- FLUSH_TIME();
- y = nz = READ( addr );
- CACHE_TIME();
- goto loop;
- }
-
- case 0xBE: // LDX abs,y
- data += y;
- HANDLE_PAGE_CROSSING( data );
- case 0xAE:{// LDX abs
- unsigned addr = data + 0x100 * GET_MSB();
- pc += 2;
- FLUSH_TIME();
- x = nz = READ( addr );
- CACHE_TIME();
- goto loop;
- }
-
- {
- fuint8 temp;
- case 0x8C: // STY abs
- temp = y;
- goto store_abs;
-
- case 0x8E: // STX abs
- temp = x;
- store_abs:
- unsigned addr = GET_ADDR();
- pc += 2;
- if ( addr <= 0x7FF )
- {
- WRITE_LOW( addr, temp );
- goto loop;
- }
- FLUSH_TIME();
- WRITE( addr, temp );
- CACHE_TIME();
- goto loop;
- }
-
-// Compare
-
- case 0xEC:{// CPX abs
- unsigned addr = GET_ADDR();
- pc++;
- FLUSH_TIME();
- data = READ( addr );
- CACHE_TIME();
- goto cpx_data;
- }
-
- case 0xE4: // CPX zp
- data = READ_LOW( data );
- case 0xE0: // CPX #imm
- cpx_data:
- nz = x - data;
- pc++;
- c = ~nz;
- nz &= 0xFF;
- goto loop;
-
- case 0xCC:{// CPY abs
- unsigned addr = GET_ADDR();
- pc++;
- FLUSH_TIME();
- data = READ( addr );
- CACHE_TIME();
- goto cpy_data;
- }
-
- case 0xC4: // CPY zp
- data = READ_LOW( data );
- case 0xC0: // CPY #imm
- cpy_data:
- nz = y - data;
- pc++;
- c = ~nz;
- nz &= 0xFF;
- goto loop;
-
-// Logical
-
- ARITH_ADDR_MODES( 0x25 ) // AND
- nz = (a &= data);
- pc++;
- goto loop;
-
- ARITH_ADDR_MODES( 0x45 ) // EOR
- nz = (a ^= data);
- pc++;
- goto loop;
-
- ARITH_ADDR_MODES( 0x05 ) // ORA
- nz = (a |= data);
- pc++;
- goto loop;
-
- case 0x2C:{// BIT abs
- unsigned addr = GET_ADDR();
- pc += 2;
- status &= ~st_v;
- READ_LIKELY_PPU( addr, nz );
- status |= nz & st_v;
- if ( a & nz )
- goto loop;
- nz <<= 8; // result must be zero, even if N bit is set
- goto loop;
- }
-
- case 0x24: // BIT zp
- nz = READ_LOW( data );
- pc++;
- status &= ~st_v;
- status |= nz & st_v;
- if ( a & nz )
- goto loop;
- nz <<= 8; // result must be zero, even if N bit is set
- goto loop;
-
-// Add/subtract
-
- ARITH_ADDR_MODES( 0xE5 ) // SBC
- case 0xEB: // unofficial equivalent
- data ^= 0xFF;
- goto adc_imm;
-
- ARITH_ADDR_MODES( 0x65 ) // ADC
- adc_imm: {
- fint16 carry = c >> 8 & 1;
- fint16 ov = (a ^ 0x80) + carry + (BOOST::int8_t) data; // sign-extend
- status &= ~st_v;
- status |= ov >> 2 & 0x40;
- c = nz = a + data + carry;
- pc++;
- a = (uint8_t) nz;
- goto loop;
- }
-
-// Shift/rotate
-
- case 0x4A: // LSR A
- c = 0;
- case 0x6A: // ROR A
- nz = c >> 1 & 0x80;
- c = a << 8;
- nz |= a >> 1;
- a = nz;
- goto loop;
-
- case 0x0A: // ASL A
- nz = a << 1;
- c = nz;
- a = (uint8_t) nz;
- goto loop;
-
- case 0x2A: { // ROL A
- nz = a << 1;
- fint16 temp = c >> 8 & 1;
- c = nz;
- nz |= temp;
- a = (uint8_t) nz;
- goto loop;
- }
-
- case 0x5E: // LSR abs,X
- data += x;
- case 0x4E: // LSR abs
- c = 0;
- case 0x6E: // ROR abs
- ror_abs: {
- ADD_PAGE();
- FLUSH_TIME();
- int temp = READ( data );
- nz = (c >> 1 & 0x80) | (temp >> 1);
- c = temp << 8;
- goto rotate_common;
- }
-
- case 0x3E: // ROL abs,X
- data += x;
- goto rol_abs;
-
- case 0x1E: // ASL abs,X
- data += x;
- case 0x0E: // ASL abs
- c = 0;
- case 0x2E: // ROL abs
- rol_abs:
- ADD_PAGE();
- nz = c >> 8 & 1;
- FLUSH_TIME();
- nz |= (c = READ( data ) << 1);
- rotate_common:
- pc++;
- WRITE( data, (uint8_t) nz );
- CACHE_TIME();
- goto loop;
-
- case 0x7E: // ROR abs,X
- data += x;
- goto ror_abs;
-
- case 0x76: // ROR zp,x
- data = uint8_t (data + x);
- goto ror_zp;
-
- case 0x56: // LSR zp,x
- data = uint8_t (data + x);
- case 0x46: // LSR zp
- c = 0;
- case 0x66: // ROR zp
- ror_zp: {
- int temp = READ_LOW( data );
- nz = (c >> 1 & 0x80) | (temp >> 1);
- c = temp << 8;
- goto write_nz_zp;
- }
-
- case 0x36: // ROL zp,x
- data = uint8_t (data + x);
- goto rol_zp;
-
- case 0x16: // ASL zp,x
- data = uint8_t (data + x);
- case 0x06: // ASL zp
- c = 0;
- case 0x26: // ROL zp
- rol_zp:
- nz = c >> 8 & 1;
- nz |= (c = READ_LOW( data ) << 1);
- goto write_nz_zp;
-
-// Increment/decrement
-
- case 0xCA: // DEX
- INC_DEC_XY( x, -1 )
-
- case 0x88: // DEY
- INC_DEC_XY( y, -1 )
-
- case 0xF6: // INC zp,x
- data = uint8_t (data + x);
- case 0xE6: // INC zp
- nz = 1;
- goto add_nz_zp;
-
- case 0xD6: // DEC zp,x
- data = uint8_t (data + x);
- case 0xC6: // DEC zp
- nz = (unsigned) -1;
- add_nz_zp:
- nz += READ_LOW( data );
- write_nz_zp:
- pc++;
- WRITE_LOW( data, nz );
- goto loop;
-
- case 0xFE: // INC abs,x
- data = x + GET_ADDR();
- goto inc_ptr;
-
- case 0xEE: // INC abs
- data = GET_ADDR();
- inc_ptr:
- nz = 1;
- goto inc_common;
-
- case 0xDE: // DEC abs,x
- data = x + GET_ADDR();
- goto dec_ptr;
-
- case 0xCE: // DEC abs
- data = GET_ADDR();
- dec_ptr:
- nz = (unsigned) -1;
- inc_common:
- FLUSH_TIME();
- nz += READ( data );
- pc += 2;
- WRITE( data, (uint8_t) nz );
- CACHE_TIME();
- goto loop;
-
-// Transfer
-
- case 0xAA: // TAX
- x = a;
- nz = a;
- goto loop;
-
- case 0x8A: // TXA
- a = x;
- nz = x;
- goto loop;
-
- case 0x9A: // TXS
- SET_SP( x ); // verified (no flag change)
- goto loop;
-
- case 0xBA: // TSX
- x = nz = GET_SP();
- goto loop;
-
-// Stack
-
- case 0x48: // PHA
- PUSH( a ); // verified
- goto loop;
-
- case 0x68: // PLA
- a = nz = READ_LOW( sp );
- sp = (sp - 0xFF) | 0x100;
- goto loop;
-
- case 0x40:{// RTI
- fuint8 temp = READ_LOW( sp );
- pc = READ_LOW( 0x100 | (sp - 0xFF) );
- pc |= READ_LOW( 0x100 | (sp - 0xFE) ) * 0x100;
- sp = (sp - 0xFD) | 0x100;
- data = status;
- SET_STATUS( temp );
- if ( !((data ^ status) & st_i) ) goto loop; // I flag didn't change
- this->r.status = status; // update externally-visible I flag
- blargg_long delta = s.base - irq_time_;
- if ( delta <= 0 ) goto loop;
- if ( status & st_i ) goto loop;
- s_time += delta;
- s.base = irq_time_;
- goto loop;
- }
-
- case 0x28:{// PLP
- fuint8 temp = READ_LOW( sp );
- sp = (sp - 0xFF) | 0x100;
- fuint8 changed = status ^ temp;
- SET_STATUS( temp );
- if ( !(changed & st_i) )
- goto loop; // I flag didn't change
- if ( status & st_i )
- goto handle_sei;
- goto handle_cli;
- }
-
- case 0x08: { // PHP
- fuint8 temp;
- CALC_STATUS( temp );
- PUSH( temp | (st_b | st_r) );
- goto loop;
- }
-
- case 0x6C:{// JMP (ind)
- data = GET_ADDR();
- check( unsigned (data - 0x2000) >= 0x4000 ); // ensure it's outside I/O space
- uint8_t const* page = s.code_map [data >> page_bits];
- pc = page [PAGE_OFFSET( data )];
- data = (data & 0xFF00) | ((data + 1) & 0xFF);
- pc |= page [PAGE_OFFSET( data )] << 8;
- goto loop;
- }
-
- case 0x00: // BRK
- goto handle_brk;
-
-// Flags
-
- case 0x38: // SEC
- c = (unsigned) ~0;
- goto loop;
-
- case 0x18: // CLC
- c = 0;
- goto loop;
-
- case 0xB8: // CLV
- status &= ~st_v;
- goto loop;
-
- case 0xD8: // CLD
- status &= ~st_d;
- goto loop;
-
- case 0xF8: // SED
- status |= st_d;
- goto loop;
-
- case 0x58: // CLI
- if ( !(status & st_i) )
- goto loop;
- status &= ~st_i;
- handle_cli: {
- //dprintf( "CLI at %d\n", TIME );
- this->r.status = status; // update externally-visible I flag
- blargg_long delta = s.base - irq_time_;
- if ( delta <= 0 )
- {
- if ( TIME < irq_time_ )
- goto loop;
- goto delayed_cli;
- }
- s.base = irq_time_;
- s_time += delta;
- if ( s_time < 0 )
- goto loop;
-
- if ( delta >= s_time + 1 )
- {
- s.base += s_time + 1;
- s_time = -1;
- goto loop;
- }
-
- // TODO: implement
- delayed_cli:
- dprintf( "Delayed CLI not emulated\n" );
- goto loop;
- }
-
- case 0x78: // SEI
- if ( status & st_i )
- goto loop;
- status |= st_i;
- handle_sei: {
- this->r.status = status; // update externally-visible I flag
- blargg_long delta = s.base - end_time_;
- s.base = end_time_;
- s_time += delta;
- if ( s_time < 0 )
- goto loop;
-
- dprintf( "Delayed SEI not emulated\n" );
- goto loop;
- }
-
-// Unofficial
-
- // SKW - Skip word
- case 0x1C: case 0x3C: case 0x5C: case 0x7C: case 0xDC: case 0xFC:
- HANDLE_PAGE_CROSSING( data + x );
- case 0x0C:
- pc++;
- // SKB - Skip byte
- case 0x74: case 0x04: case 0x14: case 0x34: case 0x44: case 0x54: case 0x64:
- case 0x80: case 0x82: case 0x89: case 0xC2: case 0xD4: case 0xE2: case 0xF4:
- pc++;
- goto loop;
-
- // NOP
- case 0xEA: case 0x1A: case 0x3A: case 0x5A: case 0x7A: case 0xDA: case 0xFA:
- goto loop;
-
- case bad_opcode: // HLT
- pc--;
- if ( pc > 0xFFFF )
- {
- // handle wrap-around (assumes caller has put page of HLT at 0x10000)
- pc &= 0xFFFF;
- goto loop;
- }
- case 0x02: case 0x12: case 0x22: case 0x32: case 0x42: case 0x52:
- case 0x62: case 0x72: case 0x92: case 0xB2: case 0xD2:
- goto stop;
-
-// Unimplemented
-
- case 0xFF: // force 256-entry jump table for optimization purposes
- c |= 1;
- default:
- check( (unsigned) opcode <= 0xFF );
- // skip over proper number of bytes
- static unsigned char const illop_lens [8] = {
- 0x40, 0x40, 0x40, 0x80, 0x40, 0x40, 0x80, 0xA0
- };
- fuint8 opcode = instr [-1];
- fint16 len = illop_lens [opcode >> 2 & 7] >> (opcode << 1 & 6) & 3;
- if ( opcode == 0x9C )
- len = 2;
- pc += len;
- error_count_++;
-
- if ( (opcode >> 4) == 0x0B )
- {
- if ( opcode == 0xB3 )
- data = READ_LOW( data );
- if ( opcode != 0xB7 )
- HANDLE_PAGE_CROSSING( data + y );
- }
- goto loop;
- }
- assert( false );
-
- int result_;
-handle_brk:
- pc++;
- result_ = 4;
-
-interrupt:
- {
- s_time += 7;
-
- WRITE_LOW( 0x100 | (sp - 1), pc >> 8 );
- WRITE_LOW( 0x100 | (sp - 2), pc );
- pc = GET_LE16( &READ_PROG( 0xFFFA ) + result_ );
-
- sp = (sp - 3) | 0x100;
- fuint8 temp;
- CALC_STATUS( temp );
- temp |= st_r;
- if ( result_ )
- temp |= st_b; // TODO: incorrectly sets B flag for IRQ
- WRITE_LOW( sp, temp );
-
- this->r.status = status |= st_i;
- blargg_long delta = s.base - end_time_;
- if ( delta >= 0 ) goto loop;
- s_time += delta;
- s.base = end_time_;
- goto loop;
- }
-
-out_of_time:
- pc--;
- FLUSH_TIME();
- CPU_DONE( this, TIME, result_ );
- CACHE_TIME();
- if ( result_ >= 0 )
- goto interrupt;
- if ( s_time < 0 )
- goto loop;
-
-stop:
-
- s.time = s_time;
-
- r.pc = pc;
- r.sp = GET_SP();
- r.a = a;
- r.x = x;
- r.y = y;
-
- {
- fuint8 temp;
- CALC_STATUS( temp );
- r.status = temp;
- }
-
- this->state_ = s;
- this->state = &this->state_;
-
- return s_time < 0;
-}
-
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Nes_Cpu.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/Nes_Cpu.h
deleted file mode 100644
index d303b57c..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Nes_Cpu.h
+++ /dev/null
@@ -1,114 +0,0 @@
-// NES 6502 CPU emulator
-
-// Game_Music_Emu 0.5.2
-#ifndef NES_CPU_H
-#define NES_CPU_H
-
-#include "blargg_common.h"
-
-typedef blargg_long nes_time_t; // clock cycle count
-typedef unsigned nes_addr_t; // 16-bit address
-enum { future_nes_time = LONG_MAX / 2 + 1 };
-
-class Nes_Cpu {
-public:
- typedef BOOST::uint8_t uint8_t;
-
- // Clear registers, map low memory and its three mirrors to address 0,
- // and mirror unmapped_page in remaining memory
- void reset( void const* unmapped_page = 0 );
-
- // Map code memory (memory accessed via the program counter). Start and size
- // must be multiple of page_size. If mirror is true, repeats code page
- // throughout address range.
- enum { page_size = 0x800 };
- void map_code( nes_addr_t start, unsigned size, void const* code, bool mirror = false );
-
- // Access emulated memory as CPU does
- uint8_t const* get_code( nes_addr_t );
-
- // 2KB of RAM at address 0
- uint8_t low_mem [0x800];
-
- // NES 6502 registers. Not kept updated during a call to run().
- struct registers_t {
- BOOST::uint16_t pc;
- BOOST::uint8_t a;
- BOOST::uint8_t x;
- BOOST::uint8_t y;
- BOOST::uint8_t status;
- BOOST::uint8_t sp;
- };
- registers_t r;
-
- // Set end_time and run CPU from current time. Returns true if execution
- // stopped due to encountering bad_opcode.
- bool run( nes_time_t end_time );
-
- // Time of beginning of next instruction to be executed
- nes_time_t time() const { return state->time + state->base; }
- void set_time( nes_time_t t ) { state->time = t - state->base; }
- void adjust_time( int delta ) { state->time += delta; }
-
- nes_time_t irq_time() const { return irq_time_; }
- void set_irq_time( nes_time_t );
-
- nes_time_t end_time() const { return end_time_; }
- void set_end_time( nes_time_t );
-
- // Number of undefined instructions encountered and skipped
- void clear_error_count() { error_count_ = 0; }
- unsigned long error_count() const { return error_count_; }
-
- // CPU invokes bad opcode handler if it encounters this
- enum { bad_opcode = 0xF2 };
-
-public:
- Nes_Cpu() { state = &state_; }
- enum { page_bits = 11 };
- enum { page_count = 0x10000 >> page_bits };
- enum { irq_inhibit = 0x04 };
-private:
- struct state_t {
- uint8_t const* code_map [page_count + 1];
- nes_time_t base;
- int time;
- };
- state_t* state; // points to state_ or a local copy within run()
- state_t state_;
- nes_time_t irq_time_;
- nes_time_t end_time_;
- unsigned long error_count_;
-
- void set_code_page( int, void const* );
- inline int update_end_time( nes_time_t end, nes_time_t irq );
-};
-
-inline BOOST::uint8_t const* Nes_Cpu::get_code( nes_addr_t addr )
-{
- return state->code_map [addr >> page_bits] + addr
- #if !BLARGG_NONPORTABLE
- % (unsigned) page_size
- #endif
- ;
-}
-
-inline int Nes_Cpu::update_end_time( nes_time_t t, nes_time_t irq )
-{
- if ( irq < t && !(r.status & irq_inhibit) ) t = irq;
- int delta = state->base - t;
- state->base = t;
- return delta;
-}
-
-inline void Nes_Cpu::set_irq_time( nes_time_t t )
-{
- state->time += update_end_time( end_time_, (irq_time_ = t) );
-}
-
-inline void Nes_Cpu::set_end_time( nes_time_t t )
-{
- state->time += update_end_time( (end_time_ = t), irq_time_ );
-}
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Nes_Fme7_Apu.cpp b/plugins/gme/Game_Music_Emu-0.5.2/gme/Nes_Fme7_Apu.cpp
deleted file mode 100644
index c058f6b1..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Nes_Fme7_Apu.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
-
-#include "Nes_Fme7_Apu.h"
-
-#include <string.h>
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-void Nes_Fme7_Apu::reset()
-{
- last_time = 0;
-
- for ( int i = 0; i < osc_count; i++ )
- oscs [i].last_amp = 0;
-
- fme7_apu_state_t* state = this;
- memset( state, 0, sizeof *state );
-}
-
-unsigned char const Nes_Fme7_Apu::amp_table [16] =
-{
- #define ENTRY( n ) (unsigned char) (n * amp_range + 0.5)
- ENTRY(0.0000), ENTRY(0.0078), ENTRY(0.0110), ENTRY(0.0156),
- ENTRY(0.0221), ENTRY(0.0312), ENTRY(0.0441), ENTRY(0.0624),
- ENTRY(0.0883), ENTRY(0.1249), ENTRY(0.1766), ENTRY(0.2498),
- ENTRY(0.3534), ENTRY(0.4998), ENTRY(0.7070), ENTRY(1.0000)
- #undef ENTRY
-};
-
-void Nes_Fme7_Apu::run_until( blip_time_t end_time )
-{
- require( end_time >= last_time );
-
- for ( int index = 0; index < osc_count; index++ )
- {
- int mode = regs [7] >> index;
- int vol_mode = regs [010 + index];
- int volume = amp_table [vol_mode & 0x0F];
-
- Blip_Buffer* const osc_output = oscs [index].output;
- if ( !osc_output )
- continue;
- osc_output->set_modified();
-
- // check for unsupported mode
- #ifndef NDEBUG
- if ( (mode & 011) <= 001 && vol_mode & 0x1F )
- dprintf( "FME7 used unimplemented sound mode: %02X, vol_mode: %02X\n",
- mode, vol_mode & 0x1F );
- #endif
-
- if ( (mode & 001) | (vol_mode & 0x10) )
- volume = 0; // noise and envelope aren't supported
-
- // period
- int const period_factor = 16;
- unsigned period = (regs [index * 2 + 1] & 0x0F) * 0x100 * period_factor +
- regs [index * 2] * period_factor;
- if ( period < 50 ) // around 22 kHz
- {
- volume = 0;
- if ( !period ) // on my AY-3-8910A, period doesn't have extra one added
- period = period_factor;
- }
-
- // current amplitude
- int amp = volume;
- if ( !phases [index] )
- amp = 0;
- {
- int delta = amp - oscs [index].last_amp;
- if ( delta )
- {
- oscs [index].last_amp = amp;
- synth.offset( last_time, delta, osc_output );
- }
- }
-
- blip_time_t time = last_time + delays [index];
- if ( time < end_time )
- {
- int delta = amp * 2 - volume;
- if ( volume )
- {
- do
- {
- delta = -delta;
- synth.offset_inline( time, delta, osc_output );
- time += period;
- }
- while ( time < end_time );
-
- oscs [index].last_amp = (delta + volume) >> 1;
- phases [index] = (delta > 0);
- }
- else
- {
- // maintain phase when silent
- int count = (end_time - time + period - 1) / period;
- phases [index] ^= count & 1;
- time += (blargg_long) count * period;
- }
- }
-
- delays [index] = time - end_time;
- }
-
- last_time = end_time;
-}
-
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Nes_Fme7_Apu.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/Nes_Fme7_Apu.h
deleted file mode 100644
index eb60af03..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Nes_Fme7_Apu.h
+++ /dev/null
@@ -1,131 +0,0 @@
-// Sunsoft FME-7 sound emulator
-
-// Game_Music_Emu 0.5.2
-#ifndef NES_FME7_APU_H
-#define NES_FME7_APU_H
-
-#include "blargg_common.h"
-#include "Blip_Buffer.h"
-
-struct fme7_apu_state_t
-{
- enum { reg_count = 14 };
- BOOST::uint8_t regs [reg_count];
- BOOST::uint8_t phases [3]; // 0 or 1
- BOOST::uint8_t latch;
- BOOST::uint16_t delays [3]; // a, b, c
-};
-
-class Nes_Fme7_Apu : private fme7_apu_state_t {
-public:
- // See Nes_Apu.h for reference
- void reset();
- void volume( double );
- void treble_eq( blip_eq_t const& );
- void output( Blip_Buffer* );
- enum { osc_count = 3 };
- void osc_output( int index, Blip_Buffer* );
- void end_frame( blip_time_t );
- void save_state( fme7_apu_state_t* ) const;
- void load_state( fme7_apu_state_t const& );
-
- // Mask and addresses of registers
- enum { addr_mask = 0xE000 };
- enum { data_addr = 0xE000 };
- enum { latch_addr = 0xC000 };
-
- // (addr & addr_mask) == latch_addr
- void write_latch( int );
-
- // (addr & addr_mask) == data_addr
- void write_data( blip_time_t, int data );
-
-public:
- Nes_Fme7_Apu();
- BLARGG_DISABLE_NOTHROW
-private:
- // noncopyable
- Nes_Fme7_Apu( const Nes_Fme7_Apu& );
- Nes_Fme7_Apu& operator = ( const Nes_Fme7_Apu& );
-
- static unsigned char const amp_table [16];
-
- struct {
- Blip_Buffer* output;
- int last_amp;
- } oscs [osc_count];
- blip_time_t last_time;
-
- enum { amp_range = 192 }; // can be any value; this gives best error/quality tradeoff
- Blip_Synth<blip_good_quality,1> synth;
-
- void run_until( blip_time_t );
-};
-
-inline void Nes_Fme7_Apu::volume( double v )
-{
- synth.volume( 0.38 / amp_range * v ); // to do: fine-tune
-}
-
-inline void Nes_Fme7_Apu::treble_eq( blip_eq_t const& eq )
-{
- synth.treble_eq( eq );
-}
-
-inline void Nes_Fme7_Apu::osc_output( int i, Blip_Buffer* buf )
-{
- assert( (unsigned) i < osc_count );
- oscs [i].output = buf;
-}
-
-inline void Nes_Fme7_Apu::output( Blip_Buffer* buf )
-{
- for ( int i = 0; i < osc_count; i++ )
- osc_output( i, buf );
-}
-
-inline Nes_Fme7_Apu::Nes_Fme7_Apu()
-{
- output( NULL );
- volume( 1.0 );
- reset();
-}
-
-inline void Nes_Fme7_Apu::write_latch( int data ) { latch = data; }
-
-inline void Nes_Fme7_Apu::write_data( blip_time_t time, int data )
-{
- if ( (unsigned) latch >= reg_count )
- {
- #ifdef dprintf
- dprintf( "FME7 write to %02X (past end of sound registers)\n", (int) latch );
- #endif
- return;
- }
-
- run_until( time );
- regs [latch] = data;
-}
-
-inline void Nes_Fme7_Apu::end_frame( blip_time_t time )
-{
- if ( time > last_time )
- run_until( time );
-
- assert( last_time >= time );
- last_time -= time;
-}
-
-inline void Nes_Fme7_Apu::save_state( fme7_apu_state_t* out ) const
-{
- *out = *this;
-}
-
-inline void Nes_Fme7_Apu::load_state( fme7_apu_state_t const& in )
-{
- reset();
- fme7_apu_state_t* state = this;
- *state = in;
-}
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Nes_Namco_Apu.cpp b/plugins/gme/Game_Music_Emu-0.5.2/gme/Nes_Namco_Apu.cpp
deleted file mode 100644
index f3235b38..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Nes_Namco_Apu.cpp
+++ /dev/null
@@ -1,145 +0,0 @@
-// Nes_Snd_Emu 0.1.8. http://www.slack.net/~ant/
-
-#include "Nes_Namco_Apu.h"
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-Nes_Namco_Apu::Nes_Namco_Apu()
-{
- output( NULL );
- volume( 1.0 );
- reset();
-}
-
-void Nes_Namco_Apu::reset()
-{
- last_time = 0;
- addr_reg = 0;
-
- int i;
- for ( i = 0; i < reg_count; i++ )
- reg [i] = 0;
-
- for ( i = 0; i < osc_count; i++ )
- {
- Namco_Osc& osc = oscs [i];
- osc.delay = 0;
- osc.last_amp = 0;
- osc.wave_pos = 0;
- }
-}
-
-void Nes_Namco_Apu::output( Blip_Buffer* buf )
-{
- for ( int i = 0; i < osc_count; i++ )
- osc_output( i, buf );
-}
-
-/*
-void Nes_Namco_Apu::reflect_state( Tagged_Data& data )
-{
- reflect_int16( data, BLARGG_4CHAR('A','D','D','R'), &addr_reg );
-
- static const char hex [17] = "0123456789ABCDEF";
- int i;
- for ( i = 0; i < reg_count; i++ )
- reflect_int16( data, 'RG\0\0' + hex [i >> 4] * 0x100 + hex [i & 15], &reg [i] );
-
- for ( i = 0; i < osc_count; i++ )
- {
- reflect_int32( data, BLARGG_4CHAR('D','L','Y','0') + i, &oscs [i].delay );
- reflect_int16( data, BLARGG_4CHAR('P','O','S','0') + i, &oscs [i].wave_pos );
- }
-}
-*/
-
-void Nes_Namco_Apu::end_frame( blip_time_t time )
-{
- if ( time > last_time )
- run_until( time );
-
- assert( last_time >= time );
- last_time -= time;
-}
-
-void Nes_Namco_Apu::run_until( blip_time_t nes_end_time )
-{
- int active_oscs = (reg [0x7F] >> 4 & 7) + 1;
- for ( int i = osc_count - active_oscs; i < osc_count; i++ )
- {
- Namco_Osc& osc = oscs [i];
- Blip_Buffer* output = osc.output;
- if ( !output )
- continue;
- output->set_modified();
-
- blip_resampled_time_t time =
- output->resampled_time( last_time ) + osc.delay;
- blip_resampled_time_t end_time = output->resampled_time( nes_end_time );
- osc.delay = 0;
- if ( time < end_time )
- {
- const BOOST::uint8_t* osc_reg = &reg [i * 8 + 0x40];
- if ( !(osc_reg [4] & 0xE0) )
- continue;
-
- int volume = osc_reg [7] & 15;
- if ( !volume )
- continue;
-
- blargg_long freq = (osc_reg [4] & 3) * 0x10000 + osc_reg [2] * 0x100L + osc_reg [0];
- if ( freq < 64 * active_oscs )
- continue; // prevent low frequencies from excessively delaying freq changes
- blip_resampled_time_t period =
- output->resampled_duration( 983040 ) / freq * active_oscs;
-
- int wave_size = 32 - (osc_reg [4] >> 2 & 7) * 4;
- if ( !wave_size )
- continue;
-
- int last_amp = osc.last_amp;
- int wave_pos = osc.wave_pos;
-
- do
- {
- // read wave sample
- int addr = wave_pos + osc_reg [6];
- int sample = reg [addr >> 1] >> (addr << 2 & 4);
- wave_pos++;
- sample = (sample & 15) * volume;
-
- // output impulse if amplitude changed
- int delta = sample - last_amp;
- if ( delta )
- {
- last_amp = sample;
- synth.offset_resampled( time, delta, output );
- }
-
- // next sample
- time += period;
- if ( wave_pos >= wave_size )
- wave_pos = 0;
- }
- while ( time < end_time );
-
- osc.wave_pos = wave_pos;
- osc.last_amp = last_amp;
- }
- osc.delay = time - end_time;
- }
-
- last_time = nes_end_time;
-}
-
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Nes_Namco_Apu.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/Nes_Namco_Apu.h
deleted file mode 100644
index db5fea4b..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Nes_Namco_Apu.h
+++ /dev/null
@@ -1,102 +0,0 @@
-// Namco 106 sound chip emulator
-
-// Nes_Snd_Emu 0.1.8
-#ifndef NES_NAMCO_APU_H
-#define NES_NAMCO_APU_H
-
-#include "blargg_common.h"
-#include "Blip_Buffer.h"
-
-struct namco_state_t;
-
-class Nes_Namco_Apu {
-public:
- // See Nes_Apu.h for reference.
- void volume( double );
- void treble_eq( const blip_eq_t& );
- void output( Blip_Buffer* );
- enum { osc_count = 8 };
- void osc_output( int index, Blip_Buffer* );
- void reset();
- void end_frame( blip_time_t );
-
- // Read/write data register is at 0x4800
- enum { data_reg_addr = 0x4800 };
- void write_data( blip_time_t, int );
- int read_data();
-
- // Write-only address register is at 0xF800
- enum { addr_reg_addr = 0xF800 };
- void write_addr( int );
-
- // to do: implement save/restore
- void save_state( namco_state_t* out ) const;
- void load_state( namco_state_t const& );
-
-public:
- Nes_Namco_Apu();
- BLARGG_DISABLE_NOTHROW
-private:
- // noncopyable
- Nes_Namco_Apu( const Nes_Namco_Apu& );
- Nes_Namco_Apu& operator = ( const Nes_Namco_Apu& );
-
- struct Namco_Osc {
- blargg_long delay;
- Blip_Buffer* output;
- short last_amp;
- short wave_pos;
- };
-
- Namco_Osc oscs [osc_count];
-
- blip_time_t last_time;
- int addr_reg;
-
- enum { reg_count = 0x80 };
- BOOST::uint8_t reg [reg_count];
- Blip_Synth<blip_good_quality,15> synth;
-
- BOOST::uint8_t& access();
- void run_until( blip_time_t );
-};
-/*
-struct namco_state_t
-{
- BOOST::uint8_t regs [0x80];
- BOOST::uint8_t addr;
- BOOST::uint8_t unused;
- BOOST::uint8_t positions [8];
- BOOST::uint32_t delays [8];
-};
-*/
-
-inline BOOST::uint8_t& Nes_Namco_Apu::access()
-{
- int addr = addr_reg & 0x7F;
- if ( addr_reg & 0x80 )
- addr_reg = (addr + 1) | 0x80;
- return reg [addr];
-}
-
-inline void Nes_Namco_Apu::volume( double v ) { synth.volume( 0.10 / osc_count * v ); }
-
-inline void Nes_Namco_Apu::treble_eq( const blip_eq_t& eq ) { synth.treble_eq( eq ); }
-
-inline void Nes_Namco_Apu::write_addr( int v ) { addr_reg = v; }
-
-inline int Nes_Namco_Apu::read_data() { return access(); }
-
-inline void Nes_Namco_Apu::osc_output( int i, Blip_Buffer* buf )
-{
- assert( (unsigned) i < osc_count );
- oscs [i].output = buf;
-}
-
-inline void Nes_Namco_Apu::write_data( blip_time_t time, int data )
-{
- run_until( time );
- access() = data;
-}
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Nes_Oscs.cpp b/plugins/gme/Game_Music_Emu-0.5.2/gme/Nes_Oscs.cpp
deleted file mode 100644
index 1ad3f59c..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Nes_Oscs.cpp
+++ /dev/null
@@ -1,551 +0,0 @@
-// Nes_Snd_Emu 0.1.8. http://www.slack.net/~ant/
-
-#include "Nes_Apu.h"
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-// Nes_Osc
-
-void Nes_Osc::clock_length( int halt_mask )
-{
- if ( length_counter && !(regs [0] & halt_mask) )
- length_counter--;
-}
-
-void Nes_Envelope::clock_envelope()
-{
- int period = regs [0] & 15;
- if ( reg_written [3] ) {
- reg_written [3] = false;
- env_delay = period;
- envelope = 15;
- }
- else if ( --env_delay < 0 ) {
- env_delay = period;
- if ( envelope | (regs [0] & 0x20) )
- envelope = (envelope - 1) & 15;
- }
-}
-
-int Nes_Envelope::volume() const
-{
- return length_counter == 0 ? 0 : (regs [0] & 0x10) ? (regs [0] & 15) : envelope;
-}
-
-// Nes_Square
-
-void Nes_Square::clock_sweep( int negative_adjust )
-{
- int sweep = regs [1];
-
- if ( --sweep_delay < 0 )
- {
- reg_written [1] = true;
-
- int period = this->period();
- int shift = sweep & shift_mask;
- if ( shift && (sweep & 0x80) && period >= 8 )
- {
- int offset = period >> shift;
-
- if ( sweep & negate_flag )
- offset = negative_adjust - offset;
-
- if ( period + offset < 0x800 )
- {
- period += offset;
- // rewrite period
- regs [2] = period & 0xFF;
- regs [3] = (regs [3] & ~7) | ((period >> 8) & 7);
- }
- }
- }
-
- if ( reg_written [1] ) {
- reg_written [1] = false;
- sweep_delay = (sweep >> 4) & 7;
- }
-}
-
-// TODO: clean up
-inline nes_time_t Nes_Square::maintain_phase( nes_time_t time, nes_time_t end_time,
- nes_time_t timer_period )
-{
- nes_time_t remain = end_time - time;
- if ( remain > 0 )
- {
- int count = (remain + timer_period - 1) / timer_period;
- phase = (phase + count) & (phase_range - 1);
- time += (blargg_long) count * timer_period;
- }
- return time;
-}
-
-void Nes_Square::run( nes_time_t time, nes_time_t end_time )
-{
- const int period = this->period();
- const int timer_period = (period + 1) * 2;
-
- if ( !output )
- {
- delay = maintain_phase( time + delay, end_time, timer_period ) - end_time;
- return;
- }
-
- output->set_modified();
-
- int offset = period >> (regs [1] & shift_mask);
- if ( regs [1] & negate_flag )
- offset = 0;
-
- const int volume = this->volume();
- if ( volume == 0 || period < 8 || (period + offset) >= 0x800 )
- {
- if ( last_amp ) {
- synth.offset( time, -last_amp, output );
- last_amp = 0;
- }
-
- time += delay;
- time = maintain_phase( time, end_time, timer_period );
- }
- else
- {
- // handle duty select
- int duty_select = (regs [0] >> 6) & 3;
- int duty = 1 << duty_select; // 1, 2, 4, 2
- int amp = 0;
- if ( duty_select == 3 ) {
- duty = 2; // negated 25%
- amp = volume;
- }
- if ( phase < duty )
- amp ^= volume;
-
- {
- int delta = update_amp( amp );
- if ( delta )
- synth.offset( time, delta, output );
- }
-
- time += delay;
- if ( time < end_time )
- {
- Blip_Buffer* const output = this->output;
- const Synth& synth = this->synth;
- int delta = amp * 2 - volume;
- int phase = this->phase;
-
- do {
- phase = (phase + 1) & (phase_range - 1);
- if ( phase == 0 || phase == duty ) {
- delta = -delta;
- synth.offset_inline( time, delta, output );
- }
- time += timer_period;
- }
- while ( time < end_time );
-
- last_amp = (delta + volume) >> 1;
- this->phase = phase;
- }
- }
-
- delay = time - end_time;
-}
-
-// Nes_Triangle
-
-void Nes_Triangle::clock_linear_counter()
-{
- if ( reg_written [3] )
- linear_counter = regs [0] & 0x7F;
- else if ( linear_counter )
- linear_counter--;
-
- if ( !(regs [0] & 0x80) )
- reg_written [3] = false;
-}
-
-inline int Nes_Triangle::calc_amp() const
-{
- int amp = phase_range - phase;
- if ( amp < 0 )
- amp = phase - (phase_range + 1);
- return amp;
-}
-
-// TODO: clean up
-inline nes_time_t Nes_Triangle::maintain_phase( nes_time_t time, nes_time_t end_time,
- nes_time_t timer_period )
-{
- nes_time_t remain = end_time - time;
- if ( remain > 0 )
- {
- int count = (remain + timer_period - 1) / timer_period;
- phase = ((unsigned) phase + 1 - count) & (phase_range * 2 - 1);
- phase++;
- time += (blargg_long) count * timer_period;
- }
- return time;
-}
-
-void Nes_Triangle::run( nes_time_t time, nes_time_t end_time )
-{
- const int timer_period = period() + 1;
- if ( !output )
- {
- time += delay;
- delay = 0;
- if ( length_counter && linear_counter && timer_period >= 3 )
- delay = maintain_phase( time, end_time, timer_period ) - end_time;
- return;
- }
-
- output->set_modified();
-
- // to do: track phase when period < 3
- // to do: Output 7.5 on dac when period < 2? More accurate, but results in more clicks.
-
- int delta = update_amp( calc_amp() );
- if ( delta )
- synth.offset( time, delta, output );
-
- time += delay;
- if ( length_counter == 0 || linear_counter == 0 || timer_period < 3 )
- {
- time = end_time;
- }
- else if ( time < end_time )
- {
- Blip_Buffer* const output = this->output;
-
- int phase = this->phase;
- int volume = 1;
- if ( phase > phase_range ) {
- phase -= phase_range;
- volume = -volume;
- }
-
- do {
- if ( --phase == 0 ) {
- phase = phase_range;
- volume = -volume;
- }
- else {
- synth.offset_inline( time, volume, output );
- }
-
- time += timer_period;
- }
- while ( time < end_time );
-
- if ( volume < 0 )
- phase += phase_range;
- this->phase = phase;
- last_amp = calc_amp();
- }
- delay = time - end_time;
-}
-
-// Nes_Dmc
-
-void Nes_Dmc::reset()
-{
- address = 0;
- dac = 0;
- buf = 0;
- bits_remain = 1;
- bits = 0;
- buf_full = false;
- silence = true;
- next_irq = Nes_Apu::no_irq;
- irq_flag = false;
- irq_enabled = false;
-
- Nes_Osc::reset();
- period = 0x1AC;
-}
-
-void Nes_Dmc::recalc_irq()
-{
- nes_time_t irq = Nes_Apu::no_irq;
- if ( irq_enabled && length_counter )
- irq = apu->last_dmc_time + delay +
- ((length_counter - 1) * 8 + bits_remain - 1) * nes_time_t (period) + 1;
- if ( irq != next_irq ) {
- next_irq = irq;
- apu->irq_changed();
- }
-}
-
-int Nes_Dmc::count_reads( nes_time_t time, nes_time_t* last_read ) const
-{
- if ( last_read )
- *last_read = time;
-
- if ( length_counter == 0 )
- return 0; // not reading
-
- nes_time_t first_read = next_read_time();
- nes_time_t avail = time - first_read;
- if ( avail <= 0 )
- return 0;
-
- int count = (avail - 1) / (period * 8) + 1;
- if ( !(regs [0] & loop_flag) && count > length_counter )
- count = length_counter;
-
- if ( last_read )
- {
- *last_read = first_read + (count - 1) * (period * 8) + 1;
- check( *last_read <= time );
- check( count == count_reads( *last_read, NULL ) );
- check( count - 1 == count_reads( *last_read - 1, NULL ) );
- }
-
- return count;
-}
-
-static short const dmc_period_table [2] [16] = {
- {428, 380, 340, 320, 286, 254, 226, 214, // NTSC
- 190, 160, 142, 128, 106, 84, 72, 54},
-
- {398, 354, 316, 298, 276, 236, 210, 198, // PAL
- 176, 148, 132, 118, 98, 78, 66, 50}
-};
-
-inline void Nes_Dmc::reload_sample()
-{
- address = 0x4000 + regs [2] * 0x40;
- length_counter = regs [3] * 0x10 + 1;
-}
-
-static byte const dac_table [128] =
-{
- 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 9,10,11,12,13,14,
- 15,15,16,17,18,19,20,20,21,22,23,24,24,25,26,27,
- 27,28,29,30,31,31,32,33,33,34,35,36,36,37,38,38,
- 39,40,41,41,42,43,43,44,45,45,46,47,47,48,48,49,
- 50,50,51,52,52,53,53,54,55,55,56,56,57,58,58,59,
- 59,60,60,61,61,62,63,63,64,64,65,65,66,66,67,67,
- 68,68,69,70,70,71,71,72,72,73,73,74,74,75,75,75,
- 76,76,77,77,78,78,79,79,80,80,81,81,82,82,82,83,
-};
-
-void Nes_Dmc::write_register( int addr, int data )
-{
- if ( addr == 0 )
- {
- period = dmc_period_table [pal_mode] [data & 15];
- irq_enabled = (data & 0xC0) == 0x80; // enabled only if loop disabled
- irq_flag &= irq_enabled;
- recalc_irq();
- }
- else if ( addr == 1 )
- {
- int old_dac = dac;
- dac = data & 0x7F;
-
- // adjust last_amp so that "pop" amplitude will be properly non-linear
- // with respect to change in dac
- int faked_nonlinear = dac - (dac_table [dac] - dac_table [old_dac]);
- if ( !nonlinear )
- last_amp = faked_nonlinear;
- }
-}
-
-void Nes_Dmc::start()
-{
- reload_sample();
- fill_buffer();
- recalc_irq();
-}
-
-void Nes_Dmc::fill_buffer()
-{
- if ( !buf_full && length_counter )
- {
- require( prg_reader ); // prg_reader must be set
- buf = prg_reader( prg_reader_data, 0x8000u + address );
- address = (address + 1) & 0x7FFF;
- buf_full = true;
- if ( --length_counter == 0 )
- {
- if ( regs [0] & loop_flag ) {
- reload_sample();
- }
- else {
- apu->osc_enables &= ~0x10;
- irq_flag = irq_enabled;
- next_irq = Nes_Apu::no_irq;
- apu->irq_changed();
- }
- }
- }
-}
-
-void Nes_Dmc::run( nes_time_t time, nes_time_t end_time )
-{
- int delta = update_amp( dac );
- if ( !output )
- {
- silence = true;
- }
- else
- {
- output->set_modified();
- if ( delta )
- synth.offset( time, delta, output );
- }
-
- time += delay;
- if ( time < end_time )
- {
- int bits_remain = this->bits_remain;
- if ( silence && !buf_full )
- {
- int count = (end_time - time + period - 1) / period;
- bits_remain = (bits_remain - 1 + 8 - (count % 8)) % 8 + 1;
- time += count * period;
- }
- else
- {
- Blip_Buffer* const output = this->output;
- const int period = this->period;
- int bits = this->bits;
- int dac = this->dac;
-
- do
- {
- if ( !silence )
- {
- int step = (bits & 1) * 4 - 2;
- bits >>= 1;
- if ( unsigned (dac + step) <= 0x7F ) {
- dac += step;
- synth.offset_inline( time, step, output );
- }
- }
-
- time += period;
-
- if ( --bits_remain == 0 )
- {
- bits_remain = 8;
- if ( !buf_full ) {
- silence = true;
- }
- else {
- silence = false;
- bits = buf;
- buf_full = false;
- if ( !output )
- silence = true;
- fill_buffer();
- }
- }
- }
- while ( time < end_time );
-
- this->dac = dac;
- this->last_amp = dac;
- this->bits = bits;
- }
- this->bits_remain = bits_remain;
- }
- delay = time - end_time;
-}
-
-// Nes_Noise
-
-static short const noise_period_table [16] = {
- 0x004, 0x008, 0x010, 0x020, 0x040, 0x060, 0x080, 0x0A0,
- 0x0CA, 0x0FE, 0x17C, 0x1FC, 0x2FA, 0x3F8, 0x7F2, 0xFE4
-};
-
-void Nes_Noise::run( nes_time_t time, nes_time_t end_time )
-{
- int period = noise_period_table [regs [2] & 15];
-
- if ( !output )
- {
- // TODO: clean up
- time += delay;
- delay = time + (end_time - time + period - 1) / period * period - end_time;
- return;
- }
-
- output->set_modified();
-
- const int volume = this->volume();
- int amp = (noise & 1) ? volume : 0;
- {
- int delta = update_amp( amp );
- if ( delta )
- synth.offset( time, delta, output );
- }
-
- time += delay;
- if ( time < end_time )
- {
- const int mode_flag = 0x80;
-
- if ( !volume )
- {
- // round to next multiple of period
- time += (end_time - time + period - 1) / period * period;
-
- // approximate noise cycling while muted, by shuffling up noise register
- // to do: precise muted noise cycling?
- if ( !(regs [2] & mode_flag) ) {
- int feedback = (noise << 13) ^ (noise << 14);
- noise = (feedback & 0x4000) | (noise >> 1);
- }
- }
- else
- {
- Blip_Buffer* const output = this->output;
-
- // using resampled time avoids conversion in synth.offset()
- blip_resampled_time_t rperiod = output->resampled_duration( period );
- blip_resampled_time_t rtime = output->resampled_time( time );
-
- int noise = this->noise;
- int delta = amp * 2 - volume;
- const int tap = (regs [2] & mode_flag ? 8 : 13);
-
- do {
- int feedback = (noise << tap) ^ (noise << 14);
- time += period;
-
- if ( (noise + 1) & 2 ) {
- // bits 0 and 1 of noise differ
- delta = -delta;
- synth.offset_resampled( rtime, delta, output );
- }
-
- rtime += rperiod;
- noise = (feedback & 0x4000) | (noise >> 1);
- }
- while ( time < end_time );
-
- last_amp = (delta + volume) >> 1;
- this->noise = noise;
- }
- }
-
- delay = time - end_time;
-}
-
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Nes_Oscs.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/Nes_Oscs.h
deleted file mode 100644
index b675bfb4..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Nes_Oscs.h
+++ /dev/null
@@ -1,147 +0,0 @@
-// Private oscillators used by Nes_Apu
-
-// Nes_Snd_Emu 0.1.8
-#ifndef NES_OSCS_H
-#define NES_OSCS_H
-
-#include "blargg_common.h"
-#include "Blip_Buffer.h"
-
-class Nes_Apu;
-
-struct Nes_Osc
-{
- unsigned char regs [4];
- bool reg_written [4];
- Blip_Buffer* output;
- int length_counter;// length counter (0 if unused by oscillator)
- int delay; // delay until next (potential) transition
- int last_amp; // last amplitude oscillator was outputting
-
- void clock_length( int halt_mask );
- int period() const {
- return (regs [3] & 7) * 0x100 + (regs [2] & 0xFF);
- }
- void reset() {
- delay = 0;
- last_amp = 0;
- }
- int update_amp( int amp ) {
- int delta = amp - last_amp;
- last_amp = amp;
- return delta;
- }
-};
-
-struct Nes_Envelope : Nes_Osc
-{
- int envelope;
- int env_delay;
-
- void clock_envelope();
- int volume() const;
- void reset() {
- envelope = 0;
- env_delay = 0;
- Nes_Osc::reset();
- }
-};
-
-// Nes_Square
-struct Nes_Square : Nes_Envelope
-{
- enum { negate_flag = 0x08 };
- enum { shift_mask = 0x07 };
- enum { phase_range = 8 };
- int phase;
- int sweep_delay;
-
- typedef Blip_Synth<blip_good_quality,1> Synth;
- Synth const& synth; // shared between squares
-
- Nes_Square( Synth const* s ) : synth( *s ) { }
-
- void clock_sweep( int adjust );
- void run( nes_time_t, nes_time_t );
- void reset() {
- sweep_delay = 0;
- Nes_Envelope::reset();
- }
- nes_time_t maintain_phase( nes_time_t time, nes_time_t end_time,
- nes_time_t timer_period );
-};
-
-// Nes_Triangle
-struct Nes_Triangle : Nes_Osc
-{
- enum { phase_range = 16 };
- int phase;
- int linear_counter;
- Blip_Synth<blip_med_quality,1> synth;
-
- int calc_amp() const;
- void run( nes_time_t, nes_time_t );
- void clock_linear_counter();
- void reset() {
- linear_counter = 0;
- phase = 1;
- Nes_Osc::reset();
- }
- nes_time_t maintain_phase( nes_time_t time, nes_time_t end_time,
- nes_time_t timer_period );
-};
-
-// Nes_Noise
-struct Nes_Noise : Nes_Envelope
-{
- int noise;
- Blip_Synth<blip_med_quality,1> synth;
-
- void run( nes_time_t, nes_time_t );
- void reset() {
- noise = 1 << 14;
- Nes_Envelope::reset();
- }
-};
-
-// Nes_Dmc
-struct Nes_Dmc : Nes_Osc
-{
- int address; // address of next byte to read
- int period;
- //int length_counter; // bytes remaining to play (already defined in Nes_Osc)
- int buf;
- int bits_remain;
- int bits;
- bool buf_full;
- bool silence;
-
- enum { loop_flag = 0x40 };
-
- int dac;
-
- nes_time_t next_irq;
- bool irq_enabled;
- bool irq_flag;
- bool pal_mode;
- bool nonlinear;
-
- int (*prg_reader)( void*, nes_addr_t ); // needs to be initialized to prg read function
- void* prg_reader_data;
-
- Nes_Apu* apu;
-
- Blip_Synth<blip_med_quality,1> synth;
-
- void start();
- void write_register( int, int );
- void run( nes_time_t, nes_time_t );
- void recalc_irq();
- void fill_buffer();
- void reload_sample();
- void reset();
- int count_reads( nes_time_t, nes_time_t* ) const;
- nes_time_t next_read_time() const;
-};
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Nes_Vrc6_Apu.cpp b/plugins/gme/Game_Music_Emu-0.5.2/gme/Nes_Vrc6_Apu.cpp
deleted file mode 100644
index d178407c..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Nes_Vrc6_Apu.cpp
+++ /dev/null
@@ -1,215 +0,0 @@
-// Nes_Snd_Emu 0.1.8. http://www.slack.net/~ant/
-
-#include "Nes_Vrc6_Apu.h"
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-Nes_Vrc6_Apu::Nes_Vrc6_Apu()
-{
- output( NULL );
- volume( 1.0 );
- reset();
-}
-
-void Nes_Vrc6_Apu::reset()
-{
- last_time = 0;
- for ( int i = 0; i < osc_count; i++ )
- {
- Vrc6_Osc& osc = oscs [i];
- for ( int j = 0; j < reg_count; j++ )
- osc.regs [j] = 0;
- osc.delay = 0;
- osc.last_amp = 0;
- osc.phase = 1;
- osc.amp = 0;
- }
-}
-
-void Nes_Vrc6_Apu::output( Blip_Buffer* buf )
-{
- for ( int i = 0; i < osc_count; i++ )
- osc_output( i, buf );
-}
-
-void Nes_Vrc6_Apu::run_until( blip_time_t time )
-{
- require( time >= last_time );
- run_square( oscs [0], time );
- run_square( oscs [1], time );
- run_saw( time );
- last_time = time;
-}
-
-void Nes_Vrc6_Apu::write_osc( blip_time_t time, int osc_index, int reg, int data )
-{
- require( (unsigned) osc_index < osc_count );
- require( (unsigned) reg < reg_count );
-
- run_until( time );
- oscs [osc_index].regs [reg] = data;
-}
-
-void Nes_Vrc6_Apu::end_frame( blip_time_t time )
-{
- if ( time > last_time )
- run_until( time );
-
- assert( last_time >= time );
- last_time -= time;
-}
-
-void Nes_Vrc6_Apu::save_state( vrc6_apu_state_t* out ) const
-{
- assert( sizeof (vrc6_apu_state_t) == 20 );
- out->saw_amp = oscs [2].amp;
- for ( int i = 0; i < osc_count; i++ )
- {
- Vrc6_Osc const& osc = oscs [i];
- for ( int r = 0; r < reg_count; r++ )
- out->regs [i] [r] = osc.regs [r];
-
- out->delays [i] = osc.delay;
- out->phases [i] = osc.phase;
- }
-}
-
-void Nes_Vrc6_Apu::load_state( vrc6_apu_state_t const& in )
-{
- reset();
- oscs [2].amp = in.saw_amp;
- for ( int i = 0; i < osc_count; i++ )
- {
- Vrc6_Osc& osc = oscs [i];
- for ( int r = 0; r < reg_count; r++ )
- osc.regs [r] = in.regs [i] [r];
-
- osc.delay = in.delays [i];
- osc.phase = in.phases [i];
- }
- if ( !oscs [2].phase )
- oscs [2].phase = 1;
-}
-
-void Nes_Vrc6_Apu::run_square( Vrc6_Osc& osc, blip_time_t end_time )
-{
- Blip_Buffer* output = osc.output;
- if ( !output )
- return;
- output->set_modified();
-
- int volume = osc.regs [0] & 15;
- if ( !(osc.regs [2] & 0x80) )
- volume = 0;
-
- int gate = osc.regs [0] & 0x80;
- int duty = ((osc.regs [0] >> 4) & 7) + 1;
- int delta = ((gate || osc.phase < duty) ? volume : 0) - osc.last_amp;
- blip_time_t time = last_time;
- if ( delta )
- {
- osc.last_amp += delta;
- square_synth.offset( time, delta, output );
- }
-
- time += osc.delay;
- osc.delay = 0;
- int period = osc.period();
- if ( volume && !gate && period > 4 )
- {
- if ( time < end_time )
- {
- int phase = osc.phase;
-
- do
- {
- phase++;
- if ( phase == 16 )
- {
- phase = 0;
- osc.last_amp = volume;
- square_synth.offset( time, volume, output );
- }
- if ( phase == duty )
- {
- osc.last_amp = 0;
- square_synth.offset( time, -volume, output );
- }
- time += period;
- }
- while ( time < end_time );
-
- osc.phase = phase;
- }
- osc.delay = time - end_time;
- }
-}
-
-void Nes_Vrc6_Apu::run_saw( blip_time_t end_time )
-{
- Vrc6_Osc& osc = oscs [2];
- Blip_Buffer* output = osc.output;
- if ( !output )
- return;
- output->set_modified();
-
- int amp = osc.amp;
- int amp_step = osc.regs [0] & 0x3F;
- blip_time_t time = last_time;
- int last_amp = osc.last_amp;
- if ( !(osc.regs [2] & 0x80) || !(amp_step | amp) )
- {
- osc.delay = 0;
- int delta = (amp >> 3) - last_amp;
- last_amp = amp >> 3;
- saw_synth.offset( time, delta, output );
- }
- else
- {
- time += osc.delay;
- if ( time < end_time )
- {
- int period = osc.period() * 2;
- int phase = osc.phase;
-
- do
- {
- if ( --phase == 0 )
- {
- phase = 7;
- amp = 0;
- }
-
- int delta = (amp >> 3) - last_amp;
- if ( delta )
- {
- last_amp = amp >> 3;
- saw_synth.offset( time, delta, output );
- }
-
- time += period;
- amp = (amp + amp_step) & 0xFF;
- }
- while ( time < end_time );
-
- osc.phase = phase;
- osc.amp = amp;
- }
-
- osc.delay = time - end_time;
- }
-
- osc.last_amp = last_amp;
-}
-
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Nes_Vrc6_Apu.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/Nes_Vrc6_Apu.h
deleted file mode 100644
index 18722233..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Nes_Vrc6_Apu.h
+++ /dev/null
@@ -1,95 +0,0 @@
-// Konami VRC6 sound chip emulator
-
-// Nes_Snd_Emu 0.1.8
-#ifndef NES_VRC6_APU_H
-#define NES_VRC6_APU_H
-
-#include "blargg_common.h"
-#include "Blip_Buffer.h"
-
-struct vrc6_apu_state_t;
-
-class Nes_Vrc6_Apu {
-public:
- // See Nes_Apu.h for reference
- void reset();
- void volume( double );
- void treble_eq( blip_eq_t const& );
- void output( Blip_Buffer* );
- enum { osc_count = 3 };
- void osc_output( int index, Blip_Buffer* );
- void end_frame( blip_time_t );
- void save_state( vrc6_apu_state_t* ) const;
- void load_state( vrc6_apu_state_t const& );
-
- // Oscillator 0 write-only registers are at $9000-$9002
- // Oscillator 1 write-only registers are at $A000-$A002
- // Oscillator 2 write-only registers are at $B000-$B002
- enum { reg_count = 3 };
- enum { base_addr = 0x9000 };
- enum { addr_step = 0x1000 };
- void write_osc( blip_time_t, int osc, int reg, int data );
-
-public:
- Nes_Vrc6_Apu();
- BLARGG_DISABLE_NOTHROW
-private:
- // noncopyable
- Nes_Vrc6_Apu( const Nes_Vrc6_Apu& );
- Nes_Vrc6_Apu& operator = ( const Nes_Vrc6_Apu& );
-
- struct Vrc6_Osc
- {
- BOOST::uint8_t regs [3];
- Blip_Buffer* output;
- int delay;
- int last_amp;
- int phase;
- int amp; // only used by saw
-
- int period() const
- {
- return (regs [2] & 0x0F) * 0x100L + regs [1] + 1;
- }
- };
-
- Vrc6_Osc oscs [osc_count];
- blip_time_t last_time;
-
- Blip_Synth<blip_med_quality,1> saw_synth;
- Blip_Synth<blip_good_quality,1> square_synth;
-
- void run_until( blip_time_t );
- void run_square( Vrc6_Osc& osc, blip_time_t );
- void run_saw( blip_time_t );
-};
-
-struct vrc6_apu_state_t
-{
- BOOST::uint8_t regs [3] [3];
- BOOST::uint8_t saw_amp;
- BOOST::uint16_t delays [3];
- BOOST::uint8_t phases [3];
- BOOST::uint8_t unused;
-};
-
-inline void Nes_Vrc6_Apu::osc_output( int i, Blip_Buffer* buf )
-{
- assert( (unsigned) i < osc_count );
- oscs [i].output = buf;
-}
-
-inline void Nes_Vrc6_Apu::volume( double v )
-{
- double const factor = 0.0967 * 2;
- saw_synth.volume( factor / 31 * v );
- square_synth.volume( factor * 0.5 / 15 * v );
-}
-
-inline void Nes_Vrc6_Apu::treble_eq( blip_eq_t const& eq )
-{
- saw_synth.treble_eq( eq );
- square_synth.treble_eq( eq );
-}
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Nsf_Emu.cpp b/plugins/gme/Game_Music_Emu-0.5.2/gme/Nsf_Emu.cpp
deleted file mode 100644
index 678bddb2..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Nsf_Emu.cpp
+++ /dev/null
@@ -1,557 +0,0 @@
-// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
-
-#include "Nsf_Emu.h"
-
-#include "blargg_endian.h"
-#include <string.h>
-#include <stdio.h>
-
-#if !NSF_EMU_APU_ONLY
- #include "Nes_Namco_Apu.h"
- #include "Nes_Vrc6_Apu.h"
- #include "Nes_Fme7_Apu.h"
-#endif
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-int const vrc6_flag = 0x01;
-int const namco_flag = 0x10;
-int const fme7_flag = 0x20;
-
-long const clock_divisor = 12;
-
-Nsf_Emu::equalizer_t const Nsf_Emu::nes_eq = { -1.0, 80 };
-Nsf_Emu::equalizer_t const Nsf_Emu::famicom_eq = { -15.0, 80 };
-
-int Nsf_Emu::pcm_read( void* emu, nes_addr_t addr )
-{
- return *((Nsf_Emu*) emu)->cpu::get_code( addr );
-}
-
-Nsf_Emu::Nsf_Emu()
-{
- vrc6 = 0;
- namco = 0;
- fme7 = 0;
-
- set_type( gme_nsf_type );
- set_silence_lookahead( 6 );
- apu.dmc_reader( pcm_read, this );
- Music_Emu::set_equalizer( nes_eq );
- set_gain( 1.4 );
- memset( unmapped_code, Nes_Cpu::bad_opcode, sizeof unmapped_code );
-}
-
-Nsf_Emu::~Nsf_Emu() { unload(); }
-
-void Nsf_Emu::unload()
-{
- #if !NSF_EMU_APU_ONLY
- {
- delete vrc6;
- vrc6 = 0;
-
- delete namco;
- namco = 0;
-
- delete fme7;
- fme7 = 0;
- }
- #endif
-
- rom.clear();
- Music_Emu::unload();
-}
-
-// Track info
-
-static void copy_nsf_fields( Nsf_Emu::header_t const& h, track_info_t* out )
-{
- GME_COPY_FIELD( h, out, game );
- GME_COPY_FIELD( h, out, author );
- GME_COPY_FIELD( h, out, copyright );
- if ( h.chip_flags )
- Gme_File::copy_field_( out->system, "Famicom" );
-}
-
-blargg_err_t Nsf_Emu::track_info_( track_info_t* out, int ) const
-{
- copy_nsf_fields( header_, out );
- return 0;
-}
-
-static blargg_err_t check_nsf_header( void const* header )
-{
- if ( memcmp( header, "NESM\x1A", 5 ) )
- return gme_wrong_file_type;
- return 0;
-}
-
-struct Nsf_File : Gme_Info_
-{
- Nsf_Emu::header_t h;
-
- Nsf_File() { set_type( gme_nsf_type ); }
-
- blargg_err_t load_( Data_Reader& in )
- {
- blargg_err_t err = in.read( &h, Nsf_Emu::header_size );
- if ( err )
- return (err == in.eof_error ? gme_wrong_file_type : err);
-
- if ( h.chip_flags & ~(namco_flag | vrc6_flag | fme7_flag) )
- set_warning( "Uses unsupported audio expansion hardware" );
-
- set_track_count( h.track_count );
- return check_nsf_header( &h );
- }
-
- blargg_err_t track_info_( track_info_t* out, int ) const
- {
- copy_nsf_fields( h, out );
- return 0;
- }
-};
-
-static Music_Emu* new_nsf_emu () { return BLARGG_NEW Nsf_Emu ; }
-static Music_Emu* new_nsf_file() { return BLARGG_NEW Nsf_File; }
-
-gme_type_t_ const gme_nsf_type [1] = { "Nintendo NES", 0, &new_nsf_emu, &new_nsf_file, "NSF", 1 };
-
-// Setup
-
-void Nsf_Emu::set_tempo_( double t )
-{
- unsigned playback_rate = get_le16( header_.ntsc_speed );
- unsigned standard_rate = 0x411A;
- clock_rate_ = 1789772.72727;
- play_period = 262 * 341L * 4 - 2; // two fewer PPU clocks every four frames
-
- if ( pal_only )
- {
- play_period = 33247 * clock_divisor;
- clock_rate_ = 1662607.125;
- standard_rate = 0x4E20;
- playback_rate = get_le16( header_.pal_speed );
- }
-
- if ( !playback_rate )
- playback_rate = standard_rate;
-
- if ( playback_rate != standard_rate || t != 1.0 )
- play_period = long (playback_rate * clock_rate_ / (1000000.0 / clock_divisor * t));
-
- apu.set_tempo( t );
-}
-
-blargg_err_t Nsf_Emu::init_sound()
-{
- if ( header_.chip_flags & ~(namco_flag | vrc6_flag | fme7_flag) )
- set_warning( "Uses unsupported audio expansion hardware" );
-
- {
- #define APU_NAMES "Square 1", "Square 2", "Triangle", "Noise", "DMC"
-
- int const count = Nes_Apu::osc_count;
- static const char* const apu_names [count] = { APU_NAMES };
- set_voice_count( count );
- set_voice_names( apu_names );
-
- }
-
- static int const types [] = {
- wave_type | 1, wave_type | 2, wave_type | 0,
- noise_type | 0, mixed_type | 1,
- wave_type | 3, wave_type | 4, wave_type | 5,
- wave_type | 6, wave_type | 7, wave_type | 8, wave_type | 9,
- wave_type |10, wave_type |11, wave_type |12, wave_type |13
- };
- set_voice_types( types ); // common to all sound chip configurations
-
- double adjusted_gain = gain();
-
- #if NSF_EMU_APU_ONLY
- {
- if ( header_.chip_flags )
- set_warning( "Uses unsupported audio expansion hardware" );
- }
- #else
- {
- if ( header_.chip_flags & (namco_flag | vrc6_flag | fme7_flag) )
- set_voice_count( Nes_Apu::osc_count + 3 );
-
- if ( header_.chip_flags & namco_flag )
- {
- namco = BLARGG_NEW Nes_Namco_Apu;
- CHECK_ALLOC( namco );
- adjusted_gain *= 0.75;
-
- int const count = Nes_Apu::osc_count + Nes_Namco_Apu::osc_count;
- static const char* const names [count] = {
- APU_NAMES,
- "Wave 1", "Wave 2", "Wave 3", "Wave 4",
- "Wave 5", "Wave 6", "Wave 7", "Wave 8"
- };
- set_voice_count( count );
- set_voice_names( names );
- }
-
- if ( header_.chip_flags & vrc6_flag )
- {
- vrc6 = BLARGG_NEW Nes_Vrc6_Apu;
- CHECK_ALLOC( vrc6 );
- adjusted_gain *= 0.75;
-
- {
- int const count = Nes_Apu::osc_count + Nes_Vrc6_Apu::osc_count;
- static const char* const names [count] = {
- APU_NAMES,
- "Saw Wave", "Square 3", "Square 4"
- };
- set_voice_count( count );
- set_voice_names( names );
- }
-
- if ( header_.chip_flags & namco_flag )
- {
- int const count = Nes_Apu::osc_count + Nes_Vrc6_Apu::osc_count +
- Nes_Namco_Apu::osc_count;
- static const char* const names [count] = {
- APU_NAMES,
- "Saw Wave", "Square 3", "Square 4",
- "Wave 1", "Wave 2", "Wave 3", "Wave 4",
- "Wave 5", "Wave 6", "Wave 7", "Wave 8"
- };
- set_voice_count( count );
- set_voice_names( names );
- }
- }
-
- if ( header_.chip_flags & fme7_flag )
- {
- fme7 = BLARGG_NEW Nes_Fme7_Apu;
- CHECK_ALLOC( fme7 );
- adjusted_gain *= 0.75;
-
- int const count = Nes_Apu::osc_count + Nes_Fme7_Apu::osc_count;
- static const char* const names [count] = {
- APU_NAMES,
- "Square 3", "Square 4", "Square 5"
- };
- set_voice_count( count );
- set_voice_names( names );
- }
-
- if ( namco ) namco->volume( adjusted_gain );
- if ( vrc6 ) vrc6 ->volume( adjusted_gain );
- if ( fme7 ) fme7 ->volume( adjusted_gain );
- }
- #endif
-
- apu.volume( adjusted_gain );
-
- return 0;
-}
-
-blargg_err_t Nsf_Emu::load_( Data_Reader& in )
-{
- assert( offsetof (header_t,unused [4]) == header_size );
- RETURN_ERR( rom.load( in, header_size, &header_, 0 ) );
-
- set_track_count( header_.track_count );
- RETURN_ERR( check_nsf_header( &header_ ) );
-
- if ( header_.vers != 1 )
- set_warning( "Unknown file version" );
-
- // sound and memory
- blargg_err_t err = init_sound();
- if ( err )
- return err;
-
- // set up data
- nes_addr_t load_addr = get_le16( header_.load_addr );
- init_addr = get_le16( header_.init_addr );
- play_addr = get_le16( header_.play_addr );
- if ( !load_addr ) load_addr = rom_begin;
- if ( !init_addr ) init_addr = rom_begin;
- if ( !play_addr ) play_addr = rom_begin;
- if ( load_addr < rom_begin || init_addr < rom_begin )
- {
- const char* w = warning();
- if ( !w )
- w = "Corrupt file (invalid load/init/play address)";
- return w;
- }
-
- rom.set_addr( load_addr % bank_size );
- int total_banks = rom.size() / bank_size;
-
- // bank switching
- int first_bank = (load_addr - rom_begin) / bank_size;
- for ( int i = 0; i < bank_count; i++ )
- {
- unsigned bank = i - first_bank;
- if ( bank >= (unsigned) total_banks )
- bank = 0;
- initial_banks [i] = bank;
-
- if ( header_.banks [i] )
- {
- // bank-switched
- memcpy( initial_banks, header_.banks, sizeof initial_banks );
- break;
- }
- }
-
- pal_only = (header_.speed_flags & 3) == 1;
-
- #if !NSF_EMU_EXTRA_FLAGS
- header_.speed_flags = 0;
- #endif
-
- set_tempo( tempo() );
-
- return setup_buffer( (long) (clock_rate_ + 0.5) );
-}
-
-void Nsf_Emu::update_eq( blip_eq_t const& eq )
-{
- apu.treble_eq( eq );
-
- #if !NSF_EMU_APU_ONLY
- {
- if ( namco ) namco->treble_eq( eq );
- if ( vrc6 ) vrc6 ->treble_eq( eq );
- if ( fme7 ) fme7 ->treble_eq( eq );
- }
- #endif
-}
-
-void Nsf_Emu::set_voice( int i, Blip_Buffer* buf, Blip_Buffer*, Blip_Buffer* )
-{
- if ( i < Nes_Apu::osc_count )
- {
- apu.osc_output( i, buf );
- return;
- }
- i -= Nes_Apu::osc_count;
-
- #if !NSF_EMU_APU_ONLY
- {
- if ( fme7 && i < Nes_Fme7_Apu::osc_count )
- {
- fme7->osc_output( i, buf );
- return;
- }
-
- if ( vrc6 )
- {
- if ( i < Nes_Vrc6_Apu::osc_count )
- {
- // put saw first
- if ( --i < 0 )
- i = 2;
- vrc6->osc_output( i, buf );
- return;
- }
- i -= Nes_Vrc6_Apu::osc_count;
- }
-
- if ( namco && i < Nes_Namco_Apu::osc_count )
- {
- namco->osc_output( i, buf );
- return;
- }
- }
- #endif
-}
-
-// Emulation
-
-// see nes_cpu_io.h for read/write functions
-
-void Nsf_Emu::cpu_write_misc( nes_addr_t addr, int data )
-{
- #if !NSF_EMU_APU_ONLY
- {
- if ( namco )
- {
- switch ( addr )
- {
- case Nes_Namco_Apu::data_reg_addr:
- namco->write_data( time(), data );
- return;
-
- case Nes_Namco_Apu::addr_reg_addr:
- namco->write_addr( data );
- return;
- }
- }
-
- if ( addr >= Nes_Fme7_Apu::latch_addr && fme7 )
- {
- switch ( addr & Nes_Fme7_Apu::addr_mask )
- {
- case Nes_Fme7_Apu::latch_addr:
- fme7->write_latch( data );
- return;
-
- case Nes_Fme7_Apu::data_addr:
- fme7->write_data( time(), data );
- return;
- }
- }
-
- if ( vrc6 )
- {
- unsigned reg = addr & (Nes_Vrc6_Apu::addr_step - 1);
- unsigned osc = unsigned (addr - Nes_Vrc6_Apu::base_addr) / Nes_Vrc6_Apu::addr_step;
- if ( osc < Nes_Vrc6_Apu::osc_count && reg < Nes_Vrc6_Apu::reg_count )
- {
- vrc6->write_osc( time(), osc, reg, data );
- return;
- }
- }
- }
- #endif
-
- // unmapped write
-
- #ifndef NDEBUG
- {
- // some games write to $8000 and $8001 repeatedly
- if ( addr == 0x8000 || addr == 0x8001 ) return;
-
- // probably namco sound mistakenly turned on in mck
- if ( addr == 0x4800 || addr == 0xF800 ) return;
-
- // memory mapper?
- if ( addr == 0xFFF8 ) return;
-
- dprintf( "write_unmapped( 0x%04X, 0x%02X )\n", (unsigned) addr, (unsigned) data );
- }
- #endif
-}
-
-blargg_err_t Nsf_Emu::start_track_( int track )
-{
- RETURN_ERR( Classic_Emu::start_track_( track ) );
-
- memset( low_mem, 0, sizeof low_mem );
- memset( sram, 0, sizeof sram );
-
- cpu::reset( unmapped_code ); // also maps low_mem
- cpu::map_code( sram_addr, sizeof sram, sram );
- for ( int i = 0; i < bank_count; ++i )
- cpu_write( bank_select_addr + i, initial_banks [i] );
-
- apu.reset( pal_only, (header_.speed_flags & 0x20) ? 0x3F : 0 );
- apu.write_register( 0, 0x4015, 0x0F );
- apu.write_register( 0, 0x4017, (header_.speed_flags & 0x10) ? 0x80 : 0 );
- #if !NSF_EMU_APU_ONLY
- {
- if ( namco ) namco->reset();
- if ( vrc6 ) vrc6 ->reset();
- if ( fme7 ) fme7 ->reset();
- }
- #endif
-
- play_ready = 4;
- play_extra = 0;
- next_play = play_period / clock_divisor;
-
- saved_state.pc = badop_addr;
- low_mem [0x1FF] = (badop_addr - 1) >> 8;
- low_mem [0x1FE] = (badop_addr - 1) & 0xFF;
- r.sp = 0xFD;
- r.pc = init_addr;
- r.a = track;
- r.x = pal_only;
-
- return 0;
-}
-
-blargg_err_t Nsf_Emu::run_clocks( blip_time_t& duration, int )
-{
- set_time( 0 );
- while ( time() < duration )
- {
- nes_time_t end = min( (blip_time_t) next_play, duration );
- end = min( end, time() + 32767 ); // allows CPU to use 16-bit time delta
- if ( cpu::run( end ) )
- {
- if ( r.pc != badop_addr )
- {
- set_warning( "Emulation error (illegal instruction)" );
- r.pc++;
- }
- else
- {
- play_ready = 1;
- if ( saved_state.pc != badop_addr )
- {
- cpu::r = saved_state;
- saved_state.pc = badop_addr;
- }
- else
- {
- set_time( end );
- }
- }
- }
-
- if ( time() >= next_play )
- {
- nes_time_t period = (play_period + play_extra) / clock_divisor;
- play_extra = play_period - period * clock_divisor;
- next_play += period;
- if ( play_ready && !--play_ready )
- {
- check( saved_state.pc == badop_addr );
- if ( r.pc != badop_addr )
- saved_state = cpu::r;
-
- r.pc = play_addr;
- low_mem [0x100 + r.sp--] = (badop_addr - 1) >> 8;
- low_mem [0x100 + r.sp--] = (badop_addr - 1) & 0xFF;
- GME_FRAME_HOOK( this );
- }
- }
- }
-
- if ( cpu::error_count() )
- {
- cpu::clear_error_count();
- set_warning( "Emulation error (illegal instruction)" );
- }
-
- duration = time();
- next_play -= duration;
- check( next_play >= 0 );
- if ( next_play < 0 )
- next_play = 0;
-
- apu.end_frame( duration );
-
- #if !NSF_EMU_APU_ONLY
- {
- if ( namco ) namco->end_frame( duration );
- if ( vrc6 ) vrc6 ->end_frame( duration );
- if ( fme7 ) fme7 ->end_frame( duration );
- }
- #endif
-
- return 0;
-}
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Nsf_Emu.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/Nsf_Emu.h
deleted file mode 100644
index e06b9172..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Nsf_Emu.h
+++ /dev/null
@@ -1,106 +0,0 @@
-// Nintendo NES/Famicom NSF music file emulator
-
-// Game_Music_Emu 0.5.2
-#ifndef NSF_EMU_H
-#define NSF_EMU_H
-
-#include "Classic_Emu.h"
-#include "Nes_Apu.h"
-#include "Nes_Cpu.h"
-
-class Nsf_Emu : private Nes_Cpu, public Classic_Emu {
- typedef Nes_Cpu cpu;
-public:
- // Equalizer profiles for US NES and Japanese Famicom
- static equalizer_t const nes_eq;
- static equalizer_t const famicom_eq;
-
- // NSF file header
- enum { header_size = 0x80 };
- struct header_t
- {
- char tag [5];
- byte vers;
- byte track_count;
- byte first_track;
- byte load_addr [2];
- byte init_addr [2];
- byte play_addr [2];
- char game [32];
- char author [32];
- char copyright [32];
- byte ntsc_speed [2];
- byte banks [8];
- byte pal_speed [2];
- byte speed_flags;
- byte chip_flags;
- byte unused [4];
- };
-
- // Header for currently loaded file
- header_t const& header() const { return header_; }
-
- static gme_type_t static_type() { return gme_nsf_type; }
-
-public:
- // deprecated
- Music_Emu::load;
- blargg_err_t load( header_t const& h, Data_Reader& in ) // use Remaining_Reader
- { return load_remaining_( &h, sizeof h, in ); }
-
-public:
- Nsf_Emu();
- ~Nsf_Emu();
- Nes_Apu* apu_() { return &apu; }
-protected:
- blargg_err_t track_info_( track_info_t*, int track ) const;
- blargg_err_t load_( Data_Reader& );
- blargg_err_t start_track_( int );
- blargg_err_t run_clocks( blip_time_t&, int );
- void set_tempo_( double );
- void set_voice( int, Blip_Buffer*, Blip_Buffer*, Blip_Buffer* );
- void update_eq( blip_eq_t const& );
- void unload();
-protected:
- enum { bank_count = 8 };
- byte initial_banks [bank_count];
- nes_addr_t init_addr;
- nes_addr_t play_addr;
- double clock_rate_;
- bool pal_only;
-
- // timing
- Nes_Cpu::registers_t saved_state;
- nes_time_t next_play;
- nes_time_t play_period;
- int play_extra;
- int play_ready;
-
- enum { rom_begin = 0x8000 };
- enum { bank_select_addr = 0x5FF8 };
- enum { bank_size = 0x1000 };
- Rom_Data<bank_size> rom;
-
-public: private: friend class Nes_Cpu;
- void cpu_jsr( nes_addr_t );
- int cpu_read( nes_addr_t );
- void cpu_write( nes_addr_t, int );
- void cpu_write_misc( nes_addr_t, int );
- enum { badop_addr = bank_select_addr };
-
-private:
- class Nes_Namco_Apu* namco;
- class Nes_Vrc6_Apu* vrc6;
- class Nes_Fme7_Apu* fme7;
- Nes_Apu apu;
- static int pcm_read( void*, nes_addr_t );
- blargg_err_t init_sound();
-
- header_t header_;
-
- enum { sram_addr = 0x6000 };
- byte sram [0x2000];
- byte unmapped_code [Nes_Cpu::page_size + 8];
-};
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Nsfe_Emu.cpp b/plugins/gme/Game_Music_Emu-0.5.2/gme/Nsfe_Emu.cpp
deleted file mode 100644
index 0a785e60..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Nsfe_Emu.cpp
+++ /dev/null
@@ -1,330 +0,0 @@
-// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
-
-#include "Nsfe_Emu.h"
-
-#include "blargg_endian.h"
-#include <string.h>
-#include <ctype.h>
-
-/* Copyright (C) 2005-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-Nsfe_Info::Nsfe_Info() { playlist_disabled = false; }
-
-Nsfe_Info::~Nsfe_Info() { }
-
-inline void Nsfe_Info::unload()
-{
- track_name_data.clear();
- track_names.clear();
- playlist.clear();
- track_times.clear();
-}
-
-// TODO: if no playlist, treat as if there is a playlist that is just 1,2,3,4,5... ?
-void Nsfe_Info::disable_playlist( bool b )
-{
- playlist_disabled = b;
- info.track_count = playlist.size();
- if ( !info.track_count || playlist_disabled )
- info.track_count = actual_track_count_;
-}
-
-int Nsfe_Info::remap_track( int track ) const
-{
- if ( !playlist_disabled && (unsigned) track < playlist.size() )
- track = playlist [track];
- return track;
-}
-
-// Read multiple strings and separate into individual strings
-static blargg_err_t read_strs( Data_Reader& in, long size, blargg_vector<char>& chars,
- blargg_vector<const char*>& strs )
-{
- RETURN_ERR( chars.resize( size + 1 ) );
- chars [size] = 0; // in case last string doesn't have terminator
- RETURN_ERR( in.read( &chars [0], size ) );
-
- RETURN_ERR( strs.resize( 128 ) );
- int count = 0;
- for ( int i = 0; i < size; i++ )
- {
- if ( (int) strs.size() <= count )
- RETURN_ERR( strs.resize( count * 2 ) );
- strs [count++] = &chars [i];
- while ( i < size && chars [i] )
- i++;
- }
-
- return strs.resize( count );
-}
-
-// Copy in to out, where out has out_max characters allocated. Truncate to
-// out_max - 1 characters.
-static void copy_str( const char* in, char* out, int out_max )
-{
- out [out_max - 1] = 0;
- strncpy( out, in, out_max - 1 );
-}
-
-struct nsfe_info_t
-{
- byte load_addr [2];
- byte init_addr [2];
- byte play_addr [2];
- byte speed_flags;
- byte chip_flags;
- byte track_count;
- byte first_track;
- byte unused [6];
-};
-
-blargg_err_t Nsfe_Info::load( Data_Reader& in, Nsf_Emu* nsf_emu )
-{
- int const nsfe_info_size = 16;
- assert( offsetof (nsfe_info_t,unused [6]) == nsfe_info_size );
-
- // check header
- byte signature [4];
- blargg_err_t err = in.read( signature, sizeof signature );
- if ( err )
- return (err == in.eof_error ? gme_wrong_file_type : err);
- if ( memcmp( signature, "NSFE", 4 ) )
- return gme_wrong_file_type;
-
- // free previous info
- track_name_data.clear();
- track_names.clear();
- playlist.clear();
- track_times.clear();
-
- // default nsf header
- static const Nsf_Emu::header_t base_header =
- {
- {'N','E','S','M','\x1A'},// tag
- 1, // version
- 1, 1, // track count, first track
- {0,0},{0,0},{0,0}, // addresses
- "","","", // strings
- {0x1A, 0x41}, // NTSC rate
- {0,0,0,0,0,0,0,0}, // banks
- {0x20, 0x4E}, // PAL rate
- 0, 0, // flags
- {0,0,0,0} // unused
- };
- Nsf_Emu::header_t& header = info;
- header = base_header;
-
- // parse tags
- int phase = 0;
- while ( phase != 3 )
- {
- // read size and tag
- byte block_header [2] [4];
- RETURN_ERR( in.read( block_header, sizeof block_header ) );
- blargg_long size = get_le32( block_header [0] );
- blargg_long tag = get_le32( block_header [1] );
-
- //dprintf( "tag: %c%c%c%c\n", char(tag), char(tag>>8), char(tag>>16), char(tag>>24) );
-
- switch ( tag )
- {
- case BLARGG_4CHAR('O','F','N','I'): {
- check( phase == 0 );
- if ( size < 8 )
- return "Corrupt file";
-
- nsfe_info_t finfo;
- finfo.track_count = 1;
- finfo.first_track = 0;
-
- RETURN_ERR( in.read( &finfo, min( size, (blargg_long) nsfe_info_size ) ) );
- if ( size > nsfe_info_size )
- RETURN_ERR( in.skip( size - nsfe_info_size ) );
- phase = 1;
- info.speed_flags = finfo.speed_flags;
- info.chip_flags = finfo.chip_flags;
- info.track_count = finfo.track_count;
- this->actual_track_count_ = finfo.track_count;
- info.first_track = finfo.first_track;
- memcpy( info.load_addr, finfo.load_addr, 2 * 3 );
- break;
- }
-
- case BLARGG_4CHAR('K','N','A','B'):
- if ( size > (int) sizeof info.banks )
- return "Corrupt file";
- RETURN_ERR( in.read( info.banks, size ) );
- break;
-
- case BLARGG_4CHAR('h','t','u','a'): {
- blargg_vector<char> chars;
- blargg_vector<const char*> strs;
- RETURN_ERR( read_strs( in, size, chars, strs ) );
- int n = strs.size();
-
- if ( n > 3 )
- copy_str( strs [3], info.dumper, sizeof info.dumper );
-
- if ( n > 2 )
- copy_str( strs [2], info.copyright, sizeof info.copyright );
-
- if ( n > 1 )
- copy_str( strs [1], info.author, sizeof info.author );
-
- if ( n > 0 )
- copy_str( strs [0], info.game, sizeof info.game );
-
- break;
- }
-
- case BLARGG_4CHAR('e','m','i','t'):
- RETURN_ERR( track_times.resize( size / 4 ) );
- RETURN_ERR( in.read( track_times.begin(), track_times.size() * 4 ) );
- break;
-
- case BLARGG_4CHAR('l','b','l','t'):
- RETURN_ERR( read_strs( in, size, track_name_data, track_names ) );
- break;
-
- case BLARGG_4CHAR('t','s','l','p'):
- RETURN_ERR( playlist.resize( size ) );
- RETURN_ERR( in.read( &playlist [0], size ) );
- break;
-
- case BLARGG_4CHAR('A','T','A','D'): {
- check( phase == 1 );
- phase = 2;
- if ( !nsf_emu )
- {
- RETURN_ERR( in.skip( size ) );
- }
- else
- {
- Subset_Reader sub( &in, size ); // limit emu to nsf data
- Remaining_Reader rem( &header, Nsf_Emu::header_size, &sub );
- RETURN_ERR( nsf_emu->load( rem ) );
- check( rem.remain() == 0 );
- }
- break;
- }
-
- case BLARGG_4CHAR('D','N','E','N'):
- check( phase == 2 );
- phase = 3;
- break;
-
- default:
- // tags that can be skipped start with a lowercase character
- check( islower( (tag >> 24) & 0xFF ) );
- RETURN_ERR( in.skip( size ) );
- break;
- }
- }
-
- return 0;
-}
-
-blargg_err_t Nsfe_Info::track_info_( track_info_t* out, int track ) const
-{
- int remapped = remap_track( track );
- if ( (unsigned) remapped < track_times.size() )
- {
- long length = (BOOST::int32_t) get_le32( track_times [remapped] );
- if ( length > 0 )
- out->length = length;
- }
- if ( (unsigned) remapped < track_names.size() )
- Gme_File::copy_field_( out->song, track_names [remapped] );
-
- GME_COPY_FIELD( info, out, game );
- GME_COPY_FIELD( info, out, author );
- GME_COPY_FIELD( info, out, copyright );
- GME_COPY_FIELD( info, out, dumper );
- return 0;
-}
-
-Nsfe_Emu::Nsfe_Emu()
-{
- loading = false;
- set_type( gme_nsfe_type );
-}
-
-Nsfe_Emu::~Nsfe_Emu() { }
-
-void Nsfe_Emu::unload()
-{
- if ( !loading )
- info.unload(); // TODO: extremely hacky!
- Nsf_Emu::unload();
-}
-
-blargg_err_t Nsfe_Emu::track_info_( track_info_t* out, int track ) const
-{
- return info.track_info_( out, track );
-}
-
-struct Nsfe_File : Gme_Info_
-{
- Nsfe_Info info;
-
- Nsfe_File() { set_type( gme_nsfe_type ); }
-
- blargg_err_t load_( Data_Reader& in )
- {
- RETURN_ERR( info.load( in, 0 ) );
- info.disable_playlist( false );
- set_track_count( info.info.track_count );
- return 0;
- }
-
- blargg_err_t track_info_( track_info_t* out, int track ) const
- {
- return info.track_info_( out, track );
- }
-};
-
-static Music_Emu* new_nsfe_emu () { return BLARGG_NEW Nsfe_Emu ; }
-static Music_Emu* new_nsfe_file() { return BLARGG_NEW Nsfe_File; }
-
-gme_type_t_ const gme_nsfe_type [1] = { "Nintendo NES", 0, &new_nsfe_emu, &new_nsfe_file, "NSFE", 1 };
-
-blargg_err_t Nsfe_Emu::load_( Data_Reader& in )
-{
- if ( loading )
- return Nsf_Emu::load_( in );
-
- // TODO: this hacky recursion-avoidance could have subtle problems
- loading = true;
- blargg_err_t err = info.load( in, this );
- loading = false;
- disable_playlist( false );
- return err;
-}
-
-void Nsfe_Emu::disable_playlist( bool b )
-{
- info.disable_playlist( b );
- set_track_count( info.info.track_count );
-}
-
-void Nsfe_Emu::clear_playlist_()
-{
- disable_playlist();
- Nsf_Emu::clear_playlist_();
-}
-
-blargg_err_t Nsfe_Emu::start_track_( int track )
-{
- return Nsf_Emu::start_track_( info.remap_track( track ) );
-}
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Nsfe_Emu.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/Nsfe_Emu.h
deleted file mode 100644
index 561c3be0..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Nsfe_Emu.h
+++ /dev/null
@@ -1,68 +0,0 @@
-// Nintendo NES/Famicom NSFE music file emulator
-
-// Game_Music_Emu 0.5.2
-#ifndef NSFE_EMU_H
-#define NSFE_EMU_H
-
-#include "blargg_common.h"
-#include "Nsf_Emu.h"
-
-// Allows reading info from NSFE file without creating emulator
-class Nsfe_Info {
-public:
- blargg_err_t load( Data_Reader&, Nsf_Emu* );
-
- struct info_t : Nsf_Emu::header_t
- {
- char game [256];
- char author [256];
- char copyright [256];
- char dumper [256];
- } info;
-
- void disable_playlist( bool = true );
-
- blargg_err_t track_info_( track_info_t* out, int track ) const;
-
- int remap_track( int i ) const;
-
- void unload();
-
- Nsfe_Info();
- ~Nsfe_Info();
-private:
- blargg_vector<char> track_name_data;
- blargg_vector<const char*> track_names;
- blargg_vector<unsigned char> playlist;
- blargg_vector<char [4]> track_times;
- int actual_track_count_;
- bool playlist_disabled;
-};
-
-class Nsfe_Emu : public Nsf_Emu {
-public:
- static gme_type_t static_type() { return gme_nsfe_type; }
-
-public:
- // deprecated
- struct header_t { char tag [4]; };
- Music_Emu::load;
- blargg_err_t load( header_t const& h, Data_Reader& in ) // use Remaining_Reader
- { return load_remaining_( &h, sizeof h, in ); }
- void disable_playlist( bool = true ); // use clear_playlist()
-
-public:
- Nsfe_Emu();
- ~Nsfe_Emu();
-protected:
- blargg_err_t load_( Data_Reader& );
- blargg_err_t track_info_( track_info_t*, int track ) const;
- blargg_err_t start_track_( int );
- void unload();
- void clear_playlist_();
-private:
- Nsfe_Info info;
- bool loading;
-};
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Sap_Apu.cpp b/plugins/gme/Game_Music_Emu-0.5.2/gme/Sap_Apu.cpp
deleted file mode 100644
index 23fa9072..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Sap_Apu.cpp
+++ /dev/null
@@ -1,334 +0,0 @@
-// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
-
-#include "Sap_Apu.h"
-
-#include <string.h>
-
-/* Copyright (C) 2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-int const max_frequency = 12000; // pure waves above this frequency are silenced
-
-static void gen_poly( blargg_ulong mask, int count, byte* out )
-{
- blargg_ulong n = 1;
- do
- {
- int bits = 0;
- int b = 0;
- do
- {
- // implemented using "Galios configuration"
- bits |= (n & 1) << b;
- n = (n >> 1) ^ (mask & -(n & 1));
- }
- while ( b++ < 7 );
- *out++ = bits;
- }
- while ( --count );
-}
-
-// poly5
-int const poly5_len = (1 << 5) - 1;
-blargg_ulong const poly5_mask = (1UL << poly5_len) - 1;
-blargg_ulong const poly5 = 0x167C6EA1;
-
-inline blargg_ulong run_poly5( blargg_ulong in, int shift )
-{
- return (in << shift & poly5_mask) | (in >> (poly5_len - shift));
-}
-
-#define POLY_MASK( width, tap1, tap2 ) \
- ((1UL << (width - 1 - tap1)) | (1UL << (width - 1 - tap2)))
-
-Sap_Apu_Impl::Sap_Apu_Impl()
-{
- gen_poly( POLY_MASK( 4, 1, 0 ), sizeof poly4, poly4 );
- gen_poly( POLY_MASK( 9, 5, 0 ), sizeof poly9, poly9 );
- gen_poly( POLY_MASK( 17, 5, 0 ), sizeof poly17, poly17 );
-
- if ( 0 ) // comment out to recauculate poly5 constant
- {
- byte poly5 [4];
- gen_poly( POLY_MASK( 5, 2, 0 ), sizeof poly5, poly5 );
- blargg_ulong n = poly5 [3] * 0x1000000L + poly5 [2] * 0x10000L +
- poly5 [1] * 0x100L + poly5 [0];
- blargg_ulong rev = n & 1;
- for ( int i = 1; i < poly5_len; i++ )
- rev |= (n >> i & 1) << (poly5_len - i);
- dprintf( "poly5: 0x%08lX\n", rev );
- }
-}
-
-Sap_Apu::Sap_Apu()
-{
- impl = 0;
- for ( int i = 0; i < osc_count; i++ )
- osc_output( i, 0 );
-}
-
-void Sap_Apu::reset( Sap_Apu_Impl* new_impl )
-{
- impl = new_impl;
- last_time = 0;
- poly5_pos = 0;
- poly4_pos = 0;
- polym_pos = 0;
- control = 0;
-
- for ( int i = 0; i < osc_count; i++ )
- memset( &oscs [i], 0, offsetof (osc_t,output) );
-}
-
-inline void Sap_Apu::calc_periods()
-{
- // 15/64 kHz clock
- int divider = 28;
- if ( this->control & 1 )
- divider = 114;
-
- for ( int i = 0; i < osc_count; i++ )
- {
- osc_t* const osc = &oscs [i];
-
- int const osc_reload = osc->regs [0]; // cache
- blargg_long period = (osc_reload + 1) * divider;
- static byte const fast_bits [osc_count] = { 1 << 6, 1 << 4, 1 << 5, 1 << 3 };
- if ( this->control & fast_bits [i] )
- {
- period = osc_reload + 4;
- if ( i & 1 )
- {
- period = osc_reload * 0x100L + osc [-1].regs [0] + 7;
- if ( !(this->control & fast_bits [i - 1]) )
- period = (period - 6) * divider;
-
- if ( (osc [-1].regs [1] & 0x1F) > 0x10 )
- dprintf( "Use of slave channel in 16-bit mode not supported\n" );
- }
- }
- osc->period = period;
- }
-}
-
-void Sap_Apu::run_until( blip_time_t end_time )
-{
- calc_periods();
- Sap_Apu_Impl* const impl = this->impl; // cache
-
- // 17/9-bit poly selection
- byte const* polym = impl->poly17;
- int polym_len = poly17_len;
- if ( this->control & 0x80 )
- {
- polym_len = poly9_len;
- polym = impl->poly9;
- }
- polym_pos %= polym_len;
-
- for ( int i = 0; i < osc_count; i++ )
- {
- osc_t* const osc = &oscs [i];
- blip_time_t time = last_time + osc->delay;
- blip_time_t const period = osc->period;
-
- // output
- Blip_Buffer* output = osc->output;
- if ( output )
- {
- output->set_modified();
-
- int const osc_control = osc->regs [1]; // cache
- int volume = (osc_control & 0x0F) * 2;
- if ( !volume || osc_control & 0x10 || // silent, DAC mode, or inaudible frequency
- ((osc_control & 0xA0) == 0xA0 && period < 1789773 / 2 / max_frequency) )
- {
- if ( !(osc_control & 0x10) )
- volume >>= 1; // inaudible frequency = half volume
-
- int delta = volume - osc->last_amp;
- if ( delta )
- {
- osc->last_amp = volume;
- impl->synth.offset( last_time, delta, output );
- }
-
- // TODO: doesn't maintain high pass flip-flop (very minor issue)
- }
- else
- {
- // high pass
- static byte const hipass_bits [osc_count] = { 1 << 2, 1 << 1, 0, 0 };
- blip_time_t period2 = 0; // unused if no high pass
- blip_time_t time2 = end_time;
- if ( this->control & hipass_bits [i] )
- {
- period2 = osc [2].period;
- time2 = last_time + osc [2].delay;
- if ( osc->invert )
- {
- // trick inner wave loop into inverting output
- osc->last_amp -= volume;
- volume = -volume;
- }
- }
-
- if ( time < end_time || time2 < end_time )
- {
- // poly source
- static byte const poly1 [] = { 0x55, 0x55 }; // square wave
- byte const* poly = poly1;
- int poly_len = 8 * sizeof poly1; // can be just 2 bits, but this is faster
- int poly_pos = osc->phase & 1;
- int poly_inc = 1;
- if ( !(osc_control & 0x20) )
- {
- poly = polym;
- poly_len = polym_len;
- poly_pos = polym_pos;
- if ( osc_control & 0x40 )
- {
- poly = impl->poly4;
- poly_len = poly4_len;
- poly_pos = poly4_pos;
- }
- poly_inc = period % poly_len;
- poly_pos = (poly_pos + osc->delay) % poly_len;
- }
- poly_inc -= poly_len; // allows more optimized inner loop below
-
- // square/poly5 wave
- blargg_ulong wave = poly5;
- check( poly5 & 1 ); // low bit is set for pure wave
- int poly5_inc = 0;
- if ( !(osc_control & 0x80) )
- {
- wave = run_poly5( wave, (osc->delay + poly5_pos) % poly5_len );
- poly5_inc = period % poly5_len;
- }
-
- // Run wave and high pass interleved with each catching up to the other.
- // Disabled high pass has no performance effect since inner wave loop
- // makes no compromise for high pass, and only runs once in that case.
- int osc_last_amp = osc->last_amp;
- do
- {
- // run high pass
- if ( time2 < time )
- {
- int delta = -osc_last_amp;
- if ( volume < 0 )
- delta += volume;
- if ( delta )
- {
- osc_last_amp += delta - volume;
- volume = -volume;
- impl->synth.offset( time2, delta, output );
- }
- }
- while ( time2 <= time ) // must advance *past* time to avoid hang
- time2 += period2;
-
- // run wave
- blip_time_t end = end_time;
- if ( end > time2 )
- end = time2;
- while ( time < end )
- {
- if ( wave & 1 )
- {
- int amp = volume & -(poly [poly_pos >> 3] >> (poly_pos & 7) & 1);
- if ( (poly_pos += poly_inc) < 0 )
- poly_pos += poly_len;
- int delta = amp - osc_last_amp;
- if ( delta )
- {
- osc_last_amp = amp;
- impl->synth.offset( time, delta, output );
- }
- }
- wave = run_poly5( wave, poly5_inc );
- time += period;
- }
- }
- while ( time < end_time || time2 < end_time );
-
- osc->phase = poly_pos;
- osc->last_amp = osc_last_amp;
- }
-
- osc->invert = 0;
- if ( volume < 0 )
- {
- // undo inversion trickery
- osc->last_amp -= volume;
- osc->invert = 1;
- }
- }
- }
-
- // maintain divider
- blip_time_t remain = end_time - time;
- if ( remain > 0 )
- {
- blargg_long count = (remain + period - 1) / period;
- osc->phase ^= count;
- time += count * period;
- }
- osc->delay = time - end_time;
- }
-
- // advance polies
- blip_time_t duration = end_time - last_time;
- last_time = end_time;
- poly4_pos = (poly4_pos + duration) % poly4_len;
- poly5_pos = (poly5_pos + duration) % poly5_len;
- polym_pos += duration; // will get %'d on next call
-}
-
-void Sap_Apu::write_data( blip_time_t time, unsigned addr, int data )
-{
- run_until( time );
- int i = (addr ^ 0xD200) >> 1;
- if ( i < osc_count )
- {
- oscs [i].regs [addr & 1] = data;
- }
- else if ( addr == 0xD208 )
- {
- control = data;
- }
- else if ( addr == 0xD209 )
- {
- oscs [0].delay = 0;
- oscs [1].delay = 0;
- oscs [2].delay = 0;
- oscs [3].delay = 0;
- }
- /*
- // TODO: are polynomials reset in this case?
- else if ( addr == 0xD20F )
- {
- if ( (data & 3) == 0 )
- polym_pos = 0;
- }
- */
-}
-
-void Sap_Apu::end_frame( blip_time_t end_time )
-{
- if ( end_time > last_time )
- run_until( end_time );
-
- last_time -= end_time;
-}
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Sap_Apu.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/Sap_Apu.h
deleted file mode 100644
index c71ce31e..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Sap_Apu.h
+++ /dev/null
@@ -1,77 +0,0 @@
-// Atari POKEY sound chip emulator
-
-// Game_Music_Emu 0.5.2
-#ifndef SAP_APU_H
-#define SAP_APU_H
-
-#include "blargg_common.h"
-#include "Blip_Buffer.h"
-
-class Sap_Apu_Impl;
-
-class Sap_Apu {
-public:
- enum { osc_count = 4 };
- void osc_output( int index, Blip_Buffer* );
-
- void reset( Sap_Apu_Impl* );
-
- enum { start_addr = 0xD200 };
- enum { end_addr = 0xD209 };
- void write_data( blip_time_t, unsigned addr, int data );
-
- void end_frame( blip_time_t );
-
-public:
- Sap_Apu();
-private:
- struct osc_t
- {
- unsigned char regs [2];
- unsigned char phase;
- unsigned char invert;
- int last_amp;
- blip_time_t delay;
- blip_time_t period; // always recalculated before use; here for convenience
- Blip_Buffer* output;
- };
- osc_t oscs [osc_count];
- Sap_Apu_Impl* impl;
- blip_time_t last_time;
- int poly5_pos;
- int poly4_pos;
- int polym_pos;
- int control;
-
- void calc_periods();
- void run_until( blip_time_t );
-
- enum { poly4_len = (1L << 4) - 1 };
- enum { poly9_len = (1L << 9) - 1 };
- enum { poly17_len = (1L << 17) - 1 };
- friend class Sap_Apu_Impl;
-};
-
-// Common tables and Blip_Synth that can be shared among multiple Sap_Apu objects
-class Sap_Apu_Impl {
-public:
- Blip_Synth<blip_good_quality,1> synth;
-
- Sap_Apu_Impl();
- void volume( double d ) { synth.volume( 1.0 / Sap_Apu::osc_count / 30 * d ); }
-
-private:
- typedef unsigned char byte;
- byte poly4 [Sap_Apu::poly4_len / 8 + 1];
- byte poly9 [Sap_Apu::poly9_len / 8 + 1];
- byte poly17 [Sap_Apu::poly17_len / 8 + 1];
- friend class Sap_Apu;
-};
-
-inline void Sap_Apu::osc_output( int i, Blip_Buffer* b )
-{
- assert( (unsigned) i < osc_count );
- oscs [i].output = b;
-}
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Sap_Cpu.cpp b/plugins/gme/Game_Music_Emu-0.5.2/gme/Sap_Cpu.cpp
deleted file mode 100644
index 10dc6061..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Sap_Cpu.cpp
+++ /dev/null
@@ -1,1011 +0,0 @@
-// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
-
-#include "Sap_Cpu.h"
-
-#include <limits.h>
-#include "blargg_endian.h"
-
-//#include "nes_cpu_log.h"
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#define FLUSH_TIME() (void) (s.time = s_time)
-#define CACHE_TIME() (void) (s_time = s.time)
-
-#include "sap_cpu_io.h"
-
-#ifndef CPU_DONE
- #define CPU_DONE( cpu, time, result_out ) { result_out = -1; }
-#endif
-
-#include "blargg_source.h"
-
-int const st_n = 0x80;
-int const st_v = 0x40;
-int const st_r = 0x20;
-int const st_b = 0x10;
-int const st_d = 0x08;
-int const st_i = 0x04;
-int const st_z = 0x02;
-int const st_c = 0x01;
-
-void Sap_Cpu::reset( void* new_mem )
-{
- check( state == &state_ );
- state = &state_;
- mem = (uint8_t*) new_mem;
- r.status = st_i;
- r.sp = 0xFF;
- r.pc = 0;
- r.a = 0;
- r.x = 0;
- r.y = 0;
- state_.time = 0;
- state_.base = 0;
- irq_time_ = future_sap_time;
- end_time_ = future_sap_time;
-
- blargg_verify_byte_order();
-}
-
-#define TIME (s_time + s.base)
-#define READ( addr ) CPU_READ( this, (addr), TIME )
-#define WRITE( addr, data ) {CPU_WRITE( this, (addr), (data), TIME );}
-#define READ_LOW( addr ) (mem [int (addr)])
-#define WRITE_LOW( addr, data ) (void) (READ_LOW( addr ) = (data))
-#define READ_PROG( addr ) (READ_LOW( addr ))
-
-#define SET_SP( v ) (sp = ((v) + 1) | 0x100)
-#define GET_SP() ((sp - 1) & 0xFF)
-#define PUSH( v ) ((sp = (sp - 1) | 0x100), WRITE_LOW( sp, v ))
-
-// even on x86, using short and unsigned char was slower
-typedef int fint16;
-typedef unsigned fuint16;
-typedef unsigned fuint8;
-typedef blargg_long fint32;
-
-bool Sap_Cpu::run( sap_time_t end_time )
-{
- bool illegal_encountered = false;
- set_end_time( end_time );
- state_t s = this->state_;
- this->state = &s;
- fint32 s_time = s.time;
- uint8_t* const mem = this->mem; // cache
-
- // registers
- fuint16 pc = r.pc;
- fuint8 a = r.a;
- fuint8 x = r.x;
- fuint8 y = r.y;
- fuint16 sp;
- SET_SP( r.sp );
-
- // status flags
- #define IS_NEG (nz & 0x8080)
-
- #define CALC_STATUS( out ) do {\
- out = status & (st_v | st_d | st_i);\
- out |= ((nz >> 8) | nz) & st_n;\
- out |= c >> 8 & st_c;\
- if ( !(nz & 0xFF) ) out |= st_z;\
- } while ( 0 )
-
- #define SET_STATUS( in ) do {\
- status = in & (st_v | st_d | st_i);\
- nz = in << 8;\
- c = nz;\
- nz |= ~in & st_z;\
- } while ( 0 )
-
- fuint8 status;
- fuint16 c; // carry set if (c & 0x100) != 0
- fuint16 nz; // Z set if (nz & 0xFF) == 0, N set if (nz & 0x8080) != 0
- {
- fuint8 temp = r.status;
- SET_STATUS( temp );
- }
-
- goto loop;
-dec_clock_loop:
- s_time--;
-loop:
-
- #ifndef NDEBUG
- {
- sap_time_t correct = end_time_;
- if ( !(status & st_i) && correct > irq_time_ )
- correct = irq_time_;
- check( s.base == correct );
- }
- #endif
-
- check( (unsigned) GET_SP() < 0x100 );
- check( (unsigned) a < 0x100 );
- check( (unsigned) x < 0x100 );
- check( (unsigned) y < 0x100 );
-
- fuint8 opcode = mem [pc];
- pc++;
- uint8_t const* instr = mem + pc;
-
- static uint8_t const clock_table [256] =
- {// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0,6,2,8,3,3,5,5,3,2,2,2,4,4,6,6,// 0
- 3,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,// 1
- 6,6,2,8,3,3,5,5,4,2,2,2,4,4,6,6,// 2
- 3,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,// 3
- 6,6,2,8,3,3,5,5,3,2,2,2,3,4,6,6,// 4
- 3,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,// 5
- 6,6,2,8,3,3,5,5,4,2,2,2,5,4,6,6,// 6
- 3,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,// 7
- 2,6,2,6,3,3,3,3,2,2,2,2,4,4,4,4,// 8
- 3,6,2,6,4,4,4,4,2,5,2,5,5,5,5,5,// 9
- 2,6,2,6,3,3,3,3,2,2,2,2,4,4,4,4,// A
- 3,5,2,5,4,4,4,4,2,4,2,4,4,4,4,4,// B
- 2,6,2,8,3,3,5,5,2,2,2,2,4,4,6,6,// C
- 3,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,// D
- 2,6,2,8,3,3,5,5,2,2,2,2,4,4,6,6,// E
- 3,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7 // F
- }; // 0x00 was 7
-
- fuint16 data;
- data = clock_table [opcode];
- if ( (s_time += data) >= 0 )
- goto possibly_out_of_time;
-almost_out_of_time:
-
- data = *instr;
-
- #ifdef NES_CPU_LOG_H
- nes_cpu_log( "cpu_log", pc - 1, opcode, instr [0], instr [1] );
- #endif
-
- switch ( opcode )
- {
-possibly_out_of_time:
- if ( s_time < (int) data )
- goto almost_out_of_time;
- s_time -= data;
- goto out_of_time;
-
-// Macros
-
-#define GET_MSB() (instr [1])
-#define ADD_PAGE() (pc++, data += 0x100 * GET_MSB())
-#define GET_ADDR() GET_LE16( instr )
-
-#define NO_PAGE_CROSSING( lsb )
-#define HANDLE_PAGE_CROSSING( lsb ) s_time += (lsb) >> 8;
-
-#define INC_DEC_XY( reg, n ) reg = uint8_t (nz = reg + n); goto loop;
-
-#define IND_Y( cross, out ) {\
- fuint16 temp = READ_LOW( data ) + y;\
- out = temp + 0x100 * READ_LOW( uint8_t (data + 1) );\
- cross( temp );\
- }
-
-#define IND_X( out ) {\
- fuint16 temp = data + x;\
- out = 0x100 * READ_LOW( uint8_t (temp + 1) ) + READ_LOW( uint8_t (temp) );\
- }
-
-#define ARITH_ADDR_MODES( op )\
-case op - 0x04: /* (ind,x) */\
- IND_X( data )\
- goto ptr##op;\
-case op + 0x0C: /* (ind),y */\
- IND_Y( HANDLE_PAGE_CROSSING, data )\
- goto ptr##op;\
-case op + 0x10: /* zp,X */\
- data = uint8_t (data + x);\
-case op + 0x00: /* zp */\
- data = READ_LOW( data );\
- goto imm##op;\
-case op + 0x14: /* abs,Y */\
- data += y;\
- goto ind##op;\
-case op + 0x18: /* abs,X */\
- data += x;\
-ind##op:\
- HANDLE_PAGE_CROSSING( data );\
-case op + 0x08: /* abs */\
- ADD_PAGE();\
-ptr##op:\
- FLUSH_TIME();\
- data = READ( data );\
- CACHE_TIME();\
-case op + 0x04: /* imm */\
-imm##op:
-
-// TODO: more efficient way to handle negative branch that wraps PC around
-#define BRANCH( cond )\
-{\
- fint16 offset = (BOOST::int8_t) data;\
- fuint16 extra_clock = (++pc & 0xFF) + offset;\
- if ( !(cond) ) goto dec_clock_loop;\
- pc += offset;\
- s_time += extra_clock >> 8 & 1;\
- goto loop;\
-}
-
-// Often-Used
-
- case 0xB5: // LDA zp,x
- a = nz = READ_LOW( uint8_t (data + x) );
- pc++;
- goto loop;
-
- case 0xA5: // LDA zp
- a = nz = READ_LOW( data );
- pc++;
- goto loop;
-
- case 0xD0: // BNE
- BRANCH( (uint8_t) nz );
-
- case 0x20: { // JSR
- fuint16 temp = pc + 1;
- pc = GET_ADDR();
- WRITE_LOW( 0x100 | (sp - 1), temp >> 8 );
- sp = (sp - 2) | 0x100;
- WRITE_LOW( sp, temp );
- goto loop;
- }
-
- case 0x4C: // JMP abs
- pc = GET_ADDR();
- goto loop;
-
- case 0xE8: // INX
- INC_DEC_XY( x, 1 )
-
- case 0x10: // BPL
- BRANCH( !IS_NEG )
-
- ARITH_ADDR_MODES( 0xC5 ) // CMP
- nz = a - data;
- pc++;
- c = ~nz;
- nz &= 0xFF;
- goto loop;
-
- case 0x30: // BMI
- BRANCH( IS_NEG )
-
- case 0xF0: // BEQ
- BRANCH( !(uint8_t) nz );
-
- case 0x95: // STA zp,x
- data = uint8_t (data + x);
- case 0x85: // STA zp
- pc++;
- WRITE_LOW( data, a );
- goto loop;
-
- case 0xC8: // INY
- INC_DEC_XY( y, 1 )
-
- case 0xA8: // TAY
- y = a;
- nz = a;
- goto loop;
-
- case 0x98: // TYA
- a = y;
- nz = y;
- goto loop;
-
- case 0xAD:{// LDA abs
- unsigned addr = GET_ADDR();
- pc += 2;
- nz = READ( addr );
- a = nz;
- goto loop;
- }
-
- case 0x60: // RTS
- pc = 1 + READ_LOW( sp );
- pc += 0x100 * READ_LOW( 0x100 | (sp - 0xFF) );
- sp = (sp - 0xFE) | 0x100;
- goto loop;
-
- {
- fuint16 addr;
-
- case 0x99: // STA abs,Y
- addr = y + GET_ADDR();
- pc += 2;
- if ( addr <= 0x7FF )
- {
- WRITE_LOW( addr, a );
- goto loop;
- }
- goto sta_ptr;
-
- case 0x8D: // STA abs
- addr = GET_ADDR();
- pc += 2;
- if ( addr <= 0x7FF )
- {
- WRITE_LOW( addr, a );
- goto loop;
- }
- goto sta_ptr;
-
- case 0x9D: // STA abs,X (slightly more common than STA abs)
- addr = x + GET_ADDR();
- pc += 2;
- if ( addr <= 0x7FF )
- {
- WRITE_LOW( addr, a );
- goto loop;
- }
- sta_ptr:
- FLUSH_TIME();
- WRITE( addr, a );
- CACHE_TIME();
- goto loop;
-
- case 0x91: // STA (ind),Y
- IND_Y( NO_PAGE_CROSSING, addr )
- pc++;
- goto sta_ptr;
-
- case 0x81: // STA (ind,X)
- IND_X( addr )
- pc++;
- goto sta_ptr;
-
- }
-
- case 0xA9: // LDA #imm
- pc++;
- a = data;
- nz = data;
- goto loop;
-
- // common read instructions
- {
- fuint16 addr;
-
- case 0xA1: // LDA (ind,X)
- IND_X( addr )
- pc++;
- goto a_nz_read_addr;
-
- case 0xB1:// LDA (ind),Y
- addr = READ_LOW( data ) + y;
- HANDLE_PAGE_CROSSING( addr );
- addr += 0x100 * READ_LOW( (uint8_t) (data + 1) );
- pc++;
- a = nz = READ_PROG( addr );
- if ( (addr ^ 0x8000) <= 0x9FFF )
- goto loop;
- goto a_nz_read_addr;
-
- case 0xB9: // LDA abs,Y
- HANDLE_PAGE_CROSSING( data + y );
- addr = GET_ADDR() + y;
- pc += 2;
- a = nz = READ_PROG( addr );
- if ( (addr ^ 0x8000) <= 0x9FFF )
- goto loop;
- goto a_nz_read_addr;
-
- case 0xBD: // LDA abs,X
- HANDLE_PAGE_CROSSING( data + x );
- addr = GET_ADDR() + x;
- pc += 2;
- a = nz = READ_PROG( addr );
- if ( (addr ^ 0x8000) <= 0x9FFF )
- goto loop;
- a_nz_read_addr:
- FLUSH_TIME();
- a = nz = READ( addr );
- CACHE_TIME();
- goto loop;
-
- }
-
-// Branch
-
- case 0x50: // BVC
- BRANCH( !(status & st_v) )
-
- case 0x70: // BVS
- BRANCH( status & st_v )
-
- case 0xB0: // BCS
- BRANCH( c & 0x100 )
-
- case 0x90: // BCC
- BRANCH( !(c & 0x100) )
-
-// Load/store
-
- case 0x94: // STY zp,x
- data = uint8_t (data + x);
- case 0x84: // STY zp
- pc++;
- WRITE_LOW( data, y );
- goto loop;
-
- case 0x96: // STX zp,y
- data = uint8_t (data + y);
- case 0x86: // STX zp
- pc++;
- WRITE_LOW( data, x );
- goto loop;
-
- case 0xB6: // LDX zp,y
- data = uint8_t (data + y);
- case 0xA6: // LDX zp
- data = READ_LOW( data );
- case 0xA2: // LDX #imm
- pc++;
- x = data;
- nz = data;
- goto loop;
-
- case 0xB4: // LDY zp,x
- data = uint8_t (data + x);
- case 0xA4: // LDY zp
- data = READ_LOW( data );
- case 0xA0: // LDY #imm
- pc++;
- y = data;
- nz = data;
- goto loop;
-
- case 0xBC: // LDY abs,X
- data += x;
- HANDLE_PAGE_CROSSING( data );
- case 0xAC:{// LDY abs
- unsigned addr = data + 0x100 * GET_MSB();
- pc += 2;
- FLUSH_TIME();
- y = nz = READ( addr );
- CACHE_TIME();
- goto loop;
- }
-
- case 0xBE: // LDX abs,y
- data += y;
- HANDLE_PAGE_CROSSING( data );
- case 0xAE:{// LDX abs
- unsigned addr = data + 0x100 * GET_MSB();
- pc += 2;
- FLUSH_TIME();
- x = nz = READ( addr );
- CACHE_TIME();
- goto loop;
- }
-
- {
- fuint8 temp;
- case 0x8C: // STY abs
- temp = y;
- goto store_abs;
-
- case 0x8E: // STX abs
- temp = x;
- store_abs:
- unsigned addr = GET_ADDR();
- pc += 2;
- if ( addr <= 0x7FF )
- {
- WRITE_LOW( addr, temp );
- goto loop;
- }
- FLUSH_TIME();
- WRITE( addr, temp );
- CACHE_TIME();
- goto loop;
- }
-
-// Compare
-
- case 0xEC:{// CPX abs
- unsigned addr = GET_ADDR();
- pc++;
- FLUSH_TIME();
- data = READ( addr );
- CACHE_TIME();
- goto cpx_data;
- }
-
- case 0xE4: // CPX zp
- data = READ_LOW( data );
- case 0xE0: // CPX #imm
- cpx_data:
- nz = x - data;
- pc++;
- c = ~nz;
- nz &= 0xFF;
- goto loop;
-
- case 0xCC:{// CPY abs
- unsigned addr = GET_ADDR();
- pc++;
- FLUSH_TIME();
- data = READ( addr );
- CACHE_TIME();
- goto cpy_data;
- }
-
- case 0xC4: // CPY zp
- data = READ_LOW( data );
- case 0xC0: // CPY #imm
- cpy_data:
- nz = y - data;
- pc++;
- c = ~nz;
- nz &= 0xFF;
- goto loop;
-
-// Logical
-
- ARITH_ADDR_MODES( 0x25 ) // AND
- nz = (a &= data);
- pc++;
- goto loop;
-
- ARITH_ADDR_MODES( 0x45 ) // EOR
- nz = (a ^= data);
- pc++;
- goto loop;
-
- ARITH_ADDR_MODES( 0x05 ) // ORA
- nz = (a |= data);
- pc++;
- goto loop;
-
- case 0x2C:{// BIT abs
- unsigned addr = GET_ADDR();
- pc += 2;
- status &= ~st_v;
- nz = READ( addr );
- status |= nz & st_v;
- if ( a & nz )
- goto loop;
- nz <<= 8; // result must be zero, even if N bit is set
- goto loop;
- }
-
- case 0x24: // BIT zp
- nz = READ_LOW( data );
- pc++;
- status &= ~st_v;
- status |= nz & st_v;
- if ( a & nz )
- goto loop;
- nz <<= 8; // result must be zero, even if N bit is set
- goto loop;
-
-// Add/subtract
-
- ARITH_ADDR_MODES( 0xE5 ) // SBC
- case 0xEB: // unofficial equivalent
- data ^= 0xFF;
- goto adc_imm;
-
- ARITH_ADDR_MODES( 0x65 ) // ADC
- adc_imm: {
- check( !(status & st_d) );
- fint16 carry = c >> 8 & 1;
- fint16 ov = (a ^ 0x80) + carry + (BOOST::int8_t) data; // sign-extend
- status &= ~st_v;
- status |= ov >> 2 & 0x40;
- c = nz = a + data + carry;
- pc++;
- a = (uint8_t) nz;
- goto loop;
- }
-
-// Shift/rotate
-
- case 0x4A: // LSR A
- c = 0;
- case 0x6A: // ROR A
- nz = c >> 1 & 0x80;
- c = a << 8;
- nz |= a >> 1;
- a = nz;
- goto loop;
-
- case 0x0A: // ASL A
- nz = a << 1;
- c = nz;
- a = (uint8_t) nz;
- goto loop;
-
- case 0x2A: { // ROL A
- nz = a << 1;
- fint16 temp = c >> 8 & 1;
- c = nz;
- nz |= temp;
- a = (uint8_t) nz;
- goto loop;
- }
-
- case 0x5E: // LSR abs,X
- data += x;
- case 0x4E: // LSR abs
- c = 0;
- case 0x6E: // ROR abs
- ror_abs: {
- ADD_PAGE();
- FLUSH_TIME();
- int temp = READ( data );
- nz = (c >> 1 & 0x80) | (temp >> 1);
- c = temp << 8;
- goto rotate_common;
- }
-
- case 0x3E: // ROL abs,X
- data += x;
- goto rol_abs;
-
- case 0x1E: // ASL abs,X
- data += x;
- case 0x0E: // ASL abs
- c = 0;
- case 0x2E: // ROL abs
- rol_abs:
- ADD_PAGE();
- nz = c >> 8 & 1;
- FLUSH_TIME();
- nz |= (c = READ( data ) << 1);
- rotate_common:
- pc++;
- WRITE( data, (uint8_t) nz );
- CACHE_TIME();
- goto loop;
-
- case 0x7E: // ROR abs,X
- data += x;
- goto ror_abs;
-
- case 0x76: // ROR zp,x
- data = uint8_t (data + x);
- goto ror_zp;
-
- case 0x56: // LSR zp,x
- data = uint8_t (data + x);
- case 0x46: // LSR zp
- c = 0;
- case 0x66: // ROR zp
- ror_zp: {
- int temp = READ_LOW( data );
- nz = (c >> 1 & 0x80) | (temp >> 1);
- c = temp << 8;
- goto write_nz_zp;
- }
-
- case 0x36: // ROL zp,x
- data = uint8_t (data + x);
- goto rol_zp;
-
- case 0x16: // ASL zp,x
- data = uint8_t (data + x);
- case 0x06: // ASL zp
- c = 0;
- case 0x26: // ROL zp
- rol_zp:
- nz = c >> 8 & 1;
- nz |= (c = READ_LOW( data ) << 1);
- goto write_nz_zp;
-
-// Increment/decrement
-
- case 0xCA: // DEX
- INC_DEC_XY( x, -1 )
-
- case 0x88: // DEY
- INC_DEC_XY( y, -1 )
-
- case 0xF6: // INC zp,x
- data = uint8_t (data + x);
- case 0xE6: // INC zp
- nz = 1;
- goto add_nz_zp;
-
- case 0xD6: // DEC zp,x
- data = uint8_t (data + x);
- case 0xC6: // DEC zp
- nz = (unsigned) -1;
- add_nz_zp:
- nz += READ_LOW( data );
- write_nz_zp:
- pc++;
- WRITE_LOW( data, nz );
- goto loop;
-
- case 0xFE: // INC abs,x
- data = x + GET_ADDR();
- goto inc_ptr;
-
- case 0xEE: // INC abs
- data = GET_ADDR();
- inc_ptr:
- nz = 1;
- goto inc_common;
-
- case 0xDE: // DEC abs,x
- data = x + GET_ADDR();
- goto dec_ptr;
-
- case 0xCE: // DEC abs
- data = GET_ADDR();
- dec_ptr:
- nz = (unsigned) -1;
- inc_common:
- FLUSH_TIME();
- nz += READ( data );
- pc += 2;
- WRITE( data, (uint8_t) nz );
- CACHE_TIME();
- goto loop;
-
-// Transfer
-
- case 0xAA: // TAX
- x = a;
- nz = a;
- goto loop;
-
- case 0x8A: // TXA
- a = x;
- nz = x;
- goto loop;
-
- case 0x9A: // TXS
- SET_SP( x ); // verified (no flag change)
- goto loop;
-
- case 0xBA: // TSX
- x = nz = GET_SP();
- goto loop;
-
-// Stack
-
- case 0x48: // PHA
- PUSH( a ); // verified
- goto loop;
-
- case 0x68: // PLA
- a = nz = READ_LOW( sp );
- sp = (sp - 0xFF) | 0x100;
- goto loop;
-
- case 0x40:{// RTI
- fuint8 temp = READ_LOW( sp );
- pc = READ_LOW( 0x100 | (sp - 0xFF) );
- pc |= READ_LOW( 0x100 | (sp - 0xFE) ) * 0x100;
- sp = (sp - 0xFD) | 0x100;
- data = status;
- SET_STATUS( temp );
- this->r.status = status; // update externally-visible I flag
- if ( (data ^ status) & st_i )
- {
- sap_time_t new_time = end_time_;
- if ( !(status & st_i) && new_time > irq_time_ )
- new_time = irq_time_;
- blargg_long delta = s.base - new_time;
- s.base = new_time;
- s_time += delta;
- }
- goto loop;
- }
-
- case 0x28:{// PLP
- fuint8 temp = READ_LOW( sp );
- sp = (sp - 0xFF) | 0x100;
- fuint8 changed = status ^ temp;
- SET_STATUS( temp );
- if ( !(changed & st_i) )
- goto loop; // I flag didn't change
- if ( status & st_i )
- goto handle_sei;
- goto handle_cli;
- }
-
- case 0x08: { // PHP
- fuint8 temp;
- CALC_STATUS( temp );
- PUSH( temp | (st_b | st_r) );
- goto loop;
- }
-
- case 0x6C:{// JMP (ind)
- data = GET_ADDR();
- pc = READ_PROG( data );
- data = (data & 0xFF00) | ((data + 1) & 0xFF);
- pc |= 0x100 * READ_PROG( data );
- goto loop;
- }
-
- case 0x00: // BRK
- goto handle_brk;
-
-// Flags
-
- case 0x38: // SEC
- c = (unsigned) ~0;
- goto loop;
-
- case 0x18: // CLC
- c = 0;
- goto loop;
-
- case 0xB8: // CLV
- status &= ~st_v;
- goto loop;
-
- case 0xD8: // CLD
- status &= ~st_d;
- goto loop;
-
- case 0xF8: // SED
- status |= st_d;
- goto loop;
-
- case 0x58: // CLI
- if ( !(status & st_i) )
- goto loop;
- status &= ~st_i;
- handle_cli: {
- this->r.status = status; // update externally-visible I flag
- blargg_long delta = s.base - irq_time_;
- if ( delta <= 0 )
- {
- if ( TIME < irq_time_ )
- goto loop;
- goto delayed_cli;
- }
- s.base = irq_time_;
- s_time += delta;
- if ( s_time < 0 )
- goto loop;
-
- if ( delta >= s_time + 1 )
- {
- // delayed irq until after next instruction
- s.base += s_time + 1;
- s_time = -1;
- irq_time_ = s.base; // TODO: remove, as only to satisfy debug check in loop
- goto loop;
- }
- delayed_cli:
- dprintf( "Delayed CLI not emulated\n" );
- goto loop;
- }
-
- case 0x78: // SEI
- if ( status & st_i )
- goto loop;
- status |= st_i;
- handle_sei: {
- this->r.status = status; // update externally-visible I flag
- blargg_long delta = s.base - end_time_;
- s.base = end_time_;
- s_time += delta;
- if ( s_time < 0 )
- goto loop;
- dprintf( "Delayed SEI not emulated\n" );
- goto loop;
- }
-
-// Unofficial
-
- // SKW - Skip word
- case 0x1C: case 0x3C: case 0x5C: case 0x7C: case 0xDC: case 0xFC:
- HANDLE_PAGE_CROSSING( data + x );
- case 0x0C:
- pc++;
- // SKB - Skip byte
- case 0x74: case 0x04: case 0x14: case 0x34: case 0x44: case 0x54: case 0x64:
- case 0x80: case 0x82: case 0x89: case 0xC2: case 0xD4: case 0xE2: case 0xF4:
- pc++;
- goto loop;
-
- // NOP
- case 0xEA: case 0x1A: case 0x3A: case 0x5A: case 0x7A: case 0xDA: case 0xFA:
- goto loop;
-
-// Unimplemented
-
- // halt
- //case 0x02: case 0x12: case 0x22: case 0x32: case 0x42: case 0x52:
- //case 0x62: case 0x72: case 0x92: case 0xB2: case 0xD2: case 0xF2:
-
- default:
- assert( (unsigned) opcode <= 0xFF );
- illegal_encountered = true;
- pc--;
- goto stop;
- }
- assert( false );
-
- int result_;
-handle_brk:
- if ( (pc - 1) >= idle_addr )
- goto idle_done;
- pc++;
- result_ = 4;
- dprintf( "BRK executed\n" );
-
-interrupt:
- {
- s_time += 7;
-
- WRITE_LOW( 0x100 | (sp - 1), pc >> 8 );
- WRITE_LOW( 0x100 | (sp - 2), pc );
- pc = GET_LE16( &READ_PROG( 0xFFFA ) + result_ );
-
- sp = (sp - 3) | 0x100;
- fuint8 temp;
- CALC_STATUS( temp );
- temp |= st_r;
- if ( result_ )
- temp |= st_b; // TODO: incorrectly sets B flag for IRQ
- WRITE_LOW( sp, temp );
-
- status &= ~st_d;
- status |= st_i;
- this->r.status = status; // update externally-visible I flag
-
- blargg_long delta = s.base - end_time_;
- s.base = end_time_;
- s_time += delta;
- goto loop;
- }
-
-idle_done:
- //s_time = 0;
- pc--;
- goto stop;
-out_of_time:
- pc--;
- FLUSH_TIME();
- CPU_DONE( this, TIME, result_ );
- CACHE_TIME();
- if ( result_ >= 0 )
- goto interrupt;
- if ( s_time < 0 )
- goto loop;
-
-stop:
-
- s.time = s_time;
-
- r.pc = pc;
- r.sp = GET_SP();
- r.a = a;
- r.x = x;
- r.y = y;
-
- {
- fuint8 temp;
- CALC_STATUS( temp );
- r.status = temp;
- }
-
- this->state_ = s;
- this->state = &this->state_;
-
- return illegal_encountered;
-}
-
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Sap_Cpu.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/Sap_Cpu.h
deleted file mode 100644
index 712f63cd..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Sap_Cpu.h
+++ /dev/null
@@ -1,83 +0,0 @@
-// Atari 6502 CPU emulator
-
-// Game_Music_Emu 0.5.2
-#ifndef SAP_CPU_H
-#define SAP_CPU_H
-
-#include "blargg_common.h"
-
-typedef blargg_long sap_time_t; // clock cycle count
-typedef unsigned sap_addr_t; // 16-bit address
-enum { future_sap_time = LONG_MAX / 2 + 1 };
-
-class Sap_Cpu {
-public:
- typedef BOOST::uint8_t uint8_t;
-
- // Clear all registers and keep pointer to 64K memory passed in
- void reset( void* mem_64k );
-
- // Run until specified time is reached. Returns true if suspicious/unsupported
- // instruction was encountered at any point during run.
- bool run( sap_time_t end_time );
-
- // Registers are not updated until run() returns (except I flag in status)
- struct registers_t {
- BOOST::uint16_t pc;
- BOOST::uint8_t a;
- BOOST::uint8_t x;
- BOOST::uint8_t y;
- BOOST::uint8_t status;
- BOOST::uint8_t sp;
- };
- registers_t r;
-
- enum { idle_addr = 0xFEFF };
-
- // Time of beginning of next instruction to be executed
- sap_time_t time() const { return state->time + state->base; }
- void set_time( sap_time_t t ) { state->time = t - state->base; }
- void adjust_time( int delta ) { state->time += delta; }
-
- sap_time_t irq_time() const { return irq_time_; }
- void set_irq_time( sap_time_t );
-
- sap_time_t end_time() const { return end_time_; }
- void set_end_time( sap_time_t );
-
-public:
- Sap_Cpu() { state = &state_; }
- enum { irq_inhibit = 0x04 };
-private:
- struct state_t {
- sap_time_t base;
- sap_time_t time;
- };
- state_t* state; // points to state_ or a local copy within run()
- state_t state_;
- sap_time_t irq_time_;
- sap_time_t end_time_;
- uint8_t* mem;
-
- inline sap_time_t update_end_time( sap_time_t end, sap_time_t irq );
-};
-
-inline sap_time_t Sap_Cpu::update_end_time( sap_time_t t, sap_time_t irq )
-{
- if ( irq < t && !(r.status & irq_inhibit) ) t = irq;
- sap_time_t delta = state->base - t;
- state->base = t;
- return delta;
-}
-
-inline void Sap_Cpu::set_irq_time( sap_time_t t )
-{
- state->time += update_end_time( end_time_, (irq_time_ = t) );
-}
-
-inline void Sap_Cpu::set_end_time( sap_time_t t )
-{
- state->time += update_end_time( (end_time_ = t), irq_time_ );
-}
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Sap_Emu.cpp b/plugins/gme/Game_Music_Emu-0.5.2/gme/Sap_Emu.cpp
deleted file mode 100644
index 8314fd6e..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Sap_Emu.cpp
+++ /dev/null
@@ -1,442 +0,0 @@
-// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
-
-#include "Sap_Emu.h"
-
-#include "blargg_endian.h"
-#include <string.h>
-
-/* Copyright (C) 2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-long const base_scanline_period = 114;
-
-Sap_Emu::Sap_Emu()
-{
- set_type( gme_sap_type );
-
- static const char* const names [Sap_Apu::osc_count * 2] = {
- "Wave 1", "Wave 2", "Wave 3", "Wave 4",
- "Wave 5", "Wave 6", "Wave 7", "Wave 8",
- };
- set_voice_names( names );
-
- static int const types [Sap_Apu::osc_count * 2] = {
- wave_type | 1, wave_type | 2, wave_type | 3, wave_type | 0,
- wave_type | 5, wave_type | 6, wave_type | 7, wave_type | 4,
- };
- set_voice_types( types );
- set_silence_lookahead( 6 );
-}
-
-Sap_Emu::~Sap_Emu() { }
-
-// Track info
-
-// Returns 16 or greater if not hex
-inline int from_hex_char( int h )
-{
- h -= 0x30;
- if ( (unsigned) h > 9 )
- h = ((h - 0x11) & 0xDF) + 10;
- return h;
-}
-
-static long from_hex( byte const* in )
-{
- unsigned result = 0;
- for ( int n = 4; n--; )
- {
- int h = from_hex_char( *in++ );
- if ( h > 15 )
- return -1;
- result = result * 0x10 + h;
- }
- return result;
-}
-
-static int from_dec( byte const* in, byte const* end )
-{
- if ( in >= end )
- return -1;
-
- int n = 0;
- while ( in < end )
- {
- int dig = *in++ - '0';
- if ( (unsigned) dig > 9 )
- return -1;
- n = n * 10 + dig;
- }
- return n;
-}
-
-static void parse_string( byte const* in, byte const* end, int len, char* out )
-{
- byte const* start = in;
- if ( *in++ == '\"' )
- {
- start++;
- while ( in < end && *in != '\"' )
- in++;
- }
- else
- {
- in = end;
- }
- len = min( len - 1, int (in - start) );
- out [len] = 0;
- memcpy( out, start, len );
-}
-
-static blargg_err_t parse_info( byte const* in, long size, Sap_Emu::info_t* out )
-{
- out->track_count = 1;
- out->author [0] = 0;
- out->name [0] = 0;
- out->copyright [0] = 0;
-
- if ( size < 16 || memcmp( in, "SAP\x0D\x0A", 5 ) )
- return gme_wrong_file_type;
-
- byte const* file_end = in + size - 5;
- in += 5;
- while ( in < file_end && (in [0] != 0xFF || in [1] != 0xFF) )
- {
- byte const* line_end = in;
- while ( line_end < file_end && *line_end != 0x0D )
- line_end++;
-
- char const* tag = (char const*) in;
- while ( in < line_end && *in > ' ' )
- in++;
- int tag_len = (char const*) in - tag;
-
- while ( in < line_end && *in <= ' ' ) in++;
-
- if ( tag_len <= 0 )
- {
- // skip line
- }
- else if ( !strncmp( "INIT", tag, tag_len ) )
- {
- out->init_addr = from_hex( in );
- if ( (unsigned long) out->init_addr > 0xFFFF )
- return "Invalid init address";
- }
- else if ( !strncmp( "PLAYER", tag, tag_len ) )
- {
- out->play_addr = from_hex( in );
- if ( (unsigned long) out->play_addr > 0xFFFF )
- return "Invalid play address";
- }
- else if ( !strncmp( "MUSIC", tag, tag_len ) )
- {
- out->music_addr = from_hex( in );
- if ( (unsigned long) out->music_addr > 0xFFFF )
- return "Invalid music address";
- }
- else if ( !strncmp( "SONGS", tag, tag_len ) )
- {
- out->track_count = from_dec( in, line_end );
- if ( out->track_count <= 0 )
- return "Invalid track count";
- }
- else if ( !strncmp( "TYPE", tag, tag_len ) )
- {
- switch ( out->type = *in )
- {
- case 'C':
- case 'B':
- break;
-
- case 'D':
- return "Digimusic not supported";
-
- default:
- return "Unsupported player type";
- }
- }
- else if ( !strncmp( "STEREO", tag, tag_len ) )
- {
- out->stereo = true;
- }
- else if ( !strncmp( "FASTPLAY", tag, tag_len ) )
- {
- out->fastplay = from_dec( in, line_end );
- if ( out->fastplay <= 0 )
- return "Invalid fastplay value";
- }
- else if ( !strncmp( "AUTHOR", tag, tag_len ) )
- {
- parse_string( in, line_end, sizeof out->author, out->author );
- }
- else if ( !strncmp( "NAME", tag, tag_len ) )
- {
- parse_string( in, line_end, sizeof out->name, out->name );
- }
- else if ( !strncmp( "DATE", tag, tag_len ) )
- {
- parse_string( in, line_end, sizeof out->copyright, out->copyright );
- }
-
- in = line_end + 2;
- }
-
- if ( in [0] != 0xFF || in [1] != 0xFF )
- return "ROM data missing";
- out->rom_data = in + 2;
-
- return 0;
-}
-
-static void copy_sap_fields( Sap_Emu::info_t const& in, track_info_t* out )
-{
- Gme_File::copy_field_( out->game, in.name );
- Gme_File::copy_field_( out->author, in.author );
- Gme_File::copy_field_( out->copyright, in.copyright );
-}
-
-blargg_err_t Sap_Emu::track_info_( track_info_t* out, int ) const
-{
- copy_sap_fields( info, out );
- return 0;
-}
-
-struct Sap_File : Gme_Info_
-{
- Sap_Emu::info_t info;
-
- Sap_File() { set_type( gme_sap_type ); }
-
- blargg_err_t load_mem_( byte const* begin, long size )
- {
- RETURN_ERR( parse_info( begin, size, &info ) );
- set_track_count( info.track_count );
- return 0;
- }
-
- blargg_err_t track_info_( track_info_t* out, int ) const
- {
- copy_sap_fields( info, out );
- return 0;
- }
-};
-
-static Music_Emu* new_sap_emu () { return BLARGG_NEW Sap_Emu ; }
-static Music_Emu* new_sap_file() { return BLARGG_NEW Sap_File; }
-
-gme_type_t_ const gme_sap_type [1] = { "Atari XL", 0, &new_sap_emu, &new_sap_file, "SAP", 1 };
-
-// Setup
-
-blargg_err_t Sap_Emu::load_mem_( byte const* in, long size )
-{
- file_end = in + size;
-
- info.warning = 0;
- info.type = 'B';
- info.stereo = false;
- info.init_addr = -1;
- info.play_addr = -1;
- info.music_addr = -1;
- info.fastplay = 312;
- RETURN_ERR( parse_info( in, size, &info ) );
-
- set_warning( info.warning );
- set_track_count( info.track_count );
- set_voice_count( Sap_Apu::osc_count << info.stereo );
- apu_impl.volume( gain() );
-
- return setup_buffer( 1773447 );
-}
-
-void Sap_Emu::update_eq( blip_eq_t const& eq )
-{
- apu_impl.synth.treble_eq( eq );
-}
-
-void Sap_Emu::set_voice( int i, Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right )
-{
- int i2 = i - Sap_Apu::osc_count;
- if ( i2 >= 0 )
- apu2.osc_output( i2, right );
- else
- apu.osc_output( i, (info.stereo ? left : center) );
-}
-
-// Emulation
-
-void Sap_Emu::set_tempo_( double t )
-{
- scanline_period = sap_time_t (base_scanline_period / t);
-}
-
-inline sap_time_t Sap_Emu::play_period() const { return info.fastplay * scanline_period; }
-
-void Sap_Emu::cpu_jsr( sap_addr_t addr )
-{
- check( r.sp >= 0xFE ); // catch anything trying to leave data on stack
- r.pc = addr;
- int high_byte = (idle_addr - 1) >> 8;
- if ( r.sp == 0xFE && mem.ram [0x1FF] == high_byte )
- r.sp = 0xFF; // pop extra byte off
- mem.ram [0x100 + r.sp--] = high_byte; // some routines use RTI to return
- mem.ram [0x100 + r.sp--] = high_byte;
- mem.ram [0x100 + r.sp--] = (idle_addr - 1) & 0xFF;
-}
-
-void Sap_Emu::run_routine( sap_addr_t addr )
-{
- cpu_jsr( addr );
- cpu::run( 312 * base_scanline_period * 60 );
- check( r.pc == idle_addr );
-}
-
-inline void Sap_Emu::call_init( int track )
-{
- switch ( info.type )
- {
- case 'B':
- r.a = track;
- run_routine( info.init_addr );
- break;
-
- case 'C':
- r.a = 0x70;
- r.x = info.music_addr&0xFF;
- r.y = info.music_addr >> 8;
- run_routine( info.play_addr + 3 );
- r.a = 0;
- r.x = track;
- run_routine( info.play_addr + 3 );
- break;
- }
-}
-
-blargg_err_t Sap_Emu::start_track_( int track )
-{
- RETURN_ERR( Classic_Emu::start_track_( track ) );
-
- memset( &mem, 0, sizeof mem );
-
- byte const* in = info.rom_data;
- while ( file_end - in >= 5 )
- {
- unsigned start = get_le16( in );
- unsigned end = get_le16( in + 2 );
- //dprintf( "Block $%04X-$%04X\n", start, end );
- in += 4;
- if ( end < start )
- {
- set_warning( "Invalid file data block" );
- break;
- }
- long len = end - start + 1;
- if ( len > file_end - in )
- {
- set_warning( "Invalid file data block" );
- break;
- }
-
- memcpy( mem.ram + start, in, len );
- in += len;
- if ( file_end - in >= 2 && in [0] == 0xFF && in [1] == 0xFF )
- in += 2;
- }
-
- apu.reset( &apu_impl );
- apu2.reset( &apu_impl );
- cpu::reset( mem.ram );
- time_mask = 0; // disables sound during init
- call_init( track );
- time_mask = -1;
-
- next_play = play_period();
-
- return 0;
-}
-
-// Emulation
-
-// see sap_cpu_io.h for read/write functions
-
-void Sap_Emu::cpu_write_( sap_addr_t addr, int data )
-{
- if ( (addr ^ Sap_Apu::start_addr) <= (Sap_Apu::end_addr - Sap_Apu::start_addr) )
- {
- GME_APU_HOOK( this, addr - Sap_Apu::start_addr, data );
- apu.write_data( time() & time_mask, addr, data );
- return;
- }
-
- if ( (addr ^ (Sap_Apu::start_addr + 0x10)) <= (Sap_Apu::end_addr - Sap_Apu::start_addr) &&
- info.stereo )
- {
- GME_APU_HOOK( this, addr - 0x10 - Sap_Apu::start_addr + 10, data );
- apu2.write_data( time() & time_mask, addr ^ 0x10, data );
- return;
- }
-
- if ( (addr & ~0x0010) != 0xD20F || data != 0x03 )
- dprintf( "Unmapped write $%04X <- $%02X\n", addr, data );
-}
-
-inline void Sap_Emu::call_play()
-{
- switch ( info.type )
- {
- case 'B':
- cpu_jsr( info.play_addr );
- break;
-
- case 'C':
- cpu_jsr( info.play_addr + 6 );
- break;
- }
-}
-
-blargg_err_t Sap_Emu::run_clocks( blip_time_t& duration, int )
-{
- set_time( 0 );
- while ( time() < duration )
- {
- if ( cpu::run( duration ) || r.pc > idle_addr )
- return "Emulation error (illegal instruction)";
-
- if ( r.pc == idle_addr )
- {
- if ( next_play <= duration )
- {
- set_time( next_play );
- next_play += play_period();
- call_play();
- GME_FRAME_HOOK( this );
- }
- else
- {
- set_time( duration );
- }
- }
- }
-
- duration = time();
- next_play -= duration;
- check( next_play >= 0 );
- if ( next_play < 0 )
- next_play = 0;
- apu.end_frame( duration );
- if ( info.stereo )
- apu2.end_frame( duration );
-
- return 0;
-}
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Sap_Emu.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/Sap_Emu.h
deleted file mode 100644
index 4878faa6..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Sap_Emu.h
+++ /dev/null
@@ -1,69 +0,0 @@
-// Atari XL/XE SAP music file emulator
-
-// Game_Music_Emu 0.5.2
-#ifndef SAP_EMU_H
-#define SAP_EMU_H
-
-#include "Classic_Emu.h"
-#include "Sap_Apu.h"
-#include "Sap_Cpu.h"
-
-class Sap_Emu : private Sap_Cpu, public Classic_Emu {
- typedef Sap_Cpu cpu;
-public:
- static gme_type_t static_type() { return gme_sap_type; }
-public:
- Sap_Emu();
- ~Sap_Emu();
- struct info_t {
- byte const* rom_data;
- const char* warning;
- long init_addr;
- long play_addr;
- long music_addr;
- int type;
- int track_count;
- int fastplay;
- bool stereo;
- char author [256];
- char name [256];
- char copyright [ 32];
- };
-protected:
- blargg_err_t track_info_( track_info_t*, int track ) const;
- blargg_err_t load_mem_( byte const*, long );
- blargg_err_t start_track_( int );
- blargg_err_t run_clocks( blip_time_t&, int );
- void set_tempo_( double );
- void set_voice( int, Blip_Buffer*, Blip_Buffer*, Blip_Buffer* );
- void update_eq( blip_eq_t const& );
-public: private: friend class Sap_Cpu;
- int cpu_read( sap_addr_t );
- void cpu_write( sap_addr_t, int );
- void cpu_write_( sap_addr_t, int );
-private:
- info_t info;
-
- byte const* file_end;
- sap_time_t scanline_period;
- sap_time_t next_play;
- sap_time_t time_mask;
- Sap_Apu apu;
- Sap_Apu apu2;
-
- // large items
- struct {
- byte padding1 [0x100];
- byte ram [0x10000];
- byte padding2 [0x100];
- } mem;
- Sap_Apu_Impl apu_impl;
-
- sap_time_t play_period() const;
- void call_play();
- void cpu_jsr( sap_addr_t );
- void call_init( int track );
- void run_routine( sap_addr_t );
-};
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Sms_Apu.cpp b/plugins/gme/Game_Music_Emu-0.5.2/gme/Sms_Apu.cpp
deleted file mode 100644
index b41fdec4..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Sms_Apu.cpp
+++ /dev/null
@@ -1,330 +0,0 @@
-// Sms_Snd_Emu 0.1.4. http://www.slack.net/~ant/
-
-#include "Sms_Apu.h"
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-// Sms_Osc
-
-Sms_Osc::Sms_Osc()
-{
- output = 0;
- outputs [0] = 0; // always stays NULL
- outputs [1] = 0;
- outputs [2] = 0;
- outputs [3] = 0;
-}
-
-void Sms_Osc::reset()
-{
- delay = 0;
- last_amp = 0;
- volume = 0;
- output_select = 3;
- output = outputs [3];
-}
-
-// Sms_Square
-
-inline void Sms_Square::reset()
-{
- period = 0;
- phase = 0;
- Sms_Osc::reset();
-}
-
-void Sms_Square::run( blip_time_t time, blip_time_t end_time )
-{
- if ( !volume || period <= 128 )
- {
- // ignore 16kHz and higher
- if ( last_amp )
- {
- synth->offset( time, -last_amp, output );
- last_amp = 0;
- }
- time += delay;
- if ( !period )
- {
- time = end_time;
- }
- else if ( time < end_time )
- {
- // keep calculating phase
- int count = (end_time - time + period - 1) / period;
- phase = (phase + count) & 1;
- time += count * period;
- }
- }
- else
- {
- int amp = phase ? volume : -volume;
- {
- int delta = amp - last_amp;
- if ( delta )
- {
- last_amp = amp;
- synth->offset( time, delta, output );
- }
- }
-
- time += delay;
- if ( time < end_time )
- {
- Blip_Buffer* const output = this->output;
- int delta = amp * 2;
- do
- {
- delta = -delta;
- synth->offset_inline( time, delta, output );
- time += period;
- phase ^= 1;
- }
- while ( time < end_time );
- this->last_amp = phase ? volume : -volume;
- }
- }
- delay = time - end_time;
-}
-
-// Sms_Noise
-
-static int const noise_periods [3] = { 0x100, 0x200, 0x400 };
-
-inline void Sms_Noise::reset()
-{
- period = &noise_periods [0];
- shifter = 0x8000;
- feedback = 0x9000;
- Sms_Osc::reset();
-}
-
-void Sms_Noise::run( blip_time_t time, blip_time_t end_time )
-{
- int amp = volume;
- if ( shifter & 1 )
- amp = -amp;
-
- {
- int delta = amp - last_amp;
- if ( delta )
- {
- last_amp = amp;
- synth.offset( time, delta, output );
- }
- }
-
- time += delay;
- if ( !volume )
- time = end_time;
-
- if ( time < end_time )
- {
- Blip_Buffer* const output = this->output;
- unsigned shifter = this->shifter;
- int delta = amp * 2;
- int period = *this->period * 2;
- if ( !period )
- period = 16;
-
- do
- {
- int changed = shifter + 1;
- shifter = (feedback & -(shifter & 1)) ^ (shifter >> 1);
- if ( changed & 2 ) // true if bits 0 and 1 differ
- {
- delta = -delta;
- synth.offset_inline( time, delta, output );
- }
- time += period;
- }
- while ( time < end_time );
-
- this->shifter = shifter;
- this->last_amp = delta >> 1;
- }
- delay = time - end_time;
-}
-
-// Sms_Apu
-
-Sms_Apu::Sms_Apu()
-{
- for ( int i = 0; i < 3; i++ )
- {
- squares [i].synth = &square_synth;
- oscs [i] = &squares [i];
- }
- oscs [3] = &noise;
-
- volume( 1.0 );
- reset();
-}
-
-Sms_Apu::~Sms_Apu()
-{
-}
-
-void Sms_Apu::volume( double vol )
-{
- vol *= 0.85 / (osc_count * 64 * 2);
- square_synth.volume( vol );
- noise.synth.volume( vol );
-}
-
-void Sms_Apu::treble_eq( const blip_eq_t& eq )
-{
- square_synth.treble_eq( eq );
- noise.synth.treble_eq( eq );
-}
-
-void Sms_Apu::osc_output( int index, Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right )
-{
- require( (unsigned) index < osc_count );
- require( (center && left && right) || (!center && !left && !right) );
- Sms_Osc& osc = *oscs [index];
- osc.outputs [1] = right;
- osc.outputs [2] = left;
- osc.outputs [3] = center;
- osc.output = osc.outputs [osc.output_select];
-}
-
-void Sms_Apu::output( Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right )
-{
- for ( int i = 0; i < osc_count; i++ )
- osc_output( i, center, left, right );
-}
-
-void Sms_Apu::reset( unsigned feedback, int noise_width )
-{
- last_time = 0;
- latch = 0;
-
- if ( !feedback || !noise_width )
- {
- feedback = 0x0009;
- noise_width = 16;
- }
- // convert to "Galios configuration"
- looped_feedback = 1 << (noise_width - 1);
- noise_feedback = 0;
- while ( noise_width-- )
- {
- noise_feedback = (noise_feedback << 1) | (feedback & 1);
- feedback >>= 1;
- }
-
- squares [0].reset();
- squares [1].reset();
- squares [2].reset();
- noise.reset();
-}
-
-void Sms_Apu::run_until( blip_time_t end_time )
-{
- require( end_time >= last_time ); // end_time must not be before previous time
-
- if ( end_time > last_time )
- {
- // run oscillators
- for ( int i = 0; i < osc_count; ++i )
- {
- Sms_Osc& osc = *oscs [i];
- if ( osc.output )
- {
- osc.output->set_modified();
- if ( i < 3 )
- squares [i].run( last_time, end_time );
- else
- noise.run( last_time, end_time );
- }
- }
-
- last_time = end_time;
- }
-}
-
-void Sms_Apu::end_frame( blip_time_t end_time )
-{
- if ( end_time > last_time )
- run_until( end_time );
-
- assert( last_time >= end_time );
- last_time -= end_time;
-}
-
-void Sms_Apu::write_ggstereo( blip_time_t time, int data )
-{
- require( (unsigned) data <= 0xFF );
-
- run_until( time );
-
- for ( int i = 0; i < osc_count; i++ )
- {
- Sms_Osc& osc = *oscs [i];
- int flags = data >> i;
- Blip_Buffer* old_output = osc.output;
- osc.output_select = (flags >> 3 & 2) | (flags & 1);
- osc.output = osc.outputs [osc.output_select];
- if ( osc.output != old_output && osc.last_amp )
- {
- if ( old_output )
- {
- old_output->set_modified();
- square_synth.offset( time, -osc.last_amp, old_output );
- }
- osc.last_amp = 0;
- }
- }
-}
-
-// volumes [i] = 64 * pow( 1.26, 15 - i ) / pow( 1.26, 15 )
-static unsigned char const volumes [16] = {
- 64, 50, 39, 31, 24, 19, 15, 12, 9, 7, 5, 4, 3, 2, 1, 0
-};
-
-void Sms_Apu::write_data( blip_time_t time, int data )
-{
- require( (unsigned) data <= 0xFF );
-
- run_until( time );
-
- if ( data & 0x80 )
- latch = data;
-
- int index = (latch >> 5) & 3;
- if ( latch & 0x10 )
- {
- oscs [index]->volume = volumes [data & 15];
- }
- else if ( index < 3 )
- {
- Sms_Square& sq = squares [index];
- if ( data & 0x80 )
- sq.period = (sq.period & 0xFF00) | (data << 4 & 0x00FF);
- else
- sq.period = (sq.period & 0x00FF) | (data << 8 & 0x3F00);
- }
- else
- {
- int select = data & 3;
- if ( select < 3 )
- noise.period = &noise_periods [select];
- else
- noise.period = &squares [2].period;
-
- noise.feedback = (data & 0x04) ? noise_feedback : looped_feedback;
- noise.shifter = 0x8000;
- }
-}
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Sms_Apu.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/Sms_Apu.h
deleted file mode 100644
index 3c11a9c3..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Sms_Apu.h
+++ /dev/null
@@ -1,75 +0,0 @@
-// Sega Master System SN76489 PSG sound chip emulator
-
-// Sms_Snd_Emu 0.1.4
-#ifndef SMS_APU_H
-#define SMS_APU_H
-
-#include "Sms_Oscs.h"
-
-class Sms_Apu {
-public:
- // Set overall volume of all oscillators, where 1.0 is full volume
- void volume( double );
-
- // Set treble equalization
- void treble_eq( const blip_eq_t& );
-
- // Outputs can be assigned to a single buffer for mono output, or to three
- // buffers for stereo output (using Stereo_Buffer to do the mixing).
-
- // Assign all oscillator outputs to specified buffer(s). If buffer
- // is NULL, silences all oscillators.
- void output( Blip_Buffer* mono );
- void output( Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right );
-
- // Assign single oscillator output to buffer(s). Valid indicies are 0 to 3,
- // which refer to Square 1, Square 2, Square 3, and Noise. If buffer is NULL,
- // silences oscillator.
- enum { osc_count = 4 };
- void osc_output( int index, Blip_Buffer* mono );
- void osc_output( int index, Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right );
-
- // Reset oscillators and internal state
- void reset( unsigned noise_feedback = 0, int noise_width = 0 );
-
- // Write GameGear left/right assignment byte
- void write_ggstereo( blip_time_t, int );
-
- // Write to data port
- void write_data( blip_time_t, int );
-
- // Run all oscillators up to specified time, end current frame, then
- // start a new frame at time 0.
- void end_frame( blip_time_t );
-
-public:
- Sms_Apu();
- ~Sms_Apu();
-private:
- // noncopyable
- Sms_Apu( const Sms_Apu& );
- Sms_Apu& operator = ( const Sms_Apu& );
-
- Sms_Osc* oscs [osc_count];
- Sms_Square squares [3];
- Sms_Square::Synth square_synth; // used by squares
- blip_time_t last_time;
- int latch;
- Sms_Noise noise;
- unsigned noise_feedback;
- unsigned looped_feedback;
-
- void run_until( blip_time_t );
-};
-
-struct sms_apu_state_t
-{
- unsigned char regs [8] [2];
- unsigned char latch;
-};
-
-inline void Sms_Apu::output( Blip_Buffer* b ) { output( b, b, b ); }
-
-inline void Sms_Apu::osc_output( int i, Blip_Buffer* b ) { osc_output( i, b, b, b ); }
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Sms_Oscs.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/Sms_Oscs.h
deleted file mode 100644
index 2a896fef..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Sms_Oscs.h
+++ /dev/null
@@ -1,49 +0,0 @@
-// Private oscillators used by Sms_Apu
-
-// Sms_Snd_Emu 0.1.4
-#ifndef SMS_OSCS_H
-#define SMS_OSCS_H
-
-#include "blargg_common.h"
-#include "Blip_Buffer.h"
-
-struct Sms_Osc
-{
- Blip_Buffer* outputs [4]; // NULL, right, left, center
- Blip_Buffer* output;
- int output_select;
-
- int delay;
- int last_amp;
- int volume;
-
- Sms_Osc();
- void reset();
-};
-
-struct Sms_Square : Sms_Osc
-{
- int period;
- int phase;
-
- typedef Blip_Synth<blip_good_quality,1> Synth;
- const Synth* synth;
-
- void reset();
- void run( blip_time_t, blip_time_t );
-};
-
-struct Sms_Noise : Sms_Osc
-{
- const int* period;
- unsigned shifter;
- unsigned feedback;
-
- typedef Blip_Synth<blip_med_quality,1> Synth;
- Synth synth;
-
- void reset();
- void run( blip_time_t, blip_time_t );
-};
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Snes_Spc.cpp b/plugins/gme/Game_Music_Emu-0.5.2/gme/Snes_Spc.cpp
deleted file mode 100644
index e909ea18..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Snes_Spc.cpp
+++ /dev/null
@@ -1,489 +0,0 @@
-// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
-
-#include "Snes_Spc.h"
-
-#include <string.h>
-
-/* Copyright (C) 2004-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-// always in the future (CPU time can go over 0, but not by this much)
-int const timer_disabled_time = 127;
-
-Snes_Spc::Snes_Spc() : dsp( mem.ram ), cpu( this, mem.ram )
-{
- set_tempo( 1.0 );
-
- // Put STOP instruction around memory to catch PC underflow/overflow.
- memset( mem.padding1, 0xFF, sizeof mem.padding1 );
- memset( mem.padding2, 0xFF, sizeof mem.padding2 );
-
- // A few tracks read from the last four bytes of IPL ROM
- boot_rom [sizeof boot_rom - 2] = 0xC0;
- boot_rom [sizeof boot_rom - 1] = 0xFF;
- memset( boot_rom, 0, sizeof boot_rom - 2 );
-}
-
-void Snes_Spc::set_tempo( double t )
-{
- int unit = (int) (16.0 / t + 0.5);
-
- timer [0].divisor = unit * 8; // 8 kHz
- timer [1].divisor = unit * 8; // 8 kHz
- timer [2].divisor = unit; // 64 kHz
-}
-
-// Load
-
-void Snes_Spc::set_ipl_rom( void const* in )
-{
- memcpy( boot_rom, in, sizeof boot_rom );
-}
-
-blargg_err_t Snes_Spc::load_spc( const void* data, long size )
-{
- struct spc_file_t {
- char signature [27];
- char unused [10];
- uint8_t pc [2];
- uint8_t a;
- uint8_t x;
- uint8_t y;
- uint8_t status;
- uint8_t sp;
- char unused2 [212];
- uint8_t ram [0x10000];
- uint8_t dsp [128];
- uint8_t ipl_rom [128];
- };
- assert( offsetof (spc_file_t,ipl_rom) == spc_file_size );
-
- const spc_file_t* spc = (spc_file_t const*) data;
-
- if ( size < spc_file_size )
- return "Not an SPC file";
-
- if ( strncmp( spc->signature, "SNES-SPC700 Sound File Data", 27 ) != 0 )
- return "Not an SPC file";
-
- registers_t regs;
- regs.pc = spc->pc [1] * 0x100 + spc->pc [0];
- regs.a = spc->a;
- regs.x = spc->x;
- regs.y = spc->y;
- regs.status = spc->status;
- regs.sp = spc->sp;
-
- if ( (unsigned long) size >= sizeof *spc )
- set_ipl_rom( spc->ipl_rom );
-
- const char* error = load_state( regs, spc->ram, spc->dsp );
-
- echo_accessed = false;
-
- return error;
-}
-
-void Snes_Spc::clear_echo()
-{
- if ( !(dsp.read( 0x6C ) & 0x20) )
- {
- unsigned addr = 0x100 * dsp.read( 0x6D );
- size_t size = 0x800 * dsp.read( 0x7D );
- memset( mem.ram + addr, 0xFF, min( size, sizeof mem.ram - addr ) );
- }
-}
-
-// Handle other file formats (emulator save states) in user code, not here.
-
-blargg_err_t Snes_Spc::load_state( const registers_t& cpu_state, const void* new_ram,
- const void* dsp_state )
-{
- // cpu
- cpu.r = cpu_state;
-
- // Allow DSP to generate one sample before code starts
- // (Tengai Makyo Zero, Tenjin's Table Toss first notes are lost since it
- // clears KON 31 cycles from starting execution. It works on the SNES
- // since the SPC player adds a few extra cycles delay after restoring
- // KON from the DSP registers at the end of an SPC file).
- extra_cycles = 32;
-
- // ram
- memcpy( mem.ram, new_ram, sizeof mem.ram );
- memcpy( extra_ram, mem.ram + rom_addr, sizeof extra_ram );
-
- // boot rom (have to force enable_rom() to update it)
- rom_enabled = !(mem.ram [0xF1] & 0x80);
- enable_rom( !rom_enabled );
-
- // dsp
- dsp.reset();
- int i;
- for ( i = 0; i < Spc_Dsp::register_count; i++ )
- dsp.write( i, ((uint8_t const*) dsp_state) [i] );
-
- // timers
- for ( i = 0; i < timer_count; i++ )
- {
- Timer& t = timer [i];
-
- t.next_tick = 0;
- t.enabled = (mem.ram [0xF1] >> i) & 1;
- if ( !t.enabled )
- t.next_tick = timer_disabled_time;
- t.count = 0;
- t.counter = mem.ram [0xFD + i] & 15;
-
- int p = mem.ram [0xFA + i];
- t.period = p ? p : 0x100;
- }
-
- // Handle registers which already give 0 when read by setting RAM and not changing it.
- // Put STOP instruction in registers which can be read, to catch attempted CPU execution.
- mem.ram [0xF0] = 0;
- mem.ram [0xF1] = 0;
- mem.ram [0xF3] = 0xFF;
- mem.ram [0xFA] = 0;
- mem.ram [0xFB] = 0;
- mem.ram [0xFC] = 0;
- mem.ram [0xFD] = 0xFF;
- mem.ram [0xFE] = 0xFF;
- mem.ram [0xFF] = 0xFF;
-
- return 0; // success
-}
-
-// Hardware
-
-// Current time starts negative and ends at 0
-inline spc_time_t Snes_Spc::time() const
-{
- return -cpu.remain();
-}
-
-// Keep track of next time to run and avoid a function call if it hasn't been reached.
-
-// Timers
-
-void Snes_Spc::Timer::run_until_( spc_time_t time )
-{
- if ( !enabled )
- dprintf( "next_tick: %ld, time: %ld", (long) next_tick, (long) time );
- assert( enabled ); // when disabled, next_tick should always be in the future
-
- int elapsed = ((time - next_tick) / divisor) + 1;
- next_tick += elapsed * divisor;
-
- elapsed += count;
- if ( elapsed >= period ) // avoid unnecessary division
- {
- int n = elapsed / period;
- elapsed -= n * period;
- counter = (counter + n) & 15;
- }
- count = elapsed;
-}
-
-// DSP
-
-const int clocks_per_sample = 32; // 1.024 MHz CPU clock / 32000 samples per second
-
-void Snes_Spc::run_dsp_( spc_time_t time )
-{
- int count = ((time - next_dsp) >> 5) + 1; // divide by clocks_per_sample
- sample_t* buf = sample_buf;
- if ( buf ) {
- sample_buf = buf + count * 2; // stereo
- assert( sample_buf <= buf_end );
- }
- next_dsp += count * clocks_per_sample;
- dsp.run( count, buf );
-}
-
-inline void Snes_Spc::run_dsp( spc_time_t time )
-{
- if ( time >= next_dsp )
- run_dsp_( time );
-}
-
-// Debug-only check for read/write within echo buffer, since this might result in
-// inaccurate emulation due to the DSP not being caught up to the present.
-inline void Snes_Spc::check_for_echo_access( spc_addr_t addr )
-{
- if ( !echo_accessed && !(dsp.read( 0x6C ) & 0x20) )
- {
- // ** If echo accesses are found that require running the DSP, cache
- // the start and end address on DSP writes to speed up checking.
-
- unsigned start = 0x100 * dsp.read( 0x6D );
- unsigned end = start + 0x800 * dsp.read( 0x7D );
- if ( start <= addr && addr < end ) {
- echo_accessed = true;
- dprintf( "Read/write at $%04X within echo buffer\n", (unsigned) addr );
- }
- }
-}
-
-// Read
-
-int Snes_Spc::read( spc_addr_t addr )
-{
- int result = mem.ram [addr];
-
- if ( (rom_addr <= addr && addr < 0xFFFC || addr >= 0xFFFE) && rom_enabled )
- dprintf( "Read from ROM: %04X -> %02X\n", addr, result );
-
- if ( unsigned (addr - 0xF0) < 0x10 )
- {
- assert( 0xF0 <= addr && addr <= 0xFF );
-
- // counters
- int i = addr - 0xFD;
- if ( i >= 0 )
- {
- Timer& t = timer [i];
- t.run_until( time() );
- int old = t.counter;
- t.counter = 0;
- return old;
- }
-
- // dsp
- if ( addr == 0xF3 )
- {
- run_dsp( time() );
- if ( mem.ram [0xF2] >= Spc_Dsp::register_count )
- dprintf( "DSP read from $%02X\n", (int) mem.ram [0xF2] );
- return dsp.read( mem.ram [0xF2] & 0x7F );
- }
-
- if ( addr == 0xF0 || addr == 0xF1 || addr == 0xF8 ||
- addr == 0xF9 || addr == 0xFA )
- dprintf( "Read from register $%02X\n", (int) addr );
-
- // Registers which always read as 0 are handled by setting mem.ram [reg] to 0
- // at startup then never changing that value.
-
- check(( check_for_echo_access( addr ), true ));
- }
-
- return result;
-}
-
-
-// Write
-
-void Snes_Spc::enable_rom( bool enable )
-{
- if ( rom_enabled != enable )
- {
- rom_enabled = enable;
- memcpy( mem.ram + rom_addr, (enable ? boot_rom : extra_ram), rom_size );
- // TODO: ROM can still get overwritten when DSP writes to echo buffer
- }
-}
-
-void Snes_Spc::write( spc_addr_t addr, int data )
-{
- // first page is very common
- if ( addr < 0xF0 ) {
- mem.ram [addr] = (uint8_t) data;
- }
- else switch ( addr )
- {
- // RAM
- default:
- check(( check_for_echo_access( addr ), true ));
- if ( addr < rom_addr ) {
- mem.ram [addr] = (uint8_t) data;
- }
- else {
- extra_ram [addr - rom_addr] = (uint8_t) data;
- if ( !rom_enabled )
- mem.ram [addr] = (uint8_t) data;
- }
- break;
-
- // DSP
- //case 0xF2: // mapped to RAM
- case 0xF3: {
- run_dsp( time() );
- int reg = mem.ram [0xF2];
- if ( next_dsp > 0 ) {
- // skip mode
-
- // key press
- if ( reg == 0x4C )
- keys_pressed |= data & ~dsp.read( 0x5C );
-
- // key release
- if ( reg == 0x5C ) {
- keys_released |= data;
- keys_pressed &= ~data;
- }
- }
- if ( reg < Spc_Dsp::register_count ) {
- dsp.write( reg, data );
- }
- else {
- dprintf( "DSP write to $%02X\n", (int) reg );
- }
- break;
- }
-
- case 0xF0: // Test register
- dprintf( "Wrote $%02X to $F0\n", (int) data );
- break;
-
- // Config
- case 0xF1:
- {
- // timers
- for ( int i = 0; i < timer_count; i++ )
- {
- Timer& t = timer [i];
- if ( !(data & (1 << i)) ) {
- t.enabled = 0;
- t.next_tick = timer_disabled_time;
- }
- else if ( !t.enabled ) {
- // just enabled
- t.enabled = 1;
- t.counter = 0;
- t.count = 0;
- t.next_tick = time();
- }
- }
-
- // port clears
- if ( data & 0x10 ) {
- mem.ram [0xF4] = 0;
- mem.ram [0xF5] = 0;
- }
- if ( data & 0x20 ) {
- mem.ram [0xF6] = 0;
- mem.ram [0xF7] = 0;
- }
-
- enable_rom( (data & 0x80) != 0 );
-
- break;
- }
-
- // Ports
- case 0xF4:
- case 0xF5:
- case 0xF6:
- case 0xF7:
- // to do: handle output ports
- break;
-
- //case 0xF8: // verified on SNES that these are read/write (RAM)
- //case 0xF9:
-
- // Timers
- case 0xFA:
- case 0xFB:
- case 0xFC: {
- Timer& t = timer [addr - 0xFA];
- if ( (t.period & 0xFF) != data ) {
- t.run_until( time() );
- t.period = data ? data : 0x100;
- }
- break;
- }
-
- // Counters (cleared on write)
- case 0xFD:
- case 0xFE:
- case 0xFF:
- dprintf( "Wrote to counter $%02X\n", (int) addr );
- timer [addr - 0xFD].counter = 0;
- break;
- }
-}
-
-// Play
-
-blargg_err_t Snes_Spc::skip( long count )
-{
- if ( count > 4 * 32000L )
- {
- // don't run DSP for long durations (2-3 times faster)
-
- const long sync_count = 32000L * 2;
-
- // keep track of any keys pressed/released (and not subsequently released)
- keys_pressed = 0;
- keys_released = 0;
- // sentinel tells play to ignore DSP
- RETURN_ERR( play( count - sync_count, skip_sentinel ) );
-
- // press/release keys now
- dsp.write( 0x5C, keys_released & ~keys_pressed );
- dsp.write( 0x4C, keys_pressed );
-
- clear_echo();
-
- // play the last few seconds normally to help synchronize DSP
- count = sync_count;
- }
-
- return play( count );
-}
-
-blargg_err_t Snes_Spc::play( long count, sample_t* out )
-{
- require( count % 2 == 0 ); // output is always in pairs of samples
-
- // CPU time() runs from -duration to 0
- spc_time_t duration = (count / 2) * clocks_per_sample;
-
- // DSP output is made on-the-fly when the CPU reads/writes DSP registers
- sample_buf = out;
- buf_end = out + (out && out != skip_sentinel ? count : 0);
- next_dsp = (out == skip_sentinel) ? clocks_per_sample : -duration + clocks_per_sample;
-
- // Localize timer next_tick times and run them to the present to prevent a running
- // but ignored timer's next_tick from getting too far behind and overflowing.
- for ( int i = 0; i < timer_count; i++ )
- {
- Timer& t = timer [i];
- if ( t.enabled )
- {
- t.next_tick -= duration;
- t.run_until( -duration );
- }
- }
-
- // Run CPU for duration, reduced by any extra cycles from previous run
- int elapsed = cpu.run( duration - extra_cycles );
- if ( elapsed > 0 )
- {
- dprintf( "Unhandled instruction $%02X, pc = $%04X\n",
- (int) cpu.read( cpu.r.pc ), (unsigned) cpu.r.pc );
- return "Emulation error (illegal/unsupported instruction)";
- }
- extra_cycles = -elapsed;
-
- // Catch DSP up to present.
- run_dsp( 0 );
- if ( out ) {
- assert( next_dsp == clocks_per_sample );
- assert( out == skip_sentinel || sample_buf - out == count );
- }
- buf_end = 0;
-
- return 0;
-}
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Snes_Spc.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/Snes_Spc.h
deleted file mode 100644
index b558fb71..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Snes_Spc.h
+++ /dev/null
@@ -1,121 +0,0 @@
-// Super Nintendo (SNES) SPC-700 APU Emulator
-
-// Game_Music_Emu 0.5.2
-#ifndef SNES_SPC_H
-#define SNES_SPC_H
-
-#include "blargg_common.h"
-#include "Spc_Cpu.h"
-#include "Spc_Dsp.h"
-
-class Snes_Spc {
-public:
-
- // Load copy of SPC data into emulator. Clear echo buffer if 'clear_echo' is true.
- enum { spc_file_size = 0x10180 };
- blargg_err_t load_spc( const void* spc, long spc_size );
-
- // Generate 'count' samples and optionally write to 'buf'. Count must be even.
- // Sample output is 16-bit 32kHz, signed stereo pairs with the left channel first.
- typedef short sample_t;
- blargg_err_t play( long count, sample_t* buf = NULL );
-
-// Optional functionality
-
- // Load copy of state into emulator.
- typedef Spc_Cpu::registers_t registers_t;
- blargg_err_t load_state( const registers_t& cpu_state, const void* ram_64k,
- const void* dsp_regs_128 );
-
- // Clear echo buffer, useful because many tracks have junk in the buffer.
- void clear_echo();
-
- // Mute voice n if bit n (1 << n) of mask is set
- enum { voice_count = Spc_Dsp::voice_count };
- void mute_voices( int mask );
-
- // Skip forward by the specified number of samples (64000 samples = 1 second)
- blargg_err_t skip( long count );
-
- // Set gain, where 1.0 is normal. When greater than 1.0, output is clamped the
- // 16-bit sample range.
- void set_gain( double );
-
- // If true, prevent channels and global volumes from being phase-negated
- void disable_surround( bool disable = true );
-
- // Set 128 bytes to use for IPL boot ROM. Makes copy. Default is zero filled,
- // to avoid including copyrighted code from the SPC-700.
- void set_ipl_rom( const void* );
-
- void set_tempo( double );
-
-public:
- Snes_Spc();
- typedef BOOST::uint8_t uint8_t;
-private:
- // timers
- struct Timer
- {
- spc_time_t next_tick;
- int period;
- int count;
- int divisor;
- int enabled;
- int counter;
-
- void run_until_( spc_time_t );
- void run_until( spc_time_t time )
- {
- if ( time >= next_tick )
- run_until_( time );
- }
- };
- enum { timer_count = 3 };
- Timer timer [timer_count];
-
- // hardware
- int extra_cycles;
- spc_time_t time() const;
- int read( spc_addr_t );
- void write( spc_addr_t, int );
- friend class Spc_Cpu;
-
- // dsp
- sample_t* sample_buf;
- sample_t* buf_end; // to do: remove this once possible bug resolved
- spc_time_t next_dsp;
- Spc_Dsp dsp;
- int keys_pressed;
- int keys_released;
- sample_t skip_sentinel [1]; // special value for play() passed by skip()
- void run_dsp( spc_time_t );
- void run_dsp_( spc_time_t );
- bool echo_accessed;
- void check_for_echo_access( spc_addr_t );
-
- // boot rom
- enum { rom_size = 64 };
- enum { rom_addr = 0xFFC0 };
- bool rom_enabled;
- void enable_rom( bool );
-
- // CPU and RAM (at end because it's large)
- Spc_Cpu cpu;
- uint8_t extra_ram [rom_size];
- struct {
- // padding to catch jumps before beginning or past end
- uint8_t padding1 [0x100];
- uint8_t ram [0x10000];
- uint8_t padding2 [0x100];
- } mem;
- uint8_t boot_rom [rom_size];
-};
-
-inline void Snes_Spc::disable_surround( bool disable ) { dsp.disable_surround( disable ); }
-
-inline void Snes_Spc::mute_voices( int mask ) { dsp.mute_voices( mask ); }
-
-inline void Snes_Spc::set_gain( double v ) { dsp.set_gain( v ); }
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Spc_Cpu.cpp b/plugins/gme/Game_Music_Emu-0.5.2/gme/Spc_Cpu.cpp
deleted file mode 100644
index fb9983b8..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Spc_Cpu.cpp
+++ /dev/null
@@ -1,1062 +0,0 @@
-// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
-
-#include "Spc_Cpu.h"
-
-#include "blargg_endian.h"
-#include "Snes_Spc.h"
-
-/* Copyright (C) 2004-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-// Several instructions are commented out (or not even implemented). These aren't
-// used by the SPC files tested.
-
-// Optimize performance for the most common instructions, and size for the rest:
-//
-// 15% 0xF0 BEQ rel
-// 8% 0xE4 MOV A,dp
-// 4% 0xF5 MOV A,abs+X
-// 4% 0xD0 BNE rel
-// 4% 0x6F RET
-// 4% 0x3F CALL addr
-// 4% 0xF4 MOV A,dp+X
-// 3% 0xC4 MOV dp,A
-// 2% 0xEB MOV Y,dp
-// 2% 0x3D INC X
-// 2% 0xF6 MOV A,abs+Y
-// (1% and below not shown)
-
-Spc_Cpu::Spc_Cpu( Snes_Spc* e, uint8_t* ram_in ) : ram( ram_in ), emu( *e )
-{
- remain_ = 0;
- assert( INT_MAX >= 0x7FFFFFFF ); // requires 32-bit int
- blargg_verify_byte_order();
-}
-
-#define READ( addr ) (emu.read( addr ))
-#define WRITE( addr, value ) (emu.write( addr, value ))
-
-#define READ_DP( addr ) READ( (addr) + dp )
-#define WRITE_DP( addr, value ) WRITE( (addr) + dp, value )
-
-#define READ_PROG( addr ) (ram [addr])
-#define READ_PROG16( addr ) GET_LE16( &READ_PROG( addr ) )
-
-int Spc_Cpu::read( spc_addr_t addr )
-{
- return READ( addr );
-}
-
-void Spc_Cpu::write( spc_addr_t addr, int data )
-{
- WRITE( addr, data );
-}
-
-// Cycle table derived from text copy of SPC-700 manual (using regular expressions)
-static unsigned char const cycle_table [0x100] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 2,8,4,5,3,4,3,6,2,6,5,4,5,4,6,8, // 0
- 2,8,4,5,4,5,5,6,5,5,6,5,2,2,4,6, // 1
- 2,8,4,5,3,4,3,6,2,6,5,4,5,4,5,4, // 2
- 2,8,4,5,4,5,5,6,5,5,6,5,2,2,3,8, // 3
- 2,8,4,5,3,4,3,6,2,6,4,4,5,4,6,6, // 4
- 2,8,4,5,4,5,5,6,5,5,4,5,2,2,4,3, // 5
- 2,8,4,5,3,4,3,6,2,6,4,4,5,4,5,5, // 6
- 2,8,4,5,4,5,5,6,5,5,5,5,2,2,3,6, // 7
- 2,8,4,5,3,4,3,6,2,6,5,4,5,2,4,5, // 8
- 2,8,4,5,4,5,5,6,5,5,5,5,2,2,12,5,// 9
- 3,8,4,5,3,4,3,6,2,6,4,4,5,2,4,4, // A
- 2,8,4,5,4,5,5,6,5,5,5,5,2,2,3,4, // B
- 3,8,4,5,4,5,4,7,2,5,6,4,5,2,4,9, // C
- 2,8,4,5,5,6,6,7,4,5,4,5,2,2,6,3, // D
- 2,8,4,5,3,4,3,6,2,4,5,3,4,3,4,3, // E
- 2,8,4,5,4,5,5,6,3,4,5,4,2,2,4,3 // F
-};
-
-// The C,mem instructions are hardly used, so a non-inline function is used for
-// the common access code.
-unsigned Spc_Cpu::mem_bit( spc_addr_t pc )
-{
- unsigned addr = READ_PROG16( pc );
- unsigned t = READ( addr & 0x1FFF ) >> (addr >> 13);
- return (t << 8) & 0x100;
-}
-
-spc_time_t Spc_Cpu::run( spc_time_t cycle_count )
-{
- remain_ = cycle_count;
-
- uint8_t* const ram = this->ram; // cache
-
- // Stack pointer is kept one greater than usual SPC stack pointer to allow
- // common pre-decrement and post-increment memory instructions that some
- // processors have. Address wrap-around isn't supported.
- #define PUSH( v ) (*--sp = uint8_t (v))
- #define PUSH16( v ) (sp -= 2, SET_LE16( sp, v ))
- #define POP() (*sp++)
- #define SET_SP( v ) (sp = ram + 0x101 + (v))
- #define GET_SP() (sp - 0x101 - ram)
-
- uint8_t* sp;
- SET_SP( r.sp );
-
- // registers
- unsigned pc = (unsigned) r.pc;
- int a = r.a;
- int x = r.x;
- int y = r.y;
-
- // status flags
-
- const int st_n = 0x80;
- const int st_v = 0x40;
- const int st_p = 0x20;
- const int st_b = 0x10;
- const int st_h = 0x08;
- const int st_i = 0x04;
- const int st_z = 0x02;
- const int st_c = 0x01;
-
- #define IS_NEG (nz & 0x880)
-
- #define CALC_STATUS( out ) do {\
- out = status & ~(st_n | st_z | st_c);\
- out |= (c >> 8) & st_c;\
- out |= (dp >> 3) & st_p;\
- if ( IS_NEG ) out |= st_n;\
- if ( !(nz & 0xFF) ) out |= st_z;\
- } while ( 0 )
-
- #define SET_STATUS( in ) do {\
- status = in & ~(st_n | st_z | st_c | st_p);\
- c = in << 8;\
- nz = (in << 4) & 0x800;\
- nz |= ~in & st_z;\
- dp = (in << 3) & 0x100;\
- } while ( 0 )
-
- int status;
- int c; // store C as 'c' & 0x100.
- int nz; // Z set if (nz & 0xFF) == 0, N set if (nz & 0x880) != 0
- unsigned dp; // direct page base
- {
- int temp = r.status;
- SET_STATUS( temp );
- }
-
- goto loop;
-
- unsigned data; // first operand of instruction and temporary across function calls
-
- // Common endings for instructions
-cbranch_taken_loop: // compare and branch
- pc += (BOOST::int8_t) READ_PROG( pc );
- remain_ -= 2;
-inc_pc_loop: // end of instruction with an operand
- pc++;
-loop:
-
- check( (unsigned) pc < 0x10000 );
- check( (unsigned) GET_SP() < 0x100 );
-
- check( (unsigned) a < 0x100 );
- check( (unsigned) x < 0x100 );
- check( (unsigned) y < 0x100 );
-
- unsigned opcode = READ_PROG( pc );
- pc++;
- // to do: if pc is at end of memory, this will get wrong byte
- data = READ_PROG( pc );
-
- if ( remain_ <= 0 )
- goto stop;
-
- remain_ -= cycle_table [opcode];
-
- // Use 'data' for temporaries whose lifetime crosses read/write calls, otherwise
- // use a local temporary.
- switch ( opcode )
- {
-
- #define BRANCH( cond ) {\
- pc++;\
- int offset = (BOOST::int8_t) data;\
- if ( cond ) {\
- pc += offset;\
- remain_ -= 2;\
- }\
- goto loop;\
- }
-
-// Most-Common
-
- case 0xF0: // BEQ (most common)
- BRANCH( !(uint8_t) nz )
-
- case 0xD0: // BNE
- BRANCH( (uint8_t) nz )
-
- case 0x3F: // CALL
- PUSH16( pc + 2 );
- pc = READ_PROG16( pc );
- goto loop;
-
- case 0x6F: // RET
- pc = POP();
- pc += POP() * 0x100;
- goto loop;
-
-#define CASE( n ) case n:
-
-// Define common address modes based on opcode for immediate mode. Execution
-// ends with data set to the address of the operand.
-#define ADDR_MODES( op )\
- CASE( op - 0x02 ) /* (X) */\
- data = x + dp;\
- pc--;\
- goto end_##op;\
- CASE( op + 0x0F ) /* (dp)+Y */\
- data = READ_PROG16( data + dp ) + y;\
- goto end_##op;\
- CASE( op - 0x01 ) /* (dp+X) */\
- data = READ_PROG16( uint8_t (data + x) + dp );\
- goto end_##op;\
- CASE( op + 0x0E ) /* abs+Y */\
- data += y;\
- goto abs_##op;\
- CASE( op + 0x0D ) /* abs+X */\
- data += x;\
- CASE( op - 0x03 ) /* abs */\
- abs_##op:\
- pc++;\
- data += 0x100 * READ_PROG( pc );\
- goto end_##op;\
- CASE( op + 0x0C ) /* dp+X */\
- data = uint8_t (data + x);\
- CASE( op - 0x04 ) /* dp */\
- data += dp;\
- end_##op:
-
-// 1. 8-bit Data Transmission Commands. Group I
-
- ADDR_MODES( 0xE8 ) // MOV A,addr
- // case 0xE4: // MOV a,dp (most common)
- mov_a_addr:
- a = nz = READ( data );
- goto inc_pc_loop;
- case 0xBF: // MOV A,(X)+
- data = x + dp;
- x = uint8_t (x + 1);
- pc--;
- goto mov_a_addr;
-
- case 0xE8: // MOV A,imm
- a = data;
- nz = data;
- goto inc_pc_loop;
-
- case 0xF9: // MOV X,dp+Y
- data = uint8_t (data + y);
- case 0xF8: // MOV X,dp
- data += dp;
- goto mov_x_addr;
- case 0xE9: // MOV X,abs
- data = READ_PROG16( pc );
- pc++;
- mov_x_addr:
- data = READ( data );
- case 0xCD: // MOV X,imm
- x = data;
- nz = data;
- goto inc_pc_loop;
-
- case 0xFB: // MOV Y,dp+X
- data = uint8_t (data + x);
- case 0xEB: // MOV Y,dp
- data += dp;
- goto mov_y_addr;
- case 0xEC: // MOV Y,abs
- data = READ_PROG16( pc );
- pc++;
- mov_y_addr:
- data = READ( data );
- case 0x8D: // MOV Y,imm
- y = data;
- nz = data;
- goto inc_pc_loop;
-
-// 2. 8-BIT DATA TRANSMISSION COMMANDS, GROUP 2
-
- ADDR_MODES( 0xC8 ) // MOV addr,A
- WRITE( data, a );
- goto inc_pc_loop;
-
- {
- int temp;
- case 0xCC: // MOV abs,Y
- temp = y;
- goto mov_abs_temp;
- case 0xC9: // MOV abs,X
- temp = x;
- mov_abs_temp:
- WRITE( READ_PROG16( pc ), temp );
- pc += 2;
- goto loop;
- }
-
- case 0xD9: // MOV dp+Y,X
- data = uint8_t (data + y);
- case 0xD8: // MOV dp,X
- WRITE( data + dp, x );
- goto inc_pc_loop;
-
- case 0xDB: // MOV dp+X,Y
- data = uint8_t (data + x);
- case 0xCB: // MOV dp,Y
- WRITE( data + dp, y );
- goto inc_pc_loop;
-
- case 0xFA: // MOV dp,dp
- data = READ( data + dp );
- case 0x8F: // MOV dp,#imm
- pc++;
- WRITE_DP( READ_PROG( pc ), data );
- goto inc_pc_loop;
-
-// 3. 8-BIT DATA TRANSMISSIN COMMANDS, GROUP 3.
-
- case 0x7D: // MOV A,X
- a = x;
- nz = x;
- goto loop;
-
- case 0xDD: // MOV A,Y
- a = y;
- nz = y;
- goto loop;
-
- case 0x5D: // MOV X,A
- x = a;
- nz = a;
- goto loop;
-
- case 0xFD: // MOV Y,A
- y = a;
- nz = a;
- goto loop;
-
- case 0x9D: // MOV X,SP
- x = nz = GET_SP();
- goto loop;
-
- case 0xBD: // MOV SP,X
- SET_SP( x );
- goto loop;
-
- //case 0xC6: // MOV (X),A (handled by MOV addr,A in group 2)
-
- case 0xAF: // MOV (X)+,A
- WRITE_DP( x, a );
- x++;
- goto loop;
-
-// 5. 8-BIT LOGIC OPERATION COMMANDS
-
-#define LOGICAL_OP( op, func )\
- ADDR_MODES( op ) /* addr */\
- data = READ( data );\
- case op: /* imm */\
- nz = a func##= data;\
- goto inc_pc_loop;\
- { unsigned addr;\
- case op + 0x11: /* X,Y */\
- data = READ_DP( y );\
- addr = x + dp;\
- pc--;\
- goto addr_##op;\
- case op + 0x01: /* dp,dp */\
- data = READ_DP( data );\
- case op + 0x10: /*dp,imm*/\
- pc++;\
- addr = READ_PROG( pc ) + dp;\
- addr_##op:\
- nz = data func READ( addr );\
- WRITE( addr, nz );\
- goto inc_pc_loop;\
- }
-
- LOGICAL_OP( 0x28, & ); // AND
-
- LOGICAL_OP( 0x08, | ); // OR
-
- LOGICAL_OP( 0x48, ^ ); // EOR
-
-// 4. 8-BIT ARITHMETIC OPERATION COMMANDS
-
- ADDR_MODES( 0x68 ) // CMP addr
- data = READ( data );
- case 0x68: // CMP imm
- nz = a - data;
- c = ~nz;
- nz &= 0xFF;
- goto inc_pc_loop;
-
- case 0x79: // CMP (X),(Y)
- data = READ_DP( x );
- nz = data - READ_DP( y );
- c = ~nz;
- nz &= 0xFF;
- goto loop;
-
- case 0x69: // CMP (dp),(dp)
- data = READ_DP( data );
- case 0x78: // CMP dp,imm
- pc++;
- nz = READ_DP( READ_PROG( pc ) ) - data;
- c = ~nz;
- nz &= 0xFF;
- goto inc_pc_loop;
-
- case 0x3E: // CMP X,dp
- data += dp;
- goto cmp_x_addr;
- case 0x1E: // CMP X,abs
- data = READ_PROG16( pc );
- pc++;
- cmp_x_addr:
- data = READ( data );
- case 0xC8: // CMP X,imm
- nz = x - data;
- c = ~nz;
- nz &= 0xFF;
- goto inc_pc_loop;
-
- case 0x7E: // CMP Y,dp
- data += dp;
- goto cmp_y_addr;
- case 0x5E: // CMP Y,abs
- data = READ_PROG16( pc );
- pc++;
- cmp_y_addr:
- data = READ( data );
- case 0xAD: // CMP Y,imm
- nz = y - data;
- c = ~nz;
- nz &= 0xFF;
- goto inc_pc_loop;
-
- {
- int addr;
- case 0xB9: // SBC (x),(y)
- case 0x99: // ADC (x),(y)
- pc--; // compensate for inc later
- data = READ_DP( x );
- addr = y + dp;
- goto adc_addr;
- case 0xA9: // SBC dp,dp
- case 0x89: // ADC dp,dp
- data = READ_DP( data );
- case 0xB8: // SBC dp,imm
- case 0x98: // ADC dp,imm
- pc++;
- addr = READ_PROG( pc ) + dp;
- adc_addr:
- nz = READ( addr );
- goto adc_data;
-
-// catch ADC and SBC together, then decode later based on operand
-#undef CASE
-#define CASE( n ) case n: case (n) + 0x20:
- ADDR_MODES( 0x88 ) // ADC/SBC addr
- data = READ( data );
- case 0xA8: // SBC imm
- case 0x88: // ADC imm
- addr = -1; // A
- nz = a;
- adc_data: {
- if ( opcode & 0x20 )
- data ^= 0xFF; // SBC
- int carry = (c >> 8) & 1;
- int ov = (nz ^ 0x80) + carry + (BOOST::int8_t) data; // sign-extend
- int hc = (nz & 15) + carry;
- c = nz += data + carry;
- hc = (nz & 15) - hc;
- status = (status & ~(st_v | st_h)) | ((ov >> 2) & st_v) | ((hc >> 1) & st_h);
- if ( addr < 0 ) {
- a = (uint8_t) nz;
- goto inc_pc_loop;
- }
- WRITE( addr, (uint8_t) nz );
- goto inc_pc_loop;
- }
-
- }
-
-// 6. ADDITION & SUBTRACTION COMMANDS
-
-#define INC_DEC_REG( reg, n )\
- nz = reg + n;\
- reg = (uint8_t) nz;\
- goto loop;
-
- case 0xBC: INC_DEC_REG( a, 1 ) // INC A
- case 0x3D: INC_DEC_REG( x, 1 ) // INC X
- case 0xFC: INC_DEC_REG( y, 1 ) // INC Y
-
- case 0x9C: INC_DEC_REG( a, -1 ) // DEC A
- case 0x1D: INC_DEC_REG( x, -1 ) // DEC X
- case 0xDC: INC_DEC_REG( y, -1 ) // DEC Y
-
- case 0x9B: // DEC dp+X
- case 0xBB: // INC dp+X
- data = uint8_t (data + x);
- case 0x8B: // DEC dp
- case 0xAB: // INC dp
- data += dp;
- goto inc_abs;
- case 0x8C: // DEC abs
- case 0xAC: // INC abs
- data = READ_PROG16( pc );
- pc++;
- inc_abs:
- nz = ((opcode >> 4) & 2) - 1;
- nz += READ( data );
- WRITE( data, (uint8_t) nz );
- goto inc_pc_loop;
-
-// 7. SHIFT, ROTATION COMMANDS
-
- case 0x5C: // LSR A
- c = 0;
- case 0x7C:{// ROR A
- nz = ((c >> 1) & 0x80) | (a >> 1);
- c = a << 8;
- a = nz;
- goto loop;
- }
-
- case 0x1C: // ASL A
- c = 0;
- case 0x3C:{// ROL A
- int temp = (c >> 8) & 1;
- c = a << 1;
- nz = c | temp;
- a = (uint8_t) nz;
- goto loop;
- }
-
- case 0x0B: // ASL dp
- c = 0;
- data += dp;
- goto rol_mem;
- case 0x1B: // ASL dp+X
- c = 0;
- case 0x3B: // ROL dp+X
- data = uint8_t (data + x);
- case 0x2B: // ROL dp
- data += dp;
- goto rol_mem;
- case 0x0C: // ASL abs
- c = 0;
- case 0x2C: // ROL abs
- data = READ_PROG16( pc );
- pc++;
- rol_mem:
- nz = (c >> 8) & 1;
- nz |= (c = READ( data ) << 1);
- WRITE( data, (uint8_t) nz );
- goto inc_pc_loop;
-
- case 0x4B: // LSR dp
- c = 0;
- data += dp;
- goto ror_mem;
- case 0x5B: // LSR dp+X
- c = 0;
- case 0x7B: // ROR dp+X
- data = uint8_t (data + x);
- case 0x6B: // ROR dp
- data += dp;
- goto ror_mem;
- case 0x4C: // LSR abs
- c = 0;
- case 0x6C: // ROR abs
- data = READ_PROG16( pc );
- pc++;
- ror_mem: {
- int temp = READ( data );
- nz = ((c >> 1) & 0x80) | (temp >> 1);
- c = temp << 8;
- WRITE( data, nz );
- goto inc_pc_loop;
- }
-
- case 0x9F: // XCN
- nz = a = (a >> 4) | uint8_t (a << 4);
- goto loop;
-
-// 8. 16-BIT TRANSMISION COMMANDS
-
- case 0xBA: // MOVW YA,dp
- a = READ_DP( data );
- nz = (a & 0x7F) | (a >> 1);
- y = READ_DP( uint8_t (data + 1) );
- nz |= y;
- goto inc_pc_loop;
-
- case 0xDA: // MOVW dp,YA
- WRITE_DP( data, a );
- WRITE_DP( uint8_t (data + 1), y );
- goto inc_pc_loop;
-
-// 9. 16-BIT OPERATION COMMANDS
-
- case 0x3A: // INCW dp
- case 0x1A:{// DECW dp
- data += dp;
-
- // low byte
- int temp = READ( data );
- temp += ((opcode >> 4) & 2) - 1; // +1 for INCW, -1 for DECW
- nz = ((temp >> 1) | temp) & 0x7F;
- WRITE( data, (uint8_t) temp );
-
- // high byte
- data = uint8_t (data + 1) + dp;
- temp >>= 8;
- temp = uint8_t (temp + READ( data ));
- nz |= temp;
- WRITE( data, temp );
-
- goto inc_pc_loop;
- }
-
- case 0x9A: // SUBW YA,dp
- case 0x7A: // ADDW YA,dp
- {
- // read 16-bit addend
- int temp = READ_DP( data );
- int sign = READ_DP( uint8_t (data + 1) );
- temp += 0x100 * sign;
- status &= ~(st_v | st_h);
-
- // to do: fix half-carry for SUBW (it's probably wrong)
-
- // for SUBW, negate and truncate to 16 bits
- if ( opcode & 0x80 ) {
- temp = (temp ^ 0xFFFF) + 1;
- sign = temp >> 8;
- }
-
- // add low byte (A)
- temp += a;
- a = (uint8_t) temp;
- nz = (temp | (temp >> 1)) & 0x7F;
-
- // add high byte (Y)
- temp >>= 8;
- c = y + temp;
- nz = (nz | c) & 0xFF;
-
- // half-carry (temporary avoids CodeWarrior optimizer bug)
- unsigned hc = (c & 15) - (y & 15);
- status |= (hc >> 4) & st_h;
-
- // overflow if sign of YA changed when previous sign and addend sign were same
- status |= (((c ^ y) & ~(y ^ sign)) >> 1) & st_v;
-
- y = (uint8_t) c;
-
- goto inc_pc_loop;
- }
-
- case 0x5A: { // CMPW YA,dp
- int temp = a - READ_DP( data );
- nz = ((temp >> 1) | temp) & 0x7F;
- temp = y + (temp >> 8);
- temp -= READ_DP( uint8_t (data + 1) );
- nz |= temp;
- c = ~temp;
- nz &= 0xFF;
- goto inc_pc_loop;
- }
-
-// 10. MULTIPLICATION & DIVISON COMMANDS
-
- case 0xCF: { // MUL YA
- unsigned temp = y * a;
- a = (uint8_t) temp;
- nz = ((temp >> 1) | temp) & 0x7F;
- y = temp >> 8;
- nz |= y;
- goto loop;
- }
-
- case 0x9E: // DIV YA,X
- {
- // behavior based on SPC CPU tests
-
- status &= ~(st_h | st_v);
-
- if ( (y & 15) >= (x & 15) )
- status |= st_h;
-
- if ( y >= x )
- status |= st_v;
-
- unsigned ya = y * 0x100 + a;
- if ( y < x * 2 )
- {
- a = ya / x;
- y = ya - a * x;
- }
- else
- {
- a = 255 - (ya - x * 0x200) / (256 - x);
- y = x + (ya - x * 0x200) % (256 - x);
- }
-
- nz = (uint8_t) a;
- a = (uint8_t) a;
-
- goto loop;
- }
-
-// 11. DECIMAL COMPENSATION COMMANDS
-
- // seem unused
- // case 0xDF: // DAA
- // case 0xBE: // DAS
-
-// 12. BRANCHING COMMANDS
-
- case 0x2F: // BRA rel
- pc += (BOOST::int8_t) data;
- goto inc_pc_loop;
-
- case 0x30: // BMI
- BRANCH( IS_NEG )
-
- case 0x10: // BPL
- BRANCH( !IS_NEG )
-
- case 0xB0: // BCS
- BRANCH( c & 0x100 )
-
- case 0x90: // BCC
- BRANCH( !(c & 0x100) )
-
- case 0x70: // BVS
- BRANCH( status & st_v )
-
- case 0x50: // BVC
- BRANCH( !(status & st_v) )
-
- case 0x03: // BBS dp.bit,rel
- case 0x23:
- case 0x43:
- case 0x63:
- case 0x83:
- case 0xA3:
- case 0xC3:
- case 0xE3:
- pc++;
- if ( (READ_DP( data ) >> (opcode >> 5)) & 1 )
- goto cbranch_taken_loop;
- goto inc_pc_loop;
-
- case 0x13: // BBC dp.bit,rel
- case 0x33:
- case 0x53:
- case 0x73:
- case 0x93:
- case 0xB3:
- case 0xD3:
- case 0xF3:
- pc++;
- if ( !((READ_DP( data ) >> (opcode >> 5)) & 1) )
- goto cbranch_taken_loop;
- goto inc_pc_loop;
-
- case 0xDE: // CBNE dp+X,rel
- data = uint8_t (data + x);
- // fall through
- case 0x2E: // CBNE dp,rel
- pc++;
- if ( READ_DP( data ) != a )
- goto cbranch_taken_loop;
- goto inc_pc_loop;
-
- case 0xFE: // DBNZ Y,rel
- y = uint8_t (y - 1);
- BRANCH( y )
-
- case 0x6E: { // DBNZ dp,rel
- pc++;
- unsigned temp = READ_DP( data ) - 1;
- WRITE_DP( (uint8_t) data, (uint8_t) temp );
- if ( temp )
- goto cbranch_taken_loop;
- goto inc_pc_loop;
- }
-
- case 0x1F: // JMP (abs+X)
- pc = READ_PROG16( pc ) + x;
- // fall through
- case 0x5F: // JMP abs
- pc = READ_PROG16( pc );
- goto loop;
-
-// 13. SUB-ROUTINE CALL RETURN COMMANDS
-
- case 0x0F:{// BRK
- check( false ); // untested
- PUSH16( pc + 1 );
- pc = READ_PROG16( 0xFFDE ); // vector address verified
- int temp;
- CALC_STATUS( temp );
- PUSH( temp );
- status = (status | st_b) & ~st_i;
- goto loop;
- }
-
- case 0x4F: // PCALL offset
- pc++;
- PUSH16( pc );
- pc = 0xFF00 + data;
- goto loop;
-
- case 0x01: // TCALL n
- case 0x11:
- case 0x21:
- case 0x31:
- case 0x41:
- case 0x51:
- case 0x61:
- case 0x71:
- case 0x81:
- case 0x91:
- case 0xA1:
- case 0xB1:
- case 0xC1:
- case 0xD1:
- case 0xE1:
- case 0xF1:
- PUSH16( pc );
- pc = READ_PROG16( 0xFFDE - (opcode >> 3) );
- goto loop;
-
-// 14. STACK OPERATION COMMANDS
-
- {
- int temp;
- case 0x7F: // RET1
- temp = POP();
- pc = POP();
- pc |= POP() << 8;
- goto set_status;
- case 0x8E: // POP PSW
- temp = POP();
- set_status:
- SET_STATUS( temp );
- goto loop;
- }
-
- case 0x0D: { // PUSH PSW
- int temp;
- CALC_STATUS( temp );
- PUSH( temp );
- goto loop;
- }
-
- case 0x2D: // PUSH A
- PUSH( a );
- goto loop;
-
- case 0x4D: // PUSH X
- PUSH( x );
- goto loop;
-
- case 0x6D: // PUSH Y
- PUSH( y );
- goto loop;
-
- case 0xAE: // POP A
- a = POP();
- goto loop;
-
- case 0xCE: // POP X
- x = POP();
- goto loop;
-
- case 0xEE: // POP Y
- y = POP();
- goto loop;
-
-// 15. BIT OPERATION COMMANDS
-
- case 0x02: // SET1
- case 0x22:
- case 0x42:
- case 0x62:
- case 0x82:
- case 0xA2:
- case 0xC2:
- case 0xE2:
- case 0x12: // CLR1
- case 0x32:
- case 0x52:
- case 0x72:
- case 0x92:
- case 0xB2:
- case 0xD2:
- case 0xF2: {
- data += dp;
- int bit = 1 << (opcode >> 5);
- int mask = ~bit;
- if ( opcode & 0x10 )
- bit = 0;
- WRITE( data, (READ( data ) & mask) | bit );
- goto inc_pc_loop;
- }
-
- case 0x0E: // TSET1 abs
- case 0x4E:{// TCLR1 abs
- data = READ_PROG16( pc );
- pc += 2;
- unsigned temp = READ( data );
- nz = temp & a;
- temp &= ~a;
- if ( !(opcode & 0x40) )
- temp |= a;
- WRITE( data, temp );
- goto loop;
- }
-
- case 0x4A: // AND1 C,mem.bit
- c &= mem_bit( pc );
- pc += 2;
- goto loop;
-
- case 0x6A: // AND1 C,/mem.bit
- check( false ); // untested
- c &= ~mem_bit( pc );
- pc += 2;
- goto loop;
-
- case 0x0A: // OR1 C,mem.bit
- check( false ); // untested
- c |= mem_bit( pc );
- pc += 2;
- goto loop;
-
- case 0x2A: // OR1 C,/mem.bit
- check( false ); // untested
- c |= ~mem_bit( pc );
- pc += 2;
- goto loop;
-
- case 0x8A: // EOR1 C,mem.bit
- c ^= mem_bit( pc );
- pc += 2;
- goto loop;
-
- case 0xEA: { // NOT1 mem.bit
- data = READ_PROG16( pc );
- pc += 2;
- unsigned temp = READ( data & 0x1FFF );
- temp ^= 1 << (data >> 13);
- WRITE( data & 0x1FFF, temp );
- goto loop;
- }
-
- case 0xCA: { // MOV1 mem.bit,C
- data = READ_PROG16( pc );
- pc += 2;
- unsigned temp = READ( data & 0x1FFF );
- unsigned bit = data >> 13;
- temp = (temp & ~(1 << bit)) | (((c >> 8) & 1) << bit);
- WRITE( data & 0x1FFF, temp );
- goto loop;
- }
-
- case 0xAA: // MOV1 C,mem.bit
- c = mem_bit( pc );
- pc += 2;
- goto loop;
-
-// 16. PROGRAM STATUS FLAG OPERATION COMMANDS
-
- case 0x60: // CLRC
- c = 0;
- goto loop;
-
- case 0x80: // SETC
- c = ~0;
- goto loop;
-
- case 0xED: // NOTC
- c ^= 0x100;
- goto loop;
-
- case 0xE0: // CLRV
- status &= ~(st_v | st_h);
- goto loop;
-
- case 0x20: // CLRP
- dp = 0;
- goto loop;
-
- case 0x40: // SETP
- dp = 0x100;
- goto loop;
-
- case 0xA0: // EI
- check( false ); // untested
- status |= st_i;
- goto loop;
-
- case 0xC0: // DI
- check( false ); // untested
- status &= ~st_i;
- goto loop;
-
-// 17. OTHER COMMANDS
-
- case 0x00: // NOP
- goto loop;
-
- //case 0xEF: // SLEEP
- //case 0xFF: // STOP
-
- } // switch
-
- // unhandled instructions fall out of switch so emulator can catch them
-
-stop:
- pc--;
-
- {
- int temp;
- CALC_STATUS( temp );
- r.status = (uint8_t) temp;
- }
-
- r.pc = pc;
- r.sp = (uint8_t) GET_SP();
- r.a = (uint8_t) a;
- r.x = (uint8_t) x;
- r.y = (uint8_t) y;
-
- return remain_;
-}
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Spc_Cpu.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/Spc_Cpu.h
deleted file mode 100644
index 2252663b..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Spc_Cpu.h
+++ /dev/null
@@ -1,57 +0,0 @@
-// Super Nintendo (SNES) SPC-700 CPU emulator
-
-// Game_Music_Emu 0.5.2
-#ifndef SPC_CPU_H
-#define SPC_CPU_H
-
-#include "blargg_common.h"
-
-typedef unsigned spc_addr_t;
-typedef blargg_long spc_time_t;
-
-class Snes_Spc;
-
-class Spc_Cpu {
- typedef BOOST::uint8_t uint8_t;
- uint8_t* const ram;
-public:
- // Keeps pointer to 64K RAM
- Spc_Cpu( Snes_Spc* spc, uint8_t* ram );
-
- // SPC-700 registers. *Not* kept updated during a call to run().
- struct registers_t {
- long pc; // more than 16 bits to allow overflow detection
- uint8_t a;
- uint8_t x;
- uint8_t y;
- uint8_t status;
- uint8_t sp;
- } r;
-
- // Run CPU for at least 'count' cycles. Return the number of cycles remaining
- // when emulation stopped (negative if extra cycles were emulated). Emulation
- // stops when there are no more remaining cycles or an unhandled instruction
- // is encountered (STOP, SLEEP, and any others not yet implemented). In the
- // latter case, the return value is greater than zero.
- spc_time_t run( spc_time_t count );
-
- // Number of clock cycles remaining for current run() call
- spc_time_t remain() const;
-
- // Access memory as the emulated CPU does
- int read ( spc_addr_t );
- void write( spc_addr_t, int );
-
-private:
- // noncopyable
- Spc_Cpu( const Spc_Cpu& );
- Spc_Cpu& operator = ( const Spc_Cpu& );
- unsigned mem_bit( spc_addr_t );
-
- spc_time_t remain_;
- Snes_Spc& emu;
-};
-
-inline spc_time_t Spc_Cpu::remain() const { return remain_; }
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Spc_Dsp.cpp b/plugins/gme/Game_Music_Emu-0.5.2/gme/Spc_Dsp.cpp
deleted file mode 100644
index 3d934f63..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Spc_Dsp.cpp
+++ /dev/null
@@ -1,666 +0,0 @@
-// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
-
-// Based on Brad Martin's OpenSPC DSP emulator
-
-#include "Spc_Dsp.h"
-
-#include "blargg_endian.h"
-#include <string.h>
-
-/* Copyright (C) 2002 Brad Martin */
-/* Copyright (C) 2004-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-#ifdef BLARGG_ENABLE_OPTIMIZER
- #include BLARGG_ENABLE_OPTIMIZER
-#endif
-
-Spc_Dsp::Spc_Dsp( uint8_t* ram_ ) : ram( ram_ )
-{
- set_gain( 1.0 );
- mute_voices( 0 );
- disable_surround( false );
-
- assert( offsetof (globals_t,unused9 [2]) == register_count );
- assert( sizeof (voice) == register_count );
- blargg_verify_byte_order();
-}
-
-void Spc_Dsp::mute_voices( int mask )
-{
- for ( int i = 0; i < voice_count; i++ )
- voice_state [i].enabled = (mask >> i & 1) ? 31 : 7;
-}
-
-void Spc_Dsp::reset()
-{
- keys = 0;
- echo_ptr = 0;
- noise_count = 0;
- noise = 1;
- fir_offset = 0;
-
- g.flags = 0xE0; // reset, mute, echo off
- g.key_ons = 0;
-
- for ( int i = 0; i < voice_count; i++ )
- {
- voice_t& v = voice_state [i];
- v.on_cnt = 0;
- v.volume [0] = 0;
- v.volume [1] = 0;
- v.envstate = state_release;
- }
-
- memset( fir_buf, 0, sizeof fir_buf );
-}
-
-void Spc_Dsp::write( int i, int data )
-{
- require( (unsigned) i < register_count );
-
- reg [i] = data;
- int high = i >> 4;
- switch ( i & 0x0F )
- {
- // voice volume
- case 0:
- case 1: {
- short* volume = voice_state [high].volume;
- int left = (int8_t) reg [i & ~1];
- int right = (int8_t) reg [i | 1];
- volume [0] = left;
- volume [1] = right;
- // kill surround only if enabled and signs of volumes differ
- if ( left * right < surround_threshold )
- {
- if ( left < 0 )
- volume [0] = -left;
- else
- volume [1] = -right;
- }
- break;
- }
-
- // fir coefficients
- case 0x0F:
- fir_coeff [high] = (int8_t) data; // sign-extend
- break;
- }
-}
-
-// This table is for envelope timing. It represents the number of counts
-// that should be subtracted from the counter each sample period (32kHz).
-// The counter starts at 30720 (0x7800). Each count divides exactly into
-// 0x7800 without remainder.
-const int env_rate_init = 0x7800;
-static short const env_rates [0x20] =
-{
- 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 int env_range = 0x800;
-
-inline int Spc_Dsp::clock_envelope( int v )
-{ /* Return value is current
- * ENVX */
- raw_voice_t& raw_voice = this->voice [v];
- voice_t& voice = voice_state [v];
-
- int envx = voice.envx;
- if ( voice.envstate == state_release )
- {
- /*
- * Docs: "When in the state of "key off". the "click" sound is
- * prevented by the addition of the fixed value 1/256" WTF???
- * Alright, I'm going to choose to interpret that this way:
- * When a note is keyed off, start the RELEASE state, which
- * subtracts 1/256th each sample period (32kHz). Note there's
- * no need for a count because it always happens every update.
- */
- envx -= env_range / 256;
- if ( envx <= 0 )
- {
- envx = 0;
- keys &= ~(1 << v);
- return -1;
- }
- voice.envx = envx;
- raw_voice.envx = envx >> 8;
- return envx;
- }
-
- int cnt = voice.envcnt;
- int adsr1 = raw_voice.adsr [0];
- if ( adsr1 & 0x80 )
- {
- switch ( voice.envstate )
- {
- case state_attack: {
- // increase envelope by 1/64 each step
- int t = adsr1 & 15;
- if ( t == 15 )
- {
- envx += env_range / 2;
- }
- else
- {
- cnt -= env_rates [t * 2 + 1];
- if ( cnt > 0 )
- break;
- envx += env_range / 64;
- cnt = env_rate_init;
- }
- if ( envx >= env_range )
- {
- envx = env_range - 1;
- voice.envstate = state_decay;
- }
- voice.envx = envx;
- break;
- }
-
- case state_decay: {
- // Docs: "DR... [is multiplied] by the fixed value
- // 1-1/256." Well, at least that makes some sense.
- // Multiplying ENVX by 255/256 every time DECAY is
- // updated.
- cnt -= env_rates [((adsr1 >> 3) & 0xE) + 0x10];
- if ( cnt <= 0 )
- {
- cnt = env_rate_init;
- envx -= ((envx - 1) >> 8) + 1;
- voice.envx = envx;
- }
- int sustain_level = raw_voice.adsr [1] >> 5;
-
- if ( envx <= (sustain_level + 1) * 0x100 )
- voice.envstate = state_sustain;
- break;
- }
-
- case state_sustain:
- // Docs: "SR [is multiplied] by the fixed value 1-1/256."
- // Multiplying ENVX by 255/256 every time SUSTAIN is
- // updated.
- cnt -= env_rates [raw_voice.adsr [1] & 0x1F];
- if ( cnt <= 0 )
- {
- cnt = env_rate_init;
- envx -= ((envx - 1) >> 8) + 1;
- voice.envx = envx;
- }
- break;
-
- case state_release:
- // handled above
- break;
- }
- }
- else
- { /* GAIN mode is set */
- /*
- * Note: if the game switches between ADSR and GAIN modes
- * partway through, should the count be reset, or should it
- * continue from where it was? Does the DSP actually watch for
- * that bit to change, or does it just go along with whatever
- * it sees when it performs the update? I'm going to assume
- * the latter and not update the count, unless I see a game
- * that obviously wants the other behavior. The effect would
- * be pretty subtle, in any case.
- */
- int t = raw_voice.gain;
- if (t < 0x80)
- {
- envx = voice.envx = t << 4;
- }
- else switch (t >> 5)
- {
- case 4: /* Docs: "Decrease (linear): Subtraction
- * of the fixed value 1/64." */
- cnt -= env_rates [t & 0x1F];
- if (cnt > 0)
- break;
- cnt = env_rate_init;
- envx -= env_range / 64;
- if ( envx < 0 )
- {
- envx = 0;
- if ( voice.envstate == state_attack )
- voice.envstate = state_decay;
- }
- voice.envx = envx;
- break;
- case 5: /* Docs: "Drecrease <sic> (exponential):
- * Multiplication by the fixed value
- * 1-1/256." */
- cnt -= env_rates [t & 0x1F];
- if (cnt > 0)
- break;
- cnt = env_rate_init;
- envx -= ((envx - 1) >> 8) + 1;
- if ( envx < 0 )
- {
- envx = 0;
- if ( voice.envstate == state_attack )
- voice.envstate = state_decay;
- }
- voice.envx = envx;
- break;
- case 6: /* Docs: "Increase (linear): Addition of
- * the fixed value 1/64." */
- cnt -= env_rates [t & 0x1F];
- if (cnt > 0)
- break;
- cnt = env_rate_init;
- envx += env_range / 64;
- if ( envx >= env_range )
- envx = env_range - 1;
- voice.envx = envx;
- break;
- case 7: /* Docs: "Increase (bent line): Addition
- * of the constant 1/64 up to .75 of the
- * constaint <sic> 1/256 from .75 to 1." */
- cnt -= env_rates [t & 0x1F];
- if (cnt > 0)
- break;
- cnt = env_rate_init;
- if ( envx < env_range * 3 / 4 )
- envx += env_range / 64;
- else
- envx += env_range / 256;
- if ( envx >= env_range )
- envx = env_range - 1;
- voice.envx = envx;
- break;
- }
- }
- voice.envcnt = cnt;
- raw_voice.envx = envx >> 4;
- return envx;
-}
-
-// Clamp n into range -32768 <= n <= 32767
-inline int clamp_16( int n )
-{
- if ( (BOOST::int16_t) n != n )
- n = BOOST::int16_t (0x7FFF - (n >> 31));
- return n;
-}
-
-void Spc_Dsp::run( long count, short* out_buf )
-{
- // to do: make clock_envelope() inline so that this becomes a leaf function?
-
- // Should we just fill the buffer with silence? Flags won't be cleared
- // during this run so it seems it should keep resetting every sample.
- if ( g.flags & 0x80 )
- reset();
-
- struct src_dir {
- char start [2];
- char loop [2];
- };
-
- const src_dir* const sd = (src_dir*) &ram [g.wave_page * 0x100];
-
- int left_volume = g.left_volume;
- int right_volume = g.right_volume;
- if ( left_volume * right_volume < surround_threshold )
- right_volume = -right_volume; // kill global surround
- left_volume *= emu_gain;
- right_volume *= emu_gain;
-
- while ( --count >= 0 )
- {
- // Here we check for keys on/off. Docs say that successive writes
- // to KON/KOF must be separated by at least 2 Ts periods or risk
- // being neglected. Therefore DSP only looks at these during an
- // update, and not at the time of the write. Only need to do this
- // once however, since the regs haven't changed over the whole
- // period we need to catch up with.
-
- g.wave_ended &= ~g.key_ons; // Keying on a voice resets that bit in ENDX.
-
- if ( g.noise_enables )
- {
- noise_count -= env_rates [g.flags & 0x1F];
- if ( noise_count <= 0 )
- {
- noise_count = env_rate_init;
-
- noise_amp = BOOST::int16_t (noise * 2);
-
- // TODO: switch to Galios style
- int feedback = (noise << 13) ^ (noise << 14);
- noise = (feedback & 0x4000) | (noise >> 1);
- }
- }
-
- // What is the expected behavior when pitch modulation is enabled on
- // voice 0? Jurassic Park 2 does this. Assume 0 for now.
- blargg_long prev_outx = 0;
-
- int echol = 0;
- int echor = 0;
- int left = 0;
- int right = 0;
- for ( int vidx = 0; vidx < voice_count; vidx++ )
- {
- const int vbit = 1 << vidx;
- raw_voice_t& raw_voice = voice [vidx];
- voice_t& voice = voice_state [vidx];
-
- if ( voice.on_cnt && !--voice.on_cnt )
- {
- // key on
- keys |= vbit;
- voice.addr = GET_LE16( sd [raw_voice.waveform].start );
- voice.block_remain = 1;
- voice.envx = 0;
- voice.block_header = 0;
- voice.fraction = 0x3FFF; // decode three samples immediately
- voice.interp0 = 0; // BRR decoder filter uses previous two samples
- voice.interp1 = 0;
-
- // NOTE: Real SNES does *not* appear to initialize the
- // envelope counter to anything in particular. The first
- // cycle always seems to come at a random time sooner than
- // expected; as yet, I have been unable to find any
- // pattern. I doubt it will matter though, so we'll go
- // ahead and do the full time for now.
- voice.envcnt = env_rate_init;
- voice.envstate = state_attack;
- }
-
- if ( g.key_ons & vbit & ~g.key_offs )
- {
- // voice doesn't come on if key off is set
- g.key_ons &= ~vbit;
- voice.on_cnt = 8;
- }
-
- if ( keys & g.key_offs & vbit )
- {
- // key off
- voice.envstate = state_release;
- voice.on_cnt = 0;
- }
-
- int envx;
- if ( !(keys & vbit) || (envx = clock_envelope( vidx )) < 0 )
- {
- raw_voice.envx = 0;
- raw_voice.outx = 0;
- prev_outx = 0;
- continue;
- }
-
- // Decode samples when fraction >= 1.0 (0x1000)
- for ( int n = voice.fraction >> 12; --n >= 0; )
- {
- if ( !--voice.block_remain )
- {
- if ( voice.block_header & 1 )
- {
- g.wave_ended |= vbit;
-
- if ( voice.block_header & 2 )
- {
- // verified (played endless looping sample and ENDX was set)
- voice.addr = GET_LE16( sd [raw_voice.waveform].loop );
- }
- else
- {
- // first block was end block; don't play anything (verified)
- goto sample_ended; // to do: find alternative to goto
- }
- }
-
- voice.block_header = ram [voice.addr++];
- voice.block_remain = 16; // nybbles
- }
-
- // if next block has end flag set, *this* block ends *early* (verified)
- if ( voice.block_remain == 9 && (ram [voice.addr + 5] & 3) == 1 &&
- (voice.block_header & 3) != 3 )
- {
- sample_ended:
- g.wave_ended |= vbit;
- keys &= ~vbit;
- raw_voice.envx = 0;
- voice.envx = 0;
- // add silence samples to interpolation buffer
- do
- {
- voice.interp3 = voice.interp2;
- voice.interp2 = voice.interp1;
- voice.interp1 = voice.interp0;
- voice.interp0 = 0;
- }
- while ( --n >= 0 );
- break;
- }
-
- int delta = ram [voice.addr];
- if ( voice.block_remain & 1 )
- {
- delta <<= 4; // use lower nybble
- voice.addr++;
- }
-
- // Use sign-extended upper nybble
- delta = int8_t (delta) >> 4;
-
- // For invalid ranges (D,E,F): if the nybble is negative,
- // the result is F000. If positive, 0000. Nothing else
- // like previous range, etc seems to have any effect. If
- // range is valid, do the shift normally. Note these are
- // both shifted right once to do the filters properly, but
- // the output will be shifted back again at the end.
- int shift = voice.block_header >> 4;
- delta = (delta << shift) >> 1;
- if ( shift > 0x0C )
- delta = (delta >> 14) & ~0x7FF;
-
- // One, two and three point IIR filters
- int smp1 = voice.interp0;
- int smp2 = voice.interp1;
- if ( voice.block_header & 8 )
- {
- delta += smp1;
- delta -= smp2 >> 1;
- if ( !(voice.block_header & 4) )
- {
- delta += (-smp1 - (smp1 >> 1)) >> 5;
- delta += smp2 >> 5;
- }
- else
- {
- delta += (-smp1 * 13) >> 7;
- delta += (smp2 + (smp2 >> 1)) >> 4;
- }
- }
- else if ( voice.block_header & 4 )
- {
- delta += smp1 >> 1;
- delta += (-smp1) >> 5;
- }
-
- voice.interp3 = voice.interp2;
- voice.interp2 = smp2;
- voice.interp1 = smp1;
- voice.interp0 = BOOST::int16_t (clamp_16( delta ) * 2); // sign-extend
- }
-
- // rate (with possible modulation)
- int rate = GET_LE16( raw_voice.rate ) & 0x3FFF;
- if ( g.pitch_mods & vbit )
- rate = (rate * (prev_outx + 32768)) >> 15;
-
- // Gaussian interpolation using most recent 4 samples
- int index = voice.fraction >> 2 & 0x3FC;
- voice.fraction = (voice.fraction & 0x0FFF) + rate;
- const BOOST::int16_t* table = (BOOST::int16_t const*) ((char const*) gauss + index);
- const BOOST::int16_t* table2 = (BOOST::int16_t const*) ((char const*) gauss + (255*4 - index));
- int s = ((table [0] * voice.interp3) >> 12) +
- ((table [1] * voice.interp2) >> 12) +
- ((table2 [1] * voice.interp1) >> 12);
- s = (BOOST::int16_t) (s * 2);
- s += (table2 [0] * voice.interp0) >> 11 & ~1;
- int output = clamp_16( s );
- if ( g.noise_enables & vbit )
- output = noise_amp;
-
- // scale output and set outx values
- output = (output * envx) >> 11 & ~1;
-
- // output and apply muting (by setting voice.enabled to 31)
- // if voice is externally disabled (not a SNES feature)
- int l = (voice.volume [0] * output) >> voice.enabled;
- int r = (voice.volume [1] * output) >> voice.enabled;
- prev_outx = output;
- raw_voice.outx = int8_t (output >> 8);
- if ( g.echo_ons & vbit )
- {
- echol += l;
- echor += r;
- }
- left += l;
- right += r;
- }
- // end of channel loop
-
- // main volume control
- left = (left * left_volume ) >> (7 + emu_gain_bits);
- right = (right * right_volume) >> (7 + emu_gain_bits);
-
- // Echo FIR filter
-
- // read feedback from echo buffer
- int echo_ptr = this->echo_ptr;
- uint8_t* echo_buf = &ram [(g.echo_page * 0x100 + echo_ptr) & 0xFFFF];
- echo_ptr += 4;
- if ( echo_ptr >= (g.echo_delay & 15) * 0x800 )
- echo_ptr = 0;
- int fb_left = (BOOST::int16_t) GET_LE16( echo_buf ); // sign-extend
- int fb_right = (BOOST::int16_t) GET_LE16( echo_buf + 2 ); // sign-extend
- this->echo_ptr = echo_ptr;
-
- // put samples in history ring buffer
- const int fir_offset = this->fir_offset;
- short (*fir_pos) [2] = &fir_buf [fir_offset];
- this->fir_offset = (fir_offset + 7) & 7; // move backwards one step
- fir_pos [0] [0] = (short) fb_left;
- fir_pos [0] [1] = (short) fb_right;
- fir_pos [8] [0] = (short) fb_left; // duplicate at +8 eliminates wrap checking below
- fir_pos [8] [1] = (short) fb_right;
-
- // FIR
- fb_left = fb_left * fir_coeff [7] +
- fir_pos [1] [0] * fir_coeff [6] +
- fir_pos [2] [0] * fir_coeff [5] +
- fir_pos [3] [0] * fir_coeff [4] +
- fir_pos [4] [0] * fir_coeff [3] +
- fir_pos [5] [0] * fir_coeff [2] +
- fir_pos [6] [0] * fir_coeff [1] +
- fir_pos [7] [0] * fir_coeff [0];
-
- fb_right = fb_right * fir_coeff [7] +
- fir_pos [1] [1] * fir_coeff [6] +
- fir_pos [2] [1] * fir_coeff [5] +
- fir_pos [3] [1] * fir_coeff [4] +
- fir_pos [4] [1] * fir_coeff [3] +
- fir_pos [5] [1] * fir_coeff [2] +
- fir_pos [6] [1] * fir_coeff [1] +
- fir_pos [7] [1] * fir_coeff [0];
-
- left += (fb_left * g.left_echo_volume ) >> 14;
- right += (fb_right * g.right_echo_volume) >> 14;
-
- // echo buffer feedback
- if ( !(g.flags & 0x20) )
- {
- echol += (fb_left * g.echo_feedback) >> 14;
- echor += (fb_right * g.echo_feedback) >> 14;
- SET_LE16( echo_buf , clamp_16( echol ) );
- SET_LE16( echo_buf + 2, clamp_16( echor ) );
- }
-
- if ( out_buf )
- {
- // write final samples
-
- left = clamp_16( left );
- right = clamp_16( right );
-
- int mute = g.flags & 0x40;
-
- out_buf [0] = (short) left;
- out_buf [1] = (short) right;
- out_buf += 2;
-
- // muting
- if ( mute )
- {
- out_buf [-2] = 0;
- out_buf [-1] = 0;
- }
- }
- }
-}
-
-// Base normal_gauss table is almost exactly (with an error of 0 or -1 for each entry):
-// int normal_gauss [512];
-// normal_gauss [i] = exp((i-511)*(i-511)*-9.975e-6)*pow(sin(0.00307096*i),1.7358)*1304.45
-
-// Interleved gauss table (to improve cache coherency).
-// gauss [i * 2 + j] = normal_gauss [(1 - j) * 256 + i]
-const BOOST::int16_t Spc_Dsp::gauss [512] =
-{
- 370,1305, 366,1305, 362,1304, 358,1304, 354,1304, 351,1304, 347,1304, 343,1303,
- 339,1303, 336,1303, 332,1302, 328,1302, 325,1301, 321,1300, 318,1300, 314,1299,
- 311,1298, 307,1297, 304,1297, 300,1296, 297,1295, 293,1294, 290,1293, 286,1292,
- 283,1291, 280,1290, 276,1288, 273,1287, 270,1286, 267,1284, 263,1283, 260,1282,
- 257,1280, 254,1279, 251,1277, 248,1275, 245,1274, 242,1272, 239,1270, 236,1269,
- 233,1267, 230,1265, 227,1263, 224,1261, 221,1259, 218,1257, 215,1255, 212,1253,
- 210,1251, 207,1248, 204,1246, 201,1244, 199,1241, 196,1239, 193,1237, 191,1234,
- 188,1232, 186,1229, 183,1227, 180,1224, 178,1221, 175,1219, 173,1216, 171,1213,
- 168,1210, 166,1207, 163,1205, 161,1202, 159,1199, 156,1196, 154,1193, 152,1190,
- 150,1186, 147,1183, 145,1180, 143,1177, 141,1174, 139,1170, 137,1167, 134,1164,
- 132,1160, 130,1157, 128,1153, 126,1150, 124,1146, 122,1143, 120,1139, 118,1136,
- 117,1132, 115,1128, 113,1125, 111,1121, 109,1117, 107,1113, 106,1109, 104,1106,
- 102,1102, 100,1098, 99,1094, 97,1090, 95,1086, 94,1082, 92,1078, 90,1074,
- 89,1070, 87,1066, 86,1061, 84,1057, 83,1053, 81,1049, 80,1045, 78,1040,
- 77,1036, 76,1032, 74,1027, 73,1023, 71,1019, 70,1014, 69,1010, 67,1005,
- 66,1001, 65, 997, 64, 992, 62, 988, 61, 983, 60, 978, 59, 974, 58, 969,
- 56, 965, 55, 960, 54, 955, 53, 951, 52, 946, 51, 941, 50, 937, 49, 932,
- 48, 927, 47, 923, 46, 918, 45, 913, 44, 908, 43, 904, 42, 899, 41, 894,
- 40, 889, 39, 884, 38, 880, 37, 875, 36, 870, 36, 865, 35, 860, 34, 855,
- 33, 851, 32, 846, 32, 841, 31, 836, 30, 831, 29, 826, 29, 821, 28, 816,
- 27, 811, 27, 806, 26, 802, 25, 797, 24, 792, 24, 787, 23, 782, 23, 777,
- 22, 772, 21, 767, 21, 762, 20, 757, 20, 752, 19, 747, 19, 742, 18, 737,
- 17, 732, 17, 728, 16, 723, 16, 718, 15, 713, 15, 708, 15, 703, 14, 698,
- 14, 693, 13, 688, 13, 683, 12, 678, 12, 674, 11, 669, 11, 664, 11, 659,
- 10, 654, 10, 649, 10, 644, 9, 640, 9, 635, 9, 630, 8, 625, 8, 620,
- 8, 615, 7, 611, 7, 606, 7, 601, 6, 596, 6, 592, 6, 587, 6, 582,
- 5, 577, 5, 573, 5, 568, 5, 563, 4, 559, 4, 554, 4, 550, 4, 545,
- 4, 540, 3, 536, 3, 531, 3, 527, 3, 522, 3, 517, 2, 513, 2, 508,
- 2, 504, 2, 499, 2, 495, 2, 491, 2, 486, 1, 482, 1, 477, 1, 473,
- 1, 469, 1, 464, 1, 460, 1, 456, 1, 451, 1, 447, 1, 443, 1, 439,
- 0, 434, 0, 430, 0, 426, 0, 422, 0, 418, 0, 414, 0, 410, 0, 405,
- 0, 401, 0, 397, 0, 393, 0, 389, 0, 385, 0, 381, 0, 378, 0, 374,
-};
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Spc_Dsp.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/Spc_Dsp.h
deleted file mode 100644
index 36492275..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Spc_Dsp.h
+++ /dev/null
@@ -1,152 +0,0 @@
-// Super Nintendo (SNES) SPC DSP emulator
-
-// Game_Music_Emu 0.5.2
-#ifndef SPC_DSP_H
-#define SPC_DSP_H
-
-#include "blargg_common.h"
-
-class Spc_Dsp {
- typedef BOOST::int8_t int8_t;
- typedef BOOST::uint8_t uint8_t;
-public:
-
- // Keeps pointer to 64K ram
- Spc_Dsp( uint8_t* ram );
-
- // Mute voice n if bit n (1 << n) of mask is clear.
- enum { voice_count = 8 };
- void mute_voices( int mask );
-
- // Clear state and silence everything.
- void reset();
-
- // Set gain, where 1.0 is normal. When greater than 1.0, output is clamped to
- // the 16-bit sample range.
- void set_gain( double );
-
- // If true, prevent channels and global volumes from being phase-negated
- void disable_surround( bool disable );
-
- // Read/write register 'n', where n ranges from 0 to register_count - 1.
- enum { register_count = 128 };
- int read ( int n );
- void write( int n, int );
-
- // Run DSP for 'count' samples. Write resulting samples to 'buf' if not NULL.
- void run( long count, short* buf = NULL );
-
-
-// End of public interface
-private:
-
- struct raw_voice_t {
- int8_t left_vol;
- int8_t right_vol;
- uint8_t rate [2];
- uint8_t waveform;
- uint8_t adsr [2]; // envelope rates for attack, decay, and sustain
- uint8_t gain; // envelope gain (if not using ADSR)
- int8_t envx; // current envelope level
- int8_t outx; // current sample
- int8_t unused [6];
- };
-
- struct globals_t {
- int8_t unused1 [12];
- int8_t left_volume; // 0C Main Volume Left (-.7)
- int8_t echo_feedback; // 0D Echo Feedback (-.7)
- int8_t unused2 [14];
- int8_t right_volume; // 1C Main Volume Right (-.7)
- int8_t unused3 [15];
- int8_t left_echo_volume; // 2C Echo Volume Left (-.7)
- uint8_t pitch_mods; // 2D Pitch Modulation on/off for each voice
- int8_t unused4 [14];
- int8_t right_echo_volume; // 3C Echo Volume Right (-.7)
- uint8_t noise_enables; // 3D Noise output on/off for each voice
- int8_t unused5 [14];
- uint8_t key_ons; // 4C Key On for each voice
- uint8_t echo_ons; // 4D Echo on/off for each voice
- int8_t unused6 [14];
- uint8_t key_offs; // 5C key off for each voice (instantiates release mode)
- uint8_t wave_page; // 5D source directory (wave table offsets)
- int8_t unused7 [14];
- uint8_t flags; // 6C flags and noise freq
- uint8_t echo_page; // 6D
- int8_t unused8 [14];
- uint8_t wave_ended; // 7C
- uint8_t echo_delay; // 7D ms >> 4
- char unused9 [2];
- };
-
- union {
- raw_voice_t voice [voice_count];
- uint8_t reg [register_count];
- globals_t g;
- };
-
- uint8_t* const ram;
-
- // Cache of echo FIR values for faster access
- short fir_coeff [voice_count];
-
- // fir_buf [i + 8] == fir_buf [i], to avoid wrap checking in FIR code
- short fir_buf [16] [2];
- int fir_offset; // (0 to 7)
-
- enum { emu_gain_bits = 8 };
- int emu_gain;
-
- int keyed_on; // 8-bits for 8 voices
- int keys;
-
- int echo_ptr;
- int noise_amp;
- int noise;
- int noise_count;
-
- int surround_threshold;
-
- static BOOST::int16_t const gauss [];
-
- enum state_t {
- state_attack,
- state_decay,
- state_sustain,
- state_release
- };
-
- struct voice_t {
- short volume [2];
- short fraction;// 12-bit fractional position
- short interp3; // most recent four decoded samples
- short interp2;
- short interp1;
- short interp0;
- short block_remain; // number of nybbles remaining in current block
- unsigned short addr;
- short block_header; // header byte from current block
- short envcnt;
- short envx;
- short on_cnt;
- short enabled; // 7 if enabled, 31 if disabled
- short envstate;
- short unused; // pad to power of 2
- };
-
- voice_t voice_state [voice_count];
-
- int clock_envelope( int );
-};
-
-inline void Spc_Dsp::disable_surround( bool disable ) { surround_threshold = disable ? 0 : -0x7FFF; }
-
-inline void Spc_Dsp::set_gain( double v ) { emu_gain = (int) (v * (1 << emu_gain_bits)); }
-
-inline int Spc_Dsp::read( int i )
-{
- assert( (unsigned) i < register_count );
- return reg [i];
-}
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Spc_Emu.cpp b/plugins/gme/Game_Music_Emu-0.5.2/gme/Spc_Emu.cpp
deleted file mode 100644
index 22be9e2a..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Spc_Emu.cpp
+++ /dev/null
@@ -1,326 +0,0 @@
-// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
-
-#include "Spc_Emu.h"
-
-#include "blargg_endian.h"
-#include <stdlib.h>
-#include <string.h>
-
-/* Copyright (C) 2004-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-Spc_Emu::Spc_Emu()
-{
- set_type( gme_spc_type );
-
- static const char* const names [Snes_Spc::voice_count] = {
- "DSP 1", "DSP 2", "DSP 3", "DSP 4", "DSP 5", "DSP 6", "DSP 7", "DSP 8"
- };
- set_voice_names( names );
-
- set_gain( 1.4 );
-}
-
-Spc_Emu::~Spc_Emu() { }
-
-// Track info
-
-long const trailer_offset = 0x10200;
-
-byte const* Spc_Emu::trailer() const { return &file_data [min( file_size, trailer_offset )]; }
-
-long Spc_Emu::trailer_size() const { return max( 0L, file_size - trailer_offset ); }
-
-static void get_spc_xid6( byte const* begin, long size, track_info_t* out )
-{
- // header
- byte const* end = begin + size;
- if ( size < 8 || memcmp( begin, "xid6", 4 ) )
- {
- check( false );
- return;
- }
- long info_size = get_le32( begin + 4 );
- byte const* in = begin + 8;
- if ( end - in > info_size )
- {
- dprintf( "Extra data after SPC xid6 info\n" );
- end = in + info_size;
- }
-
- int year = 0;
- char copyright [256 + 5];
- int copyright_len = 0;
- int const year_len = 5;
-
- while ( end - in >= 4 )
- {
- // header
- int id = in [0];
- int data = in [3] * 0x100 + in [2];
- int type = in [1];
- int len = type ? data : 0;
- in += 4;
- if ( len > end - in )
- {
- check( false );
- break; // block goes past end of data
- }
-
- // handle specific block types
- char* field = 0;
- switch ( id )
- {
- case 0x01: field = out->song; break;
- case 0x02: field = out->game; break;
- case 0x03: field = out->author; break;
- case 0x04: field = out->dumper; break;
- case 0x07: field = out->comment; break;
- case 0x14: year = data; break;
-
- //case 0x30: // intro length
- // Many SPCs have intro length set wrong for looped tracks, making it useless
- /*
- case 0x30:
- check( len == 4 );
- if ( len >= 4 )
- {
- out->intro_length = get_le32( in ) / 64;
- if ( out->length > 0 )
- {
- long loop = out->length - out->intro_length;
- if ( loop >= 2000 )
- out->loop_length = loop;
- }
- }
- break;
- */
-
- case 0x13:
- copyright_len = min( len, (int) sizeof copyright - year_len );
- memcpy( &copyright [year_len], in, copyright_len );
- break;
-
- default:
- if ( id < 0x01 || (id > 0x07 && id < 0x10) ||
- (id > 0x14 && id < 0x30) || id > 0x36 )
- dprintf( "Unknown SPC xid6 block: %X\n", (int) id );
- break;
- }
- if ( field )
- {
- check( type == 1 );
- Gme_File::copy_field_( field, (char const*) in, len );
- }
-
- // skip to next block
- in += len;
-
- // blocks are supposed to be 4-byte aligned with zero-padding...
- byte const* unaligned = in;
- while ( (in - begin) & 3 && in < end )
- {
- if ( *in++ != 0 )
- {
- // ...but some files have no padding
- in = unaligned;
- dprintf( "SPC info tag wasn't properly padded to align\n" );
- break;
- }
- }
- }
-
- char* p = &copyright [year_len];
- if ( year )
- {
- *--p = ' ';
- for ( int n = 4; n--; )
- {
- *--p = char (year % 10 + '0');
- year /= 10;
- }
- copyright_len += year_len;
- }
- if ( copyright_len )
- Gme_File::copy_field_( out->copyright, p, copyright_len );
-
- check( in == end );
-}
-
-static void get_spc_info( Spc_Emu::header_t const& h, byte const* xid6, long xid6_size,
- track_info_t* out )
-{
- // decode length (can be in text or binary format, sometimes ambiguous ugh)
- long len_secs = 0;
- for ( int i = 0; i < 3; i++ )
- {
- unsigned n = h.len_secs [i] - '0';
- if ( n > 9 )
- {
- // ignore single-digit text lengths
- // (except if author field is present and begins at offset 1, ugh)
- if ( i == 1 && (h.author [0] || !h.author [1]) )
- len_secs = 0;
- break;
- }
- len_secs *= 10;
- len_secs += n;
- }
- if ( !len_secs || len_secs > 0x1FFF )
- len_secs = get_le16( h.len_secs );
- if ( len_secs < 0x1FFF )
- out->length = len_secs * 1000;
-
- int offset = (h.author [0] < ' ' || unsigned (h.author [0] - '0') <= 9);
- Gme_File::copy_field_( out->author, &h.author [offset], sizeof h.author - offset );
-
- GME_COPY_FIELD( h, out, song );
- GME_COPY_FIELD( h, out, game );
- GME_COPY_FIELD( h, out, dumper );
- GME_COPY_FIELD( h, out, comment );
-
- if ( xid6_size )
- get_spc_xid6( xid6, xid6_size, out );
-}
-
-blargg_err_t Spc_Emu::track_info_( track_info_t* out, int ) const
-{
- get_spc_info( header(), trailer(), trailer_size(), out );
- return 0;
-}
-
-static blargg_err_t check_spc_header( void const* header )
-{
- if ( memcmp( header, "SNES-SPC700 Sound File Data", 27 ) )
- return gme_wrong_file_type;
- return 0;
-}
-
-struct Spc_File : Gme_Info_
-{
- Spc_Emu::header_t header;
- blargg_vector<byte> xid6;
-
- Spc_File() { set_type( gme_spc_type ); }
-
- blargg_err_t load_( Data_Reader& in )
- {
- long file_size = in.remain();
- if ( file_size < Snes_Spc::spc_file_size )
- return gme_wrong_file_type;
- RETURN_ERR( in.read( &header, Spc_Emu::header_size ) );
- RETURN_ERR( check_spc_header( header.tag ) );
- long const xid6_offset = 0x10200;
- long xid6_size = file_size - xid6_offset;
- if ( xid6_size > 0 )
- {
- RETURN_ERR( xid6.resize( xid6_size ) );
- RETURN_ERR( in.skip( xid6_offset - Spc_Emu::header_size ) );
- RETURN_ERR( in.read( xid6.begin(), xid6.size() ) );
- }
- return 0;
- }
-
- blargg_err_t track_info_( track_info_t* out, int ) const
- {
- get_spc_info( header, xid6.begin(), xid6.size(), out );
- return 0;
- }
-};
-
-static Music_Emu* new_spc_emu () { return BLARGG_NEW Spc_Emu ; }
-static Music_Emu* new_spc_file() { return BLARGG_NEW Spc_File; }
-
-gme_type_t_ const gme_spc_type [1] = { "Super Nintendo", 1, &new_spc_emu, &new_spc_file, "SPC", 0 };
-
-// Setup
-
-blargg_err_t Spc_Emu::set_sample_rate_( long sample_rate )
-{
- apu.set_gain( gain() );
- if ( sample_rate != native_sample_rate )
- {
- RETURN_ERR( resampler.buffer_size( native_sample_rate / 20 * 2 ) );
- resampler.time_ratio( (double) native_sample_rate / sample_rate, 0.9965 );
- }
- return 0;
-}
-
-void Spc_Emu::mute_voices_( int m )
-{
- Music_Emu::mute_voices_( m );
- apu.mute_voices( m );
-}
-
-blargg_err_t Spc_Emu::load_mem_( byte const* in, long size )
-{
- assert( offsetof (header_t,unused2 [46]) == header_size );
- file_data = in;
- file_size = size;
- set_voice_count( Snes_Spc::voice_count );
- if ( size < Snes_Spc::spc_file_size )
- return gme_wrong_file_type;
- return check_spc_header( in );
-}
-
-// Emulation
-
-void Spc_Emu::set_tempo_( double t ) { apu.set_tempo( t ); }
-
-blargg_err_t Spc_Emu::start_track_( int track )
-{
- RETURN_ERR( Music_Emu::start_track_( track ) );
- resampler.clear();
- RETURN_ERR( apu.load_spc( file_data, file_size ) );
- apu.clear_echo();
- return 0;
-}
-
-blargg_err_t Spc_Emu::skip_( long count )
-{
- if ( sample_rate() != native_sample_rate )
- {
- count = long (count * resampler.ratio()) & ~1;
- count -= resampler.skip_input( count );
- }
-
- // TODO: shouldn't skip be adjusted for the 64 samples read afterwards?
-
- if ( count > 0 )
- RETURN_ERR( apu.skip( count ) );
-
- // eliminate pop due to resampler
- const int resampler_latency = 64;
- sample_t buf [resampler_latency];
- return play_( resampler_latency, buf );
-}
-
-blargg_err_t Spc_Emu::play_( long count, sample_t* out )
-{
- if ( sample_rate() == native_sample_rate )
- return apu.play( count, out );
-
- long remain = count;
- while ( remain > 0 )
- {
- remain -= resampler.read( &out [count - remain], remain );
- if ( remain > 0 )
- {
- long n = resampler.max_write();
- RETURN_ERR( apu.play( n, resampler.buffer() ) );
- resampler.write( n );
- }
- }
- check( remain == 0 );
- return 0;
-}
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Spc_Emu.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/Spc_Emu.h
deleted file mode 100644
index 44b54c30..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Spc_Emu.h
+++ /dev/null
@@ -1,77 +0,0 @@
-// Super Nintendo SPC music file emulator
-
-// Game_Music_Emu 0.5.2
-#ifndef SPC_EMU_H
-#define SPC_EMU_H
-
-#include "Fir_Resampler.h"
-#include "Music_Emu.h"
-#include "Snes_Spc.h"
-
-class Spc_Emu : public Music_Emu {
-public:
- // The Super Nintendo hardware samples at 32kHz. Other sample rates are
- // handled by resampling the 32kHz output; emulation accuracy is not affected.
- enum { native_sample_rate = 32000 };
-
- // SPC file header
- enum { header_size = 0x100 };
- struct header_t
- {
- char tag [35];
- byte format;
- byte version;
- byte pc [2];
- byte a, x, y, psw, sp;
- byte unused [2];
- char song [32];
- char game [32];
- char dumper [16];
- char comment [32];
- byte date [11];
- byte len_secs [3];
- byte fade_msec [4];
- char author [32]; // sometimes first char should be skipped (see official SPC spec)
- byte mute_mask;
- byte emulator;
- byte unused2 [46];
- };
-
- // Header for currently loaded file
- header_t const& header() const { return *(header_t const*) file_data; }
-
- // Prevents channels and global volumes from being phase-negated
- void disable_surround( bool disable = true );
-
- static gme_type_t static_type() { return gme_spc_type; }
-
-public:
- // deprecated
- Music_Emu::load;
- blargg_err_t load( header_t const& h, Data_Reader& in ) // use Remaining_Reader
- { return load_remaining_( &h, sizeof h, in ); }
- byte const* trailer() const; // use track_info()
- long trailer_size() const;
-
-public:
- Spc_Emu();
- ~Spc_Emu();
-protected:
- blargg_err_t load_mem_( byte const*, long );
- blargg_err_t track_info_( track_info_t*, int track ) const;
- blargg_err_t set_sample_rate_( long );
- blargg_err_t start_track_( int );
- blargg_err_t play_( long, sample_t* );
- blargg_err_t skip_( long );
- void mute_voices_( int );
- void set_tempo_( double );
-private:
- byte const* file_data;
- long file_size;
- Fir_Resampler<24> resampler;
- Snes_Spc apu;
-};
-
-inline void Spc_Emu::disable_surround( bool b ) { apu.disable_surround( b ); }
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Vgm_Emu.cpp b/plugins/gme/Game_Music_Emu-0.5.2/gme/Vgm_Emu.cpp
deleted file mode 100644
index 0fef6bd9..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Vgm_Emu.cpp
+++ /dev/null
@@ -1,412 +0,0 @@
-// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
-
-#include "Vgm_Emu.h"
-
-#include "blargg_endian.h"
-#include <string.h>
-#include <math.h>
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-double const fm_gain = 3.0; // FM emulators are internally quieter to avoid 16-bit overflow
-double const rolloff = 0.990;
-double const oversample_factor = 1.5;
-
-Vgm_Emu::Vgm_Emu()
-{
- disable_oversampling_ = false;
- psg_rate = 0;
- set_type( gme_vgm_type );
-
- static int const types [8] = {
- wave_type | 1, wave_type | 0, wave_type | 2, noise_type | 0
- };
- set_voice_types( types );
-
- set_silence_lookahead( 1 ); // tracks should already be trimmed
-
- static equalizer_t const eq = { -14.0, 80 };
- set_equalizer( eq );
-}
-
-Vgm_Emu::~Vgm_Emu() { }
-
-// Track info
-
-static byte const* skip_gd3_str( byte const* in, byte const* end )
-{
- while ( end - in >= 2 )
- {
- in += 2;
- if ( !(in [-2] | in [-1]) )
- break;
- }
- return in;
-}
-
-static byte const* get_gd3_str( byte const* in, byte const* end, char* field )
-{
- byte const* mid = skip_gd3_str( in, end );
- int len = (mid - in) / 2 - 1;
- if ( len > 0 )
- {
- len = min( len, (int) Gme_File::max_field_ );
- field [len] = 0;
- for ( int i = 0; i < len; i++ )
- field [i] = (in [i * 2 + 1] ? '?' : in [i * 2]); // TODO: convert to utf-8
- }
- return mid;
-}
-
-static byte const* get_gd3_pair( byte const* in, byte const* end, char* field )
-{
- return skip_gd3_str( get_gd3_str( in, end, field ), end );
-}
-
-static void parse_gd3( byte const* in, byte const* end, track_info_t* out )
-{
- in = get_gd3_pair( in, end, out->song );
- in = get_gd3_pair( in, end, out->game );
- in = get_gd3_pair( in, end, out->system );
- in = get_gd3_pair( in, end, out->author );
- in = get_gd3_str ( in, end, out->copyright );
- in = get_gd3_pair( in, end, out->dumper );
- in = get_gd3_str ( in, end, out->comment );
-}
-
-int const gd3_header_size = 12;
-
-static long check_gd3_header( byte const* h, long remain )
-{
- if ( remain < gd3_header_size ) return 0;
- if ( memcmp( h, "Gd3 ", 4 ) ) return 0;
- if ( get_le32( h + 4 ) >= 0x200 ) return 0;
-
- long gd3_size = get_le32( h + 8 );
- if ( gd3_size > remain - gd3_header_size ) return 0;
-
- return gd3_size;
-}
-
-byte const* Vgm_Emu::gd3_data( int* size ) const
-{
- if ( size )
- *size = 0;
-
- long gd3_offset = get_le32( header().gd3_offset ) - 0x2C;
- if ( gd3_offset < 0 )
- return 0;
-
- byte const* gd3 = data + header_size + gd3_offset;
- long gd3_size = check_gd3_header( gd3, data_end - gd3 );
- if ( !gd3_size )
- return 0;
-
- if ( size )
- *size = gd3_size + gd3_header_size;
-
- return gd3;
-}
-
-static void get_vgm_length( Vgm_Emu::header_t const& h, track_info_t* out )
-{
- long length = get_le32( h.track_duration ) * 10 / 441;
- if ( length > 0 )
- {
- long loop = get_le32( h.loop_duration );
- if ( loop > 0 && get_le32( h.loop_offset ) )
- {
- out->loop_length = loop * 10 / 441;
- out->intro_length = length - out->loop_length;
- }
- else
- {
- out->length = length; // 1000 / 44100 (VGM files used 44100 as timebase)
- out->intro_length = length; // make it clear that track is no longer than length
- out->loop_length = 0;
- }
- }
-}
-
-blargg_err_t Vgm_Emu::track_info_( track_info_t* out, int ) const
-{
- get_vgm_length( header(), out );
-
- int size;
- byte const* gd3 = gd3_data( &size );
- if ( gd3 )
- parse_gd3( gd3 + gd3_header_size, gd3 + size, out );
-
- return 0;
-}
-
-static blargg_err_t check_vgm_header( Vgm_Emu::header_t const& h )
-{
- if ( memcmp( h.tag, "Vgm ", 4 ) )
- return gme_wrong_file_type;
- return 0;
-}
-
-struct Vgm_File : Gme_Info_
-{
- Vgm_Emu::header_t h;
- blargg_vector<byte> gd3;
-
- Vgm_File() { set_type( gme_vgm_type ); }
-
- blargg_err_t load_( Data_Reader& in )
- {
- long file_size = in.remain();
- if ( file_size <= Vgm_Emu::header_size )
- return gme_wrong_file_type;
-
- RETURN_ERR( in.read( &h, Vgm_Emu::header_size ) );
- RETURN_ERR( check_vgm_header( h ) );
-
- long gd3_offset = get_le32( h.gd3_offset ) - 0x2C;
- long remain = file_size - Vgm_Emu::header_size - gd3_offset;
- byte gd3_h [gd3_header_size];
- if ( gd3_offset > 0 && remain >= gd3_header_size )
- {
- RETURN_ERR( in.skip( gd3_offset ) );
- RETURN_ERR( in.read( gd3_h, sizeof gd3_h ) );
- long gd3_size = check_gd3_header( gd3_h, remain );
- if ( gd3_size )
- {
- RETURN_ERR( gd3.resize( gd3_size ) );
- RETURN_ERR( in.read( gd3.begin(), gd3.size() ) );
- }
- }
- return 0;
- }
-
- blargg_err_t track_info_( track_info_t* out, int ) const
- {
- get_vgm_length( h, out );
- if ( gd3.size() )
- parse_gd3( gd3.begin(), gd3.end(), out );
- return 0;
- }
-};
-
-static Music_Emu* new_vgm_emu () { return BLARGG_NEW Vgm_Emu ; }
-static Music_Emu* new_vgm_file() { return BLARGG_NEW Vgm_File; }
-
-gme_type_t_ const gme_vgm_type [1] = { "Sega SMS/Genesis", 1, &new_vgm_emu, &new_vgm_file, "VGM", 1 };
-gme_type_t_ const gme_vgz_type [1] = { "Sega SMS/Genesis", 1, &new_vgm_emu, &new_vgm_file, "VGZ", 1 };
-
-// Setup
-
-void Vgm_Emu::set_tempo_( double t )
-{
- if ( psg_rate )
- {
- vgm_rate = (long) (44100 * t + 0.5);
- blip_time_factor = (long) floor( double (1L << blip_time_bits) / vgm_rate * psg_rate + 0.5 );
- //dprintf( "blip_time_factor: %ld\n", blip_time_factor );
- //dprintf( "vgm_rate: %ld\n", vgm_rate );
- // TODO: remove? calculates vgm_rate more accurately (above differs at most by one Hz only)
- //blip_time_factor = (long) floor( double (1L << blip_time_bits) * psg_rate / 44100 / t + 0.5 );
- //vgm_rate = (long) floor( double (1L << blip_time_bits) * psg_rate / blip_time_factor + 0.5 );
-
- fm_time_factor = 2 + (long) floor( fm_rate * (1L << fm_time_bits) / vgm_rate + 0.5 );
- }
-}
-
-blargg_err_t Vgm_Emu::set_sample_rate_( long sample_rate )
-{
- RETURN_ERR( blip_buf.set_sample_rate( sample_rate, 1000 / 30 ) );
- return Classic_Emu::set_sample_rate_( sample_rate );
-}
-
-void Vgm_Emu::update_eq( blip_eq_t const& eq )
-{
- psg.treble_eq( eq );
- dac_synth.treble_eq( eq );
-}
-
-void Vgm_Emu::set_voice( int i, Blip_Buffer* c, Blip_Buffer* l, Blip_Buffer* r )
-{
- if ( i < psg.osc_count )
- psg.osc_output( i, c, l, r );
-}
-
-void Vgm_Emu::mute_voices_( int mask )
-{
- Classic_Emu::mute_voices_( mask );
- dac_synth.output( &blip_buf );
- if ( uses_fm )
- {
- psg.output( (mask & 0x80) ? 0 : &blip_buf );
- if ( ym2612.enabled() )
- {
- dac_synth.volume( (mask & 0x40) ? 0.0 : 0.1115 / 256 * fm_gain * gain() );
- ym2612.mute_voices( mask );
- }
-
- if ( ym2413.enabled() )
- {
- int m = mask & 0x3F;
- if ( mask & 0x20 )
- m |= 0x01E0; // channels 5-8
- if ( mask & 0x40 )
- m |= 0x3E00;
- ym2413.mute_voices( m );
- }
- }
-}
-
-blargg_err_t Vgm_Emu::load_mem_( byte const* new_data, long new_size )
-{
- assert( offsetof (header_t,unused2 [8]) == header_size );
-
- if ( new_size <= header_size )
- return gme_wrong_file_type;
-
- header_t const& h = *(header_t const*) new_data;
-
- RETURN_ERR( check_vgm_header( h ) );
-
- check( get_le32( h.version ) <= 0x150 );
-
- // psg rate
- psg_rate = get_le32( h.psg_rate );
- if ( !psg_rate )
- psg_rate = 3579545;
- blip_buf.clock_rate( psg_rate );
-
- data = new_data;
- data_end = new_data + new_size;
-
- // get loop
- loop_begin = data_end;
- if ( get_le32( h.loop_offset ) )
- loop_begin = &data [get_le32( h.loop_offset ) + offsetof (header_t,loop_offset)];
-
- set_voice_count( psg.osc_count );
-
- RETURN_ERR( setup_fm() );
-
- static const char* const fm_names [] = {
- "FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6", "PCM", "PSG"
- };
- static const char* const psg_names [] = { "Square 1", "Square 2", "Square 3", "Noise" };
- set_voice_names( uses_fm ? fm_names : psg_names );
-
- // do after FM in case output buffer is changed
- return Classic_Emu::setup_buffer( psg_rate );
-}
-
-blargg_err_t Vgm_Emu::setup_fm()
-{
- long ym2612_rate = get_le32( header().ym2612_rate );
- long ym2413_rate = get_le32( header().ym2413_rate );
- if ( ym2413_rate && get_le32( header().version ) < 0x110 )
- update_fm_rates( &ym2413_rate, &ym2612_rate );
-
- uses_fm = false;
-
- fm_rate = blip_buf.sample_rate() * oversample_factor;
-
- if ( ym2612_rate )
- {
- uses_fm = true;
- if ( disable_oversampling_ )
- fm_rate = ym2612_rate / 144.0;
- Dual_Resampler::setup( fm_rate / blip_buf.sample_rate(), rolloff, fm_gain * gain() );
- RETURN_ERR( ym2612.set_rate( fm_rate, ym2612_rate ) );
- ym2612.enable( true );
- set_voice_count( 8 );
- }
-
- if ( !uses_fm && ym2413_rate )
- {
- uses_fm = true;
- if ( disable_oversampling_ )
- fm_rate = ym2413_rate / 72.0;
- Dual_Resampler::setup( fm_rate / blip_buf.sample_rate(), rolloff, fm_gain * gain() );
- int result = ym2413.set_rate( fm_rate, ym2413_rate );
- if ( result == 2 )
- return "YM2413 FM sound isn't supported";
- CHECK_ALLOC( !result );
- ym2413.enable( true );
- set_voice_count( 8 );
- }
-
- if ( uses_fm )
- {
- RETURN_ERR( Dual_Resampler::reset( blip_buf.length() * blip_buf.sample_rate() / 1000 ) );
- psg.volume( 0.135 * fm_gain * gain() );
- }
- else
- {
- ym2612.enable( false );
- ym2413.enable( false );
- psg.volume( gain() );
- }
-
- return 0;
-}
-
-// Emulation
-
-blargg_err_t Vgm_Emu::start_track_( int track )
-{
- RETURN_ERR( Classic_Emu::start_track_( track ) );
- psg.reset( get_le16( header().noise_feedback ), header().noise_width );
-
- dac_disabled = -1;
- pos = data + header_size;
- pcm_data = pos;
- pcm_pos = pos;
- dac_amp = -1;
- vgm_time = 0;
- if ( get_le32( header().version ) >= 0x150 )
- {
- long data_offset = get_le32( header().data_offset );
- check( data_offset );
- if ( data_offset )
- pos += data_offset + offsetof (header_t,data_offset) - 0x40;
- }
-
- if ( uses_fm )
- {
- if ( ym2413.enabled() )
- ym2413.reset();
-
- if ( ym2612.enabled() )
- ym2612.reset();
-
- fm_time_offset = 0;
- blip_buf.clear();
- Dual_Resampler::clear();
- }
- return 0;
-}
-
-blargg_err_t Vgm_Emu::run_clocks( blip_time_t& time_io, int msec )
-{
- time_io = run_commands( msec * vgm_rate / 1000 );
- psg.end_frame( time_io );
- return 0;
-}
-
-blargg_err_t Vgm_Emu::play_( long count, sample_t* out )
-{
- if ( !uses_fm )
- return Classic_Emu::play_( count, out );
-
- Dual_Resampler::dual_play( count, out, blip_buf );
- return 0;
-}
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Vgm_Emu.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/Vgm_Emu.h
deleted file mode 100644
index bcb784d5..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Vgm_Emu.h
+++ /dev/null
@@ -1,84 +0,0 @@
-// Sega Master System/Mark III, Sega Genesis/Mega Drive, BBC Micro VGM music file emulator
-
-// Game_Music_Emu 0.5.2
-#ifndef VGM_EMU_H
-#define VGM_EMU_H
-
-#include "Vgm_Emu_Impl.h"
-
-// Emulates VGM music using SN76489/SN76496 PSG, YM2612, and YM2413 FM sound chips.
-// Supports custom sound buffer and frequency equalization when VGM uses just the PSG.
-// FM sound chips can be run at their proper rates, or slightly higher to reduce
-// aliasing on high notes. Currently YM2413 support requires that you supply a
-// YM2413 sound chip emulator. I can provide one I've modified to work with the library.
-class Vgm_Emu : public Vgm_Emu_Impl {
-public:
- // True if custom buffer and custom equalization are supported
- // TODO: move into Music_Emu and rename to something like supports_custom_buffer()
- bool is_classic_emu() const { return !uses_fm; }
-
- // Disable running FM chips at higher than normal rate. Will result in slightly
- // more aliasing of high notes.
- void disable_oversampling( bool disable = true ) { disable_oversampling_ = disable; }
-
- // VGM header format
- enum { header_size = 0x40 };
- struct header_t
- {
- char tag [4];
- byte data_size [4];
- byte version [4];
- byte psg_rate [4];
- byte ym2413_rate [4];
- byte gd3_offset [4];
- byte track_duration [4];
- byte loop_offset [4];
- byte loop_duration [4];
- byte frame_rate [4];
- byte noise_feedback [2];
- byte noise_width;
- byte unused1;
- byte ym2612_rate [4];
- byte ym2151_rate [4];
- byte data_offset [4];
- byte unused2 [8];
- };
-
- // Header for currently loaded file
- header_t const& header() const { return *(header_t const*) data; }
-
- static gme_type_t static_type() { return gme_vgm_type; }
-
-public:
- // deprecated
- Music_Emu::load;
- blargg_err_t load( header_t const& h, Data_Reader& in ) // use Remaining_Reader
- { return load_remaining_( &h, sizeof h, in ); }
- byte const* gd3_data( int* size_out = 0 ) const; // use track_info()
-
-public:
- Vgm_Emu();
- ~Vgm_Emu();
-protected:
- blargg_err_t track_info_( track_info_t*, int track ) const;
- blargg_err_t load_mem_( byte const*, long );
- blargg_err_t set_sample_rate_( long sample_rate );
- blargg_err_t start_track_( int );
- blargg_err_t play_( long count, sample_t* );
- blargg_err_t run_clocks( blip_time_t&, int );
- void set_tempo_( double );
- void mute_voices_( int mask );
- void set_voice( int, Blip_Buffer*, Blip_Buffer*, Blip_Buffer* );
- void update_eq( blip_eq_t const& );
-private:
- // removed; use disable_oversampling() and set_tempo() instead
- Vgm_Emu( bool oversample, double tempo = 1.0 );
- double fm_rate;
- long psg_rate;
- long vgm_rate;
- bool disable_oversampling_;
- bool uses_fm;
- blargg_err_t setup_fm();
-};
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Vgm_Emu_Impl.cpp b/plugins/gme/Game_Music_Emu-0.5.2/gme/Vgm_Emu_Impl.cpp
deleted file mode 100644
index a2d7c93e..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Vgm_Emu_Impl.cpp
+++ /dev/null
@@ -1,314 +0,0 @@
-// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
-
-#include "Vgm_Emu.h"
-
-#include <math.h>
-#include <string.h>
-#include "blargg_endian.h"
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-enum {
- cmd_gg_stereo = 0x4F,
- cmd_psg = 0x50,
- cmd_ym2413 = 0x51,
- cmd_ym2612_port0 = 0x52,
- cmd_ym2612_port1 = 0x53,
- cmd_ym2151 = 0x54,
- cmd_delay = 0x61,
- cmd_delay_735 = 0x62,
- cmd_delay_882 = 0x63,
- cmd_byte_delay = 0x64,
- cmd_end = 0x66,
- cmd_data_block = 0x67,
- cmd_short_delay = 0x70,
- cmd_pcm_delay = 0x80,
- cmd_pcm_seek = 0xE0,
-
- pcm_block_type = 0x00,
- ym2612_dac_port = 0x2A
-};
-
-inline int command_len( int command )
-{
- switch ( command >> 4 )
- {
- case 0x03:
- case 0x04:
- return 2;
-
- case 0x05:
- case 0x0A:
- case 0x0B:
- return 3;
-
- case 0x0C:
- case 0x0D:
- return 4;
-
- case 0x0E:
- case 0x0F:
- return 5;
- }
-
- check( false );
- return 1;
-}
-
-template<class Emu>
-inline void Ym_Emu<Emu>::begin_frame( short* p )
-{
- require( enabled() );
- out = p;
- last_time = 0;
-}
-
-template<class Emu>
-inline int Ym_Emu<Emu>::run_until( int time )
-{
- int count = time - last_time;
- if ( count > 0 )
- {
- if ( last_time < 0 )
- return false;
- last_time = time;
- short* p = out;
- out += count * Emu::out_chan_count;
- Emu::run( count, p );
- }
- return true;
-}
-
-inline Vgm_Emu_Impl::fm_time_t Vgm_Emu_Impl::to_fm_time( vgm_time_t t ) const
-{
- return (t * fm_time_factor + fm_time_offset) >> fm_time_bits;
-}
-
-inline blip_time_t Vgm_Emu_Impl::to_blip_time( vgm_time_t t ) const
-{
- return (t * blip_time_factor) >> blip_time_bits;
-}
-
-void Vgm_Emu_Impl::write_pcm( vgm_time_t vgm_time, int amp )
-{
- blip_time_t blip_time = to_blip_time( vgm_time );
- int old = dac_amp;
- int delta = amp - old;
- dac_amp = amp;
- if ( old >= 0 )
- dac_synth.offset_inline( blip_time, delta, &blip_buf );
- else
- dac_amp |= dac_disabled;
-}
-
-blip_time_t Vgm_Emu_Impl::run_commands( vgm_time_t end_time )
-{
- vgm_time_t vgm_time = this->vgm_time;
- byte const* pos = this->pos;
- if ( pos >= data_end )
- {
- set_track_ended();
- if ( pos > data_end )
- set_warning( "Stream lacked end event" );
- }
-
- while ( vgm_time < end_time && pos < data_end )
- {
- // TODO: be sure there are enough bytes left in stream for particular command
- // so we don't read past end
- switch ( *pos++ )
- {
- case cmd_end:
- pos = loop_begin; // if not looped, loop_begin == data_end
- break;
-
- case cmd_delay_735:
- vgm_time += 735;
- break;
-
- case cmd_delay_882:
- vgm_time += 882;
- break;
-
- case cmd_gg_stereo:
- psg.write_ggstereo( to_blip_time( vgm_time ), *pos++ );
- break;
-
- case cmd_psg:
- psg.write_data( to_blip_time( vgm_time ), *pos++ );
- break;
-
- case cmd_delay:
- vgm_time += pos [1] * 0x100L + pos [0];
- pos += 2;
- break;
-
- case cmd_byte_delay:
- vgm_time += *pos++;
- break;
-
- case cmd_ym2413:
- if ( ym2413.run_until( to_fm_time( vgm_time ) ) )
- ym2413.write( pos [0], pos [1] );
- pos += 2;
- break;
-
- case cmd_ym2612_port0:
- if ( pos [0] == ym2612_dac_port )
- {
- write_pcm( vgm_time, pos [1] );
- }
- else if ( ym2612.run_until( to_fm_time( vgm_time ) ) )
- {
- if ( pos [0] == 0x2B )
- {
- dac_disabled = (pos [1] >> 7 & 1) - 1;
- dac_amp |= dac_disabled;
- }
- ym2612.write0( pos [0], pos [1] );
- }
- pos += 2;
- break;
-
- case cmd_ym2612_port1:
- if ( ym2612.run_until( to_fm_time( vgm_time ) ) )
- ym2612.write1( pos [0], pos [1] );
- pos += 2;
- break;
-
- case cmd_data_block: {
- check( *pos == cmd_end );
- int type = pos [1];
- long size = get_le32( pos + 2 );
- pos += 6;
- if ( type == pcm_block_type )
- pcm_data = pos;
- pos += size;
- break;
- }
-
- case cmd_pcm_seek:
- pcm_pos = pcm_data + pos [3] * 0x1000000L + pos [2] * 0x10000L +
- pos [1] * 0x100L + pos [0];
- pos += 4;
- break;
-
- default:
- int cmd = pos [-1];
- switch ( cmd & 0xF0 )
- {
- case cmd_pcm_delay:
- write_pcm( vgm_time, *pcm_pos++ );
- vgm_time += cmd & 0x0F;
- break;
-
- case cmd_short_delay:
- vgm_time += (cmd & 0x0F) + 1;
- break;
-
- case 0x50:
- pos += 2;
- break;
-
- default:
- pos += command_len( cmd ) - 1;
- set_warning( "Unknown stream event" );
- }
- }
- }
- vgm_time -= end_time;
- this->pos = pos;
- this->vgm_time = vgm_time;
-
- return to_blip_time( end_time );
-}
-
-int Vgm_Emu_Impl::play_frame( blip_time_t blip_time, int sample_count, sample_t* buf )
-{
- // to do: timing is working mostly by luck
-
- int min_pairs = sample_count >> 1;
- int vgm_time = ((long) min_pairs << fm_time_bits) / fm_time_factor - 1;
- assert( to_fm_time( vgm_time ) <= min_pairs );
- int pairs = min_pairs;
- while ( (pairs = to_fm_time( vgm_time )) < min_pairs )
- vgm_time++;
- //dprintf( "pairs: %d, min_pairs: %d\n", pairs, min_pairs );
-
- if ( ym2612.enabled() )
- {
- ym2612.begin_frame( buf );
- memset( buf, 0, pairs * stereo * sizeof *buf );
- }
- else if ( ym2413.enabled() )
- {
- ym2413.begin_frame( buf );
- }
-
- run_commands( vgm_time );
- ym2612.run_until( pairs );
- ym2413.run_until( pairs );
-
- fm_time_offset = (vgm_time * fm_time_factor + fm_time_offset) -
- ((long) pairs << fm_time_bits);
-
- psg.end_frame( blip_time );
-
- return pairs * stereo;
-}
-
-// Update pre-1.10 header FM rates by scanning commands
-void Vgm_Emu_Impl::update_fm_rates( long* ym2413_rate, long* ym2612_rate ) const
-{
- byte const* p = data + 0x40;
- while ( p < data_end )
- {
- switch ( *p )
- {
- case cmd_end:
- return;
-
- case cmd_psg:
- case cmd_byte_delay:
- p += 2;
- break;
-
- case cmd_delay:
- p += 3;
- break;
-
- case cmd_data_block:
- p += 7 + get_le32( p + 3 );
- break;
-
- case cmd_ym2413:
- *ym2612_rate = 0;
- return;
-
- case cmd_ym2612_port0:
- case cmd_ym2612_port1:
- *ym2612_rate = *ym2413_rate;
- *ym2413_rate = 0;
- return;
-
- case cmd_ym2151:
- *ym2413_rate = 0;
- *ym2612_rate = 0;
- return;
-
- default:
- p += command_len( *p );
- }
- }
-}
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Vgm_Emu_Impl.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/Vgm_Emu_Impl.h
deleted file mode 100644
index 4d387d09..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Vgm_Emu_Impl.h
+++ /dev/null
@@ -1,71 +0,0 @@
-// Low-level parts of Vgm_Emu
-
-// Game_Music_Emu 0.5.2
-#ifndef VGM_EMU_IMPL_H
-#define VGM_EMU_IMPL_H
-
-#include "Dual_Resampler.h"
-#include "Classic_Emu.h"
-#include "Ym2413_Emu.h"
-#include "Ym2612_Emu.h"
-#include "Sms_Apu.h"
-
-template<class Emu>
-class Ym_Emu : public Emu {
-protected:
- int last_time;
- short* out;
- enum { disabled_time = -1 };
-public:
- Ym_Emu() : last_time( disabled_time ), out( NULL ) { }
- void enable( bool b ) { last_time = b ? 0 : disabled_time; }
- bool enabled() const { return last_time != disabled_time; }
- void begin_frame( short* p );
- int run_until( int time );
-};
-
-class Vgm_Emu_Impl : public Classic_Emu, private Dual_Resampler {
-public:
- typedef Classic_Emu::sample_t sample_t;
-protected:
- enum { stereo = 2 };
-
- typedef int vgm_time_t;
-
- enum { fm_time_bits = 12 };
- typedef int fm_time_t;
- long fm_time_offset;
- int fm_time_factor;
- fm_time_t to_fm_time( vgm_time_t ) const;
-
- enum { blip_time_bits = 12 };
- int blip_time_factor;
- blip_time_t to_blip_time( vgm_time_t ) const;
-
- byte const* data;
- byte const* loop_begin;
- byte const* data_end;
- void update_fm_rates( long* ym2413_rate, long* ym2612_rate ) const;
-
- vgm_time_t vgm_time;
- byte const* pos;
- blip_time_t run_commands( vgm_time_t );
- int play_frame( blip_time_t blip_time, int sample_count, sample_t* buf );
-
- byte const* pcm_data;
- byte const* pcm_pos;
- int dac_amp;
- int dac_disabled; // -1 if disabled
- void write_pcm( vgm_time_t, int amp );
-
- Ym_Emu<Ym2612_Emu> ym2612;
- Ym_Emu<Ym2413_Emu> ym2413;
-
- Blip_Buffer blip_buf;
- Sms_Apu psg;
- Blip_Synth<blip_med_quality,1> dac_synth;
-
- friend class Vgm_Emu;
-};
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Ym2413_Emu.cpp b/plugins/gme/Game_Music_Emu-0.5.2/gme/Ym2413_Emu.cpp
deleted file mode 100644
index ede67304..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Ym2413_Emu.cpp
+++ /dev/null
@@ -1,21 +0,0 @@
-
-// Use in place of Ym2413_Emu.cpp and ym2413.c to disable support for this chip
-
-// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
-
-#include "Ym2413_Emu.h"
-
-Ym2413_Emu::Ym2413_Emu() { }
-
-Ym2413_Emu::~Ym2413_Emu() { }
-
-int Ym2413_Emu::set_rate( double, double ) { return 2; }
-
-void Ym2413_Emu::reset() { }
-
-void Ym2413_Emu::write( int, int ) { }
-
-void Ym2413_Emu::mute_voices( int ) { }
-
-void Ym2413_Emu::run( int, sample_t* ) { }
-
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Ym2413_Emu.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/Ym2413_Emu.h
deleted file mode 100644
index 98a2a48e..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Ym2413_Emu.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// YM2413 FM sound chip emulator interface
-
-// Game_Music_Emu 0.5.2
-#ifndef YM2413_EMU_H
-#define YM2413_EMU_H
-
-class Ym2413_Emu {
- struct OPLL* opll;
-public:
- Ym2413_Emu();
- ~Ym2413_Emu();
-
- // Set output sample rate and chip clock rates, in Hz. Returns non-zero
- // if error.
- int set_rate( double sample_rate, double clock_rate );
-
- // Reset to power-up state
- void reset();
-
- // Mute voice n if bit n (1 << n) of mask is set
- enum { channel_count = 14 };
- void mute_voices( int mask );
-
- // Write 'data' to 'addr'
- void write( int addr, int data );
-
- // Run and write pair_count samples to output
- typedef short sample_t;
- enum { out_chan_count = 2 }; // stereo
- void run( int pair_count, sample_t* out );
-};
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Ym2612_Emu.cpp b/plugins/gme/Game_Music_Emu-0.5.2/gme/Ym2612_Emu.cpp
deleted file mode 100644
index 41ebb093..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Ym2612_Emu.cpp
+++ /dev/null
@@ -1,1319 +0,0 @@
-// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
-
-// Based on Gens 2.10 ym2612.c
-
-#include "Ym2612_Emu.h"
-
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include <limits.h>
-#include <stdio.h>
-#include <math.h>
-
-/* Copyright (C) 2002 Stéphane Dallongeville (gens AT consolemul.com) */
-/* Copyright (C) 2004-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-// This is mostly the original source in its C style and all.
-//
-// Somewhat optimized and simplified. Uses a template to generate the many
-// variants of Update_Chan. Rewrote header file. In need of full rewrite by
-// someone more familiar with FM sound and the YM2612. Has some inaccuracies
-// compared to the Sega Genesis sound, particularly being mixed at such a
-// high sample accuracy (the Genesis sounds like it has only 8 bit samples).
-// - Shay
-
-#ifdef BLARGG_ENABLE_OPTIMIZER
- #include BLARGG_ENABLE_OPTIMIZER
-#endif
-
-const int output_bits = 14;
-
-struct slot_t
-{
- const int *DT; // parametre detune
- int MUL; // parametre "multiple de frequence"
- int TL; // Total Level = volume lorsque l'enveloppe est au plus haut
- int TLL; // Total Level ajusted
- int SLL; // Sustin Level (ajusted) = volume où l'enveloppe termine sa premiere phase de regression
- int KSR_S; // Key Scale Rate Shift = facteur de prise en compte du KSL dans la variations de l'enveloppe
- int KSR; // Key Scale Rate = cette valeur est calculee par rapport à la frequence actuelle, elle va influer
- // sur les differents parametres de l'enveloppe comme l'attaque, le decay ... comme dans la realite !
- int SEG; // Type enveloppe SSG
- int env_xor;
- int env_max;
-
- const int *AR; // Attack Rate (table pointeur) = Taux d'attaque (AR[KSR])
- const int *DR; // Decay Rate (table pointeur) = Taux pour la regression (DR[KSR])
- const int *SR; // Sustin Rate (table pointeur) = Taux pour le maintien (SR[KSR])
- const int *RR; // Release Rate (table pointeur) = Taux pour le rel'chement (RR[KSR])
- int Fcnt; // Frequency Count = compteur-frequence pour determiner l'amplitude actuelle (SIN[Finc >> 16])
- int Finc; // frequency step = pas d'incrementation du compteur-frequence
- // plus le pas est grand, plus la frequence est aïgu (ou haute)
- int Ecurp; // Envelope current phase = cette variable permet de savoir dans quelle phase
- // de l'enveloppe on se trouve, par exemple phase d'attaque ou phase de maintenue ...
- // en fonction de la valeur de cette variable, on va appeler une fonction permettant
- // de mettre à jour l'enveloppe courante.
- int Ecnt; // Envelope counter = le compteur-enveloppe permet de savoir où l'on se trouve dans l'enveloppe
- int Einc; // Envelope step courant
- int Ecmp; // Envelope counter limite pour la prochaine phase
- int EincA; // Envelope step for Attack = pas d'incrementation du compteur durant la phase d'attaque
- // cette valeur est egal à AR[KSR]
- int EincD; // Envelope step for Decay = pas d'incrementation du compteur durant la phase de regression
- // cette valeur est egal à DR[KSR]
- int EincS; // Envelope step for Sustain = pas d'incrementation du compteur durant la phase de maintenue
- // cette valeur est egal à SR[KSR]
- int EincR; // Envelope step for Release = pas d'incrementation du compteur durant la phase de rel'chement
- // cette valeur est egal à RR[KSR]
- int *OUTp; // pointeur of SLOT output = pointeur permettant de connecter la sortie de ce slot à l'entree
- // d'un autre ou carrement à la sortie de la voie
- int INd; // input data of the slot = donnees en entree du slot
- int ChgEnM; // Change envelop mask.
- int AMS; // AMS depth level of this SLOT = degre de modulation de l'amplitude par le LFO
- int AMSon; // AMS enable flag = drapeau d'activation de l'AMS
-};
-
-struct channel_t
-{
- int S0_OUT[4]; // anciennes sorties slot 0 (pour le feed back)
- int LEFT; // LEFT enable flag
- int RIGHT; // RIGHT enable flag
- int ALGO; // Algorythm = determine les connections entre les operateurs
- int FB; // shift count of self feed back = degre de "Feed-Back" du SLOT 1 (il est son unique entree)
- int FMS; // Frequency Modulation Sensitivity of channel = degre de modulation de la frequence sur la voie par le LFO
- int AMS; // Amplitude Modulation Sensitivity of channel = degre de modulation de l'amplitude sur la voie par le LFO
- int FNUM[4]; // hauteur frequence de la voie (+ 3 pour le mode special)
- int FOCT[4]; // octave de la voie (+ 3 pour le mode special)
- int KC[4]; // Key Code = valeur fonction de la frequence (voir KSR pour les slots, KSR = KC >> KSR_S)
- slot_t SLOT[4]; // four slot.operators = les 4 slots de la voie
- int FFlag; // Frequency step recalculation flag
-};
-
-struct state_t
-{
- int TimerBase; // TimerBase calculation
- int Status; // YM2612 Status (timer overflow)
- int TimerA; // timerA limit = valeur jusqu'à laquelle le timer A doit compter
- int TimerAL;
- int TimerAcnt; // timerA counter = valeur courante du Timer A
- int TimerB; // timerB limit = valeur jusqu'à laquelle le timer B doit compter
- int TimerBL;
- int TimerBcnt; // timerB counter = valeur courante du Timer B
- int Mode; // Mode actuel des voie 3 et 6 (normal / special)
- int DAC; // DAC enabled flag
- channel_t CHANNEL[Ym2612_Emu::channel_count]; // Les 6 voies du YM2612
- int REG[2][0x100]; // Sauvegardes des valeurs de tout les registres, c'est facultatif
- // cela nous rend le debuggage plus facile
-};
-
-#ifndef PI
-#define PI 3.14159265358979323846
-#endif
-
-#define ATTACK 0
-#define DECAY 1
-#define SUBSTAIN 2
-#define RELEASE 3
-
-// SIN_LBITS <= 16
-// LFO_HBITS <= 16
-// (SIN_LBITS + SIN_HBITS) <= 26
-// (ENV_LBITS + ENV_HBITS) <= 28
-// (LFO_LBITS + LFO_HBITS) <= 28
-
-#define SIN_HBITS 12 // Sinus phase counter int part
-#define SIN_LBITS (26 - SIN_HBITS) // Sinus phase counter float part (best setting)
-
-#if (SIN_LBITS > 16)
-#define SIN_LBITS 16 // Can't be greater than 16 bits
-#endif
-
-#define ENV_HBITS 12 // Env phase counter int part
-#define ENV_LBITS (28 - ENV_HBITS) // Env phase counter float part (best setting)
-
-#define LFO_HBITS 10 // LFO phase counter int part
-#define LFO_LBITS (28 - LFO_HBITS) // LFO phase counter float part (best setting)
-
-#define SIN_LENGHT (1 << SIN_HBITS)
-#define ENV_LENGHT (1 << ENV_HBITS)
-#define LFO_LENGHT (1 << LFO_HBITS)
-
-#define TL_LENGHT (ENV_LENGHT * 3) // Env + TL scaling + LFO
-
-#define SIN_MASK (SIN_LENGHT - 1)
-#define ENV_MASK (ENV_LENGHT - 1)
-#define LFO_MASK (LFO_LENGHT - 1)
-
-#define ENV_STEP (96.0 / ENV_LENGHT) // ENV_MAX = 96 dB
-
-#define ENV_ATTACK ((ENV_LENGHT * 0) << ENV_LBITS)
-#define ENV_DECAY ((ENV_LENGHT * 1) << ENV_LBITS)
-#define ENV_END ((ENV_LENGHT * 2) << ENV_LBITS)
-
-#define MAX_OUT_BITS (SIN_HBITS + SIN_LBITS + 2) // Modulation = -4 <--> +4
-#define MAX_OUT ((1 << MAX_OUT_BITS) - 1)
-
-#define PG_CUT_OFF ((int) (78.0 / ENV_STEP))
-#define ENV_CUT_OFF ((int) (68.0 / ENV_STEP))
-
-#define AR_RATE 399128
-#define DR_RATE 5514396
-
-//#define AR_RATE 426136
-//#define DR_RATE (AR_RATE * 12)
-
-#define LFO_FMS_LBITS 9 // FIXED (LFO_FMS_BASE gives somethink as 1)
-#define LFO_FMS_BASE ((int) (0.05946309436 * 0.0338 * (double) (1 << LFO_FMS_LBITS)))
-
-#define S0 0 // Stupid typo of the YM2612
-#define S1 2
-#define S2 1
-#define S3 3
-
-inline void set_seg( slot_t& s, int seg )
-{
- s.env_xor = 0;
- s.env_max = INT_MAX;
- s.SEG = seg;
- if ( seg & 4 )
- {
- s.env_xor = ENV_MASK;
- s.env_max = ENV_MASK;
- }
-}
-
-struct tables_t
-{
- short SIN_TAB [SIN_LENGHT]; // SINUS TABLE (offset into TL TABLE)
- int LFOcnt; // LFO counter = compteur-frequence pour le LFO
- int LFOinc; // LFO step counter = pas d'incrementation du compteur-frequence du LFO
- // plus le pas est grand, plus la frequence est grande
- unsigned int AR_TAB [128]; // Attack rate table
- unsigned int DR_TAB [96]; // Decay rate table
- unsigned int DT_TAB [8] [32]; // Detune table
- unsigned int SL_TAB [16]; // Substain level table
- unsigned int NULL_RATE [32]; // Table for NULL rate
- int LFO_INC_TAB [8]; // LFO step table
-
- short ENV_TAB [2 * ENV_LENGHT + 8]; // ENV CURVE TABLE (attack & decay)
-
- short LFO_ENV_TAB [LFO_LENGHT]; // LFO AMS TABLE (adjusted for 11.8 dB)
- short LFO_FREQ_TAB [LFO_LENGHT]; // LFO FMS TABLE
- int TL_TAB [TL_LENGHT * 2]; // TOTAL LEVEL TABLE (positif and minus)
- unsigned int DECAY_TO_ATTACK [ENV_LENGHT]; // Conversion from decay to attack phase
- unsigned int FINC_TAB [2048]; // Frequency step table
-};
-
-static const unsigned char DT_DEF_TAB [4 * 32] =
-{
-// FD = 0
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-
-// FD = 1
- 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2,
- 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 8, 8, 8, 8,
-
-// FD = 2
- 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5,
- 5, 6, 6, 7, 8, 8, 9, 10, 11, 12, 13, 14, 16, 16, 16, 16,
-
-// FD = 3
- 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7,
- 8 , 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 20, 22, 22, 22, 22
-};
-
-static const unsigned char FKEY_TAB [16] =
-{
- 0, 0, 0, 0,
- 0, 0, 0, 1,
- 2, 3, 3, 3,
- 3, 3, 3, 3
-};
-
-static const unsigned char LFO_AMS_TAB [4] =
-{
- 31, 4, 1, 0
-};
-
-static const unsigned char LFO_FMS_TAB [8] =
-{
- LFO_FMS_BASE * 0, LFO_FMS_BASE * 1,
- LFO_FMS_BASE * 2, LFO_FMS_BASE * 3,
- LFO_FMS_BASE * 4, LFO_FMS_BASE * 6,
- LFO_FMS_BASE * 12, LFO_FMS_BASE * 24
-};
-
-inline void YM2612_Special_Update() { }
-
-struct Ym2612_Impl
-{
- enum { channel_count = Ym2612_Emu::channel_count };
-
- state_t YM2612;
- int mute_mask;
- tables_t g;
-
- void KEY_ON( channel_t&, int );
- void KEY_OFF( channel_t&, int );
- int SLOT_SET( int, int );
- int CHANNEL_SET( int, int );
- int YM_SET( int, int );
-
- void set_rate( double sample_rate, double clock_factor );
- void reset();
- void write0( int addr, int data );
- void write1( int addr, int data );
- void run_timer( int );
- void run( int pair_count, Ym2612_Emu::sample_t* );
-};
-
-void Ym2612_Impl::KEY_ON( channel_t& ch, int nsl)
-{
- slot_t *SL = &(ch.SLOT [nsl]); // on recupere le bon pointeur de slot
-
- if (SL->Ecurp == RELEASE) // la touche est-elle rel'chee ?
- {
- SL->Fcnt = 0;
-
- // Fix Ecco 2 splash sound
-
- SL->Ecnt = (g.DECAY_TO_ATTACK [g.ENV_TAB [SL->Ecnt >> ENV_LBITS]] + ENV_ATTACK) & SL->ChgEnM;
- SL->ChgEnM = ~0;
-
-// SL->Ecnt = g.DECAY_TO_ATTACK [g.ENV_TAB [SL->Ecnt >> ENV_LBITS]] + ENV_ATTACK;
-// SL->Ecnt = 0;
-
- SL->Einc = SL->EincA;
- SL->Ecmp = ENV_DECAY;
- SL->Ecurp = ATTACK;
- }
-}
-
-
-void Ym2612_Impl::KEY_OFF(channel_t& ch, int nsl)
-{
- slot_t *SL = &(ch.SLOT [nsl]); // on recupere le bon pointeur de slot
-
- if (SL->Ecurp != RELEASE) // la touche est-elle appuyee ?
- {
- if (SL->Ecnt < ENV_DECAY) // attack phase ?
- {
- SL->Ecnt = (g.ENV_TAB [SL->Ecnt >> ENV_LBITS] << ENV_LBITS) + ENV_DECAY;
- }
-
- SL->Einc = SL->EincR;
- SL->Ecmp = ENV_END;
- SL->Ecurp = RELEASE;
- }
-}
-
-
-int Ym2612_Impl::SLOT_SET( int Adr, int data )
-{
- int nch = Adr & 3;
- if ( nch == 3 )
- return 1;
-
- channel_t& ch = YM2612.CHANNEL [nch + (Adr & 0x100 ? 3 : 0)];
- slot_t& sl = ch.SLOT [(Adr >> 2) & 3];
-
- switch ( Adr & 0xF0 )
- {
- case 0x30:
- if ( (sl.MUL = (data & 0x0F)) != 0 ) sl.MUL <<= 1;
- else sl.MUL = 1;
-
- sl.DT = (int*) g.DT_TAB [(data >> 4) & 7];
-
- ch.SLOT [0].Finc = -1;
-
- break;
-
- case 0x40:
- sl.TL = data & 0x7F;
-
- // SOR2 do a lot of TL adjustement and this fix R.Shinobi jump sound...
- YM2612_Special_Update();
-
-#if ((ENV_HBITS - 7) < 0)
- sl.TLL = sl.TL >> (7 - ENV_HBITS);
-#else
- sl.TLL = sl.TL << (ENV_HBITS - 7);
-#endif
-
- break;
-
- case 0x50:
- sl.KSR_S = 3 - (data >> 6);
-
- ch.SLOT [0].Finc = -1;
-
- if (data &= 0x1F) sl.AR = (int*) &g.AR_TAB [data << 1];
- else sl.AR = (int*) &g.NULL_RATE [0];
-
- sl.EincA = sl.AR [sl.KSR];
- if (sl.Ecurp == ATTACK) sl.Einc = sl.EincA;
- break;
-
- case 0x60:
- if ( (sl.AMSon = (data & 0x80)) != 0 ) sl.AMS = ch.AMS;
- else sl.AMS = 31;
-
- if (data &= 0x1F) sl.DR = (int*) &g.DR_TAB [data << 1];
- else sl.DR = (int*) &g.NULL_RATE [0];
-
- sl.EincD = sl.DR [sl.KSR];
- if (sl.Ecurp == DECAY) sl.Einc = sl.EincD;
- break;
-
- case 0x70:
- if (data &= 0x1F) sl.SR = (int*) &g.DR_TAB [data << 1];
- else sl.SR = (int*) &g.NULL_RATE [0];
-
- sl.EincS = sl.SR [sl.KSR];
- if ((sl.Ecurp == SUBSTAIN) && (sl.Ecnt < ENV_END)) sl.Einc = sl.EincS;
- break;
-
- case 0x80:
- sl.SLL = g.SL_TAB [data >> 4];
-
- sl.RR = (int*) &g.DR_TAB [((data & 0xF) << 2) + 2];
-
- sl.EincR = sl.RR [sl.KSR];
- if ((sl.Ecurp == RELEASE) && (sl.Ecnt < ENV_END)) sl.Einc = sl.EincR;
- break;
-
- case 0x90:
- // SSG-EG envelope shapes :
- /*
- E At Al H
-
- 1 0 0 0 \\\\
- 1 0 0 1 \___
- 1 0 1 0 \/\/
- 1 0 1 1 \
- 1 1 0 0 ////
- 1 1 0 1 /
- 1 1 1 0 /\/\
- 1 1 1 1 /___
-
- E = SSG-EG enable
- At = Start negate
- Al = Altern
- H = Hold */
-
- set_seg( sl, (data & 8) ? (data & 0x0F) : 0 );
- break;
- }
-
- return 0;
-}
-
-
-int Ym2612_Impl::CHANNEL_SET( int Adr, int data )
-{
- int num = Adr & 3;
- if ( num == 3 )
- return 1;
-
- channel_t& ch = YM2612.CHANNEL [num + (Adr & 0x100 ? 3 : 0)];
-
- switch ( Adr & 0xFC )
- {
- case 0xA0:
- YM2612_Special_Update();
-
- ch.FNUM [0] = (ch.FNUM [0] & 0x700) + data;
- ch.KC [0] = (ch.FOCT [0] << 2) | FKEY_TAB [ch.FNUM [0] >> 7];
-
- ch.SLOT [0].Finc = -1;
- break;
-
- case 0xA4:
- YM2612_Special_Update();
-
- ch.FNUM [0] = (ch.FNUM [0] & 0x0FF) + ((data & 0x07) << 8);
- ch.FOCT [0] = (data & 0x38) >> 3;
- ch.KC [0] = (ch.FOCT [0] << 2) | FKEY_TAB [ch.FNUM [0] >> 7];
-
- ch.SLOT [0].Finc = -1;
- break;
-
- case 0xA8:
- if ( Adr < 0x100 )
- {
- num++;
-
- YM2612_Special_Update();
-
- YM2612.CHANNEL [2].FNUM [num] = (YM2612.CHANNEL [2].FNUM [num] & 0x700) + data;
- YM2612.CHANNEL [2].KC [num] = (YM2612.CHANNEL [2].FOCT [num] << 2) |
- FKEY_TAB [YM2612.CHANNEL [2].FNUM [num] >> 7];
-
- YM2612.CHANNEL [2].SLOT [0].Finc = -1;
- }
- break;
-
- case 0xAC:
- if ( Adr < 0x100 )
- {
- num++;
-
- YM2612_Special_Update();
-
- YM2612.CHANNEL [2].FNUM [num] = (YM2612.CHANNEL [2].FNUM [num] & 0x0FF) + ((data & 0x07) << 8);
- YM2612.CHANNEL [2].FOCT [num] = (data & 0x38) >> 3;
- YM2612.CHANNEL [2].KC [num] = (YM2612.CHANNEL [2].FOCT [num] << 2) |
- FKEY_TAB [YM2612.CHANNEL [2].FNUM [num] >> 7];
-
- YM2612.CHANNEL [2].SLOT [0].Finc = -1;
- }
- break;
-
- case 0xB0:
- if ( ch.ALGO != (data & 7) )
- {
- // Fix VectorMan 2 heli sound (level 1)
- YM2612_Special_Update();
-
- ch.ALGO = data & 7;
-
- ch.SLOT [0].ChgEnM = 0;
- ch.SLOT [1].ChgEnM = 0;
- ch.SLOT [2].ChgEnM = 0;
- ch.SLOT [3].ChgEnM = 0;
- }
-
- ch.FB = 9 - ((data >> 3) & 7); // Real thing ?
-
-// if (ch.FB = ((data >> 3) & 7)) ch.FB = 9 - ch.FB; // Thunder force 4 (music stage 8), Gynoug, Aladdin bug sound...
-// else ch.FB = 31;
- break;
-
- case 0xB4: {
- YM2612_Special_Update();
-
- ch.LEFT = 0 - ((data >> 7) & 1);
- ch.RIGHT = 0 - ((data >> 6) & 1);
-
- ch.AMS = LFO_AMS_TAB [(data >> 4) & 3];
- ch.FMS = LFO_FMS_TAB [data & 7];
-
- for ( int i = 0; i < 4; i++ )
- {
- slot_t& sl = ch.SLOT [i];
- sl.AMS = (sl.AMSon ? ch.AMS : 31);
- }
- break;
- }
- }
-
- return 0;
-}
-
-
-int Ym2612_Impl::YM_SET(int Adr, int data)
-{
- switch ( Adr )
- {
- case 0x22:
- if (data & 8) // LFO enable
- {
- // Cool Spot music 1, LFO modified severals time which
- // distord the sound, have to check that on a real genesis...
-
- g.LFOinc = g.LFO_INC_TAB [data & 7];
- }
- else
- {
- g.LFOinc = g.LFOcnt = 0;
- }
- break;
-
- case 0x24:
- YM2612.TimerA = (YM2612.TimerA & 0x003) | (((int) data) << 2);
-
- if (YM2612.TimerAL != (1024 - YM2612.TimerA) << 12)
- {
- YM2612.TimerAcnt = YM2612.TimerAL = (1024 - YM2612.TimerA) << 12;
- }
- break;
-
- case 0x25:
- YM2612.TimerA = (YM2612.TimerA & 0x3FC) | (data & 3);
-
- if (YM2612.TimerAL != (1024 - YM2612.TimerA) << 12)
- {
- YM2612.TimerAcnt = YM2612.TimerAL = (1024 - YM2612.TimerA) << 12;
- }
- break;
-
- case 0x26:
- YM2612.TimerB = data;
-
- if (YM2612.TimerBL != (256 - YM2612.TimerB) << (4 + 12))
- {
- YM2612.TimerBcnt = YM2612.TimerBL = (256 - YM2612.TimerB) << (4 + 12);
- }
- break;
-
- case 0x27:
- // Parametre divers
- // b7 = CSM MODE
- // b6 = 3 slot mode
- // b5 = reset b
- // b4 = reset a
- // b3 = timer enable b
- // b2 = timer enable a
- // b1 = load b
- // b0 = load a
-
- if ((data ^ YM2612.Mode) & 0x40)
- {
- // We changed the channel 2 mode, so recalculate phase step
- // This fix the punch sound in Street of Rage 2
-
- YM2612_Special_Update();
-
- YM2612.CHANNEL [2].SLOT [0].Finc = -1; // recalculate phase step
- }
-
-// if ((data & 2) && (YM2612.Status & 2)) YM2612.TimerBcnt = YM2612.TimerBL;
-// if ((data & 1) && (YM2612.Status & 1)) YM2612.TimerAcnt = YM2612.TimerAL;
-
-// YM2612.Status &= (~data >> 4); // Reset du Status au cas ou c'est demande
- YM2612.Status &= (~data >> 4) & (data >> 2); // Reset Status
-
- YM2612.Mode = data;
- break;
-
- case 0x28: {
- int nch = data & 3;
- if ( nch == 3 )
- return 1;
- if ( data & 4 )
- nch += 3;
- channel_t& ch = YM2612.CHANNEL [nch];
-
- YM2612_Special_Update();
-
- if (data & 0x10) KEY_ON(ch, S0); // On appuie sur la touche pour le slot 1
- else KEY_OFF(ch, S0); // On rel'che la touche pour le slot 1
- if (data & 0x20) KEY_ON(ch, S1); // On appuie sur la touche pour le slot 3
- else KEY_OFF(ch, S1); // On rel'che la touche pour le slot 3
- if (data & 0x40) KEY_ON(ch, S2); // On appuie sur la touche pour le slot 2
- else KEY_OFF(ch, S2); // On rel'che la touche pour le slot 2
- if (data & 0x80) KEY_ON(ch, S3); // On appuie sur la touche pour le slot 4
- else KEY_OFF(ch, S3); // On rel'che la touche pour le slot 4
- break;
- }
-
- case 0x2B:
- if (YM2612.DAC ^ (data & 0x80)) YM2612_Special_Update();
-
- YM2612.DAC = data & 0x80; // activation/desactivation du DAC
- break;
- }
-
- return 0;
-}
-
-void Ym2612_Impl::set_rate( double sample_rate, double clock_rate )
-{
- assert( sample_rate );
- assert( clock_rate > sample_rate );
-
- int i;
-
- // 144 = 12 * (prescale * 2) = 12 * 6 * 2
- // prescale set to 6 by default
-
- double Frequence = clock_rate / sample_rate / 144.0;
- if ( fabs( Frequence - 1.0 ) < 0.0000001 )
- Frequence = 1.0;
- YM2612.TimerBase = int (Frequence * 4096.0);
-
- // Tableau TL :
- // [0 - 4095] = +output [4095 - ...] = +output overflow (fill with 0)
- // [12288 - 16383] = -output [16384 - ...] = -output overflow (fill with 0)
-
- for(i = 0; i < TL_LENGHT; i++)
- {
- if (i >= PG_CUT_OFF) // YM2612 cut off sound after 78 dB (14 bits output ?)
- {
- g.TL_TAB [TL_LENGHT + i] = g.TL_TAB [i] = 0;
- }
- else
- {
- double x = MAX_OUT; // Max output
- x /= pow( 10.0, (ENV_STEP * i) / 20.0 ); // Decibel -> Voltage
-
- g.TL_TAB [i] = (int) x;
- g.TL_TAB [TL_LENGHT + i] = -g.TL_TAB [i];
- }
- }
-
- // Tableau SIN :
- // g.SIN_TAB [x] [y] = sin(x) * y;
- // x = phase and y = volume
-
- g.SIN_TAB [0] = g.SIN_TAB [SIN_LENGHT / 2] = PG_CUT_OFF;
-
- for(i = 1; i <= SIN_LENGHT / 4; i++)
- {
- double x = sin(2.0 * PI * (double) (i) / (double) (SIN_LENGHT)); // Sinus
- x = 20 * log10(1 / x); // convert to dB
-
- int j = (int) (x / ENV_STEP); // Get TL range
-
- if (j > PG_CUT_OFF) j = (int) PG_CUT_OFF;
-
- g.SIN_TAB [i] = g.SIN_TAB [(SIN_LENGHT / 2) - i] = j;
- g.SIN_TAB [(SIN_LENGHT / 2) + i] = g.SIN_TAB [SIN_LENGHT - i] = TL_LENGHT + j;
- }
-
- // Tableau LFO (LFO wav) :
-
- for(i = 0; i < LFO_LENGHT; i++)
- {
- double x = sin(2.0 * PI * (double) (i) / (double) (LFO_LENGHT)); // Sinus
- x += 1.0;
- x /= 2.0; // positive only
- x *= 11.8 / ENV_STEP; // ajusted to MAX enveloppe modulation
-
- g.LFO_ENV_TAB [i] = (int) x;
-
- x = sin(2.0 * PI * (double) (i) / (double) (LFO_LENGHT)); // Sinus
- x *= (double) ((1 << (LFO_HBITS - 1)) - 1);
-
- g.LFO_FREQ_TAB [i] = (int) x;
-
- }
-
- // Tableau Enveloppe :
- // g.ENV_TAB [0] -> g.ENV_TAB [ENV_LENGHT - 1] = attack curve
- // g.ENV_TAB [ENV_LENGHT] -> g.ENV_TAB [2 * ENV_LENGHT - 1] = decay curve
-
- for(i = 0; i < ENV_LENGHT; i++)
- {
- // Attack curve (x^8 - music level 2 Vectorman 2)
- double x = pow(((double) ((ENV_LENGHT - 1) - i) / (double) (ENV_LENGHT)), 8);
- x *= ENV_LENGHT;
-
- g.ENV_TAB [i] = (int) x;
-
- // Decay curve (just linear)
- x = pow(((double) (i) / (double) (ENV_LENGHT)), 1);
- x *= ENV_LENGHT;
-
- g.ENV_TAB [ENV_LENGHT + i] = (int) x;
- }
- for ( i = 0; i < 8; i++ )
- g.ENV_TAB [i + ENV_LENGHT * 2] = 0;
-
- g.ENV_TAB [ENV_END >> ENV_LBITS] = ENV_LENGHT - 1; // for the stopped state
-
- // Tableau pour la conversion Attack -> Decay and Decay -> Attack
-
- int j = ENV_LENGHT - 1;
- for ( i = 0; i < ENV_LENGHT; i++ )
- {
- while ( j && g.ENV_TAB [j] < i )
- j--;
-
- g.DECAY_TO_ATTACK [i] = j << ENV_LBITS;
- }
-
- // Tableau pour le Substain Level
-
- for(i = 0; i < 15; i++)
- {
- double x = i * 3; // 3 and not 6 (Mickey Mania first music for test)
- x /= ENV_STEP;
-
- g.SL_TAB [i] = ((int) x << ENV_LBITS) + ENV_DECAY;
- }
-
- g.SL_TAB [15] = ((ENV_LENGHT - 1) << ENV_LBITS) + ENV_DECAY; // special case : volume off
-
- // Tableau Frequency Step
-
- for(i = 0; i < 2048; i++)
- {
- double x = (double) (i) * Frequence;
-
-#if ((SIN_LBITS + SIN_HBITS - (21 - 7)) < 0)
- x /= (double) (1 << ((21 - 7) - SIN_LBITS - SIN_HBITS));
-#else
- x *= (double) (1 << (SIN_LBITS + SIN_HBITS - (21 - 7)));
-#endif
-
- x /= 2.0; // because MUL = value * 2
-
- g.FINC_TAB [i] = (unsigned int) x;
- }
-
- // Tableaux Attack & Decay Rate
-
- for(i = 0; i < 4; i++)
- {
- g.AR_TAB [i] = 0;
- g.DR_TAB [i] = 0;
- }
-
- for(i = 0; i < 60; i++)
- {
- double x = Frequence;
-
- x *= 1.0 + ((i & 3) * 0.25); // bits 0-1 : x1.00, x1.25, x1.50, x1.75
- x *= (double) (1 << ((i >> 2))); // bits 2-5 : shift bits (x2^0 - x2^15)
- x *= (double) (ENV_LENGHT << ENV_LBITS); // on ajuste pour le tableau g.ENV_TAB
-
- g.AR_TAB [i + 4] = (unsigned int) (x / AR_RATE);
- g.DR_TAB [i + 4] = (unsigned int) (x / DR_RATE);
- }
-
- for(i = 64; i < 96; i++)
- {
- g.AR_TAB [i] = g.AR_TAB [63];
- g.DR_TAB [i] = g.DR_TAB [63];
-
- g.NULL_RATE [i - 64] = 0;
- }
-
- for ( i = 96; i < 128; i++ )
- g.AR_TAB [i] = 0;
-
- // Tableau Detune
-
- for(i = 0; i < 4; i++)
- {
- for (int j = 0; j < 32; j++)
- {
-#if ((SIN_LBITS + SIN_HBITS - 21) < 0)
- double y = (double) DT_DEF_TAB [(i << 5) + j] * Frequence / (double) (1 << (21 - SIN_LBITS - SIN_HBITS));
-#else
- double y = (double) DT_DEF_TAB [(i << 5) + j] * Frequence * (double) (1 << (SIN_LBITS + SIN_HBITS - 21));
-#endif
-
- g.DT_TAB [i + 0] [j] = (int) y;
- g.DT_TAB [i + 4] [j] = (int) -y;
- }
- }
-
- // Tableau LFO
- g.LFO_INC_TAB [0] = (unsigned int) (3.98 * (double) (1 << (LFO_HBITS + LFO_LBITS)) / sample_rate);
- g.LFO_INC_TAB [1] = (unsigned int) (5.56 * (double) (1 << (LFO_HBITS + LFO_LBITS)) / sample_rate);
- g.LFO_INC_TAB [2] = (unsigned int) (6.02 * (double) (1 << (LFO_HBITS + LFO_LBITS)) / sample_rate);
- g.LFO_INC_TAB [3] = (unsigned int) (6.37 * (double) (1 << (LFO_HBITS + LFO_LBITS)) / sample_rate);
- g.LFO_INC_TAB [4] = (unsigned int) (6.88 * (double) (1 << (LFO_HBITS + LFO_LBITS)) / sample_rate);
- g.LFO_INC_TAB [5] = (unsigned int) (9.63 * (double) (1 << (LFO_HBITS + LFO_LBITS)) / sample_rate);
- g.LFO_INC_TAB [6] = (unsigned int) (48.1 * (double) (1 << (LFO_HBITS + LFO_LBITS)) / sample_rate);
- g.LFO_INC_TAB [7] = (unsigned int) (72.2 * (double) (1 << (LFO_HBITS + LFO_LBITS)) / sample_rate);
-
- reset();
-}
-
-const char* Ym2612_Emu::set_rate( double sample_rate, double clock_rate )
-{
- if ( !impl )
- {
- impl = (Ym2612_Impl*) malloc( sizeof *impl );
- if ( !impl )
- return "Out of memory";
- impl->mute_mask = 0;
- }
- memset( &impl->YM2612, 0, sizeof impl->YM2612 );
-
- impl->set_rate( sample_rate, clock_rate );
-
- return 0;
-}
-
-Ym2612_Emu::~Ym2612_Emu()
-{
- free( impl );
-}
-
-inline void Ym2612_Impl::write0( int opn_addr, int data )
-{
- assert( (unsigned) data <= 0xFF );
-
- if ( opn_addr < 0x30 )
- {
- YM2612.REG [0] [opn_addr] = data;
- YM_SET( opn_addr, data );
- }
- else if ( YM2612.REG [0] [opn_addr] != data )
- {
- YM2612.REG [0] [opn_addr] = data;
-
- if ( opn_addr < 0xA0 )
- SLOT_SET( opn_addr, data );
- else
- CHANNEL_SET( opn_addr, data );
- }
-}
-
-inline void Ym2612_Impl::write1( int opn_addr, int data )
-{
- assert( (unsigned) data <= 0xFF );
-
- if ( opn_addr >= 0x30 && YM2612.REG [1] [opn_addr] != data )
- {
- YM2612.REG [1] [opn_addr] = data;
-
- if ( opn_addr < 0xA0 )
- SLOT_SET( opn_addr + 0x100, data );
- else
- CHANNEL_SET( opn_addr + 0x100, data );
- }
-}
-
-void Ym2612_Emu::reset()
-{
- impl->reset();
-}
-
-void Ym2612_Impl::reset()
-{
- g.LFOcnt = 0;
- YM2612.TimerA = 0;
- YM2612.TimerAL = 0;
- YM2612.TimerAcnt = 0;
- YM2612.TimerB = 0;
- YM2612.TimerBL = 0;
- YM2612.TimerBcnt = 0;
- YM2612.DAC = 0;
-
- YM2612.Status = 0;
-
- int i;
- for ( i = 0; i < channel_count; i++ )
- {
- channel_t& ch = YM2612.CHANNEL [i];
-
- ch.LEFT = ~0;
- ch.RIGHT = ~0;
- ch.ALGO = 0;
- ch.FB = 31;
- ch.FMS = 0;
- ch.AMS = 0;
-
- for ( int j = 0 ;j < 4 ; j++ )
- {
- ch.S0_OUT [j] = 0;
- ch.FNUM [j] = 0;
- ch.FOCT [j] = 0;
- ch.KC [j] = 0;
-
- ch.SLOT [j].Fcnt = 0;
- ch.SLOT [j].Finc = 0;
- ch.SLOT [j].Ecnt = ENV_END; // Put it at the end of Decay phase...
- ch.SLOT [j].Einc = 0;
- ch.SLOT [j].Ecmp = 0;
- ch.SLOT [j].Ecurp = RELEASE;
-
- ch.SLOT [j].ChgEnM = 0;
- }
- }
-
- for ( i = 0; i < 0x100; i++ )
- {
- YM2612.REG [0] [i] = -1;
- YM2612.REG [1] [i] = -1;
- }
-
- for ( i = 0xB6; i >= 0xB4; i-- )
- {
- write0( i, 0xC0 );
- write1( i, 0xC0 );
- }
-
- for ( i = 0xB2; i >= 0x22; i-- )
- {
- write0( i, 0 );
- write1( i, 0 );
- }
-
- write0( 0x2A, 0x80 );
-}
-
-void Ym2612_Emu::write0( int addr, int data )
-{
- impl->write0( addr, data );
-}
-
-void Ym2612_Emu::write1( int addr, int data )
-{
- impl->write1( addr, data );
-}
-
-void Ym2612_Emu::mute_voices( int mask ) { impl->mute_mask = mask; }
-
-static void update_envelope_( slot_t* sl )
-{
- switch ( sl->Ecurp )
- {
- case 0:
- // Env_Attack_Next
-
- // Verified with Gynoug even in HQ (explode SFX)
- sl->Ecnt = ENV_DECAY;
-
- sl->Einc = sl->EincD;
- sl->Ecmp = sl->SLL;
- sl->Ecurp = DECAY;
- break;
-
- case 1:
- // Env_Decay_Next
-
- // Verified with Gynoug even in HQ (explode SFX)
- sl->Ecnt = sl->SLL;
-
- sl->Einc = sl->EincS;
- sl->Ecmp = ENV_END;
- sl->Ecurp = SUBSTAIN;
- break;
-
- case 2:
- // Env_Substain_Next(slot_t *SL)
- if (sl->SEG & 8) // SSG envelope type
- {
- int release = sl->SEG & 1;
-
- if ( !release )
- {
- // re KEY ON
-
- // sl->Fcnt = 0;
- // sl->ChgEnM = ~0;
-
- sl->Ecnt = 0;
- sl->Einc = sl->EincA;
- sl->Ecmp = ENV_DECAY;
- sl->Ecurp = ATTACK;
- }
-
- set_seg( *sl, (sl->SEG << 1) & 4 );
-
- if ( !release )
- break;
- }
- // fall through
-
- case 3:
- // Env_Release_Next
- sl->Ecnt = ENV_END;
- sl->Einc = 0;
- sl->Ecmp = ENV_END + 1;
- break;
-
- // default: no op
- }
-}
-
-inline void update_envelope( slot_t& sl )
-{
- int ecmp = sl.Ecmp;
- if ( (sl.Ecnt += sl.Einc) >= ecmp )
- update_envelope_( &sl );
-}
-
-template<int algo>
-struct ym2612_update_chan {
- static void func( tables_t&, channel_t&, Ym2612_Emu::sample_t*, int );
-};
-
-typedef void (*ym2612_update_chan_t)( tables_t&, channel_t&, Ym2612_Emu::sample_t*, int );
-
-template<int algo>
-void ym2612_update_chan<algo>::func( tables_t& g, channel_t& ch,
- Ym2612_Emu::sample_t* buf, int length )
-{
- int not_end = ch.SLOT [S3].Ecnt - ENV_END;
-
- // algo is a compile-time constant, so all conditions based on it are resolved
- // during compilation
-
- // special cases
- if ( algo == 7 )
- not_end |= ch.SLOT [S0].Ecnt - ENV_END;
-
- if ( algo >= 5 )
- not_end |= ch.SLOT [S2].Ecnt - ENV_END;
-
- if ( algo >= 4 )
- not_end |= ch.SLOT [S1].Ecnt - ENV_END;
-
- int CH_S0_OUT_1 = ch.S0_OUT [1];
-
- int in0 = ch.SLOT [S0].Fcnt;
- int in1 = ch.SLOT [S1].Fcnt;
- int in2 = ch.SLOT [S2].Fcnt;
- int in3 = ch.SLOT [S3].Fcnt;
-
- int YM2612_LFOinc = g.LFOinc;
- int YM2612_LFOcnt = g.LFOcnt + YM2612_LFOinc;
-
- if ( !not_end )
- return;
-
- do
- {
- // envelope
- int const env_LFO = g.LFO_ENV_TAB [YM2612_LFOcnt >> LFO_LBITS & LFO_MASK];
-
- short const* const ENV_TAB = g.ENV_TAB;
-
- #define CALC_EN( x ) \
- int temp##x = ENV_TAB [ch.SLOT [S##x].Ecnt >> ENV_LBITS] + ch.SLOT [S##x].TLL; \
- int en##x = ((temp##x ^ ch.SLOT [S##x].env_xor) + (env_LFO >> ch.SLOT [S##x].AMS)) & \
- ((temp##x - ch.SLOT [S##x].env_max) >> 31);
-
- CALC_EN( 0 )
- CALC_EN( 1 )
- CALC_EN( 2 )
- CALC_EN( 3 )
-
- int const* const TL_TAB = g.TL_TAB;
-
- #define SINT( i, o ) (TL_TAB [g.SIN_TAB [(i)] + (o)])
-
- // feedback
- int CH_S0_OUT_0 = ch.S0_OUT [0];
- {
- int temp = in0 + ((CH_S0_OUT_0 + CH_S0_OUT_1) >> ch.FB);
- CH_S0_OUT_1 = CH_S0_OUT_0;
- CH_S0_OUT_0 = SINT( (temp >> SIN_LBITS) & SIN_MASK, en0 );
- }
-
- int CH_OUTd;
- if ( algo == 0 )
- {
- int temp = in1 + CH_S0_OUT_1;
- temp = in2 + SINT( (temp >> SIN_LBITS) & SIN_MASK, en1 );
- temp = in3 + SINT( (temp >> SIN_LBITS) & SIN_MASK, en2 );
- CH_OUTd = SINT( (temp >> SIN_LBITS) & SIN_MASK, en3 );
- }
- else if ( algo == 1 )
- {
- int temp = in2 + CH_S0_OUT_1 + SINT( (in1 >> SIN_LBITS) & SIN_MASK, en1 );
- temp = in3 + SINT( (temp >> SIN_LBITS) & SIN_MASK, en2 );
- CH_OUTd = SINT( (temp >> SIN_LBITS) & SIN_MASK, en3 );
- }
- else if ( algo == 2 )
- {
- int temp = in2 + SINT( (in1 >> SIN_LBITS) & SIN_MASK, en1 );
- temp = in3 + CH_S0_OUT_1 + SINT( (temp >> SIN_LBITS) & SIN_MASK, en2 );
- CH_OUTd = SINT( (temp >> SIN_LBITS) & SIN_MASK, en3 );
- }
- else if ( algo == 3 )
- {
- int temp = in1 + CH_S0_OUT_1;
- temp = in3 + SINT( (temp >> SIN_LBITS) & SIN_MASK, en1 ) +
- SINT( (in2 >> SIN_LBITS) & SIN_MASK, en2 );
- CH_OUTd = SINT( (temp >> SIN_LBITS) & SIN_MASK, en3 );
- }
- else if ( algo == 4 )
- {
- int temp = in3 + SINT( (in2 >> SIN_LBITS) & SIN_MASK, en2 );
- CH_OUTd = SINT( (temp >> SIN_LBITS) & SIN_MASK, en3 ) +
- SINT( ((in1 + CH_S0_OUT_1) >> SIN_LBITS) & SIN_MASK, en1 );
- //DO_LIMIT
- }
- else if ( algo == 5 )
- {
- int temp = CH_S0_OUT_1;
- CH_OUTd = SINT( ((in3 + temp) >> SIN_LBITS) & SIN_MASK, en3 ) +
- SINT( ((in1 + temp) >> SIN_LBITS) & SIN_MASK, en1 ) +
- SINT( ((in2 + temp) >> SIN_LBITS) & SIN_MASK, en2 );
- //DO_LIMIT
- }
- else if ( algo == 6 )
- {
- CH_OUTd = SINT( (in3 >> SIN_LBITS) & SIN_MASK, en3 ) +
- SINT( ((in1 + CH_S0_OUT_1) >> SIN_LBITS) & SIN_MASK, en1 ) +
- SINT( (in2 >> SIN_LBITS) & SIN_MASK, en2 );
- //DO_LIMIT
- }
- else if ( algo == 7 )
- {
- CH_OUTd = SINT( (in3 >> SIN_LBITS) & SIN_MASK, en3 ) +
- SINT( (in1 >> SIN_LBITS) & SIN_MASK, en1 ) +
- SINT( (in2 >> SIN_LBITS) & SIN_MASK, en2 ) + CH_S0_OUT_1;
- //DO_LIMIT
- }
-
- CH_OUTd >>= MAX_OUT_BITS - output_bits + 2;
-
- // update phase
- unsigned freq_LFO = ((g.LFO_FREQ_TAB [YM2612_LFOcnt >> LFO_LBITS & LFO_MASK] *
- ch.FMS) >> (LFO_HBITS - 1 + 1)) + (1L << (LFO_FMS_LBITS - 1));
- YM2612_LFOcnt += YM2612_LFOinc;
- in0 += (ch.SLOT [S0].Finc * freq_LFO) >> (LFO_FMS_LBITS - 1);
- in1 += (ch.SLOT [S1].Finc * freq_LFO) >> (LFO_FMS_LBITS - 1);
- in2 += (ch.SLOT [S2].Finc * freq_LFO) >> (LFO_FMS_LBITS - 1);
- in3 += (ch.SLOT [S3].Finc * freq_LFO) >> (LFO_FMS_LBITS - 1);
-
- int t0 = buf [0] + (CH_OUTd & ch.LEFT);
- int t1 = buf [1] + (CH_OUTd & ch.RIGHT);
-
- update_envelope( ch.SLOT [0] );
- update_envelope( ch.SLOT [1] );
- update_envelope( ch.SLOT [2] );
- update_envelope( ch.SLOT [3] );
-
- ch.S0_OUT [0] = CH_S0_OUT_0;
- buf [0] = t0;
- buf [1] = t1;
- buf += 2;
- }
- while ( --length );
-
- ch.S0_OUT [1] = CH_S0_OUT_1;
-
- ch.SLOT [S0].Fcnt = in0;
- ch.SLOT [S1].Fcnt = in1;
- ch.SLOT [S2].Fcnt = in2;
- ch.SLOT [S3].Fcnt = in3;
-}
-
-static const ym2612_update_chan_t UPDATE_CHAN [8] = {
- &ym2612_update_chan<0>::func,
- &ym2612_update_chan<1>::func,
- &ym2612_update_chan<2>::func,
- &ym2612_update_chan<3>::func,
- &ym2612_update_chan<4>::func,
- &ym2612_update_chan<5>::func,
- &ym2612_update_chan<6>::func,
- &ym2612_update_chan<7>::func
-};
-
-void Ym2612_Impl::run_timer( int length )
-{
- int const step = 6;
- int remain = length;
- do
- {
- int n = step;
- if ( n > remain )
- n = remain;
- remain -= n;
-
- long i = n * YM2612.TimerBase;
- if (YM2612.Mode & 1) // Timer A ON ?
- {
- // if ((YM2612.TimerAcnt -= 14073) <= 0) // 13879=NTSC (old: 14475=NTSC 14586=PAL)
- if ((YM2612.TimerAcnt -= i) <= 0)
- {
- // timer a overflow
-
- YM2612.Status |= (YM2612.Mode & 0x04) >> 2;
- YM2612.TimerAcnt += YM2612.TimerAL;
-
- if (YM2612.Mode & 0x80)
- {
- KEY_ON( YM2612.CHANNEL [2], 0 );
- KEY_ON( YM2612.CHANNEL [2], 1 );
- KEY_ON( YM2612.CHANNEL [2], 2 );
- KEY_ON( YM2612.CHANNEL [2], 3 );
- }
- }
- }
-
- if (YM2612.Mode & 2) // Timer B ON ?
- {
- // if ((YM2612.TimerBcnt -= 14073) <= 0) // 13879=NTSC (old: 14475=NTSC 14586=PAL)
- if ((YM2612.TimerBcnt -= i) <= 0)
- {
- // timer b overflow
- YM2612.Status |= (YM2612.Mode & 0x08) >> 2;
- YM2612.TimerBcnt += YM2612.TimerBL;
- }
- }
- }
- while ( remain > 0 );
-}
-
-void Ym2612_Impl::run( int pair_count, Ym2612_Emu::sample_t* out )
-{
- if ( pair_count <= 0 )
- return;
-
- if ( YM2612.Mode & 3 )
- run_timer( pair_count );
-
- // Mise à jour des pas des compteurs-frequences s'ils ont ete modifies
-
- for ( int chi = 0; chi < channel_count; chi++ )
- {
- channel_t& ch = YM2612.CHANNEL [chi];
- if ( ch.SLOT [0].Finc != -1 )
- continue;
-
- int i2 = 0;
- if ( chi == 2 && (YM2612.Mode & 0x40) )
- i2 = 2;
-
- for ( int i = 0; i < 4; i++ )
- {
- // static int seq [4] = { 2, 1, 3, 0 };
- // if ( i2 ) i2 = seq [i];
-
- slot_t& sl = ch.SLOT [i];
- int finc = g.FINC_TAB [ch.FNUM [i2]] >> (7 - ch.FOCT [i2]);
- int ksr = ch.KC [i2] >> sl.KSR_S; // keycode attenuation
- sl.Finc = (finc + sl.DT [ch.KC [i2]]) * sl.MUL;
- if (sl.KSR != ksr) // si le KSR a change alors
- { // les differents taux pour l'enveloppe sont mis à jour
- sl.KSR = ksr;
-
- sl.EincA = sl.AR [ksr];
- sl.EincD = sl.DR [ksr];
- sl.EincS = sl.SR [ksr];
- sl.EincR = sl.RR [ksr];
-
- if (sl.Ecurp == ATTACK)
- {
- sl.Einc = sl.EincA;
- }
- else if (sl.Ecurp == DECAY)
- {
- sl.Einc = sl.EincD;
- }
- else if (sl.Ecnt < ENV_END)
- {
- if (sl.Ecurp == SUBSTAIN)
- sl.Einc = sl.EincS;
- else if (sl.Ecurp == RELEASE)
- sl.Einc = sl.EincR;
- }
- }
-
- if ( i2 )
- i2 = (i2 ^ 2) ^ (i2 >> 1);
- }
- }
-
- for ( int i = 0; i < channel_count; i++ )
- {
- if ( !(mute_mask & (1 << i)) && (i != 5 || !YM2612.DAC) )
- UPDATE_CHAN [YM2612.CHANNEL [i].ALGO]( g, YM2612.CHANNEL [i], out, pair_count );
- }
-
- g.LFOcnt += g.LFOinc * pair_count;
-}
-
-void Ym2612_Emu::run( int pair_count, sample_t* out ) { impl->run( pair_count, out ); }
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Ym2612_Emu.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/Ym2612_Emu.h
deleted file mode 100644
index 383ac72d..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/Ym2612_Emu.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// YM2612 FM sound chip emulator interface
-
-// Game_Music_Emu 0.5.2
-#ifndef YM2612_EMU_H
-#define YM2612_EMU_H
-
-struct Ym2612_Impl;
-
-class Ym2612_Emu {
- Ym2612_Impl* impl;
-public:
- Ym2612_Emu() { impl = 0; }
- ~Ym2612_Emu();
-
- // Set output sample rate and chip clock rates, in Hz. Returns non-zero
- // if error.
- const char* set_rate( double sample_rate, double clock_rate );
-
- // Reset to power-up state
- void reset();
-
- // Mute voice n if bit n (1 << n) of mask is set
- enum { channel_count = 6 };
- void mute_voices( int mask );
-
- // Write addr to register 0 then data to register 1
- void write0( int addr, int data );
-
- // Write addr to register 2 then data to register 3
- void write1( int addr, int data );
-
- // Run and add pair_count samples into current output buffer contents
- typedef short sample_t;
- enum { out_chan_count = 2 }; // stereo
- void run( int pair_count, sample_t* out );
-};
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/blargg_common.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/blargg_common.h
deleted file mode 100644
index 9ab0bd7d..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/blargg_common.h
+++ /dev/null
@@ -1,179 +0,0 @@
-// Sets up common environment for Shay Green's libraries.
-// To change configuration options, modify blargg_config.h, not this file.
-
-#ifndef BLARGG_COMMON_H
-#define BLARGG_COMMON_H
-
-#include <stddef.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <limits.h>
-#include <stdint.h>
-
-#undef BLARGG_COMMON_H
-// allow blargg_config.h to #include blargg_common.h
-#include "blargg_config.h"
-#ifndef BLARGG_COMMON_H
-#define BLARGG_COMMON_H
-
-// STATIC_CAST(T,expr): Used in place of static_cast<T> (expr)
-#ifndef STATIC_CAST
- #define STATIC_CAST(T,expr) ((T) (expr))
-#endif
-
-// blargg_err_t (0 on success, otherwise error string)
-#ifndef blargg_err_t
- typedef const char* blargg_err_t;
-#endif
-
-// blargg_vector - very lightweight vector of POD types (no constructor/destructor)
-template<class T>
-class blargg_vector {
- T* begin_;
- size_t size_;
-public:
- blargg_vector() : begin_( 0 ), size_( 0 ) { }
- ~blargg_vector() { free( begin_ ); }
- size_t size() const { return size_; }
- T* begin() const { return begin_; }
- T* end() const { return begin_ + size_; }
- blargg_err_t resize( size_t n )
- {
- void* p = realloc( begin_, n * sizeof (T) );
- if ( !p && n )
- return "Out of memory";
- begin_ = (T*) p;
- size_ = n;
- return 0;
- }
- void clear() { void* p = begin_; begin_ = 0; size_ = 0; free( p ); }
- T& operator [] ( size_t n ) const
- {
- assert( n <= size_ ); // <= to allow past-the-end value
- return begin_ [n];
- }
-};
-
-#ifndef BLARGG_DISABLE_NOTHROW
- #if __cplusplus < 199711
- #define BLARGG_THROWS( spec )
- #else
- #define BLARGG_THROWS( spec ) throw spec
- #endif
- #define BLARGG_DISABLE_NOTHROW \
- void* operator new ( size_t s ) BLARGG_THROWS(()) { return malloc( s ); }\
- void operator delete ( void* p ) { free( p ); }
- #define BLARGG_NEW new
-#else
- #include <new>
- #define BLARGG_NEW new (std::nothrow)
-#endif
-
-#define BLARGG_4CHAR( a, b, c, d ) \
- ((a&0xFF)*0x1000000L + (b&0xFF)*0x10000L + (c&0xFF)*0x100L + (d&0xFF))
-
-// BOOST_STATIC_ASSERT( expr ): Generates compile error if expr is 0.
-#ifndef BOOST_STATIC_ASSERT
- #ifdef _MSC_VER
- // MSVC6 (_MSC_VER < 1300) fails for use of __LINE__ when /Zl is specified
- #define BOOST_STATIC_ASSERT( expr ) \
- void blargg_failed_( int (*arg) [2 / (int) !!(expr) - 1] )
- #else
- // Some other compilers fail when declaring same function multiple times in class,
- // so differentiate them by line
- #define BOOST_STATIC_ASSERT( expr ) \
- void blargg_failed_( int (*arg) [2 / !!(expr) - 1] [__LINE__] )
- #endif
-#endif
-
-// BLARGG_COMPILER_HAS_BOOL: If 0, provides bool support for old compiler. If 1,
-// compiler is assumed to support bool. If undefined, availability is determined.
-#ifndef BLARGG_COMPILER_HAS_BOOL
- #if defined (__MWERKS__)
- #if !__option(bool)
- #define BLARGG_COMPILER_HAS_BOOL 0
- #endif
- #elif defined (_MSC_VER)
- #if _MSC_VER < 1100
- #define BLARGG_COMPILER_HAS_BOOL 0
- #endif
- #elif defined (__GNUC__)
- // supports bool
- #elif __cplusplus < 199711
- #define BLARGG_COMPILER_HAS_BOOL 0
- #endif
-#endif
-#if defined (BLARGG_COMPILER_HAS_BOOL) && !BLARGG_COMPILER_HAS_BOOL
- // If you get errors here, modify your blargg_config.h file
- typedef int bool;
- const bool true = 1;
- const bool false = 0;
-#endif
-
-// blargg_long/blargg_ulong = at least 32 bits, int if it's big enough
-#include <limits.h>
-
-#if 0
-#if INT_MAX >= 0x7FFFFFFF
- typedef int blargg_long;
-#else
- typedef long blargg_long;
-#endif
-#endif
-typedef int64_t blargg_long;
-
-#if UINT_MAX >= 0xFFFFFFFF
- typedef unsigned blargg_ulong;
-#else
- typedef unsigned long blargg_ulong;
-#endif
-
-// BOOST::int8_t etc.
-
-// HAVE_STDINT_H: If defined, use <stdint.h> for int8_t etc.
-#if defined (HAVE_STDINT_H)
- #include <stdint.h>
- #define BOOST
-
-// HAVE_INTTYPES_H: If defined, use <stdint.h> for int8_t etc.
-#elif defined (HAVE_INTTYPES_H)
- #include <inttypes.h>
- #define BOOST
-
-#else
- struct BOOST
- {
- #if UCHAR_MAX == 0xFF && SCHAR_MAX == 0x7F
- typedef signed char int8_t;
- typedef unsigned char uint8_t;
- #else
- // No suitable 8-bit type available
- typedef struct see_blargg_common_h int8_t;
- typedef struct see_blargg_common_h uint8_t;
- #endif
-
- #if USHRT_MAX == 0xFFFF
- typedef short int16_t;
- typedef unsigned short uint16_t;
- #else
- // No suitable 16-bit type available
- typedef struct see_blargg_common_h int16_t;
- typedef struct see_blargg_common_h uint16_t;
- #endif
-
- #if ULONG_MAX == 0xFFFFFFFF
- typedef long int32_t;
- typedef unsigned long uint32_t;
- #elif UINT_MAX == 0xFFFFFFFF
- typedef int int32_t;
- typedef unsigned int uint32_t;
- #else
- // No suitable 32-bit type available
- typedef struct see_blargg_common_h int32_t;
- typedef struct see_blargg_common_h uint32_t;
- #endif
- };
-#endif
-
-#endif
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/blargg_config.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/blargg_config.h
deleted file mode 100644
index 9e9c751d..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/blargg_config.h
+++ /dev/null
@@ -1,30 +0,0 @@
-// Library configuration. Modify this file as necessary.
-
-#ifndef BLARGG_CONFIG_H
-#define BLARGG_CONFIG_H
-
-// Uncomment to use zlib for transparent decompression of gzipped files
-//#define HAVE_ZLIB_H
-
-// Uncomment to support only the listed game music types. See gme_type_list.cpp
-// for a list of all types.
-//#define GME_TYPE_LIST gme_nsf_type, gme_gbs_type
-
-// Uncomment to enable platform-specific optimizations
-//#define BLARGG_NONPORTABLE 1
-
-// Uncomment to use faster, lower quality sound synthesis
-//#define BLIP_BUFFER_FAST 1
-
-// Uncomment if automatic byte-order determination doesn't work
-//#define BLARGG_BIG_ENDIAN 1
-
-// Uncomment if you get errors in the bool section of blargg_common.h
-//#define BLARGG_COMPILER_HAS_BOOL 1
-
-// Use standard config.h if present
-#ifdef HAVE_CONFIG_H
- #include "config.h"
-#endif
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/blargg_endian.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/blargg_endian.h
deleted file mode 100644
index 67165565..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/blargg_endian.h
+++ /dev/null
@@ -1,158 +0,0 @@
-// CPU Byte Order Utilities
-
-// Game_Music_Emu 0.5.2
-#ifndef BLARGG_ENDIAN
-#define BLARGG_ENDIAN
-
-#include "blargg_common.h"
-
-// BLARGG_CPU_CISC: Defined if CPU has very few general-purpose registers (< 16)
-#if defined (_M_IX86) || defined (_M_IA64) || defined (__i486__) || \
- defined (__x86_64__) || defined (__ia64__) || defined (__i386__)
- #define BLARGG_CPU_X86 1
- #define BLARGG_CPU_CISC 1
-#endif
-
-#if defined (__powerpc__) || defined (__ppc__) || defined (__POWERPC__) || defined (__powerc)
- #define BLARGG_CPU_POWERPC 1
-#endif
-
-// BLARGG_BIG_ENDIAN, BLARGG_LITTLE_ENDIAN: Determined automatically, otherwise only
-// one may be #defined to 1. Only needed if something actually depends on byte order.
-#if !defined (BLARGG_BIG_ENDIAN) && !defined (BLARGG_LITTLE_ENDIAN)
-#ifdef __GLIBC__
- // GCC handles this for us
- #include <endian.h>
- #if __BYTE_ORDER == __LITTLE_ENDIAN
- #define BLARGG_LITTLE_ENDIAN 1
- #elif __BYTE_ORDER == __BIG_ENDIAN
- #define BLARGG_BIG_ENDIAN 1
- #endif
-#else
-
-#if defined (LSB_FIRST) || defined (__LITTLE_ENDIAN__) || BLARGG_CPU_X86 || \
- (defined (LITTLE_ENDIAN) && LITTLE_ENDIAN+0 != 1234)
- #define BLARGG_LITTLE_ENDIAN 1
-#endif
-
-#if defined (MSB_FIRST) || defined (__BIG_ENDIAN__) || defined (WORDS_BIGENDIAN) || \
- defined (__mips__) || defined (__sparc__) || BLARGG_CPU_POWERPC || \
- (defined (BIG_ENDIAN) && BIG_ENDIAN+0 != 4321)
- #define BLARGG_BIG_ENDIAN 1
-#else
- // No endian specified; assume little-endian, since it's most common
- #define BLARGG_LITTLE_ENDIAN 1
-#endif
-#endif
-#endif
-
-#if BLARGG_LITTLE_ENDIAN && BLARGG_BIG_ENDIAN
- #undef BLARGG_LITTLE_ENDIAN
- #undef BLARGG_BIG_ENDIAN
-#endif
-
-inline void blargg_verify_byte_order()
-{
- #ifndef NDEBUG
- #if BLARGG_BIG_ENDIAN
- volatile int i = 1;
- assert( *(volatile char*) &i == 0 );
- #elif BLARGG_LITTLE_ENDIAN
- volatile int i = 1;
- assert( *(volatile char*) &i != 0 );
- #endif
- #endif
-}
-
-inline unsigned get_le16( void const* p ) {
- return ((unsigned char const*) p) [1] * 0x100u +
- ((unsigned char const*) p) [0];
-}
-inline unsigned get_be16( void const* p ) {
- return ((unsigned char const*) p) [0] * 0x100u +
- ((unsigned char const*) p) [1];
-}
-inline blargg_ulong get_le32( void const* p ) {
- return ((unsigned char const*) p) [3] * 0x01000000u +
- ((unsigned char const*) p) [2] * 0x00010000u +
- ((unsigned char const*) p) [1] * 0x00000100u +
- ((unsigned char const*) p) [0];
-}
-inline blargg_ulong get_be32( void const* p ) {
- return ((unsigned char const*) p) [0] * 0x01000000u +
- ((unsigned char const*) p) [1] * 0x00010000u +
- ((unsigned char const*) p) [2] * 0x00000100u +
- ((unsigned char const*) p) [3];
-}
-inline void set_le16( void* p, unsigned n ) {
- ((unsigned char*) p) [1] = (unsigned char) (n >> 8);
- ((unsigned char*) p) [0] = (unsigned char) n;
-}
-inline void set_be16( void* p, unsigned n ) {
- ((unsigned char*) p) [0] = (unsigned char) (n >> 8);
- ((unsigned char*) p) [1] = (unsigned char) n;
-}
-inline void set_le32( void* p, blargg_ulong n ) {
- ((unsigned char*) p) [3] = (unsigned char) (n >> 24);
- ((unsigned char*) p) [2] = (unsigned char) (n >> 16);
- ((unsigned char*) p) [1] = (unsigned char) (n >> 8);
- ((unsigned char*) p) [0] = (unsigned char) n;
-}
-inline void set_be32( void* p, blargg_ulong n ) {
- ((unsigned char*) p) [0] = (unsigned char) (n >> 24);
- ((unsigned char*) p) [1] = (unsigned char) (n >> 16);
- ((unsigned char*) p) [2] = (unsigned char) (n >> 8);
- ((unsigned char*) p) [3] = (unsigned char) n;
-}
-
-#if BLARGG_NONPORTABLE
- // Optimized implementation if byte order is known
- #if BLARGG_LITTLE_ENDIAN
- #define GET_LE16( addr ) (*(BOOST::uint16_t*) (addr))
- #define GET_LE32( addr ) (*(BOOST::uint32_t*) (addr))
- #define SET_LE16( addr, data ) (void) (*(BOOST::uint16_t*) (addr) = (data))
- #define SET_LE32( addr, data ) (void) (*(BOOST::uint32_t*) (addr) = (data))
- #elif BLARGG_BIG_ENDIAN
- #define GET_BE16( addr ) (*(BOOST::uint16_t*) (addr))
- #define GET_BE32( addr ) (*(BOOST::uint32_t*) (addr))
- #define SET_BE16( addr, data ) (void) (*(BOOST::uint16_t*) (addr) = (data))
- #define SET_BE32( addr, data ) (void) (*(BOOST::uint32_t*) (addr) = (data))
- #endif
-
- #if BLARGG_CPU_POWERPC && defined (__MWERKS__)
- // PowerPC has special byte-reversed instructions
- // to do: assumes that PowerPC is running in big-endian mode
- // to do: implement for other compilers which don't support these macros
- #define GET_LE16( addr ) (__lhbrx( (addr), 0 ))
- #define GET_LE32( addr ) (__lwbrx( (addr), 0 ))
- #define SET_LE16( addr, data ) (__sthbrx( (data), (addr), 0 ))
- #define SET_LE32( addr, data ) (__stwbrx( (data), (addr), 0 ))
- #endif
-#endif
-
-#ifndef GET_LE16
- #define GET_LE16( addr ) get_le16( addr )
- #define GET_LE32( addr ) get_le32( addr )
- #define SET_LE16( addr, data ) set_le16( addr, data )
- #define SET_LE32( addr, data ) set_le32( addr, data )
-#endif
-
-#ifndef GET_BE16
- #define GET_BE16( addr ) get_be16( addr )
- #define GET_BE32( addr ) get_be32( addr )
- #define SET_BE16( addr, data ) set_be16( addr, data )
- #define SET_BE32( addr, data ) set_be32( addr, data )
-#endif
-
-// auto-selecting versions
-
-inline void set_le( BOOST::uint16_t* p, unsigned n ) { SET_LE16( p, n ); }
-inline void set_le( BOOST::uint32_t* p, blargg_ulong n ) { SET_LE32( p, n ); }
-inline void set_be( BOOST::uint16_t* p, unsigned n ) { SET_BE16( p, n ); }
-inline void set_be( BOOST::uint32_t* p, blargg_ulong n ) { SET_BE32( p, n ); }
-inline unsigned get_le( BOOST::uint16_t* p ) { return GET_LE16( p ); }
-inline blargg_ulong get_le( BOOST::uint32_t* p ) { return GET_LE32( p ); }
-inline unsigned get_be( BOOST::uint16_t* p ) { return GET_BE16( p ); }
-inline blargg_ulong get_be( BOOST::uint32_t* p ) { return GET_BE32( p ); }
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/blargg_source.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/blargg_source.h
deleted file mode 100644
index 945bf349..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/blargg_source.h
+++ /dev/null
@@ -1,78 +0,0 @@
-// Included at the beginning of library source files, after all other #include lines
-#ifndef BLARGG_SOURCE_H
-#define BLARGG_SOURCE_H
-
-// If debugging is enabled, abort program if expr is false. Meant for checking
-// internal state and consistency. A failed assertion indicates a bug in the module.
-// void assert( bool expr );
-#include <assert.h>
-
-// If debugging is enabled and expr is false, abort program. Meant for checking
-// caller-supplied parameters and operations that are outside the control of the
-// module. A failed requirement indicates a bug outside the module.
-// void require( bool expr );
-#undef require
-#define require( expr ) assert( expr )
-
-// Like printf() except output goes to debug log file. Might be defined to do
-// nothing (not even evaluate its arguments).
-// void dprintf( const char* format, ... );
-inline void blargg_dprintf_( const char*, ... ) { }
-#undef dprintf
-#define dprintf (1) ? (void) 0 : blargg_dprintf_
-
-// If enabled, evaluate expr and if false, make debug log entry with source file
-// and line. Meant for finding situations that should be examined further, but that
-// don't indicate a problem. In all cases, execution continues normally.
-#undef check
-#define check( expr ) ((void) 0)
-
-// If expr yields error string, return it from current function, otherwise continue.
-#undef RETURN_ERR
-#define RETURN_ERR( expr ) do { \
- blargg_err_t blargg_return_err_ = (expr); \
- if ( blargg_return_err_ ) return blargg_return_err_; \
- } while ( 0 )
-
-// If ptr is 0, return out of memory error string.
-#undef CHECK_ALLOC
-#define CHECK_ALLOC( ptr ) do { if ( (ptr) == 0 ) return "Out of memory"; } while ( 0 )
-
-// Avoid any macros which evaluate their arguments multiple times
-#undef min
-#undef max
-
-// using const references generates crappy code, and I am currenly only using these
-// for built-in types, so they take arguments by value
-
-template<class T>
-inline T min( T x, T y )
-{
- if ( x < y )
- return x;
- return y;
-}
-
-template<class T>
-inline T max( T x, T y )
-{
- if ( x < y )
- return y;
- return x;
-}
-
-// TODO: good idea? bad idea?
-#undef byte
-#define byte byte_
-typedef unsigned char byte;
-
-// deprecated
-#define BLARGG_CHECK_ALLOC CHECK_ALLOC
-#define BLARGG_RETURN_ERR RETURN_ERR
-
-// BLARGG_SOURCE_BEGIN: If defined, #included, allowing redefition of dprintf and check
-#ifdef BLARGG_SOURCE_BEGIN
- #include BLARGG_SOURCE_BEGIN
-#endif
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/gb_cpu_io.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/gb_cpu_io.h
deleted file mode 100644
index ada99ead..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/gb_cpu_io.h
+++ /dev/null
@@ -1,72 +0,0 @@
-
-#include "Gbs_Emu.h"
-
-#include "blargg_source.h"
-
-int Gbs_Emu::cpu_read( gb_addr_t addr )
-{
- int result = *cpu::get_code( addr );
- if ( unsigned (addr - Gb_Apu::start_addr) < Gb_Apu::register_count )
- result = apu.read_register( clock(), addr );
-#ifndef NDEBUG
- else if ( unsigned (addr - 0x8000) < 0x2000 || unsigned (addr - 0xE000) < 0x1F00 )
- dprintf( "Read from unmapped memory $%.4x\n", (unsigned) addr );
- else if ( unsigned (addr - 0xFF01) < 0xFF80 - 0xFF01 )
- dprintf( "Unhandled I/O read 0x%4X\n", (unsigned) addr );
-#endif
- return result;
-}
-
-void Gbs_Emu::cpu_write( gb_addr_t addr, int data )
-{
- unsigned offset = addr - ram_addr;
- if ( offset <= 0xFFFF - ram_addr )
- {
- ram [offset] = data;
- if ( (addr ^ 0xE000) <= 0x1F80 - 1 )
- {
- if ( unsigned (addr - Gb_Apu::start_addr) < Gb_Apu::register_count )
- {
- GME_APU_HOOK( this, addr - Gb_Apu::start_addr, data );
- apu.write_register( clock(), addr, data );
- }
- else if ( (addr ^ 0xFF06) < 2 )
- update_timer();
- else if ( addr == joypad_addr )
- ram [offset] = 0; // keep joypad return value 0
- else
- ram [offset] = 0xFF;
-
- //if ( addr == 0xFFFF )
- // dprintf( "Wrote interrupt mask\n" );
- }
- }
- else if ( (addr ^ 0x2000) <= 0x2000 - 1 )
- {
- set_bank( data );
- }
-#ifndef NDEBUG
- else if ( unsigned (addr - 0x8000) < 0x2000 || unsigned (addr - 0xE000) < 0x1F00 )
- {
- dprintf( "Wrote to unmapped memory $%.4x\n", (unsigned) addr );
- }
-#endif
-}
-
-#define CPU_READ_FAST( cpu, addr, time, out ) \
- CPU_READ_FAST_( STATIC_CAST(Gbs_Emu*,cpu), addr, time, out )
-
-#define CPU_READ_FAST_( emu, addr, time, out ) \
-{\
- out = READ_PROG( addr );\
- if ( unsigned (addr - Gb_Apu::start_addr) <= Gb_Apu::register_count )\
- out = emu->apu.read_register( emu->cpu_time - time * clocks_per_instr, addr );\
- else\
- check( out == emu->cpu_read( addr ) );\
-}
-
-#define CPU_READ( cpu, addr, time ) \
- STATIC_CAST(Gbs_Emu*,cpu)->cpu_read( addr )
-
-#define CPU_WRITE( cpu, addr, data, time ) \
- STATIC_CAST(Gbs_Emu*,cpu)->cpu_write( addr, data )
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/gme.cpp b/plugins/gme/Game_Music_Emu-0.5.2/gme/gme.cpp
deleted file mode 100644
index d6cebfa8..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/gme.cpp
+++ /dev/null
@@ -1,256 +0,0 @@
-// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
-
-#include "Music_Emu.h"
-
-#if !GME_DISABLE_STEREO_DEPTH
-#include "Effects_Buffer.h"
-#endif
-#include "blargg_endian.h"
-#include <string.h>
-#include <ctype.h>
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-#ifndef GME_TYPE_LIST
-
-// Default list of all supported game music types (copy this to blargg_config.h
-// if you want to modify it)
-#define GME_TYPE_LIST \
- gme_ay_type,\
- gme_gbs_type,\
- gme_gym_type,\
- gme_hes_type,\
- gme_kss_type,\
- gme_nsf_type,\
- gme_nsfe_type,\
- gme_sap_type,\
- gme_spc_type,\
- gme_vgm_type,\
- gme_vgz_type
-
-#endif
-
-static gme_type_t const gme_type_list_ [] = { GME_TYPE_LIST, 0 };
-
-gme_type_t const* gme_type_list()
-{
- return gme_type_list_;
-}
-
-const char* gme_identify_header( void const* header )
-{
- switch ( get_be32( header ) )
- {
- case BLARGG_4CHAR('Z','X','A','Y'): return "AY";
- case BLARGG_4CHAR('G','B','S',0x01): return "GBS";
- case BLARGG_4CHAR('G','Y','M','X'): return "GYM";
- case BLARGG_4CHAR('H','E','S','M'): return "HES";
- case BLARGG_4CHAR('K','S','C','C'):
- case BLARGG_4CHAR('K','S','S','X'): return "KSS";
- case BLARGG_4CHAR('N','E','S','M'): return "NSF";
- case BLARGG_4CHAR('N','S','F','E'): return "NSFE";
- case BLARGG_4CHAR('S','A','P',0x0D): return "SAP";
- case BLARGG_4CHAR('S','N','E','S'): return "SPC";
- case BLARGG_4CHAR('V','g','m',' '): return "VGM";
- }
- return "";
-}
-
-static void to_uppercase( const char* in, int len, char* out )
-{
- for ( int i = 0; i < len; i++ )
- {
- if ( !(out [i] = toupper( in [i] )) )
- return;
- }
- *out = 0; // extension too long
-}
-
-gme_type_t gme_identify_extension( const char* extension_ )
-{
- char const* end = strrchr( extension_, '.' );
- if ( end )
- extension_ = end + 1;
-
- char extension [6];
- to_uppercase( extension_, sizeof extension, extension );
-
- for ( gme_type_t const* types = gme_type_list_; *types; types++ )
- if ( !strcmp( extension, (*types)->extension_ ) )
- return *types;
- return 0;
-}
-
-gme_err_t gme_identify_file( const char* path, gme_type_t* type_out )
-{
- *type_out = gme_identify_extension( path );
- // TODO: don't examine header if file has extension?
- if ( !*type_out )
- {
- char header [4];
- GME_FILE_READER in;
- RETURN_ERR( in.open( path ) );
- RETURN_ERR( in.read( header, sizeof header ) );
- *type_out = gme_identify_extension( gme_identify_header( header ) );
- }
- return 0;
-}
-
-gme_err_t gme_open_data( void const* data, long size, Music_Emu** out, long sample_rate )
-{
- require( (data || !size) && out );
- *out = 0;
-
- gme_type_t file_type = 0;
- if ( size >= 4 )
- file_type = gme_identify_extension( gme_identify_header( data ) );
- if ( !file_type )
- return gme_wrong_file_type;
-
- Music_Emu* emu = gme_new_emu( file_type, sample_rate );
- CHECK_ALLOC( emu );
-
- gme_err_t err = gme_load_data( emu, data, size );
-
- if ( err )
- delete emu;
- else
- *out = emu;
-
- return err;
-}
-
-gme_err_t gme_open_file( const char* path, Music_Emu** out, long sample_rate )
-{
- require( path && out );
- *out = 0;
-
- GME_FILE_READER in;
- RETURN_ERR( in.open( path ) );
-
- char header [4];
- int header_size = 0;
-
- gme_type_t file_type = gme_identify_extension( path );
- if ( !file_type )
- {
- header_size = sizeof header;
- RETURN_ERR( in.read( header, sizeof header ) );
- file_type = gme_identify_extension( gme_identify_header( header ) );
- }
- if ( !file_type )
- return gme_wrong_file_type;
-
- Music_Emu* emu = gme_new_emu( file_type, sample_rate );
- CHECK_ALLOC( emu );
-
- // optimization: avoids seeking/re-reading header
- Remaining_Reader rem( header, header_size, &in );
- gme_err_t err = emu->load( rem );
- in.close();
-
- if ( err )
- delete emu;
- else
- *out = emu;
-
- return err;
-}
-
-Music_Emu* gme_new_emu( gme_type_t type, long rate )
-{
- if ( type )
- {
- if ( rate == gme_info_only )
- return type->new_info();
-
- Music_Emu* me = type->new_emu();
- if ( me )
- {
- #if !GME_DISABLE_STEREO_DEPTH
- if ( type->flags_ & 1 )
- {
- me->effects_buffer = BLARGG_NEW Effects_Buffer;
- if ( me->effects_buffer )
- me->set_buffer( me->effects_buffer );
- }
-
- if ( !(type->flags_ & 1) || me->effects_buffer )
- #endif
- {
- if ( !me->set_sample_rate( rate ) )
- {
- check( me->type() == type );
- return me;
- }
- }
- delete me;
- }
- }
- return 0;
-}
-
-gme_err_t gme_load_file( Music_Emu* me, const char* path ) { return me->load_file( path ); }
-
-gme_err_t gme_load_data( Music_Emu* me, void const* data, long size )
-{
- Mem_File_Reader in( data, size );
- return me->load( in );
-}
-
-gme_err_t gme_load_custom( Music_Emu* me, gme_reader_t func, long size, void* data )
-{
- Callback_Reader in( func, size, data );
- return me->load( in );
-}
-
-void gme_delete( Music_Emu* me ) { delete me; }
-
-gme_type_t gme_type( Music_Emu const* me ) { return me->type(); }
-
-const char* gme_warning( Music_Emu* me ) { return me->warning(); }
-
-int gme_track_count( Music_Emu const* me ) { return me->track_count(); }
-
-const char* gme_track_info( Music_Emu const* me, track_info_t* out, int track )
-{
- return me->track_info( out, track );
-}
-
-void gme_set_stereo_depth( Music_Emu* me, double depth )
-{
-#if !GME_DISABLE_STEREO_DEPTH
- if ( me->effects_buffer )
- STATIC_CAST(Effects_Buffer*,me->effects_buffer)->set_depth( depth );
-#endif
-}
-
-void* gme_user_data ( Music_Emu const* me ) { return me->user_data(); }
-void gme_set_user_data ( Music_Emu* me, void* new_user_data ) { me->set_user_data( new_user_data ); }
-void gme_set_user_cleanup(Music_Emu* me, gme_user_cleanup_t func ) { me->set_user_cleanup( func ); }
-
-gme_err_t gme_start_track ( Music_Emu* me, int index ) { return me->start_track( index ); }
-gme_err_t gme_play ( Music_Emu* me, long n, short* p ) { return me->play( n, p ); }
-void gme_set_fade ( Music_Emu* me, long start_msec ) { me->set_fade( start_msec ); }
-int gme_track_ended ( Music_Emu const* me ) { return me->track_ended(); }
-long gme_tell ( Music_Emu const* me ) { return me->tell(); }
-gme_err_t gme_seek ( Music_Emu* me, long msec ) { return me->seek( msec ); }
-int gme_voice_count ( Music_Emu const* me ) { return me->voice_count(); }
-void gme_ignore_silence ( Music_Emu* me, int disable ) { me->ignore_silence( disable != 0 ); }
-void gme_set_tempo ( Music_Emu* me, double t ) { me->set_tempo( t ); }
-void gme_mute_voice ( Music_Emu* me, int index, int mute ) { me->mute_voice( index, mute != 0 ); }
-void gme_mute_voices ( Music_Emu* me, int mask ) { me->mute_voices( mask ); }
-void gme_set_equalizer ( Music_Emu* me, gme_equalizer_t const* eq ) { me->set_equalizer( *eq ); }
-gme_equalizer_t gme_equalizer( Music_Emu const* me ) { return me->equalizer(); }
-const char** gme_voice_names ( Music_Emu const* me ) { return me->voice_names(); }
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/gme.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/gme.h
deleted file mode 100644
index 469c901c..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/gme.h
+++ /dev/null
@@ -1,222 +0,0 @@
-/* Game music emulator library C interface (also usable from C++) */
-
-/* Game_Music_Emu 0.5.2 */
-#ifndef GME_H
-#define GME_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/* Error string returned by library functions, or NULL if no error (success) */
-typedef const char* gme_err_t;
-
-/* First parameter of most gme_ functions is a pointer to the Music_Emu */
-typedef struct Music_Emu Music_Emu;
-
-
-/******** Basic operations ********/
-
-/* Create emulator and load game music file/data into it. Sets *out to new emulator. */
-gme_err_t gme_open_file( const char* path, Music_Emu** out, long sample_rate );
-
-/* Number of tracks available */
-int gme_track_count( Music_Emu const* );
-
-/* Start a track, where 0 is the first track */
-gme_err_t gme_start_track( Music_Emu*, int index );
-
-/* Generate 'count' 16-bit signed samples info 'out'. Output is in stereo. */
-gme_err_t gme_play( Music_Emu*, long count, short* out );
-
-/* Finish using emulator and free memory */
-void gme_delete( Music_Emu* );
-
-
-/******** Track position/length ********/
-
-/* Set time to start fading track out. Once fade ends track_ended() returns true.
-Fade time can be changed while track is playing. */
-void gme_set_fade( Music_Emu*, long start_msec );
-
-/* True if a track has reached its end */
-int gme_track_ended( Music_Emu const* );
-
-/* Number of milliseconds (1000 = one second) played since beginning of track */
-long gme_tell( Music_Emu const* );
-
-/* Seek to new time in track. Seeking backwards or far forward can take a while. */
-gme_err_t gme_seek( Music_Emu*, long msec );
-
-
-/******** Informational ********/
-
-/* If you only need track information from a music file, pass gme_info_only for
-sample_rate to open/load. */
-enum { gme_info_only = -1 };
-
-/* Most recent warning string, or NULL if none. Clears current warning after returning.
-Warning is also cleared when loading a file and starting a track. */
-const char* gme_warning( Music_Emu* );
-
-/* Load m3u playlist file (must be done after loading music) */
-gme_err_t gme_load_m3u( Music_Emu*, const char* path );
-
-/* Clear any loaded m3u playlist and any internal playlist that the music format
-supports (NSFE for example). */
-void gme_clear_playlist( Music_Emu* );
-
-/* Get information for a particular track (length, name, author, etc.) */
-typedef struct track_info_t track_info_t;
-gme_err_t gme_track_info( Music_Emu const*, track_info_t* out, int track );
-
-struct track_info_t
-{
- long track_count;
-
- /* times in milliseconds; -1 if unknown */
- long length;
- long intro_length;
- long loop_length;
-
- /* empty string if not available */
- char system [256];
- char game [256];
- char song [256];
- char author [256];
- char copyright [256];
- char comment [256];
- char dumper [256];
-};
-enum { gme_max_field = 255 };
-
-
-/******** Advanced playback ********/
-
-/* Adjust stereo echo depth, where 0.0 = off and 1.0 = maximum. Has no effect for
-GYM, SPC, and Sega Genesis VGM music */
-void gme_set_stereo_depth( Music_Emu*, double depth );
-
-/* Disable automatic end-of-track detection and skipping of silence at beginning
-if ignore is true */
-void gme_ignore_silence( Music_Emu*, int ignore );
-
-/* Adjust song tempo, where 1.0 = normal, 0.5 = half speed, 2.0 = double speed.
-Track length as returned by track_info() assumes a tempo of 1.0. */
-void gme_set_tempo( Music_Emu*, double tempo );
-
-/* Number of voices used by currently loaded file */
-int gme_voice_count( Music_Emu const* );
-
-/* Names of voices */
-const char** gme_voice_names( Music_Emu const* );
-
-/* Mute/unmute voice i, where voice 0 is first voice */
-void gme_mute_voice( Music_Emu*, int index, int mute );
-
-/* Set muting state of all voices at once using a bit mask, where -1 mutes all
-voices, 0 unmutes them all, 0x01 mutes just the first voice, etc. */
-void gme_mute_voices( Music_Emu*, int muting_mask );
-
-/* Frequency equalizer parameters (see gme.txt) */
-typedef struct gme_equalizer_t
-{
- double treble; /* -50.0 = muffled, 0 = flat, +5.0 = extra-crisp */
- long bass; /* 1 = full bass, 90 = average, 16000 = almost no bass */
-} gme_equalizer_t;
-
-/* Get current frequency equalizater parameters */
-gme_equalizer_t gme_equalizer( Music_Emu const* );
-
-/* Change frequency equalizer parameters */
-void gme_set_equalizer( Music_Emu*, gme_equalizer_t const* eq );
-
-
-
-/******** Game music types ********/
-
-/* gme_type_t is a pointer to this structure. For example, gme_nsf_type->system is
-"Nintendo NES" and gme_nsf_type->new_emu() is equilvant to new Nsf_Emu (in C++). */
-typedef struct gme_type_t_ const* gme_type_t;
-struct gme_type_t_
-{
- const char* system; /* name of system this music file type is generally for */
- int track_count; /* non-zero for formats with a fixed number of tracks */
- Music_Emu* (*new_emu)(); /* Create new emulator for this type (useful in C++ only) */
- Music_Emu* (*new_info)(); /* Create new info reader for this type */
-
- /* internal */
- const char* extension_;
- int flags_;
-};
-
-/* Emulator type constants for each supported file type */
-extern struct gme_type_t_ const gme_ay_type [], gme_gbs_type [], gme_gym_type [],
- gme_hes_type [], gme_kss_type [], gme_nsf_type [], gme_nsfe_type [],
- gme_sap_type [], gme_spc_type [], gme_vgm_type [], gme_vgz_type [];
-
-/* Type of this emulator */
-gme_type_t gme_type( Music_Emu const* );
-
-/* Pointer to array of all music types, with NULL entry at end. Allows a player linked
-to this library to support new music types without having to be updated. */
-gme_type_t const* gme_type_list();
-
-
-/******** Advanced file loading ********/
-
-/* Error returned if file type is not supported */
-extern const char gme_wrong_file_type [];
-
-/* Same as gme_open_file(), but uses file data already in memory. Makes copy of data. */
-gme_err_t gme_open_data( void const* data, long size, Music_Emu** out, long sample_rate );
-
-/* Determine likely game music type based on first four bytes of file. Returns
-string containing proper file suffix (i.e. "NSF", "SPC", etc.) or "" if
-file header is not recognized. */
-const char* gme_identify_header( void const* header );
-
-/* Get corresponding music type for file path or extension passed in. */
-gme_type_t gme_identify_extension( const char* path_or_extension );
-
-/* Determine file type based on file's extension or header (if extension isn't recognized).
-Sets *type_out to type, or 0 if unrecognized or error. */
-gme_err_t gme_identify_file( const char* path, gme_type_t* type_out );
-
-/* Create new emulator and set sample rate. Returns NULL if out of memory. If you only need
-track information, pass gme_info_only for sample_rate. */
-Music_Emu* gme_new_emu( gme_type_t, long sample_rate );
-
-/* Load music file into emulator */
-gme_err_t gme_load_file( Music_Emu*, const char* path );
-
-/* Load music file from memory into emulator. Makes a copy of data passed. */
-gme_err_t gme_load_data( Music_Emu*, void const* data, long size );
-
-/* Load music file using custom data reader function that will be called to
-read file data. Most emulators load the entire file in one read call. */
-typedef gme_err_t (*gme_reader_t)( void* your_data, void* out, long count );
-gme_err_t gme_load_custom( Music_Emu*, gme_reader_t, long file_size, void* your_data );
-
-/* Load m3u playlist file from memory (must be done after loading music) */
-gme_err_t gme_load_m3u_data( Music_Emu*, void const* data, long size );
-
-
-/******** User data ********/
-
-/* Set/get pointer to data you want to associate with this emulator.
-You can use this for whatever you want. */
-void gme_set_user_data( Music_Emu*, void* new_user_data );
-void* gme_user_data( Music_Emu const* );
-
-/* Register cleanup function to be called when deleting emulator, or NULL to
-clear it. Passes user_data to cleanup function. */
-typedef void (*gme_user_cleanup_t)( void* user_data );
-void gme_set_user_cleanup( Music_Emu*, gme_user_cleanup_t func );
-
-
-#ifdef __cplusplus
- }
-#endif
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/hes_cpu_io.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/hes_cpu_io.h
deleted file mode 100644
index b3d71dad..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/hes_cpu_io.h
+++ /dev/null
@@ -1,101 +0,0 @@
-
-#include "Hes_Emu.h"
-
-#include "blargg_source.h"
-
-int Hes_Emu::cpu_read( hes_addr_t addr )
-{
- check( addr <= 0xFFFF );
- int result = *cpu::get_code( addr );
- if ( mmr [addr >> page_shift] == 0xFF )
- result = cpu_read_( addr );
- return result;
-}
-
-void Hes_Emu::cpu_write( hes_addr_t addr, int data )
-{
- check( addr <= 0xFFFF );
- byte* out = write_pages [addr >> page_shift];
- addr &= page_size - 1;
- if ( out )
- out [addr] = data;
- else if ( mmr [addr >> page_shift] == 0xFF )
- cpu_write_( addr, data );
-}
-
-inline byte const* Hes_Emu::cpu_set_mmr( int page, int bank )
-{
- write_pages [page] = 0;
- if ( bank < 0x80 )
- return rom.at_addr( bank * (blargg_long) page_size );
-
- byte* data = 0;
- switch ( bank )
- {
- case 0xF8:
- data = cpu::ram;
- break;
-
- case 0xF9:
- case 0xFA:
- case 0xFB:
- data = &sgx [(bank - 0xF9) * page_size];
- break;
-
- default:
- if ( bank != 0xFF )
- dprintf( "Unmapped bank $%02X\n", bank );
- return rom.unmapped();
- }
-
- write_pages [page] = data;
- return data;
-}
-
-#define CPU_READ_FAST( cpu, addr, time, out ) \
- CPU_READ_FAST_( STATIC_CAST(Hes_Emu*,cpu), addr, time, out )
-
-#define CPU_READ_FAST_( cpu, addr, time, out ) \
-{\
- out = READ_PROG( addr );\
- if ( mmr [addr >> page_shift] == 0xFF )\
- {\
- FLUSH_TIME();\
- out = cpu->cpu_read_( addr );\
- CACHE_TIME();\
- }\
-}
-
-#define CPU_WRITE_FAST( cpu, addr, data, time ) \
- CPU_WRITE_FAST_( STATIC_CAST(Hes_Emu*,cpu), addr, data, time )
-
-#define CPU_WRITE_FAST_( cpu, addr, data, time ) \
-{\
- byte* out = cpu->write_pages [addr >> page_shift];\
- addr &= page_size - 1;\
- if ( out )\
- {\
- out [addr] = data;\
- }\
- else if ( mmr [addr >> page_shift] == 0xFF )\
- {\
- FLUSH_TIME();\
- cpu->cpu_write_( addr, data );\
- CACHE_TIME();\
- }\
-}
-
-#define CPU_READ( cpu, addr, time ) \
- STATIC_CAST(Hes_Emu*,cpu)->cpu_read( addr )
-
-#define CPU_WRITE( cpu, addr, data, time ) \
- STATIC_CAST(Hes_Emu*,cpu)->cpu_write( addr, data )
-
-#define CPU_WRITE_VDP( cpu, addr, data, time ) \
- STATIC_CAST(Hes_Emu*,cpu)->cpu_write_vdp( addr, data )
-
-#define CPU_SET_MMR( cpu, page, bank ) \
- STATIC_CAST(Hes_Emu*,cpu)->cpu_set_mmr( page, bank )
-
-#define CPU_DONE( cpu, time, result_out ) \
- result_out = STATIC_CAST(Hes_Emu*,cpu)->cpu_done()
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/nes_cpu_io.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/nes_cpu_io.h
deleted file mode 100644
index 4bae3793..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/nes_cpu_io.h
+++ /dev/null
@@ -1,83 +0,0 @@
-
-#include "Nsf_Emu.h"
-
-#if !NSF_EMU_APU_ONLY
- #include "Nes_Namco_Apu.h"
-#endif
-
-#include "blargg_source.h"
-
-int Nsf_Emu::cpu_read( nes_addr_t addr )
-{
- int result;
-
- result = cpu::low_mem [addr & 0x7FF];
- if ( !(addr & 0xE000) )
- goto exit;
-
- result = *cpu::get_code( addr );
- if ( addr > 0x7FFF )
- goto exit;
-
- result = sram [addr & (sizeof sram - 1)];
- if ( addr > 0x5FFF )
- goto exit;
-
- if ( addr == Nes_Apu::status_addr )
- return apu.read_status( cpu::time() );
-
- #if !NSF_EMU_APU_ONLY
- if ( addr == Nes_Namco_Apu::data_reg_addr && namco )
- return namco->read_data();
- #endif
-
- result = addr >> 8; // simulate open bus
-
- if ( addr != 0x2002 )
- dprintf( "Read unmapped $%.4X\n", (unsigned) addr );
-
-exit:
- return result;
-}
-
-void Nsf_Emu::cpu_write( nes_addr_t addr, int data )
-{
- {
- nes_addr_t offset = addr ^ sram_addr;
- if ( offset < sizeof sram )
- {
- sram [offset] = data;
- return;
- }
- }
- {
- int temp = addr & 0x7FF;
- if ( !(addr & 0xE000) )
- {
- cpu::low_mem [temp] = data;
- return;
- }
- }
-
- if ( unsigned (addr - Nes_Apu::start_addr) <= Nes_Apu::end_addr - Nes_Apu::start_addr )
- {
- GME_APU_HOOK( this, addr - Nes_Apu::start_addr, data );
- apu.write_register( cpu::time(), addr, data );
- return;
- }
-
- unsigned bank = addr - bank_select_addr;
- if ( bank < bank_count )
- {
- blargg_long offset = rom.mask_addr( data * (blargg_long) bank_size );
- if ( offset >= rom.size() )
- set_warning( "Invalid bank" );
- cpu::map_code( (bank + 8) * bank_size, bank_size, rom.at_addr( offset ) );
- return;
- }
-
- cpu_write_misc( addr, data );
-}
-
-#define CPU_READ( cpu, addr, time ) STATIC_CAST(Nsf_Emu&,*cpu).cpu_read( addr )
-#define CPU_WRITE( cpu, addr, data, time ) STATIC_CAST(Nsf_Emu&,*cpu).cpu_write( addr, data )
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/sap_cpu_io.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/sap_cpu_io.h
deleted file mode 100644
index 8c2f6dd0..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/gme/sap_cpu_io.h
+++ /dev/null
@@ -1,26 +0,0 @@
-
-#include "Sap_Emu.h"
-
-#include "blargg_source.h"
-
-#define CPU_WRITE( cpu, addr, data, time ) STATIC_CAST(Sap_Emu&,*cpu).cpu_write( addr, data )
-
-void Sap_Emu::cpu_write( sap_addr_t addr, int data )
-{
- mem.ram [addr] = data;
- if ( (addr >> 8) == 0xD2 )
- cpu_write_( addr, data );
-}
-
-#ifdef NDEBUG
- #define CPU_READ( cpu, addr, time ) READ_LOW( addr )
-#else
- #define CPU_READ( cpu, addr, time ) STATIC_CAST(Sap_Emu&,*cpu).cpu_read( addr )
-
- int Sap_Emu::cpu_read( sap_addr_t addr )
- {
- if ( (addr & 0xF900) == 0xD000 )
- dprintf( "Unmapped read $%04X\n", addr );
- return mem.ram [addr];
- }
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/license.txt b/plugins/gme/Game_Music_Emu-0.5.2/license.txt
deleted file mode 100644
index 5faba9d4..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/license.txt
+++ /dev/null
@@ -1,504 +0,0 @@
- GNU LESSER GENERAL PUBLIC LICENSE
- Version 2.1, February 1999
-
- Copyright (C) 1991, 1999 Free Software Foundation, Inc.
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-[This is the first released version of the Lesser GPL. It also counts
- as the successor of the GNU Library Public License, version 2, hence
- the version number 2.1.]
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-Licenses are intended to guarantee your freedom to share and change
-free software--to make sure the software is free for all its users.
-
- This license, the Lesser General Public License, applies to some
-specially designated software packages--typically libraries--of the
-Free Software Foundation and other authors who decide to use it. You
-can use it too, but we suggest you first think carefully about whether
-this license or the ordinary General Public License is the better
-strategy to use in any particular case, based on the explanations below.
-
- When we speak of free software, we are referring to freedom of use,
-not price. Our General Public Licenses are designed to make sure that
-you have the freedom to distribute copies of free software (and charge
-for this service if you wish); that you receive source code or can get
-it if you want it; that you can change the software and use pieces of
-it in new free programs; and that you are informed that you can do
-these things.
-
- To protect your rights, we need to make restrictions that forbid
-distributors to deny you these rights or to ask you to surrender these
-rights. These restrictions translate to certain responsibilities for
-you if you distribute copies of the library or if you modify it.
-
- For example, if you distribute copies of the library, whether gratis
-or for a fee, you must give the recipients all the rights that we gave
-you. You must make sure that they, too, receive or can get the source
-code. If you link other code with the library, you must provide
-complete object files to the recipients, so that they can relink them
-with the library after making changes to the library and recompiling
-it. And you must show them these terms so they know their rights.
-
- We protect your rights with a two-step method: (1) we copyright the
-library, and (2) we offer you this license, which gives you legal
-permission to copy, distribute and/or modify the library.
-
- To protect each distributor, we want to make it very clear that
-there is no warranty for the free library. Also, if the library is
-modified by someone else and passed on, the recipients should know
-that what they have is not the original version, so that the original
-author's reputation will not be affected by problems that might be
-introduced by others.
-
- Finally, software patents pose a constant threat to the existence of
-any free program. We wish to make sure that a company cannot
-effectively restrict the users of a free program by obtaining a
-restrictive license from a patent holder. Therefore, we insist that
-any patent license obtained for a version of the library must be
-consistent with the full freedom of use specified in this license.
-
- Most GNU software, including some libraries, is covered by the
-ordinary GNU General Public License. This license, the GNU Lesser
-General Public License, applies to certain designated libraries, and
-is quite different from the ordinary General Public License. We use
-this license for certain libraries in order to permit linking those
-libraries into non-free programs.
-
- When a program is linked with a library, whether statically or using
-a shared library, the combination of the two is legally speaking a
-combined work, a derivative of the original library. The ordinary
-General Public License therefore permits such linking only if the
-entire combination fits its criteria of freedom. The Lesser General
-Public License permits more lax criteria for linking other code with
-the library.
-
- We call this license the "Lesser" General Public License because it
-does Less to protect the user's freedom than the ordinary General
-Public License. It also provides other free software developers Less
-of an advantage over competing non-free programs. These disadvantages
-are the reason we use the ordinary General Public License for many
-libraries. However, the Lesser license provides advantages in certain
-special circumstances.
-
- For example, on rare occasions, there may be a special need to
-encourage the widest possible use of a certain library, so that it becomes
-a de-facto standard. To achieve this, non-free programs must be
-allowed to use the library. A more frequent case is that a free
-library does the same job as widely used non-free libraries. In this
-case, there is little to gain by limiting the free library to free
-software only, so we use the Lesser General Public License.
-
- In other cases, permission to use a particular library in non-free
-programs enables a greater number of people to use a large body of
-free software. For example, permission to use the GNU C Library in
-non-free programs enables many more people to use the whole GNU
-operating system, as well as its variant, the GNU/Linux operating
-system.
-
- Although the Lesser General Public License is Less protective of the
-users' freedom, it does ensure that the user of a program that is
-linked with the Library has the freedom and the wherewithal to run
-that program using a modified version of the Library.
-
- The precise terms and conditions for copying, distribution and
-modification follow. Pay close attention to the difference between a
-"work based on the library" and a "work that uses the library". The
-former contains code derived from the library, whereas the latter must
-be combined with the library in order to run.
-
- GNU LESSER GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License Agreement applies to any software library or other
-program which contains a notice placed by the copyright holder or
-other authorized party saying it may be distributed under the terms of
-this Lesser General Public License (also called "this License").
-Each licensee is addressed as "you".
-
- A "library" means a collection of software functions and/or data
-prepared so as to be conveniently linked with application programs
-(which use some of those functions and data) to form executables.
-
- The "Library", below, refers to any such software library or work
-which has been distributed under these terms. A "work based on the
-Library" means either the Library or any derivative work under
-copyright law: that is to say, a work containing the Library or a
-portion of it, either verbatim or with modifications and/or translated
-straightforwardly into another language. (Hereinafter, translation is
-included without limitation in the term "modification".)
-
- "Source code" for a work means the preferred form of the work for
-making modifications to it. For a library, complete source code means
-all the source code for all modules it contains, plus any associated
-interface definition files, plus the scripts used to control compilation
-and installation of the library.
-
- Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running a program using the Library is not restricted, and output from
-such a program is covered only if its contents constitute a work based
-on the Library (independent of the use of the Library in a tool for
-writing it). Whether that is true depends on what the Library does
-and what the program that uses the Library does.
-
- 1. You may copy and distribute verbatim copies of the Library's
-complete source code as you receive it, in any medium, provided that
-you conspicuously and appropriately publish on each copy an
-appropriate copyright notice and disclaimer of warranty; keep intact
-all the notices that refer to this License and to the absence of any
-warranty; and distribute a copy of this License along with the
-Library.
-
- You may charge a fee for the physical act of transferring a copy,
-and you may at your option offer warranty protection in exchange for a
-fee.
-
- 2. You may modify your copy or copies of the Library or any portion
-of it, thus forming a work based on the Library, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) The modified work must itself be a software library.
-
- b) You must cause the files modified to carry prominent notices
- stating that you changed the files and the date of any change.
-
- c) You must cause the whole of the work to be licensed at no
- charge to all third parties under the terms of this License.
-
- d) If a facility in the modified Library refers to a function or a
- table of data to be supplied by an application program that uses
- the facility, other than as an argument passed when the facility
- is invoked, then you must make a good faith effort to ensure that,
- in the event an application does not supply such function or
- table, the facility still operates, and performs whatever part of
- its purpose remains meaningful.
-
- (For example, a function in a library to compute square roots has
- a purpose that is entirely well-defined independent of the
- application. Therefore, Subsection 2d requires that any
- application-supplied function or table used by this function must
- be optional: if the application does not supply it, the square
- root function must still compute square roots.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Library,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Library, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote
-it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Library.
-
-In addition, mere aggregation of another work not based on the Library
-with the Library (or with a work based on the Library) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may opt to apply the terms of the ordinary GNU General Public
-License instead of this License to a given copy of the Library. To do
-this, you must alter all the notices that refer to this License, so
-that they refer to the ordinary GNU General Public License, version 2,
-instead of to this License. (If a newer version than version 2 of the
-ordinary GNU General Public License has appeared, then you can specify
-that version instead if you wish.) Do not make any other change in
-these notices.
-
- Once this change is made in a given copy, it is irreversible for
-that copy, so the ordinary GNU General Public License applies to all
-subsequent copies and derivative works made from that copy.
-
- This option is useful when you wish to copy part of the code of
-the Library into a program that is not a library.
-
- 4. You may copy and distribute the Library (or a portion or
-derivative of it, under Section 2) in object code or executable form
-under the terms of Sections 1 and 2 above provided that you accompany
-it with the complete corresponding machine-readable source code, which
-must be distributed under the terms of Sections 1 and 2 above on a
-medium customarily used for software interchange.
-
- If distribution of object code is made by offering access to copy
-from a designated place, then offering equivalent access to copy the
-source code from the same place satisfies the requirement to
-distribute the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 5. A program that contains no derivative of any portion of the
-Library, but is designed to work with the Library by being compiled or
-linked with it, is called a "work that uses the Library". Such a
-work, in isolation, is not a derivative work of the Library, and
-therefore falls outside the scope of this License.
-
- However, linking a "work that uses the Library" with the Library
-creates an executable that is a derivative of the Library (because it
-contains portions of the Library), rather than a "work that uses the
-library". The executable is therefore covered by this License.
-Section 6 states terms for distribution of such executables.
-
- When a "work that uses the Library" uses material from a header file
-that is part of the Library, the object code for the work may be a
-derivative work of the Library even though the source code is not.
-Whether this is true is especially significant if the work can be
-linked without the Library, or if the work is itself a library. The
-threshold for this to be true is not precisely defined by law.
-
- If such an object file uses only numerical parameters, data
-structure layouts and accessors, and small macros and small inline
-functions (ten lines or less in length), then the use of the object
-file is unrestricted, regardless of whether it is legally a derivative
-work. (Executables containing this object code plus portions of the
-Library will still fall under Section 6.)
-
- Otherwise, if the work is a derivative of the Library, you may
-distribute the object code for the work under the terms of Section 6.
-Any executables containing that work also fall under Section 6,
-whether or not they are linked directly with the Library itself.
-
- 6. As an exception to the Sections above, you may also combine or
-link a "work that uses the Library" with the Library to produce a
-work containing portions of the Library, and distribute that work
-under terms of your choice, provided that the terms permit
-modification of the work for the customer's own use and reverse
-engineering for debugging such modifications.
-
- You must give prominent notice with each copy of the work that the
-Library is used in it and that the Library and its use are covered by
-this License. You must supply a copy of this License. If the work
-during execution displays copyright notices, you must include the
-copyright notice for the Library among them, as well as a reference
-directing the user to the copy of this License. Also, you must do one
-of these things:
-
- a) Accompany the work with the complete corresponding
- machine-readable source code for the Library including whatever
- changes were used in the work (which must be distributed under
- Sections 1 and 2 above); and, if the work is an executable linked
- with the Library, with the complete machine-readable "work that
- uses the Library", as object code and/or source code, so that the
- user can modify the Library and then relink to produce a modified
- executable containing the modified Library. (It is understood
- that the user who changes the contents of definitions files in the
- Library will not necessarily be able to recompile the application
- to use the modified definitions.)
-
- b) Use a suitable shared library mechanism for linking with the
- Library. A suitable mechanism is one that (1) uses at run time a
- copy of the library already present on the user's computer system,
- rather than copying library functions into the executable, and (2)
- will operate properly with a modified version of the library, if
- the user installs one, as long as the modified version is
- interface-compatible with the version that the work was made with.
-
- c) Accompany the work with a written offer, valid for at
- least three years, to give the same user the materials
- specified in Subsection 6a, above, for a charge no more
- than the cost of performing this distribution.
-
- d) If distribution of the work is made by offering access to copy
- from a designated place, offer equivalent access to copy the above
- specified materials from the same place.
-
- e) Verify that the user has already received a copy of these
- materials or that you have already sent this user a copy.
-
- For an executable, the required form of the "work that uses the
-Library" must include any data and utility programs needed for
-reproducing the executable from it. However, as a special exception,
-the materials to be distributed need not include anything that is
-normally distributed (in either source or binary form) with the major
-components (compiler, kernel, and so on) of the operating system on
-which the executable runs, unless that component itself accompanies
-the executable.
-
- It may happen that this requirement contradicts the license
-restrictions of other proprietary libraries that do not normally
-accompany the operating system. Such a contradiction means you cannot
-use both them and the Library together in an executable that you
-distribute.
-
- 7. You may place library facilities that are a work based on the
-Library side-by-side in a single library together with other library
-facilities not covered by this License, and distribute such a combined
-library, provided that the separate distribution of the work based on
-the Library and of the other library facilities is otherwise
-permitted, and provided that you do these two things:
-
- a) Accompany the combined library with a copy of the same work
- based on the Library, uncombined with any other library
- facilities. This must be distributed under the terms of the
- Sections above.
-
- b) Give prominent notice with the combined library of the fact
- that part of it is a work based on the Library, and explaining
- where to find the accompanying uncombined form of the same work.
-
- 8. You may not copy, modify, sublicense, link with, or distribute
-the Library except as expressly provided under this License. Any
-attempt otherwise to copy, modify, sublicense, link with, or
-distribute the Library is void, and will automatically terminate your
-rights under this License. However, parties who have received copies,
-or rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
- 9. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Library or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Library (or any work based on the
-Library), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Library or works based on it.
-
- 10. Each time you redistribute the Library (or any work based on the
-Library), the recipient automatically receives a license from the
-original licensor to copy, distribute, link with or modify the Library
-subject to these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties with
-this License.
-
- 11. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Library at all. For example, if a patent
-license would not permit royalty-free redistribution of the Library by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Library.
-
-If any portion of this section is held invalid or unenforceable under any
-particular circumstance, the balance of the section is intended to apply,
-and the section as a whole is intended to apply in other circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 12. If the distribution and/or use of the Library is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Library under this License may add
-an explicit geographical distribution limitation excluding those countries,
-so that distribution is permitted only in or among countries not thus
-excluded. In such case, this License incorporates the limitation as if
-written in the body of this License.
-
- 13. The Free Software Foundation may publish revised and/or new
-versions of the Lesser General Public License from time to time.
-Such new versions will be similar in spirit to the present version,
-but may differ in detail to address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Library
-specifies a version number of this License which applies to it and
-"any later version", you have the option of following the terms and
-conditions either of that version or of any later version published by
-the Free Software Foundation. If the Library does not specify a
-license version number, you may choose any version ever published by
-the Free Software Foundation.
-
- 14. If you wish to incorporate parts of the Library into other free
-programs whose distribution conditions are incompatible with these,
-write to the author to ask for permission. For software which is
-copyrighted by the Free Software Foundation, write to the Free
-Software Foundation; we sometimes make exceptions for this. Our
-decision will be guided by the two goals of preserving the free status
-of all derivatives of our free software and of promoting the sharing
-and reuse of software generally.
-
- NO WARRANTY
-
- 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
-LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Libraries
-
- If you develop a new library, and you want it to be of the greatest
-possible use to the public, we recommend making it free software that
-everyone can redistribute and change. You can do so by permitting
-redistribution under these terms (or, alternatively, under the terms of the
-ordinary General Public License).
-
- To apply these terms, attach the following notices to the library. It is
-safest to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least the
-"copyright" line and a pointer to where the full notice is found.
-
- <one line to give the library's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-Also add information on how to contact you by electronic and paper mail.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the library, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the
- library `Frob' (a library for tweaking knobs) written by James Random Hacker.
-
- <signature of Ty Coon>, 1 April 1990
- Ty Coon, President of Vice
-
-That's all there is to it!
-
-
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/player/Audio_Scope.cpp b/plugins/gme/Game_Music_Emu-0.5.2/player/Audio_Scope.cpp
deleted file mode 100644
index 74cb2c32..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/player/Audio_Scope.cpp
+++ /dev/null
@@ -1,198 +0,0 @@
-// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
-
-#include "Audio_Scope.h"
-
-#include <assert.h>
-#include <stdlib.h>
-
-/* Copyright (C) 2005-2006 by Shay Green. Permission is hereby granted, free of
-charge, to any person obtaining a copy of this software module and associated
-documentation files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use, copy, modify,
-merge, publish, distribute, sublicense, and/or sell copies of the Software, and
-to permit persons to whom the Software is furnished to do so, subject to the
-following conditions: The above copyright notice and this permission notice
-shall be included in all copies or substantial portions of the Software. THE
-SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
-INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
-PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-
-int const step_bits = 8;
-int const step_unit = 1 << step_bits;
-int const erase_color = 1;
-int const draw_color = 2;
-
-Audio_Scope::Audio_Scope()
-{
- surface = 0;
- buf = 0;
-}
-
-Audio_Scope::~Audio_Scope()
-{
- free( buf );
-
- if ( surface )
- SDL_FreeSurface( surface );
-}
-
-const char* Audio_Scope::init( int width, int height )
-{
- assert( height <= 256 );
- assert( !buf ); // can only call init() once
-
- buf = (byte*) calloc( width * sizeof *buf, 1 );
- if ( !buf )
- return "Out of memory";
-
- low_y = 0;
- high_y = height;
- buf_size = width;
-
- for ( sample_shift = 6; sample_shift < 14; )
- if ( ((0x7FFFL * 2) >> sample_shift++) < height )
- break;
-
- v_offset = height / 2 - (0x10000 >> sample_shift);
-
- screen = SDL_SetVideoMode( width, height, 0, 0 );
- if ( !screen )
- return "Couldn't set video mode";
-
- surface = SDL_CreateRGBSurface( SDL_SWSURFACE, width, height, 8, 0, 0, 0, 0 );
- if ( !screen )
- return "Couldn't create surface";
-
- static SDL_Color palette [2] = { {0, 0, 0}, {0, 255, 0} };
- SDL_SetColors( surface, palette, 1, 2 );
-
- return 0; // success
-}
-
-const char* Audio_Scope::draw( const short* in, long count, double step )
-{
- int low = low_y;
- int high = high_y;
-
- if ( count >= buf_size )
- {
- count = buf_size;
- low_y = 0x7FFF;
- high_y = 0;
- }
-
- if ( SDL_LockSurface( surface ) < 0 )
- return "Couldn't lock surface";
- render( in, count, (long) (step * step_unit) );
- SDL_UnlockSurface( surface );
-
- if ( low > low_y )
- low = low_y;
-
- if ( high < high_y )
- high = high_y;
-
- SDL_Rect r;
- r.x = 0;
- r.w = buf_size;
- r.y = low + v_offset;
- r.h = high - low + 1;
-
- if ( SDL_BlitSurface( surface, &r, screen, &r ) < 0 )
- return "Blit to screen failed";
-
- if ( SDL_Flip( screen ) < 0 )
- return "Couldn't flip screen";
-
- return 0; // success
-}
-
-void Audio_Scope::render( short const* in, long count, long step )
-{
- byte* old_pos = buf;
- long surface_pitch = surface->pitch;
- byte* out = (byte*) surface->pixels + v_offset * surface_pitch;
- int old_erase = *old_pos;
- int old_draw = 0;
- long in_pos = 0;
-
- int low_y = this->low_y;
- int high_y = this->high_y;
- int half_step = (step + step_unit / 2) >> (step_bits + 1);
-
- while ( count-- )
- {
- // Line drawing/erasing starts at previous sample and ends one short of
- // current sample, except when previous and current are the same.
-
- // Extra read on the last iteration of line loops will always be at the
- // height of the next sample, and thus within the gworld bounds.
-
- // Erase old line
- {
- int delta = *old_pos - old_erase;
- int offset = old_erase * surface_pitch;
- old_erase += delta;
-
- int next_line = surface_pitch;
- if ( delta < 0 )
- {
- delta = -delta;
- next_line = -surface_pitch;
- }
-
- do
- {
- out [offset] = erase_color;
- offset += next_line;
- }
- while ( delta-- > 1 );
- }
-
- // Draw new line and put in old_buf
- {
-
- int in_whole = in_pos >> step_bits;
- int sample = (0x7FFF * 2 - in [in_whole] - in [in_whole + half_step]) >> sample_shift;
- if ( !in_pos )
- old_draw = sample;
- in_pos += step;
-
- int delta = sample - old_draw;
- int offset = old_draw * surface_pitch;
- old_draw += delta;
-
- int next_line = surface_pitch;
- if ( delta < 0 )
- {
- delta = -delta;
- next_line = -surface_pitch;
- }
-
- *old_pos++ = sample;
-
- // min/max updating can be interleved anywhere
-
- if ( low_y > sample )
- low_y = sample;
-
- do
- {
- out [offset] = draw_color;
- offset += next_line;
- }
- while ( delta-- > 1 );
-
- if ( high_y < sample )
- high_y = sample;
- }
-
- out++;
- }
-
- this->low_y = low_y;
- this->high_y = high_y;
-}
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/player/Audio_Scope.h b/plugins/gme/Game_Music_Emu-0.5.2/player/Audio_Scope.h
deleted file mode 100644
index 75334676..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/player/Audio_Scope.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Simple audio waveform scope in a window, using SDL multimedia library
-
-#ifndef AUDIO_SCOPE_H
-#define AUDIO_SCOPE_H
-
-#include "SDL.h"
-
-class Audio_Scope {
-public:
- typedef const char* error_t;
-
- // Initialize scope window of specified size. Height must be 256 or less.
- error_t init( int width, int height );
-
- // Draw at most 'count' samples from 'in', skipping 'step' samples after
- // each sample drawn. Step can be less than 1.0.
- error_t draw( const short* in, long count, double step = 1.0 );
-
- Audio_Scope();
- ~Audio_Scope();
-
-private:
- typedef unsigned char byte;
- SDL_Surface* screen;
- SDL_Surface* surface;
- byte* buf;
- int buf_size;
- int sample_shift;
- int low_y;
- int high_y;
- int v_offset;
-
- void render( short const* in, long count, long step );
-};
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/player/Music_Player.cpp b/plugins/gme/Game_Music_Emu-0.5.2/player/Music_Player.cpp
deleted file mode 100644
index a39819f1..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/player/Music_Player.cpp
+++ /dev/null
@@ -1,231 +0,0 @@
-// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
-
-#include "Music_Player.h"
-
-#include "gme/Music_Emu.h"
-
-#include <string.h>
-#include <ctype.h>
-
-/* Copyright (C) 2005-2006 by Shay Green. Permission is hereby granted, free of
-charge, to any person obtaining a copy of this software module and associated
-documentation files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use, copy, modify,
-merge, publish, distribute, sublicense, and/or sell copies of the Software, and
-to permit persons to whom the Software is furnished to do so, subject to the
-following conditions: The above copyright notice and this permission notice
-shall be included in all copies or substantial portions of the Software. THE
-SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
-INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
-PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-
-#include "blargg_source.h"
-
-// Number of audio buffers per second. Adjust if you encounter audio skipping.
-const int fill_rate = 45;
-
-// Simple sound driver using SDL
-typedef void (*sound_callback_t)( void* data, short* out, int count );
-static const char* sound_init( long sample_rate, int buf_size, sound_callback_t, void* data );
-static void sound_start();
-static void sound_stop();
-static void sound_cleanup();
-
-Music_Player::Music_Player()
-{
- emu_ = 0;
- scope_buf = 0;
- paused = false;
-}
-
-blargg_err_t Music_Player::init( long rate )
-{
- sample_rate = rate;
-
- int min_size = sample_rate * 2 / fill_rate;
- int buf_size = 512;
- while ( buf_size < min_size )
- buf_size *= 2;
-
- return sound_init( sample_rate, buf_size, fill_buffer, this );
-}
-
-void Music_Player::stop()
-{
- sound_stop();
- delete emu_;
- emu_ = 0;
-}
-
-Music_Player::~Music_Player()
-{
- stop();
- sound_cleanup();
-}
-
-blargg_err_t Music_Player::load_file( const char* path )
-{
- stop();
-
- RETURN_ERR( gme_open_file( path, &emu_, sample_rate ) );
-
- char m3u_path [256 + 5];
- strncpy( m3u_path, path, 256 );
- m3u_path [256] = 0;
- char* p = strrchr( m3u_path, '.' );
- if ( !p )
- p = m3u_path + strlen( m3u_path );
- strcpy( p, ".m3u" );
- if ( emu_->load_m3u( m3u_path ) ) { } // ignore error
-
- return 0;
-}
-
-int Music_Player::track_count() const
-{
- return emu_ ? emu_->track_count() : false;
-}
-
-blargg_err_t Music_Player::start_track( int track )
-{
- if ( emu_ )
- {
- // Sound must not be running when operating on emulator
- sound_stop();
- RETURN_ERR( emu_->start_track( track ) );
-
- // Calculate track length
- if ( !emu_->track_info( &track_info_ ) )
- {
- if ( track_info_.length <= 0 )
- track_info_.length = track_info_.intro_length +
- track_info_.loop_length * 2;
- }
- if ( track_info_.length <= 0 )
- track_info_.length = (long) (2.5 * 60 * 1000);
- emu_->set_fade( track_info_.length );
-
- paused = false;
- sound_start();
- }
- return 0;
-}
-
-void Music_Player::pause( int b )
-{
- paused = b;
- if ( b )
- sound_stop();
- else
- sound_start();
-}
-
-void Music_Player::suspend()
-{
- if ( !paused )
- sound_stop();
-}
-
-void Music_Player::resume()
-{
- if ( !paused )
- sound_start();
-}
-
-bool Music_Player::track_ended() const
-{
- return emu_ ? emu_->track_ended() : false;
-}
-
-void Music_Player::set_stereo_depth( double tempo )
-{
- suspend();
- gme_set_stereo_depth( emu_, tempo );
- resume();
-}
-
-void Music_Player::set_tempo( double tempo )
-{
- suspend();
- emu_->set_tempo( tempo );
- resume();
-}
-
-void Music_Player::mute_voices( int mask )
-{
- suspend();
- emu_->mute_voices( mask );
- emu_->ignore_silence( mask != 0 );
- resume();
-}
-
-void Music_Player::fill_buffer( void* data, sample_t* out, int count )
-{
- Music_Player* self = (Music_Player*) data;
- if ( self->emu_ )
- {
- if ( self->emu_->play( count, out ) ) { } // ignore error
-
- if ( self->scope_buf )
- memcpy( self->scope_buf, out, self->scope_buf_size * sizeof *self->scope_buf );
- }
-}
-
-// Sound output driver using SDL
-
-#include "SDL.h"
-
-static sound_callback_t sound_callback;
-static void* sound_callback_data;
-
-static void sdl_callback( void* data, Uint8* out, int count )
-{
- if ( sound_callback )
- sound_callback( sound_callback_data, (short*) out, count / 2 );
-}
-
-static const char* sound_init( long sample_rate, int buf_size,
- sound_callback_t cb, void* data )
-{
- sound_callback = cb;
- sound_callback_data = data;
-
- static SDL_AudioSpec as; // making static clears all fields to 0
- as.freq = sample_rate;
- as.format = AUDIO_S16SYS;
- as.channels = 2;
- as.callback = sdl_callback;
- as.samples = buf_size;
- if ( SDL_OpenAudio( &as, 0 ) < 0 )
- {
- const char* err = SDL_GetError();
- if ( !err )
- err = "Couldn't open SDL audio";
- return err;
- }
-
- return 0;
-}
-
-static void sound_start()
-{
- SDL_PauseAudio( false );
-}
-
-static void sound_stop()
-{
- SDL_PauseAudio( true );
-
- // be sure audio thread is not active
- SDL_LockAudio();
- SDL_UnlockAudio();
-}
-
-static void sound_cleanup()
-{
- sound_stop();
- SDL_CloseAudio();
-}
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/player/Music_Player.h b/plugins/gme/Game_Music_Emu-0.5.2/player/Music_Player.h
deleted file mode 100644
index 7a573c45..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/player/Music_Player.h
+++ /dev/null
@@ -1,69 +0,0 @@
-// Simple game music file player
-
-// Game_Music_Emu 0.5.2
-#ifndef MUSIC_PLAYER_H
-#define MUSIC_PLAYER_H
-
-#include "gme/Music_Emu.h"
-
-class Music_Player {
-public:
- // Initialize player and set sample rate
- blargg_err_t init( long sample_rate = 44100 );
-
- // Load game music file. NULL on success, otherwise error string.
- blargg_err_t load_file( const char* path );
-
- // (Re)start playing track. Tracks are numbered from 0 to track_count() - 1.
- blargg_err_t start_track( int track );
-
- // Stop playing current file
- void stop();
-
-// Optional functions
-
- // Number of tracks in current file, or 0 if no file loaded.
- int track_count() const;
-
- // Info for current track
- track_info_t const& track_info() const { return track_info_; }
-
- // Pause/resume playing current track.
- void pause( int );
-
- // True if track ended
- bool track_ended() const;
-
- // Pointer to emulator
- Music_Emu* emu() const { return emu_; }
-
- // Set stereo depth, where 0.0 = none and 1.0 = maximum
- void set_stereo_depth( double );
-
- // Set tempo, where 0.5 = half speed, 1.0 = normal, 2.0 = double speed
- void set_tempo( double );
-
- // Set voice muting bitmask
- void mute_voices( int );
-
- // Set buffer to copy samples from each buffer into, or NULL to disable
- typedef short sample_t;
- void set_scope_buffer( sample_t* buf, int size ) { scope_buf = buf; scope_buf_size = size; }
-
-public:
- Music_Player();
- ~Music_Player();
-private:
- Music_Emu* emu_;
- sample_t* scope_buf;
- long sample_rate;
- int scope_buf_size;
- bool paused;
- track_info_t track_info_;
-
- void suspend();
- void resume();
- static void fill_buffer( void*, sample_t*, int );
-};
-
-#endif
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/player/player.cpp b/plugins/gme/Game_Music_Emu-0.5.2/player/player.cpp
deleted file mode 100644
index a0685997..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/player/player.cpp
+++ /dev/null
@@ -1,213 +0,0 @@
-/* How to play game music files with Music_Player (requires SDL library)
-
-Run program with path to a game music file.
-
-Left/Right Change track
-Space Pause/unpause
-E Normal/slight stereo echo/more stereo echo
--/= Adjust tempo
-1-9 Toggle channel on/off
-0 Reset tempo and turn channels back on */
-
-int const scope_width = 512;
-
-#include "Music_Player.h"
-#include "Audio_Scope.h"
-
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include "SDL.h"
-
-void handle_error( const char* );
-
-static bool paused;
-static Audio_Scope* scope;
-static Music_Player* player;
-static short scope_buf [scope_width * 2];
-
-static void init()
-{
- // Start SDL
- if ( SDL_Init( SDL_INIT_VIDEO | SDL_INIT_AUDIO ) < 0 )
- exit( EXIT_FAILURE );
- atexit( SDL_Quit );
- SDL_EnableKeyRepeat( 500, 80 );
-
- // Init scope
- scope = new Audio_Scope;
- if ( !scope )
- handle_error( "Out of memory" );
- if ( scope->init( scope_width, 256 ) )
- handle_error( "Couldn't initialize scope" );
- memset( scope_buf, 0, sizeof scope_buf );
-
- // Create player
- player = new Music_Player;
- if ( !player )
- handle_error( "Out of memory" );
- handle_error( player->init() );
- player->set_scope_buffer( scope_buf, scope_width * 2 );
-}
-
-static void start_track( int track, const char* path )
-{
- paused = false;
- handle_error( player->start_track( track - 1 ) );
-
- // update window title with track info
-
- long seconds = player->track_info().length / 1000;
- const char* game = player->track_info().game;
- if ( !*game )
- {
- // extract filename
- game = strrchr( path, '\\' ); // DOS
- if ( !game )
- game = strrchr( path, '/' ); // UNIX
- if ( !game )
- game = path;
- else
- game++; // skip path separator
- }
-
- char title [512];
- sprintf( title, "%s: %d/%d %s (%ld:%02ld)",
- game, track, player->track_count(), player->track_info().song,
- seconds / 60, seconds % 60 );
- SDL_WM_SetCaption( title, title );
-}
-
-int main( int argc, char** argv )
-{
- init();
-
- // Load file
- const char* path = (argc > 1 ? argv [argc - 1] : "test.nsf");
- handle_error( player->load_file( path ) );
- start_track( 1, path );
-
- // Main loop
- int track = 1;
- double tempo = 1.0;
- bool running = true;
- double stereo_depth = 0.0;
- int muting_mask = 0;
- while ( running )
- {
- SDL_Delay( 1000 / 100 );
-
- // Update scope
- scope->draw( scope_buf, scope_width, 2 );
-
- // Automatically go to next track when current one ends
- if ( player->track_ended() )
- {
- if ( track < player->track_count() )
- start_track( ++track, path );
- else
- player->pause( paused = true );
- }
-
- // Handle keyboard input
- SDL_Event e;
- while ( SDL_PollEvent( &e ) )
- {
- switch ( e.type )
- {
- case SDL_QUIT:
- running = false;
- break;
-
- case SDL_KEYDOWN:
- int key = e.key.keysym.sym;
- switch ( key )
- {
- case SDLK_q:
- case SDLK_ESCAPE: // quit
- running = false;
- break;
-
- case SDLK_LEFT: // prev track
- if ( !paused && !--track )
- track = 1;
- start_track( track, path );
- break;
-
- case SDLK_RIGHT: // next track
- if ( track < player->track_count() )
- start_track( ++track, path );
- break;
-
- case SDLK_MINUS: // reduce tempo
- tempo -= 0.1;
- if ( tempo < 0.1 )
- tempo = 0.1;
- player->set_tempo( tempo );
- break;
-
- case SDLK_EQUALS: // increase tempo
- tempo += 0.1;
- if ( tempo > 2.0 )
- tempo = 2.0;
- player->set_tempo( tempo );
- break;
-
- case SDLK_SPACE: // toggle pause
- paused = !paused;
- player->pause( paused );
- break;
-
- case SDLK_e: // toggle echo
- stereo_depth += 0.2;
- if ( stereo_depth > 0.5 )
- stereo_depth = 0;
- player->set_stereo_depth( stereo_depth );
- break;
-
- case SDLK_0: // reset tempo and muting
- tempo = 1.0;
- muting_mask = 0;
- player->set_tempo( tempo );
- player->mute_voices( muting_mask );
- break;
-
- default:
- if ( SDLK_1 <= key && key <= SDLK_9 ) // toggle muting
- {
- muting_mask ^= 1 << (key - SDLK_1);
- player->mute_voices( muting_mask );
- }
- }
- }
- }
- }
-
- // Cleanup
- delete player;
- delete scope;
-
- return 0;
-}
-
-void handle_error( const char* error )
-{
- if ( error )
- {
- // put error in window title
- char str [256];
- sprintf( str, "Error: %s", error );
- fprintf( stderr, str );
- SDL_WM_SetCaption( str, str );
-
- // wait for keyboard or mouse activity
- SDL_Event e;
- do
- {
- while ( !SDL_PollEvent( &e ) ) { }
- }
- while ( e.type != SDL_QUIT && e.type != SDL_KEYDOWN && e.type != SDL_MOUSEBUTTONDOWN );
-
- exit( EXIT_FAILURE );
- }
-}
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/readme.txt b/plugins/gme/Game_Music_Emu-0.5.2/readme.txt
deleted file mode 100644
index e3470bfa..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/readme.txt
+++ /dev/null
@@ -1,205 +0,0 @@
-Game_Music_Emu 0.5.2: Game Music Emulators
-------------------------------------------
-Game_Music_Emu is a collection of video game music file emulators that
-support the following formats and systems:
-
-AY ZX Spectrum/Amstrad CPC
-GBS Nintendo Game Boy
-GYM Sega Genesis/Mega Drive
-HES NEC TurboGrafx-16/PC Engine
-KSS MSX Home Computer/other Z80 systems (doesn't support FM sound)
-NSF/NSFE Nintendo NES/Famicom (with VRC 6, Namco 106, and FME-7 sound)
-SAP Atari systems using POKEY sound chip
-SPC Super Nintendo/Super Famicom
-VGM/VGZ Sega Master System/Mark III, Sega Genesis/Mega Drive,BBC Micro
-
-Features:
-* Can be used in C and C++ code
-* High emphasis has been placed on making the library very easy to use
-* One set of common functions work with all emulators the same way
-* Several code examples, including music player using SDL
-* Portable code for use on any system with modern or older C++ compilers
-* Adjustable output sample rate using quality band-limited resampling
-* Uniform access to text information fields and track timing information
-* End-of-track fading and automatic look ahead silence detection
-* Treble/bass and stereo echo for AY/GBS/HES/KSS/NSF/NSFE/SAP/VGM
-* Tempo can be adjusted and individual voices can be muted while playing
-* Can read music data from file, memory, or custom reader function/class
-* Can access track information without having to load into full emulator
-* M3U track listing support for multi-track formats
-* Modular design allows elimination of unneeded emulators/features
-
-This library has been used in game music players for Windows, Linux on
-several architectures, Mac OS, MorphOS, Xbox, PlayStation Portable,
-GP2X, and Nintendo DS.
-
-Author : Shay Green <gblargg@gmail.com>
-Website: http://www.slack.net/~ant/
-Forum : http://groups.google.com/group/blargg-sound-libs
-License: GNU Lesser General Public License (LGPL)
-
-
-Getting Started
----------------
-Build a program consisting of demo/basics.c, demo/Wave_Writer.cpp, and
-all source files in gme/. Be sure "test.nsf" is in the same directory.
-Running the program should generate the recording "out.wav".
-
-Read gme.txt for more information. Post to the discussion forum for
-assistance.
-
-
-Files
------
-gme.txt General notes about the library
-changes.txt Changes made since previous releases
-design.txt Library design notes
-license.txt GNU Lesser General Public License
-
-test.nsf Test file for NSF emulator
-test.m3u Test m3u playlist for features.c demo
-
-demo/
- basics.c Records NSF file to wave sound file
- cpp_basics.cpp C++ version of basics.c
- features.c Demonstrates many additional features
- Wave_Writer.h WAVE sound file writer used for demo output
- Wave_Writer.cpp
-
-player/ Player using the SDL multimedia library
- player.cpp Simple music player with waveform display
- Music_Player.cpp Stand alone player for background music
- Music_Player.h
- Audio_Scope.cpp Audio waveform scope
- Audio_Scope.h
-
-gme/
- blargg_config.h Library configuration (modify this file as needed)
-
- gme.h C interface (also usable in C++, and simpler too)
- gme.cpp
-
- Gme_File.h File loading and track information
- Music_Emu.h Track playback and adjustments
- Data_Reader.h Custom data readers
-
- Effects_Buffer.h Sound buffer with stereo echo and panning
- Effects_Buffer.cpp
-
- M3u_Playlist.h M3U playlist support
- M3u_Playlist.cpp
-
- Ay_Emu.h ZX Spectrum AY emulator
- Ay_Emu.cpp
- Ay_Apu.cpp
- Ay_Apu.h
- Ay_Cpu.cpp
- Ay_Cpu.h
-
- Gbs_Emu.h Nintendo Game Boy GBS emulator
- Gbs_Emu.cpp
- Gb_Apu.cpp
- Gb_Apu.h
- Gb_Cpu.cpp
- Gb_Cpu.h
- gb_cpu_io.h
- Gb_Oscs.cpp
- Gb_Oscs.h
-
- Hes_Emu.h TurboGrafx-16/PC Engine HES emulator
- Hes_Apu.cpp
- Hes_Apu.h
- Hes_Cpu.cpp
- Hes_Cpu.h
- hes_cpu_io.h
- Hes_Emu.cpp
-
- Kss_Emu.h MSX Home Computer/other Z80 systems KSS emulator
- Kss_Emu.cpp
- Kss_Cpu.cpp
- Kss_Cpu.h
- Kss_Scc_Apu.cpp
- Kss_Scc_Apu.h
- Ay_Apu.h
- Ay_Apu.cpp
- Sms_Apu.h
- Sms_Apu.cpp
- Sms_Oscs.h
-
- Nsf_Emu.h Nintendo NES NSF/NSFE emulator
- Nsf_Emu.cpp
- Nes_Apu.cpp
- Nes_Apu.h
- Nes_Cpu.cpp
- Nes_Cpu.h
- nes_cpu_io.h
- Nes_Oscs.cpp
- Nes_Oscs.h
- Nes_Fme7_Apu.cpp
- Nes_Fme7_Apu.h
- Nes_Namco_Apu.cpp
- Nes_Namco_Apu.h
- Nes_Vrc6_Apu.cpp
- Nes_Vrc6_Apu.h
- Nsfe_Emu.h NSFE support
- Nsfe_Emu.cpp
-
- Spc_Emu.h Super Nintendo SPC emulator
- Spc_Emu.cpp
- Snes_Spc.cpp
- Snes_Spc.h
- Spc_Cpu.cpp
- Spc_Cpu.h
- Spc_Dsp.cpp
- Spc_Dsp.h
- Fir_Resampler.cpp
- Fir_Resampler.h
-
- Sap_Emu.h Atari SAP emulator
- Sap_Emu.cpp
- Sap_Apu.cpp
- Sap_Apu.h
- Sap_Cpu.cpp
- Sap_Cpu.h
- sap_cpu_io.h
-
- Vgm_Emu.h Sega VGM emulator
- Vgm_Emu_Impl.cpp
- Vgm_Emu_Impl.h
- Vgm_Emu.cpp
- Ym2413_Emu.cpp
- Ym2413_Emu.h
- Gym_Emu.h Sega Genesis GYM emulator
- Gym_Emu.cpp
- Sms_Apu.cpp Common Sega emulator files
- Sms_Apu.h
- Sms_Oscs.h
- Ym2612_Emu.cpp
- Ym2612_Emu.h
- Dual_Resampler.cpp
- Dual_Resampler.h
- Fir_Resampler.cpp
- Fir_Resampler.h
-
- blargg_common.h Common files needed by all emulators
- blargg_endian.h
- blargg_source.h
- Blip_Buffer.cpp
- Blip_Buffer.h
- Gme_File.cpp
- Music_Emu.cpp
- Classic_Emu.h
- Classic_Emu.cpp
- Multi_Buffer.h
- Multi_Buffer.cpp
- Data_Reader.cpp
-
-
-Legal
------
-Game_Music_Emu library copyright (C) 2003-2006 Shay Green.
-SNES SPC DSP emulator based on OpenSPC, copyright (C) 2002 Brad Martin.
-Sega Genesis YM2612 emulator copyright (C) 2002 Stephane Dallongeville.
-
---
-Shay Green <gblargg@gmail.com>
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/test.m3u b/plugins/gme/Game_Music_Emu-0.5.2/test.m3u
deleted file mode 100644
index fd46bfe1..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/test.m3u
+++ /dev/null
@@ -1,2 +0,0 @@
-# filename,track number,track name,track time
-test.nsf,$00,BGM C,1:16
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/test.nsf b/plugins/gme/Game_Music_Emu-0.5.2/test.nsf
deleted file mode 100644
index da5fcedd..00000000
--- a/plugins/gme/Game_Music_Emu-0.5.2/test.nsf
+++ /dev/null
Binary files differ
diff --git a/plugins/gme/game-music-emu-0.5.5/changes.txt b/plugins/gme/game-music-emu-0.5.5/changes.txt
deleted file mode 100644
index f3038387..00000000
--- a/plugins/gme/game-music-emu-0.5.5/changes.txt
+++ /dev/null
@@ -1,225 +0,0 @@
-Game_Music_Emu Change Log
--------------------------
-
-Game_Music_Emu 0.5.5
---------------------
-- CMake build support has been added. You can build Game_Music_Emu as
-a shared library and install it so that you do not have to include your
-own copy if you know libgme will be present on your target system.
-Requires CMake 2.6 or higher.
-
-Game_Music_Emu 0.5.2
---------------------
-- *TONS* of changes and improvements. You should re-read the new header
-files and documentation as the changes will allow you to simplify your
-code a lot (it might even be simpler to just rewrite it). Existing code
-should continue to work without changes in most cases (see Deprecated
-features in gme.txt).
-
-- New file formats: AY, HES, KSS, SAP, NSFE
-
-- All-new comprehensive C interface (also usable from C++). Simplifies
-many things, especially file loading, and brings everything together in
-one header file (gme.h).
-
-- Information tags and track names and times can be accessed for all
-game music formats
-
-- New features supported by all emulators: end of track fading,
-automatic silence detection, adjustable song tempo, seek to new time in
-track
-
-- Updated mini player example to support track names and times, echo,
-tempo, and channel muting, and added visual waveform display
-
-- Improved configuration to use blargg_config.h, which you can modify
-and keep when you update to a newer libary version. Includes flag for
-library to automatically handle gzipped files using zlib (so you don't
-need to use Gzip_File_Reader anymore).
-
-- GBS: Fixed wave channel to not reset waveform when APU is powered off
-(affected Garfield). Also improved invalid bank selection (affected Game
-& Watch and others).
-
-- VGM: Added support for alternate noise shifter register
-configurations, used by other systems like the BBC Micro.
-
-- SPC: Removed IPL ROM dump from emulator, as none of the SPC files I
-scanned needed it, and an SPC file can include a copy if necessary. Also
-re-enabled supposed clamping in gaussian interpolation between the third
-and fourth lookups, though I don't know whether it matters
-
-- Added Music_Emu::load_mem() to use music data already in memory
-(without copying it)
-
-- Added Music_Emu::warning(), which reports minor problems when loading
-and playing a music file
-
-- Added Music_Emu::set_gain() for uniform adjustment of gain. Can only
-be set during initialization, so not useful as a general volume control.
-
-- Added custom operator new to ensure that no exceptions are thrown in
-the library (I'd use std::nothrow if it were part of pre-ISO (ARM) C++)
-
-- Added BLIP_BUFFER_FAST flag to blargg_config.h to use a lower quality
-bandlimited synthesis in "classic" emulators, which might help
-performance on ancient processors (measure first!). Don't use this
-unless absolutely necessary, as quality suffers.
-
-- Improved performance a bit for x86 platforms
-
-- Text files now in DOS newline format so they will open in Notepad
-properly
-
-- Removed requirement that file header structures not have any padding
-added to the end
-
-- Fixed common bug in all CPU emulators where negative program counter
-could crash emulator (occurred during a negative branch from the
-beginning of memory). Also fixed related bug in Z80 emulator for
-IX/IY+displacement mode.
-
-- Eliminated all warnings when compiling on gcc 4.0. The following
-generates no diagnostics:
-
- gcc -S gme/*.cpp -o /dev/null -ansi -fno-gnu-keywords
- -fno-nonansi-builtins -pedantic -W -Wabi -Wall -Wcast-align
- -Wcast-qual -Wchar-subscripts -Wdisabled-optimization -Werror
- -Winline -Wlong-long -Wmultichar -Winvalid-offsetof
- -Wnon-virtual-dtor -Woverloaded-virtual -Wparentheses
- -Wpointer-arith -Wredundant-decls -Wreorder -Wsign-compare
- -Wsign-promo -Wunknown-pragmas -Wwrite-strings
-
-
-Game_Music_Emu 0.3.0
---------------------
-- Added more demos, including music player using the SDL multimedia
-library for sound, and improved documentation
-
-- All: Improved interface to emulators to allow simpler setup and
-loading. Instead of various init() functions, all now support
-set_sample_rate( long rate ) and load( const char* file_path ).
-
-- All: Removed error return from start_track() and play(), and added
-error_count() to get the total number of emulation errors since the
-track was last started. See demos for examples of new usage.
-
-- All: Fixed mute_voices() muting to be preserved after loading files
-and starting tracks, instead of being cleared as it was whenever a track
-was started
-
-- VGM: Rewrote Vgm_Emu to support Sega Genesis/Mega Drive FM sound at
-any sample rate with optional FM oversampling, support for alternate
-YM2612 sound cores, and support for optional YM2413
-
-- VGM: Added tempo control, useful for slowing 60Hz NTSC Sega Genesis
-music to 50Hz PAL
-
-- VGM: Removed Vgm_Emu::track_data(), since I realized that this
-information is already present in the VGM header (oops!)
-
-- GYM: Changed Gym_Emu::track_length() operation (see Gym_Emu.h)
-
-- NSF: Added support for Sunsoft FME-7 sound chip used by Gimmick
-soundtrack
-
-- NSF: Fixed Namco 106 problems with Final Lap and others
-
-- Moved library sources to gme/ directory to reduce clutter, and merged
-boost/ functionality into blargg_common.h
-
-- Added Gzip_File_Reader for transparently using gzipped files
-
-
-Game_Music_Emu 0.2.4
---------------------
-- Created a discussion forum for problems and feedback:
-http://groups-beta.google.com/group/blargg-sound-libs
-
-- Changed error return value of Blip_Buffer::sample_rate() (also for
-Stereo_Buffer, Effects_Buffer, etc.) to blargg_err_t (defined in
-blargg_common.h), to make error reporting consistent with other
-functions. This means the "no error" return value is the opposite of
-what it was before, which will break current code which checks the error
-return value:
-
- // current code (broken)
- if ( !buf.sample_rate( samples_per_sec ) )
- out_of_memory();
-
- // quick-and-dirty fix (just remove the ! operation)
- if ( buf.sample_rate( samples_per_sec ) )
- out_of_memory();
-
- // proper fix
- blargg_err_t error = buf.sample_rate( samples_per_sec );
- if ( error )
- report_error( error );
-
-- Implemented workaround for MSVC++ 6 compiler limitations, allowing it
-to work on that compiler again
-
-- Added sample clamping to avoid wrap-around at high volumes, allowing
-higher volume with little distortion
-
-- Added to-do list and design notes
-
-- Added Music_Emu::skip( long sample_count ) to skip ahead in current
-track
-
-- Added Gym_Emu::track_length() and Vgm_Emu::track_length() for
-determining the length of non-looped GYM and VGM files
-
-- Partially implemented DMC non-linearity when its value is directly set
-using $4011, which reduces previously over-emphasized "popping" of
-percussion on some games (TMNT II in particular)
-
-- Fixed Fir_Resampler, used for SPC and GYM playback (was incorrectly
-using abs() instead of fabs()...argh)
-
-- Fixed SPC emulation bugs: eliminated clicks in Plok! soundtrack and
-now stops sample slightly earlier than the end, as the SNES does. Fixed
-a totally broken CPU addressing mode.
-
-- Fixed Konami VRC6 saw wave (was very broken before). Now VRC6 music
-sounds decent
-
-- Fixed a minor GBS emulation bug
-
-- Fixed GYM loop point bug when track was restarted before loop point
-had been reached
-
-- Made default GBS frequency equalization less muffled
-
-- Added pseudo-surround effect removal for SPC files
-
-- Added Music_Emu::voice_names() which returns names for each voice.
-
-- Added BLARGG_SOURCE_BEGIN which allows custom compiler options to be
-easily set for library sources
-
-- Changed assignment of expansion sound chips in Nsf_Emu to be spread
-more evenly when using Effects_Buffer
-
-- Changed 'size_t' values in Blip_Buffer interface to 'long'
-
-- Changed demo to generate a WAVE sound file rather than an AIFF file
-
-
-Game_Music_Emu 0.2.0
---------------------
-- Redid framework and rewrote/cleaned up emulators
-
-- Changed licensing to GNU Lesser General Public License (LGPL)
-
-- Added Sega Genesis GYM and Super Nintendo SPC emulators
-
-- Added Namco-106 and Konami VRC6 sound chip support to NSF emulator
-
-- Eliminated use of static mutable data in emulators, allowing
-multi-instance safety
-
-
-Game_Music_Emu 0.1.0
---------------------
-- First release
diff --git a/plugins/gme/game-music-emu-0.5.5/design.txt b/plugins/gme/game-music-emu-0.5.5/design.txt
deleted file mode 100644
index 8c8c65b1..00000000
--- a/plugins/gme/game-music-emu-0.5.5/design.txt
+++ /dev/null
@@ -1,194 +0,0 @@
-Game_Music_Emu 0.5.2 Design
----------------------------
-This might be slightly out-of-date at times, but will be a big help in
-understanding the library implementation.
-
-
-Architecture
-------------
-The library is essentially a bunch of independent game music file
-emulators unified with a common interface.
-
-Gme_File and Music_Emu provide a common interface to the emulators. The
-virtual functions are protected rather than public to allow pre- and
-post-processing of arguments and data in one place. This allows the
-emulator classes to assume that everything is set up properly when
-starting a track and playing samples.
-
-All file input is done with the Data_Reader interface. Many derived
-classes are present, for the usual disk-based file and block of memory,
-to specialized adaptors for things like reading a subset of data or
-combining a block of memory with a Data_Reader to the remaining data.
-This makes the library much more flexible with regard to the source of
-game music file data. I still added a specialized load_mem() function to
-have the emulator keep a pointer to data already read in memory, for
-those formats whose files can be absolutely huge (GYM, some VGMs). This
-is important if for some reason the caller must load the data ahead of
-time, but doesn't want the emulator needlessly making a copy.
-
-Since silence checking and fading are relatively complex, they are kept
-separate from basic file loading and track information, which are
-handled in the base class Gme_File. My original intent was to use
-Gme_File as the common base class for full emulators and track
-information-only readers, but implementing the C interface was much
-simpler if both derived from Music_Emu. User C++ code can still benefit
-from static checking by using Gme_File where only track information will
-be accessed.
-
-Each emulator generally has three components: main emulator, CPU
-emulator, and sound chip emulator(s). Each component has minimal
-coupling, so use in a full emulator or stand alone is fairly easy. This
-modularity really helps reduce complexity. Blip_Buffer helps a lot with
-simplifying the APU interfaces and implementation.
-
-The "classic" emulators derive from Classic_Emu, which handles
-Blip_Buffer filling and multiple channels. It uses Multi_Buffer for
-output, allowing you to derive a custom buffer that could output each
-voice to a separate sound channel and do different processing on each.
-At some point I'm going to implement a better Effects_Buffer that allows
-individual control of every channel.
-
-In implementing the C interface, I wanted a way to specify an emulator
-type that didn't require linking in all the emulators. For each emulator
-type there is a global object with pointers to functions to create the
-emulator or a track information reader. The emulator type is thus a
-pointer to this, which conveniently allows for a NULL value. The user
-referencing this emulator type object is what ultimately links the
-emulator in (unless new Foo_Emu is used in C++, of course). This type
-also serves as a useful substitute for RTTI on older C++ compilers.
-
-Addendum: I have since added gme_type_list(), which causes all listed
-emulators to be linked in. To avoid this, I make the list itself
-editable in blargg_config.h. Having a built-in list allows
-gme_load_file() to take a path and give back an emulator with the file
-loaded, which is extremely useful for new users.
-
-
-Interface conventions
-----------------------
-If a function retains a pointer to or replaces the value of an object
-passed, it takes a pointer so that it will be clear in the caller's
-source code that care is required.
-
-Multi-word names have an underscore '_' separator between individual
-words.
-
-Functions are named with lowercase words. Functions which perform an
-action with side-effects are named with a verb phrase (i.e. load, move,
-run). Functions which return the value of a piece of state are named
-using a noun phrase (i.e. loaded, moved, running).
-
-Classes are named with capitalized words. Only the first letter of an
-acronym is capitalized. Class names are nouns, sometimes suggestive of
-what they do (i.e. File_Scanner).
-
-Structure, enumeration, and typedefs to these and built-in types are
-named using lowercase words with a _t suffix.
-
-Macros are named with all-uppercase words.
-
-Internal names which can't be hidden due to technical reasons have an
-underscore '_' suffix.
-
-
-Managing Complexity
--------------------
-Complexity has been a factor in most library decisions. Many features
-have been passed by due to the complexity they would add. Once
-complexity goes past a certain level, it mentally grasping the library
-in its entirety, at which point more defects will occur and be hard to
-find.
-
-I chose 16-bit signed samples because it seems to be the most common
-format. Supporting multiple formats would add too much complexity to be
-worth it. Other formats can be obtained via conversion.
-
-I've kept interfaces fairly lean, leaving many possible features
-untapped but easy to add if necessary. For example the classic emulators
-could have volume and frequency equalization adjusted separately for
-each channel, since they each have an associated Blip_Synth.
-
-Source files of 400 lines or less seem to be the best size to limit
-complexity. In a few cases there is no reasonable way to split longer
-files, or there is benefit from having the source together in one file.
-
-
-Preventing Bugs
----------------
-I've done many things to reduce the opportunity for defects. A general
-principle is to write code so that defects will be as visible as
-possible. I've used several techniques to achieve this.
-
-I put assertions at key points where defects seem likely or where
-corruption due to a defect is likely to be visible. I've also put
-assertions where violations of the interface are likely. In emulators
-where I am unsure of exact hardware operation in a particular case, I
-output a debug-only message noting that this has occurred; many times I
-haven't implemented a hardware feature because nothing uses it. I've
-made code brittle where there is no clear reason flexibility; code
-written to handle every possibility sacrifices quality and reliability
-to handle vaguely defined situations.
-
-
-Flexibility through indirection
--------------------------------
-I've tried to allow the most flexibility of modules by using indirection
-to allow extension by the user. This keeps each module simpler and more
-focused on its unique task.
-
-The classic emulators use Multi_Buffer, which potentially allows a
-separate Blip_Buffer for each channel. This keeps emulators free of
-typical code to allow output in mono, stereo, panning, etc.
-
-All emulators use a reader object to access file data, allowing it to be
-stored in a regular file, compressed archive, memory, or generated
-on-the-fly. Again, the library can be kept free of the particulars of
-file access and changes required to support new formats.
-
-
-Emulators in general
---------------------
-When I wrote the first NES sound emulator, I stored most of the state in
-an emulator-specific format, with significant redundancy. In the
-register write function I decoded everything into named variables. I
-became tired of the verbosity and wanted to more closely model the
-hardware, so I moved to a style of storing the last written value to
-each register, along with as little other state as possible, mostly the
-internal hardware registers. While this involves slightly more
-recalculation, in most cases the emulation code is of comparable size.
-It also makes state save/restore (for use in a full emulator) much
-simpler. Finally, it makes debugging easier since the hardware registers
-used in emulation are obvious.
-
-
-CPU Cores
----------
-I've spent lots of time coming up with techniques to optimize the CPU
-cores. Some of the most important: execute multiple instructions during
-an emulation call, keep state in local variables to allow register
-assignment, optimize state representation for most common instructions,
-defer status flag calculation until actually needed, read program code
-directly without a call to the memory read function, always pre-fetch
-the operand byte before decoding instruction, and emulate instructions
-using common blocks of code.
-
-I've successfully used Nes_Cpu in a fairly complete NES emulator, and
-I'd like to make all the CPU emulators suitable for use in emulators. It
-seems a waste for them to be used only for the small amount of emulation
-necessary for game music files.
-
-I debugged the CPU cores by writing a test shell that ran them in
-parallel with other CPU cores and compared all memory accesses and
-processor states at each step. This provided good value at little cost.
-
-The CPU mapping page size is adjustable to allow the best tradeoff
-between memory/cache usage and handler granularity. The interface allows
-code to be somewhat independent of the page size.
-
-I optimize program memory accesses to direct reads rather than calls to
-the memory read function. My assumption is that it would be difficult to
-get useful code out of hardware I/O addresses, so no software will
-intentionally execute out of I/O space. Since the page size can be
-changed easily, most program memory mapping schemes can be accommodated.
-This greatly reduces memory access function calls.
-
diff --git a/plugins/gme/game-music-emu-0.5.5/gme.txt b/plugins/gme/game-music-emu-0.5.5/gme.txt
deleted file mode 100644
index ca3da769..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme.txt
+++ /dev/null
@@ -1,464 +0,0 @@
-Game_Music_Emu 0.5.5
---------------------
-Author : Shay Green <gblargg@gmail.com>
-Website: http://www.slack.net/~ant/libs/
-Forum : http://groups.google.com/group/blargg-sound-libs
-License: GNU Lesser General Public License (LGPL)
-
-Contents
---------
-* Overview
-* C and C++ interfaces
-* Function reference
-* Error handling
-* Emulator types
-* M3U playlist support
-* Information fields
-* Track length
-* Loading file data
-* Sound parameters
-* VGM/GYM YM2413 & YM2612 FM sound
-* Modular construction
-* Obscure features
-* Solving problems
-* Deprecated features
-* Thanks
-
-
-Overview
---------
-This library can open game music files, play tracks, and read game and
-track information tags. To play a game music file, do the following:
-
-* Open the file with gme_open_file()
-* Start a track with gme_start_track();
-* Generate samples as needed with gme_play()
-* Play samples through speaker using your operating system
-* Delete emulator when done with gme_delete()
-
-Your code must arrange for the generated samples to be played through
-the computer's speaker using whatever method your operating system
-requires.
-
-There are many additional features available; you can:
-
-* Determine of the type of a music file without opening it with
-gme_identify_*()
-* Load just the file's information tags with gme_info_only
-* Load from a block of memory rather than a file with gme_load_data()
-* Arrange for a fade-out at a particular time with gme_set_fade
-* Find when a track has ended with gme_track_ended()
-* Seek to a new time in the track with gme_seek()
-* Load an extended m3u playlist with gme_load_m3u()
-* Get a list of the voices (channels) and mute them individually with
-gme_voice_names() and gme_mute_voice()
-* Change the playback tempo without affecting pitch with gme_set_tempo()
-* Adjust treble/bass equalization with gme_set_equalizer()
-* Associate your own data with an emulator and later get it back with
-gme_set_user_data()
-* Register a function of yours to be called back when the emulator is
-deleted with gme_set_user_cleanup()
-
-Refer to gme.h for a comprehensive summary of features.
-
-
-C and C++ interfaces
---------------------
-While the library is written in C++, an extensive C interface is
-provided in gme.h. This C interface will be referred to throughout this
-documentation unless a feature is only available in the full C++
-interface. All C interface functions and other names have the gme_
-prefix, so you can recognize a C++-only feature by the lack of gme_ in
-the names used (contact me if you'd like a feature added to the C
-interface). If you're building a shared library, I highly recommend
-sticking to the C interface only, because it will be more stable between
-releases of the library than the C++ interface. Finally, the C and C++
-interfaces can be freely mixed without problems. Compare demo/basics.c
-with demo/cpp_basics.cpp to see how the C and C++ interfaces translate
-between each other.
-
-
-Function reference
-------------------
-Read the following header files for a complete reference to functions
-and features. The second group of header files can only be used in C++.
-
-blargg_config.h Library configuration
-gme.h C interface (also usable from C++)
-
-Gme_File.h File loading and track information
-Music_Emu.h Track playback and adjustments
-Data_Reader.h Custom data readers
-Effects_Buffer.h Sound buffer with adjustable stereo echo and panning
-M3u_Playlist.h M3U playlist support
-Gbs_Emu.h GBS equalizer settings
-Nsf_Emu.h NSF equalizer settings
-Spc_Emu.h SPC surround disable
-Vgm_Emu.h VGM oversampling disable and custom buffer query
-
-
-Error handling
---------------
-Functions which can fail have a return type of gme_err_t (blargg_err_t
-in the C++ interfaces), which is a pointer to an error string (const
-char*). If a function is successful it returns NULL. Errors that you can
-easily avoid are checked with debug assertions; gme_err_t return values
-are only used for genuine run-time errors that can't be easily predicted
-in advance (out of memory, I/O errors, incompatible file data). Your
-code should check all error values.
-
-To improve usability for C programmers, C++ programmers unfamiliar with
-exceptions, and compatibility with older C++ compilers, the library does
-*not* throw any C++ exceptions and uses malloc() instead of the standard
-operator new. This means that you *must* check for NULL when creating a
-library object with the new operator.
-
-When loading a music file in the wrong emulator or trying to load a
-non-music file, gme_wrong_file_type is returned. You can check for this
-error in C++ like this:
-
- gme_err_t err = gme_open_file( path, &emu );
- if ( err == gme_wrong_file_type )
- ...
-
-To check for minor problems, call gme_warning() to get a string
-describing the last warning. Your player should allow the user some way
-of knowing when this is the case, since these minor errors could affect
-playback. Without this information the user can't solve problems as
-well. When playing a track, gme_warning() returns minor playback-related
-problems (major playback problems end the track immediately and set the
-warning string).
-
-
-Emulator types
---------------
-The library includes several game music emulators that each support a
-different file type. Each is identified by a gme_type_t constant defined
-in gme.h, for example gme_nsf_emu is for the NSF emulator. If you use
-gme_open_file() or gme_open_data(), the library does the work of
-determining the file type and creating an appropriate emulator. If you
-want more control over this process, read on.
-
-There are two basic ways to identify a game music file's type: look at
-its file extension, or read the header data. The library includes
-functions to help with both methods. The first is preferable because it
-is fast and the most common way to identify files. Sometimes the
-extension is lost or wrong, so the header must be read.
-
-Use gme_identify_extension() to find the correct game music type based
-on a filename. To identify a file based on its extension and header
-contents, use gme_identify_file(). If you read the header data yourself,
-use gme_identify_header().
-
-If you want to remove support for some music types to reduce your
-executable size, edit GME_TYPE_LIST in blargg_config.h. For example, to
-support just NSF and GBS, use this:
-
- #define GME_TYPE_LIST gme_nsf_type, gme_gbs_type
-
-
-M3U playlist support
---------------------
-The library supports playlists in an extended m3u format with
-gme_load_m3u() to give track names and times to multi-song formats: AY,
-GBS, HES, KSS, NSF, NSFE, and SAP. Some aspects of the file format
-itself is not well-defined so some m3u files won't work properly
-(particularly those provided with KSS files). Only m3u files referencing
-a single file are supported; your code must handle m3u files covering
-more than one game music file, though it can use the built-in m3u
-parsing provided by the library.
-
-
-Information fields
-------------------
-Support is provided for the various text fields and length information
-in a file with gme_track_info(). If you just need track information for
-a file (for example, building a playlist), use gme_new_info() in place
-of gme_new_emu(), load the file normally, then you can access the track
-count and info, but nothing else.
-
- M3U VGM GYM SPC SAP NSFE NSF AY GBS HES KSS
- -------------------------------------------------------
-Track Count | * * * * * * * * *
- |
-System | * * * * * * * * * *
- |
-Game | * * * * * * *
- |
-Song | * * * * * * *
- |
-Author | * * * * * * * *
- |
-Copyright | * * * * * * * *
- |
-Comment | * * * *
- |
-Dumper | * * * *
- |
-Length | * * * * * *
- |
-Intro Length| * * *
- |
-Loop Length | * * *
-
-As listed above, the HES and KSS file formats don't include a track
-count, and tracks are often scattered over the 0-255 range, so an m3u
-playlist for these is a must.
-
-Unavailable text fields are set to an empty string and times to -1. Your
-code should be prepared for any combination of available and unavailable
-fields, as a particular music file might not use all of the supported
-fields listed above.
-
-Currently text fields are truncated to 255 characters. Obscure fields of
-some formats are not currently decoded; contact me if you want one
-added.
-
-
-Track length
-------------
-The library leaves it up to you as to when to stop playing a track. You
-can ask for available length information and then tell the library what
-time it should start fading the track with gme_set_fade(). By default it
-also continually checks for 6 or more seconds of silence to mark the end
-of a track. Here is a reasonable algorithm you can use to decide how
-long to play a track:
-
-* If the track length is > 0, use it
-* If the loop length > 0, play for intro + loop * 2
-* Otherwise, default to 2.5 minutes (150000 msec)
-
-If you want to play a track longer than normal, be sure the loop length
-isn't zero. See Music_Player.cpp around line 145 for example code.
-
-By default, the library skips silence at the beginning of a track. It
-also continually checks for the end of a non-looping track by watching
-for 6 seconds of unbroken silence. When doing this is scans *ahead* by
-several seconds so it can report the end of the track after only one
-second of silence has actually played. This feature can be disabled with
-gme_ignore_silence().
-
-
-Loading file data
------------------
-The library allows file data to be loaded in many different ways. All
-load functions return an error which you should check. The following
-examples assume these variables:
-
- Music_Emu* emu;
- gme_err_t error;
-
-If you're letting the library determine a file's type, you can use
-either gme_open_file() or gme_open_data():
-
- error = gme_open_file( pathname, &emu );
- error = gme_open_data( pointer, size, &emu );
-
-If you're manually determining file type and using used gme_new_emu() to
-create an emulator, you can use the following methods of loading:
-
-* From a block of memory:
-
- error = gme_load_data( emu, pointer, size );
-
-* Have library call your function to read data:
-
- gme_err_t my_read( void* my_data, void* out, long count )
- {
- // code that reads 'count' bytes into 'out' buffer
- // and return 0 if no error
- }
-
- error = gme_load_custom( emu, my_read, file_size, my_data );
-
-* If you must load the file data into memory yourself, you can have the
-library use your data directly *without* making a copy. If you do this,
-you must not free the data until you're done playing the file.
-
- error = emu->load_mem( pointer, size );
-
-* If you've already read the first bytes of a file (perhaps to determine
-the file type) and want to avoid seeking back to the beginning for
-performance reasons, use Remaining_Reader:
-
- Std_File_Reader in;
- error = in.open( file_path );
-
- char header [4];
- error = in.read( &header, sizeof header );
- ...
-
- Remaining_Reader rem( &header, sizeof header, &in );
- error = emu->load( rem );
-
-If you merely need access to a file's header after loading, use the
-emulator-specific header() functions, after casting the Music_Emu
-pointer to the specific emulator's type. This example examines the
-chip_flags field of the header if it's an NSF file:
-
- if ( music_emu->type() == gme_nsf_type )
- {
- Nsf_Emu* nsf_emu = (Nsf_Emu*) music_emu;
- if ( nsf_emu->header().chip_flags & 0x01 )
- ...
- }
-
-Contact me if you want more information about loading files.
-
-
-Sound parameters
-----------------
-All emulators support an arbitrary output sampling rate. A rate of 44100
-Hz should work well on most systems. Since band-limited synthesis is
-used, a sampling rate above 48000 Hz is not necessary and will actually
-reduce sound quality and performance.
-
-All emulators also support adjustable gain, mainly for the purpose of
-getting consistent volume between different music formats and avoiding
-excessive modulation. The gain can only be set *before* setting the
-emulator's sampling rate, so it's not useful as a general volume
-control. The default gains of emulators are set so that they give
-generally similar volumes, though some soundtracks are significantly
-louder or quieter than normal.
-
-Some emulators support adjustable treble and bass frequency equalization
-(AY, GBS, HES, KSS, NSF, NSFE, SAP, VGM) using set_equalizer().
-Parameters are specified using gme_equalizer_t eq = { treble_dB,
-bass_freq }. Treble_dB sets the treble level (in dB), where 0.0 dB gives
-normal treble; -200.0 dB is quite muffled, and 5.0 dB emphasizes treble
-for an extra crisp sound. Bass_freq sets the frequency where bass
-response starts to diminish; 15 Hz is normal, 0 Hz gives maximum bass,
-and 15000 Hz removes all bass. For example, the following makes the
-sound extra-crisp but lacking bass:
-
- gme_equalizer_t eq = { 5.0, 1000 };
- gme_set_equalizer( music_emu, &eq );
-
-Each emulator's equalization defaults to approximate the particular
-console's sound quality; this default can be determined by calling
-equalizer() just after creating the emulator. The Music_Emu::tv_eq
-profile gives sound as if coming from a TV speaker, and some emulators
-include other profiles for different versions of the system. For
-example, to use Famicom sound equalization with the NSF emulator, do the
-following:
-
- music_emu->set_equalizer( Nsf_Emu::famicom_eq );
-
-
-VGM/GYM YM2413 & YM2612 FM sound
---------------------------------
-The library plays Sega Genesis/Mega Drive music using a YM2612 FM sound
-chip emulator based on the Gens project. Because this has some
-inaccuracies, other YM2612 emulators can be used in its place by
-re-implementing the interface in YM2612_Emu.h. Available on my website
-is a modified version of MAME's YM2612 emulator, which sounds better in
-some ways and whose author is still making improvements.
-
-VGM music files using the YM2413 FM sound chip are also supported, but a
-YM2413 emulator isn't included with the library due to technical
-reasons. I have put one of the available YM2413 emulators on my website
-that can be used directly.
-
-
-Modular construction
---------------------
-The library is made of many fairly independent modules. If you're using
-only one music file emulator, you can eliminate many of the library
-sources from your program. Refer to the files list in readme.txt to get
-a general idea of what can be removed, and be sure to edit GME_TYPE_LIST
-(see "Emulator types" above). Post to the forum if you'd like me to put
-together a smaller version for a particular use, as this only takes me a
-few minutes to do.
-
-If you want to use one of the individual sound chip emulators (or CPU
-cores) in your own console emulator, first check the libraries page on
-my website since I have released several of them as stand alone
-libraries with included documentation and examples on their use. If you
-don't find it as a standalone library, contact me and I'll consider
-separating it.
-
-The "classic" sound chips use my Blip_Buffer library, which greatly
-simplifies their implementation and efficiently handles band-limited
-synthesis. It is also available as a stand alone library with
-documentation and many examples.
-
-
-Obscure features
-----------------
-The library's flexibility allows many possibilities. Contact me if you
-want help implementing ideas or removing limitations.
-
-* Uses no global/static variables, allowing multiple instances of any
-emulator. This is useful in a music player if you want to allow
-simultaneous recording or scanning of other tracks while one is already
-playing. This will also be useful if your platform disallows global
-data.
-
-* Emulators that support a custom sound buffer can have *every* voice
-routed to a different Blip_Buffer, allowing custom processing on each
-voice. For example you could record a Game Boy track as a 4-channel
-sound file.
-
-* Defining BLIP_BUFFER_FAST uses lower quality, less-multiply-intensive
-synthesis on "classic" emulators, which might help on some really old
-processors. This significantly lowers sound quality and prevents treble
-equalization. Try this if your platform's processor isn't fast enough
-for normal quality. Even on my ten-year-old 400 MHz Mac, this reduces
-processor usage at most by about 0.6% (from 4% to 3.4%), hardly worth
-the quality loss.
-
-
-Solving problems
-----------------
-If you're having problems, try the following:
-
-* If you're getting garbled sound, try this simple siren generator in
-place of your call to play(). This will quickly tell whether the problem
-is in the library or in your code.
-
- static void play_siren( long count, short* out )
- {
- static double a, a2;
- while ( count-- )
- *out++ = 0x2000 * sin( a += .1 + .05*sin( a2+=.00005 ) );
- }
-
-* Enable debugging support in your environment. This enables assertions
-and other run-time checks.
-
-* Turn the compiler's optimizer is off. Sometimes an optimizer generates
-bad code.
-
-* If multiple threads are being used, ensure that only one at a time is
-accessing a given set of objects from the library. This library is not
-in general thread-safe, though independent objects can be used in
-separate threads.
-
-* If all else fails, see if the demos work.
-
-
-Deprecated features
--------------------
-The following functions and other features have been deprecated and will
-be removed in a future release of the library. Alternatives to the
-deprecated features are listed to the right.
-
-Music_Emu::error_count() warning()
-load( header, reader ) see "Loading file data" above
-Spc_Emu::trailer() track_info()
-Spc_Emu::trailer_size()
-Gym_Emu::track_length() track_info()
-Vgm_Emu::gd3_data() track_info()
-Nsfe_Emu::disable_playlist() clear_playlist()
-
-
-Thanks
-------
-Big thanks to Chris Moeller (kode54) for help with library testing and
-feedback, for maintaining the Foobar2000 plugin foo_gep based on it, and
-for original work on openspc++ that was used when developing Spc_Emu.
-Brad Martin's excellent OpenSPC SNES DSP emulator worked well from the
-start. Also thanks to Richard Bannister, Mahendra Tallur, Shazz,
-nenolod, theHobbit, Johan Samuelsson, and nes6502 for testing, using,
-and giving feedback for the library in their respective game music
-players.
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Ay_Apu.cpp b/plugins/gme/game-music-emu-0.5.5/gme/Ay_Apu.cpp
deleted file mode 100644
index 8204abf2..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Ay_Apu.cpp
+++ /dev/null
@@ -1,395 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Ay_Apu.h"
-
-/* Copyright (C) 2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-// Emulation inaccuracies:
-// * Noise isn't run when not in use
-// * Changes to envelope and noise periods are delayed until next reload
-// * Super-sonic tone should attenuate output to about 60%, not 50%
-
-// Tones above this frequency are treated as disabled tone at half volume.
-// Power of two is more efficient (avoids division).
-unsigned const inaudible_freq = 16384;
-
-int const period_factor = 16;
-
-static byte const amp_table [16] =
-{
-#define ENTRY( n ) byte (n * Ay_Apu::amp_range + 0.5)
- // With channels tied together and 1K resistor to ground (as datasheet recommends),
- // output nearly matches logarithmic curve as claimed. Approx. 1.5 dB per step.
- ENTRY(0.000000),ENTRY(0.007813),ENTRY(0.011049),ENTRY(0.015625),
- ENTRY(0.022097),ENTRY(0.031250),ENTRY(0.044194),ENTRY(0.062500),
- ENTRY(0.088388),ENTRY(0.125000),ENTRY(0.176777),ENTRY(0.250000),
- ENTRY(0.353553),ENTRY(0.500000),ENTRY(0.707107),ENTRY(1.000000),
-
- /*
- // Measured from an AY-3-8910A chip with date code 8611.
-
- // Direct voltages without any load (very linear)
- ENTRY(0.000000),ENTRY(0.046237),ENTRY(0.064516),ENTRY(0.089785),
- ENTRY(0.124731),ENTRY(0.173118),ENTRY(0.225806),ENTRY(0.329032),
- ENTRY(0.360215),ENTRY(0.494624),ENTRY(0.594624),ENTRY(0.672043),
- ENTRY(0.766129),ENTRY(0.841935),ENTRY(0.926882),ENTRY(1.000000),
- // With only some load
- ENTRY(0.000000),ENTRY(0.011940),ENTRY(0.017413),ENTRY(0.024876),
- ENTRY(0.036318),ENTRY(0.054229),ENTRY(0.072637),ENTRY(0.122388),
- ENTRY(0.174129),ENTRY(0.239303),ENTRY(0.323881),ENTRY(0.410945),
- ENTRY(0.527363),ENTRY(0.651741),ENTRY(0.832338),ENTRY(1.000000),
- */
-#undef ENTRY
-};
-
-static byte const modes [8] =
-{
-#define MODE( a0,a1, b0,b1, c0,c1 ) \
- (a0 | a1<<1 | b0<<2 | b1<<3 | c0<<4 | c1<<5)
- MODE( 1,0, 1,0, 1,0 ),
- MODE( 1,0, 0,0, 0,0 ),
- MODE( 1,0, 0,1, 1,0 ),
- MODE( 1,0, 1,1, 1,1 ),
- MODE( 0,1, 0,1, 0,1 ),
- MODE( 0,1, 1,1, 1,1 ),
- MODE( 0,1, 1,0, 0,1 ),
- MODE( 0,1, 0,0, 0,0 ),
-};
-
-Ay_Apu::Ay_Apu()
-{
- // build full table of the upper 8 envelope waveforms
- for ( int m = 8; m--; )
- {
- byte* out = env.modes [m];
- int flags = modes [m];
- for ( int x = 3; --x >= 0; )
- {
- int amp = flags & 1;
- int end = flags >> 1 & 1;
- int step = end - amp;
- amp *= 15;
- for ( int y = 16; --y >= 0; )
- {
- *out++ = amp_table [amp];
- amp += step;
- }
- flags >>= 2;
- }
- }
-
- output( 0 );
- volume( 1.0 );
- reset();
-}
-
-void Ay_Apu::reset()
-{
- last_time = 0;
- noise.delay = 0;
- noise.lfsr = 1;
-
- osc_t* osc = &oscs [osc_count];
- do
- {
- osc--;
- osc->period = period_factor;
- osc->delay = 0;
- osc->last_amp = 0;
- osc->phase = 0;
- }
- while ( osc != oscs );
-
- for ( int i = sizeof regs; --i >= 0; )
- regs [i] = 0;
- regs [7] = 0xFF;
- write_data_( 13, 0 );
-}
-
-void Ay_Apu::write_data_( int addr, int data )
-{
- assert( (unsigned) addr < reg_count );
-
- if ( (unsigned) addr >= 14 )
- {
- #ifdef debug_printf
- debug_printf( "Wrote to I/O port %02X\n", (int) addr );
- #endif
- }
-
- // envelope mode
- if ( addr == 13 )
- {
- if ( !(data & 8) ) // convert modes 0-7 to proper equivalents
- data = (data & 4) ? 15 : 9;
- env.wave = env.modes [data - 7];
- env.pos = -48;
- env.delay = 0; // will get set to envelope period in run_until()
- }
- regs [addr] = data;
-
- // handle period changes accurately
- int i = addr >> 1;
- if ( i < osc_count )
- {
- blip_time_t period = (regs [i * 2 + 1] & 0x0F) * (0x100L * period_factor) +
- regs [i * 2] * period_factor;
- if ( !period )
- period = period_factor;
-
- // adjust time of next timer expiration based on change in period
- osc_t& osc = oscs [i];
- if ( (osc.delay += period - osc.period) < 0 )
- osc.delay = 0;
- osc.period = period;
- }
-
- // TODO: same as above for envelope timer, and it also has a divide by two after it
-}
-
-int const noise_off = 0x08;
-int const tone_off = 0x01;
-
-void Ay_Apu::run_until( blip_time_t final_end_time )
-{
- require( final_end_time >= last_time );
-
- // noise period and initial values
- blip_time_t const noise_period_factor = period_factor * 2; // verified
- blip_time_t noise_period = (regs [6] & 0x1F) * noise_period_factor;
- if ( !noise_period )
- noise_period = noise_period_factor;
- blip_time_t const old_noise_delay = noise.delay;
- blargg_ulong const old_noise_lfsr = noise.lfsr;
-
- // envelope period
- blip_time_t const env_period_factor = period_factor * 2; // verified
- blip_time_t env_period = (regs [12] * 0x100L + regs [11]) * env_period_factor;
- if ( !env_period )
- env_period = env_period_factor; // same as period 1 on my AY chip
- if ( !env.delay )
- env.delay = env_period;
-
- // run each osc separately
- for ( int index = 0; index < osc_count; index++ )
- {
- osc_t* const osc = &oscs [index];
- int osc_mode = regs [7] >> index;
-
- // output
- Blip_Buffer* const osc_output = osc->output;
- if ( !osc_output )
- continue;
- osc_output->set_modified();
-
- // period
- int half_vol = 0;
- blip_time_t inaudible_period = (blargg_ulong) (osc_output->clock_rate() +
- inaudible_freq) / (inaudible_freq * 2);
- if ( osc->period <= inaudible_period && !(osc_mode & tone_off) )
- {
- half_vol = 1; // Actually around 60%, but 50% is close enough
- osc_mode |= tone_off;
- }
-
- // envelope
- blip_time_t start_time = last_time;
- blip_time_t end_time = final_end_time;
- int const vol_mode = regs [0x08 + index];
- int volume = amp_table [vol_mode & 0x0F] >> half_vol;
- int osc_env_pos = env.pos;
- if ( vol_mode & 0x10 )
- {
- volume = env.wave [osc_env_pos] >> half_vol;
- // use envelope only if it's a repeating wave or a ramp that hasn't finished
- if ( !(regs [13] & 1) || osc_env_pos < -32 )
- {
- end_time = start_time + env.delay;
- if ( end_time >= final_end_time )
- end_time = final_end_time;
-
- //if ( !(regs [12] | regs [11]) )
- // debug_printf( "Used envelope period 0\n" );
- }
- else if ( !volume )
- {
- osc_mode = noise_off | tone_off;
- }
- }
- else if ( !volume )
- {
- osc_mode = noise_off | tone_off;
- }
-
- // tone time
- blip_time_t const period = osc->period;
- blip_time_t time = start_time + osc->delay;
- if ( osc_mode & tone_off ) // maintain tone's phase when off
- {
- blargg_long count = (final_end_time - time + period - 1) / period;
- time += count * period;
- osc->phase ^= count & 1;
- }
-
- // noise time
- blip_time_t ntime = final_end_time;
- blargg_ulong noise_lfsr = 1;
- if ( !(osc_mode & noise_off) )
- {
- ntime = start_time + old_noise_delay;
- noise_lfsr = old_noise_lfsr;
- //if ( (regs [6] & 0x1F) == 0 )
- // debug_printf( "Used noise period 0\n" );
- }
-
- // The following efficiently handles several cases (least demanding first):
- // * Tone, noise, and envelope disabled, where channel acts as 4-bit DAC
- // * Just tone or just noise, envelope disabled
- // * Envelope controlling tone and/or noise
- // * Tone and noise disabled, envelope enabled with high frequency
- // * Tone and noise together
- // * Tone and noise together with envelope
-
- // This loop only runs one iteration if envelope is disabled. If envelope
- // is being used as a waveform (tone and noise disabled), this loop will
- // still be reasonably efficient since the bulk of it will be skipped.
- while ( 1 )
- {
- // current amplitude
- int amp = 0;
- if ( (osc_mode | osc->phase) & 1 & (osc_mode >> 3 | noise_lfsr) )
- amp = volume;
- {
- int delta = amp - osc->last_amp;
- if ( delta )
- {
- osc->last_amp = amp;
- synth_.offset( start_time, delta, osc_output );
- }
- }
-
- // Run wave and noise interleved with each catching up to the other.
- // If one or both are disabled, their "current time" will be past end time,
- // so there will be no significant performance hit.
- if ( ntime < end_time || time < end_time )
- {
- // Since amplitude was updated above, delta will always be +/- volume,
- // so we can avoid using last_amp every time to calculate the delta.
- int delta = amp * 2 - volume;
- int delta_non_zero = delta != 0;
- int phase = osc->phase | (osc_mode & tone_off); assert( tone_off == 0x01 );
- do
- {
- // run noise
- blip_time_t end = end_time;
- if ( end_time > time ) end = time;
- if ( phase & delta_non_zero )
- {
- while ( ntime <= end ) // must advance *past* time to avoid hang
- {
- int changed = noise_lfsr + 1;
- noise_lfsr = (-(noise_lfsr & 1) & 0x12000) ^ (noise_lfsr >> 1);
- if ( changed & 2 )
- {
- delta = -delta;
- synth_.offset( ntime, delta, osc_output );
- }
- ntime += noise_period;
- }
- }
- else
- {
- // 20 or more noise periods on average for some music
- blargg_long remain = end - ntime;
- blargg_long count = remain / noise_period;
- if ( remain >= 0 )
- ntime += noise_period + count * noise_period;
- }
-
- // run tone
- end = end_time;
- if ( end_time > ntime ) end = ntime;
- if ( noise_lfsr & delta_non_zero )
- {
- while ( time < end )
- {
- delta = -delta;
- synth_.offset( time, delta, osc_output );
- time += period;
- //phase ^= 1;
- }
- //assert( phase == (delta > 0) );
- phase = unsigned (-delta) >> (CHAR_BIT * sizeof (unsigned) - 1);
- // (delta > 0)
- }
- else
- {
- // loop usually runs less than once
- //SUB_CASE_COUNTER( (time < end) * (end - time + period - 1) / period );
-
- while ( time < end )
- {
- time += period;
- phase ^= 1;
- }
- }
- }
- while ( time < end_time || ntime < end_time );
-
- osc->last_amp = (delta + volume) >> 1;
- if ( !(osc_mode & tone_off) )
- osc->phase = phase;
- }
-
- if ( end_time >= final_end_time )
- break; // breaks first time when envelope is disabled
-
- // next envelope step
- if ( ++osc_env_pos >= 0 )
- osc_env_pos -= 32;
- volume = env.wave [osc_env_pos] >> half_vol;
-
- start_time = end_time;
- end_time += env_period;
- if ( end_time > final_end_time )
- end_time = final_end_time;
- }
- osc->delay = time - final_end_time;
-
- if ( !(osc_mode & noise_off) )
- {
- noise.delay = ntime - final_end_time;
- noise.lfsr = noise_lfsr;
- }
- }
-
- // TODO: optimized saw wave envelope?
-
- // maintain envelope phase
- blip_time_t remain = final_end_time - last_time - env.delay;
- if ( remain >= 0 )
- {
- blargg_long count = (remain + env_period) / env_period;
- env.pos += count;
- if ( env.pos >= 0 )
- env.pos = (env.pos & 31) - 32;
- remain -= count * env_period;
- assert( -remain <= env_period );
- }
- env.delay = -remain;
- assert( env.delay > 0 );
- assert( env.pos < 0 );
-
- last_time = final_end_time;
-}
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Ay_Apu.h b/plugins/gme/game-music-emu-0.5.5/gme/Ay_Apu.h
deleted file mode 100644
index 42395e37..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Ay_Apu.h
+++ /dev/null
@@ -1,107 +0,0 @@
-// AY-3-8910 sound chip emulator
-
-// Game_Music_Emu 0.5.5
-#ifndef AY_APU_H
-#define AY_APU_H
-
-#include "blargg_common.h"
-#include "Blip_Buffer.h"
-
-class Ay_Apu {
-public:
- // Set buffer to generate all sound into, or disable sound if NULL
- void output( Blip_Buffer* );
-
- // Reset sound chip
- void reset();
-
- // Write to register at specified time
- enum { reg_count = 16 };
- void write( blip_time_t time, int addr, int data );
-
- // Run sound to specified time, end current time frame, then start a new
- // time frame at time 0. Time frames have no effect on emulation and each
- // can be whatever length is convenient.
- void end_frame( blip_time_t length );
-
-// Additional features
-
- // Set sound output of specific oscillator to buffer, where index is
- // 0, 1, or 2. If buffer is NULL, the specified oscillator is muted.
- enum { osc_count = 3 };
- void osc_output( int index, Blip_Buffer* );
-
- // Set overall volume (default is 1.0)
- void volume( double );
-
- // Set treble equalization (see documentation)
- void treble_eq( blip_eq_t const& );
-
-public:
- Ay_Apu();
- typedef unsigned char byte;
-private:
- struct osc_t
- {
- blip_time_t period;
- blip_time_t delay;
- short last_amp;
- short phase;
- Blip_Buffer* output;
- } oscs [osc_count];
- blip_time_t last_time;
- byte latch;
- byte regs [reg_count];
-
- struct {
- blip_time_t delay;
- blargg_ulong lfsr;
- } noise;
-
- struct {
- blip_time_t delay;
- byte const* wave;
- int pos;
- byte modes [8] [48]; // values already passed through volume table
- } env;
-
- void run_until( blip_time_t );
- void write_data_( int addr, int data );
-public:
- enum { amp_range = 255 };
- Blip_Synth<blip_good_quality,1> synth_;
-};
-
-inline void Ay_Apu::volume( double v ) { synth_.volume( 0.7 / osc_count / amp_range * v ); }
-
-inline void Ay_Apu::treble_eq( blip_eq_t const& eq ) { synth_.treble_eq( eq ); }
-
-inline void Ay_Apu::write( blip_time_t time, int addr, int data )
-{
- run_until( time );
- write_data_( addr, data );
-}
-
-inline void Ay_Apu::osc_output( int i, Blip_Buffer* buf )
-{
- assert( (unsigned) i < osc_count );
- oscs [i].output = buf;
-}
-
-inline void Ay_Apu::output( Blip_Buffer* buf )
-{
- osc_output( 0, buf );
- osc_output( 1, buf );
- osc_output( 2, buf );
-}
-
-inline void Ay_Apu::end_frame( blip_time_t time )
-{
- if ( time > last_time )
- run_until( time );
-
- assert( last_time >= time );
- last_time -= time;
-}
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Ay_Cpu.cpp b/plugins/gme/game-music-emu-0.5.5/gme/Ay_Cpu.cpp
deleted file mode 100644
index 0f67db1b..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Ay_Cpu.cpp
+++ /dev/null
@@ -1,1665 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-/*
-Last validated with zexall 2006.11.21 5:26 PM
-* Doesn't implement the R register or immediate interrupt after EI.
-* Address wrap-around isn't completely correct, but is prevented from crashing emulator.
-*/
-
-#include "Ay_Cpu.h"
-
-#include "blargg_endian.h"
-#include <string.h>
-
-//#include "z80_cpu_log.h"
-
-/* Copyright (C) 2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#define SYNC_TIME() (void) (s.time = s_time)
-#define RELOAD_TIME() (void) (s_time = s.time)
-
-// Callbacks to emulator
-
-#define CPU_OUT( cpu, addr, data, TIME )\
- ay_cpu_out( cpu, TIME, addr, data )
-
-#define CPU_IN( cpu, addr, TIME )\
- ay_cpu_in( cpu, addr )
-
-#include "blargg_source.h"
-
-// flags, named with hex value for clarity
-int const S80 = 0x80;
-int const Z40 = 0x40;
-int const F20 = 0x20;
-int const H10 = 0x10;
-int const F08 = 0x08;
-int const V04 = 0x04;
-int const P04 = 0x04;
-int const N02 = 0x02;
-int const C01 = 0x01;
-
-#define SZ28P( n ) szpc [n]
-#define SZ28PC( n ) szpc [n]
-#define SZ28C( n ) (szpc [n] & ~P04)
-#define SZ28( n ) SZ28C( n )
-
-#define SET_R( n ) (void) (r.r = n)
-#define GET_R() (r.r)
-
-Ay_Cpu::Ay_Cpu()
-{
- state = &state_;
- for ( int i = 0x100; --i >= 0; )
- {
- int even = 1;
- for ( int p = i; p; p >>= 1 )
- even ^= p;
- int n = (i & (S80 | F20 | F08)) | ((even & 1) * P04);
- szpc [i] = n;
- szpc [i + 0x100] = n | C01;
- }
- szpc [0x000] |= Z40;
- szpc [0x100] |= Z40;
-}
-
-void Ay_Cpu::reset( void* m )
-{
- mem = (uint8_t*) m;
-
- check( state == &state_ );
- state = &state_;
- state_.time = 0;
- state_.base = 0;
- end_time_ = 0;
-
- memset( &r, 0, sizeof r );
-}
-
-#define TIME (s_time + s.base)
-#define READ_PROG( addr ) (mem [addr])
-#define INSTR( offset ) READ_PROG( pc + (offset) )
-#define GET_ADDR() GET_LE16( &READ_PROG( pc ) )
-#define READ( addr ) READ_PROG( addr )
-#define WRITE( addr, data ) (void) (READ_PROG( addr ) = data)
-#define READ_WORD( addr ) GET_LE16( &READ_PROG( addr ) )
-#define WRITE_WORD( addr, data ) SET_LE16( &READ_PROG( addr ), data )
-#define IN( addr ) CPU_IN( this, addr, TIME )
-#define OUT( addr, data ) CPU_OUT( this, addr, data, TIME )
-
-#if BLARGG_BIG_ENDIAN
- #define R8( n, offset ) ((r8_ - offset) [n])
-#elif BLARGG_LITTLE_ENDIAN
- #define R8( n, offset ) ((r8_ - offset) [(n) ^ 1])
-#else
- #error "Byte order of CPU must be known"
-#endif
-
-//#define R16( n, shift, offset ) (r16_ [((n) >> shift) - (offset >> shift)])
-
-// help compiler see that it can just adjust stack offset, saving an extra instruction
-#define R16( n, shift, offset )\
- (*(uint16_t*) ((char*) r16_ - (offset >> (shift - 1)) + ((n) >> (shift - 1))))
-
-#define CASE5( a, b, c, d, e ) case 0x##a:case 0x##b:case 0x##c:case 0x##d:case 0x##e
-#define CASE6( a, b, c, d, e, f ) CASE5( a, b, c, d, e ): case 0x##f
-#define CASE7( a, b, c, d, e, f, g ) CASE6( a, b, c, d, e, f ): case 0x##g
-#define CASE8( a, b, c, d, e, f, g, h ) CASE7( a, b, c, d, e, f, g ): case 0x##h
-
-// high four bits are $ED time - 8, low four bits are $DD/$FD time - 8
-static byte const ed_dd_timing [0x100] = {
-//0 1 2 3 4 5 6 7 8 9 A B C D E F
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x06,0x0C,0x02,0x00,0x00,0x03,0x00,0x00,0x07,0x0C,0x02,0x00,0x00,0x03,0x00,
-0x00,0x00,0x00,0x00,0x0F,0x0F,0x0B,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x10,0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x10,
-0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x10,0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x10,
-0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0xA0,0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0xA0,
-0x4B,0x4B,0x7B,0xCB,0x0B,0x6B,0x00,0x0B,0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00,
-0x80,0x80,0x80,0x80,0x00,0x00,0x0B,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x0B,0x00,
-0xD0,0xD0,0xD0,0xD0,0x00,0x00,0x0B,0x00,0xD0,0xD0,0xD0,0xD0,0x00,0x00,0x0B,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x06,0x00,0x0F,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,
-};
-
-// even on x86, using short and unsigned char was slower
-typedef int fint16;
-typedef unsigned fuint16;
-typedef unsigned fuint8;
-
-bool Ay_Cpu::run( cpu_time_t end_time )
-{
- set_end_time( end_time );
- state_t s = this->state_;
- this->state = &s;
- bool warning = false;
-
- typedef BOOST::int8_t int8_t;
-
- union {
- regs_t rg;
- pairs_t rp;
- uint8_t r8_ [8]; // indexed
- uint16_t r16_ [4];
- };
- rg = this->r.b;
-
- cpu_time_t s_time = s.time;
- uint8_t* const mem = this->mem; // cache
- fuint16 pc = r.pc;
- fuint16 sp = r.sp;
- fuint16 ix = r.ix; // TODO: keep in memory for direct access?
- fuint16 iy = r.iy;
- int flags = r.b.flags;
-
- goto loop;
-jr_not_taken:
- s_time -= 5;
- goto loop;
-call_not_taken:
- s_time -= 7;
-jp_not_taken:
- pc += 2;
-loop:
-
- check( (unsigned long) pc < 0x10000 );
- check( (unsigned long) sp < 0x10000 );
- check( (unsigned) flags < 0x100 );
- check( (unsigned) ix < 0x10000 );
- check( (unsigned) iy < 0x10000 );
-
- fuint8 opcode;
- opcode = READ_PROG( pc );
- pc++;
-
- static byte const base_timing [0x100] = {
- // 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 4,10, 7, 6, 4, 4, 7, 4, 4,11, 7, 6, 4, 4, 7, 4, // 0
- 13,10, 7, 6, 4, 4, 7, 4,12,11, 7, 6, 4, 4, 7, 4, // 1
- 12,10,16, 6, 4, 4, 7, 4,12,11,16, 6, 4, 4, 7, 4, // 2
- 12,10,13, 6,11,11,10, 4,12,11,13, 6, 4, 4, 7, 4, // 3
- 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 4
- 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 5
- 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 6
- 7, 7, 7, 7, 7, 7, 4, 7, 4, 4, 4, 4, 4, 4, 7, 4, // 7
- 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 8
- 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 9
- 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // A
- 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // B
- 11,10,10,10,17,11, 7,11,11,10,10, 8,17,17, 7,11, // C
- 11,10,10,11,17,11, 7,11,11, 4,10,11,17, 8, 7,11, // D
- 11,10,10,19,17,11, 7,11,11, 4,10, 4,17, 8, 7,11, // E
- 11,10,10, 4,17,11, 7,11,11, 6,10, 4,17, 8, 7,11, // F
- };
-
- fuint16 data;
- data = base_timing [opcode];
- if ( (s_time += data) >= 0 )
- goto possibly_out_of_time;
-almost_out_of_time:
-
- data = READ_PROG( pc );
-
- #ifdef Z80_CPU_LOG_H
- //log_opcode( opcode, READ_PROG( pc ) );
- z80_log_regs( rg.a, rp.bc, rp.de, rp.hl, sp, ix, iy );
- z80_cpu_log( "new", pc - 1, opcode, READ_PROG( pc ),
- READ_PROG( pc + 1 ), READ_PROG( pc + 2 ) );
- #endif
-
- switch ( opcode )
- {
-possibly_out_of_time:
- if ( s_time < (int) data )
- goto almost_out_of_time;
- s_time -= data;
- goto out_of_time;
-
-// Common
-
- case 0x00: // NOP
- CASE7( 40, 49, 52, 5B, 64, 6D, 7F ): // LD B,B etc.
- goto loop;
-
- case 0x08:{// EX AF,AF'
- int temp = r.alt.b.a;
- r.alt.b.a = rg.a;
- rg.a = temp;
-
- temp = r.alt.b.flags;
- r.alt.b.flags = flags;
- flags = temp;
- goto loop;
- }
-
- case 0xD3: // OUT (imm),A
- pc++;
- OUT( data + rg.a * 0x100, rg.a );
- goto loop;
-
- case 0x2E: // LD L,imm
- pc++;
- rg.l = data;
- goto loop;
-
- case 0x3E: // LD A,imm
- pc++;
- rg.a = data;
- goto loop;
-
- case 0x3A:{// LD A,(addr)
- fuint16 addr = GET_ADDR();
- pc += 2;
- rg.a = READ( addr );
- goto loop;
- }
-
-// Conditional
-
-#define ZERO (flags & Z40)
-#define CARRY (flags & C01)
-#define EVEN (flags & P04)
-#define MINUS (flags & S80)
-
-// JR
-#define JR( cond ) {\
- int disp = (BOOST::int8_t) data;\
- pc++;\
- if ( !(cond) )\
- goto jr_not_taken;\
- pc += disp;\
- goto loop;\
-}
-
- case 0x20: JR( !ZERO ) // JR NZ,disp
- case 0x28: JR( ZERO ) // JR Z,disp
- case 0x30: JR( !CARRY ) // JR NC,disp
- case 0x38: JR( CARRY ) // JR C,disp
- case 0x18: JR( true ) // JR disp
-
- case 0x10:{// DJNZ disp
- int temp = rg.b - 1;
- rg.b = temp;
- JR( temp )
- }
-
-// JP
-#define JP( cond ) if ( !(cond) ) goto jp_not_taken; pc = GET_ADDR(); goto loop;
-
- case 0xC2: JP( !ZERO ) // JP NZ,addr
- case 0xCA: JP( ZERO ) // JP Z,addr
- case 0xD2: JP( !CARRY ) // JP NC,addr
- case 0xDA: JP( CARRY ) // JP C,addr
- case 0xE2: JP( !EVEN ) // JP PO,addr
- case 0xEA: JP( EVEN ) // JP PE,addr
- case 0xF2: JP( !MINUS ) // JP P,addr
- case 0xFA: JP( MINUS ) // JP M,addr
-
- case 0xC3: // JP addr
- pc = GET_ADDR();
- goto loop;
-
- case 0xE9: // JP HL
- pc = rp.hl;
- goto loop;
-
-// RET
-#define RET( cond ) if ( cond ) goto ret_taken; s_time -= 6; goto loop;
-
- case 0xC0: RET( !ZERO ) // RET NZ
- case 0xC8: RET( ZERO ) // RET Z
- case 0xD0: RET( !CARRY ) // RET NC
- case 0xD8: RET( CARRY ) // RET C
- case 0xE0: RET( !EVEN ) // RET PO
- case 0xE8: RET( EVEN ) // RET PE
- case 0xF0: RET( !MINUS ) // RET P
- case 0xF8: RET( MINUS ) // RET M
-
- case 0xC9: // RET
- ret_taken:
- pc = READ_WORD( sp );
- sp = uint16_t (sp + 2);
- goto loop;
-
-// CALL
-#define CALL( cond ) if ( cond ) goto call_taken; goto call_not_taken;
-
- case 0xC4: CALL( !ZERO ) // CALL NZ,addr
- case 0xCC: CALL( ZERO ) // CALL Z,addr
- case 0xD4: CALL( !CARRY ) // CALL NC,addr
- case 0xDC: CALL( CARRY ) // CALL C,addr
- case 0xE4: CALL( !EVEN ) // CALL PO,addr
- case 0xEC: CALL( EVEN ) // CALL PE,addr
- case 0xF4: CALL( !MINUS ) // CALL P,addr
- case 0xFC: CALL( MINUS ) // CALL M,addr
-
- case 0xCD:{// CALL addr
- call_taken:
- fuint16 addr = pc + 2;
- pc = GET_ADDR();
- sp = uint16_t (sp - 2);
- WRITE_WORD( sp, addr );
- goto loop;
- }
-
- case 0xFF: // RST
- if ( (pc - 1) > 0xFFFF )
- {
- pc = uint16_t (pc - 1);
- s_time -= 11;
- goto loop;
- }
- CASE7( C7, CF, D7, DF, E7, EF, F7 ):
- data = pc;
- pc = opcode & 0x38;
- goto push_data;
-
-// PUSH/POP
- case 0xF5: // PUSH AF
- data = rg.a * 0x100u + flags;
- goto push_data;
-
- case 0xC5: // PUSH BC
- case 0xD5: // PUSH DE
- case 0xE5: // PUSH HL
- data = R16( opcode, 4, 0xC5 );
- push_data:
- sp = uint16_t (sp - 2);
- WRITE_WORD( sp, data );
- goto loop;
-
- case 0xF1: // POP AF
- flags = READ( sp );
- rg.a = READ( sp + 1 );
- sp = uint16_t (sp + 2);
- goto loop;
-
- case 0xC1: // POP BC
- case 0xD1: // POP DE
- case 0xE1: // POP HL
- R16( opcode, 4, 0xC1 ) = READ_WORD( sp );
- sp = uint16_t (sp + 2);
- goto loop;
-
-// ADC/ADD/SBC/SUB
- case 0x96: // SUB (HL)
- case 0x86: // ADD (HL)
- flags &= ~C01;
- case 0x9E: // SBC (HL)
- case 0x8E: // ADC (HL)
- data = READ( rp.hl );
- goto adc_data;
-
- case 0xD6: // SUB A,imm
- case 0xC6: // ADD imm
- flags &= ~C01;
- case 0xDE: // SBC A,imm
- case 0xCE: // ADC imm
- pc++;
- goto adc_data;
-
- CASE7( 90, 91, 92, 93, 94, 95, 97 ): // SUB r
- CASE7( 80, 81, 82, 83, 84, 85, 87 ): // ADD r
- flags &= ~C01;
- CASE7( 98, 99, 9A, 9B, 9C, 9D, 9F ): // SBC r
- CASE7( 88, 89, 8A, 8B, 8C, 8D, 8F ): // ADC r
- data = R8( opcode & 7, 0 );
- adc_data: {
- int result = data + (flags & C01);
- data ^= rg.a;
- flags = opcode >> 3 & N02; // bit 4 is set in subtract opcodes
- if ( flags )
- result = -result;
- result += rg.a;
- data ^= result;
- flags |=(data & H10) |
- ((data - -0x80) >> 6 & V04) |
- SZ28C( result & 0x1FF );
- rg.a = result;
- goto loop;
- }
-
-// CP
- case 0xBE: // CP (HL)
- data = READ( rp.hl );
- goto cp_data;
-
- case 0xFE: // CP imm
- pc++;
- goto cp_data;
-
- CASE7( B8, B9, BA, BB, BC, BD, BF ): // CP r
- data = R8( opcode, 0xB8 );
- cp_data: {
- int result = rg.a - data;
- flags = N02 | (data & (F20 | F08)) | (result >> 8 & C01);
- data ^= rg.a;
- flags |=(((result ^ rg.a) & data) >> 5 & V04) |
- (((data & H10) ^ result) & (S80 | H10));
- if ( (uint8_t) result )
- goto loop;
- flags |= Z40;
- goto loop;
- }
-
-// ADD HL,rp
-
- case 0x39: // ADD HL,SP
- data = sp;
- goto add_hl_data;
-
- case 0x09: // ADD HL,BC
- case 0x19: // ADD HL,DE
- case 0x29: // ADD HL,HL
- data = R16( opcode, 4, 0x09 );
- add_hl_data: {
- blargg_ulong sum = rp.hl + data;
- data ^= rp.hl;
- rp.hl = sum;
- flags = (flags & (S80 | Z40 | V04)) |
- (sum >> 16) |
- (sum >> 8 & (F20 | F08)) |
- ((data ^ sum) >> 8 & H10);
- goto loop;
- }
-
- case 0x27:{// DAA
- int a = rg.a;
- if ( a > 0x99 )
- flags |= C01;
-
- int adjust = 0x60 & -(flags & C01);
-
- if ( flags & H10 || (a & 0x0F) > 9 )
- adjust |= 0x06;
-
- if ( flags & N02 )
- adjust = -adjust;
- a += adjust;
-
- flags = (flags & (C01 | N02)) |
- ((rg.a ^ a) & H10) |
- SZ28P( (uint8_t) a );
- rg.a = a;
- goto loop;
- }
- /*
- case 0x27:{// DAA
- // more optimized, but probably not worth the obscurity
- int f = (rg.a + (0xFF - 0x99)) >> 8 | flags; // (a > 0x99 ? C01 : 0) | flags
- int adjust = 0x60 & -(f & C01); // f & C01 ? 0x60 : 0
-
- if ( (((rg.a + (0x0F - 9)) ^ rg.a) | f) & H10 ) // flags & H10 || (rg.a & 0x0F) > 9
- adjust |= 0x06;
-
- if ( f & N02 )
- adjust = -adjust;
- int a = rg.a + adjust;
-
- flags = (f & (N02 | C01)) | ((rg.a ^ a) & H10) | SZ28P( (uint8_t) a );
- rg.a = a;
- goto loop;
- }
- */
-
-// INC/DEC
- case 0x34: // INC (HL)
- data = READ( rp.hl ) + 1;
- WRITE( rp.hl, data );
- goto inc_set_flags;
-
- CASE7( 04, 0C, 14, 1C, 24, 2C, 3C ): // INC r
- data = ++R8( opcode >> 3, 0 );
- inc_set_flags:
- flags = (flags & C01) |
- (((data & 0x0F) - 1) & H10) |
- SZ28( (uint8_t) data );
- if ( data != 0x80 )
- goto loop;
- flags |= V04;
- goto loop;
-
- case 0x35: // DEC (HL)
- data = READ( rp.hl ) - 1;
- WRITE( rp.hl, data );
- goto dec_set_flags;
-
- CASE7( 05, 0D, 15, 1D, 25, 2D, 3D ): // DEC r
- data = --R8( opcode >> 3, 0 );
- dec_set_flags:
- flags = (flags & C01) | N02 |
- (((data & 0x0F) + 1) & H10) |
- SZ28( (uint8_t) data );
- if ( data != 0x7F )
- goto loop;
- flags |= V04;
- goto loop;
-
- case 0x03: // INC BC
- case 0x13: // INC DE
- case 0x23: // INC HL
- R16( opcode, 4, 0x03 )++;
- goto loop;
-
- case 0x33: // INC SP
- sp = uint16_t (sp + 1);
- goto loop;
-
- case 0x0B: // DEC BC
- case 0x1B: // DEC DE
- case 0x2B: // DEC HL
- R16( opcode, 4, 0x0B )--;
- goto loop;
-
- case 0x3B: // DEC SP
- sp = uint16_t (sp - 1);
- goto loop;
-
-// AND
- case 0xA6: // AND (HL)
- data = READ( rp.hl );
- goto and_data;
-
- case 0xE6: // AND imm
- pc++;
- goto and_data;
-
- CASE7( A0, A1, A2, A3, A4, A5, A7 ): // AND r
- data = R8( opcode, 0xA0 );
- and_data:
- rg.a &= data;
- flags = SZ28P( rg.a ) | H10;
- goto loop;
-
-// OR
- case 0xB6: // OR (HL)
- data = READ( rp.hl );
- goto or_data;
-
- case 0xF6: // OR imm
- pc++;
- goto or_data;
-
- CASE7( B0, B1, B2, B3, B4, B5, B7 ): // OR r
- data = R8( opcode, 0xB0 );
- or_data:
- rg.a |= data;
- flags = SZ28P( rg.a );
- goto loop;
-
-// XOR
- case 0xAE: // XOR (HL)
- data = READ( rp.hl );
- goto xor_data;
-
- case 0xEE: // XOR imm
- pc++;
- goto xor_data;
-
- CASE7( A8, A9, AA, AB, AC, AD, AF ): // XOR r
- data = R8( opcode, 0xA8 );
- xor_data:
- rg.a ^= data;
- flags = SZ28P( rg.a );
- goto loop;
-
-// LD
- CASE7( 70, 71, 72, 73, 74, 75, 77 ): // LD (HL),r
- WRITE( rp.hl, R8( opcode, 0x70 ) );
- goto loop;
-
- CASE6( 41, 42, 43, 44, 45, 47 ): // LD B,r
- CASE6( 48, 4A, 4B, 4C, 4D, 4F ): // LD C,r
- CASE6( 50, 51, 53, 54, 55, 57 ): // LD D,r
- CASE6( 58, 59, 5A, 5C, 5D, 5F ): // LD E,r
- CASE6( 60, 61, 62, 63, 65, 67 ): // LD H,r
- CASE6( 68, 69, 6A, 6B, 6C, 6F ): // LD L,r
- CASE6( 78, 79, 7A, 7B, 7C, 7D ): // LD A,r
- R8( opcode >> 3 & 7, 0 ) = R8( opcode & 7, 0 );
- goto loop;
-
- CASE5( 06, 0E, 16, 1E, 26 ): // LD r,imm
- R8( opcode >> 3, 0 ) = data;
- pc++;
- goto loop;
-
- case 0x36: // LD (HL),imm
- pc++;
- WRITE( rp.hl, data );
- goto loop;
-
- CASE7( 46, 4E, 56, 5E, 66, 6E, 7E ): // LD r,(HL)
- R8( opcode >> 3, 8 ) = READ( rp.hl );
- goto loop;
-
- case 0x01: // LD rp,imm
- case 0x11:
- case 0x21:
- R16( opcode, 4, 0x01 ) = GET_ADDR();
- pc += 2;
- goto loop;
-
- case 0x31: // LD sp,imm
- sp = GET_ADDR();
- pc += 2;
- goto loop;
-
- case 0x2A:{// LD HL,(addr)
- fuint16 addr = GET_ADDR();
- pc += 2;
- rp.hl = READ_WORD( addr );
- goto loop;
- }
-
- case 0x32:{// LD (addr),A
- fuint16 addr = GET_ADDR();
- pc += 2;
- WRITE( addr, rg.a );
- goto loop;
- }
-
- case 0x22:{// LD (addr),HL
- fuint16 addr = GET_ADDR();
- pc += 2;
- WRITE_WORD( addr, rp.hl );
- goto loop;
- }
-
- case 0x02: // LD (BC),A
- case 0x12: // LD (DE),A
- WRITE( R16( opcode, 4, 0x02 ), rg.a );
- goto loop;
-
- case 0x0A: // LD A,(BC)
- case 0x1A: // LD A,(DE)
- rg.a = READ( R16( opcode, 4, 0x0A ) );
- goto loop;
-
- case 0xF9: // LD SP,HL
- sp = rp.hl;
- goto loop;
-
-// Rotate
-
- case 0x07:{// RLCA
- fuint16 temp = rg.a;
- temp = (temp << 1) | (temp >> 7);
- flags = (flags & (S80 | Z40 | P04)) |
- (temp & (F20 | F08 | C01));
- rg.a = temp;
- goto loop;
- }
-
- case 0x0F:{// RRCA
- fuint16 temp = rg.a;
- flags = (flags & (S80 | Z40 | P04)) |
- (temp & C01);
- temp = (temp << 7) | (temp >> 1);
- flags |= temp & (F20 | F08);
- rg.a = temp;
- goto loop;
- }
-
- case 0x17:{// RLA
- blargg_ulong temp = (rg.a << 1) | (flags & C01);
- flags = (flags & (S80 | Z40 | P04)) |
- (temp & (F20 | F08)) |
- (temp >> 8);
- rg.a = temp;
- goto loop;
- }
-
- case 0x1F:{// RRA
- fuint16 temp = (flags << 7) | (rg.a >> 1);
- flags = (flags & (S80 | Z40 | P04)) |
- (temp & (F20 | F08)) |
- (rg.a & C01);
- rg.a = temp;
- goto loop;
- }
-
-// Misc
- case 0x2F:{// CPL
- fuint16 temp = ~rg.a;
- flags = (flags & (S80 | Z40 | P04 | C01)) |
- (temp & (F20 | F08)) |
- (H10 | N02);
- rg.a = temp;
- goto loop;
- }
-
- case 0x3F:{// CCF
- flags = ((flags & (S80 | Z40 | P04 | C01)) ^ C01) |
- (flags << 4 & H10) |
- (rg.a & (F20 | F08));
- goto loop;
- }
-
- case 0x37: // SCF
- flags = (flags & (S80 | Z40 | P04)) | C01 |
- (rg.a & (F20 | F08));
- goto loop;
-
- case 0xDB: // IN A,(imm)
- pc++;
- rg.a = IN( data + rg.a * 0x100 );
- goto loop;
-
- case 0xE3:{// EX (SP),HL
- fuint16 temp = READ_WORD( sp );
- WRITE_WORD( sp, rp.hl );
- rp.hl = temp;
- goto loop;
- }
-
- case 0xEB:{// EX DE,HL
- fuint16 temp = rp.hl;
- rp.hl = rp.de;
- rp.de = temp;
- goto loop;
- }
-
- case 0xD9:{// EXX DE,HL
- fuint16 temp = r.alt.w.bc;
- r.alt.w.bc = rp.bc;
- rp.bc = temp;
-
- temp = r.alt.w.de;
- r.alt.w.de = rp.de;
- rp.de = temp;
-
- temp = r.alt.w.hl;
- r.alt.w.hl = rp.hl;
- rp.hl = temp;
- goto loop;
- }
-
- case 0xF3: // DI
- r.iff1 = 0;
- r.iff2 = 0;
- goto loop;
-
- case 0xFB: // EI
- r.iff1 = 1;
- r.iff2 = 1;
- // TODO: delayed effect
- goto loop;
-
- case 0x76: // HALT
- goto halt;
-
-//////////////////////////////////////// CB prefix
- {
- case 0xCB:
- unsigned data2;
- data2 = INSTR( 1 );
- pc++;
- switch ( data )
- {
-
- // Rotate left
-
- #define RLC( read, write ) {\
- fuint8 result = read;\
- result = uint8_t (result << 1) | (result >> 7);\
- flags = SZ28P( result ) | (result & C01);\
- write;\
- goto loop;\
- }
-
- case 0x06: // RLC (HL)
- s_time += 7;
- data = rp.hl;
- rlc_data_addr:
- RLC( READ( data ), WRITE( data, result ) )
-
- CASE7( 00, 01, 02, 03, 04, 05, 07 ):{// RLC r
- uint8_t& reg = R8( data, 0 );
- RLC( reg, reg = result )
- }
-
- #define RL( read, write ) {\
- fuint16 result = (read << 1) | (flags & C01);\
- flags = SZ28PC( result );\
- write;\
- goto loop;\
- }
-
- case 0x16: // RL (HL)
- s_time += 7;
- data = rp.hl;
- rl_data_addr:
- RL( READ( data ), WRITE( data, result ) )
-
- CASE7( 10, 11, 12, 13, 14, 15, 17 ):{// RL r
- uint8_t& reg = R8( data, 0x10 );
- RL( reg, reg = result )
- }
-
- #define SLA( read, add, write ) {\
- fuint16 result = (read << 1) | add;\
- flags = SZ28PC( result );\
- write;\
- goto loop;\
- }
-
- case 0x26: // SLA (HL)
- s_time += 7;
- data = rp.hl;
- sla_data_addr:
- SLA( READ( data ), 0, WRITE( data, result ) )
-
- CASE7( 20, 21, 22, 23, 24, 25, 27 ):{// SLA r
- uint8_t& reg = R8( data, 0x20 );
- SLA( reg, 0, reg = result )
- }
-
- case 0x36: // SLL (HL)
- s_time += 7;
- data = rp.hl;
- sll_data_addr:
- SLA( READ( data ), 1, WRITE( data, result ) )
-
- CASE7( 30, 31, 32, 33, 34, 35, 37 ):{// SLL r
- uint8_t& reg = R8( data, 0x30 );
- SLA( reg, 1, reg = result )
- }
-
- // Rotate right
-
- #define RRC( read, write ) {\
- fuint8 result = read;\
- flags = result & C01;\
- result = uint8_t (result << 7) | (result >> 1);\
- flags |= SZ28P( result );\
- write;\
- goto loop;\
- }
-
- case 0x0E: // RRC (HL)
- s_time += 7;
- data = rp.hl;
- rrc_data_addr:
- RRC( READ( data ), WRITE( data, result ) )
-
- CASE7( 08, 09, 0A, 0B, 0C, 0D, 0F ):{// RRC r
- uint8_t& reg = R8( data, 0x08 );
- RRC( reg, reg = result )
- }
-
- #define RR( read, write ) {\
- fuint8 result = read;\
- fuint8 temp = result & C01;\
- result = uint8_t (flags << 7) | (result >> 1);\
- flags = SZ28P( result ) | temp;\
- write;\
- goto loop;\
- }
-
- case 0x1E: // RR (HL)
- s_time += 7;
- data = rp.hl;
- rr_data_addr:
- RR( READ( data ), WRITE( data, result ) )
-
- CASE7( 18, 19, 1A, 1B, 1C, 1D, 1F ):{// RR r
- uint8_t& reg = R8( data, 0x18 );
- RR( reg, reg = result )
- }
-
- #define SRA( read, write ) {\
- fuint8 result = read;\
- flags = result & C01;\
- result = (result & 0x80) | (result >> 1);\
- flags |= SZ28P( result );\
- write;\
- goto loop;\
- }
-
- case 0x2E: // SRA (HL)
- data = rp.hl;
- s_time += 7;
- sra_data_addr:
- SRA( READ( data ), WRITE( data, result ) )
-
- CASE7( 28, 29, 2A, 2B, 2C, 2D, 2F ):{// SRA r
- uint8_t& reg = R8( data, 0x28 );
- SRA( reg, reg = result )
- }
-
- #define SRL( read, write ) {\
- fuint8 result = read;\
- flags = result & C01;\
- result >>= 1;\
- flags |= SZ28P( result );\
- write;\
- goto loop;\
- }
-
- case 0x3E: // SRL (HL)
- s_time += 7;
- data = rp.hl;
- srl_data_addr:
- SRL( READ( data ), WRITE( data, result ) )
-
- CASE7( 38, 39, 3A, 3B, 3C, 3D, 3F ):{// SRL r
- uint8_t& reg = R8( data, 0x38 );
- SRL( reg, reg = result )
- }
-
- // BIT
- {
- unsigned temp;
- CASE8( 46, 4E, 56, 5E, 66, 6E, 76, 7E ): // BIT b,(HL)
- s_time += 4;
- temp = READ( rp.hl );
- flags &= C01;
- goto bit_temp;
- CASE7( 40, 41, 42, 43, 44, 45, 47 ): // BIT 0,r
- CASE7( 48, 49, 4A, 4B, 4C, 4D, 4F ): // BIT 1,r
- CASE7( 50, 51, 52, 53, 54, 55, 57 ): // BIT 2,r
- CASE7( 58, 59, 5A, 5B, 5C, 5D, 5F ): // BIT 3,r
- CASE7( 60, 61, 62, 63, 64, 65, 67 ): // BIT 4,r
- CASE7( 68, 69, 6A, 6B, 6C, 6D, 6F ): // BIT 5,r
- CASE7( 70, 71, 72, 73, 74, 75, 77 ): // BIT 6,r
- CASE7( 78, 79, 7A, 7B, 7C, 7D, 7F ): // BIT 7,r
- temp = R8( data & 7, 0 );
- flags = (flags & C01) | (temp & (F20 | F08));
- bit_temp:
- int masked = temp & 1 << (data >> 3 & 7);
- flags |=(masked & S80) | H10 |
- ((masked - 1) >> 8 & (Z40 | P04));
- goto loop;
- }
-
- // SET/RES
- CASE8( 86, 8E, 96, 9E, A6, AE, B6, BE ): // RES b,(HL)
- CASE8( C6, CE, D6, DE, E6, EE, F6, FE ):{// SET b,(HL)
- s_time += 7;
- int temp = READ( rp.hl );
- int bit = 1 << (data >> 3 & 7);
- temp |= bit; // SET
- if ( !(data & 0x40) )
- temp ^= bit; // RES
- WRITE( rp.hl, temp );
- goto loop;
- }
-
- CASE7( C0, C1, C2, C3, C4, C5, C7 ): // SET 0,r
- CASE7( C8, C9, CA, CB, CC, CD, CF ): // SET 1,r
- CASE7( D0, D1, D2, D3, D4, D5, D7 ): // SET 2,r
- CASE7( D8, D9, DA, DB, DC, DD, DF ): // SET 3,r
- CASE7( E0, E1, E2, E3, E4, E5, E7 ): // SET 4,r
- CASE7( E8, E9, EA, EB, EC, ED, EF ): // SET 5,r
- CASE7( F0, F1, F2, F3, F4, F5, F7 ): // SET 6,r
- CASE7( F8, F9, FA, FB, FC, FD, FF ): // SET 7,r
- R8( data & 7, 0 ) |= 1 << (data >> 3 & 7);
- goto loop;
-
- CASE7( 80, 81, 82, 83, 84, 85, 87 ): // RES 0,r
- CASE7( 88, 89, 8A, 8B, 8C, 8D, 8F ): // RES 1,r
- CASE7( 90, 91, 92, 93, 94, 95, 97 ): // RES 2,r
- CASE7( 98, 99, 9A, 9B, 9C, 9D, 9F ): // RES 3,r
- CASE7( A0, A1, A2, A3, A4, A5, A7 ): // RES 4,r
- CASE7( A8, A9, AA, AB, AC, AD, AF ): // RES 5,r
- CASE7( B0, B1, B2, B3, B4, B5, B7 ): // RES 6,r
- CASE7( B8, B9, BA, BB, BC, BD, BF ): // RES 7,r
- R8( data & 7, 0 ) &= ~(1 << (data >> 3 & 7));
- goto loop;
- }
- assert( false );
- }
-
-//////////////////////////////////////// ED prefix
- {
- case 0xED:
- pc++;
- s_time += ed_dd_timing [data] >> 4;
- switch ( data )
- {
- {
- blargg_ulong temp;
- case 0x72: // SBC HL,SP
- case 0x7A: // ADC HL,SP
- temp = sp;
- if ( 0 )
- case 0x42: // SBC HL,BC
- case 0x52: // SBC HL,DE
- case 0x62: // SBC HL,HL
- case 0x4A: // ADC HL,BC
- case 0x5A: // ADC HL,DE
- case 0x6A: // ADC HL,HL
- temp = R16( data >> 3 & 6, 1, 0 );
- blargg_ulong sum = temp + (flags & C01);
- flags = ~data >> 2 & N02;
- if ( flags )
- sum = -sum;
- sum += rp.hl;
- temp ^= rp.hl;
- temp ^= sum;
- flags |=(sum >> 16 & C01) |
- (temp >> 8 & H10) |
- (sum >> 8 & (S80 | F20 | F08)) |
- ((temp - -0x8000) >> 14 & V04);
- rp.hl = sum;
- if ( (uint16_t) sum )
- goto loop;
- flags |= Z40;
- goto loop;
- }
-
- CASE8( 40, 48, 50, 58, 60, 68, 70, 78 ):{// IN r,(C)
- int temp = IN( rp.bc );
- R8( data >> 3, 8 ) = temp;
- flags = (flags & C01) | SZ28P( temp );
- goto loop;
- }
-
- case 0x71: // OUT (C),0
- rg.flags = 0;
- CASE7( 41, 49, 51, 59, 61, 69, 79 ): // OUT (C),r
- OUT( rp.bc, R8( data >> 3, 8 ) );
- goto loop;
-
- {
- unsigned temp;
- case 0x73: // LD (ADDR),SP
- temp = sp;
- if ( 0 )
- case 0x43: // LD (ADDR),BC
- case 0x53: // LD (ADDR),DE
- temp = R16( data, 4, 0x43 );
- fuint16 addr = GET_ADDR();
- pc += 2;
- WRITE_WORD( addr, temp );
- goto loop;
- }
-
- case 0x4B: // LD BC,(ADDR)
- case 0x5B:{// LD DE,(ADDR)
- fuint16 addr = GET_ADDR();
- pc += 2;
- R16( data, 4, 0x4B ) = READ_WORD( addr );
- goto loop;
- }
-
- case 0x7B:{// LD SP,(ADDR)
- fuint16 addr = GET_ADDR();
- pc += 2;
- sp = READ_WORD( addr );
- goto loop;
- }
-
- case 0x67:{// RRD
- fuint8 temp = READ( rp.hl );
- WRITE( rp.hl, (rg.a << 4) | (temp >> 4) );
- temp = (rg.a & 0xF0) | (temp & 0x0F);
- flags = (flags & C01) | SZ28P( temp );
- rg.a = temp;
- goto loop;
- }
-
- case 0x6F:{// RLD
- fuint8 temp = READ( rp.hl );
- WRITE( rp.hl, (temp << 4) | (rg.a & 0x0F) );
- temp = (rg.a & 0xF0) | (temp >> 4);
- flags = (flags & C01) | SZ28P( temp );
- rg.a = temp;
- goto loop;
- }
-
- CASE8( 44, 4C, 54, 5C, 64, 6C, 74, 7C ): // NEG
- opcode = 0x10; // flag to do SBC instead of ADC
- flags &= ~C01;
- data = rg.a;
- rg.a = 0;
- goto adc_data;
-
- {
- int inc;
- case 0xA9: // CPD
- case 0xB9: // CPDR
- inc = -1;
- if ( 0 )
- case 0xA1: // CPI
- case 0xB1: // CPIR
- inc = +1;
- fuint16 addr = rp.hl;
- rp.hl = addr + inc;
- int temp = READ( addr );
-
- int result = rg.a - temp;
- flags = (flags & C01) | N02 |
- ((((temp ^ rg.a) & H10) ^ result) & (S80 | H10));
-
- if ( !(uint8_t) result ) flags |= Z40;
- result -= (flags & H10) >> 4;
- flags |= result & F08;
- flags |= result << 4 & F20;
- if ( !--rp.bc )
- goto loop;
-
- flags |= V04;
- if ( flags & Z40 || data < 0xB0 )
- goto loop;
-
- pc -= 2;
- s_time += 5;
- goto loop;
- }
-
- {
- int inc;
- case 0xA8: // LDD
- case 0xB8: // LDDR
- inc = -1;
- if ( 0 )
- case 0xA0: // LDI
- case 0xB0: // LDIR
- inc = +1;
- fuint16 addr = rp.hl;
- rp.hl = addr + inc;
- int temp = READ( addr );
-
- addr = rp.de;
- rp.de = addr + inc;
- WRITE( addr, temp );
-
- temp += rg.a;
- flags = (flags & (S80 | Z40 | C01)) |
- (temp & F08) | (temp << 4 & F20);
- if ( !--rp.bc )
- goto loop;
-
- flags |= V04;
- if ( data < 0xB0 )
- goto loop;
-
- pc -= 2;
- s_time += 5;
- goto loop;
- }
-
- {
- int inc;
- case 0xAB: // OUTD
- case 0xBB: // OTDR
- inc = -1;
- if ( 0 )
- case 0xA3: // OUTI
- case 0xB3: // OTIR
- inc = +1;
- fuint16 addr = rp.hl;
- rp.hl = addr + inc;
- int temp = READ( addr );
-
- int b = --rg.b;
- flags = (temp >> 6 & N02) | SZ28( b );
- if ( b && data >= 0xB0 )
- {
- pc -= 2;
- s_time += 5;
- }
-
- OUT( rp.bc, temp );
- goto loop;
- }
-
- {
- int inc;
- case 0xAA: // IND
- case 0xBA: // INDR
- inc = -1;
- if ( 0 )
- case 0xA2: // INI
- case 0xB2: // INIR
- inc = +1;
-
- fuint16 addr = rp.hl;
- rp.hl = addr + inc;
-
- int temp = IN( rp.bc );
-
- int b = --rg.b;
- flags = (temp >> 6 & N02) | SZ28( b );
- if ( b && data >= 0xB0 )
- {
- pc -= 2;
- s_time += 5;
- }
-
- WRITE( addr, temp );
- goto loop;
- }
-
- case 0x47: // LD I,A
- r.i = rg.a;
- goto loop;
-
- case 0x4F: // LD R,A
- SET_R( rg.a );
- debug_printf( "LD R,A not supported\n" );
- warning = true;
- goto loop;
-
- case 0x57: // LD A,I
- rg.a = r.i;
- goto ld_ai_common;
-
- case 0x5F: // LD A,R
- rg.a = GET_R();
- debug_printf( "LD A,R not supported\n" );
- warning = true;
- ld_ai_common:
- flags = (flags & C01) | SZ28( rg.a ) | (r.iff2 << 2 & V04);
- goto loop;
-
- CASE8( 45, 4D, 55, 5D, 65, 6D, 75, 7D ): // RETI/RETN
- r.iff1 = r.iff2;
- goto ret_taken;
-
- case 0x46: case 0x4E: case 0x66: case 0x6E: // IM 0
- r.im = 0;
- goto loop;
-
- case 0x56: case 0x76: // IM 1
- r.im = 1;
- goto loop;
-
- case 0x5E: case 0x7E: // IM 2
- r.im = 2;
- goto loop;
-
- default:
- debug_printf( "Opcode $ED $%02X not supported\n", data );
- warning = true;
- goto loop;
- }
- assert( false );
- }
-
-//////////////////////////////////////// DD/FD prefix
- {
- fuint16 ixy;
- case 0xDD:
- ixy = ix;
- goto ix_prefix;
- case 0xFD:
- ixy = iy;
- ix_prefix:
- pc++;
- unsigned data2 = READ_PROG( pc );
- s_time += ed_dd_timing [data] & 0x0F;
- switch ( data )
- {
- // TODO: more efficient way of avoid negative address
- #define IXY_DISP( ixy, disp ) uint16_t ((ixy) + (disp))
-
- #define SET_IXY( in ) if ( opcode == 0xDD ) ix = in; else iy = in;
-
- // ADD/ADC/SUB/SBC
-
- case 0x96: // SUB (IXY+disp)
- case 0x86: // ADD (IXY+disp)
- flags &= ~C01;
- case 0x9E: // SBC (IXY+disp)
- case 0x8E: // ADC (IXY+disp)
- pc++;
- opcode = data;
- data = READ( IXY_DISP( ixy, (int8_t) data2 ) );
- goto adc_data;
-
- case 0x94: // SUB HXY
- case 0x84: // ADD HXY
- flags &= ~C01;
- case 0x9C: // SBC HXY
- case 0x8C: // ADC HXY
- opcode = data;
- data = ixy >> 8;
- goto adc_data;
-
- case 0x95: // SUB LXY
- case 0x85: // ADD LXY
- flags &= ~C01;
- case 0x9D: // SBC LXY
- case 0x8D: // ADC LXY
- opcode = data;
- data = (uint8_t) ixy;
- goto adc_data;
-
- {
- unsigned temp;
- case 0x39: // ADD IXY,SP
- temp = sp;
- goto add_ixy_data;
-
- case 0x29: // ADD IXY,HL
- temp = ixy;
- goto add_ixy_data;
-
- case 0x09: // ADD IXY,BC
- case 0x19: // ADD IXY,DE
- temp = R16( data, 4, 0x09 );
- add_ixy_data: {
- blargg_ulong sum = ixy + temp;
- temp ^= ixy;
- ixy = (uint16_t) sum;
- flags = (flags & (S80 | Z40 | V04)) |
- (sum >> 16) |
- (sum >> 8 & (F20 | F08)) |
- ((temp ^ sum) >> 8 & H10);
- goto set_ixy;
- }
- }
-
- // AND
- case 0xA6: // AND (IXY+disp)
- pc++;
- data = READ( IXY_DISP( ixy, (int8_t) data2 ) );
- goto and_data;
-
- case 0xA4: // AND HXY
- data = ixy >> 8;
- goto and_data;
-
- case 0xA5: // AND LXY
- data = (uint8_t) ixy;
- goto and_data;
-
- // OR
- case 0xB6: // OR (IXY+disp)
- pc++;
- data = READ( IXY_DISP( ixy, (int8_t) data2 ) );
- goto or_data;
-
- case 0xB4: // OR HXY
- data = ixy >> 8;
- goto or_data;
-
- case 0xB5: // OR LXY
- data = (uint8_t) ixy;
- goto or_data;
-
- // XOR
- case 0xAE: // XOR (IXY+disp)
- pc++;
- data = READ( IXY_DISP( ixy, (int8_t) data2 ) );
- goto xor_data;
-
- case 0xAC: // XOR HXY
- data = ixy >> 8;
- goto xor_data;
-
- case 0xAD: // XOR LXY
- data = (uint8_t) ixy;
- goto xor_data;
-
- // CP
- case 0xBE: // CP (IXY+disp)
- pc++;
- data = READ( IXY_DISP( ixy, (int8_t) data2 ) );
- goto cp_data;
-
- case 0xBC: // CP HXY
- data = ixy >> 8;
- goto cp_data;
-
- case 0xBD: // CP LXY
- data = (uint8_t) ixy;
- goto cp_data;
-
- // LD
- CASE7( 70, 71, 72, 73, 74, 75, 77 ): // LD (IXY+disp),r
- data = R8( data, 0x70 );
- if ( 0 )
- case 0x36: // LD (IXY+disp),imm
- pc++, data = READ_PROG( pc );
- pc++;
- WRITE( IXY_DISP( ixy, (int8_t) data2 ), data );
- goto loop;
-
- CASE5( 44, 4C, 54, 5C, 7C ): // LD r,HXY
- R8( data >> 3, 8 ) = ixy >> 8;
- goto loop;
-
- case 0x64: // LD HXY,HXY
- case 0x6D: // LD LXY,LXY
- goto loop;
-
- CASE5( 45, 4D, 55, 5D, 7D ): // LD r,LXY
- R8( data >> 3, 8 ) = ixy;
- goto loop;
-
- CASE7( 46, 4E, 56, 5E, 66, 6E, 7E ): // LD r,(IXY+disp)
- pc++;
- R8( data >> 3, 8 ) = READ( IXY_DISP( ixy, (int8_t) data2 ) );
- goto loop;
-
- case 0x26: // LD HXY,imm
- pc++;
- goto ld_hxy_data;
-
- case 0x65: // LD HXY,LXY
- data2 = (uint8_t) ixy;
- goto ld_hxy_data;
-
- CASE5( 60, 61, 62, 63, 67 ): // LD HXY,r
- data2 = R8( data, 0x60 );
- ld_hxy_data:
- ixy = (uint8_t) ixy | (data2 << 8);
- goto set_ixy;
-
- case 0x2E: // LD LXY,imm
- pc++;
- goto ld_lxy_data;
-
- case 0x6C: // LD LXY,HXY
- data2 = ixy >> 8;
- goto ld_lxy_data;
-
- CASE5( 68, 69, 6A, 6B, 6F ): // LD LXY,r
- data2 = R8( data, 0x68 );
- ld_lxy_data:
- ixy = (ixy & 0xFF00) | data2;
- set_ixy:
- if ( opcode == 0xDD )
- {
- ix = ixy;
- goto loop;
- }
- iy = ixy;
- goto loop;
-
- case 0xF9: // LD SP,IXY
- sp = ixy;
- goto loop;
-
- case 0x22:{// LD (ADDR),IXY
- fuint16 addr = GET_ADDR();
- pc += 2;
- WRITE_WORD( addr, ixy );
- goto loop;
- }
-
- case 0x21: // LD IXY,imm
- ixy = GET_ADDR();
- pc += 2;
- goto set_ixy;
-
- case 0x2A:{// LD IXY,(addr)
- fuint16 addr = GET_ADDR();
- ixy = READ_WORD( addr );
- pc += 2;
- goto set_ixy;
- }
-
- // DD/FD CB prefix
- case 0xCB: {
- data = IXY_DISP( ixy, (int8_t) data2 );
- pc++;
- data2 = READ_PROG( pc );
- pc++;
- switch ( data2 )
- {
- case 0x06: goto rlc_data_addr; // RLC (IXY)
- case 0x16: goto rl_data_addr; // RL (IXY)
- case 0x26: goto sla_data_addr; // SLA (IXY)
- case 0x36: goto sll_data_addr; // SLL (IXY)
- case 0x0E: goto rrc_data_addr; // RRC (IXY)
- case 0x1E: goto rr_data_addr; // RR (IXY)
- case 0x2E: goto sra_data_addr; // SRA (IXY)
- case 0x3E: goto srl_data_addr; // SRL (IXY)
-
- CASE8( 46, 4E, 56, 5E, 66, 6E, 76, 7E ):{// BIT b,(IXY+disp)
- fuint8 temp = READ( data );
- int masked = temp & 1 << (data2 >> 3 & 7);
- flags = (flags & C01) | H10 |
- (masked & S80) |
- ((masked - 1) >> 8 & (Z40 | P04));
- goto loop;
- }
-
- CASE8( 86, 8E, 96, 9E, A6, AE, B6, BE ): // RES b,(IXY+disp)
- CASE8( C6, CE, D6, DE, E6, EE, F6, FE ):{// SET b,(IXY+disp)
- int temp = READ( data );
- int bit = 1 << (data2 >> 3 & 7);
- temp |= bit; // SET
- if ( !(data2 & 0x40) )
- temp ^= bit; // RES
- WRITE( data, temp );
- goto loop;
- }
-
- default:
- debug_printf( "Opcode $%02X $CB $%02X not supported\n", opcode, data2 );
- warning = true;
- goto loop;
- }
- assert( false );
- }
-
- // INC/DEC
- case 0x23: // INC IXY
- ixy = uint16_t (ixy + 1);
- goto set_ixy;
-
- case 0x2B: // DEC IXY
- ixy = uint16_t (ixy - 1);
- goto set_ixy;
-
- case 0x34: // INC (IXY+disp)
- ixy = IXY_DISP( ixy, (int8_t) data2 );
- pc++;
- data = READ( ixy ) + 1;
- WRITE( ixy, data );
- goto inc_set_flags;
-
- case 0x35: // DEC (IXY+disp)
- ixy = IXY_DISP( ixy, (int8_t) data2 );
- pc++;
- data = READ( ixy ) - 1;
- WRITE( ixy, data );
- goto dec_set_flags;
-
- case 0x24: // INC HXY
- ixy = uint16_t (ixy + 0x100);
- data = ixy >> 8;
- goto inc_xy_common;
-
- case 0x2C: // INC LXY
- data = uint8_t (ixy + 1);
- ixy = (ixy & 0xFF00) | data;
- inc_xy_common:
- if ( opcode == 0xDD )
- {
- ix = ixy;
- goto inc_set_flags;
- }
- iy = ixy;
- goto inc_set_flags;
-
- case 0x25: // DEC HXY
- ixy = uint16_t (ixy - 0x100);
- data = ixy >> 8;
- goto dec_xy_common;
-
- case 0x2D: // DEC LXY
- data = uint8_t (ixy - 1);
- ixy = (ixy & 0xFF00) | data;
- dec_xy_common:
- if ( opcode == 0xDD )
- {
- ix = ixy;
- goto dec_set_flags;
- }
- iy = ixy;
- goto dec_set_flags;
-
- // PUSH/POP
- case 0xE5: // PUSH IXY
- data = ixy;
- goto push_data;
-
- case 0xE1:{// POP IXY
- ixy = READ_WORD( sp );
- sp = uint16_t (sp + 2);
- goto set_ixy;
- }
-
- // Misc
-
- case 0xE9: // JP (IXY)
- pc = ixy;
- goto loop;
-
- case 0xE3:{// EX (SP),IXY
- fuint16 temp = READ_WORD( sp );
- WRITE_WORD( sp, ixy );
- ixy = temp;
- goto set_ixy;
- }
-
- default:
- debug_printf( "Unnecessary DD/FD prefix encountered\n" );
- warning = true;
- pc--;
- goto loop;
- }
- assert( false );
- }
-
- }
- debug_printf( "Unhandled main opcode: $%02X\n", opcode );
- assert( false );
-
-halt:
- s_time &= 3; // increment by multiple of 4
-out_of_time:
- pc--;
-
- s.time = s_time;
- rg.flags = flags;
- r.ix = ix;
- r.iy = iy;
- r.sp = sp;
- r.pc = pc;
- this->r.b = rg;
- this->state_ = s;
- this->state = &this->state_;
-
- return warning;
-}
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Ay_Cpu.h b/plugins/gme/game-music-emu-0.5.5/gme/Ay_Cpu.h
deleted file mode 100644
index 2f4d351e..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Ay_Cpu.h
+++ /dev/null
@@ -1,92 +0,0 @@
-// Z80 CPU emulator
-
-// Game_Music_Emu 0.5.5
-#ifndef AY_CPU_H
-#define AY_CPU_H
-
-#include "blargg_endian.h"
-
-typedef blargg_long cpu_time_t;
-
-// must be defined by caller
-void ay_cpu_out( class Ay_Cpu*, cpu_time_t, unsigned addr, int data );
-int ay_cpu_in( class Ay_Cpu*, unsigned addr );
-
-class Ay_Cpu {
-public:
- // Clear all registers and keep pointer to 64K memory passed in
- void reset( void* mem_64k );
-
- // Run until specified time is reached. Returns true if suspicious/unsupported
- // instruction was encountered at any point during run.
- bool run( cpu_time_t end_time );
-
- // Time of beginning of next instruction
- cpu_time_t time() const { return state->time + state->base; }
-
- // Alter current time. Not supported during run() call.
- void set_time( cpu_time_t t ) { state->time = t - state->base; }
- void adjust_time( int delta ) { state->time += delta; }
-
- typedef BOOST::uint8_t uint8_t;
- typedef BOOST::uint16_t uint16_t;
-
- #if BLARGG_BIG_ENDIAN
- struct regs_t { uint8_t b, c, d, e, h, l, flags, a; };
- #else
- struct regs_t { uint8_t c, b, e, d, l, h, a, flags; };
- #endif
- BOOST_STATIC_ASSERT( sizeof (regs_t) == 8 );
-
- struct pairs_t { uint16_t bc, de, hl, fa; };
-
- // Registers are not updated until run() returns
- struct registers_t {
- uint16_t pc;
- uint16_t sp;
- uint16_t ix;
- uint16_t iy;
- union {
- regs_t b; // b.b, b.c, b.d, b.e, b.h, b.l, b.flags, b.a
- pairs_t w; // w.bc, w.de, w.hl. w.fa
- };
- union {
- regs_t b;
- pairs_t w;
- } alt;
- uint8_t iff1;
- uint8_t iff2;
- uint8_t r;
- uint8_t i;
- uint8_t im;
- };
- //registers_t r; (below for efficiency)
-
- // can read this far past end of memory
- enum { cpu_padding = 0x100 };
-
-public:
- Ay_Cpu();
-private:
- uint8_t szpc [0x200];
- uint8_t* mem;
- cpu_time_t end_time_;
- struct state_t {
- cpu_time_t base;
- cpu_time_t time;
- };
- state_t* state; // points to state_ or a local copy within run()
- state_t state_;
- void set_end_time( cpu_time_t t );
-public:
- registers_t r;
-};
-
-inline void Ay_Cpu::set_end_time( cpu_time_t t )
-{
- cpu_time_t delta = state->base - t;
- state->base = t;
- state->time += delta;
-}
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Ay_Emu.cpp b/plugins/gme/game-music-emu-0.5.5/gme/Ay_Emu.cpp
deleted file mode 100644
index 7f2c0613..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Ay_Emu.cpp
+++ /dev/null
@@ -1,410 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Ay_Emu.h"
-
-#include "blargg_endian.h"
-#include <string.h>
-
-/* Copyright (C) 2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-#include <stdio.h>
-
-long const spectrum_clock = 3546900;
-long const cpc_clock = 2000000;
-
-unsigned const ram_start = 0x4000;
-int const osc_count = Ay_Apu::osc_count + 1;
-
-Ay_Emu::Ay_Emu()
-{
- beeper_output = 0;
- set_type( gme_ay_type );
-
- static const char* const names [osc_count] = {
- "Wave 1", "Wave 2", "Wave 3", "Beeper"
- };
- set_voice_names( names );
-
- static int const types [osc_count] = {
- wave_type | 0, wave_type | 1, wave_type | 2, mixed_type | 0
- };
- set_voice_types( types );
- set_silence_lookahead( 6 );
-}
-
-Ay_Emu::~Ay_Emu() { }
-
-// Track info
-
-static byte const* get_data( Ay_Emu::file_t const& file, byte const* ptr, int min_size )
-{
- long pos = ptr - (byte const*) file.header;
- long file_size = file.end - (byte const*) file.header;
- assert( (unsigned long) pos <= (unsigned long) file_size - 2 );
- int offset = (BOOST::int16_t) get_be16( ptr );
- if ( !offset || blargg_ulong (pos + offset) > blargg_ulong (file_size - min_size) )
- return 0;
- return ptr + offset;
-}
-
-static blargg_err_t parse_header( byte const* in, long size, Ay_Emu::file_t* out )
-{
- typedef Ay_Emu::header_t header_t;
- out->header = (header_t const*) in;
- out->end = in + size;
-
- if ( size < Ay_Emu::header_size )
- return gme_wrong_file_type;
-
- header_t const& h = *(header_t const*) in;
- if ( memcmp( h.tag, "ZXAYEMUL", 8 ) )
- return gme_wrong_file_type;
-
- out->tracks = get_data( *out, h.track_info, (h.max_track + 1) * 4 );
- if ( !out->tracks )
- return "Missing track data";
-
- return 0;
-}
-
-static void copy_ay_fields( Ay_Emu::file_t const& file, track_info_t* out, int track )
-{
- Gme_File::copy_field_( out->song, (char const*) get_data( file, file.tracks + track * 4, 1 ) );
- byte const* track_info = get_data( file, file.tracks + track * 4 + 2, 6 );
- if ( track_info )
- out->length = get_be16( track_info + 4 ) * (1000L / 50); // frames to msec
-
- Gme_File::copy_field_( out->author, (char const*) get_data( file, file.header->author, 1 ) );
- Gme_File::copy_field_( out->comment, (char const*) get_data( file, file.header->comment, 1 ) );
-}
-
-blargg_err_t Ay_Emu::track_info_( track_info_t* out, int track ) const
-{
- copy_ay_fields( file, out, track );
- return 0;
-}
-
-struct Ay_File : Gme_Info_
-{
- Ay_Emu::file_t file;
-
- Ay_File() { set_type( gme_ay_type ); }
-
- blargg_err_t load_mem_( byte const* begin, long size )
- {
- RETURN_ERR( parse_header( begin, size, &file ) );
- set_track_count( file.header->max_track + 1 );
- return 0;
- }
-
- blargg_err_t track_info_( track_info_t* out, int track ) const
- {
- copy_ay_fields( file, out, track );
- return 0;
- }
-};
-
-static Music_Emu* new_ay_emu () { return BLARGG_NEW Ay_Emu ; }
-static Music_Emu* new_ay_file() { return BLARGG_NEW Ay_File; }
-
-static gme_type_t_ const gme_ay_type_ = { "ZX Spectrum", 0, &new_ay_emu, &new_ay_file, "AY", 1 };
-gme_type_t const gme_ay_type = &gme_ay_type_;
-
-// Setup
-
-blargg_err_t Ay_Emu::load_mem_( byte const* in, long size )
-{
- assert( offsetof (header_t,track_info [2]) == header_size );
-
- RETURN_ERR( parse_header( in, size, &file ) );
- set_track_count( file.header->max_track + 1 );
-
- if ( file.header->vers > 2 )
- set_warning( "Unknown file version" );
-
- set_voice_count( osc_count );
- apu.volume( gain() );
-
- return setup_buffer( spectrum_clock );
-}
-
-void Ay_Emu::update_eq( blip_eq_t const& eq )
-{
- apu.treble_eq( eq );
-}
-
-void Ay_Emu::set_voice( int i, Blip_Buffer* center, Blip_Buffer*, Blip_Buffer* )
-{
- if ( i >= Ay_Apu::osc_count )
- beeper_output = center;
- else
- apu.osc_output( i, center );
-}
-
-// Emulation
-
-void Ay_Emu::set_tempo_( double t )
-{
- play_period = blip_time_t (clock_rate() / 50 / t);
-}
-
-blargg_err_t Ay_Emu::start_track_( int track )
-{
- RETURN_ERR( Classic_Emu::start_track_( track ) );
-
- memset( mem.ram + 0x0000, 0xC9, 0x100 ); // fill RST vectors with RET
- memset( mem.ram + 0x0100, 0xFF, 0x4000 - 0x100 );
- memset( mem.ram + ram_start, 0x00, sizeof mem.ram - ram_start );
- memset( mem.padding1, 0xFF, sizeof mem.padding1 );
- memset( mem.ram + 0x10000, 0xFF, sizeof mem.ram - 0x10000 );
-
- // locate data blocks
- byte const* const data = get_data( file, file.tracks + track * 4 + 2, 14 );
- if ( !data ) return "File data missing";
-
- byte const* const more_data = get_data( file, data + 10, 6 );
- if ( !more_data ) return "File data missing";
-
- byte const* blocks = get_data( file, data + 12, 8 );
- if ( !blocks ) return "File data missing";
-
- // initial addresses
- cpu::reset( mem.ram );
- r.sp = get_be16( more_data );
- r.b.a = r.b.b = r.b.d = r.b.h = data [8];
- r.b.flags = r.b.c = r.b.e = r.b.l = data [9];
- r.alt.w = r.w;
- r.ix = r.iy = r.w.hl;
-
- unsigned addr = get_be16( blocks );
- if ( !addr ) return "File data missing";
-
- unsigned init = get_be16( more_data + 2 );
- if ( !init )
- init = addr;
-
- // copy blocks into memory
- do
- {
- blocks += 2;
- unsigned len = get_be16( blocks ); blocks += 2;
- if ( addr + len > 0x10000 )
- {
- set_warning( "Bad data block size" );
- len = 0x10000 - addr;
- }
- check( len );
- byte const* in = get_data( file, blocks, 0 ); blocks += 2;
- if ( len > blargg_ulong (file.end - in) )
- {
- set_warning( "Missing file data" );
- len = file.end - in;
- }
- //debug_printf( "addr: $%04X, len: $%04X\n", addr, len );
- if ( addr < ram_start && addr >= 0x400 ) // several tracks use low data
- debug_printf( "Block addr in ROM\n" );
-
- if (!in) {
- return "NULL in pointer\n";
- }
- memcpy( mem.ram + addr, in, len );
-
- if ( file.end - blocks < 8 )
- {
- set_warning( "Missing file data" );
- break;
- }
- }
- while ( (addr = get_be16( blocks )) != 0 );
-
- // copy and configure driver
- static byte const passive [] = {
- 0xF3, // DI
- 0xCD, 0, 0, // CALL init
- 0xED, 0x5E, // LOOP: IM 2
- 0xFB, // EI
- 0x76, // HALT
- 0x18, 0xFA // JR LOOP
- };
- static byte const active [] = {
- 0xF3, // DI
- 0xCD, 0, 0, // CALL init
- 0xED, 0x56, // LOOP: IM 1
- 0xFB, // EI
- 0x76, // HALT
- 0xCD, 0, 0, // CALL play
- 0x18, 0xF7 // JR LOOP
- };
- memcpy( mem.ram, passive, sizeof passive );
- unsigned play_addr = get_be16( more_data + 4 );
- //debug_printf( "Play: $%04X\n", play_addr );
- if ( play_addr )
- {
- memcpy( mem.ram, active, sizeof active );
- mem.ram [ 9] = play_addr;
- mem.ram [10] = play_addr >> 8;
- }
- mem.ram [2] = init;
- mem.ram [3] = init >> 8;
-
- mem.ram [0x38] = 0xFB; // Put EI at interrupt vector (followed by RET)
-
- memcpy( mem.ram + 0x10000, mem.ram, 0x80 ); // some code wraps around (ugh)
-
- beeper_delta = int (apu.amp_range * 0.65);
- last_beeper = 0;
- apu.reset();
- next_play = play_period;
-
- // start at spectrum speed
- change_clock_rate( spectrum_clock );
- set_tempo( tempo() );
-
- spectrum_mode = false;
- cpc_mode = false;
- cpc_latch = 0;
-
- return 0;
-}
-
-// Emulation
-
-void Ay_Emu::cpu_out_misc( cpu_time_t time, unsigned addr, int data )
-{
- if ( !cpc_mode )
- {
- switch ( addr & 0xFEFF )
- {
- case 0xFEFD:
- spectrum_mode = true;
- apu_addr = data & 0x0F;
- return;
-
- case 0xBEFD:
- spectrum_mode = true;
- apu.write( time, apu_addr, data );
- return;
- }
- }
-
- if ( !spectrum_mode )
- {
- switch ( addr >> 8 )
- {
- case 0xF6:
- switch ( data & 0xC0 )
- {
- case 0xC0:
- apu_addr = cpc_latch & 0x0F;
- goto enable_cpc;
-
- case 0x80:
- apu.write( time, apu_addr, cpc_latch );
- goto enable_cpc;
- }
- break;
-
- case 0xF4:
- cpc_latch = data;
- goto enable_cpc;
- }
- }
-
- debug_printf( "Unmapped OUT: $%04X <- $%02X\n", addr, data );
- return;
-
-enable_cpc:
- if ( !cpc_mode )
- {
- cpc_mode = true;
- change_clock_rate( cpc_clock );
- set_tempo( tempo() );
- }
-}
-
-void ay_cpu_out( Ay_Cpu* cpu, cpu_time_t time, unsigned addr, int data )
-{
- Ay_Emu& emu = STATIC_CAST(Ay_Emu&,*cpu);
-
- if ( (addr & 0xFF) == 0xFE && !emu.cpc_mode )
- {
- int delta = emu.beeper_delta;
- data &= 0x10;
- if ( emu.last_beeper != data )
- {
- emu.last_beeper = data;
- emu.beeper_delta = -delta;
- emu.spectrum_mode = true;
- if ( emu.beeper_output )
- emu.apu.synth_.offset( time, delta, emu.beeper_output );
- }
- }
- else
- {
- emu.cpu_out_misc( time, addr, data );
- }
-}
-
-int ay_cpu_in( Ay_Cpu*, unsigned addr )
-{
- // keyboard read and other things
- if ( (addr & 0xFF) == 0xFE )
- return 0xFF; // other values break some beeper tunes
-
- debug_printf( "Unmapped IN : $%04X\n", addr );
- return 0xFF;
-}
-
-blargg_err_t Ay_Emu::run_clocks( blip_time_t& duration, int )
-{
- set_time( 0 );
- if ( !(spectrum_mode | cpc_mode) )
- duration /= 2; // until mode is set, leave room for halved clock rate
-
- while ( time() < duration )
- {
- cpu::run( min( duration, (blip_time_t) next_play ) );
-
- if ( time() >= next_play )
- {
- next_play += play_period;
-
- if ( r.iff1 )
- {
- if ( mem.ram [r.pc] == 0x76 )
- r.pc++;
-
- r.iff1 = r.iff2 = 0;
-
- mem.ram [--r.sp] = uint8_t (r.pc >> 8);
- mem.ram [--r.sp] = uint8_t (r.pc);
- r.pc = 0x38;
- cpu::adjust_time( 12 );
- if ( r.im == 2 )
- {
- cpu::adjust_time( 6 );
- unsigned addr = r.i * 0x100u + 0xFF;
- r.pc = mem.ram [(addr + 1) & 0xFFFF] * 0x100u + mem.ram [addr];
- }
- }
- }
- }
- duration = time();
- next_play -= duration;
- check( next_play >= 0 );
- adjust_time( -duration );
-
- apu.end_frame( duration );
-
- return 0;
-}
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Ay_Emu.h b/plugins/gme/game-music-emu-0.5.5/gme/Ay_Emu.h
deleted file mode 100644
index 8cd2231d..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Ay_Emu.h
+++ /dev/null
@@ -1,70 +0,0 @@
-// Sinclair Spectrum AY music file emulator
-
-// Game_Music_Emu 0.5.5
-#ifndef AY_EMU_H
-#define AY_EMU_H
-
-#include "Classic_Emu.h"
-#include "Ay_Apu.h"
-#include "Ay_Cpu.h"
-
-class Ay_Emu : private Ay_Cpu, public Classic_Emu {
- typedef Ay_Cpu cpu;
-public:
- // AY file header
- enum { header_size = 0x14 };
- struct header_t
- {
- byte tag [8];
- byte vers;
- byte player;
- byte unused [2];
- byte author [2];
- byte comment [2];
- byte max_track;
- byte first_track;
- byte track_info [2];
- };
-
- static gme_type_t static_type() { return gme_ay_type; }
-public:
- Ay_Emu();
- ~Ay_Emu();
- struct file_t {
- header_t const* header;
- byte const* end;
- byte const* tracks;
- };
-protected:
- blargg_err_t track_info_( track_info_t*, int track ) const;
- blargg_err_t load_mem_( byte const*, long );
- blargg_err_t start_track_( int );
- blargg_err_t run_clocks( blip_time_t&, int );
- void set_tempo_( double );
- void set_voice( int, Blip_Buffer*, Blip_Buffer*, Blip_Buffer* );
- void update_eq( blip_eq_t const& );
-private:
- file_t file;
-
- unsigned play_addr;
- cpu_time_t play_period;
- cpu_time_t next_play;
- Blip_Buffer* beeper_output;
- int beeper_delta;
- int last_beeper;
- int apu_addr;
- int cpc_latch;
- bool spectrum_mode;
- bool cpc_mode;
-
- // large items
- struct {
- byte padding1 [0x100];
- byte ram [0x10000 + 0x100];
- } mem;
- Ay_Apu apu;
- friend void ay_cpu_out( Ay_Cpu*, cpu_time_t, unsigned addr, int data );
- void cpu_out_misc( cpu_time_t, unsigned addr, int data );
-};
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Blip_Buffer.cpp b/plugins/gme/game-music-emu-0.5.5/gme/Blip_Buffer.cpp
deleted file mode 100644
index 9dc89ea8..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Blip_Buffer.cpp
+++ /dev/null
@@ -1,446 +0,0 @@
-// Blip_Buffer 0.4.1. http://www.slack.net/~ant/
-
-#include "Blip_Buffer.h"
-
-#include <assert.h>
-#include <limits.h>
-#include <string.h>
-#include <stdlib.h>
-#include <math.h>
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#ifdef BLARGG_ENABLE_OPTIMIZER
- #include BLARGG_ENABLE_OPTIMIZER
-#endif
-
-int const silent_buf_size = 1; // size used for Silent_Blip_Buffer
-
-Blip_Buffer::Blip_Buffer()
-{
- factor_ = (blip_ulong)-1 / 2;
- offset_ = 0;
- buffer_ = 0;
- buffer_size_ = 0;
- sample_rate_ = 0;
- reader_accum_ = 0;
- bass_shift_ = 0;
- clock_rate_ = 0;
- bass_freq_ = 16;
- length_ = 0;
-
- // assumptions code makes about implementation-defined features
- #ifndef NDEBUG
- // right shift of negative value preserves sign
- buf_t_ i = -0x7FFFFFFE;
- assert( (i >> 1) == -0x3FFFFFFF );
-
- // casting to short truncates to 16 bits and sign-extends
- i = 0x18000;
- assert( (short) i == -0x8000 );
- #endif
-}
-
-Blip_Buffer::~Blip_Buffer()
-{
- if ( buffer_size_ != silent_buf_size )
- free( buffer_ );
-}
-
-Silent_Blip_Buffer::Silent_Blip_Buffer()
-{
- factor_ = 0;
- buffer_ = buf;
- buffer_size_ = silent_buf_size;
- memset( buf, 0, sizeof buf ); // in case machine takes exception for signed overflow
-}
-
-void Blip_Buffer::clear( int entire_buffer )
-{
- offset_ = 0;
- reader_accum_ = 0;
- modified_ = 0;
- if ( buffer_ )
- {
- long count = (entire_buffer ? buffer_size_ : samples_avail());
- memset( buffer_, 0, (count + blip_buffer_extra_) * sizeof (buf_t_) );
- }
-}
-
-Blip_Buffer::blargg_err_t Blip_Buffer::set_sample_rate( long new_rate, int msec )
-{
- if ( buffer_size_ == silent_buf_size )
- {
- assert( 0 );
- return "Internal (tried to resize Silent_Blip_Buffer)";
- }
-
- // start with maximum length that resampled time can represent
- long new_size = (UINT_MAX >> BLIP_BUFFER_ACCURACY) - blip_buffer_extra_ - 64;
- if ( msec != blip_max_length )
- {
- long s = (new_rate * (msec + 1) + 999) / 1000;
- if ( s < new_size )
- new_size = s;
- else
- assert( 0 ); // fails if requested buffer length exceeds limit
- }
-
- if ( buffer_size_ != new_size )
- {
- void* p = realloc( buffer_, (new_size + blip_buffer_extra_) * sizeof *buffer_ );
- if ( !p )
- return "Out of memory";
- buffer_ = (buf_t_*) p;
- }
-
- buffer_size_ = new_size;
- assert( buffer_size_ != silent_buf_size );
-
- // update things based on the sample rate
- sample_rate_ = new_rate;
- length_ = new_size * 1000 / new_rate - 1;
- if ( msec )
- assert( length_ == msec ); // ensure length is same as that passed in
- if ( clock_rate_ )
- clock_rate( clock_rate_ );
- bass_freq( bass_freq_ );
-
- clear();
-
- return 0; // success
-}
-
-blip_resampled_time_t Blip_Buffer::clock_rate_factor( long rate ) const
-{
- double ratio = (double) sample_rate_ / rate;
- blip_long factor = (blip_long) floor( ratio * (1L << BLIP_BUFFER_ACCURACY) + 0.5 );
- assert( factor > 0 || !sample_rate_ ); // fails if clock/output ratio is too large
- return (blip_resampled_time_t) factor;
-}
-
-void Blip_Buffer::bass_freq( int freq )
-{
- bass_freq_ = freq;
- int shift = 31;
- if ( freq > 0 )
- {
- shift = 13;
- long f = (freq << 16) / sample_rate_;
- while ( (f >>= 1) && --shift ) { }
- }
- bass_shift_ = shift;
-}
-
-void Blip_Buffer::end_frame( blip_time_t t )
-{
- offset_ += t * factor_;
- assert( samples_avail() <= (long) buffer_size_ ); // time outside buffer length
-}
-
-void Blip_Buffer::remove_silence( long count )
-{
- assert( count <= samples_avail() ); // tried to remove more samples than available
- offset_ -= (blip_resampled_time_t) count << BLIP_BUFFER_ACCURACY;
-}
-
-long Blip_Buffer::count_samples( blip_time_t t ) const
-{
- unsigned long last_sample = resampled_time( t ) >> BLIP_BUFFER_ACCURACY;
- unsigned long first_sample = offset_ >> BLIP_BUFFER_ACCURACY;
- return (long) (last_sample - first_sample);
-}
-
-blip_time_t Blip_Buffer::count_clocks( long count ) const
-{
- if ( !factor_ )
- {
- assert( 0 ); // sample rate and clock rates must be set first
- return 0;
- }
-
- if ( count > buffer_size_ )
- count = buffer_size_;
- blip_resampled_time_t time = (blip_resampled_time_t) count << BLIP_BUFFER_ACCURACY;
- return (blip_time_t) ((time - offset_ + factor_ - 1) / factor_);
-}
-
-void Blip_Buffer::remove_samples( long count )
-{
- if ( count )
- {
- remove_silence( count );
-
- // copy remaining samples to beginning and clear old samples
- long remain = samples_avail() + blip_buffer_extra_;
- memmove( buffer_, buffer_ + count, remain * sizeof *buffer_ );
- memset( buffer_ + remain, 0, count * sizeof *buffer_ );
- }
-}
-
-// Blip_Synth_
-
-Blip_Synth_Fast_::Blip_Synth_Fast_()
-{
- buf = 0;
- last_amp = 0;
- delta_factor = 0;
-}
-
-void Blip_Synth_Fast_::volume_unit( double new_unit )
-{
- delta_factor = int (new_unit * (1L << blip_sample_bits) + 0.5);
-}
-
-#if !BLIP_BUFFER_FAST
-
-Blip_Synth_::Blip_Synth_( short* p, int w ) :
- impulses( p ),
- width( w )
-{
- volume_unit_ = 0.0;
- kernel_unit = 0;
- buf = 0;
- last_amp = 0;
- delta_factor = 0;
-}
-
-#undef PI
-#define PI 3.1415926535897932384626433832795029
-
-static void gen_sinc( float* out, int count, double oversample, double treble, double cutoff )
-{
- if ( cutoff >= 0.999 )
- cutoff = 0.999;
-
- if ( treble < -300.0 )
- treble = -300.0;
- if ( treble > 5.0 )
- treble = 5.0;
-
- double const maxh = 4096.0;
- double const rolloff = pow( 10.0, 1.0 / (maxh * 20.0) * treble / (1.0 - cutoff) );
- double const pow_a_n = pow( rolloff, maxh - maxh * cutoff );
- double const to_angle = PI / 2 / maxh / oversample;
- for ( int i = 0; i < count; i++ )
- {
- double angle = ((i - count) * 2 + 1) * to_angle;
- double c = rolloff * cos( (maxh - 1.0) * angle ) - cos( maxh * angle );
- double cos_nc_angle = cos( maxh * cutoff * angle );
- double cos_nc1_angle = cos( (maxh * cutoff - 1.0) * angle );
- double cos_angle = cos( angle );
-
- c = c * pow_a_n - rolloff * cos_nc1_angle + cos_nc_angle;
- double d = 1.0 + rolloff * (rolloff - cos_angle - cos_angle);
- double b = 2.0 - cos_angle - cos_angle;
- double a = 1.0 - cos_angle - cos_nc_angle + cos_nc1_angle;
-
- out [i] = (float) ((a * d + c * b) / (b * d)); // a / b + c / d
- }
-}
-
-void blip_eq_t::generate( float* out, int count ) const
-{
- // lower cutoff freq for narrow kernels with their wider transition band
- // (8 points->1.49, 16 points->1.15)
- double oversample = blip_res * 2.25 / count + 0.85;
- double half_rate = sample_rate * 0.5;
- if ( cutoff_freq )
- oversample = half_rate / cutoff_freq;
- double cutoff = rolloff_freq * oversample / half_rate;
-
- gen_sinc( out, count, blip_res * oversample, treble, cutoff );
-
- // apply (half of) hamming window
- double to_fraction = PI / (count - 1);
- for ( int i = count; i--; )
- out [i] *= 0.54f - 0.46f * (float) cos( i * to_fraction );
-}
-
-void Blip_Synth_::adjust_impulse()
-{
- // sum pairs for each phase and add error correction to end of first half
- int const size = impulses_size();
- for ( int p = blip_res; p-- >= blip_res / 2; )
- {
- int p2 = blip_res - 2 - p;
- long error = kernel_unit;
- for ( int i = 1; i < size; i += blip_res )
- {
- error -= impulses [i + p ];
- error -= impulses [i + p2];
- }
- if ( p == p2 )
- error /= 2; // phase = 0.5 impulse uses same half for both sides
- impulses [size - blip_res + p] += (short) error;
- //printf( "error: %ld\n", error );
- }
-
- //for ( int i = blip_res; i--; printf( "\n" ) )
- // for ( int j = 0; j < width / 2; j++ )
- // printf( "%5ld,", impulses [j * blip_res + i + 1] );
-}
-
-void Blip_Synth_::treble_eq( blip_eq_t const& eq )
-{
- float fimpulse [blip_res / 2 * (blip_widest_impulse_ - 1) + blip_res * 2];
-
- int const half_size = blip_res / 2 * (width - 1);
- eq.generate( &fimpulse [blip_res], half_size );
-
- int i;
-
- // need mirror slightly past center for calculation
- for ( i = blip_res; i--; )
- fimpulse [blip_res + half_size + i] = fimpulse [blip_res + half_size - 1 - i];
-
- // starts at 0
- for ( i = 0; i < blip_res; i++ )
- fimpulse [i] = 0.0f;
-
- // find rescale factor
- double total = 0.0;
- for ( i = 0; i < half_size; i++ )
- total += fimpulse [blip_res + i];
-
- //double const base_unit = 44800.0 - 128 * 18; // allows treble up to +0 dB
- //double const base_unit = 37888.0; // allows treble to +5 dB
- double const base_unit = 32768.0; // necessary for blip_unscaled to work
- double rescale = base_unit / 2 / total;
- kernel_unit = (long) base_unit;
-
- // integrate, first difference, rescale, convert to int
- double sum = 0.0;
- double next = 0.0;
- int const impulses_size = this->impulses_size();
- for ( i = 0; i < impulses_size; i++ )
- {
- impulses [i] = (short) floor( (next - sum) * rescale + 0.5 );
- sum += fimpulse [i];
- next += fimpulse [i + blip_res];
- }
- adjust_impulse();
-
- // volume might require rescaling
- double vol = volume_unit_;
- if ( vol )
- {
- volume_unit_ = 0.0;
- volume_unit( vol );
- }
-}
-
-void Blip_Synth_::volume_unit( double new_unit )
-{
- if ( new_unit != volume_unit_ )
- {
- // use default eq if it hasn't been set yet
- if ( !kernel_unit )
- treble_eq( -8.0 );
-
- volume_unit_ = new_unit;
- double factor = new_unit * (1L << blip_sample_bits) / kernel_unit;
-
- if ( factor > 0.0 )
- {
- int shift = 0;
-
- // if unit is really small, might need to attenuate kernel
- while ( factor < 2.0 )
- {
- shift++;
- factor *= 2.0;
- }
-
- if ( shift )
- {
- kernel_unit >>= shift;
- assert( kernel_unit > 0 ); // fails if volume unit is too low
-
- // keep values positive to avoid round-towards-zero of sign-preserving
- // right shift for negative values
- long offset = 0x8000 + (1 << (shift - 1));
- long offset2 = 0x8000 >> shift;
- for ( int i = impulses_size(); i--; )
- impulses [i] = (short) (((impulses [i] + offset) >> shift) - offset2);
- adjust_impulse();
- }
- }
- delta_factor = (int) floor( factor + 0.5 );
- //printf( "delta_factor: %d, kernel_unit: %d\n", delta_factor, kernel_unit );
- }
-}
-#endif
-
-long Blip_Buffer::read_samples( blip_sample_t* BLIP_RESTRICT out, long max_samples, int stereo )
-{
- long count = samples_avail();
- if ( count > max_samples )
- count = max_samples;
-
- if ( count )
- {
- int const bass = BLIP_READER_BASS( *this );
- BLIP_READER_BEGIN( reader, *this );
-
- if ( !stereo )
- {
- for ( blip_long n = count; n; --n )
- {
- blip_long s = BLIP_READER_READ( reader );
- if ( (blip_sample_t) s != s )
- s = 0x7FFF - (s >> 24);
- *out++ = (blip_sample_t) s;
- BLIP_READER_NEXT( reader, bass );
- }
- }
- else
- {
- for ( blip_long n = count; n; --n )
- {
- blip_long s = BLIP_READER_READ( reader );
- if ( (blip_sample_t) s != s )
- s = 0x7FFF - (s >> 24);
- *out = (blip_sample_t) s;
- out += 2;
- BLIP_READER_NEXT( reader, bass );
- }
- }
- BLIP_READER_END( reader, *this );
-
- remove_samples( count );
- }
- return count;
-}
-
-void Blip_Buffer::mix_samples( blip_sample_t const* in, long count )
-{
- if ( buffer_size_ == silent_buf_size )
- {
- assert( 0 );
- return;
- }
-
- buf_t_* out = buffer_ + (offset_ >> BLIP_BUFFER_ACCURACY) + blip_widest_impulse_ / 2;
-
- int const sample_shift = blip_sample_bits - 16;
- int prev = 0;
- while ( count-- )
- {
- blip_long s = (blip_long) *in++ << sample_shift;
- *out += s - prev;
- prev = s;
- ++out;
- }
- *out -= prev;
-}
-
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Blip_Buffer.cpp.orig b/plugins/gme/game-music-emu-0.5.5/gme/Blip_Buffer.cpp.orig
deleted file mode 100644
index 9dc89ea8..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Blip_Buffer.cpp.orig
+++ /dev/null
@@ -1,446 +0,0 @@
-// Blip_Buffer 0.4.1. http://www.slack.net/~ant/
-
-#include "Blip_Buffer.h"
-
-#include <assert.h>
-#include <limits.h>
-#include <string.h>
-#include <stdlib.h>
-#include <math.h>
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#ifdef BLARGG_ENABLE_OPTIMIZER
- #include BLARGG_ENABLE_OPTIMIZER
-#endif
-
-int const silent_buf_size = 1; // size used for Silent_Blip_Buffer
-
-Blip_Buffer::Blip_Buffer()
-{
- factor_ = (blip_ulong)-1 / 2;
- offset_ = 0;
- buffer_ = 0;
- buffer_size_ = 0;
- sample_rate_ = 0;
- reader_accum_ = 0;
- bass_shift_ = 0;
- clock_rate_ = 0;
- bass_freq_ = 16;
- length_ = 0;
-
- // assumptions code makes about implementation-defined features
- #ifndef NDEBUG
- // right shift of negative value preserves sign
- buf_t_ i = -0x7FFFFFFE;
- assert( (i >> 1) == -0x3FFFFFFF );
-
- // casting to short truncates to 16 bits and sign-extends
- i = 0x18000;
- assert( (short) i == -0x8000 );
- #endif
-}
-
-Blip_Buffer::~Blip_Buffer()
-{
- if ( buffer_size_ != silent_buf_size )
- free( buffer_ );
-}
-
-Silent_Blip_Buffer::Silent_Blip_Buffer()
-{
- factor_ = 0;
- buffer_ = buf;
- buffer_size_ = silent_buf_size;
- memset( buf, 0, sizeof buf ); // in case machine takes exception for signed overflow
-}
-
-void Blip_Buffer::clear( int entire_buffer )
-{
- offset_ = 0;
- reader_accum_ = 0;
- modified_ = 0;
- if ( buffer_ )
- {
- long count = (entire_buffer ? buffer_size_ : samples_avail());
- memset( buffer_, 0, (count + blip_buffer_extra_) * sizeof (buf_t_) );
- }
-}
-
-Blip_Buffer::blargg_err_t Blip_Buffer::set_sample_rate( long new_rate, int msec )
-{
- if ( buffer_size_ == silent_buf_size )
- {
- assert( 0 );
- return "Internal (tried to resize Silent_Blip_Buffer)";
- }
-
- // start with maximum length that resampled time can represent
- long new_size = (UINT_MAX >> BLIP_BUFFER_ACCURACY) - blip_buffer_extra_ - 64;
- if ( msec != blip_max_length )
- {
- long s = (new_rate * (msec + 1) + 999) / 1000;
- if ( s < new_size )
- new_size = s;
- else
- assert( 0 ); // fails if requested buffer length exceeds limit
- }
-
- if ( buffer_size_ != new_size )
- {
- void* p = realloc( buffer_, (new_size + blip_buffer_extra_) * sizeof *buffer_ );
- if ( !p )
- return "Out of memory";
- buffer_ = (buf_t_*) p;
- }
-
- buffer_size_ = new_size;
- assert( buffer_size_ != silent_buf_size );
-
- // update things based on the sample rate
- sample_rate_ = new_rate;
- length_ = new_size * 1000 / new_rate - 1;
- if ( msec )
- assert( length_ == msec ); // ensure length is same as that passed in
- if ( clock_rate_ )
- clock_rate( clock_rate_ );
- bass_freq( bass_freq_ );
-
- clear();
-
- return 0; // success
-}
-
-blip_resampled_time_t Blip_Buffer::clock_rate_factor( long rate ) const
-{
- double ratio = (double) sample_rate_ / rate;
- blip_long factor = (blip_long) floor( ratio * (1L << BLIP_BUFFER_ACCURACY) + 0.5 );
- assert( factor > 0 || !sample_rate_ ); // fails if clock/output ratio is too large
- return (blip_resampled_time_t) factor;
-}
-
-void Blip_Buffer::bass_freq( int freq )
-{
- bass_freq_ = freq;
- int shift = 31;
- if ( freq > 0 )
- {
- shift = 13;
- long f = (freq << 16) / sample_rate_;
- while ( (f >>= 1) && --shift ) { }
- }
- bass_shift_ = shift;
-}
-
-void Blip_Buffer::end_frame( blip_time_t t )
-{
- offset_ += t * factor_;
- assert( samples_avail() <= (long) buffer_size_ ); // time outside buffer length
-}
-
-void Blip_Buffer::remove_silence( long count )
-{
- assert( count <= samples_avail() ); // tried to remove more samples than available
- offset_ -= (blip_resampled_time_t) count << BLIP_BUFFER_ACCURACY;
-}
-
-long Blip_Buffer::count_samples( blip_time_t t ) const
-{
- unsigned long last_sample = resampled_time( t ) >> BLIP_BUFFER_ACCURACY;
- unsigned long first_sample = offset_ >> BLIP_BUFFER_ACCURACY;
- return (long) (last_sample - first_sample);
-}
-
-blip_time_t Blip_Buffer::count_clocks( long count ) const
-{
- if ( !factor_ )
- {
- assert( 0 ); // sample rate and clock rates must be set first
- return 0;
- }
-
- if ( count > buffer_size_ )
- count = buffer_size_;
- blip_resampled_time_t time = (blip_resampled_time_t) count << BLIP_BUFFER_ACCURACY;
- return (blip_time_t) ((time - offset_ + factor_ - 1) / factor_);
-}
-
-void Blip_Buffer::remove_samples( long count )
-{
- if ( count )
- {
- remove_silence( count );
-
- // copy remaining samples to beginning and clear old samples
- long remain = samples_avail() + blip_buffer_extra_;
- memmove( buffer_, buffer_ + count, remain * sizeof *buffer_ );
- memset( buffer_ + remain, 0, count * sizeof *buffer_ );
- }
-}
-
-// Blip_Synth_
-
-Blip_Synth_Fast_::Blip_Synth_Fast_()
-{
- buf = 0;
- last_amp = 0;
- delta_factor = 0;
-}
-
-void Blip_Synth_Fast_::volume_unit( double new_unit )
-{
- delta_factor = int (new_unit * (1L << blip_sample_bits) + 0.5);
-}
-
-#if !BLIP_BUFFER_FAST
-
-Blip_Synth_::Blip_Synth_( short* p, int w ) :
- impulses( p ),
- width( w )
-{
- volume_unit_ = 0.0;
- kernel_unit = 0;
- buf = 0;
- last_amp = 0;
- delta_factor = 0;
-}
-
-#undef PI
-#define PI 3.1415926535897932384626433832795029
-
-static void gen_sinc( float* out, int count, double oversample, double treble, double cutoff )
-{
- if ( cutoff >= 0.999 )
- cutoff = 0.999;
-
- if ( treble < -300.0 )
- treble = -300.0;
- if ( treble > 5.0 )
- treble = 5.0;
-
- double const maxh = 4096.0;
- double const rolloff = pow( 10.0, 1.0 / (maxh * 20.0) * treble / (1.0 - cutoff) );
- double const pow_a_n = pow( rolloff, maxh - maxh * cutoff );
- double const to_angle = PI / 2 / maxh / oversample;
- for ( int i = 0; i < count; i++ )
- {
- double angle = ((i - count) * 2 + 1) * to_angle;
- double c = rolloff * cos( (maxh - 1.0) * angle ) - cos( maxh * angle );
- double cos_nc_angle = cos( maxh * cutoff * angle );
- double cos_nc1_angle = cos( (maxh * cutoff - 1.0) * angle );
- double cos_angle = cos( angle );
-
- c = c * pow_a_n - rolloff * cos_nc1_angle + cos_nc_angle;
- double d = 1.0 + rolloff * (rolloff - cos_angle - cos_angle);
- double b = 2.0 - cos_angle - cos_angle;
- double a = 1.0 - cos_angle - cos_nc_angle + cos_nc1_angle;
-
- out [i] = (float) ((a * d + c * b) / (b * d)); // a / b + c / d
- }
-}
-
-void blip_eq_t::generate( float* out, int count ) const
-{
- // lower cutoff freq for narrow kernels with their wider transition band
- // (8 points->1.49, 16 points->1.15)
- double oversample = blip_res * 2.25 / count + 0.85;
- double half_rate = sample_rate * 0.5;
- if ( cutoff_freq )
- oversample = half_rate / cutoff_freq;
- double cutoff = rolloff_freq * oversample / half_rate;
-
- gen_sinc( out, count, blip_res * oversample, treble, cutoff );
-
- // apply (half of) hamming window
- double to_fraction = PI / (count - 1);
- for ( int i = count; i--; )
- out [i] *= 0.54f - 0.46f * (float) cos( i * to_fraction );
-}
-
-void Blip_Synth_::adjust_impulse()
-{
- // sum pairs for each phase and add error correction to end of first half
- int const size = impulses_size();
- for ( int p = blip_res; p-- >= blip_res / 2; )
- {
- int p2 = blip_res - 2 - p;
- long error = kernel_unit;
- for ( int i = 1; i < size; i += blip_res )
- {
- error -= impulses [i + p ];
- error -= impulses [i + p2];
- }
- if ( p == p2 )
- error /= 2; // phase = 0.5 impulse uses same half for both sides
- impulses [size - blip_res + p] += (short) error;
- //printf( "error: %ld\n", error );
- }
-
- //for ( int i = blip_res; i--; printf( "\n" ) )
- // for ( int j = 0; j < width / 2; j++ )
- // printf( "%5ld,", impulses [j * blip_res + i + 1] );
-}
-
-void Blip_Synth_::treble_eq( blip_eq_t const& eq )
-{
- float fimpulse [blip_res / 2 * (blip_widest_impulse_ - 1) + blip_res * 2];
-
- int const half_size = blip_res / 2 * (width - 1);
- eq.generate( &fimpulse [blip_res], half_size );
-
- int i;
-
- // need mirror slightly past center for calculation
- for ( i = blip_res; i--; )
- fimpulse [blip_res + half_size + i] = fimpulse [blip_res + half_size - 1 - i];
-
- // starts at 0
- for ( i = 0; i < blip_res; i++ )
- fimpulse [i] = 0.0f;
-
- // find rescale factor
- double total = 0.0;
- for ( i = 0; i < half_size; i++ )
- total += fimpulse [blip_res + i];
-
- //double const base_unit = 44800.0 - 128 * 18; // allows treble up to +0 dB
- //double const base_unit = 37888.0; // allows treble to +5 dB
- double const base_unit = 32768.0; // necessary for blip_unscaled to work
- double rescale = base_unit / 2 / total;
- kernel_unit = (long) base_unit;
-
- // integrate, first difference, rescale, convert to int
- double sum = 0.0;
- double next = 0.0;
- int const impulses_size = this->impulses_size();
- for ( i = 0; i < impulses_size; i++ )
- {
- impulses [i] = (short) floor( (next - sum) * rescale + 0.5 );
- sum += fimpulse [i];
- next += fimpulse [i + blip_res];
- }
- adjust_impulse();
-
- // volume might require rescaling
- double vol = volume_unit_;
- if ( vol )
- {
- volume_unit_ = 0.0;
- volume_unit( vol );
- }
-}
-
-void Blip_Synth_::volume_unit( double new_unit )
-{
- if ( new_unit != volume_unit_ )
- {
- // use default eq if it hasn't been set yet
- if ( !kernel_unit )
- treble_eq( -8.0 );
-
- volume_unit_ = new_unit;
- double factor = new_unit * (1L << blip_sample_bits) / kernel_unit;
-
- if ( factor > 0.0 )
- {
- int shift = 0;
-
- // if unit is really small, might need to attenuate kernel
- while ( factor < 2.0 )
- {
- shift++;
- factor *= 2.0;
- }
-
- if ( shift )
- {
- kernel_unit >>= shift;
- assert( kernel_unit > 0 ); // fails if volume unit is too low
-
- // keep values positive to avoid round-towards-zero of sign-preserving
- // right shift for negative values
- long offset = 0x8000 + (1 << (shift - 1));
- long offset2 = 0x8000 >> shift;
- for ( int i = impulses_size(); i--; )
- impulses [i] = (short) (((impulses [i] + offset) >> shift) - offset2);
- adjust_impulse();
- }
- }
- delta_factor = (int) floor( factor + 0.5 );
- //printf( "delta_factor: %d, kernel_unit: %d\n", delta_factor, kernel_unit );
- }
-}
-#endif
-
-long Blip_Buffer::read_samples( blip_sample_t* BLIP_RESTRICT out, long max_samples, int stereo )
-{
- long count = samples_avail();
- if ( count > max_samples )
- count = max_samples;
-
- if ( count )
- {
- int const bass = BLIP_READER_BASS( *this );
- BLIP_READER_BEGIN( reader, *this );
-
- if ( !stereo )
- {
- for ( blip_long n = count; n; --n )
- {
- blip_long s = BLIP_READER_READ( reader );
- if ( (blip_sample_t) s != s )
- s = 0x7FFF - (s >> 24);
- *out++ = (blip_sample_t) s;
- BLIP_READER_NEXT( reader, bass );
- }
- }
- else
- {
- for ( blip_long n = count; n; --n )
- {
- blip_long s = BLIP_READER_READ( reader );
- if ( (blip_sample_t) s != s )
- s = 0x7FFF - (s >> 24);
- *out = (blip_sample_t) s;
- out += 2;
- BLIP_READER_NEXT( reader, bass );
- }
- }
- BLIP_READER_END( reader, *this );
-
- remove_samples( count );
- }
- return count;
-}
-
-void Blip_Buffer::mix_samples( blip_sample_t const* in, long count )
-{
- if ( buffer_size_ == silent_buf_size )
- {
- assert( 0 );
- return;
- }
-
- buf_t_* out = buffer_ + (offset_ >> BLIP_BUFFER_ACCURACY) + blip_widest_impulse_ / 2;
-
- int const sample_shift = blip_sample_bits - 16;
- int prev = 0;
- while ( count-- )
- {
- blip_long s = (blip_long) *in++ << sample_shift;
- *out += s - prev;
- prev = s;
- ++out;
- }
- *out -= prev;
-}
-
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Blip_Buffer.h b/plugins/gme/game-music-emu-0.5.5/gme/Blip_Buffer.h
deleted file mode 100644
index 4cc526d2..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Blip_Buffer.h
+++ /dev/null
@@ -1,488 +0,0 @@
-// Band-limited sound synthesis buffer
-
-// Blip_Buffer 0.4.1
-#ifndef BLIP_BUFFER_H
-#define BLIP_BUFFER_H
-
- // internal
- #include <limits.h>
- #if INT_MAX < 0x7FFFFFFF
- #error "int must be at least 32 bits"
- #endif
-
- typedef int blip_long;
- typedef unsigned blip_ulong;
-
-// Time unit at source clock rate
-typedef blip_long blip_time_t;
-
-// Output samples are 16-bit signed, with a range of -32768 to 32767
-typedef short blip_sample_t;
-enum { blip_sample_max = 32767 };
-
-class Blip_Buffer {
-public:
- typedef const char* blargg_err_t;
-
- // Set output sample rate and buffer length in milliseconds (1/1000 sec, defaults
- // to 1/4 second), then clear buffer. Returns NULL on success, otherwise if there
- // isn't enough memory, returns error without affecting current buffer setup.
- blargg_err_t set_sample_rate( long samples_per_sec, int msec_length = 1000 / 4 );
-
- // Set number of source time units per second
- void clock_rate( long );
-
- // End current time frame of specified duration and make its samples available
- // (along with any still-unread samples) for reading with read_samples(). Begins
- // a new time frame at the end of the current frame.
- void end_frame( blip_time_t time );
-
- // Read at most 'max_samples' out of buffer into 'dest', removing them from from
- // the buffer. Returns number of samples actually read and removed. If stereo is
- // true, increments 'dest' one extra time after writing each sample, to allow
- // easy interleving of two channels into a stereo output buffer.
- long read_samples( blip_sample_t* dest, long max_samples, int stereo = 0 );
-
-// Additional optional features
-
- // Current output sample rate
- long sample_rate() const;
-
- // Length of buffer, in milliseconds
- int length() const;
-
- // Number of source time units per second
- long clock_rate() const;
-
- // Set frequency high-pass filter frequency, where higher values reduce bass more
- void bass_freq( int frequency );
-
- // Number of samples delay from synthesis to samples read out
- int output_latency() const;
-
- // Remove all available samples and clear buffer to silence. If 'entire_buffer' is
- // false, just clears out any samples waiting rather than the entire buffer.
- void clear( int entire_buffer = 1 );
-
- // Number of samples available for reading with read_samples()
- long samples_avail() const;
-
- // Remove 'count' samples from those waiting to be read
- void remove_samples( long count );
-
-// Experimental features
-
- // Count number of clocks needed until 'count' samples will be available.
- // If buffer can't even hold 'count' samples, returns number of clocks until
- // buffer becomes full.
- blip_time_t count_clocks( long count ) const;
-
- // Number of raw samples that can be mixed within frame of specified duration.
- long count_samples( blip_time_t duration ) const;
-
- // Mix 'count' samples from 'buf' into buffer.
- void mix_samples( blip_sample_t const* buf, long count );
-
- // not documented yet
- void set_modified() { modified_ = 1; }
- int clear_modified() { int b = modified_; modified_ = 0; return b; }
- typedef blip_ulong blip_resampled_time_t;
- void remove_silence( long count );
- blip_resampled_time_t resampled_duration( int t ) const { return t * factor_; }
- blip_resampled_time_t resampled_time( blip_time_t t ) const { return t * factor_ + offset_; }
- blip_resampled_time_t clock_rate_factor( long clock_rate ) const;
-public:
- Blip_Buffer();
- ~Blip_Buffer();
-
- // Deprecated
- typedef blip_resampled_time_t resampled_time_t;
- blargg_err_t sample_rate( long r ) { return set_sample_rate( r ); }
- blargg_err_t sample_rate( long r, int msec ) { return set_sample_rate( r, msec ); }
-private:
- // noncopyable
- Blip_Buffer( const Blip_Buffer& );
- Blip_Buffer& operator = ( const Blip_Buffer& );
-public:
- typedef blip_time_t buf_t_;
- blip_ulong factor_;
- blip_resampled_time_t offset_;
- buf_t_* buffer_;
- blip_long buffer_size_;
- blip_long reader_accum_;
- int bass_shift_;
-private:
- long sample_rate_;
- long clock_rate_;
- int bass_freq_;
- int length_;
- int modified_;
- friend class Blip_Reader;
-};
-
-#ifdef HAVE_CONFIG_H
- #include "config.h"
-#endif
-
-// Number of bits in resample ratio fraction. Higher values give a more accurate ratio
-// but reduce maximum buffer size.
-#ifndef BLIP_BUFFER_ACCURACY
- #define BLIP_BUFFER_ACCURACY 16
-#endif
-
-// Number bits in phase offset. Fewer than 6 bits (64 phase offsets) results in
-// noticeable broadband noise when synthesizing high frequency square waves.
-// Affects size of Blip_Synth objects since they store the waveform directly.
-#ifndef BLIP_PHASE_BITS
- #if BLIP_BUFFER_FAST
- #define BLIP_PHASE_BITS 8
- #else
- #define BLIP_PHASE_BITS 6
- #endif
-#endif
-
- // Internal
- typedef blip_ulong blip_resampled_time_t;
- int const blip_widest_impulse_ = 16;
- int const blip_buffer_extra_ = blip_widest_impulse_ + 2;
- int const blip_res = 1 << BLIP_PHASE_BITS;
- class blip_eq_t;
-
- class Blip_Synth_Fast_ {
- public:
- Blip_Buffer* buf;
- int last_amp;
- int delta_factor;
-
- void volume_unit( double );
- Blip_Synth_Fast_();
- void treble_eq( blip_eq_t const& ) { }
- };
-
- class Blip_Synth_ {
- public:
- Blip_Buffer* buf;
- int last_amp;
- int delta_factor;
-
- void volume_unit( double );
- Blip_Synth_( short* impulses, int width );
- void treble_eq( blip_eq_t const& );
- private:
- double volume_unit_;
- short* const impulses;
- int const width;
- blip_long kernel_unit;
- int impulses_size() const { return blip_res / 2 * width + 1; }
- void adjust_impulse();
- };
-
-// Quality level. Start with blip_good_quality.
-const int blip_med_quality = 8;
-const int blip_good_quality = 12;
-const int blip_high_quality = 16;
-
-// Range specifies the greatest expected change in amplitude. Calculate it
-// by finding the difference between the maximum and minimum expected
-// amplitudes (max - min).
-template<int quality,int range>
-class Blip_Synth {
-public:
- // Set overall volume of waveform
- void volume( double v ) { impl.volume_unit( v * (1.0 / (range < 0 ? -range : range)) ); }
-
- // Configure low-pass filter (see blip_buffer.txt)
- void treble_eq( blip_eq_t const& eq ) { impl.treble_eq( eq ); }
-
- // Get/set Blip_Buffer used for output
- Blip_Buffer* output() const { return impl.buf; }
- void output( Blip_Buffer* b ) { impl.buf = b; impl.last_amp = 0; }
-
- // Update amplitude of waveform at given time. Using this requires a separate
- // Blip_Synth for each waveform.
- void update( blip_time_t time, int amplitude );
-
-// Low-level interface
-
- // Add an amplitude transition of specified delta, optionally into specified buffer
- // rather than the one set with output(). Delta can be positive or negative.
- // The actual change in amplitude is delta * (volume / range)
- void offset( blip_time_t, int delta, Blip_Buffer* ) const;
- void offset( blip_time_t t, int delta ) const { offset( t, delta, impl.buf ); }
-
- // Works directly in terms of fractional output samples. Contact author for more info.
- void offset_resampled( blip_resampled_time_t, int delta, Blip_Buffer* ) const;
-
- // Same as offset(), except code is inlined for higher performance
- void offset_inline( blip_time_t t, int delta, Blip_Buffer* buf ) const {
- offset_resampled( t * buf->factor_ + buf->offset_, delta, buf );
- }
- void offset_inline( blip_time_t t, int delta ) const {
- offset_resampled( t * impl.buf->factor_ + impl.buf->offset_, delta, impl.buf );
- }
-
-private:
-#if BLIP_BUFFER_FAST
- Blip_Synth_Fast_ impl;
-#else
- Blip_Synth_ impl;
- typedef short imp_t;
- imp_t impulses [blip_res * (quality / 2) + 1];
-public:
- Blip_Synth() : impl( impulses, quality ) { }
-#endif
-};
-
-// Low-pass equalization parameters
-class blip_eq_t {
-public:
- // Logarithmic rolloff to treble dB at half sampling rate. Negative values reduce
- // treble, small positive values (0 to 5.0) increase treble.
- blip_eq_t( double treble_db = 0 );
-
- // See blip_buffer.txt
- blip_eq_t( double treble, long rolloff_freq, long sample_rate, long cutoff_freq = 0 );
-
-private:
- double treble;
- long rolloff_freq;
- long sample_rate;
- long cutoff_freq;
- void generate( float* out, int count ) const;
- friend class Blip_Synth_;
-};
-
-int const blip_sample_bits = 30;
-
-// Dummy Blip_Buffer to direct sound output to, for easy muting without
-// having to stop sound code.
-class Silent_Blip_Buffer : public Blip_Buffer {
- buf_t_ buf [blip_buffer_extra_ + 1];
-public:
- // The following cannot be used (an assertion will fail if attempted):
- blargg_err_t set_sample_rate( long samples_per_sec, int msec_length );
- blip_time_t count_clocks( long count ) const;
- void mix_samples( blip_sample_t const* buf, long count );
-
- Silent_Blip_Buffer();
-};
-
- #if defined (__GNUC__) || _MSC_VER >= 1100
- #define BLIP_RESTRICT __restrict
- #else
- #define BLIP_RESTRICT
- #endif
-
-// Optimized reading from Blip_Buffer, for use in custom sample output
-
-// Begin reading from buffer. Name should be unique to the current block.
-#define BLIP_READER_BEGIN( name, blip_buffer ) \
- const Blip_Buffer::buf_t_* BLIP_RESTRICT name##_reader_buf = (blip_buffer).buffer_;\
- blip_long name##_reader_accum = (blip_buffer).reader_accum_
-
-// Get value to pass to BLIP_READER_NEXT()
-#define BLIP_READER_BASS( blip_buffer ) ((blip_buffer).bass_shift_)
-
-// Constant value to use instead of BLIP_READER_BASS(), for slightly more optimal
-// code at the cost of having no bass control
-int const blip_reader_default_bass = 9;
-
-// Current sample
-#define BLIP_READER_READ( name ) (name##_reader_accum >> (blip_sample_bits - 16))
-
-// Current raw sample in full internal resolution
-#define BLIP_READER_READ_RAW( name ) (name##_reader_accum)
-
-// Advance to next sample
-#define BLIP_READER_NEXT( name, bass ) \
- (void) (name##_reader_accum += *name##_reader_buf++ - (name##_reader_accum >> (bass)))
-
-// End reading samples from buffer. The number of samples read must now be removed
-// using Blip_Buffer::remove_samples().
-#define BLIP_READER_END( name, blip_buffer ) \
- (void) ((blip_buffer).reader_accum_ = name##_reader_accum)
-
-
-// Compatibility with older version
-const long blip_unscaled = 65535;
-const int blip_low_quality = blip_med_quality;
-const int blip_best_quality = blip_high_quality;
-
-// Deprecated; use BLIP_READER macros as follows:
-// Blip_Reader r; r.begin( buf ); -> BLIP_READER_BEGIN( r, buf );
-// int bass = r.begin( buf ) -> BLIP_READER_BEGIN( r, buf ); int bass = BLIP_READER_BASS( buf );
-// r.read() -> BLIP_READER_READ( r )
-// r.read_raw() -> BLIP_READER_READ_RAW( r )
-// r.next( bass ) -> BLIP_READER_NEXT( r, bass )
-// r.next() -> BLIP_READER_NEXT( r, blip_reader_default_bass )
-// r.end( buf ) -> BLIP_READER_END( r, buf )
-class Blip_Reader {
-public:
- int begin( Blip_Buffer& );
- blip_long read() const { return accum >> (blip_sample_bits - 16); }
- blip_long read_raw() const { return accum; }
- void next( int bass_shift = 9 ) { accum += *buf++ - (accum >> bass_shift); }
- void end( Blip_Buffer& b ) { b.reader_accum_ = accum; }
-
-private:
- const Blip_Buffer::buf_t_* buf;
- blip_long accum;
-};
-
-// End of public interface
-
-#include <assert.h>
-
-template<int quality,int range>
-inline void Blip_Synth<quality,range>::offset_resampled( blip_resampled_time_t time,
- int delta, Blip_Buffer* blip_buf ) const
-{
- // Fails if time is beyond end of Blip_Buffer, due to a bug in caller code or the
- // need for a longer buffer as set by set_sample_rate().
- assert( (blip_long) (time >> BLIP_BUFFER_ACCURACY) < blip_buf->buffer_size_ );
- delta *= impl.delta_factor;
- blip_long* BLIP_RESTRICT buf = blip_buf->buffer_ + (time >> BLIP_BUFFER_ACCURACY);
- int phase = (int) (time >> (BLIP_BUFFER_ACCURACY - BLIP_PHASE_BITS) & (blip_res - 1));
-
-#if BLIP_BUFFER_FAST
- blip_long left = buf [0] + delta;
-
- // Kind of crappy, but doing shift after multiply results in overflow.
- // Alternate way of delaying multiply by delta_factor results in worse
- // sub-sample resolution.
- blip_long right = (delta >> BLIP_PHASE_BITS) * phase;
- left -= right;
- right += buf [1];
-
- buf [0] = left;
- buf [1] = right;
-#else
-
- int const fwd = (blip_widest_impulse_ - quality) / 2;
- int const rev = fwd + quality - 2;
- int const mid = quality / 2 - 1;
-
- imp_t const* BLIP_RESTRICT imp = impulses + blip_res - phase;
-
- #if defined (_M_IX86) || defined (_M_IA64) || defined (__i486__) || \
- defined (__x86_64__) || defined (__ia64__) || defined (__i386__)
-
- // straight forward implementation resulted in better code on GCC for x86
-
- #define ADD_IMP( out, in ) \
- buf [out] += (blip_long) imp [blip_res * (in)] * delta
-
- #define BLIP_FWD( i ) {\
- ADD_IMP( fwd + i, i );\
- ADD_IMP( fwd + 1 + i, i + 1 );\
- }
- #define BLIP_REV( r ) {\
- ADD_IMP( rev - r, r + 1 );\
- ADD_IMP( rev + 1 - r, r );\
- }
-
- BLIP_FWD( 0 )
- if ( quality > 8 ) BLIP_FWD( 2 )
- if ( quality > 12 ) BLIP_FWD( 4 )
- {
- ADD_IMP( fwd + mid - 1, mid - 1 );
- ADD_IMP( fwd + mid , mid );
- imp = impulses + phase;
- }
- if ( quality > 12 ) BLIP_REV( 6 )
- if ( quality > 8 ) BLIP_REV( 4 )
- BLIP_REV( 2 )
-
- ADD_IMP( rev , 1 );
- ADD_IMP( rev + 1, 0 );
-
- #else
-
- // for RISC processors, help compiler by reading ahead of writes
-
- #define BLIP_FWD( i ) {\
- blip_long t0 = i0 * delta + buf [fwd + i];\
- blip_long t1 = imp [blip_res * (i + 1)] * delta + buf [fwd + 1 + i];\
- i0 = imp [blip_res * (i + 2)];\
- buf [fwd + i] = t0;\
- buf [fwd + 1 + i] = t1;\
- }
- #define BLIP_REV( r ) {\
- blip_long t0 = i0 * delta + buf [rev - r];\
- blip_long t1 = imp [blip_res * r] * delta + buf [rev + 1 - r];\
- i0 = imp [blip_res * (r - 1)];\
- buf [rev - r] = t0;\
- buf [rev + 1 - r] = t1;\
- }
-
- blip_long i0 = *imp;
- BLIP_FWD( 0 )
- if ( quality > 8 ) BLIP_FWD( 2 )
- if ( quality > 12 ) BLIP_FWD( 4 )
- {
- blip_long t0 = i0 * delta + buf [fwd + mid - 1];
- blip_long t1 = imp [blip_res * mid] * delta + buf [fwd + mid ];
- imp = impulses + phase;
- i0 = imp [blip_res * mid];
- buf [fwd + mid - 1] = t0;
- buf [fwd + mid ] = t1;
- }
- if ( quality > 12 ) BLIP_REV( 6 )
- if ( quality > 8 ) BLIP_REV( 4 )
- BLIP_REV( 2 )
-
- blip_long t0 = i0 * delta + buf [rev ];
- blip_long t1 = *imp * delta + buf [rev + 1];
- buf [rev ] = t0;
- buf [rev + 1] = t1;
- #endif
-
-#endif
-}
-
-#undef BLIP_FWD
-#undef BLIP_REV
-
-template<int quality,int range>
-#if BLIP_BUFFER_FAST
- inline
-#endif
-void Blip_Synth<quality,range>::offset( blip_time_t t, int delta, Blip_Buffer* buf ) const
-{
- offset_resampled( t * buf->factor_ + buf->offset_, delta, buf );
-}
-
-template<int quality,int range>
-#if BLIP_BUFFER_FAST
- inline
-#endif
-void Blip_Synth<quality,range>::update( blip_time_t t, int amp )
-{
- int delta = amp - impl.last_amp;
- impl.last_amp = amp;
- offset_resampled( t * impl.buf->factor_ + impl.buf->offset_, delta, impl.buf );
-}
-
-inline blip_eq_t::blip_eq_t( double t ) :
- treble( t ), rolloff_freq( 0 ), sample_rate( 44100 ), cutoff_freq( 0 ) { }
-inline blip_eq_t::blip_eq_t( double t, long rf, long sr, long cf ) :
- treble( t ), rolloff_freq( rf ), sample_rate( sr ), cutoff_freq( cf ) { }
-
-inline int Blip_Buffer::length() const { return length_; }
-inline long Blip_Buffer::samples_avail() const { return (long) (offset_ >> BLIP_BUFFER_ACCURACY); }
-inline long Blip_Buffer::sample_rate() const { return sample_rate_; }
-inline int Blip_Buffer::output_latency() const { return blip_widest_impulse_ / 2; }
-inline long Blip_Buffer::clock_rate() const { return clock_rate_; }
-inline void Blip_Buffer::clock_rate( long cps ) { factor_ = clock_rate_factor( clock_rate_ = cps ); }
-
-inline int Blip_Reader::begin( Blip_Buffer& blip_buf )
-{
- buf = blip_buf.buffer_;
- accum = blip_buf.reader_accum_;
- return blip_buf.bass_shift_;
-}
-
-int const blip_max_length = 0;
-int const blip_default_length = 250;
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Blip_Buffer.h.orig b/plugins/gme/game-music-emu-0.5.5/gme/Blip_Buffer.h.orig
deleted file mode 100644
index 4cc526d2..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Blip_Buffer.h.orig
+++ /dev/null
@@ -1,488 +0,0 @@
-// Band-limited sound synthesis buffer
-
-// Blip_Buffer 0.4.1
-#ifndef BLIP_BUFFER_H
-#define BLIP_BUFFER_H
-
- // internal
- #include <limits.h>
- #if INT_MAX < 0x7FFFFFFF
- #error "int must be at least 32 bits"
- #endif
-
- typedef int blip_long;
- typedef unsigned blip_ulong;
-
-// Time unit at source clock rate
-typedef blip_long blip_time_t;
-
-// Output samples are 16-bit signed, with a range of -32768 to 32767
-typedef short blip_sample_t;
-enum { blip_sample_max = 32767 };
-
-class Blip_Buffer {
-public:
- typedef const char* blargg_err_t;
-
- // Set output sample rate and buffer length in milliseconds (1/1000 sec, defaults
- // to 1/4 second), then clear buffer. Returns NULL on success, otherwise if there
- // isn't enough memory, returns error without affecting current buffer setup.
- blargg_err_t set_sample_rate( long samples_per_sec, int msec_length = 1000 / 4 );
-
- // Set number of source time units per second
- void clock_rate( long );
-
- // End current time frame of specified duration and make its samples available
- // (along with any still-unread samples) for reading with read_samples(). Begins
- // a new time frame at the end of the current frame.
- void end_frame( blip_time_t time );
-
- // Read at most 'max_samples' out of buffer into 'dest', removing them from from
- // the buffer. Returns number of samples actually read and removed. If stereo is
- // true, increments 'dest' one extra time after writing each sample, to allow
- // easy interleving of two channels into a stereo output buffer.
- long read_samples( blip_sample_t* dest, long max_samples, int stereo = 0 );
-
-// Additional optional features
-
- // Current output sample rate
- long sample_rate() const;
-
- // Length of buffer, in milliseconds
- int length() const;
-
- // Number of source time units per second
- long clock_rate() const;
-
- // Set frequency high-pass filter frequency, where higher values reduce bass more
- void bass_freq( int frequency );
-
- // Number of samples delay from synthesis to samples read out
- int output_latency() const;
-
- // Remove all available samples and clear buffer to silence. If 'entire_buffer' is
- // false, just clears out any samples waiting rather than the entire buffer.
- void clear( int entire_buffer = 1 );
-
- // Number of samples available for reading with read_samples()
- long samples_avail() const;
-
- // Remove 'count' samples from those waiting to be read
- void remove_samples( long count );
-
-// Experimental features
-
- // Count number of clocks needed until 'count' samples will be available.
- // If buffer can't even hold 'count' samples, returns number of clocks until
- // buffer becomes full.
- blip_time_t count_clocks( long count ) const;
-
- // Number of raw samples that can be mixed within frame of specified duration.
- long count_samples( blip_time_t duration ) const;
-
- // Mix 'count' samples from 'buf' into buffer.
- void mix_samples( blip_sample_t const* buf, long count );
-
- // not documented yet
- void set_modified() { modified_ = 1; }
- int clear_modified() { int b = modified_; modified_ = 0; return b; }
- typedef blip_ulong blip_resampled_time_t;
- void remove_silence( long count );
- blip_resampled_time_t resampled_duration( int t ) const { return t * factor_; }
- blip_resampled_time_t resampled_time( blip_time_t t ) const { return t * factor_ + offset_; }
- blip_resampled_time_t clock_rate_factor( long clock_rate ) const;
-public:
- Blip_Buffer();
- ~Blip_Buffer();
-
- // Deprecated
- typedef blip_resampled_time_t resampled_time_t;
- blargg_err_t sample_rate( long r ) { return set_sample_rate( r ); }
- blargg_err_t sample_rate( long r, int msec ) { return set_sample_rate( r, msec ); }
-private:
- // noncopyable
- Blip_Buffer( const Blip_Buffer& );
- Blip_Buffer& operator = ( const Blip_Buffer& );
-public:
- typedef blip_time_t buf_t_;
- blip_ulong factor_;
- blip_resampled_time_t offset_;
- buf_t_* buffer_;
- blip_long buffer_size_;
- blip_long reader_accum_;
- int bass_shift_;
-private:
- long sample_rate_;
- long clock_rate_;
- int bass_freq_;
- int length_;
- int modified_;
- friend class Blip_Reader;
-};
-
-#ifdef HAVE_CONFIG_H
- #include "config.h"
-#endif
-
-// Number of bits in resample ratio fraction. Higher values give a more accurate ratio
-// but reduce maximum buffer size.
-#ifndef BLIP_BUFFER_ACCURACY
- #define BLIP_BUFFER_ACCURACY 16
-#endif
-
-// Number bits in phase offset. Fewer than 6 bits (64 phase offsets) results in
-// noticeable broadband noise when synthesizing high frequency square waves.
-// Affects size of Blip_Synth objects since they store the waveform directly.
-#ifndef BLIP_PHASE_BITS
- #if BLIP_BUFFER_FAST
- #define BLIP_PHASE_BITS 8
- #else
- #define BLIP_PHASE_BITS 6
- #endif
-#endif
-
- // Internal
- typedef blip_ulong blip_resampled_time_t;
- int const blip_widest_impulse_ = 16;
- int const blip_buffer_extra_ = blip_widest_impulse_ + 2;
- int const blip_res = 1 << BLIP_PHASE_BITS;
- class blip_eq_t;
-
- class Blip_Synth_Fast_ {
- public:
- Blip_Buffer* buf;
- int last_amp;
- int delta_factor;
-
- void volume_unit( double );
- Blip_Synth_Fast_();
- void treble_eq( blip_eq_t const& ) { }
- };
-
- class Blip_Synth_ {
- public:
- Blip_Buffer* buf;
- int last_amp;
- int delta_factor;
-
- void volume_unit( double );
- Blip_Synth_( short* impulses, int width );
- void treble_eq( blip_eq_t const& );
- private:
- double volume_unit_;
- short* const impulses;
- int const width;
- blip_long kernel_unit;
- int impulses_size() const { return blip_res / 2 * width + 1; }
- void adjust_impulse();
- };
-
-// Quality level. Start with blip_good_quality.
-const int blip_med_quality = 8;
-const int blip_good_quality = 12;
-const int blip_high_quality = 16;
-
-// Range specifies the greatest expected change in amplitude. Calculate it
-// by finding the difference between the maximum and minimum expected
-// amplitudes (max - min).
-template<int quality,int range>
-class Blip_Synth {
-public:
- // Set overall volume of waveform
- void volume( double v ) { impl.volume_unit( v * (1.0 / (range < 0 ? -range : range)) ); }
-
- // Configure low-pass filter (see blip_buffer.txt)
- void treble_eq( blip_eq_t const& eq ) { impl.treble_eq( eq ); }
-
- // Get/set Blip_Buffer used for output
- Blip_Buffer* output() const { return impl.buf; }
- void output( Blip_Buffer* b ) { impl.buf = b; impl.last_amp = 0; }
-
- // Update amplitude of waveform at given time. Using this requires a separate
- // Blip_Synth for each waveform.
- void update( blip_time_t time, int amplitude );
-
-// Low-level interface
-
- // Add an amplitude transition of specified delta, optionally into specified buffer
- // rather than the one set with output(). Delta can be positive or negative.
- // The actual change in amplitude is delta * (volume / range)
- void offset( blip_time_t, int delta, Blip_Buffer* ) const;
- void offset( blip_time_t t, int delta ) const { offset( t, delta, impl.buf ); }
-
- // Works directly in terms of fractional output samples. Contact author for more info.
- void offset_resampled( blip_resampled_time_t, int delta, Blip_Buffer* ) const;
-
- // Same as offset(), except code is inlined for higher performance
- void offset_inline( blip_time_t t, int delta, Blip_Buffer* buf ) const {
- offset_resampled( t * buf->factor_ + buf->offset_, delta, buf );
- }
- void offset_inline( blip_time_t t, int delta ) const {
- offset_resampled( t * impl.buf->factor_ + impl.buf->offset_, delta, impl.buf );
- }
-
-private:
-#if BLIP_BUFFER_FAST
- Blip_Synth_Fast_ impl;
-#else
- Blip_Synth_ impl;
- typedef short imp_t;
- imp_t impulses [blip_res * (quality / 2) + 1];
-public:
- Blip_Synth() : impl( impulses, quality ) { }
-#endif
-};
-
-// Low-pass equalization parameters
-class blip_eq_t {
-public:
- // Logarithmic rolloff to treble dB at half sampling rate. Negative values reduce
- // treble, small positive values (0 to 5.0) increase treble.
- blip_eq_t( double treble_db = 0 );
-
- // See blip_buffer.txt
- blip_eq_t( double treble, long rolloff_freq, long sample_rate, long cutoff_freq = 0 );
-
-private:
- double treble;
- long rolloff_freq;
- long sample_rate;
- long cutoff_freq;
- void generate( float* out, int count ) const;
- friend class Blip_Synth_;
-};
-
-int const blip_sample_bits = 30;
-
-// Dummy Blip_Buffer to direct sound output to, for easy muting without
-// having to stop sound code.
-class Silent_Blip_Buffer : public Blip_Buffer {
- buf_t_ buf [blip_buffer_extra_ + 1];
-public:
- // The following cannot be used (an assertion will fail if attempted):
- blargg_err_t set_sample_rate( long samples_per_sec, int msec_length );
- blip_time_t count_clocks( long count ) const;
- void mix_samples( blip_sample_t const* buf, long count );
-
- Silent_Blip_Buffer();
-};
-
- #if defined (__GNUC__) || _MSC_VER >= 1100
- #define BLIP_RESTRICT __restrict
- #else
- #define BLIP_RESTRICT
- #endif
-
-// Optimized reading from Blip_Buffer, for use in custom sample output
-
-// Begin reading from buffer. Name should be unique to the current block.
-#define BLIP_READER_BEGIN( name, blip_buffer ) \
- const Blip_Buffer::buf_t_* BLIP_RESTRICT name##_reader_buf = (blip_buffer).buffer_;\
- blip_long name##_reader_accum = (blip_buffer).reader_accum_
-
-// Get value to pass to BLIP_READER_NEXT()
-#define BLIP_READER_BASS( blip_buffer ) ((blip_buffer).bass_shift_)
-
-// Constant value to use instead of BLIP_READER_BASS(), for slightly more optimal
-// code at the cost of having no bass control
-int const blip_reader_default_bass = 9;
-
-// Current sample
-#define BLIP_READER_READ( name ) (name##_reader_accum >> (blip_sample_bits - 16))
-
-// Current raw sample in full internal resolution
-#define BLIP_READER_READ_RAW( name ) (name##_reader_accum)
-
-// Advance to next sample
-#define BLIP_READER_NEXT( name, bass ) \
- (void) (name##_reader_accum += *name##_reader_buf++ - (name##_reader_accum >> (bass)))
-
-// End reading samples from buffer. The number of samples read must now be removed
-// using Blip_Buffer::remove_samples().
-#define BLIP_READER_END( name, blip_buffer ) \
- (void) ((blip_buffer).reader_accum_ = name##_reader_accum)
-
-
-// Compatibility with older version
-const long blip_unscaled = 65535;
-const int blip_low_quality = blip_med_quality;
-const int blip_best_quality = blip_high_quality;
-
-// Deprecated; use BLIP_READER macros as follows:
-// Blip_Reader r; r.begin( buf ); -> BLIP_READER_BEGIN( r, buf );
-// int bass = r.begin( buf ) -> BLIP_READER_BEGIN( r, buf ); int bass = BLIP_READER_BASS( buf );
-// r.read() -> BLIP_READER_READ( r )
-// r.read_raw() -> BLIP_READER_READ_RAW( r )
-// r.next( bass ) -> BLIP_READER_NEXT( r, bass )
-// r.next() -> BLIP_READER_NEXT( r, blip_reader_default_bass )
-// r.end( buf ) -> BLIP_READER_END( r, buf )
-class Blip_Reader {
-public:
- int begin( Blip_Buffer& );
- blip_long read() const { return accum >> (blip_sample_bits - 16); }
- blip_long read_raw() const { return accum; }
- void next( int bass_shift = 9 ) { accum += *buf++ - (accum >> bass_shift); }
- void end( Blip_Buffer& b ) { b.reader_accum_ = accum; }
-
-private:
- const Blip_Buffer::buf_t_* buf;
- blip_long accum;
-};
-
-// End of public interface
-
-#include <assert.h>
-
-template<int quality,int range>
-inline void Blip_Synth<quality,range>::offset_resampled( blip_resampled_time_t time,
- int delta, Blip_Buffer* blip_buf ) const
-{
- // Fails if time is beyond end of Blip_Buffer, due to a bug in caller code or the
- // need for a longer buffer as set by set_sample_rate().
- assert( (blip_long) (time >> BLIP_BUFFER_ACCURACY) < blip_buf->buffer_size_ );
- delta *= impl.delta_factor;
- blip_long* BLIP_RESTRICT buf = blip_buf->buffer_ + (time >> BLIP_BUFFER_ACCURACY);
- int phase = (int) (time >> (BLIP_BUFFER_ACCURACY - BLIP_PHASE_BITS) & (blip_res - 1));
-
-#if BLIP_BUFFER_FAST
- blip_long left = buf [0] + delta;
-
- // Kind of crappy, but doing shift after multiply results in overflow.
- // Alternate way of delaying multiply by delta_factor results in worse
- // sub-sample resolution.
- blip_long right = (delta >> BLIP_PHASE_BITS) * phase;
- left -= right;
- right += buf [1];
-
- buf [0] = left;
- buf [1] = right;
-#else
-
- int const fwd = (blip_widest_impulse_ - quality) / 2;
- int const rev = fwd + quality - 2;
- int const mid = quality / 2 - 1;
-
- imp_t const* BLIP_RESTRICT imp = impulses + blip_res - phase;
-
- #if defined (_M_IX86) || defined (_M_IA64) || defined (__i486__) || \
- defined (__x86_64__) || defined (__ia64__) || defined (__i386__)
-
- // straight forward implementation resulted in better code on GCC for x86
-
- #define ADD_IMP( out, in ) \
- buf [out] += (blip_long) imp [blip_res * (in)] * delta
-
- #define BLIP_FWD( i ) {\
- ADD_IMP( fwd + i, i );\
- ADD_IMP( fwd + 1 + i, i + 1 );\
- }
- #define BLIP_REV( r ) {\
- ADD_IMP( rev - r, r + 1 );\
- ADD_IMP( rev + 1 - r, r );\
- }
-
- BLIP_FWD( 0 )
- if ( quality > 8 ) BLIP_FWD( 2 )
- if ( quality > 12 ) BLIP_FWD( 4 )
- {
- ADD_IMP( fwd + mid - 1, mid - 1 );
- ADD_IMP( fwd + mid , mid );
- imp = impulses + phase;
- }
- if ( quality > 12 ) BLIP_REV( 6 )
- if ( quality > 8 ) BLIP_REV( 4 )
- BLIP_REV( 2 )
-
- ADD_IMP( rev , 1 );
- ADD_IMP( rev + 1, 0 );
-
- #else
-
- // for RISC processors, help compiler by reading ahead of writes
-
- #define BLIP_FWD( i ) {\
- blip_long t0 = i0 * delta + buf [fwd + i];\
- blip_long t1 = imp [blip_res * (i + 1)] * delta + buf [fwd + 1 + i];\
- i0 = imp [blip_res * (i + 2)];\
- buf [fwd + i] = t0;\
- buf [fwd + 1 + i] = t1;\
- }
- #define BLIP_REV( r ) {\
- blip_long t0 = i0 * delta + buf [rev - r];\
- blip_long t1 = imp [blip_res * r] * delta + buf [rev + 1 - r];\
- i0 = imp [blip_res * (r - 1)];\
- buf [rev - r] = t0;\
- buf [rev + 1 - r] = t1;\
- }
-
- blip_long i0 = *imp;
- BLIP_FWD( 0 )
- if ( quality > 8 ) BLIP_FWD( 2 )
- if ( quality > 12 ) BLIP_FWD( 4 )
- {
- blip_long t0 = i0 * delta + buf [fwd + mid - 1];
- blip_long t1 = imp [blip_res * mid] * delta + buf [fwd + mid ];
- imp = impulses + phase;
- i0 = imp [blip_res * mid];
- buf [fwd + mid - 1] = t0;
- buf [fwd + mid ] = t1;
- }
- if ( quality > 12 ) BLIP_REV( 6 )
- if ( quality > 8 ) BLIP_REV( 4 )
- BLIP_REV( 2 )
-
- blip_long t0 = i0 * delta + buf [rev ];
- blip_long t1 = *imp * delta + buf [rev + 1];
- buf [rev ] = t0;
- buf [rev + 1] = t1;
- #endif
-
-#endif
-}
-
-#undef BLIP_FWD
-#undef BLIP_REV
-
-template<int quality,int range>
-#if BLIP_BUFFER_FAST
- inline
-#endif
-void Blip_Synth<quality,range>::offset( blip_time_t t, int delta, Blip_Buffer* buf ) const
-{
- offset_resampled( t * buf->factor_ + buf->offset_, delta, buf );
-}
-
-template<int quality,int range>
-#if BLIP_BUFFER_FAST
- inline
-#endif
-void Blip_Synth<quality,range>::update( blip_time_t t, int amp )
-{
- int delta = amp - impl.last_amp;
- impl.last_amp = amp;
- offset_resampled( t * impl.buf->factor_ + impl.buf->offset_, delta, impl.buf );
-}
-
-inline blip_eq_t::blip_eq_t( double t ) :
- treble( t ), rolloff_freq( 0 ), sample_rate( 44100 ), cutoff_freq( 0 ) { }
-inline blip_eq_t::blip_eq_t( double t, long rf, long sr, long cf ) :
- treble( t ), rolloff_freq( rf ), sample_rate( sr ), cutoff_freq( cf ) { }
-
-inline int Blip_Buffer::length() const { return length_; }
-inline long Blip_Buffer::samples_avail() const { return (long) (offset_ >> BLIP_BUFFER_ACCURACY); }
-inline long Blip_Buffer::sample_rate() const { return sample_rate_; }
-inline int Blip_Buffer::output_latency() const { return blip_widest_impulse_ / 2; }
-inline long Blip_Buffer::clock_rate() const { return clock_rate_; }
-inline void Blip_Buffer::clock_rate( long cps ) { factor_ = clock_rate_factor( clock_rate_ = cps ); }
-
-inline int Blip_Reader::begin( Blip_Buffer& blip_buf )
-{
- buf = blip_buf.buffer_;
- accum = blip_buf.reader_accum_;
- return blip_buf.bass_shift_;
-}
-
-int const blip_max_length = 0;
-int const blip_default_length = 250;
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Classic_Emu.cpp b/plugins/gme/game-music-emu-0.5.5/gme/Classic_Emu.cpp
deleted file mode 100644
index 9b68a445..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Classic_Emu.cpp
+++ /dev/null
@@ -1,184 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Classic_Emu.h"
-
-#include "Multi_Buffer.h"
-#include <string.h>
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-Classic_Emu::Classic_Emu()
-{
- buf = 0;
- stereo_buffer = 0;
- voice_types = 0;
-
- // avoid inconsistency in our duplicated constants
- assert( (int) wave_type == (int) Multi_Buffer::wave_type );
- assert( (int) noise_type == (int) Multi_Buffer::noise_type );
- assert( (int) mixed_type == (int) Multi_Buffer::mixed_type );
-}
-
-Classic_Emu::~Classic_Emu()
-{
- delete stereo_buffer;
-}
-
-void Classic_Emu::set_equalizer_( equalizer_t const& eq )
-{
- Music_Emu::set_equalizer_( eq );
- update_eq( eq.treble );
- if ( buf )
- buf->bass_freq( (int) equalizer().bass );
-}
-
-blargg_err_t Classic_Emu::set_sample_rate_( long rate )
-{
- if ( !buf )
- {
- if ( !stereo_buffer )
- CHECK_ALLOC( stereo_buffer = BLARGG_NEW Stereo_Buffer );
- buf = stereo_buffer;
- }
- return buf->set_sample_rate( rate, 1000 / 20 );
-}
-
-void Classic_Emu::mute_voices_( int mask )
-{
- Music_Emu::mute_voices_( mask );
- for ( int i = voice_count(); i--; )
- {
- if ( mask & (1 << i) )
- {
- set_voice( i, 0, 0, 0 );
- }
- else
- {
- Multi_Buffer::channel_t ch = buf->channel( i, (voice_types ? voice_types [i] : 0) );
- assert( (ch.center && ch.left && ch.right) ||
- (!ch.center && !ch.left && !ch.right) ); // all or nothing
- set_voice( i, ch.center, ch.left, ch.right );
- }
- }
-}
-
-void Classic_Emu::change_clock_rate( long rate )
-{
- clock_rate_ = rate;
- buf->clock_rate( rate );
-}
-
-blargg_err_t Classic_Emu::setup_buffer( long rate )
-{
- change_clock_rate( rate );
- RETURN_ERR( buf->set_channel_count( voice_count() ) );
- set_equalizer( equalizer() );
- buf_changed_count = buf->channels_changed_count();
- return 0;
-}
-
-blargg_err_t Classic_Emu::start_track_( int track )
-{
- RETURN_ERR( Music_Emu::start_track_( track ) );
- buf->clear();
- return 0;
-}
-
-blargg_err_t Classic_Emu::play_( long count, sample_t* out )
-{
- long remain = count;
- while ( remain )
- {
- remain -= buf->read_samples( &out [count - remain], remain );
- if ( remain )
- {
- if ( buf_changed_count != buf->channels_changed_count() )
- {
- buf_changed_count = buf->channels_changed_count();
- remute_voices();
- }
- int msec = buf->length();
- blip_time_t clocks_emulated = (blargg_long) msec * clock_rate_ / 1000;
- RETURN_ERR( run_clocks( clocks_emulated, msec ) );
- assert( clocks_emulated );
- buf->end_frame( clocks_emulated );
- }
- }
- return 0;
-}
-
-// Rom_Data
-
-blargg_err_t Rom_Data_::load_rom_data_( Data_Reader& in,
- int header_size, void* header_out, int fill, long pad_size )
-{
- long file_offset = pad_size - header_size;
-
- rom_addr = 0;
- mask = 0;
- size_ = 0;
- rom.clear();
-
- file_size_ = in.remain();
- if ( file_size_ <= header_size ) // <= because there must be data after header
- return gme_wrong_file_type;
- blargg_err_t err = rom.resize( file_offset + file_size_ + pad_size );
- if ( !err )
- err = in.read( rom.begin() + file_offset, file_size_ );
- if ( err )
- {
- rom.clear();
- return err;
- }
-
- file_size_ -= header_size;
- memcpy( header_out, &rom [file_offset], header_size );
-
- memset( rom.begin() , fill, pad_size );
- memset( rom.end() - pad_size, fill, pad_size );
-
- return 0;
-}
-
-void Rom_Data_::set_addr_( long addr, int unit )
-{
- rom_addr = addr - unit - pad_extra;
-
- long rounded = (addr + file_size_ + unit - 1) / unit * unit;
- if ( rounded <= 0 )
- {
- rounded = 0;
- }
- else
- {
- int shift = 0;
- unsigned long max_addr = (unsigned long) (rounded - 1);
- while ( max_addr >> shift )
- shift++;
- mask = (1L << shift) - 1;
- }
-
- if ( addr < 0 )
- addr = 0;
- size_ = rounded;
- if ( rom.resize( rounded - rom_addr + pad_extra ) ) { } // OK if shrink fails
-
- if ( 0 )
- {
- debug_printf( "addr: %X\n", addr );
- debug_printf( "file_size: %d\n", file_size_ );
- debug_printf( "rounded: %d\n", rounded );
- debug_printf( "mask: $%X\n", mask );
- }
-}
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Classic_Emu.h b/plugins/gme/game-music-emu-0.5.5/gme/Classic_Emu.h
deleted file mode 100644
index d0cfda25..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Classic_Emu.h
+++ /dev/null
@@ -1,127 +0,0 @@
-// Common aspects of emulators which use Blip_Buffer for sound output
-
-// Game_Music_Emu 0.5.5
-#ifndef CLASSIC_EMU_H
-#define CLASSIC_EMU_H
-
-#include "blargg_common.h"
-#include "Blip_Buffer.h"
-#include "Music_Emu.h"
-
-class Classic_Emu : public Music_Emu {
-public:
- Classic_Emu();
- ~Classic_Emu();
- void set_buffer( Multi_Buffer* );
-protected:
- // Services
- enum { wave_type = 0x100, noise_type = 0x200, mixed_type = wave_type | noise_type };
- void set_voice_types( int const* t ) { voice_types = t; }
- blargg_err_t setup_buffer( long clock_rate );
- long clock_rate() const { return clock_rate_; }
- void change_clock_rate( long ); // experimental
-
- // Overridable
- virtual void set_voice( int index, Blip_Buffer* center,
- Blip_Buffer* left, Blip_Buffer* right ) = 0;
- virtual void update_eq( blip_eq_t const& ) = 0;
- virtual blargg_err_t start_track_( int track ) = 0;
- virtual blargg_err_t run_clocks( blip_time_t& time_io, int msec ) = 0;
-protected:
- blargg_err_t set_sample_rate_( long sample_rate );
- void mute_voices_( int );
- void set_equalizer_( equalizer_t const& );
- blargg_err_t play_( long, sample_t* );
-private:
- Multi_Buffer* buf;
- Multi_Buffer* stereo_buffer; // NULL if using custom buffer
- long clock_rate_;
- unsigned buf_changed_count;
- int const* voice_types;
-};
-
-inline void Classic_Emu::set_buffer( Multi_Buffer* new_buf )
-{
- assert( !buf && new_buf );
- buf = new_buf;
-}
-
-// ROM data handler, used by several Classic_Emu derivitives. Loads file data
-// with padding on both sides, allowing direct use in bank mapping. The main purpose
-// is to allow all file data to be loaded with only one read() call (for efficiency).
-
-class Rom_Data_ {
-public:
- typedef unsigned char byte;
-protected:
- enum { pad_extra = 8 };
- blargg_vector<byte> rom;
- long file_size_;
- blargg_long rom_addr;
- blargg_long mask;
- blargg_long size_; // TODO: eliminate
-
- blargg_err_t load_rom_data_( Data_Reader& in, int header_size, void* header_out,
- int fill, long pad_size );
- void set_addr_( long addr, int unit );
-};
-
-template<int unit>
-class Rom_Data : public Rom_Data_ {
- enum { pad_size = unit + pad_extra };
-public:
- // Load file data, using already-loaded header 'h' if not NULL. Copy header
- // from loaded file data into *out and fill unmapped bytes with 'fill'.
- blargg_err_t load( Data_Reader& in, int header_size, void* header_out, int fill )
- {
- return load_rom_data_( in, header_size, header_out, fill, pad_size );
- }
-
- // Size of file data read in (excluding header)
- long file_size() const { return file_size_; }
-
- // Pointer to beginning of file data
- byte* begin() const { return rom.begin() + pad_size; }
-
- // Set address that file data should start at
- void set_addr( long addr ) { set_addr_( addr, unit ); }
-
- // Free data
- void clear() { rom.clear(); }
-
- // Size of data + start addr, rounded to a multiple of unit
- long size() const { return size_; }
-
- // Pointer to unmapped page filled with same value
- byte* unmapped() { return rom.begin(); }
-
- // Mask address to nearest power of two greater than size()
- blargg_long mask_addr( blargg_long addr ) const
- {
- #ifdef check
- check( addr <= mask );
- #endif
- return addr & mask;
- }
-
- // Pointer to page starting at addr. Returns unmapped() if outside data.
- byte* at_addr( blargg_long addr )
- {
- blargg_ulong offset = mask_addr( addr ) - rom_addr;
- if ( offset > blargg_ulong (rom.size() - pad_size) )
- offset = 0; // unmapped
- return &rom [offset];
- }
-};
-
-#ifndef GME_APU_HOOK
- #define GME_APU_HOOK( emu, addr, data ) ((void) 0)
-#endif
-
-#ifndef GME_FRAME_HOOK
- #define GME_FRAME_HOOK( emu ) ((void) 0)
-#else
- #define GME_FRAME_HOOK_DEFINED 1
-#endif
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Data_Reader.cpp b/plugins/gme/game-music-emu-0.5.5/gme/Data_Reader.cpp
deleted file mode 100644
index 5bbfbf55..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Data_Reader.cpp
+++ /dev/null
@@ -1,315 +0,0 @@
-// File_Extractor 0.4.0. http://www.slack.net/~ant/
-
-#include "Data_Reader.h"
-
-#include "blargg_endian.h"
-#include <assert.h>
-#include <string.h>
-#include <stdio.h>
-
-/* Copyright (C) 2005-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-const char Data_Reader::eof_error [] = "Unexpected end of file";
-
-blargg_err_t Data_Reader::read( void* p, long s )
-{
- long result = read_avail( p, s );
- if ( result != s )
- {
- if ( result >= 0 && result < s )
- return eof_error;
-
- return "Read error";
- }
-
- return 0;
-}
-
-blargg_err_t Data_Reader::skip( long count )
-{
- char buf [512];
- while ( count )
- {
- long n = sizeof buf;
- if ( n > count )
- n = count;
- count -= n;
- RETURN_ERR( read( buf, n ) );
- }
- return 0;
-}
-
-long File_Reader::remain() const { return size() - tell(); }
-
-blargg_err_t File_Reader::skip( long n )
-{
- assert( n >= 0 );
- if ( !n )
- return 0;
- return seek( tell() + n );
-}
-
-// Subset_Reader
-
-Subset_Reader::Subset_Reader( Data_Reader* dr, long size )
-{
- in = dr;
- remain_ = dr->remain();
- if ( remain_ > size )
- remain_ = size;
-}
-
-long Subset_Reader::remain() const { return remain_; }
-
-long Subset_Reader::read_avail( void* p, long s )
-{
- if ( s > remain_ )
- s = remain_;
- remain_ -= s;
- return in->read_avail( p, s );
-}
-
-// Remaining_Reader
-
-Remaining_Reader::Remaining_Reader( void const* h, long size, Data_Reader* r )
-{
- header = (char const*) h;
- header_end = header + size;
- in = r;
-}
-
-long Remaining_Reader::remain() const { return header_end - header + in->remain(); }
-
-long Remaining_Reader::read_first( void* out, long count )
-{
- long first = header_end - header;
- if ( first )
- {
- if ( first > count )
- first = count;
- void const* old = header;
- header += first;
- memcpy( out, old, first );
- }
- return first;
-}
-
-long Remaining_Reader::read_avail( void* out, long count )
-{
- long first = read_first( out, count );
- long second = count - first;
- if ( second )
- {
- second = in->read_avail( (char*) out + first, second );
- if ( second <= 0 )
- return second;
- }
- return first + second;
-}
-
-blargg_err_t Remaining_Reader::read( void* out, long count )
-{
- long first = read_first( out, count );
- long second = count - first;
- if ( !second )
- return 0;
- return in->read( (char*) out + first, second );
-}
-
-// Mem_File_Reader
-
-Mem_File_Reader::Mem_File_Reader( const void* p, long s ) :
- begin( (const char*) p ),
- size_( s )
-{
- pos = 0;
-}
-
-long Mem_File_Reader::size() const { return size_; }
-
-long Mem_File_Reader::read_avail( void* p, long s )
-{
- long r = remain();
- if ( s > r )
- s = r;
- memcpy( p, begin + pos, s );
- pos += s;
- return s;
-}
-
-long Mem_File_Reader::tell() const { return pos; }
-
-blargg_err_t Mem_File_Reader::seek( long n )
-{
- if ( n > size_ )
- return eof_error;
- pos = n;
- return 0;
-}
-
-// Callback_Reader
-
-Callback_Reader::Callback_Reader( callback_t c, long size, void* d ) :
- callback( c ),
- data( d )
-{
- remain_ = size;
-}
-
-long Callback_Reader::remain() const { return remain_; }
-
-long Callback_Reader::read_avail( void* out, long count )
-{
- if ( count > remain_ )
- count = remain_;
- if ( Callback_Reader::read( out, count ) )
- count = -1;
- return count;
-}
-
-blargg_err_t Callback_Reader::read( void* out, long count )
-{
- if ( count > remain_ )
- return eof_error;
- return callback( data, out, count );
-}
-
-// Std_File_Reader
-
-Std_File_Reader::Std_File_Reader() : file_( 0 ) { }
-
-Std_File_Reader::~Std_File_Reader() { close(); }
-
-blargg_err_t Std_File_Reader::open( const char* path )
-{
- file_ = fopen( path, "rb" );
- if ( !file_ )
- return "Couldn't open file";
- return 0;
-}
-
-long Std_File_Reader::size() const
-{
- long pos = tell();
- fseek( (FILE*) file_, 0, SEEK_END );
- long result = tell();
- fseek( (FILE*) file_, pos, SEEK_SET );
- return result;
-}
-
-long Std_File_Reader::read_avail( void* p, long s )
-{
- return fread( p, 1, s, (FILE*) file_ );
-}
-
-blargg_err_t Std_File_Reader::read( void* p, long s )
-{
- if ( s == (long) fread( p, 1, s, (FILE*) file_ ) )
- return 0;
- if ( feof( (FILE*) file_ ) )
- return eof_error;
- return "Couldn't read from file";
-}
-
-long Std_File_Reader::tell() const { return ftell( (FILE*) file_ ); }
-
-blargg_err_t Std_File_Reader::seek( long n )
-{
- if ( !fseek( (FILE*) file_, n, SEEK_SET ) )
- return 0;
- if ( n > size() )
- return eof_error;
- return "Error seeking in file";
-}
-
-void Std_File_Reader::close()
-{
- if ( file_ )
- {
- fclose( (FILE*) file_ );
- file_ = 0;
- }
-}
-
-// Gzip_File_Reader
-
-#ifdef HAVE_ZLIB_H
-
-#include "zlib.h"
-
-static const char* get_gzip_eof( const char* path, long* eof )
-{
- FILE* file = fopen( path, "rb" );
- if ( !file )
- return "Couldn't open file";
-
- unsigned char buf [4];
- if ( fread( buf, 2, 1, file ) > 0 && buf [0] == 0x1F && buf [1] == 0x8B )
- {
- fseek( file, -4, SEEK_END );
- fread( buf, 4, 1, file );
- *eof = get_le32( buf );
- }
- else
- {
- fseek( file, 0, SEEK_END );
- *eof = ftell( file );
- }
- const char* err = (ferror( file ) || feof( file )) ? "Couldn't get file size" : 0;
- fclose( file );
- return err;
-}
-
-Gzip_File_Reader::Gzip_File_Reader() : file_( 0 ) { }
-
-Gzip_File_Reader::~Gzip_File_Reader() { close(); }
-
-blargg_err_t Gzip_File_Reader::open( const char* path )
-{
- close();
-
- RETURN_ERR( get_gzip_eof( path, &size_ ) );
-
- file_ = gzopen( path, "rb" );
- if ( !file_ )
- return "Couldn't open file";
-
- return 0;
-}
-
-long Gzip_File_Reader::size() const { return size_; }
-
-long Gzip_File_Reader::read_avail( void* p, long s ) { return gzread( file_, p, s ); }
-
-long Gzip_File_Reader::tell() const { return gztell( file_ ); }
-
-blargg_err_t Gzip_File_Reader::seek( long n )
-{
- if ( gzseek( file_, n, SEEK_SET ) >= 0 )
- return 0;
- if ( n > size_ )
- return eof_error;
- return "Error seeking in file";
-}
-
-void Gzip_File_Reader::close()
-{
- if ( file_ )
- {
- gzclose( file_ );
- file_ = 0;
- }
-}
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Data_Reader.h b/plugins/gme/game-music-emu-0.5.5/gme/Data_Reader.h
deleted file mode 100644
index acf571f6..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Data_Reader.h
+++ /dev/null
@@ -1,151 +0,0 @@
-// Data reader interface for uniform access
-
-// File_Extractor 0.4.0
-#ifndef DATA_READER_H
-#define DATA_READER_H
-
-#include "blargg_common.h"
-
-// Supports reading and finding out how many bytes are remaining
-class Data_Reader {
-public:
- virtual ~Data_Reader() { }
-
- static const char eof_error []; // returned by read() when request goes beyond end
-
- // Read at most count bytes and return number actually read, or <= 0 if error
- virtual long read_avail( void*, long n ) = 0;
-
- // Read exactly count bytes and return error if they couldn't be read
- virtual blargg_err_t read( void*, long count );
-
- // Number of bytes remaining until end of file
- virtual long remain() const = 0;
-
- // Read and discard count bytes
- virtual blargg_err_t skip( long count );
-
-public:
- Data_Reader() { }
- typedef blargg_err_t error_t; // deprecated
-private:
- // noncopyable
- Data_Reader( const Data_Reader& );
- Data_Reader& operator = ( const Data_Reader& );
-};
-
-// Supports seeking in addition to Data_Reader operations
-class File_Reader : public Data_Reader {
-public:
- // Size of file
- virtual long size() const = 0;
-
- // Current position in file
- virtual long tell() const = 0;
-
- // Go to new position
- virtual blargg_err_t seek( long ) = 0;
-
- long remain() const;
- blargg_err_t skip( long n );
-};
-
-// Disk file reader
-class Std_File_Reader : public File_Reader {
-public:
- blargg_err_t open( const char* path );
- void close();
-
-public:
- Std_File_Reader();
- ~Std_File_Reader();
- long size() const;
- blargg_err_t read( void*, long );
- long read_avail( void*, long );
- long tell() const;
- blargg_err_t seek( long );
-private:
- void* file_;
-};
-
-// Treats range of memory as a file
-class Mem_File_Reader : public File_Reader {
-public:
- Mem_File_Reader( const void*, long size );
-
-public:
- long size() const;
- long read_avail( void*, long );
- long tell() const;
- blargg_err_t seek( long );
-private:
- const char* const begin;
- const long size_;
- long pos;
-};
-
-// Makes it look like there are only count bytes remaining
-class Subset_Reader : public Data_Reader {
-public:
- Subset_Reader( Data_Reader*, long count );
-
-public:
- long remain() const;
- long read_avail( void*, long );
-private:
- Data_Reader* in;
- long remain_;
-};
-
-// Joins already-read header and remaining data into original file (to avoid seeking)
-class Remaining_Reader : public Data_Reader {
-public:
- Remaining_Reader( void const* header, long size, Data_Reader* );
-
-public:
- long remain() const;
- long read_avail( void*, long );
- blargg_err_t read( void*, long );
-private:
- char const* header;
- char const* header_end;
- Data_Reader* in;
- long read_first( void* out, long count );
-};
-
-// Invokes callback function to read data. Size of data must be specified in advance.
-class Callback_Reader : public Data_Reader {
-public:
- typedef const char* (*callback_t)( void* data, void* out, int count );
- Callback_Reader( callback_t, long size, void* data = 0 );
-public:
- long read_avail( void*, long );
- blargg_err_t read( void*, long );
- long remain() const;
-private:
- callback_t const callback;
- void* const data;
- long remain_;
-};
-
-#ifdef HAVE_ZLIB_H
-// Gzip compressed file reader
-class Gzip_File_Reader : public File_Reader {
-public:
- blargg_err_t open( const char* path );
- void close();
-
-public:
- Gzip_File_Reader();
- ~Gzip_File_Reader();
- long size() const;
- long read_avail( void*, long );
- long tell() const;
- blargg_err_t seek( long );
-private:
- void* file_;
- long size_;
-};
-#endif
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Dual_Resampler.cpp b/plugins/gme/game-music-emu-0.5.5/gme/Dual_Resampler.cpp
deleted file mode 100644
index 91b48472..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Dual_Resampler.cpp
+++ /dev/null
@@ -1,133 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Dual_Resampler.h"
-
-#include <stdlib.h>
-#include <string.h>
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-unsigned const resampler_extra = 256;
-
-Dual_Resampler::Dual_Resampler() {
- sample_buf_size = 0;
-}
-
-Dual_Resampler::~Dual_Resampler() { }
-
-blargg_err_t Dual_Resampler::reset( int pairs )
-{
- // expand allocations a bit
- RETURN_ERR( sample_buf.resize( (pairs + (pairs >> 2)) * 2 ) );
- resize( pairs );
- resampler_size = oversamples_per_frame + (oversamples_per_frame >> 2);
- return resampler.buffer_size( resampler_size );
-}
-
-void Dual_Resampler::resize( int pairs )
-{
- int new_sample_buf_size = pairs * 2;
- if ( sample_buf_size != new_sample_buf_size )
- {
- if ( (unsigned) new_sample_buf_size > sample_buf.size() )
- {
- check( false );
- return;
- }
- sample_buf_size = new_sample_buf_size;
- oversamples_per_frame = int (pairs * resampler.ratio()) * 2 + 2;
- clear();
- }
-}
-
-void Dual_Resampler::play_frame_( Blip_Buffer& blip_buf, dsample_t* out )
-{
- long pair_count = sample_buf_size >> 1;
- blip_time_t blip_time = blip_buf.count_clocks( pair_count );
- int sample_count = oversamples_per_frame - resampler.written();
-
- int new_count = play_frame( blip_time, sample_count, resampler.buffer() );
- assert( new_count < resampler_size );
-
- blip_buf.end_frame( blip_time );
- assert( blip_buf.samples_avail() == pair_count );
-
- resampler.write( new_count );
-
- long count = resampler.read( sample_buf.begin(), sample_buf_size );
- assert( count == (long) sample_buf_size );
-
- mix_samples( blip_buf, out );
- blip_buf.remove_samples( pair_count );
-}
-
-void Dual_Resampler::dual_play( long count, dsample_t* out, Blip_Buffer& blip_buf )
-{
- // empty extra buffer
- long remain = sample_buf_size - buf_pos;
- if ( remain )
- {
- if ( remain > count )
- remain = count;
- count -= remain;
- memcpy( out, &sample_buf [buf_pos], remain * sizeof *out );
- out += remain;
- buf_pos += remain;
- }
-
- // entire frames
- while ( count >= (long) sample_buf_size )
- {
- play_frame_( blip_buf, out );
- out += sample_buf_size;
- count -= sample_buf_size;
- }
-
- // extra
- if ( count )
- {
- play_frame_( blip_buf, sample_buf.begin() );
- buf_pos = count;
- memcpy( out, sample_buf.begin(), count * sizeof *out );
- out += count;
- }
-}
-
-void Dual_Resampler::mix_samples( Blip_Buffer& blip_buf, dsample_t* out )
-{
- Blip_Reader sn;
- int bass = sn.begin( blip_buf );
- const dsample_t* in = sample_buf.begin();
-
- for ( int n = sample_buf_size >> 1; n--; )
- {
- int s = sn.read();
- blargg_long l = (blargg_long) in [0] * 2 + s;
- if ( (BOOST::int16_t) l != l )
- l = 0x7FFF - (l >> 24);
-
- sn.next( bass );
- blargg_long r = (blargg_long) in [1] * 2 + s;
- if ( (BOOST::int16_t) r != r )
- r = 0x7FFF - (r >> 24);
-
- in += 2;
- out [0] = l;
- out [1] = r;
- out += 2;
- }
-
- sn.end( blip_buf );
-}
-
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Dual_Resampler.h b/plugins/gme/game-music-emu-0.5.5/gme/Dual_Resampler.h
deleted file mode 100644
index e3194fe7..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Dual_Resampler.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Combination of Fir_Resampler and Blip_Buffer mixing. Used by Sega FM emulators.
-
-// Game_Music_Emu 0.5.5
-#ifndef DUAL_RESAMPLER_H
-#define DUAL_RESAMPLER_H
-
-#include "Fir_Resampler.h"
-#include "Blip_Buffer.h"
-
-class Dual_Resampler {
-public:
- Dual_Resampler();
- virtual ~Dual_Resampler();
-
- typedef short dsample_t;
-
- double setup( double oversample, double rolloff, double gain );
- blargg_err_t reset( int max_pairs );
- void resize( int pairs_per_frame );
- void clear();
-
- void dual_play( long count, dsample_t* out, Blip_Buffer& );
-
-protected:
- virtual int play_frame( blip_time_t, int pcm_count, dsample_t* pcm_out ) = 0;
-private:
-
- blargg_vector<dsample_t> sample_buf;
- int sample_buf_size;
- int oversamples_per_frame;
- int buf_pos;
- int resampler_size;
-
- Fir_Resampler<12> resampler;
- void mix_samples( Blip_Buffer&, dsample_t* );
- void play_frame_( Blip_Buffer&, dsample_t* );
-};
-
-inline double Dual_Resampler::setup( double oversample, double rolloff, double gain )
-{
- return resampler.time_ratio( oversample, rolloff, gain * 0.5 );
-}
-
-inline void Dual_Resampler::clear()
-{
- buf_pos = sample_buf_size;
- resampler.clear();
-}
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Effects_Buffer.cpp b/plugins/gme/game-music-emu-0.5.5/gme/Effects_Buffer.cpp
deleted file mode 100644
index 181b11e9..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Effects_Buffer.cpp
+++ /dev/null
@@ -1,529 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Effects_Buffer.h"
-
-#include <string.h>
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-#ifdef BLARGG_ENABLE_OPTIMIZER
- #include BLARGG_ENABLE_OPTIMIZER
-#endif
-
-typedef blargg_long fixed_t;
-
-#define TO_FIXED( f ) fixed_t ((f) * (1L << 15) + 0.5)
-#define FMUL( x, y ) (((x) * (y)) >> 15)
-
-const unsigned echo_size = 4096;
-const unsigned echo_mask = echo_size - 1;
-BOOST_STATIC_ASSERT( (echo_size & echo_mask) == 0 ); // must be power of 2
-
-const unsigned reverb_size = 8192 * 2;
-const unsigned reverb_mask = reverb_size - 1;
-BOOST_STATIC_ASSERT( (reverb_size & reverb_mask) == 0 ); // must be power of 2
-
-Effects_Buffer::config_t::config_t()
-{
- pan_1 = -0.15f;
- pan_2 = 0.15f;
- reverb_delay = 88.0f;
- reverb_level = 0.12f;
- echo_delay = 61.0f;
- echo_level = 0.10f;
- delay_variance = 18.0f;
- effects_enabled = false;
-}
-
-void Effects_Buffer::set_depth( double d )
-{
- float f = (float) d;
- config_t c;
- c.pan_1 = -0.6f * f;
- c.pan_2 = 0.6f * f;
- c.reverb_delay = 880 * 0.1f;
- c.echo_delay = 610 * 0.1f;
- if ( f > 0.5 )
- f = 0.5; // TODO: more linear reduction of extreme reverb/echo
- c.reverb_level = 0.5f * f;
- c.echo_level = 0.30f * f;
- c.delay_variance = 180 * 0.1f;
- c.effects_enabled = (d > 0.0f);
- config( c );
-}
-
-Effects_Buffer::Effects_Buffer( bool center_only ) : Multi_Buffer( 2 )
-{
- buf_count = center_only ? max_buf_count - 4 : max_buf_count;
-
- echo_pos = 0;
- reverb_pos = 0;
-
- stereo_remain = 0;
- effect_remain = 0;
- effects_enabled = false;
- set_depth( 0 );
-}
-
-Effects_Buffer::~Effects_Buffer() { }
-
-blargg_err_t Effects_Buffer::set_sample_rate( long rate, int msec )
-{
- if ( !echo_buf.size() )
- RETURN_ERR( echo_buf.resize( echo_size ) );
-
- if ( !reverb_buf.size() )
- RETURN_ERR( reverb_buf.resize( reverb_size ) );
-
- for ( int i = 0; i < buf_count; i++ )
- RETURN_ERR( bufs [i].set_sample_rate( rate, msec ) );
-
- config( config_ );
- clear();
-
- return Multi_Buffer::set_sample_rate( bufs [0].sample_rate(), bufs [0].length() );
-}
-
-void Effects_Buffer::clock_rate( long rate )
-{
- for ( int i = 0; i < buf_count; i++ )
- bufs [i].clock_rate( rate );
-}
-
-void Effects_Buffer::bass_freq( int freq )
-{
- for ( int i = 0; i < buf_count; i++ )
- bufs [i].bass_freq( freq );
-}
-
-void Effects_Buffer::clear()
-{
- stereo_remain = 0;
- effect_remain = 0;
- if ( echo_buf.size() )
- memset( &echo_buf [0], 0, echo_size * sizeof echo_buf [0] );
-
- if ( reverb_buf.size() )
- memset( &reverb_buf [0], 0, reverb_size * sizeof reverb_buf [0] );
-
- for ( int i = 0; i < buf_count; i++ )
- bufs [i].clear();
-}
-
-inline int pin_range( int n, int max, int min = 0 )
-{
- if ( n < min )
- return min;
- if ( n > max )
- return max;
- return n;
-}
-
-void Effects_Buffer::config( const config_t& cfg )
-{
- channels_changed();
-
- // clear echo and reverb buffers
- if ( !config_.effects_enabled && cfg.effects_enabled && echo_buf.size() )
- {
- memset( &echo_buf [0], 0, echo_size * sizeof echo_buf [0] );
- memset( &reverb_buf [0], 0, reverb_size * sizeof reverb_buf [0] );
- }
-
- config_ = cfg;
-
- if ( config_.effects_enabled )
- {
- // convert to internal format
-
- chans.pan_1_levels [0] = TO_FIXED( 1 ) - TO_FIXED( config_.pan_1 );
- chans.pan_1_levels [1] = TO_FIXED( 2 ) - chans.pan_1_levels [0];
-
- chans.pan_2_levels [0] = TO_FIXED( 1 ) - TO_FIXED( config_.pan_2 );
- chans.pan_2_levels [1] = TO_FIXED( 2 ) - chans.pan_2_levels [0];
-
- chans.reverb_level = TO_FIXED( config_.reverb_level );
- chans.echo_level = TO_FIXED( config_.echo_level );
-
- int delay_offset = int (1.0 / 2000 * config_.delay_variance * sample_rate());
-
- int reverb_sample_delay = int (1.0 / 1000 * config_.reverb_delay * sample_rate());
- chans.reverb_delay_l = pin_range( reverb_size -
- (reverb_sample_delay - delay_offset) * 2, reverb_size - 2, 0 );
- chans.reverb_delay_r = pin_range( reverb_size + 1 -
- (reverb_sample_delay + delay_offset) * 2, reverb_size - 1, 1 );
-
- int echo_sample_delay = int (1.0 / 1000 * config_.echo_delay * sample_rate());
- chans.echo_delay_l = pin_range( echo_size - 1 - (echo_sample_delay - delay_offset),
- echo_size - 1 );
- chans.echo_delay_r = pin_range( echo_size - 1 - (echo_sample_delay + delay_offset),
- echo_size - 1 );
-
- chan_types [0].center = &bufs [0];
- chan_types [0].left = &bufs [3];
- chan_types [0].right = &bufs [4];
-
- chan_types [1].center = &bufs [1];
- chan_types [1].left = &bufs [3];
- chan_types [1].right = &bufs [4];
-
- chan_types [2].center = &bufs [2];
- chan_types [2].left = &bufs [5];
- chan_types [2].right = &bufs [6];
- assert( 2 < chan_types_count );
- }
- else
- {
- // set up outputs
- for ( unsigned i = 0; i < chan_types_count; i++ )
- {
- channel_t& c = chan_types [i];
- c.center = &bufs [0];
- c.left = &bufs [1];
- c.right = &bufs [2];
- }
- }
-
- if ( buf_count < max_buf_count )
- {
- for ( int i = 0; i < chan_types_count; i++ )
- {
- channel_t& c = chan_types [i];
- c.left = c.center;
- c.right = c.center;
- }
- }
-}
-
-Effects_Buffer::channel_t Effects_Buffer::channel( int i, int type )
-{
- int out = 2;
- if ( !type )
- {
- out = i % 5;
- if ( out > 2 )
- out = 2;
- }
- else if ( !(type & noise_type) && (type & type_index_mask) % 3 != 0 )
- {
- out = type & 1;
- }
- return chan_types [out];
-}
-
-void Effects_Buffer::end_frame( blip_time_t clock_count )
-{
- int bufs_used = 0;
- for ( int i = 0; i < buf_count; i++ )
- {
- bufs_used |= bufs [i].clear_modified() << i;
- bufs [i].end_frame( clock_count );
- }
-
- int stereo_mask = (config_.effects_enabled ? 0x78 : 0x06);
- if ( (bufs_used & stereo_mask) && buf_count == max_buf_count )
- stereo_remain = bufs [0].samples_avail() + bufs [0].output_latency();
-
- if ( effects_enabled || config_.effects_enabled )
- effect_remain = bufs [0].samples_avail() + bufs [0].output_latency();
-
- effects_enabled = config_.effects_enabled;
-}
-
-long Effects_Buffer::samples_avail() const
-{
- return bufs [0].samples_avail() * 2;
-}
-
-long Effects_Buffer::read_samples( blip_sample_t* out, long total_samples )
-{
- require( total_samples % 2 == 0 ); // count must be even
-
- long remain = bufs [0].samples_avail();
- if ( remain > (total_samples >> 1) )
- remain = (total_samples >> 1);
- total_samples = remain;
- while ( remain )
- {
- int active_bufs = buf_count;
- long count = remain;
-
- // optimizing mixing to skip any channels which had nothing added
- if ( effect_remain )
- {
- if ( count > effect_remain )
- count = effect_remain;
-
- if ( stereo_remain )
- {
- mix_enhanced( out, count );
- }
- else
- {
- mix_mono_enhanced( out, count );
- active_bufs = 3;
- }
- }
- else if ( stereo_remain )
- {
- mix_stereo( out, count );
- active_bufs = 3;
- }
- else
- {
- mix_mono( out, count );
- active_bufs = 1;
- }
-
- out += count * 2;
- remain -= count;
-
- stereo_remain -= count;
- if ( stereo_remain < 0 )
- stereo_remain = 0;
-
- effect_remain -= count;
- if ( effect_remain < 0 )
- effect_remain = 0;
-
- for ( int i = 0; i < buf_count; i++ )
- {
- if ( i < active_bufs )
- bufs [i].remove_samples( count );
- else
- bufs [i].remove_silence( count ); // keep time synchronized
- }
- }
-
- return total_samples * 2;
-}
-
-void Effects_Buffer::mix_mono( blip_sample_t* out_, blargg_long count )
-{
- blip_sample_t* BLIP_RESTRICT out = out_;
- int const bass = BLIP_READER_BASS( bufs [0] );
- BLIP_READER_BEGIN( c, bufs [0] );
-
- // unrolled loop
- for ( blargg_long n = count >> 1; n; --n )
- {
- blargg_long cs0 = BLIP_READER_READ( c );
- BLIP_READER_NEXT( c, bass );
-
- blargg_long cs1 = BLIP_READER_READ( c );
- BLIP_READER_NEXT( c, bass );
-
- if ( (BOOST::int16_t) cs0 != cs0 )
- cs0 = 0x7FFF - (cs0 >> 24);
- ((BOOST::uint32_t*) out) [0] = ((BOOST::uint16_t) cs0) | (cs0 << 16);
-
- if ( (BOOST::int16_t) cs1 != cs1 )
- cs1 = 0x7FFF - (cs1 >> 24);
- ((BOOST::uint32_t*) out) [1] = ((BOOST::uint16_t) cs1) | (cs1 << 16);
- out += 4;
- }
-
- if ( count & 1 )
- {
- int s = BLIP_READER_READ( c );
- BLIP_READER_NEXT( c, bass );
- out [0] = s;
- out [1] = s;
- if ( (BOOST::int16_t) s != s )
- {
- s = 0x7FFF - (s >> 24);
- out [0] = s;
- out [1] = s;
- }
- }
-
- BLIP_READER_END( c, bufs [0] );
-}
-
-void Effects_Buffer::mix_stereo( blip_sample_t* out_, blargg_long count )
-{
- blip_sample_t* BLIP_RESTRICT out = out_;
- int const bass = BLIP_READER_BASS( bufs [0] );
- BLIP_READER_BEGIN( c, bufs [0] );
- BLIP_READER_BEGIN( l, bufs [1] );
- BLIP_READER_BEGIN( r, bufs [2] );
-
- while ( count-- )
- {
- int cs = BLIP_READER_READ( c );
- BLIP_READER_NEXT( c, bass );
- int left = cs + BLIP_READER_READ( l );
- int right = cs + BLIP_READER_READ( r );
- BLIP_READER_NEXT( l, bass );
- BLIP_READER_NEXT( r, bass );
-
- if ( (BOOST::int16_t) left != left )
- left = 0x7FFF - (left >> 24);
-
- out [0] = left;
- out [1] = right;
-
- out += 2;
-
- if ( (BOOST::int16_t) right != right )
- out [-1] = 0x7FFF - (right >> 24);
- }
-
- BLIP_READER_END( r, bufs [2] );
- BLIP_READER_END( l, bufs [1] );
- BLIP_READER_END( c, bufs [0] );
-}
-
-void Effects_Buffer::mix_mono_enhanced( blip_sample_t* out_, blargg_long count )
-{
- blip_sample_t* BLIP_RESTRICT out = out_;
- int const bass = BLIP_READER_BASS( bufs [2] );
- BLIP_READER_BEGIN( center, bufs [2] );
- BLIP_READER_BEGIN( sq1, bufs [0] );
- BLIP_READER_BEGIN( sq2, bufs [1] );
-
- blip_sample_t* const reverb_buf = this->reverb_buf.begin();
- blip_sample_t* const echo_buf = this->echo_buf.begin();
- int echo_pos = this->echo_pos;
- int reverb_pos = this->reverb_pos;
-
- while ( count-- )
- {
- int sum1_s = BLIP_READER_READ( sq1 );
- int sum2_s = BLIP_READER_READ( sq2 );
-
- BLIP_READER_NEXT( sq1, bass );
- BLIP_READER_NEXT( sq2, bass );
-
- int new_reverb_l = FMUL( sum1_s, chans.pan_1_levels [0] ) +
- FMUL( sum2_s, chans.pan_2_levels [0] ) +
- reverb_buf [(reverb_pos + chans.reverb_delay_l) & reverb_mask];
-
- int new_reverb_r = FMUL( sum1_s, chans.pan_1_levels [1] ) +
- FMUL( sum2_s, chans.pan_2_levels [1] ) +
- reverb_buf [(reverb_pos + chans.reverb_delay_r) & reverb_mask];
-
- fixed_t reverb_level = chans.reverb_level;
- reverb_buf [reverb_pos] = (blip_sample_t) FMUL( new_reverb_l, reverb_level );
- reverb_buf [reverb_pos + 1] = (blip_sample_t) FMUL( new_reverb_r, reverb_level );
- reverb_pos = (reverb_pos + 2) & reverb_mask;
-
- int sum3_s = BLIP_READER_READ( center );
- BLIP_READER_NEXT( center, bass );
-
- int left = new_reverb_l + sum3_s + FMUL( chans.echo_level,
- echo_buf [(echo_pos + chans.echo_delay_l) & echo_mask] );
- int right = new_reverb_r + sum3_s + FMUL( chans.echo_level,
- echo_buf [(echo_pos + chans.echo_delay_r) & echo_mask] );
-
- echo_buf [echo_pos] = sum3_s;
- echo_pos = (echo_pos + 1) & echo_mask;
-
- if ( (BOOST::int16_t) left != left )
- left = 0x7FFF - (left >> 24);
-
- out [0] = left;
- out [1] = right;
-
- out += 2;
-
- if ( (BOOST::int16_t) right != right )
- out [-1] = 0x7FFF - (right >> 24);
- }
- this->reverb_pos = reverb_pos;
- this->echo_pos = echo_pos;
-
- BLIP_READER_END( sq1, bufs [0] );
- BLIP_READER_END( sq2, bufs [1] );
- BLIP_READER_END( center, bufs [2] );
-}
-
-void Effects_Buffer::mix_enhanced( blip_sample_t* out_, blargg_long count )
-{
- blip_sample_t* BLIP_RESTRICT out = out_;
- int const bass = BLIP_READER_BASS( bufs [2] );
- BLIP_READER_BEGIN( center, bufs [2] );
- BLIP_READER_BEGIN( l1, bufs [3] );
- BLIP_READER_BEGIN( r1, bufs [4] );
- BLIP_READER_BEGIN( l2, bufs [5] );
- BLIP_READER_BEGIN( r2, bufs [6] );
- BLIP_READER_BEGIN( sq1, bufs [0] );
- BLIP_READER_BEGIN( sq2, bufs [1] );
-
- blip_sample_t* const reverb_buf = this->reverb_buf.begin();
- blip_sample_t* const echo_buf = this->echo_buf.begin();
- int echo_pos = this->echo_pos;
- int reverb_pos = this->reverb_pos;
-
- while ( count-- )
- {
- int sum1_s = BLIP_READER_READ( sq1 );
- int sum2_s = BLIP_READER_READ( sq2 );
-
- BLIP_READER_NEXT( sq1, bass );
- BLIP_READER_NEXT( sq2, bass );
-
- int new_reverb_l = FMUL( sum1_s, chans.pan_1_levels [0] ) +
- FMUL( sum2_s, chans.pan_2_levels [0] ) + BLIP_READER_READ( l1 ) +
- reverb_buf [(reverb_pos + chans.reverb_delay_l) & reverb_mask];
-
- int new_reverb_r = FMUL( sum1_s, chans.pan_1_levels [1] ) +
- FMUL( sum2_s, chans.pan_2_levels [1] ) + BLIP_READER_READ( r1 ) +
- reverb_buf [(reverb_pos + chans.reverb_delay_r) & reverb_mask];
-
- BLIP_READER_NEXT( l1, bass );
- BLIP_READER_NEXT( r1, bass );
-
- fixed_t reverb_level = chans.reverb_level;
- reverb_buf [reverb_pos] = (blip_sample_t) FMUL( new_reverb_l, reverb_level );
- reverb_buf [reverb_pos + 1] = (blip_sample_t) FMUL( new_reverb_r, reverb_level );
- reverb_pos = (reverb_pos + 2) & reverb_mask;
-
- int sum3_s = BLIP_READER_READ( center );
- BLIP_READER_NEXT( center, bass );
-
- int left = new_reverb_l + sum3_s + BLIP_READER_READ( l2 ) + FMUL( chans.echo_level,
- echo_buf [(echo_pos + chans.echo_delay_l) & echo_mask] );
- int right = new_reverb_r + sum3_s + BLIP_READER_READ( r2 ) + FMUL( chans.echo_level,
- echo_buf [(echo_pos + chans.echo_delay_r) & echo_mask] );
-
- BLIP_READER_NEXT( l2, bass );
- BLIP_READER_NEXT( r2, bass );
-
- echo_buf [echo_pos] = sum3_s;
- echo_pos = (echo_pos + 1) & echo_mask;
-
- if ( (BOOST::int16_t) left != left )
- left = 0x7FFF - (left >> 24);
-
- out [0] = left;
- out [1] = right;
-
- out += 2;
-
- if ( (BOOST::int16_t) right != right )
- out [-1] = 0x7FFF - (right >> 24);
- }
- this->reverb_pos = reverb_pos;
- this->echo_pos = echo_pos;
-
- BLIP_READER_END( l1, bufs [3] );
- BLIP_READER_END( r1, bufs [4] );
- BLIP_READER_END( l2, bufs [5] );
- BLIP_READER_END( r2, bufs [6] );
- BLIP_READER_END( sq1, bufs [0] );
- BLIP_READER_END( sq2, bufs [1] );
- BLIP_READER_END( center, bufs [2] );
-}
-
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Effects_Buffer.h b/plugins/gme/game-music-emu-0.5.5/gme/Effects_Buffer.h
deleted file mode 100644
index 061f74ab..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Effects_Buffer.h
+++ /dev/null
@@ -1,86 +0,0 @@
-// Multi-channel effects buffer with panning, echo and reverb
-
-// Game_Music_Emu 0.5.5
-#ifndef EFFECTS_BUFFER_H
-#define EFFECTS_BUFFER_H
-
-#include "Multi_Buffer.h"
-
-// Effects_Buffer uses several buffers and outputs stereo sample pairs.
-class Effects_Buffer : public Multi_Buffer {
-public:
- // If center_only is true, only center buffers are created and
- // less memory is used.
- Effects_Buffer( bool center_only = false );
-
- // Channel Effect Center Pan
- // ---------------------------------
- // 0,5 reverb pan_1
- // 1,6 reverb pan_2
- // 2,7 echo -
- // 3 echo -
- // 4 echo -
-
- // Channel configuration
- struct config_t {
- double pan_1; // -1.0 = left, 0.0 = center, 1.0 = right
- double pan_2;
- double echo_delay; // msec
- double echo_level; // 0.0 to 1.0
- double reverb_delay; // msec
- double delay_variance; // difference between left/right delays (msec)
- double reverb_level; // 0.0 to 1.0
- bool effects_enabled; // if false, use optimized simple mixer
- config_t();
- };
-
- // Set configuration of buffer
- virtual void config( const config_t& );
- void set_depth( double );
-
-public:
- ~Effects_Buffer();
- blargg_err_t set_sample_rate( long samples_per_sec, int msec = blip_default_length );
- void clock_rate( long );
- void bass_freq( int );
- void clear();
- channel_t channel( int, int );
- void end_frame( blip_time_t );
- long read_samples( blip_sample_t*, long );
- long samples_avail() const;
-private:
- typedef long fixed_t;
-
- enum { max_buf_count = 7 };
- Blip_Buffer bufs [max_buf_count];
- enum { chan_types_count = 3 };
- channel_t chan_types [3];
- config_t config_;
- long stereo_remain;
- long effect_remain;
- int buf_count;
- bool effects_enabled;
-
- blargg_vector<blip_sample_t> reverb_buf;
- blargg_vector<blip_sample_t> echo_buf;
- int reverb_pos;
- int echo_pos;
-
- struct {
- fixed_t pan_1_levels [2];
- fixed_t pan_2_levels [2];
- int echo_delay_l;
- int echo_delay_r;
- fixed_t echo_level;
- int reverb_delay_l;
- int reverb_delay_r;
- fixed_t reverb_level;
- } chans;
-
- void mix_mono( blip_sample_t*, blargg_long );
- void mix_stereo( blip_sample_t*, blargg_long );
- void mix_enhanced( blip_sample_t*, blargg_long );
- void mix_mono_enhanced( blip_sample_t*, blargg_long );
-};
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Fir_Resampler.cpp b/plugins/gme/game-music-emu-0.5.5/gme/Fir_Resampler.cpp
deleted file mode 100644
index f2c905a9..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Fir_Resampler.cpp
+++ /dev/null
@@ -1,199 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Fir_Resampler.h"
-
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <math.h>
-
-/* Copyright (C) 2004-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-#undef PI
-#define PI 3.1415926535897932384626433832795029
-
-static void gen_sinc( double rolloff, int width, double offset, double spacing, double scale,
- int count, short* out )
-{
- double const maxh = 256;
- double const step = PI / maxh * spacing;
- double const to_w = maxh * 2 / width;
- double const pow_a_n = pow( rolloff, maxh );
- scale /= maxh * 2;
-
- double angle = (count / 2 - 1 + offset) * -step;
- while ( count-- )
- {
- *out++ = 0;
- double w = angle * to_w;
- if ( fabs( w ) < PI )
- {
- double rolloff_cos_a = rolloff * cos( angle );
- double num = 1 - rolloff_cos_a -
- pow_a_n * cos( maxh * angle ) +
- pow_a_n * rolloff * cos( (maxh - 1) * angle );
- double den = 1 - rolloff_cos_a - rolloff_cos_a + rolloff * rolloff;
- double sinc = scale * num / den - scale;
-
- out [-1] = (short) (cos( w ) * sinc + sinc);
- }
- angle += step;
- }
-}
-
-Fir_Resampler_::Fir_Resampler_( int width, sample_t* impulses_ ) :
- width_( width ),
- write_offset( width * stereo - stereo ),
- impulses( impulses_ )
-{
- write_pos = 0;
- res = 1;
- imp_phase = 0;
- skip_bits = 0;
- step = stereo;
- ratio_ = 1.0;
-}
-
-Fir_Resampler_::~Fir_Resampler_() { }
-
-void Fir_Resampler_::clear()
-{
- imp_phase = 0;
- if ( buf.size() )
- {
- write_pos = &buf [write_offset];
- memset( buf.begin(), 0, write_offset * sizeof buf [0] );
- }
-}
-
-blargg_err_t Fir_Resampler_::buffer_size( int new_size )
-{
- RETURN_ERR( buf.resize( new_size + write_offset ) );
- clear();
- return 0;
-}
-
-double Fir_Resampler_::time_ratio( double new_factor, double rolloff, double gain )
-{
- ratio_ = new_factor;
-
- double fstep = 0.0;
- {
- double least_error = 2;
- double pos = 0;
- res = -1;
- for ( int r = 1; r <= max_res; r++ )
- {
- pos += ratio_;
- double nearest = floor( pos + 0.5 );
- double error = fabs( pos - nearest );
- if ( error < least_error )
- {
- res = r;
- fstep = nearest / res;
- least_error = error;
- }
- }
- }
-
- skip_bits = 0;
-
- step = stereo * (int) floor( fstep );
-
- ratio_ = fstep;
- fstep = fmod( fstep, 1.0 );
-
- double filter = (ratio_ < 1.0) ? 1.0 : 1.0 / ratio_;
- double pos = 0.0;
- input_per_cycle = 0;
- for ( int i = 0; i < res; i++ )
- {
- gen_sinc( rolloff, int (width_ * filter + 1) & ~1, pos, filter,
- double (0x7FFF * gain * filter),
- (int) width_, impulses + i * width_ );
-
- pos += fstep;
- input_per_cycle += step;
- if ( pos >= 0.9999999 )
- {
- pos -= 1.0;
- skip_bits |= 1 << i;
- input_per_cycle++;
- }
- }
-
- clear();
-
- return ratio_;
-}
-
-int Fir_Resampler_::input_needed( blargg_long output_count ) const
-{
- blargg_long input_count = 0;
-
- unsigned long skip = skip_bits >> imp_phase;
- int remain = res - imp_phase;
- while ( (output_count -= 2) > 0 )
- {
- input_count += step + (skip & 1) * stereo;
- skip >>= 1;
- if ( !--remain )
- {
- skip = skip_bits;
- remain = res;
- }
- output_count -= 2;
- }
-
- long input_extra = input_count - (write_pos - &buf [(width_ - 1) * stereo]);
- if ( input_extra < 0 )
- input_extra = 0;
- return input_extra;
-}
-
-int Fir_Resampler_::avail_( blargg_long input_count ) const
-{
- int cycle_count = input_count / input_per_cycle;
- int output_count = cycle_count * res * stereo;
- input_count -= cycle_count * input_per_cycle;
-
- blargg_ulong skip = skip_bits >> imp_phase;
- int remain = res - imp_phase;
- while ( input_count >= 0 )
- {
- input_count -= step + (skip & 1) * stereo;
- skip >>= 1;
- if ( !--remain )
- {
- skip = skip_bits;
- remain = res;
- }
- output_count += 2;
- }
- return output_count;
-}
-
-int Fir_Resampler_::skip_input( long count )
-{
- int remain = write_pos - buf.begin();
- int max_count = remain - width_ * stereo;
- if ( count > max_count )
- count = max_count;
-
- remain -= count;
- write_pos = &buf [remain];
- memmove( buf.begin(), &buf [count], remain * sizeof buf [0] );
-
- return count;
-}
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Fir_Resampler.h b/plugins/gme/game-music-emu-0.5.5/gme/Fir_Resampler.h
deleted file mode 100644
index aed87492..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Fir_Resampler.h
+++ /dev/null
@@ -1,171 +0,0 @@
-// Finite impulse response (FIR) resampler with adjustable FIR size
-
-// Game_Music_Emu 0.5.5
-#ifndef FIR_RESAMPLER_H
-#define FIR_RESAMPLER_H
-
-#include "blargg_common.h"
-#include <string.h>
-
-class Fir_Resampler_ {
-public:
-
- // Use Fir_Resampler<width> (below)
-
- // Set input/output resampling ratio and optionally low-pass rolloff and gain.
- // Returns actual ratio used (rounded to internal precision).
- double time_ratio( double factor, double rolloff = 0.999, double gain = 1.0 );
-
- // Current input/output ratio
- double ratio() const { return ratio_; }
-
-// Input
-
- typedef short sample_t;
-
- // Resize and clear input buffer
- blargg_err_t buffer_size( int );
-
- // Clear input buffer. At least two output samples will be available after
- // two input samples are written.
- void clear();
-
- // Number of input samples that can be written
- int max_write() const { return buf.end() - write_pos; }
-
- // Pointer to place to write input samples
- sample_t* buffer() { return write_pos; }
-
- // Notify resampler that 'count' input samples have been written
- void write( long count );
-
- // Number of input samples in buffer
- int written() const { return write_pos - &buf [write_offset]; }
-
- // Skip 'count' input samples. Returns number of samples actually skipped.
- int skip_input( long count );
-
-// Output
-
- // Number of extra input samples needed until 'count' output samples are available
- int input_needed( blargg_long count ) const;
-
- // Number of output samples available
- int avail() const { return avail_( write_pos - &buf [width_ * stereo] ); }
-
-public:
- ~Fir_Resampler_();
-protected:
- enum { stereo = 2 };
- enum { max_res = 32 };
- blargg_vector<sample_t> buf;
- sample_t* write_pos;
- int res;
- int imp_phase;
- int const width_;
- int const write_offset;
- blargg_ulong skip_bits;
- int step;
- int input_per_cycle;
- double ratio_;
- sample_t* impulses;
-
- Fir_Resampler_( int width, sample_t* );
- int avail_( blargg_long input_count ) const;
-};
-
-// Width is number of points in FIR. Must be even and 4 or more. More points give
-// better quality and rolloff effectiveness, and take longer to calculate.
-template<int width>
-class Fir_Resampler : public Fir_Resampler_ {
- BOOST_STATIC_ASSERT( width >= 4 && width % 2 == 0 );
- short impulses [max_res] [width];
-public:
- Fir_Resampler() : Fir_Resampler_( width, impulses [0] ) { }
-
- // Read at most 'count' samples. Returns number of samples actually read.
- typedef short sample_t;
- int read( sample_t* out, blargg_long count );
-};
-
-// End of public interface
-
-inline void Fir_Resampler_::write( long count )
-{
- write_pos += count;
- assert( write_pos <= buf.end() );
-}
-
-template<int width>
-int Fir_Resampler<width>::read( sample_t* out_begin, blargg_long count )
-{
- sample_t* out = out_begin;
- const sample_t* in = buf.begin();
- sample_t* end_pos = write_pos;
- blargg_ulong skip = skip_bits >> imp_phase;
- sample_t const* imp = impulses [imp_phase];
- int remain = res - imp_phase;
- int const step = this->step;
-
- count >>= 1;
-
- if ( end_pos - in >= width * stereo )
- {
- end_pos -= width * stereo;
- do
- {
- count--;
-
- // accumulate in extended precision
- blargg_long l = 0;
- blargg_long r = 0;
-
- const sample_t* i = in;
- if ( count < 0 )
- break;
-
- for ( int n = width / 2; n; --n )
- {
- int pt0 = imp [0];
- l += pt0 * i [0];
- r += pt0 * i [1];
- int pt1 = imp [1];
- imp += 2;
- l += pt1 * i [2];
- r += pt1 * i [3];
- i += 4;
- }
-
- remain--;
-
- l >>= 15;
- r >>= 15;
-
- in += (skip * stereo) & stereo;
- skip >>= 1;
- in += step;
-
- if ( !remain )
- {
- imp = impulses [0];
- skip = skip_bits;
- remain = res;
- }
-
- out [0] = (sample_t) l;
- out [1] = (sample_t) r;
- out += 2;
- }
- while ( in <= end_pos );
- }
-
- imp_phase = res - remain;
-
- int left = write_pos - in;
- write_pos = &buf [left];
- memmove( buf.begin(), in, left * sizeof *in );
-
- return out - out_begin;
-}
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Gb_Apu.cpp b/plugins/gme/game-music-emu-0.5.5/gme/Gb_Apu.cpp
deleted file mode 100644
index 866594dd..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Gb_Apu.cpp
+++ /dev/null
@@ -1,306 +0,0 @@
-// Gb_Snd_Emu 0.1.5. http://www.slack.net/~ant/
-
-#include "Gb_Apu.h"
-
-#include <string.h>
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-unsigned const vol_reg = 0xFF24;
-unsigned const status_reg = 0xFF26;
-
-Gb_Apu::Gb_Apu()
-{
- square1.synth = &square_synth;
- square2.synth = &square_synth;
- wave.synth = &other_synth;
- noise.synth = &other_synth;
-
- oscs [0] = &square1;
- oscs [1] = &square2;
- oscs [2] = &wave;
- oscs [3] = &noise;
-
- for ( int i = 0; i < osc_count; i++ )
- {
- Gb_Osc& osc = *oscs [i];
- osc.regs = &regs [i * 5];
- osc.output = 0;
- osc.outputs [0] = 0;
- osc.outputs [1] = 0;
- osc.outputs [2] = 0;
- osc.outputs [3] = 0;
- }
-
- set_tempo( 1.0 );
- volume( 1.0 );
- reset();
-}
-
-void Gb_Apu::treble_eq( const blip_eq_t& eq )
-{
- square_synth.treble_eq( eq );
- other_synth.treble_eq( eq );
-}
-
-void Gb_Apu::osc_output( int index, Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right )
-{
- require( (unsigned) index < osc_count );
- require( (center && left && right) || (!center && !left && !right) );
- Gb_Osc& osc = *oscs [index];
- osc.outputs [1] = right;
- osc.outputs [2] = left;
- osc.outputs [3] = center;
- osc.output = osc.outputs [osc.output_select];
-}
-
-void Gb_Apu::output( Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right )
-{
- for ( int i = 0; i < osc_count; i++ )
- osc_output( i, center, left, right );
-}
-
-void Gb_Apu::update_volume()
-{
- // TODO: doesn't handle differing left/right global volume (support would
- // require modification to all oscillator code)
- int data = regs [vol_reg - start_addr];
- double vol = (max( data & 7, data >> 4 & 7 ) + 1) * volume_unit;
- square_synth.volume( vol );
- other_synth.volume( vol );
-}
-
-static unsigned char const powerup_regs [0x20] = {
- 0x80,0x3F,0x00,0xFF,0xBF, // square 1
- 0xFF,0x3F,0x00,0xFF,0xBF, // square 2
- 0x7F,0xFF,0x9F,0xFF,0xBF, // wave
- 0xFF,0xFF,0x00,0x00,0xBF, // noise
- 0x00, // left/right enables
- 0x77, // master volume
- 0x80, // power
- 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
-};
-
-void Gb_Apu::set_tempo( double t )
-{
- frame_period = 4194304 / 256; // 256 Hz
- if ( t != 1.0 )
- frame_period = blip_time_t (frame_period / t);
-}
-
-void Gb_Apu::reset()
-{
- next_frame_time = 0;
- last_time = 0;
- frame_count = 0;
-
- square1.reset();
- square2.reset();
- wave.reset();
- noise.reset();
- noise.bits = 1;
- wave.wave_pos = 0;
-
- // avoid click at beginning
- regs [vol_reg - start_addr] = 0x77;
- update_volume();
-
- regs [status_reg - start_addr] = 0x01; // force power
- write_register( 0, status_reg, 0x00 );
-
- static unsigned char const initial_wave [] = {
- 0x84,0x40,0x43,0xAA,0x2D,0x78,0x92,0x3C, // wave table
- 0x60,0x59,0x59,0xB0,0x34,0xB8,0x2E,0xDA
- };
- memcpy( wave.wave, initial_wave, sizeof wave.wave );
-}
-
-void Gb_Apu::run_until( blip_time_t end_time )
-{
- require( end_time >= last_time ); // end_time must not be before previous time
- if ( end_time == last_time )
- return;
-
- while ( true )
- {
- blip_time_t time = next_frame_time;
- if ( time > end_time )
- time = end_time;
-
- // run oscillators
- for ( int i = 0; i < osc_count; ++i )
- {
- Gb_Osc& osc = *oscs [i];
- if ( osc.output )
- {
- osc.output->set_modified(); // TODO: misses optimization opportunities?
- int playing = false;
- if ( osc.enabled && osc.volume &&
- (!(osc.regs [4] & osc.len_enabled_mask) || osc.length) )
- playing = -1;
- switch ( i )
- {
- case 0: square1.run( last_time, time, playing ); break;
- case 1: square2.run( last_time, time, playing ); break;
- case 2: wave .run( last_time, time, playing ); break;
- case 3: noise .run( last_time, time, playing ); break;
- }
- }
- }
- last_time = time;
-
- if ( time == end_time )
- break;
-
- next_frame_time += frame_period;
-
- // 256 Hz actions
- square1.clock_length();
- square2.clock_length();
- wave.clock_length();
- noise.clock_length();
-
- frame_count = (frame_count + 1) & 3;
- if ( frame_count == 0 )
- {
- // 64 Hz actions
- square1.clock_envelope();
- square2.clock_envelope();
- noise.clock_envelope();
- }
-
- if ( frame_count & 1 )
- square1.clock_sweep(); // 128 Hz action
- }
-}
-
-void Gb_Apu::end_frame( blip_time_t end_time )
-{
- if ( end_time > last_time )
- run_until( end_time );
-
- assert( next_frame_time >= end_time );
- next_frame_time -= end_time;
-
- assert( last_time >= end_time );
- last_time -= end_time;
-}
-
-void Gb_Apu::write_register( blip_time_t time, unsigned addr, int data )
-{
- require( (unsigned) data < 0x100 );
-
- int reg = addr - start_addr;
- if ( (unsigned) reg >= register_count )
- return;
-
- run_until( time );
-
- int old_reg = regs [reg];
- regs [reg] = data;
-
- if ( addr < vol_reg )
- {
- write_osc( reg / 5, reg, data );
- }
- else if ( addr == vol_reg && data != old_reg ) // global volume
- {
- // return all oscs to 0
- for ( int i = 0; i < osc_count; i++ )
- {
- Gb_Osc& osc = *oscs [i];
- int amp = osc.last_amp;
- osc.last_amp = 0;
- if ( amp && osc.enabled && osc.output )
- other_synth.offset( time, -amp, osc.output );
- }
-
- if ( wave.outputs [3] )
- other_synth.offset( time, 30, wave.outputs [3] );
-
- update_volume();
-
- if ( wave.outputs [3] )
- other_synth.offset( time, -30, wave.outputs [3] );
-
- // oscs will update with new amplitude when next run
- }
- else if ( addr == 0xFF25 || addr == status_reg )
- {
- int mask = (regs [status_reg - start_addr] & 0x80) ? ~0 : 0;
- int flags = regs [0xFF25 - start_addr] & mask;
-
- // left/right assignments
- for ( int i = 0; i < osc_count; i++ )
- {
- Gb_Osc& osc = *oscs [i];
- osc.enabled &= mask;
- int bits = flags >> i;
- Blip_Buffer* old_output = osc.output;
- osc.output_select = (bits >> 3 & 2) | (bits & 1);
- osc.output = osc.outputs [osc.output_select];
- if ( osc.output != old_output )
- {
- int amp = osc.last_amp;
- osc.last_amp = 0;
- if ( amp && old_output )
- other_synth.offset( time, -amp, old_output );
- }
- }
-
- if ( addr == status_reg && data != old_reg )
- {
- if ( !(data & 0x80) )
- {
- for ( unsigned i = 0; i < sizeof powerup_regs; i++ )
- {
- if ( i != status_reg - start_addr )
- write_register( time, i + start_addr, powerup_regs [i] );
- }
- }
- else
- {
- //debug_printf( "APU powered on\n" );
- }
- }
- }
- else if ( addr >= 0xFF30 )
- {
- int index = (addr & 0x0F) * 2;
- wave.wave [index] = data >> 4;
- wave.wave [index + 1] = data & 0x0F;
- }
-}
-
-int Gb_Apu::read_register( blip_time_t time, unsigned addr )
-{
- run_until( time );
-
- int index = addr - start_addr;
- require( (unsigned) index < register_count );
- int data = regs [index];
-
- if ( addr == status_reg )
- {
- data = (data & 0x80) | 0x70;
- for ( int i = 0; i < osc_count; i++ )
- {
- const Gb_Osc& osc = *oscs [i];
- if ( osc.enabled && (osc.length || !(osc.regs [4] & osc.len_enabled_mask)) )
- data |= 1 << i;
- }
- }
-
- return data;
-}
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Gb_Apu.h b/plugins/gme/game-music-emu-0.5.5/gme/Gb_Apu.h
deleted file mode 100644
index e74ebc55..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Gb_Apu.h
+++ /dev/null
@@ -1,90 +0,0 @@
-// Nintendo Game Boy PAPU sound chip emulator
-
-// Gb_Snd_Emu 0.1.5
-#ifndef GB_APU_H
-#define GB_APU_H
-
-#include "Gb_Oscs.h"
-
-class Gb_Apu {
-public:
-
- // Set overall volume of all oscillators, where 1.0 is full volume
- void volume( double );
-
- // Set treble equalization
- void treble_eq( const blip_eq_t& );
-
- // Outputs can be assigned to a single buffer for mono output, or to three
- // buffers for stereo output (using Stereo_Buffer to do the mixing).
-
- // Assign all oscillator outputs to specified buffer(s). If buffer
- // is NULL, silences all oscillators.
- void output( Blip_Buffer* mono );
- void output( Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right );
-
- // Assign single oscillator output to buffer(s). Valid indicies are 0 to 3,
- // which refer to Square 1, Square 2, Wave, and Noise. If buffer is NULL,
- // silences oscillator.
- enum { osc_count = 4 };
- void osc_output( int index, Blip_Buffer* mono );
- void osc_output( int index, Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right );
-
- // Reset oscillators and internal state
- void reset();
-
- // Reads and writes at addr must satisfy start_addr <= addr <= end_addr
- enum { start_addr = 0xFF10 };
- enum { end_addr = 0xFF3F };
- enum { register_count = end_addr - start_addr + 1 };
-
- // Write 'data' to address at specified time
- void write_register( blip_time_t, unsigned addr, int data );
-
- // Read from address at specified time
- int read_register( blip_time_t, unsigned addr );
-
- // Run all oscillators up to specified time, end current time frame, then
- // start a new frame at time 0.
- void end_frame( blip_time_t );
-
- void set_tempo( double );
-
-public:
- Gb_Apu();
-private:
- // noncopyable
- Gb_Apu( const Gb_Apu& );
- Gb_Apu& operator = ( const Gb_Apu& );
-
- Gb_Osc* oscs [osc_count];
- blip_time_t next_frame_time;
- blip_time_t last_time;
- blip_time_t frame_period;
- double volume_unit;
- int frame_count;
-
- Gb_Square square1;
- Gb_Square square2;
- Gb_Wave wave;
- Gb_Noise noise;
- BOOST::uint8_t regs [register_count];
- Gb_Square::Synth square_synth; // used by squares
- Gb_Wave::Synth other_synth; // used by wave and noise
-
- void update_volume();
- void run_until( blip_time_t );
- void write_osc( int index, int reg, int data );
-};
-
-inline void Gb_Apu::output( Blip_Buffer* b ) { output( b, b, b ); }
-
-inline void Gb_Apu::osc_output( int i, Blip_Buffer* b ) { osc_output( i, b, b, b ); }
-
-inline void Gb_Apu::volume( double vol )
-{
- volume_unit = 0.60 / osc_count / 15 /*steps*/ / 2 /*?*/ / 8 /*master vol range*/ * vol;
- update_volume();
-}
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Gb_Cpu.cpp b/plugins/gme/game-music-emu-0.5.5/gme/Gb_Cpu.cpp
deleted file mode 100644
index 6980aafe..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Gb_Cpu.cpp
+++ /dev/null
@@ -1,1056 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Gb_Cpu.h"
-
-#include <string.h>
-
-//#include "gb_cpu_log.h"
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "gb_cpu_io.h"
-
-#include "blargg_source.h"
-
-// Common instructions:
-//
-// 365880 FA LD A,IND16
-// 355863 20 JR NZ
-// 313655 21 LD HL,IMM
-// 274580 28 JR Z
-// 252878 FE CMP IMM
-// 230541 7E LD A,(HL)
-// 226209 2A LD A,(HL+)
-// 217467 CD CALL
-// 212034 C9 RET
-// 208376 CB CB prefix
-//
-// 27486 CB 7E BIT 7,(HL)
-// 15925 CB 76 BIT 6,(HL)
-// 13035 CB 19 RR C
-// 11557 CB 7F BIT 7,A
-// 10898 CB 37 SWAP A
-// 10208 CB 66 BIT 4,(HL)
-
-#if BLARGG_NONPORTABLE
- #define PAGE_OFFSET( addr ) (addr)
-#else
- #define PAGE_OFFSET( addr ) ((addr) & (page_size - 1))
-#endif
-
-inline void Gb_Cpu::set_code_page( int i, uint8_t* p )
-{
- state->code_map [i] = p - PAGE_OFFSET( i * (blargg_long) page_size );
-}
-
-void Gb_Cpu::reset( void* unmapped )
-{
- check( state == &state_ );
- state = &state_;
-
- state_.remain = 0;
-
- for ( int i = 0; i < page_count + 1; i++ )
- set_code_page( i, (uint8_t*) unmapped );
-
- memset( &r, 0, sizeof r );
- //interrupts_enabled = false;
-
- blargg_verify_byte_order();
-}
-
-void Gb_Cpu::map_code( gb_addr_t start, unsigned size, void* data )
-{
- // address range must begin and end on page boundaries
- require( start % page_size == 0 );
- require( size % page_size == 0 );
-
- unsigned first_page = start / page_size;
- for ( unsigned i = size / page_size; i--; )
- set_code_page( first_page + i, (uint8_t*) data + i * page_size );
-}
-
-#define READ( addr ) CPU_READ( this, (addr), s.remain )
-#define WRITE( addr, data ) {CPU_WRITE( this, (addr), (data), s.remain );}
-#define READ_FAST( addr, out ) CPU_READ_FAST( this, (addr), s.remain, out )
-#define READ_PROG( addr ) (s.code_map [(addr) >> page_shift] [PAGE_OFFSET( addr )])
-
-unsigned const z_flag = 0x80;
-unsigned const n_flag = 0x40;
-unsigned const h_flag = 0x20;
-unsigned const c_flag = 0x10;
-
-bool Gb_Cpu::run( blargg_long cycle_count )
-{
- state_.remain = blargg_ulong (cycle_count + clocks_per_instr) / clocks_per_instr;
- state_t s;
- this->state = &s;
- memcpy( &s, &this->state_, sizeof s );
-
- typedef BOOST::uint16_t uint16_t;
-
-#if BLARGG_BIG_ENDIAN
- #define R8( n ) (r8_ [n])
-#elif BLARGG_LITTLE_ENDIAN
- #define R8( n ) (r8_ [(n) ^ 1])
-#else
- #error "Byte order of CPU must be known"
-#endif
-
- union {
- core_regs_t rg; // individual registers
-
- struct {
- BOOST::uint16_t bc, de, hl, unused; // pairs
- } rp;
-
- uint8_t r8_ [8]; // indexed registers (use R8 macro due to endian dependence)
- BOOST::uint16_t r16 [4]; // indexed pairs
- };
- BOOST_STATIC_ASSERT( sizeof rg == 8 && sizeof rp == 8 );
-
- rg = r;
- unsigned pc = r.pc;
- unsigned sp = r.sp;
- unsigned flags = r.flags;
-
-loop:
-
- check( (unsigned long) pc < 0x10000 );
- check( (unsigned long) sp < 0x10000 );
- check( (flags & ~0xF0) == 0 );
-
- uint8_t const* instr = s.code_map [pc >> page_shift];
- unsigned op;
-
- // TODO: eliminate this special case
- #if BLARGG_NONPORTABLE
- op = instr [pc];
- pc++;
- instr += pc;
- #else
- instr += PAGE_OFFSET( pc );
- op = *instr++;
- pc++;
- #endif
-
-#define GET_ADDR() GET_LE16( instr )
-
- if ( !--s.remain )
- goto stop;
-
- unsigned data;
- data = *instr;
-
- #ifdef GB_CPU_LOG_H
- gb_cpu_log( "new", pc - 1, op, data, instr [1] );
- #endif
-
- switch ( op )
- {
-
-// TODO: more efficient way to handle negative branch that wraps PC around
-#define BRANCH( cond )\
-{\
- pc++;\
- int offset = (BOOST::int8_t) data;\
- if ( !(cond) ) goto loop;\
- pc = uint16_t (pc + offset);\
- goto loop;\
-}
-
-// Most Common
-
- case 0x20: // JR NZ
- BRANCH( !(flags & z_flag) )
-
- case 0x21: // LD HL,IMM (common)
- rp.hl = GET_ADDR();
- pc += 2;
- goto loop;
-
- case 0x28: // JR Z
- BRANCH( flags & z_flag )
-
- {
- unsigned temp;
- case 0xF0: // LD A,(0xFF00+imm)
- temp = data | 0xFF00;
- pc++;
- goto ld_a_ind_comm;
-
- case 0xF2: // LD A,(0xFF00+C)
- temp = rg.c | 0xFF00;
- goto ld_a_ind_comm;
-
- case 0x0A: // LD A,(BC)
- temp = rp.bc;
- goto ld_a_ind_comm;
-
- case 0x3A: // LD A,(HL-)
- temp = rp.hl;
- rp.hl = temp - 1;
- goto ld_a_ind_comm;
-
- case 0x1A: // LD A,(DE)
- temp = rp.de;
- goto ld_a_ind_comm;
-
- case 0x2A: // LD A,(HL+) (common)
- temp = rp.hl;
- rp.hl = temp + 1;
- goto ld_a_ind_comm;
-
- case 0xFA: // LD A,IND16 (common)
- temp = GET_ADDR();
- pc += 2;
- ld_a_ind_comm:
- READ_FAST( temp, rg.a );
- goto loop;
- }
-
- case 0xBE: // CMP (HL)
- data = READ( rp.hl );
- goto cmp_comm;
-
- case 0xB8: // CMP B
- case 0xB9: // CMP C
- case 0xBA: // CMP D
- case 0xBB: // CMP E
- case 0xBC: // CMP H
- case 0xBD: // CMP L
- data = R8( op & 7 );
- goto cmp_comm;
-
- case 0xFE: // CMP IMM
- pc++;
- cmp_comm:
- op = rg.a;
- data = op - data;
- sub_set_flags:
- flags = ((op & 15) - (data & 15)) & h_flag;
- flags |= (data >> 4) & c_flag;
- flags |= n_flag;
- if ( data & 0xFF )
- goto loop;
- flags |= z_flag;
- goto loop;
-
- case 0x46: // LD B,(HL)
- case 0x4E: // LD C,(HL)
- case 0x56: // LD D,(HL)
- case 0x5E: // LD E,(HL)
- case 0x66: // LD H,(HL)
- case 0x6E: // LD L,(HL)
- case 0x7E:{// LD A,(HL)
- unsigned addr = rp.hl;
- READ_FAST( addr, R8( (op >> 3) & 7 ) );
- goto loop;
- }
-
- case 0xC4: // CNZ (next-most-common)
- pc += 2;
- if ( flags & z_flag )
- goto loop;
- call:
- pc -= 2;
- case 0xCD: // CALL (most-common)
- data = pc + 2;
- pc = GET_ADDR();
- push:
- sp = (sp - 1) & 0xFFFF;
- WRITE( sp, data >> 8 );
- sp = (sp - 1) & 0xFFFF;
- WRITE( sp, data & 0xFF );
- goto loop;
-
- case 0xC8: // RNZ (next-most-common)
- if ( !(flags & z_flag) )
- goto loop;
- case 0xC9: // RET (most common)
- ret:
- pc = READ( sp );
- pc += 0x100 * READ( sp + 1 );
- sp = (sp + 2) & 0xFFFF;
- goto loop;
-
- case 0x00: // NOP
- case 0x40: // LD B,B
- case 0x49: // LD C,C
- case 0x52: // LD D,D
- case 0x5B: // LD E,E
- case 0x64: // LD H,H
- case 0x6D: // LD L,L
- case 0x7F: // LD A,A
- goto loop;
-
-// CB Instructions
-
- case 0xCB:
- pc++;
- // now data is the opcode
- switch ( data ) {
-
- {
- int temp;
- case 0x46: // BIT b,(HL)
- case 0x4E:
- case 0x56:
- case 0x5E:
- case 0x66:
- case 0x6E:
- case 0x76:
- case 0x7E:
- {
- unsigned addr = rp.hl;
- READ_FAST( addr, temp );
- goto bit_comm;
- }
-
- case 0x40: case 0x41: case 0x42: case 0x43: // BIT b,r
- case 0x44: case 0x45: case 0x47: case 0x48:
- case 0x49: case 0x4A: case 0x4B: case 0x4C:
- case 0x4D: case 0x4F: case 0x50: case 0x51:
- case 0x52: case 0x53: case 0x54: case 0x55:
- case 0x57: case 0x58: case 0x59: case 0x5A:
- case 0x5B: case 0x5C: case 0x5D: case 0x5F:
- case 0x60: case 0x61: case 0x62: case 0x63:
- case 0x64: case 0x65: case 0x67: case 0x68:
- case 0x69: case 0x6A: case 0x6B: case 0x6C:
- case 0x6D: case 0x6F: case 0x70: case 0x71:
- case 0x72: case 0x73: case 0x74: case 0x75:
- case 0x77: case 0x78: case 0x79: case 0x7A:
- case 0x7B: case 0x7C: case 0x7D: case 0x7F:
- temp = R8( data & 7 );
- bit_comm:
- int bit = (~data >> 3) & 7;
- flags &= ~n_flag;
- flags |= h_flag | z_flag;
- flags ^= (temp << bit) & z_flag;
- goto loop;
- }
-
- case 0x86: // RES b,(HL)
- case 0x8E:
- case 0x96:
- case 0x9E:
- case 0xA6:
- case 0xAE:
- case 0xB6:
- case 0xBE:
- case 0xC6: // SET b,(HL)
- case 0xCE:
- case 0xD6:
- case 0xDE:
- case 0xE6:
- case 0xEE:
- case 0xF6:
- case 0xFE: {
- int temp = READ( rp.hl );
- int bit = 1 << ((data >> 3) & 7);
- temp &= ~bit;
- if ( !(data & 0x40) )
- bit = 0;
- WRITE( rp.hl, temp | bit );
- goto loop;
- }
-
- case 0xC0: case 0xC1: case 0xC2: case 0xC3: // SET b,r
- case 0xC4: case 0xC5: case 0xC7: case 0xC8:
- case 0xC9: case 0xCA: case 0xCB: case 0xCC:
- case 0xCD: case 0xCF: case 0xD0: case 0xD1:
- case 0xD2: case 0xD3: case 0xD4: case 0xD5:
- case 0xD7: case 0xD8: case 0xD9: case 0xDA:
- case 0xDB: case 0xDC: case 0xDD: case 0xDF:
- case 0xE0: case 0xE1: case 0xE2: case 0xE3:
- case 0xE4: case 0xE5: case 0xE7: case 0xE8:
- case 0xE9: case 0xEA: case 0xEB: case 0xEC:
- case 0xED: case 0xEF: case 0xF0: case 0xF1:
- case 0xF2: case 0xF3: case 0xF4: case 0xF5:
- case 0xF7: case 0xF8: case 0xF9: case 0xFA:
- case 0xFB: case 0xFC: case 0xFD: case 0xFF:
- R8( data & 7 ) |= 1 << ((data >> 3) & 7);
- goto loop;
-
- case 0x80: case 0x81: case 0x82: case 0x83: // RES b,r
- case 0x84: case 0x85: case 0x87: case 0x88:
- case 0x89: case 0x8A: case 0x8B: case 0x8C:
- case 0x8D: case 0x8F: case 0x90: case 0x91:
- case 0x92: case 0x93: case 0x94: case 0x95:
- case 0x97: case 0x98: case 0x99: case 0x9A:
- case 0x9B: case 0x9C: case 0x9D: case 0x9F:
- case 0xA0: case 0xA1: case 0xA2: case 0xA3:
- case 0xA4: case 0xA5: case 0xA7: case 0xA8:
- case 0xA9: case 0xAA: case 0xAB: case 0xAC:
- case 0xAD: case 0xAF: case 0xB0: case 0xB1:
- case 0xB2: case 0xB3: case 0xB4: case 0xB5:
- case 0xB7: case 0xB8: case 0xB9: case 0xBA:
- case 0xBB: case 0xBC: case 0xBD: case 0xBF:
- R8( data & 7 ) &= ~(1 << ((data >> 3) & 7));
- goto loop;
-
- {
- int temp;
- case 0x36: // SWAP (HL)
- temp = READ( rp.hl );
- goto swap_comm;
-
- case 0x30: // SWAP B
- case 0x31: // SWAP C
- case 0x32: // SWAP D
- case 0x33: // SWAP E
- case 0x34: // SWAP H
- case 0x35: // SWAP L
- case 0x37: // SWAP A
- temp = R8( data & 7 );
- swap_comm:
- op = (temp >> 4) | (temp << 4);
- flags = 0;
- goto shift_comm;
- }
-
-// Shift/Rotate
-
- case 0x06: // RLC (HL)
- case 0x16: // RL (HL)
- case 0x26: // SLA (HL)
- op = READ( rp.hl );
- goto rl_comm;
-
- case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x27: // SLA A
- case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x07: // RLC A
- case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x17: // RL A
- op = R8( data & 7 );
- goto rl_comm;
-
- case 0x3E: // SRL (HL)
- data += 0x10; // bump up to 0x4n to avoid preserving sign bit
- case 0x1E: // RR (HL)
- case 0x0E: // RRC (HL)
- case 0x2E: // SRA (HL)
- op = READ( rp.hl );
- goto rr_comm;
-
- case 0x38: case 0x39: case 0x3A: case 0x3B: case 0x3C: case 0x3D: case 0x3F: // SRL A
- data += 0x10; // bump up to 0x4n
- case 0x18: case 0x19: case 0x1A: case 0x1B: case 0x1C: case 0x1D: case 0x1F: // RR A
- case 0x08: case 0x09: case 0x0A: case 0x0B: case 0x0C: case 0x0D: case 0x0F: // RRC A
- case 0x28: case 0x29: case 0x2A: case 0x2B: case 0x2C: case 0x2D: case 0x2F: // SRA A
- op = R8( data & 7 );
- goto rr_comm;
-
- } // CB op
- assert( false ); // unhandled CB op
-
- case 0x07: // RLCA
- case 0x17: // RLA
- data = op;
- op = rg.a;
- rl_comm:
- op <<= 1;
- op |= ((data & flags) >> 4) & 1; // RL and carry is set
- flags = (op >> 4) & c_flag; // C = bit shifted out
- if ( data < 0x10 ) // RLC
- op |= op >> 8;
- // SLA doesn't fill lower bit
- goto shift_comm;
-
- case 0x0F: // RRCA
- case 0x1F: // RRA
- data = op;
- op = rg.a;
- rr_comm:
- op |= (data & flags) << 4; // RR and carry is set
- flags = (op << 4) & c_flag; // C = bit shifted out
- if ( data < 0x10 ) // RRC
- op |= op << 8;
- op >>= 1;
- if ( data & 0x20 ) // SRA propagates sign bit
- op |= (op << 1) & 0x80;
- shift_comm:
- data &= 7;
- if ( !(op & 0xFF) )
- flags |= z_flag;
- if ( data == 6 )
- goto write_hl_op_ff;
- R8( data ) = op;
- goto loop;
-
-// Load
-
- case 0x70: // LD (HL),B
- case 0x71: // LD (HL),C
- case 0x72: // LD (HL),D
- case 0x73: // LD (HL),E
- case 0x74: // LD (HL),H
- case 0x75: // LD (HL),L
- case 0x77: // LD (HL),A
- op = R8( op & 7 );
- write_hl_op_ff:
- WRITE( rp.hl, op & 0xFF );
- goto loop;
-
- case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x47: // LD r,r
- case 0x48: case 0x4A: case 0x4B: case 0x4C: case 0x4D: case 0x4F:
- case 0x50: case 0x51: case 0x53: case 0x54: case 0x55: case 0x57:
- case 0x58: case 0x59: case 0x5A: case 0x5C: case 0x5D: case 0x5F:
- case 0x60: case 0x61: case 0x62: case 0x63: case 0x65: case 0x67:
- case 0x68: case 0x69: case 0x6A: case 0x6B: case 0x6C: case 0x6F:
- case 0x78: case 0x79: case 0x7A: case 0x7B: case 0x7C: case 0x7D:
- R8( (op >> 3) & 7 ) = R8( op & 7 );
- goto loop;
-
- case 0x08: // LD IND16,SP
- data = GET_ADDR();
- pc += 2;
- WRITE( data, sp&0xFF );
- data++;
- WRITE( data, sp >> 8 );
- goto loop;
-
- case 0xF9: // LD SP,HL
- sp = rp.hl;
- goto loop;
-
- case 0x31: // LD SP,IMM
- sp = GET_ADDR();
- pc += 2;
- goto loop;
-
- case 0x01: // LD BC,IMM
- case 0x11: // LD DE,IMM
- r16 [op >> 4] = GET_ADDR();
- pc += 2;
- goto loop;
-
- {
- unsigned temp;
- case 0xE0: // LD (0xFF00+imm),A
- temp = data | 0xFF00;
- pc++;
- goto write_data_rg_a;
-
- case 0xE2: // LD (0xFF00+C),A
- temp = rg.c | 0xFF00;
- goto write_data_rg_a;
-
- case 0x32: // LD (HL-),A
- temp = rp.hl;
- rp.hl = temp - 1;
- goto write_data_rg_a;
-
- case 0x02: // LD (BC),A
- temp = rp.bc;
- goto write_data_rg_a;
-
- case 0x12: // LD (DE),A
- temp = rp.de;
- goto write_data_rg_a;
-
- case 0x22: // LD (HL+),A
- temp = rp.hl;
- rp.hl = temp + 1;
- goto write_data_rg_a;
-
- case 0xEA: // LD IND16,A (common)
- temp = GET_ADDR();
- pc += 2;
- write_data_rg_a:
- WRITE( temp, rg.a );
- goto loop;
- }
-
- case 0x06: // LD B,IMM
- rg.b = data;
- pc++;
- goto loop;
-
- case 0x0E: // LD C,IMM
- rg.c = data;
- pc++;
- goto loop;
-
- case 0x16: // LD D,IMM
- rg.d = data;
- pc++;
- goto loop;
-
- case 0x1E: // LD E,IMM
- rg.e = data;
- pc++;
- goto loop;
-
- case 0x26: // LD H,IMM
- rg.h = data;
- pc++;
- goto loop;
-
- case 0x2E: // LD L,IMM
- rg.l = data;
- pc++;
- goto loop;
-
- case 0x36: // LD (HL),IMM
- WRITE( rp.hl, data );
- pc++;
- goto loop;
-
- case 0x3E: // LD A,IMM
- rg.a = data;
- pc++;
- goto loop;
-
-// Increment/Decrement
-
- case 0x03: // INC BC
- case 0x13: // INC DE
- case 0x23: // INC HL
- r16 [op >> 4]++;
- goto loop;
-
- case 0x33: // INC SP
- sp = (sp + 1) & 0xFFFF;
- goto loop;
-
- case 0x0B: // DEC BC
- case 0x1B: // DEC DE
- case 0x2B: // DEC HL
- r16 [op >> 4]--;
- goto loop;
-
- case 0x3B: // DEC SP
- sp = (sp - 1) & 0xFFFF;
- goto loop;
-
- case 0x34: // INC (HL)
- op = rp.hl;
- data = READ( op );
- data++;
- WRITE( op, data & 0xFF );
- goto inc_comm;
-
- case 0x04: // INC B
- case 0x0C: // INC C (common)
- case 0x14: // INC D
- case 0x1C: // INC E
- case 0x24: // INC H
- case 0x2C: // INC L
- case 0x3C: // INC A
- op = (op >> 3) & 7;
- R8( op ) = data = R8( op ) + 1;
- inc_comm:
- flags = (flags & c_flag) | (((data & 15) - 1) & h_flag) | ((data >> 1) & z_flag);
- goto loop;
-
- case 0x35: // DEC (HL)
- op = rp.hl;
- data = READ( op );
- data--;
- WRITE( op, data & 0xFF );
- goto dec_comm;
-
- case 0x05: // DEC B
- case 0x0D: // DEC C
- case 0x15: // DEC D
- case 0x1D: // DEC E
- case 0x25: // DEC H
- case 0x2D: // DEC L
- case 0x3D: // DEC A
- op = (op >> 3) & 7;
- data = R8( op ) - 1;
- R8( op ) = data;
- dec_comm:
- flags = (flags & c_flag) | n_flag | (((data & 15) + 0x31) & h_flag);
- if ( data & 0xFF )
- goto loop;
- flags |= z_flag;
- goto loop;
-
-// Add 16-bit
-
- {
- blargg_ulong temp; // need more than 16 bits for carry
- unsigned prev;
-
- case 0xF8: // LD HL,SP+imm
- temp = BOOST::int8_t (data); // sign-extend to 16 bits
- pc++;
- flags = 0;
- temp += sp;
- prev = sp;
- goto add_16_hl;
-
- case 0xE8: // ADD SP,IMM
- temp = BOOST::int8_t (data); // sign-extend to 16 bits
- pc++;
- flags = 0;
- temp += sp;
- prev = sp;
- sp = temp & 0xFFFF;
- goto add_16_comm;
-
- case 0x39: // ADD HL,SP
- temp = sp;
- goto add_hl_comm;
-
- case 0x09: // ADD HL,BC
- case 0x19: // ADD HL,DE
- case 0x29: // ADD HL,HL
- temp = r16 [op >> 4];
- add_hl_comm:
- prev = rp.hl;
- temp += prev;
- flags &= z_flag;
- add_16_hl:
- rp.hl = temp;
- add_16_comm:
- flags |= (temp >> 12) & c_flag;
- flags |= (((temp & 0x0FFF) - (prev & 0x0FFF)) >> 7) & h_flag;
- goto loop;
- }
-
- case 0x86: // ADD (HL)
- data = READ( rp.hl );
- goto add_comm;
-
- case 0x80: // ADD B
- case 0x81: // ADD C
- case 0x82: // ADD D
- case 0x83: // ADD E
- case 0x84: // ADD H
- case 0x85: // ADD L
- case 0x87: // ADD A
- data = R8( op & 7 );
- goto add_comm;
-
- case 0xC6: // ADD IMM
- pc++;
- add_comm:
- flags = rg.a;
- data += flags;
- flags = ((data & 15) - (flags & 15)) & h_flag;
- flags |= (data >> 4) & c_flag;
- rg.a = data;
- if ( data & 0xFF )
- goto loop;
- flags |= z_flag;
- goto loop;
-
-// Add/Subtract
-
- case 0x8E: // ADC (HL)
- data = READ( rp.hl );
- goto adc_comm;
-
- case 0x88: // ADC B
- case 0x89: // ADC C
- case 0x8A: // ADC D
- case 0x8B: // ADC E
- case 0x8C: // ADC H
- case 0x8D: // ADC L
- case 0x8F: // ADC A
- data = R8( op & 7 );
- goto adc_comm;
-
- case 0xCE: // ADC IMM
- pc++;
- adc_comm:
- data += (flags >> 4) & 1;
- data &= 0xFF; // to do: does carry get set when sum + carry = 0x100?
- goto add_comm;
-
- case 0x96: // SUB (HL)
- data = READ( rp.hl );
- goto sub_comm;
-
- case 0x90: // SUB B
- case 0x91: // SUB C
- case 0x92: // SUB D
- case 0x93: // SUB E
- case 0x94: // SUB H
- case 0x95: // SUB L
- case 0x97: // SUB A
- data = R8( op & 7 );
- goto sub_comm;
-
- case 0xD6: // SUB IMM
- pc++;
- sub_comm:
- op = rg.a;
- data = op - data;
- rg.a = data;
- goto sub_set_flags;
-
- case 0x9E: // SBC (HL)
- data = READ( rp.hl );
- goto sbc_comm;
-
- case 0x98: // SBC B
- case 0x99: // SBC C
- case 0x9A: // SBC D
- case 0x9B: // SBC E
- case 0x9C: // SBC H
- case 0x9D: // SBC L
- case 0x9F: // SBC A
- data = R8( op & 7 );
- goto sbc_comm;
-
- case 0xDE: // SBC IMM
- pc++;
- sbc_comm:
- data += (flags >> 4) & 1;
- data &= 0xFF; // to do: does carry get set when sum + carry = 0x100?
- goto sub_comm;
-
-// Logical
-
- case 0xA0: // AND B
- case 0xA1: // AND C
- case 0xA2: // AND D
- case 0xA3: // AND E
- case 0xA4: // AND H
- case 0xA5: // AND L
- data = R8( op & 7 );
- goto and_comm;
-
- case 0xA6: // AND (HL)
- data = READ( rp.hl );
- pc--;
- case 0xE6: // AND IMM
- pc++;
- and_comm:
- rg.a &= data;
- case 0xA7: // AND A
- flags = h_flag | (((rg.a - 1) >> 1) & z_flag);
- goto loop;
-
- case 0xB0: // OR B
- case 0xB1: // OR C
- case 0xB2: // OR D
- case 0xB3: // OR E
- case 0xB4: // OR H
- case 0xB5: // OR L
- data = R8( op & 7 );
- goto or_comm;
-
- case 0xB6: // OR (HL)
- data = READ( rp.hl );
- pc--;
- case 0xF6: // OR IMM
- pc++;
- or_comm:
- rg.a |= data;
- case 0xB7: // OR A
- flags = ((rg.a - 1) >> 1) & z_flag;
- goto loop;
-
- case 0xA8: // XOR B
- case 0xA9: // XOR C
- case 0xAA: // XOR D
- case 0xAB: // XOR E
- case 0xAC: // XOR H
- case 0xAD: // XOR L
- data = R8( op & 7 );
- goto xor_comm;
-
- case 0xAE: // XOR (HL)
- data = READ( rp.hl );
- pc--;
- case 0xEE: // XOR IMM
- pc++;
- xor_comm:
- data ^= rg.a;
- rg.a = data;
- data--;
- flags = (data >> 1) & z_flag;
- goto loop;
-
- case 0xAF: // XOR A
- rg.a = 0;
- flags = z_flag;
- goto loop;
-
-// Stack
-
- case 0xF1: // POP FA
- case 0xC1: // POP BC
- case 0xD1: // POP DE
- case 0xE1: // POP HL (common)
- data = READ( sp );
- r16 [(op >> 4) & 3] = data + 0x100 * READ( sp + 1 );
- sp = (sp + 2) & 0xFFFF;
- if ( op != 0xF1 )
- goto loop;
- flags = rg.flags & 0xF0;
- goto loop;
-
- case 0xC5: // PUSH BC
- data = rp.bc;
- goto push;
-
- case 0xD5: // PUSH DE
- data = rp.de;
- goto push;
-
- case 0xE5: // PUSH HL
- data = rp.hl;
- goto push;
-
- case 0xF5: // PUSH FA
- data = (flags << 8) | rg.a;
- goto push;
-
-// Flow control
-
- case 0xFF:
- if ( pc == idle_addr + 1 )
- goto stop;
- case 0xC7: case 0xCF: case 0xD7: case 0xDF: // RST
- case 0xE7: case 0xEF: case 0xF7:
- data = pc;
- pc = (op & 0x38) + rst_base;
- goto push;
-
- case 0xCC: // CZ
- pc += 2;
- if ( flags & z_flag )
- goto call;
- goto loop;
-
- case 0xD4: // CNC
- pc += 2;
- if ( !(flags & c_flag) )
- goto call;
- goto loop;
-
- case 0xDC: // CC
- pc += 2;
- if ( flags & c_flag )
- goto call;
- goto loop;
-
- case 0xD9: // RETI
- //interrupts_enabled = 1;
- goto ret;
-
- case 0xC0: // RZ
- if ( !(flags & z_flag) )
- goto ret;
- goto loop;
-
- case 0xD0: // RNC
- if ( !(flags & c_flag) )
- goto ret;
- goto loop;
-
- case 0xD8: // RC
- if ( flags & c_flag )
- goto ret;
- goto loop;
-
- case 0x18: // JR
- BRANCH( true )
-
- case 0x30: // JR NC
- BRANCH( !(flags & c_flag) )
-
- case 0x38: // JR C
- BRANCH( flags & c_flag )
-
- case 0xE9: // JP_HL
- pc = rp.hl;
- goto loop;
-
- case 0xC3: // JP (next-most-common)
- pc = GET_ADDR();
- goto loop;
-
- case 0xC2: // JP NZ
- pc += 2;
- if ( !(flags & z_flag) )
- goto jp_taken;
- goto loop;
-
- case 0xCA: // JP Z (most common)
- pc += 2;
- if ( !(flags & z_flag) )
- goto loop;
- jp_taken:
- pc -= 2;
- pc = GET_ADDR();
- goto loop;
-
- case 0xD2: // JP NC
- pc += 2;
- if ( !(flags & c_flag) )
- goto jp_taken;
- goto loop;
-
- case 0xDA: // JP C
- pc += 2;
- if ( flags & c_flag )
- goto jp_taken;
- goto loop;
-
-// Flags
-
- case 0x2F: // CPL
- rg.a = ~rg.a;
- flags |= n_flag | h_flag;
- goto loop;
-
- case 0x3F: // CCF
- flags = (flags ^ c_flag) & ~(n_flag | h_flag);
- goto loop;
-
- case 0x37: // SCF
- flags = (flags | c_flag) & ~(n_flag | h_flag);
- goto loop;
-
- case 0xF3: // DI
- //interrupts_enabled = 0;
- goto loop;
-
- case 0xFB: // EI
- //interrupts_enabled = 1;
- goto loop;
-
-// Special
-
- case 0xDD: case 0xD3: case 0xDB: case 0xE3: case 0xE4: // ?
- case 0xEB: case 0xEC: case 0xF4: case 0xFD: case 0xFC:
- case 0x10: // STOP
- case 0x27: // DAA (I'll have to implement this eventually...)
- case 0xBF:
- case 0xED: // Z80 prefix
- case 0x76: // HALT
- s.remain++;
- goto stop;
- }
-
- // If this fails then the case above is missing an opcode
- assert( false );
-
-stop:
- pc--;
-
- // copy state back
- STATIC_CAST(core_regs_t&,r) = rg;
- r.pc = pc;
- r.sp = sp;
- r.flags = flags;
-
- this->state = &state_;
- memcpy( &this->state_, &s, sizeof this->state_ );
-
- return s.remain > 0;
-}
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Gb_Cpu.h b/plugins/gme/game-music-emu-0.5.5/gme/Gb_Cpu.h
deleted file mode 100644
index 9d623e04..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Gb_Cpu.h
+++ /dev/null
@@ -1,93 +0,0 @@
-// Nintendo Game Boy CPU emulator
-// Treats every instruction as taking 4 cycles
-
-// Game_Music_Emu 0.5.5
-#ifndef GB_CPU_H
-#define GB_CPU_H
-
-#include "blargg_common.h"
-#include "blargg_endian.h"
-
-typedef unsigned gb_addr_t; // 16-bit CPU address
-
-class Gb_Cpu {
- enum { clocks_per_instr = 4 };
-public:
- typedef BOOST::uint8_t uint8_t;
-
- // Clear registers and map all pages to unmapped
- void reset( void* unmapped = 0 );
-
- // Map code memory (memory accessed via the program counter). Start and size
- // must be multiple of page_size.
- enum { page_size = 0x2000 };
- void map_code( gb_addr_t start, unsigned size, void* code );
-
- uint8_t* get_code( gb_addr_t );
-
- // Push a byte on the stack
- void push_byte( int );
-
- // Game Boy Z80 registers. *Not* kept updated during a call to run().
- struct core_regs_t {
- #if BLARGG_BIG_ENDIAN
- uint8_t b, c, d, e, h, l, flags, a;
- #else
- uint8_t c, b, e, d, l, h, a, flags;
- #endif
- };
-
- struct registers_t : core_regs_t {
- long pc; // more than 16 bits to allow overflow detection
- BOOST::uint16_t sp;
- };
- registers_t r;
-
- // Interrupt enable flag set by EI and cleared by DI
- //bool interrupts_enabled; // unused
-
- // Base address for RST vectors (normally 0)
- gb_addr_t rst_base;
-
- // If CPU executes opcode 0xFF at this address, it treats as illegal instruction
- enum { idle_addr = 0xF00D };
-
- // Run CPU for at least 'count' cycles and return false, or return true if
- // illegal instruction is encountered.
- bool run( blargg_long count );
-
- // Number of clock cycles remaining for most recent run() call
- blargg_long remain() const { return state->remain * clocks_per_instr; }
-
- // Can read this many bytes past end of a page
- enum { cpu_padding = 8 };
-
-public:
- Gb_Cpu() : rst_base( 0 ) { state = &state_; }
- enum { page_shift = 13 };
- enum { page_count = 0x10000 >> page_shift };
-private:
- // noncopyable
- Gb_Cpu( const Gb_Cpu& );
- Gb_Cpu& operator = ( const Gb_Cpu& );
-
- struct state_t {
- uint8_t* code_map [page_count + 1];
- blargg_long remain;
- };
- state_t* state; // points to state_ or a local copy within run()
- state_t state_;
-
- void set_code_page( int, uint8_t* );
-};
-
-inline BOOST::uint8_t* Gb_Cpu::get_code( gb_addr_t addr )
-{
- return state->code_map [addr >> page_shift] + addr
- #if !BLARGG_NONPORTABLE
- % (unsigned) page_size
- #endif
- ;
-}
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Gb_Oscs.cpp b/plugins/gme/game-music-emu-0.5.5/gme/Gb_Oscs.cpp
deleted file mode 100644
index 735653fa..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Gb_Oscs.cpp
+++ /dev/null
@@ -1,336 +0,0 @@
-// Gb_Snd_Emu 0.1.5. http://www.slack.net/~ant/
-
-#include "Gb_Apu.h"
-
-#include <string.h>
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-// Gb_Osc
-
-void Gb_Osc::reset()
-{
- delay = 0;
- last_amp = 0;
- length = 0;
- output_select = 3;
- output = outputs [output_select];
-}
-
-void Gb_Osc::clock_length()
-{
- if ( (regs [4] & len_enabled_mask) && length )
- length--;
-}
-
-// Gb_Env
-
-void Gb_Env::clock_envelope()
-{
- if ( env_delay && !--env_delay )
- {
- env_delay = regs [2] & 7;
- int v = volume - 1 + (regs [2] >> 2 & 2);
- if ( (unsigned) v < 15 )
- volume = v;
- }
-}
-
-bool Gb_Env::write_register( int reg, int data )
-{
- switch ( reg )
- {
- case 1:
- length = 64 - (regs [1] & 0x3F);
- break;
-
- case 2:
- if ( !(data >> 4) )
- enabled = false;
- break;
-
- case 4:
- if ( data & trigger )
- {
- env_delay = regs [2] & 7;
- volume = regs [2] >> 4;
- enabled = true;
- if ( length == 0 )
- length = 64;
- return true;
- }
- }
- return false;
-}
-
-// Gb_Square
-
-void Gb_Square::reset()
-{
- phase = 0;
- sweep_freq = 0;
- sweep_delay = 0;
- Gb_Env::reset();
-}
-
-void Gb_Square::clock_sweep()
-{
- int sweep_period = (regs [0] & period_mask) >> 4;
- if ( sweep_period && sweep_delay && !--sweep_delay )
- {
- sweep_delay = sweep_period;
- regs [3] = sweep_freq & 0xFF;
- regs [4] = (regs [4] & ~0x07) | (sweep_freq >> 8 & 0x07);
-
- int offset = sweep_freq >> (regs [0] & shift_mask);
- if ( regs [0] & 0x08 )
- offset = -offset;
- sweep_freq += offset;
-
- if ( sweep_freq < 0 )
- {
- sweep_freq = 0;
- }
- else if ( sweep_freq >= 2048 )
- {
- sweep_delay = 0; // don't modify channel frequency any further
- sweep_freq = 2048; // silence sound immediately
- }
- }
-}
-
-void Gb_Square::run( blip_time_t time, blip_time_t end_time, int playing )
-{
- if ( sweep_freq == 2048 )
- playing = false;
-
- static unsigned char const table [4] = { 1, 2, 4, 6 };
- int const duty = table [regs [1] >> 6];
- int amp = volume & playing;
- if ( phase >= duty )
- amp = -amp;
-
- int frequency = this->frequency();
- if ( unsigned (frequency - 1) > 2040 ) // frequency < 1 || frequency > 2041
- {
- // really high frequency results in DC at half volume
- amp = volume >> 1;
- playing = false;
- }
-
- {
- int delta = amp - last_amp;
- if ( delta )
- {
- last_amp = amp;
- synth->offset( time, delta, output );
- }
- }
-
- time += delay;
- if ( !playing )
- time = end_time;
-
- if ( time < end_time )
- {
- int const period = (2048 - frequency) * 4;
- Blip_Buffer* const output = this->output;
- int phase = this->phase;
- int delta = amp * 2;
- do
- {
- phase = (phase + 1) & 7;
- if ( phase == 0 || phase == duty )
- {
- delta = -delta;
- synth->offset_inline( time, delta, output );
- }
- time += period;
- }
- while ( time < end_time );
-
- this->phase = phase;
- last_amp = delta >> 1;
- }
- delay = time - end_time;
-}
-
-// Gb_Noise
-
-void Gb_Noise::run( blip_time_t time, blip_time_t end_time, int playing )
-{
- int amp = volume & playing;
- int tap = 13 - (regs [3] & 8);
- if ( bits >> tap & 2 )
- amp = -amp;
-
- {
- int delta = amp - last_amp;
- if ( delta )
- {
- last_amp = amp;
- synth->offset( time, delta, output );
- }
- }
-
- time += delay;
- if ( !playing )
- time = end_time;
-
- if ( time < end_time )
- {
- static unsigned char const table [8] = { 8, 16, 32, 48, 64, 80, 96, 112 };
- int period = table [regs [3] & 7] << (regs [3] >> 4);
-
- // keep parallel resampled time to eliminate time conversion in the loop
- Blip_Buffer* const output = this->output;
- const blip_resampled_time_t resampled_period =
- output->resampled_duration( period );
- blip_resampled_time_t resampled_time = output->resampled_time( time );
- unsigned bits = this->bits;
- int delta = amp * 2;
-
- do
- {
- unsigned changed = (bits >> tap) + 1;
- time += period;
- bits <<= 1;
- if ( changed & 2 )
- {
- delta = -delta;
- bits |= 1;
- synth->offset_resampled( resampled_time, delta, output );
- }
- resampled_time += resampled_period;
- }
- while ( time < end_time );
-
- this->bits = bits;
- last_amp = delta >> 1;
- }
- delay = time - end_time;
-}
-
-// Gb_Wave
-
-inline void Gb_Wave::write_register( int reg, int data )
-{
- switch ( reg )
- {
- case 0:
- if ( !(data & 0x80) )
- enabled = false;
- break;
-
- case 1:
- length = 256 - regs [1];
- break;
-
- case 2:
- volume = data >> 5 & 3;
- break;
-
- case 4:
- if ( data & trigger & regs [0] )
- {
- wave_pos = 0;
- enabled = true;
- if ( length == 0 )
- length = 256;
- }
- }
-}
-
-void Gb_Wave::run( blip_time_t time, blip_time_t end_time, int playing )
-{
- int volume_shift = (volume - 1) & 7; // volume = 0 causes shift = 7
- int frequency;
- {
- int amp = (wave [wave_pos] >> volume_shift & playing) * 2;
-
- frequency = this->frequency();
- if ( unsigned (frequency - 1) > 2044 ) // frequency < 1 || frequency > 2045
- {
- amp = 30 >> volume_shift & playing;
- playing = false;
- }
-
- int delta = amp - last_amp;
- if ( delta )
- {
- last_amp = amp;
- synth->offset( time, delta, output );
- }
- }
-
- time += delay;
- if ( !playing )
- time = end_time;
-
- if ( time < end_time )
- {
- Blip_Buffer* const output = this->output;
- int const period = (2048 - frequency) * 2;
- int wave_pos = (this->wave_pos + 1) & (wave_size - 1);
-
- do
- {
- int amp = (wave [wave_pos] >> volume_shift) * 2;
- wave_pos = (wave_pos + 1) & (wave_size - 1);
- int delta = amp - last_amp;
- if ( delta )
- {
- last_amp = amp;
- synth->offset_inline( time, delta, output );
- }
- time += period;
- }
- while ( time < end_time );
-
- this->wave_pos = (wave_pos - 1) & (wave_size - 1);
- }
- delay = time - end_time;
-}
-
-// Gb_Apu::write_osc
-
-void Gb_Apu::write_osc( int index, int reg, int data )
-{
- reg -= index * 5;
- Gb_Square* sq = &square2;
- switch ( index )
- {
- case 0:
- sq = &square1;
- case 1:
- if ( sq->write_register( reg, data ) && index == 0 )
- {
- square1.sweep_freq = square1.frequency();
- if ( (regs [0] & sq->period_mask) && (regs [0] & sq->shift_mask) )
- {
- square1.sweep_delay = 1; // cause sweep to recalculate now
- square1.clock_sweep();
- }
- }
- break;
-
- case 2:
- wave.write_register( reg, data );
- break;
-
- case 3:
- if ( noise.write_register( reg, data ) )
- noise.bits = 0x7FFF;
- }
-}
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Gb_Oscs.h b/plugins/gme/game-music-emu-0.5.5/gme/Gb_Oscs.h
deleted file mode 100644
index d7f88ea1..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Gb_Oscs.h
+++ /dev/null
@@ -1,83 +0,0 @@
-// Private oscillators used by Gb_Apu
-
-// Gb_Snd_Emu 0.1.5
-#ifndef GB_OSCS_H
-#define GB_OSCS_H
-
-#include "blargg_common.h"
-#include "Blip_Buffer.h"
-
-struct Gb_Osc
-{
- enum { trigger = 0x80 };
- enum { len_enabled_mask = 0x40 };
-
- Blip_Buffer* outputs [4]; // NULL, right, left, center
- Blip_Buffer* output;
- int output_select;
- BOOST::uint8_t* regs; // osc's 5 registers
-
- int delay;
- int last_amp;
- int volume;
- int length;
- int enabled;
-
- void reset();
- void clock_length();
- int frequency() const { return (regs [4] & 7) * 0x100 + regs [3]; }
-};
-
-struct Gb_Env : Gb_Osc
-{
- int env_delay;
-
- void reset();
- void clock_envelope();
- bool write_register( int, int );
-};
-
-struct Gb_Square : Gb_Env
-{
- enum { period_mask = 0x70 };
- enum { shift_mask = 0x07 };
-
- typedef Blip_Synth<blip_good_quality,1> Synth;
- Synth const* synth;
- int sweep_delay;
- int sweep_freq;
- int phase;
-
- void reset();
- void clock_sweep();
- void run( blip_time_t, blip_time_t, int playing );
-};
-
-struct Gb_Noise : Gb_Env
-{
- typedef Blip_Synth<blip_med_quality,1> Synth;
- Synth const* synth;
- unsigned bits;
-
- void run( blip_time_t, blip_time_t, int playing );
-};
-
-struct Gb_Wave : Gb_Osc
-{
- typedef Blip_Synth<blip_med_quality,1> Synth;
- Synth const* synth;
- int wave_pos;
- enum { wave_size = 32 };
- BOOST::uint8_t wave [wave_size];
-
- void write_register( int, int );
- void run( blip_time_t, blip_time_t, int playing );
-};
-
-inline void Gb_Env::reset()
-{
- env_delay = 0;
- Gb_Osc::reset();
-}
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Gbs_Emu.cpp b/plugins/gme/game-music-emu-0.5.5/gme/Gbs_Emu.cpp
deleted file mode 100644
index ceb526e5..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Gbs_Emu.cpp
+++ /dev/null
@@ -1,289 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Gbs_Emu.h"
-
-#include "blargg_endian.h"
-#include <string.h>
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-Gbs_Emu::equalizer_t const Gbs_Emu::handheld_eq = { -47.0, 2000 };
-Gbs_Emu::equalizer_t const Gbs_Emu::headphones_eq = { 0.0, 300 };
-
-Gbs_Emu::Gbs_Emu()
-{
- set_type( gme_gbs_type );
-
- static const char* const names [Gb_Apu::osc_count] = {
- "Square 1", "Square 2", "Wave", "Noise"
- };
- set_voice_names( names );
-
- static int const types [Gb_Apu::osc_count] = {
- wave_type | 1, wave_type | 2, wave_type | 0, mixed_type | 0
- };
- set_voice_types( types );
-
- set_silence_lookahead( 6 );
- set_max_initial_silence( 21 );
- set_gain( 1.2 );
-
- static equalizer_t const eq = { -1.0, 120 };
- set_equalizer( eq );
-}
-
-Gbs_Emu::~Gbs_Emu() { }
-
-void Gbs_Emu::unload()
-{
- rom.clear();
- Music_Emu::unload();
-}
-
-// Track info
-
-static void copy_gbs_fields( Gbs_Emu::header_t const& h, track_info_t* out )
-{
- GME_COPY_FIELD( h, out, game );
- GME_COPY_FIELD( h, out, author );
- GME_COPY_FIELD( h, out, copyright );
-}
-
-blargg_err_t Gbs_Emu::track_info_( track_info_t* out, int ) const
-{
- copy_gbs_fields( header_, out );
- return 0;
-}
-
-static blargg_err_t check_gbs_header( void const* header )
-{
- if ( memcmp( header, "GBS", 3 ) )
- return gme_wrong_file_type;
- return 0;
-}
-
-struct Gbs_File : Gme_Info_
-{
- Gbs_Emu::header_t h;
-
- Gbs_File() { set_type( gme_gbs_type ); }
-
- blargg_err_t load_( Data_Reader& in )
- {
- blargg_err_t err = in.read( &h, Gbs_Emu::header_size );
- if ( err )
- return (err == in.eof_error ? gme_wrong_file_type : err);
-
- set_track_count( h.track_count );
- return check_gbs_header( &h );
- }
-
- blargg_err_t track_info_( track_info_t* out, int ) const
- {
- copy_gbs_fields( h, out );
- return 0;
- }
-};
-
-static Music_Emu* new_gbs_emu () { return BLARGG_NEW Gbs_Emu ; }
-static Music_Emu* new_gbs_file() { return BLARGG_NEW Gbs_File; }
-
-static gme_type_t_ const gme_gbs_type_ = { "Game Boy", 0, &new_gbs_emu, &new_gbs_file, "GBS", 1 };
-gme_type_t const gme_gbs_type = &gme_gbs_type_;
-
-// Setup
-
-blargg_err_t Gbs_Emu::load_( Data_Reader& in )
-{
- assert( offsetof (header_t,copyright [32]) == header_size );
- RETURN_ERR( rom.load( in, header_size, &header_, 0 ) );
-
- set_track_count( header_.track_count );
- RETURN_ERR( check_gbs_header( &header_ ) );
-
- if ( header_.vers != 1 )
- set_warning( "Unknown file version" );
-
- if ( header_.timer_mode & 0x78 )
- set_warning( "Invalid timer mode" );
-
- unsigned load_addr = get_le16( header_.load_addr );
- if ( (header_.load_addr [1] | header_.init_addr [1] | header_.play_addr [1]) > 0x7F ||
- load_addr < 0x400 )
- set_warning( "Invalid load/init/play address" );
-
- set_voice_count( Gb_Apu::osc_count );
-
- apu.volume( gain() );
-
- return setup_buffer( 4194304 );
-}
-
-void Gbs_Emu::update_eq( blip_eq_t const& eq )
-{
- apu.treble_eq( eq );
-}
-
-void Gbs_Emu::set_voice( int i, Blip_Buffer* c, Blip_Buffer* l, Blip_Buffer* r )
-{
- apu.osc_output( i, c, l, r );
-}
-
-// Emulation
-
-// see gb_cpu_io.h for read/write functions
-
-void Gbs_Emu::set_bank( int n )
-{
- blargg_long addr = rom.mask_addr( n * (blargg_long) bank_size );
- if ( addr == 0 && rom.size() > bank_size )
- {
- // TODO: what is the correct behavior? Current Game & Watch Gallery
- // rip requires that this have no effect or set to bank 1.
- //debug_printf( "Selected ROM bank 0\n" );
- return;
- //n = 1;
- }
- cpu::map_code( bank_size, bank_size, rom.at_addr( addr ) );
-}
-
-void Gbs_Emu::update_timer()
-{
- if ( header_.timer_mode & 0x04 )
- {
- static byte const rates [4] = { 10, 4, 6, 8 };
- int shift = rates [ram [hi_page + 7] & 3] - (header_.timer_mode >> 7);
- play_period = (256L - ram [hi_page + 6]) << shift;
- }
- else
- {
- play_period = 70224; // 59.73 Hz
- }
- if ( tempo() != 1.0 )
- play_period = blip_time_t (play_period / tempo());
-}
-
-static BOOST::uint8_t const sound_data [Gb_Apu::register_count] = {
- 0x80, 0xBF, 0x00, 0x00, 0xBF, // square 1
- 0x00, 0x3F, 0x00, 0x00, 0xBF, // square 2
- 0x7F, 0xFF, 0x9F, 0x00, 0xBF, // wave
- 0x00, 0xFF, 0x00, 0x00, 0xBF, // noise
- 0x77, 0xF3, 0xF1, // vin/volume, status, power mode
- 0, 0, 0, 0, 0, 0, 0, 0, 0, // unused
- 0xAC, 0xDD, 0xDA, 0x48, 0x36, 0x02, 0xCF, 0x16, // waveform data
- 0x2C, 0x04, 0xE5, 0x2C, 0xAC, 0xDD, 0xDA, 0x48
-};
-
-void Gbs_Emu::cpu_jsr( gb_addr_t addr )
-{
- check( cpu::r.sp == get_le16( header_.stack_ptr ) );
- cpu::r.pc = addr;
- cpu_write( --cpu::r.sp, idle_addr >> 8 );
- cpu_write( --cpu::r.sp, idle_addr&0xFF );
-}
-
-void Gbs_Emu::set_tempo_( double t )
-{
- apu.set_tempo( t );
- update_timer();
-}
-
-blargg_err_t Gbs_Emu::start_track_( int track )
-{
- RETURN_ERR( Classic_Emu::start_track_( track ) );
-
- memset( ram, 0, 0x4000 );
- memset( ram + 0x4000, 0xFF, 0x1F80 );
- memset( ram + 0x5F80, 0, sizeof ram - 0x5F80 );
- ram [hi_page] = 0; // joypad reads back as 0
-
- apu.reset();
- for ( int i = 0; i < (int) sizeof sound_data; i++ )
- apu.write_register( 0, i + apu.start_addr, sound_data [i] );
-
- cpu::reset( rom.unmapped() );
-
- unsigned load_addr = get_le16( header_.load_addr );
- cpu::rst_base = load_addr;
- rom.set_addr( load_addr );
-
- cpu::map_code( ram_addr, 0x10000 - ram_addr, ram );
- cpu::map_code( 0, bank_size, rom.at_addr( 0 ) );
- set_bank( rom.size() > bank_size );
-
- ram [hi_page + 6] = header_.timer_modulo;
- ram [hi_page + 7] = header_.timer_mode;
- update_timer();
- next_play = play_period;
-
- cpu::r.a = track;
- cpu::r.pc = idle_addr;
- cpu::r.sp = get_le16( header_.stack_ptr );
- cpu_time = 0;
- cpu_jsr( get_le16( header_.init_addr ) );
-
- return 0;
-}
-
-blargg_err_t Gbs_Emu::run_clocks( blip_time_t& duration, int )
-{
- cpu_time = 0;
- while ( cpu_time < duration )
- {
- long count = duration - cpu_time;
- cpu_time = duration;
- bool result = cpu::run( count );
- cpu_time -= cpu::remain();
-
- if ( result )
- {
- if ( cpu::r.pc == idle_addr )
- {
- if ( next_play > duration )
- {
- cpu_time = duration;
- break;
- }
-
- if ( cpu_time < next_play )
- cpu_time = next_play;
- next_play += play_period;
- cpu_jsr( get_le16( header_.play_addr ) );
- GME_FRAME_HOOK( this );
- // TODO: handle timer rates different than 60 Hz
- }
- else if ( cpu::r.pc > 0xFFFF )
- {
- debug_printf( "PC wrapped around\n" );
- cpu::r.pc &= 0xFFFF;
- }
- else
- {
- set_warning( "Emulation error (illegal/unsupported instruction)" );
- debug_printf( "Bad opcode $%.2x at $%.4x\n",
- (int) *cpu::get_code( cpu::r.pc ), (int) cpu::r.pc );
- cpu::r.pc = (cpu::r.pc + 1) & 0xFFFF;
- cpu_time += 6;
- }
- }
- }
-
- duration = cpu_time;
- next_play -= cpu_time;
- if ( next_play < 0 ) // could go negative if routine is taking too long to return
- next_play = 0;
- apu.end_frame( cpu_time );
-
- return 0;
-}
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Gbs_Emu.h b/plugins/gme/game-music-emu-0.5.5/gme/Gbs_Emu.h
deleted file mode 100644
index f3318dc8..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Gbs_Emu.h
+++ /dev/null
@@ -1,88 +0,0 @@
-// Nintendo Game Boy GBS music file emulator
-
-// Game_Music_Emu 0.5.5
-#ifndef GBS_EMU_H
-#define GBS_EMU_H
-
-#include "Classic_Emu.h"
-#include "Gb_Apu.h"
-#include "Gb_Cpu.h"
-
-class Gbs_Emu : private Gb_Cpu, public Classic_Emu {
- typedef Gb_Cpu cpu;
-public:
- // Equalizer profiles for Game Boy Color speaker and headphones
- static equalizer_t const handheld_eq;
- static equalizer_t const headphones_eq;
-
- // GBS file header
- enum { header_size = 112 };
- struct header_t
- {
- char tag [3];
- byte vers;
- byte track_count;
- byte first_track;
- byte load_addr [2];
- byte init_addr [2];
- byte play_addr [2];
- byte stack_ptr [2];
- byte timer_modulo;
- byte timer_mode;
- char game [32];
- char author [32];
- char copyright [32];
- };
-
- // Header for currently loaded file
- header_t const& header() const { return header_; }
-
- static gme_type_t static_type() { return gme_gbs_type; }
-
-public:
- // deprecated
- Music_Emu::load;
- blargg_err_t load( header_t const& h, Data_Reader& in ) // use Remaining_Reader
- { return load_remaining_( &h, sizeof h, in ); }
-
-public:
- Gbs_Emu();
- ~Gbs_Emu();
-protected:
- blargg_err_t track_info_( track_info_t*, int track ) const;
- blargg_err_t load_( Data_Reader& );
- blargg_err_t start_track_( int );
- blargg_err_t run_clocks( blip_time_t&, int );
- void set_tempo_( double );
- void set_voice( int, Blip_Buffer*, Blip_Buffer*, Blip_Buffer* );
- void update_eq( blip_eq_t const& );
- void unload();
-private:
- // rom
- enum { bank_size = 0x4000 };
- Rom_Data<bank_size> rom;
- void set_bank( int );
-
- // timer
- blip_time_t cpu_time;
- blip_time_t play_period;
- blip_time_t next_play;
- void update_timer();
-
- header_t header_;
- void cpu_jsr( gb_addr_t );
-
-public: private: friend class Gb_Cpu;
- blip_time_t clock() const { return cpu_time - cpu::remain(); }
-
- enum { joypad_addr = 0xFF00 };
- enum { ram_addr = 0xA000 };
- enum { hi_page = 0xFF00 - ram_addr };
- byte ram [0x4000 + 0x2000 + Gb_Cpu::cpu_padding];
- Gb_Apu apu;
-
- int cpu_read( gb_addr_t );
- void cpu_write( gb_addr_t, int );
-};
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Gme_File.cpp b/plugins/gme/game-music-emu-0.5.5/gme/Gme_File.cpp
deleted file mode 100644
index 17edc9f8..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Gme_File.cpp
+++ /dev/null
@@ -1,216 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Gme_File.h"
-
-#include "blargg_endian.h"
-#include <string.h>
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-const char* const gme_wrong_file_type = "Wrong file type for this emulator";
-
-void Gme_File::clear_playlist()
-{
- playlist.clear();
- clear_playlist_();
- track_count_ = raw_track_count_;
-}
-
-void Gme_File::unload()
-{
- clear_playlist(); // *before* clearing track count
- track_count_ = 0;
- raw_track_count_ = 0;
- file_data.clear();
-}
-
-Gme_File::Gme_File()
-{
- type_ = 0;
- user_data_ = 0;
- user_cleanup_ = 0;
- unload(); // clears fields
- blargg_verify_byte_order(); // used by most emulator types, so save them the trouble
-}
-
-Gme_File::~Gme_File()
-{
- if ( user_cleanup_ )
- user_cleanup_( user_data_ );
-}
-
-blargg_err_t Gme_File::load_mem_( byte const* data, long size )
-{
- require( data != file_data.begin() ); // load_mem_() or load_() must be overridden
- Mem_File_Reader in( data, size );
- return load_( in );
-}
-
-blargg_err_t Gme_File::load_( Data_Reader& in )
-{
- RETURN_ERR( file_data.resize( in.remain() ) );
- RETURN_ERR( in.read( file_data.begin(), file_data.size() ) );
- return load_mem_( file_data.begin(), file_data.size() );
-}
-
-// public load functions call this at beginning
-void Gme_File::pre_load() { unload(); }
-
-void Gme_File::post_load_() { }
-
-// public load functions call this at end
-blargg_err_t Gme_File::post_load( blargg_err_t err )
-{
- if ( !track_count() )
- set_track_count( type()->track_count );
- if ( !err )
- post_load_();
- else
- unload();
-
- return err;
-}
-
-// Public load functions
-
-blargg_err_t Gme_File::load_mem( void const* in, long size )
-{
- pre_load();
- return post_load( load_mem_( (byte const*) in, size ) );
-}
-
-blargg_err_t Gme_File::load( Data_Reader& in )
-{
- pre_load();
- return post_load( load_( in ) );
-}
-
-blargg_err_t Gme_File::load_file( const char* path )
-{
- pre_load();
- GME_FILE_READER in;
- RETURN_ERR( in.open( path ) );
- return post_load( load_( in ) );
-}
-
-blargg_err_t Gme_File::load_remaining_( void const* h, long s, Data_Reader& in )
-{
- Remaining_Reader rem( h, s, &in );
- return load( rem );
-}
-
-// Track info
-
-void Gme_File::copy_field_( char* out, const char* in, int in_size )
-{
- if ( !in || !*in )
- return;
-
- // remove spaces/junk from beginning
- while ( in_size && unsigned (*in - 1) <= ' ' - 1 )
- {
- in++;
- in_size--;
- }
-
- // truncate
- if ( in_size > max_field_ )
- in_size = max_field_;
-
- // find terminator
- int len = 0;
- while ( len < in_size && in [len] )
- len++;
-
- // remove spaces/junk from end
- while ( len && unsigned (in [len - 1]) <= ' ' )
- len--;
-
- // copy
- out [len] = 0;
- memcpy( out, in, len );
-
- // strip out stupid fields that should have been left blank
- if ( !strcmp( out, "?" ) || !strcmp( out, "<?>" ) || !strcmp( out, "< ? >" ) )
- out [0] = 0;
-}
-
-void Gme_File::copy_field_( char* out, const char* in )
-{
- copy_field_( out, in, max_field_ );
-}
-
-blargg_err_t Gme_File::remap_track_( int* track_io ) const
-{
- if ( (unsigned) *track_io >= (unsigned) track_count() )
- return "Invalid track";
-
- if ( (unsigned) *track_io < (unsigned) playlist.size() )
- {
- M3u_Playlist::entry_t const& e = playlist [*track_io];
- *track_io = 0;
- if ( e.track >= 0 )
- {
- *track_io = e.track;
- if ( !(type_->flags_ & 0x02) )
- *track_io -= e.decimal_track;
- }
- if ( *track_io >= raw_track_count_ )
- return "Invalid track in m3u playlist";
- }
- else
- {
- check( !playlist.size() );
- }
- return 0;
-}
-
-blargg_err_t Gme_File::track_info( track_info_t* out, int track ) const
-{
- out->track_count = track_count();
- out->length = -1;
- out->loop_length = -1;
- out->intro_length = -1;
- out->song [0] = 0;
-
- out->game [0] = 0;
- out->author [0] = 0;
- out->copyright [0] = 0;
- out->comment [0] = 0;
- out->dumper [0] = 0;
- out->system [0] = 0;
-
- copy_field_( out->system, type()->system );
-
- int remapped = track;
- RETURN_ERR( remap_track_( &remapped ) );
- RETURN_ERR( track_info_( out, remapped ) );
-
- // override with m3u info
- if ( playlist.size() )
- {
- M3u_Playlist::info_t const& i = playlist.info();
- copy_field_( out->game , i.title );
- copy_field_( out->author, i.engineer );
- copy_field_( out->author, i.composer );
- copy_field_( out->dumper, i.ripping );
-
- M3u_Playlist::entry_t const& e = playlist [track];
- copy_field_( out->song, e.name );
- if ( e.length >= 0 ) out->length = e.length * 1000L;
- if ( e.intro >= 0 ) out->intro_length = e.intro * 1000L;
- if ( e.loop >= 0 ) out->loop_length = e.loop * 1000L;
- }
- return 0;
-}
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Gme_File.h b/plugins/gme/game-music-emu-0.5.5/gme/Gme_File.h
deleted file mode 100644
index f50dceae..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Gme_File.h
+++ /dev/null
@@ -1,159 +0,0 @@
-// Common interface to game music file loading and information
-
-// Game_Music_Emu 0.5.5
-#ifndef GME_FILE_H
-#define GME_FILE_H
-
-#include "gme.h"
-#include "blargg_common.h"
-#include "Data_Reader.h"
-#include "M3u_Playlist.h"
-
-// Error returned if file is wrong type
-//extern const char gme_wrong_file_type []; // declared in gme.h
-
-struct gme_type_t_
-{
- const char* system; /* name of system this music file type is generally for */
- int track_count; /* non-zero for formats with a fixed number of tracks */
- Music_Emu* (*new_emu)(); /* Create new emulator for this type (useful in C++ only) */
- Music_Emu* (*new_info)(); /* Create new info reader for this type */
-
- /* internal */
- const char* extension_;
- int flags_;
-};
-
-enum { gme_max_field = 255 };
-
-struct Gme_File {
-public:
-// File loading
-
- // Each loads game music data from a file and returns an error if
- // file is wrong type or is seriously corrupt. They also set warning
- // string for minor problems.
-
- // Load from file on disk
- blargg_err_t load_file( const char* path );
-
- // Load from custom data source (see Data_Reader.h)
- blargg_err_t load( Data_Reader& );
-
- // Load from file already read into memory. Keeps pointer to data, so you
- // must not free it until you're done with the file.
- blargg_err_t load_mem( void const* data, long size );
-
- // Load an m3u playlist. Must be done after loading main music file.
- blargg_err_t load_m3u( const char* path );
- blargg_err_t load_m3u( Data_Reader& in );
-
- // Clears any loaded m3u playlist and any internal playlist that the music
- // format supports (NSFE for example).
- void clear_playlist();
-
-// Informational
-
- // Type of emulator. For example if this returns gme_nsfe_type, this object
- // is an NSFE emulator, and you can cast to an Nsfe_Emu* if necessary.
- gme_type_t type() const;
-
- // Most recent warning string, or NULL if none. Clears current warning after
- // returning.
- const char* warning();
-
- // Number of tracks or 0 if no file has been loaded
- int track_count() const;
-
- // Get information for a track (length, name, author, etc.)
- // See gme.h for definition of struct track_info_t.
- blargg_err_t track_info( track_info_t* out, int track ) const;
-
-// User data/cleanup
-
- // Set/get pointer to data you want to associate with this emulator.
- // You can use this for whatever you want.
- void set_user_data( void* p ) { user_data_ = p; }
- void* user_data() const { return user_data_; }
-
- // Register cleanup function to be called when deleting emulator, or NULL to
- // clear it. Passes user_data to cleanup function.
- void set_user_cleanup( gme_user_cleanup_t func ) { user_cleanup_ = func; }
-
-public:
- // deprecated
- int error_count() const; // use warning()
-public:
- Gme_File();
- virtual ~Gme_File();
- BLARGG_DISABLE_NOTHROW
- typedef BOOST::uint8_t byte;
-protected:
- // Services
- void set_track_count( int n ) { track_count_ = raw_track_count_ = n; }
- void set_warning( const char* s ) { warning_ = s; }
- void set_type( gme_type_t t ) { type_ = t; }
- blargg_err_t load_remaining_( void const* header, long header_size, Data_Reader& remaining );
-
- // Overridable
- virtual void unload(); // called before loading file and if loading fails
- virtual blargg_err_t load_( Data_Reader& ); // default loads then calls load_mem_()
- virtual blargg_err_t load_mem_( byte const* data, long size ); // use data in memory
- virtual blargg_err_t track_info_( track_info_t* out, int track ) const = 0;
- virtual void pre_load();
- virtual void post_load_();
- virtual void clear_playlist_() { }
-
-public:
- blargg_err_t remap_track_( int* track_io ) const; // need by Music_Emu
-private:
- // noncopyable
- Gme_File( const Gme_File& );
- Gme_File& operator = ( const Gme_File& );
-
- gme_type_t type_;
- int track_count_;
- int raw_track_count_;
- const char* warning_;
- void* user_data_;
- gme_user_cleanup_t user_cleanup_;
- M3u_Playlist playlist;
- char playlist_warning [64];
- blargg_vector<byte> file_data; // only if loaded into memory using default load
-
- blargg_err_t load_m3u_( blargg_err_t );
- blargg_err_t post_load( blargg_err_t err );
-public:
- // track_info field copying
- enum { max_field_ = 255 };
- static void copy_field_( char* out, const char* in );
- static void copy_field_( char* out, const char* in, int len );
-};
-
-Music_Emu* gme_new_( Music_Emu*, long sample_rate );
-
-#define GME_COPY_FIELD( in, out, name ) \
- { Gme_File::copy_field_( out->name, in.name, sizeof in.name ); }
-
-#ifndef GME_FILE_READER
- #ifdef HAVE_ZLIB_H
- #define GME_FILE_READER Gzip_File_Reader
- #else
- #define GME_FILE_READER Std_File_Reader
- #endif
-#elif defined (GME_FILE_READER_INCLUDE)
- #include GME_FILE_READER_INCLUDE
-#endif
-
-inline gme_type_t Gme_File::type() const { return type_; }
-inline int Gme_File::error_count() const { return warning_ != 0; }
-inline int Gme_File::track_count() const { return track_count_; }
-
-inline const char* Gme_File::warning()
-{
- const char* s = warning_;
- warning_ = 0;
- return s;
-}
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Gym_Emu.cpp b/plugins/gme/game-music-emu-0.5.5/gme/Gym_Emu.cpp
deleted file mode 100644
index c286dea9..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Gym_Emu.cpp
+++ /dev/null
@@ -1,380 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Gym_Emu.h"
-
-#include "blargg_endian.h"
-#include <string.h>
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-double const min_tempo = 0.25;
-double const oversample_factor = 5 / 3.0;
-double const fm_gain = 3.0;
-
-const long base_clock = 53700300;
-const long clock_rate = base_clock / 15;
-
-Gym_Emu::Gym_Emu()
-{
- data = 0;
- pos = 0;
- set_type( gme_gym_type );
-
- static const char* const names [] = {
- "FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6", "PCM", "PSG"
- };
- set_voice_names( names );
- set_silence_lookahead( 1 ); // tracks should already be trimmed
-}
-
-Gym_Emu::~Gym_Emu() { }
-
-// Track info
-
-static void get_gym_info( Gym_Emu::header_t const& h, long length, track_info_t* out )
-{
- if ( !memcmp( h.tag, "GYMX", 4 ) )
- {
- length = length * 50 / 3; // 1000 / 60
- long loop = get_le32( h.loop_start );
- if ( loop )
- {
- out->intro_length = loop * 50 / 3;
- out->loop_length = length - out->intro_length;
- }
- else
- {
- out->length = length;
- out->intro_length = length; // make it clear that track is no longer than length
- out->loop_length = 0;
- }
-
- // more stupidity where the field should have been left
- if ( strcmp( h.song, "Unknown Song" ) )
- GME_COPY_FIELD( h, out, song );
-
- if ( strcmp( h.game, "Unknown Game" ) )
- GME_COPY_FIELD( h, out, game );
-
- if ( strcmp( h.copyright, "Unknown Publisher" ) )
- GME_COPY_FIELD( h, out, copyright );
-
- if ( strcmp( h.dumper, "Unknown Person" ) )
- GME_COPY_FIELD( h, out, dumper );
-
- if ( strcmp( h.comment, "Header added by YMAMP" ) )
- GME_COPY_FIELD( h, out, comment );
- }
-}
-
-blargg_err_t Gym_Emu::track_info_( track_info_t* out, int ) const
-{
- get_gym_info( header_, track_length(), out );
- return 0;
-}
-
-static long gym_track_length( byte const* p, byte const* end )
-{
- long time = 0;
- while ( p < end )
- {
- switch ( *p++ )
- {
- case 0:
- time++;
- break;
-
- case 1:
- case 2:
- p += 2;
- break;
-
- case 3:
- p += 1;
- break;
- }
- }
- return time;
-}
-
-long Gym_Emu::track_length() const { return gym_track_length( data, data_end ); }
-
-static blargg_err_t check_header( byte const* in, long size, int* data_offset = 0 )
-{
- if ( size < 4 )
- return gme_wrong_file_type;
-
- if ( memcmp( in, "GYMX", 4 ) == 0 )
- {
- if ( size < Gym_Emu::header_size + 1 )
- return gme_wrong_file_type;
-
- if ( memcmp( ((Gym_Emu::header_t const*) in)->packed, "\0\0\0\0", 4 ) != 0 )
- return "Packed GYM file not supported";
-
- if ( data_offset )
- *data_offset = Gym_Emu::header_size;
- }
- else if ( *in > 3 )
- {
- return gme_wrong_file_type;
- }
-
- return 0;
-}
-
-struct Gym_File : Gme_Info_
-{
- byte const* file_begin;
- byte const* file_end;
- int data_offset;
-
- Gym_File() { set_type( gme_gym_type ); }
-
- blargg_err_t load_mem_( byte const* in, long size )
- {
- file_begin = in;
- file_end = in + size;
- data_offset = 0;
- return check_header( in, size, &data_offset );
- }
-
- blargg_err_t track_info_( track_info_t* out, int ) const
- {
- long length = gym_track_length( &file_begin [data_offset], file_end );
- get_gym_info( *(Gym_Emu::header_t const*) file_begin, length, out );
- return 0;
- }
-};
-
-static Music_Emu* new_gym_emu () { return BLARGG_NEW Gym_Emu ; }
-static Music_Emu* new_gym_file() { return BLARGG_NEW Gym_File; }
-
-static gme_type_t_ const gme_gym_type_ = { "Sega Genesis", 1, &new_gym_emu, &new_gym_file, "GYM", 0 };
-gme_type_t const gme_gym_type = &gme_gym_type_;
-
-// Setup
-
-blargg_err_t Gym_Emu::set_sample_rate_( long sample_rate )
-{
- blip_eq_t eq( -32, 8000, sample_rate );
- apu.treble_eq( eq );
- dac_synth.treble_eq( eq );
- apu.volume( 0.135 * fm_gain * gain() );
- dac_synth.volume( 0.125 / 256 * fm_gain * gain() );
- double factor = Dual_Resampler::setup( oversample_factor, 0.990, fm_gain * gain() );
- fm_sample_rate = sample_rate * factor;
-
- RETURN_ERR( blip_buf.set_sample_rate( sample_rate, int (1000 / 60.0 / min_tempo) ) );
- blip_buf.clock_rate( clock_rate );
-
- RETURN_ERR( fm.set_rate( fm_sample_rate, base_clock / 7.0 ) );
- RETURN_ERR( Dual_Resampler::reset( long (1.0 / 60 / min_tempo * sample_rate) ) );
-
- return 0;
-}
-
-void Gym_Emu::set_tempo_( double t )
-{
- if ( t < min_tempo )
- {
- set_tempo( min_tempo );
- return;
- }
-
- if ( blip_buf.sample_rate() )
- {
- clocks_per_frame = long (clock_rate / 60 / tempo());
- Dual_Resampler::resize( long (sample_rate() / (60.0 * tempo())) );
- }
-}
-
-void Gym_Emu::mute_voices_( int mask )
-{
- Music_Emu::mute_voices_( mask );
- fm.mute_voices( mask );
- dac_muted = (mask & 0x40) != 0;
- apu.output( (mask & 0x80) ? 0 : &blip_buf );
-}
-
-blargg_err_t Gym_Emu::load_mem_( byte const* in, long size )
-{
- assert( offsetof (header_t,packed [4]) == header_size );
- int offset = 0;
- RETURN_ERR( check_header( in, size, &offset ) );
- set_voice_count( 8 );
-
- data = in + offset;
- data_end = in + size;
- loop_begin = 0;
-
- if ( offset )
- header_ = *(header_t const*) in;
- else
- memset( &header_, 0, sizeof header_ );
-
- return 0;
-}
-
-// Emulation
-
-blargg_err_t Gym_Emu::start_track_( int track )
-{
- RETURN_ERR( Music_Emu::start_track_( track ) );
-
- pos = data;
- loop_remain = get_le32( header_.loop_start );
-
- prev_dac_count = 0;
- dac_enabled = false;
- dac_amp = -1;
-
- fm.reset();
- apu.reset();
- blip_buf.clear();
- Dual_Resampler::clear();
- return 0;
-}
-
-void Gym_Emu::run_dac( int dac_count )
-{
- // Guess beginning and end of sample and adjust rate and buffer position accordingly.
-
- // count dac samples in next frame
- int next_dac_count = 0;
- const byte* p = this->pos;
- int cmd;
- while ( (cmd = *p++) != 0 )
- {
- int data = *p++;
- if ( cmd <= 2 )
- ++p;
- if ( cmd == 1 && data == 0x2A )
- next_dac_count++;
- }
-
- // detect beginning and end of sample
- int rate_count = dac_count;
- int start = 0;
- if ( !prev_dac_count && next_dac_count && dac_count < next_dac_count )
- {
- rate_count = next_dac_count;
- start = next_dac_count - dac_count;
- }
- else if ( prev_dac_count && !next_dac_count && dac_count < prev_dac_count )
- {
- rate_count = prev_dac_count;
- }
-
- // Evenly space samples within buffer section being used
- blip_resampled_time_t period = blip_buf.resampled_duration( clocks_per_frame ) / rate_count;
-
- blip_resampled_time_t time = blip_buf.resampled_time( 0 ) +
- period * start + (period >> 1);
-
- int dac_amp = this->dac_amp;
- if ( dac_amp < 0 )
- dac_amp = dac_buf [0];
-
- for ( int i = 0; i < dac_count; i++ )
- {
- int delta = dac_buf [i] - dac_amp;
- dac_amp += delta;
- dac_synth.offset_resampled( time, delta, &blip_buf );
- time += period;
- }
- this->dac_amp = dac_amp;
-}
-
-void Gym_Emu::parse_frame()
-{
- int dac_count = 0;
- const byte* pos = this->pos;
-
- if ( loop_remain && !--loop_remain )
- loop_begin = pos; // find loop on first time through sequence
-
- int cmd;
- while ( (cmd = *pos++) != 0 )
- {
- int data = *pos++;
- if ( cmd == 1 )
- {
- int data2 = *pos++;
- if ( data != 0x2A )
- {
- if ( data == 0x2B )
- dac_enabled = (data2 & 0x80) != 0;
-
- fm.write0( data, data2 );
- }
- else if ( dac_count < (int) sizeof dac_buf )
- {
- dac_buf [dac_count] = data2;
- dac_count += dac_enabled;
- }
- }
- else if ( cmd == 2 )
- {
- fm.write1( data, *pos++ );
- }
- else if ( cmd == 3 )
- {
- apu.write_data( 0, data );
- }
- else
- {
- // to do: many GYM streams are full of errors, and error count should
- // reflect cases where music is really having problems
- //log_error();
- --pos; // put data back
- }
- }
-
- // loop
- if ( pos >= data_end )
- {
- check( pos == data_end );
-
- if ( loop_begin )
- pos = loop_begin;
- else
- set_track_ended();
- }
- this->pos = pos;
-
- // dac
- if ( dac_count && !dac_muted )
- run_dac( dac_count );
- prev_dac_count = dac_count;
-}
-
-int Gym_Emu::play_frame( blip_time_t blip_time, int sample_count, sample_t* buf )
-{
- if ( !track_ended() )
- parse_frame();
-
- apu.end_frame( blip_time );
-
- memset( buf, 0, sample_count * sizeof *buf );
- fm.run( sample_count >> 1, buf );
-
- return sample_count;
-}
-
-blargg_err_t Gym_Emu::play_( long count, sample_t* out )
-{
- Dual_Resampler::dual_play( count, out, blip_buf );
- return 0;
-}
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Gym_Emu.h b/plugins/gme/game-music-emu-0.5.5/gme/Gym_Emu.h
deleted file mode 100644
index f2e13238..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Gym_Emu.h
+++ /dev/null
@@ -1,82 +0,0 @@
-// Sega Genesis/Mega Drive GYM music file emulator
-// Includes with PCM timing recovery to improve sample quality.
-
-// Game_Music_Emu 0.5.5
-#ifndef GYM_EMU_H
-#define GYM_EMU_H
-
-#include "Dual_Resampler.h"
-#include "Ym2612_Emu.h"
-#include "Music_Emu.h"
-#include "Sms_Apu.h"
-
-class Gym_Emu : public Music_Emu, private Dual_Resampler {
-public:
- // GYM file header
- enum { header_size = 428 };
- struct header_t
- {
- char tag [4];
- char song [32];
- char game [32];
- char copyright [32];
- char emulator [32];
- char dumper [32];
- char comment [256];
- byte loop_start [4]; // in 1/60 seconds, 0 if not looped
- byte packed [4];
- };
-
- // Header for currently loaded file
- header_t const& header() const { return header_; }
-
- static gme_type_t static_type() { return gme_gym_type; }
-
-public:
- // deprecated
- Music_Emu::load;
- blargg_err_t load( header_t const& h, Data_Reader& in ) // use Remaining_Reader
- { return load_remaining_( &h, sizeof h, in ); }
- enum { gym_rate = 60 };
- long track_length() const; // use track_info()
-
-public:
- Gym_Emu();
- ~Gym_Emu();
-protected:
- blargg_err_t load_mem_( byte const*, long );
- blargg_err_t track_info_( track_info_t*, int track ) const;
- blargg_err_t set_sample_rate_( long sample_rate );
- blargg_err_t start_track_( int );
- blargg_err_t play_( long count, sample_t* );
- void mute_voices_( int );
- void set_tempo_( double );
- int play_frame( blip_time_t blip_time, int sample_count, sample_t* buf );
-private:
- // sequence data begin, loop begin, current position, end
- const byte* data;
- const byte* loop_begin;
- const byte* pos;
- const byte* data_end;
- blargg_long loop_remain; // frames remaining until loop beginning has been located
- header_t header_;
- double fm_sample_rate;
- blargg_long clocks_per_frame;
- void parse_frame();
-
- // dac (pcm)
- int dac_amp;
- int prev_dac_count;
- bool dac_enabled;
- bool dac_muted;
- void run_dac( int );
-
- // sound
- Blip_Buffer blip_buf;
- Ym2612_Emu fm;
- Blip_Synth<blip_med_quality,1> dac_synth;
- Sms_Apu apu;
- byte dac_buf [1024];
-};
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Hes_Apu.cpp b/plugins/gme/game-music-emu-0.5.5/gme/Hes_Apu.cpp
deleted file mode 100644
index 63c2b707..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Hes_Apu.cpp
+++ /dev/null
@@ -1,315 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Hes_Apu.h"
-
-#include <string.h>
-
-/* Copyright (C) 2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-bool const center_waves = true; // reduces asymmetry and clamping when starting notes
-
-Hes_Apu::Hes_Apu()
-{
- Hes_Osc* osc = &oscs [osc_count];
- do
- {
- osc--;
- osc->outputs [0] = 0;
- osc->outputs [1] = 0;
- osc->chans [0] = 0;
- osc->chans [1] = 0;
- osc->chans [2] = 0;
- }
- while ( osc != oscs );
-
- reset();
-}
-
-void Hes_Apu::reset()
-{
- latch = 0;
- balance = 0xFF;
-
- Hes_Osc* osc = &oscs [osc_count];
- do
- {
- osc--;
- memset( osc, 0, offsetof (Hes_Osc,outputs) );
- osc->noise_lfsr = 1;
- osc->control = 0x40;
- osc->balance = 0xFF;
- }
- while ( osc != oscs );
-}
-
-void Hes_Apu::osc_output( int index, Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right )
-{
- require( (unsigned) index < osc_count );
- oscs [index].chans [0] = center;
- oscs [index].chans [1] = left;
- oscs [index].chans [2] = right;
-
- Hes_Osc* osc = &oscs [osc_count];
- do
- {
- osc--;
- balance_changed( *osc );
- }
- while ( osc != oscs );
-}
-
-void Hes_Osc::run_until( synth_t& synth_, blip_time_t end_time )
-{
- Blip_Buffer* const osc_outputs_0 = outputs [0]; // cache often-used values
- if ( osc_outputs_0 && control & 0x80 )
- {
- int dac = this->dac;
-
- int const volume_0 = volume [0];
- {
- int delta = dac * volume_0 - last_amp [0];
- if ( delta )
- synth_.offset( last_time, delta, osc_outputs_0 );
- osc_outputs_0->set_modified();
- }
-
- Blip_Buffer* const osc_outputs_1 = outputs [1];
- int const volume_1 = volume [1];
- if ( osc_outputs_1 )
- {
- int delta = dac * volume_1 - last_amp [1];
- if ( delta )
- synth_.offset( last_time, delta, osc_outputs_1 );
- osc_outputs_1->set_modified();
- }
-
- blip_time_t time = last_time + delay;
- if ( time < end_time )
- {
- if ( noise & 0x80 )
- {
- if ( volume_0 | volume_1 )
- {
- // noise
- int const period = (32 - (noise & 0x1F)) * 64; // TODO: correct?
- unsigned noise_lfsr = this->noise_lfsr;
- do
- {
- int new_dac = 0x1F & -(noise_lfsr >> 1 & 1);
- // Implemented using "Galios configuration"
- // TODO: find correct LFSR algorithm
- noise_lfsr = (noise_lfsr >> 1) ^ (0xE008 & -(noise_lfsr & 1));
- //noise_lfsr = (noise_lfsr >> 1) ^ (0x6000 & -(noise_lfsr & 1));
- int delta = new_dac - dac;
- if ( delta )
- {
- dac = new_dac;
- synth_.offset( time, delta * volume_0, osc_outputs_0 );
- if ( osc_outputs_1 )
- synth_.offset( time, delta * volume_1, osc_outputs_1 );
- }
- time += period;
- }
- while ( time < end_time );
-
- this->noise_lfsr = noise_lfsr;
- assert( noise_lfsr );
- }
- }
- else if ( !(control & 0x40) )
- {
- // wave
- int phase = (this->phase + 1) & 0x1F; // pre-advance for optimal inner loop
- int period = this->period * 2;
- if ( period >= 14 && (volume_0 | volume_1) )
- {
- do
- {
- int new_dac = wave [phase];
- phase = (phase + 1) & 0x1F;
- int delta = new_dac - dac;
- if ( delta )
- {
- dac = new_dac;
- synth_.offset( time, delta * volume_0, osc_outputs_0 );
- if ( osc_outputs_1 )
- synth_.offset( time, delta * volume_1, osc_outputs_1 );
- }
- time += period;
- }
- while ( time < end_time );
- }
- else
- {
- if ( !period )
- {
- // TODO: Gekisha Boy assumes that period = 0 silences wave
- //period = 0x1000 * 2;
- period = 1;
- //if ( !(volume_0 | volume_1) )
- // debug_printf( "Used period 0\n" );
- }
-
- // maintain phase when silent
- blargg_long count = (end_time - time + period - 1) / period;
- phase += count; // phase will be masked below
- time += count * period;
- }
- this->phase = (phase - 1) & 0x1F; // undo pre-advance
- }
- }
- time -= end_time;
- if ( time < 0 )
- time = 0;
- delay = time;
-
- this->dac = dac;
- last_amp [0] = dac * volume_0;
- last_amp [1] = dac * volume_1;
- }
- last_time = end_time;
-}
-
-void Hes_Apu::balance_changed( Hes_Osc& osc )
-{
- static short const log_table [32] = { // ~1.5 db per step
- #define ENTRY( factor ) short (factor * Hes_Osc::amp_range / 31.0 + 0.5)
- ENTRY( 0.000000 ),ENTRY( 0.005524 ),ENTRY( 0.006570 ),ENTRY( 0.007813 ),
- ENTRY( 0.009291 ),ENTRY( 0.011049 ),ENTRY( 0.013139 ),ENTRY( 0.015625 ),
- ENTRY( 0.018581 ),ENTRY( 0.022097 ),ENTRY( 0.026278 ),ENTRY( 0.031250 ),
- ENTRY( 0.037163 ),ENTRY( 0.044194 ),ENTRY( 0.052556 ),ENTRY( 0.062500 ),
- ENTRY( 0.074325 ),ENTRY( 0.088388 ),ENTRY( 0.105112 ),ENTRY( 0.125000 ),
- ENTRY( 0.148651 ),ENTRY( 0.176777 ),ENTRY( 0.210224 ),ENTRY( 0.250000 ),
- ENTRY( 0.297302 ),ENTRY( 0.353553 ),ENTRY( 0.420448 ),ENTRY( 0.500000 ),
- ENTRY( 0.594604 ),ENTRY( 0.707107 ),ENTRY( 0.840896 ),ENTRY( 1.000000 ),
- #undef ENTRY
- };
-
- int vol = (osc.control & 0x1F) - 0x1E * 2;
-
- int left = vol + (osc.balance >> 3 & 0x1E) + (balance >> 3 & 0x1E);
- if ( left < 0 ) left = 0;
-
- int right = vol + (osc.balance << 1 & 0x1E) + (balance << 1 & 0x1E);
- if ( right < 0 ) right = 0;
-
- left = log_table [left ];
- right = log_table [right];
-
- // optimizing for the common case of being centered also allows easy
- // panning using Effects_Buffer
- osc.outputs [0] = osc.chans [0]; // center
- osc.outputs [1] = 0;
- if ( left != right )
- {
- osc.outputs [0] = osc.chans [1]; // left
- osc.outputs [1] = osc.chans [2]; // right
- }
-
- if ( center_waves )
- {
- osc.last_amp [0] += (left - osc.volume [0]) * 16;
- osc.last_amp [1] += (right - osc.volume [1]) * 16;
- }
-
- osc.volume [0] = left;
- osc.volume [1] = right;
-}
-
-void Hes_Apu::write_data( blip_time_t time, int addr, int data )
-{
- if ( addr == 0x800 )
- {
- latch = data & 7;
- }
- else if ( addr == 0x801 )
- {
- if ( balance != data )
- {
- balance = data;
-
- Hes_Osc* osc = &oscs [osc_count];
- do
- {
- osc--;
- osc->run_until( synth, time );
- balance_changed( *oscs );
- }
- while ( osc != oscs );
- }
- }
- else if ( latch < osc_count )
- {
- Hes_Osc& osc = oscs [latch];
- osc.run_until( synth, time );
- switch ( addr )
- {
- case 0x802:
- osc.period = (osc.period & 0xF00) | data;
- break;
-
- case 0x803:
- osc.period = (osc.period & 0x0FF) | ((data & 0x0F) << 8);
- break;
-
- case 0x804:
- if ( osc.control & 0x40 & ~data )
- osc.phase = 0;
- osc.control = data;
- balance_changed( osc );
- break;
-
- case 0x805:
- osc.balance = data;
- balance_changed( osc );
- break;
-
- case 0x806:
- data &= 0x1F;
- if ( !(osc.control & 0x40) )
- {
- osc.wave [osc.phase] = data;
- osc.phase = (osc.phase + 1) & 0x1F;
- }
- else if ( osc.control & 0x80 )
- {
- osc.dac = data;
- }
- break;
-
- case 0x807:
- if ( &osc >= &oscs [4] )
- osc.noise = data;
- break;
-
- case 0x809:
- if ( !(data & 0x80) && (data & 0x03) != 0 )
- debug_printf( "HES LFO not supported\n" );
- }
- }
-}
-
-void Hes_Apu::end_frame( blip_time_t end_time )
-{
- Hes_Osc* osc = &oscs [osc_count];
- do
- {
- osc--;
- if ( end_time > osc->last_time )
- osc->run_until( synth, end_time );
- assert( osc->last_time >= end_time );
- osc->last_time -= end_time;
- }
- while ( osc != oscs );
-}
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Hes_Apu.h b/plugins/gme/game-music-emu-0.5.5/gme/Hes_Apu.h
deleted file mode 100644
index 1e546053..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Hes_Apu.h
+++ /dev/null
@@ -1,66 +0,0 @@
-// Turbo Grafx 16 (PC Engine) PSG sound chip emulator
-
-// Game_Music_Emu 0.5.5
-#ifndef HES_APU_H
-#define HES_APU_H
-
-#include "blargg_common.h"
-#include "Blip_Buffer.h"
-
-struct Hes_Osc
-{
- unsigned char wave [32];
- short volume [2];
- int last_amp [2];
- int delay;
- int period;
- unsigned char noise;
- unsigned char phase;
- unsigned char balance;
- unsigned char dac;
- blip_time_t last_time;
-
- Blip_Buffer* outputs [2];
- Blip_Buffer* chans [3];
- unsigned noise_lfsr;
- unsigned char control;
-
- enum { amp_range = 0x8000 };
- typedef Blip_Synth<blip_med_quality,1> synth_t;
-
- void run_until( synth_t& synth, blip_time_t );
-};
-
-class Hes_Apu {
-public:
- void treble_eq( blip_eq_t const& );
- void volume( double );
-
- enum { osc_count = 6 };
- void osc_output( int index, Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right );
-
- void reset();
-
- enum { start_addr = 0x0800 };
- enum { end_addr = 0x0809 };
- void write_data( blip_time_t, int addr, int data );
-
- void end_frame( blip_time_t );
-
-public:
- Hes_Apu();
-private:
- Hes_Osc oscs [osc_count];
- int latch;
- int balance;
- Hes_Osc::synth_t synth;
-
- void balance_changed( Hes_Osc& );
- void recalc_chans();
-};
-
-inline void Hes_Apu::volume( double v ) { synth.volume( 1.8 / osc_count / Hes_Osc::amp_range * v ); }
-
-inline void Hes_Apu::treble_eq( blip_eq_t const& eq ) { synth.treble_eq( eq ); }
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Hes_Cpu.cpp b/plugins/gme/game-music-emu-0.5.5/gme/Hes_Cpu.cpp
deleted file mode 100644
index 8acdd94f..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Hes_Cpu.cpp
+++ /dev/null
@@ -1,1303 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Hes_Cpu.h"
-
-#include "blargg_endian.h"
-
-//#include "hes_cpu_log.h"
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-// TODO: support T flag, including clearing it at appropriate times?
-
-// all zero-page should really use whatever is at page 1, but that would
-// reduce efficiency quite a bit
-int const ram_addr = 0x2000;
-
-#define FLUSH_TIME() (void) (s.time = s_time)
-#define CACHE_TIME() (void) (s_time = s.time)
-
-#include "hes_cpu_io.h"
-
-#include "blargg_source.h"
-
-#if BLARGG_NONPORTABLE
- #define PAGE_OFFSET( addr ) (addr)
-#else
- #define PAGE_OFFSET( addr ) ((addr) & (page_size - 1))
-#endif
-
-// status flags
-int const st_n = 0x80;
-int const st_v = 0x40;
-int const st_t = 0x20;
-int const st_b = 0x10;
-int const st_d = 0x08;
-int const st_i = 0x04;
-int const st_z = 0x02;
-int const st_c = 0x01;
-
-void Hes_Cpu::reset()
-{
- check( state == &state_ );
- state = &state_;
-
- state_.time = 0;
- state_.base = 0;
- irq_time_ = future_hes_time;
- end_time_ = future_hes_time;
-
- r.status = st_i;
- r.sp = 0;
- r.pc = 0;
- r.a = 0;
- r.x = 0;
- r.y = 0;
-
- blargg_verify_byte_order();
-}
-
-void Hes_Cpu::set_mmr( int reg, int bank )
-{
- assert( (unsigned) reg <= page_count ); // allow page past end to be set
- assert( (unsigned) bank < 0x100 );
- mmr [reg] = bank;
- uint8_t const* code = CPU_SET_MMR( this, reg, bank );
- state->code_map [reg] = code - PAGE_OFFSET( reg << page_shift );
-}
-
-#define TIME (s_time + s.base)
-
-#define READ( addr ) CPU_READ( this, (addr), TIME )
-#define WRITE( addr, data ) {CPU_WRITE( this, (addr), (data), TIME );}
-#define READ_LOW( addr ) (ram [int (addr)])
-#define WRITE_LOW( addr, data ) (void) (READ_LOW( addr ) = (data))
-#define READ_PROG( addr ) (s.code_map [(addr) >> page_shift] [PAGE_OFFSET( addr )])
-
-#define SET_SP( v ) (sp = ((v) + 1) | 0x100)
-#define GET_SP() ((sp - 1) & 0xFF)
-#define PUSH( v ) ((sp = (sp - 1) | 0x100), WRITE_LOW( sp, v ))
-
-// even on x86, using short and unsigned char was slower
-typedef int fint16;
-typedef unsigned fuint16;
-typedef unsigned fuint8;
-typedef blargg_long fint32;
-
-bool Hes_Cpu::run( hes_time_t end_time )
-{
- bool illegal_encountered = false;
- set_end_time( end_time );
- state_t s = this->state_;
- this->state = &s;
- // even on x86, using s.time in place of s_time was slower
- fint16 s_time = s.time;
-
- // registers
- fuint16 pc = r.pc;
- fuint8 a = r.a;
- fuint8 x = r.x;
- fuint8 y = r.y;
- fuint16 sp;
- SET_SP( r.sp );
-
- #define IS_NEG (nz & 0x8080)
-
- #define CALC_STATUS( out ) do {\
- out = status & (st_v | st_d | st_i);\
- out |= ((nz >> 8) | nz) & st_n;\
- out |= c >> 8 & st_c;\
- if ( !(nz & 0xFF) ) out |= st_z;\
- } while ( 0 )
-
- #define SET_STATUS( in ) do {\
- status = in & (st_v | st_d | st_i);\
- nz = in << 8;\
- c = nz;\
- nz |= ~in & st_z;\
- } while ( 0 )
-
- fuint8 status;
- fuint16 c; // carry set if (c & 0x100) != 0
- fuint16 nz; // Z set if (nz & 0xFF) == 0, N set if (nz & 0x8080) != 0
- {
- fuint8 temp = r.status;
- SET_STATUS( temp );
- }
-
- goto loop;
-branch_not_taken:
- s_time -= 2;
-loop:
-
- #ifndef NDEBUG
- {
- hes_time_t correct = end_time_;
- if ( !(status & st_i) && correct > irq_time_ )
- correct = irq_time_;
- check( s.base == correct );
- /*
- static long count;
- if ( count == 1844 ) Debugger();
- if ( s.base != correct ) debug_printf( "%ld\n", count );
- count++;
- */
- }
- #endif
-
- check( (unsigned) GET_SP() < 0x100 );
- check( (unsigned) a < 0x100 );
- check( (unsigned) x < 0x100 );
-
- uint8_t const* instr = s.code_map [pc >> page_shift];
- fuint8 opcode;
-
- // TODO: eliminate this special case
- #if BLARGG_NONPORTABLE
- opcode = instr [pc];
- pc++;
- instr += pc;
- #else
- instr += PAGE_OFFSET( pc );
- opcode = *instr++;
- pc++;
- #endif
-
- // TODO: each reference lists slightly different timing values, ugh
- static uint8_t const clock_table [256] =
- {// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 1,7,3, 4,6,4,6,7,3,2,2,2,7,5,7,6,// 0
- 4,7,7, 4,6,4,6,7,2,5,2,2,7,5,7,6,// 1
- 7,7,3, 4,4,4,6,7,4,2,2,2,5,5,7,6,// 2
- 4,7,7, 2,4,4,6,7,2,5,2,2,5,5,7,6,// 3
- 7,7,3, 4,8,4,6,7,3,2,2,2,4,5,7,6,// 4
- 4,7,7, 5,2,4,6,7,2,5,3,2,2,5,7,6,// 5
- 7,7,2, 2,4,4,6,7,4,2,2,2,7,5,7,6,// 6
- 4,7,7,17,4,4,6,7,2,5,4,2,7,5,7,6,// 7
- 4,7,2, 7,4,4,4,7,2,2,2,2,5,5,5,6,// 8
- 4,7,7, 8,4,4,4,7,2,5,2,2,5,5,5,6,// 9
- 2,7,2, 7,4,4,4,7,2,2,2,2,5,5,5,6,// A
- 4,7,7, 8,4,4,4,7,2,5,2,2,5,5,5,6,// B
- 2,7,2,17,4,4,6,7,2,2,2,2,5,5,7,6,// C
- 4,7,7,17,2,4,6,7,2,5,3,2,2,5,7,6,// D
- 2,7,2,17,4,4,6,7,2,2,2,2,5,5,7,6,// E
- 4,7,7,17,2,4,6,7,2,5,4,2,2,5,7,6 // F
- }; // 0x00 was 8
-
- fuint16 data;
- data = clock_table [opcode];
- if ( (s_time += data) >= 0 )
- goto possibly_out_of_time;
-almost_out_of_time:
-
- data = *instr;
-
- #ifdef HES_CPU_LOG_H
- log_cpu( "new", pc - 1, opcode, instr [0], instr [1], instr [2],
- instr [3], instr [4], instr [5] );
- //log_opcode( opcode );
- #endif
-
- switch ( opcode )
- {
-possibly_out_of_time:
- if ( s_time < (int) data )
- goto almost_out_of_time;
- s_time -= data;
- goto out_of_time;
-
-// Macros
-
-#define GET_MSB() (instr [1])
-#define ADD_PAGE( out ) (pc++, out = data + 0x100 * GET_MSB());
-#define GET_ADDR() GET_LE16( instr )
-
-// TODO: is the penalty really always added? the original 6502 was much better
-//#define PAGE_CROSS_PENALTY( lsb ) (void) (s_time += (lsb) >> 8)
-#define PAGE_CROSS_PENALTY( lsb )
-
-// Branch
-
-// TODO: more efficient way to handle negative branch that wraps PC around
-#define BRANCH( cond )\
-{\
- fint16 offset = (BOOST::int8_t) data;\
- pc++;\
- if ( !(cond) ) goto branch_not_taken;\
- pc = BOOST::uint16_t (pc + offset);\
- goto loop;\
-}
-
- case 0xF0: // BEQ
- BRANCH( !((uint8_t) nz) );
-
- case 0xD0: // BNE
- BRANCH( (uint8_t) nz );
-
- case 0x10: // BPL
- BRANCH( !IS_NEG );
-
- case 0x90: // BCC
- BRANCH( !(c & 0x100) )
-
- case 0x30: // BMI
- BRANCH( IS_NEG )
-
- case 0x50: // BVC
- BRANCH( !(status & st_v) )
-
- case 0x70: // BVS
- BRANCH( status & st_v )
-
- case 0xB0: // BCS
- BRANCH( c & 0x100 )
-
- case 0x80: // BRA
- branch_taken:
- BRANCH( true );
-
- case 0xFF:
- if ( pc == idle_addr + 1 )
- goto idle_done;
- case 0x0F: // BBRn
- case 0x1F:
- case 0x2F:
- case 0x3F:
- case 0x4F:
- case 0x5F:
- case 0x6F:
- case 0x7F:
- case 0x8F: // BBSn
- case 0x9F:
- case 0xAF:
- case 0xBF:
- case 0xCF:
- case 0xDF:
- case 0xEF: {
- fuint16 t = 0x101 * READ_LOW( data );
- t ^= 0xFF;
- pc++;
- data = GET_MSB();
- BRANCH( t & (1 << (opcode >> 4)) )
- }
-
- case 0x4C: // JMP abs
- pc = GET_ADDR();
- goto loop;
-
- case 0x7C: // JMP (ind+X)
- data += x;
- case 0x6C:{// JMP (ind)
- data += 0x100 * GET_MSB();
- pc = GET_LE16( &READ_PROG( data ) );
- goto loop;
- }
-
-// Subroutine
-
- case 0x44: // BSR
- WRITE_LOW( 0x100 | (sp - 1), pc >> 8 );
- sp = (sp - 2) | 0x100;
- WRITE_LOW( sp, pc );
- goto branch_taken;
-
- case 0x20: { // JSR
- fuint16 temp = pc + 1;
- pc = GET_ADDR();
- WRITE_LOW( 0x100 | (sp - 1), temp >> 8 );
- sp = (sp - 2) | 0x100;
- WRITE_LOW( sp, temp );
- goto loop;
- }
-
- case 0x60: // RTS
- pc = 0x100 * READ_LOW( 0x100 | (sp - 0xFF) );
- pc += 1 + READ_LOW( sp );
- sp = (sp - 0xFE) | 0x100;
- goto loop;
-
- case 0x00: // BRK
- goto handle_brk;
-
-// Common
-
- case 0xBD:{// LDA abs,X
- PAGE_CROSS_PENALTY( data + x );
- fuint16 addr = GET_ADDR() + x;
- pc += 2;
- CPU_READ_FAST( this, addr, TIME, nz );
- a = nz;
- goto loop;
- }
-
- case 0x9D:{// STA abs,X
- fuint16 addr = GET_ADDR() + x;
- pc += 2;
- CPU_WRITE_FAST( this, addr, a, TIME );
- goto loop;
- }
-
- case 0x95: // STA zp,x
- data = uint8_t (data + x);
- case 0x85: // STA zp
- pc++;
- WRITE_LOW( data, a );
- goto loop;
-
- case 0xAE:{// LDX abs
- fuint16 addr = GET_ADDR();
- pc += 2;
- CPU_READ_FAST( this, addr, TIME, nz );
- x = nz;
- goto loop;
- }
-
- case 0xA5: // LDA zp
- a = nz = READ_LOW( data );
- pc++;
- goto loop;
-
-// Load/store
-
- {
- fuint16 addr;
- case 0x91: // STA (ind),Y
- addr = 0x100 * READ_LOW( uint8_t (data + 1) );
- addr += READ_LOW( data ) + y;
- pc++;
- goto sta_ptr;
-
- case 0x81: // STA (ind,X)
- data = uint8_t (data + x);
- case 0x92: // STA (ind)
- addr = 0x100 * READ_LOW( uint8_t (data + 1) );
- addr += READ_LOW( data );
- pc++;
- goto sta_ptr;
-
- case 0x99: // STA abs,Y
- data += y;
- case 0x8D: // STA abs
- addr = data + 0x100 * GET_MSB();
- pc += 2;
- sta_ptr:
- CPU_WRITE_FAST( this, addr, a, TIME );
- goto loop;
- }
-
- {
- fuint16 addr;
- case 0xA1: // LDA (ind,X)
- data = uint8_t (data + x);
- case 0xB2: // LDA (ind)
- addr = 0x100 * READ_LOW( uint8_t (data + 1) );
- addr += READ_LOW( data );
- pc++;
- goto a_nz_read_addr;
-
- case 0xB1:// LDA (ind),Y
- addr = READ_LOW( data ) + y;
- PAGE_CROSS_PENALTY( addr );
- addr += 0x100 * READ_LOW( (uint8_t) (data + 1) );
- pc++;
- goto a_nz_read_addr;
-
- case 0xB9: // LDA abs,Y
- data += y;
- PAGE_CROSS_PENALTY( data );
- case 0xAD: // LDA abs
- addr = data + 0x100 * GET_MSB();
- pc += 2;
- a_nz_read_addr:
- CPU_READ_FAST( this, addr, TIME, nz );
- a = nz;
- goto loop;
- }
-
- case 0xBE:{// LDX abs,y
- PAGE_CROSS_PENALTY( data + y );
- fuint16 addr = GET_ADDR() + y;
- pc += 2;
- FLUSH_TIME();
- x = nz = READ( addr );
- CACHE_TIME();
- goto loop;
- }
-
- case 0xB5: // LDA zp,x
- a = nz = READ_LOW( uint8_t (data + x) );
- pc++;
- goto loop;
-
- case 0xA9: // LDA #imm
- pc++;
- a = data;
- nz = data;
- goto loop;
-
-// Bit operations
-
- case 0x3C: // BIT abs,x
- data += x;
- case 0x2C:{// BIT abs
- fuint16 addr;
- ADD_PAGE( addr );
- FLUSH_TIME();
- nz = READ( addr );
- CACHE_TIME();
- goto bit_common;
- }
- case 0x34: // BIT zp,x
- data = uint8_t (data + x);
- case 0x24: // BIT zp
- data = READ_LOW( data );
- case 0x89: // BIT imm
- nz = data;
- bit_common:
- pc++;
- status &= ~st_v;
- status |= nz & st_v;
- if ( nz & a )
- goto loop; // Z should be clear, and nz must be non-zero if nz & a is
- nz <<= 8; // set Z flag without affecting N flag
- goto loop;
-
- {
- fuint16 addr;
-
- case 0xB3: // TST abs,x
- addr = GET_MSB() + x;
- goto tst_abs;
-
- case 0x93: // TST abs
- addr = GET_MSB();
- tst_abs:
- addr += 0x100 * instr [2];
- pc++;
- FLUSH_TIME();
- nz = READ( addr );
- CACHE_TIME();
- goto tst_common;
- }
-
- case 0xA3: // TST zp,x
- nz = READ_LOW( uint8_t (GET_MSB() + x) );
- goto tst_common;
-
- case 0x83: // TST zp
- nz = READ_LOW( GET_MSB() );
- tst_common:
- pc += 2;
- status &= ~st_v;
- status |= nz & st_v;
- if ( nz & data )
- goto loop; // Z should be clear, and nz must be non-zero if nz & data is
- nz <<= 8; // set Z flag without affecting N flag
- goto loop;
-
- {
- fuint16 addr;
- case 0x0C: // TSB abs
- case 0x1C: // TRB abs
- addr = GET_ADDR();
- pc++;
- goto txb_addr;
-
- // TODO: everyone lists different behaviors for the status flags, ugh
- case 0x04: // TSB zp
- case 0x14: // TRB zp
- addr = data + ram_addr;
- txb_addr:
- FLUSH_TIME();
- nz = a | READ( addr );
- if ( opcode & 0x10 )
- nz ^= a; // bits from a will already be set, so this clears them
- status &= ~st_v;
- status |= nz & st_v;
- pc++;
- WRITE( addr, nz );
- CACHE_TIME();
- goto loop;
- }
-
- case 0x07: // RMBn
- case 0x17:
- case 0x27:
- case 0x37:
- case 0x47:
- case 0x57:
- case 0x67:
- case 0x77:
- pc++;
- READ_LOW( data ) &= ~(1 << (opcode >> 4));
- goto loop;
-
- case 0x87: // SMBn
- case 0x97:
- case 0xA7:
- case 0xB7:
- case 0xC7:
- case 0xD7:
- case 0xE7:
- case 0xF7:
- pc++;
- READ_LOW( data ) |= 1 << ((opcode >> 4) - 8);
- goto loop;
-
-// Load/store
-
- case 0x9E: // STZ abs,x
- data += x;
- case 0x9C: // STZ abs
- ADD_PAGE( data );
- pc++;
- FLUSH_TIME();
- WRITE( data, 0 );
- CACHE_TIME();
- goto loop;
-
- case 0x74: // STZ zp,x
- data = uint8_t (data + x);
- case 0x64: // STZ zp
- pc++;
- WRITE_LOW( data, 0 );
- goto loop;
-
- case 0x94: // STY zp,x
- data = uint8_t (data + x);
- case 0x84: // STY zp
- pc++;
- WRITE_LOW( data, y );
- goto loop;
-
- case 0x96: // STX zp,y
- data = uint8_t (data + y);
- case 0x86: // STX zp
- pc++;
- WRITE_LOW( data, x );
- goto loop;
-
- case 0xB6: // LDX zp,y
- data = uint8_t (data + y);
- case 0xA6: // LDX zp
- data = READ_LOW( data );
- case 0xA2: // LDX #imm
- pc++;
- x = data;
- nz = data;
- goto loop;
-
- case 0xB4: // LDY zp,x
- data = uint8_t (data + x);
- case 0xA4: // LDY zp
- data = READ_LOW( data );
- case 0xA0: // LDY #imm
- pc++;
- y = data;
- nz = data;
- goto loop;
-
- case 0xBC: // LDY abs,X
- data += x;
- PAGE_CROSS_PENALTY( data );
- case 0xAC:{// LDY abs
- fuint16 addr = data + 0x100 * GET_MSB();
- pc += 2;
- FLUSH_TIME();
- y = nz = READ( addr );
- CACHE_TIME();
- goto loop;
- }
-
- {
- fuint8 temp;
- case 0x8C: // STY abs
- temp = y;
- goto store_abs;
-
- case 0x8E: // STX abs
- temp = x;
- store_abs:
- fuint16 addr = GET_ADDR();
- pc += 2;
- FLUSH_TIME();
- WRITE( addr, temp );
- CACHE_TIME();
- goto loop;
- }
-
-// Compare
-
- case 0xEC:{// CPX abs
- fuint16 addr = GET_ADDR();
- pc++;
- FLUSH_TIME();
- data = READ( addr );
- CACHE_TIME();
- goto cpx_data;
- }
-
- case 0xE4: // CPX zp
- data = READ_LOW( data );
- case 0xE0: // CPX #imm
- cpx_data:
- nz = x - data;
- pc++;
- c = ~nz;
- nz &= 0xFF;
- goto loop;
-
- case 0xCC:{// CPY abs
- fuint16 addr = GET_ADDR();
- pc++;
- FLUSH_TIME();
- data = READ( addr );
- CACHE_TIME();
- goto cpy_data;
- }
-
- case 0xC4: // CPY zp
- data = READ_LOW( data );
- case 0xC0: // CPY #imm
- cpy_data:
- nz = y - data;
- pc++;
- c = ~nz;
- nz &= 0xFF;
- goto loop;
-
-// Logical
-
-#define ARITH_ADDR_MODES( op )\
- case op - 0x04: /* (ind,x) */\
- data = uint8_t (data + x);\
- case op + 0x0D: /* (ind) */\
- data = 0x100 * READ_LOW( uint8_t (data + 1) ) + READ_LOW( data );\
- goto ptr##op;\
- case op + 0x0C:{/* (ind),y */\
- fuint16 temp = READ_LOW( data ) + y;\
- PAGE_CROSS_PENALTY( temp );\
- data = temp + 0x100 * READ_LOW( uint8_t (data + 1) );\
- goto ptr##op;\
- }\
- case op + 0x10: /* zp,X */\
- data = uint8_t (data + x);\
- case op + 0x00: /* zp */\
- data = READ_LOW( data );\
- goto imm##op;\
- case op + 0x14: /* abs,Y */\
- data += y;\
- goto ind##op;\
- case op + 0x18: /* abs,X */\
- data += x;\
- ind##op:\
- PAGE_CROSS_PENALTY( data );\
- case op + 0x08: /* abs */\
- ADD_PAGE( data );\
- ptr##op:\
- FLUSH_TIME();\
- data = READ( data );\
- CACHE_TIME();\
- case op + 0x04: /* imm */\
- imm##op:
-
- ARITH_ADDR_MODES( 0xC5 ) // CMP
- nz = a - data;
- pc++;
- c = ~nz;
- nz &= 0xFF;
- goto loop;
-
- ARITH_ADDR_MODES( 0x25 ) // AND
- nz = (a &= data);
- pc++;
- goto loop;
-
- ARITH_ADDR_MODES( 0x45 ) // EOR
- nz = (a ^= data);
- pc++;
- goto loop;
-
- ARITH_ADDR_MODES( 0x05 ) // ORA
- nz = (a |= data);
- pc++;
- goto loop;
-
-// Add/subtract
-
- ARITH_ADDR_MODES( 0xE5 ) // SBC
- data ^= 0xFF;
- goto adc_imm;
-
- ARITH_ADDR_MODES( 0x65 ) // ADC
- adc_imm: {
- if ( status & st_d )
- debug_printf( "Decimal mode not supported\n" );
- fint16 carry = c >> 8 & 1;
- fint16 ov = (a ^ 0x80) + carry + (BOOST::int8_t) data; // sign-extend
- status &= ~st_v;
- status |= ov >> 2 & 0x40;
- c = nz = a + data + carry;
- pc++;
- a = (uint8_t) nz;
- goto loop;
- }
-
-// Shift/rotate
-
- case 0x4A: // LSR A
- c = 0;
- case 0x6A: // ROR A
- nz = c >> 1 & 0x80;
- c = a << 8;
- nz |= a >> 1;
- a = nz;
- goto loop;
-
- case 0x0A: // ASL A
- nz = a << 1;
- c = nz;
- a = (uint8_t) nz;
- goto loop;
-
- case 0x2A: { // ROL A
- nz = a << 1;
- fint16 temp = c >> 8 & 1;
- c = nz;
- nz |= temp;
- a = (uint8_t) nz;
- goto loop;
- }
-
- case 0x5E: // LSR abs,X
- data += x;
- case 0x4E: // LSR abs
- c = 0;
- case 0x6E: // ROR abs
- ror_abs: {
- ADD_PAGE( data );
- FLUSH_TIME();
- int temp = READ( data );
- nz = (c >> 1 & 0x80) | (temp >> 1);
- c = temp << 8;
- goto rotate_common;
- }
-
- case 0x3E: // ROL abs,X
- data += x;
- goto rol_abs;
-
- case 0x1E: // ASL abs,X
- data += x;
- case 0x0E: // ASL abs
- c = 0;
- case 0x2E: // ROL abs
- rol_abs:
- ADD_PAGE( data );
- nz = c >> 8 & 1;
- FLUSH_TIME();
- nz |= (c = READ( data ) << 1);
- rotate_common:
- pc++;
- WRITE( data, (uint8_t) nz );
- CACHE_TIME();
- goto loop;
-
- case 0x7E: // ROR abs,X
- data += x;
- goto ror_abs;
-
- case 0x76: // ROR zp,x
- data = uint8_t (data + x);
- goto ror_zp;
-
- case 0x56: // LSR zp,x
- data = uint8_t (data + x);
- case 0x46: // LSR zp
- c = 0;
- case 0x66: // ROR zp
- ror_zp: {
- int temp = READ_LOW( data );
- nz = (c >> 1 & 0x80) | (temp >> 1);
- c = temp << 8;
- goto write_nz_zp;
- }
-
- case 0x36: // ROL zp,x
- data = uint8_t (data + x);
- goto rol_zp;
-
- case 0x16: // ASL zp,x
- data = uint8_t (data + x);
- case 0x06: // ASL zp
- c = 0;
- case 0x26: // ROL zp
- rol_zp:
- nz = c >> 8 & 1;
- nz |= (c = READ_LOW( data ) << 1);
- goto write_nz_zp;
-
-// Increment/decrement
-
-#define INC_DEC_AXY( reg, n ) reg = uint8_t (nz = reg + n); goto loop;
-
- case 0x1A: // INA
- INC_DEC_AXY( a, +1 )
-
- case 0xE8: // INX
- INC_DEC_AXY( x, +1 )
-
- case 0xC8: // INY
- INC_DEC_AXY( y, +1 )
-
- case 0x3A: // DEA
- INC_DEC_AXY( a, -1 )
-
- case 0xCA: // DEX
- INC_DEC_AXY( x, -1 )
-
- case 0x88: // DEY
- INC_DEC_AXY( y, -1 )
-
- case 0xF6: // INC zp,x
- data = uint8_t (data + x);
- case 0xE6: // INC zp
- nz = 1;
- goto add_nz_zp;
-
- case 0xD6: // DEC zp,x
- data = uint8_t (data + x);
- case 0xC6: // DEC zp
- nz = (unsigned) -1;
- add_nz_zp:
- nz += READ_LOW( data );
- write_nz_zp:
- pc++;
- WRITE_LOW( data, nz );
- goto loop;
-
- case 0xFE: // INC abs,x
- data = x + GET_ADDR();
- goto inc_ptr;
-
- case 0xEE: // INC abs
- data = GET_ADDR();
- inc_ptr:
- nz = 1;
- goto inc_common;
-
- case 0xDE: // DEC abs,x
- data = x + GET_ADDR();
- goto dec_ptr;
-
- case 0xCE: // DEC abs
- data = GET_ADDR();
- dec_ptr:
- nz = (unsigned) -1;
- inc_common:
- FLUSH_TIME();
- nz += READ( data );
- pc += 2;
- WRITE( data, (uint8_t) nz );
- CACHE_TIME();
- goto loop;
-
-// Transfer
-
- case 0xA8: // TAY
- y = a;
- nz = a;
- goto loop;
-
- case 0x98: // TYA
- a = y;
- nz = y;
- goto loop;
-
- case 0xAA: // TAX
- x = a;
- nz = a;
- goto loop;
-
- case 0x8A: // TXA
- a = x;
- nz = x;
- goto loop;
-
- case 0x9A: // TXS
- SET_SP( x ); // verified (no flag change)
- goto loop;
-
- case 0xBA: // TSX
- x = nz = GET_SP();
- goto loop;
-
- #define SWAP_REGS( r1, r2 ) {\
- fuint8 t = r1;\
- r1 = r2;\
- r2 = t;\
- goto loop;\
- }
-
- case 0x02: // SXY
- SWAP_REGS( x, y );
-
- case 0x22: // SAX
- SWAP_REGS( a, x );
-
- case 0x42: // SAY
- SWAP_REGS( a, y );
-
- case 0x62: // CLA
- a = 0;
- goto loop;
-
- case 0x82: // CLX
- x = 0;
- goto loop;
-
- case 0xC2: // CLY
- y = 0;
- goto loop;
-
-// Stack
-
- case 0x48: // PHA
- PUSH( a );
- goto loop;
-
- case 0xDA: // PHX
- PUSH( x );
- goto loop;
-
- case 0x5A: // PHY
- PUSH( y );
- goto loop;
-
- case 0x40:{// RTI
- fuint8 temp = READ_LOW( sp );
- pc = READ_LOW( 0x100 | (sp - 0xFF) );
- pc |= READ_LOW( 0x100 | (sp - 0xFE) ) * 0x100;
- sp = (sp - 0xFD) | 0x100;
- data = status;
- SET_STATUS( temp );
- this->r.status = status; // update externally-visible I flag
- if ( (data ^ status) & st_i )
- {
- hes_time_t new_time = end_time_;
- if ( !(status & st_i) && new_time > irq_time_ )
- new_time = irq_time_;
- blargg_long delta = s.base - new_time;
- s.base = new_time;
- s_time += delta;
- }
- goto loop;
- }
-
- #define POP() READ_LOW( sp ); sp = (sp - 0xFF) | 0x100
-
- case 0x68: // PLA
- a = nz = POP();
- goto loop;
-
- case 0xFA: // PLX
- x = nz = POP();
- goto loop;
-
- case 0x7A: // PLY
- y = nz = POP();
- goto loop;
-
- case 0x28:{// PLP
- fuint8 temp = POP();
- fuint8 changed = status ^ temp;
- SET_STATUS( temp );
- if ( !(changed & st_i) )
- goto loop; // I flag didn't change
- if ( status & st_i )
- goto handle_sei;
- goto handle_cli;
- }
- #undef POP
-
- case 0x08: { // PHP
- fuint8 temp;
- CALC_STATUS( temp );
- PUSH( temp | st_b );
- goto loop;
- }
-
-// Flags
-
- case 0x38: // SEC
- c = (unsigned) ~0;
- goto loop;
-
- case 0x18: // CLC
- c = 0;
- goto loop;
-
- case 0xB8: // CLV
- status &= ~st_v;
- goto loop;
-
- case 0xD8: // CLD
- status &= ~st_d;
- goto loop;
-
- case 0xF8: // SED
- status |= st_d;
- goto loop;
-
- case 0x58: // CLI
- if ( !(status & st_i) )
- goto loop;
- status &= ~st_i;
- handle_cli: {
- this->r.status = status; // update externally-visible I flag
- blargg_long delta = s.base - irq_time_;
- if ( delta <= 0 )
- {
- if ( TIME < irq_time_ )
- goto loop;
- goto delayed_cli;
- }
- s.base = irq_time_;
- s_time += delta;
- if ( s_time < 0 )
- goto loop;
-
- if ( delta >= s_time + 1 )
- {
- // delayed irq until after next instruction
- s.base += s_time + 1;
- s_time = -1;
- irq_time_ = s.base; // TODO: remove, as only to satisfy debug check in loop
- goto loop;
- }
- delayed_cli:
- debug_printf( "Delayed CLI not supported\n" ); // TODO: implement
- goto loop;
- }
-
- case 0x78: // SEI
- if ( status & st_i )
- goto loop;
- status |= st_i;
- handle_sei: {
- this->r.status = status; // update externally-visible I flag
- blargg_long delta = s.base - end_time_;
- s.base = end_time_;
- s_time += delta;
- if ( s_time < 0 )
- goto loop;
- debug_printf( "Delayed SEI not supported\n" ); // TODO: implement
- goto loop;
- }
-
-// Special
-
- case 0x53:{// TAM
- fuint8 const bits = data; // avoid using data across function call
- pc++;
- for ( int i = 0; i < 8; i++ )
- if ( bits & (1 << i) )
- set_mmr( i, a );
- goto loop;
- }
-
- case 0x43:{// TMA
- pc++;
- byte const* in = mmr;
- do
- {
- if ( data & 1 )
- a = *in;
- in++;
- }
- while ( (data >>= 1) != 0 );
- goto loop;
- }
-
- case 0x03: // ST0
- case 0x13: // ST1
- case 0x23:{// ST2
- fuint16 addr = opcode >> 4;
- if ( addr )
- addr++;
- pc++;
- FLUSH_TIME();
- CPU_WRITE_VDP( this, addr, data, TIME );
- CACHE_TIME();
- goto loop;
- }
-
- case 0xEA: // NOP
- goto loop;
-
- case 0x54: // CSL
- debug_printf( "CSL not supported\n" );
- illegal_encountered = true;
- goto loop;
-
- case 0xD4: // CSH
- goto loop;
-
- case 0xF4: { // SET
- //fuint16 operand = GET_MSB();
- debug_printf( "SET not handled\n" );
- //switch ( data )
- //{
- //}
- illegal_encountered = true;
- goto loop;
- }
-
-// Block transfer
-
- {
- fuint16 in_alt;
- fint16 in_inc;
- fuint16 out_alt;
- fint16 out_inc;
-
- case 0xE3: // TIA
- in_alt = 0;
- goto bxfer_alt;
-
- case 0xF3: // TAI
- in_alt = 1;
- bxfer_alt:
- in_inc = in_alt ^ 1;
- out_alt = in_inc;
- out_inc = in_alt;
- goto bxfer;
-
- case 0xD3: // TIN
- in_inc = 1;
- out_inc = 0;
- goto bxfer_no_alt;
-
- case 0xC3: // TDD
- in_inc = -1;
- out_inc = -1;
- goto bxfer_no_alt;
-
- case 0x73: // TII
- in_inc = 1;
- out_inc = 1;
- bxfer_no_alt:
- in_alt = 0;
- out_alt = 0;
- bxfer:
- fuint16 in = GET_LE16( instr + 0 );
- fuint16 out = GET_LE16( instr + 2 );
- int count = GET_LE16( instr + 4 );
- if ( !count )
- count = 0x10000;
- pc += 6;
- WRITE_LOW( 0x100 | (sp - 1), y );
- WRITE_LOW( 0x100 | (sp - 2), a );
- WRITE_LOW( 0x100 | (sp - 3), x );
- FLUSH_TIME();
- do
- {
- // TODO: reads from $0800-$1400 in I/O page return 0 and don't access I/O
- fuint8 t = READ( in );
- in += in_inc;
- in &= 0xFFFF;
- s.time += 6;
- if ( in_alt )
- in_inc = -in_inc;
- WRITE( out, t );
- out += out_inc;
- out &= 0xFFFF;
- if ( out_alt )
- out_inc = -out_inc;
- }
- while ( --count );
- CACHE_TIME();
- goto loop;
- }
-
-// Illegal
-
- default:
- assert( (unsigned) opcode <= 0xFF );
- debug_printf( "Illegal opcode $%02X at $%04X\n", (int) opcode, (int) pc - 1 );
- illegal_encountered = true;
- goto loop;
- }
- assert( false );
-
- int result_;
-handle_brk:
- pc++;
- result_ = 6;
-
-interrupt:
- {
- s_time += 7;
-
- WRITE_LOW( 0x100 | (sp - 1), pc >> 8 );
- WRITE_LOW( 0x100 | (sp - 2), pc );
- pc = GET_LE16( &READ_PROG( 0xFFF0 ) + result_ );
-
- sp = (sp - 3) | 0x100;
- fuint8 temp;
- CALC_STATUS( temp );
- if ( result_ == 6 )
- temp |= st_b;
- WRITE_LOW( sp, temp );
-
- status &= ~st_d;
- status |= st_i;
- this->r.status = status; // update externally-visible I flag
-
- blargg_long delta = s.base - end_time_;
- s.base = end_time_;
- s_time += delta;
- goto loop;
- }
-
-idle_done:
- s_time = 0;
-out_of_time:
- pc--;
- FLUSH_TIME();
- CPU_DONE( this, TIME, result_ );
- CACHE_TIME();
- if ( result_ > 0 )
- goto interrupt;
- if ( s_time < 0 )
- goto loop;
-
- s.time = s_time;
-
- r.pc = pc;
- r.sp = GET_SP();
- r.a = a;
- r.x = x;
- r.y = y;
-
- {
- fuint8 temp;
- CALC_STATUS( temp );
- r.status = temp;
- }
-
- this->state_ = s;
- this->state = &this->state_;
-
- return illegal_encountered;
-}
-
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Hes_Cpu.h b/plugins/gme/game-music-emu-0.5.5/gme/Hes_Cpu.h
deleted file mode 100644
index cf3af87d..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Hes_Cpu.h
+++ /dev/null
@@ -1,124 +0,0 @@
-// PC Engine CPU emulator for use with HES music files
-
-// Game_Music_Emu 0.5.5
-#ifndef HES_CPU_H
-#define HES_CPU_H
-
-#include "blargg_common.h"
-
-typedef blargg_long hes_time_t; // clock cycle count
-typedef unsigned hes_addr_t; // 16-bit address
-enum { future_hes_time = INT_MAX / 2 + 1 };
-
-class Hes_Cpu {
-public:
- typedef BOOST::uint8_t uint8_t;
-
- void reset();
-
- enum { page_size = 0x2000 };
- enum { page_shift = 13 };
- enum { page_count = 8 };
- void set_mmr( int reg, int bank );
-
- uint8_t const* get_code( hes_addr_t );
-
- uint8_t ram [page_size];
-
- // not kept updated during a call to run()
- struct registers_t {
- BOOST::uint16_t pc;
- uint8_t a;
- uint8_t x;
- uint8_t y;
- uint8_t status;
- uint8_t sp;
- };
- registers_t r;
-
- // page mapping registers
- uint8_t mmr [page_count + 1];
-
- // Set end_time and run CPU from current time. Returns true if any illegal
- // instructions were encountered.
- bool run( hes_time_t end_time );
-
- // Time of beginning of next instruction to be executed
- hes_time_t time() const { return state->time + state->base; }
- void set_time( hes_time_t t ) { state->time = t - state->base; }
- void adjust_time( int delta ) { state->time += delta; }
-
- hes_time_t irq_time() const { return irq_time_; }
- void set_irq_time( hes_time_t );
-
- hes_time_t end_time() const { return end_time_; }
- void set_end_time( hes_time_t );
-
- void end_frame( hes_time_t );
-
- // Attempt to execute instruction here results in CPU advancing time to
- // lesser of irq_time() and end_time() (or end_time() if IRQs are
- // disabled)
- enum { idle_addr = 0x1FFF };
-
- // Can read this many bytes past end of a page
- enum { cpu_padding = 8 };
-
-public:
- Hes_Cpu() { state = &state_; }
- enum { irq_inhibit = 0x04 };
-private:
- // noncopyable
- Hes_Cpu( const Hes_Cpu& );
- Hes_Cpu& operator = ( const Hes_Cpu& );
-
- struct state_t {
- uint8_t const* code_map [page_count + 1];
- hes_time_t base;
- blargg_long time;
- };
- state_t* state; // points to state_ or a local copy within run()
- state_t state_;
- hes_time_t irq_time_;
- hes_time_t end_time_;
-
- void set_code_page( int, void const* );
- inline int update_end_time( hes_time_t end, hes_time_t irq );
-};
-
-inline BOOST::uint8_t const* Hes_Cpu::get_code( hes_addr_t addr )
-{
- return state->code_map [addr >> page_shift] + addr
- #if !BLARGG_NONPORTABLE
- % (unsigned) page_size
- #endif
- ;
-}
-
-inline int Hes_Cpu::update_end_time( hes_time_t t, hes_time_t irq )
-{
- if ( irq < t && !(r.status & irq_inhibit) ) t = irq;
- int delta = state->base - t;
- state->base = t;
- return delta;
-}
-
-inline void Hes_Cpu::set_irq_time( hes_time_t t )
-{
- state->time += update_end_time( end_time_, (irq_time_ = t) );
-}
-
-inline void Hes_Cpu::set_end_time( hes_time_t t )
-{
- state->time += update_end_time( (end_time_ = t), irq_time_ );
-}
-
-inline void Hes_Cpu::end_frame( hes_time_t t )
-{
- assert( state == &state_ );
- state_.base -= t;
- if ( irq_time_ < future_hes_time ) irq_time_ -= t;
- if ( end_time_ < future_hes_time ) end_time_ -= t;
-}
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Hes_Emu.cpp b/plugins/gme/game-music-emu-0.5.5/gme/Hes_Emu.cpp
deleted file mode 100644
index 9a32b688..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Hes_Emu.cpp
+++ /dev/null
@@ -1,531 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Hes_Emu.h"
-
-#include "blargg_endian.h"
-#include <string.h>
-
-/* Copyright (C) 2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-int const timer_mask = 0x04;
-int const vdp_mask = 0x02;
-int const i_flag_mask = 0x04;
-int const unmapped = 0xFF;
-
-long const period_60hz = 262 * 455L; // scanlines * clocks per scanline
-
-Hes_Emu::Hes_Emu()
-{
- timer.raw_load = 0;
- set_type( gme_hes_type );
-
- static const char* const names [Hes_Apu::osc_count] = {
- "Wave 1", "Wave 2", "Wave 3", "Wave 4", "Multi 1", "Multi 2"
- };
- set_voice_names( names );
-
- static int const types [Hes_Apu::osc_count] = {
- wave_type | 0, wave_type | 1, wave_type | 2, wave_type | 3,
- mixed_type | 0, mixed_type | 1
- };
- set_voice_types( types );
- set_silence_lookahead( 6 );
- set_gain( 1.11 );
-}
-
-Hes_Emu::~Hes_Emu() { }
-
-void Hes_Emu::unload()
-{
- rom.clear();
- Music_Emu::unload();
-}
-
-// Track info
-
-static byte const* copy_field( byte const* in, char* out )
-{
- if ( in )
- {
- int len = 0x20;
- if ( in [0x1F] && !in [0x2F] )
- len = 0x30; // fields are sometimes 16 bytes longer (ugh)
-
- // since text fields are where any data could be, detect non-text
- // and fields with data after zero byte terminator
-
- int i = 0;
- for ( i = 0; i < len && in [i]; i++ )
- if ( ((in [i] + 1) & 0xFF) < ' ' + 1 ) // also treat 0xFF as non-text
- return 0; // non-ASCII found
-
- for ( ; i < len; i++ )
- if ( in [i] )
- return 0; // data after terminator
-
- Gme_File::copy_field_( out, (char const*) in, len );
- in += len;
- }
- return in;
-}
-
-static void copy_hes_fields( byte const* in, track_info_t* out )
-{
- if ( *in >= ' ' )
- {
- in = copy_field( in, out->game );
- in = copy_field( in, out->author );
- in = copy_field( in, out->copyright );
- }
-}
-
-blargg_err_t Hes_Emu::track_info_( track_info_t* out, int ) const
-{
- copy_hes_fields( rom.begin() + 0x20, out );
- return 0;
-}
-
-static blargg_err_t check_hes_header( void const* header )
-{
- if ( memcmp( header, "HESM", 4 ) )
- return gme_wrong_file_type;
- return 0;
-}
-
-struct Hes_File : Gme_Info_
-{
- struct header_t {
- char header [Hes_Emu::header_size];
- char unused [0x20];
- byte fields [0x30 * 3];
- } h;
-
- Hes_File() { set_type( gme_hes_type ); }
-
- blargg_err_t load_( Data_Reader& in )
- {
- assert( offsetof (header_t,fields) == Hes_Emu::header_size + 0x20 );
- blargg_err_t err = in.read( &h, sizeof h );
- if ( err )
- return (err == in.eof_error ? gme_wrong_file_type : err);
- return check_hes_header( &h );
- }
-
- blargg_err_t track_info_( track_info_t* out, int ) const
- {
- copy_hes_fields( h.fields, out );
- return 0;
- }
-};
-
-static Music_Emu* new_hes_emu () { return BLARGG_NEW Hes_Emu ; }
-static Music_Emu* new_hes_file() { return BLARGG_NEW Hes_File; }
-
-static gme_type_t_ const gme_hes_type_ = { "PC Engine", 256, &new_hes_emu, &new_hes_file, "HES", 1 };
-gme_type_t const gme_hes_type = &gme_hes_type_;
-
-
-// Setup
-
-blargg_err_t Hes_Emu::load_( Data_Reader& in )
-{
- assert( offsetof (header_t,unused [4]) == header_size );
- RETURN_ERR( rom.load( in, header_size, &header_, unmapped ) );
-
- RETURN_ERR( check_hes_header( header_.tag ) );
-
- if ( header_.vers != 0 )
- set_warning( "Unknown file version" );
-
- if ( memcmp( header_.data_tag, "DATA", 4 ) )
- set_warning( "Data header missing" );
-
- if ( memcmp( header_.unused, "\0\0\0\0", 4 ) )
- set_warning( "Unknown header data" );
-
- // File spec supports multiple blocks, but I haven't found any, and
- // many files have bad sizes in the only block, so it's simpler to
- // just try to load the damn data as best as possible.
-
- long addr = get_le32( header_.addr );
- long size = get_le32( header_.size );
- long const rom_max = 0x100000;
- if ( addr & ~(rom_max - 1) )
- {
- set_warning( "Invalid address" );
- addr &= rom_max - 1;
- }
- if ( (unsigned long) (addr + size) > (unsigned long) rom_max )
- set_warning( "Invalid size" );
-
- if ( size != rom.file_size() )
- {
- if ( size <= rom.file_size() - 4 && !memcmp( rom.begin() + size, "DATA", 4 ) )
- set_warning( "Multiple DATA not supported" );
- else if ( size < rom.file_size() )
- set_warning( "Extra file data" );
- else
- set_warning( "Missing file data" );
- }
-
- rom.set_addr( addr );
-
- set_voice_count( apu.osc_count );
-
- apu.volume( gain() );
-
- return setup_buffer( 7159091 );
-}
-
-void Hes_Emu::update_eq( blip_eq_t const& eq )
-{
- apu.treble_eq( eq );
-}
-
-void Hes_Emu::set_voice( int i, Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right )
-{
- apu.osc_output( i, center, left, right );
-}
-
-// Emulation
-
-void Hes_Emu::recalc_timer_load()
-{
- timer.load = timer.raw_load * timer_base + 1;
-}
-
-void Hes_Emu::set_tempo_( double t )
-{
- play_period = hes_time_t (period_60hz / t);
- timer_base = int (1024 / t);
- recalc_timer_load();
-}
-
-blargg_err_t Hes_Emu::start_track_( int track )
-{
- RETURN_ERR( Classic_Emu::start_track_( track ) );
-
- memset( ram, 0, sizeof ram ); // some HES music relies on zero fill
- memset( sgx, 0, sizeof sgx );
-
- apu.reset();
- cpu::reset();
-
- for ( unsigned i = 0; i < sizeof header_.banks; i++ )
- set_mmr( i, header_.banks [i] );
- set_mmr( page_count, 0xFF ); // unmapped beyond end of address space
-
- irq.disables = timer_mask | vdp_mask;
- irq.timer = future_hes_time;
- irq.vdp = future_hes_time;
-
- timer.enabled = false;
- timer.raw_load= 0x80;
- timer.count = timer.load;
- timer.fired = false;
- timer.last_time = 0;
-
- vdp.latch = 0;
- vdp.control = 0;
- vdp.next_vbl = 0;
-
- ram [0x1FF] = (idle_addr - 1) >> 8;
- ram [0x1FE] = (idle_addr - 1) & 0xFF;
- r.sp = 0xFD;
- r.pc = get_le16( header_.init_addr );
- r.a = track;
-
- recalc_timer_load();
- last_frame_hook = 0;
-
- return 0;
-}
-
-// Hardware
-
-void Hes_Emu::cpu_write_vdp( int addr, int data )
-{
- switch ( addr )
- {
- case 0:
- vdp.latch = data & 0x1F;
- break;
-
- case 2:
- if ( vdp.latch == 5 )
- {
- if ( data & 0x04 )
- set_warning( "Scanline interrupt unsupported" );
- run_until( time() );
- vdp.control = data;
- irq_changed();
- }
- else
- {
- debug_printf( "VDP not supported: $%02X <- $%02X\n", vdp.latch, data );
- }
- break;
-
- case 3:
- debug_printf( "VDP MSB not supported: $%02X <- $%02X\n", vdp.latch, data );
- break;
- }
-}
-
-void Hes_Emu::cpu_write_( hes_addr_t addr, int data )
-{
- if ( unsigned (addr - apu.start_addr) <= apu.end_addr - apu.start_addr )
- {
- GME_APU_HOOK( this, addr - apu.start_addr, data );
- // avoid going way past end when a long block xfer is writing to I/O space
- hes_time_t t = min( time(), end_time() + 8 );
- apu.write_data( t, addr, data );
- return;
- }
-
- hes_time_t time = this->time();
- switch ( addr )
- {
- case 0x0000:
- case 0x0002:
- case 0x0003:
- cpu_write_vdp( addr, data );
- return;
-
- case 0x0C00: {
- run_until( time );
- timer.raw_load = (data & 0x7F) + 1;
- recalc_timer_load();
- timer.count = timer.load;
- break;
- }
-
- case 0x0C01:
- data &= 1;
- if ( timer.enabled == data )
- return;
- run_until( time );
- timer.enabled = data;
- if ( data )
- timer.count = timer.load;
- break;
-
- case 0x1402:
- run_until( time );
- irq.disables = data;
- if ( (data & 0xF8) && (data & 0xF8) != 0xF8 ) // flag questionable values
- debug_printf( "Int mask: $%02X\n", data );
- break;
-
- case 0x1403:
- run_until( time );
- if ( timer.enabled )
- timer.count = timer.load;
- timer.fired = false;
- break;
-
-#ifndef NDEBUG
- case 0x1000: // I/O port
- case 0x0402: // palette
- case 0x0403:
- case 0x0404:
- case 0x0405:
- return;
-
- default:
- debug_printf( "unmapped write $%04X <- $%02X\n", addr, data );
- return;
-#endif
- }
-
- irq_changed();
-}
-
-int Hes_Emu::cpu_read_( hes_addr_t addr )
-{
- hes_time_t time = this->time();
- addr &= page_size - 1;
- switch ( addr )
- {
- case 0x0000:
- if ( irq.vdp > time )
- return 0;
- irq.vdp = future_hes_time;
- run_until( time );
- irq_changed();
- return 0x20;
-
- case 0x0002:
- case 0x0003:
- debug_printf( "VDP read not supported: %d\n", addr );
- return 0;
-
- case 0x0C01:
- //return timer.enabled; // TODO: remove?
- case 0x0C00:
- run_until( time );
- debug_printf( "Timer count read\n" );
- return (unsigned) (timer.count - 1) / timer_base;
-
- case 0x1402:
- return irq.disables;
-
- case 0x1403:
- {
- int status = 0;
- if ( irq.timer <= time ) status |= timer_mask;
- if ( irq.vdp <= time ) status |= vdp_mask;
- return status;
- }
-
- #ifndef NDEBUG
- case 0x1000: // I/O port
- case 0x180C: // CD-ROM
- case 0x180D:
- break;
-
- default:
- debug_printf( "unmapped read $%04X\n", addr );
- #endif
- }
-
- return unmapped;
-}
-
-// see hes_cpu_io.h for core read/write functions
-
-// Emulation
-
-void Hes_Emu::run_until( hes_time_t present )
-{
- while ( vdp.next_vbl < present )
- vdp.next_vbl += play_period;
-
- hes_time_t elapsed = present - timer.last_time;
- if ( elapsed > 0 )
- {
- if ( timer.enabled )
- {
- timer.count -= elapsed;
- if ( timer.count <= 0 )
- timer.count += timer.load;
- }
- timer.last_time = present;
- }
-}
-
-void Hes_Emu::irq_changed()
-{
- hes_time_t present = time();
-
- if ( irq.timer > present )
- {
- irq.timer = future_hes_time;
- if ( timer.enabled && !timer.fired )
- irq.timer = present + timer.count;
- }
-
- if ( irq.vdp > present )
- {
- irq.vdp = future_hes_time;
- if ( vdp.control & 0x08 )
- irq.vdp = vdp.next_vbl;
- }
-
- hes_time_t time = future_hes_time;
- if ( !(irq.disables & timer_mask) ) time = irq.timer;
- if ( !(irq.disables & vdp_mask) ) time = min( time, irq.vdp );
-
- set_irq_time( time );
-}
-
-int Hes_Emu::cpu_done()
-{
- check( time() >= end_time() ||
- (!(r.status & i_flag_mask) && time() >= irq_time()) );
-
- if ( !(r.status & i_flag_mask) )
- {
- hes_time_t present = time();
-
- if ( irq.timer <= present && !(irq.disables & timer_mask) )
- {
- timer.fired = true;
- irq.timer = future_hes_time;
- irq_changed(); // overkill, but not worth writing custom code
- #if GME_FRAME_HOOK_DEFINED
- {
- unsigned const threshold = period_60hz / 30;
- unsigned long elapsed = present - last_frame_hook;
- if ( elapsed - period_60hz + threshold / 2 < threshold )
- {
- last_frame_hook = present;
- GME_FRAME_HOOK( this );
- }
- }
- #endif
- return 0x0A;
- }
-
- if ( irq.vdp <= present && !(irq.disables & vdp_mask) )
- {
- // work around for bugs with music not acknowledging VDP
- //run_until( present );
- //irq.vdp = future_hes_time;
- //irq_changed();
- #if GME_FRAME_HOOK_DEFINED
- last_frame_hook = present;
- GME_FRAME_HOOK( this );
- #endif
- return 0x08;
- }
- }
- return 0;
-}
-
-static void adjust_time( blargg_long& time, hes_time_t delta )
-{
- if ( time < future_hes_time )
- {
- time -= delta;
- if ( time < 0 )
- time = 0;
- }
-}
-
-blargg_err_t Hes_Emu::run_clocks( blip_time_t& duration_, int )
-{
- blip_time_t const duration = duration_; // cache
-
- if ( cpu::run( duration ) )
- set_warning( "Emulation error (illegal instruction)" );
-
- check( time() >= duration );
- //check( time() - duration < 20 ); // Txx instruction could cause going way over
-
- run_until( duration );
-
- // end time frame
- timer.last_time -= duration;
- vdp.next_vbl -= duration;
- #if GME_FRAME_HOOK_DEFINED
- last_frame_hook -= duration;
- #endif
- cpu::end_frame( duration );
- ::adjust_time( irq.timer, duration );
- ::adjust_time( irq.vdp, duration );
- apu.end_frame( duration );
-
- return 0;
-}
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Hes_Emu.h b/plugins/gme/game-music-emu-0.5.5/gme/Hes_Emu.h
deleted file mode 100644
index d17983c5..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Hes_Emu.h
+++ /dev/null
@@ -1,94 +0,0 @@
-// TurboGrafx-16/PC Engine HES music file emulator
-
-// Game_Music_Emu 0.5.5
-#ifndef HES_EMU_H
-#define HES_EMU_H
-
-#include "Classic_Emu.h"
-#include "Hes_Apu.h"
-#include "Hes_Cpu.h"
-
-class Hes_Emu : private Hes_Cpu, public Classic_Emu {
- typedef Hes_Cpu cpu;
-public:
- // HES file header
- enum { header_size = 0x20 };
- struct header_t
- {
- byte tag [4];
- byte vers;
- byte first_track;
- byte init_addr [2];
- byte banks [8];
- byte data_tag [4];
- byte size [4];
- byte addr [4];
- byte unused [4];
- };
-
- // Header for currently loaded file
- header_t const& header() const { return header_; }
-
- static gme_type_t static_type() { return gme_hes_type; }
-
-public:
- Hes_Emu();
- ~Hes_Emu();
-protected:
- blargg_err_t track_info_( track_info_t*, int track ) const;
- blargg_err_t load_( Data_Reader& );
- blargg_err_t start_track_( int );
- blargg_err_t run_clocks( blip_time_t&, int );
- void set_tempo_( double );
- void set_voice( int, Blip_Buffer*, Blip_Buffer*, Blip_Buffer* );
- void update_eq( blip_eq_t const& );
- void unload();
-public: private: friend class Hes_Cpu;
- byte* write_pages [page_count + 1]; // 0 if unmapped or I/O space
-
- int cpu_read_( hes_addr_t );
- int cpu_read( hes_addr_t );
- void cpu_write_( hes_addr_t, int data );
- void cpu_write( hes_addr_t, int );
- void cpu_write_vdp( int addr, int data );
- byte const* cpu_set_mmr( int page, int bank );
- int cpu_done();
-private:
- Rom_Data<page_size> rom;
- header_t header_;
- hes_time_t play_period;
- hes_time_t last_frame_hook;
- int timer_base;
-
- struct {
- hes_time_t last_time;
- blargg_long count;
- blargg_long load;
- int raw_load;
- byte enabled;
- byte fired;
- } timer;
-
- struct {
- hes_time_t next_vbl;
- byte latch;
- byte control;
- } vdp;
-
- struct {
- hes_time_t timer;
- hes_time_t vdp;
- byte disables;
- } irq;
-
- void recalc_timer_load();
-
- // large items
- Hes_Apu apu;
- byte sgx [3 * page_size + cpu_padding];
-
- void irq_changed();
- void run_until( hes_time_t );
-};
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Kss_Cpu.cpp b/plugins/gme/game-music-emu-0.5.5/gme/Kss_Cpu.cpp
deleted file mode 100644
index dac483c1..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Kss_Cpu.cpp
+++ /dev/null
@@ -1,1706 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-/*
-Last validated with zexall 2006.11.14 2:19 PM
-* Doesn't implement the R register or immediate interrupt after EI.
-* Address wrap-around isn't completely correct, but is prevented from crashing emulator.
-*/
-
-#include "Kss_Cpu.h"
-
-#include "blargg_endian.h"
-#include <string.h>
-
-//#include "z80_cpu_log.h"
-
-/* Copyright (C) 2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#define SYNC_TIME() (void) (s.time = s_time)
-#define RELOAD_TIME() (void) (s_time = s.time)
-
-// Callbacks to emulator
-
-#define CPU_OUT( cpu, addr, data, time )\
- kss_cpu_out( this, time, addr, data )
-
-#define CPU_IN( cpu, addr, time )\
- kss_cpu_in( this, time, addr )
-
-#define CPU_WRITE( cpu, addr, data, time )\
- (SYNC_TIME(), kss_cpu_write( this, addr, data ))
-
-#include "blargg_source.h"
-
-// flags, named with hex value for clarity
-int const S80 = 0x80;
-int const Z40 = 0x40;
-int const F20 = 0x20;
-int const H10 = 0x10;
-int const F08 = 0x08;
-int const V04 = 0x04;
-int const P04 = 0x04;
-int const N02 = 0x02;
-int const C01 = 0x01;
-
-#define SZ28P( n ) szpc [n]
-#define SZ28PC( n ) szpc [n]
-#define SZ28C( n ) (szpc [n] & ~P04)
-#define SZ28( n ) SZ28C( n )
-
-#define SET_R( n ) (void) (r.r = n)
-#define GET_R() (r.r)
-
-Kss_Cpu::Kss_Cpu()
-{
- state = &state_;
-
- for ( int i = 0x100; --i >= 0; )
- {
- int even = 1;
- for ( int p = i; p; p >>= 1 )
- even ^= p;
- int n = (i & (S80 | F20 | F08)) | ((even & 1) * P04);
- szpc [i] = n;
- szpc [i + 0x100] = n | C01;
- }
- szpc [0x000] |= Z40;
- szpc [0x100] |= Z40;
-}
-
-inline void Kss_Cpu::set_page( int i, void* write, void const* read )
-{
- blargg_long offset = KSS_CPU_PAGE_OFFSET( i * (blargg_long) page_size );
- state->write [i] = (byte *) write - offset;
- state->read [i] = (byte const*) read - offset;
-}
-
-void Kss_Cpu::reset( void* unmapped_write, void const* unmapped_read )
-{
- check( state == &state_ );
- state = &state_;
- state_.time = 0;
- state_.base = 0;
- end_time_ = 0;
-
- for ( int i = 0; i < page_count + 1; i++ )
- set_page( i, unmapped_write, unmapped_read );
-
- memset( &r, 0, sizeof r );
-}
-
-void Kss_Cpu::map_mem( unsigned addr, blargg_ulong size, void* write, void const* read )
-{
- // address range must begin and end on page boundaries
- require( addr % page_size == 0 );
- require( size % page_size == 0 );
-
- unsigned first_page = addr / page_size;
- for ( unsigned i = size / page_size; i--; )
- {
- blargg_long offset = i * (blargg_long) page_size;
- set_page( first_page + i, (byte*) write + offset, (byte const*) read + offset );
- }
-}
-
-#define TIME (s_time + s.base)
-#define RW_MEM( addr, rw ) (s.rw [(addr) >> page_shift] [KSS_CPU_PAGE_OFFSET( addr )])
-#define READ_PROG( addr ) RW_MEM( addr, read )
-#define READ( addr ) READ_PROG( addr )
-//#define WRITE( addr, data ) (void) (RW_MEM( addr, write ) = data)
-#define WRITE( addr, data ) CPU_WRITE( this, addr, data, TIME )
-#define READ_WORD( addr ) GET_LE16( &READ( addr ) )
-#define WRITE_WORD( addr, data ) SET_LE16( &RW_MEM( addr, write ), data )
-#define IN( addr ) CPU_IN( this, addr, TIME )
-#define OUT( addr, data ) CPU_OUT( this, addr, data, TIME )
-
-#if BLARGG_BIG_ENDIAN
- #define R8( n, offset ) ((r8_ - offset) [n])
-#elif BLARGG_LITTLE_ENDIAN
- #define R8( n, offset ) ((r8_ - offset) [(n) ^ 1])
-#else
- #error "Byte order of CPU must be known"
-#endif
-
-//#define R16( n, shift, offset ) (r16_ [((n) >> shift) - (offset >> shift)])
-
-// help compiler see that it can just adjust stack offset, saving an extra instruction
-#define R16( n, shift, offset )\
- (*(uint16_t*) ((char*) r16_ - (offset >> (shift - 1)) + ((n) >> (shift - 1))))
-
-#define CASE5( a, b, c, d, e ) case 0x##a:case 0x##b:case 0x##c:case 0x##d:case 0x##e
-#define CASE6( a, b, c, d, e, f ) CASE5( a, b, c, d, e ): case 0x##f
-#define CASE7( a, b, c, d, e, f, g ) CASE6( a, b, c, d, e, f ): case 0x##g
-#define CASE8( a, b, c, d, e, f, g, h ) CASE7( a, b, c, d, e, f, g ): case 0x##h
-
-// high four bits are $ED time - 8, low four bits are $DD/$FD time - 8
-static byte const ed_dd_timing [0x100] = {
-//0 1 2 3 4 5 6 7 8 9 A B C D E F
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x06,0x0C,0x02,0x00,0x00,0x03,0x00,0x00,0x07,0x0C,0x02,0x00,0x00,0x03,0x00,
-0x00,0x00,0x00,0x00,0x0F,0x0F,0x0B,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
-0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x10,0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x10,
-0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x10,0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x10,
-0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0xA0,0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0xA0,
-0x4B,0x4B,0x7B,0xCB,0x0B,0x6B,0x00,0x0B,0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00,
-0x80,0x80,0x80,0x80,0x00,0x00,0x0B,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x0B,0x00,
-0xD0,0xD0,0xD0,0xD0,0x00,0x00,0x0B,0x00,0xD0,0xD0,0xD0,0xD0,0x00,0x00,0x0B,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x06,0x00,0x0F,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,
-};
-
-// even on x86, using short and unsigned char was slower
-typedef int fint16;
-typedef unsigned fuint16;
-typedef unsigned fuint8;
-
-bool Kss_Cpu::run( cpu_time_t end_time )
-{
- set_end_time( end_time );
- state_t s = this->state_;
- this->state = &s;
- bool warning = false;
-
- typedef BOOST::int8_t int8_t;
-
- union {
- regs_t rg;
- pairs_t rp;
- uint8_t r8_ [8]; // indexed
- uint16_t r16_ [4];
- };
- rg = this->r.b;
-
- cpu_time_t s_time = s.time;
- fuint16 pc = r.pc;
- fuint16 sp = r.sp;
- fuint16 ix = r.ix; // TODO: keep in memory for direct access?
- fuint16 iy = r.iy;
- int flags = r.b.flags;
-
- goto loop;
-jr_not_taken:
- s_time -= 5;
- goto loop;
-call_not_taken:
- s_time -= 7;
-jp_not_taken:
- pc += 2;
-loop:
-
- check( (unsigned long) pc < 0x10000 );
- check( (unsigned long) sp < 0x10000 );
- check( (unsigned) flags < 0x100 );
- check( (unsigned) ix < 0x10000 );
- check( (unsigned) iy < 0x10000 );
-
- uint8_t const* instr = s.read [pc >> page_shift];
-#define GET_ADDR() GET_LE16( instr )
-
- fuint8 opcode;
-
- // TODO: eliminate this special case
- #if BLARGG_NONPORTABLE
- opcode = instr [pc];
- pc++;
- instr += pc;
- #else
- instr += KSS_CPU_PAGE_OFFSET( pc );
- opcode = *instr++;
- pc++;
- #endif
-
- static byte const base_timing [0x100] = {
- // 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 4,10, 7, 6, 4, 4, 7, 4, 4,11, 7, 6, 4, 4, 7, 4, // 0
- 13,10, 7, 6, 4, 4, 7, 4,12,11, 7, 6, 4, 4, 7, 4, // 1
- 12,10,16, 6, 4, 4, 7, 4,12,11,16, 6, 4, 4, 7, 4, // 2
- 12,10,13, 6,11,11,10, 4,12,11,13, 6, 4, 4, 7, 4, // 3
- 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 4
- 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 5
- 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 6
- 7, 7, 7, 7, 7, 7, 4, 7, 4, 4, 4, 4, 4, 4, 7, 4, // 7
- 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 8
- 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 9
- 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // A
- 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // B
- 11,10,10,10,17,11, 7,11,11,10,10, 8,17,17, 7,11, // C
- 11,10,10,11,17,11, 7,11,11, 4,10,11,17, 8, 7,11, // D
- 11,10,10,19,17,11, 7,11,11, 4,10, 4,17, 8, 7,11, // E
- 11,10,10, 4,17,11, 7,11,11, 6,10, 4,17, 8, 7,11, // F
- };
-
- fuint16 data;
- data = base_timing [opcode];
- if ( (s_time += data) >= 0 )
- goto possibly_out_of_time;
-almost_out_of_time:
-
- data = READ_PROG( pc );
-
- #ifdef Z80_CPU_LOG_H
- //log_opcode( opcode, READ_PROG( pc ) );
- z80_log_regs( rg.a, rp.bc, rp.de, rp.hl, sp, ix, iy );
- z80_cpu_log( "new", pc - 1, opcode, READ_PROG( pc ),
- READ_PROG( pc + 1 ), READ_PROG( pc + 2 ) );
- #endif
-
- switch ( opcode )
- {
-possibly_out_of_time:
- if ( s_time < (int) data )
- goto almost_out_of_time;
- s_time -= data;
- goto out_of_time;
-
-// Common
-
- case 0x00: // NOP
- CASE7( 40, 49, 52, 5B, 64, 6D, 7F ): // LD B,B etc.
- goto loop;
-
- case 0x08:{// EX AF,AF'
- int temp = r.alt.b.a;
- r.alt.b.a = rg.a;
- rg.a = temp;
-
- temp = r.alt.b.flags;
- r.alt.b.flags = flags;
- flags = temp;
- goto loop;
- }
-
- case 0xD3: // OUT (imm),A
- pc++;
- OUT( data + rg.a * 0x100, rg.a );
- goto loop;
-
- case 0x2E: // LD L,imm
- pc++;
- rg.l = data;
- goto loop;
-
- case 0x3E: // LD A,imm
- pc++;
- rg.a = data;
- goto loop;
-
- case 0x3A:{// LD A,(addr)
- fuint16 addr = GET_ADDR();
- pc += 2;
- rg.a = READ( addr );
- goto loop;
- }
-
-// Conditional
-
-#define ZERO (flags & Z40)
-#define CARRY (flags & C01)
-#define EVEN (flags & P04)
-#define MINUS (flags & S80)
-
-// JR
-// TODO: more efficient way to handle negative branch that wraps PC around
-#define JR( cond ) {\
- int offset = (BOOST::int8_t) data;\
- pc++;\
- if ( !(cond) )\
- goto jr_not_taken;\
- pc = uint16_t (pc + offset);\
- goto loop;\
-}
-
- case 0x20: JR( !ZERO ) // JR NZ,disp
- case 0x28: JR( ZERO ) // JR Z,disp
- case 0x30: JR( !CARRY ) // JR NC,disp
- case 0x38: JR( CARRY ) // JR C,disp
- case 0x18: JR( true ) // JR disp
-
- case 0x10:{// DJNZ disp
- int temp = rg.b - 1;
- rg.b = temp;
- JR( temp )
- }
-
-// JP
-#define JP( cond ) if ( !(cond) ) goto jp_not_taken; pc = GET_ADDR(); goto loop;
-
- case 0xC2: JP( !ZERO ) // JP NZ,addr
- case 0xCA: JP( ZERO ) // JP Z,addr
- case 0xD2: JP( !CARRY ) // JP NC,addr
- case 0xDA: JP( CARRY ) // JP C,addr
- case 0xE2: JP( !EVEN ) // JP PO,addr
- case 0xEA: JP( EVEN ) // JP PE,addr
- case 0xF2: JP( !MINUS ) // JP P,addr
- case 0xFA: JP( MINUS ) // JP M,addr
-
- case 0xC3: // JP addr
- pc = GET_ADDR();
- goto loop;
-
- case 0xE9: // JP HL
- pc = rp.hl;
- goto loop;
-
-// RET
-#define RET( cond ) if ( cond ) goto ret_taken; s_time -= 6; goto loop;
-
- case 0xC0: RET( !ZERO ) // RET NZ
- case 0xC8: RET( ZERO ) // RET Z
- case 0xD0: RET( !CARRY ) // RET NC
- case 0xD8: RET( CARRY ) // RET C
- case 0xE0: RET( !EVEN ) // RET PO
- case 0xE8: RET( EVEN ) // RET PE
- case 0xF0: RET( !MINUS ) // RET P
- case 0xF8: RET( MINUS ) // RET M
-
- case 0xC9: // RET
- ret_taken:
- pc = READ_WORD( sp );
- sp = uint16_t (sp + 2);
- goto loop;
-
-// CALL
-#define CALL( cond ) if ( cond ) goto call_taken; goto call_not_taken;
-
- case 0xC4: CALL( !ZERO ) // CALL NZ,addr
- case 0xCC: CALL( ZERO ) // CALL Z,addr
- case 0xD4: CALL( !CARRY ) // CALL NC,addr
- case 0xDC: CALL( CARRY ) // CALL C,addr
- case 0xE4: CALL( !EVEN ) // CALL PO,addr
- case 0xEC: CALL( EVEN ) // CALL PE,addr
- case 0xF4: CALL( !MINUS ) // CALL P,addr
- case 0xFC: CALL( MINUS ) // CALL M,addr
-
- case 0xCD:{// CALL addr
- call_taken:
- fuint16 addr = pc + 2;
- pc = GET_ADDR();
- sp = uint16_t (sp - 2);
- WRITE_WORD( sp, addr );
- goto loop;
- }
-
- case 0xFF: // RST
- if ( pc > idle_addr )
- goto hit_idle_addr;
- CASE7( C7, CF, D7, DF, E7, EF, F7 ):
- data = pc;
- pc = opcode & 0x38;
- goto push_data;
-
-// PUSH/POP
- case 0xF5: // PUSH AF
- data = rg.a * 0x100u + flags;
- goto push_data;
-
- case 0xC5: // PUSH BC
- case 0xD5: // PUSH DE
- case 0xE5: // PUSH HL
- data = R16( opcode, 4, 0xC5 );
- push_data:
- sp = uint16_t (sp - 2);
- WRITE_WORD( sp, data );
- goto loop;
-
- case 0xF1: // POP AF
- flags = READ( sp );
- rg.a = READ( sp + 1 );
- sp = uint16_t (sp + 2);
- goto loop;
-
- case 0xC1: // POP BC
- case 0xD1: // POP DE
- case 0xE1: // POP HL
- R16( opcode, 4, 0xC1 ) = READ_WORD( sp );
- sp = uint16_t (sp + 2);
- goto loop;
-
-// ADC/ADD/SBC/SUB
- case 0x96: // SUB (HL)
- case 0x86: // ADD (HL)
- flags &= ~C01;
- case 0x9E: // SBC (HL)
- case 0x8E: // ADC (HL)
- data = READ( rp.hl );
- goto adc_data;
-
- case 0xD6: // SUB A,imm
- case 0xC6: // ADD imm
- flags &= ~C01;
- case 0xDE: // SBC A,imm
- case 0xCE: // ADC imm
- pc++;
- goto adc_data;
-
- CASE7( 90, 91, 92, 93, 94, 95, 97 ): // SUB r
- CASE7( 80, 81, 82, 83, 84, 85, 87 ): // ADD r
- flags &= ~C01;
- CASE7( 98, 99, 9A, 9B, 9C, 9D, 9F ): // SBC r
- CASE7( 88, 89, 8A, 8B, 8C, 8D, 8F ): // ADC r
- data = R8( opcode & 7, 0 );
- adc_data: {
- int result = data + (flags & C01);
- data ^= rg.a;
- flags = opcode >> 3 & N02; // bit 4 is set in subtract opcodes
- if ( flags )
- result = -result;
- result += rg.a;
- data ^= result;
- flags |=(data & H10) |
- ((data - -0x80) >> 6 & V04) |
- SZ28C( result & 0x1FF );
- rg.a = result;
- goto loop;
- }
-
-// CP
- case 0xBE: // CP (HL)
- data = READ( rp.hl );
- goto cp_data;
-
- case 0xFE: // CP imm
- pc++;
- goto cp_data;
-
- CASE7( B8, B9, BA, BB, BC, BD, BF ): // CP r
- data = R8( opcode, 0xB8 );
- cp_data: {
- int result = rg.a - data;
- flags = N02 | (data & (F20 | F08)) | (result >> 8 & C01);
- data ^= rg.a;
- flags |=(((result ^ rg.a) & data) >> 5 & V04) |
- (((data & H10) ^ result) & (S80 | H10));
- if ( (uint8_t) result )
- goto loop;
- flags |= Z40;
- goto loop;
- }
-
-// ADD HL,rp
-
- case 0x39: // ADD HL,SP
- data = sp;
- goto add_hl_data;
-
- case 0x09: // ADD HL,BC
- case 0x19: // ADD HL,DE
- case 0x29: // ADD HL,HL
- data = R16( opcode, 4, 0x09 );
- add_hl_data: {
- blargg_ulong sum = rp.hl + data;
- data ^= rp.hl;
- rp.hl = sum;
- flags = (flags & (S80 | Z40 | V04)) |
- (sum >> 16) |
- (sum >> 8 & (F20 | F08)) |
- ((data ^ sum) >> 8 & H10);
- goto loop;
- }
-
- case 0x27:{// DAA
- int a = rg.a;
- if ( a > 0x99 )
- flags |= C01;
-
- int adjust = 0x60 & -(flags & C01);
-
- if ( flags & H10 || (a & 0x0F) > 9 )
- adjust |= 0x06;
-
- if ( flags & N02 )
- adjust = -adjust;
- a += adjust;
-
- flags = (flags & (C01 | N02)) |
- ((rg.a ^ a) & H10) |
- SZ28P( (uint8_t) a );
- rg.a = a;
- goto loop;
- }
- /*
- case 0x27:{// DAA
- // more optimized, but probably not worth the obscurity
- int f = (rg.a + (0xFF - 0x99)) >> 8 | flags; // (a > 0x99 ? C01 : 0) | flags
- int adjust = 0x60 & -(f & C01); // f & C01 ? 0x60 : 0
-
- if ( (((rg.a + (0x0F - 9)) ^ rg.a) | f) & H10 ) // flags & H10 || (rg.a & 0x0F) > 9
- adjust |= 0x06;
-
- if ( f & N02 )
- adjust = -adjust;
- int a = rg.a + adjust;
-
- flags = (f & (N02 | C01)) | ((rg.a ^ a) & H10) | SZ28P( (uint8_t) a );
- rg.a = a;
- goto loop;
- }
- */
-
-// INC/DEC
- case 0x34: // INC (HL)
- data = READ( rp.hl ) + 1;
- WRITE( rp.hl, data );
- goto inc_set_flags;
-
- CASE7( 04, 0C, 14, 1C, 24, 2C, 3C ): // INC r
- data = ++R8( opcode >> 3, 0 );
- inc_set_flags:
- flags = (flags & C01) |
- (((data & 0x0F) - 1) & H10) |
- SZ28( (uint8_t) data );
- if ( data != 0x80 )
- goto loop;
- flags |= V04;
- goto loop;
-
- case 0x35: // DEC (HL)
- data = READ( rp.hl ) - 1;
- WRITE( rp.hl, data );
- goto dec_set_flags;
-
- CASE7( 05, 0D, 15, 1D, 25, 2D, 3D ): // DEC r
- data = --R8( opcode >> 3, 0 );
- dec_set_flags:
- flags = (flags & C01) | N02 |
- (((data & 0x0F) + 1) & H10) |
- SZ28( (uint8_t) data );
- if ( data != 0x7F )
- goto loop;
- flags |= V04;
- goto loop;
-
- case 0x03: // INC BC
- case 0x13: // INC DE
- case 0x23: // INC HL
- R16( opcode, 4, 0x03 )++;
- goto loop;
-
- case 0x33: // INC SP
- sp = uint16_t (sp + 1);
- goto loop;
-
- case 0x0B: // DEC BC
- case 0x1B: // DEC DE
- case 0x2B: // DEC HL
- R16( opcode, 4, 0x0B )--;
- goto loop;
-
- case 0x3B: // DEC SP
- sp = uint16_t (sp - 1);
- goto loop;
-
-// AND
- case 0xA6: // AND (HL)
- data = READ( rp.hl );
- goto and_data;
-
- case 0xE6: // AND imm
- pc++;
- goto and_data;
-
- CASE7( A0, A1, A2, A3, A4, A5, A7 ): // AND r
- data = R8( opcode, 0xA0 );
- and_data:
- rg.a &= data;
- flags = SZ28P( rg.a ) | H10;
- goto loop;
-
-// OR
- case 0xB6: // OR (HL)
- data = READ( rp.hl );
- goto or_data;
-
- case 0xF6: // OR imm
- pc++;
- goto or_data;
-
- CASE7( B0, B1, B2, B3, B4, B5, B7 ): // OR r
- data = R8( opcode, 0xB0 );
- or_data:
- rg.a |= data;
- flags = SZ28P( rg.a );
- goto loop;
-
-// XOR
- case 0xAE: // XOR (HL)
- data = READ( rp.hl );
- goto xor_data;
-
- case 0xEE: // XOR imm
- pc++;
- goto xor_data;
-
- CASE7( A8, A9, AA, AB, AC, AD, AF ): // XOR r
- data = R8( opcode, 0xA8 );
- xor_data:
- rg.a ^= data;
- flags = SZ28P( rg.a );
- goto loop;
-
-// LD
- CASE7( 70, 71, 72, 73, 74, 75, 77 ): // LD (HL),r
- WRITE( rp.hl, R8( opcode, 0x70 ) );
- goto loop;
-
- CASE6( 41, 42, 43, 44, 45, 47 ): // LD B,r
- CASE6( 48, 4A, 4B, 4C, 4D, 4F ): // LD C,r
- CASE6( 50, 51, 53, 54, 55, 57 ): // LD D,r
- CASE6( 58, 59, 5A, 5C, 5D, 5F ): // LD E,r
- CASE6( 60, 61, 62, 63, 65, 67 ): // LD H,r
- CASE6( 68, 69, 6A, 6B, 6C, 6F ): // LD L,r
- CASE6( 78, 79, 7A, 7B, 7C, 7D ): // LD A,r
- R8( opcode >> 3 & 7, 0 ) = R8( opcode & 7, 0 );
- goto loop;
-
- CASE5( 06, 0E, 16, 1E, 26 ): // LD r,imm
- R8( opcode >> 3, 0 ) = data;
- pc++;
- goto loop;
-
- case 0x36: // LD (HL),imm
- pc++;
- WRITE( rp.hl, data );
- goto loop;
-
- CASE7( 46, 4E, 56, 5E, 66, 6E, 7E ): // LD r,(HL)
- R8( opcode >> 3, 8 ) = READ( rp.hl );
- goto loop;
-
- case 0x01: // LD rp,imm
- case 0x11:
- case 0x21:
- R16( opcode, 4, 0x01 ) = GET_ADDR();
- pc += 2;
- goto loop;
-
- case 0x31: // LD sp,imm
- sp = GET_ADDR();
- pc += 2;
- goto loop;
-
- case 0x2A:{// LD HL,(addr)
- fuint16 addr = GET_ADDR();
- pc += 2;
- rp.hl = READ_WORD( addr );
- goto loop;
- }
-
- case 0x32:{// LD (addr),A
- fuint16 addr = GET_ADDR();
- pc += 2;
- WRITE( addr, rg.a );
- goto loop;
- }
-
- case 0x22:{// LD (addr),HL
- fuint16 addr = GET_ADDR();
- pc += 2;
- WRITE_WORD( addr, rp.hl );
- goto loop;
- }
-
- case 0x02: // LD (BC),A
- case 0x12: // LD (DE),A
- WRITE( R16( opcode, 4, 0x02 ), rg.a );
- goto loop;
-
- case 0x0A: // LD A,(BC)
- case 0x1A: // LD A,(DE)
- rg.a = READ( R16( opcode, 4, 0x0A ) );
- goto loop;
-
- case 0xF9: // LD SP,HL
- sp = rp.hl;
- goto loop;
-
-// Rotate
-
- case 0x07:{// RLCA
- fuint16 temp = rg.a;
- temp = (temp << 1) | (temp >> 7);
- flags = (flags & (S80 | Z40 | P04)) |
- (temp & (F20 | F08 | C01));
- rg.a = temp;
- goto loop;
- }
-
- case 0x0F:{// RRCA
- fuint16 temp = rg.a;
- flags = (flags & (S80 | Z40 | P04)) |
- (temp & C01);
- temp = (temp << 7) | (temp >> 1);
- flags |= temp & (F20 | F08);
- rg.a = temp;
- goto loop;
- }
-
- case 0x17:{// RLA
- blargg_ulong temp = (rg.a << 1) | (flags & C01);
- flags = (flags & (S80 | Z40 | P04)) |
- (temp & (F20 | F08)) |
- (temp >> 8);
- rg.a = temp;
- goto loop;
- }
-
- case 0x1F:{// RRA
- fuint16 temp = (flags << 7) | (rg.a >> 1);
- flags = (flags & (S80 | Z40 | P04)) |
- (temp & (F20 | F08)) |
- (rg.a & C01);
- rg.a = temp;
- goto loop;
- }
-
-// Misc
- case 0x2F:{// CPL
- fuint16 temp = ~rg.a;
- flags = (flags & (S80 | Z40 | P04 | C01)) |
- (temp & (F20 | F08)) |
- (H10 | N02);
- rg.a = temp;
- goto loop;
- }
-
- case 0x3F:{// CCF
- flags = ((flags & (S80 | Z40 | P04 | C01)) ^ C01) |
- (flags << 4 & H10) |
- (rg.a & (F20 | F08));
- goto loop;
- }
-
- case 0x37: // SCF
- flags = (flags & (S80 | Z40 | P04)) | C01 |
- (rg.a & (F20 | F08));
- goto loop;
-
- case 0xDB: // IN A,(imm)
- pc++;
- rg.a = IN( data + rg.a * 0x100 );
- goto loop;
-
- case 0xE3:{// EX (SP),HL
- fuint16 temp = READ_WORD( sp );
- WRITE_WORD( sp, rp.hl );
- rp.hl = temp;
- goto loop;
- }
-
- case 0xEB:{// EX DE,HL
- fuint16 temp = rp.hl;
- rp.hl = rp.de;
- rp.de = temp;
- goto loop;
- }
-
- case 0xD9:{// EXX DE,HL
- fuint16 temp = r.alt.w.bc;
- r.alt.w.bc = rp.bc;
- rp.bc = temp;
-
- temp = r.alt.w.de;
- r.alt.w.de = rp.de;
- rp.de = temp;
-
- temp = r.alt.w.hl;
- r.alt.w.hl = rp.hl;
- rp.hl = temp;
- goto loop;
- }
-
- case 0xF3: // DI
- r.iff1 = 0;
- r.iff2 = 0;
- goto loop;
-
- case 0xFB: // EI
- r.iff1 = 1;
- r.iff2 = 1;
- // TODO: delayed effect
- goto loop;
-
- case 0x76: // HALT
- goto halt;
-
-//////////////////////////////////////// CB prefix
- {
- case 0xCB:
- unsigned data2;
- data2 = instr [1];
- pc++;
- switch ( data )
- {
-
- // Rotate left
-
- #define RLC( read, write ) {\
- fuint8 result = read;\
- result = uint8_t (result << 1) | (result >> 7);\
- flags = SZ28P( result ) | (result & C01);\
- write;\
- goto loop;\
- }
-
- case 0x06: // RLC (HL)
- s_time += 7;
- data = rp.hl;
- rlc_data_addr:
- RLC( READ( data ), WRITE( data, result ) )
-
- CASE7( 00, 01, 02, 03, 04, 05, 07 ):{// RLC r
- uint8_t& reg = R8( data, 0 );
- RLC( reg, reg = result )
- }
-
- #define RL( read, write ) {\
- fuint16 result = (read << 1) | (flags & C01);\
- flags = SZ28PC( result );\
- write;\
- goto loop;\
- }
-
- case 0x16: // RL (HL)
- s_time += 7;
- data = rp.hl;
- rl_data_addr:
- RL( READ( data ), WRITE( data, result ) )
-
- CASE7( 10, 11, 12, 13, 14, 15, 17 ):{// RL r
- uint8_t& reg = R8( data, 0x10 );
- RL( reg, reg = result )
- }
-
- #define SLA( read, add, write ) {\
- fuint16 result = (read << 1) | add;\
- flags = SZ28PC( result );\
- write;\
- goto loop;\
- }
-
- case 0x26: // SLA (HL)
- s_time += 7;
- data = rp.hl;
- sla_data_addr:
- SLA( READ( data ), 0, WRITE( data, result ) )
-
- CASE7( 20, 21, 22, 23, 24, 25, 27 ):{// SLA r
- uint8_t& reg = R8( data, 0x20 );
- SLA( reg, 0, reg = result )
- }
-
- case 0x36: // SLL (HL)
- s_time += 7;
- data = rp.hl;
- sll_data_addr:
- SLA( READ( data ), 1, WRITE( data, result ) )
-
- CASE7( 30, 31, 32, 33, 34, 35, 37 ):{// SLL r
- uint8_t& reg = R8( data, 0x30 );
- SLA( reg, 1, reg = result )
- }
-
- // Rotate right
-
- #define RRC( read, write ) {\
- fuint8 result = read;\
- flags = result & C01;\
- result = uint8_t (result << 7) | (result >> 1);\
- flags |= SZ28P( result );\
- write;\
- goto loop;\
- }
-
- case 0x0E: // RRC (HL)
- s_time += 7;
- data = rp.hl;
- rrc_data_addr:
- RRC( READ( data ), WRITE( data, result ) )
-
- CASE7( 08, 09, 0A, 0B, 0C, 0D, 0F ):{// RRC r
- uint8_t& reg = R8( data, 0x08 );
- RRC( reg, reg = result )
- }
-
- #define RR( read, write ) {\
- fuint8 result = read;\
- fuint8 temp = result & C01;\
- result = uint8_t (flags << 7) | (result >> 1);\
- flags = SZ28P( result ) | temp;\
- write;\
- goto loop;\
- }
-
- case 0x1E: // RR (HL)
- s_time += 7;
- data = rp.hl;
- rr_data_addr:
- RR( READ( data ), WRITE( data, result ) )
-
- CASE7( 18, 19, 1A, 1B, 1C, 1D, 1F ):{// RR r
- uint8_t& reg = R8( data, 0x18 );
- RR( reg, reg = result )
- }
-
- #define SRA( read, write ) {\
- fuint8 result = read;\
- flags = result & C01;\
- result = (result & 0x80) | (result >> 1);\
- flags |= SZ28P( result );\
- write;\
- goto loop;\
- }
-
- case 0x2E: // SRA (HL)
- data = rp.hl;
- s_time += 7;
- sra_data_addr:
- SRA( READ( data ), WRITE( data, result ) )
-
- CASE7( 28, 29, 2A, 2B, 2C, 2D, 2F ):{// SRA r
- uint8_t& reg = R8( data, 0x28 );
- SRA( reg, reg = result )
- }
-
- #define SRL( read, write ) {\
- fuint8 result = read;\
- flags = result & C01;\
- result >>= 1;\
- flags |= SZ28P( result );\
- write;\
- goto loop;\
- }
-
- case 0x3E: // SRL (HL)
- s_time += 7;
- data = rp.hl;
- srl_data_addr:
- SRL( READ( data ), WRITE( data, result ) )
-
- CASE7( 38, 39, 3A, 3B, 3C, 3D, 3F ):{// SRL r
- uint8_t& reg = R8( data, 0x38 );
- SRL( reg, reg = result )
- }
-
- // BIT
- {
- unsigned temp;
- CASE8( 46, 4E, 56, 5E, 66, 6E, 76, 7E ): // BIT b,(HL)
- s_time += 4;
- temp = READ( rp.hl );
- flags &= C01;
- goto bit_temp;
- CASE7( 40, 41, 42, 43, 44, 45, 47 ): // BIT 0,r
- CASE7( 48, 49, 4A, 4B, 4C, 4D, 4F ): // BIT 1,r
- CASE7( 50, 51, 52, 53, 54, 55, 57 ): // BIT 2,r
- CASE7( 58, 59, 5A, 5B, 5C, 5D, 5F ): // BIT 3,r
- CASE7( 60, 61, 62, 63, 64, 65, 67 ): // BIT 4,r
- CASE7( 68, 69, 6A, 6B, 6C, 6D, 6F ): // BIT 5,r
- CASE7( 70, 71, 72, 73, 74, 75, 77 ): // BIT 6,r
- CASE7( 78, 79, 7A, 7B, 7C, 7D, 7F ): // BIT 7,r
- temp = R8( data & 7, 0 );
- flags = (flags & C01) | (temp & (F20 | F08));
- bit_temp:
- int masked = temp & 1 << (data >> 3 & 7);
- flags |=(masked & S80) | H10 |
- ((masked - 1) >> 8 & (Z40 | P04));
- goto loop;
- }
-
- // SET/RES
- CASE8( 86, 8E, 96, 9E, A6, AE, B6, BE ): // RES b,(HL)
- CASE8( C6, CE, D6, DE, E6, EE, F6, FE ):{// SET b,(HL)
- s_time += 7;
- int temp = READ( rp.hl );
- int bit = 1 << (data >> 3 & 7);
- temp |= bit; // SET
- if ( !(data & 0x40) )
- temp ^= bit; // RES
- WRITE( rp.hl, temp );
- goto loop;
- }
-
- CASE7( C0, C1, C2, C3, C4, C5, C7 ): // SET 0,r
- CASE7( C8, C9, CA, CB, CC, CD, CF ): // SET 1,r
- CASE7( D0, D1, D2, D3, D4, D5, D7 ): // SET 2,r
- CASE7( D8, D9, DA, DB, DC, DD, DF ): // SET 3,r
- CASE7( E0, E1, E2, E3, E4, E5, E7 ): // SET 4,r
- CASE7( E8, E9, EA, EB, EC, ED, EF ): // SET 5,r
- CASE7( F0, F1, F2, F3, F4, F5, F7 ): // SET 6,r
- CASE7( F8, F9, FA, FB, FC, FD, FF ): // SET 7,r
- R8( data & 7, 0 ) |= 1 << (data >> 3 & 7);
- goto loop;
-
- CASE7( 80, 81, 82, 83, 84, 85, 87 ): // RES 0,r
- CASE7( 88, 89, 8A, 8B, 8C, 8D, 8F ): // RES 1,r
- CASE7( 90, 91, 92, 93, 94, 95, 97 ): // RES 2,r
- CASE7( 98, 99, 9A, 9B, 9C, 9D, 9F ): // RES 3,r
- CASE7( A0, A1, A2, A3, A4, A5, A7 ): // RES 4,r
- CASE7( A8, A9, AA, AB, AC, AD, AF ): // RES 5,r
- CASE7( B0, B1, B2, B3, B4, B5, B7 ): // RES 6,r
- CASE7( B8, B9, BA, BB, BC, BD, BF ): // RES 7,r
- R8( data & 7, 0 ) &= ~(1 << (data >> 3 & 7));
- goto loop;
- }
- assert( false );
- }
-
-#undef GET_ADDR
-#define GET_ADDR() GET_LE16( instr + 1 )
-
-//////////////////////////////////////// ED prefix
- {
- case 0xED:
- pc++;
- s_time += ed_dd_timing [data] >> 4;
- switch ( data )
- {
- {
- blargg_ulong temp;
- case 0x72: // SBC HL,SP
- case 0x7A: // ADC HL,SP
- temp = sp;
- if ( 0 )
- case 0x42: // SBC HL,BC
- case 0x52: // SBC HL,DE
- case 0x62: // SBC HL,HL
- case 0x4A: // ADC HL,BC
- case 0x5A: // ADC HL,DE
- case 0x6A: // ADC HL,HL
- temp = R16( data >> 3 & 6, 1, 0 );
- blargg_ulong sum = temp + (flags & C01);
- flags = ~data >> 2 & N02;
- if ( flags )
- sum = -sum;
- sum += rp.hl;
- temp ^= rp.hl;
- temp ^= sum;
- flags |=(sum >> 16 & C01) |
- (temp >> 8 & H10) |
- (sum >> 8 & (S80 | F20 | F08)) |
- ((temp - -0x8000) >> 14 & V04);
- rp.hl = sum;
- if ( (uint16_t) sum )
- goto loop;
- flags |= Z40;
- goto loop;
- }
-
- CASE8( 40, 48, 50, 58, 60, 68, 70, 78 ):{// IN r,(C)
- int temp = IN( rp.bc );
- R8( data >> 3, 8 ) = temp;
- flags = (flags & C01) | SZ28P( temp );
- goto loop;
- }
-
- case 0x71: // OUT (C),0
- rg.flags = 0;
- CASE7( 41, 49, 51, 59, 61, 69, 79 ): // OUT (C),r
- OUT( rp.bc, R8( data >> 3, 8 ) );
- goto loop;
-
- {
- unsigned temp;
- case 0x73: // LD (ADDR),SP
- temp = sp;
- if ( 0 )
- case 0x43: // LD (ADDR),BC
- case 0x53: // LD (ADDR),DE
- temp = R16( data, 4, 0x43 );
- fuint16 addr = GET_ADDR();
- pc += 2;
- WRITE_WORD( addr, temp );
- goto loop;
- }
-
- case 0x4B: // LD BC,(ADDR)
- case 0x5B:{// LD DE,(ADDR)
- fuint16 addr = GET_ADDR();
- pc += 2;
- R16( data, 4, 0x4B ) = READ_WORD( addr );
- goto loop;
- }
-
- case 0x7B:{// LD SP,(ADDR)
- fuint16 addr = GET_ADDR();
- pc += 2;
- sp = READ_WORD( addr );
- goto loop;
- }
-
- case 0x67:{// RRD
- fuint8 temp = READ( rp.hl );
- WRITE( rp.hl, (rg.a << 4) | (temp >> 4) );
- temp = (rg.a & 0xF0) | (temp & 0x0F);
- flags = (flags & C01) | SZ28P( temp );
- rg.a = temp;
- goto loop;
- }
-
- case 0x6F:{// RLD
- fuint8 temp = READ( rp.hl );
- WRITE( rp.hl, (temp << 4) | (rg.a & 0x0F) );
- temp = (rg.a & 0xF0) | (temp >> 4);
- flags = (flags & C01) | SZ28P( temp );
- rg.a = temp;
- goto loop;
- }
-
- CASE8( 44, 4C, 54, 5C, 64, 6C, 74, 7C ): // NEG
- opcode = 0x10; // flag to do SBC instead of ADC
- flags &= ~C01;
- data = rg.a;
- rg.a = 0;
- goto adc_data;
-
- {
- int inc;
- case 0xA9: // CPD
- case 0xB9: // CPDR
- inc = -1;
- if ( 0 )
- case 0xA1: // CPI
- case 0xB1: // CPIR
- inc = +1;
- fuint16 addr = rp.hl;
- rp.hl = addr + inc;
- int temp = READ( addr );
-
- int result = rg.a - temp;
- flags = (flags & C01) | N02 |
- ((((temp ^ rg.a) & H10) ^ result) & (S80 | H10));
-
- if ( !(uint8_t) result ) flags |= Z40;
- result -= (flags & H10) >> 4;
- flags |= result & F08;
- flags |= result << 4 & F20;
- if ( !--rp.bc )
- goto loop;
-
- flags |= V04;
- if ( flags & Z40 || data < 0xB0 )
- goto loop;
-
- pc -= 2;
- s_time += 5;
- goto loop;
- }
-
- {
- int inc;
- case 0xA8: // LDD
- case 0xB8: // LDDR
- inc = -1;
- if ( 0 )
- case 0xA0: // LDI
- case 0xB0: // LDIR
- inc = +1;
- fuint16 addr = rp.hl;
- rp.hl = addr + inc;
- int temp = READ( addr );
-
- addr = rp.de;
- rp.de = addr + inc;
- WRITE( addr, temp );
-
- temp += rg.a;
- flags = (flags & (S80 | Z40 | C01)) |
- (temp & F08) | (temp << 4 & F20);
- if ( !--rp.bc )
- goto loop;
-
- flags |= V04;
- if ( data < 0xB0 )
- goto loop;
-
- pc -= 2;
- s_time += 5;
- goto loop;
- }
-
- {
- int inc;
- case 0xAB: // OUTD
- case 0xBB: // OTDR
- inc = -1;
- if ( 0 )
- case 0xA3: // OUTI
- case 0xB3: // OTIR
- inc = +1;
- fuint16 addr = rp.hl;
- rp.hl = addr + inc;
- int temp = READ( addr );
-
- int b = --rg.b;
- flags = (temp >> 6 & N02) | SZ28( b );
- if ( b && data >= 0xB0 )
- {
- pc -= 2;
- s_time += 5;
- }
-
- OUT( rp.bc, temp );
- goto loop;
- }
-
- {
- int inc;
- case 0xAA: // IND
- case 0xBA: // INDR
- inc = -1;
- if ( 0 )
- case 0xA2: // INI
- case 0xB2: // INIR
- inc = +1;
-
- fuint16 addr = rp.hl;
- rp.hl = addr + inc;
-
- int temp = IN( rp.bc );
-
- int b = --rg.b;
- flags = (temp >> 6 & N02) | SZ28( b );
- if ( b && data >= 0xB0 )
- {
- pc -= 2;
- s_time += 5;
- }
-
- WRITE( addr, temp );
- goto loop;
- }
-
- case 0x47: // LD I,A
- r.i = rg.a;
- goto loop;
-
- case 0x4F: // LD R,A
- SET_R( rg.a );
- debug_printf( "LD R,A not supported\n" );
- warning = true;
- goto loop;
-
- case 0x57: // LD A,I
- rg.a = r.i;
- goto ld_ai_common;
-
- case 0x5F: // LD A,R
- rg.a = GET_R();
- debug_printf( "LD A,R not supported\n" );
- warning = true;
- ld_ai_common:
- flags = (flags & C01) | SZ28( rg.a ) | (r.iff2 << 2 & V04);
- goto loop;
-
- CASE8( 45, 4D, 55, 5D, 65, 6D, 75, 7D ): // RETI/RETN
- r.iff1 = r.iff2;
- goto ret_taken;
-
- case 0x46: case 0x4E: case 0x66: case 0x6E: // IM 0
- r.im = 0;
- goto loop;
-
- case 0x56: case 0x76: // IM 1
- r.im = 1;
- goto loop;
-
- case 0x5E: case 0x7E: // IM 2
- r.im = 2;
- goto loop;
-
- default:
- debug_printf( "Opcode $ED $%02X not supported\n", data );
- warning = true;
- goto loop;
- }
- assert( false );
- }
-
-//////////////////////////////////////// DD/FD prefix
- {
- fuint16 ixy;
- case 0xDD:
- ixy = ix;
- goto ix_prefix;
- case 0xFD:
- ixy = iy;
- ix_prefix:
- pc++;
- unsigned data2 = READ_PROG( pc );
- s_time += ed_dd_timing [data] & 0x0F;
- switch ( data )
- {
- // TODO: more efficient way of avoid negative address
- // TODO: avoid using this as argument to READ() since it is evaluated twice
- #define IXY_DISP( ixy, disp ) uint16_t ((ixy) + (disp))
-
- #define SET_IXY( in ) if ( opcode == 0xDD ) ix = in; else iy = in;
-
- // ADD/ADC/SUB/SBC
-
- case 0x96: // SUB (IXY+disp)
- case 0x86: // ADD (IXY+disp)
- flags &= ~C01;
- case 0x9E: // SBC (IXY+disp)
- case 0x8E: // ADC (IXY+disp)
- pc++;
- opcode = data;
- data = READ( IXY_DISP( ixy, (int8_t) data2 ) );
- goto adc_data;
-
- case 0x94: // SUB HXY
- case 0x84: // ADD HXY
- flags &= ~C01;
- case 0x9C: // SBC HXY
- case 0x8C: // ADC HXY
- opcode = data;
- data = ixy >> 8;
- goto adc_data;
-
- case 0x95: // SUB LXY
- case 0x85: // ADD LXY
- flags &= ~C01;
- case 0x9D: // SBC LXY
- case 0x8D: // ADC LXY
- opcode = data;
- data = (uint8_t) ixy;
- goto adc_data;
-
- {
- unsigned temp;
- case 0x39: // ADD IXY,SP
- temp = sp;
- goto add_ixy_data;
-
- case 0x29: // ADD IXY,HL
- temp = ixy;
- goto add_ixy_data;
-
- case 0x09: // ADD IXY,BC
- case 0x19: // ADD IXY,DE
- temp = R16( data, 4, 0x09 );
- add_ixy_data: {
- blargg_ulong sum = ixy + temp;
- temp ^= ixy;
- ixy = (uint16_t) sum;
- flags = (flags & (S80 | Z40 | V04)) |
- (sum >> 16) |
- (sum >> 8 & (F20 | F08)) |
- ((temp ^ sum) >> 8 & H10);
- goto set_ixy;
- }
- }
-
- // AND
- case 0xA6: // AND (IXY+disp)
- pc++;
- data = READ( IXY_DISP( ixy, (int8_t) data2 ) );
- goto and_data;
-
- case 0xA4: // AND HXY
- data = ixy >> 8;
- goto and_data;
-
- case 0xA5: // AND LXY
- data = (uint8_t) ixy;
- goto and_data;
-
- // OR
- case 0xB6: // OR (IXY+disp)
- pc++;
- data = READ( IXY_DISP( ixy, (int8_t) data2 ) );
- goto or_data;
-
- case 0xB4: // OR HXY
- data = ixy >> 8;
- goto or_data;
-
- case 0xB5: // OR LXY
- data = (uint8_t) ixy;
- goto or_data;
-
- // XOR
- case 0xAE: // XOR (IXY+disp)
- pc++;
- data = READ( IXY_DISP( ixy, (int8_t) data2 ) );
- goto xor_data;
-
- case 0xAC: // XOR HXY
- data = ixy >> 8;
- goto xor_data;
-
- case 0xAD: // XOR LXY
- data = (uint8_t) ixy;
- goto xor_data;
-
- // CP
- case 0xBE: // CP (IXY+disp)
- pc++;
- data = READ( IXY_DISP( ixy, (int8_t) data2 ) );
- goto cp_data;
-
- case 0xBC: // CP HXY
- data = ixy >> 8;
- goto cp_data;
-
- case 0xBD: // CP LXY
- data = (uint8_t) ixy;
- goto cp_data;
-
- // LD
- CASE7( 70, 71, 72, 73, 74, 75, 77 ): // LD (IXY+disp),r
- data = R8( data, 0x70 );
- if ( 0 )
- case 0x36: // LD (IXY+disp),imm
- pc++, data = READ_PROG( pc );
- pc++;
- WRITE( IXY_DISP( ixy, (int8_t) data2 ), data );
- goto loop;
-
- CASE5( 44, 4C, 54, 5C, 7C ): // LD r,HXY
- R8( data >> 3, 8 ) = ixy >> 8;
- goto loop;
-
- case 0x64: // LD HXY,HXY
- case 0x6D: // LD LXY,LXY
- goto loop;
-
- CASE5( 45, 4D, 55, 5D, 7D ): // LD r,LXY
- R8( data >> 3, 8 ) = ixy;
- goto loop;
-
- CASE7( 46, 4E, 56, 5E, 66, 6E, 7E ): // LD r,(IXY+disp)
- pc++;
- R8( data >> 3, 8 ) = READ( IXY_DISP( ixy, (int8_t) data2 ) );
- goto loop;
-
- case 0x26: // LD HXY,imm
- pc++;
- goto ld_hxy_data;
-
- case 0x65: // LD HXY,LXY
- data2 = (uint8_t) ixy;
- goto ld_hxy_data;
-
- CASE5( 60, 61, 62, 63, 67 ): // LD HXY,r
- data2 = R8( data, 0x60 );
- ld_hxy_data:
- ixy = (uint8_t) ixy | (data2 << 8);
- goto set_ixy;
-
- case 0x2E: // LD LXY,imm
- pc++;
- goto ld_lxy_data;
-
- case 0x6C: // LD LXY,HXY
- data2 = ixy >> 8;
- goto ld_lxy_data;
-
- CASE5( 68, 69, 6A, 6B, 6F ): // LD LXY,r
- data2 = R8( data, 0x68 );
- ld_lxy_data:
- ixy = (ixy & 0xFF00) | data2;
- set_ixy:
- if ( opcode == 0xDD )
- {
- ix = ixy;
- goto loop;
- }
- iy = ixy;
- goto loop;
-
- case 0xF9: // LD SP,IXY
- sp = ixy;
- goto loop;
-
- case 0x22:{// LD (ADDR),IXY
- fuint16 addr = GET_ADDR();
- pc += 2;
- WRITE_WORD( addr, ixy );
- goto loop;
- }
-
- case 0x21: // LD IXY,imm
- ixy = GET_ADDR();
- pc += 2;
- goto set_ixy;
-
- case 0x2A:{// LD IXY,(addr)
- fuint16 addr = GET_ADDR();
- ixy = READ_WORD( addr );
- pc += 2;
- goto set_ixy;
- }
-
- // DD/FD CB prefix
- case 0xCB: {
- data = IXY_DISP( ixy, (int8_t) data2 );
- pc++;
- data2 = READ_PROG( pc );
- pc++;
- switch ( data2 )
- {
- case 0x06: goto rlc_data_addr; // RLC (IXY)
- case 0x16: goto rl_data_addr; // RL (IXY)
- case 0x26: goto sla_data_addr; // SLA (IXY)
- case 0x36: goto sll_data_addr; // SLL (IXY)
- case 0x0E: goto rrc_data_addr; // RRC (IXY)
- case 0x1E: goto rr_data_addr; // RR (IXY)
- case 0x2E: goto sra_data_addr; // SRA (IXY)
- case 0x3E: goto srl_data_addr; // SRL (IXY)
-
- CASE8( 46, 4E, 56, 5E, 66, 6E, 76, 7E ):{// BIT b,(IXY+disp)
- fuint8 temp = READ( data );
- int masked = temp & 1 << (data2 >> 3 & 7);
- flags = (flags & C01) | H10 |
- (masked & S80) |
- ((masked - 1) >> 8 & (Z40 | P04));
- goto loop;
- }
-
- CASE8( 86, 8E, 96, 9E, A6, AE, B6, BE ): // RES b,(IXY+disp)
- CASE8( C6, CE, D6, DE, E6, EE, F6, FE ):{// SET b,(IXY+disp)
- int temp = READ( data );
- int bit = 1 << (data2 >> 3 & 7);
- temp |= bit; // SET
- if ( !(data2 & 0x40) )
- temp ^= bit; // RES
- WRITE( data, temp );
- goto loop;
- }
-
- default:
- debug_printf( "Opcode $%02X $CB $%02X not supported\n", opcode, data2 );
- warning = true;
- goto loop;
- }
- assert( false );
- }
-
- // INC/DEC
- case 0x23: // INC IXY
- ixy = uint16_t (ixy + 1);
- goto set_ixy;
-
- case 0x2B: // DEC IXY
- ixy = uint16_t (ixy - 1);
- goto set_ixy;
-
- case 0x34: // INC (IXY+disp)
- ixy = IXY_DISP( ixy, (int8_t) data2 );
- pc++;
- data = READ( ixy ) + 1;
- WRITE( ixy, data );
- goto inc_set_flags;
-
- case 0x35: // DEC (IXY+disp)
- ixy = IXY_DISP( ixy, (int8_t) data2 );
- pc++;
- data = READ( ixy ) - 1;
- WRITE( ixy, data );
- goto dec_set_flags;
-
- case 0x24: // INC HXY
- ixy = uint16_t (ixy + 0x100);
- data = ixy >> 8;
- goto inc_xy_common;
-
- case 0x2C: // INC LXY
- data = uint8_t (ixy + 1);
- ixy = (ixy & 0xFF00) | data;
- inc_xy_common:
- if ( opcode == 0xDD )
- {
- ix = ixy;
- goto inc_set_flags;
- }
- iy = ixy;
- goto inc_set_flags;
-
- case 0x25: // DEC HXY
- ixy = uint16_t (ixy - 0x100);
- data = ixy >> 8;
- goto dec_xy_common;
-
- case 0x2D: // DEC LXY
- data = uint8_t (ixy - 1);
- ixy = (ixy & 0xFF00) | data;
- dec_xy_common:
- if ( opcode == 0xDD )
- {
- ix = ixy;
- goto dec_set_flags;
- }
- iy = ixy;
- goto dec_set_flags;
-
- // PUSH/POP
- case 0xE5: // PUSH IXY
- data = ixy;
- goto push_data;
-
- case 0xE1:{// POP IXY
- ixy = READ_WORD( sp );
- sp = uint16_t (sp + 2);
- goto set_ixy;
- }
-
- // Misc
-
- case 0xE9: // JP (IXY)
- pc = ixy;
- goto loop;
-
- case 0xE3:{// EX (SP),IXY
- fuint16 temp = READ_WORD( sp );
- WRITE_WORD( sp, ixy );
- ixy = temp;
- goto set_ixy;
- }
-
- default:
- debug_printf( "Unnecessary DD/FD prefix encountered\n" );
- warning = true;
- pc--;
- goto loop;
- }
- assert( false );
- }
-
- }
- debug_printf( "Unhandled main opcode: $%02X\n", opcode );
- assert( false );
-
-hit_idle_addr:
- s_time -= 11;
- goto out_of_time;
-halt:
- s_time &= 3; // increment by multiple of 4
-out_of_time:
- pc--;
-
- s.time = s_time;
- rg.flags = flags;
- r.ix = ix;
- r.iy = iy;
- r.sp = sp;
- r.pc = pc;
- this->r.b = rg;
- this->state_ = s;
- this->state = &this->state_;
-
- return warning;
-}
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Kss_Cpu.h b/plugins/gme/game-music-emu-0.5.5/gme/Kss_Cpu.h
deleted file mode 100644
index 28a2fc0f..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Kss_Cpu.h
+++ /dev/null
@@ -1,124 +0,0 @@
-// Z80 CPU emulator
-
-// Game_Music_Emu 0.5.5
-#ifndef KSS_CPU_H
-#define KSS_CPU_H
-
-#include "blargg_endian.h"
-
-typedef blargg_long cpu_time_t;
-
-// must be defined by caller
-void kss_cpu_out( class Kss_Cpu*, cpu_time_t, unsigned addr, int data );
-int kss_cpu_in( class Kss_Cpu*, cpu_time_t, unsigned addr );
-void kss_cpu_write( class Kss_Cpu*, unsigned addr, int data );
-
-class Kss_Cpu {
-public:
- typedef BOOST::uint8_t uint8_t;
-
- // Clear registers and map all pages to unmapped
- void reset( void* unmapped_write, void const* unmapped_read );
-
- // Map memory. Start and size must be multiple of page_size.
- enum { page_size = 0x2000 };
- void map_mem( unsigned addr, blargg_ulong size, void* write, void const* read );
-
- // Map address to page
- uint8_t* write( unsigned addr );
- uint8_t const* read( unsigned addr );
-
- // Run until specified time is reached. Returns true if suspicious/unsupported
- // instruction was encountered at any point during run.
- bool run( cpu_time_t end_time );
-
- // Time of beginning of next instruction
- cpu_time_t time() const { return state->time + state->base; }
-
- // Alter current time. Not supported during run() call.
- void set_time( cpu_time_t t ) { state->time = t - state->base; }
- void adjust_time( int delta ) { state->time += delta; }
-
- typedef BOOST::uint16_t uint16_t;
-
- #if BLARGG_BIG_ENDIAN
- struct regs_t { uint8_t b, c, d, e, h, l, flags, a; };
- #else
- struct regs_t { uint8_t c, b, e, d, l, h, a, flags; };
- #endif
- BOOST_STATIC_ASSERT( sizeof (regs_t) == 8 );
-
- struct pairs_t { uint16_t bc, de, hl, fa; };
-
- // Registers are not updated until run() returns
- struct registers_t {
- uint16_t pc;
- uint16_t sp;
- uint16_t ix;
- uint16_t iy;
- union {
- regs_t b; // b.b, b.c, b.d, b.e, b.h, b.l, b.flags, b.a
- pairs_t w; // w.bc, w.de, w.hl. w.fa
- };
- union {
- regs_t b;
- pairs_t w;
- } alt;
- uint8_t iff1;
- uint8_t iff2;
- uint8_t r;
- uint8_t i;
- uint8_t im;
- };
- //registers_t r; (below for efficiency)
-
- enum { idle_addr = 0xFFFF };
-
- // can read this far past end of a page
- enum { cpu_padding = 0x100 };
-
-public:
- Kss_Cpu();
- enum { page_shift = 13 };
- enum { page_count = 0x10000 >> page_shift };
-private:
- uint8_t szpc [0x200];
- cpu_time_t end_time_;
- struct state_t {
- uint8_t const* read [page_count + 1];
- uint8_t * write [page_count + 1];
- cpu_time_t base;
- cpu_time_t time;
- };
- state_t* state; // points to state_ or a local copy within run()
- state_t state_;
- void set_end_time( cpu_time_t t );
- void set_page( int i, void* write, void const* read );
-public:
- registers_t r;
-};
-
-#if BLARGG_NONPORTABLE
- #define KSS_CPU_PAGE_OFFSET( addr ) (addr)
-#else
- #define KSS_CPU_PAGE_OFFSET( addr ) ((addr) & (page_size - 1))
-#endif
-
-inline BOOST::uint8_t* Kss_Cpu::write( unsigned addr )
-{
- return state->write [addr >> page_shift] + KSS_CPU_PAGE_OFFSET( addr );
-}
-
-inline BOOST::uint8_t const* Kss_Cpu::read( unsigned addr )
-{
- return state->read [addr >> page_shift] + KSS_CPU_PAGE_OFFSET( addr );
-}
-
-inline void Kss_Cpu::set_end_time( cpu_time_t t )
-{
- cpu_time_t delta = state->base - t;
- state->base = t;
- state->time += delta;
-}
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Kss_Emu.cpp b/plugins/gme/game-music-emu-0.5.5/gme/Kss_Emu.cpp
deleted file mode 100644
index 3b84509c..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Kss_Emu.cpp
+++ /dev/null
@@ -1,416 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Kss_Emu.h"
-
-#include "blargg_endian.h"
-#include <string.h>
-
-/* Copyright (C) 2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-long const clock_rate = 3579545;
-int const osc_count = Ay_Apu::osc_count + Scc_Apu::osc_count;
-
-Kss_Emu::Kss_Emu()
-{
- sn = 0;
- set_type( gme_kss_type );
- set_silence_lookahead( 6 );
- static const char* const names [osc_count] = {
- "Square 1", "Square 2", "Square 3",
- "Wave 1", "Wave 2", "Wave 3", "Wave 4", "Wave 5"
- };
- set_voice_names( names );
-
- static int const types [osc_count] = {
- wave_type | 0, wave_type | 1, wave_type | 2,
- wave_type | 3, wave_type | 4, wave_type | 5, wave_type | 6, wave_type | 7
- };
- set_voice_types( types );
-
- memset( unmapped_read, 0xFF, sizeof unmapped_read );
-}
-
-Kss_Emu::~Kss_Emu() { unload(); }
-
-void Kss_Emu::unload()
-{
- delete sn;
- sn = 0;
- Classic_Emu::unload();
-}
-
-// Track info
-
-static void copy_kss_fields( Kss_Emu::header_t const& h, track_info_t* out )
-{
- const char* system = "MSX";
- if ( h.device_flags & 0x02 )
- {
- system = "Sega Master System";
- if ( h.device_flags & 0x04 )
- system = "Game Gear";
- }
- Gme_File::copy_field_( out->system, system );
-}
-
-blargg_err_t Kss_Emu::track_info_( track_info_t* out, int ) const
-{
- copy_kss_fields( header_, out );
- return 0;
-}
-
-static blargg_err_t check_kss_header( void const* header )
-{
- if ( memcmp( header, "KSCC", 4 ) && memcmp( header, "KSSX", 4 ) )
- return gme_wrong_file_type;
- return 0;
-}
-
-struct Kss_File : Gme_Info_
-{
- Kss_Emu::header_t header_;
-
- Kss_File() { set_type( gme_kss_type ); }
-
- blargg_err_t load_( Data_Reader& in )
- {
- blargg_err_t err = in.read( &header_, Kss_Emu::header_size );
- if ( err )
- return (err == in.eof_error ? gme_wrong_file_type : err);
- return check_kss_header( &header_ );
- }
-
- blargg_err_t track_info_( track_info_t* out, int ) const
- {
- copy_kss_fields( header_, out );
- return 0;
- }
-};
-
-static Music_Emu* new_kss_emu () { return BLARGG_NEW Kss_Emu ; }
-static Music_Emu* new_kss_file() { return BLARGG_NEW Kss_File; }
-
-static gme_type_t_ const gme_kss_type_ = { "MSX", 256, &new_kss_emu, &new_kss_file, "KSS", 0x03 };
-gme_type_t const gme_kss_type = &gme_kss_type_;
-
-
-// Setup
-
-void Kss_Emu::update_gain()
-{
- double g = gain() * 1.4;
- if ( scc_accessed )
- g *= 1.5;
- ay.volume( g );
- scc.volume( g );
- if ( sn )
- sn->volume( g );
-}
-
-blargg_err_t Kss_Emu::load_( Data_Reader& in )
-{
- memset( &header_, 0, sizeof header_ );
- assert( offsetof (header_t,device_flags) == header_size - 1 );
- assert( offsetof (ext_header_t,msx_audio_vol) == ext_header_size - 1 );
- RETURN_ERR( rom.load( in, header_size, STATIC_CAST(header_t*,&header_), 0 ) );
-
- RETURN_ERR( check_kss_header( header_.tag ) );
-
- if ( header_.tag [3] == 'C' )
- {
- if ( header_.extra_header )
- {
- header_.extra_header = 0;
- set_warning( "Unknown data in header" );
- }
- if ( header_.device_flags & ~0x0F )
- {
- header_.device_flags &= 0x0F;
- set_warning( "Unknown data in header" );
- }
- }
- else
- {
- ext_header_t& ext = header_;
- memcpy( &ext, rom.begin(), min( (int) ext_header_size, (int) header_.extra_header ) );
- if ( header_.extra_header > 0x10 )
- set_warning( "Unknown data in header" );
- }
-
- if ( header_.device_flags & 0x09 )
- set_warning( "FM sound not supported" );
-
- scc_enabled = 0xC000;
- if ( header_.device_flags & 0x04 )
- scc_enabled = 0;
-
- if ( header_.device_flags & 0x02 && !sn )
- CHECK_ALLOC( sn = BLARGG_NEW( Sms_Apu ) );
-
- set_voice_count( osc_count );
-
- return setup_buffer( ::clock_rate );
-}
-
-void Kss_Emu::update_eq( blip_eq_t const& eq )
-{
- ay.treble_eq( eq );
- scc.treble_eq( eq );
- if ( sn )
- sn->treble_eq( eq );
-}
-
-void Kss_Emu::set_voice( int i, Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right )
-{
- int i2 = i - ay.osc_count;
- if ( i2 >= 0 )
- scc.osc_output( i2, center );
- else
- ay.osc_output( i, center );
- if ( sn && i < sn->osc_count )
- sn->osc_output( i, center, left, right );
-}
-
-// Emulation
-
-void Kss_Emu::set_tempo_( double t )
-{
- blip_time_t period =
- (header_.device_flags & 0x40 ? ::clock_rate / 50 : ::clock_rate / 60);
- play_period = blip_time_t (period / t);
-}
-
-blargg_err_t Kss_Emu::start_track_( int track )
-{
- RETURN_ERR( Classic_Emu::start_track_( track ) );
-
- memset( ram, 0xC9, 0x4000 );
- memset( ram + 0x4000, 0, sizeof ram - 0x4000 );
-
- // copy driver code to lo RAM
- static byte const bios [] = {
- 0xD3, 0xA0, 0xF5, 0x7B, 0xD3, 0xA1, 0xF1, 0xC9, // $0001: WRTPSG
- 0xD3, 0xA0, 0xDB, 0xA2, 0xC9 // $0009: RDPSG
- };
- static byte const vectors [] = {
- 0xC3, 0x01, 0x00, // $0093: WRTPSG vector
- 0xC3, 0x09, 0x00, // $0096: RDPSG vector
- };
- memcpy( ram + 0x01, bios, sizeof bios );
- memcpy( ram + 0x93, vectors, sizeof vectors );
-
- // copy non-banked data into RAM
- unsigned load_addr = get_le16( header_.load_addr );
- long orig_load_size = get_le16( header_.load_size );
- long load_size = min( orig_load_size, rom.file_size() );
- load_size = min( load_size, long (mem_size - load_addr) );
- if ( load_size != orig_load_size )
- set_warning( "Excessive data size" );
- memcpy( ram + load_addr, rom.begin() + header_.extra_header, load_size );
-
- rom.set_addr( -load_size - header_.extra_header );
-
- // check available bank data
- blargg_long const bank_size = this->bank_size();
- int max_banks = (rom.file_size() - load_size + bank_size - 1) / bank_size;
- bank_count = header_.bank_mode & 0x7F;
- if ( bank_count > max_banks )
- {
- bank_count = max_banks;
- set_warning( "Bank data missing" );
- }
- //debug_printf( "load_size : $%X\n", load_size );
- //debug_printf( "bank_size : $%X\n", bank_size );
- //debug_printf( "bank_count: %d (%d claimed)\n", bank_count, header_.bank_mode & 0x7F );
-
- ram [idle_addr] = 0xFF;
- cpu::reset( unmapped_write, unmapped_read );
- cpu::map_mem( 0, mem_size, ram, ram );
-
- ay.reset();
- scc.reset();
- if ( sn )
- sn->reset();
- r.sp = 0xF380;
- ram [--r.sp] = idle_addr >> 8;
- ram [--r.sp] = idle_addr & 0xFF;
- r.b.a = track;
- r.pc = get_le16( header_.init_addr );
- next_play = play_period;
- scc_accessed = false;
- gain_updated = false;
- update_gain();
- ay_latch = 0;
-
- return 0;
-}
-
-void Kss_Emu::set_bank( int logical, int physical )
-{
- unsigned const bank_size = this->bank_size();
-
- unsigned addr = 0x8000;
- if ( logical && bank_size == 8 * 1024 )
- addr = 0xA000;
-
- physical -= header_.first_bank;
- if ( (unsigned) physical >= (unsigned) bank_count )
- {
- byte* data = ram + addr;
- cpu::map_mem( addr, bank_size, data, data );
- }
- else
- {
- long phys = physical * (blargg_long) bank_size;
- for ( unsigned offset = 0; offset < bank_size; offset += page_size )
- cpu::map_mem( addr + offset, page_size,
- unmapped_write, rom.at_addr( phys + offset ) );
- }
-}
-
-void Kss_Emu::cpu_write( unsigned addr, int data )
-{
- data &= 0xFF;
- switch ( addr )
- {
- case 0x9000:
- set_bank( 0, data );
- return;
-
- case 0xB000:
- set_bank( 1, data );
- return;
- }
-
- int scc_addr = (addr & 0xDFFF) ^ 0x9800;
- if ( scc_addr < scc.reg_count )
- {
- scc_accessed = true;
- scc.write( time(), scc_addr, data );
- return;
- }
-
- debug_printf( "LD ($%04X),$%02X\n", addr, data );
-}
-
-void kss_cpu_write( Kss_Cpu* cpu, unsigned addr, int data )
-{
- *cpu->write( addr ) = data;
- if ( (addr & STATIC_CAST(Kss_Emu&,*cpu).scc_enabled) == 0x8000 )
- STATIC_CAST(Kss_Emu&,*cpu).cpu_write( addr, data );
-}
-
-void kss_cpu_out( Kss_Cpu* cpu, cpu_time_t time, unsigned addr, int data )
-{
- data &= 0xFF;
- Kss_Emu& emu = STATIC_CAST(Kss_Emu&,*cpu);
- switch ( addr & 0xFF )
- {
- case 0xA0:
- emu.ay_latch = data & 0x0F;
- return;
-
- case 0xA1:
- GME_APU_HOOK( &emu, emu.ay_latch, data );
- emu.ay.write( time, emu.ay_latch, data );
- return;
-
- case 0x06:
- if ( emu.sn && (emu.header_.device_flags & 0x04) )
- {
- emu.sn->write_ggstereo( time, data );
- return;
- }
- break;
-
- case 0x7E:
- case 0x7F:
- if ( emu.sn )
- {
- GME_APU_HOOK( &emu, 16, data );
- emu.sn->write_data( time, data );
- return;
- }
- break;
-
- case 0xFE:
- emu.set_bank( 0, data );
- return;
-
- #ifndef NDEBUG
- case 0xF1: // FM data
- if ( data )
- break; // trap non-zero data
- case 0xF0: // FM addr
- case 0xA8: // PPI
- return;
- #endif
- }
-
- debug_printf( "OUT $%04X,$%02X\n", addr, data );
-}
-
-int kss_cpu_in( Kss_Cpu*, cpu_time_t, unsigned addr )
-{
- //Kss_Emu& emu = STATIC_CAST(Kss_Emu&,*cpu);
- //switch ( addr & 0xFF )
- //{
- //}
-
- debug_printf( "IN $%04X\n", addr );
- return 0;
-}
-
-// Emulation
-
-blargg_err_t Kss_Emu::run_clocks( blip_time_t& duration, int )
-{
- while ( time() < duration )
- {
- blip_time_t end = min( duration, next_play );
- cpu::run( min( duration, next_play ) );
- if ( r.pc == idle_addr )
- set_time( end );
-
- if ( time() >= next_play )
- {
- next_play += play_period;
- if ( r.pc == idle_addr )
- {
- if ( !gain_updated )
- {
- gain_updated = true;
- if ( scc_accessed )
- update_gain();
- }
-
- ram [--r.sp] = idle_addr >> 8;
- ram [--r.sp] = idle_addr & 0xFF;
- r.pc = get_le16( header_.play_addr );
- GME_FRAME_HOOK( this );
- }
- }
- }
-
- duration = time();
- next_play -= duration;
- check( next_play >= 0 );
- adjust_time( -duration );
- ay.end_frame( duration );
- scc.end_frame( duration );
- if ( sn )
- sn->end_frame( duration );
-
- return 0;
-}
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Kss_Emu.h b/plugins/gme/game-music-emu-0.5.5/gme/Kss_Emu.h
deleted file mode 100644
index 1d6ae475..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Kss_Emu.h
+++ /dev/null
@@ -1,96 +0,0 @@
-// MSX computer KSS music file emulator
-
-// Game_Music_Emu 0.5.5
-#ifndef KSS_EMU_H
-#define KSS_EMU_H
-
-#include "Classic_Emu.h"
-#include "Kss_Scc_Apu.h"
-#include "Kss_Cpu.h"
-#include "Sms_Apu.h"
-#include "Ay_Apu.h"
-
-class Kss_Emu : private Kss_Cpu, public Classic_Emu {
- typedef Kss_Cpu cpu;
-public:
- // KSS file header
- enum { header_size = 0x10 };
- struct header_t
- {
- byte tag [4];
- byte load_addr [2];
- byte load_size [2];
- byte init_addr [2];
- byte play_addr [2];
- byte first_bank;
- byte bank_mode;
- byte extra_header;
- byte device_flags;
- };
-
- enum { ext_header_size = 0x10 };
- struct ext_header_t
- {
- byte data_size [4];
- byte unused [4];
- byte first_track [2];
- byte last_tack [2];
- byte psg_vol;
- byte scc_vol;
- byte msx_music_vol;
- byte msx_audio_vol;
- };
-
- struct composite_header_t : header_t, ext_header_t { };
-
- // Header for currently loaded file
- composite_header_t const& header() const { return header_; }
-
- static gme_type_t static_type() { return gme_kss_type; }
-public:
- Kss_Emu();
- ~Kss_Emu();
-protected:
- blargg_err_t track_info_( track_info_t*, int track ) const;
- blargg_err_t load_( Data_Reader& );
- blargg_err_t start_track_( int );
- blargg_err_t run_clocks( blip_time_t&, int );
- void set_tempo_( double );
- void set_voice( int, Blip_Buffer*, Blip_Buffer*, Blip_Buffer* );
- void update_eq( blip_eq_t const& );
- void unload();
-private:
- Rom_Data<page_size> rom;
- composite_header_t header_;
-
- bool scc_accessed;
- bool gain_updated;
- void update_gain();
-
- unsigned scc_enabled; // 0 or 0xC000
- byte const* bank_data;
- int bank_count;
- void set_bank( int logical, int physical );
- blargg_long bank_size() const { return (16 * 1024L) >> (header_.bank_mode >> 7 & 1); }
-
- blip_time_t play_period;
- blip_time_t next_play;
- int ay_latch;
-
- friend void kss_cpu_out( class Kss_Cpu*, cpu_time_t, unsigned addr, int data );
- friend int kss_cpu_in( class Kss_Cpu*, cpu_time_t, unsigned addr );
- void cpu_write( unsigned addr, int data );
- friend void kss_cpu_write( class Kss_Cpu*, unsigned addr, int data );
-
- // large items
- enum { mem_size = 0x10000 };
- byte ram [mem_size + cpu_padding];
-
- Ay_Apu ay;
- Scc_Apu scc;
- Sms_Apu* sn;
- byte unmapped_read [0x100];
- byte unmapped_write [page_size];
-};
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Kss_Scc_Apu.cpp b/plugins/gme/game-music-emu-0.5.5/gme/Kss_Scc_Apu.cpp
deleted file mode 100644
index cfccce64..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Kss_Scc_Apu.cpp
+++ /dev/null
@@ -1,97 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Kss_Scc_Apu.h"
-
-/* Copyright (C) 2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-// Tones above this frequency are treated as disabled tone at half volume.
-// Power of two is more efficient (avoids division).
-unsigned const inaudible_freq = 16384;
-
-int const wave_size = 0x20;
-
-void Scc_Apu::run_until( blip_time_t end_time )
-{
- for ( int index = 0; index < osc_count; index++ )
- {
- osc_t& osc = oscs [index];
-
- Blip_Buffer* const output = osc.output;
- if ( !output )
- continue;
- output->set_modified();
-
- blip_time_t period = (regs [0x80 + index * 2 + 1] & 0x0F) * 0x100 +
- regs [0x80 + index * 2] + 1;
- int volume = 0;
- if ( regs [0x8F] & (1 << index) )
- {
- blip_time_t inaudible_period = (blargg_ulong) (output->clock_rate() +
- inaudible_freq * 32) / (inaudible_freq * 16);
- if ( period > inaudible_period )
- volume = (regs [0x8A + index] & 0x0F) * (amp_range / 256 / 15);
- }
-
- BOOST::int8_t const* wave = (BOOST::int8_t*) regs + index * wave_size;
- if ( index == osc_count - 1 )
- wave -= wave_size; // last two oscs share wave
- {
- int amp = wave [osc.phase] * volume;
- int delta = amp - osc.last_amp;
- if ( delta )
- {
- osc.last_amp = amp;
- synth.offset( last_time, delta, output );
- }
- }
-
- blip_time_t time = last_time + osc.delay;
- if ( time < end_time )
- {
- if ( !volume )
- {
- // maintain phase
- blargg_long count = (end_time - time + period - 1) / period;
- osc.phase = (osc.phase + count) & (wave_size - 1);
- time += count * period;
- }
- else
- {
-
- int phase = osc.phase;
- int last_wave = wave [phase];
- phase = (phase + 1) & (wave_size - 1); // pre-advance for optimal inner loop
-
- do
- {
- int amp = wave [phase];
- phase = (phase + 1) & (wave_size - 1);
- int delta = amp - last_wave;
- if ( delta )
- {
- last_wave = amp;
- synth.offset( time, delta * volume, output );
- }
- time += period;
- }
- while ( time < end_time );
-
- osc.phase = phase = (phase - 1) & (wave_size - 1); // undo pre-advance
- osc.last_amp = wave [phase] * volume;
- }
- }
- osc.delay = time - end_time;
- }
- last_time = end_time;
-}
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Kss_Scc_Apu.h b/plugins/gme/game-music-emu-0.5.5/gme/Kss_Scc_Apu.h
deleted file mode 100644
index 5c65461c..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Kss_Scc_Apu.h
+++ /dev/null
@@ -1,106 +0,0 @@
-// Konami SCC sound chip emulator
-
-// Game_Music_Emu 0.5.5
-#ifndef KSS_SCC_APU_H
-#define KSS_SCC_APU_H
-
-#include "blargg_common.h"
-#include "Blip_Buffer.h"
-#include <string.h>
-
-class Scc_Apu {
-public:
- // Set buffer to generate all sound into, or disable sound if NULL
- void output( Blip_Buffer* );
-
- // Reset sound chip
- void reset();
-
- // Write to register at specified time
- enum { reg_count = 0x90 };
- void write( blip_time_t time, int reg, int data );
-
- // Run sound to specified time, end current time frame, then start a new
- // time frame at time 0. Time frames have no effect on emulation and each
- // can be whatever length is convenient.
- void end_frame( blip_time_t length );
-
-// Additional features
-
- // Set sound output of specific oscillator to buffer, where index is
- // 0 to 4. If buffer is NULL, the specified oscillator is muted.
- enum { osc_count = 5 };
- void osc_output( int index, Blip_Buffer* );
-
- // Set overall volume (default is 1.0)
- void volume( double );
-
- // Set treble equalization (see documentation)
- void treble_eq( blip_eq_t const& );
-
-public:
- Scc_Apu();
-private:
- enum { amp_range = 0x8000 };
- struct osc_t
- {
- int delay;
- int phase;
- int last_amp;
- Blip_Buffer* output;
- };
- osc_t oscs [osc_count];
- blip_time_t last_time;
- unsigned char regs [reg_count];
- Blip_Synth<blip_med_quality,1> synth;
-
- void run_until( blip_time_t );
-};
-
-inline void Scc_Apu::volume( double v ) { synth.volume( 0.43 / osc_count / amp_range * v ); }
-
-inline void Scc_Apu::treble_eq( blip_eq_t const& eq ) { synth.treble_eq( eq ); }
-
-inline void Scc_Apu::osc_output( int index, Blip_Buffer* b )
-{
- assert( (unsigned) index < osc_count );
- oscs [index].output = b;
-}
-
-inline void Scc_Apu::write( blip_time_t time, int addr, int data )
-{
- assert( (unsigned) addr < reg_count );
- run_until( time );
- regs [addr] = data;
-}
-
-inline void Scc_Apu::end_frame( blip_time_t end_time )
-{
- if ( end_time > last_time )
- run_until( end_time );
- last_time -= end_time;
- assert( last_time >= 0 );
-}
-
-inline void Scc_Apu::output( Blip_Buffer* buf )
-{
- for ( int i = 0; i < osc_count; i++ )
- oscs [i].output = buf;
-}
-
-inline Scc_Apu::Scc_Apu()
-{
- output( 0 );
-}
-
-inline void Scc_Apu::reset()
-{
- last_time = 0;
-
- for ( int i = 0; i < osc_count; i++ )
- memset( &oscs [i], 0, offsetof (osc_t,output) );
-
- memset( regs, 0, sizeof regs );
-}
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/M3u_Playlist.cpp b/plugins/gme/game-music-emu-0.5.5/gme/M3u_Playlist.cpp
deleted file mode 100644
index 75d0fcb2..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/M3u_Playlist.cpp
+++ /dev/null
@@ -1,426 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "M3u_Playlist.h"
-#include "Music_Emu.h"
-
-#include <string.h>
-
-/* Copyright (C) 2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-// gme functions defined here to avoid linking in m3u code unless it's used
-
-blargg_err_t Gme_File::load_m3u_( blargg_err_t err )
-{
- require( raw_track_count_ ); // file must be loaded first
-
- if ( !err )
- {
- if ( playlist.size() )
- track_count_ = playlist.size();
-
- int line = playlist.first_error();
- if ( line )
- {
- // avoid using bloated printf()
- char* out = &playlist_warning [sizeof playlist_warning];
- *--out = 0;
- do {
- *--out = line % 10 + '0';
- } while ( (line /= 10) > 0 );
-
- static const char str [] = "Problem in m3u at line ";
- out -= sizeof str - 1;
- memcpy( out, str, sizeof str - 1 );
- set_warning( out );
- }
- }
- return err;
-}
-
-blargg_err_t Gme_File::load_m3u( const char* path ) { return load_m3u_( playlist.load( path ) ); }
-
-blargg_err_t Gme_File::load_m3u( Data_Reader& in ) { return load_m3u_( playlist.load( in ) ); }
-
-gme_err_t gme_load_m3u( Music_Emu* me, const char* path ) { return me->load_m3u( path ); }
-
-gme_err_t gme_load_m3u_data( Music_Emu* me, const void* data, long size )
-{
- Mem_File_Reader in( data, size );
- return me->load_m3u( in );
-}
-
-
-
-static char* skip_white( char* in )
-{
- while ( *in == ' ' )
- in++;
- return in;
-}
-
-inline unsigned from_dec( unsigned n ) { return n - '0'; }
-
-static char* parse_filename( char* in, M3u_Playlist::entry_t& entry )
-{
- entry.file = in;
- entry.type = "";
- char* out = in;
- while ( 1 )
- {
- int c = *in;
- if ( !c ) break;
- in++;
-
- if ( c == ',' ) // commas in filename
- {
- char* p = skip_white( in );
- if ( *p == '$' || from_dec( *p ) <= 9 )
- {
- in = p;
- break;
- }
- }
-
- if ( c == ':' && in [0] == ':' && in [1] && in [2] != ',' ) // ::type suffix
- {
- entry.type = ++in;
- while ( (c = *in) != 0 && c != ',' )
- in++;
- if ( c == ',' )
- {
- *in++ = 0; // terminate type
- in = skip_white( in );
- }
- break;
- }
-
- if ( c == '\\' ) // \ prefix for special characters
- {
- c = *in;
- if ( !c ) break;
- in++;
- }
- *out++ = (char) c;
- }
- *out = 0; // terminate string
- return in;
-}
-
-static char* next_field( char* in, int* result )
-{
- while ( 1 )
- {
- in = skip_white( in );
-
- if ( !*in )
- break;
-
- if ( *in == ',' )
- {
- in++;
- break;
- }
-
- *result = 1;
- in++;
- }
- return skip_white( in );
-}
-
-static char* parse_int_( char* in, int* out )
-{
- int n = 0;
- while ( 1 )
- {
- unsigned d = from_dec( *in );
- if ( d > 9 )
- break;
- in++;
- n = n * 10 + d;
- *out = n;
- }
- return in;
-}
-
-static char* parse_int( char* in, int* out, int* result )
-{
- return next_field( parse_int_( in, out ), result );
-}
-
-// Returns 16 or greater if not hex
-inline int from_hex_char( int h )
-{
- h -= 0x30;
- if ( (unsigned) h > 9 )
- h = ((h - 0x11) & 0xDF) + 10;
- return h;
-}
-
-static char* parse_track( char* in, M3u_Playlist::entry_t& entry, int* result )
-{
- if ( *in == '$' )
- {
- in++;
- int n = 0;
- while ( 1 )
- {
- int h = from_hex_char( *in );
- if ( h > 15 )
- break;
- in++;
- n = n * 16 + h;
- entry.track = n;
- }
- }
- else
- {
- in = parse_int_( in, &entry.track );
- if ( entry.track >= 0 )
- entry.decimal_track = 1;
- }
- return next_field( in, result );
-}
-
-static char* parse_time_( char* in, int* out )
-{
- *out = -1;
- int n = -1;
- in = parse_int_( in, &n );
- if ( n >= 0 )
- {
- *out = n;
- if ( *in == ':' )
- {
- n = -1;
- in = parse_int_( in + 1, &n );
- if ( n >= 0 )
- *out = *out * 60 + n;
- }
- }
- return in;
-}
-
-static char* parse_time( char* in, int* out, int* result )
-{
- return next_field( parse_time_( in, out ), result );
-}
-
-static char* parse_name( char* in )
-{
- char* out = in;
- while ( 1 )
- {
- int c = *in;
- if ( !c ) break;
- in++;
-
- if ( c == ',' ) // commas in string
- {
- char* p = skip_white( in );
- if ( *p == ',' || *p == '-' || from_dec( *p ) <= 9 )
- {
- in = p;
- break;
- }
- }
-
- if ( c == '\\' ) // \ prefix for special characters
- {
- c = *in;
- if ( !c ) break;
- in++;
- }
- *out++ = (char) c;
- }
- *out = 0; // terminate string
- return in;
-}
-
-static int parse_line( char* in, M3u_Playlist::entry_t& entry )
-{
- int result = 0;
-
- // file
- entry.file = in;
- entry.type = "";
- in = parse_filename( in, entry );
-
- // track
- entry.track = -1;
- entry.decimal_track = 0;
- in = parse_track( in, entry, &result );
-
- // name
- entry.name = in;
- in = parse_name( in );
-
- // time
- entry.length = -1;
- in = parse_time( in, &entry.length, &result );
-
- // loop
- entry.intro = -1;
- entry.loop = -1;
- if ( *in == '-' )
- {
- entry.loop = entry.length;
- in++;
- }
- else
- {
- in = parse_time_( in, &entry.loop );
- if ( entry.loop >= 0 )
- {
- entry.intro = 0;
- if ( *in == '-' ) // trailing '-' means that intro length was specified
- {
- in++;
- entry.intro = entry.loop;
- entry.loop = entry.length - entry.intro;
- }
- }
- }
- in = next_field( in, &result );
-
- // fade
- entry.fade = -1;
- in = parse_time( in, &entry.fade, &result );
-
- // repeat
- entry.repeat = -1;
- in = parse_int( in, &entry.repeat, &result );
-
- return result;
-}
-
-static void parse_comment( char* in, M3u_Playlist::info_t& info, bool first )
-{
- in = skip_white( in + 1 );
- const char* field = in;
- while ( *in && *in != ':' )
- in++;
-
- if ( *in == ':' )
- {
- const char* text = skip_white( in + 1 );
- if ( *text )
- {
- *in = 0;
- if ( !strcmp( "Composer", field ) ) info.composer = text;
- else if ( !strcmp( "Engineer", field ) ) info.engineer = text;
- else if ( !strcmp( "Ripping" , field ) ) info.ripping = text;
- else if ( !strcmp( "Tagging" , field ) ) info.tagging = text;
- else
- text = 0;
- if ( text )
- return;
- *in = ':';
- }
- }
-
- if ( first )
- info.title = field;
-}
-
-blargg_err_t M3u_Playlist::parse_()
-{
- info_.title = "";
- info_.composer = "";
- info_.engineer = "";
- info_.ripping = "";
- info_.tagging = "";
-
- int const CR = 13;
- int const LF = 10;
-
- data.end() [-1] = LF; // terminate input
-
- first_error_ = 0;
- bool first_comment = true;
- int line = 0;
- int count = 0;
- char* in = data.begin();
- while ( in < data.end() )
- {
- // find end of line and terminate it
- line++;
- char* begin = in;
- while ( *in != CR && *in != LF )
- {
- if ( !*in )
- return "Not an m3u playlist";
- in++;
- }
- if ( in [0] == CR && in [1] == LF ) // treat CR,LF as a single line
- *in++ = 0;
- *in++ = 0;
-
- // parse line
- if ( *begin == '#' )
- {
- parse_comment( begin, info_, first_comment );
- first_comment = false;
- }
- else if ( *begin )
- {
- if ( (int) entries.size() <= count )
- RETURN_ERR( entries.resize( count * 2 + 64 ) );
-
- if ( !parse_line( begin, entries [count] ) )
- count++;
- else if ( !first_error_ )
- first_error_ = line;
- first_comment = false;
- }
- }
- if ( count <= 0 )
- return "Not an m3u playlist";
-
- if ( !(info_.composer [0] | info_.engineer [0] | info_.ripping [0] | info_.tagging [0]) )
- info_.title = "";
-
- return entries.resize( count );
-}
-
-blargg_err_t M3u_Playlist::parse()
-{
- blargg_err_t err = parse_();
- if ( err )
- {
- entries.clear();
- data.clear();
- }
- return err;
-}
-
-blargg_err_t M3u_Playlist::load( Data_Reader& in )
-{
- RETURN_ERR( data.resize( in.remain() + 1 ) );
- RETURN_ERR( in.read( data.begin(), data.size() - 1 ) );
- return parse();
-}
-
-blargg_err_t M3u_Playlist::load( const char* path )
-{
- GME_FILE_READER in;
- RETURN_ERR( in.open( path ) );
- return load( in );
-}
-
-blargg_err_t M3u_Playlist::load( void const* in, long size )
-{
- RETURN_ERR( data.resize( size + 1 ) );
- memcpy( data.begin(), in, size );
- return parse();
-}
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/M3u_Playlist.h b/plugins/gme/game-music-emu-0.5.5/gme/M3u_Playlist.h
deleted file mode 100644
index 266a0653..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/M3u_Playlist.h
+++ /dev/null
@@ -1,67 +0,0 @@
-// M3U playlist file parser, with support for subtrack information
-
-// Game_Music_Emu 0.5.5
-#ifndef M3U_PLAYLIST_H
-#define M3U_PLAYLIST_H
-
-#include "blargg_common.h"
-#include "Data_Reader.h"
-
-class M3u_Playlist {
-public:
- // Load playlist data
- blargg_err_t load( const char* path );
- blargg_err_t load( Data_Reader& in );
- blargg_err_t load( void const* data, long size );
-
- // Line number of first parse error, 0 if no error. Any lines with parse
- // errors are ignored.
- int first_error() const { return first_error_; }
-
- struct info_t
- {
- const char* title;
- const char* composer;
- const char* engineer;
- const char* ripping;
- const char* tagging;
- };
- info_t const& info() const { return info_; }
-
- struct entry_t
- {
- const char* file; // filename without stupid ::TYPE suffix
- const char* type; // if filename has ::TYPE suffix, this will be "TYPE". "" if none.
- const char* name;
- bool decimal_track; // true if track was specified in hex
- // integers are -1 if not present
- int track; // 1-based
- int length; // seconds
- int intro;
- int loop;
- int fade;
- int repeat; // count
- };
- entry_t const& operator [] ( int i ) const { return entries [i]; }
- int size() const { return entries.size(); }
-
- void clear();
-
-private:
- blargg_vector<entry_t> entries;
- blargg_vector<char> data;
- int first_error_;
- info_t info_;
-
- blargg_err_t parse();
- blargg_err_t parse_();
-};
-
-inline void M3u_Playlist::clear()
-{
- first_error_ = 0;
- entries.clear();
- data.clear();
-}
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Multi_Buffer.cpp b/plugins/gme/game-music-emu-0.5.5/gme/Multi_Buffer.cpp
deleted file mode 100644
index 57f93b31..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Multi_Buffer.cpp
+++ /dev/null
@@ -1,232 +0,0 @@
-// Blip_Buffer 0.4.1. http://www.slack.net/~ant/
-
-#include "Multi_Buffer.h"
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-#ifdef BLARGG_ENABLE_OPTIMIZER
- #include BLARGG_ENABLE_OPTIMIZER
-#endif
-
-Multi_Buffer::Multi_Buffer( int spf ) : samples_per_frame_( spf )
-{
- length_ = 0;
- sample_rate_ = 0;
- channels_changed_count_ = 1;
-}
-
-blargg_err_t Multi_Buffer::set_channel_count( int ) { return 0; }
-
-// Silent_Buffer
-
-Silent_Buffer::Silent_Buffer() : Multi_Buffer( 1 ) // 0 channels would probably confuse
-{
- // TODO: better to use empty Blip_Buffer so caller never has to check for NULL?
- chan.left = 0;
- chan.center = 0;
- chan.right = 0;
-}
-
-// Mono_Buffer
-
-Mono_Buffer::Mono_Buffer() : Multi_Buffer( 1 )
-{
- chan.center = &buf;
- chan.left = &buf;
- chan.right = &buf;
-}
-
-Mono_Buffer::~Mono_Buffer() { }
-
-blargg_err_t Mono_Buffer::set_sample_rate( long rate, int msec )
-{
- RETURN_ERR( buf.set_sample_rate( rate, msec ) );
- return Multi_Buffer::set_sample_rate( buf.sample_rate(), buf.length() );
-}
-
-// Stereo_Buffer
-
-Stereo_Buffer::Stereo_Buffer() : Multi_Buffer( 2 )
-{
- chan.center = &bufs [0];
- chan.left = &bufs [1];
- chan.right = &bufs [2];
-}
-
-Stereo_Buffer::~Stereo_Buffer() { }
-
-blargg_err_t Stereo_Buffer::set_sample_rate( long rate, int msec )
-{
- for ( int i = 0; i < buf_count; i++ )
- RETURN_ERR( bufs [i].set_sample_rate( rate, msec ) );
- return Multi_Buffer::set_sample_rate( bufs [0].sample_rate(), bufs [0].length() );
-}
-
-void Stereo_Buffer::clock_rate( long rate )
-{
- for ( int i = 0; i < buf_count; i++ )
- bufs [i].clock_rate( rate );
-}
-
-void Stereo_Buffer::bass_freq( int bass )
-{
- for ( unsigned i = 0; i < buf_count; i++ )
- bufs [i].bass_freq( bass );
-}
-
-void Stereo_Buffer::clear()
-{
- stereo_added = 0;
- was_stereo = false;
- for ( int i = 0; i < buf_count; i++ )
- bufs [i].clear();
-}
-
-void Stereo_Buffer::end_frame( blip_time_t clock_count )
-{
- stereo_added = 0;
- for ( unsigned i = 0; i < buf_count; i++ )
- {
- stereo_added |= bufs [i].clear_modified() << i;
- bufs [i].end_frame( clock_count );
- }
-}
-
-long Stereo_Buffer::read_samples( blip_sample_t* out, long count )
-{
- require( !(count & 1) ); // count must be even
- count = (unsigned) count / 2;
-
- long avail = bufs [0].samples_avail();
- if ( count > avail )
- count = avail;
- if ( count )
- {
- int bufs_used = stereo_added | was_stereo;
- //debug_printf( "%X\n", bufs_used );
- if ( bufs_used <= 1 )
- {
- mix_mono( out, count );
- bufs [0].remove_samples( count );
- bufs [1].remove_silence( count );
- bufs [2].remove_silence( count );
- }
- else if ( bufs_used & 1 )
- {
- mix_stereo( out, count );
- bufs [0].remove_samples( count );
- bufs [1].remove_samples( count );
- bufs [2].remove_samples( count );
- }
- else
- {
- mix_stereo_no_center( out, count );
- bufs [0].remove_silence( count );
- bufs [1].remove_samples( count );
- bufs [2].remove_samples( count );
- }
-
- // to do: this might miss opportunities for optimization
- if ( !bufs [0].samples_avail() )
- {
- was_stereo = stereo_added;
- stereo_added = 0;
- }
- }
-
- return count * 2;
-}
-
-void Stereo_Buffer::mix_stereo( blip_sample_t* out_, blargg_long count )
-{
- blip_sample_t* BLIP_RESTRICT out = out_;
- int const bass = BLIP_READER_BASS( bufs [1] );
- BLIP_READER_BEGIN( left, bufs [1] );
- BLIP_READER_BEGIN( right, bufs [2] );
- BLIP_READER_BEGIN( center, bufs [0] );
-
- for ( ; count; --count )
- {
- int c = BLIP_READER_READ( center );
- blargg_long l = c + BLIP_READER_READ( left );
- blargg_long r = c + BLIP_READER_READ( right );
- if ( (BOOST::int16_t) l != l )
- l = 0x7FFF - (l >> 24);
-
- BLIP_READER_NEXT( center, bass );
- if ( (BOOST::int16_t) r != r )
- r = 0x7FFF - (r >> 24);
-
- BLIP_READER_NEXT( left, bass );
- BLIP_READER_NEXT( right, bass );
-
- out [0] = l;
- out [1] = r;
- out += 2;
- }
-
- BLIP_READER_END( center, bufs [0] );
- BLIP_READER_END( right, bufs [2] );
- BLIP_READER_END( left, bufs [1] );
-}
-
-void Stereo_Buffer::mix_stereo_no_center( blip_sample_t* out_, blargg_long count )
-{
- blip_sample_t* BLIP_RESTRICT out = out_;
- int const bass = BLIP_READER_BASS( bufs [1] );
- BLIP_READER_BEGIN( left, bufs [1] );
- BLIP_READER_BEGIN( right, bufs [2] );
-
- for ( ; count; --count )
- {
- blargg_long l = BLIP_READER_READ( left );
- if ( (BOOST::int16_t) l != l )
- l = 0x7FFF - (l >> 24);
-
- blargg_long r = BLIP_READER_READ( right );
- if ( (BOOST::int16_t) r != r )
- r = 0x7FFF - (r >> 24);
-
- BLIP_READER_NEXT( left, bass );
- BLIP_READER_NEXT( right, bass );
-
- out [0] = l;
- out [1] = r;
- out += 2;
- }
-
- BLIP_READER_END( right, bufs [2] );
- BLIP_READER_END( left, bufs [1] );
-}
-
-void Stereo_Buffer::mix_mono( blip_sample_t* out_, blargg_long count )
-{
- blip_sample_t* BLIP_RESTRICT out = out_;
- int const bass = BLIP_READER_BASS( bufs [0] );
- BLIP_READER_BEGIN( center, bufs [0] );
-
- for ( ; count; --count )
- {
- blargg_long s = BLIP_READER_READ( center );
- if ( (BOOST::int16_t) s != s )
- s = 0x7FFF - (s >> 24);
-
- BLIP_READER_NEXT( center, bass );
- out [0] = s;
- out [1] = s;
- out += 2;
- }
-
- BLIP_READER_END( center, bufs [0] );
-}
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Multi_Buffer.h b/plugins/gme/game-music-emu-0.5.5/gme/Multi_Buffer.h
deleted file mode 100644
index 82c8b3ab..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Multi_Buffer.h
+++ /dev/null
@@ -1,158 +0,0 @@
-// Multi-channel sound buffer interface, and basic mono and stereo buffers
-
-// Blip_Buffer 0.4.1
-#ifndef MULTI_BUFFER_H
-#define MULTI_BUFFER_H
-
-#include "blargg_common.h"
-#include "Blip_Buffer.h"
-
-// Interface to one or more Blip_Buffers mapped to one or more channels
-// consisting of left, center, and right buffers.
-class Multi_Buffer {
-public:
- Multi_Buffer( int samples_per_frame );
- virtual ~Multi_Buffer() { }
-
- // Set the number of channels available
- virtual blargg_err_t set_channel_count( int );
-
- // Get indexed channel, from 0 to channel count - 1
- struct channel_t {
- Blip_Buffer* center;
- Blip_Buffer* left;
- Blip_Buffer* right;
- };
- enum { type_index_mask = 0xFF };
- enum { wave_type = 0x100, noise_type = 0x200, mixed_type = wave_type | noise_type };
- virtual channel_t channel( int index, int type ) = 0;
-
- // See Blip_Buffer.h
- virtual blargg_err_t set_sample_rate( long rate, int msec = blip_default_length ) = 0;
- virtual void clock_rate( long ) = 0;
- virtual void bass_freq( int ) = 0;
- virtual void clear() = 0;
- long sample_rate() const;
-
- // Length of buffer, in milliseconds
- int length() const;
-
- // See Blip_Buffer.h
- virtual void end_frame( blip_time_t ) = 0;
-
- // Number of samples per output frame (1 = mono, 2 = stereo)
- int samples_per_frame() const;
-
- // Count of changes to channel configuration. Incremented whenever
- // a change is made to any of the Blip_Buffers for any channel.
- unsigned channels_changed_count() { return channels_changed_count_; }
-
- // See Blip_Buffer.h
- virtual long read_samples( blip_sample_t*, long ) = 0;
- virtual long samples_avail() const = 0;
-
-public:
- BLARGG_DISABLE_NOTHROW
-protected:
- void channels_changed() { channels_changed_count_++; }
-private:
- // noncopyable
- Multi_Buffer( const Multi_Buffer& );
- Multi_Buffer& operator = ( const Multi_Buffer& );
-
- unsigned channels_changed_count_;
- long sample_rate_;
- int length_;
- int const samples_per_frame_;
-};
-
-// Uses a single buffer and outputs mono samples.
-class Mono_Buffer : public Multi_Buffer {
- Blip_Buffer buf;
- channel_t chan;
-public:
- // Buffer used for all channels
- Blip_Buffer* center() { return &buf; }
-
-public:
- Mono_Buffer();
- ~Mono_Buffer();
- blargg_err_t set_sample_rate( long rate, int msec = blip_default_length );
- void clock_rate( long rate ) { buf.clock_rate( rate ); }
- void bass_freq( int freq ) { buf.bass_freq( freq ); }
- void clear() { buf.clear(); }
- long samples_avail() const { return buf.samples_avail(); }
- long read_samples( blip_sample_t* p, long s ) { return buf.read_samples( p, s ); }
- channel_t channel( int, int ) { return chan; }
- void end_frame( blip_time_t t ) { buf.end_frame( t ); }
-};
-
-// Uses three buffers (one for center) and outputs stereo sample pairs.
-class Stereo_Buffer : public Multi_Buffer {
-public:
-
- // Buffers used for all channels
- Blip_Buffer* center() { return &bufs [0]; }
- Blip_Buffer* left() { return &bufs [1]; }
- Blip_Buffer* right() { return &bufs [2]; }
-
-public:
- Stereo_Buffer();
- ~Stereo_Buffer();
- blargg_err_t set_sample_rate( long, int msec = blip_default_length );
- void clock_rate( long );
- void bass_freq( int );
- void clear();
- channel_t channel( int, int ) { return chan; }
- void end_frame( blip_time_t );
-
- long samples_avail() const { return bufs [0].samples_avail() * 2; }
- long read_samples( blip_sample_t*, long );
-
-private:
- enum { buf_count = 3 };
- Blip_Buffer bufs [buf_count];
- channel_t chan;
- int stereo_added;
- int was_stereo;
-
- void mix_stereo_no_center( blip_sample_t*, blargg_long );
- void mix_stereo( blip_sample_t*, blargg_long );
- void mix_mono( blip_sample_t*, blargg_long );
-};
-
-// Silent_Buffer generates no samples, useful where no sound is wanted
-class Silent_Buffer : public Multi_Buffer {
- channel_t chan;
-public:
- Silent_Buffer();
- blargg_err_t set_sample_rate( long rate, int msec = blip_default_length );
- void clock_rate( long ) { }
- void bass_freq( int ) { }
- void clear() { }
- channel_t channel( int, int ) { return chan; }
- void end_frame( blip_time_t ) { }
- long samples_avail() const { return 0; }
- long read_samples( blip_sample_t*, long ) { return 0; }
-};
-
-
-inline blargg_err_t Multi_Buffer::set_sample_rate( long rate, int msec )
-{
- sample_rate_ = rate;
- length_ = msec;
- return 0;
-}
-
-inline blargg_err_t Silent_Buffer::set_sample_rate( long rate, int msec )
-{
- return Multi_Buffer::set_sample_rate( rate, msec );
-}
-
-inline int Multi_Buffer::samples_per_frame() const { return samples_per_frame_; }
-
-inline long Multi_Buffer::sample_rate() const { return sample_rate_; }
-
-inline int Multi_Buffer::length() const { return length_; }
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Music_Emu.cpp b/plugins/gme/game-music-emu-0.5.5/gme/Music_Emu.cpp
deleted file mode 100644
index 5db66fb9..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Music_Emu.cpp
+++ /dev/null
@@ -1,410 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Music_Emu.h"
-
-#include "Multi_Buffer.h"
-#include <string.h>
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-int const stereo = 2; // number of channels for stereo
-int const silence_max = 6; // seconds
-int const silence_threshold = 0x10;
-long const fade_block_size = 512;
-int const fade_shift = 8; // fade ends with gain at 1.0 / (1 << fade_shift)
-
-Music_Emu::equalizer_t const Music_Emu::tv_eq = { -8.0, 180 };
-
-void Music_Emu::clear_track_vars()
-{
- current_track_ = -1;
- out_time = 0;
- emu_time = 0;
- emu_track_ended_ = true;
- track_ended_ = true;
- fade_start = INT_MAX / 2 + 1;
- fade_step = 1;
- silence_time = 0;
- silence_count = 0;
- buf_remain = 0;
- warning(); // clear warning
-}
-
-void Music_Emu::unload()
-{
- voice_count_ = 0;
- clear_track_vars();
- Gme_File::unload();
-}
-
-Music_Emu::Music_Emu()
-{
- effects_buffer = 0;
-
- sample_rate_ = 0;
- mute_mask_ = 0;
- tempo_ = 1.0;
- gain_ = 1.0;
-
- // defaults
- max_initial_silence = 2;
- silence_lookahead = 3;
- ignore_silence_ = false;
- equalizer_.treble = -1.0;
- equalizer_.bass = 60;
-
- static const char* const names [] = {
- "Voice 1", "Voice 2", "Voice 3", "Voice 4",
- "Voice 5", "Voice 6", "Voice 7", "Voice 8"
- };
- set_voice_names( names );
- Music_Emu::unload(); // non-virtual
-}
-
-Music_Emu::~Music_Emu() { delete effects_buffer; }
-
-blargg_err_t Music_Emu::set_sample_rate( long rate )
-{
- require( !sample_rate() ); // sample rate can't be changed once set
- RETURN_ERR( set_sample_rate_( rate ) );
- RETURN_ERR( buf.resize( buf_size ) );
- sample_rate_ = rate;
- return 0;
-}
-
-void Music_Emu::pre_load()
-{
- require( sample_rate() ); // set_sample_rate() must be called before loading a file
- Gme_File::pre_load();
-}
-
-void Music_Emu::set_equalizer( equalizer_t const& eq )
-{
- equalizer_ = eq;
- set_equalizer_( eq );
-}
-
-void Music_Emu::mute_voice( int index, bool mute )
-{
- require( (unsigned) index < (unsigned) voice_count() );
- int bit = 1 << index;
- int mask = mute_mask_ | bit;
- if ( !mute )
- mask ^= bit;
- mute_voices( mask );
-}
-
-void Music_Emu::mute_voices( int mask )
-{
- require( sample_rate() ); // sample rate must be set first
- mute_mask_ = mask;
- mute_voices_( mask );
-}
-
-void Music_Emu::set_tempo( double t )
-{
- require( sample_rate() ); // sample rate must be set first
- double const min = 0.02;
- double const max = 4.00;
- if ( t < min ) t = min;
- if ( t > max ) t = max;
- tempo_ = t;
- set_tempo_( t );
-}
-
-void Music_Emu::post_load_()
-{
- set_tempo( tempo_ );
- remute_voices();
-}
-
-blargg_err_t Music_Emu::start_track( int track )
-{
- clear_track_vars();
-
- int remapped = track;
- RETURN_ERR( remap_track_( &remapped ) );
- current_track_ = track;
- RETURN_ERR( start_track_( remapped ) );
-
- emu_track_ended_ = false;
- track_ended_ = false;
-
- if ( !ignore_silence_ )
- {
- // play until non-silence or end of track
- for ( long end = max_initial_silence * stereo * sample_rate(); emu_time < end; )
- {
- fill_buf();
- if ( buf_remain | (int) emu_track_ended_ )
- break;
- }
-
- emu_time = buf_remain;
- out_time = 0;
- silence_time = 0;
- silence_count = 0;
- }
- return track_ended() ? warning() : 0;
-}
-
-void Music_Emu::end_track_if_error( blargg_err_t err )
-{
- if ( err )
- {
- emu_track_ended_ = true;
- set_warning( err );
- }
-}
-
-// Tell/Seek
-
-blargg_long Music_Emu::msec_to_samples( blargg_long msec ) const
-{
- blargg_long sec = msec / 1000;
- msec -= sec * 1000;
- return (sec * sample_rate() + msec * sample_rate() / 1000) * stereo;
-}
-
-long Music_Emu::tell() const
-{
- blargg_long rate = sample_rate() * stereo;
- blargg_long sec = out_time / rate;
- return sec * 1000 + (out_time - sec * rate) * 1000 / rate;
-}
-
-blargg_err_t Music_Emu::seek( long msec )
-{
- blargg_long time = msec_to_samples( msec );
- if ( time < out_time )
- RETURN_ERR( start_track( current_track_ ) );
- return skip( time - out_time );
-}
-
-blargg_err_t Music_Emu::skip( long count )
-{
- require( current_track() >= 0 ); // start_track() must have been called already
- out_time += count;
-
- // remove from silence and buf first
- {
- long n = min( count, silence_count );
- silence_count -= n;
- count -= n;
-
- n = min( count, buf_remain );
- buf_remain -= n;
- count -= n;
- }
-
- if ( count && !emu_track_ended_ )
- {
- emu_time += count;
- end_track_if_error( skip_( count ) );
- }
-
- if ( !(silence_count | buf_remain) ) // caught up to emulator, so update track ended
- track_ended_ |= emu_track_ended_;
-
- return 0;
-}
-
-blargg_err_t Music_Emu::skip_( long count )
-{
- // for long skip, mute sound
- const long threshold = 30000;
- if ( count > threshold )
- {
- int saved_mute = mute_mask_;
- mute_voices( ~0 );
-
- while ( count > threshold / 2 && !emu_track_ended_ )
- {
- RETURN_ERR( play_( buf_size, buf.begin() ) );
- count -= buf_size;
- }
-
- mute_voices( saved_mute );
- }
-
- while ( count && !emu_track_ended_ )
- {
- long n = buf_size;
- if ( n > count )
- n = count;
- count -= n;
- RETURN_ERR( play_( n, buf.begin() ) );
- }
- return 0;
-}
-
-// Fading
-
-void Music_Emu::set_fade( long start_msec, long length_msec )
-{
- fade_step = sample_rate() * length_msec / (fade_block_size * fade_shift * 1000 / stereo);
- fade_start = msec_to_samples( start_msec );
-}
-
-// unit / pow( 2.0, (double) x / step )
-static int int_log( blargg_long x, int step, int unit )
-{
- int shift = x / step;
- int fraction = (x - shift * step) * unit / step;
- return ((unit - fraction) + (fraction >> 1)) >> shift;
-}
-
-void Music_Emu::handle_fade( long out_count, sample_t* out )
-{
- for ( int i = 0; i < out_count; i += fade_block_size )
- {
- int const shift = 14;
- int const unit = 1 << shift;
- int gain = int_log( (out_time + i - fade_start) / fade_block_size,
- fade_step, unit );
- if ( gain < (unit >> fade_shift) )
- track_ended_ = emu_track_ended_ = true;
-
- sample_t* io = &out [i];
- for ( int count = min( fade_block_size, out_count - i ); count; --count )
- {
- *io = sample_t ((*io * gain) >> shift);
- ++io;
- }
- }
-}
-
-// Silence detection
-
-void Music_Emu::emu_play( long count, sample_t* out )
-{
- check( current_track_ >= 0 );
- emu_time += count;
- if ( current_track_ >= 0 && !emu_track_ended_ )
- end_track_if_error( play_( count, out ) );
- else
- memset( out, 0, count * sizeof *out );
-}
-
-// number of consecutive silent samples at end
-static long count_silence( Music_Emu::sample_t* begin, long size )
-{
- Music_Emu::sample_t first = *begin;
- *begin = silence_threshold; // sentinel
- Music_Emu::sample_t* p = begin + size;
- while ( (unsigned) (*--p + silence_threshold / 2) <= (unsigned) silence_threshold ) { }
- *begin = first;
- return size - (p - begin);
-}
-
-// fill internal buffer and check it for silence
-void Music_Emu::fill_buf()
-{
- assert( !buf_remain );
- if ( !emu_track_ended_ )
- {
- emu_play( buf_size, buf.begin() );
- long silence = count_silence( buf.begin(), buf_size );
- if ( silence < buf_size )
- {
- silence_time = emu_time - silence;
- buf_remain = buf_size;
- return;
- }
- }
- silence_count += buf_size;
-}
-
-blargg_err_t Music_Emu::play( long out_count, sample_t* out )
-{
- if ( track_ended_ )
- {
- memset( out, 0, out_count * sizeof *out );
- }
- else
- {
- require( current_track() >= 0 );
- require( out_count % stereo == 0 );
-
- assert( emu_time >= out_time );
-
- // prints nifty graph of how far ahead we are when searching for silence
- //debug_printf( "%*s \n", int ((emu_time - out_time) * 7 / sample_rate()), "*" );
-
- long pos = 0;
- if ( silence_count )
- {
- // during a run of silence, run emulator at >=2x speed so it gets ahead
- long ahead_time = silence_lookahead * (out_time + out_count - silence_time) + silence_time;
- while ( emu_time < ahead_time && !(buf_remain | emu_track_ended_) )
- fill_buf();
-
- // fill with silence
- pos = min( silence_count, out_count );
- memset( out, 0, pos * sizeof *out );
- silence_count -= pos;
-
- if ( emu_time - silence_time > silence_max * stereo * sample_rate() )
- {
- track_ended_ = emu_track_ended_ = true;
- silence_count = 0;
- buf_remain = 0;
- }
- }
-
- if ( buf_remain )
- {
- // empty silence buf
- long n = min( buf_remain, out_count - pos );
- memcpy( &out [pos], buf.begin() + (buf_size - buf_remain), n * sizeof *out );
- buf_remain -= n;
- pos += n;
- }
-
- // generate remaining samples normally
- long remain = out_count - pos;
- if ( remain )
- {
- emu_play( remain, out + pos );
- track_ended_ |= emu_track_ended_;
-
- if ( !ignore_silence_ || out_time > fade_start )
- {
- // check end for a new run of silence
- long silence = count_silence( out + pos, remain );
- if ( silence < remain )
- silence_time = emu_time - silence;
-
- if ( emu_time - silence_time >= buf_size )
- fill_buf(); // cause silence detection on next play()
- }
- }
-
- if ( out_time > fade_start )
- handle_fade( out_count, out );
- }
- out_time += out_count;
- return 0;
-}
-
-// Gme_Info_
-
-blargg_err_t Gme_Info_::set_sample_rate_( long ) { return 0; }
-void Gme_Info_::pre_load() { Gme_File::pre_load(); } // skip Music_Emu
-void Gme_Info_::post_load_() { Gme_File::post_load_(); } // skip Music_Emu
-void Gme_Info_::set_equalizer_( equalizer_t const& ){ check( false ); }
-void Gme_Info_::mute_voices_( int ) { check( false ); }
-void Gme_Info_::set_tempo_( double ) { }
-blargg_err_t Gme_Info_::start_track_( int ) { return "Use full emulator for playback"; }
-blargg_err_t Gme_Info_::play_( long, sample_t* ) { return "Use full emulator for playback"; }
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Music_Emu.h b/plugins/gme/game-music-emu-0.5.5/gme/Music_Emu.h
deleted file mode 100644
index c5f1d029..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Music_Emu.h
+++ /dev/null
@@ -1,211 +0,0 @@
-// Common interface to game music file emulators
-
-// Game_Music_Emu 0.5.5
-#ifndef MUSIC_EMU_H
-#define MUSIC_EMU_H
-
-#include "Gme_File.h"
-class Multi_Buffer;
-
-struct Music_Emu : public Gme_File {
-public:
-// Basic functionality (see Gme_File.h for file loading/track info functions)
-
- // Set output sample rate. Must be called only once before loading file.
- blargg_err_t set_sample_rate( long sample_rate );
-
- // Start a track, where 0 is the first track. Also clears warning string.
- blargg_err_t start_track( int );
-
- // Generate 'count' samples info 'buf'. Output is in stereo. Any emulation
- // errors set warning string, and major errors also end track.
- typedef short sample_t;
- blargg_err_t play( long count, sample_t* buf );
-
-// Informational
-
- // Sample rate sound is generated at
- long sample_rate() const;
-
- // Index of current track or -1 if one hasn't been started
- int current_track() const;
-
- // Number of voices used by currently loaded file
- int voice_count() const;
-
- // Names of voices
- const char** voice_names() const;
-
-// Track status/control
-
- // Number of milliseconds (1000 msec = 1 second) played since beginning of track
- long tell() const;
-
- // Seek to new time in track. Seeking backwards or far forward can take a while.
- blargg_err_t seek( long msec );
-
- // Skip n samples
- blargg_err_t skip( long n );
-
- // True if a track has reached its end
- bool track_ended() const;
-
- // Set start time and length of track fade out. Once fade ends track_ended() returns
- // true. Fade time can be changed while track is playing.
- void set_fade( long start_msec, long length_msec = 8000 );
-
- // Disable automatic end-of-track detection and skipping of silence at beginning
- void ignore_silence( bool disable = true );
-
- // Info for current track
- Gme_File::track_info;
- blargg_err_t track_info( track_info_t* out ) const;
-
-// Sound customization
-
- // Adjust song tempo, where 1.0 = normal, 0.5 = half speed, 2.0 = double speed.
- // Track length as returned by track_info() assumes a tempo of 1.0.
- void set_tempo( double );
-
- // Mute/unmute voice i, where voice 0 is first voice
- void mute_voice( int index, bool mute = true );
-
- // Set muting state of all voices at once using a bit mask, where -1 mutes them all,
- // 0 unmutes them all, 0x01 mutes just the first voice, etc.
- void mute_voices( int mask );
-
- // Change overall output amplitude, where 1.0 results in minimal clamping.
- // Must be called before set_sample_rate().
- void set_gain( double );
-
- // Request use of custom multichannel buffer. Only supported by "classic" emulators;
- // on others this has no effect. Should be called only once *before* set_sample_rate().
- virtual void set_buffer( Multi_Buffer* ) { }
-
-// Sound equalization (treble/bass)
-
- // Frequency equalizer parameters (see gme.txt)
- // See gme.h for definition of struct gme_equalizer_t.
- typedef gme_equalizer_t equalizer_t;
-
- // Current frequency equalizater parameters
- equalizer_t const& equalizer() const;
-
- // Set frequency equalizer parameters
- void set_equalizer( equalizer_t const& );
-
- // Equalizer settings for TV speaker
- static equalizer_t const tv_eq;
-
-public:
- Music_Emu();
- ~Music_Emu();
-protected:
- void set_max_initial_silence( int n ) { max_initial_silence = n; }
- void set_silence_lookahead( int n ) { silence_lookahead = n; }
- void set_voice_count( int n ) { voice_count_ = n; }
- void set_voice_names( const char* const* names );
- void set_track_ended() { emu_track_ended_ = true; }
- double gain() const { return gain_; }
- double tempo() const { return tempo_; }
- void remute_voices();
-
- virtual blargg_err_t set_sample_rate_( long sample_rate ) = 0;
- virtual void set_equalizer_( equalizer_t const& ) { };
- virtual void mute_voices_( int mask ) = 0;
- virtual void set_tempo_( double ) = 0;
- virtual blargg_err_t start_track_( int ) = 0; // tempo is set before this
- virtual blargg_err_t play_( long count, sample_t* out ) = 0;
- virtual blargg_err_t skip_( long count );
-protected:
- virtual void unload();
- virtual void pre_load();
- virtual void post_load_();
-private:
- // general
- equalizer_t equalizer_;
- int max_initial_silence;
- const char** voice_names_;
- int voice_count_;
- int mute_mask_;
- double tempo_;
- double gain_;
-
- long sample_rate_;
- blargg_long msec_to_samples( blargg_long msec ) const;
-
- // track-specific
- int current_track_;
- blargg_long out_time; // number of samples played since start of track
- blargg_long emu_time; // number of samples emulator has generated since start of track
- bool emu_track_ended_; // emulator has reached end of track
- volatile bool track_ended_;
- void clear_track_vars();
- void end_track_if_error( blargg_err_t );
-
- // fading
- blargg_long fade_start;
- int fade_step;
- void handle_fade( long count, sample_t* out );
-
- // silence detection
- int silence_lookahead; // speed to run emulator when looking ahead for silence
- bool ignore_silence_;
- long silence_time; // number of samples where most recent silence began
- long silence_count; // number of samples of silence to play before using buf
- long buf_remain; // number of samples left in silence buffer
- enum { buf_size = 2048 };
- blargg_vector<sample_t> buf;
- void fill_buf();
- void emu_play( long count, sample_t* out );
-
- Multi_Buffer* effects_buffer;
- friend Music_Emu* gme_new_emu( gme_type_t, int );
- friend void gme_set_stereo_depth( Music_Emu*, double );
-};
-
-// base class for info-only derivations
-struct Gme_Info_ : Music_Emu
-{
- virtual blargg_err_t set_sample_rate_( long sample_rate );
- virtual void set_equalizer_( equalizer_t const& );
- virtual void mute_voices_( int mask );
- virtual void set_tempo_( double );
- virtual blargg_err_t start_track_( int );
- virtual blargg_err_t play_( long count, sample_t* out );
- virtual void pre_load();
- virtual void post_load_();
-};
-
-inline blargg_err_t Music_Emu::track_info( track_info_t* out ) const
-{
- return track_info( out, current_track_ );
-}
-
-inline long Music_Emu::sample_rate() const { return sample_rate_; }
-inline const char** Music_Emu::voice_names() const { return voice_names_; }
-inline int Music_Emu::voice_count() const { return voice_count_; }
-inline int Music_Emu::current_track() const { return current_track_; }
-inline bool Music_Emu::track_ended() const { return track_ended_; }
-inline const Music_Emu::equalizer_t& Music_Emu::equalizer() const { return equalizer_; }
-
-inline void Music_Emu::set_tempo_( double t ) { tempo_ = t; }
-inline void Music_Emu::remute_voices() { mute_voices( mute_mask_ ); }
-inline void Music_Emu::ignore_silence( bool b ) { ignore_silence_ = b; }
-inline blargg_err_t Music_Emu::start_track_( int ) { return 0; }
-
-inline void Music_Emu::set_voice_names( const char* const* names )
-{
- // Intentional removal of const, so users don't have to remember obscure const in middle
- voice_names_ = const_cast<const char**> (names);
-}
-
-inline void Music_Emu::mute_voices_( int ) { }
-
-inline void Music_Emu::set_gain( double g )
-{
- assert( !sample_rate() ); // you must set gain before setting sample rate
- gain_ = g;
-}
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Nes_Apu.cpp b/plugins/gme/game-music-emu-0.5.5/gme/Nes_Apu.cpp
deleted file mode 100644
index 68edb446..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Nes_Apu.cpp
+++ /dev/null
@@ -1,391 +0,0 @@
-// Nes_Snd_Emu 0.1.8. http://www.slack.net/~ant/
-
-#include "Nes_Apu.h"
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-int const amp_range = 15;
-
-Nes_Apu::Nes_Apu() :
- square1( &square_synth ),
- square2( &square_synth )
-{
- tempo_ = 1.0;
- dmc.apu = this;
- dmc.prg_reader = NULL;
- irq_notifier_ = NULL;
-
- oscs [0] = &square1;
- oscs [1] = &square2;
- oscs [2] = &triangle;
- oscs [3] = &noise;
- oscs [4] = &dmc;
-
- output( NULL );
- volume( 1.0 );
- reset( false );
-}
-
-void Nes_Apu::treble_eq( const blip_eq_t& eq )
-{
- square_synth.treble_eq( eq );
- triangle.synth.treble_eq( eq );
- noise.synth.treble_eq( eq );
- dmc.synth.treble_eq( eq );
-}
-
-void Nes_Apu::enable_nonlinear( double v )
-{
- dmc.nonlinear = true;
- square_synth.volume( 1.3 * 0.25751258 / 0.742467605 * 0.25 / amp_range * v );
-
- const double tnd = 0.48 / 202 * nonlinear_tnd_gain();
- triangle.synth.volume( 3.0 * tnd );
- noise.synth.volume( 2.0 * tnd );
- dmc.synth.volume( tnd );
-
- square1 .last_amp = 0;
- square2 .last_amp = 0;
- triangle.last_amp = 0;
- noise .last_amp = 0;
- dmc .last_amp = 0;
-}
-
-void Nes_Apu::volume( double v )
-{
- dmc.nonlinear = false;
- square_synth.volume( 0.1128 / amp_range * v );
- triangle.synth.volume( 0.12765 / amp_range * v );
- noise.synth.volume( 0.0741 / amp_range * v );
- dmc.synth.volume( 0.42545 / 127 * v );
-}
-
-void Nes_Apu::output( Blip_Buffer* buffer )
-{
- for ( int i = 0; i < osc_count; i++ )
- osc_output( i, buffer );
-}
-
-void Nes_Apu::set_tempo( double t )
-{
- tempo_ = t;
- frame_period = (dmc.pal_mode ? 8314 : 7458);
- if ( t != 1.0 )
- frame_period = (int) (frame_period / t) & ~1; // must be even
-}
-
-void Nes_Apu::reset( bool pal_mode, int initial_dmc_dac )
-{
- dmc.pal_mode = pal_mode;
- set_tempo( tempo_ );
-
- square1.reset();
- square2.reset();
- triangle.reset();
- noise.reset();
- dmc.reset();
-
- last_time = 0;
- last_dmc_time = 0;
- osc_enables = 0;
- irq_flag = false;
- earliest_irq_ = no_irq;
- frame_delay = 1;
- write_register( 0, 0x4017, 0x00 );
- write_register( 0, 0x4015, 0x00 );
-
- for ( nes_addr_t addr = start_addr; addr <= 0x4013; addr++ )
- write_register( 0, addr, (addr & 3) ? 0x00 : 0x10 );
-
- dmc.dac = initial_dmc_dac;
- if ( !dmc.nonlinear )
- triangle.last_amp = 15;
- if ( !dmc.nonlinear ) // TODO: remove?
- dmc.last_amp = initial_dmc_dac; // prevent output transition
-}
-
-void Nes_Apu::irq_changed()
-{
- nes_time_t new_irq = dmc.next_irq;
- if ( dmc.irq_flag | irq_flag ) {
- new_irq = 0;
- }
- else if ( new_irq > next_irq ) {
- new_irq = next_irq;
- }
-
- if ( new_irq != earliest_irq_ ) {
- earliest_irq_ = new_irq;
- if ( irq_notifier_ )
- irq_notifier_( irq_data );
- }
-}
-
-// frames
-
-void Nes_Apu::run_until( nes_time_t end_time )
-{
- require( end_time >= last_dmc_time );
- if ( end_time > next_dmc_read_time() )
- {
- nes_time_t start = last_dmc_time;
- last_dmc_time = end_time;
- dmc.run( start, end_time );
- }
-}
-
-void Nes_Apu::run_until_( nes_time_t end_time )
-{
- require( end_time >= last_time );
-
- if ( end_time == last_time )
- return;
-
- if ( last_dmc_time < end_time )
- {
- nes_time_t start = last_dmc_time;
- last_dmc_time = end_time;
- dmc.run( start, end_time );
- }
-
- while ( true )
- {
- // earlier of next frame time or end time
- nes_time_t time = last_time + frame_delay;
- if ( time > end_time )
- time = end_time;
- frame_delay -= time - last_time;
-
- // run oscs to present
- square1.run( last_time, time );
- square2.run( last_time, time );
- triangle.run( last_time, time );
- noise.run( last_time, time );
- last_time = time;
-
- if ( time == end_time )
- break; // no more frames to run
-
- // take frame-specific actions
- frame_delay = frame_period;
- switch ( frame++ )
- {
- case 0:
- if ( !(frame_mode & 0xC0) ) {
- next_irq = time + frame_period * 4 + 2;
- irq_flag = true;
- }
- // fall through
- case 2:
- // clock length and sweep on frames 0 and 2
- square1.clock_length( 0x20 );
- square2.clock_length( 0x20 );
- noise.clock_length( 0x20 );
- triangle.clock_length( 0x80 ); // different bit for halt flag on triangle
-
- square1.clock_sweep( -1 );
- square2.clock_sweep( 0 );
-
- // frame 2 is slightly shorter in mode 1
- if ( dmc.pal_mode && frame == 3 )
- frame_delay -= 2;
- break;
-
- case 1:
- // frame 1 is slightly shorter in mode 0
- if ( !dmc.pal_mode )
- frame_delay -= 2;
- break;
-
- case 3:
- frame = 0;
-
- // frame 3 is almost twice as long in mode 1
- if ( frame_mode & 0x80 )
- frame_delay += frame_period - (dmc.pal_mode ? 2 : 6);
- break;
- }
-
- // clock envelopes and linear counter every frame
- triangle.clock_linear_counter();
- square1.clock_envelope();
- square2.clock_envelope();
- noise.clock_envelope();
- }
-}
-
-template<class T>
-inline void zero_apu_osc( T* osc, nes_time_t time )
-{
- Blip_Buffer* output = osc->output;
- int last_amp = osc->last_amp;
- osc->last_amp = 0;
- if ( output && last_amp )
- osc->synth.offset( time, -last_amp, output );
-}
-
-void Nes_Apu::end_frame( nes_time_t end_time )
-{
- if ( end_time > last_time )
- run_until_( end_time );
-
- if ( dmc.nonlinear )
- {
- zero_apu_osc( &square1, last_time );
- zero_apu_osc( &square2, last_time );
- zero_apu_osc( &triangle, last_time );
- zero_apu_osc( &noise, last_time );
- zero_apu_osc( &dmc, last_time );
- }
-
- // make times relative to new frame
- last_time -= end_time;
- require( last_time >= 0 );
-
- last_dmc_time -= end_time;
- require( last_dmc_time >= 0 );
-
- if ( next_irq != no_irq ) {
- next_irq -= end_time;
- check( next_irq >= 0 );
- }
- if ( dmc.next_irq != no_irq ) {
- dmc.next_irq -= end_time;
- check( dmc.next_irq >= 0 );
- }
- if ( earliest_irq_ != no_irq ) {
- earliest_irq_ -= end_time;
- if ( earliest_irq_ < 0 )
- earliest_irq_ = 0;
- }
-}
-
-// registers
-
-static const unsigned char length_table [0x20] = {
- 0x0A, 0xFE, 0x14, 0x02, 0x28, 0x04, 0x50, 0x06,
- 0xA0, 0x08, 0x3C, 0x0A, 0x0E, 0x0C, 0x1A, 0x0E,
- 0x0C, 0x10, 0x18, 0x12, 0x30, 0x14, 0x60, 0x16,
- 0xC0, 0x18, 0x48, 0x1A, 0x10, 0x1C, 0x20, 0x1E
-};
-
-void Nes_Apu::write_register( nes_time_t time, nes_addr_t addr, int data )
-{
- require( addr > 0x20 ); // addr must be actual address (i.e. 0x40xx)
- require( (unsigned) data <= 0xFF );
-
- // Ignore addresses outside range
- if ( unsigned (addr - start_addr) > end_addr - start_addr )
- return;
-
- run_until_( time );
-
- if ( addr < 0x4014 )
- {
- // Write to channel
- int osc_index = (addr - start_addr) >> 2;
- Nes_Osc* osc = oscs [osc_index];
-
- int reg = addr & 3;
- osc->regs [reg] = data;
- osc->reg_written [reg] = true;
-
- if ( osc_index == 4 )
- {
- // handle DMC specially
- dmc.write_register( reg, data );
- }
- else if ( reg == 3 )
- {
- // load length counter
- if ( (osc_enables >> osc_index) & 1 )
- osc->length_counter = length_table [(data >> 3) & 0x1F];
-
- // reset square phase
- if ( osc_index < 2 )
- ((Nes_Square*) osc)->phase = Nes_Square::phase_range - 1;
- }
- }
- else if ( addr == 0x4015 )
- {
- // Channel enables
- for ( int i = osc_count; i--; )
- if ( !((data >> i) & 1) )
- oscs [i]->length_counter = 0;
-
- bool recalc_irq = dmc.irq_flag;
- dmc.irq_flag = false;
-
- int old_enables = osc_enables;
- osc_enables = data;
- if ( !(data & 0x10) ) {
- dmc.next_irq = no_irq;
- recalc_irq = true;
- }
- else if ( !(old_enables & 0x10) ) {
- dmc.start(); // dmc just enabled
- }
-
- if ( recalc_irq )
- irq_changed();
- }
- else if ( addr == 0x4017 )
- {
- // Frame mode
- frame_mode = data;
-
- bool irq_enabled = !(data & 0x40);
- irq_flag &= irq_enabled;
- next_irq = no_irq;
-
- // mode 1
- frame_delay = (frame_delay & 1);
- frame = 0;
-
- if ( !(data & 0x80) )
- {
- // mode 0
- frame = 1;
- frame_delay += frame_period;
- if ( irq_enabled )
- next_irq = time + frame_delay + frame_period * 3 + 1;
- }
-
- irq_changed();
- }
-}
-
-int Nes_Apu::read_status( nes_time_t time )
-{
- run_until_( time - 1 );
-
- int result = (dmc.irq_flag << 7) | (irq_flag << 6);
-
- for ( int i = 0; i < osc_count; i++ )
- if ( oscs [i]->length_counter )
- result |= 1 << i;
-
- run_until_( time );
-
- if ( irq_flag )
- {
- result |= 0x40;
- irq_flag = false;
- irq_changed();
- }
-
- //debug_printf( "%6d/%d Read $4015->$%02X\n", frame_delay, frame, result );
-
- return result;
-}
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Nes_Apu.h b/plugins/gme/game-music-emu-0.5.5/gme/Nes_Apu.h
deleted file mode 100644
index 5e722248..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Nes_Apu.h
+++ /dev/null
@@ -1,179 +0,0 @@
-// NES 2A03 APU sound chip emulator
-
-// Nes_Snd_Emu 0.1.8
-#ifndef NES_APU_H
-#define NES_APU_H
-
-#include "blargg_common.h"
-
-typedef blargg_long nes_time_t; // CPU clock cycle count
-typedef unsigned nes_addr_t; // 16-bit memory address
-
-#include "Nes_Oscs.h"
-
-struct apu_state_t;
-class Nes_Buffer;
-
-class Nes_Apu {
-public:
- // Set buffer to generate all sound into, or disable sound if NULL
- void output( Blip_Buffer* );
-
- // Set memory reader callback used by DMC oscillator to fetch samples.
- // When callback is invoked, 'user_data' is passed unchanged as the
- // first parameter.
- void dmc_reader( int (*callback)( void* user_data, nes_addr_t ), void* user_data = NULL );
-
- // All time values are the number of CPU clock cycles relative to the
- // beginning of the current time frame. Before resetting the CPU clock
- // count, call end_frame( last_cpu_time ).
-
- // Write to register (0x4000-0x4017, except 0x4014 and 0x4016)
- enum { start_addr = 0x4000 };
- enum { end_addr = 0x4017 };
- void write_register( nes_time_t, nes_addr_t, int data );
-
- // Read from status register at 0x4015
- enum { status_addr = 0x4015 };
- int read_status( nes_time_t );
-
- // Run all oscillators up to specified time, end current time frame, then
- // start a new time frame at time 0. Time frames have no effect on emulation
- // and each can be whatever length is convenient.
- void end_frame( nes_time_t );
-
-// Additional optional features (can be ignored without any problem)
-
- // Reset internal frame counter, registers, and all oscillators.
- // Use PAL timing if pal_timing is true, otherwise use NTSC timing.
- // Set the DMC oscillator's initial DAC value to initial_dmc_dac without
- // any audible click.
- void reset( bool pal_mode = false, int initial_dmc_dac = 0 );
-
- // Adjust frame period
- void set_tempo( double );
-
- // Save/load exact emulation state
- void save_state( apu_state_t* out ) const;
- void load_state( apu_state_t const& );
-
- // Set overall volume (default is 1.0)
- void volume( double );
-
- // Set treble equalization (see notes.txt)
- void treble_eq( const blip_eq_t& );
-
- // Set sound output of specific oscillator to buffer. If buffer is NULL,
- // the specified oscillator is muted and emulation accuracy is reduced.
- // The oscillators are indexed as follows: 0) Square 1, 1) Square 2,
- // 2) Triangle, 3) Noise, 4) DMC.
- enum { osc_count = 5 };
- void osc_output( int index, Blip_Buffer* buffer );
-
- // Set IRQ time callback that is invoked when the time of earliest IRQ
- // may have changed, or NULL to disable. When callback is invoked,
- // 'user_data' is passed unchanged as the first parameter.
- void irq_notifier( void (*callback)( void* user_data ), void* user_data = NULL );
-
- // Get time that APU-generated IRQ will occur if no further register reads
- // or writes occur. If IRQ is already pending, returns irq_waiting. If no
- // IRQ will occur, returns no_irq.
- enum { no_irq = INT_MAX / 2 + 1 };
- enum { irq_waiting = 0 };
- nes_time_t earliest_irq( nes_time_t ) const;
-
- // Count number of DMC reads that would occur if 'run_until( t )' were executed.
- // If last_read is not NULL, set *last_read to the earliest time that
- // 'count_dmc_reads( time )' would result in the same result.
- int count_dmc_reads( nes_time_t t, nes_time_t* last_read = NULL ) const;
-
- // Time when next DMC memory read will occur
- nes_time_t next_dmc_read_time() const;
-
- // Run DMC until specified time, so that any DMC memory reads can be
- // accounted for (i.e. inserting CPU wait states).
- void run_until( nes_time_t );
-
-public:
- Nes_Apu();
- BLARGG_DISABLE_NOTHROW
-private:
- friend class Nes_Nonlinearizer;
- void enable_nonlinear( double volume );
- static double nonlinear_tnd_gain() { return 0.75; }
-private:
- friend struct Nes_Dmc;
-
- // noncopyable
- Nes_Apu( const Nes_Apu& );
- Nes_Apu& operator = ( const Nes_Apu& );
-
- Nes_Osc* oscs [osc_count];
- Nes_Square square1;
- Nes_Square square2;
- Nes_Noise noise;
- Nes_Triangle triangle;
- Nes_Dmc dmc;
-
- double tempo_;
- nes_time_t last_time; // has been run until this time in current frame
- nes_time_t last_dmc_time;
- nes_time_t earliest_irq_;
- nes_time_t next_irq;
- int frame_period;
- int frame_delay; // cycles until frame counter runs next
- int frame; // current frame (0-3)
- int osc_enables;
- int frame_mode;
- bool irq_flag;
- void (*irq_notifier_)( void* user_data );
- void* irq_data;
- Nes_Square::Synth square_synth; // shared by squares
-
- void irq_changed();
- void state_restored();
- void run_until_( nes_time_t );
-
- // TODO: remove
- friend class Nes_Core;
-};
-
-inline void Nes_Apu::osc_output( int osc, Blip_Buffer* buf )
-{
- assert( (unsigned) osc < osc_count );
- oscs [osc]->output = buf;
-}
-
-inline nes_time_t Nes_Apu::earliest_irq( nes_time_t ) const
-{
- return earliest_irq_;
-}
-
-inline void Nes_Apu::dmc_reader( int (*func)( void*, nes_addr_t ), void* user_data )
-{
- dmc.prg_reader_data = user_data;
- dmc.prg_reader = func;
-}
-
-inline void Nes_Apu::irq_notifier( void (*func)( void* user_data ), void* user_data )
-{
- irq_notifier_ = func;
- irq_data = user_data;
-}
-
-inline int Nes_Apu::count_dmc_reads( nes_time_t time, nes_time_t* last_read ) const
-{
- return dmc.count_reads( time, last_read );
-}
-
-inline nes_time_t Nes_Dmc::next_read_time() const
-{
- if ( length_counter == 0 )
- return Nes_Apu::no_irq; // not reading
-
- return apu->last_dmc_time + delay + long (bits_remain - 1) * period;
-}
-
-inline nes_time_t Nes_Apu::next_dmc_read_time() const { return dmc.next_read_time(); }
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Nes_Cpu.cpp b/plugins/gme/game-music-emu-0.5.5/gme/Nes_Cpu.cpp
deleted file mode 100644
index 864e0dde..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Nes_Cpu.cpp
+++ /dev/null
@@ -1,1084 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Nes_Cpu.h"
-
-#include "blargg_endian.h"
-#include <limits.h>
-
-#define BLARGG_CPU_X86 1
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#ifdef BLARGG_ENABLE_OPTIMIZER
- #include BLARGG_ENABLE_OPTIMIZER
-#endif
-
-#define FLUSH_TIME() (void) (s.time = s_time)
-#define CACHE_TIME() (void) (s_time = s.time)
-
-#include "nes_cpu_io.h"
-
-#include "blargg_source.h"
-
-#ifndef CPU_DONE
- #define CPU_DONE( cpu, time, result_out ) { result_out = -1; }
-#endif
-
-#ifndef CPU_READ_PPU
- #define CPU_READ_PPU( cpu, addr, out, time )\
- {\
- FLUSH_TIME();\
- out = CPU_READ( cpu, addr, time );\
- CACHE_TIME();\
- }
-#endif
-
-#if BLARGG_NONPORTABLE
- #define PAGE_OFFSET( addr ) (addr)
-#else
- #define PAGE_OFFSET( addr ) ((addr) & (page_size - 1))
-#endif
-
-inline void Nes_Cpu::set_code_page( int i, void const* p )
-{
- state->code_map [i] = (uint8_t const*) p - PAGE_OFFSET( i * page_size );
-}
-
-int const st_n = 0x80;
-int const st_v = 0x40;
-int const st_r = 0x20;
-int const st_b = 0x10;
-int const st_d = 0x08;
-int const st_i = 0x04;
-int const st_z = 0x02;
-int const st_c = 0x01;
-
-void Nes_Cpu::reset( void const* unmapped_page )
-{
- check( state == &state_ );
- state = &state_;
- r.status = st_i;
- r.sp = 0xFF;
- r.pc = 0;
- r.a = 0;
- r.x = 0;
- r.y = 0;
- state_.time = 0;
- state_.base = 0;
- irq_time_ = future_nes_time;
- end_time_ = future_nes_time;
- error_count_ = 0;
-
- assert( page_size == 0x800 ); // assumes this
- set_code_page( page_count, unmapped_page );
- map_code( 0x2000, 0xE000, unmapped_page, true );
- map_code( 0x0000, 0x2000, low_mem, true );
-
- blargg_verify_byte_order();
-}
-
-void Nes_Cpu::map_code( nes_addr_t start, unsigned size, void const* data, bool mirror )
-{
- // address range must begin and end on page boundaries
- require( start % page_size == 0 );
- require( size % page_size == 0 );
- require( start + size <= 0x10000 );
-
- unsigned page = start / page_size;
- for ( unsigned n = size / page_size; n; --n )
- {
- set_code_page( page++, data );
- if ( !mirror )
- data = (char const*) data + page_size;
- }
-}
-
-#define TIME (s_time + s.base)
-#define READ_LIKELY_PPU( addr, out ) {CPU_READ_PPU( this, (addr), out, TIME );}
-#define READ( addr ) CPU_READ( this, (addr), TIME )
-#define WRITE( addr, data ) {CPU_WRITE( this, (addr), (data), TIME );}
-#define READ_LOW( addr ) (low_mem [int (addr)])
-#define WRITE_LOW( addr, data ) (void) (READ_LOW( addr ) = (data))
-#define READ_PROG( addr ) (s.code_map [(addr) >> page_bits] [PAGE_OFFSET( addr )])
-
-#define SET_SP( v ) (sp = ((v) + 1) | 0x100)
-#define GET_SP() ((sp - 1) & 0xFF)
-#define PUSH( v ) ((sp = (sp - 1) | 0x100), WRITE_LOW( sp, v ))
-
-// even on x86, using short and unsigned char was slower
-typedef int fint16;
-typedef unsigned fuint16;
-typedef unsigned fuint8;
-
-bool Nes_Cpu::run( nes_time_t end_time )
-{
- set_end_time( end_time );
- state_t s = this->state_;
- this->state = &s;
- // even on x86, using s.time in place of s_time was slower
- fint16 s_time = s.time;
-
- // registers
- fuint16 pc = r.pc;
- fuint8 a = r.a;
- fuint8 x = r.x;
- fuint8 y = r.y;
- fuint16 sp;
- SET_SP( r.sp );
-
- // status flags
- #define IS_NEG (nz & 0x8080)
-
- #define CALC_STATUS( out ) do {\
- out = status & (st_v | st_d | st_i);\
- out |= ((nz >> 8) | nz) & st_n;\
- out |= c >> 8 & st_c;\
- if ( !(nz & 0xFF) ) out |= st_z;\
- } while ( 0 )
-
- #define SET_STATUS( in ) do {\
- status = in & (st_v | st_d | st_i);\
- nz = in << 8;\
- c = nz;\
- nz |= ~in & st_z;\
- } while ( 0 )
-
- fuint8 status;
- fuint16 c; // carry set if (c & 0x100) != 0
- fuint16 nz; // Z set if (nz & 0xFF) == 0, N set if (nz & 0x8080) != 0
- {
- fuint8 temp = r.status;
- SET_STATUS( temp );
- }
-
- goto loop;
-dec_clock_loop:
- s_time--;
-loop:
-
- check( (unsigned) GET_SP() < 0x100 );
- check( (unsigned) pc < 0x10000 );
- check( (unsigned) a < 0x100 );
- check( (unsigned) x < 0x100 );
- check( (unsigned) y < 0x100 );
- check( -32768 <= s_time && s_time < 32767 );
-
- uint8_t const* instr = s.code_map [pc >> page_bits];
- fuint8 opcode;
-
- // TODO: eliminate this special case
- #if BLARGG_NONPORTABLE
- opcode = instr [pc];
- pc++;
- instr += pc;
- #else
- instr += PAGE_OFFSET( pc );
- opcode = *instr++;
- pc++;
- #endif
-
- static uint8_t const clock_table [256] =
- {// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0,6,2,8,3,3,5,5,3,2,2,2,4,4,6,6,// 0
- 3,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,// 1
- 6,6,2,8,3,3,5,5,4,2,2,2,4,4,6,6,// 2
- 3,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,// 3
- 6,6,2,8,3,3,5,5,3,2,2,2,3,4,6,6,// 4
- 3,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,// 5
- 6,6,2,8,3,3,5,5,4,2,2,2,5,4,6,6,// 6
- 3,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,// 7
- 2,6,2,6,3,3,3,3,2,2,2,2,4,4,4,4,// 8
- 3,6,2,6,4,4,4,4,2,5,2,5,5,5,5,5,// 9
- 2,6,2,6,3,3,3,3,2,2,2,2,4,4,4,4,// A
- 3,5,2,5,4,4,4,4,2,4,2,4,4,4,4,4,// B
- 2,6,2,8,3,3,5,5,2,2,2,2,4,4,6,6,// C
- 3,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,// D
- 2,6,2,8,3,3,5,5,2,2,2,2,4,4,6,6,// E
- 3,5,0,8,4,4,6,6,2,4,2,7,4,4,7,7 // F
- }; // 0x00 was 7 and 0xF2 was 2
-
- fuint16 data;
-
-#if !BLARGG_CPU_X86
- if ( s_time >= 0 )
- goto out_of_time;
- s_time += clock_table [opcode];
-
- data = *instr;
-
- switch ( opcode )
- {
-#else
-
- data = clock_table [opcode];
- if ( (s_time += data) >= 0 )
- goto possibly_out_of_time;
-almost_out_of_time:
-
- data = *instr;
-
- switch ( opcode )
- {
-possibly_out_of_time:
- if ( s_time < (int) data )
- goto almost_out_of_time;
- s_time -= data;
- goto out_of_time;
-#endif
-
-// Macros
-
-#define GET_MSB() (instr [1])
-#define ADD_PAGE() (pc++, data += 0x100 * GET_MSB())
-#define GET_ADDR() GET_LE16( instr )
-
-#define NO_PAGE_CROSSING( lsb )
-#define HANDLE_PAGE_CROSSING( lsb ) s_time += (lsb) >> 8;
-
-#define INC_DEC_XY( reg, n ) reg = uint8_t (nz = reg + n); goto loop;
-
-#define IND_Y( cross, out ) {\
- fuint16 temp = READ_LOW( data ) + y;\
- out = temp + 0x100 * READ_LOW( uint8_t (data + 1) );\
- cross( temp );\
- }
-
-#define IND_X( out ) {\
- fuint16 temp = data + x;\
- out = 0x100 * READ_LOW( uint8_t (temp + 1) ) + READ_LOW( uint8_t (temp) );\
- }
-
-#define ARITH_ADDR_MODES( op )\
-case op - 0x04: /* (ind,x) */\
- IND_X( data )\
- goto ptr##op;\
-case op + 0x0C: /* (ind),y */\
- IND_Y( HANDLE_PAGE_CROSSING, data )\
- goto ptr##op;\
-case op + 0x10: /* zp,X */\
- data = uint8_t (data + x);\
-case op + 0x00: /* zp */\
- data = READ_LOW( data );\
- goto imm##op;\
-case op + 0x14: /* abs,Y */\
- data += y;\
- goto ind##op;\
-case op + 0x18: /* abs,X */\
- data += x;\
-ind##op:\
- HANDLE_PAGE_CROSSING( data );\
-case op + 0x08: /* abs */\
- ADD_PAGE();\
-ptr##op:\
- FLUSH_TIME();\
- data = READ( data );\
- CACHE_TIME();\
-case op + 0x04: /* imm */\
-imm##op:
-
-// TODO: more efficient way to handle negative branch that wraps PC around
-#define BRANCH( cond )\
-{\
- fint16 offset = (BOOST::int8_t) data;\
- fuint16 extra_clock = (++pc & 0xFF) + offset;\
- if ( !(cond) ) goto dec_clock_loop;\
- pc = BOOST::uint16_t (pc + offset);\
- s_time += extra_clock >> 8 & 1;\
- goto loop;\
-}
-
-// Often-Used
-
- case 0xB5: // LDA zp,x
- a = nz = READ_LOW( uint8_t (data + x) );
- pc++;
- goto loop;
-
- case 0xA5: // LDA zp
- a = nz = READ_LOW( data );
- pc++;
- goto loop;
-
- case 0xD0: // BNE
- BRANCH( (uint8_t) nz );
-
- case 0x20: { // JSR
- fuint16 temp = pc + 1;
- pc = GET_ADDR();
- WRITE_LOW( 0x100 | (sp - 1), temp >> 8 );
- sp = (sp - 2) | 0x100;
- WRITE_LOW( sp, temp );
- goto loop;
- }
-
- case 0x4C: // JMP abs
- pc = GET_ADDR();
- goto loop;
-
- case 0xE8: // INX
- INC_DEC_XY( x, 1 )
-
- case 0x10: // BPL
- BRANCH( !IS_NEG )
-
- ARITH_ADDR_MODES( 0xC5 ) // CMP
- nz = a - data;
- pc++;
- c = ~nz;
- nz &= 0xFF;
- goto loop;
-
- case 0x30: // BMI
- BRANCH( IS_NEG )
-
- case 0xF0: // BEQ
- BRANCH( !(uint8_t) nz );
-
- case 0x95: // STA zp,x
- data = uint8_t (data + x);
- case 0x85: // STA zp
- pc++;
- WRITE_LOW( data, a );
- goto loop;
-
- case 0xC8: // INY
- INC_DEC_XY( y, 1 )
-
- case 0xA8: // TAY
- y = a;
- nz = a;
- goto loop;
-
- case 0x98: // TYA
- a = y;
- nz = y;
- goto loop;
-
- case 0xAD:{// LDA abs
- unsigned addr = GET_ADDR();
- pc += 2;
- READ_LIKELY_PPU( addr, nz );
- a = nz;
- goto loop;
- }
-
- case 0x60: // RTS
- pc = 1 + READ_LOW( sp );
- pc += 0x100 * READ_LOW( 0x100 | (sp - 0xFF) );
- sp = (sp - 0xFE) | 0x100;
- goto loop;
-
- {
- fuint16 addr;
-
- case 0x99: // STA abs,Y
- addr = y + GET_ADDR();
- pc += 2;
- if ( addr <= 0x7FF )
- {
- WRITE_LOW( addr, a );
- goto loop;
- }
- goto sta_ptr;
-
- case 0x8D: // STA abs
- addr = GET_ADDR();
- pc += 2;
- if ( addr <= 0x7FF )
- {
- WRITE_LOW( addr, a );
- goto loop;
- }
- goto sta_ptr;
-
- case 0x9D: // STA abs,X (slightly more common than STA abs)
- addr = x + GET_ADDR();
- pc += 2;
- if ( addr <= 0x7FF )
- {
- WRITE_LOW( addr, a );
- goto loop;
- }
- sta_ptr:
- FLUSH_TIME();
- WRITE( addr, a );
- CACHE_TIME();
- goto loop;
-
- case 0x91: // STA (ind),Y
- IND_Y( NO_PAGE_CROSSING, addr )
- pc++;
- goto sta_ptr;
-
- case 0x81: // STA (ind,X)
- IND_X( addr )
- pc++;
- goto sta_ptr;
-
- }
-
- case 0xA9: // LDA #imm
- pc++;
- a = data;
- nz = data;
- goto loop;
-
- // common read instructions
- {
- fuint16 addr;
-
- case 0xA1: // LDA (ind,X)
- IND_X( addr )
- pc++;
- goto a_nz_read_addr;
-
- case 0xB1:// LDA (ind),Y
- addr = READ_LOW( data ) + y;
- HANDLE_PAGE_CROSSING( addr );
- addr += 0x100 * READ_LOW( (uint8_t) (data + 1) );
- pc++;
- a = nz = READ_PROG( addr );
- if ( (addr ^ 0x8000) <= 0x9FFF )
- goto loop;
- goto a_nz_read_addr;
-
- case 0xB9: // LDA abs,Y
- HANDLE_PAGE_CROSSING( data + y );
- addr = GET_ADDR() + y;
- pc += 2;
- a = nz = READ_PROG( addr );
- if ( (addr ^ 0x8000) <= 0x9FFF )
- goto loop;
- goto a_nz_read_addr;
-
- case 0xBD: // LDA abs,X
- HANDLE_PAGE_CROSSING( data + x );
- addr = GET_ADDR() + x;
- pc += 2;
- a = nz = READ_PROG( addr );
- if ( (addr ^ 0x8000) <= 0x9FFF )
- goto loop;
- a_nz_read_addr:
- FLUSH_TIME();
- a = nz = READ( addr );
- CACHE_TIME();
- goto loop;
-
- }
-
-// Branch
-
- case 0x50: // BVC
- BRANCH( !(status & st_v) )
-
- case 0x70: // BVS
- BRANCH( status & st_v )
-
- case 0xB0: // BCS
- BRANCH( c & 0x100 )
-
- case 0x90: // BCC
- BRANCH( !(c & 0x100) )
-
-// Load/store
-
- case 0x94: // STY zp,x
- data = uint8_t (data + x);
- case 0x84: // STY zp
- pc++;
- WRITE_LOW( data, y );
- goto loop;
-
- case 0x96: // STX zp,y
- data = uint8_t (data + y);
- case 0x86: // STX zp
- pc++;
- WRITE_LOW( data, x );
- goto loop;
-
- case 0xB6: // LDX zp,y
- data = uint8_t (data + y);
- case 0xA6: // LDX zp
- data = READ_LOW( data );
- case 0xA2: // LDX #imm
- pc++;
- x = data;
- nz = data;
- goto loop;
-
- case 0xB4: // LDY zp,x
- data = uint8_t (data + x);
- case 0xA4: // LDY zp
- data = READ_LOW( data );
- case 0xA0: // LDY #imm
- pc++;
- y = data;
- nz = data;
- goto loop;
-
- case 0xBC: // LDY abs,X
- data += x;
- HANDLE_PAGE_CROSSING( data );
- case 0xAC:{// LDY abs
- unsigned addr = data + 0x100 * GET_MSB();
- pc += 2;
- FLUSH_TIME();
- y = nz = READ( addr );
- CACHE_TIME();
- goto loop;
- }
-
- case 0xBE: // LDX abs,y
- data += y;
- HANDLE_PAGE_CROSSING( data );
- case 0xAE:{// LDX abs
- unsigned addr = data + 0x100 * GET_MSB();
- pc += 2;
- FLUSH_TIME();
- x = nz = READ( addr );
- CACHE_TIME();
- goto loop;
- }
-
- {
- fuint8 temp;
- case 0x8C: // STY abs
- temp = y;
- goto store_abs;
-
- case 0x8E: // STX abs
- temp = x;
- store_abs:
- unsigned addr = GET_ADDR();
- pc += 2;
- if ( addr <= 0x7FF )
- {
- WRITE_LOW( addr, temp );
- goto loop;
- }
- FLUSH_TIME();
- WRITE( addr, temp );
- CACHE_TIME();
- goto loop;
- }
-
-// Compare
-
- case 0xEC:{// CPX abs
- unsigned addr = GET_ADDR();
- pc++;
- FLUSH_TIME();
- data = READ( addr );
- CACHE_TIME();
- goto cpx_data;
- }
-
- case 0xE4: // CPX zp
- data = READ_LOW( data );
- case 0xE0: // CPX #imm
- cpx_data:
- nz = x - data;
- pc++;
- c = ~nz;
- nz &= 0xFF;
- goto loop;
-
- case 0xCC:{// CPY abs
- unsigned addr = GET_ADDR();
- pc++;
- FLUSH_TIME();
- data = READ( addr );
- CACHE_TIME();
- goto cpy_data;
- }
-
- case 0xC4: // CPY zp
- data = READ_LOW( data );
- case 0xC0: // CPY #imm
- cpy_data:
- nz = y - data;
- pc++;
- c = ~nz;
- nz &= 0xFF;
- goto loop;
-
-// Logical
-
- ARITH_ADDR_MODES( 0x25 ) // AND
- nz = (a &= data);
- pc++;
- goto loop;
-
- ARITH_ADDR_MODES( 0x45 ) // EOR
- nz = (a ^= data);
- pc++;
- goto loop;
-
- ARITH_ADDR_MODES( 0x05 ) // ORA
- nz = (a |= data);
- pc++;
- goto loop;
-
- case 0x2C:{// BIT abs
- unsigned addr = GET_ADDR();
- pc += 2;
- status &= ~st_v;
- READ_LIKELY_PPU( addr, nz );
- status |= nz & st_v;
- if ( a & nz )
- goto loop;
- nz <<= 8; // result must be zero, even if N bit is set
- goto loop;
- }
-
- case 0x24: // BIT zp
- nz = READ_LOW( data );
- pc++;
- status &= ~st_v;
- status |= nz & st_v;
- if ( a & nz )
- goto loop;
- nz <<= 8; // result must be zero, even if N bit is set
- goto loop;
-
-// Add/subtract
-
- ARITH_ADDR_MODES( 0xE5 ) // SBC
- case 0xEB: // unofficial equivalent
- data ^= 0xFF;
- goto adc_imm;
-
- ARITH_ADDR_MODES( 0x65 ) // ADC
- adc_imm: {
- fint16 carry = c >> 8 & 1;
- fint16 ov = (a ^ 0x80) + carry + (BOOST::int8_t) data; // sign-extend
- status &= ~st_v;
- status |= ov >> 2 & 0x40;
- c = nz = a + data + carry;
- pc++;
- a = (uint8_t) nz;
- goto loop;
- }
-
-// Shift/rotate
-
- case 0x4A: // LSR A
- c = 0;
- case 0x6A: // ROR A
- nz = c >> 1 & 0x80;
- c = a << 8;
- nz |= a >> 1;
- a = nz;
- goto loop;
-
- case 0x0A: // ASL A
- nz = a << 1;
- c = nz;
- a = (uint8_t) nz;
- goto loop;
-
- case 0x2A: { // ROL A
- nz = a << 1;
- fint16 temp = c >> 8 & 1;
- c = nz;
- nz |= temp;
- a = (uint8_t) nz;
- goto loop;
- }
-
- case 0x5E: // LSR abs,X
- data += x;
- case 0x4E: // LSR abs
- c = 0;
- case 0x6E: // ROR abs
- ror_abs: {
- ADD_PAGE();
- FLUSH_TIME();
- int temp = READ( data );
- nz = (c >> 1 & 0x80) | (temp >> 1);
- c = temp << 8;
- goto rotate_common;
- }
-
- case 0x3E: // ROL abs,X
- data += x;
- goto rol_abs;
-
- case 0x1E: // ASL abs,X
- data += x;
- case 0x0E: // ASL abs
- c = 0;
- case 0x2E: // ROL abs
- rol_abs:
- ADD_PAGE();
- nz = c >> 8 & 1;
- FLUSH_TIME();
- nz |= (c = READ( data ) << 1);
- rotate_common:
- pc++;
- WRITE( data, (uint8_t) nz );
- CACHE_TIME();
- goto loop;
-
- case 0x7E: // ROR abs,X
- data += x;
- goto ror_abs;
-
- case 0x76: // ROR zp,x
- data = uint8_t (data + x);
- goto ror_zp;
-
- case 0x56: // LSR zp,x
- data = uint8_t (data + x);
- case 0x46: // LSR zp
- c = 0;
- case 0x66: // ROR zp
- ror_zp: {
- int temp = READ_LOW( data );
- nz = (c >> 1 & 0x80) | (temp >> 1);
- c = temp << 8;
- goto write_nz_zp;
- }
-
- case 0x36: // ROL zp,x
- data = uint8_t (data + x);
- goto rol_zp;
-
- case 0x16: // ASL zp,x
- data = uint8_t (data + x);
- case 0x06: // ASL zp
- c = 0;
- case 0x26: // ROL zp
- rol_zp:
- nz = c >> 8 & 1;
- nz |= (c = READ_LOW( data ) << 1);
- goto write_nz_zp;
-
-// Increment/decrement
-
- case 0xCA: // DEX
- INC_DEC_XY( x, -1 )
-
- case 0x88: // DEY
- INC_DEC_XY( y, -1 )
-
- case 0xF6: // INC zp,x
- data = uint8_t (data + x);
- case 0xE6: // INC zp
- nz = 1;
- goto add_nz_zp;
-
- case 0xD6: // DEC zp,x
- data = uint8_t (data + x);
- case 0xC6: // DEC zp
- nz = (unsigned) -1;
- add_nz_zp:
- nz += READ_LOW( data );
- write_nz_zp:
- pc++;
- WRITE_LOW( data, nz );
- goto loop;
-
- case 0xFE: // INC abs,x
- data = x + GET_ADDR();
- goto inc_ptr;
-
- case 0xEE: // INC abs
- data = GET_ADDR();
- inc_ptr:
- nz = 1;
- goto inc_common;
-
- case 0xDE: // DEC abs,x
- data = x + GET_ADDR();
- goto dec_ptr;
-
- case 0xCE: // DEC abs
- data = GET_ADDR();
- dec_ptr:
- nz = (unsigned) -1;
- inc_common:
- FLUSH_TIME();
- nz += READ( data );
- pc += 2;
- WRITE( data, (uint8_t) nz );
- CACHE_TIME();
- goto loop;
-
-// Transfer
-
- case 0xAA: // TAX
- x = a;
- nz = a;
- goto loop;
-
- case 0x8A: // TXA
- a = x;
- nz = x;
- goto loop;
-
- case 0x9A: // TXS
- SET_SP( x ); // verified (no flag change)
- goto loop;
-
- case 0xBA: // TSX
- x = nz = GET_SP();
- goto loop;
-
-// Stack
-
- case 0x48: // PHA
- PUSH( a ); // verified
- goto loop;
-
- case 0x68: // PLA
- a = nz = READ_LOW( sp );
- sp = (sp - 0xFF) | 0x100;
- goto loop;
-
- case 0x40:{// RTI
- fuint8 temp = READ_LOW( sp );
- pc = READ_LOW( 0x100 | (sp - 0xFF) );
- pc |= READ_LOW( 0x100 | (sp - 0xFE) ) * 0x100;
- sp = (sp - 0xFD) | 0x100;
- data = status;
- SET_STATUS( temp );
- if ( !((data ^ status) & st_i) ) goto loop; // I flag didn't change
- this->r.status = status; // update externally-visible I flag
- blargg_long delta = s.base - irq_time_;
- if ( delta <= 0 ) goto loop;
- if ( status & st_i ) goto loop;
- s_time += delta;
- s.base = irq_time_;
- goto loop;
- }
-
- case 0x28:{// PLP
- fuint8 temp = READ_LOW( sp );
- sp = (sp - 0xFF) | 0x100;
- fuint8 changed = status ^ temp;
- SET_STATUS( temp );
- if ( !(changed & st_i) )
- goto loop; // I flag didn't change
- if ( status & st_i )
- goto handle_sei;
- goto handle_cli;
- }
-
- case 0x08: { // PHP
- fuint8 temp;
- CALC_STATUS( temp );
- PUSH( temp | (st_b | st_r) );
- goto loop;
- }
-
- case 0x6C:{// JMP (ind)
- data = GET_ADDR();
- check( unsigned (data - 0x2000) >= 0x4000 ); // ensure it's outside I/O space
- uint8_t const* page = s.code_map [data >> page_bits];
- pc = page [PAGE_OFFSET( data )];
- data = (data & 0xFF00) | ((data + 1) & 0xFF);
- pc |= page [PAGE_OFFSET( data )] << 8;
- goto loop;
- }
-
- case 0x00: // BRK
- goto handle_brk;
-
-// Flags
-
- case 0x38: // SEC
- c = (unsigned) ~0;
- goto loop;
-
- case 0x18: // CLC
- c = 0;
- goto loop;
-
- case 0xB8: // CLV
- status &= ~st_v;
- goto loop;
-
- case 0xD8: // CLD
- status &= ~st_d;
- goto loop;
-
- case 0xF8: // SED
- status |= st_d;
- goto loop;
-
- case 0x58: // CLI
- if ( !(status & st_i) )
- goto loop;
- status &= ~st_i;
- handle_cli: {
- //debug_printf( "CLI at %d\n", TIME );
- this->r.status = status; // update externally-visible I flag
- blargg_long delta = s.base - irq_time_;
- if ( delta <= 0 )
- {
- if ( TIME < irq_time_ )
- goto loop;
- goto delayed_cli;
- }
- s.base = irq_time_;
- s_time += delta;
- if ( s_time < 0 )
- goto loop;
-
- if ( delta >= s_time + 1 )
- {
- s.base += s_time + 1;
- s_time = -1;
- goto loop;
- }
-
- // TODO: implement
- delayed_cli:
- debug_printf( "Delayed CLI not emulated\n" );
- goto loop;
- }
-
- case 0x78: // SEI
- if ( status & st_i )
- goto loop;
- status |= st_i;
- handle_sei: {
- this->r.status = status; // update externally-visible I flag
- blargg_long delta = s.base - end_time_;
- s.base = end_time_;
- s_time += delta;
- if ( s_time < 0 )
- goto loop;
-
- debug_printf( "Delayed SEI not emulated\n" );
- goto loop;
- }
-
-// Unofficial
-
- // SKW - Skip word
- case 0x1C: case 0x3C: case 0x5C: case 0x7C: case 0xDC: case 0xFC:
- HANDLE_PAGE_CROSSING( data + x );
- case 0x0C:
- pc++;
- // SKB - Skip byte
- case 0x74: case 0x04: case 0x14: case 0x34: case 0x44: case 0x54: case 0x64:
- case 0x80: case 0x82: case 0x89: case 0xC2: case 0xD4: case 0xE2: case 0xF4:
- pc++;
- goto loop;
-
- // NOP
- case 0xEA: case 0x1A: case 0x3A: case 0x5A: case 0x7A: case 0xDA: case 0xFA:
- goto loop;
-
- case bad_opcode: // HLT
- pc--;
- if ( pc > 0xFFFF )
- {
- // handle wrap-around (assumes caller has put page of HLT at 0x10000)
- pc &= 0xFFFF;
- goto loop;
- }
- case 0x02: case 0x12: case 0x22: case 0x32: case 0x42: case 0x52:
- case 0x62: case 0x72: case 0x92: case 0xB2: case 0xD2:
- goto stop;
-
-// Unimplemented
-
- case 0xFF: // force 256-entry jump table for optimization purposes
- c |= 1;
- default:
- check( (unsigned) opcode <= 0xFF );
- // skip over proper number of bytes
- static unsigned char const illop_lens [8] = {
- 0x40, 0x40, 0x40, 0x80, 0x40, 0x40, 0x80, 0xA0
- };
- fuint8 opcode = instr [-1];
- fint16 len = illop_lens [opcode >> 2 & 7] >> (opcode << 1 & 6) & 3;
- if ( opcode == 0x9C )
- len = 2;
- pc += len;
- error_count_++;
-
- if ( (opcode >> 4) == 0x0B )
- {
- if ( opcode == 0xB3 )
- data = READ_LOW( data );
- if ( opcode != 0xB7 )
- HANDLE_PAGE_CROSSING( data + y );
- }
- goto loop;
- }
- assert( false );
-
- int result_;
-handle_brk:
- pc++;
- result_ = 4;
-
-interrupt:
- {
- s_time += 7;
-
- WRITE_LOW( 0x100 | (sp - 1), pc >> 8 );
- WRITE_LOW( 0x100 | (sp - 2), pc );
- pc = GET_LE16( &READ_PROG( 0xFFFA ) + result_ );
-
- sp = (sp - 3) | 0x100;
- fuint8 temp;
- CALC_STATUS( temp );
- temp |= st_r;
- if ( result_ )
- temp |= st_b; // TODO: incorrectly sets B flag for IRQ
- WRITE_LOW( sp, temp );
-
- this->r.status = status |= st_i;
- blargg_long delta = s.base - end_time_;
- if ( delta >= 0 ) goto loop;
- s_time += delta;
- s.base = end_time_;
- goto loop;
- }
-
-out_of_time:
- pc--;
- FLUSH_TIME();
- CPU_DONE( this, TIME, result_ );
- CACHE_TIME();
- if ( result_ >= 0 )
- goto interrupt;
- if ( s_time < 0 )
- goto loop;
-
-stop:
-
- s.time = s_time;
-
- r.pc = pc;
- r.sp = GET_SP();
- r.a = a;
- r.x = x;
- r.y = y;
-
- {
- fuint8 temp;
- CALC_STATUS( temp );
- r.status = temp;
- }
-
- this->state_ = s;
- this->state = &this->state_;
-
- return s_time < 0;
-}
-
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Nes_Cpu.h b/plugins/gme/game-music-emu-0.5.5/gme/Nes_Cpu.h
deleted file mode 100644
index 694296f7..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Nes_Cpu.h
+++ /dev/null
@@ -1,114 +0,0 @@
-// NES 6502 CPU emulator
-
-// Game_Music_Emu 0.5.5
-#ifndef NES_CPU_H
-#define NES_CPU_H
-
-#include "blargg_common.h"
-
-typedef blargg_long nes_time_t; // clock cycle count
-typedef unsigned nes_addr_t; // 16-bit address
-enum { future_nes_time = INT_MAX / 2 + 1 };
-
-class Nes_Cpu {
-public:
- typedef BOOST::uint8_t uint8_t;
-
- // Clear registers, map low memory and its three mirrors to address 0,
- // and mirror unmapped_page in remaining memory
- void reset( void const* unmapped_page = 0 );
-
- // Map code memory (memory accessed via the program counter). Start and size
- // must be multiple of page_size. If mirror is true, repeats code page
- // throughout address range.
- enum { page_size = 0x800 };
- void map_code( nes_addr_t start, unsigned size, void const* code, bool mirror = false );
-
- // Access emulated memory as CPU does
- uint8_t const* get_code( nes_addr_t );
-
- // 2KB of RAM at address 0
- uint8_t low_mem [0x800];
-
- // NES 6502 registers. Not kept updated during a call to run().
- struct registers_t {
- BOOST::uint16_t pc;
- BOOST::uint8_t a;
- BOOST::uint8_t x;
- BOOST::uint8_t y;
- BOOST::uint8_t status;
- BOOST::uint8_t sp;
- };
- registers_t r;
-
- // Set end_time and run CPU from current time. Returns true if execution
- // stopped due to encountering bad_opcode.
- bool run( nes_time_t end_time );
-
- // Time of beginning of next instruction to be executed
- nes_time_t time() const { return state->time + state->base; }
- void set_time( nes_time_t t ) { state->time = t - state->base; }
- void adjust_time( int delta ) { state->time += delta; }
-
- nes_time_t irq_time() const { return irq_time_; }
- void set_irq_time( nes_time_t );
-
- nes_time_t end_time() const { return end_time_; }
- void set_end_time( nes_time_t );
-
- // Number of undefined instructions encountered and skipped
- void clear_error_count() { error_count_ = 0; }
- unsigned long error_count() const { return error_count_; }
-
- // CPU invokes bad opcode handler if it encounters this
- enum { bad_opcode = 0xF2 };
-
-public:
- Nes_Cpu() { state = &state_; }
- enum { page_bits = 11 };
- enum { page_count = 0x10000 >> page_bits };
- enum { irq_inhibit = 0x04 };
-private:
- struct state_t {
- uint8_t const* code_map [page_count + 1];
- nes_time_t base;
- int time;
- };
- state_t* state; // points to state_ or a local copy within run()
- state_t state_;
- nes_time_t irq_time_;
- nes_time_t end_time_;
- unsigned long error_count_;
-
- void set_code_page( int, void const* );
- inline int update_end_time( nes_time_t end, nes_time_t irq );
-};
-
-inline BOOST::uint8_t const* Nes_Cpu::get_code( nes_addr_t addr )
-{
- return state->code_map [addr >> page_bits] + addr
- #if !BLARGG_NONPORTABLE
- % (unsigned) page_size
- #endif
- ;
-}
-
-inline int Nes_Cpu::update_end_time( nes_time_t t, nes_time_t irq )
-{
- if ( irq < t && !(r.status & irq_inhibit) ) t = irq;
- int delta = state->base - t;
- state->base = t;
- return delta;
-}
-
-inline void Nes_Cpu::set_irq_time( nes_time_t t )
-{
- state->time += update_end_time( end_time_, (irq_time_ = t) );
-}
-
-inline void Nes_Cpu::set_end_time( nes_time_t t )
-{
- state->time += update_end_time( (end_time_ = t), irq_time_ );
-}
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Nes_Fme7_Apu.cpp b/plugins/gme/game-music-emu-0.5.5/gme/Nes_Fme7_Apu.cpp
deleted file mode 100644
index 62594fc2..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Nes_Fme7_Apu.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Nes_Fme7_Apu.h"
-
-#include <string.h>
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-void Nes_Fme7_Apu::reset()
-{
- last_time = 0;
-
- for ( int i = 0; i < osc_count; i++ )
- oscs [i].last_amp = 0;
-
- fme7_apu_state_t* state = this;
- memset( state, 0, sizeof *state );
-}
-
-unsigned char const Nes_Fme7_Apu::amp_table [16] =
-{
- #define ENTRY( n ) (unsigned char) (n * amp_range + 0.5)
- ENTRY(0.0000), ENTRY(0.0078), ENTRY(0.0110), ENTRY(0.0156),
- ENTRY(0.0221), ENTRY(0.0312), ENTRY(0.0441), ENTRY(0.0624),
- ENTRY(0.0883), ENTRY(0.1249), ENTRY(0.1766), ENTRY(0.2498),
- ENTRY(0.3534), ENTRY(0.4998), ENTRY(0.7070), ENTRY(1.0000)
- #undef ENTRY
-};
-
-void Nes_Fme7_Apu::run_until( blip_time_t end_time )
-{
- require( end_time >= last_time );
-
- for ( int index = 0; index < osc_count; index++ )
- {
- int mode = regs [7] >> index;
- int vol_mode = regs [010 + index];
- int volume = amp_table [vol_mode & 0x0F];
-
- Blip_Buffer* const osc_output = oscs [index].output;
- if ( !osc_output )
- continue;
- osc_output->set_modified();
-
- // check for unsupported mode
- #ifndef NDEBUG
- if ( (mode & 011) <= 001 && vol_mode & 0x1F )
- debug_printf( "FME7 used unimplemented sound mode: %02X, vol_mode: %02X\n",
- mode, vol_mode & 0x1F );
- #endif
-
- if ( (mode & 001) | (vol_mode & 0x10) )
- volume = 0; // noise and envelope aren't supported
-
- // period
- int const period_factor = 16;
- unsigned period = (regs [index * 2 + 1] & 0x0F) * 0x100 * period_factor +
- regs [index * 2] * period_factor;
- if ( period < 50 ) // around 22 kHz
- {
- volume = 0;
- if ( !period ) // on my AY-3-8910A, period doesn't have extra one added
- period = period_factor;
- }
-
- // current amplitude
- int amp = volume;
- if ( !phases [index] )
- amp = 0;
- {
- int delta = amp - oscs [index].last_amp;
- if ( delta )
- {
- oscs [index].last_amp = amp;
- synth.offset( last_time, delta, osc_output );
- }
- }
-
- blip_time_t time = last_time + delays [index];
- if ( time < end_time )
- {
- int delta = amp * 2 - volume;
- if ( volume )
- {
- do
- {
- delta = -delta;
- synth.offset_inline( time, delta, osc_output );
- time += period;
- }
- while ( time < end_time );
-
- oscs [index].last_amp = (delta + volume) >> 1;
- phases [index] = (delta > 0);
- }
- else
- {
- // maintain phase when silent
- int count = (end_time - time + period - 1) / period;
- phases [index] ^= count & 1;
- time += (blargg_long) count * period;
- }
- }
-
- delays [index] = time - end_time;
- }
-
- last_time = end_time;
-}
-
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Nes_Fme7_Apu.h b/plugins/gme/game-music-emu-0.5.5/gme/Nes_Fme7_Apu.h
deleted file mode 100644
index 97094897..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Nes_Fme7_Apu.h
+++ /dev/null
@@ -1,131 +0,0 @@
-// Sunsoft FME-7 sound emulator
-
-// Game_Music_Emu 0.5.5
-#ifndef NES_FME7_APU_H
-#define NES_FME7_APU_H
-
-#include "blargg_common.h"
-#include "Blip_Buffer.h"
-
-struct fme7_apu_state_t
-{
- enum { reg_count = 14 };
- BOOST::uint8_t regs [reg_count];
- BOOST::uint8_t phases [3]; // 0 or 1
- BOOST::uint8_t latch;
- BOOST::uint16_t delays [3]; // a, b, c
-};
-
-class Nes_Fme7_Apu : private fme7_apu_state_t {
-public:
- // See Nes_Apu.h for reference
- void reset();
- void volume( double );
- void treble_eq( blip_eq_t const& );
- void output( Blip_Buffer* );
- enum { osc_count = 3 };
- void osc_output( int index, Blip_Buffer* );
- void end_frame( blip_time_t );
- void save_state( fme7_apu_state_t* ) const;
- void load_state( fme7_apu_state_t const& );
-
- // Mask and addresses of registers
- enum { addr_mask = 0xE000 };
- enum { data_addr = 0xE000 };
- enum { latch_addr = 0xC000 };
-
- // (addr & addr_mask) == latch_addr
- void write_latch( int );
-
- // (addr & addr_mask) == data_addr
- void write_data( blip_time_t, int data );
-
-public:
- Nes_Fme7_Apu();
- BLARGG_DISABLE_NOTHROW
-private:
- // noncopyable
- Nes_Fme7_Apu( const Nes_Fme7_Apu& );
- Nes_Fme7_Apu& operator = ( const Nes_Fme7_Apu& );
-
- static unsigned char const amp_table [16];
-
- struct {
- Blip_Buffer* output;
- int last_amp;
- } oscs [osc_count];
- blip_time_t last_time;
-
- enum { amp_range = 192 }; // can be any value; this gives best error/quality tradeoff
- Blip_Synth<blip_good_quality,1> synth;
-
- void run_until( blip_time_t );
-};
-
-inline void Nes_Fme7_Apu::volume( double v )
-{
- synth.volume( 0.38 / amp_range * v ); // to do: fine-tune
-}
-
-inline void Nes_Fme7_Apu::treble_eq( blip_eq_t const& eq )
-{
- synth.treble_eq( eq );
-}
-
-inline void Nes_Fme7_Apu::osc_output( int i, Blip_Buffer* buf )
-{
- assert( (unsigned) i < osc_count );
- oscs [i].output = buf;
-}
-
-inline void Nes_Fme7_Apu::output( Blip_Buffer* buf )
-{
- for ( int i = 0; i < osc_count; i++ )
- osc_output( i, buf );
-}
-
-inline Nes_Fme7_Apu::Nes_Fme7_Apu()
-{
- output( NULL );
- volume( 1.0 );
- reset();
-}
-
-inline void Nes_Fme7_Apu::write_latch( int data ) { latch = data; }
-
-inline void Nes_Fme7_Apu::write_data( blip_time_t time, int data )
-{
- if ( (unsigned) latch >= reg_count )
- {
- #ifdef debug_printf
- debug_printf( "FME7 write to %02X (past end of sound registers)\n", (int) latch );
- #endif
- return;
- }
-
- run_until( time );
- regs [latch] = data;
-}
-
-inline void Nes_Fme7_Apu::end_frame( blip_time_t time )
-{
- if ( time > last_time )
- run_until( time );
-
- assert( last_time >= time );
- last_time -= time;
-}
-
-inline void Nes_Fme7_Apu::save_state( fme7_apu_state_t* out ) const
-{
- *out = *this;
-}
-
-inline void Nes_Fme7_Apu::load_state( fme7_apu_state_t const& in )
-{
- reset();
- fme7_apu_state_t* state = this;
- *state = in;
-}
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Nes_Namco_Apu.cpp b/plugins/gme/game-music-emu-0.5.5/gme/Nes_Namco_Apu.cpp
deleted file mode 100644
index f3235b38..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Nes_Namco_Apu.cpp
+++ /dev/null
@@ -1,145 +0,0 @@
-// Nes_Snd_Emu 0.1.8. http://www.slack.net/~ant/
-
-#include "Nes_Namco_Apu.h"
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-Nes_Namco_Apu::Nes_Namco_Apu()
-{
- output( NULL );
- volume( 1.0 );
- reset();
-}
-
-void Nes_Namco_Apu::reset()
-{
- last_time = 0;
- addr_reg = 0;
-
- int i;
- for ( i = 0; i < reg_count; i++ )
- reg [i] = 0;
-
- for ( i = 0; i < osc_count; i++ )
- {
- Namco_Osc& osc = oscs [i];
- osc.delay = 0;
- osc.last_amp = 0;
- osc.wave_pos = 0;
- }
-}
-
-void Nes_Namco_Apu::output( Blip_Buffer* buf )
-{
- for ( int i = 0; i < osc_count; i++ )
- osc_output( i, buf );
-}
-
-/*
-void Nes_Namco_Apu::reflect_state( Tagged_Data& data )
-{
- reflect_int16( data, BLARGG_4CHAR('A','D','D','R'), &addr_reg );
-
- static const char hex [17] = "0123456789ABCDEF";
- int i;
- for ( i = 0; i < reg_count; i++ )
- reflect_int16( data, 'RG\0\0' + hex [i >> 4] * 0x100 + hex [i & 15], &reg [i] );
-
- for ( i = 0; i < osc_count; i++ )
- {
- reflect_int32( data, BLARGG_4CHAR('D','L','Y','0') + i, &oscs [i].delay );
- reflect_int16( data, BLARGG_4CHAR('P','O','S','0') + i, &oscs [i].wave_pos );
- }
-}
-*/
-
-void Nes_Namco_Apu::end_frame( blip_time_t time )
-{
- if ( time > last_time )
- run_until( time );
-
- assert( last_time >= time );
- last_time -= time;
-}
-
-void Nes_Namco_Apu::run_until( blip_time_t nes_end_time )
-{
- int active_oscs = (reg [0x7F] >> 4 & 7) + 1;
- for ( int i = osc_count - active_oscs; i < osc_count; i++ )
- {
- Namco_Osc& osc = oscs [i];
- Blip_Buffer* output = osc.output;
- if ( !output )
- continue;
- output->set_modified();
-
- blip_resampled_time_t time =
- output->resampled_time( last_time ) + osc.delay;
- blip_resampled_time_t end_time = output->resampled_time( nes_end_time );
- osc.delay = 0;
- if ( time < end_time )
- {
- const BOOST::uint8_t* osc_reg = &reg [i * 8 + 0x40];
- if ( !(osc_reg [4] & 0xE0) )
- continue;
-
- int volume = osc_reg [7] & 15;
- if ( !volume )
- continue;
-
- blargg_long freq = (osc_reg [4] & 3) * 0x10000 + osc_reg [2] * 0x100L + osc_reg [0];
- if ( freq < 64 * active_oscs )
- continue; // prevent low frequencies from excessively delaying freq changes
- blip_resampled_time_t period =
- output->resampled_duration( 983040 ) / freq * active_oscs;
-
- int wave_size = 32 - (osc_reg [4] >> 2 & 7) * 4;
- if ( !wave_size )
- continue;
-
- int last_amp = osc.last_amp;
- int wave_pos = osc.wave_pos;
-
- do
- {
- // read wave sample
- int addr = wave_pos + osc_reg [6];
- int sample = reg [addr >> 1] >> (addr << 2 & 4);
- wave_pos++;
- sample = (sample & 15) * volume;
-
- // output impulse if amplitude changed
- int delta = sample - last_amp;
- if ( delta )
- {
- last_amp = sample;
- synth.offset_resampled( time, delta, output );
- }
-
- // next sample
- time += period;
- if ( wave_pos >= wave_size )
- wave_pos = 0;
- }
- while ( time < end_time );
-
- osc.wave_pos = wave_pos;
- osc.last_amp = last_amp;
- }
- osc.delay = time - end_time;
- }
-
- last_time = nes_end_time;
-}
-
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Nes_Namco_Apu.h b/plugins/gme/game-music-emu-0.5.5/gme/Nes_Namco_Apu.h
deleted file mode 100644
index db5fea4b..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Nes_Namco_Apu.h
+++ /dev/null
@@ -1,102 +0,0 @@
-// Namco 106 sound chip emulator
-
-// Nes_Snd_Emu 0.1.8
-#ifndef NES_NAMCO_APU_H
-#define NES_NAMCO_APU_H
-
-#include "blargg_common.h"
-#include "Blip_Buffer.h"
-
-struct namco_state_t;
-
-class Nes_Namco_Apu {
-public:
- // See Nes_Apu.h for reference.
- void volume( double );
- void treble_eq( const blip_eq_t& );
- void output( Blip_Buffer* );
- enum { osc_count = 8 };
- void osc_output( int index, Blip_Buffer* );
- void reset();
- void end_frame( blip_time_t );
-
- // Read/write data register is at 0x4800
- enum { data_reg_addr = 0x4800 };
- void write_data( blip_time_t, int );
- int read_data();
-
- // Write-only address register is at 0xF800
- enum { addr_reg_addr = 0xF800 };
- void write_addr( int );
-
- // to do: implement save/restore
- void save_state( namco_state_t* out ) const;
- void load_state( namco_state_t const& );
-
-public:
- Nes_Namco_Apu();
- BLARGG_DISABLE_NOTHROW
-private:
- // noncopyable
- Nes_Namco_Apu( const Nes_Namco_Apu& );
- Nes_Namco_Apu& operator = ( const Nes_Namco_Apu& );
-
- struct Namco_Osc {
- blargg_long delay;
- Blip_Buffer* output;
- short last_amp;
- short wave_pos;
- };
-
- Namco_Osc oscs [osc_count];
-
- blip_time_t last_time;
- int addr_reg;
-
- enum { reg_count = 0x80 };
- BOOST::uint8_t reg [reg_count];
- Blip_Synth<blip_good_quality,15> synth;
-
- BOOST::uint8_t& access();
- void run_until( blip_time_t );
-};
-/*
-struct namco_state_t
-{
- BOOST::uint8_t regs [0x80];
- BOOST::uint8_t addr;
- BOOST::uint8_t unused;
- BOOST::uint8_t positions [8];
- BOOST::uint32_t delays [8];
-};
-*/
-
-inline BOOST::uint8_t& Nes_Namco_Apu::access()
-{
- int addr = addr_reg & 0x7F;
- if ( addr_reg & 0x80 )
- addr_reg = (addr + 1) | 0x80;
- return reg [addr];
-}
-
-inline void Nes_Namco_Apu::volume( double v ) { synth.volume( 0.10 / osc_count * v ); }
-
-inline void Nes_Namco_Apu::treble_eq( const blip_eq_t& eq ) { synth.treble_eq( eq ); }
-
-inline void Nes_Namco_Apu::write_addr( int v ) { addr_reg = v; }
-
-inline int Nes_Namco_Apu::read_data() { return access(); }
-
-inline void Nes_Namco_Apu::osc_output( int i, Blip_Buffer* buf )
-{
- assert( (unsigned) i < osc_count );
- oscs [i].output = buf;
-}
-
-inline void Nes_Namco_Apu::write_data( blip_time_t time, int data )
-{
- run_until( time );
- access() = data;
-}
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Nes_Oscs.cpp b/plugins/gme/game-music-emu-0.5.5/gme/Nes_Oscs.cpp
deleted file mode 100644
index 1ad3f59c..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Nes_Oscs.cpp
+++ /dev/null
@@ -1,551 +0,0 @@
-// Nes_Snd_Emu 0.1.8. http://www.slack.net/~ant/
-
-#include "Nes_Apu.h"
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-// Nes_Osc
-
-void Nes_Osc::clock_length( int halt_mask )
-{
- if ( length_counter && !(regs [0] & halt_mask) )
- length_counter--;
-}
-
-void Nes_Envelope::clock_envelope()
-{
- int period = regs [0] & 15;
- if ( reg_written [3] ) {
- reg_written [3] = false;
- env_delay = period;
- envelope = 15;
- }
- else if ( --env_delay < 0 ) {
- env_delay = period;
- if ( envelope | (regs [0] & 0x20) )
- envelope = (envelope - 1) & 15;
- }
-}
-
-int Nes_Envelope::volume() const
-{
- return length_counter == 0 ? 0 : (regs [0] & 0x10) ? (regs [0] & 15) : envelope;
-}
-
-// Nes_Square
-
-void Nes_Square::clock_sweep( int negative_adjust )
-{
- int sweep = regs [1];
-
- if ( --sweep_delay < 0 )
- {
- reg_written [1] = true;
-
- int period = this->period();
- int shift = sweep & shift_mask;
- if ( shift && (sweep & 0x80) && period >= 8 )
- {
- int offset = period >> shift;
-
- if ( sweep & negate_flag )
- offset = negative_adjust - offset;
-
- if ( period + offset < 0x800 )
- {
- period += offset;
- // rewrite period
- regs [2] = period & 0xFF;
- regs [3] = (regs [3] & ~7) | ((period >> 8) & 7);
- }
- }
- }
-
- if ( reg_written [1] ) {
- reg_written [1] = false;
- sweep_delay = (sweep >> 4) & 7;
- }
-}
-
-// TODO: clean up
-inline nes_time_t Nes_Square::maintain_phase( nes_time_t time, nes_time_t end_time,
- nes_time_t timer_period )
-{
- nes_time_t remain = end_time - time;
- if ( remain > 0 )
- {
- int count = (remain + timer_period - 1) / timer_period;
- phase = (phase + count) & (phase_range - 1);
- time += (blargg_long) count * timer_period;
- }
- return time;
-}
-
-void Nes_Square::run( nes_time_t time, nes_time_t end_time )
-{
- const int period = this->period();
- const int timer_period = (period + 1) * 2;
-
- if ( !output )
- {
- delay = maintain_phase( time + delay, end_time, timer_period ) - end_time;
- return;
- }
-
- output->set_modified();
-
- int offset = period >> (regs [1] & shift_mask);
- if ( regs [1] & negate_flag )
- offset = 0;
-
- const int volume = this->volume();
- if ( volume == 0 || period < 8 || (period + offset) >= 0x800 )
- {
- if ( last_amp ) {
- synth.offset( time, -last_amp, output );
- last_amp = 0;
- }
-
- time += delay;
- time = maintain_phase( time, end_time, timer_period );
- }
- else
- {
- // handle duty select
- int duty_select = (regs [0] >> 6) & 3;
- int duty = 1 << duty_select; // 1, 2, 4, 2
- int amp = 0;
- if ( duty_select == 3 ) {
- duty = 2; // negated 25%
- amp = volume;
- }
- if ( phase < duty )
- amp ^= volume;
-
- {
- int delta = update_amp( amp );
- if ( delta )
- synth.offset( time, delta, output );
- }
-
- time += delay;
- if ( time < end_time )
- {
- Blip_Buffer* const output = this->output;
- const Synth& synth = this->synth;
- int delta = amp * 2 - volume;
- int phase = this->phase;
-
- do {
- phase = (phase + 1) & (phase_range - 1);
- if ( phase == 0 || phase == duty ) {
- delta = -delta;
- synth.offset_inline( time, delta, output );
- }
- time += timer_period;
- }
- while ( time < end_time );
-
- last_amp = (delta + volume) >> 1;
- this->phase = phase;
- }
- }
-
- delay = time - end_time;
-}
-
-// Nes_Triangle
-
-void Nes_Triangle::clock_linear_counter()
-{
- if ( reg_written [3] )
- linear_counter = regs [0] & 0x7F;
- else if ( linear_counter )
- linear_counter--;
-
- if ( !(regs [0] & 0x80) )
- reg_written [3] = false;
-}
-
-inline int Nes_Triangle::calc_amp() const
-{
- int amp = phase_range - phase;
- if ( amp < 0 )
- amp = phase - (phase_range + 1);
- return amp;
-}
-
-// TODO: clean up
-inline nes_time_t Nes_Triangle::maintain_phase( nes_time_t time, nes_time_t end_time,
- nes_time_t timer_period )
-{
- nes_time_t remain = end_time - time;
- if ( remain > 0 )
- {
- int count = (remain + timer_period - 1) / timer_period;
- phase = ((unsigned) phase + 1 - count) & (phase_range * 2 - 1);
- phase++;
- time += (blargg_long) count * timer_period;
- }
- return time;
-}
-
-void Nes_Triangle::run( nes_time_t time, nes_time_t end_time )
-{
- const int timer_period = period() + 1;
- if ( !output )
- {
- time += delay;
- delay = 0;
- if ( length_counter && linear_counter && timer_period >= 3 )
- delay = maintain_phase( time, end_time, timer_period ) - end_time;
- return;
- }
-
- output->set_modified();
-
- // to do: track phase when period < 3
- // to do: Output 7.5 on dac when period < 2? More accurate, but results in more clicks.
-
- int delta = update_amp( calc_amp() );
- if ( delta )
- synth.offset( time, delta, output );
-
- time += delay;
- if ( length_counter == 0 || linear_counter == 0 || timer_period < 3 )
- {
- time = end_time;
- }
- else if ( time < end_time )
- {
- Blip_Buffer* const output = this->output;
-
- int phase = this->phase;
- int volume = 1;
- if ( phase > phase_range ) {
- phase -= phase_range;
- volume = -volume;
- }
-
- do {
- if ( --phase == 0 ) {
- phase = phase_range;
- volume = -volume;
- }
- else {
- synth.offset_inline( time, volume, output );
- }
-
- time += timer_period;
- }
- while ( time < end_time );
-
- if ( volume < 0 )
- phase += phase_range;
- this->phase = phase;
- last_amp = calc_amp();
- }
- delay = time - end_time;
-}
-
-// Nes_Dmc
-
-void Nes_Dmc::reset()
-{
- address = 0;
- dac = 0;
- buf = 0;
- bits_remain = 1;
- bits = 0;
- buf_full = false;
- silence = true;
- next_irq = Nes_Apu::no_irq;
- irq_flag = false;
- irq_enabled = false;
-
- Nes_Osc::reset();
- period = 0x1AC;
-}
-
-void Nes_Dmc::recalc_irq()
-{
- nes_time_t irq = Nes_Apu::no_irq;
- if ( irq_enabled && length_counter )
- irq = apu->last_dmc_time + delay +
- ((length_counter - 1) * 8 + bits_remain - 1) * nes_time_t (period) + 1;
- if ( irq != next_irq ) {
- next_irq = irq;
- apu->irq_changed();
- }
-}
-
-int Nes_Dmc::count_reads( nes_time_t time, nes_time_t* last_read ) const
-{
- if ( last_read )
- *last_read = time;
-
- if ( length_counter == 0 )
- return 0; // not reading
-
- nes_time_t first_read = next_read_time();
- nes_time_t avail = time - first_read;
- if ( avail <= 0 )
- return 0;
-
- int count = (avail - 1) / (period * 8) + 1;
- if ( !(regs [0] & loop_flag) && count > length_counter )
- count = length_counter;
-
- if ( last_read )
- {
- *last_read = first_read + (count - 1) * (period * 8) + 1;
- check( *last_read <= time );
- check( count == count_reads( *last_read, NULL ) );
- check( count - 1 == count_reads( *last_read - 1, NULL ) );
- }
-
- return count;
-}
-
-static short const dmc_period_table [2] [16] = {
- {428, 380, 340, 320, 286, 254, 226, 214, // NTSC
- 190, 160, 142, 128, 106, 84, 72, 54},
-
- {398, 354, 316, 298, 276, 236, 210, 198, // PAL
- 176, 148, 132, 118, 98, 78, 66, 50}
-};
-
-inline void Nes_Dmc::reload_sample()
-{
- address = 0x4000 + regs [2] * 0x40;
- length_counter = regs [3] * 0x10 + 1;
-}
-
-static byte const dac_table [128] =
-{
- 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 9,10,11,12,13,14,
- 15,15,16,17,18,19,20,20,21,22,23,24,24,25,26,27,
- 27,28,29,30,31,31,32,33,33,34,35,36,36,37,38,38,
- 39,40,41,41,42,43,43,44,45,45,46,47,47,48,48,49,
- 50,50,51,52,52,53,53,54,55,55,56,56,57,58,58,59,
- 59,60,60,61,61,62,63,63,64,64,65,65,66,66,67,67,
- 68,68,69,70,70,71,71,72,72,73,73,74,74,75,75,75,
- 76,76,77,77,78,78,79,79,80,80,81,81,82,82,82,83,
-};
-
-void Nes_Dmc::write_register( int addr, int data )
-{
- if ( addr == 0 )
- {
- period = dmc_period_table [pal_mode] [data & 15];
- irq_enabled = (data & 0xC0) == 0x80; // enabled only if loop disabled
- irq_flag &= irq_enabled;
- recalc_irq();
- }
- else if ( addr == 1 )
- {
- int old_dac = dac;
- dac = data & 0x7F;
-
- // adjust last_amp so that "pop" amplitude will be properly non-linear
- // with respect to change in dac
- int faked_nonlinear = dac - (dac_table [dac] - dac_table [old_dac]);
- if ( !nonlinear )
- last_amp = faked_nonlinear;
- }
-}
-
-void Nes_Dmc::start()
-{
- reload_sample();
- fill_buffer();
- recalc_irq();
-}
-
-void Nes_Dmc::fill_buffer()
-{
- if ( !buf_full && length_counter )
- {
- require( prg_reader ); // prg_reader must be set
- buf = prg_reader( prg_reader_data, 0x8000u + address );
- address = (address + 1) & 0x7FFF;
- buf_full = true;
- if ( --length_counter == 0 )
- {
- if ( regs [0] & loop_flag ) {
- reload_sample();
- }
- else {
- apu->osc_enables &= ~0x10;
- irq_flag = irq_enabled;
- next_irq = Nes_Apu::no_irq;
- apu->irq_changed();
- }
- }
- }
-}
-
-void Nes_Dmc::run( nes_time_t time, nes_time_t end_time )
-{
- int delta = update_amp( dac );
- if ( !output )
- {
- silence = true;
- }
- else
- {
- output->set_modified();
- if ( delta )
- synth.offset( time, delta, output );
- }
-
- time += delay;
- if ( time < end_time )
- {
- int bits_remain = this->bits_remain;
- if ( silence && !buf_full )
- {
- int count = (end_time - time + period - 1) / period;
- bits_remain = (bits_remain - 1 + 8 - (count % 8)) % 8 + 1;
- time += count * period;
- }
- else
- {
- Blip_Buffer* const output = this->output;
- const int period = this->period;
- int bits = this->bits;
- int dac = this->dac;
-
- do
- {
- if ( !silence )
- {
- int step = (bits & 1) * 4 - 2;
- bits >>= 1;
- if ( unsigned (dac + step) <= 0x7F ) {
- dac += step;
- synth.offset_inline( time, step, output );
- }
- }
-
- time += period;
-
- if ( --bits_remain == 0 )
- {
- bits_remain = 8;
- if ( !buf_full ) {
- silence = true;
- }
- else {
- silence = false;
- bits = buf;
- buf_full = false;
- if ( !output )
- silence = true;
- fill_buffer();
- }
- }
- }
- while ( time < end_time );
-
- this->dac = dac;
- this->last_amp = dac;
- this->bits = bits;
- }
- this->bits_remain = bits_remain;
- }
- delay = time - end_time;
-}
-
-// Nes_Noise
-
-static short const noise_period_table [16] = {
- 0x004, 0x008, 0x010, 0x020, 0x040, 0x060, 0x080, 0x0A0,
- 0x0CA, 0x0FE, 0x17C, 0x1FC, 0x2FA, 0x3F8, 0x7F2, 0xFE4
-};
-
-void Nes_Noise::run( nes_time_t time, nes_time_t end_time )
-{
- int period = noise_period_table [regs [2] & 15];
-
- if ( !output )
- {
- // TODO: clean up
- time += delay;
- delay = time + (end_time - time + period - 1) / period * period - end_time;
- return;
- }
-
- output->set_modified();
-
- const int volume = this->volume();
- int amp = (noise & 1) ? volume : 0;
- {
- int delta = update_amp( amp );
- if ( delta )
- synth.offset( time, delta, output );
- }
-
- time += delay;
- if ( time < end_time )
- {
- const int mode_flag = 0x80;
-
- if ( !volume )
- {
- // round to next multiple of period
- time += (end_time - time + period - 1) / period * period;
-
- // approximate noise cycling while muted, by shuffling up noise register
- // to do: precise muted noise cycling?
- if ( !(regs [2] & mode_flag) ) {
- int feedback = (noise << 13) ^ (noise << 14);
- noise = (feedback & 0x4000) | (noise >> 1);
- }
- }
- else
- {
- Blip_Buffer* const output = this->output;
-
- // using resampled time avoids conversion in synth.offset()
- blip_resampled_time_t rperiod = output->resampled_duration( period );
- blip_resampled_time_t rtime = output->resampled_time( time );
-
- int noise = this->noise;
- int delta = amp * 2 - volume;
- const int tap = (regs [2] & mode_flag ? 8 : 13);
-
- do {
- int feedback = (noise << tap) ^ (noise << 14);
- time += period;
-
- if ( (noise + 1) & 2 ) {
- // bits 0 and 1 of noise differ
- delta = -delta;
- synth.offset_resampled( rtime, delta, output );
- }
-
- rtime += rperiod;
- noise = (feedback & 0x4000) | (noise >> 1);
- }
- while ( time < end_time );
-
- last_amp = (delta + volume) >> 1;
- this->noise = noise;
- }
- }
-
- delay = time - end_time;
-}
-
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Nes_Oscs.h b/plugins/gme/game-music-emu-0.5.5/gme/Nes_Oscs.h
deleted file mode 100644
index b675bfb4..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Nes_Oscs.h
+++ /dev/null
@@ -1,147 +0,0 @@
-// Private oscillators used by Nes_Apu
-
-// Nes_Snd_Emu 0.1.8
-#ifndef NES_OSCS_H
-#define NES_OSCS_H
-
-#include "blargg_common.h"
-#include "Blip_Buffer.h"
-
-class Nes_Apu;
-
-struct Nes_Osc
-{
- unsigned char regs [4];
- bool reg_written [4];
- Blip_Buffer* output;
- int length_counter;// length counter (0 if unused by oscillator)
- int delay; // delay until next (potential) transition
- int last_amp; // last amplitude oscillator was outputting
-
- void clock_length( int halt_mask );
- int period() const {
- return (regs [3] & 7) * 0x100 + (regs [2] & 0xFF);
- }
- void reset() {
- delay = 0;
- last_amp = 0;
- }
- int update_amp( int amp ) {
- int delta = amp - last_amp;
- last_amp = amp;
- return delta;
- }
-};
-
-struct Nes_Envelope : Nes_Osc
-{
- int envelope;
- int env_delay;
-
- void clock_envelope();
- int volume() const;
- void reset() {
- envelope = 0;
- env_delay = 0;
- Nes_Osc::reset();
- }
-};
-
-// Nes_Square
-struct Nes_Square : Nes_Envelope
-{
- enum { negate_flag = 0x08 };
- enum { shift_mask = 0x07 };
- enum { phase_range = 8 };
- int phase;
- int sweep_delay;
-
- typedef Blip_Synth<blip_good_quality,1> Synth;
- Synth const& synth; // shared between squares
-
- Nes_Square( Synth const* s ) : synth( *s ) { }
-
- void clock_sweep( int adjust );
- void run( nes_time_t, nes_time_t );
- void reset() {
- sweep_delay = 0;
- Nes_Envelope::reset();
- }
- nes_time_t maintain_phase( nes_time_t time, nes_time_t end_time,
- nes_time_t timer_period );
-};
-
-// Nes_Triangle
-struct Nes_Triangle : Nes_Osc
-{
- enum { phase_range = 16 };
- int phase;
- int linear_counter;
- Blip_Synth<blip_med_quality,1> synth;
-
- int calc_amp() const;
- void run( nes_time_t, nes_time_t );
- void clock_linear_counter();
- void reset() {
- linear_counter = 0;
- phase = 1;
- Nes_Osc::reset();
- }
- nes_time_t maintain_phase( nes_time_t time, nes_time_t end_time,
- nes_time_t timer_period );
-};
-
-// Nes_Noise
-struct Nes_Noise : Nes_Envelope
-{
- int noise;
- Blip_Synth<blip_med_quality,1> synth;
-
- void run( nes_time_t, nes_time_t );
- void reset() {
- noise = 1 << 14;
- Nes_Envelope::reset();
- }
-};
-
-// Nes_Dmc
-struct Nes_Dmc : Nes_Osc
-{
- int address; // address of next byte to read
- int period;
- //int length_counter; // bytes remaining to play (already defined in Nes_Osc)
- int buf;
- int bits_remain;
- int bits;
- bool buf_full;
- bool silence;
-
- enum { loop_flag = 0x40 };
-
- int dac;
-
- nes_time_t next_irq;
- bool irq_enabled;
- bool irq_flag;
- bool pal_mode;
- bool nonlinear;
-
- int (*prg_reader)( void*, nes_addr_t ); // needs to be initialized to prg read function
- void* prg_reader_data;
-
- Nes_Apu* apu;
-
- Blip_Synth<blip_med_quality,1> synth;
-
- void start();
- void write_register( int, int );
- void run( nes_time_t, nes_time_t );
- void recalc_irq();
- void fill_buffer();
- void reload_sample();
- void reset();
- int count_reads( nes_time_t, nes_time_t* ) const;
- nes_time_t next_read_time() const;
-};
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Nes_Vrc6_Apu.cpp b/plugins/gme/game-music-emu-0.5.5/gme/Nes_Vrc6_Apu.cpp
deleted file mode 100644
index d178407c..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Nes_Vrc6_Apu.cpp
+++ /dev/null
@@ -1,215 +0,0 @@
-// Nes_Snd_Emu 0.1.8. http://www.slack.net/~ant/
-
-#include "Nes_Vrc6_Apu.h"
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-Nes_Vrc6_Apu::Nes_Vrc6_Apu()
-{
- output( NULL );
- volume( 1.0 );
- reset();
-}
-
-void Nes_Vrc6_Apu::reset()
-{
- last_time = 0;
- for ( int i = 0; i < osc_count; i++ )
- {
- Vrc6_Osc& osc = oscs [i];
- for ( int j = 0; j < reg_count; j++ )
- osc.regs [j] = 0;
- osc.delay = 0;
- osc.last_amp = 0;
- osc.phase = 1;
- osc.amp = 0;
- }
-}
-
-void Nes_Vrc6_Apu::output( Blip_Buffer* buf )
-{
- for ( int i = 0; i < osc_count; i++ )
- osc_output( i, buf );
-}
-
-void Nes_Vrc6_Apu::run_until( blip_time_t time )
-{
- require( time >= last_time );
- run_square( oscs [0], time );
- run_square( oscs [1], time );
- run_saw( time );
- last_time = time;
-}
-
-void Nes_Vrc6_Apu::write_osc( blip_time_t time, int osc_index, int reg, int data )
-{
- require( (unsigned) osc_index < osc_count );
- require( (unsigned) reg < reg_count );
-
- run_until( time );
- oscs [osc_index].regs [reg] = data;
-}
-
-void Nes_Vrc6_Apu::end_frame( blip_time_t time )
-{
- if ( time > last_time )
- run_until( time );
-
- assert( last_time >= time );
- last_time -= time;
-}
-
-void Nes_Vrc6_Apu::save_state( vrc6_apu_state_t* out ) const
-{
- assert( sizeof (vrc6_apu_state_t) == 20 );
- out->saw_amp = oscs [2].amp;
- for ( int i = 0; i < osc_count; i++ )
- {
- Vrc6_Osc const& osc = oscs [i];
- for ( int r = 0; r < reg_count; r++ )
- out->regs [i] [r] = osc.regs [r];
-
- out->delays [i] = osc.delay;
- out->phases [i] = osc.phase;
- }
-}
-
-void Nes_Vrc6_Apu::load_state( vrc6_apu_state_t const& in )
-{
- reset();
- oscs [2].amp = in.saw_amp;
- for ( int i = 0; i < osc_count; i++ )
- {
- Vrc6_Osc& osc = oscs [i];
- for ( int r = 0; r < reg_count; r++ )
- osc.regs [r] = in.regs [i] [r];
-
- osc.delay = in.delays [i];
- osc.phase = in.phases [i];
- }
- if ( !oscs [2].phase )
- oscs [2].phase = 1;
-}
-
-void Nes_Vrc6_Apu::run_square( Vrc6_Osc& osc, blip_time_t end_time )
-{
- Blip_Buffer* output = osc.output;
- if ( !output )
- return;
- output->set_modified();
-
- int volume = osc.regs [0] & 15;
- if ( !(osc.regs [2] & 0x80) )
- volume = 0;
-
- int gate = osc.regs [0] & 0x80;
- int duty = ((osc.regs [0] >> 4) & 7) + 1;
- int delta = ((gate || osc.phase < duty) ? volume : 0) - osc.last_amp;
- blip_time_t time = last_time;
- if ( delta )
- {
- osc.last_amp += delta;
- square_synth.offset( time, delta, output );
- }
-
- time += osc.delay;
- osc.delay = 0;
- int period = osc.period();
- if ( volume && !gate && period > 4 )
- {
- if ( time < end_time )
- {
- int phase = osc.phase;
-
- do
- {
- phase++;
- if ( phase == 16 )
- {
- phase = 0;
- osc.last_amp = volume;
- square_synth.offset( time, volume, output );
- }
- if ( phase == duty )
- {
- osc.last_amp = 0;
- square_synth.offset( time, -volume, output );
- }
- time += period;
- }
- while ( time < end_time );
-
- osc.phase = phase;
- }
- osc.delay = time - end_time;
- }
-}
-
-void Nes_Vrc6_Apu::run_saw( blip_time_t end_time )
-{
- Vrc6_Osc& osc = oscs [2];
- Blip_Buffer* output = osc.output;
- if ( !output )
- return;
- output->set_modified();
-
- int amp = osc.amp;
- int amp_step = osc.regs [0] & 0x3F;
- blip_time_t time = last_time;
- int last_amp = osc.last_amp;
- if ( !(osc.regs [2] & 0x80) || !(amp_step | amp) )
- {
- osc.delay = 0;
- int delta = (amp >> 3) - last_amp;
- last_amp = amp >> 3;
- saw_synth.offset( time, delta, output );
- }
- else
- {
- time += osc.delay;
- if ( time < end_time )
- {
- int period = osc.period() * 2;
- int phase = osc.phase;
-
- do
- {
- if ( --phase == 0 )
- {
- phase = 7;
- amp = 0;
- }
-
- int delta = (amp >> 3) - last_amp;
- if ( delta )
- {
- last_amp = amp >> 3;
- saw_synth.offset( time, delta, output );
- }
-
- time += period;
- amp = (amp + amp_step) & 0xFF;
- }
- while ( time < end_time );
-
- osc.phase = phase;
- osc.amp = amp;
- }
-
- osc.delay = time - end_time;
- }
-
- osc.last_amp = last_amp;
-}
-
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Nes_Vrc6_Apu.h b/plugins/gme/game-music-emu-0.5.5/gme/Nes_Vrc6_Apu.h
deleted file mode 100644
index 18722233..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Nes_Vrc6_Apu.h
+++ /dev/null
@@ -1,95 +0,0 @@
-// Konami VRC6 sound chip emulator
-
-// Nes_Snd_Emu 0.1.8
-#ifndef NES_VRC6_APU_H
-#define NES_VRC6_APU_H
-
-#include "blargg_common.h"
-#include "Blip_Buffer.h"
-
-struct vrc6_apu_state_t;
-
-class Nes_Vrc6_Apu {
-public:
- // See Nes_Apu.h for reference
- void reset();
- void volume( double );
- void treble_eq( blip_eq_t const& );
- void output( Blip_Buffer* );
- enum { osc_count = 3 };
- void osc_output( int index, Blip_Buffer* );
- void end_frame( blip_time_t );
- void save_state( vrc6_apu_state_t* ) const;
- void load_state( vrc6_apu_state_t const& );
-
- // Oscillator 0 write-only registers are at $9000-$9002
- // Oscillator 1 write-only registers are at $A000-$A002
- // Oscillator 2 write-only registers are at $B000-$B002
- enum { reg_count = 3 };
- enum { base_addr = 0x9000 };
- enum { addr_step = 0x1000 };
- void write_osc( blip_time_t, int osc, int reg, int data );
-
-public:
- Nes_Vrc6_Apu();
- BLARGG_DISABLE_NOTHROW
-private:
- // noncopyable
- Nes_Vrc6_Apu( const Nes_Vrc6_Apu& );
- Nes_Vrc6_Apu& operator = ( const Nes_Vrc6_Apu& );
-
- struct Vrc6_Osc
- {
- BOOST::uint8_t regs [3];
- Blip_Buffer* output;
- int delay;
- int last_amp;
- int phase;
- int amp; // only used by saw
-
- int period() const
- {
- return (regs [2] & 0x0F) * 0x100L + regs [1] + 1;
- }
- };
-
- Vrc6_Osc oscs [osc_count];
- blip_time_t last_time;
-
- Blip_Synth<blip_med_quality,1> saw_synth;
- Blip_Synth<blip_good_quality,1> square_synth;
-
- void run_until( blip_time_t );
- void run_square( Vrc6_Osc& osc, blip_time_t );
- void run_saw( blip_time_t );
-};
-
-struct vrc6_apu_state_t
-{
- BOOST::uint8_t regs [3] [3];
- BOOST::uint8_t saw_amp;
- BOOST::uint16_t delays [3];
- BOOST::uint8_t phases [3];
- BOOST::uint8_t unused;
-};
-
-inline void Nes_Vrc6_Apu::osc_output( int i, Blip_Buffer* buf )
-{
- assert( (unsigned) i < osc_count );
- oscs [i].output = buf;
-}
-
-inline void Nes_Vrc6_Apu::volume( double v )
-{
- double const factor = 0.0967 * 2;
- saw_synth.volume( factor / 31 * v );
- square_synth.volume( factor * 0.5 / 15 * v );
-}
-
-inline void Nes_Vrc6_Apu::treble_eq( blip_eq_t const& eq )
-{
- saw_synth.treble_eq( eq );
- square_synth.treble_eq( eq );
-}
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Nsf_Emu.cpp b/plugins/gme/game-music-emu-0.5.5/gme/Nsf_Emu.cpp
deleted file mode 100644
index 6e58164c..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Nsf_Emu.cpp
+++ /dev/null
@@ -1,559 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Nsf_Emu.h"
-
-#include "blargg_endian.h"
-#include <string.h>
-#include <stdio.h>
-
-#if !NSF_EMU_APU_ONLY
- #include "Nes_Namco_Apu.h"
- #include "Nes_Vrc6_Apu.h"
- #include "Nes_Fme7_Apu.h"
-#endif
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-int const vrc6_flag = 0x01;
-int const namco_flag = 0x10;
-int const fme7_flag = 0x20;
-
-long const clock_divisor = 12;
-
-Nsf_Emu::equalizer_t const Nsf_Emu::nes_eq = { -1.0, 80 };
-Nsf_Emu::equalizer_t const Nsf_Emu::famicom_eq = { -15.0, 80 };
-
-int Nsf_Emu::pcm_read( void* emu, nes_addr_t addr )
-{
- return *((Nsf_Emu*) emu)->cpu::get_code( addr );
-}
-
-Nsf_Emu::Nsf_Emu()
-{
- vrc6 = 0;
- namco = 0;
- fme7 = 0;
-
- set_type( gme_nsf_type );
- set_silence_lookahead( 6 );
- apu.dmc_reader( pcm_read, this );
- Music_Emu::set_equalizer( nes_eq );
- set_gain( 1.4 );
- memset( unmapped_code, Nes_Cpu::bad_opcode, sizeof unmapped_code );
-}
-
-Nsf_Emu::~Nsf_Emu() { unload(); }
-
-void Nsf_Emu::unload()
-{
- #if !NSF_EMU_APU_ONLY
- {
- delete vrc6;
- vrc6 = 0;
-
- delete namco;
- namco = 0;
-
- delete fme7;
- fme7 = 0;
- }
- #endif
-
- rom.clear();
- Music_Emu::unload();
-}
-
-// Track info
-
-static void copy_nsf_fields( Nsf_Emu::header_t const& h, track_info_t* out )
-{
- GME_COPY_FIELD( h, out, game );
- GME_COPY_FIELD( h, out, author );
- GME_COPY_FIELD( h, out, copyright );
- if ( h.chip_flags )
- Gme_File::copy_field_( out->system, "Famicom" );
-}
-
-blargg_err_t Nsf_Emu::track_info_( track_info_t* out, int ) const
-{
- copy_nsf_fields( header_, out );
- return 0;
-}
-
-static blargg_err_t check_nsf_header( void const* header )
-{
- if ( memcmp( header, "NESM\x1A", 5 ) )
- return gme_wrong_file_type;
- return 0;
-}
-
-struct Nsf_File : Gme_Info_
-{
- Nsf_Emu::header_t h;
-
- Nsf_File() { set_type( gme_nsf_type ); }
-
- blargg_err_t load_( Data_Reader& in )
- {
- blargg_err_t err = in.read( &h, Nsf_Emu::header_size );
- if ( err )
- return (err == in.eof_error ? gme_wrong_file_type : err);
-
- if ( h.chip_flags & ~(namco_flag | vrc6_flag | fme7_flag) )
- set_warning( "Uses unsupported audio expansion hardware" );
-
- set_track_count( h.track_count );
- return check_nsf_header( &h );
- }
-
- blargg_err_t track_info_( track_info_t* out, int ) const
- {
- copy_nsf_fields( h, out );
- return 0;
- }
-};
-
-static Music_Emu* new_nsf_emu () { return BLARGG_NEW Nsf_Emu ; }
-static Music_Emu* new_nsf_file() { return BLARGG_NEW Nsf_File; }
-
-static gme_type_t_ const gme_nsf_type_ = { "Nintendo NES", 0, &new_nsf_emu, &new_nsf_file, "NSF", 1 };
-gme_type_t const gme_nsf_type = &gme_nsf_type_;
-
-
-// Setup
-
-void Nsf_Emu::set_tempo_( double t )
-{
- unsigned playback_rate = get_le16( header_.ntsc_speed );
- unsigned standard_rate = 0x411A;
- clock_rate_ = 1789772.72727;
- play_period = 262 * 341L * 4 - 2; // two fewer PPU clocks every four frames
-
- if ( pal_only )
- {
- play_period = 33247 * clock_divisor;
- clock_rate_ = 1662607.125;
- standard_rate = 0x4E20;
- playback_rate = get_le16( header_.pal_speed );
- }
-
- if ( !playback_rate )
- playback_rate = standard_rate;
-
- if ( playback_rate != standard_rate || t != 1.0 )
- play_period = long (playback_rate * clock_rate_ / (1000000.0 / clock_divisor * t));
-
- apu.set_tempo( t );
-}
-
-blargg_err_t Nsf_Emu::init_sound()
-{
- if ( header_.chip_flags & ~(namco_flag | vrc6_flag | fme7_flag) )
- set_warning( "Uses unsupported audio expansion hardware" );
-
- {
- #define APU_NAMES "Square 1", "Square 2", "Triangle", "Noise", "DMC"
-
- int const count = Nes_Apu::osc_count;
- static const char* const apu_names [count] = { APU_NAMES };
- set_voice_count( count );
- set_voice_names( apu_names );
-
- }
-
- static int const types [] = {
- wave_type | 1, wave_type | 2, wave_type | 0,
- noise_type | 0, mixed_type | 1,
- wave_type | 3, wave_type | 4, wave_type | 5,
- wave_type | 6, wave_type | 7, wave_type | 8, wave_type | 9,
- wave_type |10, wave_type |11, wave_type |12, wave_type |13
- };
- set_voice_types( types ); // common to all sound chip configurations
-
- double adjusted_gain = gain();
-
- #if NSF_EMU_APU_ONLY
- {
- if ( header_.chip_flags )
- set_warning( "Uses unsupported audio expansion hardware" );
- }
- #else
- {
- if ( header_.chip_flags & (namco_flag | vrc6_flag | fme7_flag) )
- set_voice_count( Nes_Apu::osc_count + 3 );
-
- if ( header_.chip_flags & namco_flag )
- {
- namco = BLARGG_NEW Nes_Namco_Apu;
- CHECK_ALLOC( namco );
- adjusted_gain *= 0.75;
-
- int const count = Nes_Apu::osc_count + Nes_Namco_Apu::osc_count;
- static const char* const names [count] = {
- APU_NAMES,
- "Wave 1", "Wave 2", "Wave 3", "Wave 4",
- "Wave 5", "Wave 6", "Wave 7", "Wave 8"
- };
- set_voice_count( count );
- set_voice_names( names );
- }
-
- if ( header_.chip_flags & vrc6_flag )
- {
- vrc6 = BLARGG_NEW Nes_Vrc6_Apu;
- CHECK_ALLOC( vrc6 );
- adjusted_gain *= 0.75;
-
- {
- int const count = Nes_Apu::osc_count + Nes_Vrc6_Apu::osc_count;
- static const char* const names [count] = {
- APU_NAMES,
- "Saw Wave", "Square 3", "Square 4"
- };
- set_voice_count( count );
- set_voice_names( names );
- }
-
- if ( header_.chip_flags & namco_flag )
- {
- int const count = Nes_Apu::osc_count + Nes_Vrc6_Apu::osc_count +
- Nes_Namco_Apu::osc_count;
- static const char* const names [count] = {
- APU_NAMES,
- "Saw Wave", "Square 3", "Square 4",
- "Wave 1", "Wave 2", "Wave 3", "Wave 4",
- "Wave 5", "Wave 6", "Wave 7", "Wave 8"
- };
- set_voice_count( count );
- set_voice_names( names );
- }
- }
-
- if ( header_.chip_flags & fme7_flag )
- {
- fme7 = BLARGG_NEW Nes_Fme7_Apu;
- CHECK_ALLOC( fme7 );
- adjusted_gain *= 0.75;
-
- int const count = Nes_Apu::osc_count + Nes_Fme7_Apu::osc_count;
- static const char* const names [count] = {
- APU_NAMES,
- "Square 3", "Square 4", "Square 5"
- };
- set_voice_count( count );
- set_voice_names( names );
- }
-
- if ( namco ) namco->volume( adjusted_gain );
- if ( vrc6 ) vrc6 ->volume( adjusted_gain );
- if ( fme7 ) fme7 ->volume( adjusted_gain );
- }
- #endif
-
- apu.volume( adjusted_gain );
-
- return 0;
-}
-
-blargg_err_t Nsf_Emu::load_( Data_Reader& in )
-{
- assert( offsetof (header_t,unused [4]) == header_size );
- RETURN_ERR( rom.load( in, header_size, &header_, 0 ) );
-
- set_track_count( header_.track_count );
- RETURN_ERR( check_nsf_header( &header_ ) );
-
- if ( header_.vers != 1 )
- set_warning( "Unknown file version" );
-
- // sound and memory
- blargg_err_t err = init_sound();
- if ( err )
- return err;
-
- // set up data
- nes_addr_t load_addr = get_le16( header_.load_addr );
- init_addr = get_le16( header_.init_addr );
- play_addr = get_le16( header_.play_addr );
- if ( !load_addr ) load_addr = rom_begin;
- if ( !init_addr ) init_addr = rom_begin;
- if ( !play_addr ) play_addr = rom_begin;
- if ( load_addr < rom_begin || init_addr < rom_begin )
- {
- const char* w = warning();
- if ( !w )
- w = "Corrupt file (invalid load/init/play address)";
- return w;
- }
-
- rom.set_addr( load_addr % bank_size );
- int total_banks = rom.size() / bank_size;
-
- // bank switching
- int first_bank = (load_addr - rom_begin) / bank_size;
- for ( int i = 0; i < bank_count; i++ )
- {
- unsigned bank = i - first_bank;
- if ( bank >= (unsigned) total_banks )
- bank = 0;
- initial_banks [i] = bank;
-
- if ( header_.banks [i] )
- {
- // bank-switched
- memcpy( initial_banks, header_.banks, sizeof initial_banks );
- break;
- }
- }
-
- pal_only = (header_.speed_flags & 3) == 1;
-
- #if !NSF_EMU_EXTRA_FLAGS
- header_.speed_flags = 0;
- #endif
-
- set_tempo( tempo() );
-
- return setup_buffer( (long) (clock_rate_ + 0.5) );
-}
-
-void Nsf_Emu::update_eq( blip_eq_t const& eq )
-{
- apu.treble_eq( eq );
-
- #if !NSF_EMU_APU_ONLY
- {
- if ( namco ) namco->treble_eq( eq );
- if ( vrc6 ) vrc6 ->treble_eq( eq );
- if ( fme7 ) fme7 ->treble_eq( eq );
- }
- #endif
-}
-
-void Nsf_Emu::set_voice( int i, Blip_Buffer* buf, Blip_Buffer*, Blip_Buffer* )
-{
- if ( i < Nes_Apu::osc_count )
- {
- apu.osc_output( i, buf );
- return;
- }
- i -= Nes_Apu::osc_count;
-
- #if !NSF_EMU_APU_ONLY
- {
- if ( fme7 && i < Nes_Fme7_Apu::osc_count )
- {
- fme7->osc_output( i, buf );
- return;
- }
-
- if ( vrc6 )
- {
- if ( i < Nes_Vrc6_Apu::osc_count )
- {
- // put saw first
- if ( --i < 0 )
- i = 2;
- vrc6->osc_output( i, buf );
- return;
- }
- i -= Nes_Vrc6_Apu::osc_count;
- }
-
- if ( namco && i < Nes_Namco_Apu::osc_count )
- {
- namco->osc_output( i, buf );
- return;
- }
- }
- #endif
-}
-
-// Emulation
-
-// see nes_cpu_io.h for read/write functions
-
-void Nsf_Emu::cpu_write_misc( nes_addr_t addr, int data )
-{
- #if !NSF_EMU_APU_ONLY
- {
- if ( namco )
- {
- switch ( addr )
- {
- case Nes_Namco_Apu::data_reg_addr:
- namco->write_data( time(), data );
- return;
-
- case Nes_Namco_Apu::addr_reg_addr:
- namco->write_addr( data );
- return;
- }
- }
-
- if ( addr >= Nes_Fme7_Apu::latch_addr && fme7 )
- {
- switch ( addr & Nes_Fme7_Apu::addr_mask )
- {
- case Nes_Fme7_Apu::latch_addr:
- fme7->write_latch( data );
- return;
-
- case Nes_Fme7_Apu::data_addr:
- fme7->write_data( time(), data );
- return;
- }
- }
-
- if ( vrc6 )
- {
- unsigned reg = addr & (Nes_Vrc6_Apu::addr_step - 1);
- unsigned osc = unsigned (addr - Nes_Vrc6_Apu::base_addr) / Nes_Vrc6_Apu::addr_step;
- if ( osc < Nes_Vrc6_Apu::osc_count && reg < Nes_Vrc6_Apu::reg_count )
- {
- vrc6->write_osc( time(), osc, reg, data );
- return;
- }
- }
- }
- #endif
-
- // unmapped write
-
- #ifndef NDEBUG
- {
- // some games write to $8000 and $8001 repeatedly
- if ( addr == 0x8000 || addr == 0x8001 ) return;
-
- // probably namco sound mistakenly turned on in mck
- if ( addr == 0x4800 || addr == 0xF800 ) return;
-
- // memory mapper?
- if ( addr == 0xFFF8 ) return;
-
- debug_printf( "write_unmapped( 0x%04X, 0x%02X )\n", (unsigned) addr, (unsigned) data );
- }
- #endif
-}
-
-blargg_err_t Nsf_Emu::start_track_( int track )
-{
- RETURN_ERR( Classic_Emu::start_track_( track ) );
-
- memset( low_mem, 0, sizeof low_mem );
- memset( sram, 0, sizeof sram );
-
- cpu::reset( unmapped_code ); // also maps low_mem
- cpu::map_code( sram_addr, sizeof sram, sram );
- for ( int i = 0; i < bank_count; ++i )
- cpu_write( bank_select_addr + i, initial_banks [i] );
-
- apu.reset( pal_only, (header_.speed_flags & 0x20) ? 0x3F : 0 );
- apu.write_register( 0, 0x4015, 0x0F );
- apu.write_register( 0, 0x4017, (header_.speed_flags & 0x10) ? 0x80 : 0 );
- #if !NSF_EMU_APU_ONLY
- {
- if ( namco ) namco->reset();
- if ( vrc6 ) vrc6 ->reset();
- if ( fme7 ) fme7 ->reset();
- }
- #endif
-
- play_ready = 4;
- play_extra = 0;
- next_play = play_period / clock_divisor;
-
- saved_state.pc = badop_addr;
- low_mem [0x1FF] = (badop_addr - 1) >> 8;
- low_mem [0x1FE] = (badop_addr - 1) & 0xFF;
- r.sp = 0xFD;
- r.pc = init_addr;
- r.a = track;
- r.x = pal_only;
-
- return 0;
-}
-
-blargg_err_t Nsf_Emu::run_clocks( blip_time_t& duration, int )
-{
- set_time( 0 );
- while ( time() < duration )
- {
- nes_time_t end = min( (blip_time_t) next_play, duration );
- end = min( end, time() + 32767 ); // allows CPU to use 16-bit time delta
- if ( cpu::run( end ) )
- {
- if ( r.pc != badop_addr )
- {
- set_warning( "Emulation error (illegal instruction)" );
- r.pc++;
- }
- else
- {
- play_ready = 1;
- if ( saved_state.pc != badop_addr )
- {
- cpu::r = saved_state;
- saved_state.pc = badop_addr;
- }
- else
- {
- set_time( end );
- }
- }
- }
-
- if ( time() >= next_play )
- {
- nes_time_t period = (play_period + play_extra) / clock_divisor;
- play_extra = play_period - period * clock_divisor;
- next_play += period;
- if ( play_ready && !--play_ready )
- {
- check( saved_state.pc == badop_addr );
- if ( r.pc != badop_addr )
- saved_state = cpu::r;
-
- r.pc = play_addr;
- low_mem [0x100 + r.sp--] = (badop_addr - 1) >> 8;
- low_mem [0x100 + r.sp--] = (badop_addr - 1) & 0xFF;
- GME_FRAME_HOOK( this );
- }
- }
- }
-
- if ( cpu::error_count() )
- {
- cpu::clear_error_count();
- set_warning( "Emulation error (illegal instruction)" );
- }
-
- duration = time();
- next_play -= duration;
- check( next_play >= 0 );
- if ( next_play < 0 )
- next_play = 0;
-
- apu.end_frame( duration );
-
- #if !NSF_EMU_APU_ONLY
- {
- if ( namco ) namco->end_frame( duration );
- if ( vrc6 ) vrc6 ->end_frame( duration );
- if ( fme7 ) fme7 ->end_frame( duration );
- }
- #endif
-
- return 0;
-}
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Nsf_Emu.h b/plugins/gme/game-music-emu-0.5.5/gme/Nsf_Emu.h
deleted file mode 100644
index 6b213529..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Nsf_Emu.h
+++ /dev/null
@@ -1,106 +0,0 @@
-// Nintendo NES/Famicom NSF music file emulator
-
-// Game_Music_Emu 0.5.5
-#ifndef NSF_EMU_H
-#define NSF_EMU_H
-
-#include "Classic_Emu.h"
-#include "Nes_Apu.h"
-#include "Nes_Cpu.h"
-
-class Nsf_Emu : private Nes_Cpu, public Classic_Emu {
- typedef Nes_Cpu cpu;
-public:
- // Equalizer profiles for US NES and Japanese Famicom
- static equalizer_t const nes_eq;
- static equalizer_t const famicom_eq;
-
- // NSF file header
- enum { header_size = 0x80 };
- struct header_t
- {
- char tag [5];
- byte vers;
- byte track_count;
- byte first_track;
- byte load_addr [2];
- byte init_addr [2];
- byte play_addr [2];
- char game [32];
- char author [32];
- char copyright [32];
- byte ntsc_speed [2];
- byte banks [8];
- byte pal_speed [2];
- byte speed_flags;
- byte chip_flags;
- byte unused [4];
- };
-
- // Header for currently loaded file
- header_t const& header() const { return header_; }
-
- static gme_type_t static_type() { return gme_nsf_type; }
-
-public:
- // deprecated
- Music_Emu::load;
- blargg_err_t load( header_t const& h, Data_Reader& in ) // use Remaining_Reader
- { return load_remaining_( &h, sizeof h, in ); }
-
-public:
- Nsf_Emu();
- ~Nsf_Emu();
- Nes_Apu* apu_() { return &apu; }
-protected:
- blargg_err_t track_info_( track_info_t*, int track ) const;
- blargg_err_t load_( Data_Reader& );
- blargg_err_t start_track_( int );
- blargg_err_t run_clocks( blip_time_t&, int );
- void set_tempo_( double );
- void set_voice( int, Blip_Buffer*, Blip_Buffer*, Blip_Buffer* );
- void update_eq( blip_eq_t const& );
- void unload();
-protected:
- enum { bank_count = 8 };
- byte initial_banks [bank_count];
- nes_addr_t init_addr;
- nes_addr_t play_addr;
- double clock_rate_;
- bool pal_only;
-
- // timing
- Nes_Cpu::registers_t saved_state;
- nes_time_t next_play;
- nes_time_t play_period;
- int play_extra;
- int play_ready;
-
- enum { rom_begin = 0x8000 };
- enum { bank_select_addr = 0x5FF8 };
- enum { bank_size = 0x1000 };
- Rom_Data<bank_size> rom;
-
-public: private: friend class Nes_Cpu;
- void cpu_jsr( nes_addr_t );
- int cpu_read( nes_addr_t );
- void cpu_write( nes_addr_t, int );
- void cpu_write_misc( nes_addr_t, int );
- enum { badop_addr = bank_select_addr };
-
-private:
- class Nes_Namco_Apu* namco;
- class Nes_Vrc6_Apu* vrc6;
- class Nes_Fme7_Apu* fme7;
- Nes_Apu apu;
- static int pcm_read( void*, nes_addr_t );
- blargg_err_t init_sound();
-
- header_t header_;
-
- enum { sram_addr = 0x6000 };
- byte sram [0x2000];
- byte unmapped_code [Nes_Cpu::page_size + 8];
-};
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Nsfe_Emu.cpp b/plugins/gme/game-music-emu-0.5.5/gme/Nsfe_Emu.cpp
deleted file mode 100644
index eb8cdadf..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Nsfe_Emu.cpp
+++ /dev/null
@@ -1,332 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Nsfe_Emu.h"
-
-#include "blargg_endian.h"
-#include <string.h>
-#include <ctype.h>
-
-/* Copyright (C) 2005-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-Nsfe_Info::Nsfe_Info() { playlist_disabled = false; }
-
-Nsfe_Info::~Nsfe_Info() { }
-
-inline void Nsfe_Info::unload()
-{
- track_name_data.clear();
- track_names.clear();
- playlist.clear();
- track_times.clear();
-}
-
-// TODO: if no playlist, treat as if there is a playlist that is just 1,2,3,4,5... ?
-void Nsfe_Info::disable_playlist( bool b )
-{
- playlist_disabled = b;
- info.track_count = playlist.size();
- if ( !info.track_count || playlist_disabled )
- info.track_count = actual_track_count_;
-}
-
-int Nsfe_Info::remap_track( int track ) const
-{
- if ( !playlist_disabled && (unsigned) track < playlist.size() )
- track = playlist [track];
- return track;
-}
-
-// Read multiple strings and separate into individual strings
-static blargg_err_t read_strs( Data_Reader& in, long size, blargg_vector<char>& chars,
- blargg_vector<const char*>& strs )
-{
- RETURN_ERR( chars.resize( size + 1 ) );
- chars [size] = 0; // in case last string doesn't have terminator
- RETURN_ERR( in.read( &chars [0], size ) );
-
- RETURN_ERR( strs.resize( 128 ) );
- int count = 0;
- for ( int i = 0; i < size; i++ )
- {
- if ( (int) strs.size() <= count )
- RETURN_ERR( strs.resize( count * 2 ) );
- strs [count++] = &chars [i];
- while ( i < size && chars [i] )
- i++;
- }
-
- return strs.resize( count );
-}
-
-// Copy in to out, where out has out_max characters allocated. Truncate to
-// out_max - 1 characters.
-static void copy_str( const char* in, char* out, int out_max )
-{
- out [out_max - 1] = 0;
- strncpy( out, in, out_max - 1 );
-}
-
-struct nsfe_info_t
-{
- byte load_addr [2];
- byte init_addr [2];
- byte play_addr [2];
- byte speed_flags;
- byte chip_flags;
- byte track_count;
- byte first_track;
- byte unused [6];
-};
-
-blargg_err_t Nsfe_Info::load( Data_Reader& in, Nsf_Emu* nsf_emu )
-{
- int const nsfe_info_size = 16;
- assert( offsetof (nsfe_info_t,unused [6]) == nsfe_info_size );
-
- // check header
- byte signature [4];
- blargg_err_t err = in.read( signature, sizeof signature );
- if ( err )
- return (err == in.eof_error ? gme_wrong_file_type : err);
- if ( memcmp( signature, "NSFE", 4 ) )
- return gme_wrong_file_type;
-
- // free previous info
- track_name_data.clear();
- track_names.clear();
- playlist.clear();
- track_times.clear();
-
- // default nsf header
- static const Nsf_Emu::header_t base_header =
- {
- {'N','E','S','M','\x1A'},// tag
- 1, // version
- 1, 1, // track count, first track
- {0,0},{0,0},{0,0}, // addresses
- "","","", // strings
- {0x1A, 0x41}, // NTSC rate
- {0,0,0,0,0,0,0,0}, // banks
- {0x20, 0x4E}, // PAL rate
- 0, 0, // flags
- {0,0,0,0} // unused
- };
- Nsf_Emu::header_t& header = info;
- header = base_header;
-
- // parse tags
- int phase = 0;
- while ( phase != 3 )
- {
- // read size and tag
- byte block_header [2] [4];
- RETURN_ERR( in.read( block_header, sizeof block_header ) );
- blargg_long size = get_le32( block_header [0] );
- blargg_long tag = get_le32( block_header [1] );
-
- //debug_printf( "tag: %c%c%c%c\n", char(tag), char(tag>>8), char(tag>>16), char(tag>>24) );
-
- switch ( tag )
- {
- case BLARGG_4CHAR('O','F','N','I'): {
- check( phase == 0 );
- if ( size < 8 )
- return "Corrupt file";
-
- nsfe_info_t finfo;
- finfo.track_count = 1;
- finfo.first_track = 0;
-
- RETURN_ERR( in.read( &finfo, min( size, (blargg_long) nsfe_info_size ) ) );
- if ( size > nsfe_info_size )
- RETURN_ERR( in.skip( size - nsfe_info_size ) );
- phase = 1;
- info.speed_flags = finfo.speed_flags;
- info.chip_flags = finfo.chip_flags;
- info.track_count = finfo.track_count;
- this->actual_track_count_ = finfo.track_count;
- info.first_track = finfo.first_track;
- memcpy( info.load_addr, finfo.load_addr, 2 * 3 );
- break;
- }
-
- case BLARGG_4CHAR('K','N','A','B'):
- if ( size > (int) sizeof info.banks )
- return "Corrupt file";
- RETURN_ERR( in.read( info.banks, size ) );
- break;
-
- case BLARGG_4CHAR('h','t','u','a'): {
- blargg_vector<char> chars;
- blargg_vector<const char*> strs;
- RETURN_ERR( read_strs( in, size, chars, strs ) );
- int n = strs.size();
-
- if ( n > 3 )
- copy_str( strs [3], info.dumper, sizeof info.dumper );
-
- if ( n > 2 )
- copy_str( strs [2], info.copyright, sizeof info.copyright );
-
- if ( n > 1 )
- copy_str( strs [1], info.author, sizeof info.author );
-
- if ( n > 0 )
- copy_str( strs [0], info.game, sizeof info.game );
-
- break;
- }
-
- case BLARGG_4CHAR('e','m','i','t'):
- RETURN_ERR( track_times.resize( size / 4 ) );
- RETURN_ERR( in.read( track_times.begin(), track_times.size() * 4 ) );
- break;
-
- case BLARGG_4CHAR('l','b','l','t'):
- RETURN_ERR( read_strs( in, size, track_name_data, track_names ) );
- break;
-
- case BLARGG_4CHAR('t','s','l','p'):
- RETURN_ERR( playlist.resize( size ) );
- RETURN_ERR( in.read( &playlist [0], size ) );
- break;
-
- case BLARGG_4CHAR('A','T','A','D'): {
- check( phase == 1 );
- phase = 2;
- if ( !nsf_emu )
- {
- RETURN_ERR( in.skip( size ) );
- }
- else
- {
- Subset_Reader sub( &in, size ); // limit emu to nsf data
- Remaining_Reader rem( &header, Nsf_Emu::header_size, &sub );
- RETURN_ERR( nsf_emu->load( rem ) );
- check( rem.remain() == 0 );
- }
- break;
- }
-
- case BLARGG_4CHAR('D','N','E','N'):
- check( phase == 2 );
- phase = 3;
- break;
-
- default:
- // tags that can be skipped start with a lowercase character
- check( islower( (tag >> 24) & 0xFF ) );
- RETURN_ERR( in.skip( size ) );
- break;
- }
- }
-
- return 0;
-}
-
-blargg_err_t Nsfe_Info::track_info_( track_info_t* out, int track ) const
-{
- int remapped = remap_track( track );
- if ( (unsigned) remapped < track_times.size() )
- {
- long length = (BOOST::int32_t) get_le32( track_times [remapped] );
- if ( length > 0 )
- out->length = length;
- }
- if ( (unsigned) remapped < track_names.size() )
- Gme_File::copy_field_( out->song, track_names [remapped] );
-
- GME_COPY_FIELD( info, out, game );
- GME_COPY_FIELD( info, out, author );
- GME_COPY_FIELD( info, out, copyright );
- GME_COPY_FIELD( info, out, dumper );
- return 0;
-}
-
-Nsfe_Emu::Nsfe_Emu()
-{
- loading = false;
- set_type( gme_nsfe_type );
-}
-
-Nsfe_Emu::~Nsfe_Emu() { }
-
-void Nsfe_Emu::unload()
-{
- if ( !loading )
- info.unload(); // TODO: extremely hacky!
- Nsf_Emu::unload();
-}
-
-blargg_err_t Nsfe_Emu::track_info_( track_info_t* out, int track ) const
-{
- return info.track_info_( out, track );
-}
-
-struct Nsfe_File : Gme_Info_
-{
- Nsfe_Info info;
-
- Nsfe_File() { set_type( gme_nsfe_type ); }
-
- blargg_err_t load_( Data_Reader& in )
- {
- RETURN_ERR( info.load( in, 0 ) );
- info.disable_playlist( false );
- set_track_count( info.info.track_count );
- return 0;
- }
-
- blargg_err_t track_info_( track_info_t* out, int track ) const
- {
- return info.track_info_( out, track );
- }
-};
-
-static Music_Emu* new_nsfe_emu () { return BLARGG_NEW Nsfe_Emu ; }
-static Music_Emu* new_nsfe_file() { return BLARGG_NEW Nsfe_File; }
-
-static gme_type_t_ const gme_nsfe_type_ = { "Nintendo NES", 0, &new_nsfe_emu, &new_nsfe_file, "NSFE", 1 };
-gme_type_t const gme_nsfe_type = &gme_nsfe_type_;
-
-
-blargg_err_t Nsfe_Emu::load_( Data_Reader& in )
-{
- if ( loading )
- return Nsf_Emu::load_( in );
-
- // TODO: this hacky recursion-avoidance could have subtle problems
- loading = true;
- blargg_err_t err = info.load( in, this );
- loading = false;
- disable_playlist( false );
- return err;
-}
-
-void Nsfe_Emu::disable_playlist( bool b )
-{
- info.disable_playlist( b );
- set_track_count( info.info.track_count );
-}
-
-void Nsfe_Emu::clear_playlist_()
-{
- disable_playlist();
- Nsf_Emu::clear_playlist_();
-}
-
-blargg_err_t Nsfe_Emu::start_track_( int track )
-{
- return Nsf_Emu::start_track_( info.remap_track( track ) );
-}
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Nsfe_Emu.h b/plugins/gme/game-music-emu-0.5.5/gme/Nsfe_Emu.h
deleted file mode 100644
index 7971e47b..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Nsfe_Emu.h
+++ /dev/null
@@ -1,68 +0,0 @@
-// Nintendo NES/Famicom NSFE music file emulator
-
-// Game_Music_Emu 0.5.5
-#ifndef NSFE_EMU_H
-#define NSFE_EMU_H
-
-#include "blargg_common.h"
-#include "Nsf_Emu.h"
-
-// Allows reading info from NSFE file without creating emulator
-class Nsfe_Info {
-public:
- blargg_err_t load( Data_Reader&, Nsf_Emu* );
-
- struct info_t : Nsf_Emu::header_t
- {
- char game [256];
- char author [256];
- char copyright [256];
- char dumper [256];
- } info;
-
- void disable_playlist( bool = true );
-
- blargg_err_t track_info_( track_info_t* out, int track ) const;
-
- int remap_track( int i ) const;
-
- void unload();
-
- Nsfe_Info();
- ~Nsfe_Info();
-private:
- blargg_vector<char> track_name_data;
- blargg_vector<const char*> track_names;
- blargg_vector<unsigned char> playlist;
- blargg_vector<char [4]> track_times;
- int actual_track_count_;
- bool playlist_disabled;
-};
-
-class Nsfe_Emu : public Nsf_Emu {
-public:
- static gme_type_t static_type() { return gme_nsfe_type; }
-
-public:
- // deprecated
- struct header_t { char tag [4]; };
- Music_Emu::load;
- blargg_err_t load( header_t const& h, Data_Reader& in ) // use Remaining_Reader
- { return load_remaining_( &h, sizeof h, in ); }
- void disable_playlist( bool = true ); // use clear_playlist()
-
-public:
- Nsfe_Emu();
- ~Nsfe_Emu();
-protected:
- blargg_err_t load_( Data_Reader& );
- blargg_err_t track_info_( track_info_t*, int track ) const;
- blargg_err_t start_track_( int );
- void unload();
- void clear_playlist_();
-private:
- Nsfe_Info info;
- bool loading;
-};
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Sap_Apu.cpp b/plugins/gme/game-music-emu-0.5.5/gme/Sap_Apu.cpp
deleted file mode 100644
index fb56f5dc..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Sap_Apu.cpp
+++ /dev/null
@@ -1,334 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Sap_Apu.h"
-
-#include <string.h>
-
-/* Copyright (C) 2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-int const max_frequency = 12000; // pure waves above this frequency are silenced
-
-static void gen_poly( blargg_ulong mask, int count, byte* out )
-{
- blargg_ulong n = 1;
- do
- {
- int bits = 0;
- int b = 0;
- do
- {
- // implemented using "Galios configuration"
- bits |= (n & 1) << b;
- n = (n >> 1) ^ (mask & -(n & 1));
- }
- while ( b++ < 7 );
- *out++ = bits;
- }
- while ( --count );
-}
-
-// poly5
-int const poly5_len = (1 << 5) - 1;
-blargg_ulong const poly5_mask = (1UL << poly5_len) - 1;
-blargg_ulong const poly5 = 0x167C6EA1;
-
-inline blargg_ulong run_poly5( blargg_ulong in, int shift )
-{
- return (in << shift & poly5_mask) | (in >> (poly5_len - shift));
-}
-
-#define POLY_MASK( width, tap1, tap2 ) \
- ((1UL << (width - 1 - tap1)) | (1UL << (width - 1 - tap2)))
-
-Sap_Apu_Impl::Sap_Apu_Impl()
-{
- gen_poly( POLY_MASK( 4, 1, 0 ), sizeof poly4, poly4 );
- gen_poly( POLY_MASK( 9, 5, 0 ), sizeof poly9, poly9 );
- gen_poly( POLY_MASK( 17, 5, 0 ), sizeof poly17, poly17 );
-
- if ( 0 ) // comment out to recauculate poly5 constant
- {
- byte poly5 [4];
- gen_poly( POLY_MASK( 5, 2, 0 ), sizeof poly5, poly5 );
- blargg_ulong n = poly5 [3] * 0x1000000L + poly5 [2] * 0x10000L +
- poly5 [1] * 0x100L + poly5 [0];
- blargg_ulong rev = n & 1;
- for ( int i = 1; i < poly5_len; i++ )
- rev |= (n >> i & 1) << (poly5_len - i);
- debug_printf( "poly5: 0x%08lX\n", rev );
- }
-}
-
-Sap_Apu::Sap_Apu()
-{
- impl = 0;
- for ( int i = 0; i < osc_count; i++ )
- osc_output( i, 0 );
-}
-
-void Sap_Apu::reset( Sap_Apu_Impl* new_impl )
-{
- impl = new_impl;
- last_time = 0;
- poly5_pos = 0;
- poly4_pos = 0;
- polym_pos = 0;
- control = 0;
-
- for ( int i = 0; i < osc_count; i++ )
- memset( &oscs [i], 0, offsetof (osc_t,output) );
-}
-
-void Sap_Apu::calc_periods()
-{
- // 15/64 kHz clock
- int divider = 28;
- if ( this->control & 1 )
- divider = 114;
-
- for ( int i = 0; i < osc_count; i++ )
- {
- osc_t* const osc = &oscs [i];
-
- int const osc_reload = osc->regs [0]; // cache
- blargg_long period = (osc_reload + 1) * divider;
- static byte const fast_bits [osc_count] = { 1 << 6, 1 << 4, 1 << 5, 1 << 3 };
- if ( this->control & fast_bits [i] )
- {
- period = osc_reload + 4;
- if ( i & 1 )
- {
- period = osc_reload * 0x100L + osc [-1].regs [0] + 7;
- if ( !(this->control & fast_bits [i - 1]) )
- period = (period - 6) * divider;
-
- if ( (osc [-1].regs [1] & 0x1F) > 0x10 )
- debug_printf( "Use of slave channel in 16-bit mode not supported\n" );
- }
- }
- osc->period = period;
- }
-}
-
-void Sap_Apu::run_until( blip_time_t end_time )
-{
- calc_periods();
- Sap_Apu_Impl* const impl = this->impl; // cache
-
- // 17/9-bit poly selection
- byte const* polym = impl->poly17;
- int polym_len = poly17_len;
- if ( this->control & 0x80 )
- {
- polym_len = poly9_len;
- polym = impl->poly9;
- }
- polym_pos %= polym_len;
-
- for ( int i = 0; i < osc_count; i++ )
- {
- osc_t* const osc = &oscs [i];
- blip_time_t time = last_time + osc->delay;
- blip_time_t const period = osc->period;
-
- // output
- Blip_Buffer* output = osc->output;
- if ( output )
- {
- output->set_modified();
-
- int const osc_control = osc->regs [1]; // cache
- int volume = (osc_control & 0x0F) * 2;
- if ( !volume || osc_control & 0x10 || // silent, DAC mode, or inaudible frequency
- ((osc_control & 0xA0) == 0xA0 && period < 1789773 / 2 / max_frequency) )
- {
- if ( !(osc_control & 0x10) )
- volume >>= 1; // inaudible frequency = half volume
-
- int delta = volume - osc->last_amp;
- if ( delta )
- {
- osc->last_amp = volume;
- impl->synth.offset( last_time, delta, output );
- }
-
- // TODO: doesn't maintain high pass flip-flop (very minor issue)
- }
- else
- {
- // high pass
- static byte const hipass_bits [osc_count] = { 1 << 2, 1 << 1, 0, 0 };
- blip_time_t period2 = 0; // unused if no high pass
- blip_time_t time2 = end_time;
- if ( this->control & hipass_bits [i] )
- {
- period2 = osc [2].period;
- time2 = last_time + osc [2].delay;
- if ( osc->invert )
- {
- // trick inner wave loop into inverting output
- osc->last_amp -= volume;
- volume = -volume;
- }
- }
-
- if ( time < end_time || time2 < end_time )
- {
- // poly source
- static byte const poly1 [] = { 0x55, 0x55 }; // square wave
- byte const* poly = poly1;
- int poly_len = 8 * sizeof poly1; // can be just 2 bits, but this is faster
- int poly_pos = osc->phase & 1;
- int poly_inc = 1;
- if ( !(osc_control & 0x20) )
- {
- poly = polym;
- poly_len = polym_len;
- poly_pos = polym_pos;
- if ( osc_control & 0x40 )
- {
- poly = impl->poly4;
- poly_len = poly4_len;
- poly_pos = poly4_pos;
- }
- poly_inc = period % poly_len;
- poly_pos = (poly_pos + osc->delay) % poly_len;
- }
- poly_inc -= poly_len; // allows more optimized inner loop below
-
- // square/poly5 wave
- blargg_ulong wave = poly5;
- check( poly5 & 1 ); // low bit is set for pure wave
- int poly5_inc = 0;
- if ( !(osc_control & 0x80) )
- {
- wave = run_poly5( wave, (osc->delay + poly5_pos) % poly5_len );
- poly5_inc = period % poly5_len;
- }
-
- // Run wave and high pass interleved with each catching up to the other.
- // Disabled high pass has no performance effect since inner wave loop
- // makes no compromise for high pass, and only runs once in that case.
- int osc_last_amp = osc->last_amp;
- do
- {
- // run high pass
- if ( time2 < time )
- {
- int delta = -osc_last_amp;
- if ( volume < 0 )
- delta += volume;
- if ( delta )
- {
- osc_last_amp += delta - volume;
- volume = -volume;
- impl->synth.offset( time2, delta, output );
- }
- }
- while ( time2 <= time ) // must advance *past* time to avoid hang
- time2 += period2;
-
- // run wave
- blip_time_t end = end_time;
- if ( end > time2 )
- end = time2;
- while ( time < end )
- {
- if ( wave & 1 )
- {
- int amp = volume & -(poly [poly_pos >> 3] >> (poly_pos & 7) & 1);
- if ( (poly_pos += poly_inc) < 0 )
- poly_pos += poly_len;
- int delta = amp - osc_last_amp;
- if ( delta )
- {
- osc_last_amp = amp;
- impl->synth.offset( time, delta, output );
- }
- }
- wave = run_poly5( wave, poly5_inc );
- time += period;
- }
- }
- while ( time < end_time || time2 < end_time );
-
- osc->phase = poly_pos;
- osc->last_amp = osc_last_amp;
- }
-
- osc->invert = 0;
- if ( volume < 0 )
- {
- // undo inversion trickery
- osc->last_amp -= volume;
- osc->invert = 1;
- }
- }
- }
-
- // maintain divider
- blip_time_t remain = end_time - time;
- if ( remain > 0 )
- {
- blargg_long count = (remain + period - 1) / period;
- osc->phase ^= count;
- time += count * period;
- }
- osc->delay = time - end_time;
- }
-
- // advance polies
- blip_time_t duration = end_time - last_time;
- last_time = end_time;
- poly4_pos = (poly4_pos + duration) % poly4_len;
- poly5_pos = (poly5_pos + duration) % poly5_len;
- polym_pos += duration; // will get %'d on next call
-}
-
-void Sap_Apu::write_data( blip_time_t time, unsigned addr, int data )
-{
- run_until( time );
- int i = (addr ^ 0xD200) >> 1;
- if ( i < osc_count )
- {
- oscs [i].regs [addr & 1] = data;
- }
- else if ( addr == 0xD208 )
- {
- control = data;
- }
- else if ( addr == 0xD209 )
- {
- oscs [0].delay = 0;
- oscs [1].delay = 0;
- oscs [2].delay = 0;
- oscs [3].delay = 0;
- }
- /*
- // TODO: are polynomials reset in this case?
- else if ( addr == 0xD20F )
- {
- if ( (data & 3) == 0 )
- polym_pos = 0;
- }
- */
-}
-
-void Sap_Apu::end_frame( blip_time_t end_time )
-{
- if ( end_time > last_time )
- run_until( end_time );
-
- last_time -= end_time;
-}
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Sap_Apu.h b/plugins/gme/game-music-emu-0.5.5/gme/Sap_Apu.h
deleted file mode 100644
index a573499c..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Sap_Apu.h
+++ /dev/null
@@ -1,77 +0,0 @@
-// Atari POKEY sound chip emulator
-
-// Game_Music_Emu 0.5.5
-#ifndef SAP_APU_H
-#define SAP_APU_H
-
-#include "blargg_common.h"
-#include "Blip_Buffer.h"
-
-class Sap_Apu_Impl;
-
-class Sap_Apu {
-public:
- enum { osc_count = 4 };
- void osc_output( int index, Blip_Buffer* );
-
- void reset( Sap_Apu_Impl* );
-
- enum { start_addr = 0xD200 };
- enum { end_addr = 0xD209 };
- void write_data( blip_time_t, unsigned addr, int data );
-
- void end_frame( blip_time_t );
-
-public:
- Sap_Apu();
-private:
- struct osc_t
- {
- unsigned char regs [2];
- unsigned char phase;
- unsigned char invert;
- int last_amp;
- blip_time_t delay;
- blip_time_t period; // always recalculated before use; here for convenience
- Blip_Buffer* output;
- };
- osc_t oscs [osc_count];
- Sap_Apu_Impl* impl;
- blip_time_t last_time;
- int poly5_pos;
- int poly4_pos;
- int polym_pos;
- int control;
-
- void calc_periods();
- void run_until( blip_time_t );
-
- enum { poly4_len = (1L << 4) - 1 };
- enum { poly9_len = (1L << 9) - 1 };
- enum { poly17_len = (1L << 17) - 1 };
- friend class Sap_Apu_Impl;
-};
-
-// Common tables and Blip_Synth that can be shared among multiple Sap_Apu objects
-class Sap_Apu_Impl {
-public:
- Blip_Synth<blip_good_quality,1> synth;
-
- Sap_Apu_Impl();
- void volume( double d ) { synth.volume( 1.0 / Sap_Apu::osc_count / 30 * d ); }
-
-private:
- typedef unsigned char byte;
- byte poly4 [Sap_Apu::poly4_len / 8 + 1];
- byte poly9 [Sap_Apu::poly9_len / 8 + 1];
- byte poly17 [Sap_Apu::poly17_len / 8 + 1];
- friend class Sap_Apu;
-};
-
-inline void Sap_Apu::osc_output( int i, Blip_Buffer* b )
-{
- assert( (unsigned) i < osc_count );
- oscs [i].output = b;
-}
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Sap_Cpu.cpp b/plugins/gme/game-music-emu-0.5.5/gme/Sap_Cpu.cpp
deleted file mode 100644
index 35e1b511..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Sap_Cpu.cpp
+++ /dev/null
@@ -1,1011 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Sap_Cpu.h"
-
-#include <limits.h>
-#include "blargg_endian.h"
-
-//#include "nes_cpu_log.h"
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#define FLUSH_TIME() (void) (s.time = s_time)
-#define CACHE_TIME() (void) (s_time = s.time)
-
-#include "sap_cpu_io.h"
-
-#ifndef CPU_DONE
- #define CPU_DONE( cpu, time, result_out ) { result_out = -1; }
-#endif
-
-#include "blargg_source.h"
-
-int const st_n = 0x80;
-int const st_v = 0x40;
-int const st_r = 0x20;
-int const st_b = 0x10;
-int const st_d = 0x08;
-int const st_i = 0x04;
-int const st_z = 0x02;
-int const st_c = 0x01;
-
-void Sap_Cpu::reset( void* new_mem )
-{
- check( state == &state_ );
- state = &state_;
- mem = (uint8_t*) new_mem;
- r.status = st_i;
- r.sp = 0xFF;
- r.pc = 0;
- r.a = 0;
- r.x = 0;
- r.y = 0;
- state_.time = 0;
- state_.base = 0;
- irq_time_ = future_sap_time;
- end_time_ = future_sap_time;
-
- blargg_verify_byte_order();
-}
-
-#define TIME (s_time + s.base)
-#define READ( addr ) CPU_READ( this, (addr), TIME )
-#define WRITE( addr, data ) {CPU_WRITE( this, (addr), (data), TIME );}
-#define READ_LOW( addr ) (mem [int (addr)])
-#define WRITE_LOW( addr, data ) (void) (READ_LOW( addr ) = (data))
-#define READ_PROG( addr ) (READ_LOW( addr ))
-
-#define SET_SP( v ) (sp = ((v) + 1) | 0x100)
-#define GET_SP() ((sp - 1) & 0xFF)
-#define PUSH( v ) ((sp = (sp - 1) | 0x100), WRITE_LOW( sp, v ))
-
-// even on x86, using short and unsigned char was slower
-typedef int fint16;
-typedef unsigned fuint16;
-typedef unsigned fuint8;
-typedef blargg_long fint32;
-
-bool Sap_Cpu::run( sap_time_t end_time )
-{
- bool illegal_encountered = false;
- set_end_time( end_time );
- state_t s = this->state_;
- this->state = &s;
- fint32 s_time = s.time;
- uint8_t* const mem = this->mem; // cache
-
- // registers
- fuint16 pc = r.pc;
- fuint8 a = r.a;
- fuint8 x = r.x;
- fuint8 y = r.y;
- fuint16 sp;
- SET_SP( r.sp );
-
- // status flags
- #define IS_NEG (nz & 0x8080)
-
- #define CALC_STATUS( out ) do {\
- out = status & (st_v | st_d | st_i);\
- out |= ((nz >> 8) | nz) & st_n;\
- out |= c >> 8 & st_c;\
- if ( !(nz & 0xFF) ) out |= st_z;\
- } while ( 0 )
-
- #define SET_STATUS( in ) do {\
- status = in & (st_v | st_d | st_i);\
- nz = in << 8;\
- c = nz;\
- nz |= ~in & st_z;\
- } while ( 0 )
-
- fuint8 status;
- fuint16 c; // carry set if (c & 0x100) != 0
- fuint16 nz; // Z set if (nz & 0xFF) == 0, N set if (nz & 0x8080) != 0
- {
- fuint8 temp = r.status;
- SET_STATUS( temp );
- }
-
- goto loop;
-dec_clock_loop:
- s_time--;
-loop:
-
- #ifndef NDEBUG
- {
- sap_time_t correct = end_time_;
- if ( !(status & st_i) && correct > irq_time_ )
- correct = irq_time_;
- check( s.base == correct );
- }
- #endif
-
- check( (unsigned) GET_SP() < 0x100 );
- check( (unsigned) a < 0x100 );
- check( (unsigned) x < 0x100 );
- check( (unsigned) y < 0x100 );
-
- fuint8 opcode = mem [pc];
- pc++;
- uint8_t const* instr = mem + pc;
-
- static uint8_t const clock_table [256] =
- {// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0,6,2,8,3,3,5,5,3,2,2,2,4,4,6,6,// 0
- 3,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,// 1
- 6,6,2,8,3,3,5,5,4,2,2,2,4,4,6,6,// 2
- 3,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,// 3
- 6,6,2,8,3,3,5,5,3,2,2,2,3,4,6,6,// 4
- 3,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,// 5
- 6,6,2,8,3,3,5,5,4,2,2,2,5,4,6,6,// 6
- 3,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,// 7
- 2,6,2,6,3,3,3,3,2,2,2,2,4,4,4,4,// 8
- 3,6,2,6,4,4,4,4,2,5,2,5,5,5,5,5,// 9
- 2,6,2,6,3,3,3,3,2,2,2,2,4,4,4,4,// A
- 3,5,2,5,4,4,4,4,2,4,2,4,4,4,4,4,// B
- 2,6,2,8,3,3,5,5,2,2,2,2,4,4,6,6,// C
- 3,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,// D
- 2,6,2,8,3,3,5,5,2,2,2,2,4,4,6,6,// E
- 3,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7 // F
- }; // 0x00 was 7
-
- fuint16 data;
- data = clock_table [opcode];
- if ( (s_time += data) >= 0 )
- goto possibly_out_of_time;
-almost_out_of_time:
-
- data = *instr;
-
- #ifdef NES_CPU_LOG_H
- nes_cpu_log( "cpu_log", pc - 1, opcode, instr [0], instr [1] );
- #endif
-
- switch ( opcode )
- {
-possibly_out_of_time:
- if ( s_time < (int) data )
- goto almost_out_of_time;
- s_time -= data;
- goto out_of_time;
-
-// Macros
-
-#define GET_MSB() (instr [1])
-#define ADD_PAGE() (pc++, data += 0x100 * GET_MSB())
-#define GET_ADDR() GET_LE16( instr )
-
-#define NO_PAGE_CROSSING( lsb )
-#define HANDLE_PAGE_CROSSING( lsb ) s_time += (lsb) >> 8;
-
-#define INC_DEC_XY( reg, n ) reg = uint8_t (nz = reg + n); goto loop;
-
-#define IND_Y( cross, out ) {\
- fuint16 temp = READ_LOW( data ) + y;\
- out = temp + 0x100 * READ_LOW( uint8_t (data + 1) );\
- cross( temp );\
- }
-
-#define IND_X( out ) {\
- fuint16 temp = data + x;\
- out = 0x100 * READ_LOW( uint8_t (temp + 1) ) + READ_LOW( uint8_t (temp) );\
- }
-
-#define ARITH_ADDR_MODES( op )\
-case op - 0x04: /* (ind,x) */\
- IND_X( data )\
- goto ptr##op;\
-case op + 0x0C: /* (ind),y */\
- IND_Y( HANDLE_PAGE_CROSSING, data )\
- goto ptr##op;\
-case op + 0x10: /* zp,X */\
- data = uint8_t (data + x);\
-case op + 0x00: /* zp */\
- data = READ_LOW( data );\
- goto imm##op;\
-case op + 0x14: /* abs,Y */\
- data += y;\
- goto ind##op;\
-case op + 0x18: /* abs,X */\
- data += x;\
-ind##op:\
- HANDLE_PAGE_CROSSING( data );\
-case op + 0x08: /* abs */\
- ADD_PAGE();\
-ptr##op:\
- FLUSH_TIME();\
- data = READ( data );\
- CACHE_TIME();\
-case op + 0x04: /* imm */\
-imm##op:
-
-// TODO: more efficient way to handle negative branch that wraps PC around
-#define BRANCH( cond )\
-{\
- fint16 offset = (BOOST::int8_t) data;\
- fuint16 extra_clock = (++pc & 0xFF) + offset;\
- if ( !(cond) ) goto dec_clock_loop;\
- pc += offset;\
- s_time += extra_clock >> 8 & 1;\
- goto loop;\
-}
-
-// Often-Used
-
- case 0xB5: // LDA zp,x
- a = nz = READ_LOW( uint8_t (data + x) );
- pc++;
- goto loop;
-
- case 0xA5: // LDA zp
- a = nz = READ_LOW( data );
- pc++;
- goto loop;
-
- case 0xD0: // BNE
- BRANCH( (uint8_t) nz );
-
- case 0x20: { // JSR
- fuint16 temp = pc + 1;
- pc = GET_ADDR();
- WRITE_LOW( 0x100 | (sp - 1), temp >> 8 );
- sp = (sp - 2) | 0x100;
- WRITE_LOW( sp, temp );
- goto loop;
- }
-
- case 0x4C: // JMP abs
- pc = GET_ADDR();
- goto loop;
-
- case 0xE8: // INX
- INC_DEC_XY( x, 1 )
-
- case 0x10: // BPL
- BRANCH( !IS_NEG )
-
- ARITH_ADDR_MODES( 0xC5 ) // CMP
- nz = a - data;
- pc++;
- c = ~nz;
- nz &= 0xFF;
- goto loop;
-
- case 0x30: // BMI
- BRANCH( IS_NEG )
-
- case 0xF0: // BEQ
- BRANCH( !(uint8_t) nz );
-
- case 0x95: // STA zp,x
- data = uint8_t (data + x);
- case 0x85: // STA zp
- pc++;
- WRITE_LOW( data, a );
- goto loop;
-
- case 0xC8: // INY
- INC_DEC_XY( y, 1 )
-
- case 0xA8: // TAY
- y = a;
- nz = a;
- goto loop;
-
- case 0x98: // TYA
- a = y;
- nz = y;
- goto loop;
-
- case 0xAD:{// LDA abs
- unsigned addr = GET_ADDR();
- pc += 2;
- nz = READ( addr );
- a = nz;
- goto loop;
- }
-
- case 0x60: // RTS
- pc = 1 + READ_LOW( sp );
- pc += 0x100 * READ_LOW( 0x100 | (sp - 0xFF) );
- sp = (sp - 0xFE) | 0x100;
- goto loop;
-
- {
- fuint16 addr;
-
- case 0x99: // STA abs,Y
- addr = y + GET_ADDR();
- pc += 2;
- if ( addr <= 0x7FF )
- {
- WRITE_LOW( addr, a );
- goto loop;
- }
- goto sta_ptr;
-
- case 0x8D: // STA abs
- addr = GET_ADDR();
- pc += 2;
- if ( addr <= 0x7FF )
- {
- WRITE_LOW( addr, a );
- goto loop;
- }
- goto sta_ptr;
-
- case 0x9D: // STA abs,X (slightly more common than STA abs)
- addr = x + GET_ADDR();
- pc += 2;
- if ( addr <= 0x7FF )
- {
- WRITE_LOW( addr, a );
- goto loop;
- }
- sta_ptr:
- FLUSH_TIME();
- WRITE( addr, a );
- CACHE_TIME();
- goto loop;
-
- case 0x91: // STA (ind),Y
- IND_Y( NO_PAGE_CROSSING, addr )
- pc++;
- goto sta_ptr;
-
- case 0x81: // STA (ind,X)
- IND_X( addr )
- pc++;
- goto sta_ptr;
-
- }
-
- case 0xA9: // LDA #imm
- pc++;
- a = data;
- nz = data;
- goto loop;
-
- // common read instructions
- {
- fuint16 addr;
-
- case 0xA1: // LDA (ind,X)
- IND_X( addr )
- pc++;
- goto a_nz_read_addr;
-
- case 0xB1:// LDA (ind),Y
- addr = READ_LOW( data ) + y;
- HANDLE_PAGE_CROSSING( addr );
- addr += 0x100 * READ_LOW( (uint8_t) (data + 1) );
- pc++;
- a = nz = READ_PROG( addr );
- if ( (addr ^ 0x8000) <= 0x9FFF )
- goto loop;
- goto a_nz_read_addr;
-
- case 0xB9: // LDA abs,Y
- HANDLE_PAGE_CROSSING( data + y );
- addr = GET_ADDR() + y;
- pc += 2;
- a = nz = READ_PROG( addr );
- if ( (addr ^ 0x8000) <= 0x9FFF )
- goto loop;
- goto a_nz_read_addr;
-
- case 0xBD: // LDA abs,X
- HANDLE_PAGE_CROSSING( data + x );
- addr = GET_ADDR() + x;
- pc += 2;
- a = nz = READ_PROG( addr );
- if ( (addr ^ 0x8000) <= 0x9FFF )
- goto loop;
- a_nz_read_addr:
- FLUSH_TIME();
- a = nz = READ( addr );
- CACHE_TIME();
- goto loop;
-
- }
-
-// Branch
-
- case 0x50: // BVC
- BRANCH( !(status & st_v) )
-
- case 0x70: // BVS
- BRANCH( status & st_v )
-
- case 0xB0: // BCS
- BRANCH( c & 0x100 )
-
- case 0x90: // BCC
- BRANCH( !(c & 0x100) )
-
-// Load/store
-
- case 0x94: // STY zp,x
- data = uint8_t (data + x);
- case 0x84: // STY zp
- pc++;
- WRITE_LOW( data, y );
- goto loop;
-
- case 0x96: // STX zp,y
- data = uint8_t (data + y);
- case 0x86: // STX zp
- pc++;
- WRITE_LOW( data, x );
- goto loop;
-
- case 0xB6: // LDX zp,y
- data = uint8_t (data + y);
- case 0xA6: // LDX zp
- data = READ_LOW( data );
- case 0xA2: // LDX #imm
- pc++;
- x = data;
- nz = data;
- goto loop;
-
- case 0xB4: // LDY zp,x
- data = uint8_t (data + x);
- case 0xA4: // LDY zp
- data = READ_LOW( data );
- case 0xA0: // LDY #imm
- pc++;
- y = data;
- nz = data;
- goto loop;
-
- case 0xBC: // LDY abs,X
- data += x;
- HANDLE_PAGE_CROSSING( data );
- case 0xAC:{// LDY abs
- unsigned addr = data + 0x100 * GET_MSB();
- pc += 2;
- FLUSH_TIME();
- y = nz = READ( addr );
- CACHE_TIME();
- goto loop;
- }
-
- case 0xBE: // LDX abs,y
- data += y;
- HANDLE_PAGE_CROSSING( data );
- case 0xAE:{// LDX abs
- unsigned addr = data + 0x100 * GET_MSB();
- pc += 2;
- FLUSH_TIME();
- x = nz = READ( addr );
- CACHE_TIME();
- goto loop;
- }
-
- {
- fuint8 temp;
- case 0x8C: // STY abs
- temp = y;
- goto store_abs;
-
- case 0x8E: // STX abs
- temp = x;
- store_abs:
- unsigned addr = GET_ADDR();
- pc += 2;
- if ( addr <= 0x7FF )
- {
- WRITE_LOW( addr, temp );
- goto loop;
- }
- FLUSH_TIME();
- WRITE( addr, temp );
- CACHE_TIME();
- goto loop;
- }
-
-// Compare
-
- case 0xEC:{// CPX abs
- unsigned addr = GET_ADDR();
- pc++;
- FLUSH_TIME();
- data = READ( addr );
- CACHE_TIME();
- goto cpx_data;
- }
-
- case 0xE4: // CPX zp
- data = READ_LOW( data );
- case 0xE0: // CPX #imm
- cpx_data:
- nz = x - data;
- pc++;
- c = ~nz;
- nz &= 0xFF;
- goto loop;
-
- case 0xCC:{// CPY abs
- unsigned addr = GET_ADDR();
- pc++;
- FLUSH_TIME();
- data = READ( addr );
- CACHE_TIME();
- goto cpy_data;
- }
-
- case 0xC4: // CPY zp
- data = READ_LOW( data );
- case 0xC0: // CPY #imm
- cpy_data:
- nz = y - data;
- pc++;
- c = ~nz;
- nz &= 0xFF;
- goto loop;
-
-// Logical
-
- ARITH_ADDR_MODES( 0x25 ) // AND
- nz = (a &= data);
- pc++;
- goto loop;
-
- ARITH_ADDR_MODES( 0x45 ) // EOR
- nz = (a ^= data);
- pc++;
- goto loop;
-
- ARITH_ADDR_MODES( 0x05 ) // ORA
- nz = (a |= data);
- pc++;
- goto loop;
-
- case 0x2C:{// BIT abs
- unsigned addr = GET_ADDR();
- pc += 2;
- status &= ~st_v;
- nz = READ( addr );
- status |= nz & st_v;
- if ( a & nz )
- goto loop;
- nz <<= 8; // result must be zero, even if N bit is set
- goto loop;
- }
-
- case 0x24: // BIT zp
- nz = READ_LOW( data );
- pc++;
- status &= ~st_v;
- status |= nz & st_v;
- if ( a & nz )
- goto loop;
- nz <<= 8; // result must be zero, even if N bit is set
- goto loop;
-
-// Add/subtract
-
- ARITH_ADDR_MODES( 0xE5 ) // SBC
- case 0xEB: // unofficial equivalent
- data ^= 0xFF;
- goto adc_imm;
-
- ARITH_ADDR_MODES( 0x65 ) // ADC
- adc_imm: {
- check( !(status & st_d) );
- fint16 carry = c >> 8 & 1;
- fint16 ov = (a ^ 0x80) + carry + (BOOST::int8_t) data; // sign-extend
- status &= ~st_v;
- status |= ov >> 2 & 0x40;
- c = nz = a + data + carry;
- pc++;
- a = (uint8_t) nz;
- goto loop;
- }
-
-// Shift/rotate
-
- case 0x4A: // LSR A
- c = 0;
- case 0x6A: // ROR A
- nz = c >> 1 & 0x80;
- c = a << 8;
- nz |= a >> 1;
- a = nz;
- goto loop;
-
- case 0x0A: // ASL A
- nz = a << 1;
- c = nz;
- a = (uint8_t) nz;
- goto loop;
-
- case 0x2A: { // ROL A
- nz = a << 1;
- fint16 temp = c >> 8 & 1;
- c = nz;
- nz |= temp;
- a = (uint8_t) nz;
- goto loop;
- }
-
- case 0x5E: // LSR abs,X
- data += x;
- case 0x4E: // LSR abs
- c = 0;
- case 0x6E: // ROR abs
- ror_abs: {
- ADD_PAGE();
- FLUSH_TIME();
- int temp = READ( data );
- nz = (c >> 1 & 0x80) | (temp >> 1);
- c = temp << 8;
- goto rotate_common;
- }
-
- case 0x3E: // ROL abs,X
- data += x;
- goto rol_abs;
-
- case 0x1E: // ASL abs,X
- data += x;
- case 0x0E: // ASL abs
- c = 0;
- case 0x2E: // ROL abs
- rol_abs:
- ADD_PAGE();
- nz = c >> 8 & 1;
- FLUSH_TIME();
- nz |= (c = READ( data ) << 1);
- rotate_common:
- pc++;
- WRITE( data, (uint8_t) nz );
- CACHE_TIME();
- goto loop;
-
- case 0x7E: // ROR abs,X
- data += x;
- goto ror_abs;
-
- case 0x76: // ROR zp,x
- data = uint8_t (data + x);
- goto ror_zp;
-
- case 0x56: // LSR zp,x
- data = uint8_t (data + x);
- case 0x46: // LSR zp
- c = 0;
- case 0x66: // ROR zp
- ror_zp: {
- int temp = READ_LOW( data );
- nz = (c >> 1 & 0x80) | (temp >> 1);
- c = temp << 8;
- goto write_nz_zp;
- }
-
- case 0x36: // ROL zp,x
- data = uint8_t (data + x);
- goto rol_zp;
-
- case 0x16: // ASL zp,x
- data = uint8_t (data + x);
- case 0x06: // ASL zp
- c = 0;
- case 0x26: // ROL zp
- rol_zp:
- nz = c >> 8 & 1;
- nz |= (c = READ_LOW( data ) << 1);
- goto write_nz_zp;
-
-// Increment/decrement
-
- case 0xCA: // DEX
- INC_DEC_XY( x, -1 )
-
- case 0x88: // DEY
- INC_DEC_XY( y, -1 )
-
- case 0xF6: // INC zp,x
- data = uint8_t (data + x);
- case 0xE6: // INC zp
- nz = 1;
- goto add_nz_zp;
-
- case 0xD6: // DEC zp,x
- data = uint8_t (data + x);
- case 0xC6: // DEC zp
- nz = (unsigned) -1;
- add_nz_zp:
- nz += READ_LOW( data );
- write_nz_zp:
- pc++;
- WRITE_LOW( data, nz );
- goto loop;
-
- case 0xFE: // INC abs,x
- data = x + GET_ADDR();
- goto inc_ptr;
-
- case 0xEE: // INC abs
- data = GET_ADDR();
- inc_ptr:
- nz = 1;
- goto inc_common;
-
- case 0xDE: // DEC abs,x
- data = x + GET_ADDR();
- goto dec_ptr;
-
- case 0xCE: // DEC abs
- data = GET_ADDR();
- dec_ptr:
- nz = (unsigned) -1;
- inc_common:
- FLUSH_TIME();
- nz += READ( data );
- pc += 2;
- WRITE( data, (uint8_t) nz );
- CACHE_TIME();
- goto loop;
-
-// Transfer
-
- case 0xAA: // TAX
- x = a;
- nz = a;
- goto loop;
-
- case 0x8A: // TXA
- a = x;
- nz = x;
- goto loop;
-
- case 0x9A: // TXS
- SET_SP( x ); // verified (no flag change)
- goto loop;
-
- case 0xBA: // TSX
- x = nz = GET_SP();
- goto loop;
-
-// Stack
-
- case 0x48: // PHA
- PUSH( a ); // verified
- goto loop;
-
- case 0x68: // PLA
- a = nz = READ_LOW( sp );
- sp = (sp - 0xFF) | 0x100;
- goto loop;
-
- case 0x40:{// RTI
- fuint8 temp = READ_LOW( sp );
- pc = READ_LOW( 0x100 | (sp - 0xFF) );
- pc |= READ_LOW( 0x100 | (sp - 0xFE) ) * 0x100;
- sp = (sp - 0xFD) | 0x100;
- data = status;
- SET_STATUS( temp );
- this->r.status = status; // update externally-visible I flag
- if ( (data ^ status) & st_i )
- {
- sap_time_t new_time = end_time_;
- if ( !(status & st_i) && new_time > irq_time_ )
- new_time = irq_time_;
- blargg_long delta = s.base - new_time;
- s.base = new_time;
- s_time += delta;
- }
- goto loop;
- }
-
- case 0x28:{// PLP
- fuint8 temp = READ_LOW( sp );
- sp = (sp - 0xFF) | 0x100;
- fuint8 changed = status ^ temp;
- SET_STATUS( temp );
- if ( !(changed & st_i) )
- goto loop; // I flag didn't change
- if ( status & st_i )
- goto handle_sei;
- goto handle_cli;
- }
-
- case 0x08: { // PHP
- fuint8 temp;
- CALC_STATUS( temp );
- PUSH( temp | (st_b | st_r) );
- goto loop;
- }
-
- case 0x6C:{// JMP (ind)
- data = GET_ADDR();
- pc = READ_PROG( data );
- data = (data & 0xFF00) | ((data + 1) & 0xFF);
- pc |= 0x100 * READ_PROG( data );
- goto loop;
- }
-
- case 0x00: // BRK
- goto handle_brk;
-
-// Flags
-
- case 0x38: // SEC
- c = (unsigned) ~0;
- goto loop;
-
- case 0x18: // CLC
- c = 0;
- goto loop;
-
- case 0xB8: // CLV
- status &= ~st_v;
- goto loop;
-
- case 0xD8: // CLD
- status &= ~st_d;
- goto loop;
-
- case 0xF8: // SED
- status |= st_d;
- goto loop;
-
- case 0x58: // CLI
- if ( !(status & st_i) )
- goto loop;
- status &= ~st_i;
- handle_cli: {
- this->r.status = status; // update externally-visible I flag
- blargg_long delta = s.base - irq_time_;
- if ( delta <= 0 )
- {
- if ( TIME < irq_time_ )
- goto loop;
- goto delayed_cli;
- }
- s.base = irq_time_;
- s_time += delta;
- if ( s_time < 0 )
- goto loop;
-
- if ( delta >= s_time + 1 )
- {
- // delayed irq until after next instruction
- s.base += s_time + 1;
- s_time = -1;
- irq_time_ = s.base; // TODO: remove, as only to satisfy debug check in loop
- goto loop;
- }
- delayed_cli:
- debug_printf( "Delayed CLI not emulated\n" );
- goto loop;
- }
-
- case 0x78: // SEI
- if ( status & st_i )
- goto loop;
- status |= st_i;
- handle_sei: {
- this->r.status = status; // update externally-visible I flag
- blargg_long delta = s.base - end_time_;
- s.base = end_time_;
- s_time += delta;
- if ( s_time < 0 )
- goto loop;
- debug_printf( "Delayed SEI not emulated\n" );
- goto loop;
- }
-
-// Unofficial
-
- // SKW - Skip word
- case 0x1C: case 0x3C: case 0x5C: case 0x7C: case 0xDC: case 0xFC:
- HANDLE_PAGE_CROSSING( data + x );
- case 0x0C:
- pc++;
- // SKB - Skip byte
- case 0x74: case 0x04: case 0x14: case 0x34: case 0x44: case 0x54: case 0x64:
- case 0x80: case 0x82: case 0x89: case 0xC2: case 0xD4: case 0xE2: case 0xF4:
- pc++;
- goto loop;
-
- // NOP
- case 0xEA: case 0x1A: case 0x3A: case 0x5A: case 0x7A: case 0xDA: case 0xFA:
- goto loop;
-
-// Unimplemented
-
- // halt
- //case 0x02: case 0x12: case 0x22: case 0x32: case 0x42: case 0x52:
- //case 0x62: case 0x72: case 0x92: case 0xB2: case 0xD2: case 0xF2:
-
- default:
- assert( (unsigned) opcode <= 0xFF );
- illegal_encountered = true;
- pc--;
- goto stop;
- }
- assert( false );
-
- int result_;
-handle_brk:
- if ( (pc - 1) >= idle_addr )
- goto idle_done;
- pc++;
- result_ = 4;
- debug_printf( "BRK executed\n" );
-
-interrupt:
- {
- s_time += 7;
-
- WRITE_LOW( 0x100 | (sp - 1), pc >> 8 );
- WRITE_LOW( 0x100 | (sp - 2), pc );
- pc = GET_LE16( &READ_PROG( 0xFFFA ) + result_ );
-
- sp = (sp - 3) | 0x100;
- fuint8 temp;
- CALC_STATUS( temp );
- temp |= st_r;
- if ( result_ )
- temp |= st_b; // TODO: incorrectly sets B flag for IRQ
- WRITE_LOW( sp, temp );
-
- status &= ~st_d;
- status |= st_i;
- this->r.status = status; // update externally-visible I flag
-
- blargg_long delta = s.base - end_time_;
- s.base = end_time_;
- s_time += delta;
- goto loop;
- }
-
-idle_done:
- //s_time = 0;
- pc--;
- goto stop;
-out_of_time:
- pc--;
- FLUSH_TIME();
- CPU_DONE( this, TIME, result_ );
- CACHE_TIME();
- if ( result_ >= 0 )
- goto interrupt;
- if ( s_time < 0 )
- goto loop;
-
-stop:
-
- s.time = s_time;
-
- r.pc = pc;
- r.sp = GET_SP();
- r.a = a;
- r.x = x;
- r.y = y;
-
- {
- fuint8 temp;
- CALC_STATUS( temp );
- r.status = temp;
- }
-
- this->state_ = s;
- this->state = &this->state_;
-
- return illegal_encountered;
-}
-
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Sap_Cpu.h b/plugins/gme/game-music-emu-0.5.5/gme/Sap_Cpu.h
deleted file mode 100644
index bde219f6..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Sap_Cpu.h
+++ /dev/null
@@ -1,83 +0,0 @@
-// Atari 6502 CPU emulator
-
-// Game_Music_Emu 0.5.5
-#ifndef SAP_CPU_H
-#define SAP_CPU_H
-
-#include "blargg_common.h"
-
-typedef blargg_long sap_time_t; // clock cycle count
-typedef unsigned sap_addr_t; // 16-bit address
-enum { future_sap_time = INT_MAX / 2 + 1 };
-
-class Sap_Cpu {
-public:
- typedef BOOST::uint8_t uint8_t;
-
- // Clear all registers and keep pointer to 64K memory passed in
- void reset( void* mem_64k );
-
- // Run until specified time is reached. Returns true if suspicious/unsupported
- // instruction was encountered at any point during run.
- bool run( sap_time_t end_time );
-
- // Registers are not updated until run() returns (except I flag in status)
- struct registers_t {
- BOOST::uint16_t pc;
- BOOST::uint8_t a;
- BOOST::uint8_t x;
- BOOST::uint8_t y;
- BOOST::uint8_t status;
- BOOST::uint8_t sp;
- };
- registers_t r;
-
- enum { idle_addr = 0xFEFF };
-
- // Time of beginning of next instruction to be executed
- sap_time_t time() const { return state->time + state->base; }
- void set_time( sap_time_t t ) { state->time = t - state->base; }
- void adjust_time( int delta ) { state->time += delta; }
-
- sap_time_t irq_time() const { return irq_time_; }
- void set_irq_time( sap_time_t );
-
- sap_time_t end_time() const { return end_time_; }
- void set_end_time( sap_time_t );
-
-public:
- Sap_Cpu() { state = &state_; }
- enum { irq_inhibit = 0x04 };
-private:
- struct state_t {
- sap_time_t base;
- sap_time_t time;
- };
- state_t* state; // points to state_ or a local copy within run()
- state_t state_;
- sap_time_t irq_time_;
- sap_time_t end_time_;
- uint8_t* mem;
-
- inline sap_time_t update_end_time( sap_time_t end, sap_time_t irq );
-};
-
-inline sap_time_t Sap_Cpu::update_end_time( sap_time_t t, sap_time_t irq )
-{
- if ( irq < t && !(r.status & irq_inhibit) ) t = irq;
- sap_time_t delta = state->base - t;
- state->base = t;
- return delta;
-}
-
-inline void Sap_Cpu::set_irq_time( sap_time_t t )
-{
- state->time += update_end_time( end_time_, (irq_time_ = t) );
-}
-
-inline void Sap_Cpu::set_end_time( sap_time_t t )
-{
- state->time += update_end_time( (end_time_ = t), irq_time_ );
-}
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Sap_Emu.cpp b/plugins/gme/game-music-emu-0.5.5/gme/Sap_Emu.cpp
deleted file mode 100644
index aa4ce948..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Sap_Emu.cpp
+++ /dev/null
@@ -1,444 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Sap_Emu.h"
-
-#include "blargg_endian.h"
-#include <string.h>
-
-/* Copyright (C) 2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-long const base_scanline_period = 114;
-
-Sap_Emu::Sap_Emu()
-{
- set_type( gme_sap_type );
-
- static const char* const names [Sap_Apu::osc_count * 2] = {
- "Wave 1", "Wave 2", "Wave 3", "Wave 4",
- "Wave 5", "Wave 6", "Wave 7", "Wave 8",
- };
- set_voice_names( names );
-
- static int const types [Sap_Apu::osc_count * 2] = {
- wave_type | 1, wave_type | 2, wave_type | 3, wave_type | 0,
- wave_type | 5, wave_type | 6, wave_type | 7, wave_type | 4,
- };
- set_voice_types( types );
- set_silence_lookahead( 6 );
-}
-
-Sap_Emu::~Sap_Emu() { }
-
-// Track info
-
-// Returns 16 or greater if not hex
-inline int from_hex_char( int h )
-{
- h -= 0x30;
- if ( (unsigned) h > 9 )
- h = ((h - 0x11) & 0xDF) + 10;
- return h;
-}
-
-static long from_hex( byte const* in )
-{
- unsigned result = 0;
- for ( int n = 4; n--; )
- {
- int h = from_hex_char( *in++ );
- if ( h > 15 )
- return -1;
- result = result * 0x10 + h;
- }
- return result;
-}
-
-static int from_dec( byte const* in, byte const* end )
-{
- if ( in >= end )
- return -1;
-
- int n = 0;
- while ( in < end )
- {
- int dig = *in++ - '0';
- if ( (unsigned) dig > 9 )
- return -1;
- n = n * 10 + dig;
- }
- return n;
-}
-
-static void parse_string( byte const* in, byte const* end, int len, char* out )
-{
- byte const* start = in;
- if ( *in++ == '\"' )
- {
- start++;
- while ( in < end && *in != '\"' )
- in++;
- }
- else
- {
- in = end;
- }
- len = min( len - 1, int (in - start) );
- out [len] = 0;
- memcpy( out, start, len );
-}
-
-static blargg_err_t parse_info( byte const* in, long size, Sap_Emu::info_t* out )
-{
- out->track_count = 1;
- out->author [0] = 0;
- out->name [0] = 0;
- out->copyright [0] = 0;
-
- if ( size < 16 || memcmp( in, "SAP\x0D\x0A", 5 ) )
- return gme_wrong_file_type;
-
- byte const* file_end = in + size - 5;
- in += 5;
- while ( in < file_end && (in [0] != 0xFF || in [1] != 0xFF) )
- {
- byte const* line_end = in;
- while ( line_end < file_end && *line_end != 0x0D )
- line_end++;
-
- char const* tag = (char const*) in;
- while ( in < line_end && *in > ' ' )
- in++;
- int tag_len = (char const*) in - tag;
-
- while ( in < line_end && *in <= ' ' ) in++;
-
- if ( tag_len <= 0 )
- {
- // skip line
- }
- else if ( !strncmp( "INIT", tag, tag_len ) )
- {
- out->init_addr = from_hex( in );
- if ( (unsigned long) out->init_addr > 0xFFFF )
- return "Invalid init address";
- }
- else if ( !strncmp( "PLAYER", tag, tag_len ) )
- {
- out->play_addr = from_hex( in );
- if ( (unsigned long) out->play_addr > 0xFFFF )
- return "Invalid play address";
- }
- else if ( !strncmp( "MUSIC", tag, tag_len ) )
- {
- out->music_addr = from_hex( in );
- if ( (unsigned long) out->music_addr > 0xFFFF )
- return "Invalid music address";
- }
- else if ( !strncmp( "SONGS", tag, tag_len ) )
- {
- out->track_count = from_dec( in, line_end );
- if ( out->track_count <= 0 )
- return "Invalid track count";
- }
- else if ( !strncmp( "TYPE", tag, tag_len ) )
- {
- switch ( out->type = *in )
- {
- case 'C':
- case 'B':
- break;
-
- case 'D':
- return "Digimusic not supported";
-
- default:
- return "Unsupported player type";
- }
- }
- else if ( !strncmp( "STEREO", tag, tag_len ) )
- {
- out->stereo = true;
- }
- else if ( !strncmp( "FASTPLAY", tag, tag_len ) )
- {
- out->fastplay = from_dec( in, line_end );
- if ( out->fastplay <= 0 )
- return "Invalid fastplay value";
- }
- else if ( !strncmp( "AUTHOR", tag, tag_len ) )
- {
- parse_string( in, line_end, sizeof out->author, out->author );
- }
- else if ( !strncmp( "NAME", tag, tag_len ) )
- {
- parse_string( in, line_end, sizeof out->name, out->name );
- }
- else if ( !strncmp( "DATE", tag, tag_len ) )
- {
- parse_string( in, line_end, sizeof out->copyright, out->copyright );
- }
-
- in = line_end + 2;
- }
-
- if ( in [0] != 0xFF || in [1] != 0xFF )
- return "ROM data missing";
- out->rom_data = in + 2;
-
- return 0;
-}
-
-static void copy_sap_fields( Sap_Emu::info_t const& in, track_info_t* out )
-{
- Gme_File::copy_field_( out->game, in.name );
- Gme_File::copy_field_( out->author, in.author );
- Gme_File::copy_field_( out->copyright, in.copyright );
-}
-
-blargg_err_t Sap_Emu::track_info_( track_info_t* out, int ) const
-{
- copy_sap_fields( info, out );
- return 0;
-}
-
-struct Sap_File : Gme_Info_
-{
- Sap_Emu::info_t info;
-
- Sap_File() { set_type( gme_sap_type ); }
-
- blargg_err_t load_mem_( byte const* begin, long size )
- {
- RETURN_ERR( parse_info( begin, size, &info ) );
- set_track_count( info.track_count );
- return 0;
- }
-
- blargg_err_t track_info_( track_info_t* out, int ) const
- {
- copy_sap_fields( info, out );
- return 0;
- }
-};
-
-static Music_Emu* new_sap_emu () { return BLARGG_NEW Sap_Emu ; }
-static Music_Emu* new_sap_file() { return BLARGG_NEW Sap_File; }
-
-static gme_type_t_ const gme_sap_type_ = { "Atari XL", 0, &new_sap_emu, &new_sap_file, "SAP", 1 };
-gme_type_t const gme_sap_type = &gme_sap_type_;
-
-
-// Setup
-
-blargg_err_t Sap_Emu::load_mem_( byte const* in, long size )
-{
- file_end = in + size;
-
- info.warning = 0;
- info.type = 'B';
- info.stereo = false;
- info.init_addr = -1;
- info.play_addr = -1;
- info.music_addr = -1;
- info.fastplay = 312;
- RETURN_ERR( parse_info( in, size, &info ) );
-
- set_warning( info.warning );
- set_track_count( info.track_count );
- set_voice_count( Sap_Apu::osc_count << info.stereo );
- apu_impl.volume( gain() );
-
- return setup_buffer( 1773447 );
-}
-
-void Sap_Emu::update_eq( blip_eq_t const& eq )
-{
- apu_impl.synth.treble_eq( eq );
-}
-
-void Sap_Emu::set_voice( int i, Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right )
-{
- int i2 = i - Sap_Apu::osc_count;
- if ( i2 >= 0 )
- apu2.osc_output( i2, right );
- else
- apu.osc_output( i, (info.stereo ? left : center) );
-}
-
-// Emulation
-
-void Sap_Emu::set_tempo_( double t )
-{
- scanline_period = sap_time_t (base_scanline_period / t);
-}
-
-inline sap_time_t Sap_Emu::play_period() const { return info.fastplay * scanline_period; }
-
-void Sap_Emu::cpu_jsr( sap_addr_t addr )
-{
- check( r.sp >= 0xFE ); // catch anything trying to leave data on stack
- r.pc = addr;
- int high_byte = (idle_addr - 1) >> 8;
- if ( r.sp == 0xFE && mem.ram [0x1FF] == high_byte )
- r.sp = 0xFF; // pop extra byte off
- mem.ram [0x100 + r.sp--] = high_byte; // some routines use RTI to return
- mem.ram [0x100 + r.sp--] = high_byte;
- mem.ram [0x100 + r.sp--] = (idle_addr - 1) & 0xFF;
-}
-
-void Sap_Emu::run_routine( sap_addr_t addr )
-{
- cpu_jsr( addr );
- cpu::run( 312 * base_scanline_period * 60 );
- check( r.pc == idle_addr );
-}
-
-inline void Sap_Emu::call_init( int track )
-{
- switch ( info.type )
- {
- case 'B':
- r.a = track;
- run_routine( info.init_addr );
- break;
-
- case 'C':
- r.a = 0x70;
- r.x = info.music_addr&0xFF;
- r.y = info.music_addr >> 8;
- run_routine( info.play_addr + 3 );
- r.a = 0;
- r.x = track;
- run_routine( info.play_addr + 3 );
- break;
- }
-}
-
-blargg_err_t Sap_Emu::start_track_( int track )
-{
- RETURN_ERR( Classic_Emu::start_track_( track ) );
-
- memset( &mem, 0, sizeof mem );
-
- byte const* in = info.rom_data;
- while ( file_end - in >= 5 )
- {
- unsigned start = get_le16( in );
- unsigned end = get_le16( in + 2 );
- //debug_printf( "Block $%04X-$%04X\n", start, end );
- in += 4;
- if ( end < start )
- {
- set_warning( "Invalid file data block" );
- break;
- }
- long len = end - start + 1;
- if ( len > file_end - in )
- {
- set_warning( "Invalid file data block" );
- break;
- }
-
- memcpy( mem.ram + start, in, len );
- in += len;
- if ( file_end - in >= 2 && in [0] == 0xFF && in [1] == 0xFF )
- in += 2;
- }
-
- apu.reset( &apu_impl );
- apu2.reset( &apu_impl );
- cpu::reset( mem.ram );
- time_mask = 0; // disables sound during init
- call_init( track );
- time_mask = -1;
-
- next_play = play_period();
-
- return 0;
-}
-
-// Emulation
-
-// see sap_cpu_io.h for read/write functions
-
-void Sap_Emu::cpu_write_( sap_addr_t addr, int data )
-{
- if ( (addr ^ Sap_Apu::start_addr) <= (Sap_Apu::end_addr - Sap_Apu::start_addr) )
- {
- GME_APU_HOOK( this, addr - Sap_Apu::start_addr, data );
- apu.write_data( time() & time_mask, addr, data );
- return;
- }
-
- if ( (addr ^ (Sap_Apu::start_addr + 0x10)) <= (Sap_Apu::end_addr - Sap_Apu::start_addr) &&
- info.stereo )
- {
- GME_APU_HOOK( this, addr - 0x10 - Sap_Apu::start_addr + 10, data );
- apu2.write_data( time() & time_mask, addr ^ 0x10, data );
- return;
- }
-
- if ( (addr & ~0x0010) != 0xD20F || data != 0x03 )
- debug_printf( "Unmapped write $%04X <- $%02X\n", addr, data );
-}
-
-inline void Sap_Emu::call_play()
-{
- switch ( info.type )
- {
- case 'B':
- cpu_jsr( info.play_addr );
- break;
-
- case 'C':
- cpu_jsr( info.play_addr + 6 );
- break;
- }
-}
-
-blargg_err_t Sap_Emu::run_clocks( blip_time_t& duration, int )
-{
- set_time( 0 );
- while ( time() < duration )
- {
- if ( cpu::run( duration ) || r.pc > idle_addr )
- return "Emulation error (illegal instruction)";
-
- if ( r.pc == idle_addr )
- {
- if ( next_play <= duration )
- {
- set_time( next_play );
- next_play += play_period();
- call_play();
- GME_FRAME_HOOK( this );
- }
- else
- {
- set_time( duration );
- }
- }
- }
-
- duration = time();
- next_play -= duration;
- check( next_play >= 0 );
- if ( next_play < 0 )
- next_play = 0;
- apu.end_frame( duration );
- if ( info.stereo )
- apu2.end_frame( duration );
-
- return 0;
-}
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Sap_Emu.h b/plugins/gme/game-music-emu-0.5.5/gme/Sap_Emu.h
deleted file mode 100644
index 21879447..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Sap_Emu.h
+++ /dev/null
@@ -1,69 +0,0 @@
-// Atari XL/XE SAP music file emulator
-
-// Game_Music_Emu 0.5.5
-#ifndef SAP_EMU_H
-#define SAP_EMU_H
-
-#include "Classic_Emu.h"
-#include "Sap_Apu.h"
-#include "Sap_Cpu.h"
-
-class Sap_Emu : private Sap_Cpu, public Classic_Emu {
- typedef Sap_Cpu cpu;
-public:
- static gme_type_t static_type() { return gme_sap_type; }
-public:
- Sap_Emu();
- ~Sap_Emu();
- struct info_t {
- byte const* rom_data;
- const char* warning;
- long init_addr;
- long play_addr;
- long music_addr;
- int type;
- int track_count;
- int fastplay;
- bool stereo;
- char author [256];
- char name [256];
- char copyright [ 32];
- };
-protected:
- blargg_err_t track_info_( track_info_t*, int track ) const;
- blargg_err_t load_mem_( byte const*, long );
- blargg_err_t start_track_( int );
- blargg_err_t run_clocks( blip_time_t&, int );
- void set_tempo_( double );
- void set_voice( int, Blip_Buffer*, Blip_Buffer*, Blip_Buffer* );
- void update_eq( blip_eq_t const& );
-public: private: friend class Sap_Cpu;
- int cpu_read( sap_addr_t );
- void cpu_write( sap_addr_t, int );
- void cpu_write_( sap_addr_t, int );
-private:
- info_t info;
-
- byte const* file_end;
- sap_time_t scanline_period;
- sap_time_t next_play;
- sap_time_t time_mask;
- Sap_Apu apu;
- Sap_Apu apu2;
-
- // large items
- struct {
- byte padding1 [0x100];
- byte ram [0x10000];
- byte padding2 [0x100];
- } mem;
- Sap_Apu_Impl apu_impl;
-
- sap_time_t play_period() const;
- void call_play();
- void cpu_jsr( sap_addr_t );
- void call_init( int track );
- void run_routine( sap_addr_t );
-};
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Sms_Apu.cpp b/plugins/gme/game-music-emu-0.5.5/gme/Sms_Apu.cpp
deleted file mode 100644
index b41fdec4..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Sms_Apu.cpp
+++ /dev/null
@@ -1,330 +0,0 @@
-// Sms_Snd_Emu 0.1.4. http://www.slack.net/~ant/
-
-#include "Sms_Apu.h"
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-// Sms_Osc
-
-Sms_Osc::Sms_Osc()
-{
- output = 0;
- outputs [0] = 0; // always stays NULL
- outputs [1] = 0;
- outputs [2] = 0;
- outputs [3] = 0;
-}
-
-void Sms_Osc::reset()
-{
- delay = 0;
- last_amp = 0;
- volume = 0;
- output_select = 3;
- output = outputs [3];
-}
-
-// Sms_Square
-
-inline void Sms_Square::reset()
-{
- period = 0;
- phase = 0;
- Sms_Osc::reset();
-}
-
-void Sms_Square::run( blip_time_t time, blip_time_t end_time )
-{
- if ( !volume || period <= 128 )
- {
- // ignore 16kHz and higher
- if ( last_amp )
- {
- synth->offset( time, -last_amp, output );
- last_amp = 0;
- }
- time += delay;
- if ( !period )
- {
- time = end_time;
- }
- else if ( time < end_time )
- {
- // keep calculating phase
- int count = (end_time - time + period - 1) / period;
- phase = (phase + count) & 1;
- time += count * period;
- }
- }
- else
- {
- int amp = phase ? volume : -volume;
- {
- int delta = amp - last_amp;
- if ( delta )
- {
- last_amp = amp;
- synth->offset( time, delta, output );
- }
- }
-
- time += delay;
- if ( time < end_time )
- {
- Blip_Buffer* const output = this->output;
- int delta = amp * 2;
- do
- {
- delta = -delta;
- synth->offset_inline( time, delta, output );
- time += period;
- phase ^= 1;
- }
- while ( time < end_time );
- this->last_amp = phase ? volume : -volume;
- }
- }
- delay = time - end_time;
-}
-
-// Sms_Noise
-
-static int const noise_periods [3] = { 0x100, 0x200, 0x400 };
-
-inline void Sms_Noise::reset()
-{
- period = &noise_periods [0];
- shifter = 0x8000;
- feedback = 0x9000;
- Sms_Osc::reset();
-}
-
-void Sms_Noise::run( blip_time_t time, blip_time_t end_time )
-{
- int amp = volume;
- if ( shifter & 1 )
- amp = -amp;
-
- {
- int delta = amp - last_amp;
- if ( delta )
- {
- last_amp = amp;
- synth.offset( time, delta, output );
- }
- }
-
- time += delay;
- if ( !volume )
- time = end_time;
-
- if ( time < end_time )
- {
- Blip_Buffer* const output = this->output;
- unsigned shifter = this->shifter;
- int delta = amp * 2;
- int period = *this->period * 2;
- if ( !period )
- period = 16;
-
- do
- {
- int changed = shifter + 1;
- shifter = (feedback & -(shifter & 1)) ^ (shifter >> 1);
- if ( changed & 2 ) // true if bits 0 and 1 differ
- {
- delta = -delta;
- synth.offset_inline( time, delta, output );
- }
- time += period;
- }
- while ( time < end_time );
-
- this->shifter = shifter;
- this->last_amp = delta >> 1;
- }
- delay = time - end_time;
-}
-
-// Sms_Apu
-
-Sms_Apu::Sms_Apu()
-{
- for ( int i = 0; i < 3; i++ )
- {
- squares [i].synth = &square_synth;
- oscs [i] = &squares [i];
- }
- oscs [3] = &noise;
-
- volume( 1.0 );
- reset();
-}
-
-Sms_Apu::~Sms_Apu()
-{
-}
-
-void Sms_Apu::volume( double vol )
-{
- vol *= 0.85 / (osc_count * 64 * 2);
- square_synth.volume( vol );
- noise.synth.volume( vol );
-}
-
-void Sms_Apu::treble_eq( const blip_eq_t& eq )
-{
- square_synth.treble_eq( eq );
- noise.synth.treble_eq( eq );
-}
-
-void Sms_Apu::osc_output( int index, Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right )
-{
- require( (unsigned) index < osc_count );
- require( (center && left && right) || (!center && !left && !right) );
- Sms_Osc& osc = *oscs [index];
- osc.outputs [1] = right;
- osc.outputs [2] = left;
- osc.outputs [3] = center;
- osc.output = osc.outputs [osc.output_select];
-}
-
-void Sms_Apu::output( Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right )
-{
- for ( int i = 0; i < osc_count; i++ )
- osc_output( i, center, left, right );
-}
-
-void Sms_Apu::reset( unsigned feedback, int noise_width )
-{
- last_time = 0;
- latch = 0;
-
- if ( !feedback || !noise_width )
- {
- feedback = 0x0009;
- noise_width = 16;
- }
- // convert to "Galios configuration"
- looped_feedback = 1 << (noise_width - 1);
- noise_feedback = 0;
- while ( noise_width-- )
- {
- noise_feedback = (noise_feedback << 1) | (feedback & 1);
- feedback >>= 1;
- }
-
- squares [0].reset();
- squares [1].reset();
- squares [2].reset();
- noise.reset();
-}
-
-void Sms_Apu::run_until( blip_time_t end_time )
-{
- require( end_time >= last_time ); // end_time must not be before previous time
-
- if ( end_time > last_time )
- {
- // run oscillators
- for ( int i = 0; i < osc_count; ++i )
- {
- Sms_Osc& osc = *oscs [i];
- if ( osc.output )
- {
- osc.output->set_modified();
- if ( i < 3 )
- squares [i].run( last_time, end_time );
- else
- noise.run( last_time, end_time );
- }
- }
-
- last_time = end_time;
- }
-}
-
-void Sms_Apu::end_frame( blip_time_t end_time )
-{
- if ( end_time > last_time )
- run_until( end_time );
-
- assert( last_time >= end_time );
- last_time -= end_time;
-}
-
-void Sms_Apu::write_ggstereo( blip_time_t time, int data )
-{
- require( (unsigned) data <= 0xFF );
-
- run_until( time );
-
- for ( int i = 0; i < osc_count; i++ )
- {
- Sms_Osc& osc = *oscs [i];
- int flags = data >> i;
- Blip_Buffer* old_output = osc.output;
- osc.output_select = (flags >> 3 & 2) | (flags & 1);
- osc.output = osc.outputs [osc.output_select];
- if ( osc.output != old_output && osc.last_amp )
- {
- if ( old_output )
- {
- old_output->set_modified();
- square_synth.offset( time, -osc.last_amp, old_output );
- }
- osc.last_amp = 0;
- }
- }
-}
-
-// volumes [i] = 64 * pow( 1.26, 15 - i ) / pow( 1.26, 15 )
-static unsigned char const volumes [16] = {
- 64, 50, 39, 31, 24, 19, 15, 12, 9, 7, 5, 4, 3, 2, 1, 0
-};
-
-void Sms_Apu::write_data( blip_time_t time, int data )
-{
- require( (unsigned) data <= 0xFF );
-
- run_until( time );
-
- if ( data & 0x80 )
- latch = data;
-
- int index = (latch >> 5) & 3;
- if ( latch & 0x10 )
- {
- oscs [index]->volume = volumes [data & 15];
- }
- else if ( index < 3 )
- {
- Sms_Square& sq = squares [index];
- if ( data & 0x80 )
- sq.period = (sq.period & 0xFF00) | (data << 4 & 0x00FF);
- else
- sq.period = (sq.period & 0x00FF) | (data << 8 & 0x3F00);
- }
- else
- {
- int select = data & 3;
- if ( select < 3 )
- noise.period = &noise_periods [select];
- else
- noise.period = &squares [2].period;
-
- noise.feedback = (data & 0x04) ? noise_feedback : looped_feedback;
- noise.shifter = 0x8000;
- }
-}
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Sms_Apu.h b/plugins/gme/game-music-emu-0.5.5/gme/Sms_Apu.h
deleted file mode 100644
index 3c11a9c3..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Sms_Apu.h
+++ /dev/null
@@ -1,75 +0,0 @@
-// Sega Master System SN76489 PSG sound chip emulator
-
-// Sms_Snd_Emu 0.1.4
-#ifndef SMS_APU_H
-#define SMS_APU_H
-
-#include "Sms_Oscs.h"
-
-class Sms_Apu {
-public:
- // Set overall volume of all oscillators, where 1.0 is full volume
- void volume( double );
-
- // Set treble equalization
- void treble_eq( const blip_eq_t& );
-
- // Outputs can be assigned to a single buffer for mono output, or to three
- // buffers for stereo output (using Stereo_Buffer to do the mixing).
-
- // Assign all oscillator outputs to specified buffer(s). If buffer
- // is NULL, silences all oscillators.
- void output( Blip_Buffer* mono );
- void output( Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right );
-
- // Assign single oscillator output to buffer(s). Valid indicies are 0 to 3,
- // which refer to Square 1, Square 2, Square 3, and Noise. If buffer is NULL,
- // silences oscillator.
- enum { osc_count = 4 };
- void osc_output( int index, Blip_Buffer* mono );
- void osc_output( int index, Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right );
-
- // Reset oscillators and internal state
- void reset( unsigned noise_feedback = 0, int noise_width = 0 );
-
- // Write GameGear left/right assignment byte
- void write_ggstereo( blip_time_t, int );
-
- // Write to data port
- void write_data( blip_time_t, int );
-
- // Run all oscillators up to specified time, end current frame, then
- // start a new frame at time 0.
- void end_frame( blip_time_t );
-
-public:
- Sms_Apu();
- ~Sms_Apu();
-private:
- // noncopyable
- Sms_Apu( const Sms_Apu& );
- Sms_Apu& operator = ( const Sms_Apu& );
-
- Sms_Osc* oscs [osc_count];
- Sms_Square squares [3];
- Sms_Square::Synth square_synth; // used by squares
- blip_time_t last_time;
- int latch;
- Sms_Noise noise;
- unsigned noise_feedback;
- unsigned looped_feedback;
-
- void run_until( blip_time_t );
-};
-
-struct sms_apu_state_t
-{
- unsigned char regs [8] [2];
- unsigned char latch;
-};
-
-inline void Sms_Apu::output( Blip_Buffer* b ) { output( b, b, b ); }
-
-inline void Sms_Apu::osc_output( int i, Blip_Buffer* b ) { osc_output( i, b, b, b ); }
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Sms_Oscs.h b/plugins/gme/game-music-emu-0.5.5/gme/Sms_Oscs.h
deleted file mode 100644
index 2a896fef..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Sms_Oscs.h
+++ /dev/null
@@ -1,49 +0,0 @@
-// Private oscillators used by Sms_Apu
-
-// Sms_Snd_Emu 0.1.4
-#ifndef SMS_OSCS_H
-#define SMS_OSCS_H
-
-#include "blargg_common.h"
-#include "Blip_Buffer.h"
-
-struct Sms_Osc
-{
- Blip_Buffer* outputs [4]; // NULL, right, left, center
- Blip_Buffer* output;
- int output_select;
-
- int delay;
- int last_amp;
- int volume;
-
- Sms_Osc();
- void reset();
-};
-
-struct Sms_Square : Sms_Osc
-{
- int period;
- int phase;
-
- typedef Blip_Synth<blip_good_quality,1> Synth;
- const Synth* synth;
-
- void reset();
- void run( blip_time_t, blip_time_t );
-};
-
-struct Sms_Noise : Sms_Osc
-{
- const int* period;
- unsigned shifter;
- unsigned feedback;
-
- typedef Blip_Synth<blip_med_quality,1> Synth;
- Synth synth;
-
- void reset();
- void run( blip_time_t, blip_time_t );
-};
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Snes_Spc.cpp b/plugins/gme/game-music-emu-0.5.5/gme/Snes_Spc.cpp
deleted file mode 100644
index d169b388..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Snes_Spc.cpp
+++ /dev/null
@@ -1,489 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Snes_Spc.h"
-
-#include <string.h>
-
-/* Copyright (C) 2004-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-// always in the future (CPU time can go over 0, but not by this much)
-int const timer_disabled_time = 127;
-
-Snes_Spc::Snes_Spc() : dsp( mem.ram ), cpu( this, mem.ram )
-{
- set_tempo( 1.0 );
-
- // Put STOP instruction around memory to catch PC underflow/overflow.
- memset( mem.padding1, 0xFF, sizeof mem.padding1 );
- memset( mem.padding2, 0xFF, sizeof mem.padding2 );
-
- // A few tracks read from the last four bytes of IPL ROM
- boot_rom [sizeof boot_rom - 2] = 0xC0;
- boot_rom [sizeof boot_rom - 1] = 0xFF;
- memset( boot_rom, 0, sizeof boot_rom - 2 );
-}
-
-void Snes_Spc::set_tempo( double t )
-{
- int unit = (int) (16.0 / t + 0.5);
-
- timer [0].divisor = unit * 8; // 8 kHz
- timer [1].divisor = unit * 8; // 8 kHz
- timer [2].divisor = unit; // 64 kHz
-}
-
-// Load
-
-void Snes_Spc::set_ipl_rom( void const* in )
-{
- memcpy( boot_rom, in, sizeof boot_rom );
-}
-
-blargg_err_t Snes_Spc::load_spc( const void* data, long size )
-{
- struct spc_file_t {
- char signature [27];
- char unused [10];
- uint8_t pc [2];
- uint8_t a;
- uint8_t x;
- uint8_t y;
- uint8_t status;
- uint8_t sp;
- char unused2 [212];
- uint8_t ram [0x10000];
- uint8_t dsp [128];
- uint8_t ipl_rom [128];
- };
- assert( offsetof (spc_file_t,ipl_rom) == spc_file_size );
-
- const spc_file_t* spc = (spc_file_t const*) data;
-
- if ( size < spc_file_size )
- return "Not an SPC file";
-
- if ( strncmp( spc->signature, "SNES-SPC700 Sound File Data", 27 ) != 0 )
- return "Not an SPC file";
-
- registers_t regs;
- regs.pc = spc->pc [1] * 0x100 + spc->pc [0];
- regs.a = spc->a;
- regs.x = spc->x;
- regs.y = spc->y;
- regs.status = spc->status;
- regs.sp = spc->sp;
-
- if ( (unsigned long) size >= sizeof *spc )
- set_ipl_rom( spc->ipl_rom );
-
- const char* error = load_state( regs, spc->ram, spc->dsp );
-
- echo_accessed = false;
-
- return error;
-}
-
-void Snes_Spc::clear_echo()
-{
- if ( !(dsp.read( 0x6C ) & 0x20) )
- {
- unsigned addr = 0x100 * dsp.read( 0x6D );
- size_t size = 0x800 * dsp.read( 0x7D );
- memset( mem.ram + addr, 0xFF, min( size, sizeof mem.ram - addr ) );
- }
-}
-
-// Handle other file formats (emulator save states) in user code, not here.
-
-blargg_err_t Snes_Spc::load_state( const registers_t& cpu_state, const void* new_ram,
- const void* dsp_state )
-{
- // cpu
- cpu.r = cpu_state;
-
- // Allow DSP to generate one sample before code starts
- // (Tengai Makyo Zero, Tenjin's Table Toss first notes are lost since it
- // clears KON 31 cycles from starting execution. It works on the SNES
- // since the SPC player adds a few extra cycles delay after restoring
- // KON from the DSP registers at the end of an SPC file).
- extra_cycles = 32;
-
- // ram
- memcpy( mem.ram, new_ram, sizeof mem.ram );
- memcpy( extra_ram, mem.ram + rom_addr, sizeof extra_ram );
-
- // boot rom (have to force enable_rom() to update it)
- rom_enabled = !(mem.ram [0xF1] & 0x80);
- enable_rom( !rom_enabled );
-
- // dsp
- dsp.reset();
- int i;
- for ( i = 0; i < Spc_Dsp::register_count; i++ )
- dsp.write( i, ((uint8_t const*) dsp_state) [i] );
-
- // timers
- for ( i = 0; i < timer_count; i++ )
- {
- Timer& t = timer [i];
-
- t.next_tick = 0;
- t.enabled = (mem.ram [0xF1] >> i) & 1;
- if ( !t.enabled )
- t.next_tick = timer_disabled_time;
- t.count = 0;
- t.counter = mem.ram [0xFD + i] & 15;
-
- int p = mem.ram [0xFA + i];
- t.period = p ? p : 0x100;
- }
-
- // Handle registers which already give 0 when read by setting RAM and not changing it.
- // Put STOP instruction in registers which can be read, to catch attempted CPU execution.
- mem.ram [0xF0] = 0;
- mem.ram [0xF1] = 0;
- mem.ram [0xF3] = 0xFF;
- mem.ram [0xFA] = 0;
- mem.ram [0xFB] = 0;
- mem.ram [0xFC] = 0;
- mem.ram [0xFD] = 0xFF;
- mem.ram [0xFE] = 0xFF;
- mem.ram [0xFF] = 0xFF;
-
- return 0; // success
-}
-
-// Hardware
-
-// Current time starts negative and ends at 0
-inline spc_time_t Snes_Spc::time() const
-{
- return -cpu.remain();
-}
-
-// Keep track of next time to run and avoid a function call if it hasn't been reached.
-
-// Timers
-
-void Snes_Spc::Timer::run_until_( spc_time_t time )
-{
- if ( !enabled )
- debug_printf( "next_tick: %ld, time: %ld", (long) next_tick, (long) time );
- assert( enabled ); // when disabled, next_tick should always be in the future
-
- int elapsed = ((time - next_tick) / divisor) + 1;
- next_tick += elapsed * divisor;
-
- elapsed += count;
- if ( elapsed >= period ) // avoid unnecessary division
- {
- int n = elapsed / period;
- elapsed -= n * period;
- counter = (counter + n) & 15;
- }
- count = elapsed;
-}
-
-// DSP
-
-const int clocks_per_sample = 32; // 1.024 MHz CPU clock / 32000 samples per second
-
-void Snes_Spc::run_dsp_( spc_time_t time )
-{
- int count = ((time - next_dsp) >> 5) + 1; // divide by clocks_per_sample
- sample_t* buf = sample_buf;
- if ( buf ) {
- sample_buf = buf + count * 2; // stereo
- assert( sample_buf <= buf_end );
- }
- next_dsp += count * clocks_per_sample;
- dsp.run( count, buf );
-}
-
-inline void Snes_Spc::run_dsp( spc_time_t time )
-{
- if ( time >= next_dsp )
- run_dsp_( time );
-}
-
-// Debug-only check for read/write within echo buffer, since this might result in
-// inaccurate emulation due to the DSP not being caught up to the present.
-inline void Snes_Spc::check_for_echo_access( spc_addr_t addr )
-{
- if ( !echo_accessed && !(dsp.read( 0x6C ) & 0x20) )
- {
- // ** If echo accesses are found that require running the DSP, cache
- // the start and end address on DSP writes to speed up checking.
-
- unsigned start = 0x100 * dsp.read( 0x6D );
- unsigned end = start + 0x800 * dsp.read( 0x7D );
- if ( start <= addr && addr < end ) {
- echo_accessed = true;
- debug_printf( "Read/write at $%04X within echo buffer\n", (unsigned) addr );
- }
- }
-}
-
-// Read
-
-int Snes_Spc::read( spc_addr_t addr )
-{
- int result = mem.ram [addr];
-
- if ( (rom_addr <= addr && addr < 0xFFFC || addr >= 0xFFFE) && rom_enabled )
- debug_printf( "Read from ROM: %04X -> %02X\n", addr, result );
-
- if ( unsigned (addr - 0xF0) < 0x10 )
- {
- assert( 0xF0 <= addr && addr <= 0xFF );
-
- // counters
- int i = addr - 0xFD;
- if ( i >= 0 )
- {
- Timer& t = timer [i];
- t.run_until( time() );
- int old = t.counter;
- t.counter = 0;
- return old;
- }
-
- // dsp
- if ( addr == 0xF3 )
- {
- run_dsp( time() );
- if ( mem.ram [0xF2] >= Spc_Dsp::register_count )
- debug_printf( "DSP read from $%02X\n", (int) mem.ram [0xF2] );
- return dsp.read( mem.ram [0xF2] & 0x7F );
- }
-
- if ( addr == 0xF0 || addr == 0xF1 || addr == 0xF8 ||
- addr == 0xF9 || addr == 0xFA )
- debug_printf( "Read from register $%02X\n", (int) addr );
-
- // Registers which always read as 0 are handled by setting mem.ram [reg] to 0
- // at startup then never changing that value.
-
- check(( check_for_echo_access( addr ), true ));
- }
-
- return result;
-}
-
-
-// Write
-
-void Snes_Spc::enable_rom( bool enable )
-{
- if ( rom_enabled != enable )
- {
- rom_enabled = enable;
- memcpy( mem.ram + rom_addr, (enable ? boot_rom : extra_ram), rom_size );
- // TODO: ROM can still get overwritten when DSP writes to echo buffer
- }
-}
-
-void Snes_Spc::write( spc_addr_t addr, int data )
-{
- // first page is very common
- if ( addr < 0xF0 ) {
- mem.ram [addr] = (uint8_t) data;
- }
- else switch ( addr )
- {
- // RAM
- default:
- check(( check_for_echo_access( addr ), true ));
- if ( addr < rom_addr ) {
- mem.ram [addr] = (uint8_t) data;
- }
- else {
- extra_ram [addr - rom_addr] = (uint8_t) data;
- if ( !rom_enabled )
- mem.ram [addr] = (uint8_t) data;
- }
- break;
-
- // DSP
- //case 0xF2: // mapped to RAM
- case 0xF3: {
- run_dsp( time() );
- int reg = mem.ram [0xF2];
- if ( next_dsp > 0 ) {
- // skip mode
-
- // key press
- if ( reg == 0x4C )
- keys_pressed |= data & ~dsp.read( 0x5C );
-
- // key release
- if ( reg == 0x5C ) {
- keys_released |= data;
- keys_pressed &= ~data;
- }
- }
- if ( reg < Spc_Dsp::register_count ) {
- dsp.write( reg, data );
- }
- else {
- debug_printf( "DSP write to $%02X\n", (int) reg );
- }
- break;
- }
-
- case 0xF0: // Test register
- debug_printf( "Wrote $%02X to $F0\n", (int) data );
- break;
-
- // Config
- case 0xF1:
- {
- // timers
- for ( int i = 0; i < timer_count; i++ )
- {
- Timer& t = timer [i];
- if ( !(data & (1 << i)) ) {
- t.enabled = 0;
- t.next_tick = timer_disabled_time;
- }
- else if ( !t.enabled ) {
- // just enabled
- t.enabled = 1;
- t.counter = 0;
- t.count = 0;
- t.next_tick = time();
- }
- }
-
- // port clears
- if ( data & 0x10 ) {
- mem.ram [0xF4] = 0;
- mem.ram [0xF5] = 0;
- }
- if ( data & 0x20 ) {
- mem.ram [0xF6] = 0;
- mem.ram [0xF7] = 0;
- }
-
- enable_rom( (data & 0x80) != 0 );
-
- break;
- }
-
- // Ports
- case 0xF4:
- case 0xF5:
- case 0xF6:
- case 0xF7:
- // to do: handle output ports
- break;
-
- //case 0xF8: // verified on SNES that these are read/write (RAM)
- //case 0xF9:
-
- // Timers
- case 0xFA:
- case 0xFB:
- case 0xFC: {
- Timer& t = timer [addr - 0xFA];
- if ( (t.period & 0xFF) != data ) {
- t.run_until( time() );
- t.period = data ? data : 0x100;
- }
- break;
- }
-
- // Counters (cleared on write)
- case 0xFD:
- case 0xFE:
- case 0xFF:
- debug_printf( "Wrote to counter $%02X\n", (int) addr );
- timer [addr - 0xFD].counter = 0;
- break;
- }
-}
-
-// Play
-
-blargg_err_t Snes_Spc::skip( long count )
-{
- if ( count > 4 * 32000L )
- {
- // don't run DSP for long durations (2-3 times faster)
-
- const long sync_count = 32000L * 2;
-
- // keep track of any keys pressed/released (and not subsequently released)
- keys_pressed = 0;
- keys_released = 0;
- // sentinel tells play to ignore DSP
- RETURN_ERR( play( count - sync_count, skip_sentinel ) );
-
- // press/release keys now
- dsp.write( 0x5C, keys_released & ~keys_pressed );
- dsp.write( 0x4C, keys_pressed );
-
- clear_echo();
-
- // play the last few seconds normally to help synchronize DSP
- count = sync_count;
- }
-
- return play( count );
-}
-
-blargg_err_t Snes_Spc::play( long count, sample_t* out )
-{
- require( count % 2 == 0 ); // output is always in pairs of samples
-
- // CPU time() runs from -duration to 0
- spc_time_t duration = (count / 2) * clocks_per_sample;
-
- // DSP output is made on-the-fly when the CPU reads/writes DSP registers
- sample_buf = out;
- buf_end = out + (out && out != skip_sentinel ? count : 0);
- next_dsp = (out == skip_sentinel) ? clocks_per_sample : -duration + clocks_per_sample;
-
- // Localize timer next_tick times and run them to the present to prevent a running
- // but ignored timer's next_tick from getting too far behind and overflowing.
- for ( int i = 0; i < timer_count; i++ )
- {
- Timer& t = timer [i];
- if ( t.enabled )
- {
- t.next_tick -= duration;
- t.run_until( -duration );
- }
- }
-
- // Run CPU for duration, reduced by any extra cycles from previous run
- int elapsed = cpu.run( duration - extra_cycles );
- if ( elapsed > 0 )
- {
- debug_printf( "Unhandled instruction $%02X, pc = $%04X\n",
- (int) cpu.read( cpu.r.pc ), (unsigned) cpu.r.pc );
- return "Emulation error (illegal/unsupported instruction)";
- }
- extra_cycles = -elapsed;
-
- // Catch DSP up to present.
- run_dsp( 0 );
- if ( out ) {
- assert( next_dsp == clocks_per_sample );
- assert( out == skip_sentinel || sample_buf - out == count );
- }
- buf_end = 0;
-
- return 0;
-}
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Snes_Spc.h b/plugins/gme/game-music-emu-0.5.5/gme/Snes_Spc.h
deleted file mode 100644
index 1df51613..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Snes_Spc.h
+++ /dev/null
@@ -1,121 +0,0 @@
-// Super Nintendo (SNES) SPC-700 APU Emulator
-
-// Game_Music_Emu 0.5.5
-#ifndef SNES_SPC_H
-#define SNES_SPC_H
-
-#include "blargg_common.h"
-#include "Spc_Cpu.h"
-#include "Spc_Dsp.h"
-
-class Snes_Spc {
-public:
-
- // Load copy of SPC data into emulator. Clear echo buffer if 'clear_echo' is true.
- enum { spc_file_size = 0x10180 };
- blargg_err_t load_spc( const void* spc, long spc_size );
-
- // Generate 'count' samples and optionally write to 'buf'. Count must be even.
- // Sample output is 16-bit 32kHz, signed stereo pairs with the left channel first.
- typedef short sample_t;
- blargg_err_t play( long count, sample_t* buf = NULL );
-
-// Optional functionality
-
- // Load copy of state into emulator.
- typedef Spc_Cpu::registers_t registers_t;
- blargg_err_t load_state( const registers_t& cpu_state, const void* ram_64k,
- const void* dsp_regs_128 );
-
- // Clear echo buffer, useful because many tracks have junk in the buffer.
- void clear_echo();
-
- // Mute voice n if bit n (1 << n) of mask is set
- enum { voice_count = Spc_Dsp::voice_count };
- void mute_voices( int mask );
-
- // Skip forward by the specified number of samples (64000 samples = 1 second)
- blargg_err_t skip( long count );
-
- // Set gain, where 1.0 is normal. When greater than 1.0, output is clamped the
- // 16-bit sample range.
- void set_gain( double );
-
- // If true, prevent channels and global volumes from being phase-negated
- void disable_surround( bool disable = true );
-
- // Set 128 bytes to use for IPL boot ROM. Makes copy. Default is zero filled,
- // to avoid including copyrighted code from the SPC-700.
- void set_ipl_rom( const void* );
-
- void set_tempo( double );
-
-public:
- Snes_Spc();
- typedef BOOST::uint8_t uint8_t;
-private:
- // timers
- struct Timer
- {
- spc_time_t next_tick;
- int period;
- int count;
- int divisor;
- int enabled;
- int counter;
-
- void run_until_( spc_time_t );
- void run_until( spc_time_t time )
- {
- if ( time >= next_tick )
- run_until_( time );
- }
- };
- enum { timer_count = 3 };
- Timer timer [timer_count];
-
- // hardware
- int extra_cycles;
- spc_time_t time() const;
- int read( spc_addr_t );
- void write( spc_addr_t, int );
- friend class Spc_Cpu;
-
- // dsp
- sample_t* sample_buf;
- sample_t* buf_end; // to do: remove this once possible bug resolved
- spc_time_t next_dsp;
- Spc_Dsp dsp;
- int keys_pressed;
- int keys_released;
- sample_t skip_sentinel [1]; // special value for play() passed by skip()
- void run_dsp( spc_time_t );
- void run_dsp_( spc_time_t );
- bool echo_accessed;
- void check_for_echo_access( spc_addr_t );
-
- // boot rom
- enum { rom_size = 64 };
- enum { rom_addr = 0xFFC0 };
- bool rom_enabled;
- void enable_rom( bool );
-
- // CPU and RAM (at end because it's large)
- Spc_Cpu cpu;
- uint8_t extra_ram [rom_size];
- struct {
- // padding to catch jumps before beginning or past end
- uint8_t padding1 [0x100];
- uint8_t ram [0x10000];
- uint8_t padding2 [0x100];
- } mem;
- uint8_t boot_rom [rom_size];
-};
-
-inline void Snes_Spc::disable_surround( bool disable ) { dsp.disable_surround( disable ); }
-
-inline void Snes_Spc::mute_voices( int mask ) { dsp.mute_voices( mask ); }
-
-inline void Snes_Spc::set_gain( double v ) { dsp.set_gain( v ); }
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Spc_Cpu.cpp b/plugins/gme/game-music-emu-0.5.5/gme/Spc_Cpu.cpp
deleted file mode 100644
index 8b61a455..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Spc_Cpu.cpp
+++ /dev/null
@@ -1,1062 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Spc_Cpu.h"
-
-#include "blargg_endian.h"
-#include "Snes_Spc.h"
-
-/* Copyright (C) 2004-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-// Several instructions are commented out (or not even implemented). These aren't
-// used by the SPC files tested.
-
-// Optimize performance for the most common instructions, and size for the rest:
-//
-// 15% 0xF0 BEQ rel
-// 8% 0xE4 MOV A,dp
-// 4% 0xF5 MOV A,abs+X
-// 4% 0xD0 BNE rel
-// 4% 0x6F RET
-// 4% 0x3F CALL addr
-// 4% 0xF4 MOV A,dp+X
-// 3% 0xC4 MOV dp,A
-// 2% 0xEB MOV Y,dp
-// 2% 0x3D INC X
-// 2% 0xF6 MOV A,abs+Y
-// (1% and below not shown)
-
-Spc_Cpu::Spc_Cpu( Snes_Spc* e, uint8_t* ram_in ) : ram( ram_in ), emu( *e )
-{
- remain_ = 0;
- assert( INT_MAX >= 0x7FFFFFFF ); // requires 32-bit int
- blargg_verify_byte_order();
-}
-
-#define READ( addr ) (emu.read( addr ))
-#define WRITE( addr, value ) (emu.write( addr, value ))
-
-#define READ_DP( addr ) READ( (addr) + dp )
-#define WRITE_DP( addr, value ) WRITE( (addr) + dp, value )
-
-#define READ_PROG( addr ) (ram [addr])
-#define READ_PROG16( addr ) GET_LE16( &READ_PROG( addr ) )
-
-int Spc_Cpu::read( spc_addr_t addr )
-{
- return READ( addr );
-}
-
-void Spc_Cpu::write( spc_addr_t addr, int data )
-{
- WRITE( addr, data );
-}
-
-// Cycle table derived from text copy of SPC-700 manual (using regular expressions)
-static unsigned char const cycle_table [0x100] = {
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 2,8,4,5,3,4,3,6,2,6,5,4,5,4,6,8, // 0
- 2,8,4,5,4,5,5,6,5,5,6,5,2,2,4,6, // 1
- 2,8,4,5,3,4,3,6,2,6,5,4,5,4,5,4, // 2
- 2,8,4,5,4,5,5,6,5,5,6,5,2,2,3,8, // 3
- 2,8,4,5,3,4,3,6,2,6,4,4,5,4,6,6, // 4
- 2,8,4,5,4,5,5,6,5,5,4,5,2,2,4,3, // 5
- 2,8,4,5,3,4,3,6,2,6,4,4,5,4,5,5, // 6
- 2,8,4,5,4,5,5,6,5,5,5,5,2,2,3,6, // 7
- 2,8,4,5,3,4,3,6,2,6,5,4,5,2,4,5, // 8
- 2,8,4,5,4,5,5,6,5,5,5,5,2,2,12,5,// 9
- 3,8,4,5,3,4,3,6,2,6,4,4,5,2,4,4, // A
- 2,8,4,5,4,5,5,6,5,5,5,5,2,2,3,4, // B
- 3,8,4,5,4,5,4,7,2,5,6,4,5,2,4,9, // C
- 2,8,4,5,5,6,6,7,4,5,4,5,2,2,6,3, // D
- 2,8,4,5,3,4,3,6,2,4,5,3,4,3,4,3, // E
- 2,8,4,5,4,5,5,6,3,4,5,4,2,2,4,3 // F
-};
-
-// The C,mem instructions are hardly used, so a non-inline function is used for
-// the common access code.
-unsigned Spc_Cpu::mem_bit( spc_addr_t pc )
-{
- unsigned addr = READ_PROG16( pc );
- unsigned t = READ( addr & 0x1FFF ) >> (addr >> 13);
- return (t << 8) & 0x100;
-}
-
-spc_time_t Spc_Cpu::run( spc_time_t cycle_count )
-{
- remain_ = cycle_count;
-
- uint8_t* const ram = this->ram; // cache
-
- // Stack pointer is kept one greater than usual SPC stack pointer to allow
- // common pre-decrement and post-increment memory instructions that some
- // processors have. Address wrap-around isn't supported.
- #define PUSH( v ) (*--sp = uint8_t (v))
- #define PUSH16( v ) (sp -= 2, SET_LE16( sp, v ))
- #define POP() (*sp++)
- #define SET_SP( v ) (sp = ram + 0x101 + (v))
- #define GET_SP() (sp - 0x101 - ram)
-
- uint8_t* sp;
- SET_SP( r.sp );
-
- // registers
- unsigned pc = (unsigned) r.pc;
- int a = r.a;
- int x = r.x;
- int y = r.y;
-
- // status flags
-
- const int st_n = 0x80;
- const int st_v = 0x40;
- const int st_p = 0x20;
- const int st_b = 0x10;
- const int st_h = 0x08;
- const int st_i = 0x04;
- const int st_z = 0x02;
- const int st_c = 0x01;
-
- #define IS_NEG (nz & 0x880)
-
- #define CALC_STATUS( out ) do {\
- out = status & ~(st_n | st_z | st_c);\
- out |= (c >> 8) & st_c;\
- out |= (dp >> 3) & st_p;\
- if ( IS_NEG ) out |= st_n;\
- if ( !(nz & 0xFF) ) out |= st_z;\
- } while ( 0 )
-
- #define SET_STATUS( in ) do {\
- status = in & ~(st_n | st_z | st_c | st_p);\
- c = in << 8;\
- nz = (in << 4) & 0x800;\
- nz |= ~in & st_z;\
- dp = (in << 3) & 0x100;\
- } while ( 0 )
-
- int status;
- int c; // store C as 'c' & 0x100.
- int nz; // Z set if (nz & 0xFF) == 0, N set if (nz & 0x880) != 0
- unsigned dp; // direct page base
- {
- int temp = r.status;
- SET_STATUS( temp );
- }
-
- goto loop;
-
- unsigned data; // first operand of instruction and temporary across function calls
-
- // Common endings for instructions
-cbranch_taken_loop: // compare and branch
- pc += (BOOST::int8_t) READ_PROG( pc );
- remain_ -= 2;
-inc_pc_loop: // end of instruction with an operand
- pc++;
-loop:
-
- check( (unsigned) pc < 0x10000 );
- check( (unsigned) GET_SP() < 0x100 );
-
- check( (unsigned) a < 0x100 );
- check( (unsigned) x < 0x100 );
- check( (unsigned) y < 0x100 );
-
- unsigned opcode = READ_PROG( pc );
- pc++;
- // to do: if pc is at end of memory, this will get wrong byte
- data = READ_PROG( pc );
-
- if ( remain_ <= 0 )
- goto stop;
-
- remain_ -= cycle_table [opcode];
-
- // Use 'data' for temporaries whose lifetime crosses read/write calls, otherwise
- // use a local temporary.
- switch ( opcode )
- {
-
- #define BRANCH( cond ) {\
- pc++;\
- int offset = (BOOST::int8_t) data;\
- if ( cond ) {\
- pc += offset;\
- remain_ -= 2;\
- }\
- goto loop;\
- }
-
-// Most-Common
-
- case 0xF0: // BEQ (most common)
- BRANCH( !(uint8_t) nz )
-
- case 0xD0: // BNE
- BRANCH( (uint8_t) nz )
-
- case 0x3F: // CALL
- PUSH16( pc + 2 );
- pc = READ_PROG16( pc );
- goto loop;
-
- case 0x6F: // RET
- pc = POP();
- pc += POP() * 0x100;
- goto loop;
-
-#define CASE( n ) case n:
-
-// Define common address modes based on opcode for immediate mode. Execution
-// ends with data set to the address of the operand.
-#define ADDR_MODES( op )\
- CASE( op - 0x02 ) /* (X) */\
- data = x + dp;\
- pc--;\
- goto end_##op;\
- CASE( op + 0x0F ) /* (dp)+Y */\
- data = READ_PROG16( data + dp ) + y;\
- goto end_##op;\
- CASE( op - 0x01 ) /* (dp+X) */\
- data = READ_PROG16( uint8_t (data + x) + dp );\
- goto end_##op;\
- CASE( op + 0x0E ) /* abs+Y */\
- data += y;\
- goto abs_##op;\
- CASE( op + 0x0D ) /* abs+X */\
- data += x;\
- CASE( op - 0x03 ) /* abs */\
- abs_##op:\
- pc++;\
- data += 0x100 * READ_PROG( pc );\
- goto end_##op;\
- CASE( op + 0x0C ) /* dp+X */\
- data = uint8_t (data + x);\
- CASE( op - 0x04 ) /* dp */\
- data += dp;\
- end_##op:
-
-// 1. 8-bit Data Transmission Commands. Group I
-
- ADDR_MODES( 0xE8 ) // MOV A,addr
- // case 0xE4: // MOV a,dp (most common)
- mov_a_addr:
- a = nz = READ( data );
- goto inc_pc_loop;
- case 0xBF: // MOV A,(X)+
- data = x + dp;
- x = uint8_t (x + 1);
- pc--;
- goto mov_a_addr;
-
- case 0xE8: // MOV A,imm
- a = data;
- nz = data;
- goto inc_pc_loop;
-
- case 0xF9: // MOV X,dp+Y
- data = uint8_t (data + y);
- case 0xF8: // MOV X,dp
- data += dp;
- goto mov_x_addr;
- case 0xE9: // MOV X,abs
- data = READ_PROG16( pc );
- pc++;
- mov_x_addr:
- data = READ( data );
- case 0xCD: // MOV X,imm
- x = data;
- nz = data;
- goto inc_pc_loop;
-
- case 0xFB: // MOV Y,dp+X
- data = uint8_t (data + x);
- case 0xEB: // MOV Y,dp
- data += dp;
- goto mov_y_addr;
- case 0xEC: // MOV Y,abs
- data = READ_PROG16( pc );
- pc++;
- mov_y_addr:
- data = READ( data );
- case 0x8D: // MOV Y,imm
- y = data;
- nz = data;
- goto inc_pc_loop;
-
-// 2. 8-BIT DATA TRANSMISSION COMMANDS, GROUP 2
-
- ADDR_MODES( 0xC8 ) // MOV addr,A
- WRITE( data, a );
- goto inc_pc_loop;
-
- {
- int temp;
- case 0xCC: // MOV abs,Y
- temp = y;
- goto mov_abs_temp;
- case 0xC9: // MOV abs,X
- temp = x;
- mov_abs_temp:
- WRITE( READ_PROG16( pc ), temp );
- pc += 2;
- goto loop;
- }
-
- case 0xD9: // MOV dp+Y,X
- data = uint8_t (data + y);
- case 0xD8: // MOV dp,X
- WRITE( data + dp, x );
- goto inc_pc_loop;
-
- case 0xDB: // MOV dp+X,Y
- data = uint8_t (data + x);
- case 0xCB: // MOV dp,Y
- WRITE( data + dp, y );
- goto inc_pc_loop;
-
- case 0xFA: // MOV dp,dp
- data = READ( data + dp );
- case 0x8F: // MOV dp,#imm
- pc++;
- WRITE_DP( READ_PROG( pc ), data );
- goto inc_pc_loop;
-
-// 3. 8-BIT DATA TRANSMISSIN COMMANDS, GROUP 3.
-
- case 0x7D: // MOV A,X
- a = x;
- nz = x;
- goto loop;
-
- case 0xDD: // MOV A,Y
- a = y;
- nz = y;
- goto loop;
-
- case 0x5D: // MOV X,A
- x = a;
- nz = a;
- goto loop;
-
- case 0xFD: // MOV Y,A
- y = a;
- nz = a;
- goto loop;
-
- case 0x9D: // MOV X,SP
- x = nz = GET_SP();
- goto loop;
-
- case 0xBD: // MOV SP,X
- SET_SP( x );
- goto loop;
-
- //case 0xC6: // MOV (X),A (handled by MOV addr,A in group 2)
-
- case 0xAF: // MOV (X)+,A
- WRITE_DP( x, a );
- x++;
- goto loop;
-
-// 5. 8-BIT LOGIC OPERATION COMMANDS
-
-#define LOGICAL_OP( op, func )\
- ADDR_MODES( op ) /* addr */\
- data = READ( data );\
- case op: /* imm */\
- nz = a func##= data;\
- goto inc_pc_loop;\
- { unsigned addr;\
- case op + 0x11: /* X,Y */\
- data = READ_DP( y );\
- addr = x + dp;\
- pc--;\
- goto addr_##op;\
- case op + 0x01: /* dp,dp */\
- data = READ_DP( data );\
- case op + 0x10: /*dp,imm*/\
- pc++;\
- addr = READ_PROG( pc ) + dp;\
- addr_##op:\
- nz = data func READ( addr );\
- WRITE( addr, nz );\
- goto inc_pc_loop;\
- }
-
- LOGICAL_OP( 0x28, & ); // AND
-
- LOGICAL_OP( 0x08, | ); // OR
-
- LOGICAL_OP( 0x48, ^ ); // EOR
-
-// 4. 8-BIT ARITHMETIC OPERATION COMMANDS
-
- ADDR_MODES( 0x68 ) // CMP addr
- data = READ( data );
- case 0x68: // CMP imm
- nz = a - data;
- c = ~nz;
- nz &= 0xFF;
- goto inc_pc_loop;
-
- case 0x79: // CMP (X),(Y)
- data = READ_DP( x );
- nz = data - READ_DP( y );
- c = ~nz;
- nz &= 0xFF;
- goto loop;
-
- case 0x69: // CMP (dp),(dp)
- data = READ_DP( data );
- case 0x78: // CMP dp,imm
- pc++;
- nz = READ_DP( READ_PROG( pc ) ) - data;
- c = ~nz;
- nz &= 0xFF;
- goto inc_pc_loop;
-
- case 0x3E: // CMP X,dp
- data += dp;
- goto cmp_x_addr;
- case 0x1E: // CMP X,abs
- data = READ_PROG16( pc );
- pc++;
- cmp_x_addr:
- data = READ( data );
- case 0xC8: // CMP X,imm
- nz = x - data;
- c = ~nz;
- nz &= 0xFF;
- goto inc_pc_loop;
-
- case 0x7E: // CMP Y,dp
- data += dp;
- goto cmp_y_addr;
- case 0x5E: // CMP Y,abs
- data = READ_PROG16( pc );
- pc++;
- cmp_y_addr:
- data = READ( data );
- case 0xAD: // CMP Y,imm
- nz = y - data;
- c = ~nz;
- nz &= 0xFF;
- goto inc_pc_loop;
-
- {
- int addr;
- case 0xB9: // SBC (x),(y)
- case 0x99: // ADC (x),(y)
- pc--; // compensate for inc later
- data = READ_DP( x );
- addr = y + dp;
- goto adc_addr;
- case 0xA9: // SBC dp,dp
- case 0x89: // ADC dp,dp
- data = READ_DP( data );
- case 0xB8: // SBC dp,imm
- case 0x98: // ADC dp,imm
- pc++;
- addr = READ_PROG( pc ) + dp;
- adc_addr:
- nz = READ( addr );
- goto adc_data;
-
-// catch ADC and SBC together, then decode later based on operand
-#undef CASE
-#define CASE( n ) case n: case (n) + 0x20:
- ADDR_MODES( 0x88 ) // ADC/SBC addr
- data = READ( data );
- case 0xA8: // SBC imm
- case 0x88: // ADC imm
- addr = -1; // A
- nz = a;
- adc_data: {
- if ( opcode & 0x20 )
- data ^= 0xFF; // SBC
- int carry = (c >> 8) & 1;
- int ov = (nz ^ 0x80) + carry + (BOOST::int8_t) data; // sign-extend
- int hc = (nz & 15) + carry;
- c = nz += data + carry;
- hc = (nz & 15) - hc;
- status = (status & ~(st_v | st_h)) | ((ov >> 2) & st_v) | ((hc >> 1) & st_h);
- if ( addr < 0 ) {
- a = (uint8_t) nz;
- goto inc_pc_loop;
- }
- WRITE( addr, (uint8_t) nz );
- goto inc_pc_loop;
- }
-
- }
-
-// 6. ADDITION & SUBTRACTION COMMANDS
-
-#define INC_DEC_REG( reg, n )\
- nz = reg + n;\
- reg = (uint8_t) nz;\
- goto loop;
-
- case 0xBC: INC_DEC_REG( a, 1 ) // INC A
- case 0x3D: INC_DEC_REG( x, 1 ) // INC X
- case 0xFC: INC_DEC_REG( y, 1 ) // INC Y
-
- case 0x9C: INC_DEC_REG( a, -1 ) // DEC A
- case 0x1D: INC_DEC_REG( x, -1 ) // DEC X
- case 0xDC: INC_DEC_REG( y, -1 ) // DEC Y
-
- case 0x9B: // DEC dp+X
- case 0xBB: // INC dp+X
- data = uint8_t (data + x);
- case 0x8B: // DEC dp
- case 0xAB: // INC dp
- data += dp;
- goto inc_abs;
- case 0x8C: // DEC abs
- case 0xAC: // INC abs
- data = READ_PROG16( pc );
- pc++;
- inc_abs:
- nz = ((opcode >> 4) & 2) - 1;
- nz += READ( data );
- WRITE( data, (uint8_t) nz );
- goto inc_pc_loop;
-
-// 7. SHIFT, ROTATION COMMANDS
-
- case 0x5C: // LSR A
- c = 0;
- case 0x7C:{// ROR A
- nz = ((c >> 1) & 0x80) | (a >> 1);
- c = a << 8;
- a = nz;
- goto loop;
- }
-
- case 0x1C: // ASL A
- c = 0;
- case 0x3C:{// ROL A
- int temp = (c >> 8) & 1;
- c = a << 1;
- nz = c | temp;
- a = (uint8_t) nz;
- goto loop;
- }
-
- case 0x0B: // ASL dp
- c = 0;
- data += dp;
- goto rol_mem;
- case 0x1B: // ASL dp+X
- c = 0;
- case 0x3B: // ROL dp+X
- data = uint8_t (data + x);
- case 0x2B: // ROL dp
- data += dp;
- goto rol_mem;
- case 0x0C: // ASL abs
- c = 0;
- case 0x2C: // ROL abs
- data = READ_PROG16( pc );
- pc++;
- rol_mem:
- nz = (c >> 8) & 1;
- nz |= (c = READ( data ) << 1);
- WRITE( data, (uint8_t) nz );
- goto inc_pc_loop;
-
- case 0x4B: // LSR dp
- c = 0;
- data += dp;
- goto ror_mem;
- case 0x5B: // LSR dp+X
- c = 0;
- case 0x7B: // ROR dp+X
- data = uint8_t (data + x);
- case 0x6B: // ROR dp
- data += dp;
- goto ror_mem;
- case 0x4C: // LSR abs
- c = 0;
- case 0x6C: // ROR abs
- data = READ_PROG16( pc );
- pc++;
- ror_mem: {
- int temp = READ( data );
- nz = ((c >> 1) & 0x80) | (temp >> 1);
- c = temp << 8;
- WRITE( data, nz );
- goto inc_pc_loop;
- }
-
- case 0x9F: // XCN
- nz = a = (a >> 4) | uint8_t (a << 4);
- goto loop;
-
-// 8. 16-BIT TRANSMISION COMMANDS
-
- case 0xBA: // MOVW YA,dp
- a = READ_DP( data );
- nz = (a & 0x7F) | (a >> 1);
- y = READ_DP( uint8_t (data + 1) );
- nz |= y;
- goto inc_pc_loop;
-
- case 0xDA: // MOVW dp,YA
- WRITE_DP( data, a );
- WRITE_DP( uint8_t (data + 1), y );
- goto inc_pc_loop;
-
-// 9. 16-BIT OPERATION COMMANDS
-
- case 0x3A: // INCW dp
- case 0x1A:{// DECW dp
- data += dp;
-
- // low byte
- int temp = READ( data );
- temp += ((opcode >> 4) & 2) - 1; // +1 for INCW, -1 for DECW
- nz = ((temp >> 1) | temp) & 0x7F;
- WRITE( data, (uint8_t) temp );
-
- // high byte
- data = uint8_t (data + 1) + dp;
- temp >>= 8;
- temp = uint8_t (temp + READ( data ));
- nz |= temp;
- WRITE( data, temp );
-
- goto inc_pc_loop;
- }
-
- case 0x9A: // SUBW YA,dp
- case 0x7A: // ADDW YA,dp
- {
- // read 16-bit addend
- int temp = READ_DP( data );
- int sign = READ_DP( uint8_t (data + 1) );
- temp += 0x100 * sign;
- status &= ~(st_v | st_h);
-
- // to do: fix half-carry for SUBW (it's probably wrong)
-
- // for SUBW, negate and truncate to 16 bits
- if ( opcode & 0x80 ) {
- temp = (temp ^ 0xFFFF) + 1;
- sign = temp >> 8;
- }
-
- // add low byte (A)
- temp += a;
- a = (uint8_t) temp;
- nz = (temp | (temp >> 1)) & 0x7F;
-
- // add high byte (Y)
- temp >>= 8;
- c = y + temp;
- nz = (nz | c) & 0xFF;
-
- // half-carry (temporary avoids CodeWarrior optimizer bug)
- unsigned hc = (c & 15) - (y & 15);
- status |= (hc >> 4) & st_h;
-
- // overflow if sign of YA changed when previous sign and addend sign were same
- status |= (((c ^ y) & ~(y ^ sign)) >> 1) & st_v;
-
- y = (uint8_t) c;
-
- goto inc_pc_loop;
- }
-
- case 0x5A: { // CMPW YA,dp
- int temp = a - READ_DP( data );
- nz = ((temp >> 1) | temp) & 0x7F;
- temp = y + (temp >> 8);
- temp -= READ_DP( uint8_t (data + 1) );
- nz |= temp;
- c = ~temp;
- nz &= 0xFF;
- goto inc_pc_loop;
- }
-
-// 10. MULTIPLICATION & DIVISON COMMANDS
-
- case 0xCF: { // MUL YA
- unsigned temp = y * a;
- a = (uint8_t) temp;
- nz = ((temp >> 1) | temp) & 0x7F;
- y = temp >> 8;
- nz |= y;
- goto loop;
- }
-
- case 0x9E: // DIV YA,X
- {
- // behavior based on SPC CPU tests
-
- status &= ~(st_h | st_v);
-
- if ( (y & 15) >= (x & 15) )
- status |= st_h;
-
- if ( y >= x )
- status |= st_v;
-
- unsigned ya = y * 0x100 + a;
- if ( y < x * 2 )
- {
- a = ya / x;
- y = ya - a * x;
- }
- else
- {
- a = 255 - (ya - x * 0x200) / (256 - x);
- y = x + (ya - x * 0x200) % (256 - x);
- }
-
- nz = (uint8_t) a;
- a = (uint8_t) a;
-
- goto loop;
- }
-
-// 11. DECIMAL COMPENSATION COMMANDS
-
- // seem unused
- // case 0xDF: // DAA
- // case 0xBE: // DAS
-
-// 12. BRANCHING COMMANDS
-
- case 0x2F: // BRA rel
- pc += (BOOST::int8_t) data;
- goto inc_pc_loop;
-
- case 0x30: // BMI
- BRANCH( IS_NEG )
-
- case 0x10: // BPL
- BRANCH( !IS_NEG )
-
- case 0xB0: // BCS
- BRANCH( c & 0x100 )
-
- case 0x90: // BCC
- BRANCH( !(c & 0x100) )
-
- case 0x70: // BVS
- BRANCH( status & st_v )
-
- case 0x50: // BVC
- BRANCH( !(status & st_v) )
-
- case 0x03: // BBS dp.bit,rel
- case 0x23:
- case 0x43:
- case 0x63:
- case 0x83:
- case 0xA3:
- case 0xC3:
- case 0xE3:
- pc++;
- if ( (READ_DP( data ) >> (opcode >> 5)) & 1 )
- goto cbranch_taken_loop;
- goto inc_pc_loop;
-
- case 0x13: // BBC dp.bit,rel
- case 0x33:
- case 0x53:
- case 0x73:
- case 0x93:
- case 0xB3:
- case 0xD3:
- case 0xF3:
- pc++;
- if ( !((READ_DP( data ) >> (opcode >> 5)) & 1) )
- goto cbranch_taken_loop;
- goto inc_pc_loop;
-
- case 0xDE: // CBNE dp+X,rel
- data = uint8_t (data + x);
- // fall through
- case 0x2E: // CBNE dp,rel
- pc++;
- if ( READ_DP( data ) != a )
- goto cbranch_taken_loop;
- goto inc_pc_loop;
-
- case 0xFE: // DBNZ Y,rel
- y = uint8_t (y - 1);
- BRANCH( y )
-
- case 0x6E: { // DBNZ dp,rel
- pc++;
- unsigned temp = READ_DP( data ) - 1;
- WRITE_DP( (uint8_t) data, (uint8_t) temp );
- if ( temp )
- goto cbranch_taken_loop;
- goto inc_pc_loop;
- }
-
- case 0x1F: // JMP (abs+X)
- pc = READ_PROG16( pc ) + x;
- // fall through
- case 0x5F: // JMP abs
- pc = READ_PROG16( pc );
- goto loop;
-
-// 13. SUB-ROUTINE CALL RETURN COMMANDS
-
- case 0x0F:{// BRK
- check( false ); // untested
- PUSH16( pc + 1 );
- pc = READ_PROG16( 0xFFDE ); // vector address verified
- int temp;
- CALC_STATUS( temp );
- PUSH( temp );
- status = (status | st_b) & ~st_i;
- goto loop;
- }
-
- case 0x4F: // PCALL offset
- pc++;
- PUSH16( pc );
- pc = 0xFF00 + data;
- goto loop;
-
- case 0x01: // TCALL n
- case 0x11:
- case 0x21:
- case 0x31:
- case 0x41:
- case 0x51:
- case 0x61:
- case 0x71:
- case 0x81:
- case 0x91:
- case 0xA1:
- case 0xB1:
- case 0xC1:
- case 0xD1:
- case 0xE1:
- case 0xF1:
- PUSH16( pc );
- pc = READ_PROG16( 0xFFDE - (opcode >> 3) );
- goto loop;
-
-// 14. STACK OPERATION COMMANDS
-
- {
- int temp;
- case 0x7F: // RET1
- temp = POP();
- pc = POP();
- pc |= POP() << 8;
- goto set_status;
- case 0x8E: // POP PSW
- temp = POP();
- set_status:
- SET_STATUS( temp );
- goto loop;
- }
-
- case 0x0D: { // PUSH PSW
- int temp;
- CALC_STATUS( temp );
- PUSH( temp );
- goto loop;
- }
-
- case 0x2D: // PUSH A
- PUSH( a );
- goto loop;
-
- case 0x4D: // PUSH X
- PUSH( x );
- goto loop;
-
- case 0x6D: // PUSH Y
- PUSH( y );
- goto loop;
-
- case 0xAE: // POP A
- a = POP();
- goto loop;
-
- case 0xCE: // POP X
- x = POP();
- goto loop;
-
- case 0xEE: // POP Y
- y = POP();
- goto loop;
-
-// 15. BIT OPERATION COMMANDS
-
- case 0x02: // SET1
- case 0x22:
- case 0x42:
- case 0x62:
- case 0x82:
- case 0xA2:
- case 0xC2:
- case 0xE2:
- case 0x12: // CLR1
- case 0x32:
- case 0x52:
- case 0x72:
- case 0x92:
- case 0xB2:
- case 0xD2:
- case 0xF2: {
- data += dp;
- int bit = 1 << (opcode >> 5);
- int mask = ~bit;
- if ( opcode & 0x10 )
- bit = 0;
- WRITE( data, (READ( data ) & mask) | bit );
- goto inc_pc_loop;
- }
-
- case 0x0E: // TSET1 abs
- case 0x4E:{// TCLR1 abs
- data = READ_PROG16( pc );
- pc += 2;
- unsigned temp = READ( data );
- nz = temp & a;
- temp &= ~a;
- if ( !(opcode & 0x40) )
- temp |= a;
- WRITE( data, temp );
- goto loop;
- }
-
- case 0x4A: // AND1 C,mem.bit
- c &= mem_bit( pc );
- pc += 2;
- goto loop;
-
- case 0x6A: // AND1 C,/mem.bit
- check( false ); // untested
- c &= ~mem_bit( pc );
- pc += 2;
- goto loop;
-
- case 0x0A: // OR1 C,mem.bit
- check( false ); // untested
- c |= mem_bit( pc );
- pc += 2;
- goto loop;
-
- case 0x2A: // OR1 C,/mem.bit
- check( false ); // untested
- c |= ~mem_bit( pc );
- pc += 2;
- goto loop;
-
- case 0x8A: // EOR1 C,mem.bit
- c ^= mem_bit( pc );
- pc += 2;
- goto loop;
-
- case 0xEA: { // NOT1 mem.bit
- data = READ_PROG16( pc );
- pc += 2;
- unsigned temp = READ( data & 0x1FFF );
- temp ^= 1 << (data >> 13);
- WRITE( data & 0x1FFF, temp );
- goto loop;
- }
-
- case 0xCA: { // MOV1 mem.bit,C
- data = READ_PROG16( pc );
- pc += 2;
- unsigned temp = READ( data & 0x1FFF );
- unsigned bit = data >> 13;
- temp = (temp & ~(1 << bit)) | (((c >> 8) & 1) << bit);
- WRITE( data & 0x1FFF, temp );
- goto loop;
- }
-
- case 0xAA: // MOV1 C,mem.bit
- c = mem_bit( pc );
- pc += 2;
- goto loop;
-
-// 16. PROGRAM STATUS FLAG OPERATION COMMANDS
-
- case 0x60: // CLRC
- c = 0;
- goto loop;
-
- case 0x80: // SETC
- c = ~0;
- goto loop;
-
- case 0xED: // NOTC
- c ^= 0x100;
- goto loop;
-
- case 0xE0: // CLRV
- status &= ~(st_v | st_h);
- goto loop;
-
- case 0x20: // CLRP
- dp = 0;
- goto loop;
-
- case 0x40: // SETP
- dp = 0x100;
- goto loop;
-
- case 0xA0: // EI
- check( false ); // untested
- status |= st_i;
- goto loop;
-
- case 0xC0: // DI
- check( false ); // untested
- status &= ~st_i;
- goto loop;
-
-// 17. OTHER COMMANDS
-
- case 0x00: // NOP
- goto loop;
-
- //case 0xEF: // SLEEP
- //case 0xFF: // STOP
-
- } // switch
-
- // unhandled instructions fall out of switch so emulator can catch them
-
-stop:
- pc--;
-
- {
- int temp;
- CALC_STATUS( temp );
- r.status = (uint8_t) temp;
- }
-
- r.pc = pc;
- r.sp = (uint8_t) GET_SP();
- r.a = (uint8_t) a;
- r.x = (uint8_t) x;
- r.y = (uint8_t) y;
-
- return remain_;
-}
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Spc_Cpu.h b/plugins/gme/game-music-emu-0.5.5/gme/Spc_Cpu.h
deleted file mode 100644
index 40f55aea..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Spc_Cpu.h
+++ /dev/null
@@ -1,57 +0,0 @@
-// Super Nintendo (SNES) SPC-700 CPU emulator
-
-// Game_Music_Emu 0.5.5
-#ifndef SPC_CPU_H
-#define SPC_CPU_H
-
-#include "blargg_common.h"
-
-typedef unsigned spc_addr_t;
-typedef blargg_long spc_time_t;
-
-class Snes_Spc;
-
-class Spc_Cpu {
- typedef BOOST::uint8_t uint8_t;
- uint8_t* const ram;
-public:
- // Keeps pointer to 64K RAM
- Spc_Cpu( Snes_Spc* spc, uint8_t* ram );
-
- // SPC-700 registers. *Not* kept updated during a call to run().
- struct registers_t {
- long pc; // more than 16 bits to allow overflow detection
- uint8_t a;
- uint8_t x;
- uint8_t y;
- uint8_t status;
- uint8_t sp;
- } r;
-
- // Run CPU for at least 'count' cycles. Return the number of cycles remaining
- // when emulation stopped (negative if extra cycles were emulated). Emulation
- // stops when there are no more remaining cycles or an unhandled instruction
- // is encountered (STOP, SLEEP, and any others not yet implemented). In the
- // latter case, the return value is greater than zero.
- spc_time_t run( spc_time_t count );
-
- // Number of clock cycles remaining for current run() call
- spc_time_t remain() const;
-
- // Access memory as the emulated CPU does
- int read ( spc_addr_t );
- void write( spc_addr_t, int );
-
-private:
- // noncopyable
- Spc_Cpu( const Spc_Cpu& );
- Spc_Cpu& operator = ( const Spc_Cpu& );
- unsigned mem_bit( spc_addr_t );
-
- spc_time_t remain_;
- Snes_Spc& emu;
-};
-
-inline spc_time_t Spc_Cpu::remain() const { return remain_; }
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Spc_Dsp.cpp b/plugins/gme/game-music-emu-0.5.5/gme/Spc_Dsp.cpp
deleted file mode 100644
index 814ff2bd..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Spc_Dsp.cpp
+++ /dev/null
@@ -1,666 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-// Based on Brad Martin's OpenSPC DSP emulator
-
-#include "Spc_Dsp.h"
-
-#include "blargg_endian.h"
-#include <string.h>
-
-/* Copyright (C) 2002 Brad Martin */
-/* Copyright (C) 2004-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-#ifdef BLARGG_ENABLE_OPTIMIZER
- #include BLARGG_ENABLE_OPTIMIZER
-#endif
-
-Spc_Dsp::Spc_Dsp( uint8_t* ram_ ) : ram( ram_ )
-{
- set_gain( 1.0 );
- mute_voices( 0 );
- disable_surround( false );
-
- assert( offsetof (globals_t,unused9 [2]) == register_count );
- assert( sizeof (voice) == register_count );
- blargg_verify_byte_order();
-}
-
-void Spc_Dsp::mute_voices( int mask )
-{
- for ( int i = 0; i < voice_count; i++ )
- voice_state [i].enabled = (mask >> i & 1) ? 31 : 7;
-}
-
-void Spc_Dsp::reset()
-{
- keys = 0;
- echo_ptr = 0;
- noise_count = 0;
- noise = 1;
- fir_offset = 0;
-
- g.flags = 0xE0; // reset, mute, echo off
- g.key_ons = 0;
-
- for ( int i = 0; i < voice_count; i++ )
- {
- voice_t& v = voice_state [i];
- v.on_cnt = 0;
- v.volume [0] = 0;
- v.volume [1] = 0;
- v.envstate = state_release;
- }
-
- memset( fir_buf, 0, sizeof fir_buf );
-}
-
-void Spc_Dsp::write( int i, int data )
-{
- require( (unsigned) i < register_count );
-
- reg [i] = data;
- int high = i >> 4;
- switch ( i & 0x0F )
- {
- // voice volume
- case 0:
- case 1: {
- short* volume = voice_state [high].volume;
- int left = (int8_t) reg [i & ~1];
- int right = (int8_t) reg [i | 1];
- volume [0] = left;
- volume [1] = right;
- // kill surround only if enabled and signs of volumes differ
- if ( left * right < surround_threshold )
- {
- if ( left < 0 )
- volume [0] = -left;
- else
- volume [1] = -right;
- }
- break;
- }
-
- // fir coefficients
- case 0x0F:
- fir_coeff [high] = (int8_t) data; // sign-extend
- break;
- }
-}
-
-// This table is for envelope timing. It represents the number of counts
-// that should be subtracted from the counter each sample period (32kHz).
-// The counter starts at 30720 (0x7800). Each count divides exactly into
-// 0x7800 without remainder.
-const int env_rate_init = 0x7800;
-static short const env_rates [0x20] =
-{
- 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 int env_range = 0x800;
-
-inline int Spc_Dsp::clock_envelope( int v )
-{ /* Return value is current
- * ENVX */
- raw_voice_t& raw_voice = this->voice [v];
- voice_t& voice = voice_state [v];
-
- int envx = voice.envx;
- if ( voice.envstate == state_release )
- {
- /*
- * Docs: "When in the state of "key off". the "click" sound is
- * prevented by the addition of the fixed value 1/256" WTF???
- * Alright, I'm going to choose to interpret that this way:
- * When a note is keyed off, start the RELEASE state, which
- * subtracts 1/256th each sample period (32kHz). Note there's
- * no need for a count because it always happens every update.
- */
- envx -= env_range / 256;
- if ( envx <= 0 )
- {
- envx = 0;
- keys &= ~(1 << v);
- return -1;
- }
- voice.envx = envx;
- raw_voice.envx = envx >> 8;
- return envx;
- }
-
- int cnt = voice.envcnt;
- int adsr1 = raw_voice.adsr [0];
- if ( adsr1 & 0x80 )
- {
- switch ( voice.envstate )
- {
- case state_attack: {
- // increase envelope by 1/64 each step
- int t = adsr1 & 15;
- if ( t == 15 )
- {
- envx += env_range / 2;
- }
- else
- {
- cnt -= env_rates [t * 2 + 1];
- if ( cnt > 0 )
- break;
- envx += env_range / 64;
- cnt = env_rate_init;
- }
- if ( envx >= env_range )
- {
- envx = env_range - 1;
- voice.envstate = state_decay;
- }
- voice.envx = envx;
- break;
- }
-
- case state_decay: {
- // Docs: "DR... [is multiplied] by the fixed value
- // 1-1/256." Well, at least that makes some sense.
- // Multiplying ENVX by 255/256 every time DECAY is
- // updated.
- cnt -= env_rates [((adsr1 >> 3) & 0xE) + 0x10];
- if ( cnt <= 0 )
- {
- cnt = env_rate_init;
- envx -= ((envx - 1) >> 8) + 1;
- voice.envx = envx;
- }
- int sustain_level = raw_voice.adsr [1] >> 5;
-
- if ( envx <= (sustain_level + 1) * 0x100 )
- voice.envstate = state_sustain;
- break;
- }
-
- case state_sustain:
- // Docs: "SR [is multiplied] by the fixed value 1-1/256."
- // Multiplying ENVX by 255/256 every time SUSTAIN is
- // updated.
- cnt -= env_rates [raw_voice.adsr [1] & 0x1F];
- if ( cnt <= 0 )
- {
- cnt = env_rate_init;
- envx -= ((envx - 1) >> 8) + 1;
- voice.envx = envx;
- }
- break;
-
- case state_release:
- // handled above
- break;
- }
- }
- else
- { /* GAIN mode is set */
- /*
- * Note: if the game switches between ADSR and GAIN modes
- * partway through, should the count be reset, or should it
- * continue from where it was? Does the DSP actually watch for
- * that bit to change, or does it just go along with whatever
- * it sees when it performs the update? I'm going to assume
- * the latter and not update the count, unless I see a game
- * that obviously wants the other behavior. The effect would
- * be pretty subtle, in any case.
- */
- int t = raw_voice.gain;
- if (t < 0x80)
- {
- envx = voice.envx = t << 4;
- }
- else switch (t >> 5)
- {
- case 4: /* Docs: "Decrease (linear): Subtraction
- * of the fixed value 1/64." */
- cnt -= env_rates [t & 0x1F];
- if (cnt > 0)
- break;
- cnt = env_rate_init;
- envx -= env_range / 64;
- if ( envx < 0 )
- {
- envx = 0;
- if ( voice.envstate == state_attack )
- voice.envstate = state_decay;
- }
- voice.envx = envx;
- break;
- case 5: /* Docs: "Drecrease <sic> (exponential):
- * Multiplication by the fixed value
- * 1-1/256." */
- cnt -= env_rates [t & 0x1F];
- if (cnt > 0)
- break;
- cnt = env_rate_init;
- envx -= ((envx - 1) >> 8) + 1;
- if ( envx < 0 )
- {
- envx = 0;
- if ( voice.envstate == state_attack )
- voice.envstate = state_decay;
- }
- voice.envx = envx;
- break;
- case 6: /* Docs: "Increase (linear): Addition of
- * the fixed value 1/64." */
- cnt -= env_rates [t & 0x1F];
- if (cnt > 0)
- break;
- cnt = env_rate_init;
- envx += env_range / 64;
- if ( envx >= env_range )
- envx = env_range - 1;
- voice.envx = envx;
- break;
- case 7: /* Docs: "Increase (bent line): Addition
- * of the constant 1/64 up to .75 of the
- * constaint <sic> 1/256 from .75 to 1." */
- cnt -= env_rates [t & 0x1F];
- if (cnt > 0)
- break;
- cnt = env_rate_init;
- if ( envx < env_range * 3 / 4 )
- envx += env_range / 64;
- else
- envx += env_range / 256;
- if ( envx >= env_range )
- envx = env_range - 1;
- voice.envx = envx;
- break;
- }
- }
- voice.envcnt = cnt;
- raw_voice.envx = envx >> 4;
- return envx;
-}
-
-// Clamp n into range -32768 <= n <= 32767
-inline int clamp_16( int n )
-{
- if ( (BOOST::int16_t) n != n )
- n = BOOST::int16_t (0x7FFF - (n >> 31));
- return n;
-}
-
-void Spc_Dsp::run( long count, short* out_buf )
-{
- // to do: make clock_envelope() inline so that this becomes a leaf function?
-
- // Should we just fill the buffer with silence? Flags won't be cleared
- // during this run so it seems it should keep resetting every sample.
- if ( g.flags & 0x80 )
- reset();
-
- struct src_dir {
- char start [2];
- char loop [2];
- };
-
- const src_dir* const sd = (src_dir*) &ram [g.wave_page * 0x100];
-
- int left_volume = g.left_volume;
- int right_volume = g.right_volume;
- if ( left_volume * right_volume < surround_threshold )
- right_volume = -right_volume; // kill global surround
- left_volume *= emu_gain;
- right_volume *= emu_gain;
-
- while ( --count >= 0 )
- {
- // Here we check for keys on/off. Docs say that successive writes
- // to KON/KOF must be separated by at least 2 Ts periods or risk
- // being neglected. Therefore DSP only looks at these during an
- // update, and not at the time of the write. Only need to do this
- // once however, since the regs haven't changed over the whole
- // period we need to catch up with.
-
- g.wave_ended &= ~g.key_ons; // Keying on a voice resets that bit in ENDX.
-
- if ( g.noise_enables )
- {
- noise_count -= env_rates [g.flags & 0x1F];
- if ( noise_count <= 0 )
- {
- noise_count = env_rate_init;
-
- noise_amp = BOOST::int16_t (noise * 2);
-
- // TODO: switch to Galios style
- int feedback = (noise << 13) ^ (noise << 14);
- noise = (feedback & 0x4000) | (noise >> 1);
- }
- }
-
- // What is the expected behavior when pitch modulation is enabled on
- // voice 0? Jurassic Park 2 does this. Assume 0 for now.
- blargg_long prev_outx = 0;
-
- int echol = 0;
- int echor = 0;
- int left = 0;
- int right = 0;
- for ( int vidx = 0; vidx < voice_count; vidx++ )
- {
- const int vbit = 1 << vidx;
- raw_voice_t& raw_voice = voice [vidx];
- voice_t& voice = voice_state [vidx];
-
- if ( voice.on_cnt && !--voice.on_cnt )
- {
- // key on
- keys |= vbit;
- voice.addr = GET_LE16( sd [raw_voice.waveform].start );
- voice.block_remain = 1;
- voice.envx = 0;
- voice.block_header = 0;
- voice.fraction = 0x3FFF; // decode three samples immediately
- voice.interp0 = 0; // BRR decoder filter uses previous two samples
- voice.interp1 = 0;
-
- // NOTE: Real SNES does *not* appear to initialize the
- // envelope counter to anything in particular. The first
- // cycle always seems to come at a random time sooner than
- // expected; as yet, I have been unable to find any
- // pattern. I doubt it will matter though, so we'll go
- // ahead and do the full time for now.
- voice.envcnt = env_rate_init;
- voice.envstate = state_attack;
- }
-
- if ( g.key_ons & vbit & ~g.key_offs )
- {
- // voice doesn't come on if key off is set
- g.key_ons &= ~vbit;
- voice.on_cnt = 8;
- }
-
- if ( keys & g.key_offs & vbit )
- {
- // key off
- voice.envstate = state_release;
- voice.on_cnt = 0;
- }
-
- int envx;
- if ( !(keys & vbit) || (envx = clock_envelope( vidx )) < 0 )
- {
- raw_voice.envx = 0;
- raw_voice.outx = 0;
- prev_outx = 0;
- continue;
- }
-
- // Decode samples when fraction >= 1.0 (0x1000)
- for ( int n = voice.fraction >> 12; --n >= 0; )
- {
- if ( !--voice.block_remain )
- {
- if ( voice.block_header & 1 )
- {
- g.wave_ended |= vbit;
-
- if ( voice.block_header & 2 )
- {
- // verified (played endless looping sample and ENDX was set)
- voice.addr = GET_LE16( sd [raw_voice.waveform].loop );
- }
- else
- {
- // first block was end block; don't play anything (verified)
- goto sample_ended; // to do: find alternative to goto
- }
- }
-
- voice.block_header = ram [voice.addr++];
- voice.block_remain = 16; // nybbles
- }
-
- // if next block has end flag set, *this* block ends *early* (verified)
- if ( voice.block_remain == 9 && (ram [voice.addr + 5] & 3) == 1 &&
- (voice.block_header & 3) != 3 )
- {
- sample_ended:
- g.wave_ended |= vbit;
- keys &= ~vbit;
- raw_voice.envx = 0;
- voice.envx = 0;
- // add silence samples to interpolation buffer
- do
- {
- voice.interp3 = voice.interp2;
- voice.interp2 = voice.interp1;
- voice.interp1 = voice.interp0;
- voice.interp0 = 0;
- }
- while ( --n >= 0 );
- break;
- }
-
- int delta = ram [voice.addr];
- if ( voice.block_remain & 1 )
- {
- delta <<= 4; // use lower nybble
- voice.addr++;
- }
-
- // Use sign-extended upper nybble
- delta = int8_t (delta) >> 4;
-
- // For invalid ranges (D,E,F): if the nybble is negative,
- // the result is F000. If positive, 0000. Nothing else
- // like previous range, etc seems to have any effect. If
- // range is valid, do the shift normally. Note these are
- // both shifted right once to do the filters properly, but
- // the output will be shifted back again at the end.
- int shift = voice.block_header >> 4;
- delta = (delta << shift) >> 1;
- if ( shift > 0x0C )
- delta = (delta >> 14) & ~0x7FF;
-
- // One, two and three point IIR filters
- int smp1 = voice.interp0;
- int smp2 = voice.interp1;
- if ( voice.block_header & 8 )
- {
- delta += smp1;
- delta -= smp2 >> 1;
- if ( !(voice.block_header & 4) )
- {
- delta += (-smp1 - (smp1 >> 1)) >> 5;
- delta += smp2 >> 5;
- }
- else
- {
- delta += (-smp1 * 13) >> 7;
- delta += (smp2 + (smp2 >> 1)) >> 4;
- }
- }
- else if ( voice.block_header & 4 )
- {
- delta += smp1 >> 1;
- delta += (-smp1) >> 5;
- }
-
- voice.interp3 = voice.interp2;
- voice.interp2 = smp2;
- voice.interp1 = smp1;
- voice.interp0 = BOOST::int16_t (clamp_16( delta ) * 2); // sign-extend
- }
-
- // rate (with possible modulation)
- int rate = GET_LE16( raw_voice.rate ) & 0x3FFF;
- if ( g.pitch_mods & vbit )
- rate = (rate * (prev_outx + 32768)) >> 15;
-
- // Gaussian interpolation using most recent 4 samples
- int index = voice.fraction >> 2 & 0x3FC;
- voice.fraction = (voice.fraction & 0x0FFF) + rate;
- const BOOST::int16_t* table = (BOOST::int16_t const*) ((char const*) gauss + index);
- const BOOST::int16_t* table2 = (BOOST::int16_t const*) ((char const*) gauss + (255*4 - index));
- int s = ((table [0] * voice.interp3) >> 12) +
- ((table [1] * voice.interp2) >> 12) +
- ((table2 [1] * voice.interp1) >> 12);
- s = (BOOST::int16_t) (s * 2);
- s += (table2 [0] * voice.interp0) >> 11 & ~1;
- int output = clamp_16( s );
- if ( g.noise_enables & vbit )
- output = noise_amp;
-
- // scale output and set outx values
- output = (output * envx) >> 11 & ~1;
-
- // output and apply muting (by setting voice.enabled to 31)
- // if voice is externally disabled (not a SNES feature)
- int l = (voice.volume [0] * output) >> voice.enabled;
- int r = (voice.volume [1] * output) >> voice.enabled;
- prev_outx = output;
- raw_voice.outx = int8_t (output >> 8);
- if ( g.echo_ons & vbit )
- {
- echol += l;
- echor += r;
- }
- left += l;
- right += r;
- }
- // end of channel loop
-
- // main volume control
- left = (left * left_volume ) >> (7 + emu_gain_bits);
- right = (right * right_volume) >> (7 + emu_gain_bits);
-
- // Echo FIR filter
-
- // read feedback from echo buffer
- int echo_ptr = this->echo_ptr;
- uint8_t* echo_buf = &ram [(g.echo_page * 0x100 + echo_ptr) & 0xFFFF];
- echo_ptr += 4;
- if ( echo_ptr >= (g.echo_delay & 15) * 0x800 )
- echo_ptr = 0;
- int fb_left = (BOOST::int16_t) GET_LE16( echo_buf ); // sign-extend
- int fb_right = (BOOST::int16_t) GET_LE16( echo_buf + 2 ); // sign-extend
- this->echo_ptr = echo_ptr;
-
- // put samples in history ring buffer
- const int fir_offset = this->fir_offset;
- short (*fir_pos) [2] = &fir_buf [fir_offset];
- this->fir_offset = (fir_offset + 7) & 7; // move backwards one step
- fir_pos [0] [0] = (short) fb_left;
- fir_pos [0] [1] = (short) fb_right;
- fir_pos [8] [0] = (short) fb_left; // duplicate at +8 eliminates wrap checking below
- fir_pos [8] [1] = (short) fb_right;
-
- // FIR
- fb_left = fb_left * fir_coeff [7] +
- fir_pos [1] [0] * fir_coeff [6] +
- fir_pos [2] [0] * fir_coeff [5] +
- fir_pos [3] [0] * fir_coeff [4] +
- fir_pos [4] [0] * fir_coeff [3] +
- fir_pos [5] [0] * fir_coeff [2] +
- fir_pos [6] [0] * fir_coeff [1] +
- fir_pos [7] [0] * fir_coeff [0];
-
- fb_right = fb_right * fir_coeff [7] +
- fir_pos [1] [1] * fir_coeff [6] +
- fir_pos [2] [1] * fir_coeff [5] +
- fir_pos [3] [1] * fir_coeff [4] +
- fir_pos [4] [1] * fir_coeff [3] +
- fir_pos [5] [1] * fir_coeff [2] +
- fir_pos [6] [1] * fir_coeff [1] +
- fir_pos [7] [1] * fir_coeff [0];
-
- left += (fb_left * g.left_echo_volume ) >> 14;
- right += (fb_right * g.right_echo_volume) >> 14;
-
- // echo buffer feedback
- if ( !(g.flags & 0x20) )
- {
- echol += (fb_left * g.echo_feedback) >> 14;
- echor += (fb_right * g.echo_feedback) >> 14;
- SET_LE16( echo_buf , clamp_16( echol ) );
- SET_LE16( echo_buf + 2, clamp_16( echor ) );
- }
-
- if ( out_buf )
- {
- // write final samples
-
- left = clamp_16( left );
- right = clamp_16( right );
-
- int mute = g.flags & 0x40;
-
- out_buf [0] = (short) left;
- out_buf [1] = (short) right;
- out_buf += 2;
-
- // muting
- if ( mute )
- {
- out_buf [-2] = 0;
- out_buf [-1] = 0;
- }
- }
- }
-}
-
-// Base normal_gauss table is almost exactly (with an error of 0 or -1 for each entry):
-// int normal_gauss [512];
-// normal_gauss [i] = exp((i-511)*(i-511)*-9.975e-6)*pow(sin(0.00307096*i),1.7358)*1304.45
-
-// Interleved gauss table (to improve cache coherency).
-// gauss [i * 2 + j] = normal_gauss [(1 - j) * 256 + i]
-const BOOST::int16_t Spc_Dsp::gauss [512] =
-{
- 370,1305, 366,1305, 362,1304, 358,1304, 354,1304, 351,1304, 347,1304, 343,1303,
- 339,1303, 336,1303, 332,1302, 328,1302, 325,1301, 321,1300, 318,1300, 314,1299,
- 311,1298, 307,1297, 304,1297, 300,1296, 297,1295, 293,1294, 290,1293, 286,1292,
- 283,1291, 280,1290, 276,1288, 273,1287, 270,1286, 267,1284, 263,1283, 260,1282,
- 257,1280, 254,1279, 251,1277, 248,1275, 245,1274, 242,1272, 239,1270, 236,1269,
- 233,1267, 230,1265, 227,1263, 224,1261, 221,1259, 218,1257, 215,1255, 212,1253,
- 210,1251, 207,1248, 204,1246, 201,1244, 199,1241, 196,1239, 193,1237, 191,1234,
- 188,1232, 186,1229, 183,1227, 180,1224, 178,1221, 175,1219, 173,1216, 171,1213,
- 168,1210, 166,1207, 163,1205, 161,1202, 159,1199, 156,1196, 154,1193, 152,1190,
- 150,1186, 147,1183, 145,1180, 143,1177, 141,1174, 139,1170, 137,1167, 134,1164,
- 132,1160, 130,1157, 128,1153, 126,1150, 124,1146, 122,1143, 120,1139, 118,1136,
- 117,1132, 115,1128, 113,1125, 111,1121, 109,1117, 107,1113, 106,1109, 104,1106,
- 102,1102, 100,1098, 99,1094, 97,1090, 95,1086, 94,1082, 92,1078, 90,1074,
- 89,1070, 87,1066, 86,1061, 84,1057, 83,1053, 81,1049, 80,1045, 78,1040,
- 77,1036, 76,1032, 74,1027, 73,1023, 71,1019, 70,1014, 69,1010, 67,1005,
- 66,1001, 65, 997, 64, 992, 62, 988, 61, 983, 60, 978, 59, 974, 58, 969,
- 56, 965, 55, 960, 54, 955, 53, 951, 52, 946, 51, 941, 50, 937, 49, 932,
- 48, 927, 47, 923, 46, 918, 45, 913, 44, 908, 43, 904, 42, 899, 41, 894,
- 40, 889, 39, 884, 38, 880, 37, 875, 36, 870, 36, 865, 35, 860, 34, 855,
- 33, 851, 32, 846, 32, 841, 31, 836, 30, 831, 29, 826, 29, 821, 28, 816,
- 27, 811, 27, 806, 26, 802, 25, 797, 24, 792, 24, 787, 23, 782, 23, 777,
- 22, 772, 21, 767, 21, 762, 20, 757, 20, 752, 19, 747, 19, 742, 18, 737,
- 17, 732, 17, 728, 16, 723, 16, 718, 15, 713, 15, 708, 15, 703, 14, 698,
- 14, 693, 13, 688, 13, 683, 12, 678, 12, 674, 11, 669, 11, 664, 11, 659,
- 10, 654, 10, 649, 10, 644, 9, 640, 9, 635, 9, 630, 8, 625, 8, 620,
- 8, 615, 7, 611, 7, 606, 7, 601, 6, 596, 6, 592, 6, 587, 6, 582,
- 5, 577, 5, 573, 5, 568, 5, 563, 4, 559, 4, 554, 4, 550, 4, 545,
- 4, 540, 3, 536, 3, 531, 3, 527, 3, 522, 3, 517, 2, 513, 2, 508,
- 2, 504, 2, 499, 2, 495, 2, 491, 2, 486, 1, 482, 1, 477, 1, 473,
- 1, 469, 1, 464, 1, 460, 1, 456, 1, 451, 1, 447, 1, 443, 1, 439,
- 0, 434, 0, 430, 0, 426, 0, 422, 0, 418, 0, 414, 0, 410, 0, 405,
- 0, 401, 0, 397, 0, 393, 0, 389, 0, 385, 0, 381, 0, 378, 0, 374,
-};
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Spc_Dsp.h b/plugins/gme/game-music-emu-0.5.5/gme/Spc_Dsp.h
deleted file mode 100644
index 1e79870a..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Spc_Dsp.h
+++ /dev/null
@@ -1,152 +0,0 @@
-// Super Nintendo (SNES) SPC DSP emulator
-
-// Game_Music_Emu 0.5.5
-#ifndef SPC_DSP_H
-#define SPC_DSP_H
-
-#include "blargg_common.h"
-
-class Spc_Dsp {
- typedef BOOST::int8_t int8_t;
- typedef BOOST::uint8_t uint8_t;
-public:
-
- // Keeps pointer to 64K ram
- Spc_Dsp( uint8_t* ram );
-
- // Mute voice n if bit n (1 << n) of mask is clear.
- enum { voice_count = 8 };
- void mute_voices( int mask );
-
- // Clear state and silence everything.
- void reset();
-
- // Set gain, where 1.0 is normal. When greater than 1.0, output is clamped to
- // the 16-bit sample range.
- void set_gain( double );
-
- // If true, prevent channels and global volumes from being phase-negated
- void disable_surround( bool disable );
-
- // Read/write register 'n', where n ranges from 0 to register_count - 1.
- enum { register_count = 128 };
- int read ( int n );
- void write( int n, int );
-
- // Run DSP for 'count' samples. Write resulting samples to 'buf' if not NULL.
- void run( long count, short* buf = NULL );
-
-
-// End of public interface
-private:
-
- struct raw_voice_t {
- int8_t left_vol;
- int8_t right_vol;
- uint8_t rate [2];
- uint8_t waveform;
- uint8_t adsr [2]; // envelope rates for attack, decay, and sustain
- uint8_t gain; // envelope gain (if not using ADSR)
- int8_t envx; // current envelope level
- int8_t outx; // current sample
- int8_t unused [6];
- };
-
- struct globals_t {
- int8_t unused1 [12];
- int8_t left_volume; // 0C Main Volume Left (-.7)
- int8_t echo_feedback; // 0D Echo Feedback (-.7)
- int8_t unused2 [14];
- int8_t right_volume; // 1C Main Volume Right (-.7)
- int8_t unused3 [15];
- int8_t left_echo_volume; // 2C Echo Volume Left (-.7)
- uint8_t pitch_mods; // 2D Pitch Modulation on/off for each voice
- int8_t unused4 [14];
- int8_t right_echo_volume; // 3C Echo Volume Right (-.7)
- uint8_t noise_enables; // 3D Noise output on/off for each voice
- int8_t unused5 [14];
- uint8_t key_ons; // 4C Key On for each voice
- uint8_t echo_ons; // 4D Echo on/off for each voice
- int8_t unused6 [14];
- uint8_t key_offs; // 5C key off for each voice (instantiates release mode)
- uint8_t wave_page; // 5D source directory (wave table offsets)
- int8_t unused7 [14];
- uint8_t flags; // 6C flags and noise freq
- uint8_t echo_page; // 6D
- int8_t unused8 [14];
- uint8_t wave_ended; // 7C
- uint8_t echo_delay; // 7D ms >> 4
- char unused9 [2];
- };
-
- union {
- raw_voice_t voice [voice_count];
- uint8_t reg [register_count];
- globals_t g;
- };
-
- uint8_t* const ram;
-
- // Cache of echo FIR values for faster access
- short fir_coeff [voice_count];
-
- // fir_buf [i + 8] == fir_buf [i], to avoid wrap checking in FIR code
- short fir_buf [16] [2];
- int fir_offset; // (0 to 7)
-
- enum { emu_gain_bits = 8 };
- int emu_gain;
-
- int keyed_on; // 8-bits for 8 voices
- int keys;
-
- int echo_ptr;
- int noise_amp;
- int noise;
- int noise_count;
-
- int surround_threshold;
-
- static BOOST::int16_t const gauss [];
-
- enum state_t {
- state_attack,
- state_decay,
- state_sustain,
- state_release
- };
-
- struct voice_t {
- short volume [2];
- short fraction;// 12-bit fractional position
- short interp3; // most recent four decoded samples
- short interp2;
- short interp1;
- short interp0;
- short block_remain; // number of nybbles remaining in current block
- unsigned short addr;
- short block_header; // header byte from current block
- short envcnt;
- short envx;
- short on_cnt;
- short enabled; // 7 if enabled, 31 if disabled
- short envstate;
- short unused; // pad to power of 2
- };
-
- voice_t voice_state [voice_count];
-
- int clock_envelope( int );
-};
-
-inline void Spc_Dsp::disable_surround( bool disable ) { surround_threshold = disable ? 0 : -0x7FFF; }
-
-inline void Spc_Dsp::set_gain( double v ) { emu_gain = (int) (v * (1 << emu_gain_bits)); }
-
-inline int Spc_Dsp::read( int i )
-{
- assert( (unsigned) i < register_count );
- return reg [i];
-}
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Spc_Emu.cpp b/plugins/gme/game-music-emu-0.5.5/gme/Spc_Emu.cpp
deleted file mode 100644
index a5002bf7..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Spc_Emu.cpp
+++ /dev/null
@@ -1,328 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Spc_Emu.h"
-
-#include "blargg_endian.h"
-#include <stdlib.h>
-#include <string.h>
-
-/* Copyright (C) 2004-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-Spc_Emu::Spc_Emu()
-{
- set_type( gme_spc_type );
-
- static const char* const names [Snes_Spc::voice_count] = {
- "DSP 1", "DSP 2", "DSP 3", "DSP 4", "DSP 5", "DSP 6", "DSP 7", "DSP 8"
- };
- set_voice_names( names );
-
- set_gain( 1.4 );
-}
-
-Spc_Emu::~Spc_Emu() { }
-
-// Track info
-
-long const trailer_offset = 0x10200;
-
-byte const* Spc_Emu::trailer() const { return &file_data [min( file_size, trailer_offset )]; }
-
-long Spc_Emu::trailer_size() const { return max( 0L, file_size - trailer_offset ); }
-
-static void get_spc_xid6( byte const* begin, long size, track_info_t* out )
-{
- // header
- byte const* end = begin + size;
- if ( size < 8 || memcmp( begin, "xid6", 4 ) )
- {
- check( false );
- return;
- }
- long info_size = get_le32( begin + 4 );
- byte const* in = begin + 8;
- if ( end - in > info_size )
- {
- debug_printf( "Extra data after SPC xid6 info\n" );
- end = in + info_size;
- }
-
- int year = 0;
- char copyright [256 + 5];
- int copyright_len = 0;
- int const year_len = 5;
-
- while ( end - in >= 4 )
- {
- // header
- int id = in [0];
- int data = in [3] * 0x100 + in [2];
- int type = in [1];
- int len = type ? data : 0;
- in += 4;
- if ( len > end - in )
- {
- check( false );
- break; // block goes past end of data
- }
-
- // handle specific block types
- char* field = 0;
- switch ( id )
- {
- case 0x01: field = out->song; break;
- case 0x02: field = out->game; break;
- case 0x03: field = out->author; break;
- case 0x04: field = out->dumper; break;
- case 0x07: field = out->comment; break;
- case 0x14: year = data; break;
-
- //case 0x30: // intro length
- // Many SPCs have intro length set wrong for looped tracks, making it useless
- /*
- case 0x30:
- check( len == 4 );
- if ( len >= 4 )
- {
- out->intro_length = get_le32( in ) / 64;
- if ( out->length > 0 )
- {
- long loop = out->length - out->intro_length;
- if ( loop >= 2000 )
- out->loop_length = loop;
- }
- }
- break;
- */
-
- case 0x13:
- copyright_len = min( len, (int) sizeof copyright - year_len );
- memcpy( &copyright [year_len], in, copyright_len );
- break;
-
- default:
- if ( id < 0x01 || (id > 0x07 && id < 0x10) ||
- (id > 0x14 && id < 0x30) || id > 0x36 )
- debug_printf( "Unknown SPC xid6 block: %X\n", (int) id );
- break;
- }
- if ( field )
- {
- check( type == 1 );
- Gme_File::copy_field_( field, (char const*) in, len );
- }
-
- // skip to next block
- in += len;
-
- // blocks are supposed to be 4-byte aligned with zero-padding...
- byte const* unaligned = in;
- while ( (in - begin) & 3 && in < end )
- {
- if ( *in++ != 0 )
- {
- // ...but some files have no padding
- in = unaligned;
- debug_printf( "SPC info tag wasn't properly padded to align\n" );
- break;
- }
- }
- }
-
- char* p = &copyright [year_len];
- if ( year )
- {
- *--p = ' ';
- for ( int n = 4; n--; )
- {
- *--p = char (year % 10 + '0');
- year /= 10;
- }
- copyright_len += year_len;
- }
- if ( copyright_len )
- Gme_File::copy_field_( out->copyright, p, copyright_len );
-
- check( in == end );
-}
-
-static void get_spc_info( Spc_Emu::header_t const& h, byte const* xid6, long xid6_size,
- track_info_t* out )
-{
- // decode length (can be in text or binary format, sometimes ambiguous ugh)
- long len_secs = 0;
- for ( int i = 0; i < 3; i++ )
- {
- unsigned n = h.len_secs [i] - '0';
- if ( n > 9 )
- {
- // ignore single-digit text lengths
- // (except if author field is present and begins at offset 1, ugh)
- if ( i == 1 && (h.author [0] || !h.author [1]) )
- len_secs = 0;
- break;
- }
- len_secs *= 10;
- len_secs += n;
- }
- if ( !len_secs || len_secs > 0x1FFF )
- len_secs = get_le16( h.len_secs );
- if ( len_secs < 0x1FFF )
- out->length = len_secs * 1000;
-
- int offset = (h.author [0] < ' ' || unsigned (h.author [0] - '0') <= 9);
- Gme_File::copy_field_( out->author, &h.author [offset], sizeof h.author - offset );
-
- GME_COPY_FIELD( h, out, song );
- GME_COPY_FIELD( h, out, game );
- GME_COPY_FIELD( h, out, dumper );
- GME_COPY_FIELD( h, out, comment );
-
- if ( xid6_size )
- get_spc_xid6( xid6, xid6_size, out );
-}
-
-blargg_err_t Spc_Emu::track_info_( track_info_t* out, int ) const
-{
- get_spc_info( header(), trailer(), trailer_size(), out );
- return 0;
-}
-
-static blargg_err_t check_spc_header( void const* header )
-{
- if ( memcmp( header, "SNES-SPC700 Sound File Data", 27 ) )
- return gme_wrong_file_type;
- return 0;
-}
-
-struct Spc_File : Gme_Info_
-{
- Spc_Emu::header_t header;
- blargg_vector<byte> xid6;
-
- Spc_File() { set_type( gme_spc_type ); }
-
- blargg_err_t load_( Data_Reader& in )
- {
- long file_size = in.remain();
- if ( file_size < Snes_Spc::spc_file_size )
- return gme_wrong_file_type;
- RETURN_ERR( in.read( &header, Spc_Emu::header_size ) );
- RETURN_ERR( check_spc_header( header.tag ) );
- long const xid6_offset = 0x10200;
- long xid6_size = file_size - xid6_offset;
- if ( xid6_size > 0 )
- {
- RETURN_ERR( xid6.resize( xid6_size ) );
- RETURN_ERR( in.skip( xid6_offset - Spc_Emu::header_size ) );
- RETURN_ERR( in.read( xid6.begin(), xid6.size() ) );
- }
- return 0;
- }
-
- blargg_err_t track_info_( track_info_t* out, int ) const
- {
- get_spc_info( header, xid6.begin(), xid6.size(), out );
- return 0;
- }
-};
-
-static Music_Emu* new_spc_emu () { return BLARGG_NEW Spc_Emu ; }
-static Music_Emu* new_spc_file() { return BLARGG_NEW Spc_File; }
-
-static gme_type_t_ const gme_spc_type_ = { "Super Nintendo", 1, &new_spc_emu, &new_spc_file, "SPC", 0 };
-gme_type_t const gme_spc_type = &gme_spc_type_;
-
-
-// Setup
-
-blargg_err_t Spc_Emu::set_sample_rate_( long sample_rate )
-{
- apu.set_gain( gain() );
- if ( sample_rate != native_sample_rate )
- {
- RETURN_ERR( resampler.buffer_size( native_sample_rate / 20 * 2 ) );
- resampler.time_ratio( (double) native_sample_rate / sample_rate, 0.9965 );
- }
- return 0;
-}
-
-void Spc_Emu::mute_voices_( int m )
-{
- Music_Emu::mute_voices_( m );
- apu.mute_voices( m );
-}
-
-blargg_err_t Spc_Emu::load_mem_( byte const* in, long size )
-{
- assert( offsetof (header_t,unused2 [46]) == header_size );
- file_data = in;
- file_size = size;
- set_voice_count( Snes_Spc::voice_count );
- if ( size < Snes_Spc::spc_file_size )
- return gme_wrong_file_type;
- return check_spc_header( in );
-}
-
-// Emulation
-
-void Spc_Emu::set_tempo_( double t ) { apu.set_tempo( t ); }
-
-blargg_err_t Spc_Emu::start_track_( int track )
-{
- RETURN_ERR( Music_Emu::start_track_( track ) );
- resampler.clear();
- RETURN_ERR( apu.load_spc( file_data, file_size ) );
- apu.clear_echo();
- return 0;
-}
-
-blargg_err_t Spc_Emu::skip_( long count )
-{
- if ( sample_rate() != native_sample_rate )
- {
- count = long (count * resampler.ratio()) & ~1;
- count -= resampler.skip_input( count );
- }
-
- // TODO: shouldn't skip be adjusted for the 64 samples read afterwards?
-
- if ( count > 0 )
- RETURN_ERR( apu.skip( count ) );
-
- // eliminate pop due to resampler
- const int resampler_latency = 64;
- sample_t buf [resampler_latency];
- return play_( resampler_latency, buf );
-}
-
-blargg_err_t Spc_Emu::play_( long count, sample_t* out )
-{
- if ( sample_rate() == native_sample_rate )
- return apu.play( count, out );
-
- long remain = count;
- while ( remain > 0 )
- {
- remain -= resampler.read( &out [count - remain], remain );
- if ( remain > 0 )
- {
- long n = resampler.max_write();
- RETURN_ERR( apu.play( n, resampler.buffer() ) );
- resampler.write( n );
- }
- }
- check( remain == 0 );
- return 0;
-}
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Spc_Emu.h b/plugins/gme/game-music-emu-0.5.5/gme/Spc_Emu.h
deleted file mode 100644
index ab35649c..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Spc_Emu.h
+++ /dev/null
@@ -1,77 +0,0 @@
-// Super Nintendo SPC music file emulator
-
-// Game_Music_Emu 0.5.5
-#ifndef SPC_EMU_H
-#define SPC_EMU_H
-
-#include "Fir_Resampler.h"
-#include "Music_Emu.h"
-#include "Snes_Spc.h"
-
-class Spc_Emu : public Music_Emu {
-public:
- // The Super Nintendo hardware samples at 32kHz. Other sample rates are
- // handled by resampling the 32kHz output; emulation accuracy is not affected.
- enum { native_sample_rate = 32000 };
-
- // SPC file header
- enum { header_size = 0x100 };
- struct header_t
- {
- char tag [35];
- byte format;
- byte version;
- byte pc [2];
- byte a, x, y, psw, sp;
- byte unused [2];
- char song [32];
- char game [32];
- char dumper [16];
- char comment [32];
- byte date [11];
- byte len_secs [3];
- byte fade_msec [4];
- char author [32]; // sometimes first char should be skipped (see official SPC spec)
- byte mute_mask;
- byte emulator;
- byte unused2 [46];
- };
-
- // Header for currently loaded file
- header_t const& header() const { return *(header_t const*) file_data; }
-
- // Prevents channels and global volumes from being phase-negated
- void disable_surround( bool disable = true );
-
- static gme_type_t static_type() { return gme_spc_type; }
-
-public:
- // deprecated
- Music_Emu::load;
- blargg_err_t load( header_t const& h, Data_Reader& in ) // use Remaining_Reader
- { return load_remaining_( &h, sizeof h, in ); }
- byte const* trailer() const; // use track_info()
- long trailer_size() const;
-
-public:
- Spc_Emu();
- ~Spc_Emu();
-protected:
- blargg_err_t load_mem_( byte const*, long );
- blargg_err_t track_info_( track_info_t*, int track ) const;
- blargg_err_t set_sample_rate_( long );
- blargg_err_t start_track_( int );
- blargg_err_t play_( long, sample_t* );
- blargg_err_t skip_( long );
- void mute_voices_( int );
- void set_tempo_( double );
-private:
- byte const* file_data;
- long file_size;
- Fir_Resampler<24> resampler;
- Snes_Spc apu;
-};
-
-inline void Spc_Emu::disable_surround( bool b ) { apu.disable_surround( b ); }
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Vgm_Emu.cpp b/plugins/gme/game-music-emu-0.5.5/gme/Vgm_Emu.cpp
deleted file mode 100644
index 6a7cb98a..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Vgm_Emu.cpp
+++ /dev/null
@@ -1,416 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Vgm_Emu.h"
-
-#include "blargg_endian.h"
-#include <string.h>
-#include <math.h>
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-double const fm_gain = 3.0; // FM emulators are internally quieter to avoid 16-bit overflow
-double const rolloff = 0.990;
-double const oversample_factor = 1.5;
-
-Vgm_Emu::Vgm_Emu()
-{
- disable_oversampling_ = false;
- psg_rate = 0;
- set_type( gme_vgm_type );
-
- static int const types [8] = {
- wave_type | 1, wave_type | 0, wave_type | 2, noise_type | 0
- };
- set_voice_types( types );
-
- set_silence_lookahead( 1 ); // tracks should already be trimmed
-
- static equalizer_t const eq = { -14.0, 80 };
- set_equalizer( eq );
-}
-
-Vgm_Emu::~Vgm_Emu() { }
-
-// Track info
-
-static byte const* skip_gd3_str( byte const* in, byte const* end )
-{
- while ( end - in >= 2 )
- {
- in += 2;
- if ( !(in [-2] | in [-1]) )
- break;
- }
- return in;
-}
-
-static byte const* get_gd3_str( byte const* in, byte const* end, char* field )
-{
- byte const* mid = skip_gd3_str( in, end );
- int len = (mid - in) / 2 - 1;
- if ( len > 0 )
- {
- len = min( len, (int) Gme_File::max_field_ );
- field [len] = 0;
- for ( int i = 0; i < len; i++ )
- field [i] = (in [i * 2 + 1] ? '?' : in [i * 2]); // TODO: convert to utf-8
- }
- return mid;
-}
-
-static byte const* get_gd3_pair( byte const* in, byte const* end, char* field )
-{
- return skip_gd3_str( get_gd3_str( in, end, field ), end );
-}
-
-static void parse_gd3( byte const* in, byte const* end, track_info_t* out )
-{
- in = get_gd3_pair( in, end, out->song );
- in = get_gd3_pair( in, end, out->game );
- in = get_gd3_pair( in, end, out->system );
- in = get_gd3_pair( in, end, out->author );
- in = get_gd3_str ( in, end, out->copyright );
- in = get_gd3_pair( in, end, out->dumper );
- in = get_gd3_str ( in, end, out->comment );
-}
-
-int const gd3_header_size = 12;
-
-static long check_gd3_header( byte const* h, long remain )
-{
- if ( remain < gd3_header_size ) return 0;
- if ( memcmp( h, "Gd3 ", 4 ) ) return 0;
- if ( get_le32( h + 4 ) >= 0x200 ) return 0;
-
- long gd3_size = get_le32( h + 8 );
- if ( gd3_size > remain - gd3_header_size ) return 0;
-
- return gd3_size;
-}
-
-byte const* Vgm_Emu::gd3_data( int* size ) const
-{
- if ( size )
- *size = 0;
-
- long gd3_offset = get_le32( header().gd3_offset ) - 0x2C;
- if ( gd3_offset < 0 )
- return 0;
-
- byte const* gd3 = data + header_size + gd3_offset;
- long gd3_size = check_gd3_header( gd3, data_end - gd3 );
- if ( !gd3_size )
- return 0;
-
- if ( size )
- *size = gd3_size + gd3_header_size;
-
- return gd3;
-}
-
-static void get_vgm_length( Vgm_Emu::header_t const& h, track_info_t* out )
-{
- long length = get_le32( h.track_duration ) * 10 / 441;
- if ( length > 0 )
- {
- long loop = get_le32( h.loop_duration );
- if ( loop > 0 && get_le32( h.loop_offset ) )
- {
- out->loop_length = loop * 10 / 441;
- out->intro_length = length - out->loop_length;
- }
- else
- {
- out->length = length; // 1000 / 44100 (VGM files used 44100 as timebase)
- out->intro_length = length; // make it clear that track is no longer than length
- out->loop_length = 0;
- }
- }
-}
-
-blargg_err_t Vgm_Emu::track_info_( track_info_t* out, int ) const
-{
- get_vgm_length( header(), out );
-
- int size;
- byte const* gd3 = gd3_data( &size );
- if ( gd3 )
- parse_gd3( gd3 + gd3_header_size, gd3 + size, out );
-
- return 0;
-}
-
-static blargg_err_t check_vgm_header( Vgm_Emu::header_t const& h )
-{
- if ( memcmp( h.tag, "Vgm ", 4 ) )
- return gme_wrong_file_type;
- return 0;
-}
-
-struct Vgm_File : Gme_Info_
-{
- Vgm_Emu::header_t h;
- blargg_vector<byte> gd3;
-
- Vgm_File() { set_type( gme_vgm_type ); }
-
- blargg_err_t load_( Data_Reader& in )
- {
- long file_size = in.remain();
- if ( file_size <= Vgm_Emu::header_size )
- return gme_wrong_file_type;
-
- RETURN_ERR( in.read( &h, Vgm_Emu::header_size ) );
- RETURN_ERR( check_vgm_header( h ) );
-
- long gd3_offset = get_le32( h.gd3_offset ) - 0x2C;
- long remain = file_size - Vgm_Emu::header_size - gd3_offset;
- byte gd3_h [gd3_header_size];
- if ( gd3_offset > 0 && remain >= gd3_header_size )
- {
- RETURN_ERR( in.skip( gd3_offset ) );
- RETURN_ERR( in.read( gd3_h, sizeof gd3_h ) );
- long gd3_size = check_gd3_header( gd3_h, remain );
- if ( gd3_size )
- {
- RETURN_ERR( gd3.resize( gd3_size ) );
- RETURN_ERR( in.read( gd3.begin(), gd3.size() ) );
- }
- }
- return 0;
- }
-
- blargg_err_t track_info_( track_info_t* out, int ) const
- {
- get_vgm_length( h, out );
- if ( gd3.size() )
- parse_gd3( gd3.begin(), gd3.end(), out );
- return 0;
- }
-};
-
-static Music_Emu* new_vgm_emu () { return BLARGG_NEW Vgm_Emu ; }
-static Music_Emu* new_vgm_file() { return BLARGG_NEW Vgm_File; }
-
-static gme_type_t_ const gme_vgm_type_ = { "Sega SMS/Genesis", 1, &new_vgm_emu, &new_vgm_file, "VGM", 1 };
-gme_type_t const gme_vgm_type = &gme_vgm_type_;
-
-static gme_type_t_ const gme_vgz_type_ = { "Sega SMS/Genesis", 1, &new_vgm_emu, &new_vgm_file, "VGZ", 1 };
-gme_type_t const gme_vgz_type = &gme_vgz_type_;
-
-
-// Setup
-
-void Vgm_Emu::set_tempo_( double t )
-{
- if ( psg_rate )
- {
- vgm_rate = (long) (44100 * t + 0.5);
- blip_time_factor = (long) floor( double (1L << blip_time_bits) / vgm_rate * psg_rate + 0.5 );
- //debug_printf( "blip_time_factor: %ld\n", blip_time_factor );
- //debug_printf( "vgm_rate: %ld\n", vgm_rate );
- // TODO: remove? calculates vgm_rate more accurately (above differs at most by one Hz only)
- //blip_time_factor = (long) floor( double (1L << blip_time_bits) * psg_rate / 44100 / t + 0.5 );
- //vgm_rate = (long) floor( double (1L << blip_time_bits) * psg_rate / blip_time_factor + 0.5 );
-
- fm_time_factor = 2 + (long) floor( fm_rate * (1L << fm_time_bits) / vgm_rate + 0.5 );
- }
-}
-
-blargg_err_t Vgm_Emu::set_sample_rate_( long sample_rate )
-{
- RETURN_ERR( blip_buf.set_sample_rate( sample_rate, 1000 / 30 ) );
- return Classic_Emu::set_sample_rate_( sample_rate );
-}
-
-void Vgm_Emu::update_eq( blip_eq_t const& eq )
-{
- psg.treble_eq( eq );
- dac_synth.treble_eq( eq );
-}
-
-void Vgm_Emu::set_voice( int i, Blip_Buffer* c, Blip_Buffer* l, Blip_Buffer* r )
-{
- if ( i < psg.osc_count )
- psg.osc_output( i, c, l, r );
-}
-
-void Vgm_Emu::mute_voices_( int mask )
-{
- Classic_Emu::mute_voices_( mask );
- dac_synth.output( &blip_buf );
- if ( uses_fm )
- {
- psg.output( (mask & 0x80) ? 0 : &blip_buf );
- if ( ym2612.enabled() )
- {
- dac_synth.volume( (mask & 0x40) ? 0.0 : 0.1115 / 256 * fm_gain * gain() );
- ym2612.mute_voices( mask );
- }
-
- if ( ym2413.enabled() )
- {
- int m = mask & 0x3F;
- if ( mask & 0x20 )
- m |= 0x01E0; // channels 5-8
- if ( mask & 0x40 )
- m |= 0x3E00;
- ym2413.mute_voices( m );
- }
- }
-}
-
-blargg_err_t Vgm_Emu::load_mem_( byte const* new_data, long new_size )
-{
- assert( offsetof (header_t,unused2 [8]) == header_size );
-
- if ( new_size <= header_size )
- return gme_wrong_file_type;
-
- header_t const& h = *(header_t const*) new_data;
-
- RETURN_ERR( check_vgm_header( h ) );
-
- check( get_le32( h.version ) <= 0x150 );
-
- // psg rate
- psg_rate = get_le32( h.psg_rate );
- if ( !psg_rate )
- psg_rate = 3579545;
- blip_buf.clock_rate( psg_rate );
-
- data = new_data;
- data_end = new_data + new_size;
-
- // get loop
- loop_begin = data_end;
- if ( get_le32( h.loop_offset ) )
- loop_begin = &data [get_le32( h.loop_offset ) + offsetof (header_t,loop_offset)];
-
- set_voice_count( psg.osc_count );
-
- RETURN_ERR( setup_fm() );
-
- static const char* const fm_names [] = {
- "FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6", "PCM", "PSG"
- };
- static const char* const psg_names [] = { "Square 1", "Square 2", "Square 3", "Noise" };
- set_voice_names( uses_fm ? fm_names : psg_names );
-
- // do after FM in case output buffer is changed
- return Classic_Emu::setup_buffer( psg_rate );
-}
-
-blargg_err_t Vgm_Emu::setup_fm()
-{
- long ym2612_rate = get_le32( header().ym2612_rate );
- long ym2413_rate = get_le32( header().ym2413_rate );
- if ( ym2413_rate && get_le32( header().version ) < 0x110 )
- update_fm_rates( &ym2413_rate, &ym2612_rate );
-
- uses_fm = false;
-
- fm_rate = blip_buf.sample_rate() * oversample_factor;
-
- if ( ym2612_rate )
- {
- uses_fm = true;
- if ( disable_oversampling_ )
- fm_rate = ym2612_rate / 144.0;
- Dual_Resampler::setup( fm_rate / blip_buf.sample_rate(), rolloff, fm_gain * gain() );
- RETURN_ERR( ym2612.set_rate( fm_rate, ym2612_rate ) );
- ym2612.enable( true );
- set_voice_count( 8 );
- }
-
- if ( !uses_fm && ym2413_rate )
- {
- uses_fm = true;
- if ( disable_oversampling_ )
- fm_rate = ym2413_rate / 72.0;
- Dual_Resampler::setup( fm_rate / blip_buf.sample_rate(), rolloff, fm_gain * gain() );
- int result = ym2413.set_rate( fm_rate, ym2413_rate );
- if ( result == 2 )
- return "YM2413 FM sound isn't supported";
- CHECK_ALLOC( !result );
- ym2413.enable( true );
- set_voice_count( 8 );
- }
-
- if ( uses_fm )
- {
- RETURN_ERR( Dual_Resampler::reset( blip_buf.length() * blip_buf.sample_rate() / 1000 ) );
- psg.volume( 0.135 * fm_gain * gain() );
- }
- else
- {
- ym2612.enable( false );
- ym2413.enable( false );
- psg.volume( gain() );
- }
-
- return 0;
-}
-
-// Emulation
-
-blargg_err_t Vgm_Emu::start_track_( int track )
-{
- RETURN_ERR( Classic_Emu::start_track_( track ) );
- psg.reset( get_le16( header().noise_feedback ), header().noise_width );
-
- dac_disabled = -1;
- pos = data + header_size;
- pcm_data = pos;
- pcm_pos = pos;
- dac_amp = -1;
- vgm_time = 0;
- if ( get_le32( header().version ) >= 0x150 )
- {
- long data_offset = get_le32( header().data_offset );
- check( data_offset );
- if ( data_offset )
- pos += data_offset + offsetof (header_t,data_offset) - 0x40;
- }
-
- if ( uses_fm )
- {
- if ( ym2413.enabled() )
- ym2413.reset();
-
- if ( ym2612.enabled() )
- ym2612.reset();
-
- fm_time_offset = 0;
- blip_buf.clear();
- Dual_Resampler::clear();
- }
- return 0;
-}
-
-blargg_err_t Vgm_Emu::run_clocks( blip_time_t& time_io, int msec )
-{
- time_io = run_commands( msec * vgm_rate / 1000 );
- psg.end_frame( time_io );
- return 0;
-}
-
-blargg_err_t Vgm_Emu::play_( long count, sample_t* out )
-{
- if ( !uses_fm )
- return Classic_Emu::play_( count, out );
-
- Dual_Resampler::dual_play( count, out, blip_buf );
- return 0;
-}
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Vgm_Emu.h b/plugins/gme/game-music-emu-0.5.5/gme/Vgm_Emu.h
deleted file mode 100644
index bcfa506b..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Vgm_Emu.h
+++ /dev/null
@@ -1,84 +0,0 @@
-// Sega Master System/Mark III, Sega Genesis/Mega Drive, BBC Micro VGM music file emulator
-
-// Game_Music_Emu 0.5.5
-#ifndef VGM_EMU_H
-#define VGM_EMU_H
-
-#include "Vgm_Emu_Impl.h"
-
-// Emulates VGM music using SN76489/SN76496 PSG, YM2612, and YM2413 FM sound chips.
-// Supports custom sound buffer and frequency equalization when VGM uses just the PSG.
-// FM sound chips can be run at their proper rates, or slightly higher to reduce
-// aliasing on high notes. Currently YM2413 support requires that you supply a
-// YM2413 sound chip emulator. I can provide one I've modified to work with the library.
-class Vgm_Emu : public Vgm_Emu_Impl {
-public:
- // True if custom buffer and custom equalization are supported
- // TODO: move into Music_Emu and rename to something like supports_custom_buffer()
- bool is_classic_emu() const { return !uses_fm; }
-
- // Disable running FM chips at higher than normal rate. Will result in slightly
- // more aliasing of high notes.
- void disable_oversampling( bool disable = true ) { disable_oversampling_ = disable; }
-
- // VGM header format
- enum { header_size = 0x40 };
- struct header_t
- {
- char tag [4];
- byte data_size [4];
- byte version [4];
- byte psg_rate [4];
- byte ym2413_rate [4];
- byte gd3_offset [4];
- byte track_duration [4];
- byte loop_offset [4];
- byte loop_duration [4];
- byte frame_rate [4];
- byte noise_feedback [2];
- byte noise_width;
- byte unused1;
- byte ym2612_rate [4];
- byte ym2151_rate [4];
- byte data_offset [4];
- byte unused2 [8];
- };
-
- // Header for currently loaded file
- header_t const& header() const { return *(header_t const*) data; }
-
- static gme_type_t static_type() { return gme_vgm_type; }
-
-public:
- // deprecated
- Music_Emu::load;
- blargg_err_t load( header_t const& h, Data_Reader& in ) // use Remaining_Reader
- { return load_remaining_( &h, sizeof h, in ); }
- byte const* gd3_data( int* size_out = 0 ) const; // use track_info()
-
-public:
- Vgm_Emu();
- ~Vgm_Emu();
-protected:
- blargg_err_t track_info_( track_info_t*, int track ) const;
- blargg_err_t load_mem_( byte const*, long );
- blargg_err_t set_sample_rate_( long sample_rate );
- blargg_err_t start_track_( int );
- blargg_err_t play_( long count, sample_t* );
- blargg_err_t run_clocks( blip_time_t&, int );
- void set_tempo_( double );
- void mute_voices_( int mask );
- void set_voice( int, Blip_Buffer*, Blip_Buffer*, Blip_Buffer* );
- void update_eq( blip_eq_t const& );
-private:
- // removed; use disable_oversampling() and set_tempo() instead
- Vgm_Emu( bool oversample, double tempo = 1.0 );
- double fm_rate;
- long psg_rate;
- long vgm_rate;
- bool disable_oversampling_;
- bool uses_fm;
- blargg_err_t setup_fm();
-};
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Vgm_Emu_Impl.cpp b/plugins/gme/game-music-emu-0.5.5/gme/Vgm_Emu_Impl.cpp
deleted file mode 100644
index 5a9b724a..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Vgm_Emu_Impl.cpp
+++ /dev/null
@@ -1,314 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Vgm_Emu.h"
-
-#include <math.h>
-#include <string.h>
-#include "blargg_endian.h"
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-enum {
- cmd_gg_stereo = 0x4F,
- cmd_psg = 0x50,
- cmd_ym2413 = 0x51,
- cmd_ym2612_port0 = 0x52,
- cmd_ym2612_port1 = 0x53,
- cmd_ym2151 = 0x54,
- cmd_delay = 0x61,
- cmd_delay_735 = 0x62,
- cmd_delay_882 = 0x63,
- cmd_byte_delay = 0x64,
- cmd_end = 0x66,
- cmd_data_block = 0x67,
- cmd_short_delay = 0x70,
- cmd_pcm_delay = 0x80,
- cmd_pcm_seek = 0xE0,
-
- pcm_block_type = 0x00,
- ym2612_dac_port = 0x2A
-};
-
-inline int command_len( int command )
-{
- switch ( command >> 4 )
- {
- case 0x03:
- case 0x04:
- return 2;
-
- case 0x05:
- case 0x0A:
- case 0x0B:
- return 3;
-
- case 0x0C:
- case 0x0D:
- return 4;
-
- case 0x0E:
- case 0x0F:
- return 5;
- }
-
- check( false );
- return 1;
-}
-
-template<class Emu>
-inline void Ym_Emu<Emu>::begin_frame( short* p )
-{
- require( enabled() );
- out = p;
- last_time = 0;
-}
-
-template<class Emu>
-inline int Ym_Emu<Emu>::run_until( int time )
-{
- int count = time - last_time;
- if ( count > 0 )
- {
- if ( last_time < 0 )
- return false;
- last_time = time;
- short* p = out;
- out += count * Emu::out_chan_count;
- Emu::run( count, p );
- }
- return true;
-}
-
-inline Vgm_Emu_Impl::fm_time_t Vgm_Emu_Impl::to_fm_time( vgm_time_t t ) const
-{
- return (t * fm_time_factor + fm_time_offset) >> fm_time_bits;
-}
-
-inline blip_time_t Vgm_Emu_Impl::to_blip_time( vgm_time_t t ) const
-{
- return (t * blip_time_factor) >> blip_time_bits;
-}
-
-void Vgm_Emu_Impl::write_pcm( vgm_time_t vgm_time, int amp )
-{
- blip_time_t blip_time = to_blip_time( vgm_time );
- int old = dac_amp;
- int delta = amp - old;
- dac_amp = amp;
- if ( old >= 0 )
- dac_synth.offset_inline( blip_time, delta, &blip_buf );
- else
- dac_amp |= dac_disabled;
-}
-
-blip_time_t Vgm_Emu_Impl::run_commands( vgm_time_t end_time )
-{
- vgm_time_t vgm_time = this->vgm_time;
- byte const* pos = this->pos;
- if ( pos >= data_end )
- {
- set_track_ended();
- if ( pos > data_end )
- set_warning( "Stream lacked end event" );
- }
-
- while ( vgm_time < end_time && pos < data_end )
- {
- // TODO: be sure there are enough bytes left in stream for particular command
- // so we don't read past end
- switch ( *pos++ )
- {
- case cmd_end:
- pos = loop_begin; // if not looped, loop_begin == data_end
- break;
-
- case cmd_delay_735:
- vgm_time += 735;
- break;
-
- case cmd_delay_882:
- vgm_time += 882;
- break;
-
- case cmd_gg_stereo:
- psg.write_ggstereo( to_blip_time( vgm_time ), *pos++ );
- break;
-
- case cmd_psg:
- psg.write_data( to_blip_time( vgm_time ), *pos++ );
- break;
-
- case cmd_delay:
- vgm_time += pos [1] * 0x100L + pos [0];
- pos += 2;
- break;
-
- case cmd_byte_delay:
- vgm_time += *pos++;
- break;
-
- case cmd_ym2413:
- if ( ym2413.run_until( to_fm_time( vgm_time ) ) )
- ym2413.write( pos [0], pos [1] );
- pos += 2;
- break;
-
- case cmd_ym2612_port0:
- if ( pos [0] == ym2612_dac_port )
- {
- write_pcm( vgm_time, pos [1] );
- }
- else if ( ym2612.run_until( to_fm_time( vgm_time ) ) )
- {
- if ( pos [0] == 0x2B )
- {
- dac_disabled = (pos [1] >> 7 & 1) - 1;
- dac_amp |= dac_disabled;
- }
- ym2612.write0( pos [0], pos [1] );
- }
- pos += 2;
- break;
-
- case cmd_ym2612_port1:
- if ( ym2612.run_until( to_fm_time( vgm_time ) ) )
- ym2612.write1( pos [0], pos [1] );
- pos += 2;
- break;
-
- case cmd_data_block: {
- check( *pos == cmd_end );
- int type = pos [1];
- long size = get_le32( pos + 2 );
- pos += 6;
- if ( type == pcm_block_type )
- pcm_data = pos;
- pos += size;
- break;
- }
-
- case cmd_pcm_seek:
- pcm_pos = pcm_data + pos [3] * 0x1000000L + pos [2] * 0x10000L +
- pos [1] * 0x100L + pos [0];
- pos += 4;
- break;
-
- default:
- int cmd = pos [-1];
- switch ( cmd & 0xF0 )
- {
- case cmd_pcm_delay:
- write_pcm( vgm_time, *pcm_pos++ );
- vgm_time += cmd & 0x0F;
- break;
-
- case cmd_short_delay:
- vgm_time += (cmd & 0x0F) + 1;
- break;
-
- case 0x50:
- pos += 2;
- break;
-
- default:
- pos += command_len( cmd ) - 1;
- set_warning( "Unknown stream event" );
- }
- }
- }
- vgm_time -= end_time;
- this->pos = pos;
- this->vgm_time = vgm_time;
-
- return to_blip_time( end_time );
-}
-
-int Vgm_Emu_Impl::play_frame( blip_time_t blip_time, int sample_count, sample_t* buf )
-{
- // to do: timing is working mostly by luck
-
- int min_pairs = sample_count >> 1;
- int vgm_time = ((long) min_pairs << fm_time_bits) / fm_time_factor - 1;
- assert( to_fm_time( vgm_time ) <= min_pairs );
- int pairs = min_pairs;
- while ( (pairs = to_fm_time( vgm_time )) < min_pairs )
- vgm_time++;
- //debug_printf( "pairs: %d, min_pairs: %d\n", pairs, min_pairs );
-
- if ( ym2612.enabled() )
- {
- ym2612.begin_frame( buf );
- memset( buf, 0, pairs * stereo * sizeof *buf );
- }
- else if ( ym2413.enabled() )
- {
- ym2413.begin_frame( buf );
- }
-
- run_commands( vgm_time );
- ym2612.run_until( pairs );
- ym2413.run_until( pairs );
-
- fm_time_offset = (vgm_time * fm_time_factor + fm_time_offset) -
- ((long) pairs << fm_time_bits);
-
- psg.end_frame( blip_time );
-
- return pairs * stereo;
-}
-
-// Update pre-1.10 header FM rates by scanning commands
-void Vgm_Emu_Impl::update_fm_rates( long* ym2413_rate, long* ym2612_rate ) const
-{
- byte const* p = data + 0x40;
- while ( p < data_end )
- {
- switch ( *p )
- {
- case cmd_end:
- return;
-
- case cmd_psg:
- case cmd_byte_delay:
- p += 2;
- break;
-
- case cmd_delay:
- p += 3;
- break;
-
- case cmd_data_block:
- p += 7 + get_le32( p + 3 );
- break;
-
- case cmd_ym2413:
- *ym2612_rate = 0;
- return;
-
- case cmd_ym2612_port0:
- case cmd_ym2612_port1:
- *ym2612_rate = *ym2413_rate;
- *ym2413_rate = 0;
- return;
-
- case cmd_ym2151:
- *ym2413_rate = 0;
- *ym2612_rate = 0;
- return;
-
- default:
- p += command_len( *p );
- }
- }
-}
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Vgm_Emu_Impl.h b/plugins/gme/game-music-emu-0.5.5/gme/Vgm_Emu_Impl.h
deleted file mode 100644
index 8a73c328..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Vgm_Emu_Impl.h
+++ /dev/null
@@ -1,71 +0,0 @@
-// Low-level parts of Vgm_Emu
-
-// Game_Music_Emu 0.5.5
-#ifndef VGM_EMU_IMPL_H
-#define VGM_EMU_IMPL_H
-
-#include "Dual_Resampler.h"
-#include "Classic_Emu.h"
-#include "Ym2413_Emu.h"
-#include "Ym2612_Emu.h"
-#include "Sms_Apu.h"
-
-template<class Emu>
-class Ym_Emu : public Emu {
-protected:
- int last_time;
- short* out;
- enum { disabled_time = -1 };
-public:
- Ym_Emu() : last_time( disabled_time ), out( NULL ) { }
- void enable( bool b ) { last_time = b ? 0 : disabled_time; }
- bool enabled() const { return last_time != disabled_time; }
- void begin_frame( short* p );
- int run_until( int time );
-};
-
-class Vgm_Emu_Impl : public Classic_Emu, private Dual_Resampler {
-public:
- typedef Classic_Emu::sample_t sample_t;
-protected:
- enum { stereo = 2 };
-
- typedef int vgm_time_t;
-
- enum { fm_time_bits = 12 };
- typedef int fm_time_t;
- long fm_time_offset;
- int fm_time_factor;
- fm_time_t to_fm_time( vgm_time_t ) const;
-
- enum { blip_time_bits = 12 };
- int blip_time_factor;
- blip_time_t to_blip_time( vgm_time_t ) const;
-
- byte const* data;
- byte const* loop_begin;
- byte const* data_end;
- void update_fm_rates( long* ym2413_rate, long* ym2612_rate ) const;
-
- vgm_time_t vgm_time;
- byte const* pos;
- blip_time_t run_commands( vgm_time_t );
- int play_frame( blip_time_t blip_time, int sample_count, sample_t* buf );
-
- byte const* pcm_data;
- byte const* pcm_pos;
- int dac_amp;
- int dac_disabled; // -1 if disabled
- void write_pcm( vgm_time_t, int amp );
-
- Ym_Emu<Ym2612_Emu> ym2612;
- Ym_Emu<Ym2413_Emu> ym2413;
-
- Blip_Buffer blip_buf;
- Sms_Apu psg;
- Blip_Synth<blip_med_quality,1> dac_synth;
-
- friend class Vgm_Emu;
-};
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Ym2413_Emu.cpp b/plugins/gme/game-music-emu-0.5.5/gme/Ym2413_Emu.cpp
deleted file mode 100644
index be5b2d8c..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Ym2413_Emu.cpp
+++ /dev/null
@@ -1,21 +0,0 @@
-
-// Use in place of Ym2413_Emu.cpp and ym2413.c to disable support for this chip
-
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Ym2413_Emu.h"
-
-Ym2413_Emu::Ym2413_Emu() { }
-
-Ym2413_Emu::~Ym2413_Emu() { }
-
-int Ym2413_Emu::set_rate( double, double ) { return 2; }
-
-void Ym2413_Emu::reset() { }
-
-void Ym2413_Emu::write( int, int ) { }
-
-void Ym2413_Emu::mute_voices( int ) { }
-
-void Ym2413_Emu::run( int, sample_t* ) { }
-
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Ym2413_Emu.h b/plugins/gme/game-music-emu-0.5.5/gme/Ym2413_Emu.h
deleted file mode 100644
index 42314435..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Ym2413_Emu.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// YM2413 FM sound chip emulator interface
-
-// Game_Music_Emu 0.5.5
-#ifndef YM2413_EMU_H
-#define YM2413_EMU_H
-
-class Ym2413_Emu {
- struct OPLL* opll;
-public:
- Ym2413_Emu();
- ~Ym2413_Emu();
-
- // Set output sample rate and chip clock rates, in Hz. Returns non-zero
- // if error.
- int set_rate( double sample_rate, double clock_rate );
-
- // Reset to power-up state
- void reset();
-
- // Mute voice n if bit n (1 << n) of mask is set
- enum { channel_count = 14 };
- void mute_voices( int mask );
-
- // Write 'data' to 'addr'
- void write( int addr, int data );
-
- // Run and write pair_count samples to output
- typedef short sample_t;
- enum { out_chan_count = 2 }; // stereo
- void run( int pair_count, sample_t* out );
-};
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Ym2612_Emu.cpp b/plugins/gme/game-music-emu-0.5.5/gme/Ym2612_Emu.cpp
deleted file mode 100644
index 390fdfce..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Ym2612_Emu.cpp
+++ /dev/null
@@ -1,1319 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-// Based on Gens 2.10 ym2612.c
-
-#include "Ym2612_Emu.h"
-
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include <limits.h>
-#include <stdio.h>
-#include <math.h>
-
-/* Copyright (C) 2002 Stéphane Dallongeville (gens AT consolemul.com) */
-/* Copyright (C) 2004-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-// This is mostly the original source in its C style and all.
-//
-// Somewhat optimized and simplified. Uses a template to generate the many
-// variants of Update_Chan. Rewrote header file. In need of full rewrite by
-// someone more familiar with FM sound and the YM2612. Has some inaccuracies
-// compared to the Sega Genesis sound, particularly being mixed at such a
-// high sample accuracy (the Genesis sounds like it has only 8 bit samples).
-// - Shay
-
-#ifdef BLARGG_ENABLE_OPTIMIZER
- #include BLARGG_ENABLE_OPTIMIZER
-#endif
-
-const int output_bits = 14;
-
-struct slot_t
-{
- const int *DT; // parametre detune
- int MUL; // parametre "multiple de frequence"
- int TL; // Total Level = volume lorsque l'enveloppe est au plus haut
- int TLL; // Total Level ajusted
- int SLL; // Sustin Level (ajusted) = volume où l'enveloppe termine sa premiere phase de regression
- int KSR_S; // Key Scale Rate Shift = facteur de prise en compte du KSL dans la variations de l'enveloppe
- int KSR; // Key Scale Rate = cette valeur est calculee par rapport à la frequence actuelle, elle va influer
- // sur les differents parametres de l'enveloppe comme l'attaque, le decay ... comme dans la realite !
- int SEG; // Type enveloppe SSG
- int env_xor;
- int env_max;
-
- const int *AR; // Attack Rate (table pointeur) = Taux d'attaque (AR[KSR])
- const int *DR; // Decay Rate (table pointeur) = Taux pour la regression (DR[KSR])
- const int *SR; // Sustin Rate (table pointeur) = Taux pour le maintien (SR[KSR])
- const int *RR; // Release Rate (table pointeur) = Taux pour le rel'chement (RR[KSR])
- int Fcnt; // Frequency Count = compteur-frequence pour determiner l'amplitude actuelle (SIN[Finc >> 16])
- int Finc; // frequency step = pas d'incrementation du compteur-frequence
- // plus le pas est grand, plus la frequence est aïgu (ou haute)
- int Ecurp; // Envelope current phase = cette variable permet de savoir dans quelle phase
- // de l'enveloppe on se trouve, par exemple phase d'attaque ou phase de maintenue ...
- // en fonction de la valeur de cette variable, on va appeler une fonction permettant
- // de mettre à jour l'enveloppe courante.
- int Ecnt; // Envelope counter = le compteur-enveloppe permet de savoir où l'on se trouve dans l'enveloppe
- int Einc; // Envelope step courant
- int Ecmp; // Envelope counter limite pour la prochaine phase
- int EincA; // Envelope step for Attack = pas d'incrementation du compteur durant la phase d'attaque
- // cette valeur est egal à AR[KSR]
- int EincD; // Envelope step for Decay = pas d'incrementation du compteur durant la phase de regression
- // cette valeur est egal à DR[KSR]
- int EincS; // Envelope step for Sustain = pas d'incrementation du compteur durant la phase de maintenue
- // cette valeur est egal à SR[KSR]
- int EincR; // Envelope step for Release = pas d'incrementation du compteur durant la phase de rel'chement
- // cette valeur est egal à RR[KSR]
- int *OUTp; // pointeur of SLOT output = pointeur permettant de connecter la sortie de ce slot à l'entree
- // d'un autre ou carrement à la sortie de la voie
- int INd; // input data of the slot = donnees en entree du slot
- int ChgEnM; // Change envelop mask.
- int AMS; // AMS depth level of this SLOT = degre de modulation de l'amplitude par le LFO
- int AMSon; // AMS enable flag = drapeau d'activation de l'AMS
-};
-
-struct channel_t
-{
- int S0_OUT[4]; // anciennes sorties slot 0 (pour le feed back)
- int LEFT; // LEFT enable flag
- int RIGHT; // RIGHT enable flag
- int ALGO; // Algorythm = determine les connections entre les operateurs
- int FB; // shift count of self feed back = degre de "Feed-Back" du SLOT 1 (il est son unique entree)
- int FMS; // Frequency Modulation Sensitivity of channel = degre de modulation de la frequence sur la voie par le LFO
- int AMS; // Amplitude Modulation Sensitivity of channel = degre de modulation de l'amplitude sur la voie par le LFO
- int FNUM[4]; // hauteur frequence de la voie (+ 3 pour le mode special)
- int FOCT[4]; // octave de la voie (+ 3 pour le mode special)
- int KC[4]; // Key Code = valeur fonction de la frequence (voir KSR pour les slots, KSR = KC >> KSR_S)
- slot_t SLOT[4]; // four slot.operators = les 4 slots de la voie
- int FFlag; // Frequency step recalculation flag
-};
-
-struct state_t
-{
- int TimerBase; // TimerBase calculation
- int Status; // YM2612 Status (timer overflow)
- int TimerA; // timerA limit = valeur jusqu'à laquelle le timer A doit compter
- int TimerAL;
- int TimerAcnt; // timerA counter = valeur courante du Timer A
- int TimerB; // timerB limit = valeur jusqu'à laquelle le timer B doit compter
- int TimerBL;
- int TimerBcnt; // timerB counter = valeur courante du Timer B
- int Mode; // Mode actuel des voie 3 et 6 (normal / special)
- int DAC; // DAC enabled flag
- channel_t CHANNEL[Ym2612_Emu::channel_count]; // Les 6 voies du YM2612
- int REG[2][0x100]; // Sauvegardes des valeurs de tout les registres, c'est facultatif
- // cela nous rend le debuggage plus facile
-};
-
-#ifndef PI
-#define PI 3.14159265358979323846
-#endif
-
-#define ATTACK 0
-#define DECAY 1
-#define SUBSTAIN 2
-#define RELEASE 3
-
-// SIN_LBITS <= 16
-// LFO_HBITS <= 16
-// (SIN_LBITS + SIN_HBITS) <= 26
-// (ENV_LBITS + ENV_HBITS) <= 28
-// (LFO_LBITS + LFO_HBITS) <= 28
-
-#define SIN_HBITS 12 // Sinus phase counter int part
-#define SIN_LBITS (26 - SIN_HBITS) // Sinus phase counter float part (best setting)
-
-#if (SIN_LBITS > 16)
-#define SIN_LBITS 16 // Can't be greater than 16 bits
-#endif
-
-#define ENV_HBITS 12 // Env phase counter int part
-#define ENV_LBITS (28 - ENV_HBITS) // Env phase counter float part (best setting)
-
-#define LFO_HBITS 10 // LFO phase counter int part
-#define LFO_LBITS (28 - LFO_HBITS) // LFO phase counter float part (best setting)
-
-#define SIN_LENGHT (1 << SIN_HBITS)
-#define ENV_LENGHT (1 << ENV_HBITS)
-#define LFO_LENGHT (1 << LFO_HBITS)
-
-#define TL_LENGHT (ENV_LENGHT * 3) // Env + TL scaling + LFO
-
-#define SIN_MASK (SIN_LENGHT - 1)
-#define ENV_MASK (ENV_LENGHT - 1)
-#define LFO_MASK (LFO_LENGHT - 1)
-
-#define ENV_STEP (96.0 / ENV_LENGHT) // ENV_MAX = 96 dB
-
-#define ENV_ATTACK ((ENV_LENGHT * 0) << ENV_LBITS)
-#define ENV_DECAY ((ENV_LENGHT * 1) << ENV_LBITS)
-#define ENV_END ((ENV_LENGHT * 2) << ENV_LBITS)
-
-#define MAX_OUT_BITS (SIN_HBITS + SIN_LBITS + 2) // Modulation = -4 <--> +4
-#define MAX_OUT ((1 << MAX_OUT_BITS) - 1)
-
-#define PG_CUT_OFF ((int) (78.0 / ENV_STEP))
-#define ENV_CUT_OFF ((int) (68.0 / ENV_STEP))
-
-#define AR_RATE 399128
-#define DR_RATE 5514396
-
-//#define AR_RATE 426136
-//#define DR_RATE (AR_RATE * 12)
-
-#define LFO_FMS_LBITS 9 // FIXED (LFO_FMS_BASE gives somethink as 1)
-#define LFO_FMS_BASE ((int) (0.05946309436 * 0.0338 * (double) (1 << LFO_FMS_LBITS)))
-
-#define S0 0 // Stupid typo of the YM2612
-#define S1 2
-#define S2 1
-#define S3 3
-
-inline void set_seg( slot_t& s, int seg )
-{
- s.env_xor = 0;
- s.env_max = INT_MAX;
- s.SEG = seg;
- if ( seg & 4 )
- {
- s.env_xor = ENV_MASK;
- s.env_max = ENV_MASK;
- }
-}
-
-struct tables_t
-{
- short SIN_TAB [SIN_LENGHT]; // SINUS TABLE (offset into TL TABLE)
- int LFOcnt; // LFO counter = compteur-frequence pour le LFO
- int LFOinc; // LFO step counter = pas d'incrementation du compteur-frequence du LFO
- // plus le pas est grand, plus la frequence est grande
- unsigned int AR_TAB [128]; // Attack rate table
- unsigned int DR_TAB [96]; // Decay rate table
- unsigned int DT_TAB [8] [32]; // Detune table
- unsigned int SL_TAB [16]; // Substain level table
- unsigned int NULL_RATE [32]; // Table for NULL rate
- int LFO_INC_TAB [8]; // LFO step table
-
- short ENV_TAB [2 * ENV_LENGHT + 8]; // ENV CURVE TABLE (attack & decay)
-
- short LFO_ENV_TAB [LFO_LENGHT]; // LFO AMS TABLE (adjusted for 11.8 dB)
- short LFO_FREQ_TAB [LFO_LENGHT]; // LFO FMS TABLE
- int TL_TAB [TL_LENGHT * 2]; // TOTAL LEVEL TABLE (positif and minus)
- unsigned int DECAY_TO_ATTACK [ENV_LENGHT]; // Conversion from decay to attack phase
- unsigned int FINC_TAB [2048]; // Frequency step table
-};
-
-static const unsigned char DT_DEF_TAB [4 * 32] =
-{
-// FD = 0
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-
-// FD = 1
- 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2,
- 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 8, 8, 8, 8,
-
-// FD = 2
- 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5,
- 5, 6, 6, 7, 8, 8, 9, 10, 11, 12, 13, 14, 16, 16, 16, 16,
-
-// FD = 3
- 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7,
- 8 , 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 20, 22, 22, 22, 22
-};
-
-static const unsigned char FKEY_TAB [16] =
-{
- 0, 0, 0, 0,
- 0, 0, 0, 1,
- 2, 3, 3, 3,
- 3, 3, 3, 3
-};
-
-static const unsigned char LFO_AMS_TAB [4] =
-{
- 31, 4, 1, 0
-};
-
-static const unsigned char LFO_FMS_TAB [8] =
-{
- LFO_FMS_BASE * 0, LFO_FMS_BASE * 1,
- LFO_FMS_BASE * 2, LFO_FMS_BASE * 3,
- LFO_FMS_BASE * 4, LFO_FMS_BASE * 6,
- LFO_FMS_BASE * 12, LFO_FMS_BASE * 24
-};
-
-inline void YM2612_Special_Update() { }
-
-struct Ym2612_Impl
-{
- enum { channel_count = Ym2612_Emu::channel_count };
-
- state_t YM2612;
- int mute_mask;
- tables_t g;
-
- void KEY_ON( channel_t&, int );
- void KEY_OFF( channel_t&, int );
- int SLOT_SET( int, int );
- int CHANNEL_SET( int, int );
- int YM_SET( int, int );
-
- void set_rate( double sample_rate, double clock_factor );
- void reset();
- void write0( int addr, int data );
- void write1( int addr, int data );
- void run_timer( int );
- void run( int pair_count, Ym2612_Emu::sample_t* );
-};
-
-void Ym2612_Impl::KEY_ON( channel_t& ch, int nsl)
-{
- slot_t *SL = &(ch.SLOT [nsl]); // on recupere le bon pointeur de slot
-
- if (SL->Ecurp == RELEASE) // la touche est-elle rel'chee ?
- {
- SL->Fcnt = 0;
-
- // Fix Ecco 2 splash sound
-
- SL->Ecnt = (g.DECAY_TO_ATTACK [g.ENV_TAB [SL->Ecnt >> ENV_LBITS]] + ENV_ATTACK) & SL->ChgEnM;
- SL->ChgEnM = ~0;
-
-// SL->Ecnt = g.DECAY_TO_ATTACK [g.ENV_TAB [SL->Ecnt >> ENV_LBITS]] + ENV_ATTACK;
-// SL->Ecnt = 0;
-
- SL->Einc = SL->EincA;
- SL->Ecmp = ENV_DECAY;
- SL->Ecurp = ATTACK;
- }
-}
-
-
-void Ym2612_Impl::KEY_OFF(channel_t& ch, int nsl)
-{
- slot_t *SL = &(ch.SLOT [nsl]); // on recupere le bon pointeur de slot
-
- if (SL->Ecurp != RELEASE) // la touche est-elle appuyee ?
- {
- if (SL->Ecnt < ENV_DECAY) // attack phase ?
- {
- SL->Ecnt = (g.ENV_TAB [SL->Ecnt >> ENV_LBITS] << ENV_LBITS) + ENV_DECAY;
- }
-
- SL->Einc = SL->EincR;
- SL->Ecmp = ENV_END;
- SL->Ecurp = RELEASE;
- }
-}
-
-
-int Ym2612_Impl::SLOT_SET( int Adr, int data )
-{
- int nch = Adr & 3;
- if ( nch == 3 )
- return 1;
-
- channel_t& ch = YM2612.CHANNEL [nch + (Adr & 0x100 ? 3 : 0)];
- slot_t& sl = ch.SLOT [(Adr >> 2) & 3];
-
- switch ( Adr & 0xF0 )
- {
- case 0x30:
- if ( (sl.MUL = (data & 0x0F)) != 0 ) sl.MUL <<= 1;
- else sl.MUL = 1;
-
- sl.DT = (int*) g.DT_TAB [(data >> 4) & 7];
-
- ch.SLOT [0].Finc = -1;
-
- break;
-
- case 0x40:
- sl.TL = data & 0x7F;
-
- // SOR2 do a lot of TL adjustement and this fix R.Shinobi jump sound...
- YM2612_Special_Update();
-
-#if ((ENV_HBITS - 7) < 0)
- sl.TLL = sl.TL >> (7 - ENV_HBITS);
-#else
- sl.TLL = sl.TL << (ENV_HBITS - 7);
-#endif
-
- break;
-
- case 0x50:
- sl.KSR_S = 3 - (data >> 6);
-
- ch.SLOT [0].Finc = -1;
-
- if (data &= 0x1F) sl.AR = (int*) &g.AR_TAB [data << 1];
- else sl.AR = (int*) &g.NULL_RATE [0];
-
- sl.EincA = sl.AR [sl.KSR];
- if (sl.Ecurp == ATTACK) sl.Einc = sl.EincA;
- break;
-
- case 0x60:
- if ( (sl.AMSon = (data & 0x80)) != 0 ) sl.AMS = ch.AMS;
- else sl.AMS = 31;
-
- if (data &= 0x1F) sl.DR = (int*) &g.DR_TAB [data << 1];
- else sl.DR = (int*) &g.NULL_RATE [0];
-
- sl.EincD = sl.DR [sl.KSR];
- if (sl.Ecurp == DECAY) sl.Einc = sl.EincD;
- break;
-
- case 0x70:
- if (data &= 0x1F) sl.SR = (int*) &g.DR_TAB [data << 1];
- else sl.SR = (int*) &g.NULL_RATE [0];
-
- sl.EincS = sl.SR [sl.KSR];
- if ((sl.Ecurp == SUBSTAIN) && (sl.Ecnt < ENV_END)) sl.Einc = sl.EincS;
- break;
-
- case 0x80:
- sl.SLL = g.SL_TAB [data >> 4];
-
- sl.RR = (int*) &g.DR_TAB [((data & 0xF) << 2) + 2];
-
- sl.EincR = sl.RR [sl.KSR];
- if ((sl.Ecurp == RELEASE) && (sl.Ecnt < ENV_END)) sl.Einc = sl.EincR;
- break;
-
- case 0x90:
- // SSG-EG envelope shapes :
- /*
- E At Al H
-
- 1 0 0 0 \\\\
- 1 0 0 1 \___
- 1 0 1 0 \/\/
- 1 0 1 1 \
- 1 1 0 0 ////
- 1 1 0 1 /
- 1 1 1 0 /\/\
- 1 1 1 1 /___
-
- E = SSG-EG enable
- At = Start negate
- Al = Altern
- H = Hold */
-
- set_seg( sl, (data & 8) ? (data & 0x0F) : 0 );
- break;
- }
-
- return 0;
-}
-
-
-int Ym2612_Impl::CHANNEL_SET( int Adr, int data )
-{
- int num = Adr & 3;
- if ( num == 3 )
- return 1;
-
- channel_t& ch = YM2612.CHANNEL [num + (Adr & 0x100 ? 3 : 0)];
-
- switch ( Adr & 0xFC )
- {
- case 0xA0:
- YM2612_Special_Update();
-
- ch.FNUM [0] = (ch.FNUM [0] & 0x700) + data;
- ch.KC [0] = (ch.FOCT [0] << 2) | FKEY_TAB [ch.FNUM [0] >> 7];
-
- ch.SLOT [0].Finc = -1;
- break;
-
- case 0xA4:
- YM2612_Special_Update();
-
- ch.FNUM [0] = (ch.FNUM [0] & 0x0FF) + ((data & 0x07) << 8);
- ch.FOCT [0] = (data & 0x38) >> 3;
- ch.KC [0] = (ch.FOCT [0] << 2) | FKEY_TAB [ch.FNUM [0] >> 7];
-
- ch.SLOT [0].Finc = -1;
- break;
-
- case 0xA8:
- if ( Adr < 0x100 )
- {
- num++;
-
- YM2612_Special_Update();
-
- YM2612.CHANNEL [2].FNUM [num] = (YM2612.CHANNEL [2].FNUM [num] & 0x700) + data;
- YM2612.CHANNEL [2].KC [num] = (YM2612.CHANNEL [2].FOCT [num] << 2) |
- FKEY_TAB [YM2612.CHANNEL [2].FNUM [num] >> 7];
-
- YM2612.CHANNEL [2].SLOT [0].Finc = -1;
- }
- break;
-
- case 0xAC:
- if ( Adr < 0x100 )
- {
- num++;
-
- YM2612_Special_Update();
-
- YM2612.CHANNEL [2].FNUM [num] = (YM2612.CHANNEL [2].FNUM [num] & 0x0FF) + ((data & 0x07) << 8);
- YM2612.CHANNEL [2].FOCT [num] = (data & 0x38) >> 3;
- YM2612.CHANNEL [2].KC [num] = (YM2612.CHANNEL [2].FOCT [num] << 2) |
- FKEY_TAB [YM2612.CHANNEL [2].FNUM [num] >> 7];
-
- YM2612.CHANNEL [2].SLOT [0].Finc = -1;
- }
- break;
-
- case 0xB0:
- if ( ch.ALGO != (data & 7) )
- {
- // Fix VectorMan 2 heli sound (level 1)
- YM2612_Special_Update();
-
- ch.ALGO = data & 7;
-
- ch.SLOT [0].ChgEnM = 0;
- ch.SLOT [1].ChgEnM = 0;
- ch.SLOT [2].ChgEnM = 0;
- ch.SLOT [3].ChgEnM = 0;
- }
-
- ch.FB = 9 - ((data >> 3) & 7); // Real thing ?
-
-// if (ch.FB = ((data >> 3) & 7)) ch.FB = 9 - ch.FB; // Thunder force 4 (music stage 8), Gynoug, Aladdin bug sound...
-// else ch.FB = 31;
- break;
-
- case 0xB4: {
- YM2612_Special_Update();
-
- ch.LEFT = 0 - ((data >> 7) & 1);
- ch.RIGHT = 0 - ((data >> 6) & 1);
-
- ch.AMS = LFO_AMS_TAB [(data >> 4) & 3];
- ch.FMS = LFO_FMS_TAB [data & 7];
-
- for ( int i = 0; i < 4; i++ )
- {
- slot_t& sl = ch.SLOT [i];
- sl.AMS = (sl.AMSon ? ch.AMS : 31);
- }
- break;
- }
- }
-
- return 0;
-}
-
-
-int Ym2612_Impl::YM_SET(int Adr, int data)
-{
- switch ( Adr )
- {
- case 0x22:
- if (data & 8) // LFO enable
- {
- // Cool Spot music 1, LFO modified severals time which
- // distord the sound, have to check that on a real genesis...
-
- g.LFOinc = g.LFO_INC_TAB [data & 7];
- }
- else
- {
- g.LFOinc = g.LFOcnt = 0;
- }
- break;
-
- case 0x24:
- YM2612.TimerA = (YM2612.TimerA & 0x003) | (((int) data) << 2);
-
- if (YM2612.TimerAL != (1024 - YM2612.TimerA) << 12)
- {
- YM2612.TimerAcnt = YM2612.TimerAL = (1024 - YM2612.TimerA) << 12;
- }
- break;
-
- case 0x25:
- YM2612.TimerA = (YM2612.TimerA & 0x3FC) | (data & 3);
-
- if (YM2612.TimerAL != (1024 - YM2612.TimerA) << 12)
- {
- YM2612.TimerAcnt = YM2612.TimerAL = (1024 - YM2612.TimerA) << 12;
- }
- break;
-
- case 0x26:
- YM2612.TimerB = data;
-
- if (YM2612.TimerBL != (256 - YM2612.TimerB) << (4 + 12))
- {
- YM2612.TimerBcnt = YM2612.TimerBL = (256 - YM2612.TimerB) << (4 + 12);
- }
- break;
-
- case 0x27:
- // Parametre divers
- // b7 = CSM MODE
- // b6 = 3 slot mode
- // b5 = reset b
- // b4 = reset a
- // b3 = timer enable b
- // b2 = timer enable a
- // b1 = load b
- // b0 = load a
-
- if ((data ^ YM2612.Mode) & 0x40)
- {
- // We changed the channel 2 mode, so recalculate phase step
- // This fix the punch sound in Street of Rage 2
-
- YM2612_Special_Update();
-
- YM2612.CHANNEL [2].SLOT [0].Finc = -1; // recalculate phase step
- }
-
-// if ((data & 2) && (YM2612.Status & 2)) YM2612.TimerBcnt = YM2612.TimerBL;
-// if ((data & 1) && (YM2612.Status & 1)) YM2612.TimerAcnt = YM2612.TimerAL;
-
-// YM2612.Status &= (~data >> 4); // Reset du Status au cas ou c'est demande
- YM2612.Status &= (~data >> 4) & (data >> 2); // Reset Status
-
- YM2612.Mode = data;
- break;
-
- case 0x28: {
- int nch = data & 3;
- if ( nch == 3 )
- return 1;
- if ( data & 4 )
- nch += 3;
- channel_t& ch = YM2612.CHANNEL [nch];
-
- YM2612_Special_Update();
-
- if (data & 0x10) KEY_ON(ch, S0); // On appuie sur la touche pour le slot 1
- else KEY_OFF(ch, S0); // On rel'che la touche pour le slot 1
- if (data & 0x20) KEY_ON(ch, S1); // On appuie sur la touche pour le slot 3
- else KEY_OFF(ch, S1); // On rel'che la touche pour le slot 3
- if (data & 0x40) KEY_ON(ch, S2); // On appuie sur la touche pour le slot 2
- else KEY_OFF(ch, S2); // On rel'che la touche pour le slot 2
- if (data & 0x80) KEY_ON(ch, S3); // On appuie sur la touche pour le slot 4
- else KEY_OFF(ch, S3); // On rel'che la touche pour le slot 4
- break;
- }
-
- case 0x2B:
- if (YM2612.DAC ^ (data & 0x80)) YM2612_Special_Update();
-
- YM2612.DAC = data & 0x80; // activation/desactivation du DAC
- break;
- }
-
- return 0;
-}
-
-void Ym2612_Impl::set_rate( double sample_rate, double clock_rate )
-{
- assert( sample_rate );
- assert( clock_rate > sample_rate );
-
- int i;
-
- // 144 = 12 * (prescale * 2) = 12 * 6 * 2
- // prescale set to 6 by default
-
- double Frequence = clock_rate / sample_rate / 144.0;
- if ( fabs( Frequence - 1.0 ) < 0.0000001 )
- Frequence = 1.0;
- YM2612.TimerBase = int (Frequence * 4096.0);
-
- // Tableau TL :
- // [0 - 4095] = +output [4095 - ...] = +output overflow (fill with 0)
- // [12288 - 16383] = -output [16384 - ...] = -output overflow (fill with 0)
-
- for(i = 0; i < TL_LENGHT; i++)
- {
- if (i >= PG_CUT_OFF) // YM2612 cut off sound after 78 dB (14 bits output ?)
- {
- g.TL_TAB [TL_LENGHT + i] = g.TL_TAB [i] = 0;
- }
- else
- {
- double x = MAX_OUT; // Max output
- x /= pow( 10.0, (ENV_STEP * i) / 20.0 ); // Decibel -> Voltage
-
- g.TL_TAB [i] = (int) x;
- g.TL_TAB [TL_LENGHT + i] = -g.TL_TAB [i];
- }
- }
-
- // Tableau SIN :
- // g.SIN_TAB [x] [y] = sin(x) * y;
- // x = phase and y = volume
-
- g.SIN_TAB [0] = g.SIN_TAB [SIN_LENGHT / 2] = PG_CUT_OFF;
-
- for(i = 1; i <= SIN_LENGHT / 4; i++)
- {
- double x = sin(2.0 * PI * (double) (i) / (double) (SIN_LENGHT)); // Sinus
- x = 20 * log10(1 / x); // convert to dB
-
- int j = (int) (x / ENV_STEP); // Get TL range
-
- if (j > PG_CUT_OFF) j = (int) PG_CUT_OFF;
-
- g.SIN_TAB [i] = g.SIN_TAB [(SIN_LENGHT / 2) - i] = j;
- g.SIN_TAB [(SIN_LENGHT / 2) + i] = g.SIN_TAB [SIN_LENGHT - i] = TL_LENGHT + j;
- }
-
- // Tableau LFO (LFO wav) :
-
- for(i = 0; i < LFO_LENGHT; i++)
- {
- double x = sin(2.0 * PI * (double) (i) / (double) (LFO_LENGHT)); // Sinus
- x += 1.0;
- x /= 2.0; // positive only
- x *= 11.8 / ENV_STEP; // ajusted to MAX enveloppe modulation
-
- g.LFO_ENV_TAB [i] = (int) x;
-
- x = sin(2.0 * PI * (double) (i) / (double) (LFO_LENGHT)); // Sinus
- x *= (double) ((1 << (LFO_HBITS - 1)) - 1);
-
- g.LFO_FREQ_TAB [i] = (int) x;
-
- }
-
- // Tableau Enveloppe :
- // g.ENV_TAB [0] -> g.ENV_TAB [ENV_LENGHT - 1] = attack curve
- // g.ENV_TAB [ENV_LENGHT] -> g.ENV_TAB [2 * ENV_LENGHT - 1] = decay curve
-
- for(i = 0; i < ENV_LENGHT; i++)
- {
- // Attack curve (x^8 - music level 2 Vectorman 2)
- double x = pow(((double) ((ENV_LENGHT - 1) - i) / (double) (ENV_LENGHT)), 8);
- x *= ENV_LENGHT;
-
- g.ENV_TAB [i] = (int) x;
-
- // Decay curve (just linear)
- x = pow(((double) (i) / (double) (ENV_LENGHT)), 1);
- x *= ENV_LENGHT;
-
- g.ENV_TAB [ENV_LENGHT + i] = (int) x;
- }
- for ( i = 0; i < 8; i++ )
- g.ENV_TAB [i + ENV_LENGHT * 2] = 0;
-
- g.ENV_TAB [ENV_END >> ENV_LBITS] = ENV_LENGHT - 1; // for the stopped state
-
- // Tableau pour la conversion Attack -> Decay and Decay -> Attack
-
- int j = ENV_LENGHT - 1;
- for ( i = 0; i < ENV_LENGHT; i++ )
- {
- while ( j && g.ENV_TAB [j] < i )
- j--;
-
- g.DECAY_TO_ATTACK [i] = j << ENV_LBITS;
- }
-
- // Tableau pour le Substain Level
-
- for(i = 0; i < 15; i++)
- {
- double x = i * 3; // 3 and not 6 (Mickey Mania first music for test)
- x /= ENV_STEP;
-
- g.SL_TAB [i] = ((int) x << ENV_LBITS) + ENV_DECAY;
- }
-
- g.SL_TAB [15] = ((ENV_LENGHT - 1) << ENV_LBITS) + ENV_DECAY; // special case : volume off
-
- // Tableau Frequency Step
-
- for(i = 0; i < 2048; i++)
- {
- double x = (double) (i) * Frequence;
-
-#if ((SIN_LBITS + SIN_HBITS - (21 - 7)) < 0)
- x /= (double) (1 << ((21 - 7) - SIN_LBITS - SIN_HBITS));
-#else
- x *= (double) (1 << (SIN_LBITS + SIN_HBITS - (21 - 7)));
-#endif
-
- x /= 2.0; // because MUL = value * 2
-
- g.FINC_TAB [i] = (unsigned int) x;
- }
-
- // Tableaux Attack & Decay Rate
-
- for(i = 0; i < 4; i++)
- {
- g.AR_TAB [i] = 0;
- g.DR_TAB [i] = 0;
- }
-
- for(i = 0; i < 60; i++)
- {
- double x = Frequence;
-
- x *= 1.0 + ((i & 3) * 0.25); // bits 0-1 : x1.00, x1.25, x1.50, x1.75
- x *= (double) (1 << ((i >> 2))); // bits 2-5 : shift bits (x2^0 - x2^15)
- x *= (double) (ENV_LENGHT << ENV_LBITS); // on ajuste pour le tableau g.ENV_TAB
-
- g.AR_TAB [i + 4] = (unsigned int) (x / AR_RATE);
- g.DR_TAB [i + 4] = (unsigned int) (x / DR_RATE);
- }
-
- for(i = 64; i < 96; i++)
- {
- g.AR_TAB [i] = g.AR_TAB [63];
- g.DR_TAB [i] = g.DR_TAB [63];
-
- g.NULL_RATE [i - 64] = 0;
- }
-
- for ( i = 96; i < 128; i++ )
- g.AR_TAB [i] = 0;
-
- // Tableau Detune
-
- for(i = 0; i < 4; i++)
- {
- for (int j = 0; j < 32; j++)
- {
-#if ((SIN_LBITS + SIN_HBITS - 21) < 0)
- double y = (double) DT_DEF_TAB [(i << 5) + j] * Frequence / (double) (1 << (21 - SIN_LBITS - SIN_HBITS));
-#else
- double y = (double) DT_DEF_TAB [(i << 5) + j] * Frequence * (double) (1 << (SIN_LBITS + SIN_HBITS - 21));
-#endif
-
- g.DT_TAB [i + 0] [j] = (int) y;
- g.DT_TAB [i + 4] [j] = (int) -y;
- }
- }
-
- // Tableau LFO
- g.LFO_INC_TAB [0] = (unsigned int) (3.98 * (double) (1 << (LFO_HBITS + LFO_LBITS)) / sample_rate);
- g.LFO_INC_TAB [1] = (unsigned int) (5.56 * (double) (1 << (LFO_HBITS + LFO_LBITS)) / sample_rate);
- g.LFO_INC_TAB [2] = (unsigned int) (6.02 * (double) (1 << (LFO_HBITS + LFO_LBITS)) / sample_rate);
- g.LFO_INC_TAB [3] = (unsigned int) (6.37 * (double) (1 << (LFO_HBITS + LFO_LBITS)) / sample_rate);
- g.LFO_INC_TAB [4] = (unsigned int) (6.88 * (double) (1 << (LFO_HBITS + LFO_LBITS)) / sample_rate);
- g.LFO_INC_TAB [5] = (unsigned int) (9.63 * (double) (1 << (LFO_HBITS + LFO_LBITS)) / sample_rate);
- g.LFO_INC_TAB [6] = (unsigned int) (48.1 * (double) (1 << (LFO_HBITS + LFO_LBITS)) / sample_rate);
- g.LFO_INC_TAB [7] = (unsigned int) (72.2 * (double) (1 << (LFO_HBITS + LFO_LBITS)) / sample_rate);
-
- reset();
-}
-
-const char* Ym2612_Emu::set_rate( double sample_rate, double clock_rate )
-{
- if ( !impl )
- {
- impl = (Ym2612_Impl*) malloc( sizeof *impl );
- if ( !impl )
- return "Out of memory";
- impl->mute_mask = 0;
- }
- memset( &impl->YM2612, 0, sizeof impl->YM2612 );
-
- impl->set_rate( sample_rate, clock_rate );
-
- return 0;
-}
-
-Ym2612_Emu::~Ym2612_Emu()
-{
- free( impl );
-}
-
-inline void Ym2612_Impl::write0( int opn_addr, int data )
-{
- assert( (unsigned) data <= 0xFF );
-
- if ( opn_addr < 0x30 )
- {
- YM2612.REG [0] [opn_addr] = data;
- YM_SET( opn_addr, data );
- }
- else if ( YM2612.REG [0] [opn_addr] != data )
- {
- YM2612.REG [0] [opn_addr] = data;
-
- if ( opn_addr < 0xA0 )
- SLOT_SET( opn_addr, data );
- else
- CHANNEL_SET( opn_addr, data );
- }
-}
-
-inline void Ym2612_Impl::write1( int opn_addr, int data )
-{
- assert( (unsigned) data <= 0xFF );
-
- if ( opn_addr >= 0x30 && YM2612.REG [1] [opn_addr] != data )
- {
- YM2612.REG [1] [opn_addr] = data;
-
- if ( opn_addr < 0xA0 )
- SLOT_SET( opn_addr + 0x100, data );
- else
- CHANNEL_SET( opn_addr + 0x100, data );
- }
-}
-
-void Ym2612_Emu::reset()
-{
- impl->reset();
-}
-
-void Ym2612_Impl::reset()
-{
- g.LFOcnt = 0;
- YM2612.TimerA = 0;
- YM2612.TimerAL = 0;
- YM2612.TimerAcnt = 0;
- YM2612.TimerB = 0;
- YM2612.TimerBL = 0;
- YM2612.TimerBcnt = 0;
- YM2612.DAC = 0;
-
- YM2612.Status = 0;
-
- int i;
- for ( i = 0; i < channel_count; i++ )
- {
- channel_t& ch = YM2612.CHANNEL [i];
-
- ch.LEFT = ~0;
- ch.RIGHT = ~0;
- ch.ALGO = 0;
- ch.FB = 31;
- ch.FMS = 0;
- ch.AMS = 0;
-
- for ( int j = 0 ;j < 4 ; j++ )
- {
- ch.S0_OUT [j] = 0;
- ch.FNUM [j] = 0;
- ch.FOCT [j] = 0;
- ch.KC [j] = 0;
-
- ch.SLOT [j].Fcnt = 0;
- ch.SLOT [j].Finc = 0;
- ch.SLOT [j].Ecnt = ENV_END; // Put it at the end of Decay phase...
- ch.SLOT [j].Einc = 0;
- ch.SLOT [j].Ecmp = 0;
- ch.SLOT [j].Ecurp = RELEASE;
-
- ch.SLOT [j].ChgEnM = 0;
- }
- }
-
- for ( i = 0; i < 0x100; i++ )
- {
- YM2612.REG [0] [i] = -1;
- YM2612.REG [1] [i] = -1;
- }
-
- for ( i = 0xB6; i >= 0xB4; i-- )
- {
- write0( i, 0xC0 );
- write1( i, 0xC0 );
- }
-
- for ( i = 0xB2; i >= 0x22; i-- )
- {
- write0( i, 0 );
- write1( i, 0 );
- }
-
- write0( 0x2A, 0x80 );
-}
-
-void Ym2612_Emu::write0( int addr, int data )
-{
- impl->write0( addr, data );
-}
-
-void Ym2612_Emu::write1( int addr, int data )
-{
- impl->write1( addr, data );
-}
-
-void Ym2612_Emu::mute_voices( int mask ) { impl->mute_mask = mask; }
-
-static void update_envelope_( slot_t* sl )
-{
- switch ( sl->Ecurp )
- {
- case 0:
- // Env_Attack_Next
-
- // Verified with Gynoug even in HQ (explode SFX)
- sl->Ecnt = ENV_DECAY;
-
- sl->Einc = sl->EincD;
- sl->Ecmp = sl->SLL;
- sl->Ecurp = DECAY;
- break;
-
- case 1:
- // Env_Decay_Next
-
- // Verified with Gynoug even in HQ (explode SFX)
- sl->Ecnt = sl->SLL;
-
- sl->Einc = sl->EincS;
- sl->Ecmp = ENV_END;
- sl->Ecurp = SUBSTAIN;
- break;
-
- case 2:
- // Env_Substain_Next(slot_t *SL)
- if (sl->SEG & 8) // SSG envelope type
- {
- int release = sl->SEG & 1;
-
- if ( !release )
- {
- // re KEY ON
-
- // sl->Fcnt = 0;
- // sl->ChgEnM = ~0;
-
- sl->Ecnt = 0;
- sl->Einc = sl->EincA;
- sl->Ecmp = ENV_DECAY;
- sl->Ecurp = ATTACK;
- }
-
- set_seg( *sl, (sl->SEG << 1) & 4 );
-
- if ( !release )
- break;
- }
- // fall through
-
- case 3:
- // Env_Release_Next
- sl->Ecnt = ENV_END;
- sl->Einc = 0;
- sl->Ecmp = ENV_END + 1;
- break;
-
- // default: no op
- }
-}
-
-inline void update_envelope( slot_t& sl )
-{
- int ecmp = sl.Ecmp;
- if ( (sl.Ecnt += sl.Einc) >= ecmp )
- update_envelope_( &sl );
-}
-
-template<int algo>
-struct ym2612_update_chan {
- static void func( tables_t&, channel_t&, Ym2612_Emu::sample_t*, int );
-};
-
-typedef void (*ym2612_update_chan_t)( tables_t&, channel_t&, Ym2612_Emu::sample_t*, int );
-
-template<int algo>
-void ym2612_update_chan<algo>::func( tables_t& g, channel_t& ch,
- Ym2612_Emu::sample_t* buf, int length )
-{
- int not_end = ch.SLOT [S3].Ecnt - ENV_END;
-
- // algo is a compile-time constant, so all conditions based on it are resolved
- // during compilation
-
- // special cases
- if ( algo == 7 )
- not_end |= ch.SLOT [S0].Ecnt - ENV_END;
-
- if ( algo >= 5 )
- not_end |= ch.SLOT [S2].Ecnt - ENV_END;
-
- if ( algo >= 4 )
- not_end |= ch.SLOT [S1].Ecnt - ENV_END;
-
- int CH_S0_OUT_1 = ch.S0_OUT [1];
-
- int in0 = ch.SLOT [S0].Fcnt;
- int in1 = ch.SLOT [S1].Fcnt;
- int in2 = ch.SLOT [S2].Fcnt;
- int in3 = ch.SLOT [S3].Fcnt;
-
- int YM2612_LFOinc = g.LFOinc;
- int YM2612_LFOcnt = g.LFOcnt + YM2612_LFOinc;
-
- if ( !not_end )
- return;
-
- do
- {
- // envelope
- int const env_LFO = g.LFO_ENV_TAB [YM2612_LFOcnt >> LFO_LBITS & LFO_MASK];
-
- short const* const ENV_TAB = g.ENV_TAB;
-
- #define CALC_EN( x ) \
- int temp##x = ENV_TAB [ch.SLOT [S##x].Ecnt >> ENV_LBITS] + ch.SLOT [S##x].TLL; \
- int en##x = ((temp##x ^ ch.SLOT [S##x].env_xor) + (env_LFO >> ch.SLOT [S##x].AMS)) & \
- ((temp##x - ch.SLOT [S##x].env_max) >> 31);
-
- CALC_EN( 0 )
- CALC_EN( 1 )
- CALC_EN( 2 )
- CALC_EN( 3 )
-
- int const* const TL_TAB = g.TL_TAB;
-
- #define SINT( i, o ) (TL_TAB [g.SIN_TAB [(i)] + (o)])
-
- // feedback
- int CH_S0_OUT_0 = ch.S0_OUT [0];
- {
- int temp = in0 + ((CH_S0_OUT_0 + CH_S0_OUT_1) >> ch.FB);
- CH_S0_OUT_1 = CH_S0_OUT_0;
- CH_S0_OUT_0 = SINT( (temp >> SIN_LBITS) & SIN_MASK, en0 );
- }
-
- int CH_OUTd;
- if ( algo == 0 )
- {
- int temp = in1 + CH_S0_OUT_1;
- temp = in2 + SINT( (temp >> SIN_LBITS) & SIN_MASK, en1 );
- temp = in3 + SINT( (temp >> SIN_LBITS) & SIN_MASK, en2 );
- CH_OUTd = SINT( (temp >> SIN_LBITS) & SIN_MASK, en3 );
- }
- else if ( algo == 1 )
- {
- int temp = in2 + CH_S0_OUT_1 + SINT( (in1 >> SIN_LBITS) & SIN_MASK, en1 );
- temp = in3 + SINT( (temp >> SIN_LBITS) & SIN_MASK, en2 );
- CH_OUTd = SINT( (temp >> SIN_LBITS) & SIN_MASK, en3 );
- }
- else if ( algo == 2 )
- {
- int temp = in2 + SINT( (in1 >> SIN_LBITS) & SIN_MASK, en1 );
- temp = in3 + CH_S0_OUT_1 + SINT( (temp >> SIN_LBITS) & SIN_MASK, en2 );
- CH_OUTd = SINT( (temp >> SIN_LBITS) & SIN_MASK, en3 );
- }
- else if ( algo == 3 )
- {
- int temp = in1 + CH_S0_OUT_1;
- temp = in3 + SINT( (temp >> SIN_LBITS) & SIN_MASK, en1 ) +
- SINT( (in2 >> SIN_LBITS) & SIN_MASK, en2 );
- CH_OUTd = SINT( (temp >> SIN_LBITS) & SIN_MASK, en3 );
- }
- else if ( algo == 4 )
- {
- int temp = in3 + SINT( (in2 >> SIN_LBITS) & SIN_MASK, en2 );
- CH_OUTd = SINT( (temp >> SIN_LBITS) & SIN_MASK, en3 ) +
- SINT( ((in1 + CH_S0_OUT_1) >> SIN_LBITS) & SIN_MASK, en1 );
- //DO_LIMIT
- }
- else if ( algo == 5 )
- {
- int temp = CH_S0_OUT_1;
- CH_OUTd = SINT( ((in3 + temp) >> SIN_LBITS) & SIN_MASK, en3 ) +
- SINT( ((in1 + temp) >> SIN_LBITS) & SIN_MASK, en1 ) +
- SINT( ((in2 + temp) >> SIN_LBITS) & SIN_MASK, en2 );
- //DO_LIMIT
- }
- else if ( algo == 6 )
- {
- CH_OUTd = SINT( (in3 >> SIN_LBITS) & SIN_MASK, en3 ) +
- SINT( ((in1 + CH_S0_OUT_1) >> SIN_LBITS) & SIN_MASK, en1 ) +
- SINT( (in2 >> SIN_LBITS) & SIN_MASK, en2 );
- //DO_LIMIT
- }
- else if ( algo == 7 )
- {
- CH_OUTd = SINT( (in3 >> SIN_LBITS) & SIN_MASK, en3 ) +
- SINT( (in1 >> SIN_LBITS) & SIN_MASK, en1 ) +
- SINT( (in2 >> SIN_LBITS) & SIN_MASK, en2 ) + CH_S0_OUT_1;
- //DO_LIMIT
- }
-
- CH_OUTd >>= MAX_OUT_BITS - output_bits + 2;
-
- // update phase
- unsigned freq_LFO = ((g.LFO_FREQ_TAB [YM2612_LFOcnt >> LFO_LBITS & LFO_MASK] *
- ch.FMS) >> (LFO_HBITS - 1 + 1)) + (1L << (LFO_FMS_LBITS - 1));
- YM2612_LFOcnt += YM2612_LFOinc;
- in0 += (ch.SLOT [S0].Finc * freq_LFO) >> (LFO_FMS_LBITS - 1);
- in1 += (ch.SLOT [S1].Finc * freq_LFO) >> (LFO_FMS_LBITS - 1);
- in2 += (ch.SLOT [S2].Finc * freq_LFO) >> (LFO_FMS_LBITS - 1);
- in3 += (ch.SLOT [S3].Finc * freq_LFO) >> (LFO_FMS_LBITS - 1);
-
- int t0 = buf [0] + (CH_OUTd & ch.LEFT);
- int t1 = buf [1] + (CH_OUTd & ch.RIGHT);
-
- update_envelope( ch.SLOT [0] );
- update_envelope( ch.SLOT [1] );
- update_envelope( ch.SLOT [2] );
- update_envelope( ch.SLOT [3] );
-
- ch.S0_OUT [0] = CH_S0_OUT_0;
- buf [0] = t0;
- buf [1] = t1;
- buf += 2;
- }
- while ( --length );
-
- ch.S0_OUT [1] = CH_S0_OUT_1;
-
- ch.SLOT [S0].Fcnt = in0;
- ch.SLOT [S1].Fcnt = in1;
- ch.SLOT [S2].Fcnt = in2;
- ch.SLOT [S3].Fcnt = in3;
-}
-
-static const ym2612_update_chan_t UPDATE_CHAN [8] = {
- &ym2612_update_chan<0>::func,
- &ym2612_update_chan<1>::func,
- &ym2612_update_chan<2>::func,
- &ym2612_update_chan<3>::func,
- &ym2612_update_chan<4>::func,
- &ym2612_update_chan<5>::func,
- &ym2612_update_chan<6>::func,
- &ym2612_update_chan<7>::func
-};
-
-void Ym2612_Impl::run_timer( int length )
-{
- int const step = 6;
- int remain = length;
- do
- {
- int n = step;
- if ( n > remain )
- n = remain;
- remain -= n;
-
- long i = n * YM2612.TimerBase;
- if (YM2612.Mode & 1) // Timer A ON ?
- {
- // if ((YM2612.TimerAcnt -= 14073) <= 0) // 13879=NTSC (old: 14475=NTSC 14586=PAL)
- if ((YM2612.TimerAcnt -= i) <= 0)
- {
- // timer a overflow
-
- YM2612.Status |= (YM2612.Mode & 0x04) >> 2;
- YM2612.TimerAcnt += YM2612.TimerAL;
-
- if (YM2612.Mode & 0x80)
- {
- KEY_ON( YM2612.CHANNEL [2], 0 );
- KEY_ON( YM2612.CHANNEL [2], 1 );
- KEY_ON( YM2612.CHANNEL [2], 2 );
- KEY_ON( YM2612.CHANNEL [2], 3 );
- }
- }
- }
-
- if (YM2612.Mode & 2) // Timer B ON ?
- {
- // if ((YM2612.TimerBcnt -= 14073) <= 0) // 13879=NTSC (old: 14475=NTSC 14586=PAL)
- if ((YM2612.TimerBcnt -= i) <= 0)
- {
- // timer b overflow
- YM2612.Status |= (YM2612.Mode & 0x08) >> 2;
- YM2612.TimerBcnt += YM2612.TimerBL;
- }
- }
- }
- while ( remain > 0 );
-}
-
-void Ym2612_Impl::run( int pair_count, Ym2612_Emu::sample_t* out )
-{
- if ( pair_count <= 0 )
- return;
-
- if ( YM2612.Mode & 3 )
- run_timer( pair_count );
-
- // Mise à jour des pas des compteurs-frequences s'ils ont ete modifies
-
- for ( int chi = 0; chi < channel_count; chi++ )
- {
- channel_t& ch = YM2612.CHANNEL [chi];
- if ( ch.SLOT [0].Finc != -1 )
- continue;
-
- int i2 = 0;
- if ( chi == 2 && (YM2612.Mode & 0x40) )
- i2 = 2;
-
- for ( int i = 0; i < 4; i++ )
- {
- // static int seq [4] = { 2, 1, 3, 0 };
- // if ( i2 ) i2 = seq [i];
-
- slot_t& sl = ch.SLOT [i];
- int finc = g.FINC_TAB [ch.FNUM [i2]] >> (7 - ch.FOCT [i2]);
- int ksr = ch.KC [i2] >> sl.KSR_S; // keycode attenuation
- sl.Finc = (finc + sl.DT [ch.KC [i2]]) * sl.MUL;
- if (sl.KSR != ksr) // si le KSR a change alors
- { // les differents taux pour l'enveloppe sont mis à jour
- sl.KSR = ksr;
-
- sl.EincA = sl.AR [ksr];
- sl.EincD = sl.DR [ksr];
- sl.EincS = sl.SR [ksr];
- sl.EincR = sl.RR [ksr];
-
- if (sl.Ecurp == ATTACK)
- {
- sl.Einc = sl.EincA;
- }
- else if (sl.Ecurp == DECAY)
- {
- sl.Einc = sl.EincD;
- }
- else if (sl.Ecnt < ENV_END)
- {
- if (sl.Ecurp == SUBSTAIN)
- sl.Einc = sl.EincS;
- else if (sl.Ecurp == RELEASE)
- sl.Einc = sl.EincR;
- }
- }
-
- if ( i2 )
- i2 = (i2 ^ 2) ^ (i2 >> 1);
- }
- }
-
- for ( int i = 0; i < channel_count; i++ )
- {
- if ( !(mute_mask & (1 << i)) && (i != 5 || !YM2612.DAC) )
- UPDATE_CHAN [YM2612.CHANNEL [i].ALGO]( g, YM2612.CHANNEL [i], out, pair_count );
- }
-
- g.LFOcnt += g.LFOinc * pair_count;
-}
-
-void Ym2612_Emu::run( int pair_count, sample_t* out ) { impl->run( pair_count, out ); }
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/Ym2612_Emu.h b/plugins/gme/game-music-emu-0.5.5/gme/Ym2612_Emu.h
deleted file mode 100644
index 314b3399..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/Ym2612_Emu.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// YM2612 FM sound chip emulator interface
-
-// Game_Music_Emu 0.5.5
-#ifndef YM2612_EMU_H
-#define YM2612_EMU_H
-
-struct Ym2612_Impl;
-
-class Ym2612_Emu {
- Ym2612_Impl* impl;
-public:
- Ym2612_Emu() { impl = 0; }
- ~Ym2612_Emu();
-
- // Set output sample rate and chip clock rates, in Hz. Returns non-zero
- // if error.
- const char* set_rate( double sample_rate, double clock_rate );
-
- // Reset to power-up state
- void reset();
-
- // Mute voice n if bit n (1 << n) of mask is set
- enum { channel_count = 6 };
- void mute_voices( int mask );
-
- // Write addr to register 0 then data to register 1
- void write0( int addr, int data );
-
- // Write addr to register 2 then data to register 3
- void write1( int addr, int data );
-
- // Run and add pair_count samples into current output buffer contents
- typedef short sample_t;
- enum { out_chan_count = 2 }; // stereo
- void run( int pair_count, sample_t* out );
-};
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/blargg_common.h b/plugins/gme/game-music-emu-0.5.5/gme/blargg_common.h
deleted file mode 100644
index e48d6469..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/blargg_common.h
+++ /dev/null
@@ -1,175 +0,0 @@
-// Sets up common environment for Shay Green's libraries.
-// To change configuration options, modify blargg_config.h, not this file.
-
-#ifndef BLARGG_COMMON_H
-#define BLARGG_COMMON_H
-
-#include <stddef.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <limits.h>
-
-#undef BLARGG_COMMON_H
-// allow blargg_config.h to #include blargg_common.h
-#include "blargg_config.h"
-#ifndef BLARGG_COMMON_H
-#define BLARGG_COMMON_H
-
-// STATIC_CAST(T,expr): Used in place of static_cast<T> (expr)
-#ifndef STATIC_CAST
- #define STATIC_CAST(T,expr) ((T) (expr))
-#endif
-
-// blargg_err_t (0 on success, otherwise error string)
-#ifndef blargg_err_t
- typedef const char* blargg_err_t;
-#endif
-
-// blargg_vector - very lightweight vector of POD types (no constructor/destructor)
-template<class T>
-class blargg_vector {
- T* begin_;
- size_t size_;
-public:
- blargg_vector() : begin_( 0 ), size_( 0 ) { }
- ~blargg_vector() { free( begin_ ); }
- size_t size() const { return size_; }
- T* begin() const { return begin_; }
- T* end() const { return begin_ + size_; }
- blargg_err_t resize( size_t n )
- {
- void* p = realloc( begin_, n * sizeof (T) );
- if ( !p && n )
- return "Out of memory";
- begin_ = (T*) p;
- size_ = n;
- return 0;
- }
- void clear() { void* p = begin_; begin_ = 0; size_ = 0; free( p ); }
- T& operator [] ( size_t n ) const
- {
- assert( n <= size_ ); // <= to allow past-the-end value
- return begin_ [n];
- }
-};
-
-#ifndef BLARGG_DISABLE_NOTHROW
- #if __cplusplus < 199711
- #define BLARGG_THROWS( spec )
- #else
- #define BLARGG_THROWS( spec ) throw spec
- #endif
- #define BLARGG_DISABLE_NOTHROW \
- void* operator new ( size_t s ) BLARGG_THROWS(()) { return malloc( s ); }\
- void operator delete ( void* p ) { free( p ); }
- #define BLARGG_NEW new
-#else
- #include <new>
- #define BLARGG_NEW new (std::nothrow)
-#endif
-
-#define BLARGG_4CHAR( a, b, c, d ) \
- ((a&0xFF)*0x1000000L + (b&0xFF)*0x10000L + (c&0xFF)*0x100L + (d&0xFF))
-
-// BOOST_STATIC_ASSERT( expr ): Generates compile error if expr is 0.
-#ifndef BOOST_STATIC_ASSERT
- #ifdef _MSC_VER
- // MSVC6 (_MSC_VER < 1300) fails for use of __LINE__ when /Zl is specified
- #define BOOST_STATIC_ASSERT( expr ) \
- void blargg_failed_( int (*arg) [2 / (int) !!(expr) - 1] )
- #else
- // Some other compilers fail when declaring same function multiple times in class,
- // so differentiate them by line
- #define BOOST_STATIC_ASSERT( expr ) \
- void blargg_failed_( int (*arg) [2 / !!(expr) - 1] [__LINE__] )
- #endif
-#endif
-
-// BLARGG_COMPILER_HAS_BOOL: If 0, provides bool support for old compiler. If 1,
-// compiler is assumed to support bool. If undefined, availability is determined.
-#ifndef BLARGG_COMPILER_HAS_BOOL
- #if defined (__MWERKS__)
- #if !__option(bool)
- #define BLARGG_COMPILER_HAS_BOOL 0
- #endif
- #elif defined (_MSC_VER)
- #if _MSC_VER < 1100
- #define BLARGG_COMPILER_HAS_BOOL 0
- #endif
- #elif defined (__GNUC__)
- // supports bool
- #elif __cplusplus < 199711
- #define BLARGG_COMPILER_HAS_BOOL 0
- #endif
-#endif
-#if defined (BLARGG_COMPILER_HAS_BOOL) && !BLARGG_COMPILER_HAS_BOOL
- // If you get errors here, modify your blargg_config.h file
- typedef int bool;
- const bool true = 1;
- const bool false = 0;
-#endif
-
-// blargg_long/blargg_ulong = at least 32 bits, int if it's big enough
-#include <limits.h>
-
-#if INT_MAX >= 0x7FFFFFFF
- typedef int blargg_long;
-#else
- typedef long blargg_long;
-#endif
-
-#if UINT_MAX >= 0xFFFFFFFF
- typedef unsigned blargg_ulong;
-#else
- typedef unsigned long blargg_ulong;
-#endif
-
-// BOOST::int8_t etc.
-
-// HAVE_STDINT_H: If defined, use <stdint.h> for int8_t etc.
-#if defined (HAVE_STDINT_H)
- #include <stdint.h>
- #define BOOST
-
-// HAVE_INTTYPES_H: If defined, use <stdint.h> for int8_t etc.
-#elif defined (HAVE_INTTYPES_H)
- #include <inttypes.h>
- #define BOOST
-
-#else
- struct BOOST
- {
- #if UCHAR_MAX == 0xFF && SCHAR_MAX == 0x7F
- typedef signed char int8_t;
- typedef unsigned char uint8_t;
- #else
- // No suitable 8-bit type available
- typedef struct see_blargg_common_h int8_t;
- typedef struct see_blargg_common_h uint8_t;
- #endif
-
- #if USHRT_MAX == 0xFFFF
- typedef short int16_t;
- typedef unsigned short uint16_t;
- #else
- // No suitable 16-bit type available
- typedef struct see_blargg_common_h int16_t;
- typedef struct see_blargg_common_h uint16_t;
- #endif
-
- #if ULONG_MAX == 0xFFFFFFFF
- typedef long int32_t;
- typedef unsigned long uint32_t;
- #elif UINT_MAX == 0xFFFFFFFF
- typedef int int32_t;
- typedef unsigned int uint32_t;
- #else
- // No suitable 32-bit type available
- typedef struct see_blargg_common_h int32_t;
- typedef struct see_blargg_common_h uint32_t;
- #endif
- };
-#endif
-
-#endif
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/blargg_config.h b/plugins/gme/game-music-emu-0.5.5/gme/blargg_config.h
deleted file mode 100644
index 9bdbeb57..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/blargg_config.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Library configuration. Modify this file as necessary.
-
-#ifndef BLARGG_CONFIG_H
-#define BLARGG_CONFIG_H
-
-// Uncomment to use zlib for transparent decompression of gzipped files
-//#define HAVE_ZLIB_H
-
-// Uncomment to enable platform-specific optimizations
-#define BLARGG_NONPORTABLE 1
-
-// Uncomment to use faster, lower quality sound synthesis
-//#define BLIP_BUFFER_FAST 1
-
-// Uncomment if automatic byte-order determination doesn't work
-//#define BLARGG_BIG_ENDIAN 1
-
-// Uncomment if you get errors in the bool section of blargg_common.h
-//#define BLARGG_COMPILER_HAS_BOOL 1
-
-// Use standard config.h if present
-#ifdef HAVE_CONFIG_H
- #include "config.h"
-#endif
-
-// Add supported emulator types
-#include "gme_types.h"
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/blargg_endian.h b/plugins/gme/game-music-emu-0.5.5/gme/blargg_endian.h
deleted file mode 100644
index 4d160d2f..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/blargg_endian.h
+++ /dev/null
@@ -1,158 +0,0 @@
-// CPU Byte Order Utilities
-
-// Game_Music_Emu 0.5.5
-#ifndef BLARGG_ENDIAN
-#define BLARGG_ENDIAN
-
-#include "blargg_common.h"
-
-// BLARGG_CPU_CISC: Defined if CPU has very few general-purpose registers (< 16)
-#if defined (_M_IX86) || defined (_M_IA64) || defined (__i486__) || \
- defined (__x86_64__) || defined (__ia64__) || defined (__i386__)
- #define BLARGG_CPU_X86 1
- #define BLARGG_CPU_CISC 1
-#endif
-
-#if defined (__powerpc__) || defined (__ppc__) || defined (__POWERPC__) || defined (__powerc)
- #define BLARGG_CPU_POWERPC 1
-#endif
-
-// BLARGG_BIG_ENDIAN, BLARGG_LITTLE_ENDIAN: Determined automatically, otherwise only
-// one may be #defined to 1. Only needed if something actually depends on byte order.
-#if !defined (BLARGG_BIG_ENDIAN) && !defined (BLARGG_LITTLE_ENDIAN)
-#ifdef __GLIBC__
- // GCC handles this for us
- #include <endian.h>
- #if __BYTE_ORDER == __LITTLE_ENDIAN
- #define BLARGG_LITTLE_ENDIAN 1
- #elif __BYTE_ORDER == __BIG_ENDIAN
- #define BLARGG_BIG_ENDIAN 1
- #endif
-#else
-
-#if defined (LSB_FIRST) || defined (__LITTLE_ENDIAN__) || BLARGG_CPU_X86 || \
- (defined (LITTLE_ENDIAN) && LITTLE_ENDIAN+0 != 1234)
- #define BLARGG_LITTLE_ENDIAN 1
-#endif
-
-#if defined (MSB_FIRST) || defined (__BIG_ENDIAN__) || defined (WORDS_BIGENDIAN) || \
- defined (__mips__) || defined (__sparc__) || BLARGG_CPU_POWERPC || \
- (defined (BIG_ENDIAN) && BIG_ENDIAN+0 != 4321)
- #define BLARGG_BIG_ENDIAN 1
-#else
- // No endian specified; assume little-endian, since it's most common
- #define BLARGG_LITTLE_ENDIAN 1
-#endif
-#endif
-#endif
-
-#if BLARGG_LITTLE_ENDIAN && BLARGG_BIG_ENDIAN
- #undef BLARGG_LITTLE_ENDIAN
- #undef BLARGG_BIG_ENDIAN
-#endif
-
-inline void blargg_verify_byte_order()
-{
- #ifndef NDEBUG
- #if BLARGG_BIG_ENDIAN
- volatile int i = 1;
- assert( *(volatile char*) &i == 0 );
- #elif BLARGG_LITTLE_ENDIAN
- volatile int i = 1;
- assert( *(volatile char*) &i != 0 );
- #endif
- #endif
-}
-
-inline unsigned get_le16( void const* p ) {
- return ((unsigned char const*) p) [1] * 0x100u +
- ((unsigned char const*) p) [0];
-}
-inline unsigned get_be16( void const* p ) {
- return ((unsigned char const*) p) [0] * 0x100u +
- ((unsigned char const*) p) [1];
-}
-inline blargg_ulong get_le32( void const* p ) {
- return ((unsigned char const*) p) [3] * 0x01000000u +
- ((unsigned char const*) p) [2] * 0x00010000u +
- ((unsigned char const*) p) [1] * 0x00000100u +
- ((unsigned char const*) p) [0];
-}
-inline blargg_ulong get_be32( void const* p ) {
- return ((unsigned char const*) p) [0] * 0x01000000u +
- ((unsigned char const*) p) [1] * 0x00010000u +
- ((unsigned char const*) p) [2] * 0x00000100u +
- ((unsigned char const*) p) [3];
-}
-inline void set_le16( void* p, unsigned n ) {
- ((unsigned char*) p) [1] = (unsigned char) (n >> 8);
- ((unsigned char*) p) [0] = (unsigned char) n;
-}
-inline void set_be16( void* p, unsigned n ) {
- ((unsigned char*) p) [0] = (unsigned char) (n >> 8);
- ((unsigned char*) p) [1] = (unsigned char) n;
-}
-inline void set_le32( void* p, blargg_ulong n ) {
- ((unsigned char*) p) [3] = (unsigned char) (n >> 24);
- ((unsigned char*) p) [2] = (unsigned char) (n >> 16);
- ((unsigned char*) p) [1] = (unsigned char) (n >> 8);
- ((unsigned char*) p) [0] = (unsigned char) n;
-}
-inline void set_be32( void* p, blargg_ulong n ) {
- ((unsigned char*) p) [0] = (unsigned char) (n >> 24);
- ((unsigned char*) p) [1] = (unsigned char) (n >> 16);
- ((unsigned char*) p) [2] = (unsigned char) (n >> 8);
- ((unsigned char*) p) [3] = (unsigned char) n;
-}
-
-#if BLARGG_NONPORTABLE
- // Optimized implementation if byte order is known
- #if BLARGG_LITTLE_ENDIAN
- #define GET_LE16( addr ) (*(BOOST::uint16_t*) (addr))
- #define GET_LE32( addr ) (*(BOOST::uint32_t*) (addr))
- #define SET_LE16( addr, data ) (void) (*(BOOST::uint16_t*) (addr) = (data))
- #define SET_LE32( addr, data ) (void) (*(BOOST::uint32_t*) (addr) = (data))
- #elif BLARGG_BIG_ENDIAN
- #define GET_BE16( addr ) (*(BOOST::uint16_t*) (addr))
- #define GET_BE32( addr ) (*(BOOST::uint32_t*) (addr))
- #define SET_BE16( addr, data ) (void) (*(BOOST::uint16_t*) (addr) = (data))
- #define SET_BE32( addr, data ) (void) (*(BOOST::uint32_t*) (addr) = (data))
- #endif
-
- #if BLARGG_CPU_POWERPC && defined (__MWERKS__)
- // PowerPC has special byte-reversed instructions
- // to do: assumes that PowerPC is running in big-endian mode
- // to do: implement for other compilers which don't support these macros
- #define GET_LE16( addr ) (__lhbrx( (addr), 0 ))
- #define GET_LE32( addr ) (__lwbrx( (addr), 0 ))
- #define SET_LE16( addr, data ) (__sthbrx( (data), (addr), 0 ))
- #define SET_LE32( addr, data ) (__stwbrx( (data), (addr), 0 ))
- #endif
-#endif
-
-#ifndef GET_LE16
- #define GET_LE16( addr ) get_le16( addr )
- #define GET_LE32( addr ) get_le32( addr )
- #define SET_LE16( addr, data ) set_le16( addr, data )
- #define SET_LE32( addr, data ) set_le32( addr, data )
-#endif
-
-#ifndef GET_BE16
- #define GET_BE16( addr ) get_be16( addr )
- #define GET_BE32( addr ) get_be32( addr )
- #define SET_BE16( addr, data ) set_be16( addr, data )
- #define SET_BE32( addr, data ) set_be32( addr, data )
-#endif
-
-// auto-selecting versions
-
-inline void set_le( BOOST::uint16_t* p, unsigned n ) { SET_LE16( p, n ); }
-inline void set_le( BOOST::uint32_t* p, blargg_ulong n ) { SET_LE32( p, n ); }
-inline void set_be( BOOST::uint16_t* p, unsigned n ) { SET_BE16( p, n ); }
-inline void set_be( BOOST::uint32_t* p, blargg_ulong n ) { SET_BE32( p, n ); }
-inline unsigned get_le( BOOST::uint16_t* p ) { return GET_LE16( p ); }
-inline blargg_ulong get_le( BOOST::uint32_t* p ) { return GET_LE32( p ); }
-inline unsigned get_be( BOOST::uint16_t* p ) { return GET_BE16( p ); }
-inline blargg_ulong get_be( BOOST::uint32_t* p ) { return GET_BE32( p ); }
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/blargg_source.h b/plugins/gme/game-music-emu-0.5.5/gme/blargg_source.h
deleted file mode 100644
index 2b568d19..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/blargg_source.h
+++ /dev/null
@@ -1,78 +0,0 @@
-// Included at the beginning of library source files, after all other #include lines
-#ifndef BLARGG_SOURCE_H
-#define BLARGG_SOURCE_H
-
-// If debugging is enabled, abort program if expr is false. Meant for checking
-// internal state and consistency. A failed assertion indicates a bug in the module.
-// void assert( bool expr );
-#include <assert.h>
-
-// If debugging is enabled and expr is false, abort program. Meant for checking
-// caller-supplied parameters and operations that are outside the control of the
-// module. A failed requirement indicates a bug outside the module.
-// void require( bool expr );
-#undef require
-#define require( expr ) assert( expr )
-
-// Like printf() except output goes to debug log file. Might be defined to do
-// nothing (not even evaluate its arguments).
-// void debug_printf( const char* format, ... );
-inline void blargg_dprintf_( const char*, ... ) { }
-#undef debug_printf
-#define debug_printf (1) ? (void) 0 : blargg_dprintf_
-
-// If enabled, evaluate expr and if false, make debug log entry with source file
-// and line. Meant for finding situations that should be examined further, but that
-// don't indicate a problem. In all cases, execution continues normally.
-#undef check
-#define check( expr ) ((void) 0)
-
-// If expr yields error string, return it from current function, otherwise continue.
-#undef RETURN_ERR
-#define RETURN_ERR( expr ) do { \
- blargg_err_t blargg_return_err_ = (expr); \
- if ( blargg_return_err_ ) return blargg_return_err_; \
- } while ( 0 )
-
-// If ptr is 0, return out of memory error string.
-#undef CHECK_ALLOC
-#define CHECK_ALLOC( ptr ) do { if ( (ptr) == 0 ) return "Out of memory"; } while ( 0 )
-
-// Avoid any macros which evaluate their arguments multiple times
-#undef min
-#undef max
-
-// using const references generates crappy code, and I am currenly only using these
-// for built-in types, so they take arguments by value
-
-template<class T>
-inline T min( T x, T y )
-{
- if ( x < y )
- return x;
- return y;
-}
-
-template<class T>
-inline T max( T x, T y )
-{
- if ( x < y )
- return y;
- return x;
-}
-
-// TODO: good idea? bad idea?
-#undef byte
-#define byte byte_
-typedef unsigned char byte;
-
-// deprecated
-#define BLARGG_CHECK_ALLOC CHECK_ALLOC
-#define BLARGG_RETURN_ERR RETURN_ERR
-
-// BLARGG_SOURCE_BEGIN: If defined, #included, allowing redefition of debug_printf and check
-#ifdef BLARGG_SOURCE_BEGIN
- #include BLARGG_SOURCE_BEGIN
-#endif
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/gb_cpu_io.h b/plugins/gme/game-music-emu-0.5.5/gme/gb_cpu_io.h
deleted file mode 100644
index cd98ffd5..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/gb_cpu_io.h
+++ /dev/null
@@ -1,72 +0,0 @@
-
-#include "Gbs_Emu.h"
-
-#include "blargg_source.h"
-
-int Gbs_Emu::cpu_read( gb_addr_t addr )
-{
- int result = *cpu::get_code( addr );
- if ( unsigned (addr - Gb_Apu::start_addr) < Gb_Apu::register_count )
- result = apu.read_register( clock(), addr );
-#ifndef NDEBUG
- else if ( unsigned (addr - 0x8000) < 0x2000 || unsigned (addr - 0xE000) < 0x1F00 )
- debug_printf( "Read from unmapped memory $%.4x\n", (unsigned) addr );
- else if ( unsigned (addr - 0xFF01) < 0xFF80 - 0xFF01 )
- debug_printf( "Unhandled I/O read 0x%4X\n", (unsigned) addr );
-#endif
- return result;
-}
-
-void Gbs_Emu::cpu_write( gb_addr_t addr, int data )
-{
- unsigned offset = addr - ram_addr;
- if ( offset <= 0xFFFF - ram_addr )
- {
- ram [offset] = data;
- if ( (addr ^ 0xE000) <= 0x1F80 - 1 )
- {
- if ( unsigned (addr - Gb_Apu::start_addr) < Gb_Apu::register_count )
- {
- GME_APU_HOOK( this, addr - Gb_Apu::start_addr, data );
- apu.write_register( clock(), addr, data );
- }
- else if ( (addr ^ 0xFF06) < 2 )
- update_timer();
- else if ( addr == joypad_addr )
- ram [offset] = 0; // keep joypad return value 0
- else
- ram [offset] = 0xFF;
-
- //if ( addr == 0xFFFF )
- // debug_printf( "Wrote interrupt mask\n" );
- }
- }
- else if ( (addr ^ 0x2000) <= 0x2000 - 1 )
- {
- set_bank( data );
- }
-#ifndef NDEBUG
- else if ( unsigned (addr - 0x8000) < 0x2000 || unsigned (addr - 0xE000) < 0x1F00 )
- {
- debug_printf( "Wrote to unmapped memory $%.4x\n", (unsigned) addr );
- }
-#endif
-}
-
-#define CPU_READ_FAST( cpu, addr, time, out ) \
- CPU_READ_FAST_( STATIC_CAST(Gbs_Emu*,cpu), addr, time, out )
-
-#define CPU_READ_FAST_( emu, addr, time, out ) \
-{\
- out = READ_PROG( addr );\
- if ( unsigned (addr - Gb_Apu::start_addr) <= Gb_Apu::register_count )\
- out = emu->apu.read_register( emu->cpu_time - time * clocks_per_instr, addr );\
- else\
- check( out == emu->cpu_read( addr ) );\
-}
-
-#define CPU_READ( cpu, addr, time ) \
- STATIC_CAST(Gbs_Emu*,cpu)->cpu_read( addr )
-
-#define CPU_WRITE( cpu, addr, data, time ) \
- STATIC_CAST(Gbs_Emu*,cpu)->cpu_write( addr, data )
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/gme.cpp b/plugins/gme/game-music-emu-0.5.5/gme/gme.cpp
deleted file mode 100644
index 6b9dc0b8..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/gme.cpp
+++ /dev/null
@@ -1,367 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Music_Emu.h"
-
-#if !GME_DISABLE_STEREO_DEPTH
-#include "Effects_Buffer.h"
-#endif
-#include "blargg_endian.h"
-#include <string.h>
-#include <ctype.h>
-
-/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
-can redistribute it and/or modify it under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version. This
-module is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details. You should have received a copy of the GNU Lesser General Public
-License along with this module; if not, write to the Free Software Foundation,
-Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "blargg_source.h"
-
-gme_type_t const* gme_type_list()
-{
- static gme_type_t const gme_type_list_ [] = {
-#ifdef USE_GME_AY
- gme_ay_type,
-#endif
-#ifdef USE_GME_GBS
- gme_gbs_type,
-#endif
-#ifdef USE_GME_GYM
- gme_gym_type,
-#endif
-#ifdef USE_GME_HES
- gme_hes_type,
-#endif
-#ifdef USE_GME_KSS
- gme_kss_type,
-#endif
-#if defined(USE_GME_NSF) || defined(USE_GME_NSFE)
- gme_nsf_type,
-#endif
-#ifdef USE_GME_NSFE
- gme_nsfe_type,
-#endif
-#ifdef USE_GME_SAP
- gme_sap_type,
-#endif
-#ifdef USE_GME_SPC
- gme_spc_type,
-#endif
-#ifdef USE_GME_VGM
- gme_vgm_type,
- gme_vgz_type,
-#endif
- 0 };
-
- return gme_type_list_;
-}
-
-const char* gme_identify_header( void const* header )
-{
- switch ( get_be32( header ) )
- {
- case BLARGG_4CHAR('Z','X','A','Y'): return "AY";
- case BLARGG_4CHAR('G','B','S',0x01): return "GBS";
- case BLARGG_4CHAR('G','Y','M','X'): return "GYM";
- case BLARGG_4CHAR('H','E','S','M'): return "HES";
- case BLARGG_4CHAR('K','S','C','C'):
- case BLARGG_4CHAR('K','S','S','X'): return "KSS";
- case BLARGG_4CHAR('N','E','S','M'): return "NSF";
- case BLARGG_4CHAR('N','S','F','E'): return "NSFE";
- case BLARGG_4CHAR('S','A','P',0x0D): return "SAP";
- case BLARGG_4CHAR('S','N','E','S'): return "SPC";
- case BLARGG_4CHAR('V','g','m',' '): return "VGM";
- }
- return "";
-}
-
-static void to_uppercase( const char* in, int len, char* out )
-{
- for ( int i = 0; i < len; i++ )
- {
- if ( !(out [i] = toupper( in [i] )) )
- return;
- }
- *out = 0; // extension too long
-}
-
-gme_type_t gme_identify_extension( const char* extension_ )
-{
- char const* end = strrchr( extension_, '.' );
- if ( end )
- extension_ = end + 1;
-
- char extension [6];
- to_uppercase( extension_, sizeof extension, extension );
-
- for ( gme_type_t const* types = gme_type_list(); *types; types++ )
- if ( !strcmp( extension, (*types)->extension_ ) )
- return *types;
- return 0;
-}
-
-gme_err_t gme_identify_file( const char* path, gme_type_t* type_out )
-{
- *type_out = gme_identify_extension( path );
- // TODO: don't examine header if file has extension?
- if ( !*type_out )
- {
- char header [4];
- GME_FILE_READER in;
- RETURN_ERR( in.open( path ) );
- RETURN_ERR( in.read( header, sizeof header ) );
- *type_out = gme_identify_extension( gme_identify_header( header ) );
- }
- return 0;
-}
-
-gme_err_t gme_open_data( void const* data, long size, Music_Emu** out, int sample_rate )
-{
- require( (data || !size) && out );
- *out = 0;
-
- gme_type_t file_type = 0;
- if ( size >= 4 )
- file_type = gme_identify_extension( gme_identify_header( data ) );
- if ( !file_type )
- return gme_wrong_file_type;
-
- Music_Emu* emu = gme_new_emu( file_type, sample_rate );
- CHECK_ALLOC( emu );
-
- gme_err_t err = gme_load_data( emu, data, size );
-
- if ( err )
- delete emu;
- else
- *out = emu;
-
- return err;
-}
-
-gme_err_t gme_open_file( const char* path, Music_Emu** out, int sample_rate )
-{
- require( path && out );
- *out = 0;
-
- GME_FILE_READER in;
- RETURN_ERR( in.open( path ) );
-
- char header [4];
- int header_size = 0;
-
- gme_type_t file_type = gme_identify_extension( path );
- if ( !file_type )
- {
- header_size = sizeof header;
- RETURN_ERR( in.read( header, sizeof header ) );
- file_type = gme_identify_extension( gme_identify_header( header ) );
- }
- if ( !file_type )
- return gme_wrong_file_type;
-
- Music_Emu* emu = gme_new_emu( file_type, sample_rate );
- CHECK_ALLOC( emu );
-
- // optimization: avoids seeking/re-reading header
- Remaining_Reader rem( header, header_size, &in );
- gme_err_t err = emu->load( rem );
- in.close();
-
- if ( err )
- delete emu;
- else
- *out = emu;
-
- return err;
-}
-
-Music_Emu* gme_new_emu( gme_type_t type, int rate )
-{
- if ( type )
- {
- if ( rate == gme_info_only )
- return type->new_info();
-
- Music_Emu* me = type->new_emu();
- if ( me )
- {
- #if !GME_DISABLE_STEREO_DEPTH
- if ( type->flags_ & 1 )
- {
- me->effects_buffer = BLARGG_NEW Effects_Buffer;
- if ( me->effects_buffer )
- me->set_buffer( me->effects_buffer );
- }
-
- if ( !(type->flags_ & 1) || me->effects_buffer )
- #endif
- {
- if ( !me->set_sample_rate( rate ) )
- {
- check( me->type() == type );
- return me;
- }
- }
- delete me;
- }
- }
- return 0;
-}
-
-gme_err_t gme_load_file( Music_Emu* me, const char* path ) { return me->load_file( path ); }
-
-gme_err_t gme_load_data( Music_Emu* me, void const* data, long size )
-{
- Mem_File_Reader in( data, size );
- return me->load( in );
-}
-
-gme_err_t gme_load_custom( Music_Emu* me, gme_reader_t func, long size, void* data )
-{
- Callback_Reader in( func, size, data );
- return me->load( in );
-}
-
-void gme_delete( Music_Emu* me ) { delete me; }
-
-gme_type_t gme_type( Music_Emu const* me ) { return me->type(); }
-
-const char* gme_warning( Music_Emu* me ) { return me->warning(); }
-
-int gme_track_count( Music_Emu const* me ) { return me->track_count(); }
-
-struct gme_info_t_ : gme_info_t
-{
- track_info_t info;
-
- BLARGG_DISABLE_NOTHROW
-};
-
-gme_err_t gme_track_info( Music_Emu const* me, gme_info_t** out, int track )
-{
- *out = NULL;
-
- gme_info_t_* info = BLARGG_NEW gme_info_t_;
- CHECK_ALLOC( info );
-
- gme_err_t err = me->track_info( &info->info, track );
- if ( err )
- {
- gme_free_info( info );
- return err;
- }
-
- #define COPY(name) info->name = info->info.name;
-
- COPY( length );
- COPY( intro_length );
- COPY( loop_length );
-
- info->i4 = -1;
- info->i5 = -1;
- info->i6 = -1;
- info->i7 = -1;
- info->i8 = -1;
- info->i9 = -1;
- info->i10 = -1;
- info->i11 = -1;
- info->i12 = -1;
- info->i13 = -1;
- info->i14 = -1;
- info->i15 = -1;
-
- info->s7 = "";
- info->s8 = "";
- info->s9 = "";
- info->s10 = "";
- info->s11 = "";
- info->s12 = "";
- info->s13 = "";
- info->s14 = "";
- info->s15 = "";
-
- COPY( system );
- COPY( game );
- COPY( song );
- COPY( author );
- COPY( copyright );
- COPY( comment );
- COPY( dumper );
-
- #undef COPY
-
- info->play_length = info->length;
- if ( info->play_length <= 0 )
- {
- info->play_length = info->intro_length + 2 * info->loop_length; // intro + 2 loops
- if ( info->play_length <= 0 )
- info->play_length = 150 * 1000; // 2.5 minutes
- }
-
- *out = info;
-
- return 0;
-}
-
-void gme_free_info( gme_info_t* info )
-{
- delete STATIC_CAST(gme_info_t_*,info);
-}
-
-void gme_set_stereo_depth( Music_Emu* me, double depth )
-{
-#if !GME_DISABLE_STEREO_DEPTH
- if ( me->effects_buffer )
- STATIC_CAST(Effects_Buffer*,me->effects_buffer)->set_depth( depth );
-#endif
-}
-
-void* gme_user_data ( Music_Emu const* me ) { return me->user_data(); }
-void gme_set_user_data ( Music_Emu* me, void* new_user_data ) { me->set_user_data( new_user_data ); }
-void gme_set_user_cleanup(Music_Emu* me, gme_user_cleanup_t func ) { me->set_user_cleanup( func ); }
-
-gme_err_t gme_start_track ( Music_Emu* me, int index ) { return me->start_track( index ); }
-gme_err_t gme_play ( Music_Emu* me, int n, short* p ) { return me->play( n, p ); }
-void gme_set_fade ( Music_Emu* me, int start_msec ) { me->set_fade( start_msec ); }
-int gme_track_ended ( Music_Emu const* me ) { return me->track_ended(); }
-int gme_tell ( Music_Emu const* me ) { return me->tell(); }
-gme_err_t gme_seek ( Music_Emu* me, int msec ) { return me->seek( msec ); }
-int gme_voice_count ( Music_Emu const* me ) { return me->voice_count(); }
-void gme_ignore_silence ( Music_Emu* me, int disable ) { me->ignore_silence( disable != 0 ); }
-void gme_set_tempo ( Music_Emu* me, double t ) { me->set_tempo( t ); }
-void gme_mute_voice ( Music_Emu* me, int index, int mute ) { me->mute_voice( index, mute != 0 ); }
-void gme_mute_voices ( Music_Emu* me, int mask ) { me->mute_voices( mask ); }
-
-void gme_set_equalizer ( Music_Emu* me, gme_equalizer_t const* eq )
-{
- Music_Emu::equalizer_t e = me->equalizer();
- e.treble = eq->treble;
- e.bass = eq->bass;
- me->set_equalizer( e );
-}
-
-void gme_equalizer( Music_Emu const* me, gme_equalizer_t* out )
-{
- gme_equalizer_t e = { };
- e.treble = me->equalizer().treble;
- e.bass = me->equalizer().bass;
- *out = e;
-}
-
-const char* gme_voice_name( Music_Emu const* me, int i )
-{
- assert( (unsigned) i < (unsigned) me->voice_count() );
- return me->voice_names() [i];
-}
-
-const char* gme_type_system( gme_type_t type )
-{
- assert( type );
- return type->system;
-}
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/gme.h b/plugins/gme/game-music-emu-0.5.5/gme/gme.h
deleted file mode 100644
index 5b9039c4..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/gme.h
+++ /dev/null
@@ -1,254 +0,0 @@
-/* Game music emulator library C interface (also usable from C++) */
-
-/* Game_Music_Emu 0.5.5 */
-#ifndef GME_H
-#define GME_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/* Error string returned by library functions, or NULL if no error (success) */
-typedef const char* gme_err_t;
-
-/* First parameter of most gme_ functions is a pointer to the Music_Emu */
-typedef struct Music_Emu Music_Emu;
-
-
-/******** Basic operations ********/
-
-/* Create emulator and load game music file/data into it. Sets *out to new emulator. */
-gme_err_t gme_open_file( const char path [], Music_Emu** out, int sample_rate );
-
-/* Number of tracks available */
-int gme_track_count( Music_Emu const* );
-
-/* Start a track, where 0 is the first track */
-gme_err_t gme_start_track( Music_Emu*, int index );
-
-/* Generate 'count' 16-bit signed samples info 'out'. Output is in stereo. */
-gme_err_t gme_play( Music_Emu*, int count, short out [] );
-
-/* Finish using emulator and free memory */
-void gme_delete( Music_Emu* );
-
-
-/******** Track position/length ********/
-
-/* Set time to start fading track out. Once fade ends track_ended() returns true.
-Fade time can be changed while track is playing. */
-void gme_set_fade( Music_Emu*, int start_msec );
-
-/* True if a track has reached its end */
-int gme_track_ended( Music_Emu const* );
-
-/* Number of milliseconds (1000 = one second) played since beginning of track */
-int gme_tell( Music_Emu const* );
-
-/* Seek to new time in track. Seeking backwards or far forward can take a while. */
-gme_err_t gme_seek( Music_Emu*, int msec );
-
-
-/******** Informational ********/
-
-/* If you only need track information from a music file, pass gme_info_only for
-sample_rate to open/load. */
-enum { gme_info_only = -1 };
-
-/* Most recent warning string, or NULL if none. Clears current warning after returning.
-Warning is also cleared when loading a file and starting a track. */
-const char* gme_warning( Music_Emu* );
-
-/* Load m3u playlist file (must be done after loading music) */
-gme_err_t gme_load_m3u( Music_Emu*, const char path [] );
-
-/* Clear any loaded m3u playlist and any internal playlist that the music format
-supports (NSFE for example). */
-void gme_clear_playlist( Music_Emu* );
-
-/* Gets information for a particular track (length, name, author, etc.).
-Must be freed after use. */
-typedef struct gme_info_t gme_info_t;
-gme_err_t gme_track_info( Music_Emu const*, gme_info_t** out, int track );
-
-/* Frees track information */
-void gme_free_info( gme_info_t* );
-
-struct gme_info_t
-{
- /* times in milliseconds; -1 if unknown */
- int length; /* total length, if file specifies it */
- int intro_length; /* length of song up to looping section */
- int loop_length; /* length of looping section */
-
- /* Length if available, otherwise intro_length+loop_length*2 if available,
- otherwise a default of 150000 (2.5 minutes). */
- int play_length;
-
- int i4,i5,i6,i7,i8,i9,i10,i11,i12,i13,i14,i15; /* reserved */
-
- /* empty string ("") if not available */
- const char* system;
- const char* game;
- const char* song;
- const char* author;
- const char* copyright;
- const char* comment;
- const char* dumper;
-
- const char *s7,*s8,*s9,*s10,*s11,*s12,*s13,*s14,*s15; /* reserved */
-};
-
-
-/******** Advanced playback ********/
-
-/* Adjust stereo echo depth, where 0.0 = off and 1.0 = maximum. Has no effect for
-GYM, SPC, and Sega Genesis VGM music */
-void gme_set_stereo_depth( Music_Emu*, double depth );
-
-/* Disable automatic end-of-track detection and skipping of silence at beginning
-if ignore is true */
-void gme_ignore_silence( Music_Emu*, int ignore );
-
-/* Adjust song tempo, where 1.0 = normal, 0.5 = half speed, 2.0 = double speed.
-Track length as returned by track_info() assumes a tempo of 1.0. */
-void gme_set_tempo( Music_Emu*, double tempo );
-
-/* Number of voices used by currently loaded file */
-int gme_voice_count( Music_Emu const* );
-
-/* Name of voice i, from 0 to gme_voice_count() - 1 */
-const char* gme_voice_name( Music_Emu const*, int i );
-
-/* Mute/unmute voice i, where voice 0 is first voice */
-void gme_mute_voice( Music_Emu*, int index, int mute );
-
-/* Set muting state of all voices at once using a bit mask, where -1 mutes all
-voices, 0 unmutes them all, 0x01 mutes just the first voice, etc. */
-void gme_mute_voices( Music_Emu*, int muting_mask );
-
-/* Frequency equalizer parameters (see gme.txt) */
-typedef struct gme_equalizer_t
-{
- double treble; /* -50.0 = muffled, 0 = flat, +5.0 = extra-crisp */
- double bass; /* 1 = full bass, 90 = average, 16000 = almost no bass */
-
- double d2,d3,d4,d5,d6,d7,d8,d9; /* reserved */
-} gme_equalizer_t;
-
-/* Get current frequency equalizater parameters */
-void gme_equalizer( Music_Emu const*, gme_equalizer_t* out );
-
-/* Change frequency equalizer parameters */
-void gme_set_equalizer( Music_Emu*, gme_equalizer_t const* eq );
-
-
-
-/******** Game music types ********/
-
-/* Music file type identifier. Can also hold NULL. */
-typedef const struct gme_type_t_* gme_type_t;
-
-/* Emulator type constants for each supported file type */
-extern const gme_type_t
- gme_ay_type,
- gme_gbs_type,
- gme_gym_type,
- gme_hes_type,
- gme_kss_type,
- gme_nsf_type,
- gme_nsfe_type,
- gme_sap_type,
- gme_spc_type,
- gme_vgm_type,
- gme_vgz_type;
-
-/* Type of this emulator */
-gme_type_t gme_type( Music_Emu const* );
-
-/* Pointer to array of all music types, with NULL entry at end. Allows a player linked
-to this library to support new music types without having to be updated. */
-gme_type_t const* gme_type_list();
-
-/* Name of game system for this music file type */
-const char* gme_type_system( gme_type_t );
-
-/* True if this music file type supports multiple tracks */
-int gme_type_multitrack( gme_type_t );
-
-
-/******** Advanced file loading ********/
-
-/* Error returned if file type is not supported */
-extern const char* const gme_wrong_file_type;
-
-/* Same as gme_open_file(), but uses file data already in memory. Makes copy of data. */
-gme_err_t gme_open_data( void const* data, long size, Music_Emu** out, int sample_rate );
-
-/* Determine likely game music type based on first four bytes of file. Returns
-string containing proper file suffix (i.e. "NSF", "SPC", etc.) or "" if
-file header is not recognized. */
-const char* gme_identify_header( void const* header );
-
-/* Get corresponding music type for file path or extension passed in. */
-gme_type_t gme_identify_extension( const char path_or_extension [] );
-
-/* Determine file type based on file's extension or header (if extension isn't recognized).
-Sets *type_out to type, or 0 if unrecognized or error. */
-gme_err_t gme_identify_file( const char path [], gme_type_t* type_out );
-
-/* Create new emulator and set sample rate. Returns NULL if out of memory. If you only need
-track information, pass gme_info_only for sample_rate. */
-Music_Emu* gme_new_emu( gme_type_t, int sample_rate );
-
-/* Load music file into emulator */
-gme_err_t gme_load_file( Music_Emu*, const char path [] );
-
-/* Load music file from memory into emulator. Makes a copy of data passed. */
-gme_err_t gme_load_data( Music_Emu*, void const* data, long size );
-
-/* Load music file using custom data reader function that will be called to
-read file data. Most emulators load the entire file in one read call. */
-typedef gme_err_t (*gme_reader_t)( void* your_data, void* out, int count );
-gme_err_t gme_load_custom( Music_Emu*, gme_reader_t, long file_size, void* your_data );
-
-/* Load m3u playlist file from memory (must be done after loading music) */
-gme_err_t gme_load_m3u_data( Music_Emu*, void const* data, long size );
-
-
-/******** User data ********/
-
-/* Set/get pointer to data you want to associate with this emulator.
-You can use this for whatever you want. */
-void gme_set_user_data( Music_Emu*, void* new_user_data );
-void* gme_user_data( Music_Emu const* );
-
-/* Register cleanup function to be called when deleting emulator, or NULL to
-clear it. Passes user_data to cleanup function. */
-typedef void (*gme_user_cleanup_t)( void* user_data );
-void gme_set_user_cleanup( Music_Emu*, gme_user_cleanup_t func );
-
-typedef struct
-{
- long track_count;
-
- /* times in milliseconds; -1 if unknown */
- long length;
- long intro_length;
- long loop_length;
-
- /* empty string if not available */
- char system [256];
- char game [256];
- char song [256];
- char author [256];
- char copyright [256];
- char comment [256];
- char dumper [256];
-} track_info_t;
-
-#ifdef __cplusplus
- }
-#endif
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/gme_types.h b/plugins/gme/game-music-emu-0.5.5/gme/gme_types.h
deleted file mode 100644
index 915b87a0..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/gme_types.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef GME_TYPES_H
-#define GME_TYPES_H
-
-#define USE_GME_AY 1
-#define USE_GME_GBS 1
-#define USE_GME_GYM 1
-#define USE_GME_HES 1
-#define USE_GME_KSS 1
-#define USE_GME_NSF 1
-#define USE_GME_NSFE 1
-#define USE_GME_SAP 1
-#define USE_GME_SPC 1
-#define USE_GME_VGM 1
-
-#endif /* GME_TYPES_H */
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/gme_types.h.in b/plugins/gme/game-music-emu-0.5.5/gme/gme_types.h.in
deleted file mode 100644
index 4829b3e1..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/gme_types.h.in
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef GME_TYPES_H
-#define GME_TYPES_H
-
-/* CMake will either define the following to 1, or #undef it,
- * depending on the options passed to CMake. This is used to
- * conditionally compile in the various emulator types.
- *
- * See gme_type_list() in gme.cpp
- */
-
-#cmakedefine USE_GME_AY
-#cmakedefine USE_GME_GBS
-#cmakedefine USE_GME_GYM
-#cmakedefine USE_GME_HES
-#cmakedefine USE_GME_KSS
-#cmakedefine USE_GME_NSF
-#cmakedefine USE_GME_NSFE
-#cmakedefine USE_GME_SAP
-#cmakedefine USE_GME_SPC
-/* VGM and VGZ are a package deal */
-#cmakedefine USE_GME_VGM
-
-#endif /* GME_TYPES_H */
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/hes_cpu_io.h b/plugins/gme/game-music-emu-0.5.5/gme/hes_cpu_io.h
deleted file mode 100644
index ce60ce8e..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/hes_cpu_io.h
+++ /dev/null
@@ -1,101 +0,0 @@
-
-#include "Hes_Emu.h"
-
-#include "blargg_source.h"
-
-int Hes_Emu::cpu_read( hes_addr_t addr )
-{
- check( addr <= 0xFFFF );
- int result = *cpu::get_code( addr );
- if ( mmr [addr >> page_shift] == 0xFF )
- result = cpu_read_( addr );
- return result;
-}
-
-void Hes_Emu::cpu_write( hes_addr_t addr, int data )
-{
- check( addr <= 0xFFFF );
- byte* out = write_pages [addr >> page_shift];
- addr &= page_size - 1;
- if ( out )
- out [addr] = data;
- else if ( mmr [addr >> page_shift] == 0xFF )
- cpu_write_( addr, data );
-}
-
-inline byte const* Hes_Emu::cpu_set_mmr( int page, int bank )
-{
- write_pages [page] = 0;
- if ( bank < 0x80 )
- return rom.at_addr( bank * (blargg_long) page_size );
-
- byte* data = 0;
- switch ( bank )
- {
- case 0xF8:
- data = cpu::ram;
- break;
-
- case 0xF9:
- case 0xFA:
- case 0xFB:
- data = &sgx [(bank - 0xF9) * page_size];
- break;
-
- default:
- if ( bank != 0xFF )
- debug_printf( "Unmapped bank $%02X\n", bank );
- return rom.unmapped();
- }
-
- write_pages [page] = data;
- return data;
-}
-
-#define CPU_READ_FAST( cpu, addr, time, out ) \
- CPU_READ_FAST_( STATIC_CAST(Hes_Emu*,cpu), addr, time, out )
-
-#define CPU_READ_FAST_( cpu, addr, time, out ) \
-{\
- out = READ_PROG( addr );\
- if ( mmr [addr >> page_shift] == 0xFF )\
- {\
- FLUSH_TIME();\
- out = cpu->cpu_read_( addr );\
- CACHE_TIME();\
- }\
-}
-
-#define CPU_WRITE_FAST( cpu, addr, data, time ) \
- CPU_WRITE_FAST_( STATIC_CAST(Hes_Emu*,cpu), addr, data, time )
-
-#define CPU_WRITE_FAST_( cpu, addr, data, time ) \
-{\
- byte* out = cpu->write_pages [addr >> page_shift];\
- addr &= page_size - 1;\
- if ( out )\
- {\
- out [addr] = data;\
- }\
- else if ( mmr [addr >> page_shift] == 0xFF )\
- {\
- FLUSH_TIME();\
- cpu->cpu_write_( addr, data );\
- CACHE_TIME();\
- }\
-}
-
-#define CPU_READ( cpu, addr, time ) \
- STATIC_CAST(Hes_Emu*,cpu)->cpu_read( addr )
-
-#define CPU_WRITE( cpu, addr, data, time ) \
- STATIC_CAST(Hes_Emu*,cpu)->cpu_write( addr, data )
-
-#define CPU_WRITE_VDP( cpu, addr, data, time ) \
- STATIC_CAST(Hes_Emu*,cpu)->cpu_write_vdp( addr, data )
-
-#define CPU_SET_MMR( cpu, page, bank ) \
- STATIC_CAST(Hes_Emu*,cpu)->cpu_set_mmr( page, bank )
-
-#define CPU_DONE( cpu, time, result_out ) \
- result_out = STATIC_CAST(Hes_Emu*,cpu)->cpu_done()
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/nes_cpu_io.h b/plugins/gme/game-music-emu-0.5.5/gme/nes_cpu_io.h
deleted file mode 100644
index 68ce9b6f..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/nes_cpu_io.h
+++ /dev/null
@@ -1,83 +0,0 @@
-
-#include "Nsf_Emu.h"
-
-#if !NSF_EMU_APU_ONLY
- #include "Nes_Namco_Apu.h"
-#endif
-
-#include "blargg_source.h"
-
-int Nsf_Emu::cpu_read( nes_addr_t addr )
-{
- int result;
-
- result = cpu::low_mem [addr & 0x7FF];
- if ( !(addr & 0xE000) )
- goto exit;
-
- result = *cpu::get_code( addr );
- if ( addr > 0x7FFF )
- goto exit;
-
- result = sram [addr & (sizeof sram - 1)];
- if ( addr > 0x5FFF )
- goto exit;
-
- if ( addr == Nes_Apu::status_addr )
- return apu.read_status( cpu::time() );
-
- #if !NSF_EMU_APU_ONLY
- if ( addr == Nes_Namco_Apu::data_reg_addr && namco )
- return namco->read_data();
- #endif
-
- result = addr >> 8; // simulate open bus
-
- if ( addr != 0x2002 )
- debug_printf( "Read unmapped $%.4X\n", (unsigned) addr );
-
-exit:
- return result;
-}
-
-void Nsf_Emu::cpu_write( nes_addr_t addr, int data )
-{
- {
- nes_addr_t offset = addr ^ sram_addr;
- if ( offset < sizeof sram )
- {
- sram [offset] = data;
- return;
- }
- }
- {
- int temp = addr & 0x7FF;
- if ( !(addr & 0xE000) )
- {
- cpu::low_mem [temp] = data;
- return;
- }
- }
-
- if ( unsigned (addr - Nes_Apu::start_addr) <= Nes_Apu::end_addr - Nes_Apu::start_addr )
- {
- GME_APU_HOOK( this, addr - Nes_Apu::start_addr, data );
- apu.write_register( cpu::time(), addr, data );
- return;
- }
-
- unsigned bank = addr - bank_select_addr;
- if ( bank < bank_count )
- {
- blargg_long offset = rom.mask_addr( data * (blargg_long) bank_size );
- if ( offset >= rom.size() )
- set_warning( "Invalid bank" );
- cpu::map_code( (bank + 8) * bank_size, bank_size, rom.at_addr( offset ) );
- return;
- }
-
- cpu_write_misc( addr, data );
-}
-
-#define CPU_READ( cpu, addr, time ) STATIC_CAST(Nsf_Emu&,*cpu).cpu_read( addr )
-#define CPU_WRITE( cpu, addr, data, time ) STATIC_CAST(Nsf_Emu&,*cpu).cpu_write( addr, data )
diff --git a/plugins/gme/game-music-emu-0.5.5/gme/sap_cpu_io.h b/plugins/gme/game-music-emu-0.5.5/gme/sap_cpu_io.h
deleted file mode 100644
index d009d0d9..00000000
--- a/plugins/gme/game-music-emu-0.5.5/gme/sap_cpu_io.h
+++ /dev/null
@@ -1,26 +0,0 @@
-
-#include "Sap_Emu.h"
-
-#include "blargg_source.h"
-
-#define CPU_WRITE( cpu, addr, data, time ) STATIC_CAST(Sap_Emu&,*cpu).cpu_write( addr, data )
-
-void Sap_Emu::cpu_write( sap_addr_t addr, int data )
-{
- mem.ram [addr] = data;
- if ( (addr >> 8) == 0xD2 )
- cpu_write_( addr, data );
-}
-
-#ifdef NDEBUG
- #define CPU_READ( cpu, addr, time ) READ_LOW( addr )
-#else
- #define CPU_READ( cpu, addr, time ) STATIC_CAST(Sap_Emu&,*cpu).cpu_read( addr )
-
- int Sap_Emu::cpu_read( sap_addr_t addr )
- {
- if ( (addr & 0xF900) == 0xD000 )
- debug_printf( "Unmapped read $%04X\n", addr );
- return mem.ram [addr];
- }
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/license.txt b/plugins/gme/game-music-emu-0.5.5/license.txt
deleted file mode 100644
index 5faba9d4..00000000
--- a/plugins/gme/game-music-emu-0.5.5/license.txt
+++ /dev/null
@@ -1,504 +0,0 @@
- GNU LESSER GENERAL PUBLIC LICENSE
- Version 2.1, February 1999
-
- Copyright (C) 1991, 1999 Free Software Foundation, Inc.
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-[This is the first released version of the Lesser GPL. It also counts
- as the successor of the GNU Library Public License, version 2, hence
- the version number 2.1.]
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-Licenses are intended to guarantee your freedom to share and change
-free software--to make sure the software is free for all its users.
-
- This license, the Lesser General Public License, applies to some
-specially designated software packages--typically libraries--of the
-Free Software Foundation and other authors who decide to use it. You
-can use it too, but we suggest you first think carefully about whether
-this license or the ordinary General Public License is the better
-strategy to use in any particular case, based on the explanations below.
-
- When we speak of free software, we are referring to freedom of use,
-not price. Our General Public Licenses are designed to make sure that
-you have the freedom to distribute copies of free software (and charge
-for this service if you wish); that you receive source code or can get
-it if you want it; that you can change the software and use pieces of
-it in new free programs; and that you are informed that you can do
-these things.
-
- To protect your rights, we need to make restrictions that forbid
-distributors to deny you these rights or to ask you to surrender these
-rights. These restrictions translate to certain responsibilities for
-you if you distribute copies of the library or if you modify it.
-
- For example, if you distribute copies of the library, whether gratis
-or for a fee, you must give the recipients all the rights that we gave
-you. You must make sure that they, too, receive or can get the source
-code. If you link other code with the library, you must provide
-complete object files to the recipients, so that they can relink them
-with the library after making changes to the library and recompiling
-it. And you must show them these terms so they know their rights.
-
- We protect your rights with a two-step method: (1) we copyright the
-library, and (2) we offer you this license, which gives you legal
-permission to copy, distribute and/or modify the library.
-
- To protect each distributor, we want to make it very clear that
-there is no warranty for the free library. Also, if the library is
-modified by someone else and passed on, the recipients should know
-that what they have is not the original version, so that the original
-author's reputation will not be affected by problems that might be
-introduced by others.
-
- Finally, software patents pose a constant threat to the existence of
-any free program. We wish to make sure that a company cannot
-effectively restrict the users of a free program by obtaining a
-restrictive license from a patent holder. Therefore, we insist that
-any patent license obtained for a version of the library must be
-consistent with the full freedom of use specified in this license.
-
- Most GNU software, including some libraries, is covered by the
-ordinary GNU General Public License. This license, the GNU Lesser
-General Public License, applies to certain designated libraries, and
-is quite different from the ordinary General Public License. We use
-this license for certain libraries in order to permit linking those
-libraries into non-free programs.
-
- When a program is linked with a library, whether statically or using
-a shared library, the combination of the two is legally speaking a
-combined work, a derivative of the original library. The ordinary
-General Public License therefore permits such linking only if the
-entire combination fits its criteria of freedom. The Lesser General
-Public License permits more lax criteria for linking other code with
-the library.
-
- We call this license the "Lesser" General Public License because it
-does Less to protect the user's freedom than the ordinary General
-Public License. It also provides other free software developers Less
-of an advantage over competing non-free programs. These disadvantages
-are the reason we use the ordinary General Public License for many
-libraries. However, the Lesser license provides advantages in certain
-special circumstances.
-
- For example, on rare occasions, there may be a special need to
-encourage the widest possible use of a certain library, so that it becomes
-a de-facto standard. To achieve this, non-free programs must be
-allowed to use the library. A more frequent case is that a free
-library does the same job as widely used non-free libraries. In this
-case, there is little to gain by limiting the free library to free
-software only, so we use the Lesser General Public License.
-
- In other cases, permission to use a particular library in non-free
-programs enables a greater number of people to use a large body of
-free software. For example, permission to use the GNU C Library in
-non-free programs enables many more people to use the whole GNU
-operating system, as well as its variant, the GNU/Linux operating
-system.
-
- Although the Lesser General Public License is Less protective of the
-users' freedom, it does ensure that the user of a program that is
-linked with the Library has the freedom and the wherewithal to run
-that program using a modified version of the Library.
-
- The precise terms and conditions for copying, distribution and
-modification follow. Pay close attention to the difference between a
-"work based on the library" and a "work that uses the library". The
-former contains code derived from the library, whereas the latter must
-be combined with the library in order to run.
-
- GNU LESSER GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License Agreement applies to any software library or other
-program which contains a notice placed by the copyright holder or
-other authorized party saying it may be distributed under the terms of
-this Lesser General Public License (also called "this License").
-Each licensee is addressed as "you".
-
- A "library" means a collection of software functions and/or data
-prepared so as to be conveniently linked with application programs
-(which use some of those functions and data) to form executables.
-
- The "Library", below, refers to any such software library or work
-which has been distributed under these terms. A "work based on the
-Library" means either the Library or any derivative work under
-copyright law: that is to say, a work containing the Library or a
-portion of it, either verbatim or with modifications and/or translated
-straightforwardly into another language. (Hereinafter, translation is
-included without limitation in the term "modification".)
-
- "Source code" for a work means the preferred form of the work for
-making modifications to it. For a library, complete source code means
-all the source code for all modules it contains, plus any associated
-interface definition files, plus the scripts used to control compilation
-and installation of the library.
-
- Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running a program using the Library is not restricted, and output from
-such a program is covered only if its contents constitute a work based
-on the Library (independent of the use of the Library in a tool for
-writing it). Whether that is true depends on what the Library does
-and what the program that uses the Library does.
-
- 1. You may copy and distribute verbatim copies of the Library's
-complete source code as you receive it, in any medium, provided that
-you conspicuously and appropriately publish on each copy an
-appropriate copyright notice and disclaimer of warranty; keep intact
-all the notices that refer to this License and to the absence of any
-warranty; and distribute a copy of this License along with the
-Library.
-
- You may charge a fee for the physical act of transferring a copy,
-and you may at your option offer warranty protection in exchange for a
-fee.
-
- 2. You may modify your copy or copies of the Library or any portion
-of it, thus forming a work based on the Library, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) The modified work must itself be a software library.
-
- b) You must cause the files modified to carry prominent notices
- stating that you changed the files and the date of any change.
-
- c) You must cause the whole of the work to be licensed at no
- charge to all third parties under the terms of this License.
-
- d) If a facility in the modified Library refers to a function or a
- table of data to be supplied by an application program that uses
- the facility, other than as an argument passed when the facility
- is invoked, then you must make a good faith effort to ensure that,
- in the event an application does not supply such function or
- table, the facility still operates, and performs whatever part of
- its purpose remains meaningful.
-
- (For example, a function in a library to compute square roots has
- a purpose that is entirely well-defined independent of the
- application. Therefore, Subsection 2d requires that any
- application-supplied function or table used by this function must
- be optional: if the application does not supply it, the square
- root function must still compute square roots.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Library,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Library, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote
-it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Library.
-
-In addition, mere aggregation of another work not based on the Library
-with the Library (or with a work based on the Library) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may opt to apply the terms of the ordinary GNU General Public
-License instead of this License to a given copy of the Library. To do
-this, you must alter all the notices that refer to this License, so
-that they refer to the ordinary GNU General Public License, version 2,
-instead of to this License. (If a newer version than version 2 of the
-ordinary GNU General Public License has appeared, then you can specify
-that version instead if you wish.) Do not make any other change in
-these notices.
-
- Once this change is made in a given copy, it is irreversible for
-that copy, so the ordinary GNU General Public License applies to all
-subsequent copies and derivative works made from that copy.
-
- This option is useful when you wish to copy part of the code of
-the Library into a program that is not a library.
-
- 4. You may copy and distribute the Library (or a portion or
-derivative of it, under Section 2) in object code or executable form
-under the terms of Sections 1 and 2 above provided that you accompany
-it with the complete corresponding machine-readable source code, which
-must be distributed under the terms of Sections 1 and 2 above on a
-medium customarily used for software interchange.
-
- If distribution of object code is made by offering access to copy
-from a designated place, then offering equivalent access to copy the
-source code from the same place satisfies the requirement to
-distribute the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 5. A program that contains no derivative of any portion of the
-Library, but is designed to work with the Library by being compiled or
-linked with it, is called a "work that uses the Library". Such a
-work, in isolation, is not a derivative work of the Library, and
-therefore falls outside the scope of this License.
-
- However, linking a "work that uses the Library" with the Library
-creates an executable that is a derivative of the Library (because it
-contains portions of the Library), rather than a "work that uses the
-library". The executable is therefore covered by this License.
-Section 6 states terms for distribution of such executables.
-
- When a "work that uses the Library" uses material from a header file
-that is part of the Library, the object code for the work may be a
-derivative work of the Library even though the source code is not.
-Whether this is true is especially significant if the work can be
-linked without the Library, or if the work is itself a library. The
-threshold for this to be true is not precisely defined by law.
-
- If such an object file uses only numerical parameters, data
-structure layouts and accessors, and small macros and small inline
-functions (ten lines or less in length), then the use of the object
-file is unrestricted, regardless of whether it is legally a derivative
-work. (Executables containing this object code plus portions of the
-Library will still fall under Section 6.)
-
- Otherwise, if the work is a derivative of the Library, you may
-distribute the object code for the work under the terms of Section 6.
-Any executables containing that work also fall under Section 6,
-whether or not they are linked directly with the Library itself.
-
- 6. As an exception to the Sections above, you may also combine or
-link a "work that uses the Library" with the Library to produce a
-work containing portions of the Library, and distribute that work
-under terms of your choice, provided that the terms permit
-modification of the work for the customer's own use and reverse
-engineering for debugging such modifications.
-
- You must give prominent notice with each copy of the work that the
-Library is used in it and that the Library and its use are covered by
-this License. You must supply a copy of this License. If the work
-during execution displays copyright notices, you must include the
-copyright notice for the Library among them, as well as a reference
-directing the user to the copy of this License. Also, you must do one
-of these things:
-
- a) Accompany the work with the complete corresponding
- machine-readable source code for the Library including whatever
- changes were used in the work (which must be distributed under
- Sections 1 and 2 above); and, if the work is an executable linked
- with the Library, with the complete machine-readable "work that
- uses the Library", as object code and/or source code, so that the
- user can modify the Library and then relink to produce a modified
- executable containing the modified Library. (It is understood
- that the user who changes the contents of definitions files in the
- Library will not necessarily be able to recompile the application
- to use the modified definitions.)
-
- b) Use a suitable shared library mechanism for linking with the
- Library. A suitable mechanism is one that (1) uses at run time a
- copy of the library already present on the user's computer system,
- rather than copying library functions into the executable, and (2)
- will operate properly with a modified version of the library, if
- the user installs one, as long as the modified version is
- interface-compatible with the version that the work was made with.
-
- c) Accompany the work with a written offer, valid for at
- least three years, to give the same user the materials
- specified in Subsection 6a, above, for a charge no more
- than the cost of performing this distribution.
-
- d) If distribution of the work is made by offering access to copy
- from a designated place, offer equivalent access to copy the above
- specified materials from the same place.
-
- e) Verify that the user has already received a copy of these
- materials or that you have already sent this user a copy.
-
- For an executable, the required form of the "work that uses the
-Library" must include any data and utility programs needed for
-reproducing the executable from it. However, as a special exception,
-the materials to be distributed need not include anything that is
-normally distributed (in either source or binary form) with the major
-components (compiler, kernel, and so on) of the operating system on
-which the executable runs, unless that component itself accompanies
-the executable.
-
- It may happen that this requirement contradicts the license
-restrictions of other proprietary libraries that do not normally
-accompany the operating system. Such a contradiction means you cannot
-use both them and the Library together in an executable that you
-distribute.
-
- 7. You may place library facilities that are a work based on the
-Library side-by-side in a single library together with other library
-facilities not covered by this License, and distribute such a combined
-library, provided that the separate distribution of the work based on
-the Library and of the other library facilities is otherwise
-permitted, and provided that you do these two things:
-
- a) Accompany the combined library with a copy of the same work
- based on the Library, uncombined with any other library
- facilities. This must be distributed under the terms of the
- Sections above.
-
- b) Give prominent notice with the combined library of the fact
- that part of it is a work based on the Library, and explaining
- where to find the accompanying uncombined form of the same work.
-
- 8. You may not copy, modify, sublicense, link with, or distribute
-the Library except as expressly provided under this License. Any
-attempt otherwise to copy, modify, sublicense, link with, or
-distribute the Library is void, and will automatically terminate your
-rights under this License. However, parties who have received copies,
-or rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
- 9. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Library or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Library (or any work based on the
-Library), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Library or works based on it.
-
- 10. Each time you redistribute the Library (or any work based on the
-Library), the recipient automatically receives a license from the
-original licensor to copy, distribute, link with or modify the Library
-subject to these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties with
-this License.
-
- 11. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Library at all. For example, if a patent
-license would not permit royalty-free redistribution of the Library by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Library.
-
-If any portion of this section is held invalid or unenforceable under any
-particular circumstance, the balance of the section is intended to apply,
-and the section as a whole is intended to apply in other circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 12. If the distribution and/or use of the Library is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Library under this License may add
-an explicit geographical distribution limitation excluding those countries,
-so that distribution is permitted only in or among countries not thus
-excluded. In such case, this License incorporates the limitation as if
-written in the body of this License.
-
- 13. The Free Software Foundation may publish revised and/or new
-versions of the Lesser General Public License from time to time.
-Such new versions will be similar in spirit to the present version,
-but may differ in detail to address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Library
-specifies a version number of this License which applies to it and
-"any later version", you have the option of following the terms and
-conditions either of that version or of any later version published by
-the Free Software Foundation. If the Library does not specify a
-license version number, you may choose any version ever published by
-the Free Software Foundation.
-
- 14. If you wish to incorporate parts of the Library into other free
-programs whose distribution conditions are incompatible with these,
-write to the author to ask for permission. For software which is
-copyrighted by the Free Software Foundation, write to the Free
-Software Foundation; we sometimes make exceptions for this. Our
-decision will be guided by the two goals of preserving the free status
-of all derivatives of our free software and of promoting the sharing
-and reuse of software generally.
-
- NO WARRANTY
-
- 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
-LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Libraries
-
- If you develop a new library, and you want it to be of the greatest
-possible use to the public, we recommend making it free software that
-everyone can redistribute and change. You can do so by permitting
-redistribution under these terms (or, alternatively, under the terms of the
-ordinary General Public License).
-
- To apply these terms, attach the following notices to the library. It is
-safest to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least the
-"copyright" line and a pointer to where the full notice is found.
-
- <one line to give the library's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-Also add information on how to contact you by electronic and paper mail.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the library, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the
- library `Frob' (a library for tweaking knobs) written by James Random Hacker.
-
- <signature of Ty Coon>, 1 April 1990
- Ty Coon, President of Vice
-
-That's all there is to it!
-
-
diff --git a/plugins/gme/game-music-emu-0.5.5/player/Audio_Scope.cpp b/plugins/gme/game-music-emu-0.5.5/player/Audio_Scope.cpp
deleted file mode 100644
index 464392d5..00000000
--- a/plugins/gme/game-music-emu-0.5.5/player/Audio_Scope.cpp
+++ /dev/null
@@ -1,198 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Audio_Scope.h"
-
-#include <assert.h>
-#include <stdlib.h>
-
-/* Copyright (C) 2005-2006 by Shay Green. Permission is hereby granted, free of
-charge, to any person obtaining a copy of this software module and associated
-documentation files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use, copy, modify,
-merge, publish, distribute, sublicense, and/or sell copies of the Software, and
-to permit persons to whom the Software is furnished to do so, subject to the
-following conditions: The above copyright notice and this permission notice
-shall be included in all copies or substantial portions of the Software. THE
-SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
-INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
-PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-
-int const step_bits = 8;
-int const step_unit = 1 << step_bits;
-int const erase_color = 1;
-int const draw_color = 2;
-
-Audio_Scope::Audio_Scope()
-{
- surface = 0;
- buf = 0;
-}
-
-Audio_Scope::~Audio_Scope()
-{
- free( buf );
-
- if ( surface )
- SDL_FreeSurface( surface );
-}
-
-const char* Audio_Scope::init( int width, int height )
-{
- assert( height <= 256 );
- assert( !buf ); // can only call init() once
-
- buf = (byte*) calloc( width * sizeof *buf, 1 );
- if ( !buf )
- return "Out of memory";
-
- low_y = 0;
- high_y = height;
- buf_size = width;
-
- for ( sample_shift = 6; sample_shift < 14; )
- if ( ((0x7FFFL * 2) >> sample_shift++) < height )
- break;
-
- v_offset = height / 2 - (0x10000 >> sample_shift);
-
- screen = SDL_SetVideoMode( width, height, 0, 0 );
- if ( !screen )
- return "Couldn't set video mode";
-
- surface = SDL_CreateRGBSurface( SDL_SWSURFACE, width, height, 8, 0, 0, 0, 0 );
- if ( !screen )
- return "Couldn't create surface";
-
- static SDL_Color palette [2] = { {0, 0, 0}, {0, 255, 0} };
- SDL_SetColors( surface, palette, 1, 2 );
-
- return 0; // success
-}
-
-const char* Audio_Scope::draw( const short* in, long count, double step )
-{
- int low = low_y;
- int high = high_y;
-
- if ( count >= buf_size )
- {
- count = buf_size;
- low_y = 0x7FFF;
- high_y = 0;
- }
-
- if ( SDL_LockSurface( surface ) < 0 )
- return "Couldn't lock surface";
- render( in, count, (long) (step * step_unit) );
- SDL_UnlockSurface( surface );
-
- if ( low > low_y )
- low = low_y;
-
- if ( high < high_y )
- high = high_y;
-
- SDL_Rect r;
- r.x = 0;
- r.w = buf_size;
- r.y = low + v_offset;
- r.h = high - low + 1;
-
- if ( SDL_BlitSurface( surface, &r, screen, &r ) < 0 )
- return "Blit to screen failed";
-
- if ( SDL_Flip( screen ) < 0 )
- return "Couldn't flip screen";
-
- return 0; // success
-}
-
-void Audio_Scope::render( short const* in, long count, long step )
-{
- byte* old_pos = buf;
- long surface_pitch = surface->pitch;
- byte* out = (byte*) surface->pixels + v_offset * surface_pitch;
- int old_erase = *old_pos;
- int old_draw = 0;
- long in_pos = 0;
-
- int low_y = this->low_y;
- int high_y = this->high_y;
- int half_step = (step + step_unit / 2) >> (step_bits + 1);
-
- while ( count-- )
- {
- // Line drawing/erasing starts at previous sample and ends one short of
- // current sample, except when previous and current are the same.
-
- // Extra read on the last iteration of line loops will always be at the
- // height of the next sample, and thus within the gworld bounds.
-
- // Erase old line
- {
- int delta = *old_pos - old_erase;
- int offset = old_erase * surface_pitch;
- old_erase += delta;
-
- int next_line = surface_pitch;
- if ( delta < 0 )
- {
- delta = -delta;
- next_line = -surface_pitch;
- }
-
- do
- {
- out [offset] = erase_color;
- offset += next_line;
- }
- while ( delta-- > 1 );
- }
-
- // Draw new line and put in old_buf
- {
-
- int in_whole = in_pos >> step_bits;
- int sample = (0x7FFF * 2 - in [in_whole] - in [in_whole + half_step]) >> sample_shift;
- if ( !in_pos )
- old_draw = sample;
- in_pos += step;
-
- int delta = sample - old_draw;
- int offset = old_draw * surface_pitch;
- old_draw += delta;
-
- int next_line = surface_pitch;
- if ( delta < 0 )
- {
- delta = -delta;
- next_line = -surface_pitch;
- }
-
- *old_pos++ = sample;
-
- // min/max updating can be interleved anywhere
-
- if ( low_y > sample )
- low_y = sample;
-
- do
- {
- out [offset] = draw_color;
- offset += next_line;
- }
- while ( delta-- > 1 );
-
- if ( high_y < sample )
- high_y = sample;
- }
-
- out++;
- }
-
- this->low_y = low_y;
- this->high_y = high_y;
-}
diff --git a/plugins/gme/game-music-emu-0.5.5/player/Audio_Scope.h b/plugins/gme/game-music-emu-0.5.5/player/Audio_Scope.h
deleted file mode 100644
index 75334676..00000000
--- a/plugins/gme/game-music-emu-0.5.5/player/Audio_Scope.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Simple audio waveform scope in a window, using SDL multimedia library
-
-#ifndef AUDIO_SCOPE_H
-#define AUDIO_SCOPE_H
-
-#include "SDL.h"
-
-class Audio_Scope {
-public:
- typedef const char* error_t;
-
- // Initialize scope window of specified size. Height must be 256 or less.
- error_t init( int width, int height );
-
- // Draw at most 'count' samples from 'in', skipping 'step' samples after
- // each sample drawn. Step can be less than 1.0.
- error_t draw( const short* in, long count, double step = 1.0 );
-
- Audio_Scope();
- ~Audio_Scope();
-
-private:
- typedef unsigned char byte;
- SDL_Surface* screen;
- SDL_Surface* surface;
- byte* buf;
- int buf_size;
- int sample_shift;
- int low_y;
- int high_y;
- int v_offset;
-
- void render( short const* in, long count, long step );
-};
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/player/Music_Player.cpp b/plugins/gme/game-music-emu-0.5.5/player/Music_Player.cpp
deleted file mode 100644
index e73261fb..00000000
--- a/plugins/gme/game-music-emu-0.5.5/player/Music_Player.cpp
+++ /dev/null
@@ -1,231 +0,0 @@
-// Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
-
-#include "Music_Player.h"
-
-#include "gme/Music_Emu.h"
-
-#include <string.h>
-#include <ctype.h>
-
-/* Copyright (C) 2005-2006 by Shay Green. Permission is hereby granted, free of
-charge, to any person obtaining a copy of this software module and associated
-documentation files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use, copy, modify,
-merge, publish, distribute, sublicense, and/or sell copies of the Software, and
-to permit persons to whom the Software is furnished to do so, subject to the
-following conditions: The above copyright notice and this permission notice
-shall be included in all copies or substantial portions of the Software. THE
-SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
-INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
-PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-
-#include "blargg_source.h"
-
-// Number of audio buffers per second. Adjust if you encounter audio skipping.
-const int fill_rate = 45;
-
-// Simple sound driver using SDL
-typedef void (*sound_callback_t)( void* data, short* out, int count );
-static const char* sound_init( long sample_rate, int buf_size, sound_callback_t, void* data );
-static void sound_start();
-static void sound_stop();
-static void sound_cleanup();
-
-Music_Player::Music_Player()
-{
- emu_ = 0;
- scope_buf = 0;
- paused = false;
-}
-
-blargg_err_t Music_Player::init( long rate )
-{
- sample_rate = rate;
-
- int min_size = sample_rate * 2 / fill_rate;
- int buf_size = 512;
- while ( buf_size < min_size )
- buf_size *= 2;
-
- return sound_init( sample_rate, buf_size, fill_buffer, this );
-}
-
-void Music_Player::stop()
-{
- sound_stop();
- delete emu_;
- emu_ = 0;
-}
-
-Music_Player::~Music_Player()
-{
- stop();
- sound_cleanup();
-}
-
-blargg_err_t Music_Player::load_file( const char* path )
-{
- stop();
-
- RETURN_ERR( gme_open_file( path, &emu_, sample_rate ) );
-
- char m3u_path [256 + 5];
- strncpy( m3u_path, path, 256 );
- m3u_path [256] = 0;
- char* p = strrchr( m3u_path, '.' );
- if ( !p )
- p = m3u_path + strlen( m3u_path );
- strcpy( p, ".m3u" );
- if ( emu_->load_m3u( m3u_path ) ) { } // ignore error
-
- return 0;
-}
-
-int Music_Player::track_count() const
-{
- return emu_ ? emu_->track_count() : false;
-}
-
-blargg_err_t Music_Player::start_track( int track )
-{
- if ( emu_ )
- {
- // Sound must not be running when operating on emulator
- sound_stop();
- RETURN_ERR( emu_->start_track( track ) );
-
- // Calculate track length
- if ( !emu_->track_info( &track_info_ ) )
- {
- if ( track_info_.length <= 0 )
- track_info_.length = track_info_.intro_length +
- track_info_.loop_length * 2;
- }
- if ( track_info_.length <= 0 )
- track_info_.length = (long) (2.5 * 60 * 1000);
- emu_->set_fade( track_info_.length );
-
- paused = false;
- sound_start();
- }
- return 0;
-}
-
-void Music_Player::pause( int b )
-{
- paused = b;
- if ( b )
- sound_stop();
- else
- sound_start();
-}
-
-void Music_Player::suspend()
-{
- if ( !paused )
- sound_stop();
-}
-
-void Music_Player::resume()
-{
- if ( !paused )
- sound_start();
-}
-
-bool Music_Player::track_ended() const
-{
- return emu_ ? emu_->track_ended() : false;
-}
-
-void Music_Player::set_stereo_depth( double tempo )
-{
- suspend();
- gme_set_stereo_depth( emu_, tempo );
- resume();
-}
-
-void Music_Player::set_tempo( double tempo )
-{
- suspend();
- emu_->set_tempo( tempo );
- resume();
-}
-
-void Music_Player::mute_voices( int mask )
-{
- suspend();
- emu_->mute_voices( mask );
- emu_->ignore_silence( mask != 0 );
- resume();
-}
-
-void Music_Player::fill_buffer( void* data, sample_t* out, int count )
-{
- Music_Player* self = (Music_Player*) data;
- if ( self->emu_ )
- {
- if ( self->emu_->play( count, out ) ) { } // ignore error
-
- if ( self->scope_buf )
- memcpy( self->scope_buf, out, self->scope_buf_size * sizeof *self->scope_buf );
- }
-}
-
-// Sound output driver using SDL
-
-#include "SDL.h"
-
-static sound_callback_t sound_callback;
-static void* sound_callback_data;
-
-static void sdl_callback( void* data, Uint8* out, int count )
-{
- if ( sound_callback )
- sound_callback( sound_callback_data, (short*) out, count / 2 );
-}
-
-static const char* sound_init( long sample_rate, int buf_size,
- sound_callback_t cb, void* data )
-{
- sound_callback = cb;
- sound_callback_data = data;
-
- static SDL_AudioSpec as; // making static clears all fields to 0
- as.freq = sample_rate;
- as.format = AUDIO_S16SYS;
- as.channels = 2;
- as.callback = sdl_callback;
- as.samples = buf_size;
- if ( SDL_OpenAudio( &as, 0 ) < 0 )
- {
- const char* err = SDL_GetError();
- if ( !err )
- err = "Couldn't open SDL audio";
- return err;
- }
-
- return 0;
-}
-
-static void sound_start()
-{
- SDL_PauseAudio( false );
-}
-
-static void sound_stop()
-{
- SDL_PauseAudio( true );
-
- // be sure audio thread is not active
- SDL_LockAudio();
- SDL_UnlockAudio();
-}
-
-static void sound_cleanup()
-{
- sound_stop();
- SDL_CloseAudio();
-}
diff --git a/plugins/gme/game-music-emu-0.5.5/player/Music_Player.h b/plugins/gme/game-music-emu-0.5.5/player/Music_Player.h
deleted file mode 100644
index 82115fc6..00000000
--- a/plugins/gme/game-music-emu-0.5.5/player/Music_Player.h
+++ /dev/null
@@ -1,69 +0,0 @@
-// Simple game music file player
-
-// Game_Music_Emu 0.5.5
-#ifndef MUSIC_PLAYER_H
-#define MUSIC_PLAYER_H
-
-#include "gme/Music_Emu.h"
-
-class Music_Player {
-public:
- // Initialize player and set sample rate
- blargg_err_t init( long sample_rate = 44100 );
-
- // Load game music file. NULL on success, otherwise error string.
- blargg_err_t load_file( const char* path );
-
- // (Re)start playing track. Tracks are numbered from 0 to track_count() - 1.
- blargg_err_t start_track( int track );
-
- // Stop playing current file
- void stop();
-
-// Optional functions
-
- // Number of tracks in current file, or 0 if no file loaded.
- int track_count() const;
-
- // Info for current track
- track_info_t const& track_info() const { return track_info_; }
-
- // Pause/resume playing current track.
- void pause( int );
-
- // True if track ended
- bool track_ended() const;
-
- // Pointer to emulator
- Music_Emu* emu() const { return emu_; }
-
- // Set stereo depth, where 0.0 = none and 1.0 = maximum
- void set_stereo_depth( double );
-
- // Set tempo, where 0.5 = half speed, 1.0 = normal, 2.0 = double speed
- void set_tempo( double );
-
- // Set voice muting bitmask
- void mute_voices( int );
-
- // Set buffer to copy samples from each buffer into, or NULL to disable
- typedef short sample_t;
- void set_scope_buffer( sample_t* buf, int size ) { scope_buf = buf; scope_buf_size = size; }
-
-public:
- Music_Player();
- ~Music_Player();
-private:
- Music_Emu* emu_;
- sample_t* scope_buf;
- long sample_rate;
- int scope_buf_size;
- bool paused;
- track_info_t track_info_;
-
- void suspend();
- void resume();
- static void fill_buffer( void*, sample_t*, int );
-};
-
-#endif
diff --git a/plugins/gme/game-music-emu-0.5.5/player/player.cpp b/plugins/gme/game-music-emu-0.5.5/player/player.cpp
deleted file mode 100644
index 59d66729..00000000
--- a/plugins/gme/game-music-emu-0.5.5/player/player.cpp
+++ /dev/null
@@ -1,213 +0,0 @@
-/* How to play game music files with Music_Player (requires SDL library)
-
-Run program with path to a game music file.
-
-Left/Right Change track
-Space Pause/unpause
-E Normal/slight stereo echo/more stereo echo
--/= Adjust tempo
-1-9 Toggle channel on/off
-0 Reset tempo and turn channels back on */
-
-int const scope_width = 512;
-
-#include "Music_Player.h"
-#include "Audio_Scope.h"
-
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include "SDL.h"
-
-void handle_error( const char* );
-
-static bool paused;
-static Audio_Scope* scope;
-static Music_Player* player;
-static short scope_buf [scope_width * 2];
-
-static void init()
-{
- // Start SDL
- if ( SDL_Init( SDL_INIT_VIDEO | SDL_INIT_AUDIO ) < 0 )
- exit( EXIT_FAILURE );
- atexit( SDL_Quit );
- SDL_EnableKeyRepeat( 500, 80 );
-
- // Init scope
- scope = new Audio_Scope;
- if ( !scope )
- handle_error( "Out of memory" );
- if ( scope->init( scope_width, 256 ) )
- handle_error( "Couldn't initialize scope" );
- memset( scope_buf, 0, sizeof scope_buf );
-
- // Create player
- player = new Music_Player;
- if ( !player )
- handle_error( "Out of memory" );
- handle_error( player->init() );
- player->set_scope_buffer( scope_buf, scope_width * 2 );
-}
-
-static void start_track( int track, const char* path )
-{
- paused = false;
- handle_error( player->start_track( track - 1 ) );
-
- // update window title with track info
-
- long seconds = player->track_info().length / 1000;
- const char* game = player->track_info().game;
- if ( !*game )
- {
- // extract filename
- game = strrchr( path, '\\' ); // DOS
- if ( !game )
- game = strrchr( path, '/' ); // UNIX
- if ( !game )
- game = path;
- else
- game++; // skip path separator
- }
-
- char title [512];
- sprintf( title, "%s: %d/%d %s (%ld:%02ld)",
- game, track, player->track_count(), player->track_info().song,
- seconds / 60, seconds % 60 );
- SDL_WM_SetCaption( title, title );
-}
-
-int main( int argc, char** argv )
-{
- init();
-
- // Load file
- const char* path = (argc > 1 ? argv [argc - 1] : "test.nsf");
- handle_error( player->load_file( path ) );
- start_track( 1, path );
-
- // Main loop
- int track = 1;
- double tempo = 1.0;
- bool running = true;
- double stereo_depth = 0.0;
- int muting_mask = 0;
- while ( running )
- {
- SDL_Delay( 1000 / 100 );
-
- // Update scope
- scope->draw( scope_buf, scope_width, 2 );
-
- // Automatically go to next track when current one ends
- if ( player->track_ended() )
- {
- if ( track < player->track_count() )
- start_track( ++track, path );
- else
- player->pause( paused = true );
- }
-
- // Handle keyboard input
- SDL_Event e;
- while ( SDL_PollEvent( &e ) )
- {
- switch ( e.type )
- {
- case SDL_QUIT:
- running = false;
- break;
-
- case SDL_KEYDOWN:
- int key = e.key.keysym.sym;
- switch ( key )
- {
- case SDLK_q:
- case SDLK_ESCAPE: // quit
- running = false;
- break;
-
- case SDLK_LEFT: // prev track
- if ( !paused && !--track )
- track = 1;
- start_track( track, path );
- break;
-
- case SDLK_RIGHT: // next track
- if ( track < player->track_count() )
- start_track( ++track, path );
- break;
-
- case SDLK_MINUS: // reduce tempo
- tempo -= 0.1;
- if ( tempo < 0.1 )
- tempo = 0.1;
- player->set_tempo( tempo );
- break;
-
- case SDLK_EQUALS: // increase tempo
- tempo += 0.1;
- if ( tempo > 2.0 )
- tempo = 2.0;
- player->set_tempo( tempo );
- break;
-
- case SDLK_SPACE: // toggle pause
- paused = !paused;
- player->pause( paused );
- break;
-
- case SDLK_e: // toggle echo
- stereo_depth += 0.2;
- if ( stereo_depth > 0.5 )
- stereo_depth = 0;
- player->set_stereo_depth( stereo_depth );
- break;
-
- case SDLK_0: // reset tempo and muting
- tempo = 1.0;
- muting_mask = 0;
- player->set_tempo( tempo );
- player->mute_voices( muting_mask );
- break;
-
- default:
- if ( SDLK_1 <= key && key <= SDLK_9 ) // toggle muting
- {
- muting_mask ^= 1 << (key - SDLK_1);
- player->mute_voices( muting_mask );
- }
- }
- }
- }
- }
-
- // Cleanup
- delete player;
- delete scope;
-
- return 0;
-}
-
-void handle_error( const char* error )
-{
- if ( error )
- {
- // put error in window title
- char str [256];
- sprintf( str, "Error: %s", error );
- fprintf( stderr, "%s\n", str );
- SDL_WM_SetCaption( str, str );
-
- // wait for keyboard or mouse activity
- SDL_Event e;
- do
- {
- while ( !SDL_PollEvent( &e ) ) { }
- }
- while ( e.type != SDL_QUIT && e.type != SDL_KEYDOWN && e.type != SDL_MOUSEBUTTONDOWN );
-
- exit( EXIT_FAILURE );
- }
-}
diff --git a/plugins/gme/game-music-emu-0.5.5/readme.txt b/plugins/gme/game-music-emu-0.5.5/readme.txt
deleted file mode 100644
index 36213f6b..00000000
--- a/plugins/gme/game-music-emu-0.5.5/readme.txt
+++ /dev/null
@@ -1,218 +0,0 @@
-Game_Music_Emu 0.5.5: Game Music Emulators
-------------------------------------------
-Game_Music_Emu is a collection of video game music file emulators that
-support the following formats and systems:
-
-AY ZX Spectrum/Amstrad CPC
-GBS Nintendo Game Boy
-GYM Sega Genesis/Mega Drive
-HES NEC TurboGrafx-16/PC Engine
-KSS MSX Home Computer/other Z80 systems (doesn't support FM sound)
-NSF/NSFE Nintendo NES/Famicom (with VRC 6, Namco 106, and FME-7 sound)
-SAP Atari systems using POKEY sound chip
-SPC Super Nintendo/Super Famicom
-VGM/VGZ Sega Master System/Mark III, Sega Genesis/Mega Drive,BBC Micro
-
-Features:
-* Can be used in C and C++ code
-* High emphasis has been placed on making the library very easy to use
-* One set of common functions work with all emulators the same way
-* Several code examples, including music player using SDL
-* Portable code for use on any system with modern or older C++ compilers
-* Adjustable output sample rate using quality band-limited resampling
-* Uniform access to text information fields and track timing information
-* End-of-track fading and automatic look ahead silence detection
-* Treble/bass and stereo echo for AY/GBS/HES/KSS/NSF/NSFE/SAP/VGM
-* Tempo can be adjusted and individual voices can be muted while playing
-* Can read music data from file, memory, or custom reader function/class
-* Can access track information without having to load into full emulator
-* M3U track listing support for multi-track formats
-* Modular design allows elimination of unneeded emulators/features
-
-This library has been used in game music players for Windows, Linux on
-several architectures, Mac OS, MorphOS, Xbox, PlayStation Portable,
-GP2X, and Nintendo DS.
-
-Author : Shay Green <gblargg@gmail.com>
-Website: http://www.slack.net/~ant/
-Forum : http://groups.google.com/group/blargg-sound-libs
-License: GNU Lesser General Public License (LGPL)
-
-
-Getting Started
----------------
-Build a program consisting of demo/basics.c, demo/Wave_Writer.cpp, and
-all source files in gme/.
-
-If you have CMake 2.6 or higher you can use CMake to perform the build for
-you using standard CMake technique (i.e. cd to the source directory, run
-cmake, cd demo, run make)
-
-Be sure "test.nsf" is in the same directory.
-Running the program should generate the recording "out.wav".
-
-A slightly more extensive demo application is available in the player/
-directory. It requires SDL to build.
-
-Read gme.txt for more information. Post to the discussion forum for
-assistance.
-
-
-Files
------
-gme.txt General notes about the library
-changes.txt Changes made since previous releases
-design.txt Library design notes
-license.txt GNU Lesser General Public License
-CMakeLists.txt CMake build rules
-
-test.nsf Test file for NSF emulator
-test.m3u Test m3u playlist for features.c demo
-
-demo/
- basics.c Records NSF file to wave sound file
- cpp_basics.cpp C++ version of basics.c
- features.c Demonstrates many additional features
- Wave_Writer.h WAVE sound file writer used for demo output
- Wave_Writer.cpp
- CMakeLists.txt CMake build rules
-
-player/ Player using the SDL multimedia library
- player.cpp Simple music player with waveform display
- Music_Player.cpp Stand alone player for background music
- Music_Player.h
- Audio_Scope.cpp Audio waveform scope
- Audio_Scope.h
- CMakeLists.txt CMake build rules
-
-gme/
- blargg_config.h Library configuration (modify this file as needed)
-
- gme.h C interface (also usable in C++, and simpler too)
- gme.cpp
-
- Gme_File.h File loading and track information
- Music_Emu.h Track playback and adjustments
- Data_Reader.h Custom data readers
-
- Effects_Buffer.h Sound buffer with stereo echo and panning
- Effects_Buffer.cpp
-
- M3u_Playlist.h M3U playlist support
- M3u_Playlist.cpp
-
- Ay_Emu.h ZX Spectrum AY emulator
- Ay_Emu.cpp
- Ay_Apu.cpp
- Ay_Apu.h
- Ay_Cpu.cpp
- Ay_Cpu.h
-
- Gbs_Emu.h Nintendo Game Boy GBS emulator
- Gbs_Emu.cpp
- Gb_Apu.cpp
- Gb_Apu.h
- Gb_Cpu.cpp
- Gb_Cpu.h
- gb_cpu_io.h
- Gb_Oscs.cpp
- Gb_Oscs.h
-
- Hes_Emu.h TurboGrafx-16/PC Engine HES emulator
- Hes_Apu.cpp
- Hes_Apu.h
- Hes_Cpu.cpp
- Hes_Cpu.h
- hes_cpu_io.h
- Hes_Emu.cpp
-
- Kss_Emu.h MSX Home Computer/other Z80 systems KSS emulator
- Kss_Emu.cpp
- Kss_Cpu.cpp
- Kss_Cpu.h
- Kss_Scc_Apu.cpp
- Kss_Scc_Apu.h
- Ay_Apu.h
- Ay_Apu.cpp
- Sms_Apu.h
- Sms_Apu.cpp
- Sms_Oscs.h
-
- Nsf_Emu.h Nintendo NES NSF/NSFE emulator
- Nsf_Emu.cpp
- Nes_Apu.cpp
- Nes_Apu.h
- Nes_Cpu.cpp
- Nes_Cpu.h
- nes_cpu_io.h
- Nes_Oscs.cpp
- Nes_Oscs.h
- Nes_Fme7_Apu.cpp
- Nes_Fme7_Apu.h
- Nes_Namco_Apu.cpp
- Nes_Namco_Apu.h
- Nes_Vrc6_Apu.cpp
- Nes_Vrc6_Apu.h
- Nsfe_Emu.h NSFE support
- Nsfe_Emu.cpp
-
- Spc_Emu.h Super Nintendo SPC emulator
- Spc_Emu.cpp
- Snes_Spc.cpp
- Snes_Spc.h
- Spc_Cpu.cpp
- Spc_Cpu.h
- Spc_Dsp.cpp
- Spc_Dsp.h
- Fir_Resampler.cpp
- Fir_Resampler.h
-
- Sap_Emu.h Atari SAP emulator
- Sap_Emu.cpp
- Sap_Apu.cpp
- Sap_Apu.h
- Sap_Cpu.cpp
- Sap_Cpu.h
- sap_cpu_io.h
-
- Vgm_Emu.h Sega VGM emulator
- Vgm_Emu_Impl.cpp
- Vgm_Emu_Impl.h
- Vgm_Emu.cpp
- Ym2413_Emu.cpp
- Ym2413_Emu.h
- Gym_Emu.h Sega Genesis GYM emulator
- Gym_Emu.cpp
- Sms_Apu.cpp Common Sega emulator files
- Sms_Apu.h
- Sms_Oscs.h
- Ym2612_Emu.cpp
- Ym2612_Emu.h
- Dual_Resampler.cpp
- Dual_Resampler.h
- Fir_Resampler.cpp
- Fir_Resampler.h
-
- blargg_common.h Common files needed by all emulators
- blargg_endian.h
- blargg_source.h
- Blip_Buffer.cpp
- Blip_Buffer.h
- Gme_File.cpp
- Music_Emu.cpp
- Classic_Emu.h
- Classic_Emu.cpp
- Multi_Buffer.h
- Multi_Buffer.cpp
- Data_Reader.cpp
- CMakeLists.txt CMake build rules
-
-
-Legal
------
-Game_Music_Emu library copyright (C) 2003-2006 Shay Green.
-SNES SPC DSP emulator based on OpenSPC, copyright (C) 2002 Brad Martin.
-Sega Genesis YM2612 emulator copyright (C) 2002 Stephane Dallongeville.
-
---
-Shay Green <gblargg@gmail.com>