some more formating things etc
This commit is contained in:
parent
a49edee427
commit
48086ba62f
2737
src/gb/GB.cpp
2737
src/gb/GB.cpp
File diff suppressed because it is too large
Load Diff
28
src/gb/gb.h
28
src/gb/gb.h
|
@ -19,29 +19,29 @@ typedef union {
|
||||||
|
|
||||||
extern gbRegister AF, BC, DE, HL, SP, PC;
|
extern gbRegister AF, BC, DE, HL, SP, PC;
|
||||||
extern uint16_t IFF;
|
extern uint16_t IFF;
|
||||||
int gbDis(char *, u16);
|
int gbDis(char*, u16);
|
||||||
|
|
||||||
bool gbLoadRom(const char *);
|
bool gbLoadRom(const char*);
|
||||||
bool gbUpdateSizes();
|
bool gbUpdateSizes();
|
||||||
void gbEmulate(int);
|
void gbEmulate(int);
|
||||||
void gbWriteMemory(register uint16_t, register uint8_t);
|
void gbWriteMemory(register uint16_t, register uint8_t);
|
||||||
void gbDrawLine();
|
void gbDrawLine();
|
||||||
bool gbIsGameboyRom(const char *);
|
bool gbIsGameboyRom(const char*);
|
||||||
void gbGetHardwareType();
|
void gbGetHardwareType();
|
||||||
void gbReset();
|
void gbReset();
|
||||||
void gbCleanUp();
|
void gbCleanUp();
|
||||||
void gbCPUInit(const char *, bool);
|
void gbCPUInit(const char*, bool);
|
||||||
bool gbWriteBatteryFile(const char *);
|
bool gbWriteBatteryFile(const char*);
|
||||||
bool gbWriteBatteryFile(const char *, bool);
|
bool gbWriteBatteryFile(const char*, bool);
|
||||||
bool gbReadBatteryFile(const char *);
|
bool gbReadBatteryFile(const char*);
|
||||||
bool gbWriteSaveState(const char *);
|
bool gbWriteSaveState(const char*);
|
||||||
bool gbWriteMemSaveState(char *, int, long &);
|
bool gbWriteMemSaveState(char*, int, long&);
|
||||||
bool gbReadSaveState(const char *);
|
bool gbReadSaveState(const char*);
|
||||||
bool gbReadMemSaveState(char *, int);
|
bool gbReadMemSaveState(char*, int);
|
||||||
void gbSgbRenderBorder();
|
void gbSgbRenderBorder();
|
||||||
bool gbWritePNGFile(const char *);
|
bool gbWritePNGFile(const char*);
|
||||||
bool gbWriteBMPFile(const char *);
|
bool gbWriteBMPFile(const char*);
|
||||||
bool gbReadGSASnapshot(const char *);
|
bool gbReadGSASnapshot(const char*);
|
||||||
|
|
||||||
extern int gbHardware;
|
extern int gbHardware;
|
||||||
|
|
||||||
|
|
|
@ -1,31 +1,31 @@
|
||||||
#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;
|
||||||
int gbNextCheat = 0;
|
int gbNextCheat = 0;
|
||||||
bool gbCheatMap[0x10000];
|
bool gbCheatMap[0x10000];
|
||||||
|
|
||||||
#define GBCHEAT_IS_HEX(a) ( ((a)>='A' && (a) <='F') || ((a) >='0' && (a) <= '9'))
|
#define GBCHEAT_IS_HEX(a) (((a) >= 'A' && (a) <= 'F') || ((a) >= '0' && (a) <= '9'))
|
||||||
#define GBCHEAT_HEX_VALUE(a) ( (a) >= 'A' ? (a) - 'A' + 10 : (a) - '0')
|
#define GBCHEAT_HEX_VALUE(a) ((a) >= 'A' ? (a) - 'A' + 10 : (a) - '0')
|
||||||
|
|
||||||
void gbCheatUpdateMap()
|
void gbCheatUpdateMap()
|
||||||
{
|
{
|
||||||
memset(gbCheatMap, 0, 0x10000);
|
memset(gbCheatMap, 0, 0x10000);
|
||||||
|
|
||||||
for(int i = 0; i < gbCheatNumber; i++) {
|
for (int i = 0; i < gbCheatNumber; i++) {
|
||||||
if(gbCheatList[i].enabled)
|
if (gbCheatList[i].enabled)
|
||||||
gbCheatMap[gbCheatList[i].address] = true;
|
gbCheatMap[gbCheatList[i].address] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,80 +33,78 @@ void gbCheatUpdateMap()
|
||||||
void gbCheatsSaveGame(gzFile gzFile)
|
void gbCheatsSaveGame(gzFile gzFile)
|
||||||
{
|
{
|
||||||
utilWriteInt(gzFile, gbCheatNumber);
|
utilWriteInt(gzFile, gbCheatNumber);
|
||||||
if(gbCheatNumber>0)
|
if (gbCheatNumber > 0)
|
||||||
utilGzWrite(gzFile, &gbCheatList[0], sizeof(gbCheat)*gbCheatNumber);
|
utilGzWrite(gzFile, &gbCheatList[0], sizeof(gbCheat) * gbCheatNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gbCheatsReadGame(gzFile gzFile, int version)
|
void gbCheatsReadGame(gzFile gzFile, int version)
|
||||||
{
|
{
|
||||||
if(version <= 8) {
|
if (version <= 8) {
|
||||||
int gbGgOn = utilReadInt(gzFile);
|
int gbGgOn = utilReadInt(gzFile);
|
||||||
|
|
||||||
if(gbGgOn) {
|
if (gbGgOn) {
|
||||||
int n = utilReadInt(gzFile);
|
int n = utilReadInt(gzFile);
|
||||||
gbXxCheat tmpCheat;
|
gbXxCheat tmpCheat;
|
||||||
for(int i = 0; i < n; i++) {
|
for (int i = 0; i < n; i++) {
|
||||||
utilGzRead(gzFile,&tmpCheat, sizeof(gbXxCheat));
|
utilGzRead(gzFile, &tmpCheat, sizeof(gbXxCheat));
|
||||||
gbAddGgCheat(tmpCheat.cheatCode, tmpCheat.cheatDesc);
|
gbAddGgCheat(tmpCheat.cheatCode, tmpCheat.cheatDesc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int gbGsOn = utilReadInt(gzFile);
|
int gbGsOn = utilReadInt(gzFile);
|
||||||
|
|
||||||
if(gbGsOn) {
|
if (gbGsOn) {
|
||||||
int n = utilReadInt(gzFile);
|
int n = utilReadInt(gzFile);
|
||||||
gbXxCheat tmpCheat;
|
gbXxCheat tmpCheat;
|
||||||
for(int i = 0; i < n; i++) {
|
for (int i = 0; i < n; i++) {
|
||||||
utilGzRead(gzFile,&tmpCheat, sizeof(gbXxCheat));
|
utilGzRead(gzFile, &tmpCheat, sizeof(gbXxCheat));
|
||||||
gbAddGsCheat(tmpCheat.cheatCode, tmpCheat.cheatDesc);
|
gbAddGsCheat(tmpCheat.cheatCode, tmpCheat.cheatDesc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
gbCheatNumber = utilReadInt(gzFile);
|
gbCheatNumber = utilReadInt(gzFile);
|
||||||
|
|
||||||
if(gbCheatNumber>0) {
|
if (gbCheatNumber > 0) {
|
||||||
utilGzRead(gzFile, &gbCheatList[0], sizeof(gbCheat)*gbCheatNumber);
|
utilGzRead(gzFile, &gbCheatList[0], sizeof(gbCheat) * gbCheatNumber);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gbCheatUpdateMap();
|
gbCheatUpdateMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void gbCheatsReadGameSkip(gzFile gzFile, int version)
|
void gbCheatsReadGameSkip(gzFile gzFile, int version)
|
||||||
{
|
{
|
||||||
if( version <= 8 ) {
|
if (version <= 8) {
|
||||||
int gbGgOn = utilReadInt( gzFile );
|
int gbGgOn = utilReadInt(gzFile);
|
||||||
if( gbGgOn ) {
|
if (gbGgOn) {
|
||||||
int n = utilReadInt( gzFile );
|
int n = utilReadInt(gzFile);
|
||||||
if( n > 0 ) {
|
if (n > 0) {
|
||||||
utilGzSeek( gzFile, n * sizeof(gbXxCheat), SEEK_CUR );
|
utilGzSeek(gzFile, n * sizeof(gbXxCheat), SEEK_CUR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int gbGsOn = utilReadInt( gzFile );
|
int gbGsOn = utilReadInt(gzFile);
|
||||||
if( gbGsOn ) {
|
if (gbGsOn) {
|
||||||
int n = utilReadInt(gzFile);
|
int n = utilReadInt(gzFile);
|
||||||
if( n > 0 ) {
|
if (n > 0) {
|
||||||
utilGzSeek( gzFile, n * sizeof(gbXxCheat), SEEK_CUR );
|
utilGzSeek(gzFile, n * sizeof(gbXxCheat), SEEK_CUR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int n = utilReadInt( gzFile );
|
int n = utilReadInt(gzFile);
|
||||||
|
|
||||||
if( n > 0 ) {
|
if (n > 0) {
|
||||||
utilGzSeek( gzFile, n * sizeof(gbCheat), SEEK_CUR );
|
utilGzSeek(gzFile, n * sizeof(gbCheat), SEEK_CUR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void gbCheatsSaveCheatList(const char* file)
|
||||||
void gbCheatsSaveCheatList(const char *file)
|
|
||||||
{
|
{
|
||||||
if(gbCheatNumber == 0)
|
if (gbCheatNumber == 0)
|
||||||
return;
|
return;
|
||||||
FILE *f = fopen(file, "wb");
|
FILE* f = fopen(file, "wb");
|
||||||
if(f == NULL)
|
if (f == NULL)
|
||||||
return;
|
return;
|
||||||
int version = 1;
|
int version = 1;
|
||||||
fwrite(&version, 1, sizeof(version), f);
|
fwrite(&version, 1, sizeof(version), f);
|
||||||
|
@ -117,7 +115,7 @@ void gbCheatsSaveCheatList(const char *file)
|
||||||
fclose(f);
|
fclose(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool gbCheatsLoadCheatList(const char *file)
|
bool gbCheatsLoadCheatList(const char* file)
|
||||||
{
|
{
|
||||||
gbCheatNumber = 0;
|
gbCheatNumber = 0;
|
||||||
|
|
||||||
|
@ -125,19 +123,19 @@ bool gbCheatsLoadCheatList(const char *file)
|
||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
FILE *f = fopen(file, "rb");
|
FILE* f = fopen(file, "rb");
|
||||||
|
|
||||||
if(f == NULL)
|
if (f == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
int version = 0;
|
int version = 0;
|
||||||
|
|
||||||
if(fread(&version, 1, sizeof(version), f) != sizeof(version)) {
|
if (fread(&version, 1, sizeof(version), f) != sizeof(version)) {
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(version != 1) {
|
if (version != 1) {
|
||||||
systemMessage(MSG_UNSUPPORTED_CHEAT_LIST_VERSION,
|
systemMessage(MSG_UNSUPPORTED_CHEAT_LIST_VERSION,
|
||||||
N_("Unsupported cheat list version %d"), version);
|
N_("Unsupported cheat list version %d"), version);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
@ -145,24 +143,24 @@ bool gbCheatsLoadCheatList(const char *file)
|
||||||
}
|
}
|
||||||
|
|
||||||
int type = 0;
|
int type = 0;
|
||||||
if(fread(&type, 1, sizeof(type), f) != sizeof(type)) {
|
if (fread(&type, 1, sizeof(type), f) != sizeof(type)) {
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(type != 1) {
|
if (type != 1) {
|
||||||
systemMessage(MSG_UNSUPPORTED_CHEAT_LIST_TYPE,
|
systemMessage(MSG_UNSUPPORTED_CHEAT_LIST_TYPE,
|
||||||
N_("Unsupported cheat list type %d"), type);
|
N_("Unsupported cheat list type %d"), type);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(fread(&count, 1, sizeof(count), f) != sizeof(count)) {
|
if (fread(&count, 1, sizeof(count), f) != sizeof(count)) {
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(fread(gbCheatList, 1, sizeof(gbCheatList), f) > sizeof(gbCheatList)) {
|
if (fread(gbCheatList, 1, sizeof(gbCheatList), f) > sizeof(gbCheatList)) {
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -173,21 +171,21 @@ bool gbCheatsLoadCheatList(const char *file)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool gbVerifyGsCode(const char *code)
|
bool gbVerifyGsCode(const char* code)
|
||||||
{
|
{
|
||||||
size_t len = strlen(code);
|
size_t len = strlen(code);
|
||||||
|
|
||||||
if(len == 0)
|
if (len == 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if(len != 8)
|
if (len != 8)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for(int i = 0; i < 8; i++)
|
for (int i = 0; i < 8; i++)
|
||||||
if(!GBCHEAT_IS_HEX(code[i]))
|
if (!GBCHEAT_IS_HEX(code[i]))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* int address = GBCHEAT_HEX_VALUE(code[6]) << 12 |
|
/* int address = GBCHEAT_HEX_VALUE(code[6]) << 12 |
|
||||||
GBCHEAT_HEX_VALUE(code[7]) << 8 |
|
GBCHEAT_HEX_VALUE(code[7]) << 8 |
|
||||||
GBCHEAT_HEX_VALUE(code[4]) << 4 |
|
GBCHEAT_HEX_VALUE(code[4]) << 4 |
|
||||||
GBCHEAT_HEX_VALUE(code[5]);*/
|
GBCHEAT_HEX_VALUE(code[5]);*/
|
||||||
|
@ -195,15 +193,15 @@ bool gbVerifyGsCode(const char *code)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool gbAddGsCheat(const char *code, const char *desc)
|
bool gbAddGsCheat(const char* code, const char* desc)
|
||||||
{
|
{
|
||||||
if(gbCheatNumber > (MAX_CHEATS - 1)) {
|
if (gbCheatNumber > (MAX_CHEATS - 1)) {
|
||||||
systemMessage(MSG_MAXIMUM_NUMBER_OF_CHEATS,
|
systemMessage(MSG_MAXIMUM_NUMBER_OF_CHEATS,
|
||||||
N_("Maximum number of cheats reached."));
|
N_("Maximum number of cheats reached."));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!gbVerifyGsCode(code)) {
|
if (!gbVerifyGsCode(code)) {
|
||||||
systemMessage(MSG_INVALID_GAMESHARK_CODE,
|
systemMessage(MSG_INVALID_GAMESHARK_CODE,
|
||||||
N_("Invalid GameShark code: %s"), code);
|
N_("Invalid GameShark code: %s"), code);
|
||||||
return false;
|
return false;
|
||||||
|
@ -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,11 +224,10 @@ 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))
|
||||||
systemMessage(MSG_UNSUPPORTED_GAMESHARK_CODE,
|
systemMessage(MSG_UNSUPPORTED_GAMESHARK_CODE,
|
||||||
N_("Unsupported GameShark code type : %s"), code);
|
N_("Unsupported GameShark code type : %s"), code);
|
||||||
|
|
||||||
|
@ -244,42 +236,39 @@ bool gbAddGsCheat(const char *code, const char *desc)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool gbVerifyGgCode(const char *code)
|
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)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if(!GBCHEAT_IS_HEX(code[0]))
|
if (!GBCHEAT_IS_HEX(code[0]))
|
||||||
return false;
|
return false;
|
||||||
if(!GBCHEAT_IS_HEX(code[1]))
|
if (!GBCHEAT_IS_HEX(code[1]))
|
||||||
return false;
|
return false;
|
||||||
if(!GBCHEAT_IS_HEX(code[2]))
|
if (!GBCHEAT_IS_HEX(code[2]))
|
||||||
return false;
|
return false;
|
||||||
if(code[3] != '-')
|
if (code[3] != '-')
|
||||||
return false;
|
return false;
|
||||||
if(!GBCHEAT_IS_HEX(code[4]))
|
if (!GBCHEAT_IS_HEX(code[4]))
|
||||||
return false;
|
return false;
|
||||||
if(!GBCHEAT_IS_HEX(code[5]))
|
if (!GBCHEAT_IS_HEX(code[5]))
|
||||||
return false;
|
return false;
|
||||||
if(!GBCHEAT_IS_HEX(code[6]))
|
if (!GBCHEAT_IS_HEX(code[6]))
|
||||||
return false;
|
return false;
|
||||||
if(code[7] != 0) {
|
if (code[7] != 0) {
|
||||||
if(code[7] != '-')
|
if (code[7] != '-')
|
||||||
return false;
|
return false;
|
||||||
if(code[8] != 0) {
|
if (code[8] != 0) {
|
||||||
if(!GBCHEAT_IS_HEX(code[8]))
|
if (!GBCHEAT_IS_HEX(code[8]))
|
||||||
return false;
|
return false;
|
||||||
if(!GBCHEAT_IS_HEX(code[9]))
|
if (!GBCHEAT_IS_HEX(code[9]))
|
||||||
return false;
|
return false;
|
||||||
if(!GBCHEAT_IS_HEX(code[10]))
|
if (!GBCHEAT_IS_HEX(code[10]))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -287,43 +276,39 @@ 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;
|
||||||
|
|
||||||
if(address >= 0xc000)
|
if (address >= 0xc000)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
int cloak = (GBCHEAT_HEX_VALUE(code[8])) ^ (GBCHEAT_HEX_VALUE(code[9]));
|
int cloak = (GBCHEAT_HEX_VALUE(code[8])) ^ (GBCHEAT_HEX_VALUE(code[9]));
|
||||||
|
|
||||||
if(cloak >=1 && cloak <= 7)
|
if (cloak >= 1 && cloak <= 7)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool gbAddGgCheat(const char *code, const char *desc)
|
bool gbAddGgCheat(const char* code, const char* desc)
|
||||||
{
|
{
|
||||||
if(gbCheatNumber > (MAX_CHEATS - 1)) {
|
if (gbCheatNumber > (MAX_CHEATS - 1)) {
|
||||||
systemMessage(MSG_MAXIMUM_NUMBER_OF_CHEATS,
|
systemMessage(MSG_MAXIMUM_NUMBER_OF_CHEATS,
|
||||||
N_("Maximum number of cheats reached."));
|
N_("Maximum number of cheats reached."));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!gbVerifyGgCode(code)) {
|
if (!gbVerifyGgCode(code)) {
|
||||||
systemMessage(MSG_INVALID_GAMEGENIE_CODE,
|
systemMessage(MSG_INVALID_GAMEGENIE_CODE,
|
||||||
N_("Invalid GameGenie code: %s"), code);
|
N_("Invalid GameGenie code: %s"), code);
|
||||||
return false;
|
return false;
|
||||||
|
@ -337,31 +322,24 @@ 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;
|
||||||
|
|
||||||
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;
|
||||||
|
@ -373,15 +351,14 @@ bool gbAddGgCheat(const char *code, const char *desc)
|
||||||
|
|
||||||
void gbCheatRemove(int i)
|
void gbCheatRemove(int i)
|
||||||
{
|
{
|
||||||
if(i < 0 || i >= gbCheatNumber) {
|
if (i < 0 || i >= gbCheatNumber) {
|
||||||
systemMessage(MSG_INVALID_CHEAT_TO_REMOVE,
|
systemMessage(MSG_INVALID_CHEAT_TO_REMOVE,
|
||||||
N_("Invalid cheat to remove %d"), i);
|
N_("Invalid cheat to remove %d"), i);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
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--;
|
||||||
|
@ -397,8 +374,8 @@ void gbCheatRemoveAll()
|
||||||
|
|
||||||
void gbCheatEnable(int i)
|
void gbCheatEnable(int i)
|
||||||
{
|
{
|
||||||
if(i >=0 && i < gbCheatNumber) {
|
if (i >= 0 && i < gbCheatNumber) {
|
||||||
if(!gbCheatList[i].enabled) {
|
if (!gbCheatList[i].enabled) {
|
||||||
gbCheatList[i].enabled = true;
|
gbCheatList[i].enabled = true;
|
||||||
gbCheatUpdateMap();
|
gbCheatUpdateMap();
|
||||||
}
|
}
|
||||||
|
@ -407,19 +384,19 @@ void gbCheatEnable(int i)
|
||||||
|
|
||||||
void gbCheatDisable(int i)
|
void gbCheatDisable(int i)
|
||||||
{
|
{
|
||||||
if(i >=0 && i < gbCheatNumber) {
|
if (i >= 0 && i < gbCheatNumber) {
|
||||||
if(gbCheatList[i].enabled) {
|
if (gbCheatList[i].enabled) {
|
||||||
gbCheatList[i].enabled = false;
|
gbCheatList[i].enabled = false;
|
||||||
gbCheatUpdateMap();
|
gbCheatUpdateMap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool gbCheatReadGSCodeFile(const char *fileName)
|
bool gbCheatReadGSCodeFile(const char* fileName)
|
||||||
{
|
{
|
||||||
FILE *file = fopen(fileName, "rb");
|
FILE* file = fopen(fileName, "rb");
|
||||||
|
|
||||||
if(!file) {
|
if (!file) {
|
||||||
systemMessage(MSG_CANNOT_OPEN_FILE, N_("Cannot open file %s"), fileName);
|
systemMessage(MSG_CANNOT_OPEN_FILE, N_("Cannot open file %s"), fileName);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -432,7 +409,7 @@ bool gbCheatReadGSCodeFile(const char *fileName)
|
||||||
char desc[13];
|
char desc[13];
|
||||||
char code[9];
|
char code[9];
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
fread(&dummy, 1, 2, file);
|
fread(&dummy, 1, 2, file);
|
||||||
fread(desc, 1, 12, file);
|
fread(desc, 1, 12, file);
|
||||||
desc[12] = 0;
|
desc[12] = 0;
|
||||||
|
@ -441,7 +418,7 @@ bool gbCheatReadGSCodeFile(const char *fileName)
|
||||||
gbAddGsCheat(code, desc);
|
gbAddGsCheat(code, desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = 0; i < gbCheatNumber; i++)
|
for (i = 0; i < gbCheatNumber; i++)
|
||||||
gbCheatDisable(i);
|
gbCheatDisable(i);
|
||||||
|
|
||||||
fclose(file);
|
fclose(file);
|
||||||
|
@ -449,16 +426,16 @@ 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];
|
||||||
|
|
||||||
for(int i = 0; i < gbCheatNumber; i++) {
|
for (int i = 0; i < gbCheatNumber; i++) {
|
||||||
if(gbCheatList[i].enabled && gbCheatList[i].address == address) {
|
if (gbCheatList[i].enabled && gbCheatList[i].address == address) {
|
||||||
switch(gbCheatList[i].code) {
|
switch (gbCheatList[i].code) {
|
||||||
case 0x100: // GameGenie support
|
case 0x100: // GameGenie support
|
||||||
if(gbMemoryMap[address>>12][address&0xFFF] == gbCheatList[i].compare)
|
if (gbMemoryMap[address >> 12][address & 0xFFF] == gbCheatList[i].compare)
|
||||||
return gbCheatList[i].value;
|
return gbCheatList[i].value;
|
||||||
break;
|
break;
|
||||||
case 0x101: // GameGenie 6 digits code support
|
case 0x101: // GameGenie 6 digits code support
|
||||||
|
@ -467,29 +444,26 @@ 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)
|
||||||
gbNextCheat = 0;
|
gbNextCheat = 0;
|
||||||
|
|
||||||
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);
|
||||||
gbNextCheat = i+1;
|
gbNextCheat = i + 1;
|
||||||
return;
|
return;
|
||||||
case 0x90:
|
case 0x90:
|
||||||
case 0x91:
|
case 0x91:
|
||||||
|
@ -511,18 +485,17 @@ void gbCheatWrite(bool reboot)
|
||||||
gbWriteMemory(0xff70, gbCheatList[i].code & 0xf);
|
gbWriteMemory(0xff70, gbCheatList[i].code & 0xf);
|
||||||
gbWriteMemory(address, gbCheatList[i].value);
|
gbWriteMemory(address, gbCheatList[i].value);
|
||||||
gbWriteMemory(0xff70, oldbank);
|
gbWriteMemory(0xff70, oldbank);
|
||||||
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:
|
||||||
gbWriteMemory(0x0000, 0x0A);
|
gbWriteMemory(0x0000, 0x0A);
|
||||||
gbWriteMemory(0x4000, gbCheatList[i].value & 0xF);
|
gbWriteMemory(0x4000, gbCheatList[i].value & 0xF);
|
||||||
gbWriteMemory(address, gbCheatList[i].value);
|
gbWriteMemory(address, gbCheatList[i].value);
|
||||||
gbNextCheat = i+1;
|
gbNextCheat = i + 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,30 +12,30 @@ 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;
|
||||||
};
|
};
|
||||||
|
|
||||||
void gbCheatsSaveGame(gzFile);
|
void gbCheatsSaveGame(gzFile);
|
||||||
void gbCheatsReadGame(gzFile, int);
|
void gbCheatsReadGame(gzFile, int);
|
||||||
void gbCheatsReadGameSkip(gzFile, int);
|
void gbCheatsReadGameSkip(gzFile, int);
|
||||||
void gbCheatsSaveCheatList(const char *);
|
void gbCheatsSaveCheatList(const char*);
|
||||||
bool gbCheatsLoadCheatList(const char *);
|
bool gbCheatsLoadCheatList(const char*);
|
||||||
bool gbCheatReadGSCodeFile(const char *);
|
bool gbCheatReadGSCodeFile(const char*);
|
||||||
|
|
||||||
bool gbAddGsCheat(const char *, const char *);
|
bool gbAddGsCheat(const char*, const char*);
|
||||||
bool gbAddGgCheat(const char *, const char *);
|
bool gbAddGgCheat(const char*, const char*);
|
||||||
void gbCheatRemove(int);
|
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);
|
||||||
|
|
||||||
extern int gbCheatNumber;
|
extern int gbCheatNumber;
|
||||||
extern gbCheat gbCheatList[MAX_CHEATS];
|
extern gbCheat gbCheatList[MAX_CHEATS];
|
||||||
|
|
171
src/gb/gbCodes.h
171
src/gb/gbCodes.h
|
@ -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
|
||||||
|
|
|
@ -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,40 +111,40 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *addStr(char *p, const char *s)
|
static char* addStr(char* p, const char* s)
|
||||||
{
|
{
|
||||||
while(*s) {
|
while (*s) {
|
||||||
*p++ = *s++;
|
*p++ = *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;
|
||||||
if(opcode == 0xcb) {
|
if (opcode == 0xcb) {
|
||||||
opcode = GB_READ(address);
|
opcode = GB_READ(address);
|
||||||
address++;
|
address++;
|
||||||
instr++;
|
instr++;
|
||||||
|
@ -155,23 +152,24 @@ 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) {
|
||||||
if(*mnen == '%') {
|
if (*mnen == '%') {
|
||||||
mnen++;
|
mnen++;
|
||||||
switch(*mnen++) {
|
switch (*mnen++) {
|
||||||
case 'W':
|
case 'W':
|
||||||
b0 = GB_READ(address);
|
b0 = GB_READ(address);
|
||||||
address++;
|
address++;
|
||||||
b1 = GB_READ(address);
|
b1 = GB_READ(address);
|
||||||
address++;
|
address++;
|
||||||
p = addHex16(p, b0|b1<<8);
|
p = addHex16(p, b0 | b1 << 8);
|
||||||
instr += 2;
|
instr += 2;
|
||||||
*p++ = 'h';
|
*p++ = 'h';
|
||||||
break;
|
break;
|
||||||
|
@ -183,7 +181,7 @@ int gbDis(char *buffer, u16 address)
|
||||||
break;
|
break;
|
||||||
case 'D':
|
case 'D':
|
||||||
disp = GB_READ(address);
|
disp = GB_READ(address);
|
||||||
if(disp >= 0)
|
if (disp >= 0)
|
||||||
*p++ = '+';
|
*p++ = '+';
|
||||||
p += sprintf(p, "%d", disp);
|
p += sprintf(p, "%d", disp);
|
||||||
instr++;
|
instr++;
|
||||||
|
@ -191,7 +189,7 @@ int gbDis(char *buffer, u16 address)
|
||||||
case 'd':
|
case 'd':
|
||||||
disp = GB_READ(address);
|
disp = GB_READ(address);
|
||||||
address++;
|
address++;
|
||||||
p = addHex16(p, address+disp);
|
p = addHex16(p, address + disp);
|
||||||
*p++ = 'h';
|
*p++ = 'h';
|
||||||
instr++;
|
instr++;
|
||||||
break;
|
break;
|
||||||
|
@ -209,7 +207,7 @@ int gbDis(char *buffer, u16 address)
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
shift = *mnen++ - '0';
|
shift = *mnen++ - '0';
|
||||||
p = addStr(p, registers16[4+((opcode >> shift) & 3)]);
|
p = addStr(p, registers16[4 + ((opcode >> shift) & 3)]);
|
||||||
break;
|
break;
|
||||||
case 'P':
|
case 'P':
|
||||||
p = addHex(p, ((opcode >> 3) & 7) * 8);
|
p = addHex(p, ((opcode >> 3) & 7) * 8);
|
||||||
|
@ -222,9 +220,9 @@ int gbDis(char *buffer, u16 address)
|
||||||
} else
|
} else
|
||||||
*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;
|
||||||
return instr;
|
return instr;
|
||||||
|
|
351
src/gb/gbGfx.cpp
351
src/gb/gbGfx.cpp
|
@ -1,43 +1,43 @@
|
||||||
#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"
|
||||||
|
|
||||||
u8 gbInvertTab[256] = {
|
u8 gbInvertTab[256] = {
|
||||||
0x00,0x80,0x40,0xc0,0x20,0xa0,0x60,0xe0,
|
0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
|
||||||
0x10,0x90,0x50,0xd0,0x30,0xb0,0x70,0xf0,
|
0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
|
||||||
0x08,0x88,0x48,0xc8,0x28,0xa8,0x68,0xe8,
|
0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
|
||||||
0x18,0x98,0x58,0xd8,0x38,0xb8,0x78,0xf8,
|
0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
|
||||||
0x04,0x84,0x44,0xc4,0x24,0xa4,0x64,0xe4,
|
0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
|
||||||
0x14,0x94,0x54,0xd4,0x34,0xb4,0x74,0xf4,
|
0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
|
||||||
0x0c,0x8c,0x4c,0xcc,0x2c,0xac,0x6c,0xec,
|
0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
|
||||||
0x1c,0x9c,0x5c,0xdc,0x3c,0xbc,0x7c,0xfc,
|
0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
|
||||||
0x02,0x82,0x42,0xc2,0x22,0xa2,0x62,0xe2,
|
0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
|
||||||
0x12,0x92,0x52,0xd2,0x32,0xb2,0x72,0xf2,
|
0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
|
||||||
0x0a,0x8a,0x4a,0xca,0x2a,0xaa,0x6a,0xea,
|
0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
|
||||||
0x1a,0x9a,0x5a,0xda,0x3a,0xba,0x7a,0xfa,
|
0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
|
||||||
0x06,0x86,0x46,0xc6,0x26,0xa6,0x66,0xe6,
|
0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
|
||||||
0x16,0x96,0x56,0xd6,0x36,0xb6,0x76,0xf6,
|
0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
|
||||||
0x0e,0x8e,0x4e,0xce,0x2e,0xae,0x6e,0xee,
|
0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
|
||||||
0x1e,0x9e,0x5e,0xde,0x3e,0xbe,0x7e,0xfe,
|
0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
|
||||||
0x01,0x81,0x41,0xc1,0x21,0xa1,0x61,0xe1,
|
0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
|
||||||
0x11,0x91,0x51,0xd1,0x31,0xb1,0x71,0xf1,
|
0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
|
||||||
0x09,0x89,0x49,0xc9,0x29,0xa9,0x69,0xe9,
|
0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
|
||||||
0x19,0x99,0x59,0xd9,0x39,0xb9,0x79,0xf9,
|
0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
|
||||||
0x05,0x85,0x45,0xc5,0x25,0xa5,0x65,0xe5,
|
0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
|
||||||
0x15,0x95,0x55,0xd5,0x35,0xb5,0x75,0xf5,
|
0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
|
||||||
0x0d,0x8d,0x4d,0xcd,0x2d,0xad,0x6d,0xed,
|
0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
|
||||||
0x1d,0x9d,0x5d,0xdd,0x3d,0xbd,0x7d,0xfd,
|
0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
|
||||||
0x03,0x83,0x43,0xc3,0x23,0xa3,0x63,0xe3,
|
0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
|
||||||
0x13,0x93,0x53,0xd3,0x33,0xb3,0x73,0xf3,
|
0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
|
||||||
0x0b,0x8b,0x4b,0xcb,0x2b,0xab,0x6b,0xeb,
|
0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
|
||||||
0x1b,0x9b,0x5b,0xdb,0x3b,0xbb,0x7b,0xfb,
|
0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
|
||||||
0x07,0x87,0x47,0xc7,0x27,0xa7,0x67,0xe7,
|
0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
|
||||||
0x17,0x97,0x57,0xd7,0x37,0xb7,0x77,0xf7,
|
0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
|
||||||
0x0f,0x8f,0x4f,0xcf,0x2f,0xaf,0x6f,0xef,
|
0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
|
||||||
0x1f,0x9f,0x5f,0xdf,0x3f,0xbf,0x7f,0xff
|
0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
|
||||||
};
|
};
|
||||||
|
|
||||||
u16 gbLineMix[160];
|
u16 gbLineMix[160];
|
||||||
|
@ -48,9 +48,9 @@ extern int layerSettings;
|
||||||
void gbRenderLine()
|
void gbRenderLine()
|
||||||
{
|
{
|
||||||
memset(gbLineMix, 0, sizeof(gbLineMix));
|
memset(gbLineMix, 0, sizeof(gbLineMix));
|
||||||
u8 * bank0;
|
u8* bank0;
|
||||||
u8 * bank1;
|
u8* bank1;
|
||||||
if(gbCgbMode) {
|
if (gbCgbMode) {
|
||||||
bank0 = &gbVram[0x0000];
|
bank0 = &gbVram[0x0000];
|
||||||
bank1 = &gbVram[0x2000];
|
bank1 = &gbVram[0x2000];
|
||||||
} else {
|
} else {
|
||||||
|
@ -59,25 +59,25 @@ void gbRenderLine()
|
||||||
}
|
}
|
||||||
|
|
||||||
int tile_map = 0x1800;
|
int tile_map = 0x1800;
|
||||||
if((register_LCDC & 8) != 0)
|
if ((register_LCDC & 8) != 0)
|
||||||
tile_map = 0x1c00;
|
tile_map = 0x1c00;
|
||||||
|
|
||||||
int tile_pattern = 0x0800;
|
int tile_pattern = 0x0800;
|
||||||
|
|
||||||
if((register_LCDC & 16) != 0)
|
if ((register_LCDC & 16) != 0)
|
||||||
tile_pattern = 0x0000;
|
tile_pattern = 0x0000;
|
||||||
|
|
||||||
int x = 0;
|
int x = 0;
|
||||||
int y = register_LY;
|
int y = register_LY;
|
||||||
|
|
||||||
if(y >= 144)
|
if (y >= 144)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int SpritesTicks = gbSpritesTicks[x]*(gbSpeed ? 2 : 4);
|
int SpritesTicks = gbSpritesTicks[x] * (gbSpeed ? 2 : 4);
|
||||||
int sx = gbSCXLine[(gbSpeed ? 0 : 4)+SpritesTicks];
|
int sx = gbSCXLine[(gbSpeed ? 0 : 4) + SpritesTicks];
|
||||||
int sy = gbSCYLine[(gbSpeed ? 11 : 5)+SpritesTicks];
|
int sy = gbSCYLine[(gbSpeed ? 11 : 5) + SpritesTicks];
|
||||||
|
|
||||||
sy+=y;
|
sy += y;
|
||||||
|
|
||||||
sy &= 255;
|
sy &= 255;
|
||||||
|
|
||||||
|
@ -92,32 +92,30 @@ void gbRenderLine()
|
||||||
int tile_map_address = tile_map_line_y + tx;
|
int tile_map_address = tile_map_line_y + tx;
|
||||||
|
|
||||||
u8 attrs = 0;
|
u8 attrs = 0;
|
||||||
if(bank1 != NULL)
|
if (bank1 != NULL)
|
||||||
attrs = bank1[tile_map_address];
|
attrs = bank1[tile_map_address];
|
||||||
|
|
||||||
u8 tile = bank0[tile_map_address];
|
u8 tile = bank0[tile_map_address];
|
||||||
|
|
||||||
tile_map_address++;
|
tile_map_address++;
|
||||||
|
|
||||||
if(!(register_LCDC & 0x10))
|
if (!(register_LCDC & 0x10))
|
||||||
tile ^= 0x80;
|
tile ^= 0x80;
|
||||||
|
|
||||||
int tile_pattern_address = tile_pattern + tile * 16 + by*2;
|
int tile_pattern_address = tile_pattern + tile * 16 + by * 2;
|
||||||
|
|
||||||
if(register_LCDC & 0x80) {
|
|
||||||
if((register_LCDC & 0x01 || gbCgbMode) && (layerSettings & 0x0100)) {
|
|
||||||
while(x < 160) {
|
|
||||||
|
|
||||||
|
|
||||||
|
if (register_LCDC & 0x80) {
|
||||||
|
if ((register_LCDC & 0x01 || gbCgbMode) && (layerSettings & 0x0100)) {
|
||||||
|
while (x < 160) {
|
||||||
|
|
||||||
u8 tile_a = 0;
|
u8 tile_a = 0;
|
||||||
u8 tile_b = 0;
|
u8 tile_b = 0;
|
||||||
|
|
||||||
if(attrs & 0x40) {
|
if (attrs & 0x40) {
|
||||||
tile_pattern_address = tile_pattern + tile * 16 + (7-by)*2;
|
tile_pattern_address = tile_pattern + tile * 16 + (7 - by) * 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(attrs & 0x08) {
|
if (attrs & 0x08) {
|
||||||
tile_a = bank1[tile_pattern_address++];
|
tile_a = bank1[tile_pattern_address++];
|
||||||
tile_b = bank1[tile_pattern_address];
|
tile_b = bank1[tile_pattern_address];
|
||||||
} else {
|
} else {
|
||||||
|
@ -125,21 +123,21 @@ void gbRenderLine()
|
||||||
tile_b = bank0[tile_pattern_address];
|
tile_b = bank0[tile_pattern_address];
|
||||||
}
|
}
|
||||||
|
|
||||||
if(attrs & 0x20) {
|
if (attrs & 0x20) {
|
||||||
tile_a = gbInvertTab[tile_a];
|
tile_a = gbInvertTab[tile_a];
|
||||||
tile_b = gbInvertTab[tile_b];
|
tile_b = gbInvertTab[tile_b];
|
||||||
}
|
}
|
||||||
|
|
||||||
while(bx > 0) {
|
while (bx > 0) {
|
||||||
u8 c = (tile_a & bx) ? 1 : 0;
|
u8 c = (tile_a & bx) ? 1 : 0;
|
||||||
c += ((tile_b & bx) ? 2 : 0);
|
c += ((tile_b & bx) ? 2 : 0);
|
||||||
|
|
||||||
gbLineBuffer[x] = c; // mark the gbLineBuffer color
|
gbLineBuffer[x] = c; // mark the gbLineBuffer color
|
||||||
|
|
||||||
if(attrs & 0x80)
|
if (attrs & 0x80)
|
||||||
gbLineBuffer[x] |= 0x300;
|
gbLineBuffer[x] |= 0x300;
|
||||||
|
|
||||||
if(gbCgbMode) {
|
if (gbCgbMode) {
|
||||||
// Use the DMG palette if we are in compat mode.
|
// Use the DMG palette if we are in compat mode.
|
||||||
if (gbMemory[0xff6c] & 1) {
|
if (gbMemory[0xff6c] & 1) {
|
||||||
c = gbBgp[c];
|
c = gbBgp[c];
|
||||||
|
@ -147,38 +145,37 @@ void gbRenderLine()
|
||||||
c = c + (attrs & 7) * 4;
|
c = c + (attrs & 7) * 4;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
c = (gbBgpLine[x+(gbSpeed ? 5 : 11)+SpritesTicks]>>(c<<1)) &3;
|
c = (gbBgpLine[x + (gbSpeed ? 5 : 11) + SpritesTicks] >> (c << 1)) & 3;
|
||||||
if(gbSgbMode && !gbCgbMode) {
|
if (gbSgbMode && !gbCgbMode) {
|
||||||
int dx = x >> 3;
|
int dx = x >> 3;
|
||||||
int dy = y >> 3;
|
int dy = y >> 3;
|
||||||
|
|
||||||
int palette = gbSgbATF[dy * 20 + dx];
|
int palette = gbSgbATF[dy * 20 + dx];
|
||||||
|
|
||||||
if(c == 0)
|
if (c == 0)
|
||||||
palette = 0;
|
palette = 0;
|
||||||
|
|
||||||
c = c + 4*palette;
|
c = c + 4 * palette;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gbLineMix[x] = gbColorOption ? gbColorFilter[gbPalette[c] & 0x7FFF] : gbPalette[c] & 0x7FFF;
|
gbLineMix[x] = gbColorOption ? gbColorFilter[gbPalette[c] & 0x7FFF] : gbPalette[c] & 0x7FFF;
|
||||||
x++;
|
x++;
|
||||||
if(x >= 160)
|
if (x >= 160)
|
||||||
break;
|
break;
|
||||||
bx >>= 1;
|
bx >>= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bx = 128;
|
bx = 128;
|
||||||
|
|
||||||
SpritesTicks = gbSpritesTicks[x]*(gbSpeed ? 2 : 4);
|
SpritesTicks = gbSpritesTicks[x] * (gbSpeed ? 2 : 4);
|
||||||
|
|
||||||
sx = gbSCXLine[x+(gbSpeed ? 0 : 4)+SpritesTicks];
|
sx = gbSCXLine[x + (gbSpeed ? 0 : 4) + SpritesTicks];
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
sy &= 255;
|
sy &= 255;
|
||||||
|
|
||||||
|
@ -192,12 +189,12 @@ void gbRenderLine()
|
||||||
|
|
||||||
tile_map_address = tile_map_line_y + tx;
|
tile_map_address = tile_map_line_y + tx;
|
||||||
|
|
||||||
if(bank1)
|
if (bank1)
|
||||||
attrs = bank1[tile_map_line_y + tx];
|
attrs = bank1[tile_map_line_y + tx];
|
||||||
|
|
||||||
tile = bank0[tile_map_line_y + tx];
|
tile = bank0[tile_map_line_y + tx];
|
||||||
|
|
||||||
if(!(register_LCDC & 0x10))
|
if (!(register_LCDC & 0x10))
|
||||||
tile ^= 0x80;
|
tile ^= 0x80;
|
||||||
|
|
||||||
tile_pattern_address = tile_pattern + tile * 16 + by * 2;
|
tile_pattern_address = tile_pattern + tile * 16 + by * 2;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -222,14 +216,13 @@ void gbRenderLine()
|
||||||
// LCDC.0 also enables/disables the window in !gbCgbMode ?!?!
|
// LCDC.0 also enables/disables the window in !gbCgbMode ?!?!
|
||||||
// (tested on real hardware)
|
// (tested on real hardware)
|
||||||
// This fixes Last Bible II & Zankurou Musouken
|
// This fixes Last Bible II & Zankurou Musouken
|
||||||
if((register_LCDC & 0x01 || gbCgbMode) && (register_LCDC & 0x20) && (layerSettings & 0x2000) && (gbWindowLine != -2)) {
|
if ((register_LCDC & 0x01 || gbCgbMode) && (register_LCDC & 0x20) && (layerSettings & 0x2000) && (gbWindowLine != -2)) {
|
||||||
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;
|
||||||
// for (i = 0; i<160; i++)
|
// for (i = 0; i<160; i++)
|
||||||
// gbWindowColor[i] = gbLineMix[i];
|
// gbWindowColor[i] = gbLineMix[i];
|
||||||
|
@ -237,23 +230,22 @@ void gbRenderLine()
|
||||||
|
|
||||||
int wy = inUseRegister_WY;
|
int wy = inUseRegister_WY;
|
||||||
|
|
||||||
if(y >= inUseRegister_WY) {
|
if (y >= inUseRegister_WY) {
|
||||||
|
|
||||||
if ((gbWindowLine == -1) || (gbWindowLine>144))
|
if ((gbWindowLine == -1) || (gbWindowLine > 144))
|
||||||
gbWindowLine = 0;
|
gbWindowLine = 0;
|
||||||
|
|
||||||
int wx = register_WX;
|
int wx = register_WX;
|
||||||
int swx = 0;
|
int swx = 0;
|
||||||
wx -= 7;
|
wx -= 7;
|
||||||
|
|
||||||
if( wx <= 159 && gbWindowLine <= 143) {
|
if (wx <= 159 && gbWindowLine <= 143) {
|
||||||
|
|
||||||
tile_map = 0x1800;
|
tile_map = 0x1800;
|
||||||
|
|
||||||
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,24 +254,20 @@ 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)
|
||||||
swx = 2;
|
swx = 2;
|
||||||
|
|
||||||
//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;
|
||||||
}
|
}
|
||||||
|
@ -292,30 +280,32 @@ void gbRenderLine()
|
||||||
|
|
||||||
tile = bank0[tile_map_address];
|
tile = bank0[tile_map_address];
|
||||||
u8 attrs = 0;
|
u8 attrs = 0;
|
||||||
if(bank1)
|
if (bank1)
|
||||||
attrs = bank1[tile_map_address];
|
attrs = bank1[tile_map_address];
|
||||||
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;
|
||||||
|
|
||||||
if (wx)
|
if (wx)
|
||||||
for (i = 0; i<swx; i++)
|
for (i = 0; i < swx; i++)
|
||||||
gbLineMix[i] = gbWindowColor[i];
|
gbLineMix[i] = gbWindowColor[i];
|
||||||
|
|
||||||
while(x < 160) {
|
while (x < 160) {
|
||||||
u8 tile_a = 0;
|
u8 tile_a = 0;
|
||||||
u8 tile_b = 0;
|
u8 tile_b = 0;
|
||||||
|
|
||||||
if(attrs & 0x40) {
|
if (attrs & 0x40) {
|
||||||
tile_pattern_address = tile_pattern + tile * 16 + (7-by)*2;
|
tile_pattern_address = tile_pattern + tile * 16 + (7 - by) * 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(attrs & 0x08) {
|
if (attrs & 0x08) {
|
||||||
tile_a = bank1[tile_pattern_address++];
|
tile_a = bank1[tile_pattern_address++];
|
||||||
tile_b = bank1[tile_pattern_address];
|
tile_b = bank1[tile_pattern_address];
|
||||||
} else {
|
} else {
|
||||||
|
@ -323,23 +313,22 @@ void gbRenderLine()
|
||||||
tile_b = bank0[tile_pattern_address];
|
tile_b = bank0[tile_pattern_address];
|
||||||
}
|
}
|
||||||
|
|
||||||
if(attrs & 0x20) {
|
if (attrs & 0x20) {
|
||||||
tile_a = gbInvertTab[tile_a];
|
tile_a = gbInvertTab[tile_a];
|
||||||
tile_b = gbInvertTab[tile_b];
|
tile_b = gbInvertTab[tile_b];
|
||||||
}
|
}
|
||||||
|
|
||||||
while(bx > 0) {
|
while (bx > 0) {
|
||||||
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
|
||||||
gbLineBuffer[x] = 0x100 + c;
|
gbLineBuffer[x] = 0x100 + c;
|
||||||
|
|
||||||
if(gbCgbMode) {
|
if (gbCgbMode) {
|
||||||
// Use the DMG palette if we are in compat mode.
|
// Use the DMG palette if we are in compat mode.
|
||||||
if (gbMemory[0xff6c] & 1) {
|
if (gbMemory[0xff6c] & 1) {
|
||||||
c = gbBgp[c];
|
c = gbBgp[c];
|
||||||
|
@ -347,37 +336,39 @@ void gbRenderLine()
|
||||||
c = c + (attrs & 7) * 4;
|
c = c + (attrs & 7) * 4;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
c = (gbBgpLine[x+(gbSpeed ? 5 : 11)+gbSpritesTicks[x]*(gbSpeed ? 2 : 4)]>>(c<<1)) &3;
|
c = (gbBgpLine[x + (gbSpeed ? 5 : 11) + gbSpritesTicks[x] * (gbSpeed ? 2 : 4)] >> (c << 1)) & 3;
|
||||||
if(gbSgbMode && !gbCgbMode) {
|
if (gbSgbMode && !gbCgbMode) {
|
||||||
int dx = x >> 3;
|
int dx = x >> 3;
|
||||||
int dy = y >> 3;
|
int dy = y >> 3;
|
||||||
|
|
||||||
int palette = gbSgbATF[dy * 20 + dx];
|
int palette = gbSgbATF[dy * 20 + dx];
|
||||||
|
|
||||||
if(c == 0)
|
if (c == 0)
|
||||||
palette = 0;
|
palette = 0;
|
||||||
|
|
||||||
c = c + 4*palette;
|
c = c + 4 * palette;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gbLineMix[x] = gbColorOption ? gbColorFilter[gbPalette[c] & 0x7FFF] : gbPalette[c] & 0x7FFF;
|
gbLineMix[x] = gbColorOption ? gbColorFilter[gbPalette[c] & 0x7FFF] : gbPalette[c] & 0x7FFF;
|
||||||
}
|
}
|
||||||
x++;
|
x++;
|
||||||
if(x >= 160)
|
if (x >= 160)
|
||||||
break;
|
break;
|
||||||
bx >>= 1;
|
bx >>= 1;
|
||||||
}
|
}
|
||||||
tx++;
|
tx++;
|
||||||
if(tx == 32)
|
if (tx == 32)
|
||||||
tx = 0;
|
tx = 0;
|
||||||
bx = 128;
|
bx = 128;
|
||||||
tile = bank0[tile_map_line_y + tx];
|
tile = bank0[tile_map_line_y + tx];
|
||||||
if(bank1)
|
if (bank1)
|
||||||
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,11 +378,9 @@ 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;
|
||||||
else
|
else
|
||||||
gbWindowLine = 0;
|
gbWindowLine = 0;
|
||||||
|
@ -400,20 +389,19 @@ 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void gbDrawSpriteTile(int tile, int x,int y,int t, int flags,
|
void gbDrawSpriteTile(int tile, int x, int y, int t, int flags,
|
||||||
int size,int spriteNumber)
|
int size, int spriteNumber)
|
||||||
{
|
{
|
||||||
u8 * bank0;
|
u8* bank0;
|
||||||
u8 * bank1;
|
u8* bank1;
|
||||||
if(gbCgbMode) {
|
if (gbCgbMode) {
|
||||||
bank0 = &gbVram[0x0000];
|
bank0 = &gbVram[0x0000];
|
||||||
bank1 = &gbVram[0x2000];
|
bank1 = &gbVram[0x2000];
|
||||||
} else {
|
} else {
|
||||||
|
@ -423,30 +411,29 @@ 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;
|
|
||||||
}
|
}
|
||||||
u8 *pal = gbObp0;
|
u8* pal = gbObp0;
|
||||||
|
|
||||||
int flipx = (flags & 0x20);
|
int flipx = (flags & 0x20);
|
||||||
int flipy = (flags & 0x40);
|
int flipy = (flags & 0x40);
|
||||||
|
|
||||||
if((flags & 0x10))
|
if ((flags & 0x10))
|
||||||
pal = gbObp1;
|
pal = gbObp1;
|
||||||
|
|
||||||
if(flipy) {
|
if (flipy) {
|
||||||
t = (size ? 15 : 7) - t;
|
t = (size ? 15 : 7) - t;
|
||||||
}
|
}
|
||||||
|
|
||||||
int prio = flags & 0x80;
|
int prio = flags & 0x80;
|
||||||
|
|
||||||
int address = init + tile * 16 + 2*t;
|
int address = init + tile * 16 + 2 * t;
|
||||||
int a = 0;
|
int a = 0;
|
||||||
int b = 0;
|
int b = 0;
|
||||||
|
|
||||||
if(gbCgbMode && (flags & 0x08)) {
|
if (gbCgbMode && (flags & 0x08)) {
|
||||||
a = bank1[address++];
|
a = bank1[address++];
|
||||||
b = bank1[address++];
|
b = bank1[address++];
|
||||||
} else {
|
} else {
|
||||||
|
@ -454,78 +441,78 @@ void gbDrawSpriteTile(int tile, int x,int y,int t, int flags,
|
||||||
b = bank0[address++];
|
b = bank0[address++];
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int xx = 0; xx < 8; xx++) {
|
for (int xx = 0; xx < 8; xx++) {
|
||||||
u8 mask = 1 << (7-xx);
|
u8 mask = 1 << (7 - xx);
|
||||||
u8 c = 0;
|
u8 c = 0;
|
||||||
if( (a & mask))
|
if ((a & mask))
|
||||||
c++;
|
c++;
|
||||||
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)
|
||||||
xxx = (7-xx+x);
|
xxx = (7 - xx + x);
|
||||||
|
|
||||||
if(xxx < 0 || xxx > 159)
|
if (xxx < 0 || xxx > 159)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
u16 color = gbLineBuffer[xxx];
|
u16 color = gbLineBuffer[xxx];
|
||||||
|
|
||||||
// Fixes OAM-BG priority
|
// Fixes OAM-BG priority
|
||||||
if(prio && (register_LCDC & 1)) {
|
if (prio && (register_LCDC & 1)) {
|
||||||
if(color < 0x200 && ((color & 0xFF) != 0))
|
if (color < 0x200 && ((color & 0xFF) != 0))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Fixes OAM-BG priority for Moorhuhn 2
|
// Fixes OAM-BG priority for Moorhuhn 2
|
||||||
if(color >= 0x300 && color != 0x300 && (register_LCDC & 1))
|
if (color >= 0x300 && color != 0x300 && (register_LCDC & 1))
|
||||||
continue;
|
continue;
|
||||||
else if(color >= 0x200 && color < 0x300) {
|
else if (color >= 0x200 && color < 0x300) {
|
||||||
int sprite = color & 0xff;
|
int sprite = color & 0xff;
|
||||||
|
|
||||||
int spriteX = gbMemory[0xfe00 + 4 * sprite + 1] - 8;
|
int spriteX = gbMemory[0xfe00 + 4 * sprite + 1] - 8;
|
||||||
|
|
||||||
if(spriteX == x) {
|
if (spriteX == x) {
|
||||||
if(sprite < spriteNumber)
|
if (sprite < spriteNumber)
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
if(gbCgbMode) {
|
if (gbCgbMode) {
|
||||||
if(sprite < spriteNumber)
|
if (sprite < spriteNumber)
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
// Fixes GB sprites priorities (was '< x + 8' before)
|
// Fixes GB sprites priorities (was '< x + 8' before)
|
||||||
// ('A boy and his blob...' sprites' emulation is now correct)
|
// ('A boy and his blob...' sprites' emulation is now correct)
|
||||||
if(spriteX < x)
|
if (spriteX < x)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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
|
||||||
if(gbCgbMode) {
|
if (gbCgbMode) {
|
||||||
// Use the DMG palette if we are in compat mode.
|
// Use the DMG palette if we are in compat mode.
|
||||||
if (gbMemory[0xff6c] & 1) {
|
if (gbMemory[0xff6c] & 1) {
|
||||||
c = pal[c] + ((flags & 0x10) >> 4)*4 + 32;
|
c = pal[c] + ((flags & 0x10) >> 4) * 4 + 32;
|
||||||
} else {
|
} else {
|
||||||
c = c + (flags & 0x07)*4 + 32;
|
c = c + (flags & 0x07) * 4 + 32;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
c = pal[c];
|
c = pal[c];
|
||||||
|
|
||||||
if(gbSgbMode && !gbCgbMode) {
|
if (gbSgbMode && !gbCgbMode) {
|
||||||
int dx = xxx >> 3;
|
int dx = xxx >> 3;
|
||||||
int dy = y >> 3;
|
int dy = y >> 3;
|
||||||
|
|
||||||
int palette = gbSgbATF[dy * 20 + dx];
|
int palette = gbSgbATF[dy * 20 + dx];
|
||||||
|
|
||||||
if(c == 0)
|
if (c == 0)
|
||||||
palette = 0;
|
palette = 0;
|
||||||
|
|
||||||
c = c + 4*palette;
|
c = c + 4 * palette;
|
||||||
} else {
|
} else {
|
||||||
c += 4;
|
c += 4;
|
||||||
}
|
}
|
||||||
|
@ -544,45 +531,43 @@ void gbDrawSprites(bool draw)
|
||||||
int size = (register_LCDC & 4);
|
int size = (register_LCDC & 4);
|
||||||
|
|
||||||
if (!draw)
|
if (!draw)
|
||||||
memset (gbSpritesTicks, 0, sizeof(gbSpritesTicks));
|
memset(gbSpritesTicks, 0, sizeof(gbSpritesTicks));
|
||||||
|
|
||||||
if(!(register_LCDC & 0x80))
|
if (!(register_LCDC & 0x80))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if((register_LCDC & 2) && (layerSettings & 0x1000)) {
|
if ((register_LCDC & 2) && (layerSettings & 0x1000)) {
|
||||||
int yc = register_LY;
|
int yc = register_LY;
|
||||||
|
|
||||||
int address = 0xfe00;
|
int address = 0xfe00;
|
||||||
for(int i = 0; i < 40; i++) {
|
for (int i = 0; i < 40; i++) {
|
||||||
y = gbMemory[address++];
|
y = gbMemory[address++];
|
||||||
x = gbMemory[address++];
|
x = gbMemory[address++];
|
||||||
int tile = gbMemory[address++];
|
int tile = gbMemory[address++];
|
||||||
if(size)
|
if (size)
|
||||||
tile &= 254;
|
tile &= 254;
|
||||||
int flags = gbMemory[address++];
|
int flags = gbMemory[address++];
|
||||||
|
|
||||||
if(x > 0 && y > 0 && x < 168 && y < 160) {
|
if (x > 0 && y > 0 && x < 168 && y < 160) {
|
||||||
// check if sprite intersects current line
|
// check if sprite intersects current line
|
||||||
int t = yc -y + 16;
|
int t = yc - y + 16;
|
||||||
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
|
||||||
gbSpritesTicks[j] += 2+(count&1);
|
gbSpritesTicks[j] += 2 + (count & 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// sprite limit reached!
|
// sprite limit reached!
|
||||||
if(count >= 10)
|
if (count >= 10)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include <cstdlib>
|
|
||||||
#include "../common/Types.h"
|
#include "../common/Types.h"
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
u8 *gbMemoryMap[16];
|
u8* gbMemoryMap[16];
|
||||||
|
|
||||||
int gbRomSizeMask = 0;
|
int gbRomSizeMask = 0;
|
||||||
int gbRomSize = 0;
|
int gbRomSize = 0;
|
||||||
|
@ -9,18 +9,18 @@ int gbRamSizeMask = 0;
|
||||||
int gbRamSize = 0;
|
int gbRamSize = 0;
|
||||||
int gbTAMA5ramSize = 0;
|
int gbTAMA5ramSize = 0;
|
||||||
|
|
||||||
u8 *gbMemory = NULL;
|
u8* gbMemory = NULL;
|
||||||
u8 *gbVram = NULL;
|
u8* gbVram = NULL;
|
||||||
u8 *gbRom = NULL;
|
u8* gbRom = NULL;
|
||||||
u8 *gbRam = NULL;
|
u8* gbRam = NULL;
|
||||||
u8 *gbWram = NULL;
|
u8* gbWram = NULL;
|
||||||
u16 *gbLineBuffer = NULL;
|
u16* gbLineBuffer = NULL;
|
||||||
u8 *gbTAMA5ram = NULL;
|
u8* gbTAMA5ram = NULL;
|
||||||
|
|
||||||
u16 gbPalette[128];
|
u16 gbPalette[128];
|
||||||
u8 gbBgp[4] = { 0, 1, 2, 3};
|
u8 gbBgp[4] = { 0, 1, 2, 3 };
|
||||||
u8 gbObp0[4] = { 0, 1, 2, 3};
|
u8 gbObp0[4] = { 0, 1, 2, 3 };
|
||||||
u8 gbObp1[4] = { 0, 1, 2, 3};
|
u8 gbObp1[4] = { 0, 1, 2, 3 };
|
||||||
int gbWindowLine = -1;
|
int gbWindowLine = -1;
|
||||||
|
|
||||||
bool genericflashcardEnable = false;
|
bool genericflashcardEnable = false;
|
||||||
|
|
|
@ -7,17 +7,17 @@ extern int gbRamSize;
|
||||||
extern int gbRamSizeMask;
|
extern int gbRamSizeMask;
|
||||||
extern int gbTAMA5ramSize;
|
extern int gbTAMA5ramSize;
|
||||||
|
|
||||||
extern u8 *bios;
|
extern u8* bios;
|
||||||
|
|
||||||
extern u8 *gbRom;
|
extern u8* gbRom;
|
||||||
extern u8 *gbRam;
|
extern u8* gbRam;
|
||||||
extern u8 *gbVram;
|
extern u8* gbVram;
|
||||||
extern u8 *gbWram;
|
extern u8* gbWram;
|
||||||
extern u8 *gbMemory;
|
extern u8* gbMemory;
|
||||||
extern u16 *gbLineBuffer;
|
extern u16* gbLineBuffer;
|
||||||
extern u8 *gbTAMA5ram;
|
extern u8* gbTAMA5ram;
|
||||||
|
|
||||||
extern u8 *gbMemoryMap[16];
|
extern u8* gbMemoryMap[16];
|
||||||
|
|
||||||
extern int gbFrameSkip;
|
extern int gbFrameSkip;
|
||||||
extern u16 gbColorFilter[32768];
|
extern u16 gbColorFilter[32768];
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,10 +1,10 @@
|
||||||
#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;
|
||||||
u8 gbPrinterData[0x280*9];
|
u8 gbPrinterData[0x280 * 9];
|
||||||
u8 gbPrinterPacket[0x400];
|
u8 gbPrinterPacket[0x400];
|
||||||
int gbPrinterCount = 0;
|
int gbPrinterCount = 0;
|
||||||
int gbPrinterDataCount = 0;
|
int gbPrinterDataCount = 0;
|
||||||
|
@ -15,12 +15,11 @@ bool gbPrinterCheckCRC()
|
||||||
{
|
{
|
||||||
u16 crc = 0;
|
u16 crc = 0;
|
||||||
|
|
||||||
for(int i = 2; i < (6+gbPrinterDataSize); i++) {
|
for (int i = 2; i < (6 + gbPrinterDataSize); i++) {
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
@ -89,13 +88,13 @@ void gbPrinterShowData()
|
||||||
void gbPrinterReceiveData()
|
void gbPrinterReceiveData()
|
||||||
{
|
{
|
||||||
int i = gbPrinterDataCount;
|
int i = gbPrinterDataCount;
|
||||||
if(gbPrinterPacket[3]) { // compressed
|
if (gbPrinterPacket[3]) { // compressed
|
||||||
u8 *data = &gbPrinterPacket[6];
|
u8* data = &gbPrinterPacket[6];
|
||||||
u8 *dest = &gbPrinterData[gbPrinterDataCount];
|
u8* dest = &gbPrinterData[gbPrinterDataCount];
|
||||||
int len = 0;
|
int len = 0;
|
||||||
while(len < gbPrinterDataSize) {
|
while (len < gbPrinterDataSize) {
|
||||||
u8 control = *data++;
|
u8 control = *data++;
|
||||||
if(control & 0x80) { // repeated data
|
if (control & 0x80) { // repeated data
|
||||||
control &= 0x7f;
|
control &= 0x7f;
|
||||||
control += 2;
|
control += 2;
|
||||||
memset(dest, *data++, control);
|
memset(dest, *data++, control);
|
||||||
|
@ -120,7 +119,7 @@ void gbPrinterReceiveData()
|
||||||
|
|
||||||
void gbPrinterCommand()
|
void gbPrinterCommand()
|
||||||
{
|
{
|
||||||
switch(gbPrinterPacket[2]) {
|
switch (gbPrinterPacket[2]) {
|
||||||
case 0x01:
|
case 0x01:
|
||||||
// reset/initialize packet
|
// reset/initialize packet
|
||||||
gbPrinterDataCount = 0;
|
gbPrinterDataCount = 0;
|
||||||
|
@ -142,11 +141,11 @@ void gbPrinterCommand()
|
||||||
|
|
||||||
u8 gbPrinterSend(u8 b)
|
u8 gbPrinterSend(u8 b)
|
||||||
{
|
{
|
||||||
switch(gbPrinterState) {
|
switch (gbPrinterState) {
|
||||||
case 0:
|
case 0:
|
||||||
gbPrinterCount = 0;
|
gbPrinterCount = 0;
|
||||||
// receiving preamble
|
// receiving preamble
|
||||||
if(b == 0x88) {
|
if (b == 0x88) {
|
||||||
gbPrinterPacket[gbPrinterCount++] = b;
|
gbPrinterPacket[gbPrinterCount++] = b;
|
||||||
gbPrinterState++;
|
gbPrinterState++;
|
||||||
} else {
|
} else {
|
||||||
|
@ -156,7 +155,7 @@ u8 gbPrinterSend(u8 b)
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
// receiving preamble
|
// receiving preamble
|
||||||
if(b == 0x33) {
|
if (b == 0x33) {
|
||||||
gbPrinterPacket[gbPrinterCount++] = b;
|
gbPrinterPacket[gbPrinterCount++] = b;
|
||||||
gbPrinterState++;
|
gbPrinterState++;
|
||||||
} else {
|
} else {
|
||||||
|
@ -167,16 +166,16 @@ u8 gbPrinterSend(u8 b)
|
||||||
case 2:
|
case 2:
|
||||||
// receiving header
|
// receiving header
|
||||||
gbPrinterPacket[gbPrinterCount++] = b;
|
gbPrinterPacket[gbPrinterCount++] = b;
|
||||||
if(gbPrinterCount == 6) {
|
if (gbPrinterCount == 6) {
|
||||||
gbPrinterState++;
|
gbPrinterState++;
|
||||||
gbPrinterDataSize = gbPrinterPacket[4] + (gbPrinterPacket[5]<<8);
|
gbPrinterDataSize = gbPrinterPacket[4] + (gbPrinterPacket[5] << 8);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
// receiving data
|
// receiving data
|
||||||
if(gbPrinterDataSize) {
|
if (gbPrinterDataSize) {
|
||||||
gbPrinterPacket[gbPrinterCount++] = b;
|
gbPrinterPacket[gbPrinterCount++] = b;
|
||||||
if(gbPrinterCount == (6+gbPrinterDataSize)) {
|
if (gbPrinterCount == (6 + gbPrinterDataSize)) {
|
||||||
gbPrinterState++;
|
gbPrinterState++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -191,7 +190,7 @@ u8 gbPrinterSend(u8 b)
|
||||||
case 5:
|
case 5:
|
||||||
// receiving CRC-2
|
// receiving CRC-2
|
||||||
gbPrinterPacket[gbPrinterCount++] = b;
|
gbPrinterPacket[gbPrinterCount++] = b;
|
||||||
if(gbPrinterCheckCRC()) {
|
if (gbPrinterCheckCRC()) {
|
||||||
gbPrinterCommand();
|
gbPrinterCommand();
|
||||||
}
|
}
|
||||||
gbPrinterState++;
|
gbPrinterState++;
|
||||||
|
|
423
src/gb/gbSGB.cpp
423
src/gb/gbSGB.cpp
|
@ -1,13 +1,13 @@
|
||||||
#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"
|
||||||
|
|
||||||
extern u8 *pix;
|
extern u8* pix;
|
||||||
extern bool speedup;
|
extern bool speedup;
|
||||||
extern bool gbSgbResetFlag;
|
extern bool gbSgbResetFlag;
|
||||||
|
|
||||||
|
@ -15,8 +15,8 @@ extern bool gbSgbResetFlag;
|
||||||
#define GBSGB_RESET 1
|
#define GBSGB_RESET 1
|
||||||
#define GBSGB_PACKET_TRANSMIT 2
|
#define GBSGB_PACKET_TRANSMIT 2
|
||||||
|
|
||||||
u8 *gbSgbBorderChar = NULL;
|
u8* gbSgbBorderChar = NULL;
|
||||||
u8 *gbSgbBorder = NULL;
|
u8* gbSgbBorder = NULL;
|
||||||
|
|
||||||
int gbSgbCGBSupport = 0;
|
int gbSgbCGBSupport = 0;
|
||||||
int gbSgbMask = 0;
|
int gbSgbMask = 0;
|
||||||
|
@ -25,7 +25,7 @@ int gbSgbPacketState = GBSGB_NONE;
|
||||||
int gbSgbBit = 0;
|
int gbSgbBit = 0;
|
||||||
int gbSgbPacketTimeout = 0;
|
int gbSgbPacketTimeout = 0;
|
||||||
int GBSGB_PACKET_TIMEOUT = 66666;
|
int GBSGB_PACKET_TIMEOUT = 66666;
|
||||||
u8 gbSgbPacket[16*7];
|
u8 gbSgbPacket[16 * 7];
|
||||||
int gbSgbPacketNBits = 0;
|
int gbSgbPacketNBits = 0;
|
||||||
int gbSgbPacketByte = 0;
|
int gbSgbPacketByte = 0;
|
||||||
int gbSgbPacketNumber = 0;
|
int gbSgbPacketNumber = 0;
|
||||||
|
@ -33,22 +33,22 @@ int gbSgbMultiplayer = 0;
|
||||||
int gbSgbFourPlayers = 0;
|
int gbSgbFourPlayers = 0;
|
||||||
u8 gbSgbNextController = 0x0f;
|
u8 gbSgbNextController = 0x0f;
|
||||||
u8 gbSgbReadingController = 0;
|
u8 gbSgbReadingController = 0;
|
||||||
u16 gbSgbSCPPalette[4*512];
|
u16 gbSgbSCPPalette[4 * 512];
|
||||||
u8 gbSgbATF[20 * 18];
|
u8 gbSgbATF[20 * 18];
|
||||||
u8 gbSgbATFList[45 * 20 * 18];
|
u8 gbSgbATFList[45 * 20 * 18];
|
||||||
u8 gbSgbScreenBuffer[4160];
|
u8 gbSgbScreenBuffer[4160];
|
||||||
|
|
||||||
inline void gbSgbDraw24Bit(u8 *p, u16 v)
|
inline void gbSgbDraw24Bit(u8* p, u16 v)
|
||||||
{
|
{
|
||||||
memcpy(p, &systemColorMap32[v], 3);
|
memcpy(p, &systemColorMap32[v], 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void gbSgbDraw32Bit(u32 *p, u16 v)
|
inline void gbSgbDraw32Bit(u32* p, u16 v)
|
||||||
{
|
{
|
||||||
*p = systemColorMap32[v];
|
*p = systemColorMap32[v];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void gbSgbDraw16Bit(u16 *p, u16 v)
|
inline void gbSgbDraw16Bit(u16* p, u16 v)
|
||||||
{
|
{
|
||||||
*p = systemColorMap16[v];
|
*p = systemColorMap16[v];
|
||||||
}
|
}
|
||||||
|
@ -67,42 +67,42 @@ void gbSgbReset()
|
||||||
gbSgbNextController = 0x0f;
|
gbSgbNextController = 0x0f;
|
||||||
gbSgbReadingController = 0;
|
gbSgbReadingController = 0;
|
||||||
|
|
||||||
memset(gbSgbSCPPalette, 0, 512*4);
|
memset(gbSgbSCPPalette, 0, 512 * 4);
|
||||||
memset(gbSgbATF, 0, 20*18);
|
memset(gbSgbATF, 0, 20 * 18);
|
||||||
memset(gbSgbATFList, 0, 45 * 20 * 18);
|
memset(gbSgbATFList, 0, 45 * 20 * 18);
|
||||||
memset(gbSgbPacket, 0, 16 * 7);
|
memset(gbSgbPacket, 0, 16 * 7);
|
||||||
memset(gbSgbBorderChar, 0, 32*256);
|
memset(gbSgbBorderChar, 0, 32 * 256);
|
||||||
memset(gbSgbBorder, 0, 2048);
|
memset(gbSgbBorder, 0, 2048);
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
for(i = 1; i < 2048; i+=2) {
|
for (i = 1; i < 2048; i += 2) {
|
||||||
gbSgbBorder[i] = 1 << 2;
|
gbSgbBorder[i] = 1 << 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = 0; i < 32; i++) {
|
for (i = 0; i < 32; i++) {
|
||||||
gbPalette[i*4] = (0x1f) | (0x1f << 5) | (0x1f << 10);
|
gbPalette[i * 4] = (0x1f) | (0x1f << 5) | (0x1f << 10);
|
||||||
gbPalette[i*4+1] = (0x15) | (0x15 << 5) | (0x15 << 10);
|
gbPalette[i * 4 + 1] = (0x15) | (0x15 << 5) | (0x15 << 10);
|
||||||
gbPalette[i*4+2] = (0x0c) | (0x0c << 5) | (0x0c << 10);
|
gbPalette[i * 4 + 2] = (0x0c) | (0x0c << 5) | (0x0c << 10);
|
||||||
gbPalette[i*4+3] = 0;
|
gbPalette[i * 4 + 3] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void gbSgbInit()
|
void gbSgbInit()
|
||||||
{
|
{
|
||||||
gbSgbBorderChar = (u8 *)malloc(32 * 256);
|
gbSgbBorderChar = (u8*)malloc(32 * 256);
|
||||||
gbSgbBorder = (u8 *)malloc(2048);
|
gbSgbBorder = (u8*)malloc(2048);
|
||||||
|
|
||||||
gbSgbReset();
|
gbSgbReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void gbSgbShutdown()
|
void gbSgbShutdown()
|
||||||
{
|
{
|
||||||
if(gbSgbBorderChar != NULL) {
|
if (gbSgbBorderChar != NULL) {
|
||||||
free(gbSgbBorderChar);
|
free(gbSgbBorderChar);
|
||||||
gbSgbBorderChar = NULL;
|
gbSgbBorderChar = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(gbSgbBorder != NULL) {
|
if (gbSgbBorder != NULL) {
|
||||||
free(gbSgbBorder);
|
free(gbSgbBorder);
|
||||||
gbSgbBorder = NULL;
|
gbSgbBorder = NULL;
|
||||||
}
|
}
|
||||||
|
@ -110,77 +110,70 @@ 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) + gbBorderColumnSkip;
|
||||||
int yLine = (y+gbBorderRowSkip+1)*(gbBorderLineSkip+2) +
|
u16* dest = (u16*)pix + yLine;
|
||||||
gbBorderColumnSkip;
|
for (register int x = 0; x < 160; x++)
|
||||||
u16 *dest = (u16*)pix + yLine;
|
|
||||||
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++) {
|
||||||
{
|
int yLine = (y + gbBorderRowSkip) * gbBorderLineSkip + gbBorderColumnSkip;
|
||||||
for(int y = 0; y < 144; y++) {
|
u8* dest = (u8*)pix + yLine * 3;
|
||||||
int yLine = (y+gbBorderRowSkip)*gbBorderLineSkip + gbBorderColumnSkip;
|
for (register int x = 0; x < 160; x++) {
|
||||||
u8 *dest = (u8 *)pix + yLine*3;
|
|
||||||
for(register int x = 0; x < 160; x++) {
|
|
||||||
gbSgbDraw24Bit(dest, color);
|
gbSgbDraw24Bit(dest, color);
|
||||||
dest += 3;
|
dest += 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} break;
|
||||||
break;
|
case 32: {
|
||||||
case 32:
|
for (int y = 0; y < 144; y++) {
|
||||||
{
|
int yLine = (y + gbBorderRowSkip + 1) * (gbBorderLineSkip + 1) + gbBorderColumnSkip;
|
||||||
for(int y = 0; y < 144; y++) {
|
u32* dest = (u32*)pix + yLine;
|
||||||
int yLine = (y+gbBorderRowSkip+1)*(gbBorderLineSkip+1) + gbBorderColumnSkip;
|
for (register int x = 0; x < 160; x++) {
|
||||||
u32 *dest = (u32 *)pix + yLine;
|
|
||||||
for(register int x = 0; x < 160; x++) {
|
|
||||||
gbSgbDraw32Bit(dest++, color);
|
gbSgbDraw32Bit(dest++, color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} break;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define getmem(x) gbMemoryMap[(x) >> 12][(x) & 0xfff]
|
#define getmem(x) gbMemoryMap[(x) >> 12][(x)&0xfff]
|
||||||
|
|
||||||
void gbSgbRenderScreenToBuffer()
|
void gbSgbRenderScreenToBuffer()
|
||||||
{
|
{
|
||||||
u16 mapAddress = 0x9800;
|
u16 mapAddress = 0x9800;
|
||||||
|
|
||||||
if(register_LCDC & 0x08)
|
if (register_LCDC & 0x08)
|
||||||
mapAddress = 0x9c00;
|
mapAddress = 0x9c00;
|
||||||
|
|
||||||
u16 patternAddress = 0x8800;
|
u16 patternAddress = 0x8800;
|
||||||
|
|
||||||
int flag = 1;
|
int flag = 1;
|
||||||
|
|
||||||
if(register_LCDC & 0x10) {
|
if (register_LCDC & 0x10) {
|
||||||
patternAddress = 0x8000;
|
patternAddress = 0x8000;
|
||||||
flag = 0;
|
flag = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 *toAddress = gbSgbScreenBuffer;
|
u8* toAddress = gbSgbScreenBuffer;
|
||||||
|
|
||||||
for(int i = 0; i < 13; i++) {
|
for (int i = 0; i < 13; i++) {
|
||||||
for(int j = 0; j < 20; j++) {
|
for (int j = 0; j < 20; j++) {
|
||||||
int tile = getmem(mapAddress);
|
int tile = getmem(mapAddress);
|
||||||
mapAddress++;
|
mapAddress++;
|
||||||
|
|
||||||
if(flag) {
|
if (flag) {
|
||||||
if(tile > 127)
|
if (tile > 127)
|
||||||
tile -= 128;
|
tile -= 128;
|
||||||
else
|
else
|
||||||
tile += 128;
|
tile += 128;
|
||||||
}
|
}
|
||||||
for(int k = 0; k < 16; k++)
|
for (int k = 0; k < 16; k++)
|
||||||
*toAddress++ = getmem(patternAddress + tile*16 + k);
|
*toAddress++ = getmem(patternAddress + tile * 16 + k);
|
||||||
}
|
}
|
||||||
mapAddress += 12;
|
mapAddress += 12;
|
||||||
}
|
}
|
||||||
|
@ -188,18 +181,18 @@ void gbSgbRenderScreenToBuffer()
|
||||||
|
|
||||||
void gbSgbDrawBorderTile(int x, int y, int tile, int attr)
|
void gbSgbDrawBorderTile(int x, int y, int tile, int attr)
|
||||||
{
|
{
|
||||||
u16 *dest = (u16*)pix + ((y+1) * (256+2)) + x;
|
u16* dest = (u16*)pix + ((y + 1) * (256 + 2)) + x;
|
||||||
u8 *dest8 = (u8*)pix + ((y*256)+x)*3;
|
u8* dest8 = (u8*)pix + ((y * 256) + x) * 3;
|
||||||
u32 *dest32 = (u32*)pix + ((y+1)*257) + x;
|
u32* dest32 = (u32*)pix + ((y + 1) * 257) + x;
|
||||||
|
|
||||||
u8 *tileAddress = &gbSgbBorderChar[tile * 32];
|
u8* tileAddress = &gbSgbBorderChar[tile * 32];
|
||||||
u8 *tileAddress2 = &gbSgbBorderChar[tile * 32 + 16];
|
u8* tileAddress2 = &gbSgbBorderChar[tile * 32 + 16];
|
||||||
|
|
||||||
u8 l = 8;
|
u8 l = 8;
|
||||||
|
|
||||||
u8 palette = ((attr >> 2 ) & 7);
|
u8 palette = ((attr >> 2) & 7);
|
||||||
|
|
||||||
if(palette < 4)
|
if (palette < 4)
|
||||||
palette += 4;
|
palette += 4;
|
||||||
|
|
||||||
palette *= 16;
|
palette *= 16;
|
||||||
|
@ -210,37 +203,35 @@ void gbSgbDrawBorderTile(int x, int y, int tile, int attr)
|
||||||
int flipX = attr & 0x40;
|
int flipX = attr & 0x40;
|
||||||
int flipY = attr & 0x80;
|
int flipY = attr & 0x80;
|
||||||
|
|
||||||
while(l > 0) {
|
while (l > 0) {
|
||||||
u8 mask = 0x80;
|
u8 mask = 0x80;
|
||||||
u8 a = *tileAddress++;
|
u8 a = *tileAddress++;
|
||||||
u8 b = *tileAddress++;
|
u8 b = *tileAddress++;
|
||||||
u8 c = *tileAddress2++;
|
u8 c = *tileAddress2++;
|
||||||
u8 d = *tileAddress2++;
|
u8 d = *tileAddress2++;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
u8 yyy;
|
u8 yyy;
|
||||||
if(!flipY)
|
if (!flipY)
|
||||||
yyy = yy;
|
yyy = yy;
|
||||||
else
|
else
|
||||||
yyy = 7 - yy;
|
yyy = 7 - yy;
|
||||||
|
|
||||||
while(mask > 0) {
|
while (mask > 0) {
|
||||||
|
|
||||||
u8 color = 0;
|
u8 color = 0;
|
||||||
if(a & mask)
|
if (a & mask)
|
||||||
color++;
|
color++;
|
||||||
if(b & mask)
|
if (b & mask)
|
||||||
color+=2;
|
color += 2;
|
||||||
if(c & mask)
|
if (c & mask)
|
||||||
color+=4;
|
color += 4;
|
||||||
if(d & mask)
|
if (d & mask)
|
||||||
color+=8;
|
color += 8;
|
||||||
|
|
||||||
if (color || (y + yy < 40 || y + yy >= 184) || (x + xx < 48 || x + xx >= 208)) {
|
if (color || (y + yy < 40 || y + yy >= 184) || (x + xx < 48 || x + xx >= 208)) {
|
||||||
u8 xxx;
|
u8 xxx;
|
||||||
|
|
||||||
if(!flipX)
|
if (!flipX)
|
||||||
xxx = xx;
|
xxx = xx;
|
||||||
else
|
else
|
||||||
xxx = 7 - xx;
|
xxx = 7 - xx;
|
||||||
|
@ -252,15 +243,15 @@ void gbSgbDrawBorderTile(int x, int y, int tile, int attr)
|
||||||
cc = gbPalette[0];
|
cc = gbPalette[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(systemColorDepth) {
|
switch (systemColorDepth) {
|
||||||
case 16:
|
case 16:
|
||||||
gbSgbDraw16Bit(dest + yyy*(256+2) + xxx, cc);
|
gbSgbDraw16Bit(dest + yyy * (256 + 2) + xxx, cc);
|
||||||
break;
|
break;
|
||||||
case 24:
|
case 24:
|
||||||
gbSgbDraw24Bit(dest8 + (yyy*256+xxx)*3, cc);
|
gbSgbDraw24Bit(dest8 + (yyy * 256 + xxx) * 3, cc);
|
||||||
break;
|
break;
|
||||||
case 32:
|
case 32:
|
||||||
gbSgbDraw32Bit(dest32 + yyy*(256+1)+xxx, cc);
|
gbSgbDraw32Bit(dest32 + yyy * (256 + 1) + xxx, cc);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -278,15 +269,15 @@ void gbSgbDrawBorderTile(int x, int y, int tile, int attr)
|
||||||
|
|
||||||
void gbSgbRenderBorder()
|
void gbSgbRenderBorder()
|
||||||
{
|
{
|
||||||
if(gbBorderOn) {
|
if (gbBorderOn) {
|
||||||
u8 *fromAddress = gbSgbBorder;
|
u8* fromAddress = gbSgbBorder;
|
||||||
|
|
||||||
for(u8 y = 0; y < 28; y++) {
|
for (u8 y = 0; y < 28; y++) {
|
||||||
for(u8 x = 0; x< 32; x++) {
|
for (u8 x = 0; x < 32; x++) {
|
||||||
u8 tile = *fromAddress++;
|
u8 tile = *fromAddress++;
|
||||||
u8 attr = *fromAddress++;
|
u8 attr = *fromAddress++;
|
||||||
|
|
||||||
gbSgbDrawBorderTile(x*8,y*8,tile,attr);
|
gbSgbDrawBorderTile(x * 8, y * 8, tile, attr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -298,23 +289,23 @@ void gbSgbPicture()
|
||||||
|
|
||||||
memcpy(gbSgbBorder, gbSgbScreenBuffer, 2048);
|
memcpy(gbSgbBorder, gbSgbScreenBuffer, 2048);
|
||||||
|
|
||||||
u16 *paletteAddr = (u16 *)&gbSgbScreenBuffer[2048];
|
u16* paletteAddr = (u16*)&gbSgbScreenBuffer[2048];
|
||||||
|
|
||||||
for(int i = 64; i < 128; i++) {
|
for (int i = 64; i < 128; i++) {
|
||||||
gbPalette[i] = READ16LE(paletteAddr++);
|
gbPalette[i] = READ16LE(paletteAddr++);
|
||||||
}
|
}
|
||||||
|
|
||||||
gbSgbCGBSupport |= 4;
|
gbSgbCGBSupport |= 4;
|
||||||
|
|
||||||
if(gbBorderAutomatic && !gbBorderOn && gbSgbCGBSupport > 4) {
|
if (gbBorderAutomatic && !gbBorderOn && gbSgbCGBSupport > 4) {
|
||||||
gbBorderOn = 1;
|
gbBorderOn = 1;
|
||||||
systemGbBorderOn();
|
systemGbBorderOn();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(gbBorderOn && !gbSgbMask)
|
if (gbBorderOn && !gbSgbMask)
|
||||||
gbSgbRenderBorder();
|
gbSgbRenderBorder();
|
||||||
|
|
||||||
if(gbSgbMode && gbCgbMode && gbSgbCGBSupport > 4) {
|
if (gbSgbMode && gbCgbMode && gbSgbCGBSupport > 4) {
|
||||||
gbSgbCGBSupport = 0;
|
gbSgbCGBSupport = 0;
|
||||||
gbSgbMode = 0;
|
gbSgbMode = 0;
|
||||||
gbSgbMask = 0;
|
gbSgbMask = 0;
|
||||||
|
@ -322,25 +313,25 @@ void gbSgbPicture()
|
||||||
gbReset();
|
gbReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(gbSgbCGBSupport > 4)
|
if (gbSgbCGBSupport > 4)
|
||||||
gbSgbCGBSupport = 0;
|
gbSgbCGBSupport = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gbSgbSetPalette(int a,int b,u16 *p)
|
void gbSgbSetPalette(int a, int b, u16* p)
|
||||||
{
|
{
|
||||||
u16 bit00 = READ16LE(p++);
|
u16 bit00 = READ16LE(p++);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for(i = 1; i < 4; i++) {
|
for (i = 1; i < 4; i++) {
|
||||||
gbPalette[a*4+i] = READ16LE(p++);
|
gbPalette[a * 4 + i] = READ16LE(p++);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = 1; i < 4; i++) {
|
for (i = 1; i < 4; i++) {
|
||||||
gbPalette[b*4+i] = READ16LE(p++);
|
gbPalette[b * 4 + i] = READ16LE(p++);
|
||||||
}
|
}
|
||||||
|
|
||||||
gbPalette[0] = gbPalette[4] = gbPalette[8] = gbPalette[12] = bit00;
|
gbPalette[0] = gbPalette[4] = gbPalette[8] = gbPalette[12] = bit00;
|
||||||
if(gbBorderOn && !gbSgbMask)
|
if (gbBorderOn && !gbSgbMask)
|
||||||
gbSgbRenderBorder();
|
gbSgbRenderBorder();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -348,66 +339,66 @@ void gbSgbScpPalette()
|
||||||
{
|
{
|
||||||
gbSgbRenderScreenToBuffer();
|
gbSgbRenderScreenToBuffer();
|
||||||
|
|
||||||
u16 *fromAddress = (u16 *)gbSgbScreenBuffer;
|
u16* fromAddress = (u16*)gbSgbScreenBuffer;
|
||||||
|
|
||||||
for(int i = 0; i < 512*4; i++) {
|
for (int i = 0; i < 512 * 4; i++) {
|
||||||
gbSgbSCPPalette[i] = READ16LE(fromAddress++);
|
gbSgbSCPPalette[i] = READ16LE(fromAddress++);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void gbSgbSetATF(int n)
|
void gbSgbSetATF(int n)
|
||||||
{
|
{
|
||||||
if(n < 0)
|
if (n < 0)
|
||||||
n = 0;
|
n = 0;
|
||||||
if(n > 44)
|
if (n > 44)
|
||||||
n = 44;
|
n = 44;
|
||||||
memcpy(gbSgbATF,&gbSgbATFList[n * 20 * 18], 20 * 18);
|
memcpy(gbSgbATF, &gbSgbATFList[n * 20 * 18], 20 * 18);
|
||||||
|
|
||||||
if(gbSgbPacket[1] & 0x40) {
|
if (gbSgbPacket[1] & 0x40) {
|
||||||
gbSgbMask = 0;
|
gbSgbMask = 0;
|
||||||
if(gbBorderOn)
|
if (gbBorderOn)
|
||||||
gbSgbRenderBorder();
|
gbSgbRenderBorder();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void gbSgbSetPalette()
|
void gbSgbSetPalette()
|
||||||
{
|
{
|
||||||
u16 pal = READ16LE((((u16 *)&gbSgbPacket[1])))&511;
|
u16 pal = READ16LE((((u16*)&gbSgbPacket[1]))) & 511;
|
||||||
memcpy(&gbPalette[0], &gbSgbSCPPalette[pal*4], 4 * sizeof(u16));
|
memcpy(&gbPalette[0], &gbSgbSCPPalette[pal * 4], 4 * sizeof(u16));
|
||||||
|
|
||||||
pal = READ16LE((((u16 *)&gbSgbPacket[3])))&511;
|
pal = READ16LE((((u16*)&gbSgbPacket[3]))) & 511;
|
||||||
memcpy(&gbPalette[4], &gbSgbSCPPalette[pal*4], 4 * sizeof(u16));
|
memcpy(&gbPalette[4], &gbSgbSCPPalette[pal * 4], 4 * sizeof(u16));
|
||||||
|
|
||||||
pal = READ16LE((((u16 *)&gbSgbPacket[5])))&511;
|
pal = READ16LE((((u16*)&gbSgbPacket[5]))) & 511;
|
||||||
memcpy(&gbPalette[8], &gbSgbSCPPalette[pal*4], 4 * sizeof(u16));
|
memcpy(&gbPalette[8], &gbSgbSCPPalette[pal * 4], 4 * sizeof(u16));
|
||||||
|
|
||||||
pal = READ16LE((((u16 *)&gbSgbPacket[7])))&511;
|
pal = READ16LE((((u16*)&gbSgbPacket[7]))) & 511;
|
||||||
memcpy(&gbPalette[12], &gbSgbSCPPalette[pal*4], 4 * sizeof(u16));
|
memcpy(&gbPalette[12], &gbSgbSCPPalette[pal * 4], 4 * sizeof(u16));
|
||||||
|
|
||||||
u8 atf = gbSgbPacket[9];
|
u8 atf = gbSgbPacket[9];
|
||||||
|
|
||||||
if(atf & 0x80) {
|
if (atf & 0x80) {
|
||||||
gbSgbSetATF(atf & 0x3f);
|
gbSgbSetATF(atf & 0x3f);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(atf & 0x40) {
|
if (atf & 0x40) {
|
||||||
gbSgbMask = 0;
|
gbSgbMask = 0;
|
||||||
if(gbBorderOn)
|
if (gbBorderOn)
|
||||||
gbSgbRenderBorder();
|
gbSgbRenderBorder();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void gbSgbAttributeBlock()
|
void gbSgbAttributeBlock()
|
||||||
{
|
{
|
||||||
u8 *fromAddress = &gbSgbPacket[1];
|
u8* fromAddress = &gbSgbPacket[1];
|
||||||
|
|
||||||
u8 nDataSet = *fromAddress++;
|
u8 nDataSet = *fromAddress++;
|
||||||
if(nDataSet > 12)
|
if (nDataSet > 12)
|
||||||
nDataSet = 12;
|
nDataSet = 12;
|
||||||
if(nDataSet == 0)
|
if (nDataSet == 0)
|
||||||
nDataSet = 1;
|
nDataSet = 1;
|
||||||
|
|
||||||
while(nDataSet) {
|
while (nDataSet) {
|
||||||
u8 controlCode = (*fromAddress++) & 7;
|
u8 controlCode = (*fromAddress++) & 7;
|
||||||
u8 paletteDesignation = (*fromAddress++) & 0x3f;
|
u8 paletteDesignation = (*fromAddress++) & 0x3f;
|
||||||
u8 startH = (*fromAddress++) & 0x1f;
|
u8 startH = (*fromAddress++) & 0x1f;
|
||||||
|
@ -415,25 +406,23 @@ void gbSgbAttributeBlock()
|
||||||
u8 endH = (*fromAddress++) & 0x1f;
|
u8 endH = (*fromAddress++) & 0x1f;
|
||||||
u8 endV = (*fromAddress++) & 0x1f;
|
u8 endV = (*fromAddress++) & 0x1f;
|
||||||
|
|
||||||
u8 * toAddress = gbSgbATF;
|
u8* toAddress = gbSgbATF;
|
||||||
|
|
||||||
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;
|
||||||
} else {
|
} else {
|
||||||
// surrounding line
|
// surrounding line
|
||||||
if(controlCode & 0x02)
|
if (controlCode & 0x02)
|
||||||
*toAddress = (paletteDesignation>>2) & 0x03;
|
*toAddress = (paletteDesignation >> 2) & 0x03;
|
||||||
else if(controlCode == 0x01)
|
else if (controlCode == 0x01)
|
||||||
*toAddress = paletteDesignation & 0x03;
|
*toAddress = paletteDesignation & 0x03;
|
||||||
}
|
}
|
||||||
toAddress++;
|
toAddress++;
|
||||||
|
@ -447,14 +436,14 @@ void gbSgbSetColumnPalette(u8 col, u8 p)
|
||||||
{
|
{
|
||||||
// if(col < 0)
|
// if(col < 0)
|
||||||
// col = 0;
|
// col = 0;
|
||||||
if(col > 19)
|
if (col > 19)
|
||||||
col = 19;
|
col = 19;
|
||||||
|
|
||||||
p &= 3;
|
p &= 3;
|
||||||
|
|
||||||
u8 *toAddress = &gbSgbATF[col];
|
u8* toAddress = &gbSgbATF[col];
|
||||||
|
|
||||||
for(u8 y = 0; y < 18; y++) {
|
for (u8 y = 0; y < 18; y++) {
|
||||||
*toAddress = p;
|
*toAddress = p;
|
||||||
toAddress += 20;
|
toAddress += 20;
|
||||||
}
|
}
|
||||||
|
@ -464,14 +453,14 @@ void gbSgbSetRowPalette(u8 row, u8 p)
|
||||||
{
|
{
|
||||||
// if(row < 0)
|
// if(row < 0)
|
||||||
// row = 0;
|
// row = 0;
|
||||||
if(row > 17)
|
if (row > 17)
|
||||||
row = 17;
|
row = 17;
|
||||||
|
|
||||||
p &= 3;
|
p &= 3;
|
||||||
|
|
||||||
u8 *toAddress = &gbSgbATF[row*20];
|
u8* toAddress = &gbSgbATF[row * 20];
|
||||||
|
|
||||||
for(u8 x = 0; x < 20; x++) {
|
for (u8 x = 0; x < 20; x++) {
|
||||||
*toAddress++ = p;
|
*toAddress++ = p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -484,26 +473,26 @@ void gbSgbAttributeDivide()
|
||||||
u8 colorAL = (control >> 2) & 3;
|
u8 colorAL = (control >> 2) & 3;
|
||||||
u8 colorOL = (control >> 4) & 3;
|
u8 colorOL = (control >> 4) & 3;
|
||||||
|
|
||||||
if(control & 0x40) {
|
if (control & 0x40) {
|
||||||
if(coord > 17)
|
if (coord > 17)
|
||||||
coord = 17;
|
coord = 17;
|
||||||
|
|
||||||
for(u8 i = 0; i < 18; i++) {
|
for (u8 i = 0; i < 18; i++) {
|
||||||
if(i < coord)
|
if (i < coord)
|
||||||
gbSgbSetRowPalette(i, colorAL);
|
gbSgbSetRowPalette(i, colorAL);
|
||||||
else if ( i > coord)
|
else if (i > coord)
|
||||||
gbSgbSetRowPalette(i, colorBR);
|
gbSgbSetRowPalette(i, colorBR);
|
||||||
else
|
else
|
||||||
gbSgbSetRowPalette(i, colorOL);
|
gbSgbSetRowPalette(i, colorOL);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(coord > 19)
|
if (coord > 19)
|
||||||
coord = 19;
|
coord = 19;
|
||||||
|
|
||||||
for(u8 i = 0; i < 20; i++) {
|
for (u8 i = 0; i < 20; i++) {
|
||||||
if(i < coord)
|
if (i < coord)
|
||||||
gbSgbSetColumnPalette(i, colorAL);
|
gbSgbSetColumnPalette(i, colorAL);
|
||||||
else if ( i > coord)
|
else if (i > coord)
|
||||||
gbSgbSetColumnPalette(i, colorBR);
|
gbSgbSetColumnPalette(i, colorBR);
|
||||||
else
|
else
|
||||||
gbSgbSetColumnPalette(i, colorOL);
|
gbSgbSetColumnPalette(i, colorOL);
|
||||||
|
@ -513,25 +502,25 @@ void gbSgbAttributeDivide()
|
||||||
|
|
||||||
void gbSgbAttributeLine()
|
void gbSgbAttributeLine()
|
||||||
{
|
{
|
||||||
u8 *fromAddress = &gbSgbPacket[1];
|
u8* fromAddress = &gbSgbPacket[1];
|
||||||
|
|
||||||
u8 nDataSet = *fromAddress++;
|
u8 nDataSet = *fromAddress++;
|
||||||
|
|
||||||
if(nDataSet > 0x6e)
|
if (nDataSet > 0x6e)
|
||||||
nDataSet = 0x6e;
|
nDataSet = 0x6e;
|
||||||
|
|
||||||
while(nDataSet) {
|
while (nDataSet) {
|
||||||
u8 line = *fromAddress++;
|
u8 line = *fromAddress++;
|
||||||
u8 num = line & 0x1f;
|
u8 num = line & 0x1f;
|
||||||
u8 pal = (line >> 5) & 0x03;
|
u8 pal = (line >> 5) & 0x03;
|
||||||
if(line & 0x80) {
|
if (line & 0x80) {
|
||||||
if(num > 17)
|
if (num > 17)
|
||||||
num = 17;
|
num = 17;
|
||||||
gbSgbSetRowPalette(num,pal);
|
gbSgbSetRowPalette(num, pal);
|
||||||
} else {
|
} else {
|
||||||
if(num > 19)
|
if (num > 19)
|
||||||
num = 19;
|
num = 19;
|
||||||
gbSgbSetColumnPalette(num,pal);
|
gbSgbSetColumnPalette(num, pal);
|
||||||
}
|
}
|
||||||
nDataSet--;
|
nDataSet--;
|
||||||
}
|
}
|
||||||
|
@ -541,30 +530,30 @@ void gbSgbAttributeCharacter()
|
||||||
{
|
{
|
||||||
u8 startH = gbSgbPacket[1] & 0x1f;
|
u8 startH = gbSgbPacket[1] & 0x1f;
|
||||||
u8 startV = gbSgbPacket[2] & 0x1f;
|
u8 startV = gbSgbPacket[2] & 0x1f;
|
||||||
int nDataSet = READ16LE(((u16 *)&gbSgbPacket[3]));
|
int nDataSet = READ16LE(((u16*)&gbSgbPacket[3]));
|
||||||
int style = gbSgbPacket[5] & 1;
|
int style = gbSgbPacket[5] & 1;
|
||||||
if(startH > 19)
|
if (startH > 19)
|
||||||
startH = 19;
|
startH = 19;
|
||||||
if(startV > 17)
|
if (startV > 17)
|
||||||
startV = 17;
|
startV = 17;
|
||||||
|
|
||||||
u8 s = 6;
|
u8 s = 6;
|
||||||
u8 *fromAddress = &gbSgbPacket[6];
|
u8* fromAddress = &gbSgbPacket[6];
|
||||||
u8 v = *fromAddress++;
|
u8 v = *fromAddress++;
|
||||||
|
|
||||||
if(style) {
|
if (style) {
|
||||||
while(nDataSet) {
|
while (nDataSet) {
|
||||||
u8 p = (v >> s) & 3;
|
u8 p = (v >> s) & 3;
|
||||||
gbSgbATF[startV * 20 + startH] = p;
|
gbSgbATF[startV * 20 + startH] = p;
|
||||||
startV++;
|
startV++;
|
||||||
if(startV == 18) {
|
if (startV == 18) {
|
||||||
startV = 0;
|
startV = 0;
|
||||||
startH++;
|
startH++;
|
||||||
if(startH == 20)
|
if (startH == 20)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(s)
|
if (s)
|
||||||
s -= 2;
|
s -= 2;
|
||||||
else {
|
else {
|
||||||
s = 6;
|
s = 6;
|
||||||
|
@ -573,18 +562,18 @@ void gbSgbAttributeCharacter()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
while(nDataSet) {
|
while (nDataSet) {
|
||||||
u8 p = (v >> s) & 3;
|
u8 p = (v >> s) & 3;
|
||||||
gbSgbATF[startV * 20 + startH] = p;
|
gbSgbATF[startV * 20 + startH] = p;
|
||||||
startH++;
|
startH++;
|
||||||
if(startH == 20) {
|
if (startH == 20) {
|
||||||
startH = 0;
|
startH = 0;
|
||||||
startV++;
|
startV++;
|
||||||
if(startV == 18)
|
if (startV == 18)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(s)
|
if (s)
|
||||||
s -= 2;
|
s -= 2;
|
||||||
else {
|
else {
|
||||||
s = 6;
|
s = 6;
|
||||||
|
@ -599,16 +588,16 @@ void gbSgbSetATFList()
|
||||||
{
|
{
|
||||||
gbSgbRenderScreenToBuffer();
|
gbSgbRenderScreenToBuffer();
|
||||||
|
|
||||||
u8 *fromAddress = gbSgbScreenBuffer;
|
u8* fromAddress = gbSgbScreenBuffer;
|
||||||
u8 *toAddress = gbSgbATFList;
|
u8* toAddress = gbSgbATFList;
|
||||||
|
|
||||||
for(int i = 0; i < 45; i++) {
|
for (int i = 0; i < 45; i++) {
|
||||||
for(int j = 0; j < 90; j++) {
|
for (int j = 0; j < 90; j++) {
|
||||||
u8 v = *fromAddress++;
|
u8 v = *fromAddress++;
|
||||||
u8 s = 6;
|
u8 s = 6;
|
||||||
if(i == 2)
|
if (i == 2)
|
||||||
s = 6;
|
s = 6;
|
||||||
for(int k = 0; k < 4; k++) {
|
for (int k = 0; k < 4; k++) {
|
||||||
*toAddress++ = (v >> s) & 0x03;
|
*toAddress++ = (v >> s) & 0x03;
|
||||||
s -= 2;
|
s -= 2;
|
||||||
}
|
}
|
||||||
|
@ -622,7 +611,7 @@ void gbSgbMaskEnable()
|
||||||
|
|
||||||
gbSgbMask = gbSgbMaskFlag;
|
gbSgbMask = gbSgbMaskFlag;
|
||||||
|
|
||||||
switch(gbSgbMaskFlag) {
|
switch (gbSgbMaskFlag) {
|
||||||
case 1:
|
case 1:
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
|
@ -633,8 +622,8 @@ void gbSgbMaskEnable()
|
||||||
gbSgbFillScreen(gbPalette[0]);
|
gbSgbFillScreen(gbPalette[0]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(!gbSgbMask) {
|
if (!gbSgbMask) {
|
||||||
if(gbBorderOn)
|
if (gbBorderOn)
|
||||||
gbSgbRenderBorder();
|
gbSgbRenderBorder();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -643,24 +632,24 @@ void gbSgbChrTransfer()
|
||||||
{
|
{
|
||||||
gbSgbRenderScreenToBuffer();
|
gbSgbRenderScreenToBuffer();
|
||||||
|
|
||||||
int address = (gbSgbPacket[1] & 1) * (128*32);
|
int address = (gbSgbPacket[1] & 1) * (128 * 32);
|
||||||
|
|
||||||
if(gbSgbPacket[1] & 1)
|
if (gbSgbPacket[1] & 1)
|
||||||
gbSgbCGBSupport |= 2;
|
gbSgbCGBSupport |= 2;
|
||||||
else
|
else
|
||||||
gbSgbCGBSupport |= 1;
|
gbSgbCGBSupport |= 1;
|
||||||
|
|
||||||
memcpy(&gbSgbBorderChar[address], gbSgbScreenBuffer, 128 * 32);
|
memcpy(&gbSgbBorderChar[address], gbSgbScreenBuffer, 128 * 32);
|
||||||
|
|
||||||
if(gbBorderAutomatic && !gbBorderOn && gbSgbCGBSupport > 4) {
|
if (gbBorderAutomatic && !gbBorderOn && gbSgbCGBSupport > 4) {
|
||||||
gbBorderOn = 1;
|
gbBorderOn = 1;
|
||||||
systemGbBorderOn();
|
systemGbBorderOn();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(gbBorderOn && !gbSgbMask)
|
if (gbBorderOn && !gbSgbMask)
|
||||||
gbSgbRenderBorder();
|
gbSgbRenderBorder();
|
||||||
|
|
||||||
if(gbSgbMode && gbCgbMode && gbSgbCGBSupport == 7) {
|
if (gbSgbMode && gbCgbMode && gbSgbCGBSupport == 7) {
|
||||||
gbSgbCGBSupport = 0;
|
gbSgbCGBSupport = 0;
|
||||||
gbSgbMode = 0;
|
gbSgbMode = 0;
|
||||||
gbSgbMask = 0;
|
gbSgbMask = 0;
|
||||||
|
@ -668,15 +657,15 @@ void gbSgbChrTransfer()
|
||||||
gbReset();
|
gbReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(gbSgbCGBSupport > 4)
|
if (gbSgbCGBSupport > 4)
|
||||||
gbSgbCGBSupport = 0;
|
gbSgbCGBSupport = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gbSgbMultiRequest()
|
void gbSgbMultiRequest()
|
||||||
{
|
{
|
||||||
if(gbSgbPacket[1] & 1) {
|
if (gbSgbPacket[1] & 1) {
|
||||||
gbSgbMultiplayer = 1;
|
gbSgbMultiplayer = 1;
|
||||||
if(gbSgbPacket[1] & 2)
|
if (gbSgbPacket[1] & 2)
|
||||||
gbSgbFourPlayers = 1;
|
gbSgbFourPlayers = 1;
|
||||||
else
|
else
|
||||||
gbSgbFourPlayers = 0;
|
gbSgbFourPlayers = 0;
|
||||||
|
@ -693,18 +682,18 @@ void gbSgbCommand()
|
||||||
int command = gbSgbPacket[0] >> 3;
|
int command = gbSgbPacket[0] >> 3;
|
||||||
// int nPacket = gbSgbPacket[0] & 7;
|
// int nPacket = gbSgbPacket[0] & 7;
|
||||||
|
|
||||||
switch(command) {
|
switch (command) {
|
||||||
case 0x00:
|
case 0x00:
|
||||||
gbSgbSetPalette(0,1,(u16 *)&gbSgbPacket[1]);
|
gbSgbSetPalette(0, 1, (u16*)&gbSgbPacket[1]);
|
||||||
break;
|
break;
|
||||||
case 0x01:
|
case 0x01:
|
||||||
gbSgbSetPalette(2,3,(u16 *)&gbSgbPacket[1]);
|
gbSgbSetPalette(2, 3, (u16*)&gbSgbPacket[1]);
|
||||||
break;
|
break;
|
||||||
case 0x02:
|
case 0x02:
|
||||||
gbSgbSetPalette(0,3,(u16 *)&gbSgbPacket[1]);
|
gbSgbSetPalette(0, 3, (u16*)&gbSgbPacket[1]);
|
||||||
break;
|
break;
|
||||||
case 0x03:
|
case 0x03:
|
||||||
gbSgbSetPalette(1,2,(u16 *)&gbSgbPacket[1]);
|
gbSgbSetPalette(1, 2, (u16*)&gbSgbPacket[1]);
|
||||||
break;
|
break;
|
||||||
case 0x04:
|
case 0x04:
|
||||||
gbSgbAttributeBlock();
|
gbSgbAttributeBlock();
|
||||||
|
@ -754,22 +743,22 @@ void gbSgbResetPacketState()
|
||||||
void gbSgbDoBitTransfer(u8 value)
|
void gbSgbDoBitTransfer(u8 value)
|
||||||
{
|
{
|
||||||
value = value & 0x30;
|
value = value & 0x30;
|
||||||
switch(gbSgbPacketState) {
|
switch (gbSgbPacketState) {
|
||||||
case GBSGB_NONE:
|
case GBSGB_NONE:
|
||||||
if(value == 0) {
|
if (value == 0) {
|
||||||
gbSgbPacketState = GBSGB_RESET;
|
gbSgbPacketState = GBSGB_RESET;
|
||||||
gbSgbPacketTimeout = GBSGB_PACKET_TIMEOUT;
|
gbSgbPacketTimeout = GBSGB_PACKET_TIMEOUT;
|
||||||
} else if (value == 0x30) {
|
} else if (value == 0x30) {
|
||||||
if(gbSgbMultiplayer) {
|
if (gbSgbMultiplayer) {
|
||||||
if((gbSgbReadingController & 7) == 7) {
|
if ((gbSgbReadingController & 7) == 7) {
|
||||||
gbSgbReadingController = 0;
|
gbSgbReadingController = 0;
|
||||||
if(gbSgbMultiplayer) {
|
if (gbSgbMultiplayer) {
|
||||||
gbSgbNextController--;
|
gbSgbNextController--;
|
||||||
if(gbSgbFourPlayers) {
|
if (gbSgbFourPlayers) {
|
||||||
if(gbSgbNextController == 0x0b)
|
if (gbSgbNextController == 0x0b)
|
||||||
gbSgbNextController = 0x0f;
|
gbSgbNextController = 0x0f;
|
||||||
} else {
|
} else {
|
||||||
if(gbSgbNextController == 0x0d)
|
if (gbSgbNextController == 0x0d)
|
||||||
gbSgbNextController = 0x0f;
|
gbSgbNextController = 0x0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -779,21 +768,21 @@ void gbSgbDoBitTransfer(u8 value)
|
||||||
}
|
}
|
||||||
gbSgbPacketTimeout = 0;
|
gbSgbPacketTimeout = 0;
|
||||||
} else {
|
} else {
|
||||||
if(value == 0x10)
|
if (value == 0x10)
|
||||||
gbSgbReadingController |= 0x2;
|
gbSgbReadingController |= 0x2;
|
||||||
else if(value == 0x20)
|
else if (value == 0x20)
|
||||||
gbSgbReadingController |= 0x01;
|
gbSgbReadingController |= 0x01;
|
||||||
gbSgbPacketTimeout = 0;
|
gbSgbPacketTimeout = 0;
|
||||||
}
|
}
|
||||||
gbSgbPacketTimeout = 0;
|
gbSgbPacketTimeout = 0;
|
||||||
break;
|
break;
|
||||||
case GBSGB_RESET:
|
case GBSGB_RESET:
|
||||||
if(value == 0x30) {
|
if (value == 0x30) {
|
||||||
gbSgbPacketState = GBSGB_PACKET_TRANSMIT;
|
gbSgbPacketState = GBSGB_PACKET_TRANSMIT;
|
||||||
gbSgbPacketByte = 0;
|
gbSgbPacketByte = 0;
|
||||||
gbSgbPacketNBits = 0;
|
gbSgbPacketNBits = 0;
|
||||||
gbSgbPacketTimeout = GBSGB_PACKET_TIMEOUT;
|
gbSgbPacketTimeout = GBSGB_PACKET_TIMEOUT;
|
||||||
} else if(value == 0x00) {
|
} else if (value == 0x00) {
|
||||||
gbSgbPacketTimeout = GBSGB_PACKET_TIMEOUT;
|
gbSgbPacketTimeout = GBSGB_PACKET_TIMEOUT;
|
||||||
gbSgbPacketState = GBSGB_RESET;
|
gbSgbPacketState = GBSGB_RESET;
|
||||||
} else {
|
} else {
|
||||||
|
@ -802,34 +791,34 @@ void gbSgbDoBitTransfer(u8 value)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GBSGB_PACKET_TRANSMIT:
|
case GBSGB_PACKET_TRANSMIT:
|
||||||
if(value == 0) {
|
if (value == 0) {
|
||||||
gbSgbPacketState = GBSGB_RESET;
|
gbSgbPacketState = GBSGB_RESET;
|
||||||
gbSgbPacketTimeout = 0;
|
gbSgbPacketTimeout = 0;
|
||||||
} else if (value == 0x30){
|
} else if (value == 0x30) {
|
||||||
if(gbSgbPacketNBits == 128) {
|
if (gbSgbPacketNBits == 128) {
|
||||||
gbSgbPacketNBits = 0;
|
gbSgbPacketNBits = 0;
|
||||||
gbSgbPacketByte = 0;
|
gbSgbPacketByte = 0;
|
||||||
gbSgbPacketNumber++;
|
gbSgbPacketNumber++;
|
||||||
gbSgbPacketTimeout = 0;
|
gbSgbPacketTimeout = 0;
|
||||||
if(gbSgbPacketNumber == (gbSgbPacket[0] & 7)) {
|
if (gbSgbPacketNumber == (gbSgbPacket[0] & 7)) {
|
||||||
gbSgbCommand();
|
gbSgbCommand();
|
||||||
gbSgbPacketNumber = 0;
|
gbSgbPacketNumber = 0;
|
||||||
gbSgbPacketState = GBSGB_NONE;
|
gbSgbPacketState = GBSGB_NONE;
|
||||||
gbSgbPacketTimeout = 0;
|
gbSgbPacketTimeout = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(gbSgbPacketNBits < 128) {
|
if (gbSgbPacketNBits < 128) {
|
||||||
gbSgbPacket[gbSgbPacketNumber * 16 + gbSgbPacketByte] >>= 1;
|
gbSgbPacket[gbSgbPacketNumber * 16 + gbSgbPacketByte] >>= 1;
|
||||||
gbSgbPacket[gbSgbPacketNumber * 16 + gbSgbPacketByte] |= gbSgbBit;
|
gbSgbPacket[gbSgbPacketNumber * 16 + gbSgbPacketByte] |= gbSgbBit;
|
||||||
gbSgbPacketNBits++;
|
gbSgbPacketNBits++;
|
||||||
if(!(gbSgbPacketNBits & 7)) {
|
if (!(gbSgbPacketNBits & 7)) {
|
||||||
gbSgbPacketByte++;
|
gbSgbPacketByte++;
|
||||||
}
|
}
|
||||||
gbSgbPacketTimeout = GBSGB_PACKET_TIMEOUT;
|
gbSgbPacketTimeout = GBSGB_PACKET_TIMEOUT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(value == 0x20)
|
if (value == 0x20)
|
||||||
gbSgbBit = 0x00;
|
gbSgbBit = 0x00;
|
||||||
else
|
else
|
||||||
gbSgbBit = 0x80;
|
gbSgbBit = 0x80;
|
||||||
|
@ -876,9 +865,9 @@ void gbSgbSaveGame(gzFile gzFile)
|
||||||
utilWriteData(gzFile, gbSgbSaveStructV3);
|
utilWriteData(gzFile, gbSgbSaveStructV3);
|
||||||
|
|
||||||
utilGzWrite(gzFile, gbSgbBorder, 2048);
|
utilGzWrite(gzFile, gbSgbBorder, 2048);
|
||||||
utilGzWrite(gzFile, gbSgbBorderChar, 32*256);
|
utilGzWrite(gzFile, gbSgbBorderChar, 32 * 256);
|
||||||
|
|
||||||
utilGzWrite(gzFile, gbSgbPacket, 16*7);
|
utilGzWrite(gzFile, gbSgbPacket, 16 * 7);
|
||||||
|
|
||||||
utilGzWrite(gzFile, gbSgbSCPPalette, 4 * 512 * sizeof(u16));
|
utilGzWrite(gzFile, gbSgbSCPPalette, 4 * 512 * sizeof(u16));
|
||||||
utilGzWrite(gzFile, gbSgbATF, 20 * 18);
|
utilGzWrite(gzFile, gbSgbATF, 20 * 18);
|
||||||
|
@ -887,19 +876,19 @@ void gbSgbSaveGame(gzFile gzFile)
|
||||||
|
|
||||||
void gbSgbReadGame(gzFile gzFile, int version)
|
void gbSgbReadGame(gzFile gzFile, int version)
|
||||||
{
|
{
|
||||||
if(version >= 3)
|
if (version >= 3)
|
||||||
utilReadData(gzFile, gbSgbSaveStructV3);
|
utilReadData(gzFile, gbSgbSaveStructV3);
|
||||||
else {
|
else {
|
||||||
utilReadData(gzFile, gbSgbSaveStruct);
|
utilReadData(gzFile, gbSgbSaveStruct);
|
||||||
gbSgbFourPlayers = 0;
|
gbSgbFourPlayers = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(version >= 8) {
|
if (version >= 8) {
|
||||||
utilGzRead(gzFile, gbSgbBorder, 2048);
|
utilGzRead(gzFile, gbSgbBorder, 2048);
|
||||||
utilGzRead(gzFile, gbSgbBorderChar, 32*256);
|
utilGzRead(gzFile, gbSgbBorderChar, 32 * 256);
|
||||||
}
|
}
|
||||||
|
|
||||||
utilGzRead(gzFile, gbSgbPacket, 16*7);
|
utilGzRead(gzFile, gbSgbPacket, 16 * 7);
|
||||||
|
|
||||||
utilGzRead(gzFile, gbSgbSCPPalette, 4 * 512 * sizeof(u16));
|
utilGzRead(gzFile, gbSgbSCPPalette, 4 * 512 * sizeof(u16));
|
||||||
utilGzRead(gzFile, gbSgbATF, 20 * 18);
|
utilGzRead(gzFile, gbSgbATF, 20 * 18);
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
@ -29,10 +29,10 @@ static inline blip_time_t blip_time()
|
||||||
return (SOUND_CLOCK_TICKS - soundTicks) * ticks_to_time;
|
return (SOUND_CLOCK_TICKS - soundTicks) * ticks_to_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 gbSoundRead( u16 address )
|
u8 gbSoundRead(u16 address)
|
||||||
{
|
{
|
||||||
if ( gb_apu && address >= NR10 && address <= 0xFF3F )
|
if (gb_apu && address >= NR10 && address <= 0xFF3F)
|
||||||
return gb_apu->read_register( blip_time(), address );
|
return gb_apu->read_register(blip_time(), address);
|
||||||
|
|
||||||
return gbMemory[address];
|
return gbMemory[address];
|
||||||
}
|
}
|
||||||
|
@ -41,14 +41,14 @@ void gbSoundEvent(register u16 address, register int data)
|
||||||
{
|
{
|
||||||
gbMemory[address] = data;
|
gbMemory[address] = data;
|
||||||
|
|
||||||
if ( gb_apu && address >= NR10 && address <= 0xFF3F )
|
if (gb_apu && address >= NR10 && address <= 0xFF3F)
|
||||||
gb_apu->write_register( blip_time(), address, data );
|
gb_apu->write_register(blip_time(), address, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void end_frame( blip_time_t time )
|
static void end_frame(blip_time_t time)
|
||||||
{
|
{
|
||||||
gb_apu ->end_frame( time );
|
gb_apu->end_frame(time);
|
||||||
stereo_buffer->end_frame( time );
|
stereo_buffer->end_frame(time);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void apply_effects()
|
static void apply_effects()
|
||||||
|
@ -62,16 +62,15 @@ 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);
|
||||||
gb_apu->set_output( ch.center, ch.left, ch.right, i );
|
gb_apu->set_output(ch.center, ch.left, ch.right, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void gbSoundConfigEffects( gb_effects_config_t const& c )
|
void gbSoundConfigEffects(gb_effects_config_t const& c)
|
||||||
{
|
{
|
||||||
gb_effects_config = c;
|
gb_effects_config = c;
|
||||||
}
|
}
|
||||||
|
@ -80,25 +79,25 @@ static void apply_volume()
|
||||||
{
|
{
|
||||||
soundVolume_ = soundGetVolume();
|
soundVolume_ = soundGetVolume();
|
||||||
|
|
||||||
if ( gb_apu )
|
if (gb_apu)
|
||||||
gb_apu->volume( soundVolume_ );
|
gb_apu->volume(soundVolume_);
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
flush_samples(stereo_buffer);
|
flush_samples(stereo_buffer);
|
||||||
|
|
||||||
// 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())
|
||||||
apply_volume();
|
apply_volume();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,14 +105,14 @@ void gbSoundTick()
|
||||||
static void reset_apu()
|
static void reset_apu()
|
||||||
{
|
{
|
||||||
Gb_Apu::mode_t mode = Gb_Apu::mode_dmg;
|
Gb_Apu::mode_t mode = Gb_Apu::mode_dmg;
|
||||||
if ( gbHardware & 2 )
|
if (gbHardware & 2)
|
||||||
mode = Gb_Apu::mode_cgb;
|
mode = Gb_Apu::mode_cgb;
|
||||||
if ( gbHardware & 8 || declicking )
|
if (gbHardware & 8 || declicking)
|
||||||
mode = Gb_Apu::mode_agb;
|
mode = Gb_Apu::mode_agb;
|
||||||
gb_apu->reset( mode );
|
gb_apu->reset(mode);
|
||||||
gb_apu->reduce_clicks( declicking );
|
gb_apu->reduce_clicks(declicking);
|
||||||
|
|
||||||
if ( stereo_buffer )
|
if (stereo_buffer)
|
||||||
stereo_buffer->clear();
|
stereo_buffer->clear();
|
||||||
|
|
||||||
soundTicks = SOUND_CLOCK_TICKS;
|
soundTicks = SOUND_CLOCK_TICKS;
|
||||||
|
@ -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,34 +131,35 @@ 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)) {
|
||||||
stereo_buffer->clock_rate( gb_apu->clock_rate );
|
} // TODO: handle out of memory
|
||||||
|
stereo_buffer->clock_rate(gb_apu->clock_rate);
|
||||||
|
|
||||||
// Multi_Buffer
|
// Multi_Buffer
|
||||||
static int const chan_types [chan_count] = {
|
static int const chan_types[chan_count] = {
|
||||||
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();
|
||||||
apply_volume();
|
apply_volume();
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -212,24 +211,20 @@ void gbSoundReset()
|
||||||
|
|
||||||
int addr = 0xff30;
|
int addr = 0xff30;
|
||||||
|
|
||||||
while(addr < 0xff40) {
|
while (addr < 0xff40) {
|
||||||
gbMemory[addr++] = 0x00;
|
gbMemory[addr++] = 0x00;
|
||||||
gbMemory[addr++] = 0xff;
|
gbMemory[addr++] = 0xff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,202 +237,220 @@ static struct {
|
||||||
gb_apu_state_t apu;
|
gb_apu_state_t apu;
|
||||||
} state;
|
} state;
|
||||||
|
|
||||||
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 ),
|
SKIP(int, SOUND_CLOCK_TICKS),
|
||||||
SKIP( int, SOUND_CLOCK_TICKS ),
|
SKIP(int, soundLevel1),
|
||||||
SKIP( int, soundLevel1 ),
|
SKIP(int, soundLevel2),
|
||||||
SKIP( int, soundLevel2 ),
|
SKIP(int, soundBalance),
|
||||||
SKIP( int, soundBalance ),
|
SKIP(int, soundMasterOn),
|
||||||
SKIP( int, soundMasterOn ),
|
SKIP(int, soundIndex),
|
||||||
SKIP( int, soundIndex ),
|
SKIP(int, soundVIN),
|
||||||
SKIP( int, soundVIN ),
|
SKIP(int, soundOn[0]),
|
||||||
SKIP( int, soundOn [0] ),
|
SKIP(int, soundATL[0]),
|
||||||
SKIP( int, soundATL [0] ),
|
SKIP(int, sound1Skip),
|
||||||
SKIP( int, sound1Skip ),
|
SKIP(int, soundIndex[0]),
|
||||||
SKIP( int, soundIndex [0] ),
|
SKIP(int, sound1Continue),
|
||||||
SKIP( int, sound1Continue ),
|
SKIP(int, soundEnvelopeVolume[0]),
|
||||||
SKIP( int, soundEnvelopeVolume [0] ),
|
SKIP(int, soundEnvelopeATL[0]),
|
||||||
SKIP( int, soundEnvelopeATL [0] ),
|
SKIP(int, sound1EnvelopeATLReload),
|
||||||
SKIP( int, sound1EnvelopeATLReload ),
|
SKIP(int, sound1EnvelopeUpDown),
|
||||||
SKIP( int, sound1EnvelopeUpDown ),
|
SKIP(int, sound1SweepATL),
|
||||||
SKIP( int, sound1SweepATL ),
|
SKIP(int, sound1SweepATLReload),
|
||||||
SKIP( int, sound1SweepATLReload ),
|
SKIP(int, sound1SweepSteps),
|
||||||
SKIP( int, sound1SweepSteps ),
|
SKIP(int, sound1SweepUpDown),
|
||||||
SKIP( int, sound1SweepUpDown ),
|
SKIP(int, sound1SweepStep),
|
||||||
SKIP( int, sound1SweepStep ),
|
SKIP(int, soundOn[1]),
|
||||||
SKIP( int, soundOn [1] ),
|
SKIP(int, soundATL[1]),
|
||||||
SKIP( int, soundATL [1] ),
|
SKIP(int, sound2Skip),
|
||||||
SKIP( int, sound2Skip ),
|
SKIP(int, soundIndex[1]),
|
||||||
SKIP( int, soundIndex [1] ),
|
SKIP(int, sound2Continue),
|
||||||
SKIP( int, sound2Continue ),
|
SKIP(int, soundEnvelopeVolume[1]),
|
||||||
SKIP( int, soundEnvelopeVolume [1] ),
|
SKIP(int, soundEnvelopeATL[1]),
|
||||||
SKIP( int, soundEnvelopeATL [1] ),
|
SKIP(int, sound2EnvelopeATLReload),
|
||||||
SKIP( int, sound2EnvelopeATLReload ),
|
SKIP(int, sound2EnvelopeUpDown),
|
||||||
SKIP( int, sound2EnvelopeUpDown ),
|
SKIP(int, soundOn[2]),
|
||||||
SKIP( int, soundOn [2] ),
|
SKIP(int, soundATL[2]),
|
||||||
SKIP( int, soundATL [2] ),
|
SKIP(int, sound3Skip),
|
||||||
SKIP( int, sound3Skip ),
|
SKIP(int, soundIndex[2]),
|
||||||
SKIP( int, soundIndex [2] ),
|
SKIP(int, sound3Continue),
|
||||||
SKIP( int, sound3Continue ),
|
SKIP(int, sound3OutputLevel),
|
||||||
SKIP( int, sound3OutputLevel ),
|
SKIP(int, soundOn[3]),
|
||||||
SKIP( int, soundOn [3] ),
|
SKIP(int, soundATL[3]),
|
||||||
SKIP( int, soundATL [3] ),
|
SKIP(int, sound4Skip),
|
||||||
SKIP( int, sound4Skip ),
|
SKIP(int, soundIndex[3]),
|
||||||
SKIP( int, soundIndex [3] ),
|
SKIP(int, sound4Clock),
|
||||||
SKIP( int, sound4Clock ),
|
SKIP(int, sound4ShiftRight),
|
||||||
SKIP( int, sound4ShiftRight ),
|
SKIP(int, sound4ShiftSkip),
|
||||||
SKIP( int, sound4ShiftSkip ),
|
SKIP(int, sound4ShiftIndex),
|
||||||
SKIP( int, sound4ShiftIndex ),
|
SKIP(int, sound4NSteps),
|
||||||
SKIP( int, sound4NSteps ),
|
SKIP(int, sound4CountDown),
|
||||||
SKIP( int, sound4CountDown ),
|
SKIP(int, sound4Continue),
|
||||||
SKIP( int, sound4Continue ),
|
SKIP(int, soundEnvelopeVolume[2]),
|
||||||
SKIP( int, soundEnvelopeVolume [2] ),
|
SKIP(int, soundEnvelopeATL[2]),
|
||||||
SKIP( int, soundEnvelopeATL [2] ),
|
SKIP(int, sound4EnvelopeATLReload),
|
||||||
SKIP( int, sound4EnvelopeATLReload ),
|
SKIP(int, sound4EnvelopeUpDown),
|
||||||
SKIP( int, sound4EnvelopeUpDown ),
|
SKIP(int, soundEnableFlag),
|
||||||
SKIP( int, soundEnableFlag ),
|
|
||||||
{ 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 ),
|
SKIP(int, sound2ATLreload),
|
||||||
SKIP( int, sound2ATLreload ),
|
SKIP(int, freq2low),
|
||||||
SKIP( int, freq2low ),
|
SKIP(int, freq2high),
|
||||||
SKIP( int, freq2high ),
|
SKIP(int, sound3ATLreload),
|
||||||
SKIP( int, sound3ATLreload ),
|
SKIP(int, freq3low),
|
||||||
SKIP( int, freq3low ),
|
SKIP(int, freq3high),
|
||||||
SKIP( int, freq3high ),
|
SKIP(int, sound4ATLreload),
|
||||||
SKIP( int, sound4ATLreload ),
|
SKIP(int, freq4),
|
||||||
SKIP( int, freq4 ),
|
|
||||||
{ 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 ),
|
|
||||||
{ NULL, 0 }
|
{ NULL, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
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
|
||||||
state.apu.regs [nr51] = 0xFF; // channels enabled
|
state.apu.regs[nr51] = 0xFF; // channels enabled
|
||||||
state.apu.regs [nr52] = 0x80; // power on
|
state.apu.regs[nr52] = 0x80; // power on
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load state
|
// Load state
|
||||||
utilReadData( gzFile, gbsound_format );
|
utilReadData(gzFile, gbsound_format);
|
||||||
|
|
||||||
if ( version >= 11 ) // TODO: never executed; remove?
|
if (version >= 11) // TODO: never executed; remove?
|
||||||
utilReadData( gzFile, gbsound_format2 );
|
utilReadData(gzFile, gbsound_format2);
|
||||||
|
|
||||||
utilReadData( gzFile, gbsound_format3 );
|
utilReadData(gzFile, gbsound_format3);
|
||||||
|
|
||||||
int quality = 1;
|
int quality = 1;
|
||||||
if ( version >= 7 )
|
if (version >= 7)
|
||||||
quality = utilReadInt( gzFile );
|
quality = utilReadInt(gzFile);
|
||||||
|
|
||||||
gbSoundSetSampleRate( 44100 / quality );
|
gbSoundSetSampleRate(44100 / quality);
|
||||||
|
|
||||||
// Convert to format Gb_Apu uses
|
// Convert to format Gb_Apu uses
|
||||||
gb_apu_state_t& s = state.apu;
|
gb_apu_state_t& s = state.apu;
|
||||||
|
|
||||||
// Only some registers are properly preserved
|
// Only some registers are properly preserved
|
||||||
static int const regs_to_copy [] = {
|
static int const regs_to_copy[] = {
|
||||||
nr10, nr11, nr12, nr21, nr22, nr30, nr32, nr42, nr43, nr50, nr51, nr52, -1
|
nr10, nr11, nr12, nr21, nr22, nr30, nr32, nr42, nr43, nr50, nr51, nr52, -1
|
||||||
};
|
};
|
||||||
for ( int i = 0; regs_to_copy [i] >= 0; i++ )
|
for (int i = 0; regs_to_copy[i] >= 0; i++)
|
||||||
s.regs [regs_to_copy [i]] = gbMemory [0xFF10 + regs_to_copy [i]];
|
s.regs[regs_to_copy[i]] = gbMemory[0xFF10 + regs_to_copy[i]];
|
||||||
|
|
||||||
memcpy( &s.regs [0x20], &gbMemory [0xFF30], 0x10 ); // wave
|
memcpy(&s.regs[0x20], &gbMemory[0xFF30], 0x10); // wave
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
||||||
LOAD( u8 [0x40], state.apu.regs ), // last values written to registers and wave RAM (both banks)
|
LOAD(u8[0x40], state.apu.regs), // last values written to registers and wave RAM (both banks)
|
||||||
LOAD( int, state.apu.frame_time ), // clocks until next frame sequencer action
|
LOAD(int, state.apu.frame_time), // clocks until next frame sequencer action
|
||||||
LOAD( int, state.apu.frame_phase ), // next step frame sequencer will run
|
LOAD(int, state.apu.frame_phase), // next step frame sequencer will run
|
||||||
|
|
||||||
LOAD( int, state.apu.sweep_freq ), // sweep's internal frequency register
|
LOAD(int, state.apu.sweep_freq), // sweep's internal frequency register
|
||||||
LOAD( int, state.apu.sweep_delay ), // clocks until next sweep action
|
LOAD(int, state.apu.sweep_delay), // clocks until next sweep action
|
||||||
LOAD( int, state.apu.sweep_enabled ),
|
LOAD(int, state.apu.sweep_enabled),
|
||||||
LOAD( int, state.apu.sweep_neg ), // obscure internal flag
|
LOAD(int, state.apu.sweep_neg), // obscure internal flag
|
||||||
LOAD( int, state.apu.noise_divider ),
|
LOAD(int, state.apu.noise_divider),
|
||||||
LOAD( int, state.apu.wave_buf ), // last read byte of wave RAM
|
LOAD(int, state.apu.wave_buf), // last read byte of wave RAM
|
||||||
|
|
||||||
LOAD( int [4], state.apu.delay ), // clocks until next channel action
|
LOAD(int[4], state.apu.delay), // clocks until next channel action
|
||||||
LOAD( int [4], state.apu.length_ctr ),
|
LOAD(int[4], state.apu.length_ctr),
|
||||||
LOAD( int [4], state.apu.phase ), // square/wave phase, noise LFSR
|
LOAD(int[4], state.apu.phase), // square/wave phase, noise LFSR
|
||||||
LOAD( int [4], state.apu.enabled ), // internal enabled flag
|
LOAD(int[4], state.apu.enabled), // internal enabled flag
|
||||||
|
|
||||||
LOAD( int [3], state.apu.env_delay ), // clocks until next envelope action
|
LOAD(int[3], state.apu.env_delay), // clocks until next envelope action
|
||||||
LOAD( int [3], state.apu.env_volume ),
|
LOAD(int[3], state.apu.env_volume),
|
||||||
LOAD( int [3], state.apu.env_enabled ),
|
LOAD(int[3], state.apu.env_enabled),
|
||||||
|
|
||||||
SKIP( int [13], room_for_expansion ),
|
SKIP(int[13], room_for_expansion),
|
||||||
|
|
||||||
// Emulator
|
// Emulator
|
||||||
SKIP( int [16], room_for_expansion ),
|
SKIP(int[16], room_for_expansion),
|
||||||
|
|
||||||
{ NULL, 0 }
|
{ NULL, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
void gbSoundSaveGame( gzFile out )
|
void gbSoundSaveGame(gzFile out)
|
||||||
{
|
{
|
||||||
gb_apu->save_state( &state.apu );
|
gb_apu->save_state(&state.apu);
|
||||||
|
|
||||||
// Be sure areas for expansion get written as zero
|
// Be sure areas for expansion get written as zero
|
||||||
memset( dummy_state, 0, sizeof dummy_state );
|
memset(dummy_state, 0, sizeof dummy_state);
|
||||||
|
|
||||||
state.version = 1;
|
state.version = 1;
|
||||||
utilWriteData( out, gb_state );
|
utilWriteData(out, gb_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gbSoundReadGame( int version, gzFile in )
|
void gbSoundReadGame(int version, gzFile in)
|
||||||
{
|
{
|
||||||
// Prepare APU and default state
|
// Prepare APU and default state
|
||||||
reset_apu();
|
reset_apu();
|
||||||
gb_apu->save_state( &state.apu );
|
gb_apu->save_state(&state.apu);
|
||||||
|
|
||||||
if ( version > 11 )
|
if (version > 11)
|
||||||
utilReadData( in, gb_state );
|
utilReadData(in, gb_state);
|
||||||
else
|
else
|
||||||
gbSoundReadGameOld( version, in );
|
gbSoundReadGameOld(version, in);
|
||||||
|
|
||||||
gb_apu->load_state( state.apu );
|
gb_apu->load_state(state.apu);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ struct gb_effects_config_t {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Changes effects configuration
|
// Changes effects configuration
|
||||||
void gbSoundConfigEffects(gb_effects_config_t const &);
|
void gbSoundConfigEffects(gb_effects_config_t const&);
|
||||||
extern gb_effects_config_t gb_effects_config; // current configuration
|
extern gb_effects_config_t gb_effects_config; // current configuration
|
||||||
|
|
||||||
//// GB sound emulation
|
//// GB sound emulation
|
||||||
|
|
Loading…
Reference in New Issue