Carl Kenner's VBA-M changes

This commit is contained in:
dborth 2009-03-04 06:53:25 +00:00
parent fde5171e0c
commit 29985288e6
10 changed files with 220 additions and 68 deletions

View File

@ -3552,7 +3552,7 @@ void CPULoop(int ticks)
// read default joystick
joy = systemReadJoypad(-1);
P1 = 0x03FF ^ (joy & 0x3FF);
if(cpuEEPROMSensorEnabled)
//if(cpuEEPROMSensorEnabled)
systemUpdateMotionSensor();
UPDATE_REG(0x130, P1);
u16 P1CNT = READ16LE(((u16 *)&ioMem[0x132]));

View File

@ -5,7 +5,8 @@ extern int armExecute();
extern int thumbExecute();
#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 UNLIKELY(x) __builtin_expect(!!(x),0)
#else

View File

@ -52,10 +52,10 @@ u8 inline CPUReadByteQuick( u32 addr )
{
switch(addr >> 24 )
{
case 8:
case 9:
case 10:
case 12:
case 0x08:
case 0x09:
case 0x0A:
case 0x0C:
#ifdef USE_VM
return VMRead8( addr & 0x1FFFFFF );
#endif
@ -70,10 +70,10 @@ u16 inline CPUReadHalfWordQuick( u32 addr )
{
switch(addr >> 24)
{
case 8:
case 9:
case 10:
case 12:
case 0x08:
case 0x09:
case 0x0A:
case 0x0C:
#ifdef USE_VM
return VMRead16( addr & 0x1FFFFFF );
#endif
@ -88,10 +88,10 @@ u32 inline CPUReadMemoryQuick( u32 addr )
{
switch(addr >> 24)
{
case 8:
case 9:
case 10:
case 12:
case 0x08:
case 0x09:
case 0x0A:
case 0x0C:
#ifdef USE_VM
return VMRead32( addr & 0x1FFFFFF );
#endif
@ -119,7 +119,7 @@ static inline u32 CPUReadMemory(u32 address)
u32 value;
switch(address >> 24) {
case 0:
case 0x00:
if(reg[15].I >> 24) {
if(address < 0x4000) {
#ifdef GBA_LOGGING
@ -135,13 +135,13 @@ static inline u32 CPUReadMemory(u32 address)
} else
value = READ32LE(((u32 *)&bios[address & 0x3FFC]));
break;
case 2:
case 0x02:
value = READ32LE(((u32 *)&workRAM[address & 0x3FFFC]));
break;
case 3:
case 0x03:
value = READ32LE(((u32 *)&internalRAM[address & 0x7ffC]));
break;
case 4:
case 0x04:
if((address < 0x4000400) && ioReadable[address & 0x3fc]) {
if(ioReadable[(address & 0x3fc) + 2])
value = READ32LE(((u32 *)&ioMem[address & 0x3fC]));
@ -149,10 +149,10 @@ static inline u32 CPUReadMemory(u32 address)
value = READ16LE(((u16 *)&ioMem[address & 0x3fc]));
} else goto unreadable;
break;
case 5:
case 0x05:
value = READ32LE(((u32 *)&paletteRAM[address & 0x3fC]));
break;
case 6:
case 0x06:
address = (address & 0x1fffc);
if (((DISPCNT & 7) >2) && ((address & 0x1C000) == 0x18000))
{
@ -163,26 +163,41 @@ static inline u32 CPUReadMemory(u32 address)
address &= 0x17fff;
value = READ32LE(((u32 *)&vram[address]));
break;
case 7:
case 0x07:
value = READ32LE(((u32 *)&oam[address & 0x3FC]));
break;
case 8:
case 9:
case 10:
case 11:
case 12:
case 0x08:
// Must be cartridge ROM, reading other sensors doesn't allow 32-bit access.
case 0x09:
case 0x0A:
case 0x0B:
case 0x0C:
#ifdef USE_VM // Nintendo GC Virtual Memory
value = VMRead32( address & 0x1FFFFFC );
#else
value = READ32LE(((u32 *)&rom[address&0x1FFFFFC]));
#endif
break;
case 13:
case 0x0D:
if(cpuEEPROMEnabled)
// no need to swap this
return eepromRead(address);
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)
// no need to swap this
return flashRead(address);
@ -257,7 +272,7 @@ static inline u32 CPUReadHalfWord(u32 address)
u32 value;
switch(address >> 24) {
case 0:
case 0x00:
if (reg[15].I >> 24) {
if(address < 0x4000) {
#ifdef GBA_LOGGING
@ -271,13 +286,13 @@ static inline u32 CPUReadHalfWord(u32 address)
} else
value = READ16LE(((u16 *)&bios[address & 0x3FFE]));
break;
case 2:
case 0x02:
value = READ16LE(((u16 *)&workRAM[address & 0x3FFFE]));
break;
case 3:
case 0x03:
value = READ16LE(((u16 *)&internalRAM[address & 0x7ffe]));
break;
case 4:
case 0x04:
if((address < 0x4000400) && ioReadable[address & 0x3fe])
{
value = READ16LE(((u16 *)&ioMem[address & 0x3fe]));
@ -298,10 +313,10 @@ static inline u32 CPUReadHalfWord(u32 address)
}
else goto unreadable;
break;
case 5:
case 0x05:
value = READ16LE(((u16 *)&paletteRAM[address & 0x3fe]));
break;
case 6:
case 0x06:
address = (address & 0x1fffe);
if (((DISPCNT & 7) >2) && ((address & 0x1C000) == 0x18000))
{
@ -312,29 +327,49 @@ static inline u32 CPUReadHalfWord(u32 address)
address &= 0x17fff;
value = READ16LE(((u16 *)&vram[address]));
break;
case 7:
case 0x07:
value = READ16LE(((u16 *)&oam[address & 0x3fe]));
break;
case 8:
case 9:
case 10:
case 11:
case 12:
if(address == 0x80000c4 || address == 0x80000c6 || address == 0x80000c8)
value = rtcRead(address);
else
case 0x08:
// Use existing case statement and faster test for potential speed improvement
// This is possibly the GPIO port that controls the real time clock,
// WarioWare Twisted! tilt sensors, rumble, and solar sensors.
if(address >= 0x80000c4 && address <= 0x80000c8) {
// this function still works if there is no real time clock
// and does a normal memory read in that case.
value = rtcRead(address & 0xFFFFFFE);
break;
}
case 0x09:
case 0x0A:
case 0x0B:
case 0x0C:
#ifdef USE_VM // Nintendo GC Virtual Memory
value = VMRead16( address & 0x1FFFFFE );
#else
value = READ16LE(((u16 *)&rom[address & 0x1FFFFFE]));
#endif
break;
case 13:
case 0x0D:
if(cpuEEPROMEnabled)
// no need to swap this
return eepromRead(address);
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)
// no need to swap this
return flashRead(address);
@ -385,7 +420,7 @@ static inline u16 CPUReadHalfWordSigned(u32 address)
static inline u8 CPUReadByte(u32 address)
{
switch(address >> 24) {
case 0:
case 0x00:
if (reg[15].I >> 24) {
if(address < 0x4000) {
#ifdef GBA_LOGGING
@ -398,42 +433,43 @@ static inline u8 CPUReadByte(u32 address)
} else goto unreadable;
}
return bios[address & 0x3FFF];
case 2:
case 0x02:
return workRAM[address & 0x3FFFF];
case 3:
case 0x03:
return internalRAM[address & 0x7fff];
case 4:
case 0x04:
if((address < 0x4000400) && ioReadable[address & 0x3ff])
return ioMem[address & 0x3ff];
else goto unreadable;
case 5:
case 0x05:
return paletteRAM[address & 0x3ff];
case 6:
case 0x06:
address = (address & 0x1ffff);
if (((DISPCNT & 7) >2) && ((address & 0x1C000) == 0x18000))
return 0;
if ((address & 0x18000) == 0x18000)
address &= 0x17fff;
return vram[address];
case 7:
case 0x07:
return oam[address & 0x3ff];
case 8:
case 9:
case 10:
case 11:
case 12:
case 0x08:
// the real time clock doesn't support byte reads, so don't bother checking for it.
case 0x09:
case 0x0A:
case 0x0B:
case 0x0C:
#ifdef USE_VM // Nintendo GC Virtual Memory
return VMRead8( address & 0x1FFFFFF );
#else
return rom[address & 0x1FFFFFF];
#endif
case 13:
case 0x0D:
if(cpuEEPROMEnabled)
return eepromRead(address);
goto unreadable;
case 14:
if(cpuSramEnabled | cpuFlashEnabled)
return flashRead(address);
case 0x0E:
// Yoshi's Universal Gravitation (Topsy Turvy)
// Koro Koro
if(cpuEEPROMSensorEnabled) {
switch(address & 0x00008f00) {
case 0x8200:
@ -446,6 +482,8 @@ static inline u8 CPUReadByte(u32 address)
return systemGetSensorY() >> 8;
}
}
if(cpuSramEnabled | cpuFlashEnabled)
return flashRead(address);
// default
default:
unreadable:

View File

@ -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 "Globals.h"
#include "GBAGfx.h"

View File

@ -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 "Globals.h"
#include "GBAGfx.h"

View File

@ -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 "Globals.h"
#include "GBAGfx.h"

View File

@ -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 "Globals.h"
#include "GBAGfx.h"

View File

@ -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 "GBAGfx.h"
#include "Globals.h"

View File

@ -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 "Globals.h"
#include "GBAGfx.h"

View File

@ -8,6 +8,10 @@
#include <time.h>
#include <string.h>
#include <stdio.h>
u8 systemGetSensorDarkness();
int systemGetSensorZ();
enum RTCSTATE { IDLE, COMMAND, DATA, READDATA };
@ -29,6 +33,8 @@ typedef struct {
static RTCCLOCKDATA rtcClockData;
static bool rtcEnabled = false;
int WarioRumbleMotor = 0;
void rtcEnable(bool e)
{
rtcEnabled = e;
@ -50,7 +56,26 @@ u16 rtcRead(u32 address)
return rtcClockData.byte1;
break;
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;
}
}
@ -75,12 +100,52 @@ bool rtcWrite(u32 address, u16 value)
return false;
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) {
rtcClockData.byte1 = (u8)value; // read/write
} else if(address == 0x80000c4) {
if(rtcClockData.byte2 & 1) {
if(rtcClockData.state == IDLE && rtcClockData.byte0 == 1 && value == 5) {
rtcClockData.byte1 = (u8)value; // 0=read/1=write (for each of 4 low bits)
if (!(value & 8)) WarioRumbleMotor = 0;
} else if(address == 0x80000c4) { // 4 bits of I/O Port Data (upper bits not used)
// 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.bits = 0;
rtcClockData.command = 0;
@ -178,7 +243,7 @@ bool rtcWrite(u32 address, u16 value)
}
}
break;
default:
default:
break;
}
} else
@ -199,6 +264,7 @@ void rtcReset()
rtcClockData.dataLen = 0;
rtcClockData.bits = 0;
rtcClockData.state = IDLE;
rtcClockData.reserved[11] = 0;
}
void rtcSaveGame(gzFile gzFile)