mirror of
https://github.com/dborth/vbagx.git
synced 2025-02-16 18:59:12 +01:00
Carl Kenner's VBA-M changes
This commit is contained in:
parent
fde5171e0c
commit
29985288e6
@ -3552,7 +3552,7 @@ void CPULoop(int ticks)
|
|||||||
// read default joystick
|
// read default joystick
|
||||||
joy = systemReadJoypad(-1);
|
joy = systemReadJoypad(-1);
|
||||||
P1 = 0x03FF ^ (joy & 0x3FF);
|
P1 = 0x03FF ^ (joy & 0x3FF);
|
||||||
if(cpuEEPROMSensorEnabled)
|
//if(cpuEEPROMSensorEnabled)
|
||||||
systemUpdateMotionSensor();
|
systemUpdateMotionSensor();
|
||||||
UPDATE_REG(0x130, P1);
|
UPDATE_REG(0x130, P1);
|
||||||
u16 P1CNT = READ16LE(((u16 *)&ioMem[0x132]));
|
u16 P1CNT = READ16LE(((u16 *)&ioMem[0x132]));
|
||||||
|
@ -5,7 +5,8 @@ extern int armExecute();
|
|||||||
extern int thumbExecute();
|
extern int thumbExecute();
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
# define INSN_REGPARM __attribute__((regparm(1)))
|
# define INSN_REGPARM /*nothing*/
|
||||||
|
//# define INSN_REGPARM __attribute__((regparm(1)))
|
||||||
# define LIKELY(x) __builtin_expect(!!(x),1)
|
# define LIKELY(x) __builtin_expect(!!(x),1)
|
||||||
# define UNLIKELY(x) __builtin_expect(!!(x),0)
|
# define UNLIKELY(x) __builtin_expect(!!(x),0)
|
||||||
#else
|
#else
|
||||||
|
@ -52,10 +52,10 @@ u8 inline CPUReadByteQuick( u32 addr )
|
|||||||
{
|
{
|
||||||
switch(addr >> 24 )
|
switch(addr >> 24 )
|
||||||
{
|
{
|
||||||
case 8:
|
case 0x08:
|
||||||
case 9:
|
case 0x09:
|
||||||
case 10:
|
case 0x0A:
|
||||||
case 12:
|
case 0x0C:
|
||||||
#ifdef USE_VM
|
#ifdef USE_VM
|
||||||
return VMRead8( addr & 0x1FFFFFF );
|
return VMRead8( addr & 0x1FFFFFF );
|
||||||
#endif
|
#endif
|
||||||
@ -70,10 +70,10 @@ u16 inline CPUReadHalfWordQuick( u32 addr )
|
|||||||
{
|
{
|
||||||
switch(addr >> 24)
|
switch(addr >> 24)
|
||||||
{
|
{
|
||||||
case 8:
|
case 0x08:
|
||||||
case 9:
|
case 0x09:
|
||||||
case 10:
|
case 0x0A:
|
||||||
case 12:
|
case 0x0C:
|
||||||
#ifdef USE_VM
|
#ifdef USE_VM
|
||||||
return VMRead16( addr & 0x1FFFFFF );
|
return VMRead16( addr & 0x1FFFFFF );
|
||||||
#endif
|
#endif
|
||||||
@ -88,10 +88,10 @@ u32 inline CPUReadMemoryQuick( u32 addr )
|
|||||||
{
|
{
|
||||||
switch(addr >> 24)
|
switch(addr >> 24)
|
||||||
{
|
{
|
||||||
case 8:
|
case 0x08:
|
||||||
case 9:
|
case 0x09:
|
||||||
case 10:
|
case 0x0A:
|
||||||
case 12:
|
case 0x0C:
|
||||||
#ifdef USE_VM
|
#ifdef USE_VM
|
||||||
return VMRead32( addr & 0x1FFFFFF );
|
return VMRead32( addr & 0x1FFFFFF );
|
||||||
#endif
|
#endif
|
||||||
@ -119,7 +119,7 @@ static inline u32 CPUReadMemory(u32 address)
|
|||||||
|
|
||||||
u32 value;
|
u32 value;
|
||||||
switch(address >> 24) {
|
switch(address >> 24) {
|
||||||
case 0:
|
case 0x00:
|
||||||
if(reg[15].I >> 24) {
|
if(reg[15].I >> 24) {
|
||||||
if(address < 0x4000) {
|
if(address < 0x4000) {
|
||||||
#ifdef GBA_LOGGING
|
#ifdef GBA_LOGGING
|
||||||
@ -135,13 +135,13 @@ static inline u32 CPUReadMemory(u32 address)
|
|||||||
} else
|
} else
|
||||||
value = READ32LE(((u32 *)&bios[address & 0x3FFC]));
|
value = READ32LE(((u32 *)&bios[address & 0x3FFC]));
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 0x02:
|
||||||
value = READ32LE(((u32 *)&workRAM[address & 0x3FFFC]));
|
value = READ32LE(((u32 *)&workRAM[address & 0x3FFFC]));
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 0x03:
|
||||||
value = READ32LE(((u32 *)&internalRAM[address & 0x7ffC]));
|
value = READ32LE(((u32 *)&internalRAM[address & 0x7ffC]));
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 0x04:
|
||||||
if((address < 0x4000400) && ioReadable[address & 0x3fc]) {
|
if((address < 0x4000400) && ioReadable[address & 0x3fc]) {
|
||||||
if(ioReadable[(address & 0x3fc) + 2])
|
if(ioReadable[(address & 0x3fc) + 2])
|
||||||
value = READ32LE(((u32 *)&ioMem[address & 0x3fC]));
|
value = READ32LE(((u32 *)&ioMem[address & 0x3fC]));
|
||||||
@ -149,10 +149,10 @@ static inline u32 CPUReadMemory(u32 address)
|
|||||||
value = READ16LE(((u16 *)&ioMem[address & 0x3fc]));
|
value = READ16LE(((u16 *)&ioMem[address & 0x3fc]));
|
||||||
} else goto unreadable;
|
} else goto unreadable;
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 0x05:
|
||||||
value = READ32LE(((u32 *)&paletteRAM[address & 0x3fC]));
|
value = READ32LE(((u32 *)&paletteRAM[address & 0x3fC]));
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 0x06:
|
||||||
address = (address & 0x1fffc);
|
address = (address & 0x1fffc);
|
||||||
if (((DISPCNT & 7) >2) && ((address & 0x1C000) == 0x18000))
|
if (((DISPCNT & 7) >2) && ((address & 0x1C000) == 0x18000))
|
||||||
{
|
{
|
||||||
@ -163,26 +163,41 @@ static inline u32 CPUReadMemory(u32 address)
|
|||||||
address &= 0x17fff;
|
address &= 0x17fff;
|
||||||
value = READ32LE(((u32 *)&vram[address]));
|
value = READ32LE(((u32 *)&vram[address]));
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 0x07:
|
||||||
value = READ32LE(((u32 *)&oam[address & 0x3FC]));
|
value = READ32LE(((u32 *)&oam[address & 0x3FC]));
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 0x08:
|
||||||
case 9:
|
// Must be cartridge ROM, reading other sensors doesn't allow 32-bit access.
|
||||||
case 10:
|
case 0x09:
|
||||||
case 11:
|
case 0x0A:
|
||||||
case 12:
|
case 0x0B:
|
||||||
|
case 0x0C:
|
||||||
#ifdef USE_VM // Nintendo GC Virtual Memory
|
#ifdef USE_VM // Nintendo GC Virtual Memory
|
||||||
value = VMRead32( address & 0x1FFFFFC );
|
value = VMRead32( address & 0x1FFFFFC );
|
||||||
#else
|
#else
|
||||||
value = READ32LE(((u32 *)&rom[address&0x1FFFFFC]));
|
value = READ32LE(((u32 *)&rom[address&0x1FFFFFC]));
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case 13:
|
case 0x0D:
|
||||||
if(cpuEEPROMEnabled)
|
if(cpuEEPROMEnabled)
|
||||||
// no need to swap this
|
// no need to swap this
|
||||||
return eepromRead(address);
|
return eepromRead(address);
|
||||||
goto unreadable;
|
goto unreadable;
|
||||||
case 14:
|
case 0x0E:
|
||||||
|
// Yoshi's Universal Gravitation (Topsy Turvy)
|
||||||
|
// Koro Koro
|
||||||
|
if(cpuEEPROMSensorEnabled) {
|
||||||
|
switch(address & 0x00008f00) {
|
||||||
|
case 0x8200:
|
||||||
|
return systemGetSensorX() & 255;
|
||||||
|
case 0x8300:
|
||||||
|
return (systemGetSensorX() >> 8)|0x80;
|
||||||
|
case 0x8400:
|
||||||
|
return systemGetSensorY() & 255;
|
||||||
|
case 0x8500:
|
||||||
|
return systemGetSensorY() >> 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
if(cpuFlashEnabled | cpuSramEnabled)
|
if(cpuFlashEnabled | cpuSramEnabled)
|
||||||
// no need to swap this
|
// no need to swap this
|
||||||
return flashRead(address);
|
return flashRead(address);
|
||||||
@ -257,7 +272,7 @@ static inline u32 CPUReadHalfWord(u32 address)
|
|||||||
u32 value;
|
u32 value;
|
||||||
|
|
||||||
switch(address >> 24) {
|
switch(address >> 24) {
|
||||||
case 0:
|
case 0x00:
|
||||||
if (reg[15].I >> 24) {
|
if (reg[15].I >> 24) {
|
||||||
if(address < 0x4000) {
|
if(address < 0x4000) {
|
||||||
#ifdef GBA_LOGGING
|
#ifdef GBA_LOGGING
|
||||||
@ -271,13 +286,13 @@ static inline u32 CPUReadHalfWord(u32 address)
|
|||||||
} else
|
} else
|
||||||
value = READ16LE(((u16 *)&bios[address & 0x3FFE]));
|
value = READ16LE(((u16 *)&bios[address & 0x3FFE]));
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 0x02:
|
||||||
value = READ16LE(((u16 *)&workRAM[address & 0x3FFFE]));
|
value = READ16LE(((u16 *)&workRAM[address & 0x3FFFE]));
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 0x03:
|
||||||
value = READ16LE(((u16 *)&internalRAM[address & 0x7ffe]));
|
value = READ16LE(((u16 *)&internalRAM[address & 0x7ffe]));
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 0x04:
|
||||||
if((address < 0x4000400) && ioReadable[address & 0x3fe])
|
if((address < 0x4000400) && ioReadable[address & 0x3fe])
|
||||||
{
|
{
|
||||||
value = READ16LE(((u16 *)&ioMem[address & 0x3fe]));
|
value = READ16LE(((u16 *)&ioMem[address & 0x3fe]));
|
||||||
@ -298,10 +313,10 @@ static inline u32 CPUReadHalfWord(u32 address)
|
|||||||
}
|
}
|
||||||
else goto unreadable;
|
else goto unreadable;
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 0x05:
|
||||||
value = READ16LE(((u16 *)&paletteRAM[address & 0x3fe]));
|
value = READ16LE(((u16 *)&paletteRAM[address & 0x3fe]));
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 0x06:
|
||||||
address = (address & 0x1fffe);
|
address = (address & 0x1fffe);
|
||||||
if (((DISPCNT & 7) >2) && ((address & 0x1C000) == 0x18000))
|
if (((DISPCNT & 7) >2) && ((address & 0x1C000) == 0x18000))
|
||||||
{
|
{
|
||||||
@ -312,29 +327,49 @@ static inline u32 CPUReadHalfWord(u32 address)
|
|||||||
address &= 0x17fff;
|
address &= 0x17fff;
|
||||||
value = READ16LE(((u16 *)&vram[address]));
|
value = READ16LE(((u16 *)&vram[address]));
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 0x07:
|
||||||
value = READ16LE(((u16 *)&oam[address & 0x3fe]));
|
value = READ16LE(((u16 *)&oam[address & 0x3fe]));
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 0x08:
|
||||||
case 9:
|
// Use existing case statement and faster test for potential speed improvement
|
||||||
case 10:
|
// This is possibly the GPIO port that controls the real time clock,
|
||||||
case 11:
|
// WarioWare Twisted! tilt sensors, rumble, and solar sensors.
|
||||||
case 12:
|
if(address >= 0x80000c4 && address <= 0x80000c8) {
|
||||||
if(address == 0x80000c4 || address == 0x80000c6 || address == 0x80000c8)
|
// this function still works if there is no real time clock
|
||||||
value = rtcRead(address);
|
// and does a normal memory read in that case.
|
||||||
else
|
value = rtcRead(address & 0xFFFFFFE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x09:
|
||||||
|
case 0x0A:
|
||||||
|
case 0x0B:
|
||||||
|
case 0x0C:
|
||||||
#ifdef USE_VM // Nintendo GC Virtual Memory
|
#ifdef USE_VM // Nintendo GC Virtual Memory
|
||||||
value = VMRead16( address & 0x1FFFFFE );
|
value = VMRead16( address & 0x1FFFFFE );
|
||||||
#else
|
#else
|
||||||
value = READ16LE(((u16 *)&rom[address & 0x1FFFFFE]));
|
value = READ16LE(((u16 *)&rom[address & 0x1FFFFFE]));
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case 13:
|
case 0x0D:
|
||||||
if(cpuEEPROMEnabled)
|
if(cpuEEPROMEnabled)
|
||||||
// no need to swap this
|
// no need to swap this
|
||||||
return eepromRead(address);
|
return eepromRead(address);
|
||||||
goto unreadable;
|
goto unreadable;
|
||||||
case 14:
|
case 0x0E:
|
||||||
|
// Yoshi's Universal Gravitation (Topsy Turvy)
|
||||||
|
// Koro Koro
|
||||||
|
if(cpuEEPROMSensorEnabled) {
|
||||||
|
switch(address & 0x00008f00) {
|
||||||
|
case 0x8200:
|
||||||
|
return systemGetSensorX() & 255;
|
||||||
|
case 0x8300:
|
||||||
|
return (systemGetSensorX() >> 8)|0x80;
|
||||||
|
case 0x8400:
|
||||||
|
return systemGetSensorY() & 255;
|
||||||
|
case 0x8500:
|
||||||
|
return systemGetSensorY() >> 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
if(cpuFlashEnabled | cpuSramEnabled)
|
if(cpuFlashEnabled | cpuSramEnabled)
|
||||||
// no need to swap this
|
// no need to swap this
|
||||||
return flashRead(address);
|
return flashRead(address);
|
||||||
@ -385,7 +420,7 @@ static inline u16 CPUReadHalfWordSigned(u32 address)
|
|||||||
static inline u8 CPUReadByte(u32 address)
|
static inline u8 CPUReadByte(u32 address)
|
||||||
{
|
{
|
||||||
switch(address >> 24) {
|
switch(address >> 24) {
|
||||||
case 0:
|
case 0x00:
|
||||||
if (reg[15].I >> 24) {
|
if (reg[15].I >> 24) {
|
||||||
if(address < 0x4000) {
|
if(address < 0x4000) {
|
||||||
#ifdef GBA_LOGGING
|
#ifdef GBA_LOGGING
|
||||||
@ -398,42 +433,43 @@ static inline u8 CPUReadByte(u32 address)
|
|||||||
} else goto unreadable;
|
} else goto unreadable;
|
||||||
}
|
}
|
||||||
return bios[address & 0x3FFF];
|
return bios[address & 0x3FFF];
|
||||||
case 2:
|
case 0x02:
|
||||||
return workRAM[address & 0x3FFFF];
|
return workRAM[address & 0x3FFFF];
|
||||||
case 3:
|
case 0x03:
|
||||||
return internalRAM[address & 0x7fff];
|
return internalRAM[address & 0x7fff];
|
||||||
case 4:
|
case 0x04:
|
||||||
if((address < 0x4000400) && ioReadable[address & 0x3ff])
|
if((address < 0x4000400) && ioReadable[address & 0x3ff])
|
||||||
return ioMem[address & 0x3ff];
|
return ioMem[address & 0x3ff];
|
||||||
else goto unreadable;
|
else goto unreadable;
|
||||||
case 5:
|
case 0x05:
|
||||||
return paletteRAM[address & 0x3ff];
|
return paletteRAM[address & 0x3ff];
|
||||||
case 6:
|
case 0x06:
|
||||||
address = (address & 0x1ffff);
|
address = (address & 0x1ffff);
|
||||||
if (((DISPCNT & 7) >2) && ((address & 0x1C000) == 0x18000))
|
if (((DISPCNT & 7) >2) && ((address & 0x1C000) == 0x18000))
|
||||||
return 0;
|
return 0;
|
||||||
if ((address & 0x18000) == 0x18000)
|
if ((address & 0x18000) == 0x18000)
|
||||||
address &= 0x17fff;
|
address &= 0x17fff;
|
||||||
return vram[address];
|
return vram[address];
|
||||||
case 7:
|
case 0x07:
|
||||||
return oam[address & 0x3ff];
|
return oam[address & 0x3ff];
|
||||||
case 8:
|
case 0x08:
|
||||||
case 9:
|
// the real time clock doesn't support byte reads, so don't bother checking for it.
|
||||||
case 10:
|
case 0x09:
|
||||||
case 11:
|
case 0x0A:
|
||||||
case 12:
|
case 0x0B:
|
||||||
|
case 0x0C:
|
||||||
#ifdef USE_VM // Nintendo GC Virtual Memory
|
#ifdef USE_VM // Nintendo GC Virtual Memory
|
||||||
return VMRead8( address & 0x1FFFFFF );
|
return VMRead8( address & 0x1FFFFFF );
|
||||||
#else
|
#else
|
||||||
return rom[address & 0x1FFFFFF];
|
return rom[address & 0x1FFFFFF];
|
||||||
#endif
|
#endif
|
||||||
case 13:
|
case 0x0D:
|
||||||
if(cpuEEPROMEnabled)
|
if(cpuEEPROMEnabled)
|
||||||
return eepromRead(address);
|
return eepromRead(address);
|
||||||
goto unreadable;
|
goto unreadable;
|
||||||
case 14:
|
case 0x0E:
|
||||||
if(cpuSramEnabled | cpuFlashEnabled)
|
// Yoshi's Universal Gravitation (Topsy Turvy)
|
||||||
return flashRead(address);
|
// Koro Koro
|
||||||
if(cpuEEPROMSensorEnabled) {
|
if(cpuEEPROMSensorEnabled) {
|
||||||
switch(address & 0x00008f00) {
|
switch(address & 0x00008f00) {
|
||||||
case 0x8200:
|
case 0x8200:
|
||||||
@ -446,6 +482,8 @@ static inline u8 CPUReadByte(u32 address)
|
|||||||
return systemGetSensorY() >> 8;
|
return systemGetSensorY() >> 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(cpuSramEnabled | cpuFlashEnabled)
|
||||||
|
return flashRead(address);
|
||||||
// default
|
// default
|
||||||
default:
|
default:
|
||||||
unreadable:
|
unreadable:
|
||||||
|
@ -1,3 +1,11 @@
|
|||||||
|
/*
|
||||||
|
Mode 0 is the tiled graphics mode, with all the layers available.
|
||||||
|
There is no rotation or scaling in this mode.
|
||||||
|
It can be either 16 colours (with 16 different palettes) or 256 colours.
|
||||||
|
There are 1024 tiles available.
|
||||||
|
|
||||||
|
These routines only render a single line at a time, because of the way the GBA does events.
|
||||||
|
*/
|
||||||
#include "GBA.h"
|
#include "GBA.h"
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "GBAGfx.h"
|
#include "GBAGfx.h"
|
||||||
|
@ -1,3 +1,12 @@
|
|||||||
|
/*
|
||||||
|
Mode 1 is a tiled graphics mode, but with background layer 2 supporting scaling and rotation.
|
||||||
|
There is no layer 3 in this mode.
|
||||||
|
Layers 0 and 1 can be either 16 colours (with 16 different palettes) or 256 colours.
|
||||||
|
There are 1024 tiles available.
|
||||||
|
Layer 2 is 256 colours and allows only 256 tiles.
|
||||||
|
|
||||||
|
These routines only render a single line at a time, because of the way the GBA does events.
|
||||||
|
*/
|
||||||
#include "GBA.h"
|
#include "GBA.h"
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "GBAGfx.h"
|
#include "GBAGfx.h"
|
||||||
|
@ -1,3 +1,11 @@
|
|||||||
|
/*
|
||||||
|
Mode 2 is a 256 colour tiled graphics mode which supports scaling and rotation.
|
||||||
|
There is no background layer 0 or 1 in this mode. Only background layers 2 and 3.
|
||||||
|
There are 256 tiles available.
|
||||||
|
It does not support flipping.
|
||||||
|
|
||||||
|
These routines only render a single line at a time, because of the way the GBA does events.
|
||||||
|
*/
|
||||||
#include "GBA.h"
|
#include "GBA.h"
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "GBAGfx.h"
|
#include "GBAGfx.h"
|
||||||
|
@ -1,3 +1,10 @@
|
|||||||
|
/*
|
||||||
|
Mode 3 is a 15-bit (32768) colour bitmap graphics mode.
|
||||||
|
It has a single layer, background layer 2, the same size as the screen.
|
||||||
|
It doesn't support paging, scrolling, flipping, rotation or tiles.
|
||||||
|
|
||||||
|
These routines only render a single line at a time, because of the way the GBA does events.
|
||||||
|
*/
|
||||||
#include "GBA.h"
|
#include "GBA.h"
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "GBAGfx.h"
|
#include "GBAGfx.h"
|
||||||
|
@ -1,3 +1,10 @@
|
|||||||
|
/*
|
||||||
|
Mode 4 is a 256 colour bitmap graphics mode with 2 swappable pages.
|
||||||
|
It has a single layer, background layer 2, the same size as the screen.
|
||||||
|
It doesn't support scrolling, flipping, rotation or tiles.
|
||||||
|
|
||||||
|
These routines only render a single line at a time, because of the way the GBA does events.
|
||||||
|
*/
|
||||||
#include "GBA.h"
|
#include "GBA.h"
|
||||||
#include "GBAGfx.h"
|
#include "GBAGfx.h"
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
|
@ -1,3 +1,11 @@
|
|||||||
|
/*
|
||||||
|
Mode 5 is a low resolution (160x128) 15-bit colour bitmap graphics mode
|
||||||
|
with 2 swappable pages!
|
||||||
|
It has a single layer, background layer 2, lower resolution than the screen.
|
||||||
|
It doesn't support scrolling, flipping, rotation or tiles.
|
||||||
|
|
||||||
|
These routines only render a single line at a time, because of the way the GBA does events.
|
||||||
|
*/
|
||||||
#include "GBA.h"
|
#include "GBA.h"
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "GBAGfx.h"
|
#include "GBAGfx.h"
|
||||||
|
@ -8,6 +8,10 @@
|
|||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
u8 systemGetSensorDarkness();
|
||||||
|
int systemGetSensorZ();
|
||||||
|
|
||||||
enum RTCSTATE { IDLE, COMMAND, DATA, READDATA };
|
enum RTCSTATE { IDLE, COMMAND, DATA, READDATA };
|
||||||
|
|
||||||
@ -29,6 +33,8 @@ typedef struct {
|
|||||||
static RTCCLOCKDATA rtcClockData;
|
static RTCCLOCKDATA rtcClockData;
|
||||||
static bool rtcEnabled = false;
|
static bool rtcEnabled = false;
|
||||||
|
|
||||||
|
int WarioRumbleMotor = 0;
|
||||||
|
|
||||||
void rtcEnable(bool e)
|
void rtcEnable(bool e)
|
||||||
{
|
{
|
||||||
rtcEnabled = e;
|
rtcEnabled = e;
|
||||||
@ -50,7 +56,26 @@ u16 rtcRead(u32 address)
|
|||||||
return rtcClockData.byte1;
|
return rtcClockData.byte1;
|
||||||
break;
|
break;
|
||||||
case 0x80000c4:
|
case 0x80000c4:
|
||||||
return rtcClockData.byte0;
|
|
||||||
|
// Boktai Solar Sensor
|
||||||
|
if (rtcClockData.byte1 == 7) {
|
||||||
|
if (rtcClockData.reserved[11] >= systemGetSensorDarkness()) {
|
||||||
|
rtcClockData.reserved[10] = 0;
|
||||||
|
rtcClockData.reserved[11] = 0;
|
||||||
|
return 8;
|
||||||
|
} else return 0;
|
||||||
|
|
||||||
|
// WarioWare Twisted Tilt Sensor
|
||||||
|
} else if (rtcClockData.byte1 == 0x0b) {
|
||||||
|
//sprintf(DebugStr, "Reading Twisted Sensor bit %d", rtcClockData.reserved[11]);
|
||||||
|
u16 v = systemGetSensorZ();
|
||||||
|
return ((v >> rtcClockData.reserved[11]) & 1) << 2;
|
||||||
|
|
||||||
|
// Real Time Clock
|
||||||
|
} else {
|
||||||
|
//sprintf(DebugStr, "Reading RTC %02x, %02x, %02x", rtcClockData.byte0, rtcClockData.byte1, rtcClockData.byte2);
|
||||||
|
return rtcClockData.byte0;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -75,12 +100,52 @@ bool rtcWrite(u32 address, u16 value)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(address == 0x80000c8) {
|
if(address == 0x80000c8) {
|
||||||
rtcClockData.byte2 = (u8)value; // enable ?
|
rtcClockData.byte2 = (u8)value; // bit 0 = enable reading from 0x80000c4 c6 and c8
|
||||||
} else if(address == 0x80000c6) {
|
} else if(address == 0x80000c6) {
|
||||||
rtcClockData.byte1 = (u8)value; // read/write
|
rtcClockData.byte1 = (u8)value; // 0=read/1=write (for each of 4 low bits)
|
||||||
} else if(address == 0x80000c4) {
|
if (!(value & 8)) WarioRumbleMotor = 0;
|
||||||
if(rtcClockData.byte2 & 1) {
|
} else if(address == 0x80000c4) { // 4 bits of I/O Port Data (upper bits not used)
|
||||||
if(rtcClockData.state == IDLE && rtcClockData.byte0 == 1 && value == 5) {
|
|
||||||
|
// WarioWare Twisted rumble
|
||||||
|
if(rtcClockData.byte1 & 8) {
|
||||||
|
WarioRumbleMotor = value & 8;
|
||||||
|
} else {
|
||||||
|
WarioRumbleMotor = 0; // rumble is off when not writing to that pin
|
||||||
|
}
|
||||||
|
|
||||||
|
// Boktai solar sensor
|
||||||
|
if (rtcClockData.byte1 == 7) {
|
||||||
|
if (value & 2) {
|
||||||
|
// reset counter to 0
|
||||||
|
rtcClockData.reserved[11]=0;
|
||||||
|
rtcClockData.reserved[10]=0;
|
||||||
|
}
|
||||||
|
if ((value & 1) && (!(rtcClockData.reserved[10] & 1))) {
|
||||||
|
// increase counter, ready to do another read
|
||||||
|
if (rtcClockData.reserved[11]<255) rtcClockData.reserved[11]++;
|
||||||
|
}
|
||||||
|
rtcClockData.reserved[10] = value & rtcClockData.byte1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// WarioWare Twisted rotation sensor
|
||||||
|
if (rtcClockData.byte1 == 0xb) {
|
||||||
|
if (value & 2) {
|
||||||
|
// clock goes high in preperation for reading a bit
|
||||||
|
rtcClockData.reserved[11]--;
|
||||||
|
}
|
||||||
|
if (value & 1) {
|
||||||
|
// start ADC conversion
|
||||||
|
rtcClockData.reserved[11] = 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
rtcClockData.byte0 = value & rtcClockData.byte1;
|
||||||
|
|
||||||
|
// Real Time Clock
|
||||||
|
}
|
||||||
|
/**/
|
||||||
|
|
||||||
|
if(rtcClockData.byte2 & 1) { // if reading is enabled
|
||||||
|
if(rtcClockData.state == IDLE && rtcClockData.byte0 == 1 && value == 5) {
|
||||||
rtcClockData.state = COMMAND;
|
rtcClockData.state = COMMAND;
|
||||||
rtcClockData.bits = 0;
|
rtcClockData.bits = 0;
|
||||||
rtcClockData.command = 0;
|
rtcClockData.command = 0;
|
||||||
@ -178,7 +243,7 @@ bool rtcWrite(u32 address, u16 value)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
@ -199,6 +264,7 @@ void rtcReset()
|
|||||||
rtcClockData.dataLen = 0;
|
rtcClockData.dataLen = 0;
|
||||||
rtcClockData.bits = 0;
|
rtcClockData.bits = 0;
|
||||||
rtcClockData.state = IDLE;
|
rtcClockData.state = IDLE;
|
||||||
|
rtcClockData.reserved[11] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtcSaveGame(gzFile gzFile)
|
void rtcSaveGame(gzFile gzFile)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user