Compare commits
1 commit
Author | SHA1 | Date | |
---|---|---|---|
|
563a2f2956 |
9 changed files with 1098 additions and 16 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -13,5 +13,6 @@ lsnes
|
|||
/core
|
||||
/bsnes
|
||||
/gambatte
|
||||
/meteor
|
||||
src/fonts/font.cpp
|
||||
src/core/version.cpp
|
||||
|
|
16
manual.lyx
16
manual.lyx
|
@ -99,7 +99,21 @@ SVN r320, r358 or r364
|
|||
\end_layout
|
||||
|
||||
\begin_layout Enumerate
|
||||
Patched with included patches
|
||||
Patched with included patch.
|
||||
\end_layout
|
||||
|
||||
\end_deeper
|
||||
\begin_layout Enumerate
|
||||
meteor (for meteor core)
|
||||
\end_layout
|
||||
|
||||
\begin_deeper
|
||||
\begin_layout Enumerate
|
||||
1.4.0
|
||||
\end_layout
|
||||
|
||||
\begin_layout Enumerate
|
||||
Patched with included patch.
|
||||
\end_layout
|
||||
|
||||
\end_deeper
|
||||
|
|
34
manual.txt
34
manual.txt
|
@ -16,33 +16,39 @@ lsnes is SNES rerecording emulator based on bsnes core.
|
|||
|
||||
(a) SVN r320, r358 or r364
|
||||
|
||||
(b) Patched with included patches
|
||||
(b) Patched with included patch.
|
||||
|
||||
3. Zlib
|
||||
3. meteor (for meteor core)
|
||||
|
||||
4. boost_iostreams
|
||||
(a) 1.4.0
|
||||
|
||||
5. boost_filesystem
|
||||
(b) Patched with included patch.
|
||||
|
||||
6. boost_thread (if native std::thread is not available)
|
||||
4. Zlib
|
||||
|
||||
7. libsdl (SDL only)
|
||||
5. boost_iostreams
|
||||
|
||||
8. sdlmain (SDL only, part of SDL)
|
||||
6. boost_filesystem
|
||||
|
||||
9. boost_conversion (this is header-only library)
|
||||
7. boost_thread (if native std::thread is not available)
|
||||
|
||||
10. libswscale (wxwidgets graphics only)
|
||||
8. libsdl (SDL only)
|
||||
|
||||
11. Portaudio (portaudio sound only)
|
||||
9. sdlmain (SDL only, part of SDL)
|
||||
|
||||
12. libao (libao sound only)
|
||||
10. boost_conversion (this is header-only library)
|
||||
|
||||
13. Lua version 5.1.X or 5.2.X
|
||||
11. libswscale (wxwidgets graphics only)
|
||||
|
||||
14. G++ 4.6 or 4.7
|
||||
12. Portaudio (portaudio sound only)
|
||||
|
||||
15. libopus (optional, for commentary track tool)
|
||||
13. libao (libao sound only)
|
||||
|
||||
14. Lua version 5.1.X or 5.2.X
|
||||
|
||||
15. G++ 4.6 or 4.7
|
||||
|
||||
16. libopus (optional, for commentary track tool)
|
||||
|
||||
3 Building
|
||||
|
||||
|
|
489
meteor-patches/1.4.0/0001-Add-memory-watch-features.patch
Normal file
489
meteor-patches/1.4.0/0001-Add-memory-watch-features.patch
Normal file
|
@ -0,0 +1,489 @@
|
|||
From c3059a59fa95cd0e165dbcf7df4b9dc11d5b8d29 Mon Sep 17 00:00:00 2001
|
||||
From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
|
||||
Date: Sun, 17 Feb 2013 11:18:50 +0200
|
||||
Subject: [PATCH] Add memory watch features
|
||||
|
||||
---
|
||||
Makefile | 60 ++++++++++++++++++
|
||||
ameteor/include/ameteor/cartmem.hpp | 2 +
|
||||
ameteor/include/ameteor/graphics/bglayer.hpp | 3 +
|
||||
ameteor/include/ameteor/io.hpp | 3 +
|
||||
ameteor/include/ameteor/memory.hpp | 2 +
|
||||
ameteor/source/clock.cpp | 3 +-
|
||||
ameteor/source/graphics/bglayer.cpp | 85 ++++++++++++++------------
|
||||
ameteor/source/graphics/screen.cpp | 22 +++++++
|
||||
ameteor/source/io.cpp | 15 ++++-
|
||||
ameteor/source/memory.cpp | 33 +++++++++--
|
||||
10 files changed, 180 insertions(+), 48 deletions(-)
|
||||
create mode 100644 Makefile
|
||||
|
||||
diff --git a/Makefile b/Makefile
|
||||
new file mode 100644
|
||||
index 0000000..463a2f7
|
||||
--- /dev/null
|
||||
+++ b/Makefile
|
||||
@@ -0,0 +1,60 @@
|
||||
+TARGET=libmeteor.$(ARCHIVE_SUFFIX)
|
||||
+CXXFLAGS += -Wall -Wno-parentheses -I. -Iameteor/include -D__LIBRETRO__ -O3 -g
|
||||
+
|
||||
+SRCDIR := ameteor/source
|
||||
+
|
||||
+SOURCES := \
|
||||
+ $(SRCDIR)/audio/dsound.cpp \
|
||||
+ $(SRCDIR)/audio/sound1.cpp \
|
||||
+ $(SRCDIR)/audio/sound2.cpp \
|
||||
+ $(SRCDIR)/audio/sound4.cpp \
|
||||
+ $(SRCDIR)/audio/speaker.cpp \
|
||||
+ $(SRCDIR)/disassembler/argimmediate.cpp \
|
||||
+ $(SRCDIR)/disassembler/argmulregisters.cpp \
|
||||
+ $(SRCDIR)/disassembler/argpsr.cpp \
|
||||
+ $(SRCDIR)/disassembler/argregister.cpp \
|
||||
+ $(SRCDIR)/disassembler/argrelative.cpp \
|
||||
+ $(SRCDIR)/disassembler/argshift.cpp \
|
||||
+ $(SRCDIR)/disassembler/arguimmediate.cpp \
|
||||
+ $(SRCDIR)/disassembler/arguments.cpp \
|
||||
+ $(SRCDIR)/disassembler/instruction.cpp \
|
||||
+ $(SRCDIR)/graphics/bglayer.cpp \
|
||||
+ $(SRCDIR)/graphics/object.cpp \
|
||||
+ $(SRCDIR)/graphics/objects.cpp \
|
||||
+ $(SRCDIR)/graphics/renderer.cpp \
|
||||
+ $(SRCDIR)/graphics/screen.cpp \
|
||||
+ $(SRCDIR)/ameteor.cpp \
|
||||
+ $(SRCDIR)/bios.cpp \
|
||||
+ $(SRCDIR)/clock.cpp \
|
||||
+ $(SRCDIR)/cpu.cpp \
|
||||
+ $(SRCDIR)/debug.cpp \
|
||||
+ $(SRCDIR)/dma.cpp \
|
||||
+ $(SRCDIR)/eeprom.cpp \
|
||||
+ $(SRCDIR)/flash.cpp \
|
||||
+ $(SRCDIR)/cartmem.cpp \
|
||||
+ $(SRCDIR)/interpreter.cpp \
|
||||
+ $(SRCDIR)/interpreter_arm.cpp \
|
||||
+ $(SRCDIR)/interpreter_thumb.cpp \
|
||||
+ $(SRCDIR)/io.cpp \
|
||||
+ $(SRCDIR)/keypad.cpp \
|
||||
+ $(SRCDIR)/lcd.cpp \
|
||||
+ $(SRCDIR)/memory.cpp \
|
||||
+ $(SRCDIR)/sound.cpp \
|
||||
+ $(SRCDIR)/sram.cpp \
|
||||
+ $(SRCDIR)/timer.cpp
|
||||
+
|
||||
+OBJ := $(SOURCES:.cpp=.$(OBJECT_SUFFIX))
|
||||
+
|
||||
+all: $(TARGET)
|
||||
+
|
||||
+$(TARGET): $(OBJ)
|
||||
+ $(REALAR) crvs $@ $^
|
||||
+
|
||||
+%.$(OBJECT_SUFFIX): %.cpp
|
||||
+ $(CXX) -o $@ -c $< $(CXXFLAGS)
|
||||
+
|
||||
+clean:
|
||||
+ rm -f $(TARGET)
|
||||
+ rm -f $(OBJ)
|
||||
+
|
||||
+.PHONY: clean
|
||||
diff --git a/ameteor/include/ameteor/cartmem.hpp b/ameteor/include/ameteor/cartmem.hpp
|
||||
index e7ee436..a18e6d6 100644
|
||||
--- a/ameteor/include/ameteor/cartmem.hpp
|
||||
+++ b/ameteor/include/ameteor/cartmem.hpp
|
||||
@@ -44,6 +44,8 @@ namespace AMeteor
|
||||
virtual bool SaveState (std::ostream& stream);
|
||||
virtual bool LoadState (std::istream& stream);
|
||||
|
||||
+ uint8_t* GetRawData() { return m_data; }
|
||||
+ uint32_t GetRawSize() { return m_size; }
|
||||
protected:
|
||||
uint8_t* m_data;
|
||||
uint32_t m_size;
|
||||
diff --git a/ameteor/include/ameteor/graphics/bglayer.hpp b/ameteor/include/ameteor/graphics/bglayer.hpp
|
||||
index 1409929..48d19ff 100644
|
||||
--- a/ameteor/include/ameteor/graphics/bglayer.hpp
|
||||
+++ b/ameteor/include/ameteor/graphics/bglayer.hpp
|
||||
@@ -46,6 +46,9 @@ namespace AMeteor
|
||||
void DrawLine4 (uint8_t line, uint16_t* ptr,
|
||||
int32_t curX, int32_t curY,
|
||||
int16_t dx, int16_t dmx, int16_t dy, int16_t dmy, bool frame1);
|
||||
+ void DrawLine5 (uint16_t* ptr,
|
||||
+ int32_t refX, int32_t refY,
|
||||
+ int16_t dx, int16_t dy, bool frame1);
|
||||
void FillList ();
|
||||
|
||||
void UpdateCnt (uint16_t cnt);
|
||||
diff --git a/ameteor/include/ameteor/io.hpp b/ameteor/include/ameteor/io.hpp
|
||||
index 5f553c0..108e41f 100644
|
||||
--- a/ameteor/include/ameteor/io.hpp
|
||||
+++ b/ameteor/include/ameteor/io.hpp
|
||||
@@ -208,8 +208,11 @@ namespace AMeteor
|
||||
bool SaveState (std::ostream& stream);
|
||||
bool LoadState (std::istream& stream);
|
||||
|
||||
+ bool GetPolled() { return m_polled; }
|
||||
+ void SetPolled(bool f) { m_polled = f; }
|
||||
private :
|
||||
uint8_t* m_iomem;
|
||||
+ bool m_polled;
|
||||
};
|
||||
}
|
||||
|
||||
diff --git a/ameteor/include/ameteor/memory.hpp b/ameteor/include/ameteor/memory.hpp
|
||||
index a45652d..e3d1aa4 100644
|
||||
--- a/ameteor/include/ameteor/memory.hpp
|
||||
+++ b/ameteor/include/ameteor/memory.hpp
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <string>
|
||||
#include <istream>
|
||||
#include <ostream>
|
||||
+#include <map>
|
||||
|
||||
namespace AMeteor
|
||||
{
|
||||
@@ -119,6 +120,7 @@ namespace AMeteor
|
||||
|
||||
void TimeEvent ();
|
||||
|
||||
+ std::map<std::string, std::pair<uint8_t*, size_t> > GetMemories();
|
||||
private :
|
||||
// times for a 8 or 16 bits access
|
||||
uint8_t m_memtime[0xF];
|
||||
diff --git a/ameteor/source/clock.cpp b/ameteor/source/clock.cpp
|
||||
index 7f21980..460db6a 100644
|
||||
--- a/ameteor/source/clock.cpp
|
||||
+++ b/ameteor/source/clock.cpp
|
||||
@@ -35,12 +35,11 @@ namespace AMeteor
|
||||
{
|
||||
unsigned short tocommit;
|
||||
|
||||
- m_count += m_cycles;
|
||||
-
|
||||
// this loop is here because a timer can trigger a dma which will take a
|
||||
// long time, during this time the lcd must draw and the timers continue
|
||||
while (m_cycles >= m_first)
|
||||
{
|
||||
+ m_count += m_cycles;
|
||||
tocommit = m_cycles;
|
||||
m_cycles = 0;
|
||||
|
||||
diff --git a/ameteor/source/graphics/bglayer.cpp b/ameteor/source/graphics/bglayer.cpp
|
||||
index 72eea70..2c9eea4 100644
|
||||
--- a/ameteor/source/graphics/bglayer.cpp
|
||||
+++ b/ameteor/source/graphics/bglayer.cpp
|
||||
@@ -133,11 +133,11 @@ namespace AMeteor
|
||||
else
|
||||
*ptr = 0x0;
|
||||
|
||||
- if (flipH)
|
||||
- --tpChar;
|
||||
- else
|
||||
- ++tpChar;
|
||||
}
|
||||
+ if (flipH)
|
||||
+ --tpChar;
|
||||
+ else
|
||||
+ ++tpChar;
|
||||
|
||||
++ptr;
|
||||
++tileX;
|
||||
@@ -186,27 +186,27 @@ namespace AMeteor
|
||||
// we draw until the end of the tile or the line
|
||||
while (tileX < 8)
|
||||
{
|
||||
+ if (flipH)
|
||||
+ if (tileX % 2)
|
||||
+ {
|
||||
+ colorInd = *tpChar & 0xF;
|
||||
+ --tpChar;
|
||||
+ }
|
||||
+ else
|
||||
+ colorInd = *tpChar >> 4;
|
||||
+ else
|
||||
+ if (tileX % 2)
|
||||
+ {
|
||||
+ colorInd = *tpChar >> 4;
|
||||
+ ++tpChar;
|
||||
+ }
|
||||
+ else
|
||||
+ colorInd = *tpChar & 0xF;
|
||||
+
|
||||
if (mosH && i % mosH)
|
||||
*ptr = ptr[-1];
|
||||
else
|
||||
{
|
||||
- if (flipH)
|
||||
- if (tileX % 2)
|
||||
- {
|
||||
- colorInd = *tpChar & 0xF;
|
||||
- --tpChar;
|
||||
- }
|
||||
- else
|
||||
- colorInd = *tpChar >> 4;
|
||||
- else
|
||||
- if (tileX % 2)
|
||||
- {
|
||||
- colorInd = *tpChar >> 4;
|
||||
- ++tpChar;
|
||||
- }
|
||||
- else
|
||||
- colorInd = *tpChar & 0xF;
|
||||
-
|
||||
if (colorInd)
|
||||
*ptr = pPalette[colorInd] | 0x8000;
|
||||
else
|
||||
@@ -309,7 +309,7 @@ namespace AMeteor
|
||||
{
|
||||
int32_t intX, intY;
|
||||
|
||||
- uint8_t* pChar = m_memory.GetRealAddress(0x06000000);
|
||||
+ uint16_t* pChar = (uint16_t*)m_memory.GetRealAddress(0x06000000);
|
||||
|
||||
for (uint8_t x = 0; x < 240; ++x, ++ptr, curX += dx, curY += dy)
|
||||
{
|
||||
@@ -318,25 +318,9 @@ namespace AMeteor
|
||||
|
||||
// if we are off layer
|
||||
if (intX < 0 || intX >= 240)
|
||||
- if (m_cnt & (0x1 << 13))
|
||||
- {
|
||||
- // NOTE : in C++, the modulus can be negative
|
||||
- intX %= 240;
|
||||
- if (intX < 0)
|
||||
- intX += 240;
|
||||
- }
|
||||
- else
|
||||
- continue;
|
||||
+ continue;
|
||||
if (intY < 0 || intY >= 160)
|
||||
- if (m_cnt & (0x1 << 13))
|
||||
- {
|
||||
- intY %= 160;
|
||||
- if (intY < 0)
|
||||
- intY += 160;
|
||||
- }
|
||||
- else
|
||||
- continue;
|
||||
-
|
||||
+ continue;
|
||||
*ptr = pChar[intY * 240 * 2 + intX * 2] | 0x8000;
|
||||
}
|
||||
}
|
||||
@@ -413,6 +397,27 @@ namespace AMeteor
|
||||
}
|
||||
}
|
||||
|
||||
+ void BgLayer::DrawLine5 (uint16_t* ptr,
|
||||
+ int32_t curX, int32_t curY,
|
||||
+ int16_t dx, int16_t dy, bool frame1)
|
||||
+ {
|
||||
+ int32_t intX, intY;
|
||||
+ uint16_t* pChar = (uint16_t*) m_memory.GetRealAddress(frame1 ? 0x0600A000 : 0x06000000);
|
||||
+
|
||||
+ for (uint8_t x = 0; x < 240; ++x, ++ptr, curX += dx, curY += dy)
|
||||
+ {
|
||||
+ intX = curX >> 8;
|
||||
+ intY = curY >> 8;
|
||||
+
|
||||
+ // if we are off layer
|
||||
+ if (intX < 0 || intX >= 160)
|
||||
+ continue;
|
||||
+ if (intY < 0 || intY >= 128)
|
||||
+ continue;
|
||||
+ *ptr = pChar[intY * 160 + intX] | 0x8000;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
void BgLayer::UpdateCnt (uint16_t cnt)
|
||||
{
|
||||
if (m_cnt == cnt)
|
||||
diff --git a/ameteor/source/graphics/screen.cpp b/ameteor/source/graphics/screen.cpp
|
||||
index 4c5628b..85da3b9 100644
|
||||
--- a/ameteor/source/graphics/screen.cpp
|
||||
+++ b/ameteor/source/graphics/screen.cpp
|
||||
@@ -121,6 +121,16 @@ namespace AMeteor
|
||||
// if objects are enabled draw them
|
||||
if (layersOn & (0x1 << 4)) m_objs.DrawLine(line, lineObj);
|
||||
break;
|
||||
+ case 3: // bg2 only 15 bit direct color 240x160
|
||||
+ layersOn &= 0xF4;
|
||||
+ if (layersOn & (0x1 << 2))
|
||||
+ m_bgLayer2.DrawLine3(lineBg+2*WIDTH,
|
||||
+ m_refX2, m_refY2,
|
||||
+ m_io.DRead16(Io::BG2PA),
|
||||
+ m_io.DRead16(Io::BG2PC));
|
||||
+ if (layersOn & (0x1 << 4))
|
||||
+ m_objs.DrawLineHighOnly(line, lineObj);
|
||||
+ break;
|
||||
// TODO (remember, HIGH ONLY for objs, don't make shitty copy paste)
|
||||
case 4: // bg2 only in mode 4 (bitmap 256)
|
||||
layersOn &= 0xF4;
|
||||
@@ -141,6 +151,18 @@ namespace AMeteor
|
||||
// all objs with the current priority
|
||||
m_objs.DrawLineHighOnly(line, lineObj);
|
||||
break;
|
||||
+ case 5: // bg2 only 15 bit direct color 160x128 2 frames
|
||||
+ layersOn &= 0xF4;
|
||||
+ if (layersOn & (0x1 << 2))
|
||||
+ m_bgLayer2.DrawLine5(lineBg+2*WIDTH,
|
||||
+ m_refX2, m_refY2,
|
||||
+ m_io.DRead16(Io::BG2PA),
|
||||
+ m_io.DRead16(Io::BG2PC),
|
||||
+ m_dispcnt & (0x1 << 4));
|
||||
+
|
||||
+ if (layersOn & (0x1 << 4))
|
||||
+ m_objs.DrawLineHighOnly(line, lineObj);
|
||||
+ break;
|
||||
default :
|
||||
met_abort("not supported : " << (m_dispcnt & 0x7));
|
||||
break;
|
||||
diff --git a/ameteor/source/io.cpp b/ameteor/source/io.cpp
|
||||
index c0cd244..2003d21 100644
|
||||
--- a/ameteor/source/io.cpp
|
||||
+++ b/ameteor/source/io.cpp
|
||||
@@ -99,6 +99,8 @@ namespace AMeteor
|
||||
// TODO implement unreadable or write-only io
|
||||
uint8_t Io::Read8 (uint32_t add)
|
||||
{
|
||||
+ if ((add & 0xFFF) == KEYINPUT)
|
||||
+ m_polled = true;
|
||||
//debug ("IO Read8 at " << IOS_ADD << add << " of " << IOS_ADD << (int)*(uint8_t*)(m_iomem + (add & 0xFFF)));
|
||||
if ((add & 0xFF0) == 0x100)
|
||||
switch (add & 0xF)
|
||||
@@ -114,6 +116,8 @@ namespace AMeteor
|
||||
|
||||
uint16_t Io::Read16 (uint32_t add)
|
||||
{
|
||||
+ if ((add & 0xFFE) == KEYINPUT)
|
||||
+ m_polled = true;
|
||||
//debug ("IO Read16 at " << IOS_ADD << add << " of " << IOS_ADD << *(uint16_t*)(m_iomem + (add & 0xFFF)));
|
||||
// special case, reading timers
|
||||
if ((add & 0xFF0) == 0x100)
|
||||
@@ -129,6 +133,8 @@ namespace AMeteor
|
||||
|
||||
uint32_t Io::Read32 (uint32_t add)
|
||||
{
|
||||
+ if ((add & 0xFFC) == KEYINPUT)
|
||||
+ m_polled = true;
|
||||
//debug ("IO Read32 at " << IOS_ADD << add << " of " << IOS_ADD << *(uint32_t*)(m_iomem + (add & 0xFFF)));
|
||||
// special case, reading timers
|
||||
if ((add & 0xFF0) == 0x100)
|
||||
@@ -282,29 +288,36 @@ namespace AMeteor
|
||||
// update the vcounter flag and eventually trigger an interrupt
|
||||
W16(add, (val & 0xFFF8) | (m_iomem[add & 0xFFF] & 0x07));
|
||||
break;
|
||||
- // The BG*OFS are write-only, we don't need to W16()
|
||||
case BG0HOFS:
|
||||
+ W16(add, val & 0x1FF);
|
||||
LCD.UpdateBg0XOff(val & 0x1FF);
|
||||
break;
|
||||
case BG0VOFS:
|
||||
+ W16(add, val & 0x1FF);
|
||||
LCD.UpdateBg0YOff(val & 0x1FF);
|
||||
break;
|
||||
case BG1HOFS:
|
||||
+ W16(add, val & 0x1FF);
|
||||
LCD.UpdateBg1XOff(val & 0x1FF);
|
||||
break;
|
||||
case BG1VOFS:
|
||||
+ W16(add, val & 0x1FF);
|
||||
LCD.UpdateBg1YOff(val & 0x1FF);
|
||||
break;
|
||||
case BG2HOFS:
|
||||
+ W16(add, val & 0x1FF);
|
||||
LCD.UpdateBg2XOff(val & 0x1FF);
|
||||
break;
|
||||
case BG2VOFS:
|
||||
+ W16(add, val & 0x1FF);
|
||||
LCD.UpdateBg2YOff(val & 0x1FF);
|
||||
break;
|
||||
case BG3HOFS:
|
||||
+ W16(add, val & 0x1FF);
|
||||
LCD.UpdateBg3XOff(val & 0x1FF);
|
||||
break;
|
||||
case BG3VOFS:
|
||||
+ W16(add, val & 0x1FF);
|
||||
LCD.UpdateBg3YOff(val & 0x1FF);
|
||||
break;
|
||||
case BG2X_H:
|
||||
diff --git a/ameteor/source/memory.cpp b/ameteor/source/memory.cpp
|
||||
index bf17688..839841e 100644
|
||||
--- a/ameteor/source/memory.cpp
|
||||
+++ b/ameteor/source/memory.cpp
|
||||
@@ -464,8 +464,9 @@ namespace AMeteor
|
||||
// write if we have a custom bios and write it too
|
||||
bool b = m_brom;
|
||||
SS_WRITE_VAR(b);
|
||||
- if (b)
|
||||
+ if (b) {
|
||||
SS_WRITE_DATA(m_brom, 0x00004000);
|
||||
+ }
|
||||
SS_WRITE_DATA(m_wbram, 0x00040000);
|
||||
SS_WRITE_DATA(m_wcram, 0x00008000);
|
||||
SS_WRITE_DATA(m_pram , 0x00000400);
|
||||
@@ -490,9 +491,9 @@ namespace AMeteor
|
||||
// read if we have a custom bios and write it too
|
||||
bool b;
|
||||
SS_READ_VAR(b);
|
||||
- if (b)
|
||||
+ if (b) {
|
||||
SS_READ_DATA(m_brom , 0x00004000);
|
||||
- else
|
||||
+ } else
|
||||
UnloadBios();
|
||||
SS_READ_DATA(m_wbram, 0x00040000);
|
||||
SS_READ_DATA(m_wcram, 0x00008000);
|
||||
@@ -532,6 +533,8 @@ namespace AMeteor
|
||||
if (!r)
|
||||
{
|
||||
debugm("Unknown address for Read8 : " << IOS_ADD << add);
|
||||
+ if(add == R(15))
|
||||
+ return 0xFF; //We are fucked...
|
||||
// FIXME : in arm state, vba returns read8(r15 + (add & 3))
|
||||
// and in thumb read8(r15 + (add & 1))
|
||||
return Read8(R(15));
|
||||
@@ -559,8 +562,10 @@ namespace AMeteor
|
||||
if (!r)
|
||||
{
|
||||
debugm("Unknown address for Read16 : " << IOS_ADD << add);
|
||||
- if (R(15) == add)
|
||||
+ if (R(15) == add) {
|
||||
met_abort("Illegal PC");
|
||||
+ return 0xFFFF; //We are fucked.
|
||||
+ }
|
||||
// FIXME : in arm state, vba returns read16(r15 + (add & 2))
|
||||
return Read16(R(15));
|
||||
}
|
||||
@@ -586,8 +591,10 @@ namespace AMeteor
|
||||
if (!r)
|
||||
{
|
||||
debugm("Unknown address for Read32 : " << IOS_ADD << add);
|
||||
- if (R(15) == add)
|
||||
+ if (R(15) == add) {
|
||||
met_abort("Illegal PC");
|
||||
+ return 0xFFFFFFFFU; //We are fucked.
|
||||
+ }
|
||||
if (FLAG_T)
|
||||
{
|
||||
uint16_t o = Read16(R(15));
|
||||
@@ -810,4 +817,20 @@ namespace AMeteor
|
||||
if (m_cart->Write(add, val))
|
||||
CLOCK.SetBattery(CART_SAVE_TIME);
|
||||
}
|
||||
+
|
||||
+ std::map<std::string, std::pair<uint8_t*, size_t> > Memory::GetMemories()
|
||||
+ {
|
||||
+ std::map<std::string, std::pair<uint8_t*, size_t> > x;
|
||||
+ if(m_brom)
|
||||
+ x["brom"] = std::make_pair(m_brom, 0x00004000);
|
||||
+ x["wbram"] = std::make_pair(m_wbram, 0x00040000);
|
||||
+ x["wcram"] = std::make_pair(m_wcram, 0x00008000);
|
||||
+ x["pram"] = std::make_pair(m_pram, 0x00000400);
|
||||
+ x["vram"] = std::make_pair(m_vram, 0x00018000);
|
||||
+ x["oam"] = std::make_pair(m_oram, 0x00000400);
|
||||
+ if(m_cart)
|
||||
+ x["sram"] = std::make_pair(m_cart->GetRawData(), m_cart->GetRawSize());
|
||||
+ x["rom"] = std::make_pair(m_rom, 0x02000000);
|
||||
+ return x;
|
||||
+ }
|
||||
}
|
||||
--
|
||||
1.7.9.48.g85da4d
|
||||
|
|
@ -106,6 +106,9 @@ BUILD_GAMBATTE=
|
|||
# Set to non-empty value (e.g. 'yes') to build the bsnes core.
|
||||
BUILD_BSNES=yes
|
||||
|
||||
# Set to non-empty value (e.g. 'yes') to build the meteor core.
|
||||
BUILD_METEOR=
|
||||
|
||||
# Set to non-empty value (e.g. 'yes') if bsnes build uses compatiblity core, not accuracy core.
|
||||
BSNES_IS_COMPAT=
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
CORES=bsnes-legacy gambatte sky test
|
||||
CORES=bsnes-legacy gambatte sky test meteor
|
||||
ALLFILES=__all__.files
|
||||
ALLFLAGS=__all__.ldflags
|
||||
CORES_FILES=$(patsubst %,%/$(ALLFILES),$(CORES))
|
||||
|
@ -23,6 +23,9 @@ sky/$(ALLFILES): forcelook make-ports.exe
|
|||
test/$(ALLFILES): forcelook make-ports.exe
|
||||
$(MAKE) -C test
|
||||
|
||||
meteor/$(ALLFILES): forcelook
|
||||
$(MAKE) -C meteor
|
||||
|
||||
.PRECIOUS: %.$(OBJECT_SUFFIX) %.files
|
||||
|
||||
precheck:
|
||||
|
@ -30,11 +33,13 @@ precheck:
|
|||
$(MAKE) -C gambatte precheck
|
||||
$(MAKE) -C sky precheck
|
||||
$(MAKE) -C test precheck
|
||||
$(MAKE) -C meteor precheck
|
||||
|
||||
clean:
|
||||
rm -f *.$(OBJECT_SUFFIX) __all__.ldflags __all__.files
|
||||
$(MAKE) -C bsnes-legacy clean
|
||||
$(MAKE) -C gambatte clean
|
||||
$(MAKE) -C meteor clean
|
||||
$(MAKE) -C sky clean
|
||||
$(MAKE) -C test clean
|
||||
rm -f make-ports.exe
|
||||
|
|
42
src/emulation/meteor/Makefile
Normal file
42
src/emulation/meteor/Makefile
Normal file
|
@ -0,0 +1,42 @@
|
|||
ifdef BUILD_METEOR
|
||||
OBJECTS=core.$(OBJECT_SUFFIX)
|
||||
METEOR_CFLAGS=
|
||||
METEOR_LDFLAGS=
|
||||
REALAR=$(CROSS_PREFIX)ar
|
||||
export REALAR
|
||||
METEOR_LIBRARY=meteor/libmeteor.$(ARCHIVE_SUFFIX)
|
||||
|
||||
.PRECIOUS: %.$(OBJECT_SUFFIX) %.files
|
||||
|
||||
__all__.files: $(OBJECTS) ../../../$(METEOR_LIBRARY)
|
||||
lua ../../genfilelist.lua $^ >$@
|
||||
echo $(METEOR_LDFLAGS) ../$(METEOR_LIBRARY) >__all__.ldflags
|
||||
|
||||
../../../$(METEOR_LIBRARY): forcelook
|
||||
$(MAKE) -C ../../../meteor
|
||||
$(REALRANLIB) $@
|
||||
|
||||
ports.inc: ports.json ../make-ports.exe
|
||||
../make-ports.exe <$< >$@
|
||||
|
||||
%.$(OBJECT_SUFFIX): %.cpp ports.inc
|
||||
$(REALCC) -c -o $@ $< -I../../../include -I../../../meteor/ameteor/include $(CFLAGS) $(METEOR_CFLAGS)
|
||||
|
||||
else
|
||||
|
||||
OBJECTS=
|
||||
__all__.files: $(OBJECTS)
|
||||
lua ../../genfilelist.lua $^ >$@
|
||||
echo >__all__.ldflags
|
||||
|
||||
endif
|
||||
|
||||
forcelook:
|
||||
@true
|
||||
|
||||
precheck:
|
||||
@true
|
||||
|
||||
clean:
|
||||
-make -C ../../../gambatte clean
|
||||
rm -f *.$(OBJECT_SUFFIX) __all__.ldflags __all__.files
|
497
src/emulation/meteor/core.cpp
Normal file
497
src/emulation/meteor/core.cpp
Normal file
|
@ -0,0 +1,497 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2013 by Ilari Liusvaara *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program 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 General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
***************************************************************************/
|
||||
#include "lsnes.hpp"
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "core/audioapi.hpp"
|
||||
#include "core/misc.hpp"
|
||||
#include "core/command.hpp"
|
||||
#include "core/controllerframe.hpp"
|
||||
#include "core/dispatch.hpp"
|
||||
#include "core/framebuffer.hpp"
|
||||
#include "core/window.hpp"
|
||||
#include "interface/callbacks.hpp"
|
||||
#include "interface/cover.hpp"
|
||||
#include "interface/romtype.hpp"
|
||||
#include "library/framebuffer-pixfmt-rgb15.hpp"
|
||||
#include "library/string.hpp"
|
||||
//#include "library/portfn.hpp"
|
||||
#include "library/serialization.hpp"
|
||||
#include "library/minmax.hpp"
|
||||
#include "library/framebuffer.hpp"
|
||||
#define __LIBRETRO__
|
||||
#include "ameteor.hpp"
|
||||
#include "ameteor/cartmem.hpp"
|
||||
|
||||
uint64_t get_utime();
|
||||
|
||||
namespace
|
||||
{
|
||||
bool do_reset_flag = false;
|
||||
bool internal_rom = false;
|
||||
bool rtc_fixed;
|
||||
time_t rtc_fixed_val;
|
||||
std::vector<unsigned char> romdata;
|
||||
uint16_t cover_fbmem[720 * 480];
|
||||
bool pflag = false;
|
||||
int16_t soundbuf[65536];
|
||||
size_t soundbuf_fill;
|
||||
bool frame_happened;
|
||||
bool just_reset;
|
||||
|
||||
struct interface_device_reg gba_registers[] = {
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
//Framebuffer.
|
||||
struct framebuffer::info cover_fbinfo = {
|
||||
&framebuffer::pixfmt_rgb15, //Format.
|
||||
(char*)cover_fbmem, //Memory.
|
||||
720, 480, 1440, //Physical size.
|
||||
720, 480, 1440, //Logical size.
|
||||
0, 0 //Offset.
|
||||
};
|
||||
|
||||
#include "ports.inc"
|
||||
|
||||
struct _output
|
||||
{
|
||||
void frame(const uint16_t* p)
|
||||
{
|
||||
AMeteor::Stop();
|
||||
framebuffer::info inf;
|
||||
inf.type = &framebuffer::pixfmt_rgb15;
|
||||
inf.mem = const_cast<char*>(reinterpret_cast<const char*>(p));
|
||||
inf.physwidth = 240;
|
||||
inf.physheight = 160;
|
||||
inf.physstride = 480;
|
||||
inf.width = 240;
|
||||
inf.height = 160;
|
||||
inf.stride = 480;
|
||||
inf.offset_x = 0;
|
||||
inf.offset_y = 0;
|
||||
|
||||
framebuffer::raw ls(inf);
|
||||
ecore_callbacks->output_frame(ls, 262144, 4389);
|
||||
ecore_callbacks->timer_tick(4389, 262144);
|
||||
static uint32_t refreshes = 0;
|
||||
static uint64_t samples = 0;
|
||||
refreshes++;
|
||||
static double srate = 4194304.0/95.0;
|
||||
if(soundbuf_fill > 0) {
|
||||
samples += soundbuf_fill / 2;
|
||||
audioapi_submit_buffer(soundbuf, soundbuf_fill / 2, true, srate);
|
||||
soundbuf_fill = 0;
|
||||
}
|
||||
frame_happened = true;
|
||||
}
|
||||
void sample(const int16_t* s)
|
||||
{
|
||||
soundbuf[soundbuf_fill++] = s[0];
|
||||
soundbuf[soundbuf_fill++] = s[1];
|
||||
}
|
||||
void vblank()
|
||||
{
|
||||
}
|
||||
} output;
|
||||
|
||||
std::string fmt_sram_size(uint32_t sram_size)
|
||||
{
|
||||
std::string mult = "";
|
||||
if(sram_size > 1024) {
|
||||
mult = "k";
|
||||
sram_size >>= 10;
|
||||
}
|
||||
if(sram_size > 1024) {
|
||||
mult = "M";
|
||||
sram_size >>= 10;
|
||||
}
|
||||
return (stringfmt() << sram_size << mult << "B").str();
|
||||
}
|
||||
|
||||
void meteor_bus_write(uint64_t offset, uint8_t data)
|
||||
{
|
||||
uint8_t* m = AMeteor::_memory.GetRealAddress(offset);
|
||||
if(m) *m = data;
|
||||
}
|
||||
|
||||
uint8_t meteor_bus_read(uint64_t offset)
|
||||
{
|
||||
uint8_t* m = AMeteor::_memory.GetRealAddress(offset);
|
||||
return m ? *m : 0xFF;
|
||||
}
|
||||
|
||||
void avsync_hack()
|
||||
{
|
||||
//Hack: Send 223 samples.
|
||||
for(unsigned i = 0; i < 446; i++)
|
||||
soundbuf[soundbuf_fill++] = 0;
|
||||
}
|
||||
|
||||
void meteor_poll_buttons()
|
||||
{
|
||||
uint16_t x = 0;
|
||||
for(unsigned i = 0; i < 10; i++)
|
||||
if(ecore_callbacks->get_input(0, 1, i))
|
||||
x |= (1 << i);
|
||||
AMeteor::_keypad.SetPadState(x ^ 0x3FF); //Inverse polarity.
|
||||
pflag = true;
|
||||
}
|
||||
|
||||
void basic_init()
|
||||
{
|
||||
static bool done = false;
|
||||
if(done)
|
||||
return;
|
||||
done = true;
|
||||
AMeteor::_memory.LoadCartInferred();
|
||||
AMeteor::_lcd.sig_vblank.connect(syg::mem_fun(output, &_output::vblank));
|
||||
AMeteor::_lcd.GetScreen().GetRenderer().SetFrameSlot(syg::mem_fun(output, &_output::frame));
|
||||
AMeteor::_sound.GetSpeaker().SetFrameSlot(syg::mem_fun(output, &_output::sample));
|
||||
}
|
||||
|
||||
controller_set meteor_controllerconfig(std::map<std::string, std::string>& settings)
|
||||
{
|
||||
std::map<std::string, std::string> _settings = settings;
|
||||
controller_set r;
|
||||
r.ports.push_back(&psystem);
|
||||
r.logical_map.push_back(std::make_pair(0, 1));
|
||||
return r;
|
||||
}
|
||||
|
||||
std::pair<uint64_t, uint64_t> meteor_bus_map()
|
||||
{
|
||||
return std::make_pair(0x100000000ULL, 0x100000000ULL);
|
||||
}
|
||||
|
||||
void add_vma_mapped(std::list<core_vma_info>& l, const std::string& name, uint64_t base, uint8_t* ram,
|
||||
size_t ramsize, int endian, bool readonly)
|
||||
{
|
||||
core_vma_info v;
|
||||
v.name = name;
|
||||
v.base = base;
|
||||
v.size = ramsize;
|
||||
v.backing_ram = ram;
|
||||
v.endian = endian;
|
||||
v.readonly = readonly;
|
||||
v.read = NULL;
|
||||
v.write = NULL;
|
||||
l.push_back(v);
|
||||
}
|
||||
|
||||
uint64_t get_vmabase(const std::string& name)
|
||||
{
|
||||
static std::map<std::string, uint64_t> unknown;
|
||||
uint64_t unknown_next = 0x200000000ULL;
|
||||
if(name == "brom") return 0x90000000ULL;
|
||||
if(name == "wbram") return 0;
|
||||
if(name == "wcram") return 0x40000ULL;
|
||||
if(name == "pram") return 0x100000ULL;
|
||||
if(name == "vram") return 0x110000ULL;
|
||||
if(name == "oam") return 0x120000ULL;
|
||||
if(name == "sram") return 0x10000000ULL;
|
||||
if(name == "rom") return 0x80000000ULL;
|
||||
//Unknown.
|
||||
if(!unknown.count(name)) {
|
||||
unknown[name] = unknown_next;
|
||||
unknown_next += 0x100000000ULL;
|
||||
}
|
||||
return unknown[name];
|
||||
}
|
||||
|
||||
bool is_read_only_vma(const std::string& name)
|
||||
{
|
||||
if(name == "wbram") return false;
|
||||
if(name == "wcram") return false;
|
||||
if(name == "pram") return false;
|
||||
if(name == "vram") return false;
|
||||
if(name == "oam") return false;
|
||||
if(name == "sram") return false;
|
||||
//Dunno what this is.
|
||||
return true;
|
||||
}
|
||||
|
||||
std::list<core_vma_info> get_VMAlist()
|
||||
{
|
||||
std::list<core_vma_info> vmas;
|
||||
if(!internal_rom)
|
||||
return vmas;
|
||||
auto mem_map = AMeteor::_memory.GetMemories();
|
||||
for(auto i : mem_map)
|
||||
add_vma_mapped(vmas, i.first, get_vmabase(i.first), i.second.first, i.second.second, -1,
|
||||
is_read_only_vma(i.first));
|
||||
//Bus mapping.
|
||||
core_vma_info bus;
|
||||
bus.name = "BUS";
|
||||
bus.base = 0x100000000ULL;
|
||||
bus.size = 0x100000000ULL;
|
||||
bus.backing_ram = NULL;
|
||||
bus.endian = -1;
|
||||
bus.readonly = false;
|
||||
bus.read = meteor_bus_read;
|
||||
bus.write = meteor_bus_write;
|
||||
vmas.push_back(bus);
|
||||
|
||||
return vmas;
|
||||
}
|
||||
|
||||
std::set<std::string> meteor_srams()
|
||||
{
|
||||
std::set<std::string> s;
|
||||
if(!internal_rom)
|
||||
return s;
|
||||
auto mem_map = AMeteor::_memory.GetMemories();
|
||||
if(mem_map.count("sram"))
|
||||
s.insert("sram");
|
||||
return s;
|
||||
}
|
||||
|
||||
std::string get_cartridge_name()
|
||||
{
|
||||
std::ostringstream name;
|
||||
if(romdata.size() < 192)
|
||||
return ""; //Bad.
|
||||
for(unsigned i = 0; i < 12; i++) {
|
||||
if(romdata[0x0A0 + i])
|
||||
name << (char)romdata[0xA0 + i];
|
||||
else
|
||||
break;
|
||||
}
|
||||
name << "[AGB-";
|
||||
for(unsigned i = 0; i < 4; i++)
|
||||
name << (char)romdata[0xAC + i];
|
||||
name << "] (version " << (int)(unsigned char)romdata[0xBC];
|
||||
if((unsigned char)romdata[0x9C] == 0xA5)
|
||||
name << "-Debug";
|
||||
name << ")";
|
||||
return name.str();
|
||||
}
|
||||
|
||||
void redraw_cover_fbinfo();
|
||||
|
||||
struct _meteor_core : public core_core, public core_type, public core_region, public core_sysregion
|
||||
{
|
||||
_meteor_core()
|
||||
: core_core({&psystem}, {{0, "Soft reset", "reset", {}}}),
|
||||
core_type({{
|
||||
.iname = "agb",
|
||||
.hname = "Game Boy Advance",
|
||||
.id = 0,
|
||||
.sysname = "GBA",
|
||||
.bios = NULL,
|
||||
.regions = {this},
|
||||
.images = {{"rom", "Cartridge ROM", 1, 0, 0, "gba;agb"}},
|
||||
.settings = {{"extbios", "Use GBA BIOS", "0", {
|
||||
{"0", "False", 0},
|
||||
{"1", "True", 1}
|
||||
}}},
|
||||
.core = this,
|
||||
}}),
|
||||
core_region({{"world", "World", 0, 0, false, {4389, 262144}, {0}}}),
|
||||
core_sysregion("magb", *this, *this) {}
|
||||
|
||||
std::string c_core_identifier() { return "meteor 1.4.0"; }
|
||||
bool c_set_region(core_region& region) { return (®ion == this); }
|
||||
std::pair<uint32_t, uint32_t> c_video_rate() { return std::make_pair(262144, 4389); }
|
||||
std::pair<uint32_t, uint32_t> c_audio_rate() { return std::make_pair(4194304, 95); }
|
||||
std::map<std::string, std::vector<char>> c_save_sram() throw(std::bad_alloc) {
|
||||
std::map<std::string, std::vector<char>> s;
|
||||
if(!internal_rom)
|
||||
return s;
|
||||
std::vector<char> sram;
|
||||
uint32_t realsize = *(uint32_t*)(AMeteor::CartMemData + AMeteor::CartMem::MAX_SIZE);
|
||||
sram.resize(realsize);
|
||||
memcpy(&sram[0], AMeteor::CartMemData, realsize);
|
||||
s["sram"] = sram;
|
||||
return s;
|
||||
}
|
||||
void c_load_sram(std::map<std::string, std::vector<char>>& sram) throw(std::bad_alloc) {
|
||||
if(!internal_rom)
|
||||
return;
|
||||
if(!sram.count("sram")) {
|
||||
//Don't clear the SRAM descriptor.
|
||||
memset(AMeteor::CartMemData, 255, AMeteor::CartMem::MAX_SIZE);
|
||||
return;
|
||||
}
|
||||
std::vector<char>& s = sram["sram"];
|
||||
//Read the size from SRAM descriptor.
|
||||
uint32_t realsize = *(uint32_t*)(AMeteor::CartMemData + AMeteor::CartMem::MAX_SIZE);
|
||||
//Don't clear the SRAM descriptor.
|
||||
memset(AMeteor::CartMemData, 255, AMeteor::CartMem::MAX_SIZE);
|
||||
if(s.size() != realsize)
|
||||
messages << "Unexpected SRAM size, expected " << realsize << " got " << s.size()
|
||||
<< std::endl;
|
||||
memcpy(AMeteor::CartMemData, &s[0], min((size_t)realsize, s.size()));
|
||||
}
|
||||
void c_serialize(std::vector<char>& out) {
|
||||
if(!internal_rom)
|
||||
throw std::runtime_error("Can't save without ROM");
|
||||
std::ostringstream stream;
|
||||
AMeteor::SaveState(stream);
|
||||
std::string s = stream.str();
|
||||
out.resize(s.length());
|
||||
std::copy(s.begin(), s.end(), out.begin());
|
||||
}
|
||||
void c_unserialize(const char* in, size_t insize) {
|
||||
if(!internal_rom)
|
||||
throw std::runtime_error("Can't load without ROM");
|
||||
std::istringstream stream;
|
||||
stream.str(std::string((char*)in, insize));
|
||||
AMeteor::LoadState(stream);
|
||||
do_reset_flag = false;
|
||||
}
|
||||
core_region& c_get_region() { return *this; }
|
||||
void c_power() {}
|
||||
void c_unload_cartridge() {}
|
||||
std::pair<uint32_t, uint32_t> c_get_scale_factors(uint32_t width, uint32_t height) {
|
||||
return std::make_pair(max(720 / width, (uint32_t)1), max(480 / height, (uint32_t)1));
|
||||
}
|
||||
void c_install_handler() { magic_flags |= 4; }
|
||||
void c_uninstall_handler() {}
|
||||
void c_emulate() {
|
||||
if(!internal_rom)
|
||||
return;
|
||||
int16_t reset = ecore_callbacks->get_input(0, 0, 1);
|
||||
if(reset) {
|
||||
AMeteor::Reset(AMeteor::UNIT_ALL & ~AMeteor::UNIT_MEMORY_BIOS &
|
||||
~AMeteor::UNIT_MEMORY_ROM);
|
||||
just_reset = true;
|
||||
messages << "GBA reset" << std::endl;
|
||||
}
|
||||
do_reset_flag = false;
|
||||
meteor_poll_buttons();
|
||||
frame_happened = false;
|
||||
if(just_reset) {
|
||||
avsync_hack();
|
||||
just_reset = false;
|
||||
}
|
||||
while(!frame_happened) {
|
||||
AMeteor::Run(281000);
|
||||
if(!frame_happened)
|
||||
std::cerr << "Warning: Run timeout" << std::endl;
|
||||
}
|
||||
}
|
||||
void c_runtosave() {}
|
||||
bool c_get_pflag() { return AMeteor::_io.GetPolled(); }
|
||||
void c_set_pflag(bool _pflag) { AMeteor::_io.SetPolled(_pflag); }
|
||||
void c_request_reset(long delay, bool hard) { do_reset_flag = true; }
|
||||
framebuffer::raw& c_draw_cover() {
|
||||
static framebuffer::raw x(cover_fbinfo);
|
||||
redraw_cover_fbinfo();
|
||||
return x;
|
||||
}
|
||||
std::string c_get_core_shortname() { return "meteor140"; }
|
||||
void c_pre_emulate_frame(controller_frame& cf) {
|
||||
cf.axis3(0, 0, 1, do_reset_flag ? 1 : 0);
|
||||
}
|
||||
void c_execute_action(unsigned id, const std::vector<interface_action_paramval>& p)
|
||||
{
|
||||
if(id == 0)
|
||||
do_reset_flag = true;
|
||||
}
|
||||
unsigned int c_action_flags(unsigned id)
|
||||
{
|
||||
if(id == 0) return 1;
|
||||
return 0;
|
||||
}
|
||||
const interface_device_reg* c_get_registers() { return gba_registers; }
|
||||
int c_reset_action(bool hard) { return hard ? -1 : 0; }
|
||||
int t_load_rom(core_romimage* img, std::map<std::string, std::string>& settings, uint64_t rtc_sec,
|
||||
uint64_t rtc_subsec) {
|
||||
uint32_t sram_size = 0;
|
||||
std::map<std::string, std::string> _settings = settings;
|
||||
get_settings().fill_defaults(_settings);
|
||||
basic_init();
|
||||
const char* markup = img[0].markup;
|
||||
if(!markup)
|
||||
markup = "";
|
||||
std::string _markup = markup;
|
||||
std::istringstream imarkup(markup);
|
||||
const unsigned char* data = img[0].data;
|
||||
size_t size = img[0].size;
|
||||
romdata.resize(size);
|
||||
memcpy(&romdata[0], data, size);
|
||||
std::string markup_line;
|
||||
|
||||
while(std::getline(imarkup, markup_line)) {
|
||||
regex_results r;
|
||||
istrip_CR(markup_line);
|
||||
if(r = regex("sram_size=([0-9]+)", markup_line)) {
|
||||
try {
|
||||
sram_size = parse_value<uint32_t>(r[1]);
|
||||
} catch(...) {
|
||||
}
|
||||
} else if(r = regex("sram_size=([0-9]+)k", markup_line)) {
|
||||
try {
|
||||
sram_size = 1024 * parse_value<uint32_t>(r[1]);
|
||||
} catch(...) {
|
||||
}
|
||||
} else
|
||||
messages << "Unknown markup: " << markup_line << std::endl;
|
||||
}
|
||||
|
||||
AMeteor::Reset(AMeteor::UNIT_ALL);
|
||||
if(_settings["extbios"] != "0") {
|
||||
//Load the BIOS.
|
||||
std::string bname = ecore_callbacks->get_firmware_path() + "/gbabios.bin";
|
||||
if(!AMeteor::_memory.LoadBios(bname.c_str())) {
|
||||
messages << "Can't load GBA BIOS" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
AMeteor::_memory.LoadRom((const uint8_t*)data, size);
|
||||
*(uint32_t*)(AMeteor::CartMemData + AMeteor::CartMem::MAX_SIZE) = sram_size;
|
||||
if(sram_size > 0)
|
||||
messages << "SRAM size: " << fmt_sram_size(sram_size) << std::endl;
|
||||
AMeteor::_memory.LoadCartInferred();
|
||||
internal_rom = true;
|
||||
do_reset_flag = false;
|
||||
just_reset = true;
|
||||
return 0;
|
||||
}
|
||||
controller_set t_controllerconfig(std::map<std::string, std::string>& settings)
|
||||
{
|
||||
return meteor_controllerconfig(settings);
|
||||
}
|
||||
std::pair<uint64_t, uint64_t> c_get_bus_map() { return meteor_bus_map(); }
|
||||
std::list<core_vma_info> c_vma_list() { return get_VMAlist(); }
|
||||
std::set<std::string> c_srams() { return meteor_srams(); }
|
||||
double c_get_PAR() { return 1.0; }
|
||||
void c_set_debug_flags(uint64_t addr, unsigned flags_set, unsigned flags_clear) {}
|
||||
void c_set_cheat(uint64_t addr, uint64_t value, bool set) {}
|
||||
std::vector<std::string> c_get_trace_cpus() { return std::vector<std::string>(); }
|
||||
void c_debug_reset() {}
|
||||
} meteor_core;
|
||||
|
||||
void redraw_cover_fbinfo()
|
||||
{
|
||||
for(size_t i = 0; i < sizeof(cover_fbmem) / sizeof(cover_fbmem[0]); i++)
|
||||
cover_fbmem[i] = 0x0000;
|
||||
std::string ident = meteor_core.c_core_identifier();
|
||||
cover_render_string(cover_fbmem, 0, 0, ident, 0xFFFF, 0x0000, 720, 480, 1440, 2);
|
||||
cover_render_string(cover_fbmem, 0, 16, "Internal ROM name: " + get_cartridge_name(), 0xFFFF, 0x0000,
|
||||
720, 480, 1440, 2);
|
||||
unsigned y = 32;
|
||||
for(auto i : cover_information()) {
|
||||
cover_render_string(cover_fbmem, 0, y, i, 0xFFFF, 0x0000, 720, 480, 1440, 2);
|
||||
y += 16;
|
||||
}
|
||||
}
|
||||
}
|
25
src/emulation/meteor/ports.json
Normal file
25
src/emulation/meteor/ports.json
Normal file
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"ports":[{
|
||||
"symbol":"psystem", "name":"system", "hname":"system","controllers":[{
|
||||
"type":"(system)", "class":"(system)","buttons":[
|
||||
{"type":"button","symbol":"F","name":"framesync", "shadow":true},
|
||||
{"type":"button","symbol":"R","name":"reset", "shadow":true},
|
||||
{"type":"null", "shadow":true},
|
||||
{"type":"null", "shadow":true}
|
||||
]
|
||||
},{
|
||||
"type":"gamepad", "class":"gba","buttons":[
|
||||
{"type":"button","name":"A"},
|
||||
{"type":"button","name":"B"},
|
||||
{"type":"button","symbol":"s","name":"select"},
|
||||
{"type":"button","symbol":"S","name":"start"},
|
||||
{"type":"button","movie":"r","symbol":"→","name":"right","macro":">"},
|
||||
{"type":"button","movie":"l","symbol":"←","name":"left","macro":"<"},
|
||||
{"type":"button","movie":"u","symbol":"↑","name":"up","macro":"^"},
|
||||
{"type":"button","movie":"d","symbol":"↓","name":"down","macro":"v"},
|
||||
{"type":"button","name":"L"},
|
||||
{"type":"button","name":"R"}
|
||||
]
|
||||
}],"legal":[0]
|
||||
}]
|
||||
}
|
Loading…
Add table
Reference in a new issue