Backport bsnes/gambatte patches and make emu at least run
[lsnes.git] / src / core / gambatte.cpp
blob7083cd4d9005a8501f809807e14532e47d11ce41
1 /***************************************************************************
2 * Copyright (C) 2012-2013 by Ilari Liusvaara *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License version 2 as *
6 * published by the Free Software Foundation. *
7 * *
8 * This program is distributed in the hope that it will be useful, *
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
11 * GNU General Public License version 2 for more details. *
12 * *
13 * You should have received a copy of the GNU General Public License *
14 * version 2 along with this program; if not, write to the *
15 * Free Software Foundation, Inc., *
16 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
17 ***************************************************************************/
18 #ifdef CORETYPE_GAMBATTE
19 #include "lsnes.hpp"
20 #include <sstream>
21 #include <iostream>
22 #include <map>
23 #include <string>
24 #include <vector>
25 #include "core/audioapi.hpp"
26 #include "core/misc.hpp"
27 #include "core/emucore.hpp"
28 #include "core/command.hpp"
29 #include "core/controllerframe.hpp"
30 #include "core/dispatch.hpp"
31 #include "core/framebuffer.hpp"
32 #include "core/window.hpp"
33 #include "library/pixfmt-rgb32.hpp"
34 #include "library/string.hpp"
35 #include "library/serialization.hpp"
36 #include "library/minmax.hpp"
37 #include "library/framebuffer.hpp"
38 #define HAVE_CSTDINT
39 #include "libgambatte/include/gambatte.h"
41 #define SAMPLES_PER_FRAME 35112
43 #define LOGICAL_BUTTON_LEFT 0
44 #define LOGICAL_BUTTON_RIGHT 1
45 #define LOGICAL_BUTTON_UP 2
46 #define LOGICAL_BUTTON_DOWN 3
47 #define LOGICAL_BUTTON_A 4
48 #define LOGICAL_BUTTON_B 5
49 #define LOGICAL_BUTTON_SELECT 6
50 #define LOGICAL_BUTTON_START 7
52 const char* button_symbols = "ABsSrlud";
54 namespace
56 #ifdef GAMBATTE_SUPPORTS_ADV_DEBUG
57 size_t debug_size;
58 gambatte::debugbuffer debugbuf;
59 #endif
60 int regions_compatible(unsigned rom, unsigned run)
62 return 1;
65 unsigned header_fn(size_t r)
67 return 0;
70 core_type* internal_rom = NULL;
71 extern core_type type_dmg;
72 extern core_type type_gbc;
73 extern core_type type_gbc_gba;
74 bool rtc_fixed;
75 time_t rtc_fixed_val;
76 gambatte::GB* instance;
77 unsigned frame_overflow = 0;
78 std::vector<unsigned char> romdata;
79 uint32_t primary_framebuffer[160*144];
80 uint32_t norom_framebuffer[160*144];
81 uint32_t accumulator_l = 0;
82 uint32_t accumulator_r = 0;
83 unsigned accumulator_s = 0;
85 void init_norom_framebuffer()
87 static bool done = false;
88 if(done)
89 return;
90 done = true;
91 for(size_t i = 0; i < 160 * 144; i++)
92 norom_framebuffer[i] = 0xFF8080;
95 time_t walltime_fn()
97 if(rtc_fixed)
98 return rtc_fixed_val;
99 if(ecore_callbacks)
100 return ecore_callbacks->get_time();
101 else
102 return time(0);
105 class myinput : public gambatte::InputGetter
107 public:
108 unsigned operator()()
110 unsigned v = 0;
111 for(unsigned i = 0; i < 8; i++) {
112 if(ecore_callbacks->get_input(0, 0, i))
113 v |= (1 << i);
115 return v;
117 } getinput;
119 int load_rom_common(core_romimage* img, unsigned flags, uint64_t rtc_sec, uint64_t rtc_subsec,
120 core_type* inttype)
122 const char* markup = img[0].markup;
123 int flags2 = 0;
124 if(markup) {
125 flags2 = atoi(markup);
126 flags2 &= 4;
128 flags |= flags2;
129 const unsigned char* data = img[0].data;
130 size_t size = img[0].size;
132 //Reset it really.
133 instance->~GB();
134 memset(instance, 0, sizeof(gambatte::GB));
135 new(instance) gambatte::GB;
136 instance->setInputGetter(&getinput);
137 instance->set_walltime_fn(walltime_fn);
138 memset(primary_framebuffer, 0, sizeof(primary_framebuffer));
139 frame_overflow = 0;
141 rtc_fixed = true;
142 rtc_fixed_val = rtc_sec;
143 instance->load(data, size, flags);
144 rtc_fixed = false;
145 romdata.resize(size);
146 memcpy(&romdata[0], data, size);
147 internal_rom = inttype;
149 size_t dsize = (size > 65536) ? size : 65536;
150 if(dsize < instance->getSaveRam().second) dsize = instance->getSaveRam().second;
151 if(debug_size < dsize) {
152 if(debugbuf.wram) delete[] debugbuf.wram;
153 debugbuf.wram = NULL;
154 uint8_t* tmp = new uint8_t[dsize];
155 memset(tmp, 0, dsize);
156 debug_size = dsize;
157 debugbuf.wram = tmp;
159 debugbuf.bus = debugbuf.wram;
160 debugbuf.ioamhram = debugbuf.wram;
161 debugbuf.sram = debugbuf.wram;
162 debugbuf.cart = debugbuf.wram;
163 debugbuf.trace_cpu = false;
164 instance->set_debug_buffer(debugbuf);
166 return 1;
169 int load_rom_dmg(core_romimage* img, uint64_t rtc_sec, uint64_t rtc_subsec)
171 return load_rom_common(img, gambatte::GB::FORCE_DMG, rtc_sec, rtc_subsec, &type_dmg);
174 int load_rom_gbc(core_romimage* img, uint64_t rtc_sec, uint64_t rtc_subsec)
176 return load_rom_common(img, 0, rtc_sec, rtc_subsec, &type_gbc);
179 int load_rom_gbc_gba(core_romimage* img, uint64_t rtc_sec, uint64_t rtc_subsec)
181 return load_rom_common(img, gambatte::GB::GBA_CGB, rtc_sec, rtc_subsec, &type_gbc_gba);
184 uint64_t magic[4] = {35112, 2097152, 16742706, 626688};
186 core_region region_world("world", "World", 0, 0, false, magic, regions_compatible);
187 core_romimage_info image_rom_dmg("rom", "Cartridge ROM", 1, header_fn);
188 core_romimage_info image_rom_gbc("rom", "Cartridge ROM", 1, header_fn);
189 core_romimage_info image_rom_gbca("rom", "Cartridge ROM", 1, header_fn);
190 core_type type_dmg("dmg", "Game Boy", 1, load_rom_dmg, "gb;dmg");
191 core_type type_gbc("gbc", "Game Boy Color", 0, load_rom_gbc, "gbc;cgb");
192 core_type type_gbc_gba("gbc_gba", "Game Boy Color (GBA)", 2, load_rom_gbc_gba, "");
193 core_type_region_bind bind_A(type_dmg, region_world);
194 core_type_region_bind bind_B(type_gbc, region_world);
195 core_type_region_bind bind_C(type_gbc_gba, region_world);
196 core_type_image_bind bind_D(type_dmg, image_rom_dmg, 0);
197 core_type_image_bind bind_E(type_gbc, image_rom_gbc, 0);
198 core_type_image_bind bind_F(type_gbc_gba, image_rom_gbca, 0);
199 core_sysregion sr1("gdmg", type_dmg, region_world);
200 core_sysregion sr2("ggbc", type_gbc, region_world);
201 core_sysregion sr3("ggbca", type_gbc_gba, region_world);
203 const char* buttonnames[] = {"left", "right", "up", "down", "A", "B", "select", "start"};
205 void _set_core_controller(unsigned port) throw() {}
207 int get_button_id_gamepad(unsigned controller, unsigned lbid) throw()
209 if(controller)
210 return -1;
211 if(lbid == LOGICAL_BUTTON_A) return 0;
212 if(lbid == LOGICAL_BUTTON_B) return 1;
213 if(lbid == LOGICAL_BUTTON_SELECT) return 2;
214 if(lbid == LOGICAL_BUTTON_START) return 3;
215 if(lbid == LOGICAL_BUTTON_RIGHT) return 4;
216 if(lbid == LOGICAL_BUTTON_LEFT) return 5;
217 if(lbid == LOGICAL_BUTTON_UP) return 6;
218 if(lbid == LOGICAL_BUTTON_DOWN) return 7;
219 return -1;
223 int get_button_id_none(unsigned controller, unsigned lbid) throw()
225 return -1;
228 struct porttype_gamepad : public porttype_info
230 porttype_gamepad() : porttype_info("gamepad", "Gamepad", 1, generic_port_size<1, 0, 8>())
232 write = generic_port_write<1, 0, 8>;
233 read = generic_port_read<1, 0, 8>;
234 display = generic_port_display<1, 0, 8, 0>;
235 serialize = generic_port_serialize<1, 0, 8, 0>;
236 deserialize = generic_port_deserialize<1, 0, 8>;
237 legal = generic_port_legal<1>;
238 deviceflags = generic_port_deviceflags<1, 1>;
239 button_id = get_button_id_gamepad;
240 ctrlname = "gamepad";
241 controllers = 1;
242 set_core_controller = _set_core_controller;
243 button_symbols = "ABsSrlud";
246 } gamepad;
248 struct porttype_none : public porttype_info
250 porttype_none() : porttype_info("none", "None", 0, generic_port_size<0, 0, 0>())
252 write = generic_port_write<0, 0, 0>;
253 read = generic_port_read<0, 0, 0>;
254 display = generic_port_display<0, 0, 0, 0>;
255 serialize = generic_port_serialize<0, 0, 0, 0>;
256 deserialize = generic_port_deserialize<0, 0, 0>;
257 legal = generic_port_legal<2>;
258 deviceflags = generic_port_deviceflags<0, 0>;
259 button_id = get_button_id_none;
260 ctrlname = "";
261 controllers = 0;
262 set_core_controller = _set_core_controller;
263 button_symbols = "";
265 } none;
269 std::string get_logical_button_name(unsigned lbid) throw(std::bad_alloc)
271 if(lbid >= sizeof(buttonnames) / sizeof(buttonnames[0]))
272 return "";
273 return buttonnames[lbid];
276 uint32_t get_snes_cpu_rate() { return 0; }
277 uint32_t get_snes_apu_rate() { return 0; }
278 std::string get_core_identifier()
280 return "libgambatte "+gambatte::GB::version();
283 std::pair<unsigned, unsigned> get_core_logical_controller_limits()
285 return std::make_pair(1, 8);
288 bool get_core_need_analog()
290 return false;
293 std::string get_core_default_port(unsigned port)
295 return (port == 0) ? "gamepad" : "none";
298 core_region& core_get_region()
300 return region_world;
303 std::pair<uint32_t, uint32_t> get_video_rate()
305 return std::make_pair(262144, 4389);
308 std::pair<uint32_t, uint32_t> get_audio_rate()
310 return std::make_pair(32768, 1);
313 bool core_set_region(core_region& region)
315 return (&region == &region_world);
318 std::pair<bool, uint32_t> core_emulate_cycles(uint32_t cycles)
320 messages << "Delayed resets are not supported";
321 return std::make_pair(false, 0);
324 void core_runtosave()
328 void core_reset()
330 if(!internal_rom)
331 return;
332 instance->reset();
335 void do_basic_core_init()
337 instance = new gambatte::GB;
338 instance->setInputGetter(&getinput);
339 instance->set_walltime_fn(walltime_fn);
340 debug_size = 65536;
341 uint8_t* tmp = new uint8_t[debug_size];
342 memset(tmp, 0, debug_size);
343 debugbuf.wram = tmp;
344 debugbuf.bus = tmp;
345 debugbuf.ioamhram = tmp;
346 debugbuf.sram = tmp;
347 debugbuf.cart = tmp;
348 debugbuf.trace_cpu = false;
349 instance->set_debug_buffer(debugbuf);
352 void core_power()
356 void core_unload_cartridge()
358 if(!internal_rom)
359 return;
360 instance->~GB();
361 new(instance) gambatte::GB;
362 internal_rom = NULL;
365 void set_preload_settings()
369 void core_install_handler()
373 void core_uninstall_handler()
377 void core_emulate_frame_nocore()
379 init_norom_framebuffer();
380 while(true) {
381 int16_t soundbuf[(SAMPLES_PER_FRAME + 63) / 32];
382 size_t emitted = 0;
383 unsigned samples_emitted = SAMPLES_PER_FRAME - frame_overflow;
384 for(unsigned i = 0; i < samples_emitted; i++) {
385 accumulator_l += 32768;
386 accumulator_r += 32768;
387 accumulator_s++;
388 if((accumulator_s & 63) == 0) {
389 int16_t l2 = (accumulator_l >> 6) - 32768;
390 int16_t r2 = (accumulator_r >> 6) - 32768;
391 soundbuf[emitted++] = l2;
392 soundbuf[emitted++] = r2;
393 information_dispatch::do_sample(l2, r2);
394 accumulator_l = accumulator_r = 0;
395 accumulator_s = 0;
398 audioapi_submit_buffer(soundbuf, emitted / 2, true, 32768);
399 ecore_callbacks->timer_tick(samples_emitted, 2097152);
400 frame_overflow = 0;
401 break;
403 framebuffer_info inf;
404 inf.type = &_pixel_format_rgb32;
405 inf.mem = const_cast<char*>(reinterpret_cast<const char*>(norom_framebuffer));
406 inf.physwidth = 160;
407 inf.physheight = 144;
408 inf.physstride = 640;
409 inf.width = 160;
410 inf.height = 144;
411 inf.stride = 640;
412 inf.offset_x = 0;
413 inf.offset_y = 0;
415 framebuffer_raw ls(inf);
416 ecore_callbacks->output_frame(ls, 262144, 4389);
418 void core_emulate_frame()
420 if(!internal_rom) {
421 core_emulate_frame_nocore();
422 return;
424 uint32_t samplebuffer[SAMPLES_PER_FRAME + 2064];
425 while(true) {
426 int16_t soundbuf[(SAMPLES_PER_FRAME + 63) / 32 + 66];
427 size_t emitted = 0;
428 unsigned samples_emitted = SAMPLES_PER_FRAME - frame_overflow;
429 long ret = instance->runFor(primary_framebuffer, 160, samplebuffer, samples_emitted);
430 for(unsigned i = 0; i < samples_emitted; i++) {
431 uint32_t l = (int32_t)(int16_t)(samplebuffer[i]) + 32768;
432 uint32_t r = (int32_t)(int16_t)(samplebuffer[i] >> 16) + 32768;
433 accumulator_l += l;
434 accumulator_r += r;
435 accumulator_s++;
436 if((accumulator_s & 63) == 0) {
437 int16_t l2 = (accumulator_l >> 6) - 32768;
438 int16_t r2 = (accumulator_r >> 6) - 32768;
439 soundbuf[emitted++] = l2;
440 soundbuf[emitted++] = r2;
441 information_dispatch::do_sample(l2, r2);
442 accumulator_l = accumulator_r = 0;
443 accumulator_s = 0;
446 audioapi_submit_buffer(soundbuf, emitted / 2, true, 32768);
447 ecore_callbacks->timer_tick(samples_emitted, 2097152);
448 frame_overflow += samples_emitted;
449 if(frame_overflow >= SAMPLES_PER_FRAME) {
450 frame_overflow -= SAMPLES_PER_FRAME;
451 break;
454 framebuffer_info inf;
455 inf.type = &_pixel_format_rgb32;
456 inf.mem = const_cast<char*>(reinterpret_cast<const char*>(primary_framebuffer));
457 inf.physwidth = 160;
458 inf.physheight = 144;
459 inf.physstride = 640;
460 inf.width = 160;
461 inf.height = 144;
462 inf.stride = 640;
463 inf.offset_x = 0;
464 inf.offset_y = 0;
466 framebuffer_raw ls(inf);
467 ecore_callbacks->output_frame(ls, 262144, 4389);
470 std::list<vma_info> get_vma_list()
472 std::list<vma_info> vmas;
473 if(!internal_rom)
474 return vmas;
475 vma_info sram;
476 vma_info wram;
477 vma_info vram;
478 vma_info ioamhram;
479 vma_info rom;
481 auto g = instance->getSaveRam();
482 sram.name = "SRAM";
483 sram.base = 0x20000;
484 sram.size = g.second;
485 sram.backing_ram = g.first;
486 sram.native_endian = false;
487 sram.readonly = false;
488 sram.iospace_rw = NULL;
490 auto g2 = instance->getWorkRam();
491 wram.name = "WRAM";
492 wram.base = 0;
493 wram.size = g2.second;
494 wram.backing_ram = g2.first;
495 wram.native_endian = false;
496 wram.readonly = false;
497 wram.iospace_rw = NULL;
499 auto g3 = instance->getVideoRam();
500 vram.name = "VRAM";
501 vram.base = 0x10000;
502 vram.size = g3.second;
503 vram.backing_ram = g3.first;
504 vram.native_endian = false;
505 vram.readonly = false;
506 vram.iospace_rw = NULL;
508 auto g4 = instance->getIoRam();
509 ioamhram.name = "IOAMHRAM";
510 ioamhram.base = 0x18000;
511 ioamhram.size = g4.second;
512 ioamhram.backing_ram = g4.first;
513 ioamhram.native_endian = false;
514 ioamhram.readonly = false;
515 ioamhram.iospace_rw = NULL;
517 rom.name = "ROM";
518 rom.base = 0x80000000;
519 rom.size = romdata.size();
520 rom.backing_ram = (void*)&romdata[0];
521 rom.native_endian = false;
522 rom.readonly = true;
523 rom.iospace_rw = NULL;
525 if(sram.size)
526 vmas.push_back(sram);
527 vmas.push_back(wram);
528 vmas.push_back(rom);
529 vmas.push_back(vram);
530 vmas.push_back(ioamhram);
531 return vmas;
534 std::set<std::string> get_sram_set()
536 std::set<std::string> s;
537 if(!internal_rom)
538 return s;
539 auto g = instance->getSaveRam();
540 if(g.second)
541 s.insert("main");
542 s.insert("rtc");
543 return s;
546 std::map<std::string, std::vector<char>> save_sram() throw(std::bad_alloc)
548 std::map<std::string, std::vector<char>> s;
549 if(!internal_rom)
550 return s;
551 auto g = instance->getSaveRam();
552 s["main"].resize(g.second);
553 memcpy(&s["main"][0], g.first, g.second);
554 s["rtc"].resize(8);
555 time_t timebase = instance->getRtcBase();
556 for(size_t i = 0; i < 8; i++)
557 s["rtc"][i] = ((unsigned long long)timebase >> (8 * i));
558 return s;
561 void load_sram(std::map<std::string, std::vector<char>>& sram) throw(std::bad_alloc)
563 if(!internal_rom)
564 return;
565 std::vector<char> x = sram.count("main") ? sram["main"] : std::vector<char>();
566 std::vector<char> x2 = sram.count("rtc") ? sram["rtc"] : std::vector<char>();
567 auto g = instance->getSaveRam();
568 if(x.size()) {
569 if(x.size() != g.second)
570 messages << "WARNING: SRAM 'main': Loaded " << x.size()
571 << " bytes, but the SRAM is " << g.second << "." << std::endl;
572 memcpy(g.first, &x[0], min(x.size(), g.second));
574 if(x2.size()) {
575 time_t timebase = 0;
576 for(size_t i = 0; i < 8 && i < x2.size(); i++)
577 timebase |= (unsigned long long)(unsigned char)x2[i] << (8 * i);
578 instance->setRtcBase(timebase);
582 unsigned core_get_poll_flag()
584 return 2;
587 void core_set_poll_flag(unsigned pflag)
592 std::vector<char> cmp_save;
594 function_ptr_command<> cmp_save1("set-cmp-save", "", "\n", []() throw(std::bad_alloc, std::runtime_error) {
595 if(!internal_rom)
596 return;
597 instance->saveState(cmp_save);
600 function_ptr_command<> cmp_save2("do-cmp-save", "", "\n", []() throw(std::bad_alloc, std::runtime_error) {
601 std::vector<char> x;
602 if(!internal_rom)
603 return;
604 instance->saveState(x, cmp_save);
607 void core_serialize(std::vector<char>& out)
609 if(!internal_rom)
610 throw std::runtime_error("Can't save without ROM");
611 instance->saveState(out);
612 size_t osize = out.size();
613 out.resize(osize + 4 * sizeof(primary_framebuffer) / sizeof(primary_framebuffer[0]));
614 for(size_t i = 0; i < sizeof(primary_framebuffer) / sizeof(primary_framebuffer[0]); i++)
615 write32ube(&out[osize + 4 * i], primary_framebuffer[i]);
616 out.push_back(frame_overflow >> 8);
617 out.push_back(frame_overflow);
620 void core_unserialize(const char* in, size_t insize)
622 if(!internal_rom)
623 throw std::runtime_error("Can't load without ROM");
624 size_t foffset = insize - 2 - 4 * sizeof(primary_framebuffer) / sizeof(primary_framebuffer[0]);
625 std::vector<char> tmp;
626 tmp.resize(foffset);
627 memcpy(&tmp[0], in, foffset);
628 instance->loadState(tmp);
629 for(size_t i = 0; i < sizeof(primary_framebuffer) / sizeof(primary_framebuffer[0]); i++)
630 primary_framebuffer[i] = read32ube(&in[foffset + 4 * i]);
632 unsigned x1 = (unsigned char)in[insize - 2];
633 unsigned x2 = (unsigned char)in[insize - 1];
634 frame_overflow = x1 * 256 + x2;
637 std::pair<uint32_t, uint32_t> get_scale_factors(uint32_t width, uint32_t height)
639 return std::make_pair(max(512 / width, (uint32_t)1), max(448 / height, (uint32_t)1));
642 std::pair<uint64_t, uint64_t> core_get_bus_map()
644 return std::make_pair(0, 0);
647 bool core_rom_loaded()
649 return (internal_rom != NULL);
652 emucore_callbacks::~emucore_callbacks() throw() {}
654 struct emucore_callbacks* ecore_callbacks;
655 #endif