diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/GBACart.cpp | 67 | ||||
-rw-r--r-- | src/GBACart.h | 19 |
2 files changed, 70 insertions, 16 deletions
diff --git a/src/GBACart.cpp b/src/GBACart.cpp index 75bc1dc..5b81900 100644 --- a/src/GBACart.cpp +++ b/src/GBACart.cpp @@ -461,15 +461,6 @@ const char SOLAR_SENSOR_GAMECODES[10][5] = };
-struct GPIO
-{
- bool has_solar_sensor;
- u16 data;
- u16 direction;
- u16 control;
-};
-
-
bool CartInserted;
u8* CartROM;
u32 CartROMSize;
@@ -503,6 +494,7 @@ void Reset() CartGPIO = {};
GBACart_SRAM::Reset();
+ GBACart_SolarSensor::Reset();
}
void DoSavestate(Savestate* file)
@@ -578,7 +570,7 @@ void WriteGPIO(u32 addr, u16 val) case 0xC4:
CartGPIO.data &= ~CartGPIO.direction;
CartGPIO.data |= val & CartGPIO.direction;
- // TODO: process pins
+ if (CartGPIO.has_solar_sensor) GBACart_SolarSensor::Process(&CartGPIO);
break;
case 0xC6:
CartGPIO.direction = val;
@@ -593,17 +585,60 @@ void WriteGPIO(u32 addr, u16 val) // write the GPIO values in the ROM (if writable)
if (CartGPIO.control & 1)
{
- *(u16*)&CartROM[addr] = CartGPIO.data;
- *(u16*)&CartROM[addr + 2] = CartGPIO.direction;
- *(u16*)&CartROM[addr + 4] = CartGPIO.control;
+ *(u16*)&CartROM[0xC4] = CartGPIO.data;
+ *(u16*)&CartROM[0xC6] = CartGPIO.direction;
+ *(u16*)&CartROM[0xC8] = CartGPIO.control;
}
else
{
// GBATEK: "in write-only mode, reads return 00h (or [possibly] other data (...))"
// ambiguous, but mGBA sets ROM to 00h when switching to write-only, so do the same
- *(u16*)&CartROM[addr] = 0;
- *(u16*)&CartROM[addr + 2] = 0;
- *(u16*)&CartROM[addr + 4] = 0;
+ *(u16*)&CartROM[0xC4] = 0;
+ *(u16*)&CartROM[0xC6] = 0;
+ *(u16*)&CartROM[0xC8] = 0;
+ }
+}
+
+}
+
+
+namespace GBACart_SolarSensor
+{
+
+bool LightEdge;
+u8 LightCounter;
+u8 LightSample;
+u8 LightLevel; // 0-10 range
+
+// levels from mGBA
+const int GBA_LUX_LEVELS[11] = { 0, 5, 11, 18, 27, 42, 62, 84, 109, 139, 183 };
+#define LIGHT_VALUE (0xFF - (0x16 + GBA_LUX_LEVELS[LightLevel]))
+
+
+void Reset()
+{
+ LightEdge = false;
+ LightCounter = 0;
+ LightSample = 0xFF;
+ LightLevel = 0;
+}
+
+void Process(GBACart::GPIO* gpio)
+{
+ if (gpio->data & 4) return; // Boktai chip select
+ if (gpio->data & 2) // Reset
+ {
+ LightCounter = 0;
+ LightSample = LIGHT_VALUE;
+ }
+ if (gpio->data & 1 && LightEdge) LightCounter++;
+
+ LightEdge = !(gpio->data & 1);
+
+ bool sendBit = LightCounter >= LightSample;
+ if (gpio->control & 1)
+ {
+ gpio->data = (gpio->data & gpio->direction) | ((sendBit << 3) & ~gpio->direction & 0xF);
}
}
diff --git a/src/GBACart.h b/src/GBACart.h index 22a3a60..32a2171 100644 --- a/src/GBACart.h +++ b/src/GBACart.h @@ -43,6 +43,14 @@ void Write32(u32 addr, u32 val); namespace GBACart
{
+struct GPIO
+{
+ bool has_solar_sensor;
+ u16 data;
+ u16 direction;
+ u16 control;
+};
+
extern bool CartInserted;
extern u8* CartROM;
extern u32 CartROMSize;
@@ -59,4 +67,15 @@ void WriteGPIO(u32 addr, u16 val); }
+
+namespace GBACart_SolarSensor
+{
+
+extern u8 LightLevel;
+
+void Reset();
+void Process(GBACart::GPIO* gpio);
+
+}
+
#endif // GBACART_H
|