gambatte fixes: Properly save MBC3 without RTC
[lsnes.git] / libgambatte-patches / svn537 / 0005-Crash-on-illegal-instruction-fix-MBC3-bank0.patch
blob2154fceede02a2a5168d330c52727e6200a3180a
1 From 84fe61ebd27df485ff894d1d05b8950916c6508c Mon Sep 17 00:00:00 2001
2 From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
3 Date: Sat, 1 Feb 2014 12:56:47 +0200
4 Subject: [PATCH 5/9] Crash on illegal instruction, fix MBC3 bank0
6 ---
7 libgambatte/include/gambatte.h | 2 ++
8 libgambatte/src/cpu.cpp | 15 +++++++++++++++
9 libgambatte/src/cpu.h | 2 ++
10 libgambatte/src/gambatte.cpp | 5 +++++
11 libgambatte/src/mem/cartridge.cpp | 11 ++++++++---
12 5 files changed, 32 insertions(+), 3 deletions(-)
14 diff --git a/libgambatte/include/gambatte.h b/libgambatte/include/gambatte.h
15 index ea2558c..2525dad 100644
16 --- a/libgambatte/include/gambatte.h
17 +++ b/libgambatte/include/gambatte.h
18 @@ -19,6 +19,7 @@
19 #ifndef GAMBATTE_H
20 #define GAMBATTE_H
21 #define GAMBATTE_SUPPORTS_ADV_DEBUG
22 +#define GAMBATTE_SUPPORTS_EMU_FLAGS
24 #include "gbint.h"
25 #include "inputgetter.h"
26 @@ -282,6 +283,7 @@ public:
27 void set_debug_buffer(debugbuffer& dbgbuf);
28 uint8_t bus_read(unsigned addr);
29 void bus_write(unsigned addr, uint8_t val);
30 + void set_emuflags(unsigned flags);
31 private:
32 void preload_common();
33 void postload_common(const unsigned flags);
34 diff --git a/libgambatte/src/cpu.cpp b/libgambatte/src/cpu.cpp
35 index 40a81e6..037fff2 100644
36 --- a/libgambatte/src/cpu.cpp
37 +++ b/libgambatte/src/cpu.cpp
38 @@ -43,6 +43,7 @@ CPU::CPU(time_t (**_getCurrentTime)())
39 , h(0x01)
40 , l(0x4D)
41 , skip_(false)
42 +, emuflags(0)
46 @@ -1703,6 +1704,7 @@ void CPU::process(unsigned const cycles) {
47 break;
49 case 0xD3: // not specified. should freeze.
50 + if(emuflags & 1) { mem_.di(); PC_MOD((pc - 1) & 0xFFFF); }
51 break;
53 // call nc,nn (24;12 cycles):
54 @@ -1770,6 +1772,7 @@ void CPU::process(unsigned const cycles) {
55 break;
57 case 0xDB: // not specified. should freeze.
58 + if(emuflags & 1) { mem_.di(); PC_MOD((pc - 1) & 0xFFFF); }
59 break;
61 // call z,nn (24;12 cycles):
62 @@ -1785,6 +1788,10 @@ void CPU::process(unsigned const cycles) {
64 break;
66 + case 0xDD: // not specified. should freeze.
67 + if(emuflags & 1) { mem_.di(); PC_MOD((pc - 1) & 0xFFFF); }
68 + break;
70 case 0xDE:
72 unsigned data;
73 @@ -1820,8 +1827,10 @@ void CPU::process(unsigned const cycles) {
74 break;
76 case 0xE3: // not specified. should freeze.
77 + if(emuflags & 1) { mem_.di(); PC_MOD((pc - 1) & 0xFFFF); }
78 break;
79 case 0xE4: // not specified. should freeze.
80 + if(emuflags & 1) { mem_.di(); PC_MOD((pc - 1) & 0xFFFF); }
81 break;
83 case 0xE5:
84 @@ -1868,10 +1877,13 @@ void CPU::process(unsigned const cycles) {
85 break;
87 case 0xEB: // not specified. should freeze.
88 + if(emuflags & 1) { mem_.di(); PC_MOD((pc - 1) & 0xFFFF); }
89 break;
90 case 0xEC: // not specified. should freeze.
91 + if(emuflags & 1) { mem_.di(); PC_MOD((pc - 1) & 0xFFFF); }
92 break;
93 case 0xED: // not specified. should freeze.
94 + if(emuflags & 1) { mem_.di(); PC_MOD((pc - 1) & 0xFFFF); }
95 break;
97 case 0xEE:
98 @@ -1921,6 +1933,7 @@ void CPU::process(unsigned const cycles) {
99 break;
101 case 0xF4: // not specified. should freeze.
102 + if(emuflags & 1) { mem_.di(); PC_MOD((pc - 1) & 0xFFFF); }
103 break;
105 case 0xF5:
106 @@ -1985,8 +1998,10 @@ void CPU::process(unsigned const cycles) {
107 break;
109 case 0xFC: // not specified. should freeze.
110 + if(emuflags & 1) { mem_.di(); PC_MOD((pc - 1) & 0xFFFF); }
111 break;
112 case 0xFD: // not specified. should freeze
113 + if(emuflags & 1) { mem_.di(); PC_MOD((pc - 1) & 0xFFFF); }
114 break;
115 case 0xFE:
117 diff --git a/libgambatte/src/cpu.h b/libgambatte/src/cpu.h
118 index e7e46ff..c2a340b 100644
119 --- a/libgambatte/src/cpu.h
120 +++ b/libgambatte/src/cpu.h
121 @@ -94,6 +94,7 @@ public:
122 std::pair<unsigned char*, size_t> getVideoRam() { return mem_.getVideoRam(); };
123 uint8_t bus_read(unsigned addr) { return mem_.read(addr, cycleCounter_, false); }
124 void bus_write(unsigned addr, uint8_t val) { mem_.write(addr, val, cycleCounter_); }
125 + void set_emuflags(unsigned flags) { emuflags = flags; }
127 unsigned cycleCounter_;
128 unsigned short pc_;
129 @@ -103,6 +104,7 @@ public:
130 private:
131 Memory mem_;
132 bool skip_;
133 + unsigned emuflags;
135 void process(unsigned cycles);
137 diff --git a/libgambatte/src/gambatte.cpp b/libgambatte/src/gambatte.cpp
138 index 47f894e..f2310ed 100644
139 --- a/libgambatte/src/gambatte.cpp
140 +++ b/libgambatte/src/gambatte.cpp
141 @@ -362,4 +362,9 @@ void GB::bus_write(unsigned addr, uint8_t val)
142 p_->cpu.bus_write(addr, val);
145 +void GB::set_emuflags(unsigned flags)
147 + p_->cpu.set_emuflags(flags);
151 diff --git a/libgambatte/src/mem/cartridge.cpp b/libgambatte/src/mem/cartridge.cpp
152 index 1775139..bfec71c 100644
153 --- a/libgambatte/src/mem/cartridge.cpp
154 +++ b/libgambatte/src/mem/cartridge.cpp
155 @@ -294,14 +294,16 @@ public:
158 virtual void romWrite(unsigned const p, unsigned const data) {
159 + unsigned abank;
160 switch (p >> 13 & 3) {
161 case 0:
162 enableRam_ = (data & 0xF) == 0xA;
163 setRambank();
164 break;
165 case 1:
166 - rombank_ = data & 0x7F;
167 - memptrs_.setRombank(rombank_ & (rombanks(memptrs_) - 1));
168 + abank = rombank_ = data & 0x7F;
169 + if(!abank) abank = 1; //Fix pokemon Red.
170 + memptrs_.setRombank(abank & (rombanks(memptrs_) - 1));
171 break;
172 case 2:
173 rambank_ = data;
174 @@ -322,11 +324,14 @@ public:
177 virtual void loadState(SaveState::Mem const &ss) {
178 + unsigned abank;
179 rombank_ = ss.rombank;
180 rambank_ = ss.rambank;
181 enableRam_ = ss.enableRam;
182 setRambank();
183 - memptrs_.setRombank(rombank_ & (rombanks(memptrs_) - 1));
184 + abank = rombank_;
185 + if(!abank) abank = 1; //Fix pokemon Red.
186 + memptrs_.setRombank(abank & (rombanks(memptrs_) - 1));
188 void loadOrSave(loadsave& state) {
189 rtc_->loadOrSave(state);
191 2.1.3