some more formating things etc

This commit is contained in:
Zach Bacon 2016-07-09 09:53:13 -04:00
parent a49edee427
commit 48086ba62f
No known key found for this signature in database
GPG Key ID: 7D110798AFE84B3A
16 changed files with 8443 additions and 9028 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,16 +1,16 @@
#include <string.h> #include <ctype.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <ctype.h> #include <string.h>
#include "../System.h"
#include "../NLS.h" #include "../NLS.h"
#include "../System.h"
#include "../Util.h" #include "../Util.h"
#include "../common/ConfigManager.h"
#include "gb.h"
#include "gbCheats.h" #include "gbCheats.h"
#include "gbGlobals.h" #include "gbGlobals.h"
#include "gb.h"
#include "../common/ConfigManager.h"
gbCheat gbCheatList[MAX_CHEATS]; gbCheat gbCheatList[MAX_CHEATS];
int gbCheatNumber = 0; int gbCheatNumber = 0;
@ -72,7 +72,6 @@ void gbCheatsReadGame(gzFile gzFile, int version)
gbCheatUpdateMap(); gbCheatUpdateMap();
} }
void gbCheatsReadGameSkip(gzFile gzFile, int version) void gbCheatsReadGameSkip(gzFile gzFile, int version)
{ {
if (version <= 8) { if (version <= 8) {
@ -100,7 +99,6 @@ void gbCheatsReadGameSkip(gzFile gzFile, int version)
} }
} }
void gbCheatsSaveCheatList(const char* file) void gbCheatsSaveCheatList(const char* file)
{ {
if (gbCheatNumber == 0) if (gbCheatNumber == 0)
@ -214,16 +212,11 @@ bool gbAddGsCheat(const char *code, const char *desc)
strcpy(gbCheatList[i].cheatCode, code); strcpy(gbCheatList[i].cheatCode, code);
strcpy(gbCheatList[i].cheatDesc, desc); strcpy(gbCheatList[i].cheatDesc, desc);
gbCheatList[i].code = GBCHEAT_HEX_VALUE(code[0]) << 4 | gbCheatList[i].code = GBCHEAT_HEX_VALUE(code[0]) << 4 | GBCHEAT_HEX_VALUE(code[1]);
GBCHEAT_HEX_VALUE(code[1]);
gbCheatList[i].value = GBCHEAT_HEX_VALUE(code[2]) << 4 | gbCheatList[i].value = GBCHEAT_HEX_VALUE(code[2]) << 4 | GBCHEAT_HEX_VALUE(code[3]);
GBCHEAT_HEX_VALUE(code[3]);
gbCheatList[i].address = GBCHEAT_HEX_VALUE(code[6]) << 12 | gbCheatList[i].address = GBCHEAT_HEX_VALUE(code[6]) << 12 | GBCHEAT_HEX_VALUE(code[7]) << 8 | GBCHEAT_HEX_VALUE(code[4]) << 4 | GBCHEAT_HEX_VALUE(code[5]);
GBCHEAT_HEX_VALUE(code[7]) << 8 |
GBCHEAT_HEX_VALUE(code[4]) << 4 |
GBCHEAT_HEX_VALUE(code[5]);
gbCheatList[i].compare = 0; gbCheatList[i].compare = 0;
@ -231,8 +224,7 @@ bool gbAddGsCheat(const char *code, const char *desc)
int gsCode = gbCheatList[i].code; int gsCode = gbCheatList[i].code;
if ((gsCode !=1) && ((gsCode & 0xF0) !=0x80) && ((gsCode & 0xF0) !=0x90) && if ((gsCode != 1) && ((gsCode & 0xF0) != 0x80) && ((gsCode & 0xF0) != 0x90) && ((gsCode & 0xF0) != 0xA0) && ((gsCode) != 0xF0) && ((gsCode) != 0xF1))
((gsCode & 0xF0) !=0xA0) && ((gsCode) !=0xF0) && ((gsCode) !=0xF1))
systemMessage(MSG_WRONG_GAMESHARK_CODE, systemMessage(MSG_WRONG_GAMESHARK_CODE,
N_("Wrong GameShark code type : %s"), code); N_("Wrong GameShark code type : %s"), code);
else if (((gsCode & 0xF0) == 0xA0) || ((gsCode) == 0xF0) || ((gsCode) == 0xF1)) else if (((gsCode & 0xF0) == 0xA0) || ((gsCode) == 0xF0) || ((gsCode) == 0xF1))
@ -248,10 +240,7 @@ bool gbVerifyGgCode(const char *code)
{ {
size_t len = strlen(code); size_t len = strlen(code);
if(len != 11 && if (len != 11 && len != 7 && len != 6 && len != 0)
len != 7 &&
len != 6 &&
len != 0)
return false; return false;
if (len == 0) if (len == 0)
@ -287,10 +276,7 @@ bool gbVerifyGgCode(const char *code)
// int replace = (GBCHEAT_HEX_VALUE(code[0]) << 4) + // int replace = (GBCHEAT_HEX_VALUE(code[0]) << 4) +
// GBCHEAT_HEX_VALUE(code[1]); // GBCHEAT_HEX_VALUE(code[1]);
int address = (GBCHEAT_HEX_VALUE(code[2]) << 8) + int address = (GBCHEAT_HEX_VALUE(code[2]) << 8) + (GBCHEAT_HEX_VALUE(code[4]) << 4) + (GBCHEAT_HEX_VALUE(code[5])) + ((GBCHEAT_HEX_VALUE(code[6]) ^ 0x0f) << 12);
(GBCHEAT_HEX_VALUE(code[4]) << 4) +
(GBCHEAT_HEX_VALUE(code[5])) +
((GBCHEAT_HEX_VALUE(code[6]) ^ 0x0f) << 12);
if (address >= 0x8000 && address <= 0x9fff) if (address >= 0x8000 && address <= 0x9fff)
return false; return false;
@ -301,8 +287,7 @@ bool gbVerifyGgCode(const char *code)
if (code[7] == 0 || code[8] == '0') if (code[7] == 0 || code[8] == '0')
return true; return true;
int compare = (GBCHEAT_HEX_VALUE(code[8]) << 4) + int compare = (GBCHEAT_HEX_VALUE(code[8]) << 4) + (GBCHEAT_HEX_VALUE(code[10]));
(GBCHEAT_HEX_VALUE(code[10]));
compare = compare ^ 0xff; compare = compare ^ 0xff;
compare = (compare >> 2) | ((compare << 6) & 0xc0); compare = (compare >> 2) | ((compare << 6) & 0xc0);
compare ^= 0x45; compare ^= 0x45;
@ -337,20 +322,15 @@ bool gbAddGgCheat(const char *code, const char *desc)
strcpy(gbCheatList[i].cheatDesc, desc); strcpy(gbCheatList[i].cheatDesc, desc);
gbCheatList[i].code = 0x101; gbCheatList[i].code = 0x101;
gbCheatList[i].value = (GBCHEAT_HEX_VALUE(code[0]) << 4) + gbCheatList[i].value = (GBCHEAT_HEX_VALUE(code[0]) << 4) + GBCHEAT_HEX_VALUE(code[1]);
GBCHEAT_HEX_VALUE(code[1]);
gbCheatList[i].address = (GBCHEAT_HEX_VALUE(code[2]) << 8) + gbCheatList[i].address = (GBCHEAT_HEX_VALUE(code[2]) << 8) + (GBCHEAT_HEX_VALUE(code[4]) << 4) + (GBCHEAT_HEX_VALUE(code[5])) + ((GBCHEAT_HEX_VALUE(code[6]) ^ 0x0f) << 12);
(GBCHEAT_HEX_VALUE(code[4]) << 4) +
(GBCHEAT_HEX_VALUE(code[5])) +
((GBCHEAT_HEX_VALUE(code[6]) ^ 0x0f) << 12);
gbCheatList[i].compare = 0; gbCheatList[i].compare = 0;
if (len != 7 && len != 8) { if (len != 7 && len != 8) {
int compare = (GBCHEAT_HEX_VALUE(code[8]) << 4) + int compare = (GBCHEAT_HEX_VALUE(code[8]) << 4) + (GBCHEAT_HEX_VALUE(code[10]));
(GBCHEAT_HEX_VALUE(code[10]));
compare = compare ^ 0xff; compare = compare ^ 0xff;
compare = (compare >> 2) | ((compare << 6) & 0xc0); compare = (compare >> 2) | ((compare << 6) & 0xc0);
compare ^= 0x45; compare ^= 0x45;
@ -358,10 +338,8 @@ bool gbAddGgCheat(const char *code, const char *desc)
gbCheatList[i].compare = compare; gbCheatList[i].compare = compare;
//gbCheatList[i].code = 0; //gbCheatList[i].code = 0;
gbCheatList[i].code = 0x100; // fix for compare value gbCheatList[i].code = 0x100; // fix for compare value
} }
gbCheatList[i].enabled = true; gbCheatList[i].enabled = true;
gbCheatMap[gbCheatList[i].address] = true; gbCheatMap[gbCheatList[i].address] = true;
@ -380,8 +358,7 @@ void gbCheatRemove(int i)
} }
if ((i + 1) < gbCheatNumber) { if ((i + 1) < gbCheatNumber) {
memcpy(&gbCheatList[i], &gbCheatList[i+1], sizeof(gbCheat)* memcpy(&gbCheatList[i], &gbCheatList[i + 1], sizeof(gbCheat) * (gbCheatNumber - i - 1));
(gbCheatNumber-i-1));
} }
gbCheatNumber--; gbCheatNumber--;
@ -449,7 +426,7 @@ bool gbCheatReadGSCodeFile(const char *fileName)
} }
// Used to emulated GG codes // Used to emulated GG codes
u8 gbCheatRead(u16 address) uint8_t gbCheatRead(uint16_t address)
{ {
if (!cheatsEnabled) if (!cheatsEnabled)
return gbMemoryMap[address >> 12][address & 0xFFF]; return gbMemoryMap[address >> 12][address & 0xFFF];
@ -470,12 +447,10 @@ u8 gbCheatRead(u16 address)
return gbMemoryMap[address >> 12][address & 0xFFF]; return gbMemoryMap[address >> 12][address & 0xFFF];
} }
// Used to emulate GS codes. // Used to emulate GS codes.
void gbCheatWrite(bool reboot) void gbCheatWrite(bool reboot)
{ {
if(cheatsEnabled) if (cheatsEnabled) {
{
u16 address = 0; u16 address = 0;
if (gbNextCheat >= gbCheatNumber) if (gbNextCheat >= gbCheatNumber)
@ -484,8 +459,7 @@ void gbCheatWrite(bool reboot)
for (int i = gbNextCheat; i < gbCheatNumber; i++) { for (int i = gbNextCheat; i < gbCheatNumber; i++) {
if (gbCheatList[i].enabled) { if (gbCheatList[i].enabled) {
address = gbCheatList[i].address; address = gbCheatList[i].address;
if ((!reboot) && (address >= 0x8000) && !((address>=0xA000) && (address<0xC000))) if ((!reboot) && (address >= 0x8000) && !((address >= 0xA000) && (address < 0xC000))) { // These codes are executed one per one, at each Vblank
{ // These codes are executed one per one, at each Vblank
switch (gbCheatList[i].code) { switch (gbCheatList[i].code) {
case 0x01: case 0x01:
gbWriteMemory(address, gbCheatList[i].value); gbWriteMemory(address, gbCheatList[i].value);
@ -514,8 +488,7 @@ void gbCheatWrite(bool reboot)
gbNextCheat = i + 1; gbNextCheat = i + 1;
return; return;
} }
} } else // These codes are only executed when the game is booted
else // These codes are only executed when the game is booted
{ {
switch (gbCheatList[i].code & 0xF0) { switch (gbCheatList[i].code & 0xF0) {
case 0x80: case 0x80:

View File

@ -12,10 +12,10 @@ struct gbXxCheat {
struct gbCheat { struct gbCheat {
char cheatCode[20]; char cheatCode[20];
char cheatDesc[32]; char cheatDesc[32];
u16 address; uint16_t address;
int code; int code;
u8 compare; uint8_t compare;
u8 value; uint8_t value;
bool enabled; bool enabled;
}; };
@ -32,7 +32,7 @@ void gbCheatRemove(int);
void gbCheatRemoveAll(); void gbCheatRemoveAll();
void gbCheatEnable(int); void gbCheatEnable(int);
void gbCheatDisable(int); void gbCheatDisable(int);
u8 gbCheatRead(u16); uint8_t gbCheatRead(u16);
void gbCheatWrite(bool); void gbCheatWrite(bool);
bool gbVerifyGsCode(const char* code); bool gbVerifyGsCode(const char* code);
bool gbVerifyGgCode(const char* code); bool gbVerifyGgCode(const char* code);

View File

@ -22,8 +22,7 @@ break;
case 0x05: case 0x05:
// DEC B // DEC B
BC.B.B1--; BC.B.B1--;
AF.B.B0 = AF.B.B0 = N_FLAG | (AF.B.B0 & C_FLAG) | ZeroTable[BC.B.B1] | ((BC.B.B1 & 0x0F) == 0x0F ? H_FLAG : 0);
N_FLAG | (AF.B.B0 & C_FLAG) | ZeroTable[BC.B.B1] | ((BC.B.B1 & 0x0F) == 0x0F ? H_FLAG : 0);
break; break;
case 0x06: case 0x06:
// LD B, NN // LD B, NN
@ -45,8 +44,7 @@ break;
case 0x09: case 0x09:
// ADD HL,BC // ADD HL,BC
tempRegister.W = (HL.W + BC.W) & 0xFFFF; tempRegister.W = (HL.W + BC.W) & 0xFFFF;
AF.B.B0 = (AF.B.B0 & Z_FLAG) | ((HL.W ^ BC.W ^ tempRegister.W) & 0x1000 ? H_FLAG : 0) | AF.B.B0 = (AF.B.B0 & Z_FLAG) | ((HL.W ^ BC.W ^ tempRegister.W) & 0x1000 ? H_FLAG : 0) | (((long)HL.W + (long)BC.W) & 0x10000 ? C_FLAG : 0);
(((long)HL.W + (long)BC.W) & 0x10000 ? C_FLAG : 0);
HL.W = tempRegister.W; HL.W = tempRegister.W;
break; break;
case 0x0a: case 0x0a:
@ -65,8 +63,7 @@ break;
case 0x0d: case 0x0d:
// DEC C // DEC C
BC.B.B0--; BC.B.B0--;
AF.B.B0 = AF.B.B0 = N_FLAG | (AF.B.B0 & C_FLAG) | ZeroTable[BC.B.B0] | ((BC.B.B0 & 0x0F) == 0x0F ? H_FLAG : 0);
N_FLAG | (AF.B.B0 & C_FLAG) | ZeroTable[BC.B.B0] | ((BC.B.B0 & 0x0F) == 0x0F ? H_FLAG : 0);
break; break;
case 0x0e: case 0x0e:
// LD C, NN // LD C, NN
@ -114,8 +111,7 @@ break;
case 0x15: case 0x15:
// DEC D // DEC D
DE.B.B1--; DE.B.B1--;
AF.B.B0 = AF.B.B0 = N_FLAG | (AF.B.B0 & C_FLAG) | ZeroTable[DE.B.B1] | ((DE.B.B1 & 0x0F) == 0x0F ? H_FLAG : 0);
N_FLAG | (AF.B.B0 & C_FLAG) | ZeroTable[DE.B.B1] | ((DE.B.B1 & 0x0F) == 0x0F ? H_FLAG : 0);
break; break;
case 0x16: case 0x16:
// LD D,NN // LD D,NN
@ -134,8 +130,7 @@ break;
case 0x19: case 0x19:
// ADD HL,DE // ADD HL,DE
tempRegister.W = (HL.W + DE.W) & 0xFFFF; tempRegister.W = (HL.W + DE.W) & 0xFFFF;
AF.B.B0 = (AF.B.B0 & Z_FLAG) | ((HL.W ^ DE.W ^ tempRegister.W) & 0x1000 ? H_FLAG : 0) | AF.B.B0 = (AF.B.B0 & Z_FLAG) | ((HL.W ^ DE.W ^ tempRegister.W) & 0x1000 ? H_FLAG : 0) | (((long)HL.W + (long)DE.W) & 0x10000 ? C_FLAG : 0);
(((long)HL.W + (long)DE.W) & 0x10000 ? C_FLAG : 0);
HL.W = tempRegister.W; HL.W = tempRegister.W;
break; break;
case 0x1a: case 0x1a:
@ -154,8 +149,7 @@ break;
case 0x1d: case 0x1d:
// DEC E // DEC E
DE.B.B0--; DE.B.B0--;
AF.B.B0 = AF.B.B0 = N_FLAG | (AF.B.B0 & C_FLAG) | ZeroTable[DE.B.B0] | ((DE.B.B0 & 0x0F) == 0x0F ? H_FLAG : 0);
N_FLAG | (AF.B.B0 & C_FLAG) | ZeroTable[DE.B.B0] | ((DE.B.B0 & 0x0F) == 0x0F ? H_FLAG : 0);
break; break;
case 0x1e: case 0x1e:
// LD E,NN // LD E,NN
@ -197,8 +191,7 @@ break;
case 0x25: case 0x25:
// DEC H // DEC H
HL.B.B1--; HL.B.B1--;
AF.B.B0 = AF.B.B0 = N_FLAG | (AF.B.B0 & C_FLAG) | ZeroTable[HL.B.B1] | ((HL.B.B1 & 0x0F) == 0x0F ? H_FLAG : 0);
N_FLAG | (AF.B.B0 & C_FLAG) | ZeroTable[HL.B.B1] | ((HL.B.B1 & 0x0F) == 0x0F ? H_FLAG : 0);
break; break;
case 0x26: case 0x26:
// LD H,NN // LD H,NN
@ -221,8 +214,7 @@ break;
case 0x29: case 0x29:
// ADD HL,HL // ADD HL,HL
tempRegister.W = (HL.W + HL.W) & 0xFFFF; tempRegister.W = (HL.W + HL.W) & 0xFFFF;
AF.B.B0 = (AF.B.B0 & Z_FLAG) | ((HL.W ^ HL.W ^ tempRegister.W) & 0x1000 ? H_FLAG : 0) | AF.B.B0 = (AF.B.B0 & Z_FLAG) | ((HL.W ^ HL.W ^ tempRegister.W) & 0x1000 ? H_FLAG : 0) | (((long)HL.W + (long)HL.W) & 0x10000 ? C_FLAG : 0);
(((long)HL.W + (long)HL.W) & 0x10000 ? C_FLAG : 0);
HL.W = tempRegister.W; HL.W = tempRegister.W;
break; break;
case 0x2a: case 0x2a:
@ -241,8 +233,7 @@ break;
case 0x2d: case 0x2d:
// DEC L // DEC L
HL.B.B0--; HL.B.B0--;
AF.B.B0 = AF.B.B0 = N_FLAG | (AF.B.B0 & C_FLAG) | ZeroTable[HL.B.B0] | ((HL.B.B0 & 0x0F) == 0x0F ? H_FLAG : 0);
N_FLAG | (AF.B.B0 & C_FLAG) | ZeroTable[HL.B.B0] | ((HL.B.B0 & 0x0F) == 0x0F ? H_FLAG : 0);
break; break;
case 0x2e: case 0x2e:
// LD L,NN // LD L,NN
@ -284,8 +275,7 @@ break;
case 0x35: case 0x35:
// DEC (HL) // DEC (HL)
tempValue = gbReadMemory(HL.W) - 1; tempValue = gbReadMemory(HL.W) - 1;
AF.B.B0 = AF.B.B0 = N_FLAG | (AF.B.B0 & C_FLAG) | ZeroTable[tempValue] | ((tempValue & 0x0F) == 0x0F ? H_FLAG : 0);
N_FLAG | (AF.B.B0 & C_FLAG) | ZeroTable[tempValue] | ((tempValue & 0x0F) == 0x0F ? H_FLAG : 0);
gbWriteMemory(HL.W, tempValue); gbWriteMemory(HL.W, tempValue);
break; break;
case 0x36: case 0x36:
@ -307,8 +297,7 @@ break;
case 0x39: case 0x39:
// ADD HL,SP // ADD HL,SP
tempRegister.W = (HL.W + SP.W) & 0xFFFF; tempRegister.W = (HL.W + SP.W) & 0xFFFF;
AF.B.B0 = (AF.B.B0 & Z_FLAG) | ((HL.W ^ SP.W ^ tempRegister.W) & 0x1000 ? H_FLAG : 0) | AF.B.B0 = (AF.B.B0 & Z_FLAG) | ((HL.W ^ SP.W ^ tempRegister.W) & 0x1000 ? H_FLAG : 0) | (((long)HL.W + (long)SP.W) & 0x10000 ? C_FLAG : 0);
(((long)HL.W + (long)SP.W) & 0x10000 ? C_FLAG : 0);
HL.W = tempRegister.W; HL.W = tempRegister.W;
break; break;
case 0x3a: case 0x3a:
@ -327,8 +316,7 @@ break;
case 0x3d: case 0x3d:
// DEC A // DEC A
AF.B.B1--; AF.B.B1--;
AF.B.B0 = AF.B.B0 = N_FLAG | (AF.B.B0 & C_FLAG) | ZeroTable[AF.B.B1] | ((AF.B.B1 & 0x0F) == 0x0F ? H_FLAG : 0);
N_FLAG | (AF.B.B0 & C_FLAG) | ZeroTable[AF.B.B1] | ((AF.B.B1 & 0x0F) == 0x0F ? H_FLAG : 0);
break; break;
case 0x3e: case 0x3e:
// LD A,NN // LD A,NN
@ -611,165 +599,142 @@ break;
case 0x80: case 0x80:
// ADD B // ADD B
tempRegister.W = AF.B.B1 + BC.B.B1; tempRegister.W = AF.B.B1 + BC.B.B1;
AF.B.B0 = (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | AF.B.B0 = (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | ((AF.B.B1 ^ BC.B.B1 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
((AF.B.B1 ^ BC.B.B1 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
AF.B.B1 = tempRegister.B.B0; AF.B.B1 = tempRegister.B.B0;
break; break;
case 0x81: case 0x81:
// ADD C // ADD C
tempRegister.W = AF.B.B1 + BC.B.B0; tempRegister.W = AF.B.B1 + BC.B.B0;
AF.B.B0 = (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | AF.B.B0 = (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | ((AF.B.B1 ^ BC.B.B0 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
((AF.B.B1 ^ BC.B.B0 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
AF.B.B1 = tempRegister.B.B0; AF.B.B1 = tempRegister.B.B0;
break; break;
case 0x82: case 0x82:
// ADD D // ADD D
tempRegister.W = AF.B.B1 + DE.B.B1; tempRegister.W = AF.B.B1 + DE.B.B1;
AF.B.B0 = (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | AF.B.B0 = (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | ((AF.B.B1 ^ DE.B.B1 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
((AF.B.B1 ^ DE.B.B1 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
AF.B.B1 = tempRegister.B.B0; AF.B.B1 = tempRegister.B.B0;
break; break;
case 0x83: case 0x83:
// ADD E // ADD E
tempRegister.W = AF.B.B1 + DE.B.B0; tempRegister.W = AF.B.B1 + DE.B.B0;
AF.B.B0 = (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | AF.B.B0 = (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | ((AF.B.B1 ^ DE.B.B0 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
((AF.B.B1 ^ DE.B.B0 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
AF.B.B1 = tempRegister.B.B0; AF.B.B1 = tempRegister.B.B0;
break; break;
case 0x84: case 0x84:
// ADD H // ADD H
tempRegister.W = AF.B.B1 + HL.B.B1; tempRegister.W = AF.B.B1 + HL.B.B1;
AF.B.B0 = (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | AF.B.B0 = (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | ((AF.B.B1 ^ HL.B.B1 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
((AF.B.B1 ^ HL.B.B1 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
AF.B.B1 = tempRegister.B.B0; AF.B.B1 = tempRegister.B.B0;
break; break;
case 0x85: case 0x85:
// ADD L // ADD L
tempRegister.W = AF.B.B1 + HL.B.B0; tempRegister.W = AF.B.B1 + HL.B.B0;
AF.B.B0 = (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | AF.B.B0 = (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | ((AF.B.B1 ^ HL.B.B0 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
((AF.B.B1 ^ HL.B.B0 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
AF.B.B1 = tempRegister.B.B0; AF.B.B1 = tempRegister.B.B0;
break; break;
case 0x86: case 0x86:
// ADD (HL) // ADD (HL)
tempValue = gbReadMemory(HL.W); tempValue = gbReadMemory(HL.W);
tempRegister.W = AF.B.B1 + tempValue; tempRegister.W = AF.B.B1 + tempValue;
AF.B.B0 = (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | AF.B.B0 = (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | ((AF.B.B1 ^ tempValue ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
((AF.B.B1 ^ tempValue ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
AF.B.B1 = tempRegister.B.B0; AF.B.B1 = tempRegister.B.B0;
break; break;
case 0x87: case 0x87:
// ADD A // ADD A
tempRegister.W = AF.B.B1 + AF.B.B1; tempRegister.W = AF.B.B1 + AF.B.B1;
AF.B.B0 = (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | AF.B.B0 = (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | ((AF.B.B1 ^ AF.B.B1 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
((AF.B.B1 ^ AF.B.B1 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
AF.B.B1 = tempRegister.B.B0; AF.B.B1 = tempRegister.B.B0;
break; break;
case 0x88: case 0x88:
// ADC B: // ADC B:
tempRegister.W = AF.B.B1 + BC.B.B1 + (AF.B.B0 & C_FLAG ? 1 : 0); tempRegister.W = AF.B.B1 + BC.B.B1 + (AF.B.B0 & C_FLAG ? 1 : 0);
AF.B.B0 = (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | AF.B.B0 = (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | ((AF.B.B1 ^ BC.B.B1 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
((AF.B.B1 ^ BC.B.B1 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
AF.B.B1 = tempRegister.B.B0; AF.B.B1 = tempRegister.B.B0;
break; break;
case 0x89: case 0x89:
// ADC C // ADC C
tempRegister.W = AF.B.B1 + BC.B.B0 + (AF.B.B0 & C_FLAG ? 1 : 0); tempRegister.W = AF.B.B1 + BC.B.B0 + (AF.B.B0 & C_FLAG ? 1 : 0);
AF.B.B0 = (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | AF.B.B0 = (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | ((AF.B.B1 ^ BC.B.B0 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
((AF.B.B1 ^ BC.B.B0 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
AF.B.B1 = tempRegister.B.B0; AF.B.B1 = tempRegister.B.B0;
break; break;
case 0x8a: case 0x8a:
// ADC D // ADC D
tempRegister.W = AF.B.B1 + DE.B.B1 + (AF.B.B0 & C_FLAG ? 1 : 0); tempRegister.W = AF.B.B1 + DE.B.B1 + (AF.B.B0 & C_FLAG ? 1 : 0);
AF.B.B0 = (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | AF.B.B0 = (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | ((AF.B.B1 ^ DE.B.B1 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
((AF.B.B1 ^ DE.B.B1 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
AF.B.B1 = tempRegister.B.B0; AF.B.B1 = tempRegister.B.B0;
break; break;
case 0x8b: case 0x8b:
// ADC E // ADC E
tempRegister.W = AF.B.B1 + DE.B.B0 + (AF.B.B0 & C_FLAG ? 1 : 0); tempRegister.W = AF.B.B1 + DE.B.B0 + (AF.B.B0 & C_FLAG ? 1 : 0);
AF.B.B0 = (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | AF.B.B0 = (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | ((AF.B.B1 ^ DE.B.B0 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
((AF.B.B1 ^ DE.B.B0 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
AF.B.B1 = tempRegister.B.B0; AF.B.B1 = tempRegister.B.B0;
break; break;
case 0x8c: case 0x8c:
// ADC H // ADC H
tempRegister.W = AF.B.B1 + HL.B.B1 + (AF.B.B0 & C_FLAG ? 1 : 0); tempRegister.W = AF.B.B1 + HL.B.B1 + (AF.B.B0 & C_FLAG ? 1 : 0);
AF.B.B0 = (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | AF.B.B0 = (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | ((AF.B.B1 ^ HL.B.B1 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
((AF.B.B1 ^ HL.B.B1 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
AF.B.B1 = tempRegister.B.B0; AF.B.B1 = tempRegister.B.B0;
break; break;
case 0x8d: case 0x8d:
// ADC L // ADC L
tempRegister.W = AF.B.B1 + HL.B.B0 + (AF.B.B0 & C_FLAG ? 1 : 0); tempRegister.W = AF.B.B1 + HL.B.B0 + (AF.B.B0 & C_FLAG ? 1 : 0);
AF.B.B0 = (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | AF.B.B0 = (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | ((AF.B.B1 ^ HL.B.B0 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
((AF.B.B1 ^ HL.B.B0 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
AF.B.B1 = tempRegister.B.B0; AF.B.B1 = tempRegister.B.B0;
break; break;
case 0x8e: case 0x8e:
// ADC (HL) // ADC (HL)
tempValue = gbReadMemory(HL.W); tempValue = gbReadMemory(HL.W);
tempRegister.W = AF.B.B1 + tempValue + (AF.B.B0 & C_FLAG ? 1 : 0); tempRegister.W = AF.B.B1 + tempValue + (AF.B.B0 & C_FLAG ? 1 : 0);
AF.B.B0 = (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | AF.B.B0 = (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | ((AF.B.B1 ^ tempValue ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
((AF.B.B1 ^ tempValue ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
AF.B.B1 = tempRegister.B.B0; AF.B.B1 = tempRegister.B.B0;
break; break;
case 0x8f: case 0x8f:
// ADC A // ADC A
tempRegister.W = AF.B.B1 + AF.B.B1 + (AF.B.B0 & C_FLAG ? 1 : 0); tempRegister.W = AF.B.B1 + AF.B.B1 + (AF.B.B0 & C_FLAG ? 1 : 0);
AF.B.B0 = (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | AF.B.B0 = (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | ((AF.B.B1 ^ AF.B.B1 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
((AF.B.B1 ^ AF.B.B1 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
AF.B.B1 = tempRegister.B.B0; AF.B.B1 = tempRegister.B.B0;
break; break;
case 0x90: case 0x90:
// SUB B // SUB B
tempRegister.W = AF.B.B1 - BC.B.B1; tempRegister.W = AF.B.B1 - BC.B.B1;
AF.B.B0 = N_FLAG | (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | AF.B.B0 = N_FLAG | (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | ((AF.B.B1 ^ BC.B.B1 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
((AF.B.B1 ^ BC.B.B1 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
AF.B.B1 = tempRegister.B.B0; AF.B.B1 = tempRegister.B.B0;
break; break;
case 0x91: case 0x91:
// SUB C // SUB C
tempRegister.W = AF.B.B1 - BC.B.B0; tempRegister.W = AF.B.B1 - BC.B.B0;
AF.B.B0 = N_FLAG | (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | AF.B.B0 = N_FLAG | (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | ((AF.B.B1 ^ BC.B.B0 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
((AF.B.B1 ^ BC.B.B0 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
AF.B.B1 = tempRegister.B.B0; AF.B.B1 = tempRegister.B.B0;
break; break;
case 0x92: case 0x92:
// SUB D // SUB D
tempRegister.W = AF.B.B1 - DE.B.B1; tempRegister.W = AF.B.B1 - DE.B.B1;
AF.B.B0 = N_FLAG | (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | AF.B.B0 = N_FLAG | (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | ((AF.B.B1 ^ DE.B.B1 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
((AF.B.B1 ^ DE.B.B1 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
AF.B.B1 = tempRegister.B.B0; AF.B.B1 = tempRegister.B.B0;
break; break;
case 0x93: case 0x93:
// SUB E // SUB E
tempRegister.W = AF.B.B1 - DE.B.B0; tempRegister.W = AF.B.B1 - DE.B.B0;
AF.B.B0 = N_FLAG | (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | AF.B.B0 = N_FLAG | (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | ((AF.B.B1 ^ DE.B.B0 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
((AF.B.B1 ^ DE.B.B0 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
AF.B.B1 = tempRegister.B.B0; AF.B.B1 = tempRegister.B.B0;
break; break;
case 0x94: case 0x94:
// SUB H // SUB H
tempRegister.W = AF.B.B1 - HL.B.B1; tempRegister.W = AF.B.B1 - HL.B.B1;
AF.B.B0 = N_FLAG | (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | AF.B.B0 = N_FLAG | (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | ((AF.B.B1 ^ HL.B.B1 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
((AF.B.B1 ^ HL.B.B1 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
AF.B.B1 = tempRegister.B.B0; AF.B.B1 = tempRegister.B.B0;
break; break;
case 0x95: case 0x95:
// SUB L // SUB L
tempRegister.W = AF.B.B1 - HL.B.B0; tempRegister.W = AF.B.B1 - HL.B.B0;
AF.B.B0 = N_FLAG | (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | AF.B.B0 = N_FLAG | (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | ((AF.B.B1 ^ HL.B.B0 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
((AF.B.B1 ^ HL.B.B0 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
AF.B.B1 = tempRegister.B.B0; AF.B.B1 = tempRegister.B.B0;
break; break;
case 0x96: case 0x96:
// SUB (HL) // SUB (HL)
tempValue = gbReadMemory(HL.W); tempValue = gbReadMemory(HL.W);
tempRegister.W = AF.B.B1 - tempValue; tempRegister.W = AF.B.B1 - tempValue;
AF.B.B0 = N_FLAG | (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | AF.B.B0 = N_FLAG | (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | ((AF.B.B1 ^ tempValue ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
((AF.B.B1 ^ tempValue ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
AF.B.B1 = tempRegister.B.B0; AF.B.B1 = tempRegister.B.B0;
break; break;
case 0x97: case 0x97:
@ -780,58 +745,50 @@ break;
case 0x98: case 0x98:
// SBC B // SBC B
tempRegister.W = AF.B.B1 - BC.B.B1 - (AF.B.B0 & C_FLAG ? 1 : 0); tempRegister.W = AF.B.B1 - BC.B.B1 - (AF.B.B0 & C_FLAG ? 1 : 0);
AF.B.B0 = N_FLAG | (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | AF.B.B0 = N_FLAG | (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | ((AF.B.B1 ^ BC.B.B1 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
((AF.B.B1 ^ BC.B.B1 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
AF.B.B1 = tempRegister.B.B0; AF.B.B1 = tempRegister.B.B0;
break; break;
case 0x99: case 0x99:
// SBC C // SBC C
tempRegister.W = AF.B.B1 - BC.B.B0 - (AF.B.B0 & C_FLAG ? 1 : 0); tempRegister.W = AF.B.B1 - BC.B.B0 - (AF.B.B0 & C_FLAG ? 1 : 0);
AF.B.B0 = N_FLAG | (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | AF.B.B0 = N_FLAG | (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | ((AF.B.B1 ^ BC.B.B0 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
((AF.B.B1 ^ BC.B.B0 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
AF.B.B1 = tempRegister.B.B0; AF.B.B1 = tempRegister.B.B0;
break; break;
case 0x9a: case 0x9a:
// SBC D // SBC D
tempRegister.W = AF.B.B1 - DE.B.B1 - (AF.B.B0 & C_FLAG ? 1 : 0); tempRegister.W = AF.B.B1 - DE.B.B1 - (AF.B.B0 & C_FLAG ? 1 : 0);
AF.B.B0 = N_FLAG | (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | AF.B.B0 = N_FLAG | (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | ((AF.B.B1 ^ DE.B.B1 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
((AF.B.B1 ^ DE.B.B1 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
AF.B.B1 = tempRegister.B.B0; AF.B.B1 = tempRegister.B.B0;
break; break;
case 0x9b: case 0x9b:
// SBC E // SBC E
tempRegister.W = AF.B.B1 - DE.B.B0 - (AF.B.B0 & C_FLAG ? 1 : 0); tempRegister.W = AF.B.B1 - DE.B.B0 - (AF.B.B0 & C_FLAG ? 1 : 0);
AF.B.B0 = N_FLAG | (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | AF.B.B0 = N_FLAG | (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | ((AF.B.B1 ^ DE.B.B0 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
((AF.B.B1 ^ DE.B.B0 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
AF.B.B1 = tempRegister.B.B0; AF.B.B1 = tempRegister.B.B0;
break; break;
case 0x9c: case 0x9c:
// SBC H // SBC H
tempRegister.W = AF.B.B1 - HL.B.B1 - (AF.B.B0 & C_FLAG ? 1 : 0); tempRegister.W = AF.B.B1 - HL.B.B1 - (AF.B.B0 & C_FLAG ? 1 : 0);
AF.B.B0 = N_FLAG | (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | AF.B.B0 = N_FLAG | (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | ((AF.B.B1 ^ HL.B.B1 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
((AF.B.B1 ^ HL.B.B1 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
AF.B.B1 = tempRegister.B.B0; AF.B.B1 = tempRegister.B.B0;
break; break;
case 0x9d: case 0x9d:
// SBC L // SBC L
tempRegister.W = AF.B.B1 - HL.B.B0 - (AF.B.B0 & C_FLAG ? 1 : 0); tempRegister.W = AF.B.B1 - HL.B.B0 - (AF.B.B0 & C_FLAG ? 1 : 0);
AF.B.B0 = N_FLAG | (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | AF.B.B0 = N_FLAG | (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | ((AF.B.B1 ^ HL.B.B0 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
((AF.B.B1 ^ HL.B.B0 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
AF.B.B1 = tempRegister.B.B0; AF.B.B1 = tempRegister.B.B0;
break; break;
case 0x9e: case 0x9e:
// SBC (HL) // SBC (HL)
tempValue = gbReadMemory(HL.W); tempValue = gbReadMemory(HL.W);
tempRegister.W = AF.B.B1 - tempValue - (AF.B.B0 & C_FLAG ? 1 : 0); tempRegister.W = AF.B.B1 - tempValue - (AF.B.B0 & C_FLAG ? 1 : 0);
AF.B.B0 = N_FLAG | (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | AF.B.B0 = N_FLAG | (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | ((AF.B.B1 ^ tempValue ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
((AF.B.B1 ^ tempValue ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
AF.B.B1 = tempRegister.B.B0; AF.B.B1 = tempRegister.B.B0;
break; break;
case 0x9f: case 0x9f:
// SBC A // SBC A
tempRegister.W = AF.B.B1 - AF.B.B1 - (AF.B.B0 & C_FLAG ? 1 : 0); tempRegister.W = AF.B.B1 - AF.B.B1 - (AF.B.B0 & C_FLAG ? 1 : 0);
AF.B.B0 = N_FLAG | (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | AF.B.B0 = N_FLAG | (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | ((AF.B.B1 ^ AF.B.B1 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
((AF.B.B1 ^ AF.B.B1 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
AF.B.B1 = tempRegister.B.B0; AF.B.B1 = tempRegister.B.B0;
break; break;
case 0xa0: case 0xa0:
@ -960,45 +917,38 @@ break;
case 0xb8: case 0xb8:
// CP B: // CP B:
tempRegister.W = AF.B.B1 - BC.B.B1; tempRegister.W = AF.B.B1 - BC.B.B1;
AF.B.B0 = N_FLAG | (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | AF.B.B0 = N_FLAG | (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | ((AF.B.B1 ^ BC.B.B1 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
((AF.B.B1 ^ BC.B.B1 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
break; break;
case 0xb9: case 0xb9:
// CP C // CP C
tempRegister.W = AF.B.B1 - BC.B.B0; tempRegister.W = AF.B.B1 - BC.B.B0;
AF.B.B0 = N_FLAG | (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | AF.B.B0 = N_FLAG | (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | ((AF.B.B1 ^ BC.B.B0 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
((AF.B.B1 ^ BC.B.B0 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
break; break;
case 0xba: case 0xba:
// CP D // CP D
tempRegister.W = AF.B.B1 - DE.B.B1; tempRegister.W = AF.B.B1 - DE.B.B1;
AF.B.B0 = N_FLAG | (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | AF.B.B0 = N_FLAG | (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | ((AF.B.B1 ^ DE.B.B1 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
((AF.B.B1 ^ DE.B.B1 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
break; break;
case 0xbb: case 0xbb:
// CP E // CP E
tempRegister.W = AF.B.B1 - DE.B.B0; tempRegister.W = AF.B.B1 - DE.B.B0;
AF.B.B0 = N_FLAG | (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | AF.B.B0 = N_FLAG | (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | ((AF.B.B1 ^ DE.B.B0 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
((AF.B.B1 ^ DE.B.B0 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
break; break;
case 0xbc: case 0xbc:
// CP H // CP H
tempRegister.W = AF.B.B1 - HL.B.B1; tempRegister.W = AF.B.B1 - HL.B.B1;
AF.B.B0 = N_FLAG | (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | AF.B.B0 = N_FLAG | (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | ((AF.B.B1 ^ HL.B.B1 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
((AF.B.B1 ^ HL.B.B1 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
break; break;
case 0xbd: case 0xbd:
// CP L // CP L
tempRegister.W = AF.B.B1 - HL.B.B0; tempRegister.W = AF.B.B1 - HL.B.B0;
AF.B.B0 = N_FLAG | (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | AF.B.B0 = N_FLAG | (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | ((AF.B.B1 ^ HL.B.B0 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
((AF.B.B1 ^ HL.B.B0 ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
break; break;
case 0xbe: case 0xbe:
// CP (HL) // CP (HL)
tempValue = gbReadMemory(HL.W); tempValue = gbReadMemory(HL.W);
tempRegister.W = AF.B.B1 - tempValue; tempRegister.W = AF.B.B1 - tempValue;
AF.B.B0 = N_FLAG | (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | AF.B.B0 = N_FLAG | (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | ((AF.B.B1 ^ tempValue ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
((AF.B.B1 ^ tempValue ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
break; break;
case 0xbf: case 0xbf:
// CP A // CP A
@ -1056,8 +1006,7 @@ case 0xc6:
// ADD NN // ADD NN
tempValue = gbReadOpcode(PC.W++); tempValue = gbReadOpcode(PC.W++);
tempRegister.W = AF.B.B1 + tempValue; tempRegister.W = AF.B.B1 + tempValue;
AF.B.B0 = (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | AF.B.B0 = (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | ((AF.B.B1 ^ tempValue ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
((AF.B.B1 ^ tempValue ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
AF.B.B1 = tempRegister.B.B0; AF.B.B1 = tempRegister.B.B0;
break; break;
case 0xc7: case 0xc7:
@ -1114,8 +1063,7 @@ case 0xce:
// ADC NN // ADC NN
tempValue = gbReadOpcode(PC.W++); tempValue = gbReadOpcode(PC.W++);
tempRegister.W = AF.B.B1 + tempValue + (AF.B.B0 & C_FLAG ? 1 : 0); tempRegister.W = AF.B.B1 + tempValue + (AF.B.B0 & C_FLAG ? 1 : 0);
AF.B.B0 = (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | AF.B.B0 = (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | ((AF.B.B1 ^ tempValue ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
((AF.B.B1 ^ tempValue ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
AF.B.B1 = tempRegister.B.B0; AF.B.B1 = tempRegister.B.B0;
break; break;
case 0xcf: case 0xcf:
@ -1175,8 +1123,7 @@ case 0xd6:
// SUB NN // SUB NN
tempValue = gbReadOpcode(PC.W++); tempValue = gbReadOpcode(PC.W++);
tempRegister.W = AF.B.B1 - tempValue; tempRegister.W = AF.B.B1 - tempValue;
AF.B.B0 = N_FLAG | (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | AF.B.B0 = N_FLAG | (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | ((AF.B.B1 ^ tempValue ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
((AF.B.B1 ^ tempValue ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
AF.B.B1 = tempRegister.B.B0; AF.B.B1 = tempRegister.B.B0;
break; break;
case 0xd7: case 0xd7:
@ -1235,8 +1182,7 @@ case 0xde:
// SBC NN // SBC NN
tempValue = gbReadOpcode(PC.W++); tempValue = gbReadOpcode(PC.W++);
tempRegister.W = AF.B.B1 - tempValue - (AF.B.B0 & C_FLAG ? 1 : 0); tempRegister.W = AF.B.B1 - tempValue - (AF.B.B0 & C_FLAG ? 1 : 0);
AF.B.B0 = N_FLAG | (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | AF.B.B0 = N_FLAG | (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | ((AF.B.B1 ^ tempValue ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
((AF.B.B1 ^ tempValue ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
AF.B.B1 = tempRegister.B.B0; AF.B.B1 = tempRegister.B.B0;
break; break;
case 0xdf: case 0xdf:
@ -1286,8 +1232,7 @@ case 0xe8:
// ADD SP,NN // ADD SP,NN
offset = (s8)gbReadOpcode(PC.W++); offset = (s8)gbReadOpcode(PC.W++);
tempRegister.W = SP.W + offset; tempRegister.W = SP.W + offset;
AF.B.B0 = ((SP.W ^ offset ^ tempRegister.W) & 0x100 ? C_FLAG : 0) | AF.B.B0 = ((SP.W ^ offset ^ tempRegister.W) & 0x100 ? C_FLAG : 0) | ((SP.W ^ offset ^ tempRegister.W) & 0x10 ? H_FLAG : 0);
((SP.W ^ offset ^ tempRegister.W) & 0x10 ? H_FLAG : 0);
SP.W = tempRegister.W; SP.W = tempRegister.W;
break; break;
case 0xe9: case 0xe9:
@ -1365,8 +1310,7 @@ case 0xf8:
// LD HL,SP+NN // LD HL,SP+NN
offset = (s8)gbReadOpcode(PC.W++); offset = (s8)gbReadOpcode(PC.W++);
tempRegister.W = SP.W + offset; tempRegister.W = SP.W + offset;
AF.B.B0 = ((SP.W ^ offset ^ tempRegister.W) & 0x100 ? C_FLAG : 0) | AF.B.B0 = ((SP.W ^ offset ^ tempRegister.W) & 0x100 ? C_FLAG : 0) | ((SP.W ^ offset ^ tempRegister.W) & 0x10 ? H_FLAG : 0);
((SP.W ^ offset ^ tempRegister.W) & 0x10 ? H_FLAG : 0);
HL.W = tempRegister.W; HL.W = tempRegister.W;
break; break;
case 0xf9: case 0xf9:
@ -1402,8 +1346,7 @@ case 0xfe:
// CP NN // CP NN
tempValue = gbReadOpcode(PC.W++); tempValue = gbReadOpcode(PC.W++);
tempRegister.W = AF.B.B1 - tempValue; tempRegister.W = AF.B.B1 - tempValue;
AF.B.B0 = N_FLAG | (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | AF.B.B0 = N_FLAG | (tempRegister.B.B1 ? C_FLAG : 0) | ZeroTable[tempRegister.B.B0] | ((AF.B.B1 ^ tempValue ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
((AF.B.B1 ^ tempValue ^ tempRegister.B.B0) & 0x10 ? H_FLAG : 0);
break; break;
case 0xff: case 0xff:
// RST 38 // RST 38

View File

@ -5,22 +5,19 @@
#include "gbGlobals.h" #include "gbGlobals.h"
typedef struct { typedef struct {
u8 mask; uint8_t mask;
u8 value; uint8_t value;
const char* mnen; const char* mnen;
} GBOPCODE; } GBOPCODE;
#define GB_READ(x) gbMemoryMap[(x) >> 12][(x)&0xfff] #define GB_READ(x) gbMemoryMap[(x) >> 12][(x)&0xfff]
static const char *registers[] = static const char* registers[] = { "B", "C", "D", "E", "H", "L", "(HL)", "A" };
{ "B", "C", "D", "E", "H", "L", "(HL)", "A" };
static const char *registers16[] = static const char* registers16[] = { "BC", "DE", "HL", "SP", // for some operations
{ "BC", "DE", "HL", "SP", // for some operations
"BC", "DE", "HL", "AF" }; // for push/pop "BC", "DE", "HL", "AF" }; // for push/pop
static const char *cond[] = static const char* cond[] = { "NZ", "Z", "NC", "C" };
{ "NZ", "Z", "NC", "C" };
static char hexDigits[16] = { static char hexDigits[16] = {
'0', '1', '2', '3', '4', '5', '6', '7', '0', '1', '2', '3', '4', '5', '6', '7',
@ -114,14 +111,14 @@ static GBOPCODE cbOpcodes[] = {
{ 0x00, 0x00, "DB CBh,%B" } { 0x00, 0x00, "DB CBh,%B" }
}; };
static char *addHex(char *p, u8 value) static char* addHex(char* p, uint8_t value)
{ {
*p++ = hexDigits[value >> 4]; *p++ = hexDigits[value >> 4];
*p++ = hexDigits[value & 15]; *p++ = hexDigits[value & 15];
return p; return p;
} }
static char *addHex16(char *p, u16 value) static char* addHex16(char* p, uint16_t value)
{ {
p = addHex(p, value >> 8); p = addHex(p, value >> 8);
return addHex(p, value & 255); return addHex(p, value & 255);
@ -135,15 +132,15 @@ static char *addStr(char *p, const char *s)
return p; return p;
} }
int gbDis(char *buffer, u16 address) int gbDis(char* buffer, uint16_t address)
{ {
char* p = buffer; char* p = buffer;
int instr = 1; int instr = 1;
u16 addr = address; uint16_t addr = address;
sprintf(p, "%04x ", address); sprintf(p, "%04x ", address);
p += 12; p += 12;
u8 opcode = GB_READ(address); uint8_t opcode = GB_READ(address);
address++; address++;
const char* mnen; const char* mnen;
GBOPCODE* op; GBOPCODE* op;
@ -155,11 +152,12 @@ int gbDis(char *buffer, u16 address)
} else { } else {
op = opcodes; op = opcodes;
} }
while(op->value != (opcode & op->mask)) op++; while (op->value != (opcode & op->mask))
op++;
mnen = op->mnen; mnen = op->mnen;
u8 b0, b1; uint8_t b0, b1;
s8 disp; int8_t disp;
int shift; int shift;
while (*mnen) { while (*mnen) {
@ -223,7 +221,7 @@ int gbDis(char *buffer, u16 address)
*p++ = *mnen++; *p++ = *mnen++;
} }
for (int i = 0; i < instr; i++) { for (int i = 0; i < instr; i++) {
u16 a = addr + i; uint16_t a = addr + i;
addHex(buffer + 5 + i * 2, GB_READ(a)); addHex(buffer + 5 + i * 2, GB_READ(a));
} }
*p = 0; *p = 0;

View File

@ -1,7 +1,7 @@
#include <memory.h> #include <memory.h>
#include "../common/Types.h"
#include "../Util.h" #include "../Util.h"
#include "../common/Types.h"
#include "gbGlobals.h" #include "gbGlobals.h"
#include "gbSGB.h" #include "gbSGB.h"
@ -108,8 +108,6 @@ void gbRenderLine()
if ((register_LCDC & 0x01 || gbCgbMode) && (layerSettings & 0x0100)) { if ((register_LCDC & 0x01 || gbCgbMode) && (layerSettings & 0x0100)) {
while (x < 160) { while (x < 160) {
u8 tile_a = 0; u8 tile_a = 0;
u8 tile_b = 0; u8 tile_b = 0;
@ -175,7 +173,6 @@ void gbRenderLine()
sy = gbSCYLine[x + (gbSpeed ? 11 : 5) + SpritesTicks]; sy = gbSCYLine[x + (gbSpeed ? 11 : 5) + SpritesTicks];
tx = ((sx + x) >> 3) & 0x1f; tx = ((sx + x) >> 3) & 0x1f;
sy += y; sy += y;
@ -206,13 +203,10 @@ void gbRenderLine()
// Use gbBgp[0] instead of 0 (?) // Use gbBgp[0] instead of 0 (?)
// (this fixes white flashes on Last Bible II) // (this fixes white flashes on Last Bible II)
// Also added the gbColorOption (fixes Dracula Densetsu II color problems) // Also added the gbColorOption (fixes Dracula Densetsu II color problems)
for(int i = 0; i < 160; i++) for (int i = 0; i < 160; i++) {
{
u16 color = gbColorOption ? gbColorFilter[0x7FFF] : 0x7FFF; u16 color = gbColorOption ? gbColorFilter[0x7FFF] : 0x7FFF;
if (!gbCgbMode) if (!gbCgbMode)
color = gbColorOption ? color = gbColorOption ? gbColorFilter[gbPalette[gbBgpLine[i + (gbSpeed ? 5 : 11) + gbSpritesTicks[i] * (gbSpeed ? 2 : 4)] & 3] & 0x7FFF] : gbPalette[gbBgpLine[i + (gbSpeed ? 5 : 11) + gbSpritesTicks[i] * (gbSpeed ? 2 : 4)] & 3] & 0x7FFF;
gbColorFilter[gbPalette[gbBgpLine[i+(gbSpeed ? 5 : 11)+gbSpritesTicks[i]*(gbSpeed ? 2 : 4)]&3] & 0x7FFF] :
gbPalette[gbBgpLine[i+(gbSpeed ? 5 : 11)+gbSpritesTicks[i]*(gbSpeed ? 2 : 4)]&3] & 0x7FFF;
gbLineMix[i] = color; gbLineMix[i] = color;
gbLineBuffer[i] = 0; gbLineBuffer[i] = 0;
} }
@ -226,8 +220,7 @@ void gbRenderLine()
int i = 0; int i = 0;
// Fix (accurate emulation) for most of the window display problems // Fix (accurate emulation) for most of the window display problems
// (ie. Zen - Intergalactic Ninja, Urusei Yatsura...). // (ie. Zen - Intergalactic Ninja, Urusei Yatsura...).
if ((gbWindowLine == -1) || (gbWindowLine>144)) if ((gbWindowLine == -1) || (gbWindowLine > 144)) {
{
inUseRegister_WY = oldRegister_WY; inUseRegister_WY = oldRegister_WY;
if (register_LY > oldRegister_WY) if (register_LY > oldRegister_WY)
gbWindowLine = 146; gbWindowLine = 146;
@ -253,7 +246,6 @@ void gbRenderLine()
if ((register_LCDC & 0x40) != 0) if ((register_LCDC & 0x40) != 0)
tile_map = 0x1c00; tile_map = 0x1c00;
tx = 0; tx = 0;
ty = gbWindowLine >> 3; ty = gbWindowLine >> 3;
@ -262,8 +254,7 @@ void gbRenderLine()
// Tries to emulate the 'window scrolling bug' when wx == 0 (ie. wx-7 == -7). // Tries to emulate the 'window scrolling bug' when wx == 0 (ie. wx-7 == -7).
// Nothing close to perfect, but good enought for now... // Nothing close to perfect, but good enought for now...
if (wx == -7) if (wx == -7) {
{
swx = 7 - ((gbSCXLine[0] - 1) & 7); swx = 7 - ((gbSCXLine[0] - 1) & 7);
bx >>= ((gbSCXLine[0] + ((swx != 1) ? 1 : 0)) & 7); bx >>= ((gbSCXLine[0] + ((swx != 1) ? 1 : 0)) & 7);
if (swx == 1) if (swx == 1)
@ -271,15 +262,12 @@ void gbRenderLine()
//bx >>= ((gbSCXLine[0]+(((swx>1) && (swx != 7)) ? 1 : 0)) & 7); //bx >>= ((gbSCXLine[0]+(((swx>1) && (swx != 7)) ? 1 : 0)) & 7);
if (swx == 7) if (swx == 7) {
{
//wx = 0; //wx = 0;
if ((gbWindowLine > 0) || (wy == 0)) if ((gbWindowLine > 0) || (wy == 0))
swx = 0; swx = 0;
} }
} } else if (wx < 0) {
else
if(wx < 0) {
bx >>= (-wx); bx >>= (-wx);
wx = 0; wx = 0;
} }
@ -297,8 +285,10 @@ void gbRenderLine()
tile_map_address++; tile_map_address++;
if ((register_LCDC & 16) == 0) { if ((register_LCDC & 16) == 0) {
if(tile < 128) tile += 128; if (tile < 128)
else tile -= 128; tile += 128;
else
tile -= 128;
} }
tile_pattern_address = tile_pattern + tile * 16 + by * 2; tile_pattern_address = tile_pattern + tile * 16 + by * 2;
@ -332,8 +322,7 @@ void gbRenderLine()
u8 c = (tile_a & bx) != 0 ? 1 : 0; u8 c = (tile_a & bx) != 0 ? 1 : 0;
c += ((tile_b & bx) != 0 ? 2 : 0); c += ((tile_b & bx) != 0 ? 2 : 0);
if (x>=0) if (x >= 0) {
{
if (attrs & 0x80) if (attrs & 0x80)
gbLineBuffer[x] = 0x300 + c; gbLineBuffer[x] = 0x300 + c;
else else
@ -376,8 +365,10 @@ void gbRenderLine()
attrs = bank1[tile_map_line_y + tx]; attrs = bank1[tile_map_line_y + tx];
if ((register_LCDC & 16) == 0) { if ((register_LCDC & 16) == 0) {
if(tile < 128) tile += 128; if (tile < 128)
else tile -= 128; tile += 128;
else
tile -= 128;
} }
tile_pattern_address = tile_pattern + tile * 16 + by * 2; tile_pattern_address = tile_pattern + tile * 16 + by * 2;
} }
@ -387,9 +378,7 @@ void gbRenderLine()
gbWindowLine++; gbWindowLine++;
} }
} }
} } else if (gbWindowLine == -2) {
else if (gbWindowLine == -2)
{
inUseRegister_WY = oldRegister_WY; inUseRegister_WY = oldRegister_WY;
if (register_LY > oldRegister_WY) if (register_LY > oldRegister_WY)
gbWindowLine = 146; gbWindowLine = 146;
@ -400,8 +389,7 @@ void gbRenderLine()
u16 color = gbColorOption ? gbColorFilter[0x7FFF] : 0x7FFF; u16 color = gbColorOption ? gbColorFilter[0x7FFF] : 0x7FFF;
if (!gbCgbMode) if (!gbCgbMode)
color = gbColorOption ? gbColorFilter[gbPalette[0] & 0x7FFF] : gbPalette[0] & 0x7FFF; color = gbColorOption ? gbColorFilter[gbPalette[0] & 0x7FFF] : gbPalette[0] & 0x7FFF;
for(int i = 0; i < 160; i++) for (int i = 0; i < 160; i++) {
{
gbLineMix[i] = color; gbLineMix[i] = color;
gbLineBuffer[i] = 0; gbLineBuffer[i] = 0;
} }
@ -423,8 +411,7 @@ void gbDrawSpriteTile(int tile, int x,int y,int t, int flags,
int init = 0x0000; int init = 0x0000;
for (int i = 0; i<4; i++) for (int i = 0; i < 4; i++) {
{
gbObp0[i] = (gbObp0Line[x + 11 + gbSpritesTicks[x] * (gbSpeed ? 2 : 4)] >> (i << 1)) & 3; gbObp0[i] = (gbObp0Line[x + 11 + gbSpritesTicks[x] * (gbSpeed ? 2 : 4)] >> (i << 1)) & 3;
gbObp1[i] = (gbObp1Line[x + 11 + gbSpritesTicks[x] * (gbSpeed ? 2 : 4)] >> (i << 1)) & 3; gbObp1[i] = (gbObp1Line[x + 11 + gbSpritesTicks[x] * (gbSpeed ? 2 : 4)] >> (i << 1)) & 3;
} }
@ -462,7 +449,8 @@ void gbDrawSpriteTile(int tile, int x,int y,int t, int flags,
if ((b & mask)) if ((b & mask))
c += 2; c += 2;
if(c==0) continue; if (c == 0)
continue;
int xxx = xx + x; int xxx = xx + x;
if (flipx) if (flipx)
@ -502,7 +490,6 @@ void gbDrawSpriteTile(int tile, int x,int y,int t, int flags,
} }
} }
gbLineBuffer[xxx] = 0x200 + spriteNumber; gbLineBuffer[xxx] = 0x200 + spriteNumber;
// make sure that sprites will work even in CGB mode // make sure that sprites will work even in CGB mode
@ -567,11 +554,9 @@ void gbDrawSprites(bool draw)
if ((size && t >= 0 && t < 16) || (!size && t >= 0 && t < 8)) { if ((size && t >= 0 && t < 16) || (!size && t >= 0 && t < 8)) {
if (draw) if (draw)
gbDrawSpriteTile(tile, x - 8, yc, t, flags, size, i); gbDrawSpriteTile(tile, x - 8, yc, t, flags, size, i);
else else {
{
for (int j = x - 8; j < 300; j++) for (int j = x - 8; j < 300; j++)
if (j>=0) if (j >= 0) {
{
if (gbSpeed) if (gbSpeed)
gbSpritesTicks[j] += 5; gbSpritesTicks[j] += 5;
else else

View File

@ -1,5 +1,5 @@
#include <cstdlib>
#include "../common/Types.h" #include "../common/Types.h"
#include <cstdlib>
u8* gbMemoryMap[16]; u8* gbMemoryMap[16];

View File

@ -1,8 +1,8 @@
#include "gbMemory.h"
#include "../System.h" #include "../System.h"
#include "../common/Port.h" #include "../common/Port.h"
#include "gbGlobals.h"
#include "gbMemory.h"
#include "gb.h" #include "gb.h"
#include "gbGlobals.h"
u8 gbDaysinMonth[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; u8 gbDaysinMonth[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
const u8 gbDisabledRam[8] = { 0x80, 0xff, 0xf0, 0x00, 0x30, 0xbf, 0xbf, 0xbf }; const u8 gbDisabledRam[8] = { 0x80, 0xff, 0xf0, 0x00, 0x30, 0xbf, 0xbf, 0xbf };
extern int gbGBCColorType; extern int gbGBCColorType;
@ -43,9 +43,7 @@ void mapperMBC1ROM(u16 address, u8 value)
if (gbDataMBC1.mapperRomBank0Remapping == 3) { if (gbDataMBC1.mapperRomBank0Remapping == 3) {
tmpAddress = (value & 0xf) << 14; tmpAddress = (value & 0xf) << 14;
tmpAddress |= (gbDataMBC1.mapperROMHighAddress & 3) << 18; tmpAddress |= (gbDataMBC1.mapperROMHighAddress & 3) << 18;
} } else if (gbDataMBC1.mapperMemoryModel == 0) {
else
if(gbDataMBC1.mapperMemoryModel == 0) {
// model is 16/8, so we have a high address in use // model is 16/8, so we have a high address in use
tmpAddress |= (gbDataMBC1.mapperROMHighAddress & 3) << 19; tmpAddress |= (gbDataMBC1.mapperROMHighAddress & 3) << 19;
} }
@ -59,10 +57,8 @@ void mapperMBC1ROM(u16 address, u8 value)
break; break;
case 0x4000: // RAM bank select case 0x4000: // RAM bank select
if (gbDataMBC1.mapperMemoryModel == 1) { if (gbDataMBC1.mapperMemoryModel == 1) {
if (!gbRamSize) if (!gbRamSize) {
{ if (gbDataMBC1.mapperRomBank0Remapping == 3) {
if (gbDataMBC1.mapperRomBank0Remapping == 3)
{
gbDataMBC1.mapperROMHighAddress = value & 0x03; gbDataMBC1.mapperROMHighAddress = value & 0x03;
tmpAddress = (gbDataMBC1.mapperROMHighAddress) << 18; tmpAddress = (gbDataMBC1.mapperROMHighAddress) << 18;
tmpAddress &= gbRomSizeMask; tmpAddress &= gbRomSizeMask;
@ -74,8 +70,8 @@ void mapperMBC1ROM(u16 address, u8 value)
gbMemoryMap[0x05] = &gbRom[tmpAddress + 0x5000]; gbMemoryMap[0x05] = &gbRom[tmpAddress + 0x5000];
gbMemoryMap[0x06] = &gbRom[tmpAddress + 0x6000]; gbMemoryMap[0x06] = &gbRom[tmpAddress + 0x6000];
gbMemoryMap[0x07] = &gbRom[tmpAddress + 0x7000]; gbMemoryMap[0x07] = &gbRom[tmpAddress + 0x7000];
} } else
else gbDataMBC1.mapperRomBank0Remapping = 0; gbDataMBC1.mapperRomBank0Remapping = 0;
} }
// 4/32 model, RAM bank switching provided // 4/32 model, RAM bank switching provided
value = value & 0x03; value = value & 0x03;
@ -123,15 +119,14 @@ void mapperMBC1ROM(u16 address, u8 value)
gbMemoryMap[0x0a] = &gbRam[gbDataMBC1.mapperRAMAddress]; gbMemoryMap[0x0a] = &gbRam[gbDataMBC1.mapperRAMAddress];
gbMemoryMap[0x0b] = &gbRam[gbDataMBC1.mapperRAMAddress + 0x1000]; gbMemoryMap[0x0b] = &gbRam[gbDataMBC1.mapperRAMAddress + 0x1000];
gbDataMBC1.mapperRomBank0Remapping = 0; gbDataMBC1.mapperRomBank0Remapping = 0;
} } else
else gbDataMBC1.mapperRomBank0Remapping |=2; gbDataMBC1.mapperRomBank0Remapping |= 2;
gbDataMBC1.mapperRAMBank = value; gbDataMBC1.mapperRAMBank = value;
gbDataMBC1.mapperRAMAddress = tmpAddress; gbDataMBC1.mapperRAMAddress = tmpAddress;
tmpAddress = gbDataMBC1.mapperROMBank << 14; tmpAddress = gbDataMBC1.mapperROMBank << 14;
tmpAddress &= gbRomSizeMask; tmpAddress &= gbRomSizeMask;
gbMemoryMap[0x04] = &gbRom[tmpAddress]; gbMemoryMap[0x04] = &gbRom[tmpAddress];
gbMemoryMap[0x05] = &gbRom[tmpAddress + 0x1000]; gbMemoryMap[0x05] = &gbRom[tmpAddress + 0x1000];
@ -177,26 +172,20 @@ u8 mapperMBC1ReadRAM(u16 address)
if (!genericflashcardEnable) if (!genericflashcardEnable)
return 0xff; return 0xff;
else else if ((address & 0x1000) >= 0x1000) {
if ((address & 0x1000) >= 0x1000)
{
// The value returned when reading RAM while it's disabled // The value returned when reading RAM while it's disabled
// is constant, exept for the GBASP hardware. // is constant, exept for the GBASP hardware.
// (actually, is the address that read is out of the ROM, the returned value if 0xff...) // (actually, is the address that read is out of the ROM, the returned value if 0xff...)
if (PC.W >= 0xff80) if (PC.W >= 0xff80)
return 0xff; return 0xff;
else else if ((gbHardware & 0x08) && (gbGBCColorType == 2)) {
if ((gbHardware & 0x08) && (gbGBCColorType == 2))
{
if (address & 1) if (address & 1)
return 0xfb; return 0xfb;
else else
return 0x7a; return 0x7a;
} } else
else
return 0x0a; return 0x0a;
} } else
else
return gbDisabledRam[address & 7]; return gbDisabledRam[address & 7];
} }
@ -218,9 +207,7 @@ void memoryUpdateMapMBC1()
gbMemoryMap[0x05] = &gbRom[tmpAddress + 0x1000]; gbMemoryMap[0x05] = &gbRom[tmpAddress + 0x1000];
gbMemoryMap[0x06] = &gbRom[tmpAddress + 0x2000]; gbMemoryMap[0x06] = &gbRom[tmpAddress + 0x2000];
gbMemoryMap[0x07] = &gbRom[tmpAddress + 0x3000]; gbMemoryMap[0x07] = &gbRom[tmpAddress + 0x3000];
} } else {
else
{
if (gbDataMBC1.mapperMemoryModel == 0) { if (gbDataMBC1.mapperMemoryModel == 0) {
// model is 16/8, so we have a high address in use // model is 16/8, so we have a high address in use
tmpAddress |= (gbDataMBC1.mapperROMHighAddress & 3) << 19; tmpAddress |= (gbDataMBC1.mapperROMHighAddress & 3) << 19;
@ -359,8 +346,7 @@ void memoryUpdateMBC3Clock()
gbDataMBC3.mapperDays %= 512; gbDataMBC3.mapperDays %= 512;
gbDataMBC3.mapperControl |= 0x80; gbDataMBC3.mapperControl |= 0x80;
} }
gbDataMBC3.mapperControl = (gbDataMBC3.mapperControl & 0xfe) | gbDataMBC3.mapperControl = (gbDataMBC3.mapperControl & 0xfe) | (gbDataMBC3.mapperDays > 255 ? 1 : 0);
(gbDataMBC3.mapperDays>255 ? 1 : 0);
} }
} }
gbDataMBC3.mapperLastTime = now; gbDataMBC3.mapperLastTime = now;
@ -488,26 +474,20 @@ u8 mapperMBC3ReadRAM(u16 address)
if (!genericflashcardEnable) if (!genericflashcardEnable)
return 0xff; return 0xff;
else else if ((address & 0x1000) >= 0x1000) {
if ((address & 0x1000) >= 0x1000)
{
// The value returned when reading RAM while it's disabled // The value returned when reading RAM while it's disabled
// is constant, exept for the GBASP hardware. // is constant, exept for the GBASP hardware.
// (actually, is the address that read is out of the ROM, the returned value if 0xff...) // (actually, is the address that read is out of the ROM, the returned value if 0xff...)
if (PC.W >= 0xff80) if (PC.W >= 0xff80)
return 0xff; return 0xff;
else else if ((gbHardware & 0x08) && (gbGBCColorType == 2)) {
if ((gbHardware & 0x08) && (gbGBCColorType == 2))
{
if (address & 1) if (address & 1)
return 0xfb; return 0xfb;
else else
return 0x7a; return 0x7a;
} } else
else
return 0x0a; return 0x0a;
} } else
else
return gbDisabledRam[address & 7]; return gbDisabledRam[address & 7];
} }
@ -619,33 +599,26 @@ u8 mapperMBC5ReadRAM(u16 address)
if (!genericflashcardEnable) if (!genericflashcardEnable)
return 0xff; return 0xff;
else else if ((address & 0x1000) >= 0x1000) {
if ((address & 0x1000) >= 0x1000)
{
// The value returned when reading RAM while it's disabled // The value returned when reading RAM while it's disabled
// is constant, exept for the GBASP hardware. // is constant, exept for the GBASP hardware.
// (actually, is the address that read is out of the ROM, the returned value if 0xff...) // (actually, is the address that read is out of the ROM, the returned value if 0xff...)
if (PC.W >= 0xff80) if (PC.W >= 0xff80)
return 0xff; return 0xff;
else else if ((gbHardware & 0x08) && (gbGBCColorType == 2)) {
if ((gbHardware & 0x08) && (gbGBCColorType == 2))
{
if (address & 1) if (address & 1)
return 0xfb; return 0xfb;
else else
return 0x7a; return 0x7a;
} } else
else
return 0x0a; return 0x0a;
} } else
else
return gbDisabledRam[address & 7]; return gbDisabledRam[address & 7];
} }
void memoryUpdateMapMBC5() void memoryUpdateMapMBC5()
{ {
int tmpAddress = (gbDataMBC5.mapperROMBank << 14) | int tmpAddress = (gbDataMBC5.mapperROMBank << 14) | (gbDataMBC5.mapperROMHighAddress << 22);
(gbDataMBC5.mapperROMHighAddress << 22) ;
tmpAddress &= gbRomSizeMask; tmpAddress &= gbRomSizeMask;
gbMemoryMap[0x04] = &gbRom[tmpAddress]; gbMemoryMap[0x04] = &gbRom[tmpAddress];
@ -747,26 +720,20 @@ u8 mapperMBC7ReadRAM(u16 address)
if (!genericflashcardEnable) if (!genericflashcardEnable)
return 0xff; return 0xff;
else else if ((address & 0x1000) >= 0x1000) {
if ((address & 0x1000) >= 0x1000)
{
// The value returned when reading RAM while it's disabled // The value returned when reading RAM while it's disabled
// is constant, exept for the GBASP hardware. // is constant, exept for the GBASP hardware.
// (actually, is the address that read is out of the ROM, the returned value if 0xff...) // (actually, is the address that read is out of the ROM, the returned value if 0xff...)
if (PC.W >= 0xff80) if (PC.W >= 0xff80)
return 0xff; return 0xff;
else else if ((gbHardware & 0x08) && (gbGBCColorType == 2)) {
if ((gbHardware & 0x08) && (gbGBCColorType == 2))
{
if (address & 1) if (address & 1)
return 0xfb; return 0xfb;
else else
return 0x7a; return 0x7a;
} } else
else
return 0x0a; return 0x0a;
} } else
else
return gbDisabledRam[address & 7]; return gbDisabledRam[address & 7];
} }
@ -882,8 +849,7 @@ void mapperMBC7RAM(u16 address, u8 value)
if (gbDataMBC7.count == 1) { if (gbDataMBC7.count == 1) {
gbDataMBC7.state = 4; gbDataMBC7.state = 4;
gbDataMBC7.count = 0; gbDataMBC7.count = 0;
gbDataMBC7.buffer = (gbMemory[0xa000+gbDataMBC7.address*2]<<8)| gbDataMBC7.buffer = (gbMemory[0xa000 + gbDataMBC7.address * 2] << 8) | (gbMemory[0xa000 + gbDataMBC7.address * 2 + 1]);
(gbMemory[0xa000+gbDataMBC7.address*2+1]);
} }
break; break;
case 3: case 3:
@ -1028,7 +994,6 @@ mapperHuC3 gbDataHuC3 = {
0 // RAM read value 0 // RAM read value
}; };
// HuC3 ROM write registers // HuC3 ROM write registers
void mapperHuC3ROM(u16 address, u8 value) void mapperHuC3ROM(u16 address, u8 value)
{ {
@ -1076,8 +1041,7 @@ void mapperHuC3ROM(u16 address, u8 value)
// HuC3 read RAM // HuC3 read RAM
u8 mapperHuC3ReadRAM(u16 address) u8 mapperHuC3ReadRAM(u16 address)
{ {
if(gbDataHuC3.mapperRAMFlag > 0x0b && if (gbDataHuC3.mapperRAMFlag > 0x0b && gbDataHuC3.mapperRAMFlag < 0x0e) {
gbDataHuC3.mapperRAMFlag < 0x0e) {
if (gbDataHuC3.mapperRAMFlag != 0x0c) if (gbDataHuC3.mapperRAMFlag != 0x0c)
return 1; return 1;
return gbDataHuC3.mapperRAMValue; return gbDataHuC3.mapperRAMValue;
@ -1090,8 +1054,7 @@ void mapperHuC3RAM(u16 address, u8 value)
{ {
int* p; int* p;
if(gbDataHuC3.mapperRAMFlag < 0x0b || if (gbDataHuC3.mapperRAMFlag < 0x0b || gbDataHuC3.mapperRAMFlag > 0x0e) {
gbDataHuC3.mapperRAMFlag > 0x0e) {
if (gbDataHuC3.mapperRAMEnable) { if (gbDataHuC3.mapperRAMEnable) {
if (gbRamSize) { if (gbRamSize) {
gbMemoryMap[address >> 12][address & 0x0fff] = value; gbMemoryMap[address >> 12][address & 0x0fff] = value;
@ -1115,16 +1078,10 @@ void mapperHuC3RAM(u16 address, u8 value)
*(p + gbDataHuC3.mapperRegister1++) = value & 0x0f; *(p + gbDataHuC3.mapperRegister1++) = value & 0x0f;
if (gbDataHuC3.mapperRegister1 > 6) if (gbDataHuC3.mapperRegister1 > 6)
gbDataHuC3.mapperRegister1 = 0; gbDataHuC3.mapperRegister1 = 0;
gbDataHuC3.mapperAddress = gbDataHuC3.mapperAddress = (gbDataHuC3.mapperRegister6 << 24) | (gbDataHuC3.mapperRegister5 << 16) | (gbDataHuC3.mapperRegister4 << 8) | (gbDataHuC3.mapperRegister3 << 4) | (gbDataHuC3.mapperRegister2);
(gbDataHuC3.mapperRegister6 << 24) |
(gbDataHuC3.mapperRegister5 << 16) |
(gbDataHuC3.mapperRegister4 << 8) |
(gbDataHuC3.mapperRegister3 << 4) |
(gbDataHuC3.mapperRegister2);
break; break;
case 0x40: case 0x40:
gbDataHuC3.mapperRegister1 = (gbDataHuC3.mapperRegister1 & 0xf0) | gbDataHuC3.mapperRegister1 = (gbDataHuC3.mapperRegister1 & 0xf0) | (value & 0x0f);
(value & 0x0f);
gbDataHuC3.mapperRegister2 = (gbDataHuC3.mapperAddress & 0x0f); gbDataHuC3.mapperRegister2 = (gbDataHuC3.mapperAddress & 0x0f);
gbDataHuC3.mapperRegister3 = ((gbDataHuC3.mapperAddress >> 4) & 0x0f); gbDataHuC3.mapperRegister3 = ((gbDataHuC3.mapperAddress >> 4) & 0x0f);
gbDataHuC3.mapperRegister4 = ((gbDataHuC3.mapperAddress >> 8) & 0x0f); gbDataHuC3.mapperRegister4 = ((gbDataHuC3.mapperAddress >> 8) & 0x0f);
@ -1135,8 +1092,7 @@ void mapperHuC3RAM(u16 address, u8 value)
gbDataHuC3.mapperRAMValue = 0; gbDataHuC3.mapperRAMValue = 0;
break; break;
case 0x50: case 0x50:
gbDataHuC3.mapperRegister1 = (gbDataHuC3.mapperRegister1 & 0x0f) | gbDataHuC3.mapperRegister1 = (gbDataHuC3.mapperRegister1 & 0x0f) | ((value << 4) & 0x0f);
((value << 4)&0x0f);
break; break;
default: default:
gbDataHuC3.mapperRAMValue = 1; gbDataHuC3.mapperRAMValue = 1;
@ -1213,7 +1169,6 @@ mapperTAMA5 gbDataTAMA5 = {
(time_t)-1 // last time (time_t)-1 // last time
}; };
void memoryUpdateTAMA5Clock() void memoryUpdateTAMA5Clock()
{ {
if ((gbDataTAMA5.mapperYears & 3) == 0) if ((gbDataTAMA5.mapperYears & 3) == 0)
@ -1246,20 +1201,16 @@ void memoryUpdateTAMA5Clock()
if (gbDataTAMA5.mapperHours > 23) { if (gbDataTAMA5.mapperHours > 23) {
gbDataTAMA5.mapperHours -= 24; gbDataTAMA5.mapperHours -= 24;
diff++; diff++;
} }
time_t days = diff; time_t days = diff;
while (days) while (days) {
{
gbDataTAMA5.mapperDays++; gbDataTAMA5.mapperDays++;
days--; days--;
if (gbDataTAMA5.mapperDays>gbDaysinMonth[gbDataTAMA5.mapperMonths-1]) if (gbDataTAMA5.mapperDays > gbDaysinMonth[gbDataTAMA5.mapperMonths - 1]) {
{
gbDataTAMA5.mapperDays = 1; gbDataTAMA5.mapperDays = 1;
gbDataTAMA5.mapperMonths++; gbDataTAMA5.mapperMonths++;
if (gbDataTAMA5.mapperMonths>12) if (gbDataTAMA5.mapperMonths > 12) {
{
gbDataTAMA5.mapperMonths = 1; gbDataTAMA5.mapperMonths = 1;
gbDataTAMA5.mapperYears++; gbDataTAMA5.mapperYears++;
if ((gbDataTAMA5.mapperYears & 3) == 0) if ((gbDataTAMA5.mapperYears & 3) == 0)
@ -1271,18 +1222,13 @@ void memoryUpdateTAMA5Clock()
} }
} }
gbDataTAMA5.mapperLastTime = now; gbDataTAMA5.mapperLastTime = now;
} }
// TAMA5 RAM write // TAMA5 RAM write
void mapperTAMA5RAM(u16 address, u8 value) void mapperTAMA5RAM(u16 address, u8 value)
{ {
if ((address & 0xffff) <= 0xa001) if ((address & 0xffff) <= 0xa001) {
{ switch (address & 1) {
switch (address & 1)
{
case 0: // 'Values' Register case 0: // 'Values' Register
{ {
value &= 0xf; value &= 0xf;
@ -1294,8 +1240,7 @@ void mapperTAMA5RAM(u16 address, u8 value)
if ((gbDataTAMA5.mapperCommandNumber & 0xe) == 0) // Read Command !!! if ((gbDataTAMA5.mapperCommandNumber & 0xe) == 0) // Read Command !!!
{ {
gbDataTAMA5.mapperROMBank = gbDataTAMA5.mapperCommands[0] | gbDataTAMA5.mapperROMBank = gbDataTAMA5.mapperCommands[0] | (gbDataTAMA5.mapperCommands[1] << 4);
(gbDataTAMA5.mapperCommands[1]<<4);
int tmpAddress = (gbDataTAMA5.mapperROMBank << 14); int tmpAddress = (gbDataTAMA5.mapperROMBank << 14);
@ -1306,23 +1251,16 @@ void mapperTAMA5RAM(u16 address, u8 value)
gbMemoryMap[0x07] = &gbRom[tmpAddress + 0x3000]; gbMemoryMap[0x07] = &gbRom[tmpAddress + 0x3000];
gbDataTAMA5.mapperCommands[0x0f] = 0; gbDataTAMA5.mapperCommands[0x0f] = 0;
} } else if ((gbDataTAMA5.mapperCommandNumber & 0xe) == 4) {
else if ((gbDataTAMA5.mapperCommandNumber & 0xe) == 4)
{
gbDataTAMA5.mapperCommands[0x0f] = 1; gbDataTAMA5.mapperCommands[0x0f] = 1;
if (gbDataTAMA5.mapperCommandNumber == 4) if (gbDataTAMA5.mapperCommandNumber == 4)
gbDataTAMA5.mapperCommands[5] = 0; // correct ? gbDataTAMA5.mapperCommands[5] = 0; // correct ?
} } else if ((gbDataTAMA5.mapperCommandNumber & 0xe) == 6) {
else if ((gbDataTAMA5.mapperCommandNumber & 0xe) == 6) gbDataTAMA5.mapperRamByteSelect = (gbDataTAMA5.mapperCommands[7] << 4) | (gbDataTAMA5.mapperCommands[6] & 0x0f);
{
gbDataTAMA5.mapperRamByteSelect = (gbDataTAMA5.mapperCommands[7]<<4) |
(gbDataTAMA5.mapperCommands[6]&0x0f);
// Write Commands !!! // Write Commands !!!
if (gbDataTAMA5.mapperCommands[0x0f] && (gbDataTAMA5.mapperCommandNumber == 7)) if (gbDataTAMA5.mapperCommands[0x0f] && (gbDataTAMA5.mapperCommandNumber == 7)) {
{ int data = (gbDataTAMA5.mapperCommands[0x04] & 0x0f) | (gbDataTAMA5.mapperCommands[0x05] << 4);
int data = (gbDataTAMA5.mapperCommands[0x04] & 0x0f) |
(gbDataTAMA5.mapperCommands[0x05] <<4);
// Not sure when the write command should reset... // Not sure when the write command should reset...
// but it doesn't seem to matter. // but it doesn't seem to matter.
@ -1330,8 +1268,7 @@ void mapperTAMA5RAM(u16 address, u8 value)
if (gbDataTAMA5.mapperRamByteSelect == 0x8) // Timer stuff if (gbDataTAMA5.mapperRamByteSelect == 0x8) // Timer stuff
{ {
switch (data & 0xf) switch (data & 0xf) {
{
case 0x7: case 0x7:
gbDataTAMA5.mapperDays = ((gbDataTAMA5.mapperDays) / 10) * 10 + (data >> 4); gbDataTAMA5.mapperDays = ((gbDataTAMA5.mapperDays) / 10) * 10 + (data >> 4);
break; break;
@ -1348,14 +1285,12 @@ void mapperTAMA5RAM(u16 address, u8 value)
gbDataTAMA5.mapperYears = ((gbDataTAMA5.mapperYears) % 1000) + (data >> 4) * 1000; gbDataTAMA5.mapperYears = ((gbDataTAMA5.mapperYears) % 1000) + (data >> 4) * 1000;
break; break;
case 0xc: case 0xc:
gbDataTAMA5.mapperYears = (gbDataTAMA5.mapperYears%100) + (gbDataTAMA5.mapperYears/1000)*1000 + gbDataTAMA5.mapperYears = (gbDataTAMA5.mapperYears % 100) + (gbDataTAMA5.mapperYears / 1000) * 1000 + (data >> 4) * 100;
(data >>4)*100;
break; break;
default: default:
break; break;
} }
} } else if (gbDataTAMA5.mapperRamByteSelect == 0x18) // Timer stuff again
else if (gbDataTAMA5.mapperRamByteSelect == 0x18) // Timer stuff again
{ {
memoryUpdateTAMA5Clock(); memoryUpdateTAMA5Clock();
gbDataTAMA5.mapperLSeconds = gbDataTAMA5.mapperSeconds; gbDataTAMA5.mapperLSeconds = gbDataTAMA5.mapperSeconds;
@ -1378,8 +1313,7 @@ void mapperTAMA5RAM(u16 address, u8 value)
int Years3 = (gbDataTAMA5.mapperLYears / 100) % 10; int Years3 = (gbDataTAMA5.mapperLYears / 100) % 10;
int Years4 = (gbDataTAMA5.mapperLYears / 1000); int Years4 = (gbDataTAMA5.mapperLYears / 1000);
switch (data & 0x0f) switch (data & 0x0f) {
{
// I guess cases 0 and 1 are used for secondsL and secondsH // I guess cases 0 and 1 are used for secondsL and secondsH
// so the game would update the timer values on screen when // so the game would update the timer values on screen when
// the seconds reset to 0... ? // the seconds reset to 0... ?
@ -1420,28 +1354,20 @@ void mapperTAMA5RAM(u16 address, u8 value)
time(&gbDataTAMA5.mapperLastTime); time(&gbDataTAMA5.mapperLastTime);
gbMemoryMap[0xa][0] = 1; gbMemoryMap[0xa][0] = 1;
} } else if (gbDataTAMA5.mapperRamByteSelect == 0x28) // Timer stuff again
else if (gbDataTAMA5.mapperRamByteSelect == 0x28) // Timer stuff again
{ {
if ((data & 0xf) == 0xb) if ((data & 0xf) == 0xb)
gbDataTAMA5.mapperYears = ((gbDataTAMA5.mapperYears >> 2) << 2) + (data & 3); gbDataTAMA5.mapperYears = ((gbDataTAMA5.mapperYears >> 2) << 2) + (data & 3);
} } else if (gbDataTAMA5.mapperRamByteSelect == 0x44) {
else if (gbDataTAMA5.mapperRamByteSelect == 0x44)
{
gbDataTAMA5.mapperMinutes = (data / 16) * 10 + data % 16; gbDataTAMA5.mapperMinutes = (data / 16) * 10 + data % 16;
} } else if (gbDataTAMA5.mapperRamByteSelect == 0x54) {
else if (gbDataTAMA5.mapperRamByteSelect == 0x54)
{
gbDataTAMA5.mapperHours = (data / 16) * 10 + data % 16; gbDataTAMA5.mapperHours = (data / 16) * 10 + data % 16;
} } else {
else
{
gbTAMA5ram[gbDataTAMA5.mapperRamByteSelect] = data; gbTAMA5ram[gbDataTAMA5.mapperRamByteSelect] = data;
} }
} }
} }
} } break;
break;
case 1: // 'Commands' Register case 1: // 'Commands' Register
{ {
gbMemoryMap[0xa][1] = gbDataTAMA5.mapperCommandNumber = value; gbMemoryMap[0xa][1] = gbDataTAMA5.mapperCommandNumber = value;
@ -1450,8 +1376,7 @@ void mapperTAMA5RAM(u16 address, u8 value)
// However as I couldn't find any 'copy' command // However as I couldn't find any 'copy' command
// (that seems to be needed for the saving system to work) // (that seems to be needed for the saving system to work)
// I put it there... // I put it there...
if (value == 0x0a) if (value == 0x0a) {
{
for (int i = 0; i < 0x10; i++) for (int i = 0; i < 0x10; i++)
for (int j = 0; j < 0x10; j++) for (int j = 0; j < 0x10; j++)
if (!(j & 2)) if (!(j & 2))
@ -1461,13 +1386,9 @@ void mapperTAMA5RAM(u16 address, u8 value)
gbMemoryMap[0xe][k] = gbTAMA5ram[k];*/ gbMemoryMap[0xe][k] = gbTAMA5ram[k];*/
gbMemoryMap[0xa][0] = gbDataTAMA5.mapperRAMEnable = 1; gbMemoryMap[0xa][0] = gbDataTAMA5.mapperRAMEnable = 1;
} } else {
else if ((value & 0x0e) == 0x0c) {
{ gbDataTAMA5.mapperRamByteSelect = gbDataTAMA5.mapperCommands[6] | (gbDataTAMA5.mapperCommands[7] << 4);
if ((value & 0x0e) == 0x0c)
{
gbDataTAMA5.mapperRamByteSelect = gbDataTAMA5.mapperCommands[6] |
(gbDataTAMA5.mapperCommands[7]<<4);
u8 byte = gbTAMA5ram[gbDataTAMA5.mapperRamByteSelect]; u8 byte = gbTAMA5ram[gbDataTAMA5.mapperRamByteSelect];
@ -1479,9 +1400,7 @@ void mapperTAMA5RAM(u16 address, u8 value)
break; break;
} }
} }
} } else {
else
{
if (gbDataTAMA5.mapperRAMEnable) { if (gbDataTAMA5.mapperRAMEnable) {
if (gbDataTAMA5.mapperRAMBank != -1) { if (gbDataTAMA5.mapperRAMBank != -1) {
if (gbRamSize) { if (gbRamSize) {
@ -1493,14 +1412,12 @@ void mapperTAMA5RAM(u16 address, u8 value)
} }
} }
// TAMA5 read RAM // TAMA5 read RAM
u8 mapperTAMA5ReadRAM(u16 address) u8 mapperTAMA5ReadRAM(u16 address)
{ {
return gbMemoryMap[address >> 12][address & 0xfff]; return gbMemoryMap[address >> 12][address & 0xfff];
} }
void memoryUpdateMapTAMA5() void memoryUpdateMapTAMA5()
{ {
int tmpAddress = (gbDataTAMA5.mapperROMBank << 14); int tmpAddress = (gbDataTAMA5.mapperROMBank << 14);
@ -1552,8 +1469,7 @@ void mapperMMM01ROM(u16 address, u8 value)
if (gbDataMMM01.mapperMemoryModel == 0) { if (gbDataMMM01.mapperMemoryModel == 0) {
// model is 16/8, so we have a high address in use // model is 16/8, so we have a high address in use
tmpAddress |= (gbDataMMM01.mapperROMHighAddress) << 19; tmpAddress |= (gbDataMMM01.mapperROMHighAddress) << 19;
} } else
else
tmpAddress |= gbDataMMM01.mapperRomBank0Remapping << 18; tmpAddress |= gbDataMMM01.mapperRomBank0Remapping << 18;
tmpAddress &= gbRomSizeMask; tmpAddress &= gbRomSizeMask;
@ -1658,7 +1574,6 @@ void mapperGGROM(u16 address, u8 value)
} }
} }
// GS3 Used to emulate the GS V3.0 rom bank switching // GS3 Used to emulate the GS V3.0 rom bank switching
mapperGS3 gbDataGS3 = { 1 }; // ROM bank mapperGS3 gbDataGS3 = { 1 }; // ROM bank
@ -1685,8 +1600,7 @@ void mapperGS3ROM(u16 address, u8 value)
gbDataGS3.mapperROMBank = value; gbDataGS3.mapperROMBank = value;
gbMemoryMap[0x04] = &gbRom[tmpAddress]; gbMemoryMap[0x04] = &gbRom[tmpAddress];
gbMemoryMap[0x05] = &gbRom[tmpAddress + 0x1000]; gbMemoryMap[0x05] = &gbRom[tmpAddress + 0x1000];
} } else
else
gbMemoryMap[address >> 12][address & 0x0fff] = value; gbMemoryMap[address >> 12][address & 0x0fff] = value;
break; break;
} }

View File

@ -1,6 +1,6 @@
#include <stdio.h>
#include <memory.h>
#include "../System.h" #include "../System.h"
#include <memory.h>
#include <stdio.h>
u8 gbPrinterStatus = 0; u8 gbPrinterStatus = 0;
int gbPrinterState = 0; int gbPrinterState = 0;
@ -19,8 +19,7 @@ bool gbPrinterCheckCRC()
crc += gbPrinterPacket[i]; crc += gbPrinterPacket[i];
} }
int msgCrc = gbPrinterPacket[6+gbPrinterDataSize] + int msgCrc = gbPrinterPacket[6 + gbPrinterDataSize] + (gbPrinterPacket[7 + gbPrinterDataSize] << 8);
(gbPrinterPacket[7+gbPrinterDataSize]<<8);
return msgCrc == crc; return msgCrc == crc;
} }

View File

@ -1,9 +1,9 @@
#include <stdlib.h>
#include <memory.h> #include <memory.h>
#include <stdlib.h>
#include "../System.h" #include "../System.h"
#include "../common/Port.h"
#include "../Util.h" #include "../Util.h"
#include "../common/Port.h"
#include "gb.h" #include "gb.h"
#include "gbGlobals.h" #include "gbGlobals.h"
@ -111,19 +111,15 @@ void gbSgbShutdown()
void gbSgbFillScreen(u16 color) void gbSgbFillScreen(u16 color)
{ {
switch (systemColorDepth) { switch (systemColorDepth) {
case 16: case 16: {
{
for (int y = 0; y < 144; y++) { for (int y = 0; y < 144; y++) {
int yLine = (y+gbBorderRowSkip+1)*(gbBorderLineSkip+2) + int yLine = (y + gbBorderRowSkip + 1) * (gbBorderLineSkip + 2) + gbBorderColumnSkip;
gbBorderColumnSkip;
u16* dest = (u16*)pix + yLine; u16* dest = (u16*)pix + yLine;
for (register int x = 0; x < 160; x++) for (register int x = 0; x < 160; x++)
gbSgbDraw16Bit(dest++, color); gbSgbDraw16Bit(dest++, color);
} }
} } break;
break; case 24: {
case 24:
{
for (int y = 0; y < 144; y++) { for (int y = 0; y < 144; y++) {
int yLine = (y + gbBorderRowSkip) * gbBorderLineSkip + gbBorderColumnSkip; int yLine = (y + gbBorderRowSkip) * gbBorderLineSkip + gbBorderColumnSkip;
u8* dest = (u8*)pix + yLine * 3; u8* dest = (u8*)pix + yLine * 3;
@ -132,10 +128,8 @@ void gbSgbFillScreen(u16 color)
dest += 3; dest += 3;
} }
} }
} } break;
break; case 32: {
case 32:
{
for (int y = 0; y < 144; y++) { for (int y = 0; y < 144; y++) {
int yLine = (y + gbBorderRowSkip + 1) * (gbBorderLineSkip + 1) + gbBorderColumnSkip; int yLine = (y + gbBorderRowSkip + 1) * (gbBorderLineSkip + 1) + gbBorderColumnSkip;
u32* dest = (u32*)pix + yLine; u32* dest = (u32*)pix + yLine;
@ -143,8 +137,7 @@ void gbSgbFillScreen(u16 color)
gbSgbDraw32Bit(dest++, color); gbSgbDraw32Bit(dest++, color);
} }
} }
} } break;
break;
} }
} }
@ -217,8 +210,6 @@ void gbSgbDrawBorderTile(int x, int y, int tile, int attr)
u8 c = *tileAddress2++; u8 c = *tileAddress2++;
u8 d = *tileAddress2++; u8 d = *tileAddress2++;
u8 yyy; u8 yyy;
if (!flipY) if (!flipY)
yyy = yy; yyy = yy;
@ -419,13 +410,11 @@ void gbSgbAttributeBlock()
for (u8 y = 0; y < 18; y++) { for (u8 y = 0; y < 18; y++) {
for (u8 x = 0; x < 20; x++) { for (u8 x = 0; x < 20; x++) {
if(x < startH || y < startV || if (x < startH || y < startV || x > endH || y > endV) {
x > endH || y > endV) {
// outside // outside
if (controlCode & 0x04) if (controlCode & 0x04)
*toAddress = (paletteDesignation >> 4) & 0x03; *toAddress = (paletteDesignation >> 4) & 0x03;
} else if(x > startH && x < endH && } else if (x > startH && x < endH && y > startV && y < endV) {
y > startV && y < endV) {
// inside // inside
if (controlCode & 0x01) if (controlCode & 0x01)
*toAddress = paletteDesignation & 0x03; *toAddress = paletteDesignation & 0x03;

View File

@ -1,13 +1,13 @@
#include <string.h> #include <string.h>
#include "../gba/Sound.h"
#include "../Util.h" #include "../Util.h"
#include "../gba/Sound.h"
#include "gb.h"
#include "gbGlobals.h" #include "gbGlobals.h"
#include "gbSound.h" #include "gbSound.h"
#include "gb.h"
#include "../apu/Gb_Apu.h"
#include "../apu/Effects_Buffer.h" #include "../apu/Effects_Buffer.h"
#include "../apu/Gb_Apu.h"
extern long soundSampleRate; // current sound quality extern long soundSampleRate; // current sound quality
@ -62,8 +62,7 @@ static void apply_effects()
stereo_buffer->config().surround = gb_effects_config_current.surround; stereo_buffer->config().surround = gb_effects_config_current.surround;
stereo_buffer->apply_config(); stereo_buffer->apply_config();
for ( int i = 0; i < chan_count; i++ ) for (int i = 0; i < chan_count; i++) {
{
Multi_Buffer::channel_t ch = { 0, 0, 0 }; Multi_Buffer::channel_t ch = { 0, 0, 0 };
if (prevSoundEnable >> i & 1) if (prevSoundEnable >> i & 1)
ch = stereo_buffer->channel(i); ch = stereo_buffer->channel(i);
@ -86,8 +85,7 @@ static void apply_volume()
void gbSoundTick() void gbSoundTick()
{ {
if ( gb_apu && stereo_buffer ) if (gb_apu && stereo_buffer) {
{
// Run sound hardware to present // Run sound hardware to present
end_frame(SOUND_CLOCK_TICKS * ticks_to_time); end_frame(SOUND_CLOCK_TICKS * ticks_to_time);
@ -95,7 +93,8 @@ void gbSoundTick()
// Update effects config if it was changed // Update effects config if it was changed
if (memcmp(&gb_effects_config_current, &gb_effects_config, if (memcmp(&gb_effects_config_current, &gb_effects_config,
sizeof gb_effects_config ) || soundGetEnable() != prevSoundEnable ) sizeof gb_effects_config)
|| soundGetEnable() != prevSoundEnable)
apply_effects(); apply_effects();
if (soundVolume_ != soundGetVolume()) if (soundVolume_ != soundGetVolume())
@ -122,8 +121,7 @@ static void reset_apu()
static void remake_stereo_buffer() static void remake_stereo_buffer()
{ {
// APU // APU
if ( !gb_apu ) if (!gb_apu) {
{
gb_apu = new Gb_Apu; // TODO: handle errors gb_apu = new Gb_Apu; // TODO: handle errors
reset_apu(); reset_apu();
} }
@ -133,7 +131,8 @@ static void remake_stereo_buffer()
stereo_buffer = 0; stereo_buffer = 0;
stereo_buffer = new Simple_Effects_Buffer; // TODO: handle out of memory stereo_buffer = new Simple_Effects_Buffer; // TODO: handle out of memory
if ( stereo_buffer->set_sample_rate( soundSampleRate ) ) { } // TODO: handle out of memory if (stereo_buffer->set_sample_rate(soundSampleRate)) {
} // TODO: handle out of memory
stereo_buffer->clock_rate(gb_apu->clock_rate); stereo_buffer->clock_rate(gb_apu->clock_rate);
// Multi_Buffer // Multi_Buffer
@ -141,7 +140,8 @@ static void remake_stereo_buffer()
Multi_Buffer::wave_type + 1, Multi_Buffer::wave_type + 2, Multi_Buffer::wave_type + 1, Multi_Buffer::wave_type + 2,
Multi_Buffer::wave_type + 3, Multi_Buffer::mixed_type + 1 Multi_Buffer::wave_type + 3, Multi_Buffer::mixed_type + 1
}; };
if ( stereo_buffer->set_channel_count( chan_count, chan_types ) ) { } // TODO: handle errors if (stereo_buffer->set_channel_count(chan_count, chan_types)) {
} // TODO: handle errors
// Volume Level // Volume Level
apply_effects(); apply_effects();
@ -150,17 +150,16 @@ static void remake_stereo_buffer()
void gbSoundSetDeclicking(bool enable) void gbSoundSetDeclicking(bool enable)
{ {
if ( declicking != enable ) if (declicking != enable) {
{
declicking = enable; declicking = enable;
if ( gb_apu ) if (gb_apu) {
{
// Can't change sound hardware mode without resetting APU, so save/load // Can't change sound hardware mode without resetting APU, so save/load
// state around mode change // state around mode change
gb_apu_state_t state; gb_apu_state_t state;
gb_apu->save_state(&state); gb_apu->save_state(&state);
reset_apu(); reset_apu();
if ( gb_apu->load_state( state ) ) { } // ignore error if (gb_apu->load_state(state)) {
} // ignore error
} }
} }
} }
@ -220,16 +219,12 @@ void gbSoundReset()
void gbSoundSetSampleRate(long sampleRate) void gbSoundSetSampleRate(long sampleRate)
{ {
if ( soundSampleRate != sampleRate ) if (soundSampleRate != sampleRate) {
{ if (systemCanChangeSoundQuality()) {
if ( systemCanChangeSoundQuality() )
{
soundShutdown(); soundShutdown();
soundSampleRate = sampleRate; soundSampleRate = sampleRate;
soundInit(); soundInit();
} } else {
else
{
soundSampleRate = sampleRate; soundSampleRate = sampleRate;
} }
@ -244,14 +239,19 @@ static struct {
static char dummy_state[735 * 2]; static char dummy_state[735 * 2];
#define SKIP( type, name ) { dummy_state, sizeof (type) } #define SKIP(type, name) \
{ \
dummy_state, sizeof(type) \
}
#define LOAD( type, name ) { &name, sizeof (type) } #define LOAD(type, name) \
{ \
&name, sizeof(type) \
}
// Old save state support // Old save state support
static variable_desc gbsound_format [] = static variable_desc gbsound_format[] = {
{
SKIP(int, soundPaused), SKIP(int, soundPaused),
SKIP(int, soundPlay), SKIP(int, soundPlay),
SKIP(int, soundTicks), SKIP(int, soundTicks),
@ -310,8 +310,7 @@ static variable_desc gbsound_format [] =
{ NULL, 0 } { NULL, 0 }
}; };
static variable_desc gbsound_format2 [] = static variable_desc gbsound_format2[] = {
{
SKIP(int, sound1ATLreload), SKIP(int, sound1ATLreload),
SKIP(int, freq1low), SKIP(int, freq1low),
SKIP(int, freq1high), SKIP(int, freq1high),
@ -326,8 +325,7 @@ static variable_desc gbsound_format2 [] =
{ NULL, 0 } { NULL, 0 }
}; };
static variable_desc gbsound_format3 [] = static variable_desc gbsound_format3[] = {
{
SKIP(u8[2 * 735], soundBuffer), SKIP(u8[2 * 735], soundBuffer),
SKIP(u8[2 * 735], soundBuffer), SKIP(u8[2 * 735], soundBuffer),
SKIP(u16[735], soundFinalWave), SKIP(u16[735], soundFinalWave),
@ -336,17 +334,33 @@ static variable_desc gbsound_format3 [] =
enum { enum {
nr10 = 0, nr10 = 0,
nr11, nr12, nr13, nr14, nr11,
nr20, nr21, nr22, nr23, nr24, nr12,
nr30, nr31, nr32, nr33, nr34, nr13,
nr40, nr41, nr42, nr43, nr44, nr14,
nr50, nr51, nr52 nr20,
nr21,
nr22,
nr23,
nr24,
nr30,
nr31,
nr32,
nr33,
nr34,
nr40,
nr41,
nr42,
nr43,
nr44,
nr50,
nr51,
nr52
}; };
static void gbSoundReadGameOld(int version, gzFile gzFile) static void gbSoundReadGameOld(int version, gzFile gzFile)
{ {
if ( version == 11 ) if (version == 11) {
{
// Version 11 didn't save any state // Version 11 didn't save any state
// TODO: same for version 10? // TODO: same for version 10?
state.apu.regs[nr50] = 0x77; // volume at max state.apu.regs[nr50] = 0x77; // volume at max
@ -384,8 +398,7 @@ static void gbSoundReadGameOld(int version,gzFile gzFile)
// New state format // New state format
static variable_desc gb_state [] = static variable_desc gb_state[] = {
{
LOAD(int, state.version), // room_for_expansion will be used by later versions LOAD(int, state.version), // room_for_expansion will be used by later versions
// APU // APU