diff --git a/src/gb/gbGfx.cpp b/src/gb/gbGfx.cpp index 7ad0a463..95d2932e 100644 --- a/src/gb/gbGfx.cpp +++ b/src/gb/gbGfx.cpp @@ -1,11 +1,10 @@ #include #include "../Util.h" -#include "../common/Types.h" #include "gbGlobals.h" #include "gbSGB.h" -u8 gbInvertTab[256] = { +uint8_t gbInvertTab[256] = { 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, @@ -40,16 +39,16 @@ u8 gbInvertTab[256] = { 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff }; -u16 gbLineMix[160]; -u16 gbWindowColor[160]; +uint16_t gbLineMix[160]; +uint16_t gbWindowColor[160]; extern int inUseRegister_WY; extern int layerSettings; void gbRenderLine() { memset(gbLineMix, 0, sizeof(gbLineMix)); - u8* bank0; - u8* bank1; + uint8_t* bank0; + uint8_t* bank1; if (gbCgbMode) { bank0 = &gbVram[0x0000]; bank1 = &gbVram[0x2000]; @@ -91,11 +90,11 @@ void gbRenderLine() int tile_map_address = tile_map_line_y + tx; - u8 attrs = 0; + uint8_t attrs = 0; if (bank1 != NULL) attrs = bank1[tile_map_address]; - u8 tile = bank0[tile_map_address]; + uint8_t tile = bank0[tile_map_address]; tile_map_address++; @@ -108,8 +107,8 @@ void gbRenderLine() if ((register_LCDC & 0x01 || gbCgbMode) && (layerSettings & 0x0100)) { while (x < 160) { - u8 tile_a = 0; - u8 tile_b = 0; + uint8_t tile_a = 0; + uint8_t tile_b = 0; if (attrs & 0x40) { tile_pattern_address = tile_pattern + tile * 16 + (7 - by) * 2; @@ -129,7 +128,7 @@ void gbRenderLine() } while (bx > 0) { - u8 c = (tile_a & bx) ? 1 : 0; + uint8_t c = (tile_a & bx) ? 1 : 0; c += ((tile_b & bx) ? 2 : 0); gbLineBuffer[x] = c; // mark the gbLineBuffer color @@ -204,7 +203,7 @@ void gbRenderLine() // (this fixes white flashes on Last Bible II) // Also added the gbColorOption (fixes Dracula Densetsu II color problems) for (int i = 0; i < 160; i++) { - u16 color = gbColorOption ? gbColorFilter[0x7FFF] : 0x7FFF; + uint16_t color = gbColorOption ? gbColorFilter[0x7FFF] : 0x7FFF; if (!gbCgbMode) 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; gbLineMix[i] = color; @@ -279,7 +278,7 @@ void gbRenderLine() x = wx; tile = bank0[tile_map_address]; - u8 attrs = 0; + uint8_t attrs = 0; if (bank1) attrs = bank1[tile_map_address]; tile_map_address++; @@ -298,8 +297,8 @@ void gbRenderLine() gbLineMix[i] = gbWindowColor[i]; while (x < 160) { - u8 tile_a = 0; - u8 tile_b = 0; + uint8_t tile_a = 0; + uint8_t tile_b = 0; if (attrs & 0x40) { tile_pattern_address = tile_pattern + tile * 16 + (7 - by) * 2; @@ -319,7 +318,7 @@ void gbRenderLine() } while (bx > 0) { - u8 c = (tile_a & bx) != 0 ? 1 : 0; + uint8_t c = (tile_a & bx) != 0 ? 1 : 0; c += ((tile_b & bx) != 0 ? 2 : 0); if (x >= 0) { @@ -386,7 +385,7 @@ void gbRenderLine() gbWindowLine = 0; } } else { - u16 color = gbColorOption ? gbColorFilter[0x7FFF] : 0x7FFF; + uint16_t color = gbColorOption ? gbColorFilter[0x7FFF] : 0x7FFF; if (!gbCgbMode) color = gbColorOption ? gbColorFilter[gbPalette[0] & 0x7FFF] : gbPalette[0] & 0x7FFF; for (int i = 0; i < 160; i++) { @@ -399,8 +398,8 @@ void gbRenderLine() void gbDrawSpriteTile(int tile, int x, int y, int t, int flags, int size, int spriteNumber) { - u8* bank0; - u8* bank1; + uint8_t* bank0; + uint8_t* bank1; if (gbCgbMode) { bank0 = &gbVram[0x0000]; bank1 = &gbVram[0x2000]; @@ -415,7 +414,7 @@ void gbDrawSpriteTile(int tile, int x, int y, int t, int flags, 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; } - u8* pal = gbObp0; + uint8_t* pal = gbObp0; int flipx = (flags & 0x20); int flipy = (flags & 0x40); @@ -442,8 +441,8 @@ void gbDrawSpriteTile(int tile, int x, int y, int t, int flags, } for (int xx = 0; xx < 8; xx++) { - u8 mask = 1 << (7 - xx); - u8 c = 0; + uint8_t mask = 1 << (7 - xx); + uint8_t c = 0; if ((a & mask)) c++; if ((b & mask)) @@ -459,7 +458,7 @@ void gbDrawSpriteTile(int tile, int x, int y, int t, int flags, if (xxx < 0 || xxx > 159) continue; - u16 color = gbLineBuffer[xxx]; + uint16_t color = gbLineBuffer[xxx]; // Fixes OAM-BG priority if (prio && (register_LCDC & 1)) { diff --git a/src/gba/BreakpointStructures.cpp b/src/gba/BreakpointStructures.cpp index 3661ae8f..bf8a1a21 100644 --- a/src/gba/BreakpointStructures.cpp +++ b/src/gba/BreakpointStructures.cpp @@ -95,10 +95,10 @@ w, word, u32 --> word sw, sword, s32, int --> signed word */ +#include #include #include #include -#include #include "BreakpointStructures.h" #include "remote.h" @@ -107,14 +107,14 @@ sw, sword, s32, int --> signed word #define strdup _strdup #endif -extern bool dexp_eval(char *, u32*); +extern bool dexp_eval(char*, u32*); //struct intToString{ // int value; // char mapping[20]; //}; -struct ConditionalBreak* conditionals[16] = {0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0}; +struct ConditionalBreak* conditionals[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; //struct intToString breakFlagMapping[] = { // {0x80,"Thumb"}, @@ -143,156 +143,158 @@ struct intToString compareFlagMapping[] = { // //char* compareFlagMapping[] = {"Never","==",">",">=","<","<=","!=","<=>"}; - - - //Constructors - //case '*': flag = 0xf; break; - //case 't': flag = 0x8; break; // thumb - //case 'a': flag = 0x4; break; // arm - //case 'x': flag = 0xC; break; - //case 'r': flag = 0x2; break; // mem read - //case 'w': flag = 0x1; break; // mem write - //case 'i': flag = 0x3; break; -struct ConditionalBreak* addConditionalBreak(u32 address, u8 flag){ - u8 condIndex = address>>24; - struct ConditionalBreak* cond = NULL; - BreakSet((&map[condIndex])->breakPoints,address & (&map[condIndex])->mask,((flag&0xf)|(flag>>4))); - if(flag & 0xf0){ - struct ConditionalBreak* base = conditionals[condIndex]; - struct ConditionalBreak* prev = conditionals[condIndex]; - if(conditionals[condIndex]){ - while((base) && (address >= base->break_address)){ - if(base->break_address == address){ - if(base->type_flags & 0xf0){ - base->type_flags |= (flag&0xf0); - flag &= 0xf; - cond = base; - goto addCB_nextHandle; - }else{ - goto condCreateForFlagAlways; - } - }else{ - prev = base; - base = base->next; - } - } - } -condCreateForFlagAlways: - cond = (struct ConditionalBreak*)malloc(sizeof(struct ConditionalBreak)); - cond->break_address = address; - cond->type_flags = flag&0xf0; - cond->next = base; - cond->firstCond = NULL; - if(prev == conditionals[condIndex]) - conditionals[condIndex] = cond; - else - prev->next = cond; - } - flag &= 0xf; +//case '*': flag = 0xf; break; +//case 't': flag = 0x8; break; // thumb +//case 'a': flag = 0x4; break; // arm +//case 'x': flag = 0xC; break; +//case 'r': flag = 0x2; break; // mem read +//case 'w': flag = 0x1; break; // mem write +//case 'i': flag = 0x3; break; +struct ConditionalBreak* addConditionalBreak(u32 address, u8 flag) +{ + u8 condIndex = address >> 24; + struct ConditionalBreak* cond = NULL; + BreakSet((&map[condIndex])->breakPoints, address & (&map[condIndex])->mask, ((flag & 0xf) | (flag >> 4))); + if (flag & 0xf0) { + struct ConditionalBreak* base = conditionals[condIndex]; + struct ConditionalBreak* prev = conditionals[condIndex]; + if (conditionals[condIndex]) { + while ((base) && (address >= base->break_address)) { + if (base->break_address == address) { + if (base->type_flags & 0xf0) { + base->type_flags |= (flag & 0xf0); + flag &= 0xf; + cond = base; + goto addCB_nextHandle; + } else { + goto condCreateForFlagAlways; + } + } else { + prev = base; + base = base->next; + } + } + } + condCreateForFlagAlways: + cond = (struct ConditionalBreak*)malloc(sizeof(struct ConditionalBreak)); + cond->break_address = address; + cond->type_flags = flag & 0xf0; + cond->next = base; + cond->firstCond = NULL; + if (prev == conditionals[condIndex]) + conditionals[condIndex] = cond; + else + prev->next = cond; + } + flag &= 0xf; -addCB_nextHandle: - if(flag == 0) - return cond; +addCB_nextHandle: + if (flag == 0) + return cond; - cond = (struct ConditionalBreak*)malloc(sizeof(struct ConditionalBreak)); - cond->break_address = address; - cond->type_flags = flag; - cond->next = NULL; - cond->firstCond = NULL; - if(conditionals[condIndex] == NULL){ - conditionals[condIndex] = cond; - return cond; - }else{ - struct ConditionalBreak *curr, *prev; - curr = conditionals[condIndex]; - prev = conditionals[condIndex]; - while(curr){ - if(curr->break_address > address){ - if(prev == curr){ - conditionals[condIndex] = cond; - }else{ - prev->next = cond; - } - cond->next = curr; - return cond; - } - prev = curr; - curr = prev->next; - } - prev->next = cond; - return cond; - } + cond = (struct ConditionalBreak*)malloc(sizeof(struct ConditionalBreak)); + cond->break_address = address; + cond->type_flags = flag; + cond->next = NULL; + cond->firstCond = NULL; + if (conditionals[condIndex] == NULL) { + conditionals[condIndex] = cond; + return cond; + } else { + struct ConditionalBreak *curr, *prev; + curr = conditionals[condIndex]; + prev = conditionals[condIndex]; + while (curr) { + if (curr->break_address > address) { + if (prev == curr) { + conditionals[condIndex] = cond; + } else { + prev->next = cond; + } + cond->next = curr; + return cond; + } + prev = curr; + curr = prev->next; + } + prev->next = cond; + return cond; + } } - -void addCondition(struct ConditionalBreak* base, struct ConditionalBreakNode* toAdd){ - if(base->firstCond){ - struct ConditionalBreakNode* curr, *prev; - curr = base->firstCond; - prev = base->firstCond; - while(curr){ - prev = curr; - curr = curr->next; - } - prev->next = toAdd; - }else{ - base->firstCond = toAdd; - } +void addCondition(struct ConditionalBreak* base, struct ConditionalBreakNode* toAdd) +{ + if (base->firstCond) { + struct ConditionalBreakNode *curr, *prev; + curr = base->firstCond; + prev = base->firstCond; + while (curr) { + prev = curr; + curr = curr->next; + } + prev->next = toAdd; + } else { + base->firstCond = toAdd; + } } //destructors -void freeConditionalBreak(struct ConditionalBreak* toFree){ - struct ConditionalBreakNode* freeMe; - while(toFree->firstCond){ - freeMe = toFree->firstCond; - toFree->firstCond = toFree->firstCond->next; - free(freeMe); - } - free(toFree); +void freeConditionalBreak(struct ConditionalBreak* toFree) +{ + struct ConditionalBreakNode* freeMe; + while (toFree->firstCond) { + freeMe = toFree->firstCond; + toFree->firstCond = toFree->firstCond->next; + free(freeMe); + } + free(toFree); } -void freeConditionalNode(struct ConditionalBreakNode* toDel){ - if(toDel->next) - freeConditionalNode(toDel->next); - if(toDel->address) - free(toDel->address); - if(toDel->value) - free(toDel->value); - free(toDel); +void freeConditionalNode(struct ConditionalBreakNode* toDel) +{ + if (toDel->next) + freeConditionalNode(toDel->next); + if (toDel->address) + free(toDel->address); + if (toDel->value) + free(toDel->value); + free(toDel); } -void freeAllConditionals(){ - for(int i = 0; i<16; i++){ - while(conditionals[i]){ - struct ConditionalBreak* tmp = conditionals[i]; - conditionals[i] = conditionals[i]->next; - freeConditionalBreak(tmp); - } - } - } +void freeAllConditionals() +{ + for (int i = 0; i < 16; i++) { + while (conditionals[i]) { + struct ConditionalBreak* tmp = conditionals[i]; + conditionals[i] = conditionals[i]->next; + freeConditionalBreak(tmp); + } + } +} -int removeConditionalBreak(struct ConditionalBreak* toDelete){ - if(toDelete){ - u8 condIndex = toDelete->break_address>>24; - struct ConditionalBreak* base = conditionals[condIndex]; - struct ConditionalBreak* prev = conditionals[condIndex]; - while(base){ - if(base == toDelete){ - if(base == prev){ - conditionals[condIndex] = base->next; - }else{ - prev->next = base->next; - } - freeConditionalBreak(toDelete); - return 0; - } - prev = base; - base = base->next; - } - return -1; //failed to remove - } - return -2; //delete failed because container was not there +int removeConditionalBreak(struct ConditionalBreak* toDelete) +{ + if (toDelete) { + u8 condIndex = toDelete->break_address >> 24; + struct ConditionalBreak* base = conditionals[condIndex]; + struct ConditionalBreak* prev = conditionals[condIndex]; + while (base) { + if (base == toDelete) { + if (base == prev) { + conditionals[condIndex] = base->next; + } else { + prev->next = base->next; + } + freeConditionalBreak(toDelete); + return 0; + } + prev = base; + base = base->next; + } + return -1; //failed to remove + } + return -2; //delete failed because container was not there } /* @@ -391,218 +393,218 @@ int removeAllConditions(u32 address, u8 flags){ return true; }*/ -void recountFlagsForAddress(u32 address){ - struct ConditionalBreak* base = conditionals[address>>24]; - u8 flags = 0; - while(base){ - if(base->break_address < address){ - base = base->next; - }else{ - if(base->break_address == address){ - flags |= base->type_flags; - }else{ - BreakClear((&map[address>>24])->breakPoints,address & (&map[address>>24])->mask,0xff); - BreakSet((&map[address>>24])->breakPoints,address & (&map[address>>24])->mask,((flags>>4) | (flags&0x8))); - return; - } - base = base->next; - } - } - BreakClear((&map[address>>24])->breakPoints,address & (&map[address>>24])->mask,0xff); - BreakSet((&map[address>>24])->breakPoints,address & (&map[address>>24])->mask,((flags>>4) | (flags&0x8))); +void recountFlagsForAddress(u32 address) +{ + struct ConditionalBreak* base = conditionals[address >> 24]; + u8 flags = 0; + while (base) { + if (base->break_address < address) { + base = base->next; + } else { + if (base->break_address == address) { + flags |= base->type_flags; + } else { + BreakClear((&map[address >> 24])->breakPoints, address & (&map[address >> 24])->mask, 0xff); + BreakSet((&map[address >> 24])->breakPoints, address & (&map[address >> 24])->mask, ((flags >> 4) | (flags & 0x8))); + return; + } + base = base->next; + } + } + BreakClear((&map[address >> 24])->breakPoints, address & (&map[address >> 24])->mask, 0xff); + BreakSet((&map[address >> 24])->breakPoints, address & (&map[address >> 24])->mask, ((flags >> 4) | (flags & 0x8))); } - //Removers -int removeConditionalBreakNo(u32 addrNo, u8 number){ -if(conditionals[addrNo>>24]){ - struct ConditionalBreak* base = conditionals[addrNo>>24]; - struct ConditionalBreak* curr = conditionals[addrNo>>24]; - u8 count = 1; - while (curr->break_address < addrNo){ - base = curr; - curr = curr->next; - } - if(curr->break_address == addrNo){ - if(number == 1){ - if(base == curr){ - conditionals[addrNo>>24] = curr->next; - freeConditionalBreak(curr); - }else{ - base->next = curr->next; - freeConditionalBreak(curr); - } - recountFlagsForAddress(addrNo); - return 0; - }else{ - int count = 1; - while(curr && (curr->break_address == addrNo)){ - if(count == number){ - base->next = curr->next; - freeConditionalBreak(curr); - recountFlagsForAddress(addrNo); - return 1; - } - count++; - base = curr; - curr = curr->next; - } - return -1; - } - } - } - return -2; +int removeConditionalBreakNo(u32 addrNo, u8 number) +{ + if (conditionals[addrNo >> 24]) { + struct ConditionalBreak* base = conditionals[addrNo >> 24]; + struct ConditionalBreak* curr = conditionals[addrNo >> 24]; + u8 count = 1; + while (curr->break_address < addrNo) { + base = curr; + curr = curr->next; + } + if (curr->break_address == addrNo) { + if (number == 1) { + if (base == curr) { + conditionals[addrNo >> 24] = curr->next; + freeConditionalBreak(curr); + } else { + base->next = curr->next; + freeConditionalBreak(curr); + } + recountFlagsForAddress(addrNo); + return 0; + } else { + int count = 1; + while (curr && (curr->break_address == addrNo)) { + if (count == number) { + base->next = curr->next; + freeConditionalBreak(curr); + recountFlagsForAddress(addrNo); + return 1; + } + count++; + base = curr; + curr = curr->next; + } + return -1; + } + } + } + return -2; } -int removeFlagFromConditionalBreakNo(u32 addrNo, u8 number, u8 flag){ - if(conditionals[addrNo>>24]){ - struct ConditionalBreak* base = conditionals[addrNo>>24]; - struct ConditionalBreak* curr = conditionals[addrNo>>24]; - u8 count = 1; - while (curr->break_address < addrNo){ - base = curr; - curr = curr->next; - } - if(curr->break_address == addrNo){ - if(number == 1){ - curr->type_flags &= ~flag; - if(curr->type_flags == 0){ - if(base == curr){ - conditionals[addrNo>>24] = curr->next; - freeConditionalBreak(curr); - }else{ - base->next = curr->next; - freeConditionalBreak(curr); - } - } - recountFlagsForAddress(addrNo); - return 0; - }else{ - int count = 1; - while(curr && (curr->break_address == addrNo)){ - if(count == number){ - curr->type_flags &= ~flag; - if(!curr->type_flags){ - base->next = curr->next; - freeConditionalBreak(curr); - recountFlagsForAddress(addrNo); - return 1; - } - recountFlagsForAddress(addrNo); - return 0; - } - count++; - base = curr; - curr = curr->next; - } - return -1; - } - } - } - return -2; +int removeFlagFromConditionalBreakNo(u32 addrNo, u8 number, u8 flag) +{ + if (conditionals[addrNo >> 24]) { + struct ConditionalBreak* base = conditionals[addrNo >> 24]; + struct ConditionalBreak* curr = conditionals[addrNo >> 24]; + u8 count = 1; + while (curr->break_address < addrNo) { + base = curr; + curr = curr->next; + } + if (curr->break_address == addrNo) { + if (number == 1) { + curr->type_flags &= ~flag; + if (curr->type_flags == 0) { + if (base == curr) { + conditionals[addrNo >> 24] = curr->next; + freeConditionalBreak(curr); + } else { + base->next = curr->next; + freeConditionalBreak(curr); + } + } + recountFlagsForAddress(addrNo); + return 0; + } else { + int count = 1; + while (curr && (curr->break_address == addrNo)) { + if (count == number) { + curr->type_flags &= ~flag; + if (!curr->type_flags) { + base->next = curr->next; + freeConditionalBreak(curr); + recountFlagsForAddress(addrNo); + return 1; + } + recountFlagsForAddress(addrNo); + return 0; + } + count++; + base = curr; + curr = curr->next; + } + return -1; + } + } + } + return -2; } -int removeConditionalWithAddress(u32 address){ - u8 addrNo = address>>24; - if(conditionals[addrNo] != NULL){ - struct ConditionalBreak* base = conditionals[addrNo]; - struct ConditionalBreak* curr = conditionals[addrNo]; - u8 count = 0; - u8 flags = 0; - while(curr && address >= curr->break_address){ - if(curr->break_address == address){ - base->next = curr->next; - flags |= curr->type_flags; - freeConditionalBreak(curr); - curr = base->next; - count++; - }else{ - base = curr; - curr = curr->next; - } - } - BreakClear((&map[address>>24])->breakPoints,address & (&map[address>>24])->mask,((flags&0xf)|(flags>>4))); - return count; - } - return -2; +int removeConditionalWithAddress(u32 address) +{ + u8 addrNo = address >> 24; + if (conditionals[addrNo] != NULL) { + struct ConditionalBreak* base = conditionals[addrNo]; + struct ConditionalBreak* curr = conditionals[addrNo]; + u8 count = 0; + u8 flags = 0; + while (curr && address >= curr->break_address) { + if (curr->break_address == address) { + base->next = curr->next; + flags |= curr->type_flags; + freeConditionalBreak(curr); + curr = base->next; + count++; + } else { + base = curr; + curr = curr->next; + } + } + BreakClear((&map[address >> 24])->breakPoints, address & (&map[address >> 24])->mask, ((flags & 0xf) | (flags >> 4))); + return count; + } + return -2; } -int removeConditionalWithFlag(u8 flag, bool orMode){ - for(u8 addrNo = 0; addrNo < 16;addrNo++){ - if(conditionals[addrNo] != NULL){ - struct ConditionalBreak* base = conditionals[addrNo]; - struct ConditionalBreak* curr = conditionals[addrNo]; - u8 count = 0; - while(curr){ - if(((curr->type_flags & flag) == curr->type_flags) || (orMode && (curr->type_flags & flag))){ - curr->type_flags &= ~flag; - BreakClear((&map[addrNo])->breakPoints,curr->break_address & (&map[addrNo])->mask,((flag&0xf)|(flag>>4))); - if(curr->type_flags == 0){ - if(base == conditionals[addrNo]){ - conditionals[addrNo]= curr->next; - base = curr->next; - curr = base; - } - else{ - base->next = curr->next; - freeConditionalBreak(curr); - curr = base->next; - } - count++; - }else{ - base = curr; - curr = curr->next; - } - }else{ - base = curr; - curr = curr->next; - } - } - return count; - } - } - return -2; +int removeConditionalWithFlag(u8 flag, bool orMode) +{ + for (u8 addrNo = 0; addrNo < 16; addrNo++) { + if (conditionals[addrNo] != NULL) { + struct ConditionalBreak* base = conditionals[addrNo]; + struct ConditionalBreak* curr = conditionals[addrNo]; + u8 count = 0; + while (curr) { + if (((curr->type_flags & flag) == curr->type_flags) || (orMode && (curr->type_flags & flag))) { + curr->type_flags &= ~flag; + BreakClear((&map[addrNo])->breakPoints, curr->break_address & (&map[addrNo])->mask, ((flag & 0xf) | (flag >> 4))); + if (curr->type_flags == 0) { + if (base == conditionals[addrNo]) { + conditionals[addrNo] = curr->next; + base = curr->next; + curr = base; + } else { + base->next = curr->next; + freeConditionalBreak(curr); + curr = base->next; + } + count++; + } else { + base = curr; + curr = curr->next; + } + } else { + base = curr; + curr = curr->next; + } + } + return count; + } + } + return -2; } -int removeConditionalWithAddressAndFlag(u32 address, u8 flag, bool orMode){ - u8 addrNo = address>>24; - if(conditionals[addrNo] != NULL){ - struct ConditionalBreak* base = conditionals[addrNo]; - struct ConditionalBreak* curr = conditionals[addrNo]; - u8 count = 0; - while(curr && address >= curr->break_address){ - if((curr->break_address == address) && - (((curr->type_flags & flag) == curr->type_flags) || (orMode && (curr->type_flags & flag)))){ - curr->type_flags &= ~flag; - BreakClear((&map[address>>24])->breakPoints,curr->break_address & (&map[address>>24])->mask,((flag&0xf)|(flag>>4))); - if(curr->type_flags == 0){ - if(curr == conditionals[addrNo]){ - conditionals[addrNo] = curr->next; - freeConditionalBreak(curr); - curr = conditionals[addrNo]; - } - else{ - base->next = curr->next; - freeConditionalBreak(curr); - curr = base->next; - } - count++; - }else{ - base = curr; - curr = curr->next; - } - }else{ - base = curr; - curr = curr->next; - } - } - return count; - } - return -2; +int removeConditionalWithAddressAndFlag(u32 address, u8 flag, bool orMode) +{ + u8 addrNo = address >> 24; + if (conditionals[addrNo] != NULL) { + struct ConditionalBreak* base = conditionals[addrNo]; + struct ConditionalBreak* curr = conditionals[addrNo]; + u8 count = 0; + while (curr && address >= curr->break_address) { + if ((curr->break_address == address) && (((curr->type_flags & flag) == curr->type_flags) || (orMode && (curr->type_flags & flag)))) { + curr->type_flags &= ~flag; + BreakClear((&map[address >> 24])->breakPoints, curr->break_address & (&map[address >> 24])->mask, ((flag & 0xf) | (flag >> 4))); + if (curr->type_flags == 0) { + if (curr == conditionals[addrNo]) { + conditionals[addrNo] = curr->next; + freeConditionalBreak(curr); + curr = conditionals[addrNo]; + } else { + base->next = curr->next; + freeConditionalBreak(curr); + curr = base->next; + } + count++; + } else { + base = curr; + curr = curr->next; + } + } else { + base = curr; + curr = curr->next; + } + } + return count; + } + return -2; } - - //true creating code for a given expression. //It assumes an if was found, and that all up to the if was removed. //receives an array of chars following the pattern: @@ -610,236 +612,259 @@ int removeConditionalWithAddressAndFlag(u32 address, u8 flag, bool orMode){ //next = 0; - now->exp_type_flags = 0; - if(exp[i][0] == '\''){ - now->exp_type_flags |= parseExpressionType(&exp[i][1]); - i++; - if(i >= n) goto fail; - }else{ - now->exp_type_flags |= 6; //assume signed word - } - now->address = strdup(exp[i]); - i++; - if(i >= n) goto fail; - char* operandName = exp[i]; - now->cond_flags = parseConditionOperand(exp[i]); - i++; - if(i >= n) goto fail; +void parseAndCreateConditionalBreaks(u32 address, u8 flags, char** exp, int n) +{ + struct ConditionalBreak* workBreak = addConditionalBreak(address, flags); + flags &= 0xf; + if (!flags) + return; + bool notBk = true; + struct ConditionalBreakNode* now = (struct ConditionalBreakNode*)malloc(sizeof(struct ConditionalBreakNode)); + struct ConditionalBreakNode* toAdd = now; + for (int i = 0; i < n; i++) { + now->next = 0; + now->exp_type_flags = 0; + if (exp[i][0] == '\'') { + now->exp_type_flags |= parseExpressionType(&exp[i][1]); + i++; + if (i >= n) + goto fail; + } else { + now->exp_type_flags |= 6; //assume signed word + } + now->address = strdup(exp[i]); + i++; + if (i >= n) + goto fail; + char* operandName = exp[i]; + now->cond_flags = parseConditionOperand(exp[i]); + i++; + if (i >= n) + goto fail; - if(exp[i][0] == '\''){ - now->exp_type_flags |= (parseExpressionType(&exp[i][1])<<4); - i++; - if(i >= n) goto fail; - }else{ - now->exp_type_flags |= 0x60; //assume signed word - } - now->value = strdup(exp[i]); - i++; - u32 val; - if(!dexp_eval(now->value, &val) || !dexp_eval(now->address, &val)){ - printf("Invalid expression.\n"); - if(workBreak) - removeConditionalBreak(workBreak); - return; - } - if(i < n){ - if(strcmp(exp[i], "&&") == 0){ - now = (struct ConditionalBreakNode*)malloc(sizeof(struct ConditionalBreakNode)); - toAdd->next = now; - }else if (strcmp(exp[i], "||") == 0){ - addCondition(workBreak,toAdd); - printf("Added break on address %08x, with condition:\n%s %s %s\n", address, now->address, operandName,now->value); - workBreak = addConditionalBreak(address, flags); - now = (struct ConditionalBreakNode*)malloc(sizeof(struct ConditionalBreakNode)); - toAdd = now; - } - }else{ - addCondition(workBreak,toAdd); - printf("Added break on address %08x, ending with condition: \n%s %s %s\n", address, now->address, operandName,now->value); - return; - } - } - return; + if (exp[i][0] == '\'') { + now->exp_type_flags |= (parseExpressionType(&exp[i][1]) << 4); + i++; + if (i >= n) + goto fail; + } else { + now->exp_type_flags |= 0x60; //assume signed word + } + now->value = strdup(exp[i]); + i++; + u32 val; + if (!dexp_eval(now->value, &val) || !dexp_eval(now->address, &val)) { + printf("Invalid expression.\n"); + if (workBreak) + removeConditionalBreak(workBreak); + return; + } + if (i < n) { + if (strcmp(exp[i], "&&") == 0) { + now = (struct ConditionalBreakNode*)malloc(sizeof(struct ConditionalBreakNode)); + toAdd->next = now; + } else if (strcmp(exp[i], "||") == 0) { + addCondition(workBreak, toAdd); + printf("Added break on address %08x, with condition:\n%s %s %s\n", address, now->address, operandName, now->value); + workBreak = addConditionalBreak(address, flags); + now = (struct ConditionalBreakNode*)malloc(sizeof(struct ConditionalBreakNode)); + toAdd = now; + } + } else { + addCondition(workBreak, toAdd); + printf("Added break on address %08x, ending with condition: \n%s %s %s\n", address, now->address, operandName, now->value); + return; + } + } + return; - fail: - printf("Not enough material (expressions) to work with."); - removeConditionalBreak(workBreak); - return; +fail: + printf("Not enough material (expressions) to work with."); + removeConditionalBreak(workBreak); + return; } //aux -u8 parseExpressionType(char* given_type){ - u8 flags = 0; - //for such a small string, pays off to convert first - char* type = strdup(given_type); - for(int i = 0; type[i] != '\0'; i++){ - type[i] = toupper(type[i]); - } - if((type[0] == 'S') || type[0] == 'U'){ - flags |= (4 - ((type[0]-'S')<<1)); - type++; - if(type[0] == 'H'){ - type[0] = '1'; - type[1] = '6'; - type[2] = '\0'; - }else if(type[0] == 'W'){ - type[0] = '3'; - type[1] = '2'; - type[2] = '\0'; - }else if(type[0] == 'B'){ - type[0] = '8'; - type[1] = '\0'; - } - int size; - sscanf(type, "%d",&size); - size = (size>>3) - 1; - flags |= (size >= 2 ? 2: ((u8)size)); - free(type); - return flags; - } - if(strcmp(type, "INT")==0){ - flags = 6; - } - if(type[0] == 'H'){ - flags = 1; - }else if(type[0] == 'W'){ - flags = 2; - }else if(type[0] == 'B'){ - flags = 0; - }else{ - flags = 6; - } - free(type); - return flags; +u8 parseExpressionType(char* given_type) +{ + u8 flags = 0; + //for such a small string, pays off to convert first + char* type = strdup(given_type); + for (int i = 0; type[i] != '\0'; i++) { + type[i] = toupper(type[i]); + } + if ((type[0] == 'S') || type[0] == 'U') { + flags |= (4 - ((type[0] - 'S') << 1)); + type++; + if (type[0] == 'H') { + type[0] = '1'; + type[1] = '6'; + type[2] = '\0'; + } else if (type[0] == 'W') { + type[0] = '3'; + type[1] = '2'; + type[2] = '\0'; + } else if (type[0] == 'B') { + type[0] = '8'; + type[1] = '\0'; + } + int size; + sscanf(type, "%d", &size); + size = (size >> 3) - 1; + flags |= (size >= 2 ? 2 : ((u8)size)); + free(type); + return flags; + } + if (strcmp(type, "INT") == 0) { + flags = 6; + } + if (type[0] == 'H') { + flags = 1; + } else if (type[0] == 'W') { + flags = 2; + } else if (type[0] == 'B') { + flags = 0; + } else { + flags = 6; + } + free(type); + return flags; } -u8 parseConditionOperand(char* type){ - u8 flag = 0; - if(toupper(type[0]) == 'S'){ - flag = 8; - type++; - } - switch(type[0]){ - case '!': if(type[1] == '=' || type[1] == '\0') - return flag | 0x6; - break; - case '=': if(type[1] == '=' || type[1] == '\0') - return flag | 0x1; - break; - case '<': if(type[1] == '>') - return flag | 0x6; - if(type[1] == '=') - return flag | 0x5; - if(type[1] == '\0') - return flag | 0x4; - break; - case '>': if(type[1] == '<') - return flag | 0x6; - if(type[1] == '=') - return flag | 0x3; - if(type[1] == '\0') - return flag | 0x2; - break; - default: ; - } - switch(tolower(type[0])){ - case 'l': if(tolower(type[1]) == 'e') - return flag | 0x5; - if(tolower(type[1]) == 't') - return flag | 0x4; - break; - case 'g': if(tolower(type[1]) == 'e') - return flag | 0x3; - if(tolower(type[1]) == 't') - return flag | 0x2; +u8 parseConditionOperand(char* type) +{ + u8 flag = 0; + if (toupper(type[0]) == 'S') { + flag = 8; + type++; + } + switch (type[0]) { + case '!': + if (type[1] == '=' || type[1] == '\0') + return flag | 0x6; + break; + case '=': + if (type[1] == '=' || type[1] == '\0') + return flag | 0x1; + break; + case '<': + if (type[1] == '>') + return flag | 0x6; + if (type[1] == '=') + return flag | 0x5; + if (type[1] == '\0') + return flag | 0x4; + break; + case '>': + if (type[1] == '<') + return flag | 0x6; + if (type[1] == '=') + return flag | 0x3; + if (type[1] == '\0') + return flag | 0x2; + break; + default:; + } + switch (tolower(type[0])) { + case 'l': + if (tolower(type[1]) == 'e') + return flag | 0x5; + if (tolower(type[1]) == 't') + return flag | 0x4; + break; + case 'g': + if (tolower(type[1]) == 'e') + return flag | 0x3; + if (tolower(type[1]) == 't') + return flag | 0x2; - case 'e': if(tolower(type[1]) == 'q') - return flag | 0x1; - if(type[1] == '\0') - return flag | 0x1; - case 'n': if(tolower(type[1]) == 'e') - return flag | 0x6; - default:; - } - return flag; + case 'e': + if (tolower(type[1]) == 'q') + return flag | 0x1; + if (type[1] == '\0') + return flag | 0x1; + case 'n': + if (tolower(type[1]) == 'e') + return flag | 0x6; + default:; + } + return flag; } -u32 calculateFinalValue(char* expToEval, u8 type_of_flags){ - u32 val; - if(!dexp_eval(expToEval, &val)){ - printf("Invalid expression.\n"); - return 0; - } - if(type_of_flags&0x4){ - switch(type_of_flags&0x3){ - case 0: return (s8)(val&0xff); - case 1: return (s16)(val&0xffff); - default: return (int)val; - } - }else{ - switch(type_of_flags&0x3){ - case 0: return (u8)(val&0xff); - case 1: return (u16)(val&0xffff); - default: return val; - } - } +u32 calculateFinalValue(char* expToEval, u8 type_of_flags) +{ + u32 val; + if (!dexp_eval(expToEval, &val)) { + printf("Invalid expression.\n"); + return 0; + } + if (type_of_flags & 0x4) { + switch (type_of_flags & 0x3) { + case 0: + return (s8)(val & 0xff); + case 1: + return (s16)(val & 0xffff); + default: + return (int)val; + } + } else { + switch (type_of_flags & 0x3) { + case 0: + return (u8)(val & 0xff); + case 1: + return (u16)(val & 0xffff); + default: + return val; + } + } } //check for execution -bool isCorrectBreak(struct ConditionalBreak* toTest, u8 accessType){ +bool isCorrectBreak(struct ConditionalBreak* toTest, u8 accessType) +{ - return (toTest->type_flags & accessType); + return (toTest->type_flags & accessType); } +bool doBreak(struct ConditionalBreak* toTest) +{ + struct ConditionalBreakNode* toExamine = toTest->firstCond; -bool doBreak(struct ConditionalBreak* toTest){ - struct ConditionalBreakNode* toExamine = toTest->firstCond; - - bool globalVeredict = true; - bool veredict = false; - while(toExamine && globalVeredict){ - u32 address = calculateFinalValue(toExamine->address, toExamine->exp_type_flags&0xf); - u32 value = calculateFinalValue(toExamine->value, toExamine->exp_type_flags>>4); - if((toExamine->cond_flags &0x7) != 0){ - veredict = veredict || ((toExamine->cond_flags&1)? (address == value):false); - veredict = veredict || ((toExamine->cond_flags&4)? ((toExamine->cond_flags&8)? ((int)address < (int)value) : (address < value)) : false); - veredict = veredict || ((toExamine->cond_flags&2)? ((toExamine->cond_flags&8)? ((int)address > (int)value) : (address > value)) : false); - } - toExamine = toExamine->next; - globalVeredict = veredict && globalVeredict; - - } - return globalVeredict; + bool globalVeredict = true; + bool veredict = false; + while (toExamine && globalVeredict) { + u32 address = calculateFinalValue(toExamine->address, toExamine->exp_type_flags & 0xf); + u32 value = calculateFinalValue(toExamine->value, toExamine->exp_type_flags >> 4); + if ((toExamine->cond_flags & 0x7) != 0) { + veredict = veredict || ((toExamine->cond_flags & 1) ? (address == value) : false); + veredict = veredict || ((toExamine->cond_flags & 4) ? ((toExamine->cond_flags & 8) ? ((int)address < (int)value) : (address < value)) : false); + veredict = veredict || ((toExamine->cond_flags & 2) ? ((toExamine->cond_flags & 8) ? ((int)address > (int)value) : (address > value)) : false); + } + toExamine = toExamine->next; + globalVeredict = veredict && globalVeredict; + } + return globalVeredict; } -bool doesBreak(u32 address, u8 allowedFlags){ - u8 addrNo = address>>24; - if(conditionals[addrNo]){ - struct ConditionalBreak* base = conditionals[addrNo]; - while(base && base->break_address < address){ - base = base->next; - } - while(base && base->break_address == address){ - if(base->type_flags & allowedFlags &0xf0){ - return true; - } - if(isCorrectBreak(base,allowedFlags) && doBreak(base)){ - return true; - } - base = base->next; - } - } - return false; +bool doesBreak(u32 address, u8 allowedFlags) +{ + u8 addrNo = address >> 24; + if (conditionals[addrNo]) { + struct ConditionalBreak* base = conditionals[addrNo]; + while (base && base->break_address < address) { + base = base->next; + } + while (base && base->break_address == address) { + if (base->type_flags & allowedFlags & 0xf0) { + return true; + } + if (isCorrectBreak(base, allowedFlags) && doBreak(base)) { + return true; + } + base = base->next; + } + } + return false; } /* diff --git a/src/gba/BreakpointStructures.h b/src/gba/BreakpointStructures.h index 7f2f025e..4bef73c9 100644 --- a/src/gba/BreakpointStructures.h +++ b/src/gba/BreakpointStructures.h @@ -3,34 +3,30 @@ #include "../common/Types.h" -#define readWord(addr) \ - ((map[(addr) >> 24].address[(addr)&map[(addr) >> 24].mask]) + \ - ((map[(addr + 1) >> 24].address[(addr + 1) & map[(addr + 1) >> 24].mask]) << 8) + \ - ((map[(addr + 2) >> 24].address[(addr + 2) & map[(addr + 2) >> 24].mask]) << 16) + \ - ((map[(addr + 3) >> 24].address[(addr + 3) & map[(addr + 3) >> 24].mask]) << 24)) +#define readWord(addr) \ + ((map[(addr) >> 24].address[(addr)&map[(addr) >> 24].mask]) + ((map[(addr + 1) >> 24].address[(addr + 1) & map[(addr + 1) >> 24].mask]) << 8) + ((map[(addr + 2) >> 24].address[(addr + 2) & map[(addr + 2) >> 24].mask]) << 16) + ((map[(addr + 3) >> 24].address[(addr + 3) & map[(addr + 3) >> 24].mask]) << 24)) -#define readHalfWord(addr) \ - ((&map[(addr) >> 24].address[(addr)&map[(addr) >> 24].mask]) + \ - ((&map[(addr + 1) >> 24].address[(addr + 1) & map[(addr + 1) >> 24].mask]) << 8)) +#define readHalfWord(addr) \ + ((&map[(addr) >> 24].address[(addr)&map[(addr) >> 24].mask]) + ((&map[(addr + 1) >> 24].address[(addr + 1) & map[(addr + 1) >> 24].mask]) << 8)) #define readByte(addr) map[(addr) >> 24].address[(addr)&map[(addr) >> 24].mask] struct ConditionalBreakNode { - char *address; - char *value; - u8 cond_flags; - u8 exp_type_flags; - struct ConditionalBreakNode *next; + char* address; + char* value; + u8 cond_flags; + u8 exp_type_flags; + struct ConditionalBreakNode* next; }; struct ConditionalBreak { - u32 break_address; - u8 type_flags; - struct ConditionalBreakNode *firstCond; - struct ConditionalBreak *next; + u32 break_address; + u8 type_flags; + struct ConditionalBreakNode* firstCond; + struct ConditionalBreak* next; }; -extern struct ConditionalBreak *conditionals[16]; +extern struct ConditionalBreak* conditionals[16]; // conditional break manipulators // case '*': flag = 0xf; break; @@ -40,7 +36,7 @@ extern struct ConditionalBreak *conditionals[16]; // case 'r': flag = 0x2; break; // mem read // case 'w': flag = 0x1; break; // mem write // case 'i': flag = 0x3; break; -struct ConditionalBreak *addConditionalBreak(u32 address, u8 flag); +struct ConditionalBreak* addConditionalBreak(u32 address, u8 flag); int removeConditionalBreakNo(u32 address, u8 number); int removeFlagFromConditionalBreakNo(u32 address, u8 number, u8 flag); @@ -49,17 +45,17 @@ int removeConditionalWithFlag(u8 flag, bool orMode); int removeConditionalWithAddressAndFlag(u32 address, u8 flag, bool orMode); // void freeConditionalBreak(struct ConditionalBreak* toFree); -void addCondition(struct ConditionalBreak *base, struct ConditionalBreakNode *toAdd); +void addCondition(struct ConditionalBreak* base, struct ConditionalBreakNode* toAdd); // bool removeCondition(struct ConditionalBreak* base, struct ConditionalBreakNode* toDel); // bool removeCondition(u32 address, u8 flags, u8 num); -void freeConditionalNode(struct ConditionalBreakNode *toDel); +void freeConditionalNode(struct ConditionalBreakNode* toDel); -void parseAndCreateConditionalBreaks(u32 address, u8 flags, char **exp, int n); +void parseAndCreateConditionalBreaks(u32 address, u8 flags, char** exp, int n); -bool isCorrectBreak(struct ConditionalBreak *toTest, u8 accessType); +bool isCorrectBreak(struct ConditionalBreak* toTest, u8 accessType); bool doesBreak(u32 address, u8 allowedFlags); -bool doBreak(struct ConditionalBreak *toTest); +bool doBreak(struct ConditionalBreak* toTest); // printing the structure(AKA list Breaks) // void printConditionalBreak(struct ConditionalBreak* toPrint, bool printAddress); diff --git a/src/gba/CheatSearch.cpp b/src/gba/CheatSearch.cpp index fd643d2f..e452c68b 100644 --- a/src/gba/CheatSearch.cpp +++ b/src/gba/CheatSearch.cpp @@ -1,311 +1,310 @@ -#include #include +#include #include "CheatSearch.h" CheatSearchBlock cheatSearchBlocks[4]; CheatSearchData cheatSearchData = { - 0, - cheatSearchBlocks + 0, + cheatSearchBlocks }; static bool cheatSearchEQ(u32 a, u32 b) { - return a == b; + return a == b; } static bool cheatSearchNE(u32 a, u32 b) { - return a != b; + return a != b; } static bool cheatSearchLT(u32 a, u32 b) { - return a < b; + return a < b; } static bool cheatSearchLE(u32 a, u32 b) { - return a <= b; + return a <= b; } static bool cheatSearchGT(u32 a, u32 b) { - return a > b; + return a > b; } static bool cheatSearchGE(u32 a, u32 b) { - return a >= b; + return a >= b; } static bool cheatSearchSignedEQ(s32 a, s32 b) { - return a == b; + return a == b; } static bool cheatSearchSignedNE(s32 a, s32 b) { - return a != b; + return a != b; } static bool cheatSearchSignedLT(s32 a, s32 b) { - return a < b; + return a < b; } static bool cheatSearchSignedLE(s32 a, s32 b) { - return a <= b; + return a <= b; } static bool cheatSearchSignedGT(s32 a, s32 b) { - return a > b; + return a > b; } static bool cheatSearchSignedGE(s32 a, s32 b) { - return a >= b; + return a >= b; } -static bool (*cheatSearchFunc[])(u32,u32) = { - cheatSearchEQ, - cheatSearchNE, - cheatSearchLT, - cheatSearchLE, - cheatSearchGT, - cheatSearchGE +static bool (*cheatSearchFunc[])(u32, u32) = { + cheatSearchEQ, + cheatSearchNE, + cheatSearchLT, + cheatSearchLE, + cheatSearchGT, + cheatSearchGE }; -static bool (*cheatSearchSignedFunc[])(s32,s32) = { - cheatSearchSignedEQ, - cheatSearchSignedNE, - cheatSearchSignedLT, - cheatSearchSignedLE, - cheatSearchSignedGT, - cheatSearchSignedGE +static bool (*cheatSearchSignedFunc[])(s32, s32) = { + cheatSearchSignedEQ, + cheatSearchSignedNE, + cheatSearchSignedLT, + cheatSearchSignedLE, + cheatSearchSignedGT, + cheatSearchSignedGE }; -void cheatSearchCleanup(CheatSearchData *cs) +void cheatSearchCleanup(CheatSearchData* cs) { - int count = cs->count; + int count = cs->count; - for(int i = 0; i < count; i++) { - free(cs->blocks[i].saved); - free(cs->blocks[i].bits); - } - cs->count = 0; + for (int i = 0; i < count; i++) { + free(cs->blocks[i].saved); + free(cs->blocks[i].bits); + } + cs->count = 0; } -void cheatSearchStart(const CheatSearchData *cs) +void cheatSearchStart(const CheatSearchData* cs) { - int count = cs->count; + int count = cs->count; - for(int i = 0; i < count; i++) { - CheatSearchBlock *block = &cs->blocks[i]; + for (int i = 0; i < count; i++) { + CheatSearchBlock* block = &cs->blocks[i]; - memset(block->bits, 0xff, block->size >> 3); - memcpy(block->saved, block->data, block->size); - } + memset(block->bits, 0xff, block->size >> 3); + memcpy(block->saved, block->data, block->size); + } } -s32 cheatSearchSignedRead(u8 *data, int off, int size) +s32 cheatSearchSignedRead(u8* data, int off, int size) { - u32 res = data[off++]; + u32 res = data[off++]; - switch(size) { - case BITS_8: - res <<= 24; - return ((s32)res) >> 24; - case BITS_16: - res |= ((u32)data[off++])<<8; - res <<= 16; - return ((s32)res) >> 16; - case BITS_32: - res |= ((u32)data[off++])<<8; - res |= ((u32)data[off++])<<16; - res |= ((u32)data[off++])<<24; + switch (size) { + case BITS_8: + res <<= 24; + return ((s32)res) >> 24; + case BITS_16: + res |= ((u32)data[off++]) << 8; + res <<= 16; + return ((s32)res) >> 16; + case BITS_32: + res |= ((u32)data[off++]) << 8; + res |= ((u32)data[off++]) << 16; + res |= ((u32)data[off++]) << 24; + return (s32)res; + } return (s32)res; - } - return (s32)res; } -u32 cheatSearchRead(u8 *data, int off, int size) +u32 cheatSearchRead(u8* data, int off, int size) { - u32 res = data[off++]; - if(size == BITS_16) - res |= ((u32)data[off++])<<8; - else if(size == BITS_32) { - res |= ((u32)data[off++])<<8; - res |= ((u32)data[off++])<<16; - res |= ((u32)data[off++])<<24; - } - return res; + u32 res = data[off++]; + if (size == BITS_16) + res |= ((u32)data[off++]) << 8; + else if (size == BITS_32) { + res |= ((u32)data[off++]) << 8; + res |= ((u32)data[off++]) << 16; + res |= ((u32)data[off++]) << 24; + } + return res; } -void cheatSearch(const CheatSearchData *cs, int compare, int size, - bool isSigned) +void cheatSearch(const CheatSearchData* cs, int compare, int size, + bool isSigned) { - if(compare < 0 || compare > SEARCH_GE) - return; - int inc = 1; - if(size == BITS_16) - inc = 2; - else if(size == BITS_32) - inc = 4; + if (compare < 0 || compare > SEARCH_GE) + return; + int inc = 1; + if (size == BITS_16) + inc = 2; + else if (size == BITS_32) + inc = 4; - if(isSigned) { - bool (*func)(s32,s32) = cheatSearchSignedFunc[compare]; + if (isSigned) { + bool (*func)(s32, s32) = cheatSearchSignedFunc[compare]; - for(int i = 0; i < cs->count; i++) { - CheatSearchBlock *block = &cs->blocks[i]; - int size2 = block->size; - u8 *bits = block->bits; - u8 *data = block->data; - u8 *saved = block->saved; + for (int i = 0; i < cs->count; i++) { + CheatSearchBlock* block = &cs->blocks[i]; + int size2 = block->size; + u8* bits = block->bits; + u8* data = block->data; + u8* saved = block->saved; - for(int j = 0; j < size2; j += inc) { - if(IS_BIT_SET(bits, j)) { - s32 a = cheatSearchSignedRead(data, j, size); - s32 b = cheatSearchSignedRead(saved,j, size); + for (int j = 0; j < size2; j += inc) { + if (IS_BIT_SET(bits, j)) { + s32 a = cheatSearchSignedRead(data, j, size); + s32 b = cheatSearchSignedRead(saved, j, size); - if(!func(a, b)) { - CLEAR_BIT(bits, j); - if(size == BITS_16) - CLEAR_BIT(bits, j+1); - if(size == BITS_32) { - CLEAR_BIT(bits, j+2); - CLEAR_BIT(bits, j+3); - } - } - } - } + if (!func(a, b)) { + CLEAR_BIT(bits, j); + if (size == BITS_16) + CLEAR_BIT(bits, j + 1); + if (size == BITS_32) { + CLEAR_BIT(bits, j + 2); + CLEAR_BIT(bits, j + 3); + } + } + } + } + } + } else { + bool (*func)(u32, u32) = cheatSearchFunc[compare]; + + for (int i = 0; i < cs->count; i++) { + CheatSearchBlock* block = &cs->blocks[i]; + int size2 = block->size; + u8* bits = block->bits; + u8* data = block->data; + u8* saved = block->saved; + + for (int j = 0; j < size2; j += inc) { + if (IS_BIT_SET(bits, j)) { + u32 a = cheatSearchRead(data, j, size); + u32 b = cheatSearchRead(saved, j, size); + + if (!func(a, b)) { + CLEAR_BIT(bits, j); + if (size == BITS_16) + CLEAR_BIT(bits, j + 1); + if (size == BITS_32) { + CLEAR_BIT(bits, j + 2); + CLEAR_BIT(bits, j + 3); + } + } + } + } + } } - } else { - bool (*func)(u32,u32) = cheatSearchFunc[compare]; - - for(int i = 0; i < cs->count; i++) { - CheatSearchBlock *block = &cs->blocks[i]; - int size2 = block->size; - u8 *bits = block->bits; - u8 *data = block->data; - u8 *saved = block->saved; - - for(int j = 0; j < size2; j += inc) { - if(IS_BIT_SET(bits, j)) { - u32 a = cheatSearchRead(data, j, size); - u32 b = cheatSearchRead(saved,j, size); - - if(!func(a, b)) { - CLEAR_BIT(bits, j); - if(size == BITS_16) - CLEAR_BIT(bits, j+1); - if(size == BITS_32) { - CLEAR_BIT(bits, j+2); - CLEAR_BIT(bits, j+3); - } - } - } - } - } - } } -void cheatSearchValue(const CheatSearchData *cs, int compare, int size, - bool isSigned, u32 value) +void cheatSearchValue(const CheatSearchData* cs, int compare, int size, + bool isSigned, u32 value) { - if(compare < 0 || compare > SEARCH_GE) - return; - int inc = 1; - if(size == BITS_16) - inc = 2; - else if(size == BITS_32) - inc = 4; + if (compare < 0 || compare > SEARCH_GE) + return; + int inc = 1; + if (size == BITS_16) + inc = 2; + else if (size == BITS_32) + inc = 4; - if(isSigned) { - bool (*func)(s32,s32) = cheatSearchSignedFunc[compare]; + if (isSigned) { + bool (*func)(s32, s32) = cheatSearchSignedFunc[compare]; - for(int i = 0; i < cs->count; i++) { - CheatSearchBlock *block = &cs->blocks[i]; - int size2 = block->size; - u8 *bits = block->bits; - u8 *data = block->data; + for (int i = 0; i < cs->count; i++) { + CheatSearchBlock* block = &cs->blocks[i]; + int size2 = block->size; + u8* bits = block->bits; + u8* data = block->data; - for(int j = 0; j < size2; j += inc) { - if(IS_BIT_SET(bits, j)) { - s32 a = cheatSearchSignedRead(data, j, size); - s32 b = (s32)value; + for (int j = 0; j < size2; j += inc) { + if (IS_BIT_SET(bits, j)) { + s32 a = cheatSearchSignedRead(data, j, size); + s32 b = (s32)value; - if(!func(a, b)) { - CLEAR_BIT(bits, j); - if(size == BITS_16) - CLEAR_BIT(bits, j+1); - if(size == BITS_32) { - CLEAR_BIT(bits, j+2); - CLEAR_BIT(bits, j+3); - } - } - } - } + if (!func(a, b)) { + CLEAR_BIT(bits, j); + if (size == BITS_16) + CLEAR_BIT(bits, j + 1); + if (size == BITS_32) { + CLEAR_BIT(bits, j + 2); + CLEAR_BIT(bits, j + 3); + } + } + } + } + } + } else { + bool (*func)(u32, u32) = cheatSearchFunc[compare]; + + for (int i = 0; i < cs->count; i++) { + CheatSearchBlock* block = &cs->blocks[i]; + int size2 = block->size; + u8* bits = block->bits; + u8* data = block->data; + + for (int j = 0; j < size2; j += inc) { + if (IS_BIT_SET(bits, j)) { + u32 a = cheatSearchRead(data, j, size); + + if (!func(a, value)) { + CLEAR_BIT(bits, j); + if (size == BITS_16) + CLEAR_BIT(bits, j + 1); + if (size == BITS_32) { + CLEAR_BIT(bits, j + 2); + CLEAR_BIT(bits, j + 3); + } + } + } + } + } } - } else { - bool (*func)(u32,u32) = cheatSearchFunc[compare]; - - for(int i = 0; i < cs->count; i++) { - CheatSearchBlock *block = &cs->blocks[i]; - int size2 = block->size; - u8 *bits = block->bits; - u8 *data = block->data; - - for(int j = 0; j < size2; j += inc) { - if(IS_BIT_SET(bits, j)) { - u32 a = cheatSearchRead(data, j, size); - - if(!func(a, value)) { - CLEAR_BIT(bits, j); - if(size == BITS_16) - CLEAR_BIT(bits, j+1); - if(size == BITS_32) { - CLEAR_BIT(bits, j+2); - CLEAR_BIT(bits, j+3); - } - } - } - } - } - } } -int cheatSearchGetCount(const CheatSearchData *cs, int size) +int cheatSearchGetCount(const CheatSearchData* cs, int size) { - int res = 0; - int inc = 1; - if(size == BITS_16) - inc = 2; - else if(size == BITS_32) - inc = 4; + int res = 0; + int inc = 1; + if (size == BITS_16) + inc = 2; + else if (size == BITS_32) + inc = 4; - for(int i = 0; i < cs->count; i++) { - CheatSearchBlock *block = &cs->blocks[i]; + for (int i = 0; i < cs->count; i++) { + CheatSearchBlock* block = &cs->blocks[i]; - int size2 = block->size; - u8 *bits = block->bits; - for(int j = 0; j < size2; j += inc) { - if(IS_BIT_SET(bits, j)) - res++; + int size2 = block->size; + u8* bits = block->bits; + for (int j = 0; j < size2; j += inc) { + if (IS_BIT_SET(bits, j)) + res++; + } } - } - return res; + return res; } -void cheatSearchUpdateValues(const CheatSearchData *cs) +void cheatSearchUpdateValues(const CheatSearchData* cs) { - for(int i = 0; i < cs->count; i++) { - CheatSearchBlock *block = &cs->blocks[i]; + for (int i = 0; i < cs->count; i++) { + CheatSearchBlock* block = &cs->blocks[i]; - memcpy(block->saved, block->data, block->size); - } + memcpy(block->saved, block->data, block->size); + } } - diff --git a/src/gba/CheatSearch.h b/src/gba/CheatSearch.h index 77d5c227..620eeca0 100644 --- a/src/gba/CheatSearch.h +++ b/src/gba/CheatSearch.h @@ -4,21 +4,28 @@ #include "../System.h" struct CheatSearchBlock { - int size; - u32 offset; - u8 *bits; - u8 *data; - u8 *saved; + int size; + u32 offset; + u8* bits; + u8* data; + u8* saved; }; struct CheatSearchData { - int count; - CheatSearchBlock *blocks; + int count; + CheatSearchBlock* blocks; }; -enum { SEARCH_EQ, SEARCH_NE, SEARCH_LT, SEARCH_LE, SEARCH_GT, SEARCH_GE }; +enum { SEARCH_EQ, + SEARCH_NE, + SEARCH_LT, + SEARCH_LE, + SEARCH_GT, + SEARCH_GE }; -enum { BITS_8, BITS_16, BITS_32 }; +enum { BITS_8, + BITS_16, + BITS_32 }; #define SET_BIT(bits, off) (bits)[(off) >> 3] |= (1 << ((off)&7)) @@ -28,13 +35,13 @@ enum { BITS_8, BITS_16, BITS_32 }; extern CheatSearchData cheatSearchData; -void cheatSearchCleanup(CheatSearchData *cs); -void cheatSearchStart(const CheatSearchData *cs); -void cheatSearch(const CheatSearchData *cs, int compare, int size, bool isSigned); -void cheatSearchValue(const CheatSearchData *cs, int compare, int size, bool isSigned, u32 value); -int cheatSearchGetCount(const CheatSearchData *cs, int size); -void cheatSearchUpdateValues(const CheatSearchData *cs); -s32 cheatSearchSignedRead(u8 *data, int off, int size); -u32 cheatSearchRead(u8 *data, int off, int size); +void cheatSearchCleanup(CheatSearchData* cs); +void cheatSearchStart(const CheatSearchData* cs); +void cheatSearch(const CheatSearchData* cs, int compare, int size, bool isSigned); +void cheatSearchValue(const CheatSearchData* cs, int compare, int size, bool isSigned, u32 value); +int cheatSearchGetCount(const CheatSearchData* cs, int size); +void cheatSearchUpdateValues(const CheatSearchData* cs); +s32 cheatSearchSignedRead(u8* data, int off, int size); +u32 cheatSearchRead(u8* data, int off, int size); #endif // CHEATSEARCH_H diff --git a/src/gba/Cheats.cpp b/src/gba/Cheats.cpp index f024df11..fe70bf23 100644 --- a/src/gba/Cheats.cpp +++ b/src/gba/Cheats.cpp @@ -1,14 +1,14 @@ -#include -#include -#include #include +#include +#include +#include -#include "GBA.h" -#include "GBAinline.h" -#include "Cheats.h" -#include "Globals.h" #include "../NLS.h" #include "../Util.h" +#include "Cheats.h" +#include "GBA.h" +#include "GBAinline.h" +#include "Globals.h" /** * Gameshark code types: (based on AR v1.0) @@ -61,128 +61,128 @@ * FAAAAAAA YYYY - if 16-bit value at address AND YYYY = 0 then skip next code **/ -#define UNKNOWN_CODE -1 -#define INT_8_BIT_WRITE 0 -#define INT_16_BIT_WRITE 1 -#define INT_32_BIT_WRITE 2 -#define GSA_16_BIT_ROM_PATCH 3 -#define GSA_8_BIT_GS_WRITE 4 -#define GSA_16_BIT_GS_WRITE 5 -#define GSA_32_BIT_GS_WRITE 6 -#define CBA_IF_KEYS_PRESSED 7 -#define CBA_IF_TRUE 8 -#define CBA_SLIDE_CODE 9 -#define CBA_IF_FALSE 10 -#define CBA_AND 11 -#define GSA_8_BIT_GS_WRITE2 12 -#define GSA_16_BIT_GS_WRITE2 13 -#define GSA_32_BIT_GS_WRITE2 14 -#define GSA_16_BIT_ROM_PATCH2C 15 -#define GSA_8_BIT_SLIDE 16 -#define GSA_16_BIT_SLIDE 17 -#define GSA_32_BIT_SLIDE 18 -#define GSA_8_BIT_IF_TRUE 19 -#define GSA_32_BIT_IF_TRUE 20 -#define GSA_8_BIT_IF_FALSE 21 -#define GSA_32_BIT_IF_FALSE 22 -#define GSA_8_BIT_FILL 23 -#define GSA_16_BIT_FILL 24 -#define GSA_8_BIT_IF_TRUE2 25 -#define GSA_16_BIT_IF_TRUE2 26 -#define GSA_32_BIT_IF_TRUE2 27 -#define GSA_8_BIT_IF_FALSE2 28 -#define GSA_16_BIT_IF_FALSE2 29 -#define GSA_32_BIT_IF_FALSE2 30 -#define GSA_SLOWDOWN 31 -#define CBA_ADD 32 -#define CBA_OR 33 -#define CBA_LT 34 -#define CBA_GT 35 -#define CBA_SUPER 36 -#define GSA_8_BIT_POINTER 37 -#define GSA_16_BIT_POINTER 38 -#define GSA_32_BIT_POINTER 39 -#define GSA_8_BIT_ADD 40 -#define GSA_16_BIT_ADD 41 -#define GSA_32_BIT_ADD 42 -#define GSA_8_BIT_IF_LOWER_U 43 -#define GSA_16_BIT_IF_LOWER_U 44 -#define GSA_32_BIT_IF_LOWER_U 45 -#define GSA_8_BIT_IF_HIGHER_U 46 -#define GSA_16_BIT_IF_HIGHER_U 47 -#define GSA_32_BIT_IF_HIGHER_U 48 -#define GSA_8_BIT_IF_AND 49 -#define GSA_16_BIT_IF_AND 50 -#define GSA_32_BIT_IF_AND 51 -#define GSA_8_BIT_IF_LOWER_U2 52 -#define GSA_16_BIT_IF_LOWER_U2 53 -#define GSA_32_BIT_IF_LOWER_U2 54 -#define GSA_8_BIT_IF_HIGHER_U2 55 -#define GSA_16_BIT_IF_HIGHER_U2 56 -#define GSA_32_BIT_IF_HIGHER_U2 57 -#define GSA_8_BIT_IF_AND2 58 -#define GSA_16_BIT_IF_AND2 59 -#define GSA_32_BIT_IF_AND2 60 -#define GSA_ALWAYS 61 -#define GSA_ALWAYS2 62 -#define GSA_8_BIT_IF_LOWER_S 63 -#define GSA_16_BIT_IF_LOWER_S 64 -#define GSA_32_BIT_IF_LOWER_S 65 -#define GSA_8_BIT_IF_HIGHER_S 66 -#define GSA_16_BIT_IF_HIGHER_S 67 -#define GSA_32_BIT_IF_HIGHER_S 68 -#define GSA_8_BIT_IF_LOWER_S2 69 -#define GSA_16_BIT_IF_LOWER_S2 70 -#define GSA_32_BIT_IF_LOWER_S2 71 -#define GSA_8_BIT_IF_HIGHER_S2 72 -#define GSA_16_BIT_IF_HIGHER_S2 73 -#define GSA_32_BIT_IF_HIGHER_S2 74 -#define GSA_16_BIT_WRITE_IOREGS 75 -#define GSA_32_BIT_WRITE_IOREGS 76 -#define GSA_CODES_ON 77 -#define GSA_8_BIT_IF_TRUE3 78 -#define GSA_16_BIT_IF_TRUE3 79 -#define GSA_32_BIT_IF_TRUE3 80 -#define GSA_8_BIT_IF_FALSE3 81 -#define GSA_16_BIT_IF_FALSE3 82 -#define GSA_32_BIT_IF_FALSE3 83 -#define GSA_8_BIT_IF_LOWER_S3 84 -#define GSA_16_BIT_IF_LOWER_S3 85 -#define GSA_32_BIT_IF_LOWER_S3 86 -#define GSA_8_BIT_IF_HIGHER_S3 87 -#define GSA_16_BIT_IF_HIGHER_S3 88 -#define GSA_32_BIT_IF_HIGHER_S3 89 -#define GSA_8_BIT_IF_LOWER_U3 90 -#define GSA_16_BIT_IF_LOWER_U3 91 -#define GSA_32_BIT_IF_LOWER_U3 92 -#define GSA_8_BIT_IF_HIGHER_U3 93 -#define GSA_16_BIT_IF_HIGHER_U3 94 -#define GSA_32_BIT_IF_HIGHER_U3 95 -#define GSA_8_BIT_IF_AND3 96 -#define GSA_16_BIT_IF_AND3 97 -#define GSA_32_BIT_IF_AND3 98 -#define GSA_ALWAYS3 99 -#define GSA_16_BIT_ROM_PATCH2D 100 -#define GSA_16_BIT_ROM_PATCH2E 101 -#define GSA_16_BIT_ROM_PATCH2F 102 -#define GSA_GROUP_WRITE 103 -#define GSA_32_BIT_ADD2 104 -#define GSA_32_BIT_SUB2 105 -#define GSA_16_BIT_IF_LOWER_OR_EQ_U 106 -#define GSA_16_BIT_IF_HIGHER_OR_EQ_U 107 -#define GSA_16_BIT_MIF_TRUE 108 -#define GSA_16_BIT_MIF_FALSE 109 -#define GSA_16_BIT_MIF_LOWER_OR_EQ_U 110 +#define UNKNOWN_CODE -1 +#define INT_8_BIT_WRITE 0 +#define INT_16_BIT_WRITE 1 +#define INT_32_BIT_WRITE 2 +#define GSA_16_BIT_ROM_PATCH 3 +#define GSA_8_BIT_GS_WRITE 4 +#define GSA_16_BIT_GS_WRITE 5 +#define GSA_32_BIT_GS_WRITE 6 +#define CBA_IF_KEYS_PRESSED 7 +#define CBA_IF_TRUE 8 +#define CBA_SLIDE_CODE 9 +#define CBA_IF_FALSE 10 +#define CBA_AND 11 +#define GSA_8_BIT_GS_WRITE2 12 +#define GSA_16_BIT_GS_WRITE2 13 +#define GSA_32_BIT_GS_WRITE2 14 +#define GSA_16_BIT_ROM_PATCH2C 15 +#define GSA_8_BIT_SLIDE 16 +#define GSA_16_BIT_SLIDE 17 +#define GSA_32_BIT_SLIDE 18 +#define GSA_8_BIT_IF_TRUE 19 +#define GSA_32_BIT_IF_TRUE 20 +#define GSA_8_BIT_IF_FALSE 21 +#define GSA_32_BIT_IF_FALSE 22 +#define GSA_8_BIT_FILL 23 +#define GSA_16_BIT_FILL 24 +#define GSA_8_BIT_IF_TRUE2 25 +#define GSA_16_BIT_IF_TRUE2 26 +#define GSA_32_BIT_IF_TRUE2 27 +#define GSA_8_BIT_IF_FALSE2 28 +#define GSA_16_BIT_IF_FALSE2 29 +#define GSA_32_BIT_IF_FALSE2 30 +#define GSA_SLOWDOWN 31 +#define CBA_ADD 32 +#define CBA_OR 33 +#define CBA_LT 34 +#define CBA_GT 35 +#define CBA_SUPER 36 +#define GSA_8_BIT_POINTER 37 +#define GSA_16_BIT_POINTER 38 +#define GSA_32_BIT_POINTER 39 +#define GSA_8_BIT_ADD 40 +#define GSA_16_BIT_ADD 41 +#define GSA_32_BIT_ADD 42 +#define GSA_8_BIT_IF_LOWER_U 43 +#define GSA_16_BIT_IF_LOWER_U 44 +#define GSA_32_BIT_IF_LOWER_U 45 +#define GSA_8_BIT_IF_HIGHER_U 46 +#define GSA_16_BIT_IF_HIGHER_U 47 +#define GSA_32_BIT_IF_HIGHER_U 48 +#define GSA_8_BIT_IF_AND 49 +#define GSA_16_BIT_IF_AND 50 +#define GSA_32_BIT_IF_AND 51 +#define GSA_8_BIT_IF_LOWER_U2 52 +#define GSA_16_BIT_IF_LOWER_U2 53 +#define GSA_32_BIT_IF_LOWER_U2 54 +#define GSA_8_BIT_IF_HIGHER_U2 55 +#define GSA_16_BIT_IF_HIGHER_U2 56 +#define GSA_32_BIT_IF_HIGHER_U2 57 +#define GSA_8_BIT_IF_AND2 58 +#define GSA_16_BIT_IF_AND2 59 +#define GSA_32_BIT_IF_AND2 60 +#define GSA_ALWAYS 61 +#define GSA_ALWAYS2 62 +#define GSA_8_BIT_IF_LOWER_S 63 +#define GSA_16_BIT_IF_LOWER_S 64 +#define GSA_32_BIT_IF_LOWER_S 65 +#define GSA_8_BIT_IF_HIGHER_S 66 +#define GSA_16_BIT_IF_HIGHER_S 67 +#define GSA_32_BIT_IF_HIGHER_S 68 +#define GSA_8_BIT_IF_LOWER_S2 69 +#define GSA_16_BIT_IF_LOWER_S2 70 +#define GSA_32_BIT_IF_LOWER_S2 71 +#define GSA_8_BIT_IF_HIGHER_S2 72 +#define GSA_16_BIT_IF_HIGHER_S2 73 +#define GSA_32_BIT_IF_HIGHER_S2 74 +#define GSA_16_BIT_WRITE_IOREGS 75 +#define GSA_32_BIT_WRITE_IOREGS 76 +#define GSA_CODES_ON 77 +#define GSA_8_BIT_IF_TRUE3 78 +#define GSA_16_BIT_IF_TRUE3 79 +#define GSA_32_BIT_IF_TRUE3 80 +#define GSA_8_BIT_IF_FALSE3 81 +#define GSA_16_BIT_IF_FALSE3 82 +#define GSA_32_BIT_IF_FALSE3 83 +#define GSA_8_BIT_IF_LOWER_S3 84 +#define GSA_16_BIT_IF_LOWER_S3 85 +#define GSA_32_BIT_IF_LOWER_S3 86 +#define GSA_8_BIT_IF_HIGHER_S3 87 +#define GSA_16_BIT_IF_HIGHER_S3 88 +#define GSA_32_BIT_IF_HIGHER_S3 89 +#define GSA_8_BIT_IF_LOWER_U3 90 +#define GSA_16_BIT_IF_LOWER_U3 91 +#define GSA_32_BIT_IF_LOWER_U3 92 +#define GSA_8_BIT_IF_HIGHER_U3 93 +#define GSA_16_BIT_IF_HIGHER_U3 94 +#define GSA_32_BIT_IF_HIGHER_U3 95 +#define GSA_8_BIT_IF_AND3 96 +#define GSA_16_BIT_IF_AND3 97 +#define GSA_32_BIT_IF_AND3 98 +#define GSA_ALWAYS3 99 +#define GSA_16_BIT_ROM_PATCH2D 100 +#define GSA_16_BIT_ROM_PATCH2E 101 +#define GSA_16_BIT_ROM_PATCH2F 102 +#define GSA_GROUP_WRITE 103 +#define GSA_32_BIT_ADD2 104 +#define GSA_32_BIT_SUB2 105 +#define GSA_16_BIT_IF_LOWER_OR_EQ_U 106 +#define GSA_16_BIT_IF_HIGHER_OR_EQ_U 107 +#define GSA_16_BIT_MIF_TRUE 108 +#define GSA_16_BIT_MIF_FALSE 109 +#define GSA_16_BIT_MIF_LOWER_OR_EQ_U 110 #define GSA_16_BIT_MIF_HIGHER_OR_EQ_U 111 -#define MASTER_CODE 112 -#define CHEATS_16_BIT_WRITE 114 -#define CHEATS_32_BIT_WRITE 115 +#define MASTER_CODE 112 +#define CHEATS_16_BIT_WRITE 114 +#define CHEATS_32_BIT_WRITE 115 CheatsData cheatsList[MAX_CHEATS]; int cheatsNumber = 0; -u32 rompatch2addr [4]; -u16 rompatch2val [4]; -u16 rompatch2oldval [4]; +u32 rompatch2addr[4]; +u16 rompatch2val[4]; +u16 rompatch2oldval[4]; u8 cheatsCBASeedBuffer[0x30]; u32 cheatsCBASeed[4]; @@ -193,52 +193,52 @@ u16 super = 0; extern u32 mastercode; u8 cheatsCBACurrentSeed[12] = { - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 }; u32 seeds_v1[4]; u32 seeds_v3[4]; -u32 seed_gen(u8 upper, u8 seed, u8 *deadtable1, u8 *deadtable2); +u32 seed_gen(u8 upper, u8 seed, u8* deadtable1, u8* deadtable2); //seed tables for AR v1 u8 v1_deadtable1[256] = { - 0x31, 0x1C, 0x23, 0xE5, 0x89, 0x8E, 0xA1, 0x37, 0x74, 0x6D, 0x67, 0xFC, 0x1F, 0xC0, 0xB1, 0x94, - 0x3B, 0x05, 0x56, 0x86, 0x00, 0x24, 0xF0, 0x17, 0x72, 0xA2, 0x3D, 0x1B, 0xE3, 0x17, 0xC5, 0x0B, - 0xB9, 0xE2, 0xBD, 0x58, 0x71, 0x1B, 0x2C, 0xFF, 0xE4, 0xC9, 0x4C, 0x5E, 0xC9, 0x55, 0x33, 0x45, - 0x7C, 0x3F, 0xB2, 0x51, 0xFE, 0x10, 0x7E, 0x75, 0x3C, 0x90, 0x8D, 0xDA, 0x94, 0x38, 0xC3, 0xE9, - 0x95, 0xEA, 0xCE, 0xA6, 0x06, 0xE0, 0x4F, 0x3F, 0x2A, 0xE3, 0x3A, 0xE4, 0x43, 0xBD, 0x7F, 0xDA, - 0x55, 0xF0, 0xEA, 0xCB, 0x2C, 0xA8, 0x47, 0x61, 0xA0, 0xEF, 0xCB, 0x13, 0x18, 0x20, 0xAF, 0x3E, - 0x4D, 0x9E, 0x1E, 0x77, 0x51, 0xC5, 0x51, 0x20, 0xCF, 0x21, 0xF9, 0x39, 0x94, 0xDE, 0xDD, 0x79, - 0x4E, 0x80, 0xC4, 0x9D, 0x94, 0xD5, 0x95, 0x01, 0x27, 0x27, 0xBD, 0x6D, 0x78, 0xB5, 0xD1, 0x31, - 0x6A, 0x65, 0x74, 0x74, 0x58, 0xB3, 0x7C, 0xC9, 0x5A, 0xED, 0x50, 0x03, 0xC4, 0xA2, 0x94, 0x4B, - 0xF0, 0x58, 0x09, 0x6F, 0x3E, 0x7D, 0xAE, 0x7D, 0x58, 0xA0, 0x2C, 0x91, 0xBB, 0xE1, 0x70, 0xEB, - 0x73, 0xA6, 0x9A, 0x44, 0x25, 0x90, 0x16, 0x62, 0x53, 0xAE, 0x08, 0xEB, 0xDC, 0xF0, 0xEE, 0x77, - 0xC2, 0xDE, 0x81, 0xE8, 0x30, 0x89, 0xDB, 0xFE, 0xBC, 0xC2, 0xDF, 0x26, 0xE9, 0x8B, 0xD6, 0x93, - 0xF0, 0xCB, 0x56, 0x90, 0xC0, 0x46, 0x68, 0x15, 0x43, 0xCB, 0xE9, 0x98, 0xE3, 0xAF, 0x31, 0x25, - 0x4D, 0x7B, 0xF3, 0xB1, 0x74, 0xE2, 0x64, 0xAC, 0xD9, 0xF6, 0xA0, 0xD5, 0x0B, 0x9B, 0x49, 0x52, - 0x69, 0x3B, 0x71, 0x00, 0x2F, 0xBB, 0xBA, 0x08, 0xB1, 0xAE, 0xBB, 0xB3, 0xE1, 0xC9, 0xA6, 0x7F, - 0x17, 0x97, 0x28, 0x72, 0x12, 0x6E, 0x91, 0xAE, 0x3A, 0xA2, 0x35, 0x46, 0x27, 0xF8, 0x12, 0x50 + 0x31, 0x1C, 0x23, 0xE5, 0x89, 0x8E, 0xA1, 0x37, 0x74, 0x6D, 0x67, 0xFC, 0x1F, 0xC0, 0xB1, 0x94, + 0x3B, 0x05, 0x56, 0x86, 0x00, 0x24, 0xF0, 0x17, 0x72, 0xA2, 0x3D, 0x1B, 0xE3, 0x17, 0xC5, 0x0B, + 0xB9, 0xE2, 0xBD, 0x58, 0x71, 0x1B, 0x2C, 0xFF, 0xE4, 0xC9, 0x4C, 0x5E, 0xC9, 0x55, 0x33, 0x45, + 0x7C, 0x3F, 0xB2, 0x51, 0xFE, 0x10, 0x7E, 0x75, 0x3C, 0x90, 0x8D, 0xDA, 0x94, 0x38, 0xC3, 0xE9, + 0x95, 0xEA, 0xCE, 0xA6, 0x06, 0xE0, 0x4F, 0x3F, 0x2A, 0xE3, 0x3A, 0xE4, 0x43, 0xBD, 0x7F, 0xDA, + 0x55, 0xF0, 0xEA, 0xCB, 0x2C, 0xA8, 0x47, 0x61, 0xA0, 0xEF, 0xCB, 0x13, 0x18, 0x20, 0xAF, 0x3E, + 0x4D, 0x9E, 0x1E, 0x77, 0x51, 0xC5, 0x51, 0x20, 0xCF, 0x21, 0xF9, 0x39, 0x94, 0xDE, 0xDD, 0x79, + 0x4E, 0x80, 0xC4, 0x9D, 0x94, 0xD5, 0x95, 0x01, 0x27, 0x27, 0xBD, 0x6D, 0x78, 0xB5, 0xD1, 0x31, + 0x6A, 0x65, 0x74, 0x74, 0x58, 0xB3, 0x7C, 0xC9, 0x5A, 0xED, 0x50, 0x03, 0xC4, 0xA2, 0x94, 0x4B, + 0xF0, 0x58, 0x09, 0x6F, 0x3E, 0x7D, 0xAE, 0x7D, 0x58, 0xA0, 0x2C, 0x91, 0xBB, 0xE1, 0x70, 0xEB, + 0x73, 0xA6, 0x9A, 0x44, 0x25, 0x90, 0x16, 0x62, 0x53, 0xAE, 0x08, 0xEB, 0xDC, 0xF0, 0xEE, 0x77, + 0xC2, 0xDE, 0x81, 0xE8, 0x30, 0x89, 0xDB, 0xFE, 0xBC, 0xC2, 0xDF, 0x26, 0xE9, 0x8B, 0xD6, 0x93, + 0xF0, 0xCB, 0x56, 0x90, 0xC0, 0x46, 0x68, 0x15, 0x43, 0xCB, 0xE9, 0x98, 0xE3, 0xAF, 0x31, 0x25, + 0x4D, 0x7B, 0xF3, 0xB1, 0x74, 0xE2, 0x64, 0xAC, 0xD9, 0xF6, 0xA0, 0xD5, 0x0B, 0x9B, 0x49, 0x52, + 0x69, 0x3B, 0x71, 0x00, 0x2F, 0xBB, 0xBA, 0x08, 0xB1, 0xAE, 0xBB, 0xB3, 0xE1, 0xC9, 0xA6, 0x7F, + 0x17, 0x97, 0x28, 0x72, 0x12, 0x6E, 0x91, 0xAE, 0x3A, 0xA2, 0x35, 0x46, 0x27, 0xF8, 0x12, 0x50 }; u8 v1_deadtable2[256] = { - 0xD8, 0x65, 0x04, 0xC2, 0x65, 0xD5, 0xB0, 0x0C, 0xDF, 0x9D, 0xF0, 0xC3, 0x9A, 0x17, 0xC9, 0xA6, - 0xE1, 0xAC, 0x0D, 0x14, 0x2F, 0x3C, 0x2C, 0x87, 0xA2, 0xBF, 0x4D, 0x5F, 0xAC, 0x2D, 0x9D, 0xE1, - 0x0C, 0x9C, 0xE7, 0x7F, 0xFC, 0xA8, 0x66, 0x59, 0xAC, 0x18, 0xD7, 0x05, 0xF0, 0xBF, 0xD1, 0x8B, - 0x35, 0x9F, 0x59, 0xB4, 0xBA, 0x55, 0xB2, 0x85, 0xFD, 0xB1, 0x72, 0x06, 0x73, 0xA4, 0xDB, 0x48, - 0x7B, 0x5F, 0x67, 0xA5, 0x95, 0xB9, 0xA5, 0x4A, 0xCF, 0xD1, 0x44, 0xF3, 0x81, 0xF5, 0x6D, 0xF6, - 0x3A, 0xC3, 0x57, 0x83, 0xFA, 0x8E, 0x15, 0x2A, 0xA2, 0x04, 0xB2, 0x9D, 0xA8, 0x0D, 0x7F, 0xB8, - 0x0F, 0xF6, 0xAC, 0xBE, 0x97, 0xCE, 0x16, 0xE6, 0x31, 0x10, 0x60, 0x16, 0xB5, 0x83, 0x45, 0xEE, - 0xD7, 0x5F, 0x2C, 0x08, 0x58, 0xB1, 0xFD, 0x7E, 0x79, 0x00, 0x34, 0xAD, 0xB5, 0x31, 0x34, 0x39, - 0xAF, 0xA8, 0xDD, 0x52, 0x6A, 0xB0, 0x60, 0x35, 0xB8, 0x1D, 0x52, 0xF5, 0xF5, 0x30, 0x00, 0x7B, - 0xF4, 0xBA, 0x03, 0xCB, 0x3A, 0x84, 0x14, 0x8A, 0x6A, 0xEF, 0x21, 0xBD, 0x01, 0xD8, 0xA0, 0xD4, - 0x43, 0xBE, 0x23, 0xE7, 0x76, 0x27, 0x2C, 0x3F, 0x4D, 0x3F, 0x43, 0x18, 0xA7, 0xC3, 0x47, 0xA5, - 0x7A, 0x1D, 0x02, 0x55, 0x09, 0xD1, 0xFF, 0x55, 0x5E, 0x17, 0xA0, 0x56, 0xF4, 0xC9, 0x6B, 0x90, - 0xB4, 0x80, 0xA5, 0x07, 0x22, 0xFB, 0x22, 0x0D, 0xD9, 0xC0, 0x5B, 0x08, 0x35, 0x05, 0xC1, 0x75, - 0x4F, 0xD0, 0x51, 0x2D, 0x2E, 0x5E, 0x69, 0xE7, 0x3B, 0xC2, 0xDA, 0xFF, 0xF6, 0xCE, 0x3E, 0x76, - 0xE8, 0x36, 0x8C, 0x39, 0xD8, 0xF3, 0xE9, 0xA6, 0x42, 0xE6, 0xC1, 0x4C, 0x05, 0xBE, 0x17, 0xF2, - 0x5C, 0x1B, 0x19, 0xDB, 0x0F, 0xF3, 0xF8, 0x49, 0xEB, 0x36, 0xF6, 0x40, 0x6F, 0xAD, 0xC1, 0x8C + 0xD8, 0x65, 0x04, 0xC2, 0x65, 0xD5, 0xB0, 0x0C, 0xDF, 0x9D, 0xF0, 0xC3, 0x9A, 0x17, 0xC9, 0xA6, + 0xE1, 0xAC, 0x0D, 0x14, 0x2F, 0x3C, 0x2C, 0x87, 0xA2, 0xBF, 0x4D, 0x5F, 0xAC, 0x2D, 0x9D, 0xE1, + 0x0C, 0x9C, 0xE7, 0x7F, 0xFC, 0xA8, 0x66, 0x59, 0xAC, 0x18, 0xD7, 0x05, 0xF0, 0xBF, 0xD1, 0x8B, + 0x35, 0x9F, 0x59, 0xB4, 0xBA, 0x55, 0xB2, 0x85, 0xFD, 0xB1, 0x72, 0x06, 0x73, 0xA4, 0xDB, 0x48, + 0x7B, 0x5F, 0x67, 0xA5, 0x95, 0xB9, 0xA5, 0x4A, 0xCF, 0xD1, 0x44, 0xF3, 0x81, 0xF5, 0x6D, 0xF6, + 0x3A, 0xC3, 0x57, 0x83, 0xFA, 0x8E, 0x15, 0x2A, 0xA2, 0x04, 0xB2, 0x9D, 0xA8, 0x0D, 0x7F, 0xB8, + 0x0F, 0xF6, 0xAC, 0xBE, 0x97, 0xCE, 0x16, 0xE6, 0x31, 0x10, 0x60, 0x16, 0xB5, 0x83, 0x45, 0xEE, + 0xD7, 0x5F, 0x2C, 0x08, 0x58, 0xB1, 0xFD, 0x7E, 0x79, 0x00, 0x34, 0xAD, 0xB5, 0x31, 0x34, 0x39, + 0xAF, 0xA8, 0xDD, 0x52, 0x6A, 0xB0, 0x60, 0x35, 0xB8, 0x1D, 0x52, 0xF5, 0xF5, 0x30, 0x00, 0x7B, + 0xF4, 0xBA, 0x03, 0xCB, 0x3A, 0x84, 0x14, 0x8A, 0x6A, 0xEF, 0x21, 0xBD, 0x01, 0xD8, 0xA0, 0xD4, + 0x43, 0xBE, 0x23, 0xE7, 0x76, 0x27, 0x2C, 0x3F, 0x4D, 0x3F, 0x43, 0x18, 0xA7, 0xC3, 0x47, 0xA5, + 0x7A, 0x1D, 0x02, 0x55, 0x09, 0xD1, 0xFF, 0x55, 0x5E, 0x17, 0xA0, 0x56, 0xF4, 0xC9, 0x6B, 0x90, + 0xB4, 0x80, 0xA5, 0x07, 0x22, 0xFB, 0x22, 0x0D, 0xD9, 0xC0, 0x5B, 0x08, 0x35, 0x05, 0xC1, 0x75, + 0x4F, 0xD0, 0x51, 0x2D, 0x2E, 0x5E, 0x69, 0xE7, 0x3B, 0xC2, 0xDA, 0xFF, 0xF6, 0xCE, 0x3E, 0x76, + 0xE8, 0x36, 0x8C, 0x39, 0xD8, 0xF3, 0xE9, 0xA6, 0x42, 0xE6, 0xC1, 0x4C, 0x05, 0xBE, 0x17, 0xF2, + 0x5C, 0x1B, 0x19, 0xDB, 0x0F, 0xF3, 0xF8, 0x49, 0xEB, 0x36, 0xF6, 0x40, 0x6F, 0xAD, 0xC1, 0x8C }; //seed tables for AR v3 @@ -280,39 +280,167 @@ u8 v3_deadtable2[256] = { }; #define debuggerReadMemory(addr) \ - READ32LE((&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask])) + READ32LE((&map[(addr) >> 24].address[(addr)&map[(addr) >> 24].mask])) #define debuggerReadHalfWord(addr) \ - READ16LE((&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask])) + READ16LE((&map[(addr) >> 24].address[(addr)&map[(addr) >> 24].mask])) #define debuggerReadByte(addr) \ - map[(addr)>>24].address[(addr) & map[(addr)>>24].mask] + map[(addr) >> 24].address[(addr)&map[(addr) >> 24].mask] #define debuggerWriteMemory(addr, value) \ - WRITE32LE(&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask], value) + WRITE32LE(&map[(addr) >> 24].address[(addr)&map[(addr) >> 24].mask], value) #define debuggerWriteHalfWord(addr, value) \ - WRITE16LE(&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask], value) + WRITE16LE(&map[(addr) >> 24].address[(addr)&map[(addr) >> 24].mask], value) #define debuggerWriteByte(addr, value) \ - map[(addr)>>24].address[(addr) & map[(addr)>>24].mask] = (value) + map[(addr) >> 24].address[(addr)&map[(addr) >> 24].mask] = (value) +#define CHEAT_IS_HEX(a) (((a) >= 'A' && (a) <= 'F') || ((a) >= '0' && (a) <= '9')) -#define CHEAT_IS_HEX(a) ( ((a)>='A' && (a) <='F') || ((a) >='0' && (a) <= '9')) +#define CHEAT_PATCH_ROM_16BIT(a, v) \ + WRITE16LE(((u16*)&rom[(a)&0x1ffffff]), v); -#define CHEAT_PATCH_ROM_16BIT(a,v) \ - WRITE16LE(((u16 *)&rom[(a) & 0x1ffffff]), v); - -#define CHEAT_PATCH_ROM_32BIT(a,v) \ - WRITE32LE(((u32 *)&rom[(a) & 0x1ffffff]), v); +#define CHEAT_PATCH_ROM_32BIT(a, v) \ + WRITE32LE(((u32*)&rom[(a)&0x1ffffff]), v); static bool isMultilineWithData(int i) { - // we consider it a multiline code if it has more than one line of data - // otherwise, it can still be considered a single code - // (Only CBA codes can be true multilines !!!) - if(i < cheatsNumber && i >= 0) - switch(cheatsList[i].size) { + // we consider it a multiline code if it has more than one line of data + // otherwise, it can still be considered a single code + // (Only CBA codes can be true multilines !!!) + if (i < cheatsNumber && i >= 0) + switch (cheatsList[i].size) { + case INT_8_BIT_WRITE: + case INT_16_BIT_WRITE: + case INT_32_BIT_WRITE: + case GSA_16_BIT_ROM_PATCH: + case GSA_8_BIT_GS_WRITE: + case GSA_16_BIT_GS_WRITE: + case GSA_32_BIT_GS_WRITE: + case CBA_AND: + case CBA_IF_KEYS_PRESSED: + case CBA_IF_TRUE: + case CBA_IF_FALSE: + case GSA_8_BIT_IF_TRUE: + case GSA_32_BIT_IF_TRUE: + case GSA_8_BIT_IF_FALSE: + case GSA_32_BIT_IF_FALSE: + case GSA_8_BIT_FILL: + case GSA_16_BIT_FILL: + case GSA_8_BIT_IF_TRUE2: + case GSA_16_BIT_IF_TRUE2: + case GSA_32_BIT_IF_TRUE2: + case GSA_8_BIT_IF_FALSE2: + case GSA_16_BIT_IF_FALSE2: + case GSA_32_BIT_IF_FALSE2: + case GSA_SLOWDOWN: + case CBA_ADD: + case CBA_OR: + case CBA_LT: + case CBA_GT: + case GSA_8_BIT_POINTER: + case GSA_16_BIT_POINTER: + case GSA_32_BIT_POINTER: + case GSA_8_BIT_ADD: + case GSA_16_BIT_ADD: + case GSA_32_BIT_ADD: + case GSA_8_BIT_IF_LOWER_U: + case GSA_16_BIT_IF_LOWER_U: + case GSA_32_BIT_IF_LOWER_U: + case GSA_8_BIT_IF_HIGHER_U: + case GSA_16_BIT_IF_HIGHER_U: + case GSA_32_BIT_IF_HIGHER_U: + case GSA_8_BIT_IF_AND: + case GSA_16_BIT_IF_AND: + case GSA_32_BIT_IF_AND: + case GSA_8_BIT_IF_LOWER_U2: + case GSA_16_BIT_IF_LOWER_U2: + case GSA_32_BIT_IF_LOWER_U2: + case GSA_8_BIT_IF_HIGHER_U2: + case GSA_16_BIT_IF_HIGHER_U2: + case GSA_32_BIT_IF_HIGHER_U2: + case GSA_8_BIT_IF_AND2: + case GSA_16_BIT_IF_AND2: + case GSA_32_BIT_IF_AND2: + case GSA_ALWAYS: + case GSA_ALWAYS2: + case GSA_8_BIT_IF_LOWER_S: + case GSA_16_BIT_IF_LOWER_S: + case GSA_32_BIT_IF_LOWER_S: + case GSA_8_BIT_IF_HIGHER_S: + case GSA_16_BIT_IF_HIGHER_S: + case GSA_32_BIT_IF_HIGHER_S: + case GSA_8_BIT_IF_LOWER_S2: + case GSA_16_BIT_IF_LOWER_S2: + case GSA_32_BIT_IF_LOWER_S2: + case GSA_8_BIT_IF_HIGHER_S2: + case GSA_16_BIT_IF_HIGHER_S2: + case GSA_32_BIT_IF_HIGHER_S2: + case GSA_16_BIT_WRITE_IOREGS: + case GSA_32_BIT_WRITE_IOREGS: + case GSA_CODES_ON: + case GSA_8_BIT_IF_TRUE3: + case GSA_16_BIT_IF_TRUE3: + case GSA_32_BIT_IF_TRUE3: + case GSA_8_BIT_IF_FALSE3: + case GSA_16_BIT_IF_FALSE3: + case GSA_32_BIT_IF_FALSE3: + case GSA_8_BIT_IF_LOWER_S3: + case GSA_16_BIT_IF_LOWER_S3: + case GSA_32_BIT_IF_LOWER_S3: + case GSA_8_BIT_IF_HIGHER_S3: + case GSA_16_BIT_IF_HIGHER_S3: + case GSA_32_BIT_IF_HIGHER_S3: + case GSA_8_BIT_IF_LOWER_U3: + case GSA_16_BIT_IF_LOWER_U3: + case GSA_32_BIT_IF_LOWER_U3: + case GSA_8_BIT_IF_HIGHER_U3: + case GSA_16_BIT_IF_HIGHER_U3: + case GSA_32_BIT_IF_HIGHER_U3: + case GSA_8_BIT_IF_AND3: + case GSA_16_BIT_IF_AND3: + case GSA_32_BIT_IF_AND3: + case GSA_ALWAYS3: + case GSA_8_BIT_GS_WRITE2: + case GSA_16_BIT_GS_WRITE2: + case GSA_32_BIT_GS_WRITE2: + case GSA_16_BIT_ROM_PATCH2C: + case GSA_16_BIT_ROM_PATCH2D: + case GSA_16_BIT_ROM_PATCH2E: + case GSA_16_BIT_ROM_PATCH2F: + case GSA_8_BIT_SLIDE: + case GSA_16_BIT_SLIDE: + case GSA_32_BIT_SLIDE: + case GSA_GROUP_WRITE: + case GSA_32_BIT_ADD2: + case GSA_32_BIT_SUB2: + case GSA_16_BIT_IF_LOWER_OR_EQ_U: + case GSA_16_BIT_IF_HIGHER_OR_EQ_U: + case GSA_16_BIT_MIF_TRUE: + case GSA_16_BIT_MIF_FALSE: + case GSA_16_BIT_MIF_LOWER_OR_EQ_U: + case GSA_16_BIT_MIF_HIGHER_OR_EQ_U: + case MASTER_CODE: + case CHEATS_16_BIT_WRITE: + case CHEATS_32_BIT_WRITE: + return false; + // the codes below have two lines of data + case CBA_SLIDE_CODE: + case CBA_SUPER: + return true; + } + return false; +} + +static int getCodeLength(int num) +{ + if (num >= cheatsNumber || num < 0) + return 1; + + // this is for all the codes that are true multiline + switch (cheatsList[num].size) { case INT_8_BIT_WRITE: case INT_16_BIT_WRITE: case INT_32_BIT_WRITE: @@ -321,66 +449,17 @@ static bool isMultilineWithData(int i) case GSA_16_BIT_GS_WRITE: case GSA_32_BIT_GS_WRITE: case CBA_AND: - case CBA_IF_KEYS_PRESSED: - case CBA_IF_TRUE: - case CBA_IF_FALSE: - case GSA_8_BIT_IF_TRUE: - case GSA_32_BIT_IF_TRUE: - case GSA_8_BIT_IF_FALSE: - case GSA_32_BIT_IF_FALSE: case GSA_8_BIT_FILL: case GSA_16_BIT_FILL: - case GSA_8_BIT_IF_TRUE2: - case GSA_16_BIT_IF_TRUE2: - case GSA_32_BIT_IF_TRUE2: - case GSA_8_BIT_IF_FALSE2: - case GSA_16_BIT_IF_FALSE2: - case GSA_32_BIT_IF_FALSE2: case GSA_SLOWDOWN: case CBA_ADD: case CBA_OR: - case CBA_LT: - case CBA_GT: case GSA_8_BIT_POINTER: case GSA_16_BIT_POINTER: case GSA_32_BIT_POINTER: case GSA_8_BIT_ADD: case GSA_16_BIT_ADD: case GSA_32_BIT_ADD: - case GSA_8_BIT_IF_LOWER_U: - case GSA_16_BIT_IF_LOWER_U: - case GSA_32_BIT_IF_LOWER_U: - case GSA_8_BIT_IF_HIGHER_U: - case GSA_16_BIT_IF_HIGHER_U: - case GSA_32_BIT_IF_HIGHER_U: - case GSA_8_BIT_IF_AND: - case GSA_16_BIT_IF_AND: - case GSA_32_BIT_IF_AND: - case GSA_8_BIT_IF_LOWER_U2: - case GSA_16_BIT_IF_LOWER_U2: - case GSA_32_BIT_IF_LOWER_U2: - case GSA_8_BIT_IF_HIGHER_U2: - case GSA_16_BIT_IF_HIGHER_U2: - case GSA_32_BIT_IF_HIGHER_U2: - case GSA_8_BIT_IF_AND2: - case GSA_16_BIT_IF_AND2: - case GSA_32_BIT_IF_AND2: - case GSA_ALWAYS: - case GSA_ALWAYS2: - case GSA_8_BIT_IF_LOWER_S: - case GSA_16_BIT_IF_LOWER_S: - case GSA_32_BIT_IF_LOWER_S: - case GSA_8_BIT_IF_HIGHER_S: - case GSA_16_BIT_IF_HIGHER_S: - case GSA_32_BIT_IF_HIGHER_S: - case GSA_8_BIT_IF_LOWER_S2: - case GSA_16_BIT_IF_LOWER_S2: - case GSA_32_BIT_IF_LOWER_S2: - case GSA_8_BIT_IF_HIGHER_S2: - case GSA_16_BIT_IF_HIGHER_S2: - case GSA_32_BIT_IF_HIGHER_S2: - case GSA_16_BIT_WRITE_IOREGS: - case GSA_32_BIT_WRITE_IOREGS: case GSA_CODES_ON: case GSA_8_BIT_IF_TRUE3: case GSA_16_BIT_IF_TRUE3: @@ -403,7 +482,24 @@ static bool isMultilineWithData(int i) case GSA_8_BIT_IF_AND3: case GSA_16_BIT_IF_AND3: case GSA_32_BIT_IF_AND3: - case GSA_ALWAYS3: + case GSA_8_BIT_IF_LOWER_U: + case GSA_16_BIT_IF_LOWER_U: + case GSA_32_BIT_IF_LOWER_U: + case GSA_8_BIT_IF_HIGHER_U: + case GSA_16_BIT_IF_HIGHER_U: + case GSA_32_BIT_IF_HIGHER_U: + case GSA_8_BIT_IF_AND: + case GSA_16_BIT_IF_AND: + case GSA_32_BIT_IF_AND: + case GSA_ALWAYS: + case GSA_8_BIT_IF_LOWER_S: + case GSA_16_BIT_IF_LOWER_S: + case GSA_32_BIT_IF_LOWER_S: + case GSA_8_BIT_IF_HIGHER_S: + case GSA_16_BIT_IF_HIGHER_S: + case GSA_32_BIT_IF_HIGHER_S: + case GSA_16_BIT_WRITE_IOREGS: + case GSA_32_BIT_WRITE_IOREGS: case GSA_8_BIT_GS_WRITE2: case GSA_16_BIT_GS_WRITE2: case GSA_32_BIT_GS_WRITE2: @@ -414,6 +510,36 @@ static bool isMultilineWithData(int i) case GSA_8_BIT_SLIDE: case GSA_16_BIT_SLIDE: case GSA_32_BIT_SLIDE: + case GSA_8_BIT_IF_TRUE: + case GSA_32_BIT_IF_TRUE: + case GSA_8_BIT_IF_FALSE: + case GSA_32_BIT_IF_FALSE: + case CBA_LT: + case CBA_GT: + case CBA_IF_TRUE: + case CBA_IF_FALSE: + case GSA_8_BIT_IF_TRUE2: + case GSA_16_BIT_IF_TRUE2: + case GSA_32_BIT_IF_TRUE2: + case GSA_8_BIT_IF_FALSE2: + case GSA_16_BIT_IF_FALSE2: + case GSA_32_BIT_IF_FALSE2: + case GSA_8_BIT_IF_LOWER_U2: + case GSA_16_BIT_IF_LOWER_U2: + case GSA_32_BIT_IF_LOWER_U2: + case GSA_8_BIT_IF_HIGHER_U2: + case GSA_16_BIT_IF_HIGHER_U2: + case GSA_32_BIT_IF_HIGHER_U2: + case GSA_8_BIT_IF_AND2: + case GSA_16_BIT_IF_AND2: + case GSA_32_BIT_IF_AND2: + case GSA_ALWAYS2: + case GSA_8_BIT_IF_LOWER_S2: + case GSA_16_BIT_IF_LOWER_S2: + case GSA_32_BIT_IF_LOWER_S2: + case GSA_8_BIT_IF_HIGHER_S2: + case GSA_16_BIT_IF_HIGHER_S2: + case GSA_32_BIT_IF_HIGHER_S2: case GSA_GROUP_WRITE: case GSA_32_BIT_ADD2: case GSA_32_BIT_SUB2: @@ -426,2465 +552,2307 @@ static bool isMultilineWithData(int i) case MASTER_CODE: case CHEATS_16_BIT_WRITE: case CHEATS_32_BIT_WRITE: - return false; - // the codes below have two lines of data + case UNKNOWN_CODE: + return 1; + case CBA_IF_KEYS_PRESSED: case CBA_SLIDE_CODE: + return 2; case CBA_SUPER: - return true; + return ((((cheatsList[num].value - 1) & 0xFFFF) / 3) + 1); } - return false; -} - -static int getCodeLength(int num) -{ - if(num >= cheatsNumber || num < 0) return 1; - - // this is for all the codes that are true multiline - switch(cheatsList[num].size) { - case INT_8_BIT_WRITE: - case INT_16_BIT_WRITE: - case INT_32_BIT_WRITE: - case GSA_16_BIT_ROM_PATCH: - case GSA_8_BIT_GS_WRITE: - case GSA_16_BIT_GS_WRITE: - case GSA_32_BIT_GS_WRITE: - case CBA_AND: - case GSA_8_BIT_FILL: - case GSA_16_BIT_FILL: - case GSA_SLOWDOWN: - case CBA_ADD: - case CBA_OR: - case GSA_8_BIT_POINTER: - case GSA_16_BIT_POINTER: - case GSA_32_BIT_POINTER: - case GSA_8_BIT_ADD: - case GSA_16_BIT_ADD: - case GSA_32_BIT_ADD: - case GSA_CODES_ON: - case GSA_8_BIT_IF_TRUE3: - case GSA_16_BIT_IF_TRUE3: - case GSA_32_BIT_IF_TRUE3: - case GSA_8_BIT_IF_FALSE3: - case GSA_16_BIT_IF_FALSE3: - case GSA_32_BIT_IF_FALSE3: - case GSA_8_BIT_IF_LOWER_S3: - case GSA_16_BIT_IF_LOWER_S3: - case GSA_32_BIT_IF_LOWER_S3: - case GSA_8_BIT_IF_HIGHER_S3: - case GSA_16_BIT_IF_HIGHER_S3: - case GSA_32_BIT_IF_HIGHER_S3: - case GSA_8_BIT_IF_LOWER_U3: - case GSA_16_BIT_IF_LOWER_U3: - case GSA_32_BIT_IF_LOWER_U3: - case GSA_8_BIT_IF_HIGHER_U3: - case GSA_16_BIT_IF_HIGHER_U3: - case GSA_32_BIT_IF_HIGHER_U3: - case GSA_8_BIT_IF_AND3: - case GSA_16_BIT_IF_AND3: - case GSA_32_BIT_IF_AND3: - case GSA_8_BIT_IF_LOWER_U: - case GSA_16_BIT_IF_LOWER_U: - case GSA_32_BIT_IF_LOWER_U: - case GSA_8_BIT_IF_HIGHER_U: - case GSA_16_BIT_IF_HIGHER_U: - case GSA_32_BIT_IF_HIGHER_U: - case GSA_8_BIT_IF_AND: - case GSA_16_BIT_IF_AND: - case GSA_32_BIT_IF_AND: - case GSA_ALWAYS: - case GSA_8_BIT_IF_LOWER_S: - case GSA_16_BIT_IF_LOWER_S: - case GSA_32_BIT_IF_LOWER_S: - case GSA_8_BIT_IF_HIGHER_S: - case GSA_16_BIT_IF_HIGHER_S: - case GSA_32_BIT_IF_HIGHER_S: - case GSA_16_BIT_WRITE_IOREGS: - case GSA_32_BIT_WRITE_IOREGS: - case GSA_8_BIT_GS_WRITE2: - case GSA_16_BIT_GS_WRITE2: - case GSA_32_BIT_GS_WRITE2: - case GSA_16_BIT_ROM_PATCH2C: - case GSA_16_BIT_ROM_PATCH2D: - case GSA_16_BIT_ROM_PATCH2E: - case GSA_16_BIT_ROM_PATCH2F: - case GSA_8_BIT_SLIDE: - case GSA_16_BIT_SLIDE: - case GSA_32_BIT_SLIDE: - case GSA_8_BIT_IF_TRUE: - case GSA_32_BIT_IF_TRUE: - case GSA_8_BIT_IF_FALSE: - case GSA_32_BIT_IF_FALSE: - case CBA_LT: - case CBA_GT: - case CBA_IF_TRUE: - case CBA_IF_FALSE: - case GSA_8_BIT_IF_TRUE2: - case GSA_16_BIT_IF_TRUE2: - case GSA_32_BIT_IF_TRUE2: - case GSA_8_BIT_IF_FALSE2: - case GSA_16_BIT_IF_FALSE2: - case GSA_32_BIT_IF_FALSE2: - case GSA_8_BIT_IF_LOWER_U2: - case GSA_16_BIT_IF_LOWER_U2: - case GSA_32_BIT_IF_LOWER_U2: - case GSA_8_BIT_IF_HIGHER_U2: - case GSA_16_BIT_IF_HIGHER_U2: - case GSA_32_BIT_IF_HIGHER_U2: - case GSA_8_BIT_IF_AND2: - case GSA_16_BIT_IF_AND2: - case GSA_32_BIT_IF_AND2: - case GSA_ALWAYS2: - case GSA_8_BIT_IF_LOWER_S2: - case GSA_16_BIT_IF_LOWER_S2: - case GSA_32_BIT_IF_LOWER_S2: - case GSA_8_BIT_IF_HIGHER_S2: - case GSA_16_BIT_IF_HIGHER_S2: - case GSA_32_BIT_IF_HIGHER_S2: - case GSA_GROUP_WRITE: - case GSA_32_BIT_ADD2: - case GSA_32_BIT_SUB2: - case GSA_16_BIT_IF_LOWER_OR_EQ_U: - case GSA_16_BIT_IF_HIGHER_OR_EQ_U: - case GSA_16_BIT_MIF_TRUE: - case GSA_16_BIT_MIF_FALSE: - case GSA_16_BIT_MIF_LOWER_OR_EQ_U: - case GSA_16_BIT_MIF_HIGHER_OR_EQ_U: - case MASTER_CODE: - case CHEATS_16_BIT_WRITE: - case CHEATS_32_BIT_WRITE: - case UNKNOWN_CODE: - return 1; - case CBA_IF_KEYS_PRESSED: - case CBA_SLIDE_CODE: - return 2; - case CBA_SUPER: - return ((((cheatsList[num].value-1) & 0xFFFF)/3) + 1); - } - return 1; } int cheatsCheckKeys(u32 keys, u32 extended) { - bool onoff = true; - int ticks = 0; - int i; - mastercode = 0; + bool onoff = true; + int ticks = 0; + int i; + mastercode = 0; - for (i = 0; i<4; i++) - if (rompatch2addr [i] != 0) { - CHEAT_PATCH_ROM_16BIT(rompatch2addr [i],rompatch2oldval [i]); - rompatch2addr [i] = 0; - } + for (i = 0; i < 4; i++) + if (rompatch2addr[i] != 0) { + CHEAT_PATCH_ROM_16BIT(rompatch2addr[i], rompatch2oldval[i]); + rompatch2addr[i] = 0; + } - for (i = 0; i < cheatsNumber; i++) { - if(!cheatsList[i].enabled) { - // make sure we skip other lines in this code - i += getCodeLength(i)-1; - continue; - } - switch(cheatsList[i].size) { - case GSA_CODES_ON: - onoff = true; - break; - case GSA_SLOWDOWN: - // check if button was pressed and released, if so toggle our state - if((cheatsList[i].status & 4) && !(extended & 4)) - cheatsList[i].status ^= 1; - if(extended & 4) - cheatsList[i].status |= 4; - else - cheatsList[i].status &= ~4; - - if(cheatsList[i].status & 1) - ticks += ((cheatsList[i].value & 0xFFFF) * 7); - break; - case GSA_8_BIT_SLIDE: - i++; - if(i < cheatsNumber) { - u32 addr = cheatsList[i-1].value; - u8 value = cheatsList[i].rawaddress; - int vinc = (cheatsList[i].value >> 24) & 255; - int count = (cheatsList[i].value >> 16) & 255; - int ainc = (cheatsList[i].value & 0xffff); - while(count > 0) { - CPUWriteByte(addr, value); - value += vinc; - addr += ainc; - count--; + for (i = 0; i < cheatsNumber; i++) { + if (!cheatsList[i].enabled) { + // make sure we skip other lines in this code + i += getCodeLength(i) - 1; + continue; } - } - break; - case GSA_16_BIT_SLIDE: - i++; - if(i < cheatsNumber) { - u32 addr = cheatsList[i-1].value; - u16 value = cheatsList[i].rawaddress; - int vinc = (cheatsList[i].value >> 24) & 255; - int count = (cheatsList[i].value >> 16) & 255; - int ainc = (cheatsList[i].value & 0xffff)*2; - while(count > 0) { - CPUWriteHalfWord(addr, value); - value += vinc; - addr += ainc; - count--; - } - } - break; - case GSA_32_BIT_SLIDE: - i++; - if(i < cheatsNumber) { - u32 addr = cheatsList[i-1].value; - u32 value = cheatsList[i].rawaddress; - int vinc = (cheatsList[i].value >> 24) & 255; - int count = (cheatsList[i].value >> 16) & 255; - int ainc = (cheatsList[i].value & 0xffff)*4; - while(count > 0) { - CPUWriteMemory(addr, value); - value += vinc; - addr += ainc; - count--; - } - } - break; - case GSA_8_BIT_GS_WRITE2: - i++; - if(i < cheatsNumber) { - if(extended & 4) { - CPUWriteByte(cheatsList[i-1].value, cheatsList[i].address); - } - } - break; - case GSA_16_BIT_GS_WRITE2: - i++; - if(i < cheatsNumber) { - if(extended & 4) { - CPUWriteHalfWord(cheatsList[i-1].value, cheatsList[i].address); - } - } - break; - case GSA_32_BIT_GS_WRITE2: - i++; - if(i < cheatsNumber) { - if(extended & 4) { - CPUWriteMemory(cheatsList[i-1].value, cheatsList[i].address); - } - } - break; - case GSA_16_BIT_ROM_PATCH: - if((cheatsList[i].status & 1) == 0) { - if(CPUReadHalfWord(cheatsList[i].address) != cheatsList[i].value) { - cheatsList[i].oldValue = CPUReadHalfWord(cheatsList[i].address); - cheatsList[i].status |= 1; - CHEAT_PATCH_ROM_16BIT(cheatsList[i].address, cheatsList[i].value); - } - } - break; - case GSA_16_BIT_ROM_PATCH2C: - i++; - if(i < cheatsNumber) { - rompatch2addr [0] = ((cheatsList[i-1].value & 0x00FFFFFF) << 1) + 0x8000000; - rompatch2oldval [0] = CPUReadHalfWord(rompatch2addr [0]); - rompatch2val [0] = cheatsList[i].rawaddress & 0xFFFF; - } - break; - case GSA_16_BIT_ROM_PATCH2D: - i++; - if(i < cheatsNumber) { - rompatch2addr [1] = ((cheatsList[i-1].value & 0x00FFFFFF) << 1) + 0x8000000; - rompatch2oldval [1] = CPUReadHalfWord(rompatch2addr [1]); - rompatch2val [1] = cheatsList[i].rawaddress & 0xFFFF; - } - break; - case GSA_16_BIT_ROM_PATCH2E: - i++; - if(i < cheatsNumber) { - rompatch2addr [2] = ((cheatsList[i-1].value & 0x00FFFFFF) << 1) + 0x8000000; - rompatch2oldval [2] = CPUReadHalfWord(rompatch2addr [2]); - rompatch2val [2] = cheatsList[i].rawaddress & 0xFFFF; - } - break; - case GSA_16_BIT_ROM_PATCH2F: - i++; - if(i < cheatsNumber) { - rompatch2addr [3] = ((cheatsList[i-1].value & 0x00FFFFFF) << 1) + 0x8000000; - rompatch2oldval [3] = CPUReadHalfWord(rompatch2addr [3]); - rompatch2val [3] = cheatsList[i].rawaddress & 0xFFFF; - } - break; - case MASTER_CODE: - mastercode = cheatsList[i].address; - break; - } - if (onoff) { - switch(cheatsList[i].size) { - case INT_8_BIT_WRITE: - CPUWriteByte(cheatsList[i].address, cheatsList[i].value); - break; - case INT_16_BIT_WRITE: - CPUWriteHalfWord(cheatsList[i].address, cheatsList[i].value); - break; - case INT_32_BIT_WRITE: - CPUWriteMemory(cheatsList[i].address, cheatsList[i].value); - break; - case GSA_8_BIT_GS_WRITE: - if(extended & 4) { - CPUWriteByte(cheatsList[i].address, cheatsList[i].value); - } - break; - case GSA_16_BIT_GS_WRITE: - if(extended & 4) { - CPUWriteHalfWord(cheatsList[i].address, cheatsList[i].value); - } - break; - case GSA_32_BIT_GS_WRITE: - if(extended & 4) { - CPUWriteMemory(cheatsList[i].address, cheatsList[i].value); - } - break; - case CBA_IF_KEYS_PRESSED: - { - u16 value = cheatsList[i].value; - u32 addr = cheatsList[i].address; - if((addr & 0xF0) == 0x20) { - if((keys & value) == 0) { - i++; - } - } else if((addr & 0xF0) == 0x10) { - if((keys & value) == value) { - i++; - } - } else if((addr & 0xF0) == 0x00) { - if(((~keys) & 0x3FF) == value) { - i++; - } - } - } - break; - case CBA_IF_TRUE: - if(CPUReadHalfWord(cheatsList[i].address) != cheatsList[i].value) { - i++; - } - break; - case CBA_SLIDE_CODE: - { - u32 address = cheatsList[i].address; - u16 value = cheatsList[i].value; - i++; - if(i < cheatsNumber) { - int count = ((cheatsList[i].address - 1) & 0xFFFF); - u16 vinc = (cheatsList[i].address >> 16) & 0xFFFF; - int inc = cheatsList[i].value; - for(int x = 0; x <= count ; x++) { - CPUWriteHalfWord(address, value); - address += inc; - value += vinc; - } - } - } - break; - case CBA_IF_FALSE: - if(CPUReadHalfWord(cheatsList[i].address) == cheatsList[i].value){ - i++; - } - break; - case CBA_AND: - CPUWriteHalfWord(cheatsList[i].address, - CPUReadHalfWord(cheatsList[i].address) & - cheatsList[i].value); - break; - case GSA_8_BIT_IF_TRUE: - if(CPUReadByte(cheatsList[i].address) != cheatsList[i].value) { - i++; - } - break; - case GSA_32_BIT_IF_TRUE: - if(CPUReadMemory(cheatsList[i].address) != cheatsList[i].value) { - i++; - } - break; - case GSA_8_BIT_IF_FALSE: - if(CPUReadByte(cheatsList[i].address) == cheatsList[i].value) { - i++; - } - break; - case GSA_32_BIT_IF_FALSE: - if(CPUReadMemory(cheatsList[i].address) == cheatsList[i].value) { - i++; - } - break; - case GSA_8_BIT_FILL: - { - u32 addr = cheatsList[i].address; - u8 v = cheatsList[i].value & 0xff; - u32 end = addr + (cheatsList[i].value >> 8); - do { - CPUWriteByte(addr, v); - addr++; - } while (addr <= end); - } - break; - case GSA_16_BIT_FILL: - { - u32 addr = cheatsList[i].address; - u16 v = cheatsList[i].value & 0xffff; - u32 end = addr + ((cheatsList[i].value >> 16) << 1); - do { - CPUWriteHalfWord(addr, v); - addr+=2; - } while (addr <= end); - } - break; - case GSA_8_BIT_IF_TRUE2: - if(CPUReadByte(cheatsList[i].address) != cheatsList[i].value) { - i+=2; - } - break; - case GSA_16_BIT_IF_TRUE2: - if(CPUReadHalfWord(cheatsList[i].address) != cheatsList[i].value) { - i+=2; - } - break; - case GSA_32_BIT_IF_TRUE2: - if(CPUReadMemory(cheatsList[i].address) != cheatsList[i].value) { - i+=2; - } - break; - case GSA_8_BIT_IF_FALSE2: - if(CPUReadByte(cheatsList[i].address) == cheatsList[i].value) { - i+=2; - } - break; - case GSA_16_BIT_IF_FALSE2: - if(CPUReadHalfWord(cheatsList[i].address) == cheatsList[i].value) { - i+=2; - } - break; - case GSA_32_BIT_IF_FALSE2: - if(CPUReadMemory(cheatsList[i].address) == cheatsList[i].value) { - i+=2; - } - break; - case CBA_ADD: - if ((cheatsList[i].address & 1) == 0) { - CPUWriteHalfWord(cheatsList[i].address, - CPUReadHalfWord(cheatsList[i].address) + - cheatsList[i].value); - } else { - CPUWriteMemory(cheatsList[i].address & 0x0FFFFFFE, - CPUReadMemory(cheatsList[i].address & 0x0FFFFFFE) + - cheatsList[i].value); - } - break; - case CBA_OR: - CPUWriteHalfWord(cheatsList[i].address, - CPUReadHalfWord(cheatsList[i].address) | - cheatsList[i].value); - break; - case CBA_GT: - if (!(CPUReadHalfWord(cheatsList[i].address) > cheatsList[i].value)){ - i++; - } - break; - case CBA_LT: - if (!(CPUReadHalfWord(cheatsList[i].address) < cheatsList[i].value)){ - i++; - } - break; - case CBA_SUPER: - { - int count = 2*((cheatsList[i].value -1) & 0xFFFF)+1; - u32 address = cheatsList[i].address; - for(int x = 0; x <= count; x++) { - u8 b; - int res = x % 6; - if (res==0) - i++; - if(res < 4) - b = (cheatsList[i].address >> (24-8*res)) & 0xFF; + switch (cheatsList[i].size) { + case GSA_CODES_ON: + onoff = true; + break; + case GSA_SLOWDOWN: + // check if button was pressed and released, if so toggle our state + if ((cheatsList[i].status & 4) && !(extended & 4)) + cheatsList[i].status ^= 1; + if (extended & 4) + cheatsList[i].status |= 4; else - b = (cheatsList[i].value >> (8 - 8*(res-4))) & 0xFF; - CPUWriteByte(address, b); - address++; - } - } - break; - case GSA_8_BIT_POINTER : - if (((CPUReadMemory(cheatsList[i].address)>=0x02000000) && (CPUReadMemory(cheatsList[i].address)<0x02040000)) || - ((CPUReadMemory(cheatsList[i].address)>=0x03000000) && (CPUReadMemory(cheatsList[i].address)<0x03008000))) - { - CPUWriteByte(CPUReadMemory(cheatsList[i].address)+((cheatsList[i].value & 0xFFFFFF00) >> 8), - cheatsList[i].value & 0xFF); + cheatsList[i].status &= ~4; + + if (cheatsList[i].status & 1) + ticks += ((cheatsList[i].value & 0xFFFF) * 7); + break; + case GSA_8_BIT_SLIDE: + i++; + if (i < cheatsNumber) { + u32 addr = cheatsList[i - 1].value; + u8 value = cheatsList[i].rawaddress; + int vinc = (cheatsList[i].value >> 24) & 255; + int count = (cheatsList[i].value >> 16) & 255; + int ainc = (cheatsList[i].value & 0xffff); + while (count > 0) { + CPUWriteByte(addr, value); + value += vinc; + addr += ainc; + count--; + } + } + break; + case GSA_16_BIT_SLIDE: + i++; + if (i < cheatsNumber) { + u32 addr = cheatsList[i - 1].value; + u16 value = cheatsList[i].rawaddress; + int vinc = (cheatsList[i].value >> 24) & 255; + int count = (cheatsList[i].value >> 16) & 255; + int ainc = (cheatsList[i].value & 0xffff) * 2; + while (count > 0) { + CPUWriteHalfWord(addr, value); + value += vinc; + addr += ainc; + count--; + } + } + break; + case GSA_32_BIT_SLIDE: + i++; + if (i < cheatsNumber) { + u32 addr = cheatsList[i - 1].value; + u32 value = cheatsList[i].rawaddress; + int vinc = (cheatsList[i].value >> 24) & 255; + int count = (cheatsList[i].value >> 16) & 255; + int ainc = (cheatsList[i].value & 0xffff) * 4; + while (count > 0) { + CPUWriteMemory(addr, value); + value += vinc; + addr += ainc; + count--; + } + } + break; + case GSA_8_BIT_GS_WRITE2: + i++; + if (i < cheatsNumber) { + if (extended & 4) { + CPUWriteByte(cheatsList[i - 1].value, cheatsList[i].address); + } + } + break; + case GSA_16_BIT_GS_WRITE2: + i++; + if (i < cheatsNumber) { + if (extended & 4) { + CPUWriteHalfWord(cheatsList[i - 1].value, cheatsList[i].address); + } + } + break; + case GSA_32_BIT_GS_WRITE2: + i++; + if (i < cheatsNumber) { + if (extended & 4) { + CPUWriteMemory(cheatsList[i - 1].value, cheatsList[i].address); + } + } + break; + case GSA_16_BIT_ROM_PATCH: + if ((cheatsList[i].status & 1) == 0) { + if (CPUReadHalfWord(cheatsList[i].address) != cheatsList[i].value) { + cheatsList[i].oldValue = CPUReadHalfWord(cheatsList[i].address); + cheatsList[i].status |= 1; + CHEAT_PATCH_ROM_16BIT(cheatsList[i].address, cheatsList[i].value); + } + } + break; + case GSA_16_BIT_ROM_PATCH2C: + i++; + if (i < cheatsNumber) { + rompatch2addr[0] = ((cheatsList[i - 1].value & 0x00FFFFFF) << 1) + 0x8000000; + rompatch2oldval[0] = CPUReadHalfWord(rompatch2addr[0]); + rompatch2val[0] = cheatsList[i].rawaddress & 0xFFFF; + } + break; + case GSA_16_BIT_ROM_PATCH2D: + i++; + if (i < cheatsNumber) { + rompatch2addr[1] = ((cheatsList[i - 1].value & 0x00FFFFFF) << 1) + 0x8000000; + rompatch2oldval[1] = CPUReadHalfWord(rompatch2addr[1]); + rompatch2val[1] = cheatsList[i].rawaddress & 0xFFFF; + } + break; + case GSA_16_BIT_ROM_PATCH2E: + i++; + if (i < cheatsNumber) { + rompatch2addr[2] = ((cheatsList[i - 1].value & 0x00FFFFFF) << 1) + 0x8000000; + rompatch2oldval[2] = CPUReadHalfWord(rompatch2addr[2]); + rompatch2val[2] = cheatsList[i].rawaddress & 0xFFFF; + } + break; + case GSA_16_BIT_ROM_PATCH2F: + i++; + if (i < cheatsNumber) { + rompatch2addr[3] = ((cheatsList[i - 1].value & 0x00FFFFFF) << 1) + 0x8000000; + rompatch2oldval[3] = CPUReadHalfWord(rompatch2addr[3]); + rompatch2val[3] = cheatsList[i].rawaddress & 0xFFFF; + } + break; + case MASTER_CODE: + mastercode = cheatsList[i].address; + break; } - break; - case GSA_16_BIT_POINTER : - if (((CPUReadMemory(cheatsList[i].address)>=0x02000000) && (CPUReadMemory(cheatsList[i].address)<0x02040000)) || - ((CPUReadMemory(cheatsList[i].address)>=0x03000000) && (CPUReadMemory(cheatsList[i].address)<0x03008000))) - { - CPUWriteHalfWord(CPUReadMemory(cheatsList[i].address)+((cheatsList[i].value & 0xFFFF0000) >> 15), - cheatsList[i].value & 0xFFFF); - } - break; - case GSA_32_BIT_POINTER : - if (((CPUReadMemory(cheatsList[i].address)>=0x02000000) && (CPUReadMemory(cheatsList[i].address)<0x02040000)) || - ((CPUReadMemory(cheatsList[i].address)>=0x03000000) && (CPUReadMemory(cheatsList[i].address)<0x03008000))) - { - CPUWriteMemory(CPUReadMemory(cheatsList[i].address), - cheatsList[i].value); - } - break; - case GSA_8_BIT_ADD : - CPUWriteByte(cheatsList[i].address, + if (onoff) { + switch (cheatsList[i].size) { + case INT_8_BIT_WRITE: + CPUWriteByte(cheatsList[i].address, cheatsList[i].value); + break; + case INT_16_BIT_WRITE: + CPUWriteHalfWord(cheatsList[i].address, cheatsList[i].value); + break; + case INT_32_BIT_WRITE: + CPUWriteMemory(cheatsList[i].address, cheatsList[i].value); + break; + case GSA_8_BIT_GS_WRITE: + if (extended & 4) { + CPUWriteByte(cheatsList[i].address, cheatsList[i].value); + } + break; + case GSA_16_BIT_GS_WRITE: + if (extended & 4) { + CPUWriteHalfWord(cheatsList[i].address, cheatsList[i].value); + } + break; + case GSA_32_BIT_GS_WRITE: + if (extended & 4) { + CPUWriteMemory(cheatsList[i].address, cheatsList[i].value); + } + break; + case CBA_IF_KEYS_PRESSED: { + u16 value = cheatsList[i].value; + u32 addr = cheatsList[i].address; + if ((addr & 0xF0) == 0x20) { + if ((keys & value) == 0) { + i++; + } + } else if ((addr & 0xF0) == 0x10) { + if ((keys & value) == value) { + i++; + } + } else if ((addr & 0xF0) == 0x00) { + if (((~keys) & 0x3FF) == value) { + i++; + } + } + } break; + case CBA_IF_TRUE: + if (CPUReadHalfWord(cheatsList[i].address) != cheatsList[i].value) { + i++; + } + break; + case CBA_SLIDE_CODE: { + u32 address = cheatsList[i].address; + u16 value = cheatsList[i].value; + i++; + if (i < cheatsNumber) { + int count = ((cheatsList[i].address - 1) & 0xFFFF); + u16 vinc = (cheatsList[i].address >> 16) & 0xFFFF; + int inc = cheatsList[i].value; + for (int x = 0; x <= count; x++) { + CPUWriteHalfWord(address, value); + address += inc; + value += vinc; + } + } + } break; + case CBA_IF_FALSE: + if (CPUReadHalfWord(cheatsList[i].address) == cheatsList[i].value) { + i++; + } + break; + case CBA_AND: + CPUWriteHalfWord(cheatsList[i].address, + CPUReadHalfWord(cheatsList[i].address) & cheatsList[i].value); + break; + case GSA_8_BIT_IF_TRUE: + if (CPUReadByte(cheatsList[i].address) != cheatsList[i].value) { + i++; + } + break; + case GSA_32_BIT_IF_TRUE: + if (CPUReadMemory(cheatsList[i].address) != cheatsList[i].value) { + i++; + } + break; + case GSA_8_BIT_IF_FALSE: + if (CPUReadByte(cheatsList[i].address) == cheatsList[i].value) { + i++; + } + break; + case GSA_32_BIT_IF_FALSE: + if (CPUReadMemory(cheatsList[i].address) == cheatsList[i].value) { + i++; + } + break; + case GSA_8_BIT_FILL: { + u32 addr = cheatsList[i].address; + u8 v = cheatsList[i].value & 0xff; + u32 end = addr + (cheatsList[i].value >> 8); + do { + CPUWriteByte(addr, v); + addr++; + } while (addr <= end); + } break; + case GSA_16_BIT_FILL: { + u32 addr = cheatsList[i].address; + u16 v = cheatsList[i].value & 0xffff; + u32 end = addr + ((cheatsList[i].value >> 16) << 1); + do { + CPUWriteHalfWord(addr, v); + addr += 2; + } while (addr <= end); + } break; + case GSA_8_BIT_IF_TRUE2: + if (CPUReadByte(cheatsList[i].address) != cheatsList[i].value) { + i += 2; + } + break; + case GSA_16_BIT_IF_TRUE2: + if (CPUReadHalfWord(cheatsList[i].address) != cheatsList[i].value) { + i += 2; + } + break; + case GSA_32_BIT_IF_TRUE2: + if (CPUReadMemory(cheatsList[i].address) != cheatsList[i].value) { + i += 2; + } + break; + case GSA_8_BIT_IF_FALSE2: + if (CPUReadByte(cheatsList[i].address) == cheatsList[i].value) { + i += 2; + } + break; + case GSA_16_BIT_IF_FALSE2: + if (CPUReadHalfWord(cheatsList[i].address) == cheatsList[i].value) { + i += 2; + } + break; + case GSA_32_BIT_IF_FALSE2: + if (CPUReadMemory(cheatsList[i].address) == cheatsList[i].value) { + i += 2; + } + break; + case CBA_ADD: + if ((cheatsList[i].address & 1) == 0) { + CPUWriteHalfWord(cheatsList[i].address, + CPUReadHalfWord(cheatsList[i].address) + cheatsList[i].value); + } else { + CPUWriteMemory(cheatsList[i].address & 0x0FFFFFFE, + CPUReadMemory(cheatsList[i].address & 0x0FFFFFFE) + cheatsList[i].value); + } + break; + case CBA_OR: + CPUWriteHalfWord(cheatsList[i].address, + CPUReadHalfWord(cheatsList[i].address) | cheatsList[i].value); + break; + case CBA_GT: + if (!(CPUReadHalfWord(cheatsList[i].address) > cheatsList[i].value)) { + i++; + } + break; + case CBA_LT: + if (!(CPUReadHalfWord(cheatsList[i].address) < cheatsList[i].value)) { + i++; + } + break; + case CBA_SUPER: { + int count = 2 * ((cheatsList[i].value - 1) & 0xFFFF) + 1; + u32 address = cheatsList[i].address; + for (int x = 0; x <= count; x++) { + u8 b; + int res = x % 6; + if (res == 0) + i++; + if (res < 4) + b = (cheatsList[i].address >> (24 - 8 * res)) & 0xFF; + else + b = (cheatsList[i].value >> (8 - 8 * (res - 4))) & 0xFF; + CPUWriteByte(address, b); + address++; + } + } break; + case GSA_8_BIT_POINTER: + if (((CPUReadMemory(cheatsList[i].address) >= 0x02000000) && (CPUReadMemory(cheatsList[i].address) < 0x02040000)) || ((CPUReadMemory(cheatsList[i].address) >= 0x03000000) && (CPUReadMemory(cheatsList[i].address) < 0x03008000))) { + CPUWriteByte(CPUReadMemory(cheatsList[i].address) + ((cheatsList[i].value & 0xFFFFFF00) >> 8), + cheatsList[i].value & 0xFF); + } + break; + case GSA_16_BIT_POINTER: + if (((CPUReadMemory(cheatsList[i].address) >= 0x02000000) && (CPUReadMemory(cheatsList[i].address) < 0x02040000)) || ((CPUReadMemory(cheatsList[i].address) >= 0x03000000) && (CPUReadMemory(cheatsList[i].address) < 0x03008000))) { + CPUWriteHalfWord(CPUReadMemory(cheatsList[i].address) + ((cheatsList[i].value & 0xFFFF0000) >> 15), + cheatsList[i].value & 0xFFFF); + } + break; + case GSA_32_BIT_POINTER: + if (((CPUReadMemory(cheatsList[i].address) >= 0x02000000) && (CPUReadMemory(cheatsList[i].address) < 0x02040000)) || ((CPUReadMemory(cheatsList[i].address) >= 0x03000000) && (CPUReadMemory(cheatsList[i].address) < 0x03008000))) { + CPUWriteMemory(CPUReadMemory(cheatsList[i].address), + cheatsList[i].value); + } + break; + case GSA_8_BIT_ADD: + CPUWriteByte(cheatsList[i].address, ((cheatsList[i].value & 0xFF) + CPUReadMemory(cheatsList[i].address)) & 0xFF); - break; - case GSA_16_BIT_ADD : - CPUWriteHalfWord(cheatsList[i].address, - ((cheatsList[i].value & 0xFFFF) + CPUReadMemory(cheatsList[i].address)) & 0xFFFF); - break; - case GSA_32_BIT_ADD : - CPUWriteMemory(cheatsList[i].address , - (cheatsList[i].value + CPUReadMemory(cheatsList[i].address)) & 0xFFFFFFFF); - break; - case GSA_8_BIT_IF_LOWER_U: - if (!(CPUReadByte(cheatsList[i].address) < (cheatsList[i].value & 0xFF))) { - i++; + break; + case GSA_16_BIT_ADD: + CPUWriteHalfWord(cheatsList[i].address, + ((cheatsList[i].value & 0xFFFF) + CPUReadMemory(cheatsList[i].address)) & 0xFFFF); + break; + case GSA_32_BIT_ADD: + CPUWriteMemory(cheatsList[i].address, + (cheatsList[i].value + CPUReadMemory(cheatsList[i].address)) & 0xFFFFFFFF); + break; + case GSA_8_BIT_IF_LOWER_U: + if (!(CPUReadByte(cheatsList[i].address) < (cheatsList[i].value & 0xFF))) { + i++; + } + break; + case GSA_16_BIT_IF_LOWER_U: + if (!(CPUReadHalfWord(cheatsList[i].address) < (cheatsList[i].value & 0xFFFF))) { + i++; + } + break; + case GSA_32_BIT_IF_LOWER_U: + if (!(CPUReadMemory(cheatsList[i].address) < cheatsList[i].value)) { + i++; + } + break; + case GSA_8_BIT_IF_HIGHER_U: + if (!(CPUReadByte(cheatsList[i].address) > (cheatsList[i].value & 0xFF))) { + i++; + } + break; + case GSA_16_BIT_IF_HIGHER_U: + if (!(CPUReadHalfWord(cheatsList[i].address) > (cheatsList[i].value & 0xFFFF))) { + i++; + } + break; + case GSA_32_BIT_IF_HIGHER_U: + if (!(CPUReadMemory(cheatsList[i].address) > cheatsList[i].value)) { + i++; + } + break; + case GSA_8_BIT_IF_AND: + if (!(CPUReadByte(cheatsList[i].address) & (cheatsList[i].value & 0xFF))) { + i++; + } + break; + case GSA_16_BIT_IF_AND: + if (!(CPUReadHalfWord(cheatsList[i].address) & (cheatsList[i].value & 0xFFFF))) { + i++; + } + break; + case GSA_32_BIT_IF_AND: + if (!(CPUReadMemory(cheatsList[i].address) & cheatsList[i].value)) { + i++; + } + break; + case GSA_8_BIT_IF_LOWER_U2: + if (!(CPUReadByte(cheatsList[i].address) < (cheatsList[i].value & 0xFF))) { + i += 2; + } + break; + case GSA_16_BIT_IF_LOWER_U2: + if (!(CPUReadHalfWord(cheatsList[i].address) < (cheatsList[i].value & 0xFFFF))) { + i += 2; + } + break; + case GSA_32_BIT_IF_LOWER_U2: + if (!(CPUReadMemory(cheatsList[i].address) < cheatsList[i].value)) { + i += 2; + } + break; + case GSA_8_BIT_IF_HIGHER_U2: + if (!(CPUReadByte(cheatsList[i].address) > (cheatsList[i].value & 0xFF))) { + i += 2; + } + break; + case GSA_16_BIT_IF_HIGHER_U2: + if (!(CPUReadHalfWord(cheatsList[i].address) > (cheatsList[i].value & 0xFFFF))) { + i += 2; + } + break; + case GSA_32_BIT_IF_HIGHER_U2: + if (!(CPUReadMemory(cheatsList[i].address) > cheatsList[i].value)) { + i += 2; + } + break; + case GSA_8_BIT_IF_AND2: + if (!(CPUReadByte(cheatsList[i].address) & (cheatsList[i].value & 0xFF))) { + i += 2; + } + break; + case GSA_16_BIT_IF_AND2: + if (!(CPUReadHalfWord(cheatsList[i].address) & (cheatsList[i].value & 0xFFFF))) { + i += 2; + } + break; + case GSA_32_BIT_IF_AND2: + if (!(CPUReadMemory(cheatsList[i].address) & cheatsList[i].value)) { + i += 2; + } + break; + case GSA_ALWAYS: + i++; + break; + case GSA_ALWAYS2: + i += 2; + break; + case GSA_8_BIT_IF_LOWER_S: + if (!((s8)CPUReadByte(cheatsList[i].address) < ((s8)cheatsList[i].value & 0xFF))) { + i++; + } + break; + case GSA_16_BIT_IF_LOWER_S: + if (!((s16)CPUReadHalfWord(cheatsList[i].address) < ((s16)cheatsList[i].value & 0xFFFF))) { + i++; + } + break; + case GSA_32_BIT_IF_LOWER_S: + if (!((s32)CPUReadMemory(cheatsList[i].address) < (s32)cheatsList[i].value)) { + i++; + } + break; + case GSA_8_BIT_IF_HIGHER_S: + if (!((s8)CPUReadByte(cheatsList[i].address) > ((s8)cheatsList[i].value & 0xFF))) { + i++; + } + break; + case GSA_16_BIT_IF_HIGHER_S: + if (!((s16)CPUReadHalfWord(cheatsList[i].address) > ((s16)cheatsList[i].value & 0xFFFF))) { + i++; + } + break; + case GSA_32_BIT_IF_HIGHER_S: + if (!((s32)CPUReadMemory(cheatsList[i].address) > (s32)cheatsList[i].value)) { + i++; + } + break; + case GSA_8_BIT_IF_LOWER_S2: + if (!((s8)CPUReadByte(cheatsList[i].address) < ((s8)cheatsList[i].value & 0xFF))) { + i += 2; + } + break; + case GSA_16_BIT_IF_LOWER_S2: + if (!((s16)CPUReadHalfWord(cheatsList[i].address) < ((s16)cheatsList[i].value & 0xFFFF))) { + i += 2; + } + break; + case GSA_32_BIT_IF_LOWER_S2: + if (!((s32)CPUReadMemory(cheatsList[i].address) < (s32)cheatsList[i].value)) { + i += 2; + } + break; + case GSA_8_BIT_IF_HIGHER_S2: + if (!((s8)CPUReadByte(cheatsList[i].address) > ((s8)cheatsList[i].value & 0xFF))) { + i += 2; + } + break; + case GSA_16_BIT_IF_HIGHER_S2: + if (!((s16)CPUReadHalfWord(cheatsList[i].address) > ((s16)cheatsList[i].value & 0xFFFF))) { + i += 2; + } + break; + case GSA_32_BIT_IF_HIGHER_S2: + if (!((s32)CPUReadMemory(cheatsList[i].address) > (s32)cheatsList[i].value)) { + i += 2; + } + break; + case GSA_16_BIT_WRITE_IOREGS: + if ((cheatsList[i].address <= 0x3FF) && (cheatsList[i].address != 0x6) && (cheatsList[i].address != 0x130)) + ioMem[cheatsList[i].address & 0x3FE] = cheatsList[i].value & 0xFFFF; + break; + case GSA_32_BIT_WRITE_IOREGS: + if (cheatsList[i].address <= 0x3FF) { + if (((cheatsList[i].address & 0x3FC) != 0x6) && ((cheatsList[i].address & 0x3FC) != 0x130)) + ioMem[cheatsList[i].address & 0x3FC] = (cheatsList[i].value & 0xFFFF); + if ((((cheatsList[i].address & 0x3FC) + 2) != 0x6) && ((cheatsList[i].address & 0x3FC) + 2) != 0x130) + ioMem[(cheatsList[i].address & 0x3FC) + 2] = ((cheatsList[i].value >> 16) & 0xFFFF); + } + break; + case GSA_8_BIT_IF_TRUE3: + if (CPUReadByte(cheatsList[i].address) != cheatsList[i].value) { + onoff = false; + } + break; + case GSA_16_BIT_IF_TRUE3: + if (CPUReadHalfWord(cheatsList[i].address) != cheatsList[i].value) { + onoff = false; + } + break; + case GSA_32_BIT_IF_TRUE3: + if (CPUReadMemory(cheatsList[i].address) != cheatsList[i].value) { + onoff = false; + } + break; + case GSA_8_BIT_IF_FALSE3: + if (CPUReadByte(cheatsList[i].address) == cheatsList[i].value) { + onoff = false; + } + break; + case GSA_16_BIT_IF_FALSE3: + if (CPUReadHalfWord(cheatsList[i].address) == cheatsList[i].value) { + onoff = false; + } + break; + case GSA_32_BIT_IF_FALSE3: + if (CPUReadMemory(cheatsList[i].address) == cheatsList[i].value) { + onoff = false; + } + break; + case GSA_8_BIT_IF_LOWER_S3: + if (!((s8)CPUReadByte(cheatsList[i].address) < ((s8)cheatsList[i].value & 0xFF))) { + onoff = false; + } + break; + case GSA_16_BIT_IF_LOWER_S3: + if (!((s16)CPUReadHalfWord(cheatsList[i].address) < ((s16)cheatsList[i].value & 0xFFFF))) { + onoff = false; + } + break; + case GSA_32_BIT_IF_LOWER_S3: + if (!((s32)CPUReadMemory(cheatsList[i].address) < (s32)cheatsList[i].value)) { + onoff = false; + } + break; + case GSA_8_BIT_IF_HIGHER_S3: + if (!((s8)CPUReadByte(cheatsList[i].address) > ((s8)cheatsList[i].value & 0xFF))) { + onoff = false; + } + break; + case GSA_16_BIT_IF_HIGHER_S3: + if (!((s16)CPUReadHalfWord(cheatsList[i].address) > ((s16)cheatsList[i].value & 0xFFFF))) { + onoff = false; + } + break; + case GSA_32_BIT_IF_HIGHER_S3: + if (!((s32)CPUReadMemory(cheatsList[i].address) > (s32)cheatsList[i].value)) { + onoff = false; + } + break; + case GSA_8_BIT_IF_LOWER_U3: + if (!(CPUReadByte(cheatsList[i].address) < (cheatsList[i].value & 0xFF))) { + onoff = false; + } + break; + case GSA_16_BIT_IF_LOWER_U3: + if (!(CPUReadHalfWord(cheatsList[i].address) < (cheatsList[i].value & 0xFFFF))) { + onoff = false; + } + break; + case GSA_32_BIT_IF_LOWER_U3: + if (!(CPUReadMemory(cheatsList[i].address) < cheatsList[i].value)) { + onoff = false; + } + break; + case GSA_8_BIT_IF_HIGHER_U3: + if (!(CPUReadByte(cheatsList[i].address) > (cheatsList[i].value & 0xFF))) { + onoff = false; + } + break; + case GSA_16_BIT_IF_HIGHER_U3: + if (!(CPUReadHalfWord(cheatsList[i].address) > (cheatsList[i].value & 0xFFFF))) { + onoff = false; + } + break; + case GSA_32_BIT_IF_HIGHER_U3: + if (!(CPUReadMemory(cheatsList[i].address) > cheatsList[i].value)) { + onoff = false; + } + break; + case GSA_8_BIT_IF_AND3: + if (!(CPUReadByte(cheatsList[i].address) & (cheatsList[i].value & 0xFF))) { + onoff = false; + } + break; + case GSA_16_BIT_IF_AND3: + if (!(CPUReadHalfWord(cheatsList[i].address) & (cheatsList[i].value & 0xFFFF))) { + onoff = false; + } + break; + case GSA_32_BIT_IF_AND3: + if (!(CPUReadMemory(cheatsList[i].address) & cheatsList[i].value)) { + onoff = false; + } + break; + case GSA_ALWAYS3: + if (!(CPUReadMemory(cheatsList[i].address) & cheatsList[i].value)) { + onoff = false; + } + break; + case GSA_GROUP_WRITE: { + int count = ((cheatsList[i].address) & 0xFFFE) + 1; + u32 value = cheatsList[i].value; + if (count == 0) + i++; + else + for (int x = 1; x <= count; x++) { + if ((x % 2) == 0) { + if (x < count) + i++; + CPUWriteMemory(cheatsList[i].rawaddress, value); + } else + CPUWriteMemory(cheatsList[i].value, value); + } + } break; + case GSA_32_BIT_ADD2: + CPUWriteMemory(cheatsList[i].value, + (CPUReadMemory(cheatsList[i].value) + cheatsList[i + 1].rawaddress) & 0xFFFFFFFF); + i++; + break; + case GSA_32_BIT_SUB2: + CPUWriteMemory(cheatsList[i].value, + (CPUReadMemory(cheatsList[i].value) - cheatsList[i + 1].rawaddress) & 0xFFFFFFFF); + i++; + break; + case GSA_16_BIT_IF_LOWER_OR_EQ_U: + if (CPUReadHalfWord(cheatsList[i].address) > cheatsList[i].value) { + i++; + } + break; + case GSA_16_BIT_IF_HIGHER_OR_EQ_U: + if (CPUReadHalfWord(cheatsList[i].address) < cheatsList[i].value) { + i++; + } + break; + case GSA_16_BIT_MIF_TRUE: + if (CPUReadHalfWord(cheatsList[i].address) != cheatsList[i].value) { + i += ((cheatsList[i].rawaddress >> 0x10) & 0xFF); + } + break; + case GSA_16_BIT_MIF_FALSE: + if (CPUReadHalfWord(cheatsList[i].address) == cheatsList[i].value) { + i += (cheatsList[i].rawaddress >> 0x10) & 0xFF; + } + break; + case GSA_16_BIT_MIF_LOWER_OR_EQ_U: + if (CPUReadHalfWord(cheatsList[i].address) > cheatsList[i].value) { + i += (cheatsList[i].rawaddress >> 0x10) & 0xFF; + } + break; + case GSA_16_BIT_MIF_HIGHER_OR_EQ_U: + if (CPUReadHalfWord(cheatsList[i].address) < cheatsList[i].value) { + i += (cheatsList[i].rawaddress >> 0x10) & 0xFF; + } + break; + case CHEATS_16_BIT_WRITE: + if ((cheatsList[i].address >> 24) >= 0x08) { + CHEAT_PATCH_ROM_16BIT(cheatsList[i].address, cheatsList[i].value); + } else { + CPUWriteHalfWord(cheatsList[i].address, cheatsList[i].value); + } + break; + case CHEATS_32_BIT_WRITE: + if ((cheatsList[i].address >> 24) >= 0x08) { + CHEAT_PATCH_ROM_32BIT(cheatsList[i].address, cheatsList[i].value); + } else { + CPUWriteMemory(cheatsList[i].address, cheatsList[i].value); + } + break; + } } - break; - case GSA_16_BIT_IF_LOWER_U: - if (!(CPUReadHalfWord(cheatsList[i].address) < (cheatsList[i].value & 0xFFFF))) { - i++; - } - break; - case GSA_32_BIT_IF_LOWER_U: - if (!(CPUReadMemory(cheatsList[i].address) < cheatsList[i].value)) { - i++; - } - break; - case GSA_8_BIT_IF_HIGHER_U: - if (!(CPUReadByte(cheatsList[i].address) > (cheatsList[i].value & 0xFF))) { - i++; - } - break; - case GSA_16_BIT_IF_HIGHER_U: - if (!(CPUReadHalfWord(cheatsList[i].address) > (cheatsList[i].value & 0xFFFF))) { - i++; - } - break; - case GSA_32_BIT_IF_HIGHER_U: - if (!(CPUReadMemory(cheatsList[i].address) > cheatsList[i].value)) { - i++; - } - break; - case GSA_8_BIT_IF_AND: - if (!(CPUReadByte(cheatsList[i].address) & (cheatsList[i].value & 0xFF))) { - i++; - } - break; - case GSA_16_BIT_IF_AND: - if (!(CPUReadHalfWord(cheatsList[i].address) & (cheatsList[i].value & 0xFFFF))) { - i++; - } - break; - case GSA_32_BIT_IF_AND: - if (!(CPUReadMemory(cheatsList[i].address) & cheatsList[i].value)) { - i++; - } - break; - case GSA_8_BIT_IF_LOWER_U2: - if (!(CPUReadByte(cheatsList[i].address) < (cheatsList[i].value & 0xFF))) { - i+=2; - } - break; - case GSA_16_BIT_IF_LOWER_U2: - if (!(CPUReadHalfWord(cheatsList[i].address) < (cheatsList[i].value & 0xFFFF))) { - i+=2; - } - break; - case GSA_32_BIT_IF_LOWER_U2: - if (!(CPUReadMemory(cheatsList[i].address) < cheatsList[i].value)) { - i+=2; - } - break; - case GSA_8_BIT_IF_HIGHER_U2: - if (!(CPUReadByte(cheatsList[i].address) > (cheatsList[i].value & 0xFF))) { - i+=2; - } - break; - case GSA_16_BIT_IF_HIGHER_U2: - if (!(CPUReadHalfWord(cheatsList[i].address) > (cheatsList[i].value & 0xFFFF))) { - i+=2; - } - break; - case GSA_32_BIT_IF_HIGHER_U2: - if (!(CPUReadMemory(cheatsList[i].address) > cheatsList[i].value)) { - i+=2; - } - break; - case GSA_8_BIT_IF_AND2: - if (!(CPUReadByte(cheatsList[i].address) & (cheatsList[i].value & 0xFF))) { - i+=2; - } - break; - case GSA_16_BIT_IF_AND2: - if (!(CPUReadHalfWord(cheatsList[i].address) & (cheatsList[i].value & 0xFFFF))) { - i+=2; - } - break; - case GSA_32_BIT_IF_AND2: - if (!(CPUReadMemory(cheatsList[i].address) & cheatsList[i].value)) { - i+=2; - } - break; - case GSA_ALWAYS: - i++; - break; - case GSA_ALWAYS2: - i+=2; - break; - case GSA_8_BIT_IF_LOWER_S: - if (!((s8)CPUReadByte(cheatsList[i].address) < ((s8)cheatsList[i].value & 0xFF))) { - i++; - } - break; - case GSA_16_BIT_IF_LOWER_S: - if (!((s16)CPUReadHalfWord(cheatsList[i].address) < ((s16)cheatsList[i].value & 0xFFFF))) { - i++; - } - break; - case GSA_32_BIT_IF_LOWER_S: - if (!((s32)CPUReadMemory(cheatsList[i].address) < (s32)cheatsList[i].value)) { - i++; - } - break; - case GSA_8_BIT_IF_HIGHER_S: - if (!((s8)CPUReadByte(cheatsList[i].address) > ((s8)cheatsList[i].value & 0xFF))) { - i++; - } - break; - case GSA_16_BIT_IF_HIGHER_S: - if (!((s16)CPUReadHalfWord(cheatsList[i].address) > ((s16)cheatsList[i].value & 0xFFFF))) { - i++; - } - break; - case GSA_32_BIT_IF_HIGHER_S: - if (!((s32)CPUReadMemory(cheatsList[i].address) > (s32)cheatsList[i].value)) { - i++; - } - break; - case GSA_8_BIT_IF_LOWER_S2: - if (!((s8)CPUReadByte(cheatsList[i].address) < ((s8)cheatsList[i].value & 0xFF))) { - i+=2; - } - break; - case GSA_16_BIT_IF_LOWER_S2: - if (!((s16)CPUReadHalfWord(cheatsList[i].address) < ((s16)cheatsList[i].value & 0xFFFF))) { - i+=2; - } - break; - case GSA_32_BIT_IF_LOWER_S2: - if (!((s32)CPUReadMemory(cheatsList[i].address) < (s32)cheatsList[i].value)) { - i+=2; - } - break; - case GSA_8_BIT_IF_HIGHER_S2: - if (!((s8)CPUReadByte(cheatsList[i].address) > ((s8)cheatsList[i].value & 0xFF))) { - i+=2; - } - break; - case GSA_16_BIT_IF_HIGHER_S2: - if (!((s16)CPUReadHalfWord(cheatsList[i].address) > ((s16)cheatsList[i].value & 0xFFFF))) { - i+=2; - } - break; - case GSA_32_BIT_IF_HIGHER_S2: - if (!((s32)CPUReadMemory(cheatsList[i].address) > (s32)cheatsList[i].value)) { - i+=2; - } - break; - case GSA_16_BIT_WRITE_IOREGS: - if ((cheatsList[i].address <= 0x3FF) && (cheatsList[i].address != 0x6) && - (cheatsList[i].address != 0x130)) - ioMem[cheatsList[i].address & 0x3FE]=cheatsList[i].value & 0xFFFF; - break; - case GSA_32_BIT_WRITE_IOREGS: - if (cheatsList[i].address<=0x3FF) - { - if (((cheatsList[i].address & 0x3FC) != 0x6) && ((cheatsList[i].address & 0x3FC) != 0x130)) - ioMem[cheatsList[i].address & 0x3FC]= (cheatsList[i].value & 0xFFFF); - if ((((cheatsList[i].address & 0x3FC)+2) != 0x6) && ((cheatsList[i].address & 0x3FC) +2) != 0x130) - ioMem[(cheatsList[i].address & 0x3FC) + 2 ]= ((cheatsList[i].value>>16 ) & 0xFFFF); - } - break; - case GSA_8_BIT_IF_TRUE3: - if(CPUReadByte(cheatsList[i].address) != cheatsList[i].value) { - onoff=false; - } - break; - case GSA_16_BIT_IF_TRUE3: - if(CPUReadHalfWord(cheatsList[i].address) != cheatsList[i].value) { - onoff=false; - } - break; - case GSA_32_BIT_IF_TRUE3: - if(CPUReadMemory(cheatsList[i].address) != cheatsList[i].value) { - onoff=false; - } - break; - case GSA_8_BIT_IF_FALSE3: - if(CPUReadByte(cheatsList[i].address) == cheatsList[i].value) { - onoff=false; - } - break; - case GSA_16_BIT_IF_FALSE3: - if(CPUReadHalfWord(cheatsList[i].address) == cheatsList[i].value) { - onoff=false; - } - break; - case GSA_32_BIT_IF_FALSE3: - if(CPUReadMemory(cheatsList[i].address) == cheatsList[i].value) { - onoff=false; - } - break; - case GSA_8_BIT_IF_LOWER_S3: - if (!((s8)CPUReadByte(cheatsList[i].address) < ((s8)cheatsList[i].value & 0xFF))) { - onoff=false; - } - break; - case GSA_16_BIT_IF_LOWER_S3: - if (!((s16)CPUReadHalfWord(cheatsList[i].address) < ((s16)cheatsList[i].value & 0xFFFF))) { - onoff=false; - } - break; - case GSA_32_BIT_IF_LOWER_S3: - if (!((s32)CPUReadMemory(cheatsList[i].address) < (s32)cheatsList[i].value)) { - onoff=false; - } - break; - case GSA_8_BIT_IF_HIGHER_S3: - if (!((s8)CPUReadByte(cheatsList[i].address) > ((s8)cheatsList[i].value & 0xFF))) { - onoff=false; - } - break; - case GSA_16_BIT_IF_HIGHER_S3: - if (!((s16)CPUReadHalfWord(cheatsList[i].address) > ((s16)cheatsList[i].value & 0xFFFF))) { - onoff=false; - } - break; - case GSA_32_BIT_IF_HIGHER_S3: - if (!((s32)CPUReadMemory(cheatsList[i].address) > (s32)cheatsList[i].value)) { - onoff=false; - } - break; - case GSA_8_BIT_IF_LOWER_U3: - if (!(CPUReadByte(cheatsList[i].address) < (cheatsList[i].value & 0xFF))) { - onoff=false; - } - break; - case GSA_16_BIT_IF_LOWER_U3: - if (!(CPUReadHalfWord(cheatsList[i].address) < (cheatsList[i].value & 0xFFFF))) { - onoff=false; - } - break; - case GSA_32_BIT_IF_LOWER_U3: - if (!(CPUReadMemory(cheatsList[i].address) < cheatsList[i].value)) { - onoff=false; - } - break; - case GSA_8_BIT_IF_HIGHER_U3: - if (!(CPUReadByte(cheatsList[i].address) > (cheatsList[i].value & 0xFF))) { - onoff=false; - } - break; - case GSA_16_BIT_IF_HIGHER_U3: - if (!(CPUReadHalfWord(cheatsList[i].address) > (cheatsList[i].value & 0xFFFF))) { - onoff=false; - } - break; - case GSA_32_BIT_IF_HIGHER_U3: - if (!(CPUReadMemory(cheatsList[i].address) > cheatsList[i].value)) { - onoff=false; - } - break; - case GSA_8_BIT_IF_AND3: - if (!(CPUReadByte(cheatsList[i].address) & (cheatsList[i].value & 0xFF))) { - onoff=false; - } - break; - case GSA_16_BIT_IF_AND3: - if (!(CPUReadHalfWord(cheatsList[i].address) & (cheatsList[i].value & 0xFFFF))) { - onoff=false; - } - break; - case GSA_32_BIT_IF_AND3: - if (!(CPUReadMemory(cheatsList[i].address) & cheatsList[i].value)) { - onoff=false; - } - break; - case GSA_ALWAYS3: - if (!(CPUReadMemory(cheatsList[i].address) & cheatsList[i].value)) { - onoff=false; - } - break; - case GSA_GROUP_WRITE: - { - int count = ((cheatsList[i].address) & 0xFFFE) +1; - u32 value = cheatsList[i].value; - if (count==0) - i++; - else - for (int x = 1; x <= count; x++) { - if ((x % 2) ==0){ - if (x cheatsList[i].value) { - i++; - } - break; - case GSA_16_BIT_IF_HIGHER_OR_EQ_U: - if(CPUReadHalfWord(cheatsList[i].address) < cheatsList[i].value) { - i++; - } - break; - case GSA_16_BIT_MIF_TRUE: - if(CPUReadHalfWord(cheatsList[i].address) != cheatsList[i].value) { - i+=((cheatsList[i].rawaddress >> 0x10) & 0xFF); - } - break; - case GSA_16_BIT_MIF_FALSE: - if(CPUReadHalfWord(cheatsList[i].address) == cheatsList[i].value) { - i+=(cheatsList[i].rawaddress >> 0x10) & 0xFF; - } - break; - case GSA_16_BIT_MIF_LOWER_OR_EQ_U: - if(CPUReadHalfWord(cheatsList[i].address) > cheatsList[i].value) { - i+=(cheatsList[i].rawaddress >> 0x10) & 0xFF; - } - break; - case GSA_16_BIT_MIF_HIGHER_OR_EQ_U: - if(CPUReadHalfWord(cheatsList[i].address) < cheatsList[i].value) { - i+=(cheatsList[i].rawaddress >> 0x10) & 0xFF; - } - break; - case CHEATS_16_BIT_WRITE: - if ((cheatsList[i].address>>24)>=0x08) { - CHEAT_PATCH_ROM_16BIT(cheatsList[i].address, cheatsList[i].value); - } else { - CPUWriteHalfWord(cheatsList[i].address, cheatsList[i].value); - } - break; - case CHEATS_32_BIT_WRITE: - if ((cheatsList[i].address>>24)>=0x08) { - CHEAT_PATCH_ROM_32BIT(cheatsList[i].address, cheatsList[i].value); - } else { - CPUWriteMemory(cheatsList[i].address, cheatsList[i].value); - } - break; - } } - } - for (i = 0; i<4; i++) - if (rompatch2addr [i] != 0) - CHEAT_PATCH_ROM_16BIT(rompatch2addr [i],rompatch2val [i]); - return ticks; + for (i = 0; i < 4; i++) + if (rompatch2addr[i] != 0) + CHEAT_PATCH_ROM_16BIT(rompatch2addr[i], rompatch2val[i]); + return ticks; } -void cheatsAdd(const char *codeStr, - const char *desc, - u32 rawaddress, - u32 address, - u32 value, - int code, - int size) +void cheatsAdd(const char* codeStr, + const char* desc, + u32 rawaddress, + u32 address, + u32 value, + int code, + int size) { - if(cheatsNumber < MAX_CHEATS) { - int x = cheatsNumber; - cheatsList[x].code = code; - cheatsList[x].size = size; - cheatsList[x].rawaddress = rawaddress; - cheatsList[x].address = address; - cheatsList[x].value = value; - strcpy(cheatsList[x].codestring, codeStr); - strcpy(cheatsList[x].desc, desc); - cheatsList[x].enabled = true; - cheatsList[x].status = 0; + if (cheatsNumber < MAX_CHEATS) { + int x = cheatsNumber; + cheatsList[x].code = code; + cheatsList[x].size = size; + cheatsList[x].rawaddress = rawaddress; + cheatsList[x].address = address; + cheatsList[x].value = value; + strcpy(cheatsList[x].codestring, codeStr); + strcpy(cheatsList[x].desc, desc); + cheatsList[x].enabled = true; + cheatsList[x].status = 0; - // we only store the old value for this simple codes. ROM patching - // is taken care when it actually patches the ROM - switch(cheatsList[x].size) { - case INT_8_BIT_WRITE: - cheatsList[x].oldValue = CPUReadByte(address); - break; - case INT_16_BIT_WRITE: - cheatsList[x].oldValue = CPUReadHalfWord(address); - break; - case INT_32_BIT_WRITE: - cheatsList[x].oldValue = CPUReadMemory(address); - break; - case CHEATS_16_BIT_WRITE: - cheatsList[x].oldValue = CPUReadHalfWord(address); - break; - case CHEATS_32_BIT_WRITE: - cheatsList[x].oldValue = CPUReadMemory(address); - break; + // we only store the old value for this simple codes. ROM patching + // is taken care when it actually patches the ROM + switch (cheatsList[x].size) { + case INT_8_BIT_WRITE: + cheatsList[x].oldValue = CPUReadByte(address); + break; + case INT_16_BIT_WRITE: + cheatsList[x].oldValue = CPUReadHalfWord(address); + break; + case INT_32_BIT_WRITE: + cheatsList[x].oldValue = CPUReadMemory(address); + break; + case CHEATS_16_BIT_WRITE: + cheatsList[x].oldValue = CPUReadHalfWord(address); + break; + case CHEATS_32_BIT_WRITE: + cheatsList[x].oldValue = CPUReadMemory(address); + break; + } + cheatsNumber++; } - cheatsNumber++; - } } void cheatsDelete(int number, bool restore) { - if(number < cheatsNumber && number >= 0) { - int x = number; + if (number < cheatsNumber && number >= 0) { + int x = number; - if(restore) { - switch(cheatsList[x].size) { - case INT_8_BIT_WRITE: - CPUWriteByte(cheatsList[x].address, (u8)cheatsList[x].oldValue); - break; - case INT_16_BIT_WRITE: - CPUWriteHalfWord(cheatsList[x].address, (u16)cheatsList[x].oldValue); - break; - case INT_32_BIT_WRITE: - CPUWriteMemory(cheatsList[x].address, cheatsList[x].oldValue); - break; - case CHEATS_16_BIT_WRITE: - if ((cheatsList[x].address>>24)>=0x08) { - CHEAT_PATCH_ROM_16BIT(cheatsList[x].address, cheatsList[x].oldValue); - } else { - CPUWriteHalfWord(cheatsList[x].address, cheatsList[x].oldValue); + if (restore) { + switch (cheatsList[x].size) { + case INT_8_BIT_WRITE: + CPUWriteByte(cheatsList[x].address, (u8)cheatsList[x].oldValue); + break; + case INT_16_BIT_WRITE: + CPUWriteHalfWord(cheatsList[x].address, (u16)cheatsList[x].oldValue); + break; + case INT_32_BIT_WRITE: + CPUWriteMemory(cheatsList[x].address, cheatsList[x].oldValue); + break; + case CHEATS_16_BIT_WRITE: + if ((cheatsList[x].address >> 24) >= 0x08) { + CHEAT_PATCH_ROM_16BIT(cheatsList[x].address, cheatsList[x].oldValue); + } else { + CPUWriteHalfWord(cheatsList[x].address, cheatsList[x].oldValue); + } + break; + case CHEATS_32_BIT_WRITE: + if ((cheatsList[x].address >> 24) >= 0x08) { + CHEAT_PATCH_ROM_32BIT(cheatsList[x].address, cheatsList[x].oldValue); + } else { + CPUWriteMemory(cheatsList[x].address, cheatsList[x].oldValue); + } + case GSA_16_BIT_ROM_PATCH: + if (cheatsList[x].status & 1) { + cheatsList[x].status &= ~1; + CHEAT_PATCH_ROM_16BIT(cheatsList[x].address, + cheatsList[x].oldValue); + } + break; + case GSA_16_BIT_ROM_PATCH2C: + case GSA_16_BIT_ROM_PATCH2D: + case GSA_16_BIT_ROM_PATCH2E: + case GSA_16_BIT_ROM_PATCH2F: + if (cheatsList[x].status & 1) { + cheatsList[x].status &= ~1; + } + break; + case MASTER_CODE: + mastercode = 0; + break; + } } - break; - case CHEATS_32_BIT_WRITE: - if ((cheatsList[x].address>>24)>=0x08) { - CHEAT_PATCH_ROM_32BIT(cheatsList[x].address, cheatsList[x].oldValue); - } else { - CPUWriteMemory(cheatsList[x].address, cheatsList[x].oldValue); + if ((x + 1) < cheatsNumber) { + memcpy(&cheatsList[x], &cheatsList[x + 1], sizeof(CheatsData) * (cheatsNumber - x - 1)); } - case GSA_16_BIT_ROM_PATCH: - if(cheatsList[x].status & 1) { - cheatsList[x].status &= ~1; - CHEAT_PATCH_ROM_16BIT(cheatsList[x].address, - cheatsList[x].oldValue); - } - break; - case GSA_16_BIT_ROM_PATCH2C: - case GSA_16_BIT_ROM_PATCH2D: - case GSA_16_BIT_ROM_PATCH2E: - case GSA_16_BIT_ROM_PATCH2F: - if(cheatsList[x].status & 1) { - cheatsList[x].status &= ~1; - } - break; - case MASTER_CODE: - mastercode=0; - break; - } + cheatsNumber--; } - if((x+1) < cheatsNumber) { - memcpy(&cheatsList[x], &cheatsList[x+1], sizeof(CheatsData)* - (cheatsNumber-x-1)); - } - cheatsNumber--; - } } void cheatsDeleteAll(bool restore) { - for(int i = cheatsNumber-1; i >= 0; i--) { - cheatsDelete(i, restore); - } + for (int i = cheatsNumber - 1; i >= 0; i--) { + cheatsDelete(i, restore); + } } void cheatsEnable(int i) { - if(i >= 0 && i < cheatsNumber) { - cheatsList[i].enabled = true; - mastercode = 0; - } + if (i >= 0 && i < cheatsNumber) { + cheatsList[i].enabled = true; + mastercode = 0; + } } void cheatsDisable(int i) { - if(i >= 0 && i < cheatsNumber) { - switch(cheatsList[i].size) { - case GSA_16_BIT_ROM_PATCH: - if(cheatsList[i].status & 1) { - cheatsList[i].status &= ~1; - CHEAT_PATCH_ROM_16BIT(cheatsList[i].address, - cheatsList[i].oldValue); - } - break; - case GSA_16_BIT_ROM_PATCH2C: - case GSA_16_BIT_ROM_PATCH2D: - case GSA_16_BIT_ROM_PATCH2E: - case GSA_16_BIT_ROM_PATCH2F: - if(cheatsList[i].status & 1) { - cheatsList[i].status &= ~1; - } - break; - case MASTER_CODE: - mastercode=0; - break; + if (i >= 0 && i < cheatsNumber) { + switch (cheatsList[i].size) { + case GSA_16_BIT_ROM_PATCH: + if (cheatsList[i].status & 1) { + cheatsList[i].status &= ~1; + CHEAT_PATCH_ROM_16BIT(cheatsList[i].address, + cheatsList[i].oldValue); + } + break; + case GSA_16_BIT_ROM_PATCH2C: + case GSA_16_BIT_ROM_PATCH2D: + case GSA_16_BIT_ROM_PATCH2E: + case GSA_16_BIT_ROM_PATCH2F: + if (cheatsList[i].status & 1) { + cheatsList[i].status &= ~1; + } + break; + case MASTER_CODE: + mastercode = 0; + break; + } + cheatsList[i].enabled = false; } - cheatsList[i].enabled = false; - } } -bool cheatsVerifyCheatCode(const char *code, const char *desc) +bool cheatsVerifyCheatCode(const char* code, const char* desc) { - size_t len = strlen(code); - if(len != 11 && len != 13 && len != 17) { - systemMessage(MSG_INVALID_CHEAT_CODE, N_("Invalid cheat code '%s': wrong length"), code); - return false; - } - - if(code[8] != ':') { - systemMessage(MSG_INVALID_CHEAT_CODE, N_("Invalid cheat code '%s': no colon"), code); - return false; - } - - size_t i; - for(i = 0; i < 8; i++) { - if(!CHEAT_IS_HEX(code[i])) { - // wrong cheat - systemMessage(MSG_INVALID_CHEAT_CODE, - N_("Invalid cheat code '%s': first part is not hex"), code); - return false; + size_t len = strlen(code); + if (len != 11 && len != 13 && len != 17) { + systemMessage(MSG_INVALID_CHEAT_CODE, N_("Invalid cheat code '%s': wrong length"), code); + return false; } - } - for(i = 9; i < len; i++) { - if(!CHEAT_IS_HEX(code[i])) { - // wrong cheat - systemMessage(MSG_INVALID_CHEAT_CODE, - N_("Invalid cheat code '%s' second part is not hex"), code); - return false; + + if (code[8] != ':') { + systemMessage(MSG_INVALID_CHEAT_CODE, N_("Invalid cheat code '%s': no colon"), code); + return false; } - } - u32 address = 0; - u32 value = 0; + size_t i; + for (i = 0; i < 8; i++) { + if (!CHEAT_IS_HEX(code[i])) { + // wrong cheat + systemMessage(MSG_INVALID_CHEAT_CODE, + N_("Invalid cheat code '%s': first part is not hex"), code); + return false; + } + } + for (i = 9; i < len; i++) { + if (!CHEAT_IS_HEX(code[i])) { + // wrong cheat + systemMessage(MSG_INVALID_CHEAT_CODE, + N_("Invalid cheat code '%s' second part is not hex"), code); + return false; + } + } - char buffer[10]; - strncpy(buffer, code, 8); - buffer[8] = 0; - sscanf(buffer, "%x", &address); + u32 address = 0; + u32 value = 0; - switch(address >> 24) { - case 0x02: - case 0x03: - case 0x04: - case 0x05: - case 0x06: - case 0x07: - case 0x08: - case 0x09: - case 0x0A: - case 0x0B: - case 0x0C: - case 0x0D: - break; - default: - systemMessage(MSG_INVALID_CHEAT_CODE_ADDRESS, - N_("Invalid cheat code address: %08x"), - address); - return false; - } + char buffer[10]; + strncpy(buffer, code, 8); + buffer[8] = 0; + sscanf(buffer, "%x", &address); - strncpy(buffer, &code[9], 8); - sscanf(buffer, "%x", &value); - int type = 0; - if(len == 13) - type = 114; - if(len == 17) - type = 115; - cheatsAdd(code, desc, address, address, value, type, type); - return true; + switch (address >> 24) { + case 0x02: + case 0x03: + case 0x04: + case 0x05: + case 0x06: + case 0x07: + case 0x08: + case 0x09: + case 0x0A: + case 0x0B: + case 0x0C: + case 0x0D: + break; + default: + systemMessage(MSG_INVALID_CHEAT_CODE_ADDRESS, + N_("Invalid cheat code address: %08x"), + address); + return false; + } + + strncpy(buffer, &code[9], 8); + sscanf(buffer, "%x", &value); + int type = 0; + if (len == 13) + type = 114; + if (len == 17) + type = 115; + cheatsAdd(code, desc, address, address, value, type, type); + return true; } -void cheatsAddCheatCode(const char *code, const char *desc) +void cheatsAddCheatCode(const char* code, const char* desc) { - cheatsVerifyCheatCode(code, desc); + cheatsVerifyCheatCode(code, desc); } u16 cheatsGSAGetDeadface(bool v3) { - for(int i = cheatsNumber-1; i >= 0; i--) - if ((cheatsList[i].address == 0xDEADFACE) && (cheatsList[i].code == (v3 ? 257 : 256))) - return cheatsList[i].value & 0xFFFF; - return 0; + for (int i = cheatsNumber - 1; i >= 0; i--) + if ((cheatsList[i].address == 0xDEADFACE) && (cheatsList[i].code == (v3 ? 257 : 256))) + return cheatsList[i].value & 0xFFFF; + return 0; } -void cheatsGSAChangeEncryption(u16 value, bool v3) { - int i; - u8 *deadtable1, *deadtable2; +void cheatsGSAChangeEncryption(u16 value, bool v3) +{ + int i; + u8 *deadtable1, *deadtable2; - if (v3) { - deadtable1 = (u8*)(&v3_deadtable1); - deadtable2 = (u8*)(&v3_deadtable2); - for (i = 0; i < 4; i++) - seeds_v3[i] = seed_gen(((value & 0xFF00) >> 8), (value & 0xFF) + i, deadtable1, deadtable2); - } - else { - deadtable1 = (u8*)(&v1_deadtable1); - deadtable2 = (u8*)(&v1_deadtable2); - for (i = 0; i < 4; i++){ - seeds_v1[i] = seed_gen(((value & 0xFF00) >> 8), (value & 0xFF) + i, deadtable1, deadtable2); - } - } + if (v3) { + deadtable1 = (u8*)(&v3_deadtable1); + deadtable2 = (u8*)(&v3_deadtable2); + for (i = 0; i < 4; i++) + seeds_v3[i] = seed_gen(((value & 0xFF00) >> 8), (value & 0xFF) + i, deadtable1, deadtable2); + } else { + deadtable1 = (u8*)(&v1_deadtable1); + deadtable2 = (u8*)(&v1_deadtable2); + for (i = 0; i < 4; i++) { + seeds_v1[i] = seed_gen(((value & 0xFF00) >> 8), (value & 0xFF) + i, deadtable1, deadtable2); + } + } } -u32 seed_gen(u8 upper, u8 seed, u8 *deadtable1, u8 *deadtable2) { - int i; - u32 newseed = 0; +u32 seed_gen(u8 upper, u8 seed, u8* deadtable1, u8* deadtable2) +{ + int i; + u32 newseed = 0; - for (i = 0; i < 4; i++) - newseed = ((newseed << 8) | ((deadtable1[(i + upper) & 0xFF] + deadtable2[seed]) & 0xFF)); + for (i = 0; i < 4; i++) + newseed = ((newseed << 8) | ((deadtable1[(i + upper) & 0xFF] + deadtable2[seed]) & 0xFF)); - return newseed; + return newseed; } void cheatsDecryptGSACode(u32& address, u32& value, bool v3) { - u32 rollingseed = 0xC6EF3720; - u32 *seeds = v3 ? seeds_v3 : seeds_v1; + u32 rollingseed = 0xC6EF3720; + u32* seeds = v3 ? seeds_v3 : seeds_v1; - int bitsleft = 32; - while (bitsleft > 0) { - value -= ((((address << 4) + seeds[2]) ^ (address + rollingseed)) ^ - ((address >> 5) + seeds[3])); - address -= ((((value << 4) + seeds[0]) ^ (value + rollingseed)) ^ - ((value >> 5) + seeds[1])); - rollingseed -= 0x9E3779B9; - bitsleft--; - } + int bitsleft = 32; + while (bitsleft > 0) { + value -= ((((address << 4) + seeds[2]) ^ (address + rollingseed)) ^ ((address >> 5) + seeds[3])); + address -= ((((value << 4) + seeds[0]) ^ (value + rollingseed)) ^ ((value >> 5) + seeds[1])); + rollingseed -= 0x9E3779B9; + bitsleft--; + } } -void cheatsAddGSACode(const char *code, const char *desc, bool v3) +void cheatsAddGSACode(const char* code, const char* desc, bool v3) { - if(strlen(code) != 16) { - // wrong cheat - systemMessage(MSG_INVALID_GSA_CODE, - N_("Invalid GSA code. Format is XXXXXXXXYYYYYYYY")); - return; - } - - int i; - for(i = 0; i < 16; i++) { - if(!CHEAT_IS_HEX(code[i])) { - // wrong cheat - systemMessage(MSG_INVALID_GSA_CODE, - N_("Invalid GSA code. Format is XXXXXXXXYYYYYYYY")); - return; + if (strlen(code) != 16) { + // wrong cheat + systemMessage(MSG_INVALID_GSA_CODE, + N_("Invalid GSA code. Format is XXXXXXXXYYYYYYYY")); + return; } - } - char buffer[10]; - strncpy(buffer, code, 8); - buffer[8] = 0; - u32 address; - sscanf(buffer, "%x", &address); - strncpy(buffer, &code[8], 8); - buffer[8] = 0; - u32 value; - sscanf(buffer, "%x", &value); - cheatsGSAChangeEncryption(cheatsGSAGetDeadface (v3), v3); - cheatsDecryptGSACode(address, value, v3); - - if(value == 0x1DC0DE) { - u32 gamecode = READ32LE(((u32 *)&rom[0xac])); - if(gamecode != address) { - char buffer[5]; - *((u32 *)buffer) = address; - buffer[4] = 0; - char buffer2[5]; - *((u32 *)buffer2) = READ32LE(((u32 *)&rom[0xac])); - buffer2[4] = 0; - systemMessage(MSG_GBA_CODE_WARNING, N_("Warning: cheats are for game %s. Current game is %s.\nCodes may not work correctly."), - buffer, buffer2); - } - cheatsAdd(code, desc, address, address & 0x0FFFFFFF, value, v3 ? 257 : 256, - UNKNOWN_CODE); - return; - } - if(isMultilineWithData(cheatsNumber-1)) { - cheatsAdd(code, desc, address, address, value, v3 ? 257 : 256, UNKNOWN_CODE); - return; - } - if(v3) { - int type = ((address >> 25) & 127) | ((address >> 17) & 0x80); - u32 addr = (address & 0x00F00000) << 4 | (address & 0x0003FFFF); - u16 mcode = (address>>24 & 0xFF); - - if ((mcode & 0xFE) == 0xC4) - { - cheatsAdd(code, desc, address, (address & 0x1FFFFFF) | (0x08000000), - value, 257, MASTER_CODE); - mastercode = (address & 0x1FFFFFF) | (0x08000000); - } - else - switch(type) { - case 0x00: - if(address == 0) { - type = (value >> 25) & 127; - addr = (value & 0x00F00000) << 4 | (value & 0x0003FFFF); - switch(type) { - case 0x04: - cheatsAdd(code, desc, address, 0, value & 0x00FFFFFF, 257, GSA_SLOWDOWN); - break; - case 0x08: - cheatsAdd(code, desc, address, 0, addr, 257, GSA_8_BIT_GS_WRITE2); - break; - case 0x09: - cheatsAdd(code, desc, address, 0, addr, 257, GSA_16_BIT_GS_WRITE2); - break; - case 0x0a: - cheatsAdd(code, desc, address, 0, addr, 257, GSA_32_BIT_GS_WRITE2); - break; - case 0x0c: - cheatsAdd(code, desc, address, 0, value & 0x00FFFFFF, 257, GSA_16_BIT_ROM_PATCH2C); - break; - case 0x0d: - cheatsAdd(code, desc, address, 0, value & 0x00FFFFFF, 257, GSA_16_BIT_ROM_PATCH2D); - break; - case 0x0e: - cheatsAdd(code, desc, address, 0, value & 0x00FFFFFF, 257, GSA_16_BIT_ROM_PATCH2E); - break; - case 0x0f: - cheatsAdd(code, desc, address, 0, value & 0x00FFFFFF, 257, GSA_16_BIT_ROM_PATCH2F); - break; - case 0x20: - cheatsAdd(code, desc, address, 0, addr, 257, GSA_CODES_ON); - break; - case 0x40: - cheatsAdd(code, desc, address, 0, addr, 257, GSA_8_BIT_SLIDE); - break; - case 0x41: - cheatsAdd(code, desc, address, 0, addr, 257, GSA_16_BIT_SLIDE); - break; - case 0x42: - cheatsAdd(code, desc, address, 0, addr, 257, GSA_32_BIT_SLIDE); - break; - default: - cheatsAdd(code, desc, address, address, value, 257, UNKNOWN_CODE); - break; + int i; + for (i = 0; i < 16; i++) { + if (!CHEAT_IS_HEX(code[i])) { + // wrong cheat + systemMessage(MSG_INVALID_GSA_CODE, + N_("Invalid GSA code. Format is XXXXXXXXYYYYYYYY")); + return; } - } else - cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_FILL); - break; - case 0x01: - cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_FILL); - break; - case 0x02: - cheatsAdd(code, desc, address, addr, value, 257, INT_32_BIT_WRITE); - break; - case 0x04: - cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_TRUE); - break; - case 0x05: - cheatsAdd(code, desc, address, addr, value, 257, CBA_IF_TRUE); - break; - case 0x06: - cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_TRUE); - break; - case 0x07: - cheatsAdd(code, desc, address, addr, value, 257, GSA_ALWAYS); - break; - case 0x08: - cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_FALSE); - break; - case 0x09: - cheatsAdd(code, desc, address, addr, value, 257, CBA_IF_FALSE); - break; - case 0x0a: - cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_FALSE); - break; - case 0xc: - cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_LOWER_S); - break; - case 0xd: - cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_LOWER_S); - break; - case 0xe: - cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_LOWER_S); - break; - case 0x10: - cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_HIGHER_S); - break; - case 0x11: - cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_HIGHER_S); - break; - case 0x12: - cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_HIGHER_S); - break; - case 0x14: - cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_LOWER_U); - break; - case 0x15: - cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_LOWER_U); - break; - case 0x16: - cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_LOWER_U); - break; - case 0x18: - cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_HIGHER_U); - break; - case 0x19: - cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_HIGHER_U); - break; - case 0x1A: - cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_HIGHER_U); - break; - case 0x1C: - cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_AND); - break; - case 0x1D: - cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_AND); - break; - case 0x1E: - cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_AND); - break; - case 0x20: - cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_POINTER); - break; - case 0x21: - cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_POINTER); - break; - case 0x22: - cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_POINTER); - break; - case 0x24: - cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_TRUE2); - break; - case 0x25: - cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_TRUE2); - break; - case 0x26: - cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_TRUE2); - break; - case 0x27: - cheatsAdd(code, desc, address, addr, value, 257, GSA_ALWAYS2); - break; - case 0x28: - cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_FALSE2); - break; - case 0x29: - cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_FALSE2); - break; - case 0x2a: - cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_FALSE2); - break; - case 0x2c: - cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_LOWER_S2); - break; - case 0x2d: - cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_LOWER_S2); - break; - case 0x2e: - cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_LOWER_S2); - break; - case 0x30: - cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_HIGHER_S2); - break; - case 0x31: - cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_HIGHER_S2); - break; - case 0x32: - cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_HIGHER_S2); - break; - case 0x34: - cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_LOWER_U2); - break; - case 0x35: - cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_LOWER_U2); - break; - case 0x36: - cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_LOWER_U2); - break; - case 0x38: - cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_HIGHER_U2); - break; - case 0x39: - cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_HIGHER_U2); - break; - case 0x3A: - cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_HIGHER_U2); - break; - case 0x3C: - cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_AND2); - break; - case 0x3D: - cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_AND2); - break; - case 0x3E: - cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_AND2); - break; - case 0x40: - cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_ADD); - break; - case 0x41: - cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_ADD); - break; - case 0x42: - cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_ADD); - break; - case 0x44: - cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_TRUE3); - break; - case 0x45: - cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_TRUE3); - break; - case 0x46: - cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_TRUE3); - break; - case 0x47: - cheatsAdd(code, desc, address, addr, value, 257, GSA_ALWAYS3); - break; - case 0x48: - cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_FALSE3); - break; - case 0x49: - cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_FALSE3); - break; - case 0x4a: - cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_FALSE3); - break; - case 0x4c: - cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_LOWER_S3); - break; - case 0x4d: - cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_LOWER_S3); - break; - case 0x4e: - cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_LOWER_S3); - break; - case 0x50: - cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_HIGHER_S3); - break; - case 0x51: - cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_HIGHER_S3); - break; - case 0x52: - cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_HIGHER_S3); - break; - case 0x54: - cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_LOWER_U3); - break; - case 0x55: - cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_LOWER_U3); - break; - case 0x56: - cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_LOWER_U3); - break; - case 0x58: - cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_HIGHER_U3); - break; - case 0x59: - cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_HIGHER_U3); - break; - case 0x5a: - cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_HIGHER_U3); - break; - case 0x5c: - cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_AND3); - break; - case 0x5d: - cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_AND3); - break; - case 0x5e: - cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_AND3); - break; - case 0x63: - cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_WRITE_IOREGS); - break; - case 0xE3: - cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_WRITE_IOREGS); - break; - default: - cheatsAdd(code, desc, address, address, value, 257, UNKNOWN_CODE); - break; } - } else { - int type = (address >> 28) & 15; - switch(type) { - case 0: - case 1: - case 2: - cheatsAdd(code, desc, address, address & 0x0FFFFFFF, value, 256, type); - break; - case 3: - switch ((address >> 0x10) & 0xFF){ - case 0x00: - cheatsAdd(code, desc, address, address & 0x0FFFFFFF, value, 256, GSA_GROUP_WRITE); - break; - case 0x10: - cheatsAdd(code, desc, address, value & 0x0FFFFFFF, address & 0xFF, 256, GSA_32_BIT_ADD ); - break; - case 0x20: - cheatsAdd(code, desc, address, value & 0x0FFFFFFF, (~(address & 0xFF)+1), 256, GSA_32_BIT_ADD ); - break; - case 0x30: - cheatsAdd(code, desc, address, value & 0x0FFFFFFF, address & 0xFFFF, 256, GSA_32_BIT_ADD ); - break; - case 0x40: - cheatsAdd(code, desc, address, value & 0x0FFFFFFF, (~(address & 0xFFFF)+1), 256, GSA_32_BIT_ADD ); - break; - case 0x50: - cheatsAdd(code, desc, address, address & 0x0FFFFFFF, value, 256, GSA_32_BIT_ADD2); - break; - case 0x60: - cheatsAdd(code, desc, address, address & 0x0FFFFFFF, value, 256, GSA_32_BIT_SUB2); - break; - default: - // unsupported code - cheatsAdd(code, desc, address, address, value, 256, - UNKNOWN_CODE); - break; - } - break; - case 6: - address <<= 1; - type = (value >> 24) & 0xFF; - if(type == 0x00) { - cheatsAdd(code, desc, address, address & 0x0FFFFFFF, value & 0xFFFF, 256, - GSA_16_BIT_ROM_PATCH); - break; - } - // unsupported code - cheatsAdd(code, desc, address, address, value, 256, - UNKNOWN_CODE); - break; - case 8: - switch((address >> 20) & 15) { - case 1: - cheatsAdd(code, desc, address, address & 0x0F0FFFFF, value, 256, - GSA_8_BIT_GS_WRITE); - break; - case 2: - cheatsAdd(code, desc, address, address & 0x0F0FFFFF, value, 256, - GSA_16_BIT_GS_WRITE); - break; - case 4: - // This code is buggy : the value is always set to 0 ! - cheatsAdd(code, desc, address, address & 0x0F0FFFFF, 0, 256, - GSA_32_BIT_GS_WRITE); - break; - case 15: - cheatsAdd(code, desc, address, 0, value & 0xFFFF, 256, GSA_SLOWDOWN); - break; - default: - // unsupported code - cheatsAdd(code, desc, address, address, value, 256, - UNKNOWN_CODE); - break; - } - break; - case 0x0d: - if(address != 0xDEADFACE) { - switch((value >> 20) & 0xF) { + + char buffer[10]; + strncpy(buffer, code, 8); + buffer[8] = 0; + u32 address; + sscanf(buffer, "%x", &address); + strncpy(buffer, &code[8], 8); + buffer[8] = 0; + u32 value; + sscanf(buffer, "%x", &value); + cheatsGSAChangeEncryption(cheatsGSAGetDeadface(v3), v3); + cheatsDecryptGSACode(address, value, v3); + + if (value == 0x1DC0DE) { + u32 gamecode = READ32LE(((u32*)&rom[0xac])); + if (gamecode != address) { + char buffer[5]; + *((u32*)buffer) = address; + buffer[4] = 0; + char buffer2[5]; + *((u32*)buffer2) = READ32LE(((u32*)&rom[0xac])); + buffer2[4] = 0; + systemMessage(MSG_GBA_CODE_WARNING, N_("Warning: cheats are for game %s. Current game is %s.\nCodes may not work correctly."), + buffer, buffer2); + } + cheatsAdd(code, desc, address, address & 0x0FFFFFFF, value, v3 ? 257 : 256, + UNKNOWN_CODE); + return; + } + if (isMultilineWithData(cheatsNumber - 1)) { + cheatsAdd(code, desc, address, address, value, v3 ? 257 : 256, UNKNOWN_CODE); + return; + } + if (v3) { + int type = ((address >> 25) & 127) | ((address >> 17) & 0x80); + u32 addr = (address & 0x00F00000) << 4 | (address & 0x0003FFFF); + u16 mcode = (address >> 24 & 0xFF); + + if ((mcode & 0xFE) == 0xC4) { + cheatsAdd(code, desc, address, (address & 0x1FFFFFF) | (0x08000000), + value, 257, MASTER_CODE); + mastercode = (address & 0x1FFFFFF) | (0x08000000); + } else + switch (type) { + case 0x00: + if (address == 0) { + type = (value >> 25) & 127; + addr = (value & 0x00F00000) << 4 | (value & 0x0003FFFF); + switch (type) { + case 0x04: + cheatsAdd(code, desc, address, 0, value & 0x00FFFFFF, 257, GSA_SLOWDOWN); + break; + case 0x08: + cheatsAdd(code, desc, address, 0, addr, 257, GSA_8_BIT_GS_WRITE2); + break; + case 0x09: + cheatsAdd(code, desc, address, 0, addr, 257, GSA_16_BIT_GS_WRITE2); + break; + case 0x0a: + cheatsAdd(code, desc, address, 0, addr, 257, GSA_32_BIT_GS_WRITE2); + break; + case 0x0c: + cheatsAdd(code, desc, address, 0, value & 0x00FFFFFF, 257, GSA_16_BIT_ROM_PATCH2C); + break; + case 0x0d: + cheatsAdd(code, desc, address, 0, value & 0x00FFFFFF, 257, GSA_16_BIT_ROM_PATCH2D); + break; + case 0x0e: + cheatsAdd(code, desc, address, 0, value & 0x00FFFFFF, 257, GSA_16_BIT_ROM_PATCH2E); + break; + case 0x0f: + cheatsAdd(code, desc, address, 0, value & 0x00FFFFFF, 257, GSA_16_BIT_ROM_PATCH2F); + break; + case 0x20: + cheatsAdd(code, desc, address, 0, addr, 257, GSA_CODES_ON); + break; + case 0x40: + cheatsAdd(code, desc, address, 0, addr, 257, GSA_8_BIT_SLIDE); + break; + case 0x41: + cheatsAdd(code, desc, address, 0, addr, 257, GSA_16_BIT_SLIDE); + break; + case 0x42: + cheatsAdd(code, desc, address, 0, addr, 257, GSA_32_BIT_SLIDE); + break; + default: + cheatsAdd(code, desc, address, address, value, 257, UNKNOWN_CODE); + break; + } + } else + cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_FILL); + break; + case 0x01: + cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_FILL); + break; + case 0x02: + cheatsAdd(code, desc, address, addr, value, 257, INT_32_BIT_WRITE); + break; + case 0x04: + cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_TRUE); + break; + case 0x05: + cheatsAdd(code, desc, address, addr, value, 257, CBA_IF_TRUE); + break; + case 0x06: + cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_TRUE); + break; + case 0x07: + cheatsAdd(code, desc, address, addr, value, 257, GSA_ALWAYS); + break; + case 0x08: + cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_FALSE); + break; + case 0x09: + cheatsAdd(code, desc, address, addr, value, 257, CBA_IF_FALSE); + break; + case 0x0a: + cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_FALSE); + break; + case 0xc: + cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_LOWER_S); + break; + case 0xd: + cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_LOWER_S); + break; + case 0xe: + cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_LOWER_S); + break; + case 0x10: + cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_HIGHER_S); + break; + case 0x11: + cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_HIGHER_S); + break; + case 0x12: + cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_HIGHER_S); + break; + case 0x14: + cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_LOWER_U); + break; + case 0x15: + cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_LOWER_U); + break; + case 0x16: + cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_LOWER_U); + break; + case 0x18: + cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_HIGHER_U); + break; + case 0x19: + cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_HIGHER_U); + break; + case 0x1A: + cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_HIGHER_U); + break; + case 0x1C: + cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_AND); + break; + case 0x1D: + cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_AND); + break; + case 0x1E: + cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_AND); + break; + case 0x20: + cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_POINTER); + break; + case 0x21: + cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_POINTER); + break; + case 0x22: + cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_POINTER); + break; + case 0x24: + cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_TRUE2); + break; + case 0x25: + cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_TRUE2); + break; + case 0x26: + cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_TRUE2); + break; + case 0x27: + cheatsAdd(code, desc, address, addr, value, 257, GSA_ALWAYS2); + break; + case 0x28: + cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_FALSE2); + break; + case 0x29: + cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_FALSE2); + break; + case 0x2a: + cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_FALSE2); + break; + case 0x2c: + cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_LOWER_S2); + break; + case 0x2d: + cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_LOWER_S2); + break; + case 0x2e: + cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_LOWER_S2); + break; + case 0x30: + cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_HIGHER_S2); + break; + case 0x31: + cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_HIGHER_S2); + break; + case 0x32: + cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_HIGHER_S2); + break; + case 0x34: + cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_LOWER_U2); + break; + case 0x35: + cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_LOWER_U2); + break; + case 0x36: + cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_LOWER_U2); + break; + case 0x38: + cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_HIGHER_U2); + break; + case 0x39: + cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_HIGHER_U2); + break; + case 0x3A: + cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_HIGHER_U2); + break; + case 0x3C: + cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_AND2); + break; + case 0x3D: + cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_AND2); + break; + case 0x3E: + cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_AND2); + break; + case 0x40: + cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_ADD); + break; + case 0x41: + cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_ADD); + break; + case 0x42: + cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_ADD); + break; + case 0x44: + cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_TRUE3); + break; + case 0x45: + cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_TRUE3); + break; + case 0x46: + cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_TRUE3); + break; + case 0x47: + cheatsAdd(code, desc, address, addr, value, 257, GSA_ALWAYS3); + break; + case 0x48: + cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_FALSE3); + break; + case 0x49: + cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_FALSE3); + break; + case 0x4a: + cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_FALSE3); + break; + case 0x4c: + cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_LOWER_S3); + break; + case 0x4d: + cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_LOWER_S3); + break; + case 0x4e: + cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_LOWER_S3); + break; + case 0x50: + cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_HIGHER_S3); + break; + case 0x51: + cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_HIGHER_S3); + break; + case 0x52: + cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_HIGHER_S3); + break; + case 0x54: + cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_LOWER_U3); + break; + case 0x55: + cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_LOWER_U3); + break; + case 0x56: + cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_LOWER_U3); + break; + case 0x58: + cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_HIGHER_U3); + break; + case 0x59: + cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_HIGHER_U3); + break; + case 0x5a: + cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_HIGHER_U3); + break; + case 0x5c: + cheatsAdd(code, desc, address, addr, value, 257, GSA_8_BIT_IF_AND3); + break; + case 0x5d: + cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_IF_AND3); + break; + case 0x5e: + cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_IF_AND3); + break; + case 0x63: + cheatsAdd(code, desc, address, addr, value, 257, GSA_16_BIT_WRITE_IOREGS); + break; + case 0xE3: + cheatsAdd(code, desc, address, addr, value, 257, GSA_32_BIT_WRITE_IOREGS); + break; + default: + cheatsAdd(code, desc, address, address, value, 257, UNKNOWN_CODE); + break; + } + } else { + int type = (address >> 28) & 15; + switch (type) { case 0: - cheatsAdd(code, desc, address, address & 0x0FFFFFFF, value & 0xFFFF, 256, - CBA_IF_TRUE); - break; case 1: - cheatsAdd(code, desc, address, address & 0x0FFFFFFF, value & 0xFFFF, 256, - CBA_IF_FALSE); - break; case 2: - cheatsAdd(code, desc, address, address & 0x0FFFFFFF, value & 0xFFFF, 256, - GSA_16_BIT_IF_LOWER_OR_EQ_U); - break; + cheatsAdd(code, desc, address, address & 0x0FFFFFFF, value, 256, type); + break; case 3: - cheatsAdd(code, desc, address, address & 0x0FFFFFFF, value & 0xFFFF, 256, - GSA_16_BIT_IF_HIGHER_OR_EQ_U); - break; - default: - // unsupported code - cheatsAdd(code, desc, address, address, value, 256, - UNKNOWN_CODE); - break; - } - } else - cheatsAdd(code, desc, address, address, value, 256, - UNKNOWN_CODE); - break; - case 0x0e: - switch((value >> 28) & 0xF) { - case 0: - cheatsAdd(code, desc, address, value & 0x0FFFFFFF, address & 0xFFFF, 256, - GSA_16_BIT_MIF_TRUE); - break; - case 1: - cheatsAdd(code, desc, address, value & 0x0FFFFFFF, address & 0xFFFF, 256, - GSA_16_BIT_MIF_FALSE); - break; - case 2: - cheatsAdd(code, desc, address, value & 0x0FFFFFFF, address & 0xFFFF, 256, - GSA_16_BIT_MIF_LOWER_OR_EQ_U); - break; - case 3: - cheatsAdd(code, desc, address, value & 0x0FFFFFFF, address & 0xFFFF, 256, - GSA_16_BIT_MIF_HIGHER_OR_EQ_U); - break; - default: - // unsupported code - cheatsAdd(code, desc, address, address, value, 256, - UNKNOWN_CODE); - break; - } - break; - case 0x0f: - cheatsAdd(code, desc, address, (address & 0xFFFFFFF), value, 256, MASTER_CODE); - mastercode = (address & 0xFFFFFFF); - break; - default: - // unsupported code - cheatsAdd(code, desc, address, address, value, 256, + switch ((address >> 0x10) & 0xFF) { + case 0x00: + cheatsAdd(code, desc, address, address & 0x0FFFFFFF, value, 256, GSA_GROUP_WRITE); + break; + case 0x10: + cheatsAdd(code, desc, address, value & 0x0FFFFFFF, address & 0xFF, 256, GSA_32_BIT_ADD); + break; + case 0x20: + cheatsAdd(code, desc, address, value & 0x0FFFFFFF, (~(address & 0xFF) + 1), 256, GSA_32_BIT_ADD); + break; + case 0x30: + cheatsAdd(code, desc, address, value & 0x0FFFFFFF, address & 0xFFFF, 256, GSA_32_BIT_ADD); + break; + case 0x40: + cheatsAdd(code, desc, address, value & 0x0FFFFFFF, (~(address & 0xFFFF) + 1), 256, GSA_32_BIT_ADD); + break; + case 0x50: + cheatsAdd(code, desc, address, address & 0x0FFFFFFF, value, 256, GSA_32_BIT_ADD2); + break; + case 0x60: + cheatsAdd(code, desc, address, address & 0x0FFFFFFF, value, 256, GSA_32_BIT_SUB2); + break; + default: + // unsupported code + cheatsAdd(code, desc, address, address, value, 256, + UNKNOWN_CODE); + break; + } + break; + case 6: + address <<= 1; + type = (value >> 24) & 0xFF; + if (type == 0x00) { + cheatsAdd(code, desc, address, address & 0x0FFFFFFF, value & 0xFFFF, 256, + GSA_16_BIT_ROM_PATCH); + break; + } + // unsupported code + cheatsAdd(code, desc, address, address, value, 256, UNKNOWN_CODE); - break; + break; + case 8: + switch ((address >> 20) & 15) { + case 1: + cheatsAdd(code, desc, address, address & 0x0F0FFFFF, value, 256, + GSA_8_BIT_GS_WRITE); + break; + case 2: + cheatsAdd(code, desc, address, address & 0x0F0FFFFF, value, 256, + GSA_16_BIT_GS_WRITE); + break; + case 4: + // This code is buggy : the value is always set to 0 ! + cheatsAdd(code, desc, address, address & 0x0F0FFFFF, 0, 256, + GSA_32_BIT_GS_WRITE); + break; + case 15: + cheatsAdd(code, desc, address, 0, value & 0xFFFF, 256, GSA_SLOWDOWN); + break; + default: + // unsupported code + cheatsAdd(code, desc, address, address, value, 256, + UNKNOWN_CODE); + break; + } + break; + case 0x0d: + if (address != 0xDEADFACE) { + switch ((value >> 20) & 0xF) { + case 0: + cheatsAdd(code, desc, address, address & 0x0FFFFFFF, value & 0xFFFF, 256, + CBA_IF_TRUE); + break; + case 1: + cheatsAdd(code, desc, address, address & 0x0FFFFFFF, value & 0xFFFF, 256, + CBA_IF_FALSE); + break; + case 2: + cheatsAdd(code, desc, address, address & 0x0FFFFFFF, value & 0xFFFF, 256, + GSA_16_BIT_IF_LOWER_OR_EQ_U); + break; + case 3: + cheatsAdd(code, desc, address, address & 0x0FFFFFFF, value & 0xFFFF, 256, + GSA_16_BIT_IF_HIGHER_OR_EQ_U); + break; + default: + // unsupported code + cheatsAdd(code, desc, address, address, value, 256, + UNKNOWN_CODE); + break; + } + } else + cheatsAdd(code, desc, address, address, value, 256, + UNKNOWN_CODE); + break; + case 0x0e: + switch ((value >> 28) & 0xF) { + case 0: + cheatsAdd(code, desc, address, value & 0x0FFFFFFF, address & 0xFFFF, 256, + GSA_16_BIT_MIF_TRUE); + break; + case 1: + cheatsAdd(code, desc, address, value & 0x0FFFFFFF, address & 0xFFFF, 256, + GSA_16_BIT_MIF_FALSE); + break; + case 2: + cheatsAdd(code, desc, address, value & 0x0FFFFFFF, address & 0xFFFF, 256, + GSA_16_BIT_MIF_LOWER_OR_EQ_U); + break; + case 3: + cheatsAdd(code, desc, address, value & 0x0FFFFFFF, address & 0xFFFF, 256, + GSA_16_BIT_MIF_HIGHER_OR_EQ_U); + break; + default: + // unsupported code + cheatsAdd(code, desc, address, address, value, 256, + UNKNOWN_CODE); + break; + } + break; + case 0x0f: + cheatsAdd(code, desc, address, (address & 0xFFFFFFF), value, 256, MASTER_CODE); + mastercode = (address & 0xFFFFFFF); + break; + default: + // unsupported code + cheatsAdd(code, desc, address, address, value, 256, + UNKNOWN_CODE); + break; + } } - } } -bool cheatsImportGSACodeFile(const char *name, int game, bool v3) +bool cheatsImportGSACodeFile(const char* name, int game, bool v3) { - FILE *f = fopen(name, "rb"); - if(!f) + FILE* f = fopen(name, "rb"); + if (!f) + return false; + + int games = 0; + int len = 0; + fseek(f, 0x1e, SEEK_CUR); + fread(&games, 1, 4, f); + bool found = false; + int g = 0; + while (games > 0) { + if (g == game) { + found = true; + break; + } + fread(&len, 1, 4, f); + fseek(f, len, SEEK_CUR); + int codes = 0; + fread(&codes, 1, 4, f); + while (codes > 0) { + fread(&len, 1, 4, f); + fseek(f, len, SEEK_CUR); + fseek(f, 8, SEEK_CUR); + fread(&len, 1, 4, f); + fseek(f, len * 12, SEEK_CUR); + codes--; + } + games--; + g++; + } + if (found) { + char desc[256]; + char code[17]; + fread(&len, 1, 4, f); + fseek(f, len, SEEK_CUR); + int codes = 0; + fread(&codes, 1, 4, f); + while (codes > 0) { + fread(&len, 1, 4, f); + fread(desc, 1, len, f); + desc[len] = 0; + desc[31] = 0; + fread(&len, 1, 4, f); + fseek(f, len, SEEK_CUR); + fseek(f, 4, SEEK_CUR); + fread(&len, 1, 4, f); + while (len) { + fseek(f, 4, SEEK_CUR); + fread(code, 1, 8, f); + fseek(f, 4, SEEK_CUR); + fread(&code[8], 1, 8, f); + code[16] = 0; + cheatsAddGSACode(code, desc, v3); + len -= 2; + } + codes--; + } + } + fclose(f); return false; - - int games = 0; - int len = 0; - fseek(f, 0x1e, SEEK_CUR); - fread(&games, 1, 4, f); - bool found = false; - int g = 0; - while(games > 0) { - if(g == game) { - found = true; - break; - } - fread(&len, 1, 4, f); - fseek(f,len,SEEK_CUR); - int codes = 0; - fread(&codes, 1, 4, f); - while(codes > 0) { - fread(&len, 1, 4, f); - fseek(f, len, SEEK_CUR); - fseek(f, 8, SEEK_CUR); - fread(&len, 1, 4, f); - fseek(f, len*12, SEEK_CUR); - codes--; - } - games--; - g++; - } - if(found) { - char desc[256]; - char code[17]; - fread(&len, 1, 4, f); - fseek(f, len, SEEK_CUR); - int codes = 0; - fread(&codes, 1, 4, f); - while(codes > 0) { - fread(&len, 1, 4, f); - fread(desc, 1, len, f); - desc[len] =0; - desc[31] = 0; - fread(&len, 1, 4, f); - fseek(f, len, SEEK_CUR); - fseek(f, 4, SEEK_CUR); - fread(&len, 1, 4, f); - while(len) { - fseek(f, 4, SEEK_CUR); - fread(code, 1, 8, f); - fseek(f, 4, SEEK_CUR); - fread(&code[8], 1, 8, f); - code[16] = 0; - cheatsAddGSACode(code, desc, v3); - len -= 2; - } - codes--; - } - } - fclose(f); - return false; } -void cheatsCBAReverseArray(u8 *array, u8 *dest) +void cheatsCBAReverseArray(u8* array, u8* dest) { - dest[0] = array[3]; - dest[1] = array[2]; - dest[2] = array[1]; - dest[3] = array[0]; - dest[4] = array[5]; - dest[5] = array[4]; + dest[0] = array[3]; + dest[1] = array[2]; + dest[2] = array[1]; + dest[3] = array[0]; + dest[4] = array[5]; + dest[5] = array[4]; } -void chatsCBAScramble(u8 *array, int count, u8 b) +void chatsCBAScramble(u8* array, int count, u8 b) { - u8 *x = array + (count >> 3); - u8 *y = array + (b >> 3); - u32 z = *x & (1 << (count & 7)); - u32 x0 = (*x & (~(1 << (count & 7)))); - if (z != 0) - z = 1; - if ((*y & (1 << (b & 7))) != 0) - x0 |= (1 << (count & 7)); - *x = x0; - u32 temp = *y & (~(1 << (b & 7))); - if (z != 0) - temp |= (1 << (b & 7)); - *y = temp; + u8* x = array + (count >> 3); + u8* y = array + (b >> 3); + u32 z = *x & (1 << (count & 7)); + u32 x0 = (*x & (~(1 << (count & 7)))); + if (z != 0) + z = 1; + if ((*y & (1 << (b & 7))) != 0) + x0 |= (1 << (count & 7)); + *x = x0; + u32 temp = *y & (~(1 << (b & 7))); + if (z != 0) + temp |= (1 << (b & 7)); + *y = temp; } -u32 cheatsCBAGetValue(u8 *array) +u32 cheatsCBAGetValue(u8* array) { - return array[0] | array[1]<<8 | array[2] << 16 | array[3]<<24; + return array[0] | array[1] << 8 | array[2] << 16 | array[3] << 24; } -u16 cheatsCBAGetData(u8 *array) +u16 cheatsCBAGetData(u8* array) { - return array[4] | array[5]<<8; + return array[4] | array[5] << 8; } -void cheatsCBAArrayToValue(u8 *array, u8 *dest) +void cheatsCBAArrayToValue(u8* array, u8* dest) { - dest[0] = array[3]; - dest[1] = array[2]; - dest[2] = array[1]; - dest[3] = array[0]; - dest[4] = array[5]; - dest[5] = array[4]; + dest[0] = array[3]; + dest[1] = array[2]; + dest[2] = array[1]; + dest[3] = array[0]; + dest[4] = array[5]; + dest[5] = array[4]; } -void cheatsCBAParseSeedCode(u32 address, u32 value, u32 *array) +void cheatsCBAParseSeedCode(u32 address, u32 value, u32* array) { - array[0] = 1; - array[1] = value & 0xFF; - array[2] = (address >> 0x10) & 0xFF; - array[3] = (value >> 8) & 0xFF; - array[4] = (address >> 0x18) & 0x0F; - array[5] = address & 0xFFFF; - array[6] = address; - array[7] = value; + array[0] = 1; + array[1] = value & 0xFF; + array[2] = (address >> 0x10) & 0xFF; + array[3] = (value >> 8) & 0xFF; + array[4] = (address >> 0x18) & 0x0F; + array[5] = address & 0xFFFF; + array[6] = address; + array[7] = value; } u32 cheatsCBAEncWorker() { - u32 x = (cheatsCBATemporaryValue * 0x41c64e6d) + 0x3039; - u32 y = (x * 0x41c64e6d) + 0x3039; - u32 z = x >> 0x10; - x = ((y >> 0x10) & 0x7fff) << 0x0f; - z = (z << 0x1e) | x; - x = (y * 0x41c64e6d) + 0x3039; - cheatsCBATemporaryValue = x; - return z | ((x >> 0x10) & 0x7fff); + u32 x = (cheatsCBATemporaryValue * 0x41c64e6d) + 0x3039; + u32 y = (x * 0x41c64e6d) + 0x3039; + u32 z = x >> 0x10; + x = ((y >> 0x10) & 0x7fff) << 0x0f; + z = (z << 0x1e) | x; + x = (y * 0x41c64e6d) + 0x3039; + cheatsCBATemporaryValue = x; + return z | ((x >> 0x10) & 0x7fff); } #define ROR(v, s) \ - (((v) >> (s)) | (((v) & ((1 << (s))-1)) << (32 - (s)))) + (((v) >> (s)) | (((v) & ((1 << (s)) - 1)) << (32 - (s)))) u32 cheatsCBACalcIndex(u32 x, u32 y) { - if(y != 0) { - if(y == 1) - x = 0; - else if(x == y) - x = 0; - if(y < 1) - return x; - else if(x < y) - return x; - u32 x0 = 1; + if (y != 0) { + if (y == 1) + x = 0; + else if (x == y) + x = 0; + if (y < 1) + return x; + else if (x < y) + return x; + u32 x0 = 1; - while(y < 0x10000000) { - if(y < x) { - y = y << 4; - x0 = x0 << 4; - } else break; - } + while (y < 0x10000000) { + if (y < x) { + y = y << 4; + x0 = x0 << 4; + } else + break; + } - while(y < 0x80000000) { - if(y < x) { - y = y << 1; - x0 = x0 << 1; - } else break; - } + while (y < 0x80000000) { + if (y < x) { + y = y << 1; + x0 = x0 << 1; + } else + break; + } - loop: - u32 z = 0; - if(x >= y) - x -= y; - if(x >= (y >> 1)) { - x -= (y >> 1); - z |= ROR(x0, 1); - } - if(x >= (y >> 2)) { - x -= (y >> 2); - z |= ROR(x0, 2); - } - if(x >= (y >> 3)) { - x -= (y >> 3); - z |= ROR(x0, 3); - } + loop: + u32 z = 0; + if (x >= y) + x -= y; + if (x >= (y >> 1)) { + x -= (y >> 1); + z |= ROR(x0, 1); + } + if (x >= (y >> 2)) { + x -= (y >> 2); + z |= ROR(x0, 2); + } + if (x >= (y >> 3)) { + x -= (y >> 3); + z |= ROR(x0, 3); + } - u32 temp = x0; + u32 temp = x0; - if(x != 0) { - x0 = x0 >> 4; - if(x0 != 0) { - y = y >> 4; - goto loop; - } - } + if (x != 0) { + x0 = x0 >> 4; + if (x0 != 0) { + y = y >> 4; + goto loop; + } + } - z = z & 0xe0000000; + z = z & 0xe0000000; - if(z != 0) { - if((temp & 7) == 0) + if (z != 0) { + if ((temp & 7) == 0) + return x; + } else + return x; + + if ((z & ROR(temp, 3)) != 0) + x += y >> 3; + if ((z & ROR(temp, 2)) != 0) + x += y >> 2; + if ((z & ROR(temp, 1)) != 0) + x += y >> 1; return x; - } else - return x; - - if((z & ROR(temp, 3)) != 0) - x += y >> 3; - if((z & ROR(temp, 2)) != 0) - x += y >> 2; - if((z & ROR(temp, 1)) != 0) - x += y >> 1; - return x; - } else { - } - // should not happen in the current code - return 0; + } else { + } + // should not happen in the current code + return 0; } -void cheatsCBAUpdateSeedBuffer(u32 a, u8 *buffer, int count) +void cheatsCBAUpdateSeedBuffer(u32 a, u8* buffer, int count) { - int i; - for(i = 0; i < count; i++) - buffer[i] = i; - for(i = 0; (u32)i < a; i++) { - u32 a = cheatsCBACalcIndex(cheatsCBAEncWorker(), count); - u32 b = cheatsCBACalcIndex(cheatsCBAEncWorker(), count); - u32 t = buffer[a]; - buffer[a] = buffer[b]; - buffer[b] = t; - } + int i; + for (i = 0; i < count; i++) + buffer[i] = i; + for (i = 0; (u32)i < a; i++) { + u32 a = cheatsCBACalcIndex(cheatsCBAEncWorker(), count); + u32 b = cheatsCBACalcIndex(cheatsCBAEncWorker(), count); + u32 t = buffer[a]; + buffer[a] = buffer[b]; + buffer[b] = t; + } } -void cheatsCBAChangeEncryption(u32 *seed) +void cheatsCBAChangeEncryption(u32* seed) { - int i; + int i; - cheatsCBATemporaryValue = (seed[1] ^ 0x1111); - cheatsCBAUpdateSeedBuffer(0x50, cheatsCBASeedBuffer, 0x30); - cheatsCBATemporaryValue = 0x4efad1c3; + cheatsCBATemporaryValue = (seed[1] ^ 0x1111); + cheatsCBAUpdateSeedBuffer(0x50, cheatsCBASeedBuffer, 0x30); + cheatsCBATemporaryValue = 0x4efad1c3; - for(i = 0; (u32)i < seed[4]; i++) { - cheatsCBATemporaryValue = cheatsCBAEncWorker(); - } - cheatsCBASeed[2] = cheatsCBAEncWorker(); - cheatsCBASeed[3] = cheatsCBAEncWorker(); + for (i = 0; (u32)i < seed[4]; i++) { + cheatsCBATemporaryValue = cheatsCBAEncWorker(); + } + cheatsCBASeed[2] = cheatsCBAEncWorker(); + cheatsCBASeed[3] = cheatsCBAEncWorker(); - cheatsCBATemporaryValue = seed[3] ^ 0xf254; + cheatsCBATemporaryValue = seed[3] ^ 0xf254; - for(i = 0; (u32)i < seed[3]; i++) { - cheatsCBATemporaryValue = cheatsCBAEncWorker(); - } + for (i = 0; (u32)i < seed[3]; i++) { + cheatsCBATemporaryValue = cheatsCBAEncWorker(); + } - cheatsCBASeed[0] = cheatsCBAEncWorker(); - cheatsCBASeed[1] = cheatsCBAEncWorker(); + cheatsCBASeed[0] = cheatsCBAEncWorker(); + cheatsCBASeed[1] = cheatsCBAEncWorker(); - *((u32 *)&cheatsCBACurrentSeed[0]) = seed[6]; - *((u32 *)&cheatsCBACurrentSeed[4]) = seed[7]; - *((u32 *)&cheatsCBACurrentSeed[8]) = 0; + *((u32*)&cheatsCBACurrentSeed[0]) = seed[6]; + *((u32*)&cheatsCBACurrentSeed[4]) = seed[7]; + *((u32*)&cheatsCBACurrentSeed[8]) = 0; } u16 cheatsCBAGenValue(u32 x, u32 y, u32 z) { - y <<= 0x10; - z <<= 0x10; - x <<= 0x18; - u32 x0 = (int)y >> 0x10; - z = (int)z >> 0x10; - x = (int)x >> 0x10; - for(int i = 0; i < 8; i++) { - u32 temp = z ^ x; - if ((int)temp >= 0) { - temp = z << 0x11; + y <<= 0x10; + z <<= 0x10; + x <<= 0x18; + u32 x0 = (int)y >> 0x10; + z = (int)z >> 0x10; + x = (int)x >> 0x10; + for (int i = 0; i < 8; i++) { + u32 temp = z ^ x; + if ((int)temp >= 0) { + temp = z << 0x11; + } else { + temp = z << 0x01; + temp ^= x0; + temp = temp << 0x10; + } + z = (int)temp >> 0x10; + temp = x << 0x11; + x = (int)temp >> 0x10; } - else { - temp = z << 0x01; - temp ^= x0; - temp = temp << 0x10; - } - z = (int)temp >> 0x10; - temp = x << 0x11; - x = (int)temp >> 0x10; - } - return z & 0xffff; + return z & 0xffff; } -void cheatsCBAGenTable() { - for (int i = 0; i < 0x100; i++) { - cheatsCBATable[i] = cheatsCBAGenValue(i, 0x1021, 0); - } - cheatsCBATableGenerated = true; -} - -u16 cheatsCBACalcCRC(u8 *rom, int count) +void cheatsCBAGenTable() { - u32 crc = 0xffffffff; - - if (count & 3) { - // 0x08000EAE - } else { - count = (count >> 2) - 1; - if(count != -1) { - while(count != -1) { - crc = (((crc << 0x08) ^ cheatsCBATable[(((u32)crc << 0x10) >> 0x18) - ^ *rom++]) << 0x10) >> 0x10; - crc = (((crc << 0x08) ^ cheatsCBATable[(((u32)crc << 0x10) >> 0x18) - ^ *rom++]) << 0x10) >> 0x10; - crc = (((crc << 0x08) ^ cheatsCBATable[(((u32)crc << 0x10) >> 0x18) - ^ *rom++]) << 0x10) >> 0x10; - crc = (((crc << 0x08) ^ cheatsCBATable[(((u32)crc << 0x10) >> 0x18) - ^ *rom++]) << 0x10) >> 0x10; - count--; - } + for (int i = 0; i < 0x100; i++) { + cheatsCBATable[i] = cheatsCBAGenValue(i, 0x1021, 0); } - } - return crc & 0xffff; + cheatsCBATableGenerated = true; } -void cheatsCBADecrypt(u8 *decrypt) +u16 cheatsCBACalcCRC(u8* rom, int count) { - u8 buffer[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - u8 *array = &buffer[1]; + u32 crc = 0xffffffff; - cheatsCBAReverseArray(decrypt, array); + if (count & 3) { + // 0x08000EAE + } else { + count = (count >> 2) - 1; + if (count != -1) { + while (count != -1) { + crc = (((crc << 0x08) ^ cheatsCBATable[(((u32)crc << 0x10) >> 0x18) + ^ *rom++]) + << 0x10) + >> 0x10; + crc = (((crc << 0x08) ^ cheatsCBATable[(((u32)crc << 0x10) >> 0x18) + ^ *rom++]) + << 0x10) + >> 0x10; + crc = (((crc << 0x08) ^ cheatsCBATable[(((u32)crc << 0x10) >> 0x18) + ^ *rom++]) + << 0x10) + >> 0x10; + crc = (((crc << 0x08) ^ cheatsCBATable[(((u32)crc << 0x10) >> 0x18) + ^ *rom++]) + << 0x10) + >> 0x10; + count--; + } + } + } + return crc & 0xffff; +} - for(int count = 0x2f; count >= 0; count--) { - chatsCBAScramble(array, count, cheatsCBASeedBuffer[count]); - } - cheatsCBAArrayToValue(array, decrypt); - *((u32 *)decrypt) = cheatsCBAGetValue(decrypt) ^ - cheatsCBASeed[0]; - *((u16 *)(decrypt+4)) = (cheatsCBAGetData(decrypt) ^ - cheatsCBASeed[1]) & 0xffff; +void cheatsCBADecrypt(u8* decrypt) +{ + u8 buffer[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + u8* array = &buffer[1]; - cheatsCBAReverseArray(decrypt, array); + cheatsCBAReverseArray(decrypt, array); - u32 cs = cheatsCBAGetValue(cheatsCBACurrentSeed); - for(int i = 0; i <= 4; i++) { - array[i] = ((cs >> 8) ^ array[i+1]) ^ array[i] ; - } + for (int count = 0x2f; count >= 0; count--) { + chatsCBAScramble(array, count, cheatsCBASeedBuffer[count]); + } + cheatsCBAArrayToValue(array, decrypt); + *((u32*)decrypt) = cheatsCBAGetValue(decrypt) ^ cheatsCBASeed[0]; + *((u16*)(decrypt + 4)) = (cheatsCBAGetData(decrypt) ^ cheatsCBASeed[1]) & 0xffff; - array[5] = (cs >> 8) ^ array[5]; + cheatsCBAReverseArray(decrypt, array); - for(int j = 5; j >=0; j--) { - array[j] = (cs ^ array[j-1]) ^ array[j]; - } + u32 cs = cheatsCBAGetValue(cheatsCBACurrentSeed); + for (int i = 0; i <= 4; i++) { + array[i] = ((cs >> 8) ^ array[i + 1]) ^ array[i]; + } - cheatsCBAArrayToValue(array, decrypt); + array[5] = (cs >> 8) ^ array[5]; - *((u32 *)decrypt) = cheatsCBAGetValue(decrypt) - ^ cheatsCBASeed[2]; - *((u16 *)(decrypt+4)) = (cheatsCBAGetData(decrypt) - ^ cheatsCBASeed[3]) & 0xffff; + for (int j = 5; j >= 0; j--) { + array[j] = (cs ^ array[j - 1]) ^ array[j]; + } + + cheatsCBAArrayToValue(array, decrypt); + + *((u32*)decrypt) = cheatsCBAGetValue(decrypt) + ^ cheatsCBASeed[2]; + *((u16*)(decrypt + 4)) = (cheatsCBAGetData(decrypt) + ^ cheatsCBASeed[3]) + & 0xffff; } int cheatsCBAGetCount() { - int count = 0; - for(int i = 0; i < cheatsNumber; i++) { - if(cheatsList[i].code == 512) - count++; - } - return count; + int count = 0; + for (int i = 0; i < cheatsNumber; i++) { + if (cheatsList[i].code == 512) + count++; + } + return count; } bool cheatsCBAShouldDecrypt() { - for(int i = 0; i < cheatsNumber; i++) { - if(cheatsList[i].code == 512) { - return (cheatsList[i].codestring[0] == '9'); + for (int i = 0; i < cheatsNumber; i++) { + if (cheatsList[i].code == 512) { + return (cheatsList[i].codestring[0] == '9'); + } } - } - return false; + return false; } -void cheatsAddCBACode(const char *code, const char *desc) +void cheatsAddCBACode(const char* code, const char* desc) { - if(strlen(code) != 13) { - // wrong cheat - systemMessage(MSG_INVALID_CBA_CODE, - N_("Invalid CBA code. Format is XXXXXXXX YYYY.")); - return; - } - - int i; - for(i = 0; i < 8; i++) { - if(!CHEAT_IS_HEX(code[i])) { - // wrong cheat - systemMessage(MSG_INVALID_CBA_CODE, - N_("Invalid CBA code. Format is XXXXXXXX YYYY.")); - return; - } - } - - if(code[8] != ' ') { - systemMessage(MSG_INVALID_CBA_CODE, - N_("Invalid CBA code. Format is XXXXXXXX YYYY.")); - return; - } - - for(i = 9; i < 13; i++) { - if(!CHEAT_IS_HEX(code[i])) { - // wrong cheat - systemMessage(MSG_INVALID_CBA_CODE, - N_("Invalid CBA code. Format is XXXXXXXX YYYY.")); - return; - } - } - - char buffer[10]; - strncpy(buffer, code, 8); - buffer[8] = 0; - u32 address; - sscanf(buffer, "%x", &address); - strncpy(buffer, &code[9], 4); - buffer[4] = 0; - u32 value; - sscanf(buffer, "%x", &value); - - u8 array[8] = { - address & 255, - (address >> 8) & 255, - (address >> 16) & 255, - (address >> 24) & 255, - (value & 255), - (value >> 8) & 255, - 0, - 0 - }; - - if(cheatsCBAGetCount() == 0 && - (address >> 28) == 9) { - u32 seed[8]; - cheatsCBAParseSeedCode(address, value, seed); - cheatsCBAChangeEncryption(seed); - cheatsAdd(code, desc, address, address & 0x0FFFFFFF, value, 512, UNKNOWN_CODE); - } else { - if(cheatsCBAShouldDecrypt()) - cheatsCBADecrypt(array); - - address = READ32LE(((u32 *)array)); - value = READ16LE(((u16 *)&array[4])); - - int type = (address >> 28) & 15; - - if(isMultilineWithData(cheatsNumber-1) || (super>0)) { - cheatsAdd(code, desc, address, address, value, 512, UNKNOWN_CODE); - if (super>0) - super-= 1; - return; + if (strlen(code) != 13) { + // wrong cheat + systemMessage(MSG_INVALID_CBA_CODE, + N_("Invalid CBA code. Format is XXXXXXXX YYYY.")); + return; } - switch(type) { - case 0x00: - { - if(!cheatsCBATableGenerated) - cheatsCBAGenTable(); - u32 crc = cheatsCBACalcCRC(rom, 0x10000); - if(crc != address) { - systemMessage(MSG_CBA_CODE_WARNING, - N_("Warning: Codes seem to be for a different game.\nCodes may not work correctly.")); + int i; + for (i = 0; i < 8; i++) { + if (!CHEAT_IS_HEX(code[i])) { + // wrong cheat + systemMessage(MSG_INVALID_CBA_CODE, + N_("Invalid CBA code. Format is XXXXXXXX YYYY.")); + return; + } + } + + if (code[8] != ' ') { + systemMessage(MSG_INVALID_CBA_CODE, + N_("Invalid CBA code. Format is XXXXXXXX YYYY.")); + return; + } + + for (i = 9; i < 13; i++) { + if (!CHEAT_IS_HEX(code[i])) { + // wrong cheat + systemMessage(MSG_INVALID_CBA_CODE, + N_("Invalid CBA code. Format is XXXXXXXX YYYY.")); + return; + } + } + + char buffer[10]; + strncpy(buffer, code, 8); + buffer[8] = 0; + u32 address; + sscanf(buffer, "%x", &address); + strncpy(buffer, &code[9], 4); + buffer[4] = 0; + u32 value; + sscanf(buffer, "%x", &value); + + u8 array[8] = { + address & 255, + (address >> 8) & 255, + (address >> 16) & 255, + (address >> 24) & 255, + (value & 255), + (value >> 8) & 255, + 0, + 0 + }; + + if (cheatsCBAGetCount() == 0 && (address >> 28) == 9) { + u32 seed[8]; + cheatsCBAParseSeedCode(address, value, seed); + cheatsCBAChangeEncryption(seed); + cheatsAdd(code, desc, address, address & 0x0FFFFFFF, value, 512, UNKNOWN_CODE); + } else { + if (cheatsCBAShouldDecrypt()) + cheatsCBADecrypt(array); + + address = READ32LE(((u32*)array)); + value = READ16LE(((u16*)&array[4])); + + int type = (address >> 28) & 15; + + if (isMultilineWithData(cheatsNumber - 1) || (super > 0)) { + cheatsAdd(code, desc, address, address, value, 512, UNKNOWN_CODE); + if (super > 0) + super -= 1; + return; + } + + switch (type) { + case 0x00: { + if (!cheatsCBATableGenerated) + cheatsCBAGenTable(); + u32 crc = cheatsCBACalcCRC(rom, 0x10000); + if (crc != address) { + systemMessage(MSG_CBA_CODE_WARNING, + N_("Warning: Codes seem to be for a different game.\nCodes may not work correctly.")); + } + cheatsAdd(code, desc, address, address & 0x0FFFFFFF, value, 512, + UNKNOWN_CODE); + } break; + case 0x01: + cheatsAdd(code, desc, address, (address & 0x1FFFFFF) | 0x08000000, value, 512, MASTER_CODE); + mastercode = (address & 0x1FFFFFF) | 0x08000000; + break; + case 0x02: + cheatsAdd(code, desc, address, address & 0x0FFFFFFE, value, 512, + CBA_OR); + break; + case 0x03: + cheatsAdd(code, desc, address, address & 0x0FFFFFFF, value, 512, + INT_8_BIT_WRITE); + break; + case 0x04: + cheatsAdd(code, desc, address, address & 0x0FFFFFFE, value, 512, + CBA_SLIDE_CODE); + break; + case 0x05: + cheatsAdd(code, desc, address, address & 0x0FFFFFFE, value, 512, + CBA_SUPER); + super = getCodeLength(cheatsNumber - 1); + break; + case 0x06: + cheatsAdd(code, desc, address, address & 0x0FFFFFFE, value, 512, + CBA_AND); + break; + case 0x07: + cheatsAdd(code, desc, address, address & 0x0FFFFFFE, value, 512, + CBA_IF_TRUE); + break; + case 0x08: + cheatsAdd(code, desc, address, address & 0x0FFFFFFE, value, 512, + INT_16_BIT_WRITE); + break; + case 0x0a: + cheatsAdd(code, desc, address, address & 0x0FFFFFFE, value, 512, + CBA_IF_FALSE); + break; + case 0x0b: + cheatsAdd(code, desc, address, address & 0x0FFFFFFE, value, 512, + CBA_GT); + break; + case 0x0c: + cheatsAdd(code, desc, address, address & 0x0FFFFFFE, value, 512, + CBA_LT); + break; + case 0x0d: + if ((address & 0xF0) < 0x30) + cheatsAdd(code, desc, address, address & 0xF0, value, 512, + CBA_IF_KEYS_PRESSED); + break; + case 0x0e: + cheatsAdd(code, desc, address, address & 0x0FFFFFFF, value & 0x8000 ? value | 0xFFFF0000 : value, 512, + CBA_ADD); + break; + case 0x0f: + cheatsAdd(code, desc, address, address & 0x0FFFFFFE, value, 512, + GSA_16_BIT_IF_AND); + break; + default: + // unsupported code + cheatsAdd(code, desc, address, address & 0xFFFFFFFF, value, 512, + UNKNOWN_CODE); + break; } - cheatsAdd(code, desc, address, address & 0x0FFFFFFF, value, 512, - UNKNOWN_CODE); - } - break; - case 0x01: - cheatsAdd(code, desc, address, (address & 0x1FFFFFF) | 0x08000000, value, 512, MASTER_CODE); - mastercode = (address & 0x1FFFFFF) | 0x08000000; - break; - case 0x02: - cheatsAdd(code, desc, address, address & 0x0FFFFFFE, value, 512, - CBA_OR); - break; - case 0x03: - cheatsAdd(code, desc, address, address & 0x0FFFFFFF, value, 512, - INT_8_BIT_WRITE); - break; - case 0x04: - cheatsAdd(code, desc, address, address & 0x0FFFFFFE, value, 512, - CBA_SLIDE_CODE); - break; - case 0x05: - cheatsAdd(code, desc, address, address & 0x0FFFFFFE, value, 512, - CBA_SUPER); - super = getCodeLength(cheatsNumber-1); - break; - case 0x06: - cheatsAdd(code, desc, address, address & 0x0FFFFFFE, value, 512, - CBA_AND); - break; - case 0x07: - cheatsAdd(code, desc, address, address & 0x0FFFFFFE, value, 512, - CBA_IF_TRUE); - break; - case 0x08: - cheatsAdd(code, desc, address, address & 0x0FFFFFFE, value, 512, - INT_16_BIT_WRITE); - break; - case 0x0a: - cheatsAdd(code, desc, address, address & 0x0FFFFFFE, value, 512, - CBA_IF_FALSE); - break; - case 0x0b: - cheatsAdd(code, desc, address, address & 0x0FFFFFFE, value, 512, - CBA_GT); - break; - case 0x0c: - cheatsAdd(code, desc, address, address & 0x0FFFFFFE, value, 512, - CBA_LT); - break; - case 0x0d: - if ((address & 0xF0)<0x30) - cheatsAdd(code, desc, address, address & 0xF0, value, 512, - CBA_IF_KEYS_PRESSED); - break; - case 0x0e: - cheatsAdd(code, desc, address, address & 0x0FFFFFFF, value & 0x8000 ? value | 0xFFFF0000 : value, 512, - CBA_ADD); - break; - case 0x0f: - cheatsAdd(code, desc, address, address & 0x0FFFFFFE, value, 512, - GSA_16_BIT_IF_AND); - break; - default: - // unsupported code - cheatsAdd(code, desc, address, address & 0xFFFFFFFF, value, 512, - UNKNOWN_CODE); - break; } - } } #ifndef __LIBRETRO__ void cheatsSaveGame(gzFile file) { - utilWriteInt(file, cheatsNumber); + utilWriteInt(file, cheatsNumber); - utilGzWrite(file, cheatsList, sizeof(cheatsList)); + utilGzWrite(file, cheatsList, sizeof(cheatsList)); } void cheatsReadGame(gzFile file, int version) { - cheatsNumber = 0; + cheatsNumber = 0; - cheatsNumber = utilReadInt(file); + cheatsNumber = utilReadInt(file); - if (version > 8) - utilGzRead(file, cheatsList, sizeof(cheatsList)); + if (version > 8) + utilGzRead(file, cheatsList, sizeof(cheatsList)); + bool firstCodeBreaker = true; - bool firstCodeBreaker = true; + for (int i = 0; i < cheatsNumber; i++) { + if (version < 9) { + cheatsList[i].code = utilReadInt(file); + cheatsList[i].size = utilReadInt(file); + cheatsList[i].status = utilReadInt(file); + cheatsList[i].enabled = utilReadInt(file) ? true : false; + utilGzRead(file, &cheatsList[i].address, sizeof(u32)); + cheatsList[i].rawaddress = cheatsList[i].address; + utilGzRead(file, &cheatsList[i].value, sizeof(u32)); + utilGzRead(file, &cheatsList[i].oldValue, sizeof(u32)); + utilGzRead(file, &cheatsList[i].codestring, 20 * sizeof(char)); + utilGzRead(file, &cheatsList[i].desc, 32 * sizeof(char)); + } - for(int i = 0; i < cheatsNumber; i++) { - if (version <9) - { - cheatsList[i].code = utilReadInt(file); - cheatsList[i].size = utilReadInt(file); - cheatsList[i].status = utilReadInt(file); - cheatsList[i].enabled = utilReadInt(file) ? true : false; - utilGzRead(file, &cheatsList[i].address, sizeof(u32)); - cheatsList[i].rawaddress = cheatsList[i].address; - utilGzRead(file, &cheatsList[i].value, sizeof(u32)); - utilGzRead(file, &cheatsList[i].oldValue, sizeof(u32)); - utilGzRead(file, &cheatsList[i].codestring, 20*sizeof(char)); - utilGzRead(file, &cheatsList[i].desc, 32*sizeof(char)); + cheatsList[i].status = 0; + if (!cheatsList[i].codestring[0]) { + switch (cheatsList[i].size) { + case 0: + sprintf(cheatsList[i].codestring, "%08x:%02x", cheatsList[i].address, + cheatsList[i].value); + break; + case 1: + sprintf(cheatsList[i].codestring, "%08x:%04x", cheatsList[i].address, + cheatsList[i].value); + break; + case 2: + sprintf(cheatsList[i].codestring, "%08x:%08x", cheatsList[i].address, + cheatsList[i].value); + break; + } + } + + if (cheatsList[i].enabled) { + cheatsEnable(i); + } + + if (cheatsList[i].code == 512 && firstCodeBreaker) { + firstCodeBreaker = false; + char buffer[10]; + strncpy(buffer, cheatsList[i].codestring, 8); + buffer[8] = 0; + u32 address; + sscanf(buffer, "%x", &address); + if ((address >> 28) == 9) { + strncpy(buffer, &cheatsList[i].codestring[9], 4); + buffer[4] = 0; + u32 value; + sscanf(buffer, "%x", &value); + + u32 seed[8]; + cheatsCBAParseSeedCode(address, value, seed); + cheatsCBAChangeEncryption(seed); + } + } } - - cheatsList[i].status = 0; - if(!cheatsList[i].codestring[0]) { - switch(cheatsList[i].size) { - case 0: - sprintf(cheatsList[i].codestring, "%08x:%02x", cheatsList[i].address, - cheatsList[i].value); - break; - case 1: - sprintf(cheatsList[i].codestring, "%08x:%04x", cheatsList[i].address, - cheatsList[i].value); - break; - case 2: - sprintf(cheatsList[i].codestring, "%08x:%08x", cheatsList[i].address, - cheatsList[i].value); - break; - } - } - - if(cheatsList[i].enabled) { - cheatsEnable(i); - } - - if(cheatsList[i].code == 512 && firstCodeBreaker) { - firstCodeBreaker = false; - char buffer[10]; - strncpy(buffer, cheatsList[i].codestring, 8); - buffer[8] = 0; - u32 address; - sscanf(buffer, "%x", &address); - if((address >> 28) == 9) { - strncpy(buffer, &cheatsList[i].codestring[9], 4); - buffer[4] = 0; - u32 value; - sscanf(buffer, "%x", &value); - - u32 seed[8]; - cheatsCBAParseSeedCode(address, value, seed); - cheatsCBAChangeEncryption(seed); - } - } - } } - // skip the cheat list data -void cheatsReadGameSkip( gzFile file, int version ) +void cheatsReadGameSkip(gzFile file, int version) { - int nCheats = 0; - nCheats = utilReadInt( file ); + int nCheats = 0; + nCheats = utilReadInt(file); - if( version >= 9 ) { - utilGzSeek( file, sizeof( cheatsList ), SEEK_CUR ); - } - - for( int i = 0; i < nCheats; i++ ) { - if( version < 9 ) { - utilGzSeek( file, ( 7 * sizeof(int) ) + ( 52 * sizeof(char) ), SEEK_CUR ); + if (version >= 9) { + utilGzSeek(file, sizeof(cheatsList), SEEK_CUR); + } + + for (int i = 0; i < nCheats; i++) { + if (version < 9) { + utilGzSeek(file, (7 * sizeof(int)) + (52 * sizeof(char)), SEEK_CUR); + } } - } } - -void cheatsSaveCheatList(const char *file) +void cheatsSaveCheatList(const char* file) { - if(cheatsNumber == 0) - return; - FILE *f = fopen(file, "wb"); - if(f == NULL) - return; - int version = 1; - fwrite(&version, 1, sizeof(version), f); - int type = 1; - fwrite(&type, 1, sizeof(type), f); - fwrite(&cheatsNumber, 1, sizeof(cheatsNumber), f); - fwrite(cheatsList, 1, sizeof(CheatsData) * cheatsNumber, f); - fclose(f); + if (cheatsNumber == 0) + return; + FILE* f = fopen(file, "wb"); + if (f == NULL) + return; + int version = 1; + fwrite(&version, 1, sizeof(version), f); + int type = 1; + fwrite(&type, 1, sizeof(type), f); + fwrite(&cheatsNumber, 1, sizeof(cheatsNumber), f); + fwrite(cheatsList, 1, sizeof(CheatsData) * cheatsNumber, f); + fclose(f); } -bool cheatsLoadCheatList(const char *file) +bool cheatsLoadCheatList(const char* file) { - int count = 0; + int count = 0; - FILE *f = fopen(file, "rb"); + FILE* f = fopen(file, "rb"); - if(f == NULL) - return false; + if (f == NULL) + return false; - int version = 0; + int version = 0; - if(fread(&version, 1, sizeof(version), f) != sizeof(version)) { - fclose(f); - return false; - } - - if(version != 1) { - systemMessage(MSG_UNSUPPORTED_CHEAT_LIST_VERSION, - N_("Unsupported cheat list version %d"), version); - fclose(f); - return false; - } - - int type = 0; - if(fread(&type, 1, sizeof(type), f) != sizeof(type)) { - fclose(f); - return false; - } - - - if((type != 0) && (type != 1)) { - systemMessage(MSG_UNSUPPORTED_CHEAT_LIST_TYPE, - N_("Unsupported cheat list type %d"), type); - fclose(f); - return false; - } - - if(fread(&count, 1, sizeof(count), f) != sizeof(count)) { - fclose(f); - return false; - } - if (type == 1) - { - if(fread(cheatsList, 1, sizeof(cheatsList), f) > sizeof(cheatsList)) { - fclose(f); - return false; - } - } - else if (type == 0) - { - for(int i = 0; i < count; i++) { - fread(&cheatsList[i].code, 1, sizeof(int),f); - fread(&cheatsList[i].size, 1, sizeof(int),f); - fread(&cheatsList[i].status, 1, sizeof(int),f); - fread(&cheatsList[i].enabled, 1, sizeof(int),f); - cheatsList[i].enabled = cheatsList[i].enabled ? true : false; - fread(&cheatsList[i].address, 1, sizeof(u32),f); - cheatsList[i].rawaddress = cheatsList[i].address; - fread(&cheatsList[i].value, 1, sizeof(u32),f); - fread(&cheatsList[i].oldValue, 1, sizeof(u32),f); - fread(&cheatsList[i].codestring, 1, 20*sizeof(char),f); - if(fread(&cheatsList[i].desc, 1, 32*sizeof(char),f) != 32*sizeof(char)) { + if (fread(&version, 1, sizeof(version), f) != sizeof(version)) { fclose(f); return false; - } - } - } - - bool firstCodeBreaker = true; - - for(int i = 0; i < count; i++) { - cheatsList[i].status = 0; // remove old status as it is not used - if(!cheatsList[i].codestring[0]) { - switch(cheatsList[i].size) { - case 0: - sprintf(cheatsList[i].codestring, "%08x:%02x", cheatsList[i].address, - cheatsList[i].value); - break; - case 1: - sprintf(cheatsList[i].codestring, "%08x:%04x", cheatsList[i].address, - cheatsList[i].value); - break; - case 2: - sprintf(cheatsList[i].codestring, "%08x:%08x", cheatsList[i].address, - cheatsList[i].value); - break; - } } - if(cheatsList[i].code == 512 && firstCodeBreaker) { - firstCodeBreaker = false; - char buffer[10]; - strncpy(buffer, cheatsList[i].codestring, 8); - buffer[8] = 0; - u32 address; - sscanf(buffer, "%x", &address); - if((address >> 28) == 9) { - strncpy(buffer, &cheatsList[i].codestring[9], 4); - buffer[4] = 0; - u32 value; - sscanf(buffer, "%x", &value); - - u32 seed[8]; - cheatsCBAParseSeedCode(address, value, seed); - cheatsCBAChangeEncryption(seed); - } + if (version != 1) { + systemMessage(MSG_UNSUPPORTED_CHEAT_LIST_VERSION, + N_("Unsupported cheat list version %d"), version); + fclose(f); + return false; } - } - cheatsNumber = count; - fclose(f); - return true; + + int type = 0; + if (fread(&type, 1, sizeof(type), f) != sizeof(type)) { + fclose(f); + return false; + } + + if ((type != 0) && (type != 1)) { + systemMessage(MSG_UNSUPPORTED_CHEAT_LIST_TYPE, + N_("Unsupported cheat list type %d"), type); + fclose(f); + return false; + } + + if (fread(&count, 1, sizeof(count), f) != sizeof(count)) { + fclose(f); + return false; + } + if (type == 1) { + if (fread(cheatsList, 1, sizeof(cheatsList), f) > sizeof(cheatsList)) { + fclose(f); + return false; + } + } else if (type == 0) { + for (int i = 0; i < count; i++) { + fread(&cheatsList[i].code, 1, sizeof(int), f); + fread(&cheatsList[i].size, 1, sizeof(int), f); + fread(&cheatsList[i].status, 1, sizeof(int), f); + fread(&cheatsList[i].enabled, 1, sizeof(int), f); + cheatsList[i].enabled = cheatsList[i].enabled ? true : false; + fread(&cheatsList[i].address, 1, sizeof(u32), f); + cheatsList[i].rawaddress = cheatsList[i].address; + fread(&cheatsList[i].value, 1, sizeof(u32), f); + fread(&cheatsList[i].oldValue, 1, sizeof(u32), f); + fread(&cheatsList[i].codestring, 1, 20 * sizeof(char), f); + if (fread(&cheatsList[i].desc, 1, 32 * sizeof(char), f) != 32 * sizeof(char)) { + fclose(f); + return false; + } + } + } + + bool firstCodeBreaker = true; + + for (int i = 0; i < count; i++) { + cheatsList[i].status = 0; // remove old status as it is not used + if (!cheatsList[i].codestring[0]) { + switch (cheatsList[i].size) { + case 0: + sprintf(cheatsList[i].codestring, "%08x:%02x", cheatsList[i].address, + cheatsList[i].value); + break; + case 1: + sprintf(cheatsList[i].codestring, "%08x:%04x", cheatsList[i].address, + cheatsList[i].value); + break; + case 2: + sprintf(cheatsList[i].codestring, "%08x:%08x", cheatsList[i].address, + cheatsList[i].value); + break; + } + } + + if (cheatsList[i].code == 512 && firstCodeBreaker) { + firstCodeBreaker = false; + char buffer[10]; + strncpy(buffer, cheatsList[i].codestring, 8); + buffer[8] = 0; + u32 address; + sscanf(buffer, "%x", &address); + if ((address >> 28) == 9) { + strncpy(buffer, &cheatsList[i].codestring[9], 4); + buffer[4] = 0; + u32 value; + sscanf(buffer, "%x", &value); + + u32 seed[8]; + cheatsCBAParseSeedCode(address, value, seed); + cheatsCBAChangeEncryption(seed); + } + } + } + cheatsNumber = count; + fclose(f); + return true; } #endif extern int cpuNextEvent; -extern void debuggerBreakOnWrite(u32 , u32, u32, int, int); +extern void debuggerBreakOnWrite(u32, u32, u32, int, int); #ifdef BKPT_SUPPORT static u8 cheatsGetType(u32 address) { - switch(address >> 24) { - case 2: - return freezeWorkRAM[address & 0x3FFFF]; - case 3: - return freezeInternalRAM[address & 0x7FFF]; - case 5: - return freezePRAM[address & 0x3FC]; - case 6: - if (address > 0x06010000) - return freezeVRAM[address & 0x17FFF]; - else - return freezeVRAM[address & 0x1FFFF]; - case 7: - return freezeOAM[address & 0x3FC]; - } - return 0; + switch (address >> 24) { + case 2: + return freezeWorkRAM[address & 0x3FFFF]; + case 3: + return freezeInternalRAM[address & 0x7FFF]; + case 5: + return freezePRAM[address & 0x3FC]; + case 6: + if (address > 0x06010000) + return freezeVRAM[address & 0x17FFF]; + else + return freezeVRAM[address & 0x1FFFF]; + case 7: + return freezeOAM[address & 0x3FC]; + } + return 0; } #endif void cheatsWriteMemory(u32 address, u32 value) { #ifdef BKPT_SUPPORT - if(cheatsNumber == 0) { - int type = cheatsGetType(address); - u32 oldValue = debuggerReadMemory(address); - if(type == 1 || (type == 2 && oldValue != value)) { - debuggerBreakOnWrite(address, oldValue, value, 2, type); - cpuNextEvent = 0; + if (cheatsNumber == 0) { + int type = cheatsGetType(address); + u32 oldValue = debuggerReadMemory(address); + if (type == 1 || (type == 2 && oldValue != value)) { + debuggerBreakOnWrite(address, oldValue, value, 2, type); + cpuNextEvent = 0; + } + debuggerWriteMemory(address, value); } - debuggerWriteMemory(address, value); - } #endif } void cheatsWriteHalfWord(u32 address, u16 value) { #ifdef BKPT_SUPPORT - if(cheatsNumber == 0) { - int type = cheatsGetType(address); - u16 oldValue = debuggerReadHalfWord(address); - if(type == 1 || (type == 2 && oldValue != value)) { - debuggerBreakOnWrite(address, oldValue, value, 1, type); - cpuNextEvent = 0; + if (cheatsNumber == 0) { + int type = cheatsGetType(address); + u16 oldValue = debuggerReadHalfWord(address); + if (type == 1 || (type == 2 && oldValue != value)) { + debuggerBreakOnWrite(address, oldValue, value, 1, type); + cpuNextEvent = 0; + } + debuggerWriteHalfWord(address, value); } - debuggerWriteHalfWord(address, value); - } #endif } void cheatsWriteByte(u32 address, u8 value) { #ifdef BKPT_SUPPORT - if(cheatsNumber == 0) { - int type = cheatsGetType(address); - u8 oldValue = debuggerReadByte(address); - if(type == 1 || (type == 2 && oldValue != value)) { - debuggerBreakOnWrite(address, oldValue, value, 0, type); - cpuNextEvent = 0; + if (cheatsNumber == 0) { + int type = cheatsGetType(address); + u8 oldValue = debuggerReadByte(address); + if (type == 1 || (type == 2 && oldValue != value)) { + debuggerBreakOnWrite(address, oldValue, value, 0, type); + cpuNextEvent = 0; + } + debuggerWriteByte(address, value); } - debuggerWriteByte(address, value); - } #endif } diff --git a/src/gba/Cheats.h b/src/gba/Cheats.h index cc7c96a5..68ade2a7 100644 --- a/src/gba/Cheats.h +++ b/src/gba/Cheats.h @@ -4,24 +4,24 @@ #include "../common/ConfigManager.h" struct CheatsData { - int code; - int size; - int status; - bool enabled; - u32 rawaddress; - u32 address; - u32 value; - u32 oldValue; - char codestring[20]; - char desc[32]; + int code; + int size; + int status; + bool enabled; + u32 rawaddress; + u32 address; + u32 value; + u32 oldValue; + char codestring[20]; + char desc[32]; }; -void cheatsAdd(const char *codeStr, const char *desc, u32 rawaddress, u32 address, u32 value, - int code, int size); -void cheatsAddCheatCode(const char *code, const char *desc); -void cheatsAddGSACode(const char *code, const char *desc, bool v3); -void cheatsAddCBACode(const char *code, const char *desc); -bool cheatsImportGSACodeFile(const char *name, int game, bool v3); +void cheatsAdd(const char* codeStr, const char* desc, u32 rawaddress, u32 address, u32 value, + int code, int size); +void cheatsAddCheatCode(const char* code, const char* desc); +void cheatsAddGSACode(const char* code, const char* desc, bool v3); +void cheatsAddCBACode(const char* code, const char* desc); +bool cheatsImportGSACodeFile(const char* name, int game, bool v3); void cheatsDelete(int number, bool restore); void cheatsDeleteAll(bool restore); void cheatsEnable(int number); @@ -30,8 +30,8 @@ void cheatsDisable(int number); void cheatsSaveGame(gzFile file); void cheatsReadGame(gzFile file, int version); void cheatsReadGameSkip(gzFile file, int version); -void cheatsSaveCheatList(const char *file); -bool cheatsLoadCheatList(const char *file); +void cheatsSaveCheatList(const char* file); +bool cheatsLoadCheatList(const char* file); #endif void cheatsWriteMemory(u32 address, u32 value); void cheatsWriteHalfWord(u32 address, u16 value); diff --git a/src/gba/EEprom.cpp b/src/gba/EEprom.cpp index 4dbb3b81..2b2967ec 100644 --- a/src/gba/EEprom.cpp +++ b/src/gba/EEprom.cpp @@ -1,8 +1,8 @@ -#include -#include -#include "GBA.h" #include "EEprom.h" #include "../Util.h" +#include "GBA.h" +#include +#include extern int cpuDmaCount; @@ -14,7 +14,7 @@ int eepromAddress = 0; #ifdef __LIBRETRO__ // Workaround for broken-by-design GBA save semantics extern u8 libretro_save_buf[0x20000 + 0x2000]; -u8 *eepromData = libretro_save_buf + 0x20000; +u8* eepromData = libretro_save_buf + 0x20000; #else u8 eepromData[0x2000]; #endif @@ -24,198 +24,195 @@ bool eepromInUse = false; int eepromSize = 512; variable_desc eepromSaveData[] = { - { &eepromMode, sizeof(int) }, - { &eepromByte, sizeof(int) }, - { &eepromBits , sizeof(int) }, - { &eepromAddress , sizeof(int) }, - { &eepromInUse, sizeof(bool) }, - { &eepromData[0], 512 }, - { &eepromBuffer[0], 16 }, - { NULL, 0 } + { &eepromMode, sizeof(int) }, + { &eepromByte, sizeof(int) }, + { &eepromBits, sizeof(int) }, + { &eepromAddress, sizeof(int) }, + { &eepromInUse, sizeof(bool) }, + { &eepromData[0], 512 }, + { &eepromBuffer[0], 16 }, + { NULL, 0 } }; void eepromInit() { #ifdef __LIBRETRO__ - memset(eepromData, 255, 0x2000); + memset(eepromData, 255, 0x2000); #else - memset(eepromData, 255, sizeof(eepromData)); + memset(eepromData, 255, sizeof(eepromData)); #endif } void eepromReset() { - eepromMode = EEPROM_IDLE; - eepromByte = 0; - eepromBits = 0; - eepromAddress = 0; - eepromInUse = false; - eepromSize = 512; + eepromMode = EEPROM_IDLE; + eepromByte = 0; + eepromBits = 0; + eepromAddress = 0; + eepromInUse = false; + eepromSize = 512; } #ifdef __LIBRETRO__ -void eepromSaveGame(uint8_t *& data) +void eepromSaveGame(uint8_t*& data) { - utilWriteDataMem(data, eepromSaveData); - utilWriteIntMem(data, eepromSize); - utilWriteMem(data, eepromData, 0x2000); + utilWriteDataMem(data, eepromSaveData); + utilWriteIntMem(data, eepromSize); + utilWriteMem(data, eepromData, 0x2000); } -void eepromReadGame(const uint8_t *& data, int version) +void eepromReadGame(const uint8_t*& data, int version) { - utilReadDataMem(data, eepromSaveData); - if (version >= SAVE_GAME_VERSION_3) { - eepromSize = utilReadIntMem(data); - utilReadMem(eepromData, data, 0x2000); - } else { - // prior to 0.7.1, only 4K EEPROM was supported - eepromSize = 512; - } + utilReadDataMem(data, eepromSaveData); + if (version >= SAVE_GAME_VERSION_3) { + eepromSize = utilReadIntMem(data); + utilReadMem(eepromData, data, 0x2000); + } else { + // prior to 0.7.1, only 4K EEPROM was supported + eepromSize = 512; + } } #else void eepromSaveGame(gzFile gzFile) { - utilWriteData(gzFile, eepromSaveData); - utilWriteInt(gzFile, eepromSize); - utilGzWrite(gzFile, eepromData, 0x2000); + utilWriteData(gzFile, eepromSaveData); + utilWriteInt(gzFile, eepromSize); + utilGzWrite(gzFile, eepromData, 0x2000); } void eepromReadGame(gzFile gzFile, int version) { - utilReadData(gzFile, eepromSaveData); - if(version >= SAVE_GAME_VERSION_3) { - eepromSize = utilReadInt(gzFile); - utilGzRead(gzFile, eepromData, 0x2000); - } else { - // prior to 0.7.1, only 4K EEPROM was supported - eepromSize = 512; - } + utilReadData(gzFile, eepromSaveData); + if (version >= SAVE_GAME_VERSION_3) { + eepromSize = utilReadInt(gzFile); + utilGzRead(gzFile, eepromData, 0x2000); + } else { + // prior to 0.7.1, only 4K EEPROM was supported + eepromSize = 512; + } } void eepromReadGameSkip(gzFile gzFile, int version) { - // skip the eeprom data in a save game - utilReadDataSkip(gzFile, eepromSaveData); - if(version >= SAVE_GAME_VERSION_3) { - utilGzSeek(gzFile, sizeof(int), SEEK_CUR); - utilGzSeek(gzFile, 0x2000, SEEK_CUR); - } + // skip the eeprom data in a save game + utilReadDataSkip(gzFile, eepromSaveData); + if (version >= SAVE_GAME_VERSION_3) { + utilGzSeek(gzFile, sizeof(int), SEEK_CUR); + utilGzSeek(gzFile, 0x2000, SEEK_CUR); + } } #endif int eepromRead(u32 /* address */) { - switch(eepromMode) { - case EEPROM_IDLE: - case EEPROM_READADDRESS: - case EEPROM_WRITEDATA: + switch (eepromMode) { + case EEPROM_IDLE: + case EEPROM_READADDRESS: + case EEPROM_WRITEDATA: + return 1; + case EEPROM_READDATA: { + eepromBits++; + if (eepromBits == 4) { + eepromMode = EEPROM_READDATA2; + eepromBits = 0; + eepromByte = 0; + } + return 0; + } + case EEPROM_READDATA2: { + int data = 0; + int address = eepromAddress << 3; + int mask = 1 << (7 - (eepromBits & 7)); + data = (eepromData[address + eepromByte] & mask) ? 1 : 0; + eepromBits++; + if ((eepromBits & 7) == 0) + eepromByte++; + if (eepromBits == 0x40) + eepromMode = EEPROM_IDLE; + return data; + } + default: + return 0; + } return 1; - case EEPROM_READDATA: - { - eepromBits++; - if(eepromBits == 4) { - eepromMode = EEPROM_READDATA2; - eepromBits = 0; - eepromByte = 0; - } - return 0; - } - case EEPROM_READDATA2: - { - int data = 0; - int address = eepromAddress << 3; - int mask = 1 << (7 - (eepromBits & 7)); - data = (eepromData[address+eepromByte] & mask) ? 1 : 0; - eepromBits++; - if((eepromBits & 7) == 0) - eepromByte++; - if(eepromBits == 0x40) - eepromMode = EEPROM_IDLE; - return data; - } - default: - return 0; - } - return 1; } void eepromWrite(u32 /* address */, u8 value) { - if(cpuDmaCount == 0) - return; - int bit = value & 1; - switch(eepromMode) { - case EEPROM_IDLE: - eepromByte = 0; - eepromBits = 1; - eepromBuffer[eepromByte] = bit; - eepromMode = EEPROM_READADDRESS; - break; - case EEPROM_READADDRESS: - eepromBuffer[eepromByte] <<= 1; - eepromBuffer[eepromByte] |= bit; - eepromBits++; - if((eepromBits & 7) == 0) { - eepromByte++; - } - if(cpuDmaCount == 0x11 || cpuDmaCount == 0x51) { - if(eepromBits == 0x11) { - eepromInUse = true; - eepromSize = 0x2000; - eepromAddress = ((eepromBuffer[0] & 0x3F) << 8) | - ((eepromBuffer[1] & 0xFF)); - if(!(eepromBuffer[0] & 0x40)) { - eepromBuffer[0] = bit; - eepromBits = 1; - eepromByte = 0; - eepromMode = EEPROM_WRITEDATA; - } else { - eepromMode = EEPROM_READDATA; - eepromByte = 0; - eepromBits = 0; + if (cpuDmaCount == 0) + return; + int bit = value & 1; + switch (eepromMode) { + case EEPROM_IDLE: + eepromByte = 0; + eepromBits = 1; + eepromBuffer[eepromByte] = bit; + eepromMode = EEPROM_READADDRESS; + break; + case EEPROM_READADDRESS: + eepromBuffer[eepromByte] <<= 1; + eepromBuffer[eepromByte] |= bit; + eepromBits++; + if ((eepromBits & 7) == 0) { + eepromByte++; } - } - } else { - if(eepromBits == 9) { - eepromInUse = true; - eepromAddress = (eepromBuffer[0] & 0x3F); - if(!(eepromBuffer[0] & 0x40)) { - eepromBuffer[0] = bit; - eepromBits = 1; - eepromByte = 0; - eepromMode = EEPROM_WRITEDATA; + if (cpuDmaCount == 0x11 || cpuDmaCount == 0x51) { + if (eepromBits == 0x11) { + eepromInUse = true; + eepromSize = 0x2000; + eepromAddress = ((eepromBuffer[0] & 0x3F) << 8) | ((eepromBuffer[1] & 0xFF)); + if (!(eepromBuffer[0] & 0x40)) { + eepromBuffer[0] = bit; + eepromBits = 1; + eepromByte = 0; + eepromMode = EEPROM_WRITEDATA; + } else { + eepromMode = EEPROM_READDATA; + eepromByte = 0; + eepromBits = 0; + } + } } else { - eepromMode = EEPROM_READDATA; - eepromByte = 0; - eepromBits = 0; + if (eepromBits == 9) { + eepromInUse = true; + eepromAddress = (eepromBuffer[0] & 0x3F); + if (!(eepromBuffer[0] & 0x40)) { + eepromBuffer[0] = bit; + eepromBits = 1; + eepromByte = 0; + eepromMode = EEPROM_WRITEDATA; + } else { + eepromMode = EEPROM_READDATA; + eepromByte = 0; + eepromBits = 0; + } + } } - } + break; + case EEPROM_READDATA: + case EEPROM_READDATA2: + // should we reset here? + eepromMode = EEPROM_IDLE; + break; + case EEPROM_WRITEDATA: + eepromBuffer[eepromByte] <<= 1; + eepromBuffer[eepromByte] |= bit; + eepromBits++; + if ((eepromBits & 7) == 0) { + eepromByte++; + } + if (eepromBits == 0x40) { + eepromInUse = true; + // write data; + for (int i = 0; i < 8; i++) { + eepromData[(eepromAddress << 3) + i] = eepromBuffer[i]; + } + systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED; + } else if (eepromBits == 0x41) { + eepromMode = EEPROM_IDLE; + eepromByte = 0; + eepromBits = 0; + } + break; } - break; - case EEPROM_READDATA: - case EEPROM_READDATA2: - // should we reset here? - eepromMode = EEPROM_IDLE; - break; - case EEPROM_WRITEDATA: - eepromBuffer[eepromByte] <<= 1; - eepromBuffer[eepromByte] |= bit; - eepromBits++; - if((eepromBits & 7) == 0) { - eepromByte++; - } - if(eepromBits == 0x40) { - eepromInUse = true; - // write data; - for(int i = 0; i < 8; i++) { - eepromData[(eepromAddress << 3) + i] = eepromBuffer[i]; - } - systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED; - } else if(eepromBits == 0x41) { - eepromMode = EEPROM_IDLE; - eepromByte = 0; - eepromBits = 0; - } - break; - } } diff --git a/src/gba/EEprom.h b/src/gba/EEprom.h index a6d9323c..41c8d708 100644 --- a/src/gba/EEprom.h +++ b/src/gba/EEprom.h @@ -2,8 +2,8 @@ #define EEPROM_H #ifdef __LIBRETRO__ -extern void eepromSaveGame(u8 *&data); -extern void eepromReadGame(const u8 *&data, int version); +extern void eepromSaveGame(u8*& data); +extern void eepromReadGame(const u8*& data, int version); #else extern void eepromSaveGame(gzFile _gzFile); extern void eepromReadGame(gzFile _gzFile, int version); @@ -14,7 +14,7 @@ extern void eepromWrite(u32 address, u8 value); extern void eepromInit(); extern void eepromReset(); #ifdef __LIBRETRO__ -extern u8 *eepromData; +extern u8* eepromData; #else extern u8 eepromData[0x2000]; #endif diff --git a/src/gba/Flash.cpp b/src/gba/Flash.cpp index d8282fbd..9700abe8 100644 --- a/src/gba/Flash.cpp +++ b/src/gba/Flash.cpp @@ -1,26 +1,26 @@ -#include -#include -#include +#include "Flash.h" +#include "../Util.h" #include "GBA.h" #include "Globals.h" -#include "Flash.h" #include "Sram.h" -#include "../Util.h" +#include +#include +#include -#define FLASH_READ_ARRAY 0 -#define FLASH_CMD_1 1 -#define FLASH_CMD_2 2 -#define FLASH_AUTOSELECT 3 -#define FLASH_CMD_3 4 -#define FLASH_CMD_4 5 -#define FLASH_CMD_5 6 -#define FLASH_ERASE_COMPLETE 7 -#define FLASH_PROGRAM 8 -#define FLASH_SETBANK 9 +#define FLASH_READ_ARRAY 0 +#define FLASH_CMD_1 1 +#define FLASH_CMD_2 2 +#define FLASH_AUTOSELECT 3 +#define FLASH_CMD_3 4 +#define FLASH_CMD_4 5 +#define FLASH_CMD_5 6 +#define FLASH_ERASE_COMPLETE 7 +#define FLASH_PROGRAM 8 +#define FLASH_SETBANK 9 #ifdef __LIBRETRO__ extern uint8_t libretro_save_buf[0x20000 + 0x2000]; -uint8_t *flashSaveMemory = libretro_save_buf; +uint8_t* flashSaveMemory = libretro_save_buf; #else uint8_t flashSaveMemory[FLASH_128K_SZ]; #endif @@ -33,252 +33,251 @@ int flashManufacturerID = 0x32; int flashBank = 0; static variable_desc flashSaveData[] = { - { &flashState, sizeof(int) }, - { &flashReadState, sizeof(int) }, - { &flashSaveMemory[0], 0x10000 }, - { NULL, 0 } + { &flashState, sizeof(int) }, + { &flashReadState, sizeof(int) }, + { &flashSaveMemory[0], 0x10000 }, + { NULL, 0 } }; static variable_desc flashSaveData2[] = { - { &flashState, sizeof(int) }, - { &flashReadState, sizeof(int) }, - { &flashSize, sizeof(int) }, - { &flashSaveMemory[0], 0x20000 }, - { NULL, 0 } + { &flashState, sizeof(int) }, + { &flashReadState, sizeof(int) }, + { &flashSize, sizeof(int) }, + { &flashSaveMemory[0], 0x20000 }, + { NULL, 0 } }; static variable_desc flashSaveData3[] = { - { &flashState, sizeof(int) }, - { &flashReadState, sizeof(int) }, - { &flashSize, sizeof(int) }, - { &flashBank, sizeof(int) }, - { &flashSaveMemory[0], 0x20000 }, - { NULL, 0 } + { &flashState, sizeof(int) }, + { &flashReadState, sizeof(int) }, + { &flashSize, sizeof(int) }, + { &flashBank, sizeof(int) }, + { &flashSaveMemory[0], 0x20000 }, + { NULL, 0 } }; void flashInit() { #ifdef __LIBRETRO__ - memset(flashSaveMemory, 0xff, 0x20000); + memset(flashSaveMemory, 0xff, 0x20000); #else - memset(flashSaveMemory, 0xff, sizeof(flashSaveMemory)); + memset(flashSaveMemory, 0xff, sizeof(flashSaveMemory)); #endif } void flashReset() { - flashState = FLASH_READ_ARRAY; - flashReadState = FLASH_READ_ARRAY; - flashBank = 0; + flashState = FLASH_READ_ARRAY; + flashReadState = FLASH_READ_ARRAY; + flashBank = 0; } #ifdef __LIBRETRO__ -void flashSaveGame(uint8_t *& data) +void flashSaveGame(uint8_t*& data) { - utilWriteDataMem(data, flashSaveData3); + utilWriteDataMem(data, flashSaveData3); } -void flashReadGame(const uint8_t *& data, int) +void flashReadGame(const uint8_t*& data, int) { - utilReadDataMem(data, flashSaveData3); + utilReadDataMem(data, flashSaveData3); } #else void flashSaveGame(gzFile gzFile) { - utilWriteData(gzFile, flashSaveData3); + utilWriteData(gzFile, flashSaveData3); } void flashReadGame(gzFile gzFile, int version) { - if(version < SAVE_GAME_VERSION_5) - utilReadData(gzFile, flashSaveData); - else if(version < SAVE_GAME_VERSION_7) { - utilReadData(gzFile, flashSaveData2); - flashBank = 0; - flashSetSize(flashSize); - } else { - utilReadData(gzFile, flashSaveData3); - } + if (version < SAVE_GAME_VERSION_5) + utilReadData(gzFile, flashSaveData); + else if (version < SAVE_GAME_VERSION_7) { + utilReadData(gzFile, flashSaveData2); + flashBank = 0; + flashSetSize(flashSize); + } else { + utilReadData(gzFile, flashSaveData3); + } } void flashReadGameSkip(gzFile gzFile, int version) { - // skip the flash data in a save game - if(version < SAVE_GAME_VERSION_5) - utilReadDataSkip(gzFile, flashSaveData); - else if(version < SAVE_GAME_VERSION_7) { - utilReadDataSkip(gzFile, flashSaveData2); - } else { - utilReadDataSkip(gzFile, flashSaveData3); - } + // skip the flash data in a save game + if (version < SAVE_GAME_VERSION_5) + utilReadDataSkip(gzFile, flashSaveData); + else if (version < SAVE_GAME_VERSION_7) { + utilReadDataSkip(gzFile, flashSaveData2); + } else { + utilReadDataSkip(gzFile, flashSaveData3); + } } #endif - void flashSetSize(int size) { - // log("Setting flash size to %d\n", size); - if(size == 0x10000) { - flashDeviceID = 0x1b; - flashManufacturerID = 0x32; - } else { - flashDeviceID = 0x13; //0x09; - flashManufacturerID = 0x62; //0xc2; - } - // Added to make 64k saves compatible with 128k ones - // (allow wrongfuly set 64k saves to work for Pokemon games) - if ((size == 0x20000) && (flashSize == 0x10000)) - memcpy((u8 *)(flashSaveMemory+0x10000), (u8 *)(flashSaveMemory), 0x10000); - flashSize = size; + // log("Setting flash size to %d\n", size); + if (size == 0x10000) { + flashDeviceID = 0x1b; + flashManufacturerID = 0x32; + } else { + flashDeviceID = 0x13; //0x09; + flashManufacturerID = 0x62; //0xc2; + } + // Added to make 64k saves compatible with 128k ones + // (allow wrongfuly set 64k saves to work for Pokemon games) + if ((size == 0x20000) && (flashSize == 0x10000)) + memcpy((u8*)(flashSaveMemory + 0x10000), (u8*)(flashSaveMemory), 0x10000); + flashSize = size; } u8 flashRead(u32 address) { - // log("Reading %08x from %08x\n", address, reg[15].I); - // log("Current read state is %d\n", flashReadState); - address &= 0xFFFF; + // log("Reading %08x from %08x\n", address, reg[15].I); + // log("Current read state is %d\n", flashReadState); + address &= 0xFFFF; - switch(flashReadState) { - case FLASH_READ_ARRAY: - return flashSaveMemory[(flashBank << 16) + address]; - case FLASH_AUTOSELECT: - switch(address & 0xFF) { - case 0: - // manufacturer ID - return flashManufacturerID; - case 1: - // device ID - return flashDeviceID; - } - break; - case FLASH_ERASE_COMPLETE: - flashState = FLASH_READ_ARRAY; - flashReadState = FLASH_READ_ARRAY; - return 0xFF; - }; - return 0; + switch (flashReadState) { + case FLASH_READ_ARRAY: + return flashSaveMemory[(flashBank << 16) + address]; + case FLASH_AUTOSELECT: + switch (address & 0xFF) { + case 0: + // manufacturer ID + return flashManufacturerID; + case 1: + // device ID + return flashDeviceID; + } + break; + case FLASH_ERASE_COMPLETE: + flashState = FLASH_READ_ARRAY; + flashReadState = FLASH_READ_ARRAY; + return 0xFF; + }; + return 0; } void flashSaveDecide(u32 address, u8 byte) { - if (saveType == 1) - return; + if (saveType == 1) + return; - // log("Deciding save type %08x\n", address); - if(address == 0x0e005555) { - saveType = 3; - cpuSaveGameFunc = flashWrite; - } else { - saveType = 2; - cpuSaveGameFunc = sramWrite; - } + // log("Deciding save type %08x\n", address); + if (address == 0x0e005555) { + saveType = 3; + cpuSaveGameFunc = flashWrite; + } else { + saveType = 2; + cpuSaveGameFunc = sramWrite; + } - (*cpuSaveGameFunc)(address, byte); + (*cpuSaveGameFunc)(address, byte); } void flashDelayedWrite(u32 address, u8 byte) { - saveType = 3; - cpuSaveGameFunc = flashWrite; - flashWrite(address, byte); + saveType = 3; + cpuSaveGameFunc = flashWrite; + flashWrite(address, byte); } void flashWrite(u32 address, u8 byte) { - // log("Writing %02x at %08x\n", byte, address); - // log("Current state is %d\n", flashState); - address &= 0xFFFF; - switch(flashState) { - case FLASH_READ_ARRAY: - if(address == 0x5555 && byte == 0xAA) - flashState = FLASH_CMD_1; - break; - case FLASH_CMD_1: - if(address == 0x2AAA && byte == 0x55) - flashState = FLASH_CMD_2; - else - flashState = FLASH_READ_ARRAY; - break; - case FLASH_CMD_2: - if(address == 0x5555) { - if(byte == 0x90) { - flashState = FLASH_AUTOSELECT; - flashReadState = FLASH_AUTOSELECT; - } else if(byte == 0x80) { - flashState = FLASH_CMD_3; - } else if(byte == 0xF0) { + // log("Writing %02x at %08x\n", byte, address); + // log("Current state is %d\n", flashState); + address &= 0xFFFF; + switch (flashState) { + case FLASH_READ_ARRAY: + if (address == 0x5555 && byte == 0xAA) + flashState = FLASH_CMD_1; + break; + case FLASH_CMD_1: + if (address == 0x2AAA && byte == 0x55) + flashState = FLASH_CMD_2; + else + flashState = FLASH_READ_ARRAY; + break; + case FLASH_CMD_2: + if (address == 0x5555) { + if (byte == 0x90) { + flashState = FLASH_AUTOSELECT; + flashReadState = FLASH_AUTOSELECT; + } else if (byte == 0x80) { + flashState = FLASH_CMD_3; + } else if (byte == 0xF0) { + flashState = FLASH_READ_ARRAY; + flashReadState = FLASH_READ_ARRAY; + } else if (byte == 0xA0) { + flashState = FLASH_PROGRAM; + } else if (byte == 0xB0 && flashSize == 0x20000) { + flashState = FLASH_SETBANK; + } else { + flashState = FLASH_READ_ARRAY; + flashReadState = FLASH_READ_ARRAY; + } + } else { + flashState = FLASH_READ_ARRAY; + flashReadState = FLASH_READ_ARRAY; + } + break; + case FLASH_CMD_3: + if (address == 0x5555 && byte == 0xAA) { + flashState = FLASH_CMD_4; + } else { + flashState = FLASH_READ_ARRAY; + flashReadState = FLASH_READ_ARRAY; + } + break; + case FLASH_CMD_4: + if (address == 0x2AAA && byte == 0x55) { + flashState = FLASH_CMD_5; + } else { + flashState = FLASH_READ_ARRAY; + flashReadState = FLASH_READ_ARRAY; + } + break; + case FLASH_CMD_5: + if (byte == 0x30) { + // SECTOR ERASE + memset(&flashSaveMemory[(flashBank << 16) + (address & 0xF000)], + 0, + 0x1000); + systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED; + flashReadState = FLASH_ERASE_COMPLETE; + } else if (byte == 0x10) { + // CHIP ERASE + memset(flashSaveMemory, 0, flashSize); + systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED; + flashReadState = FLASH_ERASE_COMPLETE; + } else { + flashState = FLASH_READ_ARRAY; + flashReadState = FLASH_READ_ARRAY; + } + break; + case FLASH_AUTOSELECT: + if (byte == 0xF0) { + flashState = FLASH_READ_ARRAY; + flashReadState = FLASH_READ_ARRAY; + } else if (address == 0x5555 && byte == 0xAA) + flashState = FLASH_CMD_1; + else { + flashState = FLASH_READ_ARRAY; + flashReadState = FLASH_READ_ARRAY; + } + break; + case FLASH_PROGRAM: + flashSaveMemory[(flashBank << 16) + address] = byte; + systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED; flashState = FLASH_READ_ARRAY; flashReadState = FLASH_READ_ARRAY; - } else if(byte == 0xA0) { - flashState = FLASH_PROGRAM; - } else if(byte == 0xB0 && flashSize == 0x20000) { - flashState = FLASH_SETBANK; - } else { + break; + case FLASH_SETBANK: + if (address == 0) { + flashBank = (byte & 1); + } flashState = FLASH_READ_ARRAY; flashReadState = FLASH_READ_ARRAY; - } - } else { - flashState = FLASH_READ_ARRAY; - flashReadState = FLASH_READ_ARRAY; + break; } - break; - case FLASH_CMD_3: - if(address == 0x5555 && byte == 0xAA) { - flashState = FLASH_CMD_4; - } else { - flashState = FLASH_READ_ARRAY; - flashReadState = FLASH_READ_ARRAY; - } - break; - case FLASH_CMD_4: - if(address == 0x2AAA && byte == 0x55) { - flashState = FLASH_CMD_5; - } else { - flashState = FLASH_READ_ARRAY; - flashReadState = FLASH_READ_ARRAY; - } - break; - case FLASH_CMD_5: - if(byte == 0x30) { - // SECTOR ERASE - memset(&flashSaveMemory[(flashBank << 16) + (address & 0xF000)], - 0, - 0x1000); - systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED; - flashReadState = FLASH_ERASE_COMPLETE; - } else if(byte == 0x10) { - // CHIP ERASE - memset(flashSaveMemory, 0, flashSize); - systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED; - flashReadState = FLASH_ERASE_COMPLETE; - } else { - flashState = FLASH_READ_ARRAY; - flashReadState = FLASH_READ_ARRAY; - } - break; - case FLASH_AUTOSELECT: - if(byte == 0xF0) { - flashState = FLASH_READ_ARRAY; - flashReadState = FLASH_READ_ARRAY; - } else if(address == 0x5555 && byte == 0xAA) - flashState = FLASH_CMD_1; - else { - flashState = FLASH_READ_ARRAY; - flashReadState = FLASH_READ_ARRAY; - } - break; - case FLASH_PROGRAM: - flashSaveMemory[(flashBank<<16)+address] = byte; - systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED; - flashState = FLASH_READ_ARRAY; - flashReadState = FLASH_READ_ARRAY; - break; - case FLASH_SETBANK: - if(address == 0) { - flashBank = (byte & 1); - } - flashState = FLASH_READ_ARRAY; - flashReadState = FLASH_READ_ARRAY; - break; - } } diff --git a/src/gba/Flash.h b/src/gba/Flash.h index f24780c1..16873c17 100644 --- a/src/gba/Flash.h +++ b/src/gba/Flash.h @@ -4,8 +4,8 @@ #define FLASH_128K_SZ 0x20000 #ifdef __LIBRETRO__ -extern void flashSaveGame(u8 *&data); -extern void flashReadGame(const u8 *&data, int); +extern void flashSaveGame(u8*& data); +extern void flashReadGame(const u8*& data, int); #else extern void flashSaveGame(gzFile _gzFile); extern void flashReadGame(gzFile _gzFile, int version); @@ -15,7 +15,7 @@ extern u8 flashRead(u32 address); extern void flashWrite(u32 address, u8 byte); extern void flashDelayedWrite(u32 address, u8 byte); #ifdef __LIBRETRO__ -extern uint8_t *flashSaveMemory; +extern uint8_t* flashSaveMemory; #else extern u8 flashSaveMemory[FLASH_128K_SZ]; #endif diff --git a/src/gba/GBA-arm.cpp b/src/gba/GBA-arm.cpp index 1fbba0c0..fa049c06 100644 --- a/src/gba/GBA-arm.cpp +++ b/src/gba/GBA-arm.cpp @@ -1,25 +1,25 @@ -#include -#include #include #include +#include +#include #include +#include "../NLS.h" +#include "../System.h" +#include "../Util.h" +#include "../common/ConfigManager.h" +#include "Cheats.h" +#include "EEprom.h" +#include "Flash.h" #include "GBA.h" #include "GBAcpu.h" #include "GBAinline.h" #include "Globals.h" -#include "EEprom.h" -#include "Flash.h" #include "Sound.h" #include "Sram.h" -#include "bios.h" -#include "Cheats.h" -#include "../NLS.h" -#include "elf.h" -#include "../Util.h" -#include "../System.h" -#include "../common/ConfigManager.h" #include "agbprint.h" +#include "bios.h" +#include "elf.h" #include "remote.h" #ifdef PROFILING @@ -27,11 +27,11 @@ #endif #ifdef _MSC_VER - // Disable "empty statement" warnings - #pragma warning(disable: 4390) - // Visual C's inline assembler treats "offset" as a reserved word, so we - // tell it otherwise. If you want to use it, write "OFFSET" in capitals. - #define offset offset_ +// Disable "empty statement" warnings +#pragma warning(disable : 4390) +// Visual C's inline assembler treats "offset" as a reserved word, so we +// tell it otherwise. If you want to use it, write "OFFSET" in capitals. +#define offset offset_ #endif /////////////////////////////////////////////////////////////////////////// @@ -43,7 +43,7 @@ static INSN_REGPARM void armUnknownInsn(u32 opcode) #ifdef GBA_LOGGING if (systemVerbose & VERBOSE_UNDEFINED) { log("Undefined ARM instruction %08x at %08x\n", opcode, - armNextPC-4); + armNextPC - 4); } #endif CPUUndefinedException(); @@ -54,23 +54,22 @@ static INSN_REGPARM void armBreakpoint(u32 opcode) { reg[15].I -= 4; armNextPC -= 4; - dbgSignal(5, (opcode & 0x0f) | ((opcode>>4) & 0xfff0)); + dbgSignal(5, (opcode & 0x0f) | ((opcode >> 4) & 0xfff0)); clockTicks = -1; } #endif - // Subroutine to count instructions (for debugging/optimizing) //#define INSN_COUNTER // comment out if you don't want it #ifdef INSN_COUNTER static void count(u32 opcode, int cond_res) { - static int insncount = 0; // number of insns seen - static int executed = 0; // number of insns executed - static int mergewith[4096]; // map instructions to routines - static int count[4096]; // count of each 12-bit code - int index = ((opcode>>16)&0xFF0) | ((opcode>>4)&0x0F); - static FILE *outfile = NULL; + static int insncount = 0; // number of insns seen + static int executed = 0; // number of insns executed + static int mergewith[4096]; // map instructions to routines + static int count[4096]; // count of each 12-bit code + int index = ((opcode >> 16) & 0xFF0) | ((opcode >> 4) & 0x0F); + static FILE* outfile = NULL; if (!insncount) { for (int i = 0; i < 4096; i++) { @@ -87,7 +86,7 @@ static void count(u32 opcode, int cond_res) executed++; } insncount++; - if (outfile && insncount%1000000 == 0) { + if (outfile && insncount % 1000000 == 0) { fprintf(outfile, "Total instructions: %d\n", insncount); fprintf(outfile, "Instructions executed: %d\n", executed); for (int i = 0; i < 4096; i++) { @@ -101,12 +100,14 @@ static void count(u32 opcode, int cond_res) // Common macros ////////////////////////////////////////////////////////// #ifdef BKPT_SUPPORT -#define CONSOLE_OUTPUT(a,b) do { \ - if ((opcode == 0xe0000000) && (reg[0].I == 0xC0DED00D)) { \ - dbgOutput((a), (b)); \ -} while (0) +#define CONSOLE_OUTPUT(a, b) \ + do { \ + if ((opcode == 0xe0000000) && (reg[0].I == 0xC0DED00D)) { \ + dbgOutput((a), (b)); \ + } \ + while (0) #else -#define CONSOLE_OUTPUT(a,b) /* nothing */ +#define CONSOLE_OUTPUT(a, b) /* nothing */ #endif #define NEG(i) ((i) >> 31) @@ -139,208 +140,201 @@ static void count(u32 opcode, int cond_res) #ifndef C_CORE -#if 0 // definitions have changed +#if 0 // definitions have changed //#ifdef __POWERPC__ - #define OP_SUBS \ - {\ - register int Flags; \ - register int Result; \ - asm volatile("subco. %0, %2, %3\n" \ - "mcrxr cr1\n" \ - "mfcr %1\n" \ - : "=r" (Result), \ - "=r" (Flags) \ - : "r" (reg[base].I), \ - "r" (value) \ - ); \ - reg[dest].I = Result; \ - Z_FLAG = (Flags >> 29) & 1; \ - N_FLAG = (Flags >> 31) & 1; \ - C_FLAG = (Flags >> 25) & 1; \ - V_FLAG = (Flags >> 26) & 1; \ - } - #define OP_RSBS \ - {\ - register int Flags; \ - register int Result; \ - asm volatile("subfco. %0, %2, %3\n" \ - "mcrxr cr1\n" \ - "mfcr %1\n" \ - : "=r" (Result), \ - "=r" (Flags) \ - : "r" (reg[base].I), \ - "r" (value) \ - ); \ - reg[dest].I = Result; \ - Z_FLAG = (Flags >> 29) & 1; \ - N_FLAG = (Flags >> 31) & 1; \ - C_FLAG = (Flags >> 25) & 1; \ - V_FLAG = (Flags >> 26) & 1; \ - } - #define OP_ADDS \ - {\ - register int Flags; \ - register int Result; \ - asm volatile("addco. %0, %2, %3\n" \ - "mcrxr cr1\n" \ - "mfcr %1\n" \ - : "=r" (Result), \ - "=r" (Flags) \ - : "r" (reg[base].I), \ - "r" (value) \ - ); \ - reg[dest].I = Result; \ - Z_FLAG = (Flags >> 29) & 1; \ - N_FLAG = (Flags >> 31) & 1; \ - C_FLAG = (Flags >> 25) & 1; \ - V_FLAG = (Flags >> 26) & 1; \ - } - #define OP_ADCS \ - {\ - register int Flags; \ - register int Result; \ - asm volatile("mtspr xer, %4\n" \ - "addeo. %0, %2, %3\n" \ - "mcrxr cr1\n" \ - "mfcr %1\n" \ - : "=r" (Result), \ - "=r" (Flags) \ - : "r" (reg[base].I), \ - "r" (value), \ - "r" (C_FLAG << 29) \ - ); \ - reg[dest].I = Result; \ - Z_FLAG = (Flags >> 29) & 1; \ - N_FLAG = (Flags >> 31) & 1; \ - C_FLAG = (Flags >> 25) & 1; \ - V_FLAG = (Flags >> 26) & 1; \ - } - #define OP_SBCS \ - {\ - register int Flags; \ - register int Result; \ - asm volatile("mtspr xer, %4\n" \ - "subfeo. %0, %3, %2\n" \ - "mcrxr cr1\n" \ - "mfcr %1\n" \ - : "=r" (Result), \ - "=r" (Flags) \ - : "r" (reg[base].I), \ - "r" (value), \ - "r" (C_FLAG << 29) \ - ); \ - reg[dest].I = Result; \ - Z_FLAG = (Flags >> 29) & 1; \ - N_FLAG = (Flags >> 31) & 1; \ - C_FLAG = (Flags >> 25) & 1; \ - V_FLAG = (Flags >> 26) & 1; \ - } - #define OP_RSCS \ - {\ - register int Flags; \ - register int Result; \ - asm volatile("mtspr xer, %4\n" \ - "subfeo. %0, %2, %3\n" \ - "mcrxr cr1\n" \ - "mfcr %1\n" \ - : "=r" (Result), \ - "=r" (Flags) \ - : "r" (reg[base].I), \ - "r" (value), \ - "r" (C_FLAG << 29) \ - ); \ - reg[dest].I = Result; \ - Z_FLAG = (Flags >> 29) & 1; \ - N_FLAG = (Flags >> 31) & 1; \ - C_FLAG = (Flags >> 25) & 1; \ - V_FLAG = (Flags >> 26) & 1; \ - } - #define OP_CMP \ - {\ - register int Flags; \ - register int Result; \ - asm volatile("subco. %0, %2, %3\n" \ - "mcrxr cr1\n" \ - "mfcr %1\n" \ - : "=r" (Result), \ - "=r" (Flags) \ - : "r" (reg[base].I), \ - "r" (value) \ - ); \ - Z_FLAG = (Flags >> 29) & 1; \ - N_FLAG = (Flags >> 31) & 1; \ - C_FLAG = (Flags >> 25) & 1; \ - V_FLAG = (Flags >> 26) & 1; \ - } - #define OP_CMN \ - {\ - register int Flags; \ - register int Result; \ - asm volatile("addco. %0, %2, %3\n" \ - "mcrxr cr1\n" \ - "mfcr %1\n" \ - : "=r" (Result), \ - "=r" (Flags) \ - : "r" (reg[base].I), \ - "r" (value) \ - ); \ - Z_FLAG = (Flags >> 29) & 1; \ - N_FLAG = (Flags >> 31) & 1; \ - C_FLAG = (Flags >> 25) & 1; \ - V_FLAG = (Flags >> 26) & 1; \ - } +#define OP_SUBS \ + { \ + register int Flags; \ + register int Result; \ + asm volatile("subco. %0, %2, %3\n" \ + "mcrxr cr1\n" \ + "mfcr %1\n" \ + : "=r"(Result), \ + "=r"(Flags) \ + : "r"(reg[base].I), \ + "r"(value)); \ + reg[dest].I = Result; \ + Z_FLAG = (Flags >> 29) & 1; \ + N_FLAG = (Flags >> 31) & 1; \ + C_FLAG = (Flags >> 25) & 1; \ + V_FLAG = (Flags >> 26) & 1; \ + } +#define OP_RSBS \ + { \ + register int Flags; \ + register int Result; \ + asm volatile("subfco. %0, %2, %3\n" \ + "mcrxr cr1\n" \ + "mfcr %1\n" \ + : "=r"(Result), \ + "=r"(Flags) \ + : "r"(reg[base].I), \ + "r"(value)); \ + reg[dest].I = Result; \ + Z_FLAG = (Flags >> 29) & 1; \ + N_FLAG = (Flags >> 31) & 1; \ + C_FLAG = (Flags >> 25) & 1; \ + V_FLAG = (Flags >> 26) & 1; \ + } +#define OP_ADDS \ + { \ + register int Flags; \ + register int Result; \ + asm volatile("addco. %0, %2, %3\n" \ + "mcrxr cr1\n" \ + "mfcr %1\n" \ + : "=r"(Result), \ + "=r"(Flags) \ + : "r"(reg[base].I), \ + "r"(value)); \ + reg[dest].I = Result; \ + Z_FLAG = (Flags >> 29) & 1; \ + N_FLAG = (Flags >> 31) & 1; \ + C_FLAG = (Flags >> 25) & 1; \ + V_FLAG = (Flags >> 26) & 1; \ + } +#define OP_ADCS \ + { \ + register int Flags; \ + register int Result; \ + asm volatile("mtspr xer, %4\n" \ + "addeo. %0, %2, %3\n" \ + "mcrxr cr1\n" \ + "mfcr %1\n" \ + : "=r"(Result), \ + "=r"(Flags) \ + : "r"(reg[base].I), \ + "r"(value), \ + "r"(C_FLAG << 29)); \ + reg[dest].I = Result; \ + Z_FLAG = (Flags >> 29) & 1; \ + N_FLAG = (Flags >> 31) & 1; \ + C_FLAG = (Flags >> 25) & 1; \ + V_FLAG = (Flags >> 26) & 1; \ + } +#define OP_SBCS \ + { \ + register int Flags; \ + register int Result; \ + asm volatile("mtspr xer, %4\n" \ + "subfeo. %0, %3, %2\n" \ + "mcrxr cr1\n" \ + "mfcr %1\n" \ + : "=r"(Result), \ + "=r"(Flags) \ + : "r"(reg[base].I), \ + "r"(value), \ + "r"(C_FLAG << 29)); \ + reg[dest].I = Result; \ + Z_FLAG = (Flags >> 29) & 1; \ + N_FLAG = (Flags >> 31) & 1; \ + C_FLAG = (Flags >> 25) & 1; \ + V_FLAG = (Flags >> 26) & 1; \ + } +#define OP_RSCS \ + { \ + register int Flags; \ + register int Result; \ + asm volatile("mtspr xer, %4\n" \ + "subfeo. %0, %2, %3\n" \ + "mcrxr cr1\n" \ + "mfcr %1\n" \ + : "=r"(Result), \ + "=r"(Flags) \ + : "r"(reg[base].I), \ + "r"(value), \ + "r"(C_FLAG << 29)); \ + reg[dest].I = Result; \ + Z_FLAG = (Flags >> 29) & 1; \ + N_FLAG = (Flags >> 31) & 1; \ + C_FLAG = (Flags >> 25) & 1; \ + V_FLAG = (Flags >> 26) & 1; \ + } +#define OP_CMP \ + { \ + register int Flags; \ + register int Result; \ + asm volatile("subco. %0, %2, %3\n" \ + "mcrxr cr1\n" \ + "mfcr %1\n" \ + : "=r"(Result), \ + "=r"(Flags) \ + : "r"(reg[base].I), \ + "r"(value)); \ + Z_FLAG = (Flags >> 29) & 1; \ + N_FLAG = (Flags >> 31) & 1; \ + C_FLAG = (Flags >> 25) & 1; \ + V_FLAG = (Flags >> 26) & 1; \ + } +#define OP_CMN \ + { \ + register int Flags; \ + register int Result; \ + asm volatile("addco. %0, %2, %3\n" \ + "mcrxr cr1\n" \ + "mfcr %1\n" \ + : "=r"(Result), \ + "=r"(Flags) \ + : "r"(reg[base].I), \ + "r"(value)); \ + Z_FLAG = (Flags >> 29) & 1; \ + N_FLAG = (Flags >> 31) & 1; \ + C_FLAG = (Flags >> 25) & 1; \ + V_FLAG = (Flags >> 26) & 1; \ + } -#else // !__POWERPC__ +#else // !__POWERPC__ // Macros to emit instructions in the format used by the particular compiler. // We use GNU assembler syntax: "op src, dest" rather than "op dest, src" #ifdef __GNUC__ - #define ALU_HEADER asm("mov %%ecx, %%edi; " - #define ALU_TRAILER : "=D" (opcode) : "c" (opcode) : "eax", "ebx", "edx", "esi") - #define EMIT0(op) #op "; " - #define EMIT1(op,arg) #op " " arg "; " - #define EMIT2(op,src,dest) #op " " src ", " dest "; " - #define KONST(val) "$" #val - #define ASMVAR(cvar) ASMVAR2 (__USER_LABEL_PREFIX__, cvar) - #define ASMVAR2(prefix,cvar) STRING (prefix) cvar - #define STRING(x) #x - #define VAR(var) ASMVAR(#var) - #define VARL(var) ASMVAR(#var) - #define REGREF1(index) ASMVAR("reg(" index ")") - #define REGREF2(index,scale) ASMVAR("reg(," index "," #scale ")") - #define LABEL(n) #n ": " - #define LABELREF(n,dir) #n#dir - #define al "%%al" - #define ah "%%ah" - #define eax "%%eax" - #define bl "%%bl" - #define bh "%%bh" - #define ebx "%%ebx" - #define cl "%%cl" - #define ch "%%ch" - #define ecx "%%ecx" - #define dl "%%dl" - #define dh "%%dh" - #define edx "%%edx" - #define esp "%%esp" - #define ebp "%%ebp" - #define esi "%%esi" - #define edi "%%edi" - #define movzx movzb +#define ALU_HEADER asm("mov %%ecx, %%edi; " +#define ALU_TRAILER : "=D" (opcode) : "c" (opcode) : "eax", "ebx", "edx", "esi") +#define EMIT0(op) #op "; " +#define EMIT1(op, arg) #op " " arg "; " +#define EMIT2(op, src, dest) #op " " src ", " dest "; " +#define KONST(val) "$" #val +#define ASMVAR(cvar) ASMVAR2(__USER_LABEL_PREFIX__, cvar) +#define ASMVAR2(prefix, cvar) STRING(prefix) \ + cvar +#define STRING(x) #x +#define VAR(var) ASMVAR(#var) +#define VARL(var) ASMVAR(#var) +#define REGREF1(index) ASMVAR("reg(" index ")") +#define REGREF2(index, scale) ASMVAR("reg(," index "," #scale ")") +#define LABEL(n) #n ": " +#define LABELREF(n, dir) #n #dir +#define al "%%al" +#define ah "%%ah" +#define eax "%%eax" +#define bl "%%bl" +#define bh "%%bh" +#define ebx "%%ebx" +#define cl "%%cl" +#define ch "%%ch" +#define ecx "%%ecx" +#define dl "%%dl" +#define dh "%%dh" +#define edx "%%edx" +#define esp "%%esp" +#define ebp "%%ebp" +#define esi "%%esi" +#define edi "%%edi" +#define movzx movzb #else - #define ALU_HEADER __asm { __asm mov ecx, opcode - #define ALU_TRAILER } - #define EMIT0(op) __asm op - #define EMIT1(op,arg) __asm op arg - #define EMIT2(op,src,dest) __asm op dest, src - #define KONST(val) val - #define VAR(var) var - #define VARL(var) dword ptr var - #define REGREF1(index) reg[index] - #define REGREF2(index,scale) reg[index*scale] - #define LABEL(n) __asm l##n: - #define LABELREF(n,dir) l##n +#define ALU_HEADER __asm { __asm mov ecx, opcode +#define ALU_TRAILER } +#define EMIT0(op) __asm op +#define EMIT1(op, arg) __asm op arg +#define EMIT2(op, src, dest) __asm op dest, src +#define KONST(val) val +#define VAR(var) var +#define VARL(var) dword ptr var +#define REGREF1(index) reg[index] +#define REGREF2(index, scale) reg[index * scale] +#define LABEL(n) __asm l##n: +#define LABELREF(n, dir) l##n #endif //X//#ifndef _MSC_VER @@ -352,53 +346,53 @@ static void count(u32 opcode, int cond_res) // ESI -> Rd (destination) index * 4 // Helper macros for loading value / shift count -#define VALUE_LOAD_IMM \ - EMIT2(and, KONST(0x0F), eax) \ - EMIT2(mov, REGREF2(eax,4), eax) \ - EMIT2(shr, KONST(7), ecx) \ - EMIT2(and, KONST(0x1F), ecx) -#define VALUE_LOAD_REG \ - EMIT2(and, KONST(0x0F), eax) \ - EMIT2(cmp, KONST(0x0F), eax) \ - EMIT2(mov, REGREF2(eax,4), eax) \ - EMIT1(jne, LABELREF(3,f)) \ - EMIT2(add, KONST(4), eax) \ - LABEL(3) \ - EMIT2(movzx, ch, ecx) \ - EMIT2(and, KONST(0x0F), ecx) \ - EMIT2(mov, REGREF2(ecx,4), ecx) +#define VALUE_LOAD_IMM \ + EMIT2(and, KONST(0x0F), eax) \ + EMIT2(mov, REGREF2(eax, 4), eax) \ + EMIT2(shr, KONST(7), ecx) \ + EMIT2(and, KONST(0x1F), ecx) +#define VALUE_LOAD_REG \ + EMIT2(and, KONST(0x0F), eax) \ + EMIT2(cmp, KONST(0x0F), eax) \ + EMIT2(mov, REGREF2(eax, 4), eax) \ + EMIT1(jne, LABELREF(3, f)) \ + EMIT2(add, KONST(4), eax) \ + LABEL(3) \ + EMIT2(movzx, ch, ecx) \ + EMIT2(and, KONST(0x0F), ecx) \ + EMIT2(mov, REGREF2(ecx, 4), ecx) // Helper macros for setting flags -#define SETCOND_LOGICAL \ - EMIT1(sets, VAR(N_FLAG)) \ - EMIT1(setz, VAR(Z_FLAG)) \ +#define SETCOND_LOGICAL \ + EMIT1(sets, VAR(N_FLAG)) \ + EMIT1(setz, VAR(Z_FLAG)) \ EMIT2(mov, bl, VAR(C_FLAG)) -#define SETCOND_ADD \ - EMIT1(sets, VAR(N_FLAG)) \ - EMIT1(setz, VAR(Z_FLAG)) \ - EMIT1(seto, VAR(V_FLAG)) \ +#define SETCOND_ADD \ + EMIT1(sets, VAR(N_FLAG)) \ + EMIT1(setz, VAR(Z_FLAG)) \ + EMIT1(seto, VAR(V_FLAG)) \ EMIT1(setc, VAR(C_FLAG)) -#define SETCOND_SUB \ - EMIT1(sets, VAR(N_FLAG)) \ - EMIT1(setz, VAR(Z_FLAG)) \ - EMIT1(seto, VAR(V_FLAG)) \ +#define SETCOND_SUB \ + EMIT1(sets, VAR(N_FLAG)) \ + EMIT1(setz, VAR(Z_FLAG)) \ + EMIT1(seto, VAR(V_FLAG)) \ EMIT1(setnc, VAR(C_FLAG)) // ALU initialization -#define ALU_INIT(LOAD_C_FLAG) \ - ALU_HEADER \ - LOAD_C_FLAG \ - EMIT2(mov, ecx, edx) \ - EMIT2(shr, KONST(14), edx) \ - EMIT2(mov, ecx, eax) \ - EMIT2(mov, ecx, esi) \ - EMIT2(shr, KONST(10), esi) \ - EMIT2(and, KONST(0x3C), edx) \ - EMIT2(mov, REGREF1(edx), edx) \ +#define ALU_INIT(LOAD_C_FLAG) \ + ALU_HEADER \ + LOAD_C_FLAG \ + EMIT2(mov, ecx, edx) \ + EMIT2(shr, KONST(14), edx) \ + EMIT2(mov, ecx, eax) \ + EMIT2(mov, ecx, esi) \ + EMIT2(shr, KONST(10), esi) \ + EMIT2(and, KONST(0x3C), edx) \ + EMIT2(mov, REGREF1(edx), edx) \ EMIT2(and, KONST(0x3C), esi) #define LOAD_C_FLAG_YES EMIT2(mov, VAR(C_FLAG), bl) -#define LOAD_C_FLAG_NO /*nothing*/ +#define LOAD_C_FLAG_NO /*nothing*/ #define ALU_INIT_C ALU_INIT(LOAD_C_FLAG_YES) #define ALU_INIT_NC ALU_INIT(LOAD_C_FLAG_NO) @@ -406,350 +400,342 @@ static void count(u32 opcode, int cond_res) // according to the value // OP Rd,Rb,Rm LSL # -#define VALUE_LSL_IMM_C \ - VALUE_LOAD_IMM \ - EMIT1(jnz, LABELREF(1,f)) \ - EMIT1(jmp, LABELREF(0,f)) \ - LABEL(1) \ - EMIT2(shl, cl, eax) \ - EMIT1(setc, bl) \ +#define VALUE_LSL_IMM_C \ + VALUE_LOAD_IMM \ + EMIT1(jnz, LABELREF(1, f)) \ + EMIT1(jmp, LABELREF(0, f)) \ + LABEL(1) \ + EMIT2(shl, cl, eax) \ + EMIT1(setc, bl) \ LABEL(0) #define VALUE_LSL_IMM_NC \ - VALUE_LOAD_IMM \ + VALUE_LOAD_IMM \ EMIT2(shl, cl, eax) // OP Rd,Rb,Rm LSL Rs -#define VALUE_LSL_REG_C \ - VALUE_LOAD_REG \ - EMIT2(test, cl, cl) \ - EMIT1(jz, LABELREF(0,f)) \ - EMIT2(cmp, KONST(0x20), cl) \ - EMIT1(je, LABELREF(1,f)) \ - EMIT1(ja, LABELREF(2,f)) \ - EMIT2(shl, cl, eax) \ - EMIT1(setc, bl) \ - EMIT1(jmp, LABELREF(0,f)) \ - LABEL(1) \ - EMIT2(test, KONST(1), al) \ - EMIT1(setnz, bl) \ - EMIT2(xor, eax, eax) \ - EMIT1(jmp, LABELREF(0,f)) \ - LABEL(2) \ - EMIT2(xor, ebx, ebx) \ - EMIT2(xor, eax, eax) \ +#define VALUE_LSL_REG_C \ + VALUE_LOAD_REG \ + EMIT2(test, cl, cl) \ + EMIT1(jz, LABELREF(0, f)) \ + EMIT2(cmp, KONST(0x20), cl) \ + EMIT1(je, LABELREF(1, f)) \ + EMIT1(ja, LABELREF(2, f)) \ + EMIT2(shl, cl, eax) \ + EMIT1(setc, bl) \ + EMIT1(jmp, LABELREF(0, f)) \ + LABEL(1) \ + EMIT2(test, KONST(1), al) \ + EMIT1(setnz, bl) \ + EMIT2 (xor, eax, eax) \ + EMIT1(jmp, LABELREF(0, f)) \ + LABEL(2) \ + EMIT2 (xor, ebx, ebx) \ + EMIT2 (xor, eax, eax) \ LABEL(0) -#define VALUE_LSL_REG_NC \ - VALUE_LOAD_REG \ - EMIT2(cmp, KONST(0x20), cl) \ - EMIT1(jae, LABELREF(1,f)) \ - EMIT2(shl, cl, eax) \ - EMIT1(jmp, LABELREF(0,f)) \ - LABEL(1) \ - EMIT2(xor, eax, eax) \ +#define VALUE_LSL_REG_NC \ + VALUE_LOAD_REG \ + EMIT2(cmp, KONST(0x20), cl) \ + EMIT1(jae, LABELREF(1, f)) \ + EMIT2(shl, cl, eax) \ + EMIT1(jmp, LABELREF(0, f)) \ + LABEL(1) \ + EMIT2 (xor, eax, eax) \ LABEL(0) // OP Rd,Rb,Rm LSR # -#define VALUE_LSR_IMM_C \ - VALUE_LOAD_IMM \ - EMIT1(jz, LABELREF(1,f)) \ - EMIT2(shr, cl, eax) \ - EMIT1(setc, bl) \ - EMIT1(jmp, LABELREF(0,f)) \ - LABEL(1) \ - EMIT2(test, eax, eax) \ - EMIT1(sets, bl) \ - EMIT2(xor, eax, eax) \ +#define VALUE_LSR_IMM_C \ + VALUE_LOAD_IMM \ + EMIT1(jz, LABELREF(1, f)) \ + EMIT2(shr, cl, eax) \ + EMIT1(setc, bl) \ + EMIT1(jmp, LABELREF(0, f)) \ + LABEL(1) \ + EMIT2(test, eax, eax) \ + EMIT1(sets, bl) \ + EMIT2 (xor, eax, eax) \ LABEL(0) -#define VALUE_LSR_IMM_NC \ - VALUE_LOAD_IMM \ - EMIT1(jz, LABELREF(1,f)) \ - EMIT2(shr, cl, eax) \ - EMIT1(jmp, LABELREF(0,f)) \ - LABEL(1) \ - EMIT2(xor, eax, eax) \ +#define VALUE_LSR_IMM_NC \ + VALUE_LOAD_IMM \ + EMIT1(jz, LABELREF(1, f)) \ + EMIT2(shr, cl, eax) \ + EMIT1(jmp, LABELREF(0, f)) \ + LABEL(1) \ + EMIT2 (xor, eax, eax) \ LABEL(0) // OP Rd,Rb,Rm LSR Rs -#define VALUE_LSR_REG_C \ - VALUE_LOAD_REG \ - EMIT2(test, cl, cl) \ - EMIT1(jz, LABELREF(0,f)) \ - EMIT2(cmp, KONST(0x20), cl) \ - EMIT1(je, LABELREF(1,f)) \ - EMIT1(ja, LABELREF(2,f)) \ - EMIT2(shr, cl, eax) \ - EMIT1(setc, bl) \ - EMIT1(jmp, LABELREF(0,f)) \ - LABEL(1) \ - EMIT2(test, eax, eax) \ - EMIT1(sets, bl) \ - EMIT2(xor, eax, eax) \ - EMIT1(jmp, LABELREF(0,f)) \ - LABEL(2) \ - EMIT2(xor, ebx, ebx) \ - EMIT2(xor, eax, eax) \ +#define VALUE_LSR_REG_C \ + VALUE_LOAD_REG \ + EMIT2(test, cl, cl) \ + EMIT1(jz, LABELREF(0, f)) \ + EMIT2(cmp, KONST(0x20), cl) \ + EMIT1(je, LABELREF(1, f)) \ + EMIT1(ja, LABELREF(2, f)) \ + EMIT2(shr, cl, eax) \ + EMIT1(setc, bl) \ + EMIT1(jmp, LABELREF(0, f)) \ + LABEL(1) \ + EMIT2(test, eax, eax) \ + EMIT1(sets, bl) \ + EMIT2 (xor, eax, eax) \ + EMIT1(jmp, LABELREF(0, f)) \ + LABEL(2) \ + EMIT2 (xor, ebx, ebx) \ + EMIT2 (xor, eax, eax) \ LABEL(0) -#define VALUE_LSR_REG_NC \ - VALUE_LOAD_REG \ - EMIT2(cmp, KONST(0x20), cl) \ - EMIT1(jae, LABELREF(1,f)) \ - EMIT2(shr, cl, eax) \ - EMIT1(jmp, LABELREF(0,f)) \ - LABEL(1) \ - EMIT2(xor, eax, eax) \ +#define VALUE_LSR_REG_NC \ + VALUE_LOAD_REG \ + EMIT2(cmp, KONST(0x20), cl) \ + EMIT1(jae, LABELREF(1, f)) \ + EMIT2(shr, cl, eax) \ + EMIT1(jmp, LABELREF(0, f)) \ + LABEL(1) \ + EMIT2 (xor, eax, eax) \ LABEL(0) // OP Rd,Rb,Rm ASR # -#define VALUE_ASR_IMM_C \ - VALUE_LOAD_IMM \ - EMIT1(jz, LABELREF(1,f)) \ - EMIT2(sar, cl, eax) \ - EMIT1(setc, bl) \ - EMIT1(jmp, LABELREF(0,f)) \ - LABEL(1) \ - EMIT2(sar, KONST(31), eax) \ - EMIT1(sets, bl) \ +#define VALUE_ASR_IMM_C \ + VALUE_LOAD_IMM \ + EMIT1(jz, LABELREF(1, f)) \ + EMIT2(sar, cl, eax) \ + EMIT1(setc, bl) \ + EMIT1(jmp, LABELREF(0, f)) \ + LABEL(1) \ + EMIT2(sar, KONST(31), eax) \ + EMIT1(sets, bl) \ LABEL(0) -#define VALUE_ASR_IMM_NC \ - VALUE_LOAD_IMM \ - EMIT1(jz, LABELREF(1,f)) \ - EMIT2(sar, cl, eax) \ - EMIT1(jmp, LABELREF(0,f)) \ - LABEL(1) \ - EMIT2(sar, KONST(31), eax) \ +#define VALUE_ASR_IMM_NC \ + VALUE_LOAD_IMM \ + EMIT1(jz, LABELREF(1, f)) \ + EMIT2(sar, cl, eax) \ + EMIT1(jmp, LABELREF(0, f)) \ + LABEL(1) \ + EMIT2(sar, KONST(31), eax) \ LABEL(0) // OP Rd,Rb,Rm ASR Rs -#define VALUE_ASR_REG_C \ - VALUE_LOAD_REG \ - EMIT2(test, cl, cl) \ - EMIT1(jz, LABELREF(0,f)) \ - EMIT2(cmp, KONST(0x20), cl) \ - EMIT1(jae, LABELREF(1,f)) \ - EMIT2(sar, cl, eax) \ - EMIT1(setc, bl) \ - EMIT1(jmp, LABELREF(0,f)) \ - LABEL(1) \ - EMIT2(sar, KONST(31), eax) \ - EMIT1(sets, bl) \ +#define VALUE_ASR_REG_C \ + VALUE_LOAD_REG \ + EMIT2(test, cl, cl) \ + EMIT1(jz, LABELREF(0, f)) \ + EMIT2(cmp, KONST(0x20), cl) \ + EMIT1(jae, LABELREF(1, f)) \ + EMIT2(sar, cl, eax) \ + EMIT1(setc, bl) \ + EMIT1(jmp, LABELREF(0, f)) \ + LABEL(1) \ + EMIT2(sar, KONST(31), eax) \ + EMIT1(sets, bl) \ LABEL(0) -#define VALUE_ASR_REG_NC \ - VALUE_LOAD_REG \ - EMIT2(cmp, KONST(0x20), cl) \ - EMIT1(jae, LABELREF(1,f)) \ - EMIT2(sar, cl, eax) \ - EMIT1(jmp, LABELREF(0,f)) \ - LABEL(1) \ - EMIT2(sar, KONST(31), eax) \ +#define VALUE_ASR_REG_NC \ + VALUE_LOAD_REG \ + EMIT2(cmp, KONST(0x20), cl) \ + EMIT1(jae, LABELREF(1, f)) \ + EMIT2(sar, cl, eax) \ + EMIT1(jmp, LABELREF(0, f)) \ + LABEL(1) \ + EMIT2(sar, KONST(31), eax) \ LABEL(0) // OP Rd,Rb,Rm ROR # -#define VALUE_ROR_IMM_C \ - VALUE_LOAD_IMM \ - EMIT1(jz, LABELREF(1,f)) \ - EMIT2(ror, cl, eax) \ - EMIT1(jmp, LABELREF(0,f)) \ - LABEL(1) \ - EMIT2(bt, KONST(0), ebx) \ - EMIT2(rcr, KONST(1), eax) \ - LABEL(0) \ +#define VALUE_ROR_IMM_C \ + VALUE_LOAD_IMM \ + EMIT1(jz, LABELREF(1, f)) \ + EMIT2(ror, cl, eax) \ + EMIT1(jmp, LABELREF(0, f)) \ + LABEL(1) \ + EMIT2(bt, KONST(0), ebx) \ + EMIT2(rcr, KONST(1), eax) \ + LABEL(0) \ EMIT1(setc, bl) -#define VALUE_ROR_IMM_NC \ - VALUE_LOAD_IMM \ - EMIT1(jz, LABELREF(1,f)) \ - EMIT2(ror, cl, eax) \ - EMIT1(jmp, LABELREF(0,f)) \ - LABEL(1) \ - EMIT2(bt, KONST(0), VARL(C_FLAG)) \ - EMIT2(rcr, KONST(1), eax) \ +#define VALUE_ROR_IMM_NC \ + VALUE_LOAD_IMM \ + EMIT1(jz, LABELREF(1, f)) \ + EMIT2(ror, cl, eax) \ + EMIT1(jmp, LABELREF(0, f)) \ + LABEL(1) \ + EMIT2(bt, KONST(0), VARL(C_FLAG)) \ + EMIT2(rcr, KONST(1), eax) \ LABEL(0) // OP Rd,Rb,Rm ROR Rs -#define VALUE_ROR_REG_C \ - VALUE_LOAD_REG \ - EMIT2(bt, KONST(0), ebx) \ - EMIT2(ror, cl, eax) \ +#define VALUE_ROR_REG_C \ + VALUE_LOAD_REG \ + EMIT2(bt, KONST(0), ebx) \ + EMIT2(ror, cl, eax) \ EMIT1(setc, bl) #define VALUE_ROR_REG_NC \ - VALUE_LOAD_REG \ + VALUE_LOAD_REG \ EMIT2(ror, cl, eax) // OP Rd,Rb,# ROR # -#define VALUE_IMM_C \ - EMIT2(movzx, ch, ecx) \ - EMIT2(add, ecx, ecx) \ - EMIT2(movzx, al, eax) \ - EMIT2(bt, KONST(0), ebx) \ - EMIT2(ror, cl, eax) \ +#define VALUE_IMM_C \ + EMIT2(movzx, ch, ecx) \ + EMIT2(add, ecx, ecx) \ + EMIT2(movzx, al, eax) \ + EMIT2(bt, KONST(0), ebx) \ + EMIT2(ror, cl, eax) \ EMIT1(setc, bl) -#define VALUE_IMM_NC \ - EMIT2(movzx, ch, ecx) \ - EMIT2(add, ecx, ecx) \ - EMIT2(movzx, al, eax) \ +#define VALUE_IMM_NC \ + EMIT2(movzx, ch, ecx) \ + EMIT2(add, ecx, ecx) \ + EMIT2(movzx, al, eax) \ EMIT2(ror, cl, eax) // Macros to perform ALU ops // Set condition codes iff the destination register is not R15 (PC) -#define CHECK_PC(OP, SETCOND) \ - EMIT2(cmp, KONST(0x3C), esi) \ - EMIT1(je, LABELREF(8,f)) \ - OP SETCOND \ - EMIT1(jmp, LABELREF(9,f)) \ - LABEL(8) \ - OP \ - LABEL(9) +#define CHECK_PC(OP, SETCOND) \ + EMIT2(cmp, KONST(0x3C), esi) \ + EMIT1(je, LABELREF(8, f)) \ + OP SETCOND \ + EMIT1(jmp, LABELREF(9, f)) \ + LABEL(8) \ + OP \ + LABEL(9) -#define OP_AND \ - EMIT2(and, eax, edx) \ +#define OP_AND \ + EMIT2(and, eax, edx) \ EMIT2(mov, edx, REGREF1(esi)) -#define OP_ANDS CHECK_PC(OP_AND, SETCOND_LOGICAL) -#define OP_EOR \ - EMIT2(xor, eax, edx) \ +#define OP_ANDS CHECK_PC(OP_AND, SETCOND_LOGICAL) +#define OP_EOR \ + EMIT2 (xor, eax, edx) \ EMIT2(mov, edx, REGREF1(esi)) -#define OP_EORS CHECK_PC(OP_EOR, SETCOND_LOGICAL) -#define OP_SUB \ - EMIT2(sub, eax, edx) \ +#define OP_EORS CHECK_PC(OP_EOR, SETCOND_LOGICAL) +#define OP_SUB \ + EMIT2(sub, eax, edx) \ EMIT2(mov, edx, REGREF1(esi)) -#define OP_SUBS CHECK_PC(OP_SUB, SETCOND_SUB) -#define OP_RSB \ - EMIT2(sub, edx, eax) \ +#define OP_SUBS CHECK_PC(OP_SUB, SETCOND_SUB) +#define OP_RSB \ + EMIT2(sub, edx, eax) \ EMIT2(mov, eax, REGREF1(esi)) -#define OP_RSBS CHECK_PC(OP_RSB, SETCOND_SUB) -#define OP_ADD \ - EMIT2(add, eax, edx) \ +#define OP_RSBS CHECK_PC(OP_RSB, SETCOND_SUB) +#define OP_ADD \ + EMIT2(add, eax, edx) \ EMIT2(mov, edx, REGREF1(esi)) -#define OP_ADDS CHECK_PC(OP_ADD, SETCOND_ADD) -#define OP_ADC \ - EMIT2(bt, KONST(0), VARL(C_FLAG)) \ - EMIT2(adc, eax, edx) \ +#define OP_ADDS CHECK_PC(OP_ADD, SETCOND_ADD) +#define OP_ADC \ + EMIT2(bt, KONST(0), VARL(C_FLAG)) \ + EMIT2(adc, eax, edx) \ EMIT2(mov, edx, REGREF1(esi)) -#define OP_ADCS CHECK_PC(OP_ADC, SETCOND_ADD) -#define OP_SBC \ - EMIT2(bt, KONST(0), VARL(C_FLAG)) \ - EMIT0(cmc) \ - EMIT2(sbb, eax, edx) \ +#define OP_ADCS CHECK_PC(OP_ADC, SETCOND_ADD) +#define OP_SBC \ + EMIT2(bt, KONST(0), VARL(C_FLAG)) \ + EMIT0(cmc) \ + EMIT2(sbb, eax, edx) \ EMIT2(mov, edx, REGREF1(esi)) -#define OP_SBCS CHECK_PC(OP_SBC, SETCOND_SUB) -#define OP_RSC \ - EMIT2(bt, KONST(0), VARL(C_FLAG)) \ - EMIT0(cmc) \ - EMIT2(sbb, edx, eax) \ +#define OP_SBCS CHECK_PC(OP_SBC, SETCOND_SUB) +#define OP_RSC \ + EMIT2(bt, KONST(0), VARL(C_FLAG)) \ + EMIT0(cmc) \ + EMIT2(sbb, edx, eax) \ EMIT2(mov, eax, REGREF1(esi)) -#define OP_RSCS CHECK_PC(OP_RSC, SETCOND_SUB) -#define OP_TST \ - EMIT2(and, eax, edx) \ +#define OP_RSCS CHECK_PC(OP_RSC, SETCOND_SUB) +#define OP_TST \ + EMIT2(and, eax, edx) \ SETCOND_LOGICAL -#define OP_TEQ \ - EMIT2(xor, eax, edx) \ +#define OP_TEQ \ + EMIT2 (xor, eax, edx) \ SETCOND_LOGICAL -#define OP_CMP \ - EMIT2(sub, eax, edx) \ +#define OP_CMP \ + EMIT2(sub, eax, edx) \ SETCOND_SUB -#define OP_CMN \ - EMIT2(add, eax, edx) \ +#define OP_CMN \ + EMIT2(add, eax, edx) \ SETCOND_ADD -#define OP_ORR \ - EMIT2(or, eax, edx) \ +#define OP_ORR \ + EMIT2(or, eax, edx) \ EMIT2(mov, edx, REGREF1(esi)) -#define OP_ORRS CHECK_PC(OP_ORR, SETCOND_LOGICAL) +#define OP_ORRS CHECK_PC(OP_ORR, SETCOND_LOGICAL) #define OP_MOV \ EMIT2(mov, eax, REGREF1(esi)) -#define OP_MOVS CHECK_PC(EMIT2(test,eax,eax) EMIT2(mov,eax,REGREF1(esi)), SETCOND_LOGICAL) -#define OP_BIC \ - EMIT1(not, eax) \ - EMIT2(and, eax, edx) \ +#define OP_MOVS CHECK_PC(EMIT2(test, eax, eax) EMIT2(mov, eax, REGREF1(esi)), SETCOND_LOGICAL) +#define OP_BIC \ + EMIT1(not, eax) \ + EMIT2(and, eax, edx) \ EMIT2(mov, edx, REGREF1(esi)) -#define OP_BICS CHECK_PC(OP_BIC, SETCOND_LOGICAL) -#define OP_MVN \ - EMIT1(not, eax) \ +#define OP_BICS CHECK_PC(OP_BIC, SETCOND_LOGICAL) +#define OP_MVN \ + EMIT1(not, eax) \ EMIT2(mov, eax, REGREF1(esi)) -#define OP_MVNS CHECK_PC(OP_MVN EMIT2(test,eax,eax), SETCOND_LOGICAL) +#define OP_MVNS CHECK_PC(OP_MVN EMIT2(test, eax, eax), SETCOND_LOGICAL) // ALU cleanup macro -#define ALU_FINISH ALU_TRAILER +#define ALU_FINISH ALU_TRAILER // End of ALU macros //X//#endif //_MSC_VER #ifdef __GNUC__ -#define ROR_IMM_MSR \ - asm ("ror %%cl, %%eax;" \ - : "=a" (value) \ - : "a" (opcode & 0xFF), "c" (shift)); +#define ROR_IMM_MSR \ + asm("ror %%cl, %%eax;" \ + : "=a"(value) \ + : "a"(opcode & 0xFF), "c"(shift)); -#define ROR_OFFSET \ - asm("ror %%cl, %0" \ - : "=r" (offset) \ - : "0" (offset), "c" (shift)); +#define ROR_OFFSET \ + asm("ror %%cl, %0" \ + : "=r"(offset) \ + : "0"(offset), "c"(shift)); -#define RRX_OFFSET \ - asm(EMIT2(btl,KONST(0),VAR(C_FLAG)) \ - "rcr $1, %0" \ - : "=r" (offset) \ - : "0" (offset)); +#define RRX_OFFSET \ + asm(EMIT2(btl, KONST(0), VAR(C_FLAG)) "rcr $1, %0" \ + : "=r"(offset) \ + : "0"(offset)); -#else // !__GNUC__, i.e. Visual C++ +#else // !__GNUC__, i.e. Visual C++ -#define ROR_IMM_MSR \ +#define ROR_IMM_MSR \ __asm { \ __asm mov ecx, shift \ - __asm ror value, cl \ - } - - -#define ROR_OFFSET \ - __asm { \ - __asm mov ecx, shift \ - __asm ror offset, cl \ + __asm ror value, cl \ } -#define RRX_OFFSET \ +#define ROR_OFFSET \ + __asm { \ + __asm mov ecx, shift \ + __asm ror offset, cl \ + } + +#define RRX_OFFSET \ __asm { \ __asm bt dword ptr C_FLAG, 0 \ - __asm rcr offset, 1 \ + __asm rcr offset, 1 \ } -#endif // !__GNUC__ +#endif // !__GNUC__ -#endif // !__POWERPC__ -#endif // !C_CORE +#endif // !__POWERPC__ +#endif // !C_CORE // C core -#define C_SETCOND_LOGICAL \ - N_FLAG = ((s32)res < 0) ? true : false; \ - Z_FLAG = (res == 0) ? true : false; \ +#define C_SETCOND_LOGICAL \ + N_FLAG = ((s32)res < 0) ? true : false; \ + Z_FLAG = (res == 0) ? true : false; \ C_FLAG = C_OUT; -#define C_SETCOND_ADD \ - N_FLAG = ((s32)res < 0) ? true : false; \ - Z_FLAG = (res == 0) ? true : false; \ - V_FLAG = ((NEG(lhs) & NEG(rhs) & POS(res)) | \ - (POS(lhs) & POS(rhs) & NEG(res))) ? true : false;\ - C_FLAG = ((NEG(lhs) & NEG(rhs)) | \ - (NEG(lhs) & POS(res)) | \ - (NEG(rhs) & POS(res))) ? true : false; -#define C_SETCOND_SUB \ - N_FLAG = ((s32)res < 0) ? true : false; \ - Z_FLAG = (res == 0) ? true : false; \ - V_FLAG = ((NEG(lhs) & POS(rhs) & POS(res)) | \ - (POS(lhs) & NEG(rhs) & NEG(res))) ? true : false;\ - C_FLAG = ((NEG(lhs) & POS(rhs)) | \ - (NEG(lhs) & POS(res)) | \ - (POS(rhs) & POS(res))) ? true : false; +#define C_SETCOND_ADD \ + N_FLAG = ((s32)res < 0) ? true : false; \ + Z_FLAG = (res == 0) ? true : false; \ + V_FLAG = ((NEG(lhs) & NEG(rhs) & POS(res)) | (POS(lhs) & POS(rhs) & NEG(res))) ? true : false; \ + C_FLAG = ((NEG(lhs) & NEG(rhs)) | (NEG(lhs) & POS(res)) | (NEG(rhs) & POS(res))) ? true : false; +#define C_SETCOND_SUB \ + N_FLAG = ((s32)res < 0) ? true : false; \ + Z_FLAG = (res == 0) ? true : false; \ + V_FLAG = ((NEG(lhs) & POS(rhs) & POS(res)) | (POS(lhs) & NEG(rhs) & NEG(res))) ? true : false; \ + C_FLAG = ((NEG(lhs) & POS(rhs)) | (NEG(lhs) & POS(res)) | (POS(rhs) & POS(res))) ? true : false; #ifndef ALU_INIT_C - #define ALU_INIT_C \ - int dest = (opcode>>12) & 15; \ - bool C_OUT = C_FLAG; \ +#define ALU_INIT_C \ + int dest = (opcode >> 12) & 15; \ + bool C_OUT = C_FLAG; \ u32 value; #endif // OP Rd,Rb,Rm LSL # #ifndef VALUE_LSL_IMM_C - #define VALUE_LSL_IMM_C \ +#define VALUE_LSL_IMM_C \ unsigned int shift = (opcode >> 7) & 0x1F; \ - if (LIKELY(!shift)) { /* LSL #0 most common? */ \ + if (LIKELY(!shift)) { /* LSL #0 most common? */ \ value = reg[opcode & 0x0F].I; \ } else { \ u32 v = reg[opcode & 0x0F].I; \ @@ -759,355 +745,354 @@ static void count(u32 opcode, int cond_res) #endif // OP Rd,Rb,Rm LSL Rs #ifndef VALUE_LSL_REG_C - #define VALUE_LSL_REG_C \ - u32 shift = reg[(opcode >> 8)&15].B.B0; \ - u32 rm = reg[opcode & 0x0F].I; \ - if((opcode & 0x0F) == 15) { \ - rm += 4; \ - } \ - if (LIKELY(shift)) { \ - if (shift == 32) { \ - value = 0; \ - C_OUT = (rm & 1 ? true : false); \ - } else if (LIKELY(shift < 32)) { \ - u32 v = rm; \ - C_OUT = (v >> (32 - shift)) & 1 ? true : false; \ - value = v << shift; \ - } else { \ - value = 0; \ - C_OUT = false; \ - } \ - } else { \ - value = rm; \ +#define VALUE_LSL_REG_C \ + u32 shift = reg[(opcode >> 8) & 15].B.B0; \ + u32 rm = reg[opcode & 0x0F].I; \ + if ((opcode & 0x0F) == 15) { \ + rm += 4; \ + } \ + if (LIKELY(shift)) { \ + if (shift == 32) { \ + value = 0; \ + C_OUT = (rm & 1 ? true : false); \ + } else if (LIKELY(shift < 32)) { \ + u32 v = rm; \ + C_OUT = (v >> (32 - shift)) & 1 ? true : false; \ + value = v << shift; \ + } else { \ + value = 0; \ + C_OUT = false; \ + } \ + } else { \ + value = rm; \ } #endif // OP Rd,Rb,Rm LSR # #ifndef VALUE_LSR_IMM_C - #define VALUE_LSR_IMM_C \ - u32 shift = (opcode >> 7) & 0x1F; \ - if (LIKELY(shift)) { \ - u32 v = reg[opcode & 0x0F].I; \ - C_OUT = (v >> (shift - 1)) & 1 ? true : false; \ - value = v >> shift; \ - } else { \ - value = 0; \ - C_OUT = (reg[opcode & 0x0F].I & 0x80000000) ? true : false;\ +#define VALUE_LSR_IMM_C \ + u32 shift = (opcode >> 7) & 0x1F; \ + if (LIKELY(shift)) { \ + u32 v = reg[opcode & 0x0F].I; \ + C_OUT = (v >> (shift - 1)) & 1 ? true : false; \ + value = v >> shift; \ + } else { \ + value = 0; \ + C_OUT = (reg[opcode & 0x0F].I & 0x80000000) ? true : false; \ } #endif // OP Rd,Rb,Rm LSR Rs #ifndef VALUE_LSR_REG_C - #define VALUE_LSR_REG_C \ - unsigned int shift = reg[(opcode >> 8)&15].B.B0; \ - u32 rm = reg[opcode & 0x0F].I; \ - if((opcode & 0x0F) == 15) { \ - rm += 4; \ - } \ - if (LIKELY(shift)) { \ - if (shift == 32) { \ - value = 0; \ - C_OUT = (rm & 0x80000000 ? true : false);\ - } else if (LIKELY(shift < 32)) { \ - u32 v = rm; \ - C_OUT = (v >> (shift - 1)) & 1 ? true : false;\ - value = v >> shift; \ - } else { \ - value = 0; \ - C_OUT = false; \ - } \ - } else { \ - value = rm; \ +#define VALUE_LSR_REG_C \ + unsigned int shift = reg[(opcode >> 8) & 15].B.B0; \ + u32 rm = reg[opcode & 0x0F].I; \ + if ((opcode & 0x0F) == 15) { \ + rm += 4; \ + } \ + if (LIKELY(shift)) { \ + if (shift == 32) { \ + value = 0; \ + C_OUT = (rm & 0x80000000 ? true : false); \ + } else if (LIKELY(shift < 32)) { \ + u32 v = rm; \ + C_OUT = (v >> (shift - 1)) & 1 ? true : false; \ + value = v >> shift; \ + } else { \ + value = 0; \ + C_OUT = false; \ + } \ + } else { \ + value = rm; \ } #endif // OP Rd,Rb,Rm ASR # #ifndef VALUE_ASR_IMM_C - #define VALUE_ASR_IMM_C \ - unsigned int shift = (opcode >> 7) & 0x1F; \ - if (LIKELY(shift)) { \ +#define VALUE_ASR_IMM_C \ + unsigned int shift = (opcode >> 7) & 0x1F; \ + if (LIKELY(shift)) { \ /* VC++ BUG: u32 v; (s32)v>>n is optimized to shr! */ \ - s32 v = reg[opcode & 0x0F].I; \ - C_OUT = (v >> (int)(shift - 1)) & 1 ? true : false;\ - value = v >> (int)shift; \ - } else { \ - if (reg[opcode & 0x0F].I & 0x80000000) { \ - value = 0xFFFFFFFF; \ - C_OUT = true; \ - } else { \ - value = 0; \ - C_OUT = false; \ - } \ + s32 v = reg[opcode & 0x0F].I; \ + C_OUT = (v >> (int)(shift - 1)) & 1 ? true : false; \ + value = v >> (int)shift; \ + } else { \ + if (reg[opcode & 0x0F].I & 0x80000000) { \ + value = 0xFFFFFFFF; \ + C_OUT = true; \ + } else { \ + value = 0; \ + C_OUT = false; \ + } \ } #endif // OP Rd,Rb,Rm ASR Rs #ifndef VALUE_ASR_REG_C - #define VALUE_ASR_REG_C \ - unsigned int shift = reg[(opcode >> 8)&15].B.B0; \ - u32 rm = reg[opcode & 0x0F].I; \ - if((opcode & 0x0F) == 15) { \ - rm += 4; \ - } \ - if (LIKELY(shift < 32)) { \ - if (LIKELY(shift)) { \ - s32 v = rm; \ - C_OUT = (v >> (int)(shift - 1)) & 1 ? true : false;\ - value = v >> (int)shift; \ - } else { \ - value = rm; \ - } \ - } else { \ - if (reg[opcode & 0x0F].I & 0x80000000) { \ - value = 0xFFFFFFFF; \ - C_OUT = true; \ - } else { \ - value = 0; \ - C_OUT = false; \ - } \ +#define VALUE_ASR_REG_C \ + unsigned int shift = reg[(opcode >> 8) & 15].B.B0; \ + u32 rm = reg[opcode & 0x0F].I; \ + if ((opcode & 0x0F) == 15) { \ + rm += 4; \ + } \ + if (LIKELY(shift < 32)) { \ + if (LIKELY(shift)) { \ + s32 v = rm; \ + C_OUT = (v >> (int)(shift - 1)) & 1 ? true : false; \ + value = v >> (int)shift; \ + } else { \ + value = rm; \ + } \ + } else { \ + if (reg[opcode & 0x0F].I & 0x80000000) { \ + value = 0xFFFFFFFF; \ + C_OUT = true; \ + } else { \ + value = 0; \ + C_OUT = false; \ + } \ } #endif // OP Rd,Rb,Rm ROR # #ifndef VALUE_ROR_IMM_C - #define VALUE_ROR_IMM_C \ - unsigned int shift = (opcode >> 7) & 0x1F; \ - if (LIKELY(shift)) { \ - u32 v = reg[opcode & 0x0F].I; \ - C_OUT = (v >> (shift - 1)) & 1 ? true : false; \ - value = ((v << (32 - shift)) | \ - (v >> shift)); \ - } else { \ - u32 v = reg[opcode & 0x0F].I; \ - C_OUT = (v & 1) ? true : false; \ - value = ((v >> 1) | \ - (C_FLAG << 31)); \ +#define VALUE_ROR_IMM_C \ + unsigned int shift = (opcode >> 7) & 0x1F; \ + if (LIKELY(shift)) { \ + u32 v = reg[opcode & 0x0F].I; \ + C_OUT = (v >> (shift - 1)) & 1 ? true : false; \ + value = ((v << (32 - shift)) | (v >> shift)); \ + } else { \ + u32 v = reg[opcode & 0x0F].I; \ + C_OUT = (v & 1) ? true : false; \ + value = ((v >> 1) | (C_FLAG << 31)); \ } #endif // OP Rd,Rb,Rm ROR Rs #ifndef VALUE_ROR_REG_C - #define VALUE_ROR_REG_C \ - unsigned int shift = reg[(opcode >> 8)&15].B.B0; \ - u32 rm = reg[opcode & 0x0F].I; \ - if((opcode & 0x0F) == 15) { \ - rm += 4; \ - } \ - if (LIKELY(shift & 0x1F)) { \ - u32 v = rm; \ - C_OUT = (v >> (shift - 1)) & 1 ? true : false; \ - value = ((v << (32 - shift)) | \ - (v >> shift)); \ - } else { \ - value = rm; \ - if (shift) \ - C_OUT = (value & 0x80000000 ? true : false);\ +#define VALUE_ROR_REG_C \ + unsigned int shift = reg[(opcode >> 8) & 15].B.B0; \ + u32 rm = reg[opcode & 0x0F].I; \ + if ((opcode & 0x0F) == 15) { \ + rm += 4; \ + } \ + if (LIKELY(shift & 0x1F)) { \ + u32 v = rm; \ + C_OUT = (v >> (shift - 1)) & 1 ? true : false; \ + value = ((v << (32 - shift)) | (v >> shift)); \ + } else { \ + value = rm; \ + if (shift) \ + C_OUT = (value & 0x80000000 ? true : false); \ } #endif // OP Rd,Rb,# ROR # #ifndef VALUE_IMM_C - #define VALUE_IMM_C \ - int shift = (opcode & 0xF00) >> 7; \ - if (UNLIKELY(shift)) { \ - u32 v = opcode & 0xFF; \ - C_OUT = (v >> (shift - 1)) & 1 ? true : false; \ - value = ((v << (32 - shift)) | \ - (v >> shift)); \ - } else { \ - value = opcode & 0xFF; \ +#define VALUE_IMM_C \ + int shift = (opcode & 0xF00) >> 7; \ + if (UNLIKELY(shift)) { \ + u32 v = opcode & 0xFF; \ + C_OUT = (v >> (shift - 1)) & 1 ? true : false; \ + value = ((v << (32 - shift)) | (v >> shift)); \ + } else { \ + value = opcode & 0xFF; \ } #endif // Make the non-carry versions default to the carry versions // (this is fine for C--the compiler will optimize the dead code out) #ifndef ALU_INIT_NC - #define ALU_INIT_NC ALU_INIT_C +#define ALU_INIT_NC ALU_INIT_C #endif #ifndef VALUE_LSL_IMM_NC - #define VALUE_LSL_IMM_NC VALUE_LSL_IMM_C +#define VALUE_LSL_IMM_NC VALUE_LSL_IMM_C #endif #ifndef VALUE_LSL_REG_NC - #define VALUE_LSL_REG_NC VALUE_LSL_REG_C +#define VALUE_LSL_REG_NC VALUE_LSL_REG_C #endif #ifndef VALUE_LSR_IMM_NC - #define VALUE_LSR_IMM_NC VALUE_LSR_IMM_C +#define VALUE_LSR_IMM_NC VALUE_LSR_IMM_C #endif #ifndef VALUE_LSR_REG_NC - #define VALUE_LSR_REG_NC VALUE_LSR_REG_C +#define VALUE_LSR_REG_NC VALUE_LSR_REG_C #endif #ifndef VALUE_ASR_IMM_NC - #define VALUE_ASR_IMM_NC VALUE_ASR_IMM_C +#define VALUE_ASR_IMM_NC VALUE_ASR_IMM_C #endif #ifndef VALUE_ASR_REG_NC - #define VALUE_ASR_REG_NC VALUE_ASR_REG_C +#define VALUE_ASR_REG_NC VALUE_ASR_REG_C #endif #ifndef VALUE_ROR_IMM_NC - #define VALUE_ROR_IMM_NC VALUE_ROR_IMM_C +#define VALUE_ROR_IMM_NC VALUE_ROR_IMM_C #endif #ifndef VALUE_ROR_REG_NC - #define VALUE_ROR_REG_NC VALUE_ROR_REG_C +#define VALUE_ROR_REG_NC VALUE_ROR_REG_C #endif #ifndef VALUE_IMM_NC - #define VALUE_IMM_NC VALUE_IMM_C +#define VALUE_IMM_NC VALUE_IMM_C #endif -#define C_CHECK_PC(SETCOND) if (LIKELY(dest != 15)) { SETCOND } +#define C_CHECK_PC(SETCOND) \ + if (LIKELY(dest != 15)) { \ + SETCOND \ + } #ifndef OP_AND - #define OP_AND \ - u32 res = reg[(opcode>>16)&15].I & value; \ +#define OP_AND \ + u32 res = reg[(opcode >> 16) & 15].I & value; \ reg[dest].I = res; #endif #ifndef OP_ANDS - #define OP_ANDS OP_AND C_CHECK_PC(C_SETCOND_LOGICAL) +#define OP_ANDS OP_AND C_CHECK_PC(C_SETCOND_LOGICAL) #endif #ifndef OP_EOR - #define OP_EOR \ - u32 res = reg[(opcode>>16)&15].I ^ value; \ +#define OP_EOR \ + u32 res = reg[(opcode >> 16) & 15].I ^ value; \ reg[dest].I = res; #endif #ifndef OP_EORS - #define OP_EORS OP_EOR C_CHECK_PC(C_SETCOND_LOGICAL) +#define OP_EORS OP_EOR C_CHECK_PC(C_SETCOND_LOGICAL) #endif #ifndef OP_SUB - #define OP_SUB \ - u32 lhs = reg[(opcode>>16)&15].I; \ - u32 rhs = value; \ - u32 res = lhs - rhs; \ +#define OP_SUB \ + u32 lhs = reg[(opcode >> 16) & 15].I; \ + u32 rhs = value; \ + u32 res = lhs - rhs; \ reg[dest].I = res; #endif #ifndef OP_SUBS - #define OP_SUBS OP_SUB C_CHECK_PC(C_SETCOND_SUB) +#define OP_SUBS OP_SUB C_CHECK_PC(C_SETCOND_SUB) #endif #ifndef OP_RSB - #define OP_RSB \ - u32 lhs = value; \ - u32 rhs = reg[(opcode>>16)&15].I; \ - u32 res = lhs - rhs; \ +#define OP_RSB \ + u32 lhs = value; \ + u32 rhs = reg[(opcode >> 16) & 15].I; \ + u32 res = lhs - rhs; \ reg[dest].I = res; #endif #ifndef OP_RSBS - #define OP_RSBS OP_RSB C_CHECK_PC(C_SETCOND_SUB) +#define OP_RSBS OP_RSB C_CHECK_PC(C_SETCOND_SUB) #endif #ifndef OP_ADD - #define OP_ADD \ - u32 lhs = reg[(opcode>>16)&15].I; \ - u32 rhs = value; \ - u32 res = lhs + rhs; \ +#define OP_ADD \ + u32 lhs = reg[(opcode >> 16) & 15].I; \ + u32 rhs = value; \ + u32 res = lhs + rhs; \ reg[dest].I = res; #endif #ifndef OP_ADDS - #define OP_ADDS OP_ADD C_CHECK_PC(C_SETCOND_ADD) +#define OP_ADDS OP_ADD C_CHECK_PC(C_SETCOND_ADD) #endif #ifndef OP_ADC - #define OP_ADC \ - u32 lhs = reg[(opcode>>16)&15].I; \ - u32 rhs = value; \ - u32 res = lhs + rhs + (u32)C_FLAG; \ +#define OP_ADC \ + u32 lhs = reg[(opcode >> 16) & 15].I; \ + u32 rhs = value; \ + u32 res = lhs + rhs + (u32)C_FLAG; \ reg[dest].I = res; #endif #ifndef OP_ADCS - #define OP_ADCS OP_ADC C_CHECK_PC(C_SETCOND_ADD) +#define OP_ADCS OP_ADC C_CHECK_PC(C_SETCOND_ADD) #endif #ifndef OP_SBC - #define OP_SBC \ - u32 lhs = reg[(opcode>>16)&15].I; \ - u32 rhs = value; \ - u32 res = lhs - rhs - !((u32)C_FLAG); \ +#define OP_SBC \ + u32 lhs = reg[(opcode >> 16) & 15].I; \ + u32 rhs = value; \ + u32 res = lhs - rhs - !((u32)C_FLAG); \ reg[dest].I = res; #endif #ifndef OP_SBCS - #define OP_SBCS OP_SBC C_CHECK_PC(C_SETCOND_SUB) +#define OP_SBCS OP_SBC C_CHECK_PC(C_SETCOND_SUB) #endif #ifndef OP_RSC - #define OP_RSC \ - u32 lhs = value; \ - u32 rhs = reg[(opcode>>16)&15].I; \ - u32 res = lhs - rhs - !((u32)C_FLAG); \ +#define OP_RSC \ + u32 lhs = value; \ + u32 rhs = reg[(opcode >> 16) & 15].I; \ + u32 res = lhs - rhs - !((u32)C_FLAG); \ reg[dest].I = res; #endif #ifndef OP_RSCS - #define OP_RSCS OP_RSC C_CHECK_PC(C_SETCOND_SUB) +#define OP_RSCS OP_RSC C_CHECK_PC(C_SETCOND_SUB) #endif #ifndef OP_TST - #define OP_TST \ - u32 res = reg[(opcode >> 16) & 0x0F].I & value; \ +#define OP_TST \ + u32 res = reg[(opcode >> 16) & 0x0F].I & value; \ C_SETCOND_LOGICAL; #endif #ifndef OP_TEQ - #define OP_TEQ \ - u32 res = reg[(opcode >> 16) & 0x0F].I ^ value; \ +#define OP_TEQ \ + u32 res = reg[(opcode >> 16) & 0x0F].I ^ value; \ C_SETCOND_LOGICAL; #endif #ifndef OP_CMP - #define OP_CMP \ - u32 lhs = reg[(opcode>>16)&15].I; \ - u32 rhs = value; \ - u32 res = lhs - rhs; \ +#define OP_CMP \ + u32 lhs = reg[(opcode >> 16) & 15].I; \ + u32 rhs = value; \ + u32 res = lhs - rhs; \ C_SETCOND_SUB; #endif #ifndef OP_CMN - #define OP_CMN \ - u32 lhs = reg[(opcode>>16)&15].I; \ - u32 rhs = value; \ - u32 res = lhs + rhs; \ +#define OP_CMN \ + u32 lhs = reg[(opcode >> 16) & 15].I; \ + u32 rhs = value; \ + u32 res = lhs + rhs; \ C_SETCOND_ADD; #endif #ifndef OP_ORR - #define OP_ORR \ - u32 res = reg[(opcode >> 16) & 0x0F].I | value; \ +#define OP_ORR \ + u32 res = reg[(opcode >> 16) & 0x0F].I | value; \ reg[dest].I = res; #endif #ifndef OP_ORRS - #define OP_ORRS OP_ORR C_CHECK_PC(C_SETCOND_LOGICAL) +#define OP_ORRS OP_ORR C_CHECK_PC(C_SETCOND_LOGICAL) #endif #ifndef OP_MOV - #define OP_MOV \ - u32 res = value; \ +#define OP_MOV \ + u32 res = value; \ reg[dest].I = res; #endif #ifndef OP_MOVS - #define OP_MOVS OP_MOV C_CHECK_PC(C_SETCOND_LOGICAL) +#define OP_MOVS OP_MOV C_CHECK_PC(C_SETCOND_LOGICAL) #endif #ifndef OP_BIC - #define OP_BIC \ - u32 res = reg[(opcode >> 16) & 0x0F].I & (~value); \ +#define OP_BIC \ + u32 res = reg[(opcode >> 16) & 0x0F].I & (~value); \ reg[dest].I = res; #endif #ifndef OP_BICS - #define OP_BICS OP_BIC C_CHECK_PC(C_SETCOND_LOGICAL) +#define OP_BICS OP_BIC C_CHECK_PC(C_SETCOND_LOGICAL) #endif #ifndef OP_MVN - #define OP_MVN \ - u32 res = ~value; \ +#define OP_MVN \ + u32 res = ~value; \ reg[dest].I = res; #endif #ifndef OP_MVNS - #define OP_MVNS OP_MVN C_CHECK_PC(C_SETCOND_LOGICAL) +#define OP_MVNS OP_MVN C_CHECK_PC(C_SETCOND_LOGICAL) #endif #ifndef SETCOND_NONE - #define SETCOND_NONE /*nothing*/ +#define SETCOND_NONE /*nothing*/ #endif #ifndef SETCOND_MUL - #define SETCOND_MUL \ - N_FLAG = ((s32)reg[dest].I < 0) ? true : false; \ - Z_FLAG = reg[dest].I ? false : true; +#define SETCOND_MUL \ + N_FLAG = ((s32)reg[dest].I < 0) ? true : false; \ + Z_FLAG = reg[dest].I ? false : true; #endif #ifndef SETCOND_MULL - #define SETCOND_MULL \ - N_FLAG = (reg[dest].I & 0x80000000) ? true : false;\ - Z_FLAG = reg[dest].I || reg[acc].I ? false : true; +#define SETCOND_MULL \ + N_FLAG = (reg[dest].I & 0x80000000) ? true : false; \ + Z_FLAG = reg[dest].I || reg[acc].I ? false : true; #endif #ifndef ALU_FINISH - #define ALU_FINISH /*nothing*/ +#define ALU_FINISH /*nothing*/ #endif #ifndef ROR_IMM_MSR - #define ROR_IMM_MSR \ - u32 v = opcode & 0xff; \ +#define ROR_IMM_MSR \ + u32 v = opcode & 0xff; \ value = ((v << (32 - shift)) | (v >> shift)); #endif #ifndef ROR_OFFSET - #define ROR_OFFSET \ +#define ROR_OFFSET \ offset = ((offset << (32 - shift)) | (offset >> shift)); #endif #ifndef RRX_OFFSET - #define RRX_OFFSET \ +#define RRX_OFFSET \ offset = ((offset >> 1) | ((int)C_FLAG << 31)); #endif @@ -1120,165 +1105,165 @@ static void count(u32 opcode, int cond_res) // ISREGSHIFT: 1 for insns of the form ...,Rn LSL/etc Rs; 0 otherwise // ALU_INIT, GETVALUE, OP, and ALU_FINISH are concatenated in order. #define ALU_INSN(ALU_INIT, GETVALUE, OP, MODECHANGE, ISREGSHIFT) \ - ALU_INIT GETVALUE OP ALU_FINISH; \ - if (LIKELY((opcode & 0x0000F000) != 0x0000F000)) { \ - clockTicks = 1 + ISREGSHIFT \ - + codeTicksAccessSeq32(armNextPC); \ - } else { \ - MODECHANGE; \ - if (armState) { \ - reg[15].I &= 0xFFFFFFFC; \ - armNextPC = reg[15].I; \ - reg[15].I += 4; \ - ARM_PREFETCH; \ - } else { \ - reg[15].I &= 0xFFFFFFFE; \ - armNextPC = reg[15].I; \ - reg[15].I += 2; \ - THUMB_PREFETCH; \ - } \ - clockTicks = 3 + ISREGSHIFT \ - + codeTicksAccess32(armNextPC) \ - + codeTicksAccessSeq32(armNextPC) \ - + codeTicksAccessSeq32(armNextPC); \ + ALU_INIT GETVALUE OP ALU_FINISH; \ + if (LIKELY((opcode & 0x0000F000) != 0x0000F000)) { \ + clockTicks = 1 + ISREGSHIFT \ + + codeTicksAccessSeq32(armNextPC); \ + } else { \ + MODECHANGE; \ + if (armState) { \ + reg[15].I &= 0xFFFFFFFC; \ + armNextPC = reg[15].I; \ + reg[15].I += 4; \ + ARM_PREFETCH; \ + } else { \ + reg[15].I &= 0xFFFFFFFE; \ + armNextPC = reg[15].I; \ + reg[15].I += 2; \ + THUMB_PREFETCH; \ + } \ + clockTicks = 3 + ISREGSHIFT \ + + codeTicksAccess32(armNextPC) \ + + codeTicksAccessSeq32(armNextPC) \ + + codeTicksAccessSeq32(armNextPC); \ } -#define MODECHANGE_NO /*nothing*/ +#define MODECHANGE_NO /*nothing*/ #define MODECHANGE_YES CPUSwitchMode(reg[17].I & 0x1f, false); -#define DEFINE_ALU_INSN_C(CODE1, CODE2, OP, MODECHANGE) \ - static INSN_REGPARM void arm##CODE1##0(u32 opcode) { ALU_INSN(ALU_INIT_C, VALUE_LSL_IMM_C, OP_##OP, MODECHANGE_##MODECHANGE, 0); }\ - static INSN_REGPARM void arm##CODE1##1(u32 opcode) { ALU_INSN(ALU_INIT_C, VALUE_LSL_REG_C, OP_##OP, MODECHANGE_##MODECHANGE, 1); }\ - static INSN_REGPARM void arm##CODE1##2(u32 opcode) { ALU_INSN(ALU_INIT_C, VALUE_LSR_IMM_C, OP_##OP, MODECHANGE_##MODECHANGE, 0); }\ - static INSN_REGPARM void arm##CODE1##3(u32 opcode) { ALU_INSN(ALU_INIT_C, VALUE_LSR_REG_C, OP_##OP, MODECHANGE_##MODECHANGE, 1); }\ - static INSN_REGPARM void arm##CODE1##4(u32 opcode) { ALU_INSN(ALU_INIT_C, VALUE_ASR_IMM_C, OP_##OP, MODECHANGE_##MODECHANGE, 0); }\ - static INSN_REGPARM void arm##CODE1##5(u32 opcode) { ALU_INSN(ALU_INIT_C, VALUE_ASR_REG_C, OP_##OP, MODECHANGE_##MODECHANGE, 1); }\ - static INSN_REGPARM void arm##CODE1##6(u32 opcode) { ALU_INSN(ALU_INIT_C, VALUE_ROR_IMM_C, OP_##OP, MODECHANGE_##MODECHANGE, 0); }\ - static INSN_REGPARM void arm##CODE1##7(u32 opcode) { ALU_INSN(ALU_INIT_C, VALUE_ROR_REG_C, OP_##OP, MODECHANGE_##MODECHANGE, 1); }\ - static INSN_REGPARM void arm##CODE2##0(u32 opcode) { ALU_INSN(ALU_INIT_C, VALUE_IMM_C, OP_##OP, MODECHANGE_##MODECHANGE, 0); } -#define DEFINE_ALU_INSN_NC(CODE1, CODE2, OP, MODECHANGE) \ - static INSN_REGPARM void arm##CODE1##0(u32 opcode) { ALU_INSN(ALU_INIT_NC, VALUE_LSL_IMM_NC, OP_##OP, MODECHANGE_##MODECHANGE, 0); }\ - static INSN_REGPARM void arm##CODE1##1(u32 opcode) { ALU_INSN(ALU_INIT_NC, VALUE_LSL_REG_NC, OP_##OP, MODECHANGE_##MODECHANGE, 1); }\ - static INSN_REGPARM void arm##CODE1##2(u32 opcode) { ALU_INSN(ALU_INIT_NC, VALUE_LSR_IMM_NC, OP_##OP, MODECHANGE_##MODECHANGE, 0); }\ - static INSN_REGPARM void arm##CODE1##3(u32 opcode) { ALU_INSN(ALU_INIT_NC, VALUE_LSR_REG_NC, OP_##OP, MODECHANGE_##MODECHANGE, 1); }\ - static INSN_REGPARM void arm##CODE1##4(u32 opcode) { ALU_INSN(ALU_INIT_NC, VALUE_ASR_IMM_NC, OP_##OP, MODECHANGE_##MODECHANGE, 0); }\ - static INSN_REGPARM void arm##CODE1##5(u32 opcode) { ALU_INSN(ALU_INIT_NC, VALUE_ASR_REG_NC, OP_##OP, MODECHANGE_##MODECHANGE, 1); }\ - static INSN_REGPARM void arm##CODE1##6(u32 opcode) { ALU_INSN(ALU_INIT_NC, VALUE_ROR_IMM_NC, OP_##OP, MODECHANGE_##MODECHANGE, 0); }\ - static INSN_REGPARM void arm##CODE1##7(u32 opcode) { ALU_INSN(ALU_INIT_NC, VALUE_ROR_REG_NC, OP_##OP, MODECHANGE_##MODECHANGE, 1); }\ - static INSN_REGPARM void arm##CODE2##0(u32 opcode) { ALU_INSN(ALU_INIT_NC, VALUE_IMM_NC, OP_##OP, MODECHANGE_##MODECHANGE, 0); } +#define DEFINE_ALU_INSN_C(CODE1, CODE2, OP, MODECHANGE) \ + static INSN_REGPARM void arm##CODE1##0(u32 opcode) { ALU_INSN(ALU_INIT_C, VALUE_LSL_IMM_C, OP_##OP, MODECHANGE_##MODECHANGE, 0); } \ + static INSN_REGPARM void arm##CODE1##1(u32 opcode) { ALU_INSN(ALU_INIT_C, VALUE_LSL_REG_C, OP_##OP, MODECHANGE_##MODECHANGE, 1); } \ + static INSN_REGPARM void arm##CODE1##2(u32 opcode) { ALU_INSN(ALU_INIT_C, VALUE_LSR_IMM_C, OP_##OP, MODECHANGE_##MODECHANGE, 0); } \ + static INSN_REGPARM void arm##CODE1##3(u32 opcode) { ALU_INSN(ALU_INIT_C, VALUE_LSR_REG_C, OP_##OP, MODECHANGE_##MODECHANGE, 1); } \ + static INSN_REGPARM void arm##CODE1##4(u32 opcode) { ALU_INSN(ALU_INIT_C, VALUE_ASR_IMM_C, OP_##OP, MODECHANGE_##MODECHANGE, 0); } \ + static INSN_REGPARM void arm##CODE1##5(u32 opcode) { ALU_INSN(ALU_INIT_C, VALUE_ASR_REG_C, OP_##OP, MODECHANGE_##MODECHANGE, 1); } \ + static INSN_REGPARM void arm##CODE1##6(u32 opcode) { ALU_INSN(ALU_INIT_C, VALUE_ROR_IMM_C, OP_##OP, MODECHANGE_##MODECHANGE, 0); } \ + static INSN_REGPARM void arm##CODE1##7(u32 opcode) { ALU_INSN(ALU_INIT_C, VALUE_ROR_REG_C, OP_##OP, MODECHANGE_##MODECHANGE, 1); } \ + static INSN_REGPARM void arm##CODE2##0(u32 opcode) { ALU_INSN(ALU_INIT_C, VALUE_IMM_C, OP_##OP, MODECHANGE_##MODECHANGE, 0); } +#define DEFINE_ALU_INSN_NC(CODE1, CODE2, OP, MODECHANGE) \ + static INSN_REGPARM void arm##CODE1##0(u32 opcode) { ALU_INSN(ALU_INIT_NC, VALUE_LSL_IMM_NC, OP_##OP, MODECHANGE_##MODECHANGE, 0); } \ + static INSN_REGPARM void arm##CODE1##1(u32 opcode) { ALU_INSN(ALU_INIT_NC, VALUE_LSL_REG_NC, OP_##OP, MODECHANGE_##MODECHANGE, 1); } \ + static INSN_REGPARM void arm##CODE1##2(u32 opcode) { ALU_INSN(ALU_INIT_NC, VALUE_LSR_IMM_NC, OP_##OP, MODECHANGE_##MODECHANGE, 0); } \ + static INSN_REGPARM void arm##CODE1##3(u32 opcode) { ALU_INSN(ALU_INIT_NC, VALUE_LSR_REG_NC, OP_##OP, MODECHANGE_##MODECHANGE, 1); } \ + static INSN_REGPARM void arm##CODE1##4(u32 opcode) { ALU_INSN(ALU_INIT_NC, VALUE_ASR_IMM_NC, OP_##OP, MODECHANGE_##MODECHANGE, 0); } \ + static INSN_REGPARM void arm##CODE1##5(u32 opcode) { ALU_INSN(ALU_INIT_NC, VALUE_ASR_REG_NC, OP_##OP, MODECHANGE_##MODECHANGE, 1); } \ + static INSN_REGPARM void arm##CODE1##6(u32 opcode) { ALU_INSN(ALU_INIT_NC, VALUE_ROR_IMM_NC, OP_##OP, MODECHANGE_##MODECHANGE, 0); } \ + static INSN_REGPARM void arm##CODE1##7(u32 opcode) { ALU_INSN(ALU_INIT_NC, VALUE_ROR_REG_NC, OP_##OP, MODECHANGE_##MODECHANGE, 1); } \ + static INSN_REGPARM void arm##CODE2##0(u32 opcode) { ALU_INSN(ALU_INIT_NC, VALUE_IMM_NC, OP_##OP, MODECHANGE_##MODECHANGE, 0); } // AND -DEFINE_ALU_INSN_NC(00, 20, AND, NO) +DEFINE_ALU_INSN_NC(00, 20, AND, NO) // ANDS -DEFINE_ALU_INSN_C (01, 21, ANDS, YES) +DEFINE_ALU_INSN_C(01, 21, ANDS, YES) // EOR -DEFINE_ALU_INSN_NC(02, 22, EOR, NO) +DEFINE_ALU_INSN_NC(02, 22, EOR, NO) // EORS -DEFINE_ALU_INSN_C (03, 23, EORS, YES) +DEFINE_ALU_INSN_C(03, 23, EORS, YES) // SUB -DEFINE_ALU_INSN_NC(04, 24, SUB, NO) +DEFINE_ALU_INSN_NC(04, 24, SUB, NO) // SUBS DEFINE_ALU_INSN_NC(05, 25, SUBS, YES) // RSB -DEFINE_ALU_INSN_NC(06, 26, RSB, NO) +DEFINE_ALU_INSN_NC(06, 26, RSB, NO) // RSBS DEFINE_ALU_INSN_NC(07, 27, RSBS, YES) // ADD -DEFINE_ALU_INSN_NC(08, 28, ADD, NO) +DEFINE_ALU_INSN_NC(08, 28, ADD, NO) // ADDS DEFINE_ALU_INSN_NC(09, 29, ADDS, YES) // ADC -DEFINE_ALU_INSN_NC(0A, 2A, ADC, NO) +DEFINE_ALU_INSN_NC(0A, 2A, ADC, NO) // ADCS DEFINE_ALU_INSN_NC(0B, 2B, ADCS, YES) // SBC -DEFINE_ALU_INSN_NC(0C, 2C, SBC, NO) +DEFINE_ALU_INSN_NC(0C, 2C, SBC, NO) // SBCS DEFINE_ALU_INSN_NC(0D, 2D, SBCS, YES) // RSC -DEFINE_ALU_INSN_NC(0E, 2E, RSC, NO) +DEFINE_ALU_INSN_NC(0E, 2E, RSC, NO) // RSCS DEFINE_ALU_INSN_NC(0F, 2F, RSCS, YES) // TST -DEFINE_ALU_INSN_C (11, 31, TST, NO) +DEFINE_ALU_INSN_C(11, 31, TST, NO) // TEQ -DEFINE_ALU_INSN_C (13, 33, TEQ, NO) +DEFINE_ALU_INSN_C(13, 33, TEQ, NO) // CMP -DEFINE_ALU_INSN_NC(15, 35, CMP, NO) +DEFINE_ALU_INSN_NC(15, 35, CMP, NO) // CMN -DEFINE_ALU_INSN_NC(17, 37, CMN, NO) +DEFINE_ALU_INSN_NC(17, 37, CMN, NO) // ORR -DEFINE_ALU_INSN_NC(18, 38, ORR, NO) +DEFINE_ALU_INSN_NC(18, 38, ORR, NO) // ORRS -DEFINE_ALU_INSN_C (19, 39, ORRS, YES) +DEFINE_ALU_INSN_C(19, 39, ORRS, YES) // MOV -DEFINE_ALU_INSN_NC(1A, 3A, MOV, NO) +DEFINE_ALU_INSN_NC(1A, 3A, MOV, NO) // MOVS -DEFINE_ALU_INSN_C (1B, 3B, MOVS, YES) +DEFINE_ALU_INSN_C(1B, 3B, MOVS, YES) // BIC -DEFINE_ALU_INSN_NC(1C, 3C, BIC, NO) +DEFINE_ALU_INSN_NC(1C, 3C, BIC, NO) // BICS -DEFINE_ALU_INSN_C (1D, 3D, BICS, YES) +DEFINE_ALU_INSN_C(1D, 3D, BICS, YES) // MVN -DEFINE_ALU_INSN_NC(1E, 3E, MVN, NO) +DEFINE_ALU_INSN_NC(1E, 3E, MVN, NO) // MVNS -DEFINE_ALU_INSN_C (1F, 3F, MVNS, YES) +DEFINE_ALU_INSN_C(1F, 3F, MVNS, YES) // Multiply instructions ////////////////////////////////////////////////// // OP: OP_MUL, OP_MLA etc. // SETCOND: SETCOND_NONE, SETCOND_MUL, or SETCOND_MULL // CYCLES: base cycle count (1, 2, or 3) -#define MUL_INSN(OP, SETCOND, CYCLES) \ - int mult = (opcode & 0x0F); \ - u32 rs = reg[(opcode >> 8) & 0x0F].I; \ - int acc = (opcode >> 12) & 0x0F; /* or destLo */ \ - int dest = (opcode >> 16) & 0x0F; /* or destHi */ \ - OP; \ - SETCOND; \ - if ((s32)rs < 0) \ - rs = ~rs; \ - if ((rs & 0xFFFFFF00) == 0) \ - clockTicks += 0; \ - else if ((rs & 0xFFFF0000) == 0) \ - clockTicks += 1; \ - else if ((rs & 0xFF000000) == 0) \ - clockTicks += 2; \ - else \ - clockTicks += 3; \ - if (busPrefetchCount == 0) \ - busPrefetchCount = ((busPrefetchCount+1)<> 8) & 0x0F].I; \ + int acc = (opcode >> 12) & 0x0F; /* or destLo */ \ + int dest = (opcode >> 16) & 0x0F; /* or destHi */ \ + OP; \ + SETCOND; \ + if ((s32)rs < 0) \ + rs = ~rs; \ + if ((rs & 0xFFFFFF00) == 0) \ + clockTicks += 0; \ + else if ((rs & 0xFFFF0000) == 0) \ + clockTicks += 1; \ + else if ((rs & 0xFF000000) == 0) \ + clockTicks += 2; \ + else \ + clockTicks += 3; \ + if (busPrefetchCount == 0) \ + busPrefetchCount = ((busPrefetchCount + 1) << clockTicks) - 1; \ clockTicks += 1 + codeTicksAccess32(armNextPC); #define OP_MUL \ reg[dest].I = reg[mult].I * rs; #define OP_MLA \ reg[dest].I = reg[mult].I * rs + reg[acc].I; -#define OP_MULL(SIGN) \ - SIGN##64 res = (SIGN##64)(SIGN##32)reg[mult].I \ - * (SIGN##64)(SIGN##32)rs; \ - reg[acc].I = (u32)res; \ +#define OP_MULL(SIGN) \ + SIGN##64 res = (SIGN##64)(SIGN##32)reg[mult].I \ + * (SIGN##64)(SIGN##32)rs; \ + reg[acc].I = (u32)res; \ reg[dest].I = (u32)(res >> 32); -#define OP_MLAL(SIGN) \ - SIGN##64 res = ((SIGN##64)reg[dest].I<<32 | reg[acc].I)\ - + ((SIGN##64)(SIGN##32)reg[mult].I \ - * (SIGN##64)(SIGN##32)rs); \ - reg[acc].I = (u32)res; \ +#define OP_MLAL(SIGN) \ + SIGN##64 res = ((SIGN##64)reg[dest].I << 32 | reg[acc].I) \ + + ((SIGN##64)(SIGN##32)reg[mult].I \ + * (SIGN##64)(SIGN##32)rs); \ + reg[acc].I = (u32)res; \ reg[dest].I = (u32)(res >> 32); #define OP_UMULL OP_MULL(u) #define OP_UMLAL OP_MLAL(u) @@ -1322,10 +1307,10 @@ static INSN_REGPARM void arm109(u32 opcode) { u32 address = reg[(opcode >> 16) & 15].I; u32 temp = CPUReadMemory(address); - CPUWriteMemory(address, reg[opcode&15].I); + CPUWriteMemory(address, reg[opcode & 15].I); reg[(opcode >> 12) & 15].I = temp; clockTicks = 4 + dataTicksAccess32(address) + dataTicksAccess32(address) - + codeTicksAccess32(armNextPC); + + codeTicksAccess32(armNextPC); } // SWPB Rd, Rm, [Rn] @@ -1333,10 +1318,10 @@ static INSN_REGPARM void arm149(u32 opcode) { u32 address = reg[(opcode >> 16) & 15].I; u32 temp = CPUReadByte(address); - CPUWriteByte(address, reg[opcode&15].B.B0); - reg[(opcode>>12)&15].I = temp; + CPUWriteByte(address, reg[opcode & 15].B.B0); + reg[(opcode >> 12) & 15].I = temp; clockTicks = 4 + dataTicksAccess32(address) + dataTicksAccess32(address) - + codeTicksAccess32(armNextPC); + + codeTicksAccess32(armNextPC); } // MRS Rd, CPSR @@ -1381,7 +1366,7 @@ static INSN_REGPARM void arm120(u32 opcode) CPUSwitchMode(newValue & 0x1F, false); reg[16].I = newValue; CPUUpdateFlags(); - if (!armState) { // this should not be allowed, but it seems to work + if (!armState) { // this should not be allowed, but it seems to work THUMB_PREFETCH; reg[15].I = armNextPC + 2; } @@ -1437,7 +1422,7 @@ static INSN_REGPARM void arm320(u32 opcode) CPUSwitchMode(newValue & 0x1F, false); reg[16].I = newValue; CPUUpdateFlags(); - if (!armState) { // this should not be allowed, but it seems to work + if (!armState) { // this should not be allowed, but it seems to work THUMB_PREFETCH; reg[15].I = armNextPC + 2; } @@ -1483,16 +1468,16 @@ static INSN_REGPARM void arm121(u32 opcode) reg[15].I += 4; ARM_PREFETCH; clockTicks = 3 + codeTicksAccessSeq32(armNextPC) - + codeTicksAccessSeq32(armNextPC) - + codeTicksAccess32(armNextPC); + + codeTicksAccessSeq32(armNextPC) + + codeTicksAccess32(armNextPC); } else { reg[15].I = reg[base].I & 0xFFFFFFFE; armNextPC = reg[15].I; reg[15].I += 2; THUMB_PREFETCH; clockTicks = 3 + codeTicksAccessSeq16(armNextPC) - + codeTicksAccessSeq16(armNextPC) - + codeTicksAccess16(armNextPC); + + codeTicksAccessSeq16(armNextPC) + + codeTicksAccess16(armNextPC); } } else { armUnknownInsn(opcode); @@ -1504,107 +1489,106 @@ static INSN_REGPARM void arm121(u32 opcode) #define OFFSET_IMM \ int offset = opcode & 0xFFF; #define OFFSET_IMM8 \ - int offset = ((opcode & 0x0F) | ((opcode>>4) & 0xF0)); + int offset = ((opcode & 0x0F) | ((opcode >> 4) & 0xF0)); #define OFFSET_REG \ int offset = reg[opcode & 15].I; #define OFFSET_LSL \ - int offset = reg[opcode & 15].I << ((opcode>>7) & 31); -#define OFFSET_LSR \ - int shift = (opcode >> 7) & 31; \ + int offset = reg[opcode & 15].I << ((opcode >> 7) & 31); +#define OFFSET_LSR \ + int shift = (opcode >> 7) & 31; \ int offset = shift ? reg[opcode & 15].I >> shift : 0; -#define OFFSET_ASR \ - int shift = (opcode >> 7) & 31; \ - int offset; \ - if (shift) \ - offset = (int)((s32)reg[opcode & 15].I >> shift);\ - else if (reg[opcode & 15].I & 0x80000000) \ - offset = 0xFFFFFFFF; \ - else \ +#define OFFSET_ASR \ + int shift = (opcode >> 7) & 31; \ + int offset; \ + if (shift) \ + offset = (int)((s32)reg[opcode & 15].I >> shift); \ + else if (reg[opcode & 15].I & 0x80000000) \ + offset = 0xFFFFFFFF; \ + else \ offset = 0; -#define OFFSET_ROR \ - int shift = (opcode >> 7) & 31; \ - u32 offset = reg[opcode & 15].I; \ - if (shift) { \ - ROR_OFFSET; \ - } else { \ - RRX_OFFSET; \ +#define OFFSET_ROR \ + int shift = (opcode >> 7) & 31; \ + u32 offset = reg[opcode & 15].I; \ + if (shift) { \ + ROR_OFFSET; \ + } else { \ + RRX_OFFSET; \ } #define ADDRESS_POST (reg[base].I) #define ADDRESS_PREDEC (reg[base].I - offset) #define ADDRESS_PREINC (reg[base].I + offset) -#define OP_STR CPUWriteMemory(address, reg[dest].I) -#define OP_STRH CPUWriteHalfWord(address, reg[dest].W.W0) -#define OP_STRB CPUWriteByte(address, reg[dest].B.B0) -#define OP_LDR reg[dest].I = CPUReadMemory(address) -#define OP_LDRH reg[dest].I = CPUReadHalfWord(address) -#define OP_LDRB reg[dest].I = CPUReadByte(address) -#define OP_LDRSH reg[dest].I = (u32)CPUReadHalfWordSigned(address) -#define OP_LDRSB reg[dest].I = (s8)CPUReadByte(address) +#define OP_STR CPUWriteMemory(address, reg[dest].I) +#define OP_STRH CPUWriteHalfWord(address, reg[dest].W.W0) +#define OP_STRB CPUWriteByte(address, reg[dest].B.B0) +#define OP_LDR reg[dest].I = CPUReadMemory(address) +#define OP_LDRH reg[dest].I = CPUReadHalfWord(address) +#define OP_LDRB reg[dest].I = CPUReadByte(address) +#define OP_LDRSH reg[dest].I = (u32)CPUReadHalfWordSigned(address) +#define OP_LDRSB reg[dest].I = (s8)CPUReadByte(address) -#define WRITEBACK_NONE /*nothing*/ -#define WRITEBACK_PRE reg[base].I = address -#define WRITEBACK_POSTDEC reg[base].I = address - offset -#define WRITEBACK_POSTINC reg[base].I = address + offset +#define WRITEBACK_NONE /*nothing*/ +#define WRITEBACK_PRE reg[base].I = address +#define WRITEBACK_POSTDEC reg[base].I = address - offset +#define WRITEBACK_POSTINC reg[base].I = address + offset #define LDRSTR_INIT(CALC_OFFSET, CALC_ADDRESS) \ - if (busPrefetchCount == 0) \ - busPrefetch = busPrefetchEnable; \ - int dest = (opcode >> 12) & 15; \ - int base = (opcode >> 16) & 15; \ - CALC_OFFSET; \ + if (busPrefetchCount == 0) \ + busPrefetch = busPrefetchEnable; \ + int dest = (opcode >> 12) & 15; \ + int base = (opcode >> 16) & 15; \ + CALC_OFFSET; \ u32 address = CALC_ADDRESS; #define STR(CALC_OFFSET, CALC_ADDRESS, STORE_DATA, WRITEBACK1, WRITEBACK2, SIZE) \ - LDRSTR_INIT(CALC_OFFSET, CALC_ADDRESS); \ - WRITEBACK1; \ - STORE_DATA; \ - WRITEBACK2; \ - clockTicks = 2 + dataTicksAccess##SIZE(address) \ - + codeTicksAccess32(armNextPC); + LDRSTR_INIT(CALC_OFFSET, CALC_ADDRESS); \ + WRITEBACK1; \ + STORE_DATA; \ + WRITEBACK2; \ + clockTicks = 2 + dataTicksAccess##SIZE(address) \ + + codeTicksAccess32(armNextPC); #define LDR(CALC_OFFSET, CALC_ADDRESS, LOAD_DATA, WRITEBACK, SIZE) \ - LDRSTR_INIT(CALC_OFFSET, CALC_ADDRESS); \ - LOAD_DATA; \ - if (dest != base) \ - { \ - WRITEBACK; \ - } \ - clockTicks = 0; \ - if (dest == 15) { \ - reg[15].I &= 0xFFFFFFFC; \ - armNextPC = reg[15].I; \ - reg[15].I += 4; \ - ARM_PREFETCH; \ - clockTicks += 2 + dataTicksAccessSeq32(address) \ - + dataTicksAccessSeq32(address);\ - } \ - clockTicks += 3 + dataTicksAccess##SIZE(address) \ - + codeTicksAccess32(armNextPC); + LDRSTR_INIT(CALC_OFFSET, CALC_ADDRESS); \ + LOAD_DATA; \ + if (dest != base) { \ + WRITEBACK; \ + } \ + clockTicks = 0; \ + if (dest == 15) { \ + reg[15].I &= 0xFFFFFFFC; \ + armNextPC = reg[15].I; \ + reg[15].I += 4; \ + ARM_PREFETCH; \ + clockTicks += 2 + dataTicksAccessSeq32(address) \ + + dataTicksAccessSeq32(address); \ + } \ + clockTicks += 3 + dataTicksAccess##SIZE(address) \ + + codeTicksAccess32(armNextPC); #define STR_POSTDEC(CALC_OFFSET, STORE_DATA, SIZE) \ - STR(CALC_OFFSET, ADDRESS_POST, STORE_DATA, WRITEBACK_NONE, WRITEBACK_POSTDEC, SIZE) + STR(CALC_OFFSET, ADDRESS_POST, STORE_DATA, WRITEBACK_NONE, WRITEBACK_POSTDEC, SIZE) #define STR_POSTINC(CALC_OFFSET, STORE_DATA, SIZE) \ - STR(CALC_OFFSET, ADDRESS_POST, STORE_DATA, WRITEBACK_NONE, WRITEBACK_POSTINC, SIZE) + STR(CALC_OFFSET, ADDRESS_POST, STORE_DATA, WRITEBACK_NONE, WRITEBACK_POSTINC, SIZE) #define STR_PREDEC(CALC_OFFSET, STORE_DATA, SIZE) \ - STR(CALC_OFFSET, ADDRESS_PREDEC, STORE_DATA, WRITEBACK_NONE, WRITEBACK_NONE, SIZE) + STR(CALC_OFFSET, ADDRESS_PREDEC, STORE_DATA, WRITEBACK_NONE, WRITEBACK_NONE, SIZE) #define STR_PREDEC_WB(CALC_OFFSET, STORE_DATA, SIZE) \ - STR(CALC_OFFSET, ADDRESS_PREDEC, STORE_DATA, WRITEBACK_PRE, WRITEBACK_NONE, SIZE) + STR(CALC_OFFSET, ADDRESS_PREDEC, STORE_DATA, WRITEBACK_PRE, WRITEBACK_NONE, SIZE) #define STR_PREINC(CALC_OFFSET, STORE_DATA, SIZE) \ - STR(CALC_OFFSET, ADDRESS_PREINC, STORE_DATA, WRITEBACK_NONE, WRITEBACK_NONE, SIZE) + STR(CALC_OFFSET, ADDRESS_PREINC, STORE_DATA, WRITEBACK_NONE, WRITEBACK_NONE, SIZE) #define STR_PREINC_WB(CALC_OFFSET, STORE_DATA, SIZE) \ - STR(CALC_OFFSET, ADDRESS_PREINC, STORE_DATA, WRITEBACK_PRE, WRITEBACK_NONE, SIZE) + STR(CALC_OFFSET, ADDRESS_PREINC, STORE_DATA, WRITEBACK_PRE, WRITEBACK_NONE, SIZE) #define LDR_POSTDEC(CALC_OFFSET, LOAD_DATA, SIZE) \ - LDR(CALC_OFFSET, ADDRESS_POST, LOAD_DATA, WRITEBACK_POSTDEC, SIZE) + LDR(CALC_OFFSET, ADDRESS_POST, LOAD_DATA, WRITEBACK_POSTDEC, SIZE) #define LDR_POSTINC(CALC_OFFSET, LOAD_DATA, SIZE) \ - LDR(CALC_OFFSET, ADDRESS_POST, LOAD_DATA, WRITEBACK_POSTINC, SIZE) + LDR(CALC_OFFSET, ADDRESS_POST, LOAD_DATA, WRITEBACK_POSTINC, SIZE) #define LDR_PREDEC(CALC_OFFSET, LOAD_DATA, SIZE) \ - LDR(CALC_OFFSET, ADDRESS_PREDEC, LOAD_DATA, WRITEBACK_NONE, SIZE) + LDR(CALC_OFFSET, ADDRESS_PREDEC, LOAD_DATA, WRITEBACK_NONE, SIZE) #define LDR_PREDEC_WB(CALC_OFFSET, LOAD_DATA, SIZE) \ - LDR(CALC_OFFSET, ADDRESS_PREDEC, LOAD_DATA, WRITEBACK_PRE, SIZE) + LDR(CALC_OFFSET, ADDRESS_PREDEC, LOAD_DATA, WRITEBACK_PRE, SIZE) #define LDR_PREINC(CALC_OFFSET, LOAD_DATA, SIZE) \ - LDR(CALC_OFFSET, ADDRESS_PREINC, LOAD_DATA, WRITEBACK_NONE, SIZE) + LDR(CALC_OFFSET, ADDRESS_PREINC, LOAD_DATA, WRITEBACK_NONE, SIZE) #define LDR_PREINC_WB(CALC_OFFSET, LOAD_DATA, SIZE) \ - LDR(CALC_OFFSET, ADDRESS_PREINC, LOAD_DATA, WRITEBACK_PRE, SIZE) + LDR(CALC_OFFSET, ADDRESS_PREINC, LOAD_DATA, WRITEBACK_PRE, SIZE) // STRH Rd, [Rn], -Rm static INSN_REGPARM void arm00B(u32 opcode) { STR_POSTDEC(OFFSET_REG, OP_STRH, 16); } @@ -1951,200 +1935,199 @@ static INSN_REGPARM void arm7F6(u32 opcode) { LDR_PREINC_WB(OFFSET_ROR, OP_LDRB, // STM/LDM //////////////////////////////////////////////////////////////// -#define STM_REG(bit,num) \ - if (opcode & (1U<<(bit))) { \ - CPUWriteMemory(address, reg[(num)].I); \ - if (!count) { \ - clockTicks += 1 + dataTicksAccess32(address);\ - } else { \ - clockTicks += 1 + dataTicksAccessSeq32(address);\ - } \ - count++; \ - address += 4; \ +#define STM_REG(bit, num) \ + if (opcode & (1U << (bit))) { \ + CPUWriteMemory(address, reg[(num)].I); \ + if (!count) { \ + clockTicks += 1 + dataTicksAccess32(address); \ + } else { \ + clockTicks += 1 + dataTicksAccessSeq32(address); \ + } \ + count++; \ + address += 4; \ } -#define STMW_REG(bit,num) \ - if (opcode & (1U<<(bit))) { \ - CPUWriteMemory(address, reg[(num)].I); \ - if (!count) { \ - clockTicks += 1 + dataTicksAccess32(address);\ - } else { \ - clockTicks += 1 + dataTicksAccessSeq32(address);\ - } \ - reg[base].I = temp; \ - count++; \ - address += 4; \ +#define STMW_REG(bit, num) \ + if (opcode & (1U << (bit))) { \ + CPUWriteMemory(address, reg[(num)].I); \ + if (!count) { \ + clockTicks += 1 + dataTicksAccess32(address); \ + } else { \ + clockTicks += 1 + dataTicksAccessSeq32(address); \ + } \ + reg[base].I = temp; \ + count++; \ + address += 4; \ } -#define LDM_REG(bit,num) \ - if (opcode & (1U<<(bit))) { \ - reg[(num)].I = CPUReadMemory(address); \ - if (!count) { \ - clockTicks += 1 + dataTicksAccess32(address);\ - } else { \ - clockTicks += 1 + dataTicksAccessSeq32(address);\ - } \ - count++; \ - address += 4; \ +#define LDM_REG(bit, num) \ + if (opcode & (1U << (bit))) { \ + reg[(num)].I = CPUReadMemory(address); \ + if (!count) { \ + clockTicks += 1 + dataTicksAccess32(address); \ + } else { \ + clockTicks += 1 + dataTicksAccessSeq32(address); \ + } \ + count++; \ + address += 4; \ } #define STM_LOW(STORE_REG) \ - STORE_REG(0, 0); \ - STORE_REG(1, 1); \ - STORE_REG(2, 2); \ - STORE_REG(3, 3); \ - STORE_REG(4, 4); \ - STORE_REG(5, 5); \ - STORE_REG(6, 6); \ + STORE_REG(0, 0); \ + STORE_REG(1, 1); \ + STORE_REG(2, 2); \ + STORE_REG(3, 3); \ + STORE_REG(4, 4); \ + STORE_REG(5, 5); \ + STORE_REG(6, 6); \ STORE_REG(7, 7); #define STM_HIGH(STORE_REG) \ - STORE_REG(8, 8); \ - STORE_REG(9, 9); \ - STORE_REG(10, 10); \ - STORE_REG(11, 11); \ - STORE_REG(12, 12); \ - STORE_REG(13, 13); \ + STORE_REG(8, 8); \ + STORE_REG(9, 9); \ + STORE_REG(10, 10); \ + STORE_REG(11, 11); \ + STORE_REG(12, 12); \ + STORE_REG(13, 13); \ STORE_REG(14, 14); -#define STM_HIGH_2(STORE_REG) \ - if (armMode == 0x11) { \ - STORE_REG(8, R8_FIQ); \ - STORE_REG(9, R9_FIQ); \ - STORE_REG(10, R10_FIQ); \ - STORE_REG(11, R11_FIQ); \ - STORE_REG(12, R12_FIQ); \ - } else { \ - STORE_REG(8, 8); \ - STORE_REG(9, 9); \ - STORE_REG(10, 10); \ - STORE_REG(11, 11); \ - STORE_REG(12, 12); \ - } \ - if (armMode != 0x10 && armMode != 0x1F) { \ - STORE_REG(13, R13_USR); \ - STORE_REG(14, R14_USR); \ - } else { \ - STORE_REG(13, 13); \ - STORE_REG(14, 14); \ +#define STM_HIGH_2(STORE_REG) \ + if (armMode == 0x11) { \ + STORE_REG(8, R8_FIQ); \ + STORE_REG(9, R9_FIQ); \ + STORE_REG(10, R10_FIQ); \ + STORE_REG(11, R11_FIQ); \ + STORE_REG(12, R12_FIQ); \ + } else { \ + STORE_REG(8, 8); \ + STORE_REG(9, 9); \ + STORE_REG(10, 10); \ + STORE_REG(11, 11); \ + STORE_REG(12, 12); \ + } \ + if (armMode != 0x10 && armMode != 0x1F) { \ + STORE_REG(13, R13_USR); \ + STORE_REG(14, R14_USR); \ + } else { \ + STORE_REG(13, 13); \ + STORE_REG(14, 14); \ } -#define STM_PC \ - if (opcode & (1U<<15)) { \ - CPUWriteMemory(address, reg[15].I+4); \ - if (!count) { \ - clockTicks += 1 + dataTicksAccess32(address);\ - } else { \ - clockTicks += 1 + dataTicksAccessSeq32(address);\ - } \ - count++; \ - } -#define STMW_PC \ - if (opcode & (1U<<15)) { \ - CPUWriteMemory(address, reg[15].I+4); \ - if (!count) { \ - clockTicks += 1 + dataTicksAccess32(address);\ - } else { \ - clockTicks += 1 + dataTicksAccessSeq32(address);\ - } \ - reg[base].I = temp; \ - count++; \ - } -#define LDM_LOW \ - LDM_REG(0, 0); \ - LDM_REG(1, 1); \ - LDM_REG(2, 2); \ - LDM_REG(3, 3); \ - LDM_REG(4, 4); \ - LDM_REG(5, 5); \ - LDM_REG(6, 6); \ - LDM_REG(7, 7); -#define LDM_HIGH \ - LDM_REG(8, 8); \ - LDM_REG(9, 9); \ - LDM_REG(10, 10); \ - LDM_REG(11, 11); \ - LDM_REG(12, 12); \ - LDM_REG(13, 13); \ - LDM_REG(14, 14); -#define LDM_HIGH_2 \ - if (armMode == 0x11) { \ - LDM_REG(8, R8_FIQ); \ - LDM_REG(9, R9_FIQ); \ - LDM_REG(10, R10_FIQ); \ - LDM_REG(11, R11_FIQ); \ - LDM_REG(12, R12_FIQ); \ - } else { \ - LDM_REG(8, 8); \ - LDM_REG(9, 9); \ - LDM_REG(10, 10); \ - LDM_REG(11, 11); \ - LDM_REG(12, 12); \ - } \ - if (armMode != 0x10 && armMode != 0x1F) { \ - LDM_REG(13, R13_USR); \ - LDM_REG(14, R14_USR); \ - } else { \ - LDM_REG(13, 13); \ - LDM_REG(14, 14); \ - } -#define STM_ALL \ - STM_LOW(STM_REG); \ - STM_HIGH(STM_REG); \ - STM_PC; -#define STMW_ALL \ - STM_LOW(STMW_REG); \ - STM_HIGH(STMW_REG); \ - STMW_PC; -#define LDM_ALL \ - LDM_LOW; \ - LDM_HIGH; \ - if (opcode & (1U<<15)) { \ - reg[15].I = CPUReadMemory(address); \ - if (!count) { \ - clockTicks += 1 + dataTicksAccess32(address);\ - } else { \ - clockTicks += 1 + dataTicksAccessSeq32(address);\ - } \ - count++; \ - } \ - if (opcode & (1U<<15)) { \ - armNextPC = reg[15].I; \ - reg[15].I += 4; \ - ARM_PREFETCH; \ - clockTicks += 1 + codeTicksAccessSeq32(armNextPC);\ - } -#define STM_ALL_2 \ - STM_LOW(STM_REG); \ - STM_HIGH_2(STM_REG); \ - STM_PC; -#define STMW_ALL_2 \ - STM_LOW(STMW_REG); \ - STM_HIGH_2(STMW_REG); \ - STMW_PC; -#define LDM_ALL_2 \ - LDM_LOW; \ - if (opcode & (1U<<15)) { \ - LDM_HIGH; \ - reg[15].I = CPUReadMemory(address); \ - if (!count) { \ - clockTicks += 1 + dataTicksAccess32(address); \ - } else { \ +#define STM_PC \ + if (opcode & (1U << 15)) { \ + CPUWriteMemory(address, reg[15].I + 4); \ + if (!count) { \ + clockTicks += 1 + dataTicksAccess32(address); \ + } else { \ clockTicks += 1 + dataTicksAccessSeq32(address); \ - } \ - count++; \ - } else { \ - LDM_HIGH_2; \ + } \ + count++; \ } -#define LDM_ALL_2B \ - if (opcode & (1U<<15)) { \ - CPUSwitchMode(reg[17].I & 0x1F, false); \ - if (armState) { \ - armNextPC = reg[15].I & 0xFFFFFFFC; \ - reg[15].I = armNextPC + 4; \ - ARM_PREFETCH; \ - } else { \ - armNextPC = reg[15].I & 0xFFFFFFFE; \ - reg[15].I = armNextPC + 2; \ - THUMB_PREFETCH; \ - } \ - clockTicks += 1 + codeTicksAccessSeq32(armNextPC);\ +#define STMW_PC \ + if (opcode & (1U << 15)) { \ + CPUWriteMemory(address, reg[15].I + 4); \ + if (!count) { \ + clockTicks += 1 + dataTicksAccess32(address); \ + } else { \ + clockTicks += 1 + dataTicksAccessSeq32(address); \ + } \ + reg[base].I = temp; \ + count++; \ + } +#define LDM_LOW \ + LDM_REG(0, 0); \ + LDM_REG(1, 1); \ + LDM_REG(2, 2); \ + LDM_REG(3, 3); \ + LDM_REG(4, 4); \ + LDM_REG(5, 5); \ + LDM_REG(6, 6); \ + LDM_REG(7, 7); +#define LDM_HIGH \ + LDM_REG(8, 8); \ + LDM_REG(9, 9); \ + LDM_REG(10, 10); \ + LDM_REG(11, 11); \ + LDM_REG(12, 12); \ + LDM_REG(13, 13); \ + LDM_REG(14, 14); +#define LDM_HIGH_2 \ + if (armMode == 0x11) { \ + LDM_REG(8, R8_FIQ); \ + LDM_REG(9, R9_FIQ); \ + LDM_REG(10, R10_FIQ); \ + LDM_REG(11, R11_FIQ); \ + LDM_REG(12, R12_FIQ); \ + } else { \ + LDM_REG(8, 8); \ + LDM_REG(9, 9); \ + LDM_REG(10, 10); \ + LDM_REG(11, 11); \ + LDM_REG(12, 12); \ + } \ + if (armMode != 0x10 && armMode != 0x1F) { \ + LDM_REG(13, R13_USR); \ + LDM_REG(14, R14_USR); \ + } else { \ + LDM_REG(13, 13); \ + LDM_REG(14, 14); \ + } +#define STM_ALL \ + STM_LOW(STM_REG); \ + STM_HIGH(STM_REG); \ + STM_PC; +#define STMW_ALL \ + STM_LOW(STMW_REG); \ + STM_HIGH(STMW_REG); \ + STMW_PC; +#define LDM_ALL \ + LDM_LOW; \ + LDM_HIGH; \ + if (opcode & (1U << 15)) { \ + reg[15].I = CPUReadMemory(address); \ + if (!count) { \ + clockTicks += 1 + dataTicksAccess32(address); \ + } else { \ + clockTicks += 1 + dataTicksAccessSeq32(address); \ + } \ + count++; \ + } \ + if (opcode & (1U << 15)) { \ + armNextPC = reg[15].I; \ + reg[15].I += 4; \ + ARM_PREFETCH; \ + clockTicks += 1 + codeTicksAccessSeq32(armNextPC); \ + } +#define STM_ALL_2 \ + STM_LOW(STM_REG); \ + STM_HIGH_2(STM_REG); \ + STM_PC; +#define STMW_ALL_2 \ + STM_LOW(STMW_REG); \ + STM_HIGH_2(STMW_REG); \ + STMW_PC; +#define LDM_ALL_2 \ + LDM_LOW; \ + if (opcode & (1U << 15)) { \ + LDM_HIGH; \ + reg[15].I = CPUReadMemory(address); \ + if (!count) { \ + clockTicks += 1 + dataTicksAccess32(address); \ + } else { \ + clockTicks += 1 + dataTicksAccessSeq32(address); \ + } \ + count++; \ + } else { \ + LDM_HIGH_2; \ + } +#define LDM_ALL_2B \ + if (opcode & (1U << 15)) { \ + CPUSwitchMode(reg[17].I & 0x1F, false); \ + if (armState) { \ + armNextPC = reg[15].I & 0xFFFFFFFC; \ + reg[15].I = armNextPC + 4; \ + ARM_PREFETCH; \ + } else { \ + armNextPC = reg[15].I & 0xFFFFFFFE; \ + reg[15].I = armNextPC + 2; \ + THUMB_PREFETCH; \ + } \ + clockTicks += 1 + codeTicksAccessSeq32(armNextPC); \ } - // STMDA Rn, {Rlist} static INSN_REGPARM void arm800(u32 opcode) @@ -2152,8 +2135,7 @@ static INSN_REGPARM void arm800(u32 opcode) if (busPrefetchCount == 0) busPrefetch = busPrefetchEnable; int base = (opcode & 0x000F0000) >> 16; - u32 temp = reg[base].I - - 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); + u32 temp = reg[base].I - 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); u32 address = (temp + 4) & 0xFFFFFFFC; int count = 0; STM_ALL; @@ -2166,8 +2148,7 @@ static INSN_REGPARM void arm810(u32 opcode) if (busPrefetchCount == 0) busPrefetch = busPrefetchEnable; int base = (opcode & 0x000F0000) >> 16; - u32 temp = reg[base].I - - 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); + u32 temp = reg[base].I - 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); u32 address = (temp + 4) & 0xFFFFFFFC; int count = 0; LDM_ALL; @@ -2180,9 +2161,8 @@ static INSN_REGPARM void arm820(u32 opcode) if (busPrefetchCount == 0) busPrefetch = busPrefetchEnable; int base = (opcode & 0x000F0000) >> 16; - u32 temp = reg[base].I - - 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); - u32 address = (temp+4) & 0xFFFFFFFC; + u32 temp = reg[base].I - 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); + u32 address = (temp + 4) & 0xFFFFFFFC; int count = 0; STMW_ALL; clockTicks += 1 + codeTicksAccess32(armNextPC); @@ -2194,8 +2174,7 @@ static INSN_REGPARM void arm830(u32 opcode) if (busPrefetchCount == 0) busPrefetch = busPrefetchEnable; int base = (opcode & 0x000F0000) >> 16; - u32 temp = reg[base].I - - 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); + u32 temp = reg[base].I - 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); u32 address = (temp + 4) & 0xFFFFFFFC; int count = 0; LDM_ALL; @@ -2210,9 +2189,8 @@ static INSN_REGPARM void arm840(u32 opcode) if (busPrefetchCount == 0) busPrefetch = busPrefetchEnable; int base = (opcode & 0x000F0000) >> 16; - u32 temp = reg[base].I - - 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); - u32 address = (temp+4) & 0xFFFFFFFC; + u32 temp = reg[base].I - 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); + u32 address = (temp + 4) & 0xFFFFFFFC; int count = 0; STM_ALL_2; clockTicks += 1 + codeTicksAccess32(armNextPC); @@ -2224,8 +2202,7 @@ static INSN_REGPARM void arm850(u32 opcode) if (busPrefetchCount == 0) busPrefetch = busPrefetchEnable; int base = (opcode & 0x000F0000) >> 16; - u32 temp = reg[base].I - - 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); + u32 temp = reg[base].I - 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); u32 address = (temp + 4) & 0xFFFFFFFC; int count = 0; LDM_ALL_2; @@ -2239,9 +2216,8 @@ static INSN_REGPARM void arm860(u32 opcode) if (busPrefetchCount == 0) busPrefetch = busPrefetchEnable; int base = (opcode & 0x000F0000) >> 16; - u32 temp = reg[base].I - - 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); - u32 address = (temp+4) & 0xFFFFFFFC; + u32 temp = reg[base].I - 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); + u32 address = (temp + 4) & 0xFFFFFFFC; int count = 0; STMW_ALL_2; clockTicks += 1 + codeTicksAccess32(armNextPC); @@ -2253,8 +2229,7 @@ static INSN_REGPARM void arm870(u32 opcode) if (busPrefetchCount == 0) busPrefetch = busPrefetchEnable; int base = (opcode & 0x000F0000) >> 16; - u32 temp = reg[base].I - - 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); + u32 temp = reg[base].I - 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); u32 address = (temp + 4) & 0xFFFFFFFC; int count = 0; LDM_ALL_2; @@ -2296,8 +2271,7 @@ static INSN_REGPARM void arm8A0(u32 opcode) int base = (opcode & 0x000F0000) >> 16; u32 address = reg[base].I & 0xFFFFFFFC; int count = 0; - u32 temp = reg[base].I + - 4 * (cpuBitsSet[opcode & 0xFF] + cpuBitsSet[(opcode >> 8) & 255]); + u32 temp = reg[base].I + 4 * (cpuBitsSet[opcode & 0xFF] + cpuBitsSet[(opcode >> 8) & 255]); STMW_ALL; clockTicks += 1 + codeTicksAccess32(armNextPC); } @@ -2308,8 +2282,7 @@ static INSN_REGPARM void arm8B0(u32 opcode) if (busPrefetchCount == 0) busPrefetch = busPrefetchEnable; int base = (opcode & 0x000F0000) >> 16; - u32 temp = reg[base].I + - 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); + u32 temp = reg[base].I + 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); u32 address = reg[base].I & 0xFFFFFFFC; int count = 0; LDM_ALL; @@ -2351,8 +2324,7 @@ static INSN_REGPARM void arm8E0(u32 opcode) int base = (opcode & 0x000F0000) >> 16; u32 address = reg[base].I & 0xFFFFFFFC; int count = 0; - u32 temp = reg[base].I + - 4 * (cpuBitsSet[opcode & 0xFF] + cpuBitsSet[(opcode >> 8) & 255]); + u32 temp = reg[base].I + 4 * (cpuBitsSet[opcode & 0xFF] + cpuBitsSet[(opcode >> 8) & 255]); STMW_ALL_2; clockTicks += 1 + codeTicksAccess32(armNextPC); } @@ -2363,8 +2335,7 @@ static INSN_REGPARM void arm8F0(u32 opcode) if (busPrefetchCount == 0) busPrefetch = busPrefetchEnable; int base = (opcode & 0x000F0000) >> 16; - u32 temp = reg[base].I + - 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); + u32 temp = reg[base].I + 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); u32 address = reg[base].I & 0xFFFFFFFC; int count = 0; LDM_ALL_2; @@ -2380,8 +2351,7 @@ static INSN_REGPARM void arm900(u32 opcode) if (busPrefetchCount == 0) busPrefetch = busPrefetchEnable; int base = (opcode & 0x000F0000) >> 16; - u32 temp = reg[base].I - - 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); + u32 temp = reg[base].I - 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); u32 address = temp & 0xFFFFFFFC; int count = 0; STM_ALL; @@ -2394,8 +2364,7 @@ static INSN_REGPARM void arm910(u32 opcode) if (busPrefetchCount == 0) busPrefetch = busPrefetchEnable; int base = (opcode & 0x000F0000) >> 16; - u32 temp = reg[base].I - - 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); + u32 temp = reg[base].I - 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); u32 address = temp & 0xFFFFFFFC; int count = 0; LDM_ALL; @@ -2408,8 +2377,7 @@ static INSN_REGPARM void arm920(u32 opcode) if (busPrefetchCount == 0) busPrefetch = busPrefetchEnable; int base = (opcode & 0x000F0000) >> 16; - u32 temp = reg[base].I - - 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); + u32 temp = reg[base].I - 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); u32 address = temp & 0xFFFFFFFC; int count = 0; STMW_ALL; @@ -2422,8 +2390,7 @@ static INSN_REGPARM void arm930(u32 opcode) if (busPrefetchCount == 0) busPrefetch = busPrefetchEnable; int base = (opcode & 0x000F0000) >> 16; - u32 temp = reg[base].I - - 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); + u32 temp = reg[base].I - 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); u32 address = temp & 0xFFFFFFFC; int count = 0; LDM_ALL; @@ -2438,8 +2405,7 @@ static INSN_REGPARM void arm940(u32 opcode) if (busPrefetchCount == 0) busPrefetch = busPrefetchEnable; int base = (opcode & 0x000F0000) >> 16; - u32 temp = reg[base].I - - 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); + u32 temp = reg[base].I - 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); u32 address = temp & 0xFFFFFFFC; int count = 0; STM_ALL_2; @@ -2452,8 +2418,7 @@ static INSN_REGPARM void arm950(u32 opcode) if (busPrefetchCount == 0) busPrefetch = busPrefetchEnable; int base = (opcode & 0x000F0000) >> 16; - u32 temp = reg[base].I - - 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); + u32 temp = reg[base].I - 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); u32 address = temp & 0xFFFFFFFC; int count = 0; LDM_ALL_2; @@ -2467,8 +2432,7 @@ static INSN_REGPARM void arm960(u32 opcode) if (busPrefetchCount == 0) busPrefetch = busPrefetchEnable; int base = (opcode & 0x000F0000) >> 16; - u32 temp = reg[base].I - - 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); + u32 temp = reg[base].I - 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); u32 address = temp & 0xFFFFFFFC; int count = 0; STMW_ALL_2; @@ -2481,8 +2445,7 @@ static INSN_REGPARM void arm970(u32 opcode) if (busPrefetchCount == 0) busPrefetch = busPrefetchEnable; int base = (opcode & 0x000F0000) >> 16; - u32 temp = reg[base].I - - 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); + u32 temp = reg[base].I - 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); u32 address = temp & 0xFFFFFFFC; int count = 0; LDM_ALL_2; @@ -2498,7 +2461,7 @@ static INSN_REGPARM void arm980(u32 opcode) if (busPrefetchCount == 0) busPrefetch = busPrefetchEnable; int base = (opcode & 0x000F0000) >> 16; - u32 address = (reg[base].I+4) & 0xFFFFFFFC; + u32 address = (reg[base].I + 4) & 0xFFFFFFFC; int count = 0; STM_ALL; clockTicks += 1 + codeTicksAccess32(armNextPC); @@ -2510,7 +2473,7 @@ static INSN_REGPARM void arm990(u32 opcode) if (busPrefetchCount == 0) busPrefetch = busPrefetchEnable; int base = (opcode & 0x000F0000) >> 16; - u32 address = (reg[base].I+4) & 0xFFFFFFFC; + u32 address = (reg[base].I + 4) & 0xFFFFFFFC; int count = 0; LDM_ALL; clockTicks += 2 + codeTicksAccess32(armNextPC); @@ -2522,10 +2485,9 @@ static INSN_REGPARM void arm9A0(u32 opcode) if (busPrefetchCount == 0) busPrefetch = busPrefetchEnable; int base = (opcode & 0x000F0000) >> 16; - u32 address = (reg[base].I+4) & 0xFFFFFFFC; + u32 address = (reg[base].I + 4) & 0xFFFFFFFC; int count = 0; - u32 temp = reg[base].I + - 4 * (cpuBitsSet[opcode & 0xFF] + cpuBitsSet[(opcode >> 8) & 255]); + u32 temp = reg[base].I + 4 * (cpuBitsSet[opcode & 0xFF] + cpuBitsSet[(opcode >> 8) & 255]); STMW_ALL; clockTicks += 1 + codeTicksAccess32(armNextPC); } @@ -2536,9 +2498,8 @@ static INSN_REGPARM void arm9B0(u32 opcode) if (busPrefetchCount == 0) busPrefetch = busPrefetchEnable; int base = (opcode & 0x000F0000) >> 16; - u32 temp = reg[base].I + - 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); - u32 address = (reg[base].I+4) & 0xFFFFFFFC; + u32 temp = reg[base].I + 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); + u32 address = (reg[base].I + 4) & 0xFFFFFFFC; int count = 0; LDM_ALL; clockTicks += 2 + codeTicksAccess32(armNextPC); @@ -2552,7 +2513,7 @@ static INSN_REGPARM void arm9C0(u32 opcode) if (busPrefetchCount == 0) busPrefetch = busPrefetchEnable; int base = (opcode & 0x000F0000) >> 16; - u32 address = (reg[base].I+4) & 0xFFFFFFFC; + u32 address = (reg[base].I + 4) & 0xFFFFFFFC; int count = 0; STM_ALL_2; clockTicks += 1 + codeTicksAccess32(armNextPC); @@ -2564,7 +2525,7 @@ static INSN_REGPARM void arm9D0(u32 opcode) if (busPrefetchCount == 0) busPrefetch = busPrefetchEnable; int base = (opcode & 0x000F0000) >> 16; - u32 address = (reg[base].I+4) & 0xFFFFFFFC; + u32 address = (reg[base].I + 4) & 0xFFFFFFFC; int count = 0; LDM_ALL_2; LDM_ALL_2B; @@ -2577,10 +2538,9 @@ static INSN_REGPARM void arm9E0(u32 opcode) if (busPrefetchCount == 0) busPrefetch = busPrefetchEnable; int base = (opcode & 0x000F0000) >> 16; - u32 address = (reg[base].I+4) & 0xFFFFFFFC; + u32 address = (reg[base].I + 4) & 0xFFFFFFFC; int count = 0; - u32 temp = reg[base].I + - 4 * (cpuBitsSet[opcode & 0xFF] + cpuBitsSet[(opcode >> 8) & 255]); + u32 temp = reg[base].I + 4 * (cpuBitsSet[opcode & 0xFF] + cpuBitsSet[(opcode >> 8) & 255]); STMW_ALL_2; clockTicks += 1 + codeTicksAccess32(armNextPC); } @@ -2591,9 +2551,8 @@ static INSN_REGPARM void arm9F0(u32 opcode) if (busPrefetchCount == 0) busPrefetch = busPrefetchEnable; int base = (opcode & 0x000F0000) >> 16; - u32 temp = reg[base].I + - 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); - u32 address = (reg[base].I+4) & 0xFFFFFFFC; + u32 temp = reg[base].I + 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]); + u32 address = (reg[base].I + 4) & 0xFFFFFFFC; int count = 0; LDM_ALL_2; if (!(opcode & (1U << base))) @@ -2609,8 +2568,8 @@ static INSN_REGPARM void armA00(u32 opcode) { int offset = opcode & 0x00FFFFFF; if (offset & 0x00800000) - offset |= 0xFF000000; // negative offset - reg[15].I += offset<<2; + offset |= 0xFF000000; // negative offset + reg[15].I += offset << 2; armNextPC = reg[15].I; reg[15].I += 4; ARM_PREFETCH; @@ -2624,9 +2583,9 @@ static INSN_REGPARM void armB00(u32 opcode) { int offset = opcode & 0x00FFFFFF; if (offset & 0x00800000) - offset |= 0xFF000000; // negative offset + offset |= 0xFF000000; // negative offset reg[14].I = reg[15].I - 4; - reg[15].I += offset<<2; + reg[15].I += offset << 2; armNextPC = reg[15].I; reg[15].I += 4; ARM_PREFETCH; @@ -2635,22 +2594,20 @@ static INSN_REGPARM void armB00(u32 opcode) busPrefetchCount = 0; } - #ifdef GP_SUPPORT // MRC static INSN_REGPARM void armE01(u32 opcode) { } #else - #define armE01 armUnknownInsn +#define armE01 armUnknownInsn #endif - // SWI static INSN_REGPARM void armF00(u32 opcode) { - clockTicks = codeTicksAccessSeq32(armNextPC) + 1; - clockTicks = (clockTicks * 2) + codeTicksAccess32(armNextPC) + 1; + clockTicks = codeTicksAccessSeq32(armNextPC) + 1; + clockTicks = (clockTicks * 2) + codeTicksAccess32(armNextPC) + 1; busPrefetchCount = 0; CPUSoftwareInterrupt(opcode & 0x00FFFFFF); } @@ -2658,202 +2615,203 @@ static INSN_REGPARM void armF00(u32 opcode) // Instruction table ////////////////////////////////////////////////////// typedef INSN_REGPARM void (*insnfunc_t)(u32 opcode); -#define REP16(insn) \ - insn,insn,insn,insn,insn,insn,insn,insn,\ - insn,insn,insn,insn,insn,insn,insn,insn -#define REP256(insn) \ - REP16(insn),REP16(insn),REP16(insn),REP16(insn),\ - REP16(insn),REP16(insn),REP16(insn),REP16(insn),\ - REP16(insn),REP16(insn),REP16(insn),REP16(insn),\ - REP16(insn),REP16(insn),REP16(insn),REP16(insn) +#define REP16(insn) \ + insn, insn, insn, insn, insn, insn, insn, insn, \ + insn, insn, insn, insn, insn, insn, insn, insn +#define REP256(insn) \ + REP16(insn) \ + , REP16(insn), REP16(insn), REP16(insn), \ + REP16(insn), REP16(insn), REP16(insn), REP16(insn), \ + REP16(insn), REP16(insn), REP16(insn), REP16(insn), \ + REP16(insn), REP16(insn), REP16(insn), REP16(insn) #define arm_UI armUnknownInsn #ifdef BKPT_SUPPORT - #define arm_BP armBreakpoint +#define arm_BP armBreakpoint #else - #define arm_BP armUnknownInsn +#define arm_BP armUnknownInsn #endif static insnfunc_t armInsnTable[4096] = { - arm000,arm001,arm002,arm003,arm004,arm005,arm006,arm007, // 000 - arm000,arm009,arm002,arm00B,arm004,arm_UI,arm006,arm_UI, // 008 - arm010,arm011,arm012,arm013,arm014,arm015,arm016,arm017, // 010 - arm010,arm019,arm012,arm01B,arm014,arm01D,arm016,arm01F, // 018 - arm020,arm021,arm022,arm023,arm024,arm025,arm026,arm027, // 020 - arm020,arm029,arm022,arm_UI,arm024,arm_UI,arm026,arm_UI, // 028 - arm030,arm031,arm032,arm033,arm034,arm035,arm036,arm037, // 030 - arm030,arm039,arm032,arm_UI,arm034,arm01D,arm036,arm01F, // 038 - arm040,arm041,arm042,arm043,arm044,arm045,arm046,arm047, // 040 - arm040,arm_UI,arm042,arm04B,arm044,arm_UI,arm046,arm_UI, // 048 - arm050,arm051,arm052,arm053,arm054,arm055,arm056,arm057, // 050 - arm050,arm_UI,arm052,arm05B,arm054,arm05D,arm056,arm05F, // 058 - arm060,arm061,arm062,arm063,arm064,arm065,arm066,arm067, // 060 - arm060,arm_UI,arm062,arm_UI,arm064,arm_UI,arm066,arm_UI, // 068 - arm070,arm071,arm072,arm073,arm074,arm075,arm076,arm077, // 070 - arm070,arm_UI,arm072,arm_UI,arm074,arm05D,arm076,arm05F, // 078 - arm080,arm081,arm082,arm083,arm084,arm085,arm086,arm087, // 080 - arm080,arm089,arm082,arm08B,arm084,arm_UI,arm086,arm_UI, // 088 - arm090,arm091,arm092,arm093,arm094,arm095,arm096,arm097, // 090 - arm090,arm099,arm092,arm09B,arm094,arm09D,arm096,arm09F, // 098 - arm0A0,arm0A1,arm0A2,arm0A3,arm0A4,arm0A5,arm0A6,arm0A7, // 0A0 - arm0A0,arm0A9,arm0A2,arm_UI,arm0A4,arm_UI,arm0A6,arm_UI, // 0A8 - arm0B0,arm0B1,arm0B2,arm0B3,arm0B4,arm0B5,arm0B6,arm0B7, // 0B0 - arm0B0,arm0B9,arm0B2,arm_UI,arm0B4,arm09D,arm0B6,arm09F, // 0B8 - arm0C0,arm0C1,arm0C2,arm0C3,arm0C4,arm0C5,arm0C6,arm0C7, // 0C0 - arm0C0,arm0C9,arm0C2,arm0CB,arm0C4,arm_UI,arm0C6,arm_UI, // 0C8 - arm0D0,arm0D1,arm0D2,arm0D3,arm0D4,arm0D5,arm0D6,arm0D7, // 0D0 - arm0D0,arm0D9,arm0D2,arm0DB,arm0D4,arm0DD,arm0D6,arm0DF, // 0D8 - arm0E0,arm0E1,arm0E2,arm0E3,arm0E4,arm0E5,arm0E6,arm0E7, // 0E0 - arm0E0,arm0E9,arm0E2,arm0CB,arm0E4,arm_UI,arm0E6,arm_UI, // 0E8 - arm0F0,arm0F1,arm0F2,arm0F3,arm0F4,arm0F5,arm0F6,arm0F7, // 0F0 - arm0F0,arm0F9,arm0F2,arm0DB,arm0F4,arm0DD,arm0F6,arm0DF, // 0F8 + arm000, arm001, arm002, arm003, arm004, arm005, arm006, arm007, // 000 + arm000, arm009, arm002, arm00B, arm004, arm_UI, arm006, arm_UI, // 008 + arm010, arm011, arm012, arm013, arm014, arm015, arm016, arm017, // 010 + arm010, arm019, arm012, arm01B, arm014, arm01D, arm016, arm01F, // 018 + arm020, arm021, arm022, arm023, arm024, arm025, arm026, arm027, // 020 + arm020, arm029, arm022, arm_UI, arm024, arm_UI, arm026, arm_UI, // 028 + arm030, arm031, arm032, arm033, arm034, arm035, arm036, arm037, // 030 + arm030, arm039, arm032, arm_UI, arm034, arm01D, arm036, arm01F, // 038 + arm040, arm041, arm042, arm043, arm044, arm045, arm046, arm047, // 040 + arm040, arm_UI, arm042, arm04B, arm044, arm_UI, arm046, arm_UI, // 048 + arm050, arm051, arm052, arm053, arm054, arm055, arm056, arm057, // 050 + arm050, arm_UI, arm052, arm05B, arm054, arm05D, arm056, arm05F, // 058 + arm060, arm061, arm062, arm063, arm064, arm065, arm066, arm067, // 060 + arm060, arm_UI, arm062, arm_UI, arm064, arm_UI, arm066, arm_UI, // 068 + arm070, arm071, arm072, arm073, arm074, arm075, arm076, arm077, // 070 + arm070, arm_UI, arm072, arm_UI, arm074, arm05D, arm076, arm05F, // 078 + arm080, arm081, arm082, arm083, arm084, arm085, arm086, arm087, // 080 + arm080, arm089, arm082, arm08B, arm084, arm_UI, arm086, arm_UI, // 088 + arm090, arm091, arm092, arm093, arm094, arm095, arm096, arm097, // 090 + arm090, arm099, arm092, arm09B, arm094, arm09D, arm096, arm09F, // 098 + arm0A0, arm0A1, arm0A2, arm0A3, arm0A4, arm0A5, arm0A6, arm0A7, // 0A0 + arm0A0, arm0A9, arm0A2, arm_UI, arm0A4, arm_UI, arm0A6, arm_UI, // 0A8 + arm0B0, arm0B1, arm0B2, arm0B3, arm0B4, arm0B5, arm0B6, arm0B7, // 0B0 + arm0B0, arm0B9, arm0B2, arm_UI, arm0B4, arm09D, arm0B6, arm09F, // 0B8 + arm0C0, arm0C1, arm0C2, arm0C3, arm0C4, arm0C5, arm0C6, arm0C7, // 0C0 + arm0C0, arm0C9, arm0C2, arm0CB, arm0C4, arm_UI, arm0C6, arm_UI, // 0C8 + arm0D0, arm0D1, arm0D2, arm0D3, arm0D4, arm0D5, arm0D6, arm0D7, // 0D0 + arm0D0, arm0D9, arm0D2, arm0DB, arm0D4, arm0DD, arm0D6, arm0DF, // 0D8 + arm0E0, arm0E1, arm0E2, arm0E3, arm0E4, arm0E5, arm0E6, arm0E7, // 0E0 + arm0E0, arm0E9, arm0E2, arm0CB, arm0E4, arm_UI, arm0E6, arm_UI, // 0E8 + arm0F0, arm0F1, arm0F2, arm0F3, arm0F4, arm0F5, arm0F6, arm0F7, // 0F0 + arm0F0, arm0F9, arm0F2, arm0DB, arm0F4, arm0DD, arm0F6, arm0DF, // 0F8 - arm100,arm_UI,arm_UI,arm_UI,arm_UI,arm_UI,arm_UI,arm_UI, // 100 - arm_UI,arm109,arm_UI,arm10B,arm_UI,arm_UI,arm_UI,arm_UI, // 108 - arm110,arm111,arm112,arm113,arm114,arm115,arm116,arm117, // 110 - arm110,arm_UI,arm112,arm11B,arm114,arm11D,arm116,arm11F, // 118 - arm120,arm121,arm_UI,arm_UI,arm_UI,arm_UI,arm_UI,arm_BP, // 120 - arm_UI,arm_UI,arm_UI,arm12B,arm_UI,arm_UI,arm_UI,arm_UI, // 128 - arm130,arm131,arm132,arm133,arm134,arm135,arm136,arm137, // 130 - arm130,arm_UI,arm132,arm13B,arm134,arm13D,arm136,arm13F, // 138 - arm140,arm_UI,arm_UI,arm_UI,arm_UI,arm_UI,arm_UI,arm_UI, // 140 - arm_UI,arm149,arm_UI,arm14B,arm_UI,arm_UI,arm_UI,arm_UI, // 148 - arm150,arm151,arm152,arm153,arm154,arm155,arm156,arm157, // 150 - arm150,arm_UI,arm152,arm15B,arm154,arm15D,arm156,arm15F, // 158 - arm160,arm_UI,arm_UI,arm_UI,arm_UI,arm_UI,arm_UI,arm_UI, // 160 - arm_UI,arm_UI,arm_UI,arm16B,arm_UI,arm_UI,arm_UI,arm_UI, // 168 - arm170,arm171,arm172,arm173,arm174,arm175,arm176,arm177, // 170 - arm170,arm_UI,arm172,arm17B,arm174,arm17D,arm176,arm17F, // 178 - arm180,arm181,arm182,arm183,arm184,arm185,arm186,arm187, // 180 - arm180,arm_UI,arm182,arm18B,arm184,arm_UI,arm186,arm_UI, // 188 - arm190,arm191,arm192,arm193,arm194,arm195,arm196,arm197, // 190 - arm190,arm_UI,arm192,arm19B,arm194,arm19D,arm196,arm19F, // 198 - arm1A0,arm1A1,arm1A2,arm1A3,arm1A4,arm1A5,arm1A6,arm1A7, // 1A0 - arm1A0,arm_UI,arm1A2,arm1AB,arm1A4,arm_UI,arm1A6,arm_UI, // 1A8 - arm1B0,arm1B1,arm1B2,arm1B3,arm1B4,arm1B5,arm1B6,arm1B7, // 1B0 - arm1B0,arm_UI,arm1B2,arm1BB,arm1B4,arm1BD,arm1B6,arm1BF, // 1B8 - arm1C0,arm1C1,arm1C2,arm1C3,arm1C4,arm1C5,arm1C6,arm1C7, // 1C0 - arm1C0,arm_UI,arm1C2,arm1CB,arm1C4,arm_UI,arm1C6,arm_UI, // 1C8 - arm1D0,arm1D1,arm1D2,arm1D3,arm1D4,arm1D5,arm1D6,arm1D7, // 1D0 - arm1D0,arm_UI,arm1D2,arm1DB,arm1D4,arm1DD,arm1D6,arm1DF, // 1D8 - arm1E0,arm1E1,arm1E2,arm1E3,arm1E4,arm1E5,arm1E6,arm1E7, // 1E0 - arm1E0,arm_UI,arm1E2,arm1EB,arm1E4,arm_UI,arm1E6,arm_UI, // 1E8 - arm1F0,arm1F1,arm1F2,arm1F3,arm1F4,arm1F5,arm1F6,arm1F7, // 1F0 - arm1F0,arm_UI,arm1F2,arm1FB,arm1F4,arm1FD,arm1F6,arm1FF, // 1F8 + arm100, arm_UI, arm_UI, arm_UI, arm_UI, arm_UI, arm_UI, arm_UI, // 100 + arm_UI, arm109, arm_UI, arm10B, arm_UI, arm_UI, arm_UI, arm_UI, // 108 + arm110, arm111, arm112, arm113, arm114, arm115, arm116, arm117, // 110 + arm110, arm_UI, arm112, arm11B, arm114, arm11D, arm116, arm11F, // 118 + arm120, arm121, arm_UI, arm_UI, arm_UI, arm_UI, arm_UI, arm_BP, // 120 + arm_UI, arm_UI, arm_UI, arm12B, arm_UI, arm_UI, arm_UI, arm_UI, // 128 + arm130, arm131, arm132, arm133, arm134, arm135, arm136, arm137, // 130 + arm130, arm_UI, arm132, arm13B, arm134, arm13D, arm136, arm13F, // 138 + arm140, arm_UI, arm_UI, arm_UI, arm_UI, arm_UI, arm_UI, arm_UI, // 140 + arm_UI, arm149, arm_UI, arm14B, arm_UI, arm_UI, arm_UI, arm_UI, // 148 + arm150, arm151, arm152, arm153, arm154, arm155, arm156, arm157, // 150 + arm150, arm_UI, arm152, arm15B, arm154, arm15D, arm156, arm15F, // 158 + arm160, arm_UI, arm_UI, arm_UI, arm_UI, arm_UI, arm_UI, arm_UI, // 160 + arm_UI, arm_UI, arm_UI, arm16B, arm_UI, arm_UI, arm_UI, arm_UI, // 168 + arm170, arm171, arm172, arm173, arm174, arm175, arm176, arm177, // 170 + arm170, arm_UI, arm172, arm17B, arm174, arm17D, arm176, arm17F, // 178 + arm180, arm181, arm182, arm183, arm184, arm185, arm186, arm187, // 180 + arm180, arm_UI, arm182, arm18B, arm184, arm_UI, arm186, arm_UI, // 188 + arm190, arm191, arm192, arm193, arm194, arm195, arm196, arm197, // 190 + arm190, arm_UI, arm192, arm19B, arm194, arm19D, arm196, arm19F, // 198 + arm1A0, arm1A1, arm1A2, arm1A3, arm1A4, arm1A5, arm1A6, arm1A7, // 1A0 + arm1A0, arm_UI, arm1A2, arm1AB, arm1A4, arm_UI, arm1A6, arm_UI, // 1A8 + arm1B0, arm1B1, arm1B2, arm1B3, arm1B4, arm1B5, arm1B6, arm1B7, // 1B0 + arm1B0, arm_UI, arm1B2, arm1BB, arm1B4, arm1BD, arm1B6, arm1BF, // 1B8 + arm1C0, arm1C1, arm1C2, arm1C3, arm1C4, arm1C5, arm1C6, arm1C7, // 1C0 + arm1C0, arm_UI, arm1C2, arm1CB, arm1C4, arm_UI, arm1C6, arm_UI, // 1C8 + arm1D0, arm1D1, arm1D2, arm1D3, arm1D4, arm1D5, arm1D6, arm1D7, // 1D0 + arm1D0, arm_UI, arm1D2, arm1DB, arm1D4, arm1DD, arm1D6, arm1DF, // 1D8 + arm1E0, arm1E1, arm1E2, arm1E3, arm1E4, arm1E5, arm1E6, arm1E7, // 1E0 + arm1E0, arm_UI, arm1E2, arm1EB, arm1E4, arm_UI, arm1E6, arm_UI, // 1E8 + arm1F0, arm1F1, arm1F2, arm1F3, arm1F4, arm1F5, arm1F6, arm1F7, // 1F0 + arm1F0, arm_UI, arm1F2, arm1FB, arm1F4, arm1FD, arm1F6, arm1FF, // 1F8 - REP16(arm200),REP16(arm210),REP16(arm220),REP16(arm230), // 200 - REP16(arm240),REP16(arm250),REP16(arm260),REP16(arm270), // 240 - REP16(arm280),REP16(arm290),REP16(arm2A0),REP16(arm2B0), // 280 - REP16(arm2C0),REP16(arm2D0),REP16(arm2E0),REP16(arm2F0), // 2C0 - REP16(arm_UI),REP16(arm310),REP16(arm320),REP16(arm330), // 300 - REP16(arm_UI),REP16(arm350),REP16(arm360),REP16(arm370), // 340 - REP16(arm380),REP16(arm390),REP16(arm3A0),REP16(arm3B0), // 380 - REP16(arm3C0),REP16(arm3D0),REP16(arm3E0),REP16(arm3F0), // 3C0 + REP16(arm200), REP16(arm210), REP16(arm220), REP16(arm230), // 200 + REP16(arm240), REP16(arm250), REP16(arm260), REP16(arm270), // 240 + REP16(arm280), REP16(arm290), REP16(arm2A0), REP16(arm2B0), // 280 + REP16(arm2C0), REP16(arm2D0), REP16(arm2E0), REP16(arm2F0), // 2C0 + REP16(arm_UI), REP16(arm310), REP16(arm320), REP16(arm330), // 300 + REP16(arm_UI), REP16(arm350), REP16(arm360), REP16(arm370), // 340 + REP16(arm380), REP16(arm390), REP16(arm3A0), REP16(arm3B0), // 380 + REP16(arm3C0), REP16(arm3D0), REP16(arm3E0), REP16(arm3F0), // 3C0 - REP16(arm400),REP16(arm410),REP16(arm400),REP16(arm410), // 400 - REP16(arm440),REP16(arm450),REP16(arm440),REP16(arm450), // 440 - REP16(arm480),REP16(arm490),REP16(arm480),REP16(arm490), // 480 - REP16(arm4C0),REP16(arm4D0),REP16(arm4C0),REP16(arm4D0), // 4C0 - REP16(arm500),REP16(arm510),REP16(arm520),REP16(arm530), // 500 - REP16(arm540),REP16(arm550),REP16(arm560),REP16(arm570), // 540 - REP16(arm580),REP16(arm590),REP16(arm5A0),REP16(arm5B0), // 580 - REP16(arm5C0),REP16(arm5D0),REP16(arm5E0),REP16(arm5F0), // 5C0 + REP16(arm400), REP16(arm410), REP16(arm400), REP16(arm410), // 400 + REP16(arm440), REP16(arm450), REP16(arm440), REP16(arm450), // 440 + REP16(arm480), REP16(arm490), REP16(arm480), REP16(arm490), // 480 + REP16(arm4C0), REP16(arm4D0), REP16(arm4C0), REP16(arm4D0), // 4C0 + REP16(arm500), REP16(arm510), REP16(arm520), REP16(arm530), // 500 + REP16(arm540), REP16(arm550), REP16(arm560), REP16(arm570), // 540 + REP16(arm580), REP16(arm590), REP16(arm5A0), REP16(arm5B0), // 580 + REP16(arm5C0), REP16(arm5D0), REP16(arm5E0), REP16(arm5F0), // 5C0 - arm600,arm_UI,arm602,arm_UI,arm604,arm_UI,arm606,arm_UI, // 600 - arm600,arm_UI,arm602,arm_UI,arm604,arm_UI,arm606,arm_UI, // 608 - arm610,arm_UI,arm612,arm_UI,arm614,arm_UI,arm616,arm_UI, // 610 - arm610,arm_UI,arm612,arm_UI,arm614,arm_UI,arm616,arm_UI, // 618 - arm600,arm_UI,arm602,arm_UI,arm604,arm_UI,arm606,arm_UI, // 620 - arm600,arm_UI,arm602,arm_UI,arm604,arm_UI,arm606,arm_UI, // 628 - arm610,arm_UI,arm612,arm_UI,arm614,arm_UI,arm616,arm_UI, // 630 - arm610,arm_UI,arm612,arm_UI,arm614,arm_UI,arm616,arm_UI, // 638 - arm640,arm_UI,arm642,arm_UI,arm644,arm_UI,arm646,arm_UI, // 640 - arm640,arm_UI,arm642,arm_UI,arm644,arm_UI,arm646,arm_UI, // 648 - arm650,arm_UI,arm652,arm_UI,arm654,arm_UI,arm656,arm_UI, // 650 - arm650,arm_UI,arm652,arm_UI,arm654,arm_UI,arm656,arm_UI, // 658 - arm640,arm_UI,arm642,arm_UI,arm644,arm_UI,arm646,arm_UI, // 660 - arm640,arm_UI,arm642,arm_UI,arm644,arm_UI,arm646,arm_UI, // 668 - arm650,arm_UI,arm652,arm_UI,arm654,arm_UI,arm656,arm_UI, // 670 - arm650,arm_UI,arm652,arm_UI,arm654,arm_UI,arm656,arm_UI, // 678 - arm680,arm_UI,arm682,arm_UI,arm684,arm_UI,arm686,arm_UI, // 680 - arm680,arm_UI,arm682,arm_UI,arm684,arm_UI,arm686,arm_UI, // 688 - arm690,arm_UI,arm692,arm_UI,arm694,arm_UI,arm696,arm_UI, // 690 - arm690,arm_UI,arm692,arm_UI,arm694,arm_UI,arm696,arm_UI, // 698 - arm680,arm_UI,arm682,arm_UI,arm684,arm_UI,arm686,arm_UI, // 6A0 - arm680,arm_UI,arm682,arm_UI,arm684,arm_UI,arm686,arm_UI, // 6A8 - arm690,arm_UI,arm692,arm_UI,arm694,arm_UI,arm696,arm_UI, // 6B0 - arm690,arm_UI,arm692,arm_UI,arm694,arm_UI,arm696,arm_UI, // 6B8 - arm6C0,arm_UI,arm6C2,arm_UI,arm6C4,arm_UI,arm6C6,arm_UI, // 6C0 - arm6C0,arm_UI,arm6C2,arm_UI,arm6C4,arm_UI,arm6C6,arm_UI, // 6C8 - arm6D0,arm_UI,arm6D2,arm_UI,arm6D4,arm_UI,arm6D6,arm_UI, // 6D0 - arm6D0,arm_UI,arm6D2,arm_UI,arm6D4,arm_UI,arm6D6,arm_UI, // 6D8 - arm6C0,arm_UI,arm6C2,arm_UI,arm6C4,arm_UI,arm6C6,arm_UI, // 6E0 - arm6C0,arm_UI,arm6C2,arm_UI,arm6C4,arm_UI,arm6C6,arm_UI, // 6E8 - arm6D0,arm_UI,arm6D2,arm_UI,arm6D4,arm_UI,arm6D6,arm_UI, // 6F0 - arm6D0,arm_UI,arm6D2,arm_UI,arm6D4,arm_UI,arm6D6,arm_UI, // 6F8 + arm600, arm_UI, arm602, arm_UI, arm604, arm_UI, arm606, arm_UI, // 600 + arm600, arm_UI, arm602, arm_UI, arm604, arm_UI, arm606, arm_UI, // 608 + arm610, arm_UI, arm612, arm_UI, arm614, arm_UI, arm616, arm_UI, // 610 + arm610, arm_UI, arm612, arm_UI, arm614, arm_UI, arm616, arm_UI, // 618 + arm600, arm_UI, arm602, arm_UI, arm604, arm_UI, arm606, arm_UI, // 620 + arm600, arm_UI, arm602, arm_UI, arm604, arm_UI, arm606, arm_UI, // 628 + arm610, arm_UI, arm612, arm_UI, arm614, arm_UI, arm616, arm_UI, // 630 + arm610, arm_UI, arm612, arm_UI, arm614, arm_UI, arm616, arm_UI, // 638 + arm640, arm_UI, arm642, arm_UI, arm644, arm_UI, arm646, arm_UI, // 640 + arm640, arm_UI, arm642, arm_UI, arm644, arm_UI, arm646, arm_UI, // 648 + arm650, arm_UI, arm652, arm_UI, arm654, arm_UI, arm656, arm_UI, // 650 + arm650, arm_UI, arm652, arm_UI, arm654, arm_UI, arm656, arm_UI, // 658 + arm640, arm_UI, arm642, arm_UI, arm644, arm_UI, arm646, arm_UI, // 660 + arm640, arm_UI, arm642, arm_UI, arm644, arm_UI, arm646, arm_UI, // 668 + arm650, arm_UI, arm652, arm_UI, arm654, arm_UI, arm656, arm_UI, // 670 + arm650, arm_UI, arm652, arm_UI, arm654, arm_UI, arm656, arm_UI, // 678 + arm680, arm_UI, arm682, arm_UI, arm684, arm_UI, arm686, arm_UI, // 680 + arm680, arm_UI, arm682, arm_UI, arm684, arm_UI, arm686, arm_UI, // 688 + arm690, arm_UI, arm692, arm_UI, arm694, arm_UI, arm696, arm_UI, // 690 + arm690, arm_UI, arm692, arm_UI, arm694, arm_UI, arm696, arm_UI, // 698 + arm680, arm_UI, arm682, arm_UI, arm684, arm_UI, arm686, arm_UI, // 6A0 + arm680, arm_UI, arm682, arm_UI, arm684, arm_UI, arm686, arm_UI, // 6A8 + arm690, arm_UI, arm692, arm_UI, arm694, arm_UI, arm696, arm_UI, // 6B0 + arm690, arm_UI, arm692, arm_UI, arm694, arm_UI, arm696, arm_UI, // 6B8 + arm6C0, arm_UI, arm6C2, arm_UI, arm6C4, arm_UI, arm6C6, arm_UI, // 6C0 + arm6C0, arm_UI, arm6C2, arm_UI, arm6C4, arm_UI, arm6C6, arm_UI, // 6C8 + arm6D0, arm_UI, arm6D2, arm_UI, arm6D4, arm_UI, arm6D6, arm_UI, // 6D0 + arm6D0, arm_UI, arm6D2, arm_UI, arm6D4, arm_UI, arm6D6, arm_UI, // 6D8 + arm6C0, arm_UI, arm6C2, arm_UI, arm6C4, arm_UI, arm6C6, arm_UI, // 6E0 + arm6C0, arm_UI, arm6C2, arm_UI, arm6C4, arm_UI, arm6C6, arm_UI, // 6E8 + arm6D0, arm_UI, arm6D2, arm_UI, arm6D4, arm_UI, arm6D6, arm_UI, // 6F0 + arm6D0, arm_UI, arm6D2, arm_UI, arm6D4, arm_UI, arm6D6, arm_UI, // 6F8 - arm700,arm_UI,arm702,arm_UI,arm704,arm_UI,arm706,arm_UI, // 700 - arm700,arm_UI,arm702,arm_UI,arm704,arm_UI,arm706,arm_UI, // 708 - arm710,arm_UI,arm712,arm_UI,arm714,arm_UI,arm716,arm_UI, // 710 - arm710,arm_UI,arm712,arm_UI,arm714,arm_UI,arm716,arm_UI, // 718 - arm720,arm_UI,arm722,arm_UI,arm724,arm_UI,arm726,arm_UI, // 720 - arm720,arm_UI,arm722,arm_UI,arm724,arm_UI,arm726,arm_UI, // 728 - arm730,arm_UI,arm732,arm_UI,arm734,arm_UI,arm736,arm_UI, // 730 - arm730,arm_UI,arm732,arm_UI,arm734,arm_UI,arm736,arm_UI, // 738 - arm740,arm_UI,arm742,arm_UI,arm744,arm_UI,arm746,arm_UI, // 740 - arm740,arm_UI,arm742,arm_UI,arm744,arm_UI,arm746,arm_UI, // 748 - arm750,arm_UI,arm752,arm_UI,arm754,arm_UI,arm756,arm_UI, // 750 - arm750,arm_UI,arm752,arm_UI,arm754,arm_UI,arm756,arm_UI, // 758 - arm760,arm_UI,arm762,arm_UI,arm764,arm_UI,arm766,arm_UI, // 760 - arm760,arm_UI,arm762,arm_UI,arm764,arm_UI,arm766,arm_UI, // 768 - arm770,arm_UI,arm772,arm_UI,arm774,arm_UI,arm776,arm_UI, // 770 - arm770,arm_UI,arm772,arm_UI,arm774,arm_UI,arm776,arm_UI, // 778 - arm780,arm_UI,arm782,arm_UI,arm784,arm_UI,arm786,arm_UI, // 780 - arm780,arm_UI,arm782,arm_UI,arm784,arm_UI,arm786,arm_UI, // 788 - arm790,arm_UI,arm792,arm_UI,arm794,arm_UI,arm796,arm_UI, // 790 - arm790,arm_UI,arm792,arm_UI,arm794,arm_UI,arm796,arm_UI, // 798 - arm7A0,arm_UI,arm7A2,arm_UI,arm7A4,arm_UI,arm7A6,arm_UI, // 7A0 - arm7A0,arm_UI,arm7A2,arm_UI,arm7A4,arm_UI,arm7A6,arm_UI, // 7A8 - arm7B0,arm_UI,arm7B2,arm_UI,arm7B4,arm_UI,arm7B6,arm_UI, // 7B0 - arm7B0,arm_UI,arm7B2,arm_UI,arm7B4,arm_UI,arm7B6,arm_UI, // 7B8 - arm7C0,arm_UI,arm7C2,arm_UI,arm7C4,arm_UI,arm7C6,arm_UI, // 7C0 - arm7C0,arm_UI,arm7C2,arm_UI,arm7C4,arm_UI,arm7C6,arm_UI, // 7C8 - arm7D0,arm_UI,arm7D2,arm_UI,arm7D4,arm_UI,arm7D6,arm_UI, // 7D0 - arm7D0,arm_UI,arm7D2,arm_UI,arm7D4,arm_UI,arm7D6,arm_UI, // 7D8 - arm7E0,arm_UI,arm7E2,arm_UI,arm7E4,arm_UI,arm7E6,arm_UI, // 7E0 - arm7E0,arm_UI,arm7E2,arm_UI,arm7E4,arm_UI,arm7E6,arm_UI, // 7E8 - arm7F0,arm_UI,arm7F2,arm_UI,arm7F4,arm_UI,arm7F6,arm_UI, // 7F0 - arm7F0,arm_UI,arm7F2,arm_UI,arm7F4,arm_UI,arm7F6,arm_BP, // 7F8 + arm700, arm_UI, arm702, arm_UI, arm704, arm_UI, arm706, arm_UI, // 700 + arm700, arm_UI, arm702, arm_UI, arm704, arm_UI, arm706, arm_UI, // 708 + arm710, arm_UI, arm712, arm_UI, arm714, arm_UI, arm716, arm_UI, // 710 + arm710, arm_UI, arm712, arm_UI, arm714, arm_UI, arm716, arm_UI, // 718 + arm720, arm_UI, arm722, arm_UI, arm724, arm_UI, arm726, arm_UI, // 720 + arm720, arm_UI, arm722, arm_UI, arm724, arm_UI, arm726, arm_UI, // 728 + arm730, arm_UI, arm732, arm_UI, arm734, arm_UI, arm736, arm_UI, // 730 + arm730, arm_UI, arm732, arm_UI, arm734, arm_UI, arm736, arm_UI, // 738 + arm740, arm_UI, arm742, arm_UI, arm744, arm_UI, arm746, arm_UI, // 740 + arm740, arm_UI, arm742, arm_UI, arm744, arm_UI, arm746, arm_UI, // 748 + arm750, arm_UI, arm752, arm_UI, arm754, arm_UI, arm756, arm_UI, // 750 + arm750, arm_UI, arm752, arm_UI, arm754, arm_UI, arm756, arm_UI, // 758 + arm760, arm_UI, arm762, arm_UI, arm764, arm_UI, arm766, arm_UI, // 760 + arm760, arm_UI, arm762, arm_UI, arm764, arm_UI, arm766, arm_UI, // 768 + arm770, arm_UI, arm772, arm_UI, arm774, arm_UI, arm776, arm_UI, // 770 + arm770, arm_UI, arm772, arm_UI, arm774, arm_UI, arm776, arm_UI, // 778 + arm780, arm_UI, arm782, arm_UI, arm784, arm_UI, arm786, arm_UI, // 780 + arm780, arm_UI, arm782, arm_UI, arm784, arm_UI, arm786, arm_UI, // 788 + arm790, arm_UI, arm792, arm_UI, arm794, arm_UI, arm796, arm_UI, // 790 + arm790, arm_UI, arm792, arm_UI, arm794, arm_UI, arm796, arm_UI, // 798 + arm7A0, arm_UI, arm7A2, arm_UI, arm7A4, arm_UI, arm7A6, arm_UI, // 7A0 + arm7A0, arm_UI, arm7A2, arm_UI, arm7A4, arm_UI, arm7A6, arm_UI, // 7A8 + arm7B0, arm_UI, arm7B2, arm_UI, arm7B4, arm_UI, arm7B6, arm_UI, // 7B0 + arm7B0, arm_UI, arm7B2, arm_UI, arm7B4, arm_UI, arm7B6, arm_UI, // 7B8 + arm7C0, arm_UI, arm7C2, arm_UI, arm7C4, arm_UI, arm7C6, arm_UI, // 7C0 + arm7C0, arm_UI, arm7C2, arm_UI, arm7C4, arm_UI, arm7C6, arm_UI, // 7C8 + arm7D0, arm_UI, arm7D2, arm_UI, arm7D4, arm_UI, arm7D6, arm_UI, // 7D0 + arm7D0, arm_UI, arm7D2, arm_UI, arm7D4, arm_UI, arm7D6, arm_UI, // 7D8 + arm7E0, arm_UI, arm7E2, arm_UI, arm7E4, arm_UI, arm7E6, arm_UI, // 7E0 + arm7E0, arm_UI, arm7E2, arm_UI, arm7E4, arm_UI, arm7E6, arm_UI, // 7E8 + arm7F0, arm_UI, arm7F2, arm_UI, arm7F4, arm_UI, arm7F6, arm_UI, // 7F0 + arm7F0, arm_UI, arm7F2, arm_UI, arm7F4, arm_UI, arm7F6, arm_BP, // 7F8 - REP16(arm800),REP16(arm810),REP16(arm820),REP16(arm830), // 800 - REP16(arm840),REP16(arm850),REP16(arm860),REP16(arm870), // 840 - REP16(arm880),REP16(arm890),REP16(arm8A0),REP16(arm8B0), // 880 - REP16(arm8C0),REP16(arm8D0),REP16(arm8E0),REP16(arm8F0), // 8C0 - REP16(arm900),REP16(arm910),REP16(arm920),REP16(arm930), // 900 - REP16(arm940),REP16(arm950),REP16(arm960),REP16(arm970), // 940 - REP16(arm980),REP16(arm990),REP16(arm9A0),REP16(arm9B0), // 980 - REP16(arm9C0),REP16(arm9D0),REP16(arm9E0),REP16(arm9F0), // 9C0 + REP16(arm800), REP16(arm810), REP16(arm820), REP16(arm830), // 800 + REP16(arm840), REP16(arm850), REP16(arm860), REP16(arm870), // 840 + REP16(arm880), REP16(arm890), REP16(arm8A0), REP16(arm8B0), // 880 + REP16(arm8C0), REP16(arm8D0), REP16(arm8E0), REP16(arm8F0), // 8C0 + REP16(arm900), REP16(arm910), REP16(arm920), REP16(arm930), // 900 + REP16(arm940), REP16(arm950), REP16(arm960), REP16(arm970), // 940 + REP16(arm980), REP16(arm990), REP16(arm9A0), REP16(arm9B0), // 980 + REP16(arm9C0), REP16(arm9D0), REP16(arm9E0), REP16(arm9F0), // 9C0 - REP256(armA00), // A00 - REP256(armB00), // B00 - REP256(arm_UI), // C00 - REP256(arm_UI), // D00 + REP256(armA00), // A00 + REP256(armB00), // B00 + REP256(arm_UI), // C00 + REP256(arm_UI), // D00 - arm_UI,armE01,arm_UI,armE01,arm_UI,armE01,arm_UI,armE01, // E00 - arm_UI,armE01,arm_UI,armE01,arm_UI,armE01,arm_UI,armE01, // E08 - arm_UI,armE01,arm_UI,armE01,arm_UI,armE01,arm_UI,armE01, // E10 - arm_UI,armE01,arm_UI,armE01,arm_UI,armE01,arm_UI,armE01, // E18 - REP16(arm_UI), // E20 - REP16(arm_UI), // E30 - REP16(arm_UI),REP16(arm_UI),REP16(arm_UI),REP16(arm_UI), // E40 - REP16(arm_UI),REP16(arm_UI),REP16(arm_UI),REP16(arm_UI), // E80 - REP16(arm_UI),REP16(arm_UI),REP16(arm_UI),REP16(arm_UI), // EC0 + arm_UI, armE01, arm_UI, armE01, arm_UI, armE01, arm_UI, armE01, // E00 + arm_UI, armE01, arm_UI, armE01, arm_UI, armE01, arm_UI, armE01, // E08 + arm_UI, armE01, arm_UI, armE01, arm_UI, armE01, arm_UI, armE01, // E10 + arm_UI, armE01, arm_UI, armE01, arm_UI, armE01, arm_UI, armE01, // E18 + REP16(arm_UI), // E20 + REP16(arm_UI), // E30 + REP16(arm_UI), REP16(arm_UI), REP16(arm_UI), REP16(arm_UI), // E40 + REP16(arm_UI), REP16(arm_UI), REP16(arm_UI), REP16(arm_UI), // E80 + REP16(arm_UI), REP16(arm_UI), REP16(arm_UI), REP16(arm_UI), // EC0 - REP256(armF00), // F00 + REP256(armF00), // F00 }; // Wrapper routine (execution loop) /////////////////////////////////////// #if 0 -#include +#include static void tester(void) { static int ran=0;if(ran)return;ran=1; FILE*f=fopen("p:\\timing.txt","w");if(!f)return; @@ -2869,12 +2827,12 @@ static void tester(void) { int armExecute() { do { - if( cheatsEnabled ) { - cpuMasterCodeCheck(); - } + if (cheatsEnabled) { + cpuMasterCodeCheck(); + } if ((armNextPC & 0x0803FFFF) == 0x08020000) - busPrefetchCount = 0x100; + busPrefetchCount = 0x100; u32 opcode = cpuPrefetch[0]; cpuPrefetch[0] = cpuPrefetch[1]; @@ -2893,72 +2851,72 @@ int armExecute() #endif armNextPC = reg[15].I; - reg[15].I += 4; - ARM_PREFETCH_NEXT; + reg[15].I += 4; + ARM_PREFETCH_NEXT; #ifdef BKPT_SUPPORT - u32 memAddr = armNextPC; - memoryMap *m = &map[memAddr >> 24]; - if (m->breakPoints && BreakARMCheck(m->breakPoints, memAddr & m->mask)) { - if (debuggerBreakOnExecution(memAddr, armState)){ - // Revert tickcount? - debugger = true; - return 0; - } - } + u32 memAddr = armNextPC; + memoryMap* m = &map[memAddr >> 24]; + if (m->breakPoints && BreakARMCheck(m->breakPoints, memAddr & m->mask)) { + if (debuggerBreakOnExecution(memAddr, armState)) { + // Revert tickcount? + debugger = true; + return 0; + } + } #endif int cond = opcode >> 28; bool cond_res = true; - if (UNLIKELY(cond != 0x0E)) { // most opcodes are AL (always) - switch(cond) { - case 0x00: // EQ + if (UNLIKELY(cond != 0x0E)) { // most opcodes are AL (always) + switch (cond) { + case 0x00: // EQ cond_res = Z_FLAG; break; - case 0x01: // NE + case 0x01: // NE cond_res = !Z_FLAG; break; - case 0x02: // CS + case 0x02: // CS cond_res = C_FLAG; break; - case 0x03: // CC + case 0x03: // CC cond_res = !C_FLAG; break; - case 0x04: // MI + case 0x04: // MI cond_res = N_FLAG; break; - case 0x05: // PL + case 0x05: // PL cond_res = !N_FLAG; break; - case 0x06: // VS + case 0x06: // VS cond_res = V_FLAG; break; - case 0x07: // VC + case 0x07: // VC cond_res = !V_FLAG; break; - case 0x08: // HI + case 0x08: // HI cond_res = C_FLAG && !Z_FLAG; break; - case 0x09: // LS + case 0x09: // LS cond_res = !C_FLAG || Z_FLAG; break; - case 0x0A: // GE + case 0x0A: // GE cond_res = N_FLAG == V_FLAG; break; - case 0x0B: // LT + case 0x0B: // LT cond_res = N_FLAG != V_FLAG; break; - case 0x0C: // GT - cond_res = !Z_FLAG &&(N_FLAG == V_FLAG); + case 0x0C: // GT + cond_res = !Z_FLAG && (N_FLAG == V_FLAG); break; - case 0x0D: // LE + case 0x0D: // LE cond_res = Z_FLAG || (N_FLAG != V_FLAG); break; - case 0x0E: // AL (impossible, checked above) + case 0x0E: // AL (impossible, checked above) cond_res = true; break; - case 0x0F: - default: + case 0x0F: + default: // ??? cond_res = false; break; @@ -2966,46 +2924,46 @@ int armExecute() } if (cond_res) - (*armInsnTable[((opcode>>16)&0xFF0) | ((opcode>>4)&0x0F)])(opcode); + (*armInsnTable[((opcode >> 16) & 0xFF0) | ((opcode >> 4) & 0x0F)])(opcode); #ifdef INSN_COUNTER count(opcode, cond_res); #endif #ifdef BKPT_SUPPORT - if (enableRegBreak){ - if (lowRegBreakCounter[0]) - breakReg_check(0); - if (lowRegBreakCounter[1]) - breakReg_check(1); - if (lowRegBreakCounter[2]) - breakReg_check(2); - if (lowRegBreakCounter[3]) - breakReg_check(3); - if (medRegBreakCounter[0]) - breakReg_check(4); - if (medRegBreakCounter[1]) - breakReg_check(5); - if (medRegBreakCounter[2]) - breakReg_check(6); - if (medRegBreakCounter[3]) - breakReg_check(7); - if (highRegBreakCounter[0]) - breakReg_check(8); - if (highRegBreakCounter[1]) - breakReg_check(9); - if (highRegBreakCounter[2]) - breakReg_check(10); - if (highRegBreakCounter[3]) - breakReg_check(11); - if (statusRegBreakCounter[0]) - breakReg_check(12); - if (statusRegBreakCounter[1]) - breakReg_check(13); - if (statusRegBreakCounter[2]) - breakReg_check(14); - if (statusRegBreakCounter[3]) - breakReg_check(15); - } + if (enableRegBreak) { + if (lowRegBreakCounter[0]) + breakReg_check(0); + if (lowRegBreakCounter[1]) + breakReg_check(1); + if (lowRegBreakCounter[2]) + breakReg_check(2); + if (lowRegBreakCounter[3]) + breakReg_check(3); + if (medRegBreakCounter[0]) + breakReg_check(4); + if (medRegBreakCounter[1]) + breakReg_check(5); + if (medRegBreakCounter[2]) + breakReg_check(6); + if (medRegBreakCounter[3]) + breakReg_check(7); + if (highRegBreakCounter[0]) + breakReg_check(8); + if (highRegBreakCounter[1]) + breakReg_check(9); + if (highRegBreakCounter[2]) + breakReg_check(10); + if (highRegBreakCounter[3]) + breakReg_check(11); + if (statusRegBreakCounter[0]) + breakReg_check(12); + if (statusRegBreakCounter[1]) + breakReg_check(13); + if (statusRegBreakCounter[2]) + breakReg_check(14); + if (statusRegBreakCounter[3]) + breakReg_check(15); + } #endif if (clockTicks < 0) return 0; @@ -3013,7 +2971,7 @@ int armExecute() clockTicks = 1 + codeTicksAccessSeq32(oldArmNextPC); cpuTotalTicks += clockTicks; - } while (cpuTotalTicks -#include #include #include +#include +#include #include #ifndef _MSC_VER #include #endif +#include "../NLS.h" +#include "../System.h" +#include "../Util.h" +#include "../common/ConfigManager.h" +#include "Cheats.h" +#include "EEprom.h" +#include "Flash.h" #include "GBA.h" #include "GBAcpu.h" #include "GBAinline.h" #include "Globals.h" -#include "EEprom.h" -#include "Flash.h" #include "Sound.h" #include "Sram.h" -#include "bios.h" -#include "Cheats.h" -#include "../NLS.h" -#include "elf.h" -#include "../Util.h" -#include "../System.h" -#include "../common/ConfigManager.h" #include "agbprint.h" +#include "bios.h" +#include "elf.h" #include "remote.h" #ifdef PROFILING @@ -40,43 +40,45 @@ static int clockTicks; static INSN_REGPARM void thumbUnknownInsn(u32 opcode) { #ifdef GBA_LOGGING - if(systemVerbose & VERBOSE_UNDEFINED) - log("Undefined THUMB instruction %04x at %08x\n", opcode, armNextPC-2); + if (systemVerbose & VERBOSE_UNDEFINED) + log("Undefined THUMB instruction %04x at %08x\n", opcode, armNextPC - 2); #endif - CPUUndefinedException(); + CPUUndefinedException(); } #ifdef BKPT_SUPPORT static INSN_REGPARM void thumbBreakpoint(u32 opcode) { - reg[15].I -= 2; - armNextPC -= 2; - dbgSignal(5, opcode & 255); - clockTicks = -1; + reg[15].I -= 2; + armNextPC -= 2; + dbgSignal(5, opcode & 255); + clockTicks = -1; } #endif // Common macros ////////////////////////////////////////////////////////// #ifdef BKPT_SUPPORT -# define THUMB_CONSOLE_OUTPUT(a,b) do { \ - if ((opcode == 0x4000) && (reg[0].I == 0xC0DED00D)) { \ - dbgOutput((a), (b)); \ - } \ -} while (0) -# define UPDATE_OLDREG do { \ - if (debugger_last) { \ - snprintf(oldbuffer, sizeof(oldbuffer), "%08X", \ - armState ? reg[15].I - 4 : reg[15].I - 2); \ - int i; \ - for (i = 0; i < 18; i++) { \ - oldreg[i] = reg[i].I; \ - } \ - } \ -} while (0) +#define THUMB_CONSOLE_OUTPUT(a, b) \ + do { \ + if ((opcode == 0x4000) && (reg[0].I == 0xC0DED00D)) { \ + dbgOutput((a), (b)); \ + } \ + } while (0) +#define UPDATE_OLDREG \ + do { \ + if (debugger_last) { \ + snprintf(oldbuffer, sizeof(oldbuffer), "%08X", \ + armState ? reg[15].I - 4 : reg[15].I - 2); \ + int i; \ + for (i = 0; i < 18; i++) { \ + oldreg[i] = reg[i].I; \ + } \ + } \ + } while (0) #else -# define THUMB_CONSOLE_OUTPUT(a,b) -# define UPDATE_OLDREG +#define THUMB_CONSOLE_OUTPUT(a, b) +#define UPDATE_OLDREG #endif #define NEG(i) ((i) >> 31) @@ -85,82 +87,78 @@ static INSN_REGPARM void thumbBreakpoint(u32 opcode) #ifndef C_CORE #ifdef __GNUC__ #ifdef __POWERPC__ - #define ADD_RD_RS_RN(N) \ - { \ - register int Flags; \ - register int Result; \ - asm volatile("addco. %0, %2, %3\n" \ - "mcrxr cr1\n" \ - "mfcr %1\n" \ - : "=r" (Result), \ - "=r" (Flags) \ - : "r" (reg[source].I), \ - "r" (reg[N].I) \ - ); \ - reg[dest].I = Result; \ - Z_FLAG = (Flags >> 29) & 1; \ - N_FLAG = (Flags >> 31) & 1; \ - C_FLAG = (Flags >> 25) & 1; \ - V_FLAG = (Flags >> 26) & 1; \ - } - #define ADD_RD_RS_O3(N) \ - { \ - register int Flags; \ - register int Result; \ - asm volatile("addco. %0, %2, %3\n" \ - "mcrxr cr1\n" \ - "mfcr %1\n" \ - : "=r" (Result), \ - "=r" (Flags) \ - : "r" (reg[source].I), \ - "r" (N) \ - ); \ - reg[dest].I = Result; \ - Z_FLAG = (Flags >> 29) & 1; \ - N_FLAG = (Flags >> 31) & 1; \ - C_FLAG = (Flags >> 25) & 1; \ - V_FLAG = (Flags >> 26) & 1; \ - } - #define ADD_RD_RS_O3_0 ADD_RD_RS_O3 - #define ADD_RN_O8(d) \ - {\ - register int Flags; \ - register int Result; \ - asm volatile("addco. %0, %2, %3\n" \ - "mcrxr cr1\n" \ - "mfcr %1\n" \ - : "=r" (Result), \ - "=r" (Flags) \ - : "r" (reg[(d)].I), \ - "r" (opcode & 255) \ - ); \ - reg[(d)].I = Result; \ - Z_FLAG = (Flags >> 29) & 1; \ - N_FLAG = (Flags >> 31) & 1; \ - C_FLAG = (Flags >> 25) & 1; \ - V_FLAG = (Flags >> 26) & 1; \ - } - #define CMN_RD_RS \ - {\ - register int Flags; \ - register int Result; \ - asm volatile("addco. %0, %2, %3\n" \ - "mcrxr cr1\n" \ - "mfcr %1\n" \ - : "=r" (Result), \ - "=r" (Flags) \ - : "r" (reg[dest].I), \ - "r" (value) \ - ); \ - Z_FLAG = (Flags >> 29) & 1; \ - N_FLAG = (Flags >> 31) & 1; \ - C_FLAG = (Flags >> 25) & 1; \ - V_FLAG = (Flags >> 26) & 1; \ - } - #define ADC_RD_RS \ - {\ - register int Flags; \ - register int Result; \ +#define ADD_RD_RS_RN(N) \ + { \ + register int Flags; \ + register int Result; \ + asm volatile("addco. %0, %2, %3\n" \ + "mcrxr cr1\n" \ + "mfcr %1\n" \ + : "=r"(Result), \ + "=r"(Flags) \ + : "r"(reg[source].I), \ + "r"(reg[N].I)); \ + reg[dest].I = Result; \ + Z_FLAG = (Flags >> 29) & 1; \ + N_FLAG = (Flags >> 31) & 1; \ + C_FLAG = (Flags >> 25) & 1; \ + V_FLAG = (Flags >> 26) & 1; \ + } +#define ADD_RD_RS_O3(N) \ + { \ + register int Flags; \ + register int Result; \ + asm volatile("addco. %0, %2, %3\n" \ + "mcrxr cr1\n" \ + "mfcr %1\n" \ + : "=r"(Result), \ + "=r"(Flags) \ + : "r"(reg[source].I), \ + "r"(N)); \ + reg[dest].I = Result; \ + Z_FLAG = (Flags >> 29) & 1; \ + N_FLAG = (Flags >> 31) & 1; \ + C_FLAG = (Flags >> 25) & 1; \ + V_FLAG = (Flags >> 26) & 1; \ + } +#define ADD_RD_RS_O3_0 ADD_RD_RS_O3 +#define ADD_RN_O8(d) \ + { \ + register int Flags; \ + register int Result; \ + asm volatile("addco. %0, %2, %3\n" \ + "mcrxr cr1\n" \ + "mfcr %1\n" \ + : "=r"(Result), \ + "=r"(Flags) \ + : "r"(reg[(d)].I), \ + "r"(opcode & 255)); \ + reg[(d)].I = Result; \ + Z_FLAG = (Flags >> 29) & 1; \ + N_FLAG = (Flags >> 31) & 1; \ + C_FLAG = (Flags >> 25) & 1; \ + V_FLAG = (Flags >> 26) & 1; \ + } +#define CMN_RD_RS \ + { \ + register int Flags; \ + register int Result; \ + asm volatile("addco. %0, %2, %3\n" \ + "mcrxr cr1\n" \ + "mfcr %1\n" \ + : "=r"(Result), \ + "=r"(Flags) \ + : "r"(reg[dest].I), \ + "r"(value)); \ + Z_FLAG = (Flags >> 29) & 1; \ + N_FLAG = (Flags >> 31) & 1; \ + C_FLAG = (Flags >> 25) & 1; \ + V_FLAG = (Flags >> 26) & 1; \ + } +#define ADC_RD_RS \ + { \ + register int Flags; \ + register int Result; \ asm volatile("mtspr 1, %4\n" \ /* reg 1 is xer */ "addeo. %0, %2, %3\n" \ "mcrxr cr1\n" \ @@ -170,89 +168,85 @@ static INSN_REGPARM void thumbBreakpoint(u32 opcode) : "r" (reg[dest].I), \ "r" (value), \ "r" (C_FLAG << 29) \ - ); \ - reg[dest].I = Result; \ - Z_FLAG = (Flags >> 29) & 1; \ - N_FLAG = (Flags >> 31) & 1; \ - C_FLAG = (Flags >> 25) & 1; \ - V_FLAG = (Flags >> 26) & 1; \ - } - #define SUB_RD_RS_RN(N) \ - {\ - register int Flags; \ - register int Result; \ - asm volatile("subco. %0, %2, %3\n" \ - "mcrxr cr1\n" \ - "mfcr %1\n" \ - : "=r" (Result), \ - "=r" (Flags) \ - : "r" (reg[source].I), \ - "r" (reg[N].I) \ - ); \ - reg[dest].I = Result; \ - Z_FLAG = (Flags >> 29) & 1; \ - N_FLAG = (Flags >> 31) & 1; \ - C_FLAG = (Flags >> 25) & 1; \ - V_FLAG = (Flags >> 26) & 1; \ - } - #define SUB_RD_RS_O3(N) \ - {\ - register int Flags; \ - register int Result; \ - asm volatile("subco. %0, %2, %3\n" \ - "mcrxr cr1\n" \ - "mfcr %1\n" \ - : "=r" (Result), \ - "=r" (Flags) \ - : "r" (reg[source].I), \ - "r" (N) \ - ); \ - reg[dest].I = Result; \ - Z_FLAG = (Flags >> 29) & 1; \ - N_FLAG = (Flags >> 31) & 1; \ - C_FLAG = (Flags >> 25) & 1; \ - V_FLAG = (Flags >> 26) & 1; \ - } - #define SUB_RD_RS_O3_0 SUB_RD_RS_O3 - #define SUB_RN_O8(d) \ - {\ - register int Flags; \ - register int Result; \ - asm volatile("subco. %0, %2, %3\n" \ - "mcrxr cr1\n" \ - "mfcr %1\n" \ - : "=r" (Result), \ - "=r" (Flags) \ - : "r" (reg[(d)].I), \ - "r" (opcode & 255) \ - ); \ - reg[(d)].I = Result; \ - Z_FLAG = (Flags >> 29) & 1; \ - N_FLAG = (Flags >> 31) & 1; \ - C_FLAG = (Flags >> 25) & 1; \ - V_FLAG = (Flags >> 26) & 1; \ - } - #define CMP_RN_O8(d) \ - {\ - register int Flags; \ - register int Result; \ - asm volatile("subco. %0, %2, %3\n" \ - "mcrxr cr1\n" \ - "mfcr %1\n" \ - : "=r" (Result), \ - "=r" (Flags) \ - : "r" (reg[(d)].I), \ - "r" (opcode & 255) \ - ); \ - Z_FLAG = (Flags >> 29) & 1; \ - N_FLAG = (Flags >> 31) & 1; \ - C_FLAG = (Flags >> 25) & 1; \ - V_FLAG = (Flags >> 26) & 1; \ - } - #define SBC_RD_RS \ - {\ - register int Flags; \ - register int Result; \ + ); + reg[dest].I = Result; + Z_FLAG = (Flags >> 29) & 1; + N_FLAG = (Flags >> 31) & 1; + C_FLAG = (Flags >> 25) & 1; + V_FLAG = (Flags >> 26) & 1; + } +#define SUB_RD_RS_RN(N) \ + { \ + register int Flags; \ + register int Result; \ + asm volatile("subco. %0, %2, %3\n" \ + "mcrxr cr1\n" \ + "mfcr %1\n" \ + : "=r"(Result), \ + "=r"(Flags) \ + : "r"(reg[source].I), \ + "r"(reg[N].I)); \ + reg[dest].I = Result; \ + Z_FLAG = (Flags >> 29) & 1; \ + N_FLAG = (Flags >> 31) & 1; \ + C_FLAG = (Flags >> 25) & 1; \ + V_FLAG = (Flags >> 26) & 1; \ + } +#define SUB_RD_RS_O3(N) \ + { \ + register int Flags; \ + register int Result; \ + asm volatile("subco. %0, %2, %3\n" \ + "mcrxr cr1\n" \ + "mfcr %1\n" \ + : "=r"(Result), \ + "=r"(Flags) \ + : "r"(reg[source].I), \ + "r"(N)); \ + reg[dest].I = Result; \ + Z_FLAG = (Flags >> 29) & 1; \ + N_FLAG = (Flags >> 31) & 1; \ + C_FLAG = (Flags >> 25) & 1; \ + V_FLAG = (Flags >> 26) & 1; \ + } +#define SUB_RD_RS_O3_0 SUB_RD_RS_O3 +#define SUB_RN_O8(d) \ + { \ + register int Flags; \ + register int Result; \ + asm volatile("subco. %0, %2, %3\n" \ + "mcrxr cr1\n" \ + "mfcr %1\n" \ + : "=r"(Result), \ + "=r"(Flags) \ + : "r"(reg[(d)].I), \ + "r"(opcode & 255)); \ + reg[(d)].I = Result; \ + Z_FLAG = (Flags >> 29) & 1; \ + N_FLAG = (Flags >> 31) & 1; \ + C_FLAG = (Flags >> 25) & 1; \ + V_FLAG = (Flags >> 26) & 1; \ + } +#define CMP_RN_O8(d) \ + { \ + register int Flags; \ + register int Result; \ + asm volatile("subco. %0, %2, %3\n" \ + "mcrxr cr1\n" \ + "mfcr %1\n" \ + : "=r"(Result), \ + "=r"(Flags) \ + : "r"(reg[(d)].I), \ + "r"(opcode & 255)); \ + Z_FLAG = (Flags >> 29) & 1; \ + N_FLAG = (Flags >> 31) & 1; \ + C_FLAG = (Flags >> 25) & 1; \ + V_FLAG = (Flags >> 26) & 1; \ + } +#define SBC_RD_RS \ + { \ + register int Flags; \ + register int Result; \ asm volatile("mtspr 1, %4\n" \ /* reg 1 is xer */ "subfeo. %0, %3, %2\n" \ "mcrxr cr1\n" \ @@ -262,2125 +256,1945 @@ static INSN_REGPARM void thumbBreakpoint(u32 opcode) : "r" (reg[dest].I), \ "r" (value), \ "r" (C_FLAG << 29) \ - ); \ - reg[dest].I = Result; \ - Z_FLAG = (Flags >> 29) & 1; \ - N_FLAG = (Flags >> 31) & 1; \ - C_FLAG = (Flags >> 25) & 1; \ - V_FLAG = (Flags >> 26) & 1; \ - } - #define NEG_RD_RS \ - {\ - register int Flags; \ - register int Result; \ - asm volatile("subfco. %0, %2, %3\n" \ - "mcrxr cr1\n" \ - "mfcr %1\n" \ - : "=r" (Result), \ - "=r" (Flags) \ - : "r" (reg[source].I), \ - "r" (0) \ - ); \ - reg[dest].I = Result; \ - Z_FLAG = (Flags >> 29) & 1; \ - N_FLAG = (Flags >> 31) & 1; \ - C_FLAG = (Flags >> 25) & 1; \ - V_FLAG = (Flags >> 26) & 1; \ - } - #define CMP_RD_RS \ - {\ - register int Flags; \ - register int Result; \ - asm volatile("subco. %0, %2, %3\n" \ - "mcrxr cr1\n" \ - "mfcr %1\n" \ - : "=r" (Result), \ - "=r" (Flags) \ - : "r" (reg[dest].I), \ - "r" (value) \ - ); \ - Z_FLAG = (Flags >> 29) & 1; \ - N_FLAG = (Flags >> 31) & 1; \ - C_FLAG = (Flags >> 25) & 1; \ - V_FLAG = (Flags >> 26) & 1; \ - } + ); + reg[dest].I = Result; + Z_FLAG = (Flags >> 29) & 1; + N_FLAG = (Flags >> 31) & 1; + C_FLAG = (Flags >> 25) & 1; + V_FLAG = (Flags >> 26) & 1; + } +#define NEG_RD_RS \ + { \ + register int Flags; \ + register int Result; \ + asm volatile("subfco. %0, %2, %3\n" \ + "mcrxr cr1\n" \ + "mfcr %1\n" \ + : "=r"(Result), \ + "=r"(Flags) \ + : "r"(reg[source].I), \ + "r"(0)); \ + reg[dest].I = Result; \ + Z_FLAG = (Flags >> 29) & 1; \ + N_FLAG = (Flags >> 31) & 1; \ + C_FLAG = (Flags >> 25) & 1; \ + V_FLAG = (Flags >> 26) & 1; \ + } +#define CMP_RD_RS \ + { \ + register int Flags; \ + register int Result; \ + asm volatile("subco. %0, %2, %3\n" \ + "mcrxr cr1\n" \ + "mfcr %1\n" \ + : "=r"(Result), \ + "=r"(Flags) \ + : "r"(reg[dest].I), \ + "r"(value)); \ + Z_FLAG = (Flags >> 29) & 1; \ + N_FLAG = (Flags >> 31) & 1; \ + C_FLAG = (Flags >> 25) & 1; \ + V_FLAG = (Flags >> 26) & 1; \ + } #else - #define EMIT1(op,arg) #op " " arg "; " - #define EMIT2(op,src,dest) #op " " src ", " dest "; " - #define KONST(val) "$" #val - #define ASMVAR(cvar) ASMVAR2 (__USER_LABEL_PREFIX__, cvar) - #define ASMVAR2(prefix,cvar) STRING (prefix) cvar - #define STRING(x) #x - #define VAR(var) ASMVAR(#var) - #define REGREF1(index) ASMVAR("reg(" index ")") - #define REGREF2(index,scale) ASMVAR("reg(," index "," #scale ")") - #define eax "%%eax" - #define ecx "%%ecx" - #define edx "%%edx" - #define ADD_RN_O8(d) \ - asm ("andl $0xFF, %%eax;"\ - "addl %%eax, %0;"\ - EMIT1(setsb, VAR(N_FLAG)) \ - EMIT1(setzb, VAR(Z_FLAG)) \ - EMIT1(setcb, VAR(C_FLAG)) \ - EMIT1(setob, VAR(V_FLAG)) \ - : "=m" (reg[(d)].I)); - #define CMN_RD_RS \ - asm ("add %0, %1;"\ - EMIT1(setsb, VAR(N_FLAG)) \ - EMIT1(setzb, VAR(Z_FLAG)) \ - EMIT1(setcb, VAR(C_FLAG)) \ - EMIT1(setob, VAR(V_FLAG)) \ - : \ - : "r" (value), "r" (reg[dest].I):"1"); - #define ADC_RD_RS \ - asm (EMIT2(bt,KONST(0),VAR(C_FLAG)) \ - "adc %1, %%ebx;"\ - EMIT1(setsb, VAR(N_FLAG)) \ - EMIT1(setzb, VAR(Z_FLAG)) \ - EMIT1(setcb, VAR(C_FLAG)) \ - EMIT1(setob, VAR(V_FLAG)) \ - : "=b" (reg[dest].I)\ - : "r" (value), "b" (reg[dest].I)); - #define SUB_RN_O8(d) \ - asm ("andl $0xFF, %%eax;"\ - "subl %%eax, %0;"\ - EMIT1(setsb, VAR(N_FLAG)) \ - EMIT1(setzb, VAR(Z_FLAG)) \ - EMIT1(setncb, VAR(C_FLAG)) \ - EMIT1(setob, VAR(V_FLAG)) \ - : "=m" (reg[(d)].I)); - #define MOV_RN_O8(d) \ - asm ("andl $0xFF, %%eax;"\ - EMIT2(movb,KONST(0),VAR(N_FLAG)) \ - "movl %%eax, %0;"\ - EMIT1(setzb, VAR(Z_FLAG)) \ - : "=m" (reg[(d)].I)); - #define CMP_RN_O8(d) \ - asm ("andl $0xFF, %%eax;"\ - "cmpl %%eax, %0;"\ - EMIT1(setsb, VAR(N_FLAG)) \ - EMIT1(setzb, VAR(Z_FLAG)) \ - EMIT1(setncb, VAR(C_FLAG)) \ - EMIT1(setob, VAR(V_FLAG)) \ - : \ - : "m" (reg[(d)].I)); - #define SBC_RD_RS \ - asm volatile (EMIT2(bt,KONST(0),VAR(C_FLAG)) \ - "cmc;"\ - "sbb %1, %%ebx;"\ - EMIT1(setsb, VAR(N_FLAG)) \ - EMIT1(setzb, VAR(Z_FLAG)) \ - EMIT1(setncb, VAR(C_FLAG)) \ - EMIT1(setob, VAR(V_FLAG)) \ - : "=b" (reg[dest].I)\ - : "r" (value), "b" (reg[dest].I) : "cc", "memory"); - #define LSL_RD_RS \ - asm ("shl %%cl, %%eax;"\ - EMIT1(setcb, VAR(C_FLAG)) \ - : "=a" (value)\ - : "a" (reg[dest].I), "c" (value)); - #define LSR_RD_RS \ - asm ("shr %%cl, %%eax;"\ - EMIT1(setcb, VAR(C_FLAG)) \ - : "=a" (value)\ - : "a" (reg[dest].I), "c" (value)); - #define ASR_RD_RS \ - asm ("sar %%cl, %%eax;"\ - EMIT1(setcb, VAR(C_FLAG)) \ - : "=a" (value)\ - : "a" (reg[dest].I), "c" (value)); - #define ROR_RD_RS \ - asm ("ror %%cl, %%eax;"\ - EMIT1(setcb, VAR(C_FLAG)) \ - : "=a" (value)\ - : "a" (reg[dest].I), "c" (value)); - #define NEG_RD_RS \ - asm ("neg %%ebx;"\ - EMIT1(setsb, VAR(N_FLAG)) \ - EMIT1(setzb, VAR(Z_FLAG)) \ - EMIT1(setncb, VAR(C_FLAG)) \ - EMIT1(setob, VAR(V_FLAG)) \ - : "=b" (reg[dest].I)\ - : "b" (reg[source].I)); - #define CMP_RD_RS \ - asm ("sub %0, %1;"\ - EMIT1(setsb, VAR(N_FLAG)) \ - EMIT1(setzb, VAR(Z_FLAG)) \ - EMIT1(setncb, VAR(C_FLAG)) \ - EMIT1(setob, VAR(V_FLAG)) \ - : \ - : "r" (value), "r" (reg[dest].I):"1"); - #define IMM5_INSN(OP,N) \ - asm("movl %%eax,%%ecx;" \ - "shrl $1,%%eax;" \ - "andl $7,%%ecx;" \ - "andl $0x1C,%%eax;" \ - EMIT2(movl, REGREF1(eax), edx) \ - OP \ - EMIT1(setsb, VAR(N_FLAG)) \ - EMIT1(setzb, VAR(Z_FLAG)) \ - EMIT2(movl, edx, REGREF2(ecx,4)) \ - : : "i" (N)) - #define IMM5_INSN_0(OP) \ - asm("movl %%eax,%%ecx;" \ - "shrl $1,%%eax;" \ - "andl $7,%%ecx;" \ - "andl $0x1C,%%eax;" \ - EMIT2(movl, REGREF1(eax), edx) \ - OP \ - EMIT1(setsb, VAR(N_FLAG)) \ - EMIT1(setzb, VAR(Z_FLAG)) \ - EMIT2(movl, edx, REGREF2(ecx,4)) \ - : : ) - #define IMM5_LSL \ - "shll %0,%%edx;"\ - EMIT1(setcb, VAR(C_FLAG)) - #define IMM5_LSL_0 \ - "testl %%edx,%%edx;" - #define IMM5_LSR \ - "shrl %0,%%edx;"\ - EMIT1(setcb, VAR(C_FLAG)) - #define IMM5_LSR_0 \ - "testl %%edx,%%edx;"\ - EMIT1(setsb, VAR(C_FLAG)) \ - "xorl %%edx,%%edx;" - #define IMM5_ASR \ - "sarl %0,%%edx;"\ - EMIT1(setcb, VAR(C_FLAG)) - #define IMM5_ASR_0 \ - "sarl $31,%%edx;"\ - EMIT1(setsb, VAR(C_FLAG)) - #define THREEARG_INSN(OP,N) \ - asm("movl %%eax,%%edx;" \ - "shrl $1,%%edx;" \ - "andl $0x1C,%%edx;" \ - "andl $7,%%eax;" \ - EMIT2(movl, REGREF1(edx), ecx) \ - OP(N) \ - EMIT1(setsb, VAR(N_FLAG)) \ - EMIT1(setzb, VAR(Z_FLAG)) \ - EMIT2(movl, ecx, REGREF2(eax,4)) \ - : : ) - #define ADD_RD_RS_RN(N) \ - EMIT2(add,VAR(reg)"+"#N"*4",ecx) \ - EMIT1(setcb, VAR(C_FLAG)) \ - EMIT1(setob, VAR(V_FLAG)) - #define ADD_RD_RS_O3(N) \ - "add $"#N",%%ecx;" \ - EMIT1(setcb, VAR(C_FLAG)) \ - EMIT1(setob, VAR(V_FLAG)) - #define ADD_RD_RS_O3_0(N) \ - EMIT2(movb,KONST(0),VAR(C_FLAG)) \ - "add $0,%%ecx;" \ - EMIT2(movb,KONST(0),VAR(V_FLAG)) - #define SUB_RD_RS_RN(N) \ - EMIT2(sub,VAR(reg)"+"#N"*4",ecx) \ - EMIT1(setncb, VAR(C_FLAG)) \ - EMIT1(setob, VAR(V_FLAG)) - #define SUB_RD_RS_O3(N) \ - "sub $"#N",%%ecx;" \ - EMIT1(setncb, VAR(C_FLAG)) \ - EMIT1(setob, VAR(V_FLAG)) - #define SUB_RD_RS_O3_0(N) \ - EMIT2(movb,KONST(1),VAR(C_FLAG)) \ - "sub $0,%%ecx;" \ - EMIT2(movb,KONST(0),VAR(V_FLAG)) +#define EMIT1(op, arg) #op " " arg "; " +#define EMIT2(op, src, dest) #op " " src ", " dest "; " +#define KONST(val) "$" #val +#define ASMVAR(cvar) ASMVAR2(__USER_LABEL_PREFIX__, cvar) +#define ASMVAR2(prefix, cvar) STRING(prefix) \ + cvar +#define STRING(x) #x +#define VAR(var) ASMVAR(#var) +#define REGREF1(index) ASMVAR("reg(" index ")") +#define REGREF2(index, scale) ASMVAR("reg(," index "," #scale ")") +#define eax "%%eax" +#define ecx "%%ecx" +#define edx "%%edx" +#define ADD_RN_O8(d) \ + asm("andl $0xFF, %%eax;" \ + "addl %%eax, %0;" EMIT1(setsb, VAR(N_FLAG)) \ + EMIT1(setzb, VAR(Z_FLAG)) \ + EMIT1(setcb, VAR(C_FLAG)) \ + EMIT1(setob, VAR(V_FLAG)) \ + : "=m"(reg[(d)].I)); +#define CMN_RD_RS \ + asm("add %0, %1;" EMIT1(setsb, VAR(N_FLAG)) \ + EMIT1(setzb, VAR(Z_FLAG)) \ + EMIT1(setcb, VAR(C_FLAG)) \ + EMIT1(setob, VAR(V_FLAG)) \ + : \ + : "r"(value), "r"(reg[dest].I) \ + : "1"); +#define ADC_RD_RS \ + asm(EMIT2(bt, KONST(0), VAR(C_FLAG)) "adc %1, %%ebx;" EMIT1(setsb, VAR(N_FLAG)) \ + EMIT1(setzb, VAR(Z_FLAG)) \ + EMIT1(setcb, VAR(C_FLAG)) \ + EMIT1(setob, VAR(V_FLAG)) \ + : "=b"(reg[dest].I) \ + : "r"(value), "b"(reg[dest].I)); +#define SUB_RN_O8(d) \ + asm("andl $0xFF, %%eax;" \ + "subl %%eax, %0;" EMIT1(setsb, VAR(N_FLAG)) \ + EMIT1(setzb, VAR(Z_FLAG)) \ + EMIT1(setncb, VAR(C_FLAG)) \ + EMIT1(setob, VAR(V_FLAG)) \ + : "=m"(reg[(d)].I)); +#define MOV_RN_O8(d) \ + asm("andl $0xFF, %%eax;" EMIT2(movb, KONST(0), VAR(N_FLAG)) "movl %%eax, %0;" EMIT1(setzb, VAR(Z_FLAG)) \ + : "=m"(reg[(d)].I)); +#define CMP_RN_O8(d) \ + asm("andl $0xFF, %%eax;" \ + "cmpl %%eax, %0;" EMIT1(setsb, VAR(N_FLAG)) \ + EMIT1(setzb, VAR(Z_FLAG)) \ + EMIT1(setncb, VAR(C_FLAG)) \ + EMIT1(setob, VAR(V_FLAG)) \ + : \ + : "m"(reg[(d)].I)); +#define SBC_RD_RS \ + asm volatile(EMIT2(bt, KONST(0), VAR(C_FLAG)) "cmc;" \ + "sbb %1, %%ebx;" EMIT1(setsb, VAR(N_FLAG)) \ + EMIT1(setzb, VAR(Z_FLAG)) \ + EMIT1(setncb, VAR(C_FLAG)) \ + EMIT1(setob, VAR(V_FLAG)) \ + : "=b"(reg[dest].I) \ + : "r"(value), "b"(reg[dest].I) \ + : "cc", "memory"); +#define LSL_RD_RS \ + asm("shl %%cl, %%eax;" EMIT1(setcb, VAR(C_FLAG)) \ + : "=a"(value) \ + : "a"(reg[dest].I), "c"(value)); +#define LSR_RD_RS \ + asm("shr %%cl, %%eax;" EMIT1(setcb, VAR(C_FLAG)) \ + : "=a"(value) \ + : "a"(reg[dest].I), "c"(value)); +#define ASR_RD_RS \ + asm("sar %%cl, %%eax;" EMIT1(setcb, VAR(C_FLAG)) \ + : "=a"(value) \ + : "a"(reg[dest].I), "c"(value)); +#define ROR_RD_RS \ + asm("ror %%cl, %%eax;" EMIT1(setcb, VAR(C_FLAG)) \ + : "=a"(value) \ + : "a"(reg[dest].I), "c"(value)); +#define NEG_RD_RS \ + asm("neg %%ebx;" EMIT1(setsb, VAR(N_FLAG)) \ + EMIT1(setzb, VAR(Z_FLAG)) \ + EMIT1(setncb, VAR(C_FLAG)) \ + EMIT1(setob, VAR(V_FLAG)) \ + : "=b"(reg[dest].I) \ + : "b"(reg[source].I)); +#define CMP_RD_RS \ + asm("sub %0, %1;" EMIT1(setsb, VAR(N_FLAG)) \ + EMIT1(setzb, VAR(Z_FLAG)) \ + EMIT1(setncb, VAR(C_FLAG)) \ + EMIT1(setob, VAR(V_FLAG)) \ + : \ + : "r"(value), "r"(reg[dest].I) \ + : "1"); +#define IMM5_INSN(OP, N) \ + asm("movl %%eax,%%ecx;" \ + "shrl $1,%%eax;" \ + "andl $7,%%ecx;" \ + "andl $0x1C,%%eax;" EMIT2(movl, REGREF1(eax), edx) \ + OP \ + EMIT1(setsb, VAR(N_FLAG)) \ + EMIT1(setzb, VAR(Z_FLAG)) \ + EMIT2(movl, edx, REGREF2(ecx, 4)) \ + : \ + : "i"(N)) +#define IMM5_INSN_0(OP) \ + asm("movl %%eax,%%ecx;" \ + "shrl $1,%%eax;" \ + "andl $7,%%ecx;" \ + "andl $0x1C,%%eax;" EMIT2(movl, REGREF1(eax), edx) \ + OP \ + EMIT1(setsb, VAR(N_FLAG)) \ + EMIT1(setzb, VAR(Z_FLAG)) \ + EMIT2(movl, edx, REGREF2(ecx, 4)) \ + : \ + :) +#define IMM5_LSL \ + "shll %0,%%edx;" EMIT1(setcb, VAR(C_FLAG)) +#define IMM5_LSL_0 \ + "testl %%edx,%%edx;" +#define IMM5_LSR \ + "shrl %0,%%edx;" EMIT1(setcb, VAR(C_FLAG)) +#define IMM5_LSR_0 \ + "testl %%edx,%%edx;" EMIT1(setsb, VAR(C_FLAG)) "xorl %%edx,%%edx;" +#define IMM5_ASR \ + "sarl %0,%%edx;" EMIT1(setcb, VAR(C_FLAG)) +#define IMM5_ASR_0 \ + "sarl $31,%%edx;" EMIT1(setsb, VAR(C_FLAG)) +#define THREEARG_INSN(OP, N) \ + asm("movl %%eax,%%edx;" \ + "shrl $1,%%edx;" \ + "andl $0x1C,%%edx;" \ + "andl $7,%%eax;" EMIT2(movl, REGREF1(edx), ecx) \ + OP(N) \ + EMIT1(setsb, VAR(N_FLAG)) \ + EMIT1(setzb, VAR(Z_FLAG)) \ + EMIT2(movl, ecx, REGREF2(eax, 4)) \ + : \ + :) +#define ADD_RD_RS_RN(N) \ + EMIT2(add, VAR(reg) "+" #N "*4", ecx) \ + EMIT1(setcb, VAR(C_FLAG)) \ + EMIT1(setob, VAR(V_FLAG)) +#define ADD_RD_RS_O3(N) \ + "add $" #N ",%%ecx;" EMIT1(setcb, VAR(C_FLAG)) \ + EMIT1(setob, VAR(V_FLAG)) +#define ADD_RD_RS_O3_0(N) \ + EMIT2(movb, KONST(0), VAR(C_FLAG)) \ + "add $0,%%ecx;" EMIT2(movb, KONST(0), VAR(V_FLAG)) +#define SUB_RD_RS_RN(N) \ + EMIT2(sub, VAR(reg) "+" #N "*4", ecx) \ + EMIT1(setncb, VAR(C_FLAG)) \ + EMIT1(setob, VAR(V_FLAG)) +#define SUB_RD_RS_O3(N) \ + "sub $" #N ",%%ecx;" EMIT1(setncb, VAR(C_FLAG)) \ + EMIT1(setob, VAR(V_FLAG)) +#define SUB_RD_RS_O3_0(N) \ + EMIT2(movb, KONST(1), VAR(C_FLAG)) \ + "sub $0,%%ecx;" EMIT2(movb, KONST(0), VAR(V_FLAG)) #endif #else // !__GNUC__ - #define ADD_RD_RS_RN(N) \ - {\ - __asm mov eax, source\ - __asm mov ebx, dword ptr [OFFSET reg+4*eax]\ - __asm add ebx, dword ptr [OFFSET reg+4*N]\ - __asm mov eax, dest\ - __asm mov dword ptr [OFFSET reg+4*eax], ebx\ - __asm sets byte ptr N_FLAG\ - __asm setz byte ptr Z_FLAG\ - __asm setc byte ptr C_FLAG\ - __asm seto byte ptr V_FLAG\ - } - #define ADD_RD_RS_O3(N) \ - {\ - __asm mov eax, source\ - __asm mov ebx, dword ptr [OFFSET reg+4*eax]\ - __asm add ebx, N\ - __asm mov eax, dest\ - __asm mov dword ptr [OFFSET reg+4*eax], ebx\ - __asm sets byte ptr N_FLAG\ - __asm setz byte ptr Z_FLAG\ - __asm setc byte ptr C_FLAG\ - __asm seto byte ptr V_FLAG\ - } - #define ADD_RD_RS_O3_0 \ - {\ - __asm mov eax, source\ - __asm mov ebx, dword ptr [OFFSET reg+4*eax]\ - __asm add ebx, 0\ - __asm mov eax, dest\ - __asm mov dword ptr [OFFSET reg+4*eax], ebx\ - __asm sets byte ptr N_FLAG\ - __asm setz byte ptr Z_FLAG\ - __asm mov byte ptr C_FLAG, 0\ - __asm mov byte ptr V_FLAG, 0\ - } - #define ADD_RN_O8(d) \ - {\ - __asm mov ebx, opcode\ - __asm and ebx, 255\ - __asm add dword ptr [OFFSET reg+4*(d)], ebx\ - __asm sets byte ptr N_FLAG\ - __asm setz byte ptr Z_FLAG\ - __asm setc byte ptr C_FLAG\ - __asm seto byte ptr V_FLAG\ - } - #define CMN_RD_RS \ - {\ - __asm mov eax, dest\ - __asm mov ebx, dword ptr [OFFSET reg+4*eax]\ - __asm add ebx, value\ - __asm sets byte ptr N_FLAG\ - __asm setz byte ptr Z_FLAG\ - __asm setc byte ptr C_FLAG\ - __asm seto byte ptr V_FLAG\ - } - #define ADC_RD_RS \ - {\ - __asm mov ebx, dest\ - __asm mov ebx, dword ptr [OFFSET reg+4*ebx]\ - __asm bt word ptr C_FLAG, 0\ - __asm adc ebx, value\ - __asm mov eax, dest\ - __asm mov dword ptr [OFFSET reg+4*eax], ebx\ - __asm sets byte ptr N_FLAG\ - __asm setz byte ptr Z_FLAG\ - __asm setc byte ptr C_FLAG\ - __asm seto byte ptr V_FLAG\ - } - #define SUB_RD_RS_RN(N) \ - {\ - __asm mov eax, source\ - __asm mov ebx, dword ptr [OFFSET reg+4*eax]\ - __asm sub ebx, dword ptr [OFFSET reg+4*N]\ - __asm mov eax, dest\ - __asm mov dword ptr [OFFSET reg+4*eax], ebx\ - __asm sets byte ptr N_FLAG\ - __asm setz byte ptr Z_FLAG\ - __asm setnc byte ptr C_FLAG\ - __asm seto byte ptr V_FLAG\ - } - #define SUB_RD_RS_O3(N) \ - {\ - __asm mov eax, source\ - __asm mov ebx, dword ptr [OFFSET reg+4*eax]\ - __asm sub ebx, N\ - __asm mov eax, dest\ - __asm mov dword ptr [OFFSET reg+4*eax], ebx\ - __asm sets byte ptr N_FLAG\ - __asm setz byte ptr Z_FLAG\ - __asm setnc byte ptr C_FLAG\ - __asm seto byte ptr V_FLAG\ - } - #define SUB_RD_RS_O3_0 \ - {\ - __asm mov eax, source\ - __asm mov ebx, dword ptr [OFFSET reg+4*eax]\ - __asm sub ebx, 0\ - __asm mov eax, dest\ - __asm mov dword ptr [OFFSET reg+4*eax], ebx\ - __asm sets byte ptr N_FLAG\ - __asm setz byte ptr Z_FLAG\ - __asm mov byte ptr C_FLAG, 1\ - __asm mov byte ptr V_FLAG, 0\ - } - #define SUB_RN_O8(d) \ - {\ - __asm mov ebx, opcode\ - __asm and ebx, 255\ - __asm sub dword ptr [OFFSET reg + 4*(d)], ebx\ - __asm sets byte ptr N_FLAG\ - __asm setz byte ptr Z_FLAG\ - __asm setnc byte ptr C_FLAG\ - __asm seto byte ptr V_FLAG\ - } - #define MOV_RN_O8(d) \ - {\ - __asm mov eax, opcode\ - __asm and eax, 255\ - __asm mov dword ptr [OFFSET reg+4*(d)], eax\ - __asm sets byte ptr N_FLAG\ - __asm setz byte ptr Z_FLAG\ - } - #define CMP_RN_O8(d) \ - {\ - __asm mov eax, dword ptr [OFFSET reg+4*(d)]\ - __asm mov ebx, opcode\ - __asm and ebx, 255\ - __asm sub eax, ebx\ - __asm sets byte ptr N_FLAG\ - __asm setz byte ptr Z_FLAG\ - __asm setnc byte ptr C_FLAG\ - __asm seto byte ptr V_FLAG\ - } - #define SBC_RD_RS \ - {\ - __asm mov ebx, dest\ - __asm mov ebx, dword ptr [OFFSET reg + 4*ebx]\ - __asm mov eax, value\ - __asm bt word ptr C_FLAG, 0\ - __asm cmc\ - __asm sbb ebx, eax\ - __asm mov eax, dest\ - __asm mov dword ptr [OFFSET reg + 4*eax], ebx\ - __asm sets byte ptr N_FLAG\ - __asm setz byte ptr Z_FLAG\ - __asm setnc byte ptr C_FLAG\ - __asm seto byte ptr V_FLAG\ - } - #define LSL_RD_RM_I5 \ - {\ - __asm mov eax, source\ - __asm mov eax, dword ptr [OFFSET reg + 4 * eax]\ - __asm mov cl, byte ptr shift\ - __asm shl eax, cl\ - __asm mov value, eax\ - __asm setc byte ptr C_FLAG\ - } - #define LSL_RD_RS \ - {\ - __asm mov eax, dest\ - __asm mov eax, dword ptr [OFFSET reg + 4 * eax]\ - __asm mov cl, byte ptr value\ - __asm shl eax, cl\ - __asm mov value, eax\ - __asm setc byte ptr C_FLAG\ - } - #define LSR_RD_RM_I5 \ - {\ - __asm mov eax, source\ - __asm mov eax, dword ptr [OFFSET reg + 4 * eax]\ - __asm mov cl, byte ptr shift\ - __asm shr eax, cl\ - __asm mov value, eax\ - __asm setc byte ptr C_FLAG\ - } - #define LSR_RD_RS \ - {\ - __asm mov eax, dest\ - __asm mov eax, dword ptr [OFFSET reg + 4 * eax]\ - __asm mov cl, byte ptr value\ - __asm shr eax, cl\ - __asm mov value, eax\ - __asm setc byte ptr C_FLAG\ - } - #define ASR_RD_RM_I5 \ - {\ - __asm mov eax, source\ - __asm mov eax, dword ptr [OFFSET reg + 4*eax]\ - __asm mov cl, byte ptr shift\ - __asm sar eax, cl\ - __asm mov value, eax\ - __asm setc byte ptr C_FLAG\ - } - #define ASR_RD_RS \ - {\ - __asm mov eax, dest\ - __asm mov eax, dword ptr [OFFSET reg + 4*eax]\ - __asm mov cl, byte ptr value\ - __asm sar eax, cl\ - __asm mov value, eax\ - __asm setc byte ptr C_FLAG\ - } - #define ROR_RD_RS \ - {\ - __asm mov eax, dest\ - __asm mov eax, dword ptr [OFFSET reg + 4*eax]\ - __asm mov cl, byte ptr value\ - __asm ror eax, cl\ - __asm mov value, eax\ - __asm setc byte ptr C_FLAG\ - } - #define NEG_RD_RS \ - {\ - __asm mov ebx, source\ - __asm mov ebx, dword ptr [OFFSET reg+4*ebx]\ - __asm neg ebx\ - __asm mov eax, dest\ - __asm mov dword ptr [OFFSET reg+4*eax],ebx\ - __asm sets byte ptr N_FLAG\ - __asm setz byte ptr Z_FLAG\ - __asm setnc byte ptr C_FLAG\ - __asm seto byte ptr V_FLAG\ - } - #define CMP_RD_RS \ - {\ - __asm mov eax, dest\ - __asm mov ebx, dword ptr [OFFSET reg+4*eax]\ - __asm sub ebx, value\ - __asm sets byte ptr N_FLAG\ - __asm setz byte ptr Z_FLAG\ - __asm setnc byte ptr C_FLAG\ - __asm seto byte ptr V_FLAG\ - } +#define ADD_RD_RS_RN(N) \ + { \ + __asm mov eax, source __asm mov ebx, dword ptr[OFFSET reg + 4 * eax] __asm add ebx, dword ptr[OFFSET reg + 4 * N] __asm mov eax, dest __asm mov dword ptr[OFFSET reg + 4 * eax], ebx __asm sets byte ptr N_FLAG __asm setz byte ptr Z_FLAG __asm setc byte ptr C_FLAG __asm seto byte ptr V_FLAG \ + } +#define ADD_RD_RS_O3(N) \ + { \ + __asm mov eax, source __asm mov ebx, dword ptr[OFFSET reg + 4 * eax] __asm add ebx, N __asm mov eax, dest __asm mov dword ptr[OFFSET reg + 4 * eax], ebx __asm sets byte ptr N_FLAG __asm setz byte ptr Z_FLAG __asm setc byte ptr C_FLAG __asm seto byte ptr V_FLAG \ + } +#define ADD_RD_RS_O3_0 \ + { \ + __asm mov eax, source __asm mov ebx, dword ptr[OFFSET reg + 4 * eax] __asm add ebx, 0 __asm mov eax, dest __asm mov dword ptr[OFFSET reg + 4 * eax], ebx __asm sets byte ptr N_FLAG __asm setz byte ptr Z_FLAG __asm mov byte ptr C_FLAG, 0 __asm mov byte ptr V_FLAG, 0 \ + } +#define ADD_RN_O8(d) \ + { \ + __asm mov ebx, opcode __asm and ebx, 255 __asm add dword ptr[OFFSET reg + 4 * (d)], ebx __asm sets byte ptr N_FLAG __asm setz byte ptr Z_FLAG __asm setc byte ptr C_FLAG __asm seto byte ptr V_FLAG \ + } +#define CMN_RD_RS \ + { \ + __asm mov eax, dest __asm mov ebx, dword ptr[OFFSET reg + 4 * eax] __asm add ebx, value __asm sets byte ptr N_FLAG __asm setz byte ptr Z_FLAG __asm setc byte ptr C_FLAG __asm seto byte ptr V_FLAG \ + } +#define ADC_RD_RS \ + { \ + __asm mov ebx, dest __asm mov ebx, dword ptr[OFFSET reg + 4 * ebx] __asm bt word ptr C_FLAG, 0 __asm adc ebx, value __asm mov eax, dest __asm mov dword ptr[OFFSET reg + 4 * eax], ebx __asm sets byte ptr N_FLAG __asm setz byte ptr Z_FLAG __asm setc byte ptr C_FLAG __asm seto byte ptr V_FLAG \ + } +#define SUB_RD_RS_RN(N) \ + { \ + __asm mov eax, source __asm mov ebx, dword ptr[OFFSET reg + 4 * eax] __asm sub ebx, dword ptr[OFFSET reg + 4 * N] __asm mov eax, dest __asm mov dword ptr[OFFSET reg + 4 * eax], ebx __asm sets byte ptr N_FLAG __asm setz byte ptr Z_FLAG __asm setnc byte ptr C_FLAG __asm seto byte ptr V_FLAG \ + } +#define SUB_RD_RS_O3(N) \ + { \ + __asm mov eax, source __asm mov ebx, dword ptr[OFFSET reg + 4 * eax] __asm sub ebx, N __asm mov eax, dest __asm mov dword ptr[OFFSET reg + 4 * eax], ebx __asm sets byte ptr N_FLAG __asm setz byte ptr Z_FLAG __asm setnc byte ptr C_FLAG __asm seto byte ptr V_FLAG \ + } +#define SUB_RD_RS_O3_0 \ + { \ + __asm mov eax, source __asm mov ebx, dword ptr[OFFSET reg + 4 * eax] __asm sub ebx, 0 __asm mov eax, dest __asm mov dword ptr[OFFSET reg + 4 * eax], ebx __asm sets byte ptr N_FLAG __asm setz byte ptr Z_FLAG __asm mov byte ptr C_FLAG, 1 __asm mov byte ptr V_FLAG, 0 \ + } +#define SUB_RN_O8(d) \ + { \ + __asm mov ebx, opcode __asm and ebx, 255 __asm sub dword ptr[OFFSET reg + 4 * (d)], ebx __asm sets byte ptr N_FLAG __asm setz byte ptr Z_FLAG __asm setnc byte ptr C_FLAG __asm seto byte ptr V_FLAG \ + } +#define MOV_RN_O8(d) \ + { \ + __asm mov eax, opcode __asm and eax, 255 __asm mov dword ptr[OFFSET reg + 4 * (d)], eax __asm sets byte ptr N_FLAG __asm setz byte ptr Z_FLAG \ + } +#define CMP_RN_O8(d) \ + { \ + __asm mov eax, dword ptr[OFFSET reg + 4 * (d)] __asm mov ebx, opcode __asm and ebx, 255 __asm sub eax, ebx __asm sets byte ptr N_FLAG __asm setz byte ptr Z_FLAG __asm setnc byte ptr C_FLAG __asm seto byte ptr V_FLAG \ + } +#define SBC_RD_RS \ + { \ + __asm mov ebx, dest __asm mov ebx, dword ptr[OFFSET reg + 4 * ebx] __asm mov eax, value __asm bt word ptr C_FLAG, 0 __asm cmc __asm sbb ebx, eax __asm mov eax, dest __asm mov dword ptr[OFFSET reg + 4 * eax], ebx __asm sets byte ptr N_FLAG __asm setz byte ptr Z_FLAG __asm setnc byte ptr C_FLAG __asm seto byte ptr V_FLAG \ + } +#define LSL_RD_RM_I5 \ + { \ + __asm mov eax, source __asm mov eax, dword ptr[OFFSET reg + 4 * eax] __asm mov cl, byte ptr shift __asm shl eax, cl __asm mov value, eax __asm setc byte ptr C_FLAG \ + } +#define LSL_RD_RS \ + { \ + __asm mov eax, dest __asm mov eax, dword ptr[OFFSET reg + 4 * eax] __asm mov cl, byte ptr value __asm shl eax, cl __asm mov value, eax __asm setc byte ptr C_FLAG \ + } +#define LSR_RD_RM_I5 \ + { \ + __asm mov eax, source __asm mov eax, dword ptr[OFFSET reg + 4 * eax] __asm mov cl, byte ptr shift __asm shr eax, cl __asm mov value, eax __asm setc byte ptr C_FLAG \ + } +#define LSR_RD_RS \ + { \ + __asm mov eax, dest __asm mov eax, dword ptr[OFFSET reg + 4 * eax] __asm mov cl, byte ptr value __asm shr eax, cl __asm mov value, eax __asm setc byte ptr C_FLAG \ + } +#define ASR_RD_RM_I5 \ + { \ + __asm mov eax, source __asm mov eax, dword ptr[OFFSET reg + 4 * eax] __asm mov cl, byte ptr shift __asm sar eax, cl __asm mov value, eax __asm setc byte ptr C_FLAG \ + } +#define ASR_RD_RS \ + { \ + __asm mov eax, dest __asm mov eax, dword ptr[OFFSET reg + 4 * eax] __asm mov cl, byte ptr value __asm sar eax, cl __asm mov value, eax __asm setc byte ptr C_FLAG \ + } +#define ROR_RD_RS \ + { \ + __asm mov eax, dest __asm mov eax, dword ptr[OFFSET reg + 4 * eax] __asm mov cl, byte ptr value __asm ror eax, cl __asm mov value, eax __asm setc byte ptr C_FLAG \ + } +#define NEG_RD_RS \ + { \ + __asm mov ebx, source __asm mov ebx, dword ptr[OFFSET reg + 4 * ebx] __asm neg ebx __asm mov eax, dest __asm mov dword ptr[OFFSET reg + 4 * eax], ebx __asm sets byte ptr N_FLAG __asm setz byte ptr Z_FLAG __asm setnc byte ptr C_FLAG __asm seto byte ptr V_FLAG \ + } +#define CMP_RD_RS \ + { \ + __asm mov eax, dest __asm mov ebx, dword ptr[OFFSET reg + 4 * eax] __asm sub ebx, value __asm sets byte ptr N_FLAG __asm setz byte ptr Z_FLAG __asm setnc byte ptr C_FLAG __asm seto byte ptr V_FLAG \ + } #endif #endif -// C core + // C core #ifndef ADDCARRY - #define ADDCARRY(a, b, c) \ - C_FLAG = ((NEG(a) & NEG(b)) |\ - (NEG(a) & POS(c)) |\ - (NEG(b) & POS(c))) ? true : false; +#define ADDCARRY(a, b, c) \ + C_FLAG = ((NEG(a) & NEG(b)) | (NEG(a) & POS(c)) | (NEG(b) & POS(c))) ? true : false; #endif #ifndef ADDOVERFLOW - #define ADDOVERFLOW(a, b, c) \ - V_FLAG = ((NEG(a) & NEG(b) & POS(c)) |\ - (POS(a) & POS(b) & NEG(c))) ? true : false; +#define ADDOVERFLOW(a, b, c) \ + V_FLAG = ((NEG(a) & NEG(b) & POS(c)) | (POS(a) & POS(b) & NEG(c))) ? true : false; #endif #ifndef SUBCARRY - #define SUBCARRY(a, b, c) \ - C_FLAG = ((NEG(a) & POS(b)) |\ - (NEG(a) & POS(c)) |\ - (POS(b) & POS(c))) ? true : false; +#define SUBCARRY(a, b, c) \ + C_FLAG = ((NEG(a) & POS(b)) | (NEG(a) & POS(c)) | (POS(b) & POS(c))) ? true : false; #endif #ifndef SUBOVERFLOW - #define SUBOVERFLOW(a, b, c)\ - V_FLAG = ((NEG(a) & POS(b) & POS(c)) |\ - (POS(a) & NEG(b) & NEG(c))) ? true : false; +#define SUBOVERFLOW(a, b, c) \ + V_FLAG = ((NEG(a) & POS(b) & POS(c)) | (POS(a) & NEG(b) & NEG(c))) ? true : false; #endif #ifndef ADD_RD_RS_RN - #define ADD_RD_RS_RN(N) \ - {\ - u32 lhs = reg[source].I;\ - u32 rhs = reg[N].I;\ - u32 res = lhs + rhs;\ - reg[dest].I = res;\ - Z_FLAG = (res == 0) ? true : false;\ - N_FLAG = NEG(res) ? true : false;\ - ADDCARRY(lhs, rhs, res);\ - ADDOVERFLOW(lhs, rhs, res);\ - } +#define ADD_RD_RS_RN(N) \ + { \ + u32 lhs = reg[source].I; \ + u32 rhs = reg[N].I; \ + u32 res = lhs + rhs; \ + reg[dest].I = res; \ + Z_FLAG = (res == 0) ? true : false; \ + N_FLAG = NEG(res) ? true : false; \ + ADDCARRY(lhs, rhs, res); \ + ADDOVERFLOW(lhs, rhs, res); \ + } #endif #ifndef ADD_RD_RS_O3 - #define ADD_RD_RS_O3(N) \ - {\ - u32 lhs = reg[source].I;\ - u32 rhs = N;\ - u32 res = lhs + rhs;\ - reg[dest].I = res;\ - Z_FLAG = (res == 0) ? true : false;\ - N_FLAG = NEG(res) ? true : false;\ - ADDCARRY(lhs, rhs, res);\ - ADDOVERFLOW(lhs, rhs, res);\ - } +#define ADD_RD_RS_O3(N) \ + { \ + u32 lhs = reg[source].I; \ + u32 rhs = N; \ + u32 res = lhs + rhs; \ + reg[dest].I = res; \ + Z_FLAG = (res == 0) ? true : false; \ + N_FLAG = NEG(res) ? true : false; \ + ADDCARRY(lhs, rhs, res); \ + ADDOVERFLOW(lhs, rhs, res); \ + } #endif #ifndef ADD_RD_RS_O3_0 -# define ADD_RD_RS_O3_0 ADD_RD_RS_O3 +#define ADD_RD_RS_O3_0 ADD_RD_RS_O3 #endif #ifndef ADD_RN_O8 - #define ADD_RN_O8(d) \ - {\ - u32 lhs = reg[(d)].I;\ - u32 rhs = (opcode & 255);\ - u32 res = lhs + rhs;\ - reg[(d)].I = res;\ - Z_FLAG = (res == 0) ? true : false;\ - N_FLAG = NEG(res) ? true : false;\ - ADDCARRY(lhs, rhs, res);\ - ADDOVERFLOW(lhs, rhs, res);\ - } +#define ADD_RN_O8(d) \ + { \ + u32 lhs = reg[(d)].I; \ + u32 rhs = (opcode & 255); \ + u32 res = lhs + rhs; \ + reg[(d)].I = res; \ + Z_FLAG = (res == 0) ? true : false; \ + N_FLAG = NEG(res) ? true : false; \ + ADDCARRY(lhs, rhs, res); \ + ADDOVERFLOW(lhs, rhs, res); \ + } #endif #ifndef CMN_RD_RS - #define CMN_RD_RS \ - {\ - u32 lhs = reg[dest].I;\ - u32 rhs = value;\ - u32 res = lhs + rhs;\ - Z_FLAG = (res == 0) ? true : false;\ - N_FLAG = NEG(res) ? true : false;\ - ADDCARRY(lhs, rhs, res);\ - ADDOVERFLOW(lhs, rhs, res);\ - } +#define CMN_RD_RS \ + { \ + u32 lhs = reg[dest].I; \ + u32 rhs = value; \ + u32 res = lhs + rhs; \ + Z_FLAG = (res == 0) ? true : false; \ + N_FLAG = NEG(res) ? true : false; \ + ADDCARRY(lhs, rhs, res); \ + ADDOVERFLOW(lhs, rhs, res); \ + } #endif #ifndef ADC_RD_RS - #define ADC_RD_RS \ - {\ - u32 lhs = reg[dest].I;\ - u32 rhs = value;\ - u32 res = lhs + rhs + (u32)C_FLAG;\ - reg[dest].I = res;\ - Z_FLAG = (res == 0) ? true : false;\ - N_FLAG = NEG(res) ? true : false;\ - ADDCARRY(lhs, rhs, res);\ - ADDOVERFLOW(lhs, rhs, res);\ - } +#define ADC_RD_RS \ + { \ + u32 lhs = reg[dest].I; \ + u32 rhs = value; \ + u32 res = lhs + rhs + (u32)C_FLAG; \ + reg[dest].I = res; \ + Z_FLAG = (res == 0) ? true : false; \ + N_FLAG = NEG(res) ? true : false; \ + ADDCARRY(lhs, rhs, res); \ + ADDOVERFLOW(lhs, rhs, res); \ + } #endif #ifndef SUB_RD_RS_RN - #define SUB_RD_RS_RN(N) \ - {\ - u32 lhs = reg[source].I;\ - u32 rhs = reg[N].I;\ - u32 res = lhs - rhs;\ - reg[dest].I = res;\ - Z_FLAG = (res == 0) ? true : false;\ - N_FLAG = NEG(res) ? true : false;\ - SUBCARRY(lhs, rhs, res);\ - SUBOVERFLOW(lhs, rhs, res);\ - } +#define SUB_RD_RS_RN(N) \ + { \ + u32 lhs = reg[source].I; \ + u32 rhs = reg[N].I; \ + u32 res = lhs - rhs; \ + reg[dest].I = res; \ + Z_FLAG = (res == 0) ? true : false; \ + N_FLAG = NEG(res) ? true : false; \ + SUBCARRY(lhs, rhs, res); \ + SUBOVERFLOW(lhs, rhs, res); \ + } #endif #ifndef SUB_RD_RS_O3 - #define SUB_RD_RS_O3(N) \ - {\ - u32 lhs = reg[source].I;\ - u32 rhs = N;\ - u32 res = lhs - rhs;\ - reg[dest].I = res;\ - Z_FLAG = (res == 0) ? true : false;\ - N_FLAG = NEG(res) ? true : false;\ - SUBCARRY(lhs, rhs, res);\ - SUBOVERFLOW(lhs, rhs, res);\ - } +#define SUB_RD_RS_O3(N) \ + { \ + u32 lhs = reg[source].I; \ + u32 rhs = N; \ + u32 res = lhs - rhs; \ + reg[dest].I = res; \ + Z_FLAG = (res == 0) ? true : false; \ + N_FLAG = NEG(res) ? true : false; \ + SUBCARRY(lhs, rhs, res); \ + SUBOVERFLOW(lhs, rhs, res); \ + } #endif #ifndef SUB_RD_RS_O3_0 -# define SUB_RD_RS_O3_0 SUB_RD_RS_O3 +#define SUB_RD_RS_O3_0 SUB_RD_RS_O3 #endif #ifndef SUB_RN_O8 - #define SUB_RN_O8(d) \ - {\ - u32 lhs = reg[(d)].I;\ - u32 rhs = (opcode & 255);\ - u32 res = lhs - rhs;\ - reg[(d)].I = res;\ - Z_FLAG = (res == 0) ? true : false;\ - N_FLAG = NEG(res) ? true : false;\ - SUBCARRY(lhs, rhs, res);\ - SUBOVERFLOW(lhs, rhs, res);\ - } +#define SUB_RN_O8(d) \ + { \ + u32 lhs = reg[(d)].I; \ + u32 rhs = (opcode & 255); \ + u32 res = lhs - rhs; \ + reg[(d)].I = res; \ + Z_FLAG = (res == 0) ? true : false; \ + N_FLAG = NEG(res) ? true : false; \ + SUBCARRY(lhs, rhs, res); \ + SUBOVERFLOW(lhs, rhs, res); \ + } #endif #ifndef MOV_RN_O8 - #define MOV_RN_O8(d) \ - {\ - reg[d].I = opcode & 255;\ - N_FLAG = false;\ - Z_FLAG = (reg[d].I ? false : true);\ - } +#define MOV_RN_O8(d) \ + { \ + reg[d].I = opcode & 255; \ + N_FLAG = false; \ + Z_FLAG = (reg[d].I ? false : true); \ + } #endif #ifndef CMP_RN_O8 - #define CMP_RN_O8(d) \ - {\ - u32 lhs = reg[(d)].I;\ - u32 rhs = (opcode & 255);\ - u32 res = lhs - rhs;\ - Z_FLAG = (res == 0) ? true : false;\ - N_FLAG = NEG(res) ? true : false;\ - SUBCARRY(lhs, rhs, res);\ - SUBOVERFLOW(lhs, rhs, res);\ - } +#define CMP_RN_O8(d) \ + { \ + u32 lhs = reg[(d)].I; \ + u32 rhs = (opcode & 255); \ + u32 res = lhs - rhs; \ + Z_FLAG = (res == 0) ? true : false; \ + N_FLAG = NEG(res) ? true : false; \ + SUBCARRY(lhs, rhs, res); \ + SUBOVERFLOW(lhs, rhs, res); \ + } #endif #ifndef SBC_RD_RS - #define SBC_RD_RS \ - {\ - u32 lhs = reg[dest].I;\ - u32 rhs = value;\ - u32 res = lhs - rhs - !((u32)C_FLAG);\ - reg[dest].I = res;\ - Z_FLAG = (res == 0) ? true : false;\ - N_FLAG = NEG(res) ? true : false;\ - SUBCARRY(lhs, rhs, res);\ - SUBOVERFLOW(lhs, rhs, res);\ - } +#define SBC_RD_RS \ + { \ + u32 lhs = reg[dest].I; \ + u32 rhs = value; \ + u32 res = lhs - rhs - !((u32)C_FLAG); \ + reg[dest].I = res; \ + Z_FLAG = (res == 0) ? true : false; \ + N_FLAG = NEG(res) ? true : false; \ + SUBCARRY(lhs, rhs, res); \ + SUBOVERFLOW(lhs, rhs, res); \ + } #endif #ifndef LSL_RD_RM_I5 - #define LSL_RD_RM_I5 \ - {\ - C_FLAG = (reg[source].I >> (32 - shift)) & 1 ? true : false;\ - value = reg[source].I << shift;\ - } +#define LSL_RD_RM_I5 \ + { \ + C_FLAG = (reg[source].I >> (32 - shift)) & 1 ? true : false; \ + value = reg[source].I << shift; \ + } #endif #ifndef LSL_RD_RS - #define LSL_RD_RS \ - {\ - C_FLAG = (reg[dest].I >> (32 - value)) & 1 ? true : false;\ - value = reg[dest].I << value;\ - } +#define LSL_RD_RS \ + { \ + C_FLAG = (reg[dest].I >> (32 - value)) & 1 ? true : false; \ + value = reg[dest].I << value; \ + } #endif #ifndef LSR_RD_RM_I5 - #define LSR_RD_RM_I5 \ - {\ - C_FLAG = (reg[source].I >> (shift - 1)) & 1 ? true : false;\ - value = reg[source].I >> shift;\ - } +#define LSR_RD_RM_I5 \ + { \ + C_FLAG = (reg[source].I >> (shift - 1)) & 1 ? true : false; \ + value = reg[source].I >> shift; \ + } #endif #ifndef LSR_RD_RS - #define LSR_RD_RS \ - {\ - C_FLAG = (reg[dest].I >> (value - 1)) & 1 ? true : false;\ - value = reg[dest].I >> value;\ - } +#define LSR_RD_RS \ + { \ + C_FLAG = (reg[dest].I >> (value - 1)) & 1 ? true : false; \ + value = reg[dest].I >> value; \ + } #endif #ifndef ASR_RD_RM_I5 - #define ASR_RD_RM_I5 \ - {\ - C_FLAG = ((s32)reg[source].I >> (int)(shift - 1)) & 1 ? true : false;\ - value = (s32)reg[source].I >> (int)shift;\ - } +#define ASR_RD_RM_I5 \ + { \ + C_FLAG = ((s32)reg[source].I >> (int)(shift - 1)) & 1 ? true : false; \ + value = (s32)reg[source].I >> (int)shift; \ + } #endif #ifndef ASR_RD_RS - #define ASR_RD_RS \ - {\ - C_FLAG = ((s32)reg[dest].I >> (int)(value - 1)) & 1 ? true : false;\ - value = (s32)reg[dest].I >> (int)value;\ - } +#define ASR_RD_RS \ + { \ + C_FLAG = ((s32)reg[dest].I >> (int)(value - 1)) & 1 ? true : false; \ + value = (s32)reg[dest].I >> (int)value; \ + } #endif #ifndef ROR_RD_RS - #define ROR_RD_RS \ - {\ - C_FLAG = (reg[dest].I >> (value - 1)) & 1 ? true : false;\ - value = ((reg[dest].I << (32 - value)) |\ - (reg[dest].I >> value));\ - } +#define ROR_RD_RS \ + { \ + C_FLAG = (reg[dest].I >> (value - 1)) & 1 ? true : false; \ + value = ((reg[dest].I << (32 - value)) | (reg[dest].I >> value)); \ + } #endif #ifndef NEG_RD_RS - #define NEG_RD_RS \ - {\ - u32 lhs = reg[source].I;\ - u32 rhs = 0;\ - u32 res = rhs - lhs;\ - reg[dest].I = res;\ - Z_FLAG = (res == 0) ? true : false;\ - N_FLAG = NEG(res) ? true : false;\ - SUBCARRY(rhs, lhs, res);\ - SUBOVERFLOW(rhs, lhs, res);\ - } +#define NEG_RD_RS \ + { \ + u32 lhs = reg[source].I; \ + u32 rhs = 0; \ + u32 res = rhs - lhs; \ + reg[dest].I = res; \ + Z_FLAG = (res == 0) ? true : false; \ + N_FLAG = NEG(res) ? true : false; \ + SUBCARRY(rhs, lhs, res); \ + SUBOVERFLOW(rhs, lhs, res); \ + } #endif #ifndef CMP_RD_RS - #define CMP_RD_RS \ - {\ - u32 lhs = reg[dest].I;\ - u32 rhs = value;\ - u32 res = lhs - rhs;\ - Z_FLAG = (res == 0) ? true : false;\ - N_FLAG = NEG(res) ? true : false;\ - SUBCARRY(lhs, rhs, res);\ - SUBOVERFLOW(lhs, rhs, res);\ - } +#define CMP_RD_RS \ + { \ + u32 lhs = reg[dest].I; \ + u32 rhs = value; \ + u32 res = lhs - rhs; \ + Z_FLAG = (res == 0) ? true : false; \ + N_FLAG = NEG(res) ? true : false; \ + SUBCARRY(lhs, rhs, res); \ + SUBOVERFLOW(lhs, rhs, res); \ + } #endif #ifndef IMM5_INSN - #define IMM5_INSN(OP,N) \ - int dest = opcode & 0x07;\ - int source = (opcode >> 3) & 0x07;\ - u32 value;\ - OP(N);\ - reg[dest].I = value;\ - N_FLAG = (value & 0x80000000 ? true : false);\ - Z_FLAG = (value ? false : true); - #define IMM5_INSN_0(OP) \ - int dest = opcode & 0x07;\ - int source = (opcode >> 3) & 0x07;\ - u32 value;\ - OP;\ - reg[dest].I = value;\ - N_FLAG = (value & 0x80000000 ? true : false);\ - Z_FLAG = (value ? false : true); - #define IMM5_LSL(N) \ - int shift = N;\ - LSL_RD_RM_I5; - #define IMM5_LSL_0 \ - value = reg[source].I; - #define IMM5_LSR(N) \ - int shift = N;\ - LSR_RD_RM_I5; - #define IMM5_LSR_0 \ - C_FLAG = reg[source].I & 0x80000000 ? true : false;\ - value = 0; - #define IMM5_ASR(N) \ - int shift = N;\ - ASR_RD_RM_I5; - #define IMM5_ASR_0 \ - if(reg[source].I & 0x80000000) {\ - value = 0xFFFFFFFF;\ - C_FLAG = true;\ - } else {\ - value = 0;\ - C_FLAG = false;\ - } +#define IMM5_INSN(OP, N) \ + int dest = opcode & 0x07; \ + int source = (opcode >> 3) & 0x07; \ + u32 value; \ + OP(N); \ + reg[dest].I = value; \ + N_FLAG = (value & 0x80000000 ? true : false); \ + Z_FLAG = (value ? false : true); +#define IMM5_INSN_0(OP) \ + int dest = opcode & 0x07; \ + int source = (opcode >> 3) & 0x07; \ + u32 value; \ + OP; \ + reg[dest].I = value; \ + N_FLAG = (value & 0x80000000 ? true : false); \ + Z_FLAG = (value ? false : true); +#define IMM5_LSL(N) \ + int shift = N; \ + LSL_RD_RM_I5; +#define IMM5_LSL_0 \ + value = reg[source].I; +#define IMM5_LSR(N) \ + int shift = N; \ + LSR_RD_RM_I5; +#define IMM5_LSR_0 \ + C_FLAG = reg[source].I & 0x80000000 ? true : false; \ + value = 0; +#define IMM5_ASR(N) \ + int shift = N; \ + ASR_RD_RM_I5; +#define IMM5_ASR_0 \ + if (reg[source].I & 0x80000000) { \ + value = 0xFFFFFFFF; \ + C_FLAG = true; \ + } else { \ + value = 0; \ + C_FLAG = false; \ + } #endif #ifndef THREEARG_INSN - #define THREEARG_INSN(OP,N) \ - int dest = opcode & 0x07; \ - int source = (opcode >> 3) & 0x07; \ - OP(N); +#define THREEARG_INSN(OP, N) \ + int dest = opcode & 0x07; \ + int source = (opcode >> 3) & 0x07; \ + OP(N); #endif -// Shift instructions ///////////////////////////////////////////////////// + // Shift instructions ///////////////////////////////////////////////////// -#define DEFINE_IMM5_INSN(OP,BASE) \ - static INSN_REGPARM void thumb##BASE##_00(u32 opcode) { IMM5_INSN_0(OP##_0); } \ - static INSN_REGPARM void thumb##BASE##_01(u32 opcode) { IMM5_INSN(OP, 1); } \ - static INSN_REGPARM void thumb##BASE##_02(u32 opcode) { IMM5_INSN(OP, 2); } \ - static INSN_REGPARM void thumb##BASE##_03(u32 opcode) { IMM5_INSN(OP, 3); } \ - static INSN_REGPARM void thumb##BASE##_04(u32 opcode) { IMM5_INSN(OP, 4); } \ - static INSN_REGPARM void thumb##BASE##_05(u32 opcode) { IMM5_INSN(OP, 5); } \ - static INSN_REGPARM void thumb##BASE##_06(u32 opcode) { IMM5_INSN(OP, 6); } \ - static INSN_REGPARM void thumb##BASE##_07(u32 opcode) { IMM5_INSN(OP, 7); } \ - static INSN_REGPARM void thumb##BASE##_08(u32 opcode) { IMM5_INSN(OP, 8); } \ - static INSN_REGPARM void thumb##BASE##_09(u32 opcode) { IMM5_INSN(OP, 9); } \ - static INSN_REGPARM void thumb##BASE##_0A(u32 opcode) { IMM5_INSN(OP,10); } \ - static INSN_REGPARM void thumb##BASE##_0B(u32 opcode) { IMM5_INSN(OP,11); } \ - static INSN_REGPARM void thumb##BASE##_0C(u32 opcode) { IMM5_INSN(OP,12); } \ - static INSN_REGPARM void thumb##BASE##_0D(u32 opcode) { IMM5_INSN(OP,13); } \ - static INSN_REGPARM void thumb##BASE##_0E(u32 opcode) { IMM5_INSN(OP,14); } \ - static INSN_REGPARM void thumb##BASE##_0F(u32 opcode) { IMM5_INSN(OP,15); } \ - static INSN_REGPARM void thumb##BASE##_10(u32 opcode) { IMM5_INSN(OP,16); } \ - static INSN_REGPARM void thumb##BASE##_11(u32 opcode) { IMM5_INSN(OP,17); } \ - static INSN_REGPARM void thumb##BASE##_12(u32 opcode) { IMM5_INSN(OP,18); } \ - static INSN_REGPARM void thumb##BASE##_13(u32 opcode) { IMM5_INSN(OP,19); } \ - static INSN_REGPARM void thumb##BASE##_14(u32 opcode) { IMM5_INSN(OP,20); } \ - static INSN_REGPARM void thumb##BASE##_15(u32 opcode) { IMM5_INSN(OP,21); } \ - static INSN_REGPARM void thumb##BASE##_16(u32 opcode) { IMM5_INSN(OP,22); } \ - static INSN_REGPARM void thumb##BASE##_17(u32 opcode) { IMM5_INSN(OP,23); } \ - static INSN_REGPARM void thumb##BASE##_18(u32 opcode) { IMM5_INSN(OP,24); } \ - static INSN_REGPARM void thumb##BASE##_19(u32 opcode) { IMM5_INSN(OP,25); } \ - static INSN_REGPARM void thumb##BASE##_1A(u32 opcode) { IMM5_INSN(OP,26); } \ - static INSN_REGPARM void thumb##BASE##_1B(u32 opcode) { IMM5_INSN(OP,27); } \ - static INSN_REGPARM void thumb##BASE##_1C(u32 opcode) { IMM5_INSN(OP,28); } \ - static INSN_REGPARM void thumb##BASE##_1D(u32 opcode) { IMM5_INSN(OP,29); } \ - static INSN_REGPARM void thumb##BASE##_1E(u32 opcode) { IMM5_INSN(OP,30); } \ - static INSN_REGPARM void thumb##BASE##_1F(u32 opcode) { IMM5_INSN(OP,31); } +#define DEFINE_IMM5_INSN(OP, BASE) \ + static INSN_REGPARM void thumb##BASE##_00(u32 opcode) { IMM5_INSN_0(OP##_0); } \ + static INSN_REGPARM void thumb##BASE##_01(u32 opcode) { IMM5_INSN(OP, 1); } \ + static INSN_REGPARM void thumb##BASE##_02(u32 opcode) { IMM5_INSN(OP, 2); } \ + static INSN_REGPARM void thumb##BASE##_03(u32 opcode) { IMM5_INSN(OP, 3); } \ + static INSN_REGPARM void thumb##BASE##_04(u32 opcode) { IMM5_INSN(OP, 4); } \ + static INSN_REGPARM void thumb##BASE##_05(u32 opcode) { IMM5_INSN(OP, 5); } \ + static INSN_REGPARM void thumb##BASE##_06(u32 opcode) { IMM5_INSN(OP, 6); } \ + static INSN_REGPARM void thumb##BASE##_07(u32 opcode) { IMM5_INSN(OP, 7); } \ + static INSN_REGPARM void thumb##BASE##_08(u32 opcode) { IMM5_INSN(OP, 8); } \ + static INSN_REGPARM void thumb##BASE##_09(u32 opcode) { IMM5_INSN(OP, 9); } \ + static INSN_REGPARM void thumb##BASE##_0A(u32 opcode) { IMM5_INSN(OP, 10); } \ + static INSN_REGPARM void thumb##BASE##_0B(u32 opcode) { IMM5_INSN(OP, 11); } \ + static INSN_REGPARM void thumb##BASE##_0C(u32 opcode) { IMM5_INSN(OP, 12); } \ + static INSN_REGPARM void thumb##BASE##_0D(u32 opcode) { IMM5_INSN(OP, 13); } \ + static INSN_REGPARM void thumb##BASE##_0E(u32 opcode) { IMM5_INSN(OP, 14); } \ + static INSN_REGPARM void thumb##BASE##_0F(u32 opcode) { IMM5_INSN(OP, 15); } \ + static INSN_REGPARM void thumb##BASE##_10(u32 opcode) { IMM5_INSN(OP, 16); } \ + static INSN_REGPARM void thumb##BASE##_11(u32 opcode) { IMM5_INSN(OP, 17); } \ + static INSN_REGPARM void thumb##BASE##_12(u32 opcode) { IMM5_INSN(OP, 18); } \ + static INSN_REGPARM void thumb##BASE##_13(u32 opcode) { IMM5_INSN(OP, 19); } \ + static INSN_REGPARM void thumb##BASE##_14(u32 opcode) { IMM5_INSN(OP, 20); } \ + static INSN_REGPARM void thumb##BASE##_15(u32 opcode) { IMM5_INSN(OP, 21); } \ + static INSN_REGPARM void thumb##BASE##_16(u32 opcode) { IMM5_INSN(OP, 22); } \ + static INSN_REGPARM void thumb##BASE##_17(u32 opcode) { IMM5_INSN(OP, 23); } \ + static INSN_REGPARM void thumb##BASE##_18(u32 opcode) { IMM5_INSN(OP, 24); } \ + static INSN_REGPARM void thumb##BASE##_19(u32 opcode) { IMM5_INSN(OP, 25); } \ + static INSN_REGPARM void thumb##BASE##_1A(u32 opcode) { IMM5_INSN(OP, 26); } \ + static INSN_REGPARM void thumb##BASE##_1B(u32 opcode) { IMM5_INSN(OP, 27); } \ + static INSN_REGPARM void thumb##BASE##_1C(u32 opcode) { IMM5_INSN(OP, 28); } \ + static INSN_REGPARM void thumb##BASE##_1D(u32 opcode) { IMM5_INSN(OP, 29); } \ + static INSN_REGPARM void thumb##BASE##_1E(u32 opcode) { IMM5_INSN(OP, 30); } \ + static INSN_REGPARM void thumb##BASE##_1F(u32 opcode) { IMM5_INSN(OP, 31); } -// LSL Rd, Rm, #Imm 5 -DEFINE_IMM5_INSN(IMM5_LSL,00) -// LSR Rd, Rm, #Imm 5 -DEFINE_IMM5_INSN(IMM5_LSR,08) -// ASR Rd, Rm, #Imm 5 -DEFINE_IMM5_INSN(IMM5_ASR,10) + // LSL Rd, Rm, #Imm 5 + DEFINE_IMM5_INSN(IMM5_LSL, 00) + // LSR Rd, Rm, #Imm 5 + DEFINE_IMM5_INSN(IMM5_LSR, 08) + // ASR Rd, Rm, #Imm 5 + DEFINE_IMM5_INSN(IMM5_ASR, 10) -// 3-argument ADD/SUB ///////////////////////////////////////////////////// + // 3-argument ADD/SUB ///////////////////////////////////////////////////// -#define DEFINE_REG3_INSN(OP,BASE) \ - static INSN_REGPARM void thumb##BASE##_0(u32 opcode) { THREEARG_INSN(OP,0); } \ - static INSN_REGPARM void thumb##BASE##_1(u32 opcode) { THREEARG_INSN(OP,1); } \ - static INSN_REGPARM void thumb##BASE##_2(u32 opcode) { THREEARG_INSN(OP,2); } \ - static INSN_REGPARM void thumb##BASE##_3(u32 opcode) { THREEARG_INSN(OP,3); } \ - static INSN_REGPARM void thumb##BASE##_4(u32 opcode) { THREEARG_INSN(OP,4); } \ - static INSN_REGPARM void thumb##BASE##_5(u32 opcode) { THREEARG_INSN(OP,5); } \ - static INSN_REGPARM void thumb##BASE##_6(u32 opcode) { THREEARG_INSN(OP,6); } \ - static INSN_REGPARM void thumb##BASE##_7(u32 opcode) { THREEARG_INSN(OP,7); } +#define DEFINE_REG3_INSN(OP, BASE) \ + static INSN_REGPARM void thumb##BASE##_0(u32 opcode) { THREEARG_INSN(OP, 0); } \ + static INSN_REGPARM void thumb##BASE##_1(u32 opcode) { THREEARG_INSN(OP, 1); } \ + static INSN_REGPARM void thumb##BASE##_2(u32 opcode) { THREEARG_INSN(OP, 2); } \ + static INSN_REGPARM void thumb##BASE##_3(u32 opcode) { THREEARG_INSN(OP, 3); } \ + static INSN_REGPARM void thumb##BASE##_4(u32 opcode) { THREEARG_INSN(OP, 4); } \ + static INSN_REGPARM void thumb##BASE##_5(u32 opcode) { THREEARG_INSN(OP, 5); } \ + static INSN_REGPARM void thumb##BASE##_6(u32 opcode) { THREEARG_INSN(OP, 6); } \ + static INSN_REGPARM void thumb##BASE##_7(u32 opcode) { THREEARG_INSN(OP, 7); } -#define DEFINE_IMM3_INSN(OP,BASE) \ - static INSN_REGPARM void thumb##BASE##_0(u32 opcode) { THREEARG_INSN(OP##_0,0); } \ - static INSN_REGPARM void thumb##BASE##_1(u32 opcode) { THREEARG_INSN(OP,1); } \ - static INSN_REGPARM void thumb##BASE##_2(u32 opcode) { THREEARG_INSN(OP,2); } \ - static INSN_REGPARM void thumb##BASE##_3(u32 opcode) { THREEARG_INSN(OP,3); } \ - static INSN_REGPARM void thumb##BASE##_4(u32 opcode) { THREEARG_INSN(OP,4); } \ - static INSN_REGPARM void thumb##BASE##_5(u32 opcode) { THREEARG_INSN(OP,5); } \ - static INSN_REGPARM void thumb##BASE##_6(u32 opcode) { THREEARG_INSN(OP,6); } \ - static INSN_REGPARM void thumb##BASE##_7(u32 opcode) { THREEARG_INSN(OP,7); } +#define DEFINE_IMM3_INSN(OP, BASE) \ + static INSN_REGPARM void thumb##BASE##_0(u32 opcode) { THREEARG_INSN(OP##_0, 0); } \ + static INSN_REGPARM void thumb##BASE##_1(u32 opcode) { THREEARG_INSN(OP, 1); } \ + static INSN_REGPARM void thumb##BASE##_2(u32 opcode) { THREEARG_INSN(OP, 2); } \ + static INSN_REGPARM void thumb##BASE##_3(u32 opcode) { THREEARG_INSN(OP, 3); } \ + static INSN_REGPARM void thumb##BASE##_4(u32 opcode) { THREEARG_INSN(OP, 4); } \ + static INSN_REGPARM void thumb##BASE##_5(u32 opcode) { THREEARG_INSN(OP, 5); } \ + static INSN_REGPARM void thumb##BASE##_6(u32 opcode) { THREEARG_INSN(OP, 6); } \ + static INSN_REGPARM void thumb##BASE##_7(u32 opcode) { THREEARG_INSN(OP, 7); } -// ADD Rd, Rs, Rn -DEFINE_REG3_INSN(ADD_RD_RS_RN,18) -// SUB Rd, Rs, Rn -DEFINE_REG3_INSN(SUB_RD_RS_RN,1A) -// ADD Rd, Rs, #Offset3 -DEFINE_IMM3_INSN(ADD_RD_RS_O3,1C) -// SUB Rd, Rs, #Offset3 -DEFINE_IMM3_INSN(SUB_RD_RS_O3,1E) + // ADD Rd, Rs, Rn + DEFINE_REG3_INSN(ADD_RD_RS_RN, 18) + // SUB Rd, Rs, Rn + DEFINE_REG3_INSN(SUB_RD_RS_RN, 1A) + // ADD Rd, Rs, #Offset3 + DEFINE_IMM3_INSN(ADD_RD_RS_O3, 1C) + // SUB Rd, Rs, #Offset3 + DEFINE_IMM3_INSN(SUB_RD_RS_O3, 1E) -// MOV/CMP/ADD/SUB immediate ////////////////////////////////////////////// + // MOV/CMP/ADD/SUB immediate ////////////////////////////////////////////// -// MOV R0, #Offset8 -static INSN_REGPARM void thumb20(u32 opcode) { MOV_RN_O8(0); } -// MOV R1, #Offset8 -static INSN_REGPARM void thumb21(u32 opcode) { MOV_RN_O8(1); } -// MOV R2, #Offset8 -static INSN_REGPARM void thumb22(u32 opcode) { MOV_RN_O8(2); } -// MOV R3, #Offset8 -static INSN_REGPARM void thumb23(u32 opcode) { MOV_RN_O8(3); } -// MOV R4, #Offset8 -static INSN_REGPARM void thumb24(u32 opcode) { MOV_RN_O8(4); } -// MOV R5, #Offset8 -static INSN_REGPARM void thumb25(u32 opcode) { MOV_RN_O8(5); } -// MOV R6, #Offset8 -static INSN_REGPARM void thumb26(u32 opcode) { MOV_RN_O8(6); } -// MOV R7, #Offset8 -static INSN_REGPARM void thumb27(u32 opcode) { MOV_RN_O8(7); } + // MOV R0, #Offset8 + static INSN_REGPARM void thumb20(u32 opcode) { MOV_RN_O8(0); } + // MOV R1, #Offset8 + static INSN_REGPARM void thumb21(u32 opcode) { MOV_RN_O8(1); } + // MOV R2, #Offset8 + static INSN_REGPARM void thumb22(u32 opcode) { MOV_RN_O8(2); } + // MOV R3, #Offset8 + static INSN_REGPARM void thumb23(u32 opcode) { MOV_RN_O8(3); } + // MOV R4, #Offset8 + static INSN_REGPARM void thumb24(u32 opcode) { MOV_RN_O8(4); } + // MOV R5, #Offset8 + static INSN_REGPARM void thumb25(u32 opcode) { MOV_RN_O8(5); } + // MOV R6, #Offset8 + static INSN_REGPARM void thumb26(u32 opcode) { MOV_RN_O8(6); } + // MOV R7, #Offset8 + static INSN_REGPARM void thumb27(u32 opcode) { MOV_RN_O8(7); } -// CMP R0, #Offset8 -static INSN_REGPARM void thumb28(u32 opcode) { CMP_RN_O8(0); } -// CMP R1, #Offset8 -static INSN_REGPARM void thumb29(u32 opcode) { CMP_RN_O8(1); } -// CMP R2, #Offset8 -static INSN_REGPARM void thumb2A(u32 opcode) { CMP_RN_O8(2); } -// CMP R3, #Offset8 -static INSN_REGPARM void thumb2B(u32 opcode) { CMP_RN_O8(3); } -// CMP R4, #Offset8 -static INSN_REGPARM void thumb2C(u32 opcode) { CMP_RN_O8(4); } -// CMP R5, #Offset8 -static INSN_REGPARM void thumb2D(u32 opcode) { CMP_RN_O8(5); } -// CMP R6, #Offset8 -static INSN_REGPARM void thumb2E(u32 opcode) { CMP_RN_O8(6); } -// CMP R7, #Offset8 -static INSN_REGPARM void thumb2F(u32 opcode) { CMP_RN_O8(7); } + // CMP R0, #Offset8 + static INSN_REGPARM void thumb28(u32 opcode) { CMP_RN_O8(0); } + // CMP R1, #Offset8 + static INSN_REGPARM void thumb29(u32 opcode) { CMP_RN_O8(1); } + // CMP R2, #Offset8 + static INSN_REGPARM void thumb2A(u32 opcode) { CMP_RN_O8(2); } + // CMP R3, #Offset8 + static INSN_REGPARM void thumb2B(u32 opcode) { CMP_RN_O8(3); } + // CMP R4, #Offset8 + static INSN_REGPARM void thumb2C(u32 opcode) { CMP_RN_O8(4); } + // CMP R5, #Offset8 + static INSN_REGPARM void thumb2D(u32 opcode) { CMP_RN_O8(5); } + // CMP R6, #Offset8 + static INSN_REGPARM void thumb2E(u32 opcode) { CMP_RN_O8(6); } + // CMP R7, #Offset8 + static INSN_REGPARM void thumb2F(u32 opcode) { CMP_RN_O8(7); } -// ADD R0,#Offset8 -static INSN_REGPARM void thumb30(u32 opcode) { ADD_RN_O8(0); } -// ADD R1,#Offset8 -static INSN_REGPARM void thumb31(u32 opcode) { ADD_RN_O8(1); } -// ADD R2,#Offset8 -static INSN_REGPARM void thumb32(u32 opcode) { ADD_RN_O8(2); } -// ADD R3,#Offset8 -static INSN_REGPARM void thumb33(u32 opcode) { ADD_RN_O8(3); } -// ADD R4,#Offset8 -static INSN_REGPARM void thumb34(u32 opcode) { ADD_RN_O8(4); } -// ADD R5,#Offset8 -static INSN_REGPARM void thumb35(u32 opcode) { ADD_RN_O8(5); } -// ADD R6,#Offset8 -static INSN_REGPARM void thumb36(u32 opcode) { ADD_RN_O8(6); } -// ADD R7,#Offset8 -static INSN_REGPARM void thumb37(u32 opcode) { ADD_RN_O8(7); } + // ADD R0,#Offset8 + static INSN_REGPARM void thumb30(u32 opcode) { ADD_RN_O8(0); } + // ADD R1,#Offset8 + static INSN_REGPARM void thumb31(u32 opcode) { ADD_RN_O8(1); } + // ADD R2,#Offset8 + static INSN_REGPARM void thumb32(u32 opcode) { ADD_RN_O8(2); } + // ADD R3,#Offset8 + static INSN_REGPARM void thumb33(u32 opcode) { ADD_RN_O8(3); } + // ADD R4,#Offset8 + static INSN_REGPARM void thumb34(u32 opcode) { ADD_RN_O8(4); } + // ADD R5,#Offset8 + static INSN_REGPARM void thumb35(u32 opcode) { ADD_RN_O8(5); } + // ADD R6,#Offset8 + static INSN_REGPARM void thumb36(u32 opcode) { ADD_RN_O8(6); } + // ADD R7,#Offset8 + static INSN_REGPARM void thumb37(u32 opcode) { ADD_RN_O8(7); } -// SUB R0,#Offset8 -static INSN_REGPARM void thumb38(u32 opcode) { SUB_RN_O8(0); } -// SUB R1,#Offset8 -static INSN_REGPARM void thumb39(u32 opcode) { SUB_RN_O8(1); } -// SUB R2,#Offset8 -static INSN_REGPARM void thumb3A(u32 opcode) { SUB_RN_O8(2); } -// SUB R3,#Offset8 -static INSN_REGPARM void thumb3B(u32 opcode) { SUB_RN_O8(3); } -// SUB R4,#Offset8 -static INSN_REGPARM void thumb3C(u32 opcode) { SUB_RN_O8(4); } -// SUB R5,#Offset8 -static INSN_REGPARM void thumb3D(u32 opcode) { SUB_RN_O8(5); } -// SUB R6,#Offset8 -static INSN_REGPARM void thumb3E(u32 opcode) { SUB_RN_O8(6); } -// SUB R7,#Offset8 -static INSN_REGPARM void thumb3F(u32 opcode) { SUB_RN_O8(7); } + // SUB R0,#Offset8 + static INSN_REGPARM void thumb38(u32 opcode) { SUB_RN_O8(0); } + // SUB R1,#Offset8 + static INSN_REGPARM void thumb39(u32 opcode) { SUB_RN_O8(1); } + // SUB R2,#Offset8 + static INSN_REGPARM void thumb3A(u32 opcode) { SUB_RN_O8(2); } + // SUB R3,#Offset8 + static INSN_REGPARM void thumb3B(u32 opcode) { SUB_RN_O8(3); } + // SUB R4,#Offset8 + static INSN_REGPARM void thumb3C(u32 opcode) { SUB_RN_O8(4); } + // SUB R5,#Offset8 + static INSN_REGPARM void thumb3D(u32 opcode) { SUB_RN_O8(5); } + // SUB R6,#Offset8 + static INSN_REGPARM void thumb3E(u32 opcode) { SUB_RN_O8(6); } + // SUB R7,#Offset8 + static INSN_REGPARM void thumb3F(u32 opcode) { SUB_RN_O8(7); } -// ALU operations ///////////////////////////////////////////////////////// + // ALU operations ///////////////////////////////////////////////////////// -// AND Rd, Rs -static INSN_REGPARM void thumb40_0(u32 opcode) -{ - int dest = opcode & 7; - reg[dest].I &= reg[(opcode >> 3)&7].I; - N_FLAG = reg[dest].I & 0x80000000 ? true : false; - Z_FLAG = reg[dest].I ? false : true; - THUMB_CONSOLE_OUTPUT(NULL, reg[2].I); -} + // AND Rd, Rs + static INSN_REGPARM void thumb40_0(u32 opcode) + { + int dest = opcode & 7; + reg[dest].I &= reg[(opcode >> 3) & 7].I; + N_FLAG = reg[dest].I & 0x80000000 ? true : false; + Z_FLAG = reg[dest].I ? false : true; + THUMB_CONSOLE_OUTPUT(NULL, reg[2].I); + } -// EOR Rd, Rs -static INSN_REGPARM void thumb40_1(u32 opcode) -{ - int dest = opcode & 7; - reg[dest].I ^= reg[(opcode >> 3)&7].I; - N_FLAG = reg[dest].I & 0x80000000 ? true : false; - Z_FLAG = reg[dest].I ? false : true; -} + // EOR Rd, Rs + static INSN_REGPARM void thumb40_1(u32 opcode) + { + int dest = opcode & 7; + reg[dest].I ^= reg[(opcode >> 3) & 7].I; + N_FLAG = reg[dest].I & 0x80000000 ? true : false; + Z_FLAG = reg[dest].I ? false : true; + } -// LSL Rd, Rs -static INSN_REGPARM void thumb40_2(u32 opcode) -{ - int dest = opcode & 7; - u32 value = reg[(opcode >> 3)&7].B.B0; - if(value) { - if(value == 32) { - value = 0; - C_FLAG = (reg[dest].I & 1 ? true : false); - } else if(value < 32) { - LSL_RD_RS; - } else { - value = 0; - C_FLAG = false; + // LSL Rd, Rs + static INSN_REGPARM void thumb40_2(u32 opcode) + { + int dest = opcode & 7; + u32 value = reg[(opcode >> 3) & 7].B.B0; + if (value) { + if (value == 32) { + value = 0; + C_FLAG = (reg[dest].I & 1 ? true : false); + } else if (value < 32) { + LSL_RD_RS; + } else { + value = 0; + C_FLAG = false; + } + reg[dest].I = value; + } + N_FLAG = reg[dest].I & 0x80000000 ? true : false; + Z_FLAG = reg[dest].I ? false : true; + clockTicks = codeTicksAccess16(armNextPC) + 2; + } + + // LSR Rd, Rs + static INSN_REGPARM void thumb40_3(u32 opcode) + { + int dest = opcode & 7; + u32 value = reg[(opcode >> 3) & 7].B.B0; + if (value) { + if (value == 32) { + value = 0; + C_FLAG = (reg[dest].I & 0x80000000 ? true : false); + } else if (value < 32) { + LSR_RD_RS; + } else { + value = 0; + C_FLAG = false; + } + reg[dest].I = value; + } + N_FLAG = reg[dest].I & 0x80000000 ? true : false; + Z_FLAG = reg[dest].I ? false : true; + clockTicks = codeTicksAccess16(armNextPC) + 2; + } + + // ASR Rd, Rs + static INSN_REGPARM void thumb41_0(u32 opcode) + { + int dest = opcode & 7; + u32 value = reg[(opcode >> 3) & 7].B.B0; + if (value) { + if (value < 32) { + ASR_RD_RS; + reg[dest].I = value; + } else { + if (reg[dest].I & 0x80000000) { + reg[dest].I = 0xFFFFFFFF; + C_FLAG = true; + } else { + reg[dest].I = 0x00000000; + C_FLAG = false; + } + } + } + N_FLAG = reg[dest].I & 0x80000000 ? true : false; + Z_FLAG = reg[dest].I ? false : true; + clockTicks = codeTicksAccess16(armNextPC) + 2; + } + + // ADC Rd, Rs + static INSN_REGPARM void thumb41_1(u32 opcode) + { + int dest = opcode & 0x07; + u32 value = reg[(opcode >> 3) & 7].I; + ADC_RD_RS; + } + + // SBC Rd, Rs + static INSN_REGPARM void thumb41_2(u32 opcode) + { + int dest = opcode & 0x07; + u32 value = reg[(opcode >> 3) & 7].I; + SBC_RD_RS; + } + + // ROR Rd, Rs + static INSN_REGPARM void thumb41_3(u32 opcode) + { + int dest = opcode & 7; + u32 value = reg[(opcode >> 3) & 7].B.B0; + + if (value) { + value = value & 0x1f; + if (value == 0) { + C_FLAG = (reg[dest].I & 0x80000000 ? true : false); + } else { + ROR_RD_RS; + reg[dest].I = value; + } + } + clockTicks = codeTicksAccess16(armNextPC) + 2; + N_FLAG = reg[dest].I & 0x80000000 ? true : false; + Z_FLAG = reg[dest].I ? false : true; + } + + // TST Rd, Rs + static INSN_REGPARM void thumb42_0(u32 opcode) + { + u32 value = reg[opcode & 7].I & reg[(opcode >> 3) & 7].I; + N_FLAG = value & 0x80000000 ? true : false; + Z_FLAG = value ? false : true; + } + + // NEG Rd, Rs + static INSN_REGPARM void thumb42_1(u32 opcode) + { + int dest = opcode & 7; + int source = (opcode >> 3) & 7; + NEG_RD_RS; + } + + // CMP Rd, Rs + static INSN_REGPARM void thumb42_2(u32 opcode) + { + int dest = opcode & 7; + u32 value = reg[(opcode >> 3) & 7].I; + CMP_RD_RS; + } + + // CMN Rd, Rs + static INSN_REGPARM void thumb42_3(u32 opcode) + { + int dest = opcode & 7; + u32 value = reg[(opcode >> 3) & 7].I; + CMN_RD_RS; + } + + // ORR Rd, Rs + static INSN_REGPARM void thumb43_0(u32 opcode) + { + int dest = opcode & 7; + reg[dest].I |= reg[(opcode >> 3) & 7].I; + Z_FLAG = reg[dest].I ? false : true; + N_FLAG = reg[dest].I & 0x80000000 ? true : false; + } + + // MUL Rd, Rs + static INSN_REGPARM void thumb43_1(u32 opcode) + { + clockTicks = 1; + int dest = opcode & 7; + u32 rm = reg[dest].I; + reg[dest].I = reg[(opcode >> 3) & 7].I * rm; + if (((s32)rm) < 0) + rm = ~rm; + if ((rm & 0xFFFFFF00) == 0) + clockTicks += 0; + else if ((rm & 0xFFFF0000) == 0) + clockTicks += 1; + else if ((rm & 0xFF000000) == 0) + clockTicks += 2; + else + clockTicks += 3; + busPrefetchCount = (busPrefetchCount << clockTicks) | (0xFF >> (8 - clockTicks)); + clockTicks += codeTicksAccess16(armNextPC) + 1; + Z_FLAG = reg[dest].I ? false : true; + N_FLAG = reg[dest].I & 0x80000000 ? true : false; + } + + // BIC Rd, Rs + static INSN_REGPARM void thumb43_2(u32 opcode) + { + int dest = opcode & 7; + reg[dest].I &= (~reg[(opcode >> 3) & 7].I); + Z_FLAG = reg[dest].I ? false : true; + N_FLAG = reg[dest].I & 0x80000000 ? true : false; + } + + // MVN Rd, Rs + static INSN_REGPARM void thumb43_3(u32 opcode) + { + int dest = opcode & 7; + reg[dest].I = ~reg[(opcode >> 3) & 7].I; + Z_FLAG = reg[dest].I ? false : true; + N_FLAG = reg[dest].I & 0x80000000 ? true : false; + } + + // High-register instructions and BX ////////////////////////////////////// + + // ADD Rd, Hs + static INSN_REGPARM void thumb44_1(u32 opcode) + { + reg[opcode & 7].I += reg[((opcode >> 3) & 7) + 8].I; + } + + // ADD Hd, Rs + static INSN_REGPARM void thumb44_2(u32 opcode) + { + reg[(opcode & 7) + 8].I += reg[(opcode >> 3) & 7].I; + if ((opcode & 7) == 7) { + reg[15].I &= 0xFFFFFFFE; + armNextPC = reg[15].I; + reg[15].I += 2; + THUMB_PREFETCH; + clockTicks = codeTicksAccessSeq16(armNextPC) * 2 + + codeTicksAccess16(armNextPC) + 3; + } + } + + // ADD Hd, Hs + static INSN_REGPARM void thumb44_3(u32 opcode) + { + reg[(opcode & 7) + 8].I += reg[((opcode >> 3) & 7) + 8].I; + if ((opcode & 7) == 7) { + reg[15].I &= 0xFFFFFFFE; + armNextPC = reg[15].I; + reg[15].I += 2; + THUMB_PREFETCH; + clockTicks = codeTicksAccessSeq16(armNextPC) * 2 + + codeTicksAccess16(armNextPC) + 3; + } + } + + // CMP Rd, Hs + static INSN_REGPARM void thumb45_1(u32 opcode) + { + int dest = opcode & 7; + u32 value = reg[((opcode >> 3) & 7) + 8].I; + CMP_RD_RS; + } + + // CMP Hd, Rs + static INSN_REGPARM void thumb45_2(u32 opcode) + { + int dest = (opcode & 7) + 8; + u32 value = reg[(opcode >> 3) & 7].I; + CMP_RD_RS; + } + + // CMP Hd, Hs + static INSN_REGPARM void thumb45_3(u32 opcode) + { + int dest = (opcode & 7) + 8; + u32 value = reg[((opcode >> 3) & 7) + 8].I; + CMP_RD_RS; + } + + // MOV Rd, Rs + static INSN_REGPARM void thumb46_0(u32 opcode) + { + reg[opcode & 7].I = reg[((opcode >> 3) & 7)].I; + clockTicks = codeTicksAccessSeq16(armNextPC) + 1; + } + + // MOV Rd, Hs + static INSN_REGPARM void thumb46_1(u32 opcode) + { + reg[opcode & 7].I = reg[((opcode >> 3) & 7) + 8].I; + clockTicks = codeTicksAccessSeq16(armNextPC) + 1; + } + + // MOV Hd, Rs + static INSN_REGPARM void thumb46_2(u32 opcode) + { + reg[(opcode & 7) + 8].I = reg[(opcode >> 3) & 7].I; + if ((opcode & 7) == 7) { + UPDATE_OLDREG; + reg[15].I &= 0xFFFFFFFE; + armNextPC = reg[15].I; + reg[15].I += 2; + THUMB_PREFETCH; + clockTicks = codeTicksAccessSeq16(armNextPC) * 2 + + codeTicksAccess16(armNextPC) + 3; + } + } + + // MOV Hd, Hs + static INSN_REGPARM void thumb46_3(u32 opcode) + { + reg[(opcode & 7) + 8].I = reg[((opcode >> 3) & 7) + 8].I; + if ((opcode & 7) == 7) { + UPDATE_OLDREG; + reg[15].I &= 0xFFFFFFFE; + armNextPC = reg[15].I; + reg[15].I += 2; + THUMB_PREFETCH; + clockTicks = codeTicksAccessSeq16(armNextPC) * 2 + + codeTicksAccess16(armNextPC) + 3; + } + } + + // BX Rs + static INSN_REGPARM void thumb47(u32 opcode) + { + int base = (opcode >> 3) & 15; + busPrefetchCount = 0; + UPDATE_OLDREG; + reg[15].I = reg[base].I; + if (reg[base].I & 1) { + armState = false; + reg[15].I &= 0xFFFFFFFE; + armNextPC = reg[15].I; + reg[15].I += 2; + THUMB_PREFETCH; + clockTicks = codeTicksAccessSeq16(armNextPC) * 2 + codeTicksAccess16(armNextPC) + 3; + } else { + armState = true; + reg[15].I &= 0xFFFFFFFC; + armNextPC = reg[15].I; + reg[15].I += 4; + ARM_PREFETCH; + clockTicks = codeTicksAccessSeq32(armNextPC) * 2 + codeTicksAccess32(armNextPC) + 3; + } + } + + // Load/store instructions //////////////////////////////////////////////// + + // LDR R0~R7,[PC, #Imm] + static INSN_REGPARM void thumb48(u32 opcode) + { + u8 regist = (opcode >> 8) & 7; + if (busPrefetchCount == 0) + busPrefetch = busPrefetchEnable; + u32 address = (reg[15].I & 0xFFFFFFFC) + ((opcode & 0xFF) << 2); + reg[regist].I = CPUReadMemoryQuick(address); + busPrefetchCount = 0; + clockTicks = 3 + dataTicksAccess32(address) + codeTicksAccess16(armNextPC); + } + + // STR Rd, [Rs, Rn] + static INSN_REGPARM void thumb50(u32 opcode) + { + if (busPrefetchCount == 0) + busPrefetch = busPrefetchEnable; + u32 address = reg[(opcode >> 3) & 7].I + reg[(opcode >> 6) & 7].I; + CPUWriteMemory(address, reg[opcode & 7].I); + clockTicks = dataTicksAccess32(address) + codeTicksAccess16(armNextPC) + 2; + } + + // STRH Rd, [Rs, Rn] + static INSN_REGPARM void thumb52(u32 opcode) + { + if (busPrefetchCount == 0) + busPrefetch = busPrefetchEnable; + u32 address = reg[(opcode >> 3) & 7].I + reg[(opcode >> 6) & 7].I; + CPUWriteHalfWord(address, reg[opcode & 7].W.W0); + clockTicks = dataTicksAccess16(address) + codeTicksAccess16(armNextPC) + 2; + } + + // STRB Rd, [Rs, Rn] + static INSN_REGPARM void thumb54(u32 opcode) + { + if (busPrefetchCount == 0) + busPrefetch = busPrefetchEnable; + u32 address = reg[(opcode >> 3) & 7].I + reg[(opcode >> 6) & 7].I; + CPUWriteByte(address, reg[opcode & 7].B.B0); + clockTicks = dataTicksAccess16(address) + codeTicksAccess16(armNextPC) + 2; + } + + // LDSB Rd, [Rs, Rn] + static INSN_REGPARM void thumb56(u32 opcode) + { + if (busPrefetchCount == 0) + busPrefetch = busPrefetchEnable; + u32 address = reg[(opcode >> 3) & 7].I + reg[(opcode >> 6) & 7].I; + reg[opcode & 7].I = (s8)CPUReadByte(address); + clockTicks = 3 + dataTicksAccess16(address) + codeTicksAccess16(armNextPC); + } + + // LDR Rd, [Rs, Rn] + static INSN_REGPARM void thumb58(u32 opcode) + { + if (busPrefetchCount == 0) + busPrefetch = busPrefetchEnable; + u32 address = reg[(opcode >> 3) & 7].I + reg[(opcode >> 6) & 7].I; + reg[opcode & 7].I = CPUReadMemory(address); + clockTicks = 3 + dataTicksAccess32(address) + codeTicksAccess16(armNextPC); + } + + // LDRH Rd, [Rs, Rn] + static INSN_REGPARM void thumb5A(u32 opcode) + { + if (busPrefetchCount == 0) + busPrefetch = busPrefetchEnable; + u32 address = reg[(opcode >> 3) & 7].I + reg[(opcode >> 6) & 7].I; + reg[opcode & 7].I = CPUReadHalfWord(address); + clockTicks = 3 + dataTicksAccess32(address) + codeTicksAccess16(armNextPC); + } + + // LDRB Rd, [Rs, Rn] + static INSN_REGPARM void thumb5C(u32 opcode) + { + if (busPrefetchCount == 0) + busPrefetch = busPrefetchEnable; + u32 address = reg[(opcode >> 3) & 7].I + reg[(opcode >> 6) & 7].I; + reg[opcode & 7].I = CPUReadByte(address); + clockTicks = 3 + dataTicksAccess16(address) + codeTicksAccess16(armNextPC); + } + + // LDSH Rd, [Rs, Rn] + static INSN_REGPARM void thumb5E(u32 opcode) + { + if (busPrefetchCount == 0) + busPrefetch = busPrefetchEnable; + u32 address = reg[(opcode >> 3) & 7].I + reg[(opcode >> 6) & 7].I; + reg[opcode & 7].I = (u32)CPUReadHalfWordSigned(address); + clockTicks = 3 + dataTicksAccess16(address) + codeTicksAccess16(armNextPC); + } + + // STR Rd, [Rs, #Imm] + static INSN_REGPARM void thumb60(u32 opcode) + { + if (busPrefetchCount == 0) + busPrefetch = busPrefetchEnable; + u32 address = reg[(opcode >> 3) & 7].I + (((opcode >> 6) & 31) << 2); + CPUWriteMemory(address, reg[opcode & 7].I); + clockTicks = dataTicksAccess32(address) + codeTicksAccess16(armNextPC) + 2; + } + + // LDR Rd, [Rs, #Imm] + static INSN_REGPARM void thumb68(u32 opcode) + { + if (busPrefetchCount == 0) + busPrefetch = busPrefetchEnable; + u32 address = reg[(opcode >> 3) & 7].I + (((opcode >> 6) & 31) << 2); + reg[opcode & 7].I = CPUReadMemory(address); + clockTicks = 3 + dataTicksAccess32(address) + codeTicksAccess16(armNextPC); + } + + // STRB Rd, [Rs, #Imm] + static INSN_REGPARM void thumb70(u32 opcode) + { + if (busPrefetchCount == 0) + busPrefetch = busPrefetchEnable; + u32 address = reg[(opcode >> 3) & 7].I + (((opcode >> 6) & 31)); + CPUWriteByte(address, reg[opcode & 7].B.B0); + clockTicks = dataTicksAccess16(address) + codeTicksAccess16(armNextPC) + 2; + } + + // LDRB Rd, [Rs, #Imm] + static INSN_REGPARM void thumb78(u32 opcode) + { + if (busPrefetchCount == 0) + busPrefetch = busPrefetchEnable; + u32 address = reg[(opcode >> 3) & 7].I + (((opcode >> 6) & 31)); + reg[opcode & 7].I = CPUReadByte(address); + clockTicks = 3 + dataTicksAccess16(address) + codeTicksAccess16(armNextPC); + } + + // STRH Rd, [Rs, #Imm] + static INSN_REGPARM void thumb80(u32 opcode) + { + if (busPrefetchCount == 0) + busPrefetch = busPrefetchEnable; + u32 address = reg[(opcode >> 3) & 7].I + (((opcode >> 6) & 31) << 1); + CPUWriteHalfWord(address, reg[opcode & 7].W.W0); + clockTicks = dataTicksAccess16(address) + codeTicksAccess16(armNextPC) + 2; + } + + // LDRH Rd, [Rs, #Imm] + static INSN_REGPARM void thumb88(u32 opcode) + { + if (busPrefetchCount == 0) + busPrefetch = busPrefetchEnable; + u32 address = reg[(opcode >> 3) & 7].I + (((opcode >> 6) & 31) << 1); + reg[opcode & 7].I = CPUReadHalfWord(address); + clockTicks = 3 + dataTicksAccess16(address) + codeTicksAccess16(armNextPC); + } + + // STR R0~R7, [SP, #Imm] + static INSN_REGPARM void thumb90(u32 opcode) + { + u8 regist = (opcode >> 8) & 7; + if (busPrefetchCount == 0) + busPrefetch = busPrefetchEnable; + u32 address = reg[13].I + ((opcode & 255) << 2); + CPUWriteMemory(address, reg[regist].I); + clockTicks = dataTicksAccess32(address) + codeTicksAccess16(armNextPC) + 2; + } + + // LDR R0~R7, [SP, #Imm] + static INSN_REGPARM void thumb98(u32 opcode) + { + u8 regist = (opcode >> 8) & 7; + if (busPrefetchCount == 0) + busPrefetch = busPrefetchEnable; + u32 address = reg[13].I + ((opcode & 255) << 2); + reg[regist].I = CPUReadMemoryQuick(address); + clockTicks = 3 + dataTicksAccess32(address) + codeTicksAccess16(armNextPC); + } + + // PC/stack-related /////////////////////////////////////////////////////// + + // ADD R0~R7, PC, Imm + static INSN_REGPARM void thumbA0(u32 opcode) + { + u8 regist = (opcode >> 8) & 7; + reg[regist].I = (reg[15].I & 0xFFFFFFFC) + ((opcode & 255) << 2); + clockTicks = 1 + codeTicksAccess16(armNextPC); + } + + // ADD R0~R7, SP, Imm + static INSN_REGPARM void thumbA8(u32 opcode) + { + u8 regist = (opcode >> 8) & 7; + reg[regist].I = reg[13].I + ((opcode & 255) << 2); + clockTicks = 1 + codeTicksAccess16(armNextPC); + } + + // ADD SP, Imm + static INSN_REGPARM void thumbB0(u32 opcode) + { + int offset = (opcode & 127) << 2; + if (opcode & 0x80) + offset = -offset; + reg[13].I += offset; + clockTicks = 1 + codeTicksAccess16(armNextPC); + } + + // Push and pop /////////////////////////////////////////////////////////// + +#define PUSH_REG(val, r) \ + if (opcode & (val)) { \ + CPUWriteMemory(address, reg[(r)].I); \ + if (!count) { \ + clockTicks += 1 + dataTicksAccess32(address); \ + } else { \ + clockTicks += 1 + dataTicksAccessSeq32(address); \ + } \ + count++; \ + address += 4; \ } - reg[dest].I = value; - } - N_FLAG = reg[dest].I & 0x80000000 ? true : false; - Z_FLAG = reg[dest].I ? false : true; - clockTicks = codeTicksAccess16(armNextPC)+2; -} -// LSR Rd, Rs -static INSN_REGPARM void thumb40_3(u32 opcode) -{ - int dest = opcode & 7; - u32 value = reg[(opcode >> 3)&7].B.B0; - if(value) { - if(value == 32) { - value = 0; - C_FLAG = (reg[dest].I & 0x80000000 ? true : false); - } else if(value < 32) { - LSR_RD_RS; - } else { - value = 0; - C_FLAG = false; +#define POP_REG(val, r) \ + if (opcode & (val)) { \ + reg[(r)].I = CPUReadMemory(address); \ + if (!count) { \ + clockTicks += 1 + dataTicksAccess32(address); \ + } else { \ + clockTicks += 1 + dataTicksAccessSeq32(address); \ + } \ + count++; \ + address += 4; \ } - reg[dest].I = value; - } - N_FLAG = reg[dest].I & 0x80000000 ? true : false; - Z_FLAG = reg[dest].I ? false : true; - clockTicks = codeTicksAccess16(armNextPC)+2; -} -// ASR Rd, Rs -static INSN_REGPARM void thumb41_0(u32 opcode) -{ - int dest = opcode & 7; - u32 value = reg[(opcode >> 3)&7].B.B0; - if(value) { - if(value < 32) { - ASR_RD_RS; - reg[dest].I = value; - } else { - if(reg[dest].I & 0x80000000){ - reg[dest].I = 0xFFFFFFFF; - C_FLAG = true; - } else { - reg[dest].I = 0x00000000; - C_FLAG = false; - } + // PUSH {Rlist} + static INSN_REGPARM void thumbB4(u32 opcode) + { + if (busPrefetchCount == 0) + busPrefetch = busPrefetchEnable; + int count = 0; + u32 temp = reg[13].I - 4 * cpuBitsSet[opcode & 0xff]; + u32 address = temp & 0xFFFFFFFC; + PUSH_REG(1, 0); + PUSH_REG(2, 1); + PUSH_REG(4, 2); + PUSH_REG(8, 3); + PUSH_REG(16, 4); + PUSH_REG(32, 5); + PUSH_REG(64, 6); + PUSH_REG(128, 7); + clockTicks += 1 + codeTicksAccess16(armNextPC); + reg[13].I = temp; + } + + // PUSH {Rlist, LR} + static INSN_REGPARM void thumbB5(u32 opcode) + { + if (busPrefetchCount == 0) + busPrefetch = busPrefetchEnable; + int count = 0; + u32 temp = reg[13].I - 4 - 4 * cpuBitsSet[opcode & 0xff]; + u32 address = temp & 0xFFFFFFFC; + PUSH_REG(1, 0); + PUSH_REG(2, 1); + PUSH_REG(4, 2); + PUSH_REG(8, 3); + PUSH_REG(16, 4); + PUSH_REG(32, 5); + PUSH_REG(64, 6); + PUSH_REG(128, 7); + PUSH_REG(256, 14); + clockTicks += 1 + codeTicksAccess16(armNextPC); + reg[13].I = temp; + } + + // POP {Rlist} + static INSN_REGPARM void thumbBC(u32 opcode) + { + if (busPrefetchCount == 0) + busPrefetch = busPrefetchEnable; + int count = 0; + u32 address = reg[13].I & 0xFFFFFFFC; + u32 temp = reg[13].I + 4 * cpuBitsSet[opcode & 0xFF]; + POP_REG(1, 0); + POP_REG(2, 1); + POP_REG(4, 2); + POP_REG(8, 3); + POP_REG(16, 4); + POP_REG(32, 5); + POP_REG(64, 6); + POP_REG(128, 7); + reg[13].I = temp; + clockTicks = 2 + codeTicksAccess16(armNextPC); + } + + // POP {Rlist, PC} + static INSN_REGPARM void thumbBD(u32 opcode) + { + if (busPrefetchCount == 0) + busPrefetch = busPrefetchEnable; + int count = 0; + u32 address = reg[13].I & 0xFFFFFFFC; + u32 temp = reg[13].I + 4 + 4 * cpuBitsSet[opcode & 0xFF]; + POP_REG(1, 0); + POP_REG(2, 1); + POP_REG(4, 2); + POP_REG(8, 3); + POP_REG(16, 4); + POP_REG(32, 5); + POP_REG(64, 6); + POP_REG(128, 7); + reg[15].I = (CPUReadMemory(address) & 0xFFFFFFFE); + if (!count) { + clockTicks += 1 + dataTicksAccess32(address); + } else { + clockTicks += 1 + dataTicksAccessSeq32(address); + } + count++; + armNextPC = reg[15].I; + reg[15].I += 2; + reg[13].I = temp; + THUMB_PREFETCH; + busPrefetchCount = 0; + clockTicks += 3 + codeTicksAccess16(armNextPC) + codeTicksAccess16(armNextPC); + } + + // Load/store multiple //////////////////////////////////////////////////// + +#define THUMB_STM_REG(val, r, b) \ + if (opcode & (val)) { \ + CPUWriteMemory(address, reg[(r)].I); \ + reg[(b)].I = temp; \ + if (!count) { \ + clockTicks += 1 + dataTicksAccess32(address); \ + } else { \ + clockTicks += 1 + dataTicksAccessSeq32(address); \ + } \ + count++; \ + address += 4; \ } - } - N_FLAG = reg[dest].I & 0x80000000 ? true : false; - Z_FLAG = reg[dest].I ? false : true; - clockTicks = codeTicksAccess16(armNextPC)+2; -} -// ADC Rd, Rs -static INSN_REGPARM void thumb41_1(u32 opcode) -{ - int dest = opcode & 0x07; - u32 value = reg[(opcode >> 3)&7].I; - ADC_RD_RS; -} - -// SBC Rd, Rs -static INSN_REGPARM void thumb41_2(u32 opcode) -{ - int dest = opcode & 0x07; - u32 value = reg[(opcode >> 3)&7].I; - SBC_RD_RS; -} - -// ROR Rd, Rs -static INSN_REGPARM void thumb41_3(u32 opcode) -{ - int dest = opcode & 7; - u32 value = reg[(opcode >> 3)&7].B.B0; - - if(value) { - value = value & 0x1f; - if(value == 0) { - C_FLAG = (reg[dest].I & 0x80000000 ? true : false); - } else { - ROR_RD_RS; - reg[dest].I = value; +#define THUMB_LDM_REG(val, r) \ + if (opcode & (val)) { \ + reg[(r)].I = CPUReadMemory(address); \ + if (!count) { \ + clockTicks += 1 + dataTicksAccess32(address); \ + } else { \ + clockTicks += 1 + dataTicksAccessSeq32(address); \ + } \ + count++; \ + address += 4; \ } - } - clockTicks = codeTicksAccess16(armNextPC)+2; - N_FLAG = reg[dest].I & 0x80000000 ? true : false; - Z_FLAG = reg[dest].I ? false : true; -} -// TST Rd, Rs -static INSN_REGPARM void thumb42_0(u32 opcode) -{ - u32 value = reg[opcode & 7].I & reg[(opcode >> 3) & 7].I; - N_FLAG = value & 0x80000000 ? true : false; - Z_FLAG = value ? false : true; -} - -// NEG Rd, Rs -static INSN_REGPARM void thumb42_1(u32 opcode) -{ - int dest = opcode & 7; - int source = (opcode >> 3) & 7; - NEG_RD_RS; -} - -// CMP Rd, Rs -static INSN_REGPARM void thumb42_2(u32 opcode) -{ - int dest = opcode & 7; - u32 value = reg[(opcode >> 3)&7].I; - CMP_RD_RS; -} - -// CMN Rd, Rs -static INSN_REGPARM void thumb42_3(u32 opcode) -{ - int dest = opcode & 7; - u32 value = reg[(opcode >> 3)&7].I; - CMN_RD_RS; -} - -// ORR Rd, Rs -static INSN_REGPARM void thumb43_0(u32 opcode) -{ - int dest = opcode & 7; - reg[dest].I |= reg[(opcode >> 3) & 7].I; - Z_FLAG = reg[dest].I ? false : true; - N_FLAG = reg[dest].I & 0x80000000 ? true : false; -} - -// MUL Rd, Rs -static INSN_REGPARM void thumb43_1(u32 opcode) -{ - clockTicks = 1; - int dest = opcode & 7; - u32 rm = reg[dest].I; - reg[dest].I = reg[(opcode >> 3) & 7].I * rm; - if (((s32)rm) < 0) - rm = ~rm; - if ((rm & 0xFFFFFF00) == 0) - clockTicks += 0; - else if ((rm & 0xFFFF0000) == 0) - clockTicks += 1; - else if ((rm & 0xFF000000) == 0) - clockTicks += 2; - else - clockTicks += 3; - busPrefetchCount = (busPrefetchCount<>(8-clockTicks)); - clockTicks += codeTicksAccess16(armNextPC) + 1; - Z_FLAG = reg[dest].I ? false : true; - N_FLAG = reg[dest].I & 0x80000000 ? true : false; -} - -// BIC Rd, Rs -static INSN_REGPARM void thumb43_2(u32 opcode) -{ - int dest = opcode & 7; - reg[dest].I &= (~reg[(opcode >> 3) & 7].I); - Z_FLAG = reg[dest].I ? false : true; - N_FLAG = reg[dest].I & 0x80000000 ? true : false; -} - -// MVN Rd, Rs -static INSN_REGPARM void thumb43_3(u32 opcode) -{ - int dest = opcode & 7; - reg[dest].I = ~reg[(opcode >> 3) & 7].I; - Z_FLAG = reg[dest].I ? false : true; - N_FLAG = reg[dest].I & 0x80000000 ? true : false; -} - -// High-register instructions and BX ////////////////////////////////////// - -// ADD Rd, Hs -static INSN_REGPARM void thumb44_1(u32 opcode) -{ - reg[opcode&7].I += reg[((opcode>>3)&7)+8].I; -} - -// ADD Hd, Rs -static INSN_REGPARM void thumb44_2(u32 opcode) -{ - reg[(opcode&7)+8].I += reg[(opcode>>3)&7].I; - if((opcode&7) == 7) { - reg[15].I &= 0xFFFFFFFE; - armNextPC = reg[15].I; - reg[15].I += 2; - THUMB_PREFETCH; - clockTicks = codeTicksAccessSeq16(armNextPC)*2 - + codeTicksAccess16(armNextPC) + 3; - } -} - -// ADD Hd, Hs -static INSN_REGPARM void thumb44_3(u32 opcode) -{ - reg[(opcode&7)+8].I += reg[((opcode>>3)&7)+8].I; - if((opcode&7) == 7) { - reg[15].I &= 0xFFFFFFFE; - armNextPC = reg[15].I; - reg[15].I += 2; - THUMB_PREFETCH; - clockTicks = codeTicksAccessSeq16(armNextPC)*2 - + codeTicksAccess16(armNextPC) + 3; - } -} - -// CMP Rd, Hs -static INSN_REGPARM void thumb45_1(u32 opcode) -{ - int dest = opcode & 7; - u32 value = reg[((opcode>>3)&7)+8].I; - CMP_RD_RS; -} - -// CMP Hd, Rs -static INSN_REGPARM void thumb45_2(u32 opcode) -{ - int dest = (opcode & 7) + 8; - u32 value = reg[(opcode>>3)&7].I; - CMP_RD_RS; -} - -// CMP Hd, Hs -static INSN_REGPARM void thumb45_3(u32 opcode) -{ - int dest = (opcode & 7) + 8; - u32 value = reg[((opcode>>3)&7)+8].I; - CMP_RD_RS; -} - -// MOV Rd, Rs -static INSN_REGPARM void thumb46_0(u32 opcode) -{ - reg[opcode&7].I = reg[((opcode>>3)&7)].I; - clockTicks = codeTicksAccessSeq16(armNextPC) + 1; -} - -// MOV Rd, Hs -static INSN_REGPARM void thumb46_1(u32 opcode) -{ - reg[opcode&7].I = reg[((opcode>>3)&7)+8].I; - clockTicks = codeTicksAccessSeq16(armNextPC) + 1; -} - -// MOV Hd, Rs -static INSN_REGPARM void thumb46_2(u32 opcode) -{ - reg[(opcode&7)+8].I = reg[(opcode>>3)&7].I; - if((opcode&7) == 7) { - UPDATE_OLDREG; - reg[15].I &= 0xFFFFFFFE; - armNextPC = reg[15].I; - reg[15].I += 2; - THUMB_PREFETCH; - clockTicks = codeTicksAccessSeq16(armNextPC)*2 - + codeTicksAccess16(armNextPC) + 3; - } -} - -// MOV Hd, Hs -static INSN_REGPARM void thumb46_3(u32 opcode) -{ - reg[(opcode&7)+8].I = reg[((opcode>>3)&7)+8].I; - if((opcode&7) == 7) { - UPDATE_OLDREG; - reg[15].I &= 0xFFFFFFFE; - armNextPC = reg[15].I; - reg[15].I += 2; - THUMB_PREFETCH; - clockTicks = codeTicksAccessSeq16(armNextPC)*2 - + codeTicksAccess16(armNextPC) + 3; - } -} - - -// BX Rs -static INSN_REGPARM void thumb47(u32 opcode) -{ - int base = (opcode >> 3) & 15; - busPrefetchCount=0; - UPDATE_OLDREG; - reg[15].I = reg[base].I; - if(reg[base].I & 1) { - armState = false; - reg[15].I &= 0xFFFFFFFE; - armNextPC = reg[15].I; - reg[15].I += 2; - THUMB_PREFETCH; - clockTicks = codeTicksAccessSeq16(armNextPC)*2 + codeTicksAccess16(armNextPC) + 3; - } else { - armState = true; - reg[15].I &= 0xFFFFFFFC; - armNextPC = reg[15].I; - reg[15].I += 4; - ARM_PREFETCH; - clockTicks = codeTicksAccessSeq32(armNextPC)*2 + codeTicksAccess32(armNextPC) + 3; - } -} - -// Load/store instructions //////////////////////////////////////////////// - -// LDR R0~R7,[PC, #Imm] -static INSN_REGPARM void thumb48(u32 opcode) -{ - u8 regist = (opcode >> 8) & 7; - if (busPrefetchCount == 0) - busPrefetch = busPrefetchEnable; - u32 address = (reg[15].I & 0xFFFFFFFC) + ((opcode & 0xFF) << 2); - reg[regist].I = CPUReadMemoryQuick(address); - busPrefetchCount=0; - clockTicks = 3 + dataTicksAccess32(address) + codeTicksAccess16(armNextPC); -} - -// STR Rd, [Rs, Rn] -static INSN_REGPARM void thumb50(u32 opcode) -{ - if (busPrefetchCount == 0) - busPrefetch = busPrefetchEnable; - u32 address = reg[(opcode>>3)&7].I + reg[(opcode>>6)&7].I; - CPUWriteMemory(address, reg[opcode & 7].I); - clockTicks = dataTicksAccess32(address) + codeTicksAccess16(armNextPC) + 2; -} - -// STRH Rd, [Rs, Rn] -static INSN_REGPARM void thumb52(u32 opcode) -{ - if (busPrefetchCount == 0) - busPrefetch = busPrefetchEnable; - u32 address = reg[(opcode>>3)&7].I + reg[(opcode>>6)&7].I; - CPUWriteHalfWord(address, reg[opcode&7].W.W0); - clockTicks = dataTicksAccess16(address) + codeTicksAccess16(armNextPC) + 2; -} - -// STRB Rd, [Rs, Rn] -static INSN_REGPARM void thumb54(u32 opcode) -{ - if (busPrefetchCount == 0) - busPrefetch = busPrefetchEnable; - u32 address = reg[(opcode>>3)&7].I + reg[(opcode >>6)&7].I; - CPUWriteByte(address, reg[opcode & 7].B.B0); - clockTicks = dataTicksAccess16(address) + codeTicksAccess16(armNextPC) + 2; -} - -// LDSB Rd, [Rs, Rn] -static INSN_REGPARM void thumb56(u32 opcode) -{ - if (busPrefetchCount == 0) - busPrefetch = busPrefetchEnable; - u32 address = reg[(opcode>>3)&7].I + reg[(opcode>>6)&7].I; - reg[opcode&7].I = (s8)CPUReadByte(address); - clockTicks = 3 + dataTicksAccess16(address) + codeTicksAccess16(armNextPC); -} - -// LDR Rd, [Rs, Rn] -static INSN_REGPARM void thumb58(u32 opcode) -{ - if (busPrefetchCount == 0) - busPrefetch = busPrefetchEnable; - u32 address = reg[(opcode>>3)&7].I + reg[(opcode>>6)&7].I; - reg[opcode&7].I = CPUReadMemory(address); - clockTicks = 3 + dataTicksAccess32(address) + codeTicksAccess16(armNextPC); -} - -// LDRH Rd, [Rs, Rn] -static INSN_REGPARM void thumb5A(u32 opcode) -{ - if (busPrefetchCount == 0) - busPrefetch = busPrefetchEnable; - u32 address = reg[(opcode>>3)&7].I + reg[(opcode>>6)&7].I; - reg[opcode&7].I = CPUReadHalfWord(address); - clockTicks = 3 + dataTicksAccess32(address) + codeTicksAccess16(armNextPC); -} - -// LDRB Rd, [Rs, Rn] -static INSN_REGPARM void thumb5C(u32 opcode) -{ - if (busPrefetchCount == 0) - busPrefetch = busPrefetchEnable; - u32 address = reg[(opcode>>3)&7].I + reg[(opcode>>6)&7].I; - reg[opcode&7].I = CPUReadByte(address); - clockTicks = 3 + dataTicksAccess16(address) + codeTicksAccess16(armNextPC); -} - -// LDSH Rd, [Rs, Rn] -static INSN_REGPARM void thumb5E(u32 opcode) -{ - if (busPrefetchCount == 0) - busPrefetch = busPrefetchEnable; - u32 address = reg[(opcode>>3)&7].I + reg[(opcode>>6)&7].I; - reg[opcode&7].I = (u32)CPUReadHalfWordSigned(address); - clockTicks = 3 + dataTicksAccess16(address) + codeTicksAccess16(armNextPC); -} - -// STR Rd, [Rs, #Imm] -static INSN_REGPARM void thumb60(u32 opcode) -{ - if (busPrefetchCount == 0) - busPrefetch = busPrefetchEnable; - u32 address = reg[(opcode>>3)&7].I + (((opcode>>6)&31)<<2); - CPUWriteMemory(address, reg[opcode&7].I); - clockTicks = dataTicksAccess32(address) + codeTicksAccess16(armNextPC) + 2; -} - -// LDR Rd, [Rs, #Imm] -static INSN_REGPARM void thumb68(u32 opcode) -{ - if (busPrefetchCount == 0) - busPrefetch = busPrefetchEnable; - u32 address = reg[(opcode>>3)&7].I + (((opcode>>6)&31)<<2); - reg[opcode&7].I = CPUReadMemory(address); - clockTicks = 3 + dataTicksAccess32(address) + codeTicksAccess16(armNextPC); -} - -// STRB Rd, [Rs, #Imm] -static INSN_REGPARM void thumb70(u32 opcode) -{ - if (busPrefetchCount == 0) - busPrefetch = busPrefetchEnable; - u32 address = reg[(opcode>>3)&7].I + (((opcode>>6)&31)); - CPUWriteByte(address, reg[opcode&7].B.B0); - clockTicks = dataTicksAccess16(address) + codeTicksAccess16(armNextPC) + 2; -} - -// LDRB Rd, [Rs, #Imm] -static INSN_REGPARM void thumb78(u32 opcode) -{ - if (busPrefetchCount == 0) - busPrefetch = busPrefetchEnable; - u32 address = reg[(opcode>>3)&7].I + (((opcode>>6)&31)); - reg[opcode&7].I = CPUReadByte(address); - clockTicks = 3 + dataTicksAccess16(address) + codeTicksAccess16(armNextPC); -} - -// STRH Rd, [Rs, #Imm] -static INSN_REGPARM void thumb80(u32 opcode) -{ - if (busPrefetchCount == 0) - busPrefetch = busPrefetchEnable; - u32 address = reg[(opcode>>3)&7].I + (((opcode>>6)&31)<<1); - CPUWriteHalfWord(address, reg[opcode&7].W.W0); - clockTicks = dataTicksAccess16(address) + codeTicksAccess16(armNextPC) + 2; -} - -// LDRH Rd, [Rs, #Imm] -static INSN_REGPARM void thumb88(u32 opcode) -{ - if (busPrefetchCount == 0) - busPrefetch = busPrefetchEnable; - u32 address = reg[(opcode>>3)&7].I + (((opcode>>6)&31)<<1); - reg[opcode&7].I = CPUReadHalfWord(address); - clockTicks = 3 + dataTicksAccess16(address) + codeTicksAccess16(armNextPC); -} - -// STR R0~R7, [SP, #Imm] -static INSN_REGPARM void thumb90(u32 opcode) -{ - u8 regist = (opcode >> 8) & 7; - if (busPrefetchCount == 0) - busPrefetch = busPrefetchEnable; - u32 address = reg[13].I + ((opcode&255)<<2); - CPUWriteMemory(address, reg[regist].I); - clockTicks = dataTicksAccess32(address) + codeTicksAccess16(armNextPC) + 2; -} - -// LDR R0~R7, [SP, #Imm] -static INSN_REGPARM void thumb98(u32 opcode) -{ - u8 regist = (opcode >> 8) & 7; - if (busPrefetchCount == 0) - busPrefetch = busPrefetchEnable; - u32 address = reg[13].I + ((opcode&255)<<2); - reg[regist].I = CPUReadMemoryQuick(address); - clockTicks = 3 + dataTicksAccess32(address) + codeTicksAccess16(armNextPC); -} - -// PC/stack-related /////////////////////////////////////////////////////// - -// ADD R0~R7, PC, Imm -static INSN_REGPARM void thumbA0(u32 opcode) -{ - u8 regist = (opcode >> 8) & 7; - reg[regist].I = (reg[15].I & 0xFFFFFFFC) + ((opcode&255)<<2); - clockTicks = 1 + codeTicksAccess16(armNextPC); -} - -// ADD R0~R7, SP, Imm -static INSN_REGPARM void thumbA8(u32 opcode) -{ - u8 regist = (opcode >> 8) & 7; - reg[regist].I = reg[13].I + ((opcode&255)<<2); - clockTicks = 1 + codeTicksAccess16(armNextPC); -} - -// ADD SP, Imm -static INSN_REGPARM void thumbB0(u32 opcode) -{ - int offset = (opcode & 127) << 2; - if(opcode & 0x80) - offset = -offset; - reg[13].I += offset; - clockTicks = 1 + codeTicksAccess16(armNextPC); -} - -// Push and pop /////////////////////////////////////////////////////////// - -#define PUSH_REG(val, r) \ - if (opcode & (val)) { \ - CPUWriteMemory(address, reg[(r)].I); \ - if (!count) { \ - clockTicks += 1 + dataTicksAccess32(address); \ - } else { \ - clockTicks += 1 + dataTicksAccessSeq32(address); \ - } \ - count++; \ - address += 4; \ - } - -#define POP_REG(val, r) \ - if (opcode & (val)) { \ - reg[(r)].I = CPUReadMemory(address); \ - if (!count) { \ - clockTicks += 1 + dataTicksAccess32(address); \ - } else { \ - clockTicks += 1 + dataTicksAccessSeq32(address); \ - } \ - count++; \ - address += 4; \ - } - -// PUSH {Rlist} -static INSN_REGPARM void thumbB4(u32 opcode) -{ - if (busPrefetchCount == 0) - busPrefetch = busPrefetchEnable; - int count = 0; - u32 temp = reg[13].I - 4 * cpuBitsSet[opcode & 0xff]; - u32 address = temp & 0xFFFFFFFC; - PUSH_REG(1, 0); - PUSH_REG(2, 1); - PUSH_REG(4, 2); - PUSH_REG(8, 3); - PUSH_REG(16, 4); - PUSH_REG(32, 5); - PUSH_REG(64, 6); - PUSH_REG(128, 7); - clockTicks += 1 + codeTicksAccess16(armNextPC); - reg[13].I = temp; -} - -// PUSH {Rlist, LR} -static INSN_REGPARM void thumbB5(u32 opcode) -{ - if (busPrefetchCount == 0) - busPrefetch = busPrefetchEnable; - int count = 0; - u32 temp = reg[13].I - 4 - 4 * cpuBitsSet[opcode & 0xff]; - u32 address = temp & 0xFFFFFFFC; - PUSH_REG(1, 0); - PUSH_REG(2, 1); - PUSH_REG(4, 2); - PUSH_REG(8, 3); - PUSH_REG(16, 4); - PUSH_REG(32, 5); - PUSH_REG(64, 6); - PUSH_REG(128, 7); - PUSH_REG(256, 14); - clockTicks += 1 + codeTicksAccess16(armNextPC); - reg[13].I = temp; -} - -// POP {Rlist} -static INSN_REGPARM void thumbBC(u32 opcode) -{ - if (busPrefetchCount == 0) - busPrefetch = busPrefetchEnable; - int count = 0; - u32 address = reg[13].I & 0xFFFFFFFC; - u32 temp = reg[13].I + 4*cpuBitsSet[opcode & 0xFF]; - POP_REG(1, 0); - POP_REG(2, 1); - POP_REG(4, 2); - POP_REG(8, 3); - POP_REG(16, 4); - POP_REG(32, 5); - POP_REG(64, 6); - POP_REG(128, 7); - reg[13].I = temp; - clockTicks = 2 + codeTicksAccess16(armNextPC); -} - -// POP {Rlist, PC} -static INSN_REGPARM void thumbBD(u32 opcode) -{ - if (busPrefetchCount == 0) - busPrefetch = busPrefetchEnable; - int count = 0; - u32 address = reg[13].I & 0xFFFFFFFC; - u32 temp = reg[13].I + 4 + 4*cpuBitsSet[opcode & 0xFF]; - POP_REG(1, 0); - POP_REG(2, 1); - POP_REG(4, 2); - POP_REG(8, 3); - POP_REG(16, 4); - POP_REG(32, 5); - POP_REG(64, 6); - POP_REG(128, 7); - reg[15].I = (CPUReadMemory(address) & 0xFFFFFFFE); - if (!count) { - clockTicks += 1 + dataTicksAccess32(address); - } else { - clockTicks += 1 + dataTicksAccessSeq32(address); - } - count++; - armNextPC = reg[15].I; - reg[15].I += 2; - reg[13].I = temp; - THUMB_PREFETCH; - busPrefetchCount = 0; - clockTicks += 3 + codeTicksAccess16(armNextPC) + codeTicksAccess16(armNextPC); -} - -// Load/store multiple //////////////////////////////////////////////////// - -#define THUMB_STM_REG(val,r,b) \ - if(opcode & (val)) { \ - CPUWriteMemory(address, reg[(r)].I); \ - reg[(b)].I = temp; \ - if (!count) { \ - clockTicks += 1 + dataTicksAccess32(address); \ - } else { \ - clockTicks += 1 + dataTicksAccessSeq32(address); \ - } \ - count++; \ - address += 4; \ - } - -#define THUMB_LDM_REG(val,r) \ - if(opcode & (val)) { \ - reg[(r)].I = CPUReadMemory(address); \ - if (!count) { \ - clockTicks += 1 + dataTicksAccess32(address); \ - } else { \ - clockTicks += 1 + dataTicksAccessSeq32(address); \ - } \ - count++; \ - address += 4; \ - } - -// STM R0~7!, {Rlist} -static INSN_REGPARM void thumbC0(u32 opcode) -{ - u8 regist = (opcode >> 8) & 7; - if (busPrefetchCount == 0) - busPrefetch = busPrefetchEnable; - u32 address = reg[regist].I & 0xFFFFFFFC; - u32 temp = reg[regist].I + 4*cpuBitsSet[opcode & 0xff]; - int count = 0; - // store - THUMB_STM_REG(1, 0, regist); - THUMB_STM_REG(2, 1, regist); - THUMB_STM_REG(4, 2, regist); - THUMB_STM_REG(8, 3, regist); - THUMB_STM_REG(16, 4, regist); - THUMB_STM_REG(32, 5, regist); - THUMB_STM_REG(64, 6, regist); - THUMB_STM_REG(128, 7, regist); - clockTicks = 1 + codeTicksAccess16(armNextPC); -} - -// LDM R0~R7!, {Rlist} -static INSN_REGPARM void thumbC8(u32 opcode) -{ - u8 regist = (opcode >> 8) & 7; - if (busPrefetchCount == 0) - busPrefetch = busPrefetchEnable; - u32 address = reg[regist].I & 0xFFFFFFFC; - u32 temp = reg[regist].I + 4*cpuBitsSet[opcode & 0xFF]; - int count = 0; - // load - THUMB_LDM_REG(1, 0); - THUMB_LDM_REG(2, 1); - THUMB_LDM_REG(4, 2); - THUMB_LDM_REG(8, 3); - THUMB_LDM_REG(16, 4); - THUMB_LDM_REG(32, 5); - THUMB_LDM_REG(64, 6); - THUMB_LDM_REG(128, 7); - clockTicks = 2 + codeTicksAccess16(armNextPC); - if(!(opcode & (1<> 8) & 7; + if (busPrefetchCount == 0) + busPrefetch = busPrefetchEnable; + u32 address = reg[regist].I & 0xFFFFFFFC; + u32 temp = reg[regist].I + 4 * cpuBitsSet[opcode & 0xff]; + int count = 0; + // store + THUMB_STM_REG(1, 0, regist); + THUMB_STM_REG(2, 1, regist); + THUMB_STM_REG(4, 2, regist); + THUMB_STM_REG(8, 3, regist); + THUMB_STM_REG(16, 4, regist); + THUMB_STM_REG(32, 5, regist); + THUMB_STM_REG(64, 6, regist); + THUMB_STM_REG(128, 7, regist); + clockTicks = 1 + codeTicksAccess16(armNextPC); + } + + // LDM R0~R7!, {Rlist} + static INSN_REGPARM void thumbC8(u32 opcode) + { + u8 regist = (opcode >> 8) & 7; + if (busPrefetchCount == 0) + busPrefetch = busPrefetchEnable; + u32 address = reg[regist].I & 0xFFFFFFFC; + u32 temp = reg[regist].I + 4 * cpuBitsSet[opcode & 0xFF]; + int count = 0; + // load + THUMB_LDM_REG(1, 0); + THUMB_LDM_REG(2, 1); + THUMB_LDM_REG(4, 2); + THUMB_LDM_REG(8, 3); + THUMB_LDM_REG(16, 4); + THUMB_LDM_REG(32, 5); + THUMB_LDM_REG(64, 6); + THUMB_LDM_REG(128, 7); + clockTicks = 2 + codeTicksAccess16(armNextPC); + if (!(opcode & (1 << regist))) + reg[regist].I = temp; + } + + // Conditional branches /////////////////////////////////////////////////// + + // BEQ offset + static INSN_REGPARM void thumbD0(u32 opcode) + { + UPDATE_OLDREG; + clockTicks = codeTicksAccessSeq16(armNextPC) + 1; + if (Z_FLAG) { + reg[15].I += ((s8)(opcode & 0xFF)) << 1; + armNextPC = reg[15].I; + reg[15].I += 2; + THUMB_PREFETCH; + clockTicks += codeTicksAccessSeq16(armNextPC) + codeTicksAccess16(armNextPC) + 2; + busPrefetchCount = 0; + } + } + + // BNE offset + static INSN_REGPARM void thumbD1(u32 opcode) + { + UPDATE_OLDREG; + clockTicks = codeTicksAccessSeq16(armNextPC) + 1; + if (!Z_FLAG) { + reg[15].I += ((s8)(opcode & 0xFF)) << 1; + armNextPC = reg[15].I; + reg[15].I += 2; + THUMB_PREFETCH; + clockTicks += codeTicksAccessSeq16(armNextPC) + codeTicksAccess16(armNextPC) + 2; + busPrefetchCount = 0; + } + } + + // BCS offset + static INSN_REGPARM void thumbD2(u32 opcode) + { + UPDATE_OLDREG; + clockTicks = codeTicksAccessSeq16(armNextPC) + 1; + if (C_FLAG) { + reg[15].I += ((s8)(opcode & 0xFF)) << 1; + armNextPC = reg[15].I; + reg[15].I += 2; + THUMB_PREFETCH; + clockTicks += codeTicksAccessSeq16(armNextPC) + codeTicksAccess16(armNextPC) + 2; + busPrefetchCount = 0; + } + } + + // BCC offset + static INSN_REGPARM void thumbD3(u32 opcode) + { + UPDATE_OLDREG; + clockTicks = codeTicksAccessSeq16(armNextPC) + 1; + if (!C_FLAG) { + reg[15].I += ((s8)(opcode & 0xFF)) << 1; + armNextPC = reg[15].I; + reg[15].I += 2; + THUMB_PREFETCH; + clockTicks += codeTicksAccessSeq16(armNextPC) + codeTicksAccess16(armNextPC) + 2; + busPrefetchCount = 0; + } + } + + // BMI offset + static INSN_REGPARM void thumbD4(u32 opcode) + { + UPDATE_OLDREG; + clockTicks = codeTicksAccessSeq16(armNextPC) + 1; + if (N_FLAG) { + reg[15].I += ((s8)(opcode & 0xFF)) << 1; + armNextPC = reg[15].I; + reg[15].I += 2; + THUMB_PREFETCH; + clockTicks += codeTicksAccessSeq16(armNextPC) + codeTicksAccess16(armNextPC) + 2; + busPrefetchCount = 0; + } + } + + // BPL offset + static INSN_REGPARM void thumbD5(u32 opcode) + { + UPDATE_OLDREG; + clockTicks = codeTicksAccessSeq16(armNextPC) + 1; + if (!N_FLAG) { + reg[15].I += ((s8)(opcode & 0xFF)) << 1; + armNextPC = reg[15].I; + reg[15].I += 2; + THUMB_PREFETCH; + clockTicks += codeTicksAccessSeq16(armNextPC) + codeTicksAccess16(armNextPC) + 2; + busPrefetchCount = 0; + } + } + + // BVS offset + static INSN_REGPARM void thumbD6(u32 opcode) + { + UPDATE_OLDREG; + clockTicks = codeTicksAccessSeq16(armNextPC) + 1; + if (V_FLAG) { + reg[15].I += ((s8)(opcode & 0xFF)) << 1; + armNextPC = reg[15].I; + reg[15].I += 2; + THUMB_PREFETCH; + clockTicks += codeTicksAccessSeq16(armNextPC) + codeTicksAccess16(armNextPC) + 2; + busPrefetchCount = 0; + } + } + + // BVC offset + static INSN_REGPARM void thumbD7(u32 opcode) + { + UPDATE_OLDREG; + clockTicks = codeTicksAccessSeq16(armNextPC) + 1; + if (!V_FLAG) { + reg[15].I += ((s8)(opcode & 0xFF)) << 1; + armNextPC = reg[15].I; + reg[15].I += 2; + THUMB_PREFETCH; + clockTicks += codeTicksAccessSeq16(armNextPC) + codeTicksAccess16(armNextPC) + 2; + busPrefetchCount = 0; + } + } + + // BHI offset + static INSN_REGPARM void thumbD8(u32 opcode) + { + UPDATE_OLDREG; + clockTicks = codeTicksAccessSeq16(armNextPC) + 1; + if (C_FLAG && !Z_FLAG) { + reg[15].I += ((s8)(opcode & 0xFF)) << 1; + armNextPC = reg[15].I; + reg[15].I += 2; + THUMB_PREFETCH; + clockTicks += codeTicksAccessSeq16(armNextPC) + codeTicksAccess16(armNextPC) + 2; + busPrefetchCount = 0; + } + } + + // BLS offset + static INSN_REGPARM void thumbD9(u32 opcode) + { + UPDATE_OLDREG; + clockTicks = codeTicksAccessSeq16(armNextPC) + 1; + if (!C_FLAG || Z_FLAG) { + reg[15].I += ((s8)(opcode & 0xFF)) << 1; + armNextPC = reg[15].I; + reg[15].I += 2; + THUMB_PREFETCH; + clockTicks += codeTicksAccessSeq16(armNextPC) + codeTicksAccess16(armNextPC) + 2; + busPrefetchCount = 0; + } + } + + // BGE offset + static INSN_REGPARM void thumbDA(u32 opcode) + { + UPDATE_OLDREG; + clockTicks = codeTicksAccessSeq16(armNextPC) + 1; + if (N_FLAG == V_FLAG) { + reg[15].I += ((s8)(opcode & 0xFF)) << 1; + armNextPC = reg[15].I; + reg[15].I += 2; + THUMB_PREFETCH; + clockTicks += codeTicksAccessSeq16(armNextPC) + codeTicksAccess16(armNextPC) + 2; + busPrefetchCount = 0; + } + } + + // BLT offset + static INSN_REGPARM void thumbDB(u32 opcode) + { + UPDATE_OLDREG; + clockTicks = codeTicksAccessSeq16(armNextPC) + 1; + if (N_FLAG != V_FLAG) { + reg[15].I += ((s8)(opcode & 0xFF)) << 1; + armNextPC = reg[15].I; + reg[15].I += 2; + THUMB_PREFETCH; + clockTicks += codeTicksAccessSeq16(armNextPC) + codeTicksAccess16(armNextPC) + 2; + busPrefetchCount = 0; + } + } + + // BGT offset + static INSN_REGPARM void thumbDC(u32 opcode) + { + UPDATE_OLDREG; + clockTicks = codeTicksAccessSeq16(armNextPC) + 1; + if (!Z_FLAG && (N_FLAG == V_FLAG)) { + reg[15].I += ((s8)(opcode & 0xFF)) << 1; + armNextPC = reg[15].I; + reg[15].I += 2; + THUMB_PREFETCH; + clockTicks += codeTicksAccessSeq16(armNextPC) + codeTicksAccess16(armNextPC) + 2; + busPrefetchCount = 0; + } + } + + // BLE offset + static INSN_REGPARM void thumbDD(u32 opcode) + { + UPDATE_OLDREG; + clockTicks = codeTicksAccessSeq16(armNextPC); + if (Z_FLAG || (N_FLAG != V_FLAG)) { + reg[15].I += ((s8)(opcode & 0xFF)) << 1; + armNextPC = reg[15].I; + reg[15].I += 2; + THUMB_PREFETCH; + clockTicks += codeTicksAccessSeq16(armNextPC) + codeTicksAccess16(armNextPC) + 2; + busPrefetchCount = 0; + } + } + + // SWI, B, BL ///////////////////////////////////////////////////////////// + + // SWI #comment + static INSN_REGPARM void thumbDF(u32 opcode) + { + u32 address = 0; + //clockTicks = codeTicksAccessSeq16(address)*2 + codeTicksAccess16(address)+3; + clockTicks = 3; + busPrefetchCount = 0; + CPUSoftwareInterrupt(opcode & 0xFF); + } + + // B offset + static INSN_REGPARM void thumbE0(u32 opcode) + { + int offset = (opcode & 0x3FF) << 1; + if (opcode & 0x0400) + offset |= 0xFFFFF800; + reg[15].I += offset; + armNextPC = reg[15].I; + reg[15].I += 2; + THUMB_PREFETCH; + clockTicks = codeTicksAccessSeq16(armNextPC) * 2 + codeTicksAccess16(armNextPC) + 3; + busPrefetchCount = 0; + } + + // BLL #offset (forward) + static INSN_REGPARM void thumbF0(u32 opcode) + { + int offset = (opcode & 0x7FF); + reg[14].I = reg[15].I + (offset << 12); + clockTicks = codeTicksAccessSeq16(armNextPC) + 1; + } + + // BLL #offset (backward) + static INSN_REGPARM void thumbF4(u32 opcode) + { + int offset = (opcode & 0x7FF); + reg[14].I = reg[15].I + ((offset << 12) | 0xFF800000); + clockTicks = codeTicksAccessSeq16(armNextPC) + 1; + } + + // BLH #offset + static INSN_REGPARM void thumbF8(u32 opcode) + { + int offset = (opcode & 0x7FF); + u32 temp = reg[15].I - 2; + reg[15].I = (reg[14].I + (offset << 1)) & 0xFFFFFFFE; + armNextPC = reg[15].I; + reg[15].I += 2; + reg[14].I = temp | 1; + THUMB_PREFETCH; + clockTicks = codeTicksAccessSeq16(armNextPC) * 2 + codeTicksAccess16(armNextPC) + 3; + busPrefetchCount = 0; + } + + // Instruction table ////////////////////////////////////////////////////// + + typedef INSN_REGPARM void (*insnfunc_t)(u32 opcode); #define thumbUI thumbUnknownInsn #ifdef BKPT_SUPPORT - #define thumbBP thumbBreakpoint +#define thumbBP thumbBreakpoint #else - #define thumbBP thumbUnknownInsn +#define thumbBP thumbUnknownInsn #endif -static insnfunc_t thumbInsnTable[1024] = { - thumb00_00,thumb00_01,thumb00_02,thumb00_03,thumb00_04,thumb00_05,thumb00_06,thumb00_07, // 00 - thumb00_08,thumb00_09,thumb00_0A,thumb00_0B,thumb00_0C,thumb00_0D,thumb00_0E,thumb00_0F, - thumb00_10,thumb00_11,thumb00_12,thumb00_13,thumb00_14,thumb00_15,thumb00_16,thumb00_17, - thumb00_18,thumb00_19,thumb00_1A,thumb00_1B,thumb00_1C,thumb00_1D,thumb00_1E,thumb00_1F, - thumb08_00,thumb08_01,thumb08_02,thumb08_03,thumb08_04,thumb08_05,thumb08_06,thumb08_07, // 08 - thumb08_08,thumb08_09,thumb08_0A,thumb08_0B,thumb08_0C,thumb08_0D,thumb08_0E,thumb08_0F, - thumb08_10,thumb08_11,thumb08_12,thumb08_13,thumb08_14,thumb08_15,thumb08_16,thumb08_17, - thumb08_18,thumb08_19,thumb08_1A,thumb08_1B,thumb08_1C,thumb08_1D,thumb08_1E,thumb08_1F, - thumb10_00,thumb10_01,thumb10_02,thumb10_03,thumb10_04,thumb10_05,thumb10_06,thumb10_07, // 10 - thumb10_08,thumb10_09,thumb10_0A,thumb10_0B,thumb10_0C,thumb10_0D,thumb10_0E,thumb10_0F, - thumb10_10,thumb10_11,thumb10_12,thumb10_13,thumb10_14,thumb10_15,thumb10_16,thumb10_17, - thumb10_18,thumb10_19,thumb10_1A,thumb10_1B,thumb10_1C,thumb10_1D,thumb10_1E,thumb10_1F, - thumb18_0,thumb18_1,thumb18_2,thumb18_3,thumb18_4,thumb18_5,thumb18_6,thumb18_7, // 18 - thumb1A_0,thumb1A_1,thumb1A_2,thumb1A_3,thumb1A_4,thumb1A_5,thumb1A_6,thumb1A_7, - thumb1C_0,thumb1C_1,thumb1C_2,thumb1C_3,thumb1C_4,thumb1C_5,thumb1C_6,thumb1C_7, - thumb1E_0,thumb1E_1,thumb1E_2,thumb1E_3,thumb1E_4,thumb1E_5,thumb1E_6,thumb1E_7, - thumb20,thumb20,thumb20,thumb20,thumb21,thumb21,thumb21,thumb21, // 20 - thumb22,thumb22,thumb22,thumb22,thumb23,thumb23,thumb23,thumb23, - thumb24,thumb24,thumb24,thumb24,thumb25,thumb25,thumb25,thumb25, - thumb26,thumb26,thumb26,thumb26,thumb27,thumb27,thumb27,thumb27, - thumb28,thumb28,thumb28,thumb28,thumb29,thumb29,thumb29,thumb29, // 28 - thumb2A,thumb2A,thumb2A,thumb2A,thumb2B,thumb2B,thumb2B,thumb2B, - thumb2C,thumb2C,thumb2C,thumb2C,thumb2D,thumb2D,thumb2D,thumb2D, - thumb2E,thumb2E,thumb2E,thumb2E,thumb2F,thumb2F,thumb2F,thumb2F, - thumb30,thumb30,thumb30,thumb30,thumb31,thumb31,thumb31,thumb31, // 30 - thumb32,thumb32,thumb32,thumb32,thumb33,thumb33,thumb33,thumb33, - thumb34,thumb34,thumb34,thumb34,thumb35,thumb35,thumb35,thumb35, - thumb36,thumb36,thumb36,thumb36,thumb37,thumb37,thumb37,thumb37, - thumb38,thumb38,thumb38,thumb38,thumb39,thumb39,thumb39,thumb39, // 38 - thumb3A,thumb3A,thumb3A,thumb3A,thumb3B,thumb3B,thumb3B,thumb3B, - thumb3C,thumb3C,thumb3C,thumb3C,thumb3D,thumb3D,thumb3D,thumb3D, - thumb3E,thumb3E,thumb3E,thumb3E,thumb3F,thumb3F,thumb3F,thumb3F, - thumb40_0,thumb40_1,thumb40_2,thumb40_3,thumb41_0,thumb41_1,thumb41_2,thumb41_3, // 40 - thumb42_0,thumb42_1,thumb42_2,thumb42_3,thumb43_0,thumb43_1,thumb43_2,thumb43_3, - thumbUI,thumb44_1,thumb44_2,thumb44_3,thumbUI,thumb45_1,thumb45_2,thumb45_3, - thumb46_0,thumb46_1,thumb46_2,thumb46_3,thumb47,thumb47,thumbUI,thumbUI, - thumb48,thumb48,thumb48,thumb48,thumb48,thumb48,thumb48,thumb48, // 48 - thumb48,thumb48,thumb48,thumb48,thumb48,thumb48,thumb48,thumb48, - thumb48,thumb48,thumb48,thumb48,thumb48,thumb48,thumb48,thumb48, - thumb48,thumb48,thumb48,thumb48,thumb48,thumb48,thumb48,thumb48, - thumb50,thumb50,thumb50,thumb50,thumb50,thumb50,thumb50,thumb50, // 50 - thumb52,thumb52,thumb52,thumb52,thumb52,thumb52,thumb52,thumb52, - thumb54,thumb54,thumb54,thumb54,thumb54,thumb54,thumb54,thumb54, - thumb56,thumb56,thumb56,thumb56,thumb56,thumb56,thumb56,thumb56, - thumb58,thumb58,thumb58,thumb58,thumb58,thumb58,thumb58,thumb58, // 58 - thumb5A,thumb5A,thumb5A,thumb5A,thumb5A,thumb5A,thumb5A,thumb5A, - thumb5C,thumb5C,thumb5C,thumb5C,thumb5C,thumb5C,thumb5C,thumb5C, - thumb5E,thumb5E,thumb5E,thumb5E,thumb5E,thumb5E,thumb5E,thumb5E, - thumb60,thumb60,thumb60,thumb60,thumb60,thumb60,thumb60,thumb60, // 60 - thumb60,thumb60,thumb60,thumb60,thumb60,thumb60,thumb60,thumb60, - thumb60,thumb60,thumb60,thumb60,thumb60,thumb60,thumb60,thumb60, - thumb60,thumb60,thumb60,thumb60,thumb60,thumb60,thumb60,thumb60, - thumb68,thumb68,thumb68,thumb68,thumb68,thumb68,thumb68,thumb68, // 68 - thumb68,thumb68,thumb68,thumb68,thumb68,thumb68,thumb68,thumb68, - thumb68,thumb68,thumb68,thumb68,thumb68,thumb68,thumb68,thumb68, - thumb68,thumb68,thumb68,thumb68,thumb68,thumb68,thumb68,thumb68, - thumb70,thumb70,thumb70,thumb70,thumb70,thumb70,thumb70,thumb70, // 70 - thumb70,thumb70,thumb70,thumb70,thumb70,thumb70,thumb70,thumb70, - thumb70,thumb70,thumb70,thumb70,thumb70,thumb70,thumb70,thumb70, - thumb70,thumb70,thumb70,thumb70,thumb70,thumb70,thumb70,thumb70, - thumb78,thumb78,thumb78,thumb78,thumb78,thumb78,thumb78,thumb78, // 78 - thumb78,thumb78,thumb78,thumb78,thumb78,thumb78,thumb78,thumb78, - thumb78,thumb78,thumb78,thumb78,thumb78,thumb78,thumb78,thumb78, - thumb78,thumb78,thumb78,thumb78,thumb78,thumb78,thumb78,thumb78, - thumb80,thumb80,thumb80,thumb80,thumb80,thumb80,thumb80,thumb80, // 80 - thumb80,thumb80,thumb80,thumb80,thumb80,thumb80,thumb80,thumb80, - thumb80,thumb80,thumb80,thumb80,thumb80,thumb80,thumb80,thumb80, - thumb80,thumb80,thumb80,thumb80,thumb80,thumb80,thumb80,thumb80, - thumb88,thumb88,thumb88,thumb88,thumb88,thumb88,thumb88,thumb88, // 88 - thumb88,thumb88,thumb88,thumb88,thumb88,thumb88,thumb88,thumb88, - thumb88,thumb88,thumb88,thumb88,thumb88,thumb88,thumb88,thumb88, - thumb88,thumb88,thumb88,thumb88,thumb88,thumb88,thumb88,thumb88, - thumb90,thumb90,thumb90,thumb90,thumb90,thumb90,thumb90,thumb90, // 90 - thumb90,thumb90,thumb90,thumb90,thumb90,thumb90,thumb90,thumb90, - thumb90,thumb90,thumb90,thumb90,thumb90,thumb90,thumb90,thumb90, - thumb90,thumb90,thumb90,thumb90,thumb90,thumb90,thumb90,thumb90, - thumb98,thumb98,thumb98,thumb98,thumb98,thumb98,thumb98,thumb98, // 98 - thumb98,thumb98,thumb98,thumb98,thumb98,thumb98,thumb98,thumb98, - thumb98,thumb98,thumb98,thumb98,thumb98,thumb98,thumb98,thumb98, - thumb98,thumb98,thumb98,thumb98,thumb98,thumb98,thumb98,thumb98, - thumbA0,thumbA0,thumbA0,thumbA0,thumbA0,thumbA0,thumbA0,thumbA0, // A0 - thumbA0,thumbA0,thumbA0,thumbA0,thumbA0,thumbA0,thumbA0,thumbA0, - thumbA0,thumbA0,thumbA0,thumbA0,thumbA0,thumbA0,thumbA0,thumbA0, - thumbA0,thumbA0,thumbA0,thumbA0,thumbA0,thumbA0,thumbA0,thumbA0, - thumbA8,thumbA8,thumbA8,thumbA8,thumbA8,thumbA8,thumbA8,thumbA8, // A8 - thumbA8,thumbA8,thumbA8,thumbA8,thumbA8,thumbA8,thumbA8,thumbA8, - thumbA8,thumbA8,thumbA8,thumbA8,thumbA8,thumbA8,thumbA8,thumbA8, - thumbA8,thumbA8,thumbA8,thumbA8,thumbA8,thumbA8,thumbA8,thumbA8, - thumbB0,thumbB0,thumbB0,thumbB0,thumbUI,thumbUI,thumbUI,thumbUI, // B0 - thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,thumbUI, - thumbB4,thumbB4,thumbB4,thumbB4,thumbB5,thumbB5,thumbB5,thumbB5, - thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,thumbUI, - thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,thumbUI, // B8 - thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,thumbUI, - thumbBC,thumbBC,thumbBC,thumbBC,thumbBD,thumbBD,thumbBD,thumbBD, - thumbBP,thumbBP,thumbBP,thumbBP,thumbUI,thumbUI,thumbUI,thumbUI, - thumbC0,thumbC0,thumbC0,thumbC0,thumbC0,thumbC0,thumbC0,thumbC0, // C0 - thumbC0,thumbC0,thumbC0,thumbC0,thumbC0,thumbC0,thumbC0,thumbC0, - thumbC0,thumbC0,thumbC0,thumbC0,thumbC0,thumbC0,thumbC0,thumbC0, - thumbC0,thumbC0,thumbC0,thumbC0,thumbC0,thumbC0,thumbC0,thumbC0, - thumbC8,thumbC8,thumbC8,thumbC8,thumbC8,thumbC8,thumbC8,thumbC8, // C8 - thumbC8,thumbC8,thumbC8,thumbC8,thumbC8,thumbC8,thumbC8,thumbC8, - thumbC8,thumbC8,thumbC8,thumbC8,thumbC8,thumbC8,thumbC8,thumbC8, - thumbC8,thumbC8,thumbC8,thumbC8,thumbC8,thumbC8,thumbC8,thumbC8, - thumbD0,thumbD0,thumbD0,thumbD0,thumbD1,thumbD1,thumbD1,thumbD1, // D0 - thumbD2,thumbD2,thumbD2,thumbD2,thumbD3,thumbD3,thumbD3,thumbD3, - thumbD4,thumbD4,thumbD4,thumbD4,thumbD5,thumbD5,thumbD5,thumbD5, - thumbD6,thumbD6,thumbD6,thumbD6,thumbD7,thumbD7,thumbD7,thumbD7, - thumbD8,thumbD8,thumbD8,thumbD8,thumbD9,thumbD9,thumbD9,thumbD9, // D8 - thumbDA,thumbDA,thumbDA,thumbDA,thumbDB,thumbDB,thumbDB,thumbDB, - thumbDC,thumbDC,thumbDC,thumbDC,thumbDD,thumbDD,thumbDD,thumbDD, - thumbUI,thumbUI,thumbUI,thumbUI,thumbDF,thumbDF,thumbDF,thumbDF, - thumbE0,thumbE0,thumbE0,thumbE0,thumbE0,thumbE0,thumbE0,thumbE0, // E0 - thumbE0,thumbE0,thumbE0,thumbE0,thumbE0,thumbE0,thumbE0,thumbE0, - thumbE0,thumbE0,thumbE0,thumbE0,thumbE0,thumbE0,thumbE0,thumbE0, - thumbE0,thumbE0,thumbE0,thumbE0,thumbE0,thumbE0,thumbE0,thumbE0, - thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,thumbUI, // E8 - thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,thumbUI, - thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,thumbUI, - thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,thumbUI, - thumbF0,thumbF0,thumbF0,thumbF0,thumbF0,thumbF0,thumbF0,thumbF0, // F0 - thumbF0,thumbF0,thumbF0,thumbF0,thumbF0,thumbF0,thumbF0,thumbF0, - thumbF4,thumbF4,thumbF4,thumbF4,thumbF4,thumbF4,thumbF4,thumbF4, - thumbF4,thumbF4,thumbF4,thumbF4,thumbF4,thumbF4,thumbF4,thumbF4, - thumbF8,thumbF8,thumbF8,thumbF8,thumbF8,thumbF8,thumbF8,thumbF8, // F8 - thumbF8,thumbF8,thumbF8,thumbF8,thumbF8,thumbF8,thumbF8,thumbF8, - thumbF8,thumbF8,thumbF8,thumbF8,thumbF8,thumbF8,thumbF8,thumbF8, - thumbF8,thumbF8,thumbF8,thumbF8,thumbF8,thumbF8,thumbF8,thumbF8, -}; + static insnfunc_t thumbInsnTable[1024] = { + thumb00_00, thumb00_01, thumb00_02, thumb00_03, thumb00_04, thumb00_05, thumb00_06, thumb00_07, // 00 + thumb00_08, thumb00_09, thumb00_0A, thumb00_0B, thumb00_0C, thumb00_0D, thumb00_0E, thumb00_0F, + thumb00_10, thumb00_11, thumb00_12, thumb00_13, thumb00_14, thumb00_15, thumb00_16, thumb00_17, + thumb00_18, thumb00_19, thumb00_1A, thumb00_1B, thumb00_1C, thumb00_1D, thumb00_1E, thumb00_1F, + thumb08_00, thumb08_01, thumb08_02, thumb08_03, thumb08_04, thumb08_05, thumb08_06, thumb08_07, // 08 + thumb08_08, thumb08_09, thumb08_0A, thumb08_0B, thumb08_0C, thumb08_0D, thumb08_0E, thumb08_0F, + thumb08_10, thumb08_11, thumb08_12, thumb08_13, thumb08_14, thumb08_15, thumb08_16, thumb08_17, + thumb08_18, thumb08_19, thumb08_1A, thumb08_1B, thumb08_1C, thumb08_1D, thumb08_1E, thumb08_1F, + thumb10_00, thumb10_01, thumb10_02, thumb10_03, thumb10_04, thumb10_05, thumb10_06, thumb10_07, // 10 + thumb10_08, thumb10_09, thumb10_0A, thumb10_0B, thumb10_0C, thumb10_0D, thumb10_0E, thumb10_0F, + thumb10_10, thumb10_11, thumb10_12, thumb10_13, thumb10_14, thumb10_15, thumb10_16, thumb10_17, + thumb10_18, thumb10_19, thumb10_1A, thumb10_1B, thumb10_1C, thumb10_1D, thumb10_1E, thumb10_1F, + thumb18_0, thumb18_1, thumb18_2, thumb18_3, thumb18_4, thumb18_5, thumb18_6, thumb18_7, // 18 + thumb1A_0, thumb1A_1, thumb1A_2, thumb1A_3, thumb1A_4, thumb1A_5, thumb1A_6, thumb1A_7, + thumb1C_0, thumb1C_1, thumb1C_2, thumb1C_3, thumb1C_4, thumb1C_5, thumb1C_6, thumb1C_7, + thumb1E_0, thumb1E_1, thumb1E_2, thumb1E_3, thumb1E_4, thumb1E_5, thumb1E_6, thumb1E_7, + thumb20, thumb20, thumb20, thumb20, thumb21, thumb21, thumb21, thumb21, // 20 + thumb22, thumb22, thumb22, thumb22, thumb23, thumb23, thumb23, thumb23, + thumb24, thumb24, thumb24, thumb24, thumb25, thumb25, thumb25, thumb25, + thumb26, thumb26, thumb26, thumb26, thumb27, thumb27, thumb27, thumb27, + thumb28, thumb28, thumb28, thumb28, thumb29, thumb29, thumb29, thumb29, // 28 + thumb2A, thumb2A, thumb2A, thumb2A, thumb2B, thumb2B, thumb2B, thumb2B, + thumb2C, thumb2C, thumb2C, thumb2C, thumb2D, thumb2D, thumb2D, thumb2D, + thumb2E, thumb2E, thumb2E, thumb2E, thumb2F, thumb2F, thumb2F, thumb2F, + thumb30, thumb30, thumb30, thumb30, thumb31, thumb31, thumb31, thumb31, // 30 + thumb32, thumb32, thumb32, thumb32, thumb33, thumb33, thumb33, thumb33, + thumb34, thumb34, thumb34, thumb34, thumb35, thumb35, thumb35, thumb35, + thumb36, thumb36, thumb36, thumb36, thumb37, thumb37, thumb37, thumb37, + thumb38, thumb38, thumb38, thumb38, thumb39, thumb39, thumb39, thumb39, // 38 + thumb3A, thumb3A, thumb3A, thumb3A, thumb3B, thumb3B, thumb3B, thumb3B, + thumb3C, thumb3C, thumb3C, thumb3C, thumb3D, thumb3D, thumb3D, thumb3D, + thumb3E, thumb3E, thumb3E, thumb3E, thumb3F, thumb3F, thumb3F, thumb3F, + thumb40_0, thumb40_1, thumb40_2, thumb40_3, thumb41_0, thumb41_1, thumb41_2, thumb41_3, // 40 + thumb42_0, thumb42_1, thumb42_2, thumb42_3, thumb43_0, thumb43_1, thumb43_2, thumb43_3, + thumbUI, thumb44_1, thumb44_2, thumb44_3, thumbUI, thumb45_1, thumb45_2, thumb45_3, + thumb46_0, thumb46_1, thumb46_2, thumb46_3, thumb47, thumb47, thumbUI, thumbUI, + thumb48, thumb48, thumb48, thumb48, thumb48, thumb48, thumb48, thumb48, // 48 + thumb48, thumb48, thumb48, thumb48, thumb48, thumb48, thumb48, thumb48, + thumb48, thumb48, thumb48, thumb48, thumb48, thumb48, thumb48, thumb48, + thumb48, thumb48, thumb48, thumb48, thumb48, thumb48, thumb48, thumb48, + thumb50, thumb50, thumb50, thumb50, thumb50, thumb50, thumb50, thumb50, // 50 + thumb52, thumb52, thumb52, thumb52, thumb52, thumb52, thumb52, thumb52, + thumb54, thumb54, thumb54, thumb54, thumb54, thumb54, thumb54, thumb54, + thumb56, thumb56, thumb56, thumb56, thumb56, thumb56, thumb56, thumb56, + thumb58, thumb58, thumb58, thumb58, thumb58, thumb58, thumb58, thumb58, // 58 + thumb5A, thumb5A, thumb5A, thumb5A, thumb5A, thumb5A, thumb5A, thumb5A, + thumb5C, thumb5C, thumb5C, thumb5C, thumb5C, thumb5C, thumb5C, thumb5C, + thumb5E, thumb5E, thumb5E, thumb5E, thumb5E, thumb5E, thumb5E, thumb5E, + thumb60, thumb60, thumb60, thumb60, thumb60, thumb60, thumb60, thumb60, // 60 + thumb60, thumb60, thumb60, thumb60, thumb60, thumb60, thumb60, thumb60, + thumb60, thumb60, thumb60, thumb60, thumb60, thumb60, thumb60, thumb60, + thumb60, thumb60, thumb60, thumb60, thumb60, thumb60, thumb60, thumb60, + thumb68, thumb68, thumb68, thumb68, thumb68, thumb68, thumb68, thumb68, // 68 + thumb68, thumb68, thumb68, thumb68, thumb68, thumb68, thumb68, thumb68, + thumb68, thumb68, thumb68, thumb68, thumb68, thumb68, thumb68, thumb68, + thumb68, thumb68, thumb68, thumb68, thumb68, thumb68, thumb68, thumb68, + thumb70, thumb70, thumb70, thumb70, thumb70, thumb70, thumb70, thumb70, // 70 + thumb70, thumb70, thumb70, thumb70, thumb70, thumb70, thumb70, thumb70, + thumb70, thumb70, thumb70, thumb70, thumb70, thumb70, thumb70, thumb70, + thumb70, thumb70, thumb70, thumb70, thumb70, thumb70, thumb70, thumb70, + thumb78, thumb78, thumb78, thumb78, thumb78, thumb78, thumb78, thumb78, // 78 + thumb78, thumb78, thumb78, thumb78, thumb78, thumb78, thumb78, thumb78, + thumb78, thumb78, thumb78, thumb78, thumb78, thumb78, thumb78, thumb78, + thumb78, thumb78, thumb78, thumb78, thumb78, thumb78, thumb78, thumb78, + thumb80, thumb80, thumb80, thumb80, thumb80, thumb80, thumb80, thumb80, // 80 + thumb80, thumb80, thumb80, thumb80, thumb80, thumb80, thumb80, thumb80, + thumb80, thumb80, thumb80, thumb80, thumb80, thumb80, thumb80, thumb80, + thumb80, thumb80, thumb80, thumb80, thumb80, thumb80, thumb80, thumb80, + thumb88, thumb88, thumb88, thumb88, thumb88, thumb88, thumb88, thumb88, // 88 + thumb88, thumb88, thumb88, thumb88, thumb88, thumb88, thumb88, thumb88, + thumb88, thumb88, thumb88, thumb88, thumb88, thumb88, thumb88, thumb88, + thumb88, thumb88, thumb88, thumb88, thumb88, thumb88, thumb88, thumb88, + thumb90, thumb90, thumb90, thumb90, thumb90, thumb90, thumb90, thumb90, // 90 + thumb90, thumb90, thumb90, thumb90, thumb90, thumb90, thumb90, thumb90, + thumb90, thumb90, thumb90, thumb90, thumb90, thumb90, thumb90, thumb90, + thumb90, thumb90, thumb90, thumb90, thumb90, thumb90, thumb90, thumb90, + thumb98, thumb98, thumb98, thumb98, thumb98, thumb98, thumb98, thumb98, // 98 + thumb98, thumb98, thumb98, thumb98, thumb98, thumb98, thumb98, thumb98, + thumb98, thumb98, thumb98, thumb98, thumb98, thumb98, thumb98, thumb98, + thumb98, thumb98, thumb98, thumb98, thumb98, thumb98, thumb98, thumb98, + thumbA0, thumbA0, thumbA0, thumbA0, thumbA0, thumbA0, thumbA0, thumbA0, // A0 + thumbA0, thumbA0, thumbA0, thumbA0, thumbA0, thumbA0, thumbA0, thumbA0, + thumbA0, thumbA0, thumbA0, thumbA0, thumbA0, thumbA0, thumbA0, thumbA0, + thumbA0, thumbA0, thumbA0, thumbA0, thumbA0, thumbA0, thumbA0, thumbA0, + thumbA8, thumbA8, thumbA8, thumbA8, thumbA8, thumbA8, thumbA8, thumbA8, // A8 + thumbA8, thumbA8, thumbA8, thumbA8, thumbA8, thumbA8, thumbA8, thumbA8, + thumbA8, thumbA8, thumbA8, thumbA8, thumbA8, thumbA8, thumbA8, thumbA8, + thumbA8, thumbA8, thumbA8, thumbA8, thumbA8, thumbA8, thumbA8, thumbA8, + thumbB0, thumbB0, thumbB0, thumbB0, thumbUI, thumbUI, thumbUI, thumbUI, // B0 + thumbUI, thumbUI, thumbUI, thumbUI, thumbUI, thumbUI, thumbUI, thumbUI, + thumbB4, thumbB4, thumbB4, thumbB4, thumbB5, thumbB5, thumbB5, thumbB5, + thumbUI, thumbUI, thumbUI, thumbUI, thumbUI, thumbUI, thumbUI, thumbUI, + thumbUI, thumbUI, thumbUI, thumbUI, thumbUI, thumbUI, thumbUI, thumbUI, // B8 + thumbUI, thumbUI, thumbUI, thumbUI, thumbUI, thumbUI, thumbUI, thumbUI, + thumbBC, thumbBC, thumbBC, thumbBC, thumbBD, thumbBD, thumbBD, thumbBD, + thumbBP, thumbBP, thumbBP, thumbBP, thumbUI, thumbUI, thumbUI, thumbUI, + thumbC0, thumbC0, thumbC0, thumbC0, thumbC0, thumbC0, thumbC0, thumbC0, // C0 + thumbC0, thumbC0, thumbC0, thumbC0, thumbC0, thumbC0, thumbC0, thumbC0, + thumbC0, thumbC0, thumbC0, thumbC0, thumbC0, thumbC0, thumbC0, thumbC0, + thumbC0, thumbC0, thumbC0, thumbC0, thumbC0, thumbC0, thumbC0, thumbC0, + thumbC8, thumbC8, thumbC8, thumbC8, thumbC8, thumbC8, thumbC8, thumbC8, // C8 + thumbC8, thumbC8, thumbC8, thumbC8, thumbC8, thumbC8, thumbC8, thumbC8, + thumbC8, thumbC8, thumbC8, thumbC8, thumbC8, thumbC8, thumbC8, thumbC8, + thumbC8, thumbC8, thumbC8, thumbC8, thumbC8, thumbC8, thumbC8, thumbC8, + thumbD0, thumbD0, thumbD0, thumbD0, thumbD1, thumbD1, thumbD1, thumbD1, // D0 + thumbD2, thumbD2, thumbD2, thumbD2, thumbD3, thumbD3, thumbD3, thumbD3, + thumbD4, thumbD4, thumbD4, thumbD4, thumbD5, thumbD5, thumbD5, thumbD5, + thumbD6, thumbD6, thumbD6, thumbD6, thumbD7, thumbD7, thumbD7, thumbD7, + thumbD8, thumbD8, thumbD8, thumbD8, thumbD9, thumbD9, thumbD9, thumbD9, // D8 + thumbDA, thumbDA, thumbDA, thumbDA, thumbDB, thumbDB, thumbDB, thumbDB, + thumbDC, thumbDC, thumbDC, thumbDC, thumbDD, thumbDD, thumbDD, thumbDD, + thumbUI, thumbUI, thumbUI, thumbUI, thumbDF, thumbDF, thumbDF, thumbDF, + thumbE0, thumbE0, thumbE0, thumbE0, thumbE0, thumbE0, thumbE0, thumbE0, // E0 + thumbE0, thumbE0, thumbE0, thumbE0, thumbE0, thumbE0, thumbE0, thumbE0, + thumbE0, thumbE0, thumbE0, thumbE0, thumbE0, thumbE0, thumbE0, thumbE0, + thumbE0, thumbE0, thumbE0, thumbE0, thumbE0, thumbE0, thumbE0, thumbE0, + thumbUI, thumbUI, thumbUI, thumbUI, thumbUI, thumbUI, thumbUI, thumbUI, // E8 + thumbUI, thumbUI, thumbUI, thumbUI, thumbUI, thumbUI, thumbUI, thumbUI, + thumbUI, thumbUI, thumbUI, thumbUI, thumbUI, thumbUI, thumbUI, thumbUI, + thumbUI, thumbUI, thumbUI, thumbUI, thumbUI, thumbUI, thumbUI, thumbUI, + thumbF0, thumbF0, thumbF0, thumbF0, thumbF0, thumbF0, thumbF0, thumbF0, // F0 + thumbF0, thumbF0, thumbF0, thumbF0, thumbF0, thumbF0, thumbF0, thumbF0, + thumbF4, thumbF4, thumbF4, thumbF4, thumbF4, thumbF4, thumbF4, thumbF4, + thumbF4, thumbF4, thumbF4, thumbF4, thumbF4, thumbF4, thumbF4, thumbF4, + thumbF8, thumbF8, thumbF8, thumbF8, thumbF8, thumbF8, thumbF8, thumbF8, // F8 + thumbF8, thumbF8, thumbF8, thumbF8, thumbF8, thumbF8, thumbF8, thumbF8, + thumbF8, thumbF8, thumbF8, thumbF8, thumbF8, thumbF8, thumbF8, thumbF8, + thumbF8, thumbF8, thumbF8, thumbF8, thumbF8, thumbF8, thumbF8, thumbF8, + }; -// Wrapper routine (execution loop) /////////////////////////////////////// + // Wrapper routine (execution loop) /////////////////////////////////////// -int thumbExecute() -{ - do { - if( cheatsEnabled ) { - cpuMasterCodeCheck(); - } + int thumbExecute() + { + do { + if (cheatsEnabled) { + cpuMasterCodeCheck(); + } - //if ((armNextPC & 0x0803FFFF) == 0x08020000) - // busPrefetchCount=0x100; + //if ((armNextPC & 0x0803FFFF) == 0x08020000) + // busPrefetchCount=0x100; - u32 opcode = cpuPrefetch[0]; - cpuPrefetch[0] = cpuPrefetch[1]; + u32 opcode = cpuPrefetch[0]; + cpuPrefetch[0] = cpuPrefetch[1]; - busPrefetch = false; - if (busPrefetchCount & 0xFFFFFF00) - busPrefetchCount = 0x100 | (busPrefetchCount & 0xFF); - clockTicks = 0; - u32 oldArmNextPC = armNextPC; + busPrefetch = false; + if (busPrefetchCount & 0xFFFFFF00) + busPrefetchCount = 0x100 | (busPrefetchCount & 0xFF); + clockTicks = 0; + u32 oldArmNextPC = armNextPC; #ifndef FINAL_VERSION - if(armNextPC == stop) { - armNextPC++; - } + if (armNextPC == stop) { + armNextPC++; + } #endif - armNextPC = reg[15].I; - reg[15].I += 2; - THUMB_PREFETCH_NEXT; + armNextPC = reg[15].I; + reg[15].I += 2; + THUMB_PREFETCH_NEXT; #ifdef BKPT_SUPPORT - u32 memAddr = armNextPC; - memoryMap *m = &map[memAddr >> 24]; - if (m->breakPoints && BreakThumbCheck(m->breakPoints, memAddr & m->mask)) { - if (debuggerBreakOnExecution(memAddr, armState)){ - // Revert tickcount? - debugger = true; - return 0 ; - } - } + u32 memAddr = armNextPC; + memoryMap* m = &map[memAddr >> 24]; + if (m->breakPoints && BreakThumbCheck(m->breakPoints, memAddr & m->mask)) { + if (debuggerBreakOnExecution(memAddr, armState)) { + // Revert tickcount? + debugger = true; + return 0; + } + } #endif - (*thumbInsnTable[opcode>>6])(opcode); - + (*thumbInsnTable[opcode >> 6])(opcode); #ifdef BKPT_SUPPORT - if (enableRegBreak){ - if (lowRegBreakCounter[0]) - breakReg_check(0); - if (lowRegBreakCounter[1]) - breakReg_check(1); - if (lowRegBreakCounter[2]) - breakReg_check(2); - if (lowRegBreakCounter[3]) - breakReg_check(3); - if (medRegBreakCounter[0]) - breakReg_check(4); - if (medRegBreakCounter[1]) - breakReg_check(5); - if (medRegBreakCounter[2]) - breakReg_check(6); - if (medRegBreakCounter[3]) - breakReg_check(7); - if (highRegBreakCounter[0]) - breakReg_check(8); - if (highRegBreakCounter[1]) - breakReg_check(9); - if (highRegBreakCounter[2]) - breakReg_check(10); - if (highRegBreakCounter[3]) - breakReg_check(11); - if (statusRegBreakCounter[0]) - breakReg_check(12); - if (statusRegBreakCounter[1]) - breakReg_check(13); - if (statusRegBreakCounter[2]) - breakReg_check(14); - if (statusRegBreakCounter[3]) - breakReg_check(15); - } + if (enableRegBreak) { + if (lowRegBreakCounter[0]) + breakReg_check(0); + if (lowRegBreakCounter[1]) + breakReg_check(1); + if (lowRegBreakCounter[2]) + breakReg_check(2); + if (lowRegBreakCounter[3]) + breakReg_check(3); + if (medRegBreakCounter[0]) + breakReg_check(4); + if (medRegBreakCounter[1]) + breakReg_check(5); + if (medRegBreakCounter[2]) + breakReg_check(6); + if (medRegBreakCounter[3]) + breakReg_check(7); + if (highRegBreakCounter[0]) + breakReg_check(8); + if (highRegBreakCounter[1]) + breakReg_check(9); + if (highRegBreakCounter[2]) + breakReg_check(10); + if (highRegBreakCounter[3]) + breakReg_check(11); + if (statusRegBreakCounter[0]) + breakReg_check(12); + if (statusRegBreakCounter[1]) + breakReg_check(13); + if (statusRegBreakCounter[2]) + breakReg_check(14); + if (statusRegBreakCounter[3]) + breakReg_check(15); + } #endif - if (clockTicks < 0) - return 0; - if (clockTicks==0) - clockTicks = codeTicksAccessSeq16(oldArmNextPC) + 1; - cpuTotalTicks += clockTicks; + if (clockTicks < 0) + return 0; + if (clockTicks == 0) + clockTicks = codeTicksAccessSeq16(oldArmNextPC) + 1; + cpuTotalTicks += clockTicks; - } while (cpuTotalTicks < cpuNextEvent && !armState && !holdState && !SWITicks && !debugger); - return 1; -} + } while (cpuTotalTicks < cpuNextEvent && !armState && !holdState && !SWITicks && !debugger); + return 1; + } diff --git a/src/gba/GBA.cpp b/src/gba/GBA.cpp index 291020e4..62fe0970 100644 --- a/src/gba/GBA.cpp +++ b/src/gba/GBA.cpp @@ -1,32 +1,32 @@ -#include -#include -#include #include #include +#include +#include +#include #include #ifndef _MSC_VER #include #endif +#include "../NLS.h" +#include "../System.h" +#include "../Util.h" +#include "../common/ConfigManager.h" +#include "../common/Port.h" +#include "Cheats.h" +#include "EEprom.h" +#include "Flash.h" #include "GBA.h" +#include "GBAGfx.h" +#include "GBALink.h" #include "GBAcpu.h" #include "GBAinline.h" #include "Globals.h" -#include "GBAGfx.h" -#include "EEprom.h" -#include "Flash.h" #include "Sound.h" #include "Sram.h" -#include "bios.h" -#include "Cheats.h" -#include "../NLS.h" -#include "elf.h" -#include "../Util.h" -#include "../common/Port.h" -#include "../common/ConfigManager.h" -#include "../System.h" #include "agbprint.h" +#include "bios.h" +#include "elf.h" #include "ereader.h" -#include "GBALink.h" #ifdef PROFILING #include "prof/prof.h" @@ -72,7 +72,7 @@ int cpuTotalTicks = 0; #ifdef PROFILING int profilingTicks = 0; int profilingTicksReload = 0; -static profile_segment *profilSegment = NULL; +static profile_segment* profilSegment = NULL; #endif #ifdef BKPT_SUPPORT @@ -90,22 +90,22 @@ u16 timer0Value = 0; bool timer0On = false; int timer0Ticks = 0; int timer0Reload = 0; -int timer0ClockReload = 0; +int timer0ClockReload = 0; u16 timer1Value = 0; bool timer1On = false; int timer1Ticks = 0; int timer1Reload = 0; -int timer1ClockReload = 0; +int timer1ClockReload = 0; u16 timer2Value = 0; bool timer2On = false; int timer2Ticks = 0; int timer2Reload = 0; -int timer2ClockReload = 0; +int timer2ClockReload = 0; u16 timer3Value = 0; bool timer3On = false; int timer3Ticks = 0; int timer3Reload = 0; -int timer3ClockReload = 0; +int timer3ClockReload = 0; u32 dma0Source = 0; u32 dma0Dest = 0; u32 dma1Source = 0; @@ -114,7 +114,7 @@ u32 dma2Source = 0; u32 dma2Dest = 0; u32 dma3Source = 0; u32 dma3Dest = 0; -void (*cpuSaveGameFunc)(u32,u8) = flashSaveDecide; +void (*cpuSaveGameFunc)(u32, u8) = flashSaveDecide; void (*renderLine)() = mode0RenderLine; bool fxOn = false; bool windowOn = false; @@ -131,30 +131,25 @@ int armOpcodeCount = 0; int thumbOpcodeCount = 0; const int TIMER_TICKS[4] = { - 0, - 6, - 8, - 10 + 0, + 6, + 8, + 10 }; -const u32 objTilesAddress [3] = {0x010000, 0x014000, 0x014000}; +const u32 objTilesAddress[3] = { 0x010000, 0x014000, 0x014000 }; const u8 gamepakRamWaitState[4] = { 4, 3, 2, 8 }; -const u8 gamepakWaitState[4] = { 4, 3, 2, 8 }; +const u8 gamepakWaitState[4] = { 4, 3, 2, 8 }; const u8 gamepakWaitState0[2] = { 2, 1 }; const u8 gamepakWaitState1[2] = { 4, 1 }; const u8 gamepakWaitState2[2] = { 8, 1 }; -const bool isInRom [16]= - { false, false, false, false, false, false, false, false, +const bool isInRom[16] = { false, false, false, false, false, false, false, false, true, true, true, true, true, true, false, false }; -u8 memoryWait[16] = - { 0, 0, 2, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 0 }; -u8 memoryWait32[16] = - { 0, 0, 5, 0, 0, 1, 1, 0, 7, 7, 9, 9, 13, 13, 4, 0 }; -u8 memoryWaitSeq[16] = - { 0, 0, 2, 0, 0, 0, 0, 0, 2, 2, 4, 4, 8, 8, 4, 0 }; -u8 memoryWaitSeq32[16] = - { 0, 0, 5, 0, 0, 1, 1, 0, 5, 5, 9, 9, 17, 17, 4, 0 }; +u8 memoryWait[16] = { 0, 0, 2, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 0 }; +u8 memoryWait32[16] = { 0, 0, 5, 0, 0, 1, 1, 0, 7, 7, 9, 9, 13, 13, 4, 0 }; +u8 memoryWaitSeq[16] = { 0, 0, 2, 0, 0, 0, 0, 0, 2, 2, 4, 4, 8, 8, 4, 0 }; +u8 memoryWaitSeq32[16] = { 0, 0, 5, 0, 0, 1, 1, 0, 5, 5, 9, 9, 17, 17, 4, 0 }; // The videoMemoryWait constants are used to add some waitstates // if the opcode access video memory data outside of vblank/hblank @@ -163,7 +158,6 @@ u8 memoryWaitSeq32[16] = //const u8 videoMemoryWait[16] = // {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - u8 biosProtected[4]; #ifdef WORDS_BIGENDIAN @@ -171,388 +165,387 @@ bool cpuBiosSwapped = false; #endif u32 myROM[] = { -0xEA000006, -0xEA000093, -0xEA000006, -0x00000000, -0x00000000, -0x00000000, -0xEA000088, -0x00000000, -0xE3A00302, -0xE1A0F000, -0xE92D5800, -0xE55EC002, -0xE28FB03C, -0xE79BC10C, -0xE14FB000, -0xE92D0800, -0xE20BB080, -0xE38BB01F, -0xE129F00B, -0xE92D4004, -0xE1A0E00F, -0xE12FFF1C, -0xE8BD4004, -0xE3A0C0D3, -0xE129F00C, -0xE8BD0800, -0xE169F00B, -0xE8BD5800, -0xE1B0F00E, -0x0000009C, -0x0000009C, -0x0000009C, -0x0000009C, -0x000001F8, -0x000001F0, -0x000000AC, -0x000000A0, -0x000000FC, -0x00000168, -0xE12FFF1E, -0xE1A03000, -0xE1A00001, -0xE1A01003, -0xE2113102, -0x42611000, -0xE033C040, -0x22600000, -0xE1B02001, -0xE15200A0, -0x91A02082, -0x3AFFFFFC, -0xE1500002, -0xE0A33003, -0x20400002, -0xE1320001, -0x11A020A2, -0x1AFFFFF9, -0xE1A01000, -0xE1A00003, -0xE1B0C08C, -0x22600000, -0x42611000, -0xE12FFF1E, -0xE92D0010, -0xE1A0C000, -0xE3A01001, -0xE1500001, -0x81A000A0, -0x81A01081, -0x8AFFFFFB, -0xE1A0000C, -0xE1A04001, -0xE3A03000, -0xE1A02001, -0xE15200A0, -0x91A02082, -0x3AFFFFFC, -0xE1500002, -0xE0A33003, -0x20400002, -0xE1320001, -0x11A020A2, -0x1AFFFFF9, -0xE0811003, -0xE1B010A1, -0xE1510004, -0x3AFFFFEE, -0xE1A00004, -0xE8BD0010, -0xE12FFF1E, -0xE0010090, -0xE1A01741, -0xE2611000, -0xE3A030A9, -0xE0030391, -0xE1A03743, -0xE2833E39, -0xE0030391, -0xE1A03743, -0xE2833C09, -0xE283301C, -0xE0030391, -0xE1A03743, -0xE2833C0F, -0xE28330B6, -0xE0030391, -0xE1A03743, -0xE2833C16, -0xE28330AA, -0xE0030391, -0xE1A03743, -0xE2833A02, -0xE2833081, -0xE0030391, -0xE1A03743, -0xE2833C36, -0xE2833051, -0xE0030391, -0xE1A03743, -0xE2833CA2, -0xE28330F9, -0xE0000093, -0xE1A00840, -0xE12FFF1E, -0xE3A00001, -0xE3A01001, -0xE92D4010, -0xE3A03000, -0xE3A04001, -0xE3500000, -0x1B000004, -0xE5CC3301, -0xEB000002, -0x0AFFFFFC, -0xE8BD4010, -0xE12FFF1E, -0xE3A0C301, -0xE5CC3208, -0xE15C20B8, -0xE0110002, -0x10222000, -0x114C20B8, -0xE5CC4208, -0xE12FFF1E, -0xE92D500F, -0xE3A00301, -0xE1A0E00F, -0xE510F004, -0xE8BD500F, -0xE25EF004, -0xE59FD044, -0xE92D5000, -0xE14FC000, -0xE10FE000, -0xE92D5000, -0xE3A0C302, -0xE5DCE09C, -0xE35E00A5, -0x1A000004, -0x05DCE0B4, -0x021EE080, -0xE28FE004, -0x159FF018, -0x059FF018, -0xE59FD018, -0xE8BD5000, -0xE169F00C, -0xE8BD5000, -0xE25EF004, -0x03007FF0, -0x09FE2000, -0x09FFC000, -0x03007FE0 + 0xEA000006, + 0xEA000093, + 0xEA000006, + 0x00000000, + 0x00000000, + 0x00000000, + 0xEA000088, + 0x00000000, + 0xE3A00302, + 0xE1A0F000, + 0xE92D5800, + 0xE55EC002, + 0xE28FB03C, + 0xE79BC10C, + 0xE14FB000, + 0xE92D0800, + 0xE20BB080, + 0xE38BB01F, + 0xE129F00B, + 0xE92D4004, + 0xE1A0E00F, + 0xE12FFF1C, + 0xE8BD4004, + 0xE3A0C0D3, + 0xE129F00C, + 0xE8BD0800, + 0xE169F00B, + 0xE8BD5800, + 0xE1B0F00E, + 0x0000009C, + 0x0000009C, + 0x0000009C, + 0x0000009C, + 0x000001F8, + 0x000001F0, + 0x000000AC, + 0x000000A0, + 0x000000FC, + 0x00000168, + 0xE12FFF1E, + 0xE1A03000, + 0xE1A00001, + 0xE1A01003, + 0xE2113102, + 0x42611000, + 0xE033C040, + 0x22600000, + 0xE1B02001, + 0xE15200A0, + 0x91A02082, + 0x3AFFFFFC, + 0xE1500002, + 0xE0A33003, + 0x20400002, + 0xE1320001, + 0x11A020A2, + 0x1AFFFFF9, + 0xE1A01000, + 0xE1A00003, + 0xE1B0C08C, + 0x22600000, + 0x42611000, + 0xE12FFF1E, + 0xE92D0010, + 0xE1A0C000, + 0xE3A01001, + 0xE1500001, + 0x81A000A0, + 0x81A01081, + 0x8AFFFFFB, + 0xE1A0000C, + 0xE1A04001, + 0xE3A03000, + 0xE1A02001, + 0xE15200A0, + 0x91A02082, + 0x3AFFFFFC, + 0xE1500002, + 0xE0A33003, + 0x20400002, + 0xE1320001, + 0x11A020A2, + 0x1AFFFFF9, + 0xE0811003, + 0xE1B010A1, + 0xE1510004, + 0x3AFFFFEE, + 0xE1A00004, + 0xE8BD0010, + 0xE12FFF1E, + 0xE0010090, + 0xE1A01741, + 0xE2611000, + 0xE3A030A9, + 0xE0030391, + 0xE1A03743, + 0xE2833E39, + 0xE0030391, + 0xE1A03743, + 0xE2833C09, + 0xE283301C, + 0xE0030391, + 0xE1A03743, + 0xE2833C0F, + 0xE28330B6, + 0xE0030391, + 0xE1A03743, + 0xE2833C16, + 0xE28330AA, + 0xE0030391, + 0xE1A03743, + 0xE2833A02, + 0xE2833081, + 0xE0030391, + 0xE1A03743, + 0xE2833C36, + 0xE2833051, + 0xE0030391, + 0xE1A03743, + 0xE2833CA2, + 0xE28330F9, + 0xE0000093, + 0xE1A00840, + 0xE12FFF1E, + 0xE3A00001, + 0xE3A01001, + 0xE92D4010, + 0xE3A03000, + 0xE3A04001, + 0xE3500000, + 0x1B000004, + 0xE5CC3301, + 0xEB000002, + 0x0AFFFFFC, + 0xE8BD4010, + 0xE12FFF1E, + 0xE3A0C301, + 0xE5CC3208, + 0xE15C20B8, + 0xE0110002, + 0x10222000, + 0x114C20B8, + 0xE5CC4208, + 0xE12FFF1E, + 0xE92D500F, + 0xE3A00301, + 0xE1A0E00F, + 0xE510F004, + 0xE8BD500F, + 0xE25EF004, + 0xE59FD044, + 0xE92D5000, + 0xE14FC000, + 0xE10FE000, + 0xE92D5000, + 0xE3A0C302, + 0xE5DCE09C, + 0xE35E00A5, + 0x1A000004, + 0x05DCE0B4, + 0x021EE080, + 0xE28FE004, + 0x159FF018, + 0x059FF018, + 0xE59FD018, + 0xE8BD5000, + 0xE169F00C, + 0xE8BD5000, + 0xE25EF004, + 0x03007FF0, + 0x09FE2000, + 0x09FFC000, + 0x03007FE0 }; variable_desc saveGameStruct[] = { - { &DISPCNT , sizeof(u16) }, - { &DISPSTAT , sizeof(u16) }, - { &VCOUNT , sizeof(u16) }, - { &BG0CNT , sizeof(u16) }, - { &BG1CNT , sizeof(u16) }, - { &BG2CNT , sizeof(u16) }, - { &BG3CNT , sizeof(u16) }, - { &BG0HOFS , sizeof(u16) }, - { &BG0VOFS , sizeof(u16) }, - { &BG1HOFS , sizeof(u16) }, - { &BG1VOFS , sizeof(u16) }, - { &BG2HOFS , sizeof(u16) }, - { &BG2VOFS , sizeof(u16) }, - { &BG3HOFS , sizeof(u16) }, - { &BG3VOFS , sizeof(u16) }, - { &BG2PA , sizeof(u16) }, - { &BG2PB , sizeof(u16) }, - { &BG2PC , sizeof(u16) }, - { &BG2PD , sizeof(u16) }, - { &BG2X_L , sizeof(u16) }, - { &BG2X_H , sizeof(u16) }, - { &BG2Y_L , sizeof(u16) }, - { &BG2Y_H , sizeof(u16) }, - { &BG3PA , sizeof(u16) }, - { &BG3PB , sizeof(u16) }, - { &BG3PC , sizeof(u16) }, - { &BG3PD , sizeof(u16) }, - { &BG3X_L , sizeof(u16) }, - { &BG3X_H , sizeof(u16) }, - { &BG3Y_L , sizeof(u16) }, - { &BG3Y_H , sizeof(u16) }, - { &WIN0H , sizeof(u16) }, - { &WIN1H , sizeof(u16) }, - { &WIN0V , sizeof(u16) }, - { &WIN1V , sizeof(u16) }, - { &WININ , sizeof(u16) }, - { &WINOUT , sizeof(u16) }, - { &MOSAIC , sizeof(u16) }, - { &BLDMOD , sizeof(u16) }, - { &COLEV , sizeof(u16) }, - { &COLY , sizeof(u16) }, - { &DM0SAD_L , sizeof(u16) }, - { &DM0SAD_H , sizeof(u16) }, - { &DM0DAD_L , sizeof(u16) }, - { &DM0DAD_H , sizeof(u16) }, - { &DM0CNT_L , sizeof(u16) }, - { &DM0CNT_H , sizeof(u16) }, - { &DM1SAD_L , sizeof(u16) }, - { &DM1SAD_H , sizeof(u16) }, - { &DM1DAD_L , sizeof(u16) }, - { &DM1DAD_H , sizeof(u16) }, - { &DM1CNT_L , sizeof(u16) }, - { &DM1CNT_H , sizeof(u16) }, - { &DM2SAD_L , sizeof(u16) }, - { &DM2SAD_H , sizeof(u16) }, - { &DM2DAD_L , sizeof(u16) }, - { &DM2DAD_H , sizeof(u16) }, - { &DM2CNT_L , sizeof(u16) }, - { &DM2CNT_H , sizeof(u16) }, - { &DM3SAD_L , sizeof(u16) }, - { &DM3SAD_H , sizeof(u16) }, - { &DM3DAD_L , sizeof(u16) }, - { &DM3DAD_H , sizeof(u16) }, - { &DM3CNT_L , sizeof(u16) }, - { &DM3CNT_H , sizeof(u16) }, - { &TM0D , sizeof(u16) }, - { &TM0CNT , sizeof(u16) }, - { &TM1D , sizeof(u16) }, - { &TM1CNT , sizeof(u16) }, - { &TM2D , sizeof(u16) }, - { &TM2CNT , sizeof(u16) }, - { &TM3D , sizeof(u16) }, - { &TM3CNT , sizeof(u16) }, - { &P1 , sizeof(u16) }, - { &IE , sizeof(u16) }, - { &IF , sizeof(u16) }, - { &IME , sizeof(u16) }, - { &holdState, sizeof(bool) }, - { &holdType, sizeof(int) }, - { &lcdTicks, sizeof(int) }, - { &timer0On , sizeof(bool) }, - { &timer0Ticks , sizeof(int) }, - { &timer0Reload , sizeof(int) }, - { &timer0ClockReload , sizeof(int) }, - { &timer1On , sizeof(bool) }, - { &timer1Ticks , sizeof(int) }, - { &timer1Reload , sizeof(int) }, - { &timer1ClockReload , sizeof(int) }, - { &timer2On , sizeof(bool) }, - { &timer2Ticks , sizeof(int) }, - { &timer2Reload , sizeof(int) }, - { &timer2ClockReload , sizeof(int) }, - { &timer3On , sizeof(bool) }, - { &timer3Ticks , sizeof(int) }, - { &timer3Reload , sizeof(int) }, - { &timer3ClockReload , sizeof(int) }, - { &dma0Source , sizeof(u32) }, - { &dma0Dest , sizeof(u32) }, - { &dma1Source , sizeof(u32) }, - { &dma1Dest , sizeof(u32) }, - { &dma2Source , sizeof(u32) }, - { &dma2Dest , sizeof(u32) }, - { &dma3Source , sizeof(u32) }, - { &dma3Dest , sizeof(u32) }, - { &fxOn, sizeof(bool) }, - { &windowOn, sizeof(bool) }, - { &N_FLAG , sizeof(bool) }, - { &C_FLAG , sizeof(bool) }, - { &Z_FLAG , sizeof(bool) }, - { &V_FLAG , sizeof(bool) }, - { &armState , sizeof(bool) }, - { &armIrqEnable , sizeof(bool) }, - { &armNextPC , sizeof(u32) }, - { &armMode , sizeof(int) }, - { &saveType , sizeof(int) }, - { NULL, 0 } + { &DISPCNT, sizeof(u16) }, + { &DISPSTAT, sizeof(u16) }, + { &VCOUNT, sizeof(u16) }, + { &BG0CNT, sizeof(u16) }, + { &BG1CNT, sizeof(u16) }, + { &BG2CNT, sizeof(u16) }, + { &BG3CNT, sizeof(u16) }, + { &BG0HOFS, sizeof(u16) }, + { &BG0VOFS, sizeof(u16) }, + { &BG1HOFS, sizeof(u16) }, + { &BG1VOFS, sizeof(u16) }, + { &BG2HOFS, sizeof(u16) }, + { &BG2VOFS, sizeof(u16) }, + { &BG3HOFS, sizeof(u16) }, + { &BG3VOFS, sizeof(u16) }, + { &BG2PA, sizeof(u16) }, + { &BG2PB, sizeof(u16) }, + { &BG2PC, sizeof(u16) }, + { &BG2PD, sizeof(u16) }, + { &BG2X_L, sizeof(u16) }, + { &BG2X_H, sizeof(u16) }, + { &BG2Y_L, sizeof(u16) }, + { &BG2Y_H, sizeof(u16) }, + { &BG3PA, sizeof(u16) }, + { &BG3PB, sizeof(u16) }, + { &BG3PC, sizeof(u16) }, + { &BG3PD, sizeof(u16) }, + { &BG3X_L, sizeof(u16) }, + { &BG3X_H, sizeof(u16) }, + { &BG3Y_L, sizeof(u16) }, + { &BG3Y_H, sizeof(u16) }, + { &WIN0H, sizeof(u16) }, + { &WIN1H, sizeof(u16) }, + { &WIN0V, sizeof(u16) }, + { &WIN1V, sizeof(u16) }, + { &WININ, sizeof(u16) }, + { &WINOUT, sizeof(u16) }, + { &MOSAIC, sizeof(u16) }, + { &BLDMOD, sizeof(u16) }, + { &COLEV, sizeof(u16) }, + { &COLY, sizeof(u16) }, + { &DM0SAD_L, sizeof(u16) }, + { &DM0SAD_H, sizeof(u16) }, + { &DM0DAD_L, sizeof(u16) }, + { &DM0DAD_H, sizeof(u16) }, + { &DM0CNT_L, sizeof(u16) }, + { &DM0CNT_H, sizeof(u16) }, + { &DM1SAD_L, sizeof(u16) }, + { &DM1SAD_H, sizeof(u16) }, + { &DM1DAD_L, sizeof(u16) }, + { &DM1DAD_H, sizeof(u16) }, + { &DM1CNT_L, sizeof(u16) }, + { &DM1CNT_H, sizeof(u16) }, + { &DM2SAD_L, sizeof(u16) }, + { &DM2SAD_H, sizeof(u16) }, + { &DM2DAD_L, sizeof(u16) }, + { &DM2DAD_H, sizeof(u16) }, + { &DM2CNT_L, sizeof(u16) }, + { &DM2CNT_H, sizeof(u16) }, + { &DM3SAD_L, sizeof(u16) }, + { &DM3SAD_H, sizeof(u16) }, + { &DM3DAD_L, sizeof(u16) }, + { &DM3DAD_H, sizeof(u16) }, + { &DM3CNT_L, sizeof(u16) }, + { &DM3CNT_H, sizeof(u16) }, + { &TM0D, sizeof(u16) }, + { &TM0CNT, sizeof(u16) }, + { &TM1D, sizeof(u16) }, + { &TM1CNT, sizeof(u16) }, + { &TM2D, sizeof(u16) }, + { &TM2CNT, sizeof(u16) }, + { &TM3D, sizeof(u16) }, + { &TM3CNT, sizeof(u16) }, + { &P1, sizeof(u16) }, + { &IE, sizeof(u16) }, + { &IF, sizeof(u16) }, + { &IME, sizeof(u16) }, + { &holdState, sizeof(bool) }, + { &holdType, sizeof(int) }, + { &lcdTicks, sizeof(int) }, + { &timer0On, sizeof(bool) }, + { &timer0Ticks, sizeof(int) }, + { &timer0Reload, sizeof(int) }, + { &timer0ClockReload, sizeof(int) }, + { &timer1On, sizeof(bool) }, + { &timer1Ticks, sizeof(int) }, + { &timer1Reload, sizeof(int) }, + { &timer1ClockReload, sizeof(int) }, + { &timer2On, sizeof(bool) }, + { &timer2Ticks, sizeof(int) }, + { &timer2Reload, sizeof(int) }, + { &timer2ClockReload, sizeof(int) }, + { &timer3On, sizeof(bool) }, + { &timer3Ticks, sizeof(int) }, + { &timer3Reload, sizeof(int) }, + { &timer3ClockReload, sizeof(int) }, + { &dma0Source, sizeof(u32) }, + { &dma0Dest, sizeof(u32) }, + { &dma1Source, sizeof(u32) }, + { &dma1Dest, sizeof(u32) }, + { &dma2Source, sizeof(u32) }, + { &dma2Dest, sizeof(u32) }, + { &dma3Source, sizeof(u32) }, + { &dma3Dest, sizeof(u32) }, + { &fxOn, sizeof(bool) }, + { &windowOn, sizeof(bool) }, + { &N_FLAG, sizeof(bool) }, + { &C_FLAG, sizeof(bool) }, + { &Z_FLAG, sizeof(bool) }, + { &V_FLAG, sizeof(bool) }, + { &armState, sizeof(bool) }, + { &armIrqEnable, sizeof(bool) }, + { &armNextPC, sizeof(u32) }, + { &armMode, sizeof(int) }, + { &saveType, sizeof(int) }, + { NULL, 0 } }; static int romSize = 0x2000000; #ifdef PROFILING -void cpuProfil(profile_segment *seg) +void cpuProfil(profile_segment* seg) { profilSegment = seg; } void cpuEnableProfiling(int hz) { - if(hz == 0) - hz = 100; - profilingTicks = profilingTicksReload = 16777216 / hz; - profSetHertz(hz); + if (hz == 0) + hz = 100; + profilingTicks = profilingTicksReload = 16777216 / hz; + profSetHertz(hz); } #endif - inline int CPUUpdateTicks() { - int cpuLoopTicks = lcdTicks; + int cpuLoopTicks = lcdTicks; - if(soundTicks < cpuLoopTicks) - cpuLoopTicks = soundTicks; + if (soundTicks < cpuLoopTicks) + cpuLoopTicks = soundTicks; - if(timer0On && (timer0Ticks < cpuLoopTicks)) { - cpuLoopTicks = timer0Ticks; - } - if(timer1On && !(TM1CNT & 4) && (timer1Ticks < cpuLoopTicks)) { - cpuLoopTicks = timer1Ticks; - } - if(timer2On && !(TM2CNT & 4) && (timer2Ticks < cpuLoopTicks)) { - cpuLoopTicks = timer2Ticks; - } - if(timer3On && !(TM3CNT & 4) && (timer3Ticks < cpuLoopTicks)) { - cpuLoopTicks = timer3Ticks; - } -#ifdef PROFILING - if(profilingTicksReload != 0) { - if(profilingTicks < cpuLoopTicks) { - cpuLoopTicks = profilingTicks; + if (timer0On && (timer0Ticks < cpuLoopTicks)) { + cpuLoopTicks = timer0Ticks; + } + if (timer1On && !(TM1CNT & 4) && (timer1Ticks < cpuLoopTicks)) { + cpuLoopTicks = timer1Ticks; + } + if (timer2On && !(TM2CNT & 4) && (timer2Ticks < cpuLoopTicks)) { + cpuLoopTicks = timer2Ticks; + } + if (timer3On && !(TM3CNT & 4) && (timer3Ticks < cpuLoopTicks)) { + cpuLoopTicks = timer3Ticks; + } +#ifdef PROFILING + if (profilingTicksReload != 0) { + if (profilingTicks < cpuLoopTicks) { + cpuLoopTicks = profilingTicks; + } } - } #endif - if (SWITicks) { - if (SWITicks < cpuLoopTicks) - cpuLoopTicks = SWITicks; - } + if (SWITicks) { + if (SWITicks < cpuLoopTicks) + cpuLoopTicks = SWITicks; + } - if (IRQTicks) { - if (IRQTicks < cpuLoopTicks) - cpuLoopTicks = IRQTicks; - } + if (IRQTicks) { + if (IRQTicks < cpuLoopTicks) + cpuLoopTicks = IRQTicks; + } - return cpuLoopTicks; + return cpuLoopTicks; } void CPUUpdateWindow0() { - int x00 = WIN0H>>8; - int x01 = WIN0H & 255; + int x00 = WIN0H >> 8; + int x01 = WIN0H & 255; - if(x00 <= x01) { - for(int i = 0; i < 240; i++) { - gfxInWin0[i] = (i >= x00 && i < x01); + if (x00 <= x01) { + for (int i = 0; i < 240; i++) { + gfxInWin0[i] = (i >= x00 && i < x01); + } + } else { + for (int i = 0; i < 240; i++) { + gfxInWin0[i] = (i >= x00 || i < x01); + } } - } else { - for(int i = 0; i < 240; i++) { - gfxInWin0[i] = (i >= x00 || i < x01); - } - } } void CPUUpdateWindow1() { - int x00 = WIN1H>>8; - int x01 = WIN1H & 255; + int x00 = WIN1H >> 8; + int x01 = WIN1H & 255; - if(x00 <= x01) { - for(int i = 0; i < 240; i++) { - gfxInWin1[i] = (i >= x00 && i < x01); + if (x00 <= x01) { + for (int i = 0; i < 240; i++) { + gfxInWin1[i] = (i >= x00 && i < x01); + } + } else { + for (int i = 0; i < 240; i++) { + gfxInWin1[i] = (i >= x00 || i < x01); + } } - } else { - for(int i = 0; i < 240; i++) { - gfxInWin1[i] = (i >= x00 || i < x01); - } - } } extern u32 line0[240]; @@ -560,28 +553,28 @@ extern u32 line1[240]; extern u32 line2[240]; extern u32 line3[240]; -#define CLEAR_ARRAY(a) \ - {\ - u32 *array = (a);\ - for(int i = 0; i < 240; i++) {\ - *array++ = 0x80000000;\ - }\ - }\ +#define CLEAR_ARRAY(a) \ + { \ + u32* array = (a); \ + for (int i = 0; i < 240; i++) { \ + *array++ = 0x80000000; \ + } \ + } void CPUUpdateRenderBuffers(bool force) { - if(!(layerEnable & 0x0100) || force) { - CLEAR_ARRAY(line0); - } - if(!(layerEnable & 0x0200) || force) { - CLEAR_ARRAY(line1); - } - if(!(layerEnable & 0x0400) || force) { - CLEAR_ARRAY(line2); - } - if(!(layerEnable & 0x0800) || force) { - CLEAR_ARRAY(line3); - } + if (!(layerEnable & 0x0100) || force) { + CLEAR_ARRAY(line0); + } + if (!(layerEnable & 0x0200) || force) { + CLEAR_ARRAY(line1); + } + if (!(layerEnable & 0x0400) || force) { + CLEAR_ARRAY(line2); + } + if (!(layerEnable & 0x0800) || force) { + CLEAR_ARRAY(line3); + } } #ifdef __LIBRETRO__ @@ -589,4051 +582,3924 @@ void CPUUpdateRenderBuffers(bool force) unsigned int CPUWriteState(u8* data, unsigned size) { - uint8_t *orig = data; + uint8_t* orig = data; - utilWriteIntMem(data, SAVE_GAME_VERSION); - utilWriteMem(data, &rom[0xa0], 16); - utilWriteIntMem(data, useBios); - utilWriteMem(data, ®[0], sizeof(reg)); + utilWriteIntMem(data, SAVE_GAME_VERSION); + utilWriteMem(data, &rom[0xa0], 16); + utilWriteIntMem(data, useBios); + utilWriteMem(data, ®[0], sizeof(reg)); - utilWriteDataMem(data, saveGameStruct); + utilWriteDataMem(data, saveGameStruct); - utilWriteIntMem(data, stopState); - utilWriteIntMem(data, IRQTicks); + utilWriteIntMem(data, stopState); + utilWriteIntMem(data, IRQTicks); - utilWriteMem(data, internalRAM, 0x8000); - utilWriteMem(data, paletteRAM, 0x400); - utilWriteMem(data, workRAM, 0x40000); - utilWriteMem(data, vram, 0x20000); - utilWriteMem(data, oam, 0x400); + utilWriteMem(data, internalRAM, 0x8000); + utilWriteMem(data, paletteRAM, 0x400); + utilWriteMem(data, workRAM, 0x40000); + utilWriteMem(data, vram, 0x20000); + utilWriteMem(data, oam, 0x400); #ifdef __LIBRETRO__ - utilWriteMem(data, pix, 4 * 240 * 160); + utilWriteMem(data, pix, 4 * 240 * 160); #else - utilWriteMem(data, pix, 4 * 241 * 162); + utilWriteMem(data, pix, 4 * 241 * 162); #endif - utilWriteMem(data, ioMem, 0x400); + utilWriteMem(data, ioMem, 0x400); - eepromSaveGame(data); - flashSaveGame(data); - soundSaveGame(data); - rtcSaveGame(data); + eepromSaveGame(data); + flashSaveGame(data); + soundSaveGame(data); + rtcSaveGame(data); - return (ptrdiff_t)data - (ptrdiff_t)orig; + return (ptrdiff_t)data - (ptrdiff_t)orig; } -bool CPUWriteMemState(char *memory, int available, long& reserved) +bool CPUWriteMemState(char* memory, int available, long& reserved) { - return false; + return false; } #else static bool CPUWriteState(gzFile gzFile) { - utilWriteInt(gzFile, SAVE_GAME_VERSION); + utilWriteInt(gzFile, SAVE_GAME_VERSION); - utilGzWrite(gzFile, &rom[0xa0], 16); + utilGzWrite(gzFile, &rom[0xa0], 16); - utilWriteInt(gzFile, useBios); + utilWriteInt(gzFile, useBios); - utilGzWrite(gzFile, ®[0], sizeof(reg)); + utilGzWrite(gzFile, ®[0], sizeof(reg)); - utilWriteData(gzFile, saveGameStruct); + utilWriteData(gzFile, saveGameStruct); - // new to version 0.7.1 - utilWriteInt(gzFile, stopState); - // new to version 0.8 - utilWriteInt(gzFile, IRQTicks); + // new to version 0.7.1 + utilWriteInt(gzFile, stopState); + // new to version 0.8 + utilWriteInt(gzFile, IRQTicks); - utilGzWrite(gzFile, internalRAM, 0x8000); - utilGzWrite(gzFile, paletteRAM, 0x400); - utilGzWrite(gzFile, workRAM, 0x40000); - utilGzWrite(gzFile, vram, 0x20000); - utilGzWrite(gzFile, oam, 0x400); + utilGzWrite(gzFile, internalRAM, 0x8000); + utilGzWrite(gzFile, paletteRAM, 0x400); + utilGzWrite(gzFile, workRAM, 0x40000); + utilGzWrite(gzFile, vram, 0x20000); + utilGzWrite(gzFile, oam, 0x400); #ifdef __LIBRETRO__ - utilGzWrite(gzFile, pix, 4*240*160); + utilGzWrite(gzFile, pix, 4 * 240 * 160); #else - utilGzWrite(gzFile, pix, 4*241*162); + utilGzWrite(gzFile, pix, 4 * 241 * 162); #endif - utilGzWrite(gzFile, ioMem, 0x400); + utilGzWrite(gzFile, ioMem, 0x400); - eepromSaveGame(gzFile); - flashSaveGame(gzFile); - soundSaveGame(gzFile); + eepromSaveGame(gzFile); + flashSaveGame(gzFile); + soundSaveGame(gzFile); - cheatsSaveGame(gzFile); + cheatsSaveGame(gzFile); - // version 1.5 - rtcSaveGame(gzFile); + // version 1.5 + rtcSaveGame(gzFile); - return true; + return true; } -bool CPUWriteState(const char *file) +bool CPUWriteState(const char* file) { - gzFile gzFile = utilGzOpen(file, "wb"); + gzFile gzFile = utilGzOpen(file, "wb"); - if(gzFile == NULL) { - systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"), file); - return false; - } + if (gzFile == NULL) { + systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"), file); + return false; + } - bool res = CPUWriteState(gzFile); + bool res = CPUWriteState(gzFile); - utilGzClose(gzFile); + utilGzClose(gzFile); - return res; + return res; } - -bool CPUWriteMemState(char *memory, int available, long& reserved) +bool CPUWriteMemState(char* memory, int available, long& reserved) { - gzFile gzFile = utilMemGzOpen(memory, available, "w"); + gzFile gzFile = utilMemGzOpen(memory, available, "w"); - if(gzFile == NULL) { - return false; - } + if (gzFile == NULL) { + return false; + } - bool res = CPUWriteState(gzFile); + bool res = CPUWriteState(gzFile); - reserved = utilGzMemTell(gzFile)+8; + reserved = utilGzMemTell(gzFile) + 8; - if(reserved >= (available)) - res = false; + if (reserved >= (available)) + res = false; - utilGzClose(gzFile); + utilGzClose(gzFile); - return res; + return res; } #endif - #ifdef __LIBRETRO__ bool CPUReadState(const u8* data, unsigned size) { - // Don't really care about version. - int version = utilReadIntMem(data); - if (version != SAVE_GAME_VERSION) - return false; + // Don't really care about version. + int version = utilReadIntMem(data); + if (version != SAVE_GAME_VERSION) + return false; - char romname[16]; - utilReadMem(romname, data, 16); - if (memcmp(&rom[0xa0], romname, 16) != 0) - return false; + char romname[16]; + utilReadMem(romname, data, 16); + if (memcmp(&rom[0xa0], romname, 16) != 0) + return false; - // Don't care about use bios ... - utilReadIntMem(data); + // Don't care about use bios ... + utilReadIntMem(data); - utilReadMem(®[0], data, sizeof(reg)); + utilReadMem(®[0], data, sizeof(reg)); - utilReadDataMem(data, saveGameStruct); + utilReadDataMem(data, saveGameStruct); - stopState = utilReadIntMem(data) ? true : false; + stopState = utilReadIntMem(data) ? true : false; - IRQTicks = utilReadIntMem(data); - if (IRQTicks > 0) - intState = true; - else - { - intState = false; - IRQTicks = 0; - } + IRQTicks = utilReadIntMem(data); + if (IRQTicks > 0) + intState = true; + else { + intState = false; + IRQTicks = 0; + } - utilReadMem(internalRAM, data, 0x8000); - utilReadMem(paletteRAM, data, 0x400); - utilReadMem(workRAM, data, 0x40000); - utilReadMem(vram, data, 0x20000); - utilReadMem(oam, data, 0x400); + utilReadMem(internalRAM, data, 0x8000); + utilReadMem(paletteRAM, data, 0x400); + utilReadMem(workRAM, data, 0x40000); + utilReadMem(vram, data, 0x20000); + utilReadMem(oam, data, 0x400); #ifdef __LIBRETRO__ - utilReadMem(pix, data, 4*240*160); + utilReadMem(pix, data, 4 * 240 * 160); #else - utilReadMem(pix, data, 4*241*162); + utilReadMem(pix, data, 4 * 241 * 162); #endif - utilReadMem(ioMem, data, 0x400); + utilReadMem(ioMem, data, 0x400); - eepromReadGame(data, version); - flashReadGame(data, version); - soundReadGame(data, version); - rtcReadGame(data); + eepromReadGame(data, version); + flashReadGame(data, version); + soundReadGame(data, version); + rtcReadGame(data); - //// Copypasta stuff ... - // set pointers! - layerEnable = layerSettings & DISPCNT; + //// Copypasta stuff ... + // set pointers! + layerEnable = layerSettings & DISPCNT; - CPUUpdateRender(); + CPUUpdateRender(); - // CPU Update Render Buffers set to true - CLEAR_ARRAY(line0); - CLEAR_ARRAY(line1); - CLEAR_ARRAY(line2); - CLEAR_ARRAY(line3); - // End of CPU Update Render Buffers set to true + // CPU Update Render Buffers set to true + CLEAR_ARRAY(line0); + CLEAR_ARRAY(line1); + CLEAR_ARRAY(line2); + CLEAR_ARRAY(line3); + // End of CPU Update Render Buffers set to true - CPUUpdateWindow0(); - CPUUpdateWindow1(); - gbaSaveType = 0; - switch(saveType) { - case 0: - cpuSaveGameFunc = flashSaveDecide; - break; - case 1: - cpuSaveGameFunc = sramWrite; - gbaSaveType = 1; - break; - case 2: - cpuSaveGameFunc = flashWrite; - gbaSaveType = 2; - break; - case 3: - break; - case 5: - gbaSaveType = 5; - break; - default: + CPUUpdateWindow0(); + CPUUpdateWindow1(); + gbaSaveType = 0; + switch (saveType) { + case 0: + cpuSaveGameFunc = flashSaveDecide; + break; + case 1: + cpuSaveGameFunc = sramWrite; + gbaSaveType = 1; + break; + case 2: + cpuSaveGameFunc = flashWrite; + gbaSaveType = 2; + break; + case 3: + break; + case 5: + gbaSaveType = 5; + break; + default: #ifdef CELL_VBA_DEBUG - systemMessage(MSG_UNSUPPORTED_SAVE_TYPE, - N_("Unsupported save type %d"), saveType); + systemMessage(MSG_UNSUPPORTED_SAVE_TYPE, + N_("Unsupported save type %d"), saveType); #endif - break; - } - if(eepromInUse) - gbaSaveType = 3; + break; + } + if (eepromInUse) + gbaSaveType = 3; - systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED; - if(armState) { - ARM_PREFETCH; - } else { - THUMB_PREFETCH; - } + systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED; + if (armState) { + ARM_PREFETCH; + } else { + THUMB_PREFETCH; + } - CPUUpdateRegister(0x204, CPUReadHalfWordQuick(0x4000204)); + CPUUpdateRegister(0x204, CPUReadHalfWordQuick(0x4000204)); - return true; + return true; } #else static bool CPUReadState(gzFile gzFile) { - int version = utilReadInt(gzFile); + int version = utilReadInt(gzFile); - if(version > SAVE_GAME_VERSION || version < SAVE_GAME_VERSION_1) { - systemMessage(MSG_UNSUPPORTED_VBA_SGM, - N_("Unsupported VisualBoyAdvance save game version %d"), - version); - return false; - } - - u8 romname[17]; - - utilGzRead(gzFile, romname, 16); - - if(memcmp(&rom[0xa0], romname, 16) != 0) { - romname[16]=0; - for(int i = 0; i < 16; i++) - if(romname[i] < 32) - romname[i] = 32; - systemMessage(MSG_CANNOT_LOAD_SGM, N_("Cannot load save game for %s"), romname); - return false; - } - - bool ub = utilReadInt(gzFile) ? true : false; - - if(ub != useBios) { - if(useBios) - systemMessage(MSG_SAVE_GAME_NOT_USING_BIOS, - N_("Save game is not using the BIOS files")); - else - systemMessage(MSG_SAVE_GAME_USING_BIOS, - N_("Save game is using the BIOS file")); - return false; - } - - utilGzRead(gzFile, ®[0], sizeof(reg)); - - utilReadData(gzFile, saveGameStruct); - - if(version < SAVE_GAME_VERSION_3) - stopState = false; - else - stopState = utilReadInt(gzFile) ? true : false; - - if(version < SAVE_GAME_VERSION_4) - { - IRQTicks = 0; - intState = false; - } - else - { - IRQTicks = utilReadInt(gzFile); - if (IRQTicks>0) - intState = true; - else - { - intState = false; - IRQTicks = 0; + if (version > SAVE_GAME_VERSION || version < SAVE_GAME_VERSION_1) { + systemMessage(MSG_UNSUPPORTED_VBA_SGM, + N_("Unsupported VisualBoyAdvance save game version %d"), + version); + return false; } - } - utilGzRead(gzFile, internalRAM, 0x8000); - utilGzRead(gzFile, paletteRAM, 0x400); - utilGzRead(gzFile, workRAM, 0x40000); - utilGzRead(gzFile, vram, 0x20000); - utilGzRead(gzFile, oam, 0x400); + u8 romname[17]; + + utilGzRead(gzFile, romname, 16); + + if (memcmp(&rom[0xa0], romname, 16) != 0) { + romname[16] = 0; + for (int i = 0; i < 16; i++) + if (romname[i] < 32) + romname[i] = 32; + systemMessage(MSG_CANNOT_LOAD_SGM, N_("Cannot load save game for %s"), romname); + return false; + } + + bool ub = utilReadInt(gzFile) ? true : false; + + if (ub != useBios) { + if (useBios) + systemMessage(MSG_SAVE_GAME_NOT_USING_BIOS, + N_("Save game is not using the BIOS files")); + else + systemMessage(MSG_SAVE_GAME_USING_BIOS, + N_("Save game is using the BIOS file")); + return false; + } + + utilGzRead(gzFile, ®[0], sizeof(reg)); + + utilReadData(gzFile, saveGameStruct); + + if (version < SAVE_GAME_VERSION_3) + stopState = false; + else + stopState = utilReadInt(gzFile) ? true : false; + + if (version < SAVE_GAME_VERSION_4) { + IRQTicks = 0; + intState = false; + } else { + IRQTicks = utilReadInt(gzFile); + if (IRQTicks > 0) + intState = true; + else { + intState = false; + IRQTicks = 0; + } + } + + utilGzRead(gzFile, internalRAM, 0x8000); + utilGzRead(gzFile, paletteRAM, 0x400); + utilGzRead(gzFile, workRAM, 0x40000); + utilGzRead(gzFile, vram, 0x20000); + utilGzRead(gzFile, oam, 0x400); #ifdef __LIBRETRO__ - utilGzRead(gzFile, pix, 4*240*160); + utilGzRead(gzFile, pix, 4 * 240 * 160); #else - if(version < SAVE_GAME_VERSION_6) - utilGzRead(gzFile, pix, 4*240*160); - else - utilGzRead(gzFile, pix, 4*241*162); + if (version < SAVE_GAME_VERSION_6) + utilGzRead(gzFile, pix, 4 * 240 * 160); + else + utilGzRead(gzFile, pix, 4 * 241 * 162); #endif - utilGzRead(gzFile, ioMem, 0x400); + utilGzRead(gzFile, ioMem, 0x400); - if(skipSaveGameBattery) { - // skip eeprom data - eepromReadGameSkip(gzFile, version); - // skip flash data - flashReadGameSkip(gzFile, version); - } else { - eepromReadGame(gzFile, version); - flashReadGame(gzFile, version); - } - soundReadGame(gzFile, version); - - if(version > SAVE_GAME_VERSION_1) { - if(skipSaveGameCheats) { - // skip cheats list data - cheatsReadGameSkip(gzFile, version); + if (skipSaveGameBattery) { + // skip eeprom data + eepromReadGameSkip(gzFile, version); + // skip flash data + flashReadGameSkip(gzFile, version); } else { - cheatsReadGame(gzFile, version); + eepromReadGame(gzFile, version); + flashReadGame(gzFile, version); } - } - if(version > SAVE_GAME_VERSION_6) { - rtcReadGame(gzFile); - } + soundReadGame(gzFile, version); - if(version <= SAVE_GAME_VERSION_7) { - u32 temp; -#define SWAP(a,b,c) \ - temp = (a);\ - (a) = (b)<<16|(c);\ - (b) = (temp) >> 16;\ - (c) = (temp) & 0xFFFF; + if (version > SAVE_GAME_VERSION_1) { + if (skipSaveGameCheats) { + // skip cheats list data + cheatsReadGameSkip(gzFile, version); + } else { + cheatsReadGame(gzFile, version); + } + } + if (version > SAVE_GAME_VERSION_6) { + rtcReadGame(gzFile); + } - SWAP(dma0Source, DM0SAD_H, DM0SAD_L); - SWAP(dma0Dest, DM0DAD_H, DM0DAD_L); - SWAP(dma1Source, DM1SAD_H, DM1SAD_L); - SWAP(dma1Dest, DM1DAD_H, DM1DAD_L); - SWAP(dma2Source, DM2SAD_H, DM2SAD_L); - SWAP(dma2Dest, DM2DAD_H, DM2DAD_L); - SWAP(dma3Source, DM3SAD_H, DM3SAD_L); - SWAP(dma3Dest, DM3DAD_H, DM3DAD_L); - } + if (version <= SAVE_GAME_VERSION_7) { + u32 temp; +#define SWAP(a, b, c) \ + temp = (a); \ + (a) = (b) << 16 | (c); \ + (b) = (temp) >> 16; \ + (c) = (temp)&0xFFFF; - if(version <= SAVE_GAME_VERSION_8) { - timer0ClockReload = TIMER_TICKS[TM0CNT & 3]; - timer1ClockReload = TIMER_TICKS[TM1CNT & 3]; - timer2ClockReload = TIMER_TICKS[TM2CNT & 3]; - timer3ClockReload = TIMER_TICKS[TM3CNT & 3]; + SWAP(dma0Source, DM0SAD_H, DM0SAD_L); + SWAP(dma0Dest, DM0DAD_H, DM0DAD_L); + SWAP(dma1Source, DM1SAD_H, DM1SAD_L); + SWAP(dma1Dest, DM1DAD_H, DM1DAD_L); + SWAP(dma2Source, DM2SAD_H, DM2SAD_L); + SWAP(dma2Dest, DM2DAD_H, DM2DAD_L); + SWAP(dma3Source, DM3SAD_H, DM3SAD_L); + SWAP(dma3Dest, DM3DAD_H, DM3DAD_L); + } - timer0Ticks = ((0x10000 - TM0D) << timer0ClockReload) - timer0Ticks; - timer1Ticks = ((0x10000 - TM1D) << timer1ClockReload) - timer1Ticks; - timer2Ticks = ((0x10000 - TM2D) << timer2ClockReload) - timer2Ticks; - timer3Ticks = ((0x10000 - TM3D) << timer3ClockReload) - timer3Ticks; - interp_rate(); - } + if (version <= SAVE_GAME_VERSION_8) { + timer0ClockReload = TIMER_TICKS[TM0CNT & 3]; + timer1ClockReload = TIMER_TICKS[TM1CNT & 3]; + timer2ClockReload = TIMER_TICKS[TM2CNT & 3]; + timer3ClockReload = TIMER_TICKS[TM3CNT & 3]; - // set pointers! - layerEnable = layerSettings & DISPCNT; + timer0Ticks = ((0x10000 - TM0D) << timer0ClockReload) - timer0Ticks; + timer1Ticks = ((0x10000 - TM1D) << timer1ClockReload) - timer1Ticks; + timer2Ticks = ((0x10000 - TM2D) << timer2ClockReload) - timer2Ticks; + timer3Ticks = ((0x10000 - TM3D) << timer3ClockReload) - timer3Ticks; + interp_rate(); + } - CPUUpdateRender(); - CPUUpdateRenderBuffers(true); - CPUUpdateWindow0(); - CPUUpdateWindow1(); - gbaSaveType = 0; - SetSaveType(saveType); - if(eepromInUse) - gbaSaveType = 3; + // set pointers! + layerEnable = layerSettings & DISPCNT; - systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED; - if(armState) { - ARM_PREFETCH; - } else { - THUMB_PREFETCH; - } + CPUUpdateRender(); + CPUUpdateRenderBuffers(true); + CPUUpdateWindow0(); + CPUUpdateWindow1(); + gbaSaveType = 0; + SetSaveType(saveType); + if (eepromInUse) + gbaSaveType = 3; - CPUUpdateRegister(0x204, CPUReadHalfWordQuick(0x4000204)); + systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED; + if (armState) { + ARM_PREFETCH; + } else { + THUMB_PREFETCH; + } - return true; + CPUUpdateRegister(0x204, CPUReadHalfWordQuick(0x4000204)); + + return true; } -bool CPUReadMemState(char *memory, int available) +bool CPUReadMemState(char* memory, int available) { - gzFile gzFile = utilMemGzOpen(memory, available, "r"); + gzFile gzFile = utilMemGzOpen(memory, available, "r"); - bool res = CPUReadState(gzFile); + bool res = CPUReadState(gzFile); - utilGzClose(gzFile); + utilGzClose(gzFile); - return res; + return res; } -bool CPUReadState(const char * file) +bool CPUReadState(const char* file) { - gzFile gzFile = utilGzOpen(file, "rb"); + gzFile gzFile = utilGzOpen(file, "rb"); - if(gzFile == NULL) - return false; + if (gzFile == NULL) + return false; - bool res = CPUReadState(gzFile); + bool res = CPUReadState(gzFile); - utilGzClose(gzFile); + utilGzClose(gzFile); - return res; + return res; } #endif -bool CPUExportEepromFile(const char *fileName) +bool CPUExportEepromFile(const char* fileName) { - if(eepromInUse) { - FILE *file = fopen(fileName, "wb"); + if (eepromInUse) { + FILE* file = fopen(fileName, "wb"); - if(!file) { - systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"), - fileName); - return false; - } - - for(int i = 0; i < eepromSize;) { - for(int j = 0; j < 8; j++) { - if(fwrite(&eepromData[i+7-j], 1, 1, file) != 1) { - fclose(file); - return false; + if (!file) { + systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"), + fileName); + return false; } - } - i += 8; + + for (int i = 0; i < eepromSize;) { + for (int j = 0; j < 8; j++) { + if (fwrite(&eepromData[i + 7 - j], 1, 1, file) != 1) { + fclose(file); + return false; + } + } + i += 8; + } + fclose(file); } - fclose(file); - } - return true; + return true; } -bool CPUWriteBatteryFile(const char *fileName) +bool CPUWriteBatteryFile(const char* fileName) { - if(gbaSaveType == 0) { - if(eepromInUse) - gbaSaveType = 3; - else switch(saveType) { - case 1: - gbaSaveType = 1; - break; - case 2: - gbaSaveType = 2; - break; - } - } - - if((gbaSaveType) && (gbaSaveType!=5)) { - FILE *file = fopen(fileName, "wb"); - - if(!file) { - systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"), - fileName); - return false; + if (gbaSaveType == 0) { + if (eepromInUse) + gbaSaveType = 3; + else + switch (saveType) { + case 1: + gbaSaveType = 1; + break; + case 2: + gbaSaveType = 2; + break; + } } - // only save if Flash/Sram in use or EEprom in use - if(gbaSaveType != 3) { - if(gbaSaveType == 2) { - if(fwrite(flashSaveMemory, 1, flashSize, file) != (size_t)flashSize) { - fclose(file); - return false; + if ((gbaSaveType) && (gbaSaveType != 5)) { + FILE* file = fopen(fileName, "wb"); + + if (!file) { + systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"), + fileName); + return false; } - } else { - if(fwrite(flashSaveMemory, 1, 0x8000, file) != 0x8000) { - fclose(file); - return false; + + // only save if Flash/Sram in use or EEprom in use + if (gbaSaveType != 3) { + if (gbaSaveType == 2) { + if (fwrite(flashSaveMemory, 1, flashSize, file) != (size_t)flashSize) { + fclose(file); + return false; + } + } else { + if (fwrite(flashSaveMemory, 1, 0x8000, file) != 0x8000) { + fclose(file); + return false; + } + } + } else { + if (fwrite(eepromData, 1, eepromSize, file) != (size_t)eepromSize) { + fclose(file); + return false; + } + } + fclose(file); + } + return true; +} + +bool CPUReadGSASnapshot(const char* fileName) +{ + int i; + FILE* file = fopen(fileName, "rb"); + + if (!file) { + systemMessage(MSG_CANNOT_OPEN_FILE, N_("Cannot open file %s"), fileName); + return false; + } + + // check file size to know what we should read + fseek(file, 0, SEEK_END); + + // long size = ftell(file); + fseek(file, 0x0, SEEK_SET); + fread(&i, 1, 4, file); + fseek(file, i, SEEK_CUR); // Skip SharkPortSave + fseek(file, 4, SEEK_CUR); // skip some sort of flag + fread(&i, 1, 4, file); // name length + fseek(file, i, SEEK_CUR); // skip name + fread(&i, 1, 4, file); // desc length + fseek(file, i, SEEK_CUR); // skip desc + fread(&i, 1, 4, file); // notes length + fseek(file, i, SEEK_CUR); // skip notes + int saveSize; + fread(&saveSize, 1, 4, file); // read length + saveSize -= 0x1c; // remove header size + char buffer[17]; + char buffer2[17]; + fread(buffer, 1, 16, file); + buffer[16] = 0; + for (i = 0; i < 16; i++) + if (buffer[i] < 32) + buffer[i] = 32; + memcpy(buffer2, &rom[0xa0], 16); + buffer2[16] = 0; + for (i = 0; i < 16; i++) + if (buffer2[i] < 32) + buffer2[i] = 32; + if (memcmp(buffer, buffer2, 16)) { + systemMessage(MSG_CANNOT_IMPORT_SNAPSHOT_FOR, + N_("Cannot import snapshot for %s. Current game is %s"), + buffer, + buffer2); + fclose(file); + return false; + } + fseek(file, 12, SEEK_CUR); // skip some flags + if (saveSize >= 65536) { + if (fread(flashSaveMemory, 1, saveSize, file) != (size_t)saveSize) { + fclose(file); + return false; } - } } else { - if(fwrite(eepromData, 1, eepromSize, file) != (size_t)eepromSize) { + systemMessage(MSG_UNSUPPORTED_SNAPSHOT_FILE, + N_("Unsupported snapshot file %s"), + fileName); fclose(file); return false; - } } fclose(file); - } - return true; + CPUReset(); + return true; } -bool CPUReadGSASnapshot(const char *fileName) +bool CPUReadGSASPSnapshot(const char* fileName) { - int i; - FILE *file = fopen(fileName, "rb"); + const char gsvfooter[] = "xV4\x12"; + const size_t namepos = 0x0c, namesz = 12; + const size_t footerpos = 0x42c, footersz = 4; - if(!file) { - systemMessage(MSG_CANNOT_OPEN_FILE, N_("Cannot open file %s"), fileName); - return false; - } + char footer[footersz + 1], romname[namesz + 1], savename[namesz + 1]; + ; + FILE* file = fopen(fileName, "rb"); - // check file size to know what we should read - fseek(file, 0, SEEK_END); - - // long size = ftell(file); - fseek(file, 0x0, SEEK_SET); - fread(&i, 1, 4, file); - fseek(file, i, SEEK_CUR); // Skip SharkPortSave - fseek(file, 4, SEEK_CUR); // skip some sort of flag - fread(&i, 1, 4, file); // name length - fseek(file, i, SEEK_CUR); // skip name - fread(&i, 1, 4, file); // desc length - fseek(file, i, SEEK_CUR); // skip desc - fread(&i, 1, 4, file); // notes length - fseek(file, i, SEEK_CUR); // skip notes - int saveSize; - fread(&saveSize, 1, 4, file); // read length - saveSize -= 0x1c; // remove header size - char buffer[17]; - char buffer2[17]; - fread(buffer, 1, 16, file); - buffer[16] = 0; - for(i = 0; i < 16; i++) - if(buffer[i] < 32) - buffer[i] = 32; - memcpy(buffer2, &rom[0xa0], 16); - buffer2[16] = 0; - for(i = 0; i < 16; i++) - if(buffer2[i] < 32) - buffer2[i] = 32; - if(memcmp(buffer, buffer2, 16)) { - systemMessage(MSG_CANNOT_IMPORT_SNAPSHOT_FOR, - N_("Cannot import snapshot for %s. Current game is %s"), - buffer, - buffer2); - fclose(file); - return false; - } - fseek(file, 12, SEEK_CUR); // skip some flags - if(saveSize >= 65536) { - if(fread(flashSaveMemory, 1, saveSize, file) != (size_t)saveSize) { - fclose(file); - return false; + if (!file) { + systemMessage(MSG_CANNOT_OPEN_FILE, N_("Cannot open file %s"), fileName); + return false; } - } else { - systemMessage(MSG_UNSUPPORTED_SNAPSHOT_FILE, - N_("Unsupported snapshot file %s"), - fileName); - fclose(file); - return false; - } - fclose(file); - CPUReset(); - return true; -} -bool CPUReadGSASPSnapshot(const char *fileName) -{ - const char gsvfooter[] = "xV4\x12"; - const size_t namepos=0x0c, namesz=12; - const size_t footerpos=0x42c, footersz=4; + // read save name + fseek(file, namepos, SEEK_SET); + fread(savename, 1, namesz, file); + savename[namesz] = 0; - char footer[footersz+1], romname[namesz+1], savename[namesz+1];; - FILE *file = fopen(fileName, "rb"); + memcpy(romname, &rom[0xa0], namesz); + romname[namesz] = 0; - if(!file) { - systemMessage(MSG_CANNOT_OPEN_FILE, N_("Cannot open file %s"), fileName); - return false; - } - - // read save name - fseek(file, namepos, SEEK_SET); - fread(savename, 1, namesz, file); - savename[namesz] = 0; - - memcpy(romname, &rom[0xa0], namesz); - romname[namesz] = 0; - - if(memcmp(romname, savename, namesz)) { - systemMessage(MSG_CANNOT_IMPORT_SNAPSHOT_FOR, - N_("Cannot import snapshot for %s. Current game is %s"), - savename, - romname); - fclose(file); - return false; - } - - // read footer tag - fseek(file, footerpos, SEEK_SET); - fread(footer, 1, footersz, file); - footer[footersz] = 0; - - if(memcmp(footer, gsvfooter, footersz)) { - systemMessage(0, - N_("Unsupported snapshot file %s. Footer '%s' at %u should be '%s'"), - fileName, - footer, - footerpos, - gsvfooter); - fclose(file); - return false; - } - - // Read up to 128k save - fread(flashSaveMemory, 1, FLASH_128K_SZ, file); - - fclose(file); - CPUReset(); - return true; -} - - -bool CPUWriteGSASnapshot(const char *fileName, - const char *title, - const char *desc, - const char *notes) -{ - FILE *file = fopen(fileName, "wb"); - - if(!file) { - systemMessage(MSG_CANNOT_OPEN_FILE, N_("Cannot open file %s"), fileName); - return false; - } - - u8 buffer[17]; - - utilPutDword(buffer, 0x0d); // SharkPortSave length - fwrite(buffer, 1, 4, file); - fwrite("SharkPortSave", 1, 0x0d, file); - utilPutDword(buffer, 0x000f0000); - fwrite(buffer, 1, 4, file); // save type 0x000f0000 = GBA save - utilPutDword(buffer, (u32)strlen(title)); - fwrite(buffer, 1, 4, file); // title length - fwrite(title, 1, strlen(title), file); - utilPutDword(buffer, (u32)strlen(desc)); - fwrite(buffer, 1, 4, file); // desc length - fwrite(desc, 1, strlen(desc), file); - utilPutDword(buffer, (u32)strlen(notes)); - fwrite(buffer, 1, 4, file); // notes length - fwrite(notes, 1, strlen(notes), file); - int saveSize = 0x10000; - if(gbaSaveType == 2) - saveSize = flashSize; - int totalSize = saveSize + 0x1c; - - utilPutDword(buffer, totalSize); // length of remainder of save - CRC - fwrite(buffer, 1, 4, file); - - char *temp = new char[0x2001c]; - memset(temp, 0, 28); - memcpy(temp, &rom[0xa0], 16); // copy internal name - temp[0x10] = rom[0xbe]; // reserved area (old checksum) - temp[0x11] = rom[0xbf]; // reserved area (old checksum) - temp[0x12] = rom[0xbd]; // complement check - temp[0x13] = rom[0xb0]; // maker - temp[0x14] = 1; // 1 save ? - memcpy(&temp[0x1c], flashSaveMemory, saveSize); // copy save - fwrite(temp, 1, totalSize, file); // write save + header - u32 crc = 0; - - for(int i = 0; i < totalSize; i++) { - crc += ((u32)temp[i] << (crc % 0x18)); - } - - utilPutDword(buffer, crc); - fwrite(buffer, 1, 4, file); // CRC? - - fclose(file); - delete [] temp; - return true; -} - -bool CPUImportEepromFile(const char *fileName) -{ - FILE *file = fopen(fileName, "rb"); - - if(!file) - return false; - - // check file size to know what we should read - fseek(file, 0, SEEK_END); - - long size = ftell(file); - fseek(file, 0, SEEK_SET); - if(size == 512 || size == 0x2000) { - if(fread(eepromData, 1, size, file) != (size_t)size) { - fclose(file); - return false; - } - for(int i = 0; i < size;) { - u8 tmp = eepromData[i]; - eepromData[i] = eepromData[7-i]; - eepromData[7-i] = tmp; - i++; - tmp = eepromData[i]; - eepromData[i] = eepromData[7-i]; - eepromData[7-i] = tmp; - i++; - tmp = eepromData[i]; - eepromData[i] = eepromData[7-i]; - eepromData[7-i] = tmp; - i++; - tmp = eepromData[i]; - eepromData[i] = eepromData[7-i]; - eepromData[7-i] = tmp; - i++; - i += 4; - } - } else { - fclose(file); - return false; - } - fclose(file); - return true; -} - -bool CPUReadBatteryFile(const char *fileName) -{ - FILE *file = fopen(fileName, "rb"); - - if(!file) - return false; - - // check file size to know what we should read - fseek(file, 0, SEEK_END); - - long size = ftell(file); - fseek(file, 0, SEEK_SET); - systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED; - - if(size == 512 || size == 0x2000) { - if(fread(eepromData, 1, size, file) != (size_t)size) { - fclose(file); - return false; - } - } else { - if(size == 0x20000) { - if(fread(flashSaveMemory, 1, 0x20000, file) != 0x20000) { + if (memcmp(romname, savename, namesz)) { + systemMessage(MSG_CANNOT_IMPORT_SNAPSHOT_FOR, + N_("Cannot import snapshot for %s. Current game is %s"), + savename, + romname); fclose(file); return false; - } - flashSetSize(0x20000); - } else if(size == 0x10000) { - if(fread(flashSaveMemory, 1, 0x10000, file) != 0x10000) { + } + + // read footer tag + fseek(file, footerpos, SEEK_SET); + fread(footer, 1, footersz, file); + footer[footersz] = 0; + + if (memcmp(footer, gsvfooter, footersz)) { + systemMessage(0, + N_("Unsupported snapshot file %s. Footer '%s' at %u should be '%s'"), + fileName, + footer, + footerpos, + gsvfooter); fclose(file); return false; - } - flashSetSize(0x10000); - } else if (size == 0x8000) { - if (fread(flashSaveMemory, 1, 0x8000, file) != 0x8000) { - fclose(file); - return false; - } } - } - fclose(file); - return true; + + // Read up to 128k save + fread(flashSaveMemory, 1, FLASH_128K_SZ, file); + + fclose(file); + CPUReset(); + return true; } -bool CPUWritePNGFile(const char *fileName) +bool CPUWriteGSASnapshot(const char* fileName, + const char* title, + const char* desc, + const char* notes) { - return utilWritePNGFile(fileName, 240, 160, pix); -} + FILE* file = fopen(fileName, "wb"); -bool CPUWriteBMPFile(const char *fileName) -{ - return utilWriteBMPFile(fileName, 240, 160, pix); -} - -bool CPUIsZipFile(const char * file) -{ - if(strlen(file) > 4) { - const char * p = strrchr(file,'.'); - - if(p != NULL) { - if(_stricmp(p, ".zip") == 0) - return true; + if (!file) { + systemMessage(MSG_CANNOT_OPEN_FILE, N_("Cannot open file %s"), fileName); + return false; } - } - return false; + u8 buffer[17]; + + utilPutDword(buffer, 0x0d); // SharkPortSave length + fwrite(buffer, 1, 4, file); + fwrite("SharkPortSave", 1, 0x0d, file); + utilPutDword(buffer, 0x000f0000); + fwrite(buffer, 1, 4, file); // save type 0x000f0000 = GBA save + utilPutDword(buffer, (u32)strlen(title)); + fwrite(buffer, 1, 4, file); // title length + fwrite(title, 1, strlen(title), file); + utilPutDword(buffer, (u32)strlen(desc)); + fwrite(buffer, 1, 4, file); // desc length + fwrite(desc, 1, strlen(desc), file); + utilPutDword(buffer, (u32)strlen(notes)); + fwrite(buffer, 1, 4, file); // notes length + fwrite(notes, 1, strlen(notes), file); + int saveSize = 0x10000; + if (gbaSaveType == 2) + saveSize = flashSize; + int totalSize = saveSize + 0x1c; + + utilPutDword(buffer, totalSize); // length of remainder of save - CRC + fwrite(buffer, 1, 4, file); + + char* temp = new char[0x2001c]; + memset(temp, 0, 28); + memcpy(temp, &rom[0xa0], 16); // copy internal name + temp[0x10] = rom[0xbe]; // reserved area (old checksum) + temp[0x11] = rom[0xbf]; // reserved area (old checksum) + temp[0x12] = rom[0xbd]; // complement check + temp[0x13] = rom[0xb0]; // maker + temp[0x14] = 1; // 1 save ? + memcpy(&temp[0x1c], flashSaveMemory, saveSize); // copy save + fwrite(temp, 1, totalSize, file); // write save + header + u32 crc = 0; + + for (int i = 0; i < totalSize; i++) { + crc += ((u32)temp[i] << (crc % 0x18)); + } + + utilPutDword(buffer, crc); + fwrite(buffer, 1, 4, file); // CRC? + + fclose(file); + delete[] temp; + return true; } -bool CPUIsGBAImage(const char * file) +bool CPUImportEepromFile(const char* fileName) { - cpuIsMultiBoot = false; - if(strlen(file) > 4) { - const char * p = strrchr(file,'.'); + FILE* file = fopen(fileName, "rb"); - if(p != NULL) { - if(_stricmp(p, ".gba") == 0) - return true; - if(_stricmp(p, ".agb") == 0) - return true; - if(_stricmp(p, ".bin") == 0) - return true; - if(_stricmp(p, ".elf") == 0) - return true; - if(_stricmp(p, ".mb") == 0) { - cpuIsMultiBoot = true; - return true; - } + if (!file) + return false; + + // check file size to know what we should read + fseek(file, 0, SEEK_END); + + long size = ftell(file); + fseek(file, 0, SEEK_SET); + if (size == 512 || size == 0x2000) { + if (fread(eepromData, 1, size, file) != (size_t)size) { + fclose(file); + return false; + } + for (int i = 0; i < size;) { + u8 tmp = eepromData[i]; + eepromData[i] = eepromData[7 - i]; + eepromData[7 - i] = tmp; + i++; + tmp = eepromData[i]; + eepromData[i] = eepromData[7 - i]; + eepromData[7 - i] = tmp; + i++; + tmp = eepromData[i]; + eepromData[i] = eepromData[7 - i]; + eepromData[7 - i] = tmp; + i++; + tmp = eepromData[i]; + eepromData[i] = eepromData[7 - i]; + eepromData[7 - i] = tmp; + i++; + i += 4; + } + } else { + fclose(file); + return false; } - } - - return false; + fclose(file); + return true; } -bool CPUIsGBABios(const char * file) +bool CPUReadBatteryFile(const char* fileName) { - if(strlen(file) > 4) { - const char * p = strrchr(file,'.'); + FILE* file = fopen(fileName, "rb"); - if(p != NULL) { - if(_stricmp(p, ".gba") == 0) - return true; - if(_stricmp(p, ".agb") == 0) - return true; - if(_stricmp(p, ".bin") == 0) - return true; - if(_stricmp(p, ".bios") == 0) - return true; - if(_stricmp(p, ".rom") == 0) - return true; + if (!file) + return false; + + // check file size to know what we should read + fseek(file, 0, SEEK_END); + + long size = ftell(file); + fseek(file, 0, SEEK_SET); + systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED; + + if (size == 512 || size == 0x2000) { + if (fread(eepromData, 1, size, file) != (size_t)size) { + fclose(file); + return false; + } + } else { + if (size == 0x20000) { + if (fread(flashSaveMemory, 1, 0x20000, file) != 0x20000) { + fclose(file); + return false; + } + flashSetSize(0x20000); + } else if (size == 0x10000) { + if (fread(flashSaveMemory, 1, 0x10000, file) != 0x10000) { + fclose(file); + return false; + } + flashSetSize(0x10000); + } else if (size == 0x8000) { + if (fread(flashSaveMemory, 1, 0x8000, file) != 0x8000) { + fclose(file); + return false; + } + } } - } - - return false; + fclose(file); + return true; } -bool CPUIsELF(const char *file) +bool CPUWritePNGFile(const char* fileName) { - if(file == NULL) - return false; + return utilWritePNGFile(fileName, 240, 160, pix); +} - if(strlen(file) > 4) { - const char * p = strrchr(file,'.'); +bool CPUWriteBMPFile(const char* fileName) +{ + return utilWriteBMPFile(fileName, 240, 160, pix); +} - if(p != NULL) { - if(_stricmp(p, ".elf") == 0) - return true; +bool CPUIsZipFile(const char* file) +{ + if (strlen(file) > 4) { + const char* p = strrchr(file, '.'); + + if (p != NULL) { + if (_stricmp(p, ".zip") == 0) + return true; + } } - } - return false; + + return false; +} + +bool CPUIsGBAImage(const char* file) +{ + cpuIsMultiBoot = false; + if (strlen(file) > 4) { + const char* p = strrchr(file, '.'); + + if (p != NULL) { + if (_stricmp(p, ".gba") == 0) + return true; + if (_stricmp(p, ".agb") == 0) + return true; + if (_stricmp(p, ".bin") == 0) + return true; + if (_stricmp(p, ".elf") == 0) + return true; + if (_stricmp(p, ".mb") == 0) { + cpuIsMultiBoot = true; + return true; + } + } + } + + return false; +} + +bool CPUIsGBABios(const char* file) +{ + if (strlen(file) > 4) { + const char* p = strrchr(file, '.'); + + if (p != NULL) { + if (_stricmp(p, ".gba") == 0) + return true; + if (_stricmp(p, ".agb") == 0) + return true; + if (_stricmp(p, ".bin") == 0) + return true; + if (_stricmp(p, ".bios") == 0) + return true; + if (_stricmp(p, ".rom") == 0) + return true; + } + } + + return false; +} + +bool CPUIsELF(const char* file) +{ + if (file == NULL) + return false; + + if (strlen(file) > 4) { + const char* p = strrchr(file, '.'); + + if (p != NULL) { + if (_stricmp(p, ".elf") == 0) + return true; + } + } + return false; } void CPUCleanUp() { #ifdef PROFILING - if(profilingTicksReload) { - profCleanup(); - } + if (profilingTicksReload) { + profCleanup(); + } #endif - if(rom != NULL) { - free(rom); - rom = NULL; - } + if (rom != NULL) { + free(rom); + rom = NULL; + } - if(vram != NULL) { - free(vram); - vram = NULL; - } + if (vram != NULL) { + free(vram); + vram = NULL; + } - if(paletteRAM != NULL) { - free(paletteRAM); - paletteRAM = NULL; - } + if (paletteRAM != NULL) { + free(paletteRAM); + paletteRAM = NULL; + } - if(internalRAM != NULL) { - free(internalRAM); - internalRAM = NULL; - } + if (internalRAM != NULL) { + free(internalRAM); + internalRAM = NULL; + } - if(workRAM != NULL) { - free(workRAM); - workRAM = NULL; - } + if (workRAM != NULL) { + free(workRAM); + workRAM = NULL; + } - if(bios != NULL) { - free(bios); - bios = NULL; - } + if (bios != NULL) { + free(bios); + bios = NULL; + } - if(pix != NULL) { - free(pix); - pix = NULL; - } + if (pix != NULL) { + free(pix); + pix = NULL; + } - if(oam != NULL) { - free(oam); - oam = NULL; - } + if (oam != NULL) { + free(oam); + oam = NULL; + } - if(ioMem != NULL) { - free(ioMem); - ioMem = NULL; - } + if (ioMem != NULL) { + free(ioMem); + ioMem = NULL; + } #ifndef NO_DEBUGGER - elfCleanUp(); + elfCleanUp(); #endif //NO_DEBUGGER - systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED; + systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED; - emulating = 0; + emulating = 0; } void SetMapMasks() { - map[0].mask = 0x3FFF; - map[2].mask = 0x3FFFF; - map[3].mask = 0x7FFF; - map[4].mask = 0x3FF; - map[5].mask = 0x3FF; - map[6].mask = 0x1FFFF; - map[7].mask = 0x3FF; - map[8].mask = 0x1FFFFFF; - map[9].mask = 0x1FFFFFF; - map[10].mask = 0x1FFFFFF; - map[12].mask = 0x1FFFFFF; - map[14].mask = 0xFFFF; + map[0].mask = 0x3FFF; + map[2].mask = 0x3FFFF; + map[3].mask = 0x7FFF; + map[4].mask = 0x3FF; + map[5].mask = 0x3FF; + map[6].mask = 0x1FFFF; + map[7].mask = 0x3FF; + map[8].mask = 0x1FFFFFF; + map[9].mask = 0x1FFFFFF; + map[10].mask = 0x1FFFFFF; + map[12].mask = 0x1FFFFFF; + map[14].mask = 0xFFFF; - for (int i = 0; i < 16; i++) { - map[i].size = map[i].mask + 1; - if (map[i].size > 0) { - map[i].trace = (u8 *)calloc(map[i].size >> 3, sizeof(u8)); + for (int i = 0; i < 16; i++) { + map[i].size = map[i].mask + 1; + if (map[i].size > 0) { + map[i].trace = (u8*)calloc(map[i].size >> 3, sizeof(u8)); - map[i].breakPoints = (u8 *)calloc(map[i].size >> 1, sizeof(u8)); //\\ + map[i].breakPoints = (u8*)calloc(map[i].size >> 1, sizeof(u8)); //\\ - if (map[i].trace == NULL || map[i].breakPoints == NULL) { - systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"), - "TRACE"); - } - } - else { - map[i].trace = NULL; - map[i].breakPoints = NULL; //\\ + if (map[i].trace == NULL || map[i].breakPoints == NULL) { + systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"), + "TRACE"); + } + } else { + map[i].trace = NULL; + map[i].breakPoints = NULL; //\\ - } - } - clearBreakRegList(); + } + } + clearBreakRegList(); } -int CPULoadRom(const char *szFile) +int CPULoadRom(const char* szFile) { - romSize = 0x2000000; - if(rom != NULL) { - CPUCleanUp(); - } + romSize = 0x2000000; + if (rom != NULL) { + CPUCleanUp(); + } - systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED; + systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED; - rom = (u8 *)malloc(0x2000000); - if(rom == NULL) { - systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"), - "ROM"); - return 0; - } - workRAM = (u8 *)calloc(1, 0x40000); - if(workRAM == NULL) { - systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"), - "WRAM"); - return 0; - } + rom = (u8*)malloc(0x2000000); + if (rom == NULL) { + systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"), + "ROM"); + return 0; + } + workRAM = (u8*)calloc(1, 0x40000); + if (workRAM == NULL) { + systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"), + "WRAM"); + return 0; + } - u8 *whereToLoad = cpuIsMultiBoot ? workRAM : rom; + u8* whereToLoad = cpuIsMultiBoot ? workRAM : rom; #ifndef NO_DEBUGGER - if(CPUIsELF(szFile)) { - FILE *f = fopen(szFile, "rb"); - if(!f) { - systemMessage(MSG_ERROR_OPENING_IMAGE, N_("Error opening image %s"), - szFile); - free(rom); - rom = NULL; - free(workRAM); - workRAM = NULL; - return 0; - } - bool res = elfRead(szFile, romSize, f); - if(!res || romSize == 0) { - free(rom); - rom = NULL; - free(workRAM); - workRAM = NULL; - elfCleanUp(); - return 0; - } - } else + if (CPUIsELF(szFile)) { + FILE* f = fopen(szFile, "rb"); + if (!f) { + systemMessage(MSG_ERROR_OPENING_IMAGE, N_("Error opening image %s"), + szFile); + free(rom); + rom = NULL; + free(workRAM); + workRAM = NULL; + return 0; + } + bool res = elfRead(szFile, romSize, f); + if (!res || romSize == 0) { + free(rom); + rom = NULL; + free(workRAM); + workRAM = NULL; + elfCleanUp(); + return 0; + } + } else #endif //NO_DEBUGGER - if(szFile!=NULL) - { - if(!utilLoad(szFile, - utilIsGBAImage, - whereToLoad, - romSize)) { - free(rom); - rom = NULL; - free(workRAM); - workRAM = NULL; - return 0; - } - } + if (szFile != NULL) { + if (!utilLoad(szFile, + utilIsGBAImage, + whereToLoad, + romSize)) { + free(rom); + rom = NULL; + free(workRAM); + workRAM = NULL; + return 0; + } + } - u16 *temp = (u16 *)(rom+((romSize+1)&~1)); - int i; - for(i = (romSize+1)&~1; i < 0x2000000; i+=2) { - WRITE16LE(temp, (i >> 1) & 0xFFFF); - temp++; - } + u16* temp = (u16*)(rom + ((romSize + 1) & ~1)); + int i; + for (i = (romSize + 1) & ~1; i < 0x2000000; i += 2) { + WRITE16LE(temp, (i >> 1) & 0xFFFF); + temp++; + } - bios = (u8 *)calloc(1,0x4000); - if(bios == NULL) { - systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"), - "BIOS"); - CPUCleanUp(); - return 0; - } - internalRAM = (u8 *)calloc(1,0x8000); - if(internalRAM == NULL) { - systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"), - "IRAM"); - CPUCleanUp(); - return 0; - } - paletteRAM = (u8 *)calloc(1,0x400); - if(paletteRAM == NULL) { - systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"), - "PRAM"); - CPUCleanUp(); - return 0; - } - vram = (u8 *)calloc(1, 0x20000); - if(vram == NULL) { - systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"), - "VRAM"); - CPUCleanUp(); - return 0; - } - oam = (u8 *)calloc(1, 0x400); - if(oam == NULL) { - systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"), - "OAM"); - CPUCleanUp(); - return 0; - } + bios = (u8*)calloc(1, 0x4000); + if (bios == NULL) { + systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"), + "BIOS"); + CPUCleanUp(); + return 0; + } + internalRAM = (u8*)calloc(1, 0x8000); + if (internalRAM == NULL) { + systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"), + "IRAM"); + CPUCleanUp(); + return 0; + } + paletteRAM = (u8*)calloc(1, 0x400); + if (paletteRAM == NULL) { + systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"), + "PRAM"); + CPUCleanUp(); + return 0; + } + vram = (u8*)calloc(1, 0x20000); + if (vram == NULL) { + systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"), + "VRAM"); + CPUCleanUp(); + return 0; + } + oam = (u8*)calloc(1, 0x400); + if (oam == NULL) { + systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"), + "OAM"); + CPUCleanUp(); + return 0; + } #ifdef __LIBRETRO__ - pix = (u8 *)calloc(1, 4 * 240 * 160); + pix = (u8*)calloc(1, 4 * 240 * 160); #else - pix = (u8 *)calloc(1, 4 * 241 * 162); + pix = (u8*)calloc(1, 4 * 241 * 162); #endif - if(pix == NULL) { - systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"), - "PIX"); - CPUCleanUp(); - return 0; - } - ioMem = (u8 *)calloc(1, 0x400); - if(ioMem == NULL) { - systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"), - "IO"); - CPUCleanUp(); - return 0; - } + if (pix == NULL) { + systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"), + "PIX"); + CPUCleanUp(); + return 0; + } + ioMem = (u8*)calloc(1, 0x400); + if (ioMem == NULL) { + systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"), + "IO"); + CPUCleanUp(); + return 0; + } - flashInit(); - eepromInit(); + flashInit(); + eepromInit(); - CPUUpdateRenderBuffers(true); + CPUUpdateRenderBuffers(true); - return romSize; + return romSize; } -int CPULoadRomData(const char *data, int size) +int CPULoadRomData(const char* data, int size) { - romSize = 0x2000000; - if(rom != NULL) { - CPUCleanUp(); - } + romSize = 0x2000000; + if (rom != NULL) { + CPUCleanUp(); + } - systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED; + systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED; - rom = (u8 *)malloc(0x2000000); - if(rom == NULL) { - systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"), - "ROM"); - return 0; - } - workRAM = (u8 *)calloc(1, 0x40000); - if(workRAM == NULL) { - systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"), - "WRAM"); - return 0; - } + rom = (u8*)malloc(0x2000000); + if (rom == NULL) { + systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"), + "ROM"); + return 0; + } + workRAM = (u8*)calloc(1, 0x40000); + if (workRAM == NULL) { + systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"), + "WRAM"); + return 0; + } - u8 *whereToLoad = cpuIsMultiBoot ? workRAM : rom; + u8* whereToLoad = cpuIsMultiBoot ? workRAM : rom; - romSize = size % 2 == 0 ? size : size + 1; - memcpy(whereToLoad, data, size); + romSize = size % 2 == 0 ? size : size + 1; + memcpy(whereToLoad, data, size); - u16 *temp = (u16 *)(rom+((romSize+1)&~1)); - int i; - for(i = (romSize+1)&~1; i < 0x2000000; i+=2) { - WRITE16LE(temp, (i >> 1) & 0xFFFF); - temp++; - } + u16* temp = (u16*)(rom + ((romSize + 1) & ~1)); + int i; + for (i = (romSize + 1) & ~1; i < 0x2000000; i += 2) { + WRITE16LE(temp, (i >> 1) & 0xFFFF); + temp++; + } - bios = (u8 *)calloc(1,0x4000); - if(bios == NULL) { - systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"), - "BIOS"); - CPUCleanUp(); - return 0; - } - internalRAM = (u8 *)calloc(1,0x8000); - if(internalRAM == NULL) { - systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"), - "IRAM"); - CPUCleanUp(); - return 0; - } - paletteRAM = (u8 *)calloc(1,0x400); - if(paletteRAM == NULL) { - systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"), - "PRAM"); - CPUCleanUp(); - return 0; - } - vram = (u8 *)calloc(1, 0x20000); - if(vram == NULL) { - systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"), - "VRAM"); - CPUCleanUp(); - return 0; - } - oam = (u8 *)calloc(1, 0x400); - if(oam == NULL) { - systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"), - "OAM"); - CPUCleanUp(); - return 0; - } + bios = (u8*)calloc(1, 0x4000); + if (bios == NULL) { + systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"), + "BIOS"); + CPUCleanUp(); + return 0; + } + internalRAM = (u8*)calloc(1, 0x8000); + if (internalRAM == NULL) { + systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"), + "IRAM"); + CPUCleanUp(); + return 0; + } + paletteRAM = (u8*)calloc(1, 0x400); + if (paletteRAM == NULL) { + systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"), + "PRAM"); + CPUCleanUp(); + return 0; + } + vram = (u8*)calloc(1, 0x20000); + if (vram == NULL) { + systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"), + "VRAM"); + CPUCleanUp(); + return 0; + } + oam = (u8*)calloc(1, 0x400); + if (oam == NULL) { + systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"), + "OAM"); + CPUCleanUp(); + return 0; + } #ifdef __LIBRETRO__ - pix = (u8 *)calloc(1, 4 * 240 * 160); + pix = (u8*)calloc(1, 4 * 240 * 160); #else - pix = (u8 *)calloc(1, 4 * 241 * 162); + pix = (u8*)calloc(1, 4 * 241 * 162); #endif - if(pix == NULL) { - systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"), - "PIX"); - CPUCleanUp(); - return 0; - } - ioMem = (u8 *)calloc(1, 0x400); - if(ioMem == NULL) { - systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"), - "IO"); - CPUCleanUp(); - return 0; - } + if (pix == NULL) { + systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"), + "PIX"); + CPUCleanUp(); + return 0; + } + ioMem = (u8*)calloc(1, 0x400); + if (ioMem == NULL) { + systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"), + "IO"); + CPUCleanUp(); + return 0; + } - flashInit(); - eepromInit(); + flashInit(); + eepromInit(); - CPUUpdateRenderBuffers(true); + CPUUpdateRenderBuffers(true); #ifdef BKPT_SUPPORT - SetMapMasks(); + SetMapMasks(); #endif - return romSize; + return romSize; } -void doMirroring (bool b) +void doMirroring(bool b) { - int romSizeRounded = romSize; - romSizeRounded--; - romSizeRounded |= romSizeRounded >> 1; - romSizeRounded |= romSizeRounded >> 2; - romSizeRounded |= romSizeRounded >> 4; - romSizeRounded |= romSizeRounded >> 8; - romSizeRounded |= romSizeRounded >> 16; - romSizeRounded++; - u32 mirroredRomSize = (((romSizeRounded) >> 20) & 0x3F) << 20; - u32 mirroredRomAddress = mirroredRomSize; - if ((mirroredRomSize <=0x800000) && (b)) - { - if (mirroredRomSize==0) - mirroredRomSize=0x100000; - while (mirroredRomAddress<0x01000000) - { - memcpy ((u16 *)(rom+mirroredRomAddress), (u16 *)(rom), mirroredRomSize); - mirroredRomAddress+=mirroredRomSize; + int romSizeRounded = romSize; + romSizeRounded--; + romSizeRounded |= romSizeRounded >> 1; + romSizeRounded |= romSizeRounded >> 2; + romSizeRounded |= romSizeRounded >> 4; + romSizeRounded |= romSizeRounded >> 8; + romSizeRounded |= romSizeRounded >> 16; + romSizeRounded++; + u32 mirroredRomSize = (((romSizeRounded) >> 20) & 0x3F) << 20; + u32 mirroredRomAddress = mirroredRomSize; + if ((mirroredRomSize <= 0x800000) && (b)) { + if (mirroredRomSize == 0) + mirroredRomSize = 0x100000; + while (mirroredRomAddress < 0x01000000) { + memcpy((u16*)(rom + mirroredRomAddress), (u16*)(rom), mirroredRomSize); + mirroredRomAddress += mirroredRomSize; + } } - } } const char* GetLoadDotCodeFile() { - return loadDotCodeFile; + return loadDotCodeFile; } const char* GetSaveDotCodeFile() { - return saveDotCodeFile; + return saveDotCodeFile; } -void SetLoadDotCodeFile(const char *szFile) +void SetLoadDotCodeFile(const char* szFile) { - loadDotCodeFile = strdup(szFile); + loadDotCodeFile = strdup(szFile); } -void SetSaveDotCodeFile(const char *szFile) +void SetSaveDotCodeFile(const char* szFile) { - saveDotCodeFile = strdup(szFile); + saveDotCodeFile = strdup(szFile); } void CPUUpdateRender() { - switch(DISPCNT & 7) { - case 0: - if((!fxOn && !windowOn && !(layerEnable & 0x8000)) || - cpuDisableSfx) - renderLine = mode0RenderLine; - else if(fxOn && !windowOn && !(layerEnable & 0x8000)) - renderLine = mode0RenderLineNoWindow; - else - renderLine = mode0RenderLineAll; - break; - case 1: - if((!fxOn && !windowOn && !(layerEnable & 0x8000)) || - cpuDisableSfx) - renderLine = mode1RenderLine; - else if(fxOn && !windowOn && !(layerEnable & 0x8000)) - renderLine = mode1RenderLineNoWindow; - else - renderLine = mode1RenderLineAll; - break; - case 2: - if((!fxOn && !windowOn && !(layerEnable & 0x8000)) || - cpuDisableSfx) - renderLine = mode2RenderLine; - else if(fxOn && !windowOn && !(layerEnable & 0x8000)) - renderLine = mode2RenderLineNoWindow; - else - renderLine = mode2RenderLineAll; - break; - case 3: - if((!fxOn && !windowOn && !(layerEnable & 0x8000)) || - cpuDisableSfx) - renderLine = mode3RenderLine; - else if(fxOn && !windowOn && !(layerEnable & 0x8000)) - renderLine = mode3RenderLineNoWindow; - else - renderLine = mode3RenderLineAll; - break; - case 4: - if((!fxOn && !windowOn && !(layerEnable & 0x8000)) || - cpuDisableSfx) - renderLine = mode4RenderLine; - else if(fxOn && !windowOn && !(layerEnable & 0x8000)) - renderLine = mode4RenderLineNoWindow; - else - renderLine = mode4RenderLineAll; - break; - case 5: - if((!fxOn && !windowOn && !(layerEnable & 0x8000)) || - cpuDisableSfx) - renderLine = mode5RenderLine; - else if(fxOn && !windowOn && !(layerEnable & 0x8000)) - renderLine = mode5RenderLineNoWindow; - else - renderLine = mode5RenderLineAll; - default: - break; - } + switch (DISPCNT & 7) { + case 0: + if ((!fxOn && !windowOn && !(layerEnable & 0x8000)) || cpuDisableSfx) + renderLine = mode0RenderLine; + else if (fxOn && !windowOn && !(layerEnable & 0x8000)) + renderLine = mode0RenderLineNoWindow; + else + renderLine = mode0RenderLineAll; + break; + case 1: + if ((!fxOn && !windowOn && !(layerEnable & 0x8000)) || cpuDisableSfx) + renderLine = mode1RenderLine; + else if (fxOn && !windowOn && !(layerEnable & 0x8000)) + renderLine = mode1RenderLineNoWindow; + else + renderLine = mode1RenderLineAll; + break; + case 2: + if ((!fxOn && !windowOn && !(layerEnable & 0x8000)) || cpuDisableSfx) + renderLine = mode2RenderLine; + else if (fxOn && !windowOn && !(layerEnable & 0x8000)) + renderLine = mode2RenderLineNoWindow; + else + renderLine = mode2RenderLineAll; + break; + case 3: + if ((!fxOn && !windowOn && !(layerEnable & 0x8000)) || cpuDisableSfx) + renderLine = mode3RenderLine; + else if (fxOn && !windowOn && !(layerEnable & 0x8000)) + renderLine = mode3RenderLineNoWindow; + else + renderLine = mode3RenderLineAll; + break; + case 4: + if ((!fxOn && !windowOn && !(layerEnable & 0x8000)) || cpuDisableSfx) + renderLine = mode4RenderLine; + else if (fxOn && !windowOn && !(layerEnable & 0x8000)) + renderLine = mode4RenderLineNoWindow; + else + renderLine = mode4RenderLineAll; + break; + case 5: + if ((!fxOn && !windowOn && !(layerEnable & 0x8000)) || cpuDisableSfx) + renderLine = mode5RenderLine; + else if (fxOn && !windowOn && !(layerEnable & 0x8000)) + renderLine = mode5RenderLineNoWindow; + else + renderLine = mode5RenderLineAll; + default: + break; + } } void CPUUpdateCPSR() { - u32 CPSR = reg[16].I & 0x40; - if(N_FLAG) - CPSR |= 0x80000000; - if(Z_FLAG) - CPSR |= 0x40000000; - if(C_FLAG) - CPSR |= 0x20000000; - if(V_FLAG) - CPSR |= 0x10000000; - if(!armState) - CPSR |= 0x00000020; - if(!armIrqEnable) - CPSR |= 0x80; - CPSR |= (armMode & 0x1F); - reg[16].I = CPSR; + u32 CPSR = reg[16].I & 0x40; + if (N_FLAG) + CPSR |= 0x80000000; + if (Z_FLAG) + CPSR |= 0x40000000; + if (C_FLAG) + CPSR |= 0x20000000; + if (V_FLAG) + CPSR |= 0x10000000; + if (!armState) + CPSR |= 0x00000020; + if (!armIrqEnable) + CPSR |= 0x80; + CPSR |= (armMode & 0x1F); + reg[16].I = CPSR; } void CPUUpdateFlags(bool breakLoop) { - u32 CPSR = reg[16].I; + u32 CPSR = reg[16].I; - N_FLAG = (CPSR & 0x80000000) ? true: false; - Z_FLAG = (CPSR & 0x40000000) ? true: false; - C_FLAG = (CPSR & 0x20000000) ? true: false; - V_FLAG = (CPSR & 0x10000000) ? true: false; - armState = (CPSR & 0x20) ? false : true; - armIrqEnable = (CPSR & 0x80) ? false : true; - if(breakLoop) { - if (armIrqEnable && (IF & IE) && (IME & 1)) - cpuNextEvent = cpuTotalTicks; - } + N_FLAG = (CPSR & 0x80000000) ? true : false; + Z_FLAG = (CPSR & 0x40000000) ? true : false; + C_FLAG = (CPSR & 0x20000000) ? true : false; + V_FLAG = (CPSR & 0x10000000) ? true : false; + armState = (CPSR & 0x20) ? false : true; + armIrqEnable = (CPSR & 0x80) ? false : true; + if (breakLoop) { + if (armIrqEnable && (IF & IE) && (IME & 1)) + cpuNextEvent = cpuTotalTicks; + } } void CPUUpdateFlags() { - CPUUpdateFlags(true); + CPUUpdateFlags(true); } #ifdef WORDS_BIGENDIAN -static void CPUSwap(volatile u32 *a, volatile u32 *b) +static void CPUSwap(volatile u32* a, volatile u32* b) { - volatile u32 c = *b; - *b = *a; - *a = c; + volatile u32 c = *b; + *b = *a; + *a = c; } #else -static void CPUSwap(u32 *a, u32 *b) +static void CPUSwap(u32* a, u32* b) { - u32 c = *b; - *b = *a; - *a = c; + u32 c = *b; + *b = *a; + *a = c; } #endif void CPUSwitchMode(int mode, bool saveState, bool breakLoop) { - // if(armMode == mode) - // return; + // if(armMode == mode) + // return; - CPUUpdateCPSR(); + CPUUpdateCPSR(); - switch(armMode) { - case 0x10: - case 0x1F: - reg[R13_USR].I = reg[13].I; - reg[R14_USR].I = reg[14].I; - reg[17].I = reg[16].I; - break; - case 0x11: - CPUSwap(®[R8_FIQ].I, ®[8].I); - CPUSwap(®[R9_FIQ].I, ®[9].I); - CPUSwap(®[R10_FIQ].I, ®[10].I); - CPUSwap(®[R11_FIQ].I, ®[11].I); - CPUSwap(®[R12_FIQ].I, ®[12].I); - reg[R13_FIQ].I = reg[13].I; - reg[R14_FIQ].I = reg[14].I; - reg[SPSR_FIQ].I = reg[17].I; - break; - case 0x12: - reg[R13_IRQ].I = reg[13].I; - reg[R14_IRQ].I = reg[14].I; - reg[SPSR_IRQ].I = reg[17].I; - break; - case 0x13: - reg[R13_SVC].I = reg[13].I; - reg[R14_SVC].I = reg[14].I; - reg[SPSR_SVC].I = reg[17].I; - break; - case 0x17: - reg[R13_ABT].I = reg[13].I; - reg[R14_ABT].I = reg[14].I; - reg[SPSR_ABT].I = reg[17].I; - break; - case 0x1b: - reg[R13_UND].I = reg[13].I; - reg[R14_UND].I = reg[14].I; - reg[SPSR_UND].I = reg[17].I; - break; - } + switch (armMode) { + case 0x10: + case 0x1F: + reg[R13_USR].I = reg[13].I; + reg[R14_USR].I = reg[14].I; + reg[17].I = reg[16].I; + break; + case 0x11: + CPUSwap(®[R8_FIQ].I, ®[8].I); + CPUSwap(®[R9_FIQ].I, ®[9].I); + CPUSwap(®[R10_FIQ].I, ®[10].I); + CPUSwap(®[R11_FIQ].I, ®[11].I); + CPUSwap(®[R12_FIQ].I, ®[12].I); + reg[R13_FIQ].I = reg[13].I; + reg[R14_FIQ].I = reg[14].I; + reg[SPSR_FIQ].I = reg[17].I; + break; + case 0x12: + reg[R13_IRQ].I = reg[13].I; + reg[R14_IRQ].I = reg[14].I; + reg[SPSR_IRQ].I = reg[17].I; + break; + case 0x13: + reg[R13_SVC].I = reg[13].I; + reg[R14_SVC].I = reg[14].I; + reg[SPSR_SVC].I = reg[17].I; + break; + case 0x17: + reg[R13_ABT].I = reg[13].I; + reg[R14_ABT].I = reg[14].I; + reg[SPSR_ABT].I = reg[17].I; + break; + case 0x1b: + reg[R13_UND].I = reg[13].I; + reg[R14_UND].I = reg[14].I; + reg[SPSR_UND].I = reg[17].I; + break; + } - u32 CPSR = reg[16].I; - u32 SPSR = reg[17].I; + u32 CPSR = reg[16].I; + u32 SPSR = reg[17].I; - switch(mode) { - case 0x10: - case 0x1F: - reg[13].I = reg[R13_USR].I; - reg[14].I = reg[R14_USR].I; - reg[16].I = SPSR; - break; - case 0x11: - CPUSwap(®[8].I, ®[R8_FIQ].I); - CPUSwap(®[9].I, ®[R9_FIQ].I); - CPUSwap(®[10].I, ®[R10_FIQ].I); - CPUSwap(®[11].I, ®[R11_FIQ].I); - CPUSwap(®[12].I, ®[R12_FIQ].I); - reg[13].I = reg[R13_FIQ].I; - reg[14].I = reg[R14_FIQ].I; - if(saveState) - reg[17].I = CPSR; - else - reg[17].I = reg[SPSR_FIQ].I; - break; - case 0x12: - reg[13].I = reg[R13_IRQ].I; - reg[14].I = reg[R14_IRQ].I; - reg[16].I = SPSR; - if(saveState) - reg[17].I = CPSR; - else - reg[17].I = reg[SPSR_IRQ].I; - break; - case 0x13: - reg[13].I = reg[R13_SVC].I; - reg[14].I = reg[R14_SVC].I; - reg[16].I = SPSR; - if(saveState) - reg[17].I = CPSR; - else - reg[17].I = reg[SPSR_SVC].I; - break; - case 0x17: - reg[13].I = reg[R13_ABT].I; - reg[14].I = reg[R14_ABT].I; - reg[16].I = SPSR; - if(saveState) - reg[17].I = CPSR; - else - reg[17].I = reg[SPSR_ABT].I; - break; - case 0x1b: - reg[13].I = reg[R13_UND].I; - reg[14].I = reg[R14_UND].I; - reg[16].I = SPSR; - if(saveState) - reg[17].I = CPSR; - else - reg[17].I = reg[SPSR_UND].I; - break; - default: - systemMessage(MSG_UNSUPPORTED_ARM_MODE, N_("Unsupported ARM mode %02x"), mode); - break; - } - armMode = mode; - CPUUpdateFlags(breakLoop); - CPUUpdateCPSR(); + switch (mode) { + case 0x10: + case 0x1F: + reg[13].I = reg[R13_USR].I; + reg[14].I = reg[R14_USR].I; + reg[16].I = SPSR; + break; + case 0x11: + CPUSwap(®[8].I, ®[R8_FIQ].I); + CPUSwap(®[9].I, ®[R9_FIQ].I); + CPUSwap(®[10].I, ®[R10_FIQ].I); + CPUSwap(®[11].I, ®[R11_FIQ].I); + CPUSwap(®[12].I, ®[R12_FIQ].I); + reg[13].I = reg[R13_FIQ].I; + reg[14].I = reg[R14_FIQ].I; + if (saveState) + reg[17].I = CPSR; + else + reg[17].I = reg[SPSR_FIQ].I; + break; + case 0x12: + reg[13].I = reg[R13_IRQ].I; + reg[14].I = reg[R14_IRQ].I; + reg[16].I = SPSR; + if (saveState) + reg[17].I = CPSR; + else + reg[17].I = reg[SPSR_IRQ].I; + break; + case 0x13: + reg[13].I = reg[R13_SVC].I; + reg[14].I = reg[R14_SVC].I; + reg[16].I = SPSR; + if (saveState) + reg[17].I = CPSR; + else + reg[17].I = reg[SPSR_SVC].I; + break; + case 0x17: + reg[13].I = reg[R13_ABT].I; + reg[14].I = reg[R14_ABT].I; + reg[16].I = SPSR; + if (saveState) + reg[17].I = CPSR; + else + reg[17].I = reg[SPSR_ABT].I; + break; + case 0x1b: + reg[13].I = reg[R13_UND].I; + reg[14].I = reg[R14_UND].I; + reg[16].I = SPSR; + if (saveState) + reg[17].I = CPSR; + else + reg[17].I = reg[SPSR_UND].I; + break; + default: + systemMessage(MSG_UNSUPPORTED_ARM_MODE, N_("Unsupported ARM mode %02x"), mode); + break; + } + armMode = mode; + CPUUpdateFlags(breakLoop); + CPUUpdateCPSR(); } void CPUSwitchMode(int mode, bool saveState) { - CPUSwitchMode(mode, saveState, true); + CPUSwitchMode(mode, saveState, true); } void CPUUndefinedException() { - u32 PC = reg[15].I; - bool savedArmState = armState; - CPUSwitchMode(0x1b, true, false); - reg[14].I = PC - (savedArmState ? 4 : 2); - reg[15].I = 0x04; - armState = true; - armIrqEnable = false; - armNextPC = 0x04; - ARM_PREFETCH; - reg[15].I += 4; + u32 PC = reg[15].I; + bool savedArmState = armState; + CPUSwitchMode(0x1b, true, false); + reg[14].I = PC - (savedArmState ? 4 : 2); + reg[15].I = 0x04; + armState = true; + armIrqEnable = false; + armNextPC = 0x04; + ARM_PREFETCH; + reg[15].I += 4; } void CPUSoftwareInterrupt() { - u32 PC = reg[15].I; - bool savedArmState = armState; - CPUSwitchMode(0x13, true, false); - reg[14].I = PC - (savedArmState ? 4 : 2); - reg[15].I = 0x08; - armState = true; - armIrqEnable = false; - armNextPC = 0x08; - ARM_PREFETCH; - reg[15].I += 4; + u32 PC = reg[15].I; + bool savedArmState = armState; + CPUSwitchMode(0x13, true, false); + reg[14].I = PC - (savedArmState ? 4 : 2); + reg[15].I = 0x08; + armState = true; + armIrqEnable = false; + armNextPC = 0x08; + ARM_PREFETCH; + reg[15].I += 4; } void CPUSoftwareInterrupt(int comment) { - static bool disableMessage = false; - if(armState) comment >>= 16; + static bool disableMessage = false; + if (armState) + comment >>= 16; #ifdef BKPT_SUPPORT - if(comment == 0xff) { - dbgOutput(NULL, reg[0].I); - return; - } + if (comment == 0xff) { + dbgOutput(NULL, reg[0].I); + return; + } #endif #ifdef PROFILING - if(comment == 0xfe) { - profStartup(reg[0].I, reg[1].I); - return; - } - if(comment == 0xfd) { - profControl(reg[0].I); - return; - } - if(comment == 0xfc) { - profCleanup(); - return; - } - if(comment == 0xfb) { - profCount(); - return; - } + if (comment == 0xfe) { + profStartup(reg[0].I, reg[1].I); + return; + } + if (comment == 0xfd) { + profControl(reg[0].I); + return; + } + if (comment == 0xfc) { + profCleanup(); + return; + } + if (comment == 0xfb) { + profCount(); + return; + } #endif - if(comment == 0xfa) { - agbPrintFlush(); - return; - } + if (comment == 0xfa) { + agbPrintFlush(); + return; + } #ifdef SDL - if(comment == 0xf9) { - emulating = 0; - cpuNextEvent = cpuTotalTicks; - cpuBreakLoop = true; - return; - } -#endif - if(useBios) { -#ifdef GBA_LOGGING - if(systemVerbose & VERBOSE_SWI) { - log("SWI: %08x at %08x (0x%08x,0x%08x,0x%08x,VCOUNT = %2d)\n", comment, - armState ? armNextPC - 4: armNextPC -2, - reg[0].I, - reg[1].I, - reg[2].I, - VCOUNT); + if (comment == 0xf9) { + emulating = 0; + cpuNextEvent = cpuTotalTicks; + cpuBreakLoop = true; + return; } #endif - if ((comment & 0xF8) != 0xE0) - { - CPUSoftwareInterrupt(); - return; - } - else - { - if (CheckEReaderRegion()) - BIOS_EReader_ScanCard(comment); - else - CPUSoftwareInterrupt(); - return; - } - } - // This would be correct, but it causes problems if uncommented - // else { - // biosProtected = 0xe3a02004; - // } + if (useBios) { +#ifdef GBA_LOGGING + if (systemVerbose & VERBOSE_SWI) { + log("SWI: %08x at %08x (0x%08x,0x%08x,0x%08x,VCOUNT = %2d)\n", comment, + armState ? armNextPC - 4 : armNextPC - 2, + reg[0].I, + reg[1].I, + reg[2].I, + VCOUNT); + } +#endif + if ((comment & 0xF8) != 0xE0) { + CPUSoftwareInterrupt(); + return; + } else { + if (CheckEReaderRegion()) + BIOS_EReader_ScanCard(comment); + else + CPUSoftwareInterrupt(); + return; + } + } + // This would be correct, but it causes problems if uncommented + // else { + // biosProtected = 0xe3a02004; + // } - switch(comment) { - case 0x00: - BIOS_SoftReset(); - ARM_PREFETCH; - break; - case 0x01: - BIOS_RegisterRamReset(); - break; - case 0x02: + switch (comment) { + case 0x00: + BIOS_SoftReset(); + ARM_PREFETCH; + break; + case 0x01: + BIOS_RegisterRamReset(); + break; + case 0x02: #ifdef GBA_LOGGING - if(systemVerbose & VERBOSE_SWI) { - /*log("Halt: (VCOUNT = %2d)\n", + if (systemVerbose & VERBOSE_SWI) { + /*log("Halt: (VCOUNT = %2d)\n", VCOUNT);*/ - } + } #endif - holdState = true; - holdType = -1; - cpuNextEvent = cpuTotalTicks; - break; - case 0x03: + holdState = true; + holdType = -1; + cpuNextEvent = cpuTotalTicks; + break; + case 0x03: #ifdef GBA_LOGGING - if(systemVerbose & VERBOSE_SWI) { - /*log("Stop: (VCOUNT = %2d)\n", + if (systemVerbose & VERBOSE_SWI) { + /*log("Stop: (VCOUNT = %2d)\n", VCOUNT);*/ - } -#endif - holdState = true; - holdType = -1; - stopState = true; - cpuNextEvent = cpuTotalTicks; - break; - case 0x04: -#ifdef GBA_LOGGING - if(systemVerbose & VERBOSE_SWI) { - log("IntrWait: 0x%08x,0x%08x (VCOUNT = %2d)\n", - reg[0].I, - reg[1].I, - VCOUNT); - } -#endif - CPUSoftwareInterrupt(); - break; - case 0x05: -#ifdef GBA_LOGGING - if(systemVerbose & VERBOSE_SWI) { - log("VBlankIntrWait: (VCOUNT = %2d)\n", - VCOUNT); - } -#endif - CPUSoftwareInterrupt(); - break; - case 0x06: - CPUSoftwareInterrupt(); - break; - case 0x07: - CPUSoftwareInterrupt(); - break; - case 0x08: - BIOS_Sqrt(); - break; - case 0x09: - BIOS_ArcTan(); - break; - case 0x0A: - BIOS_ArcTan2(); - break; - case 0x0B: - { - int len = (reg[2].I & 0x1FFFFF) >>1; - if (!(((reg[0].I & 0xe000000) == 0) || - ((reg[0].I + len) & 0xe000000) == 0)) - { - if ((reg[2].I >> 24) & 1) - { - if ((reg[2].I >> 26) & 1) - SWITicks = (7 + memoryWait32[(reg[1].I>>24) & 0xF]) * (len>>1); - else - SWITicks = (8 + memoryWait[(reg[1].I>>24) & 0xF]) * (len); } - else - { - if ((reg[2].I >> 26) & 1) - SWITicks = (10 + memoryWait32[(reg[0].I>>24) & 0xF] + - memoryWait32[(reg[1].I>>24) & 0xF]) * (len>>1); - else - SWITicks = (11 + memoryWait[(reg[0].I>>24) & 0xF] + - memoryWait[(reg[1].I>>24) & 0xF]) * len; - } - } - } - BIOS_CpuSet(); - break; - case 0x0C: - { - int len = (reg[2].I & 0x1FFFFF) >>5; - if (!(((reg[0].I & 0xe000000) == 0) || - ((reg[0].I + len) & 0xe000000) == 0)) - { - if ((reg[2].I >> 24) & 1) - SWITicks = (6 + memoryWait32[(reg[1].I>>24) & 0xF] + - 7 * (memoryWaitSeq32[(reg[1].I>>24) & 0xF] + 1)) * len; - else - SWITicks = (9 + memoryWait32[(reg[0].I>>24) & 0xF] + - memoryWait32[(reg[1].I>>24) & 0xF] + - 7 * (memoryWaitSeq32[(reg[0].I>>24) & 0xF] + - memoryWaitSeq32[(reg[1].I>>24) & 0xF] + 2)) * len; - } - } - BIOS_CpuFastSet(); - break; - case 0x0D: - BIOS_GetBiosChecksum(); - break; - case 0x0E: - BIOS_BgAffineSet(); - break; - case 0x0F: - BIOS_ObjAffineSet(); - break; - case 0x10: - { - int len = CPUReadHalfWord(reg[2].I); - if (!(((reg[0].I & 0xe000000) == 0) || - ((reg[0].I + len) & 0xe000000) == 0)) - SWITicks = (32 + memoryWait[(reg[0].I>>24) & 0xF]) * len; - } - BIOS_BitUnPack(); - break; - case 0x11: - { - u32 len = CPUReadMemory(reg[0].I) >> 8; - if(!(((reg[0].I & 0xe000000) == 0) || - ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0)) - SWITicks = (9 + memoryWait[(reg[1].I>>24) & 0xF]) * len; - } - BIOS_LZ77UnCompWram(); - break; - case 0x12: - { - u32 len = CPUReadMemory(reg[0].I) >> 8; - if(!(((reg[0].I & 0xe000000) == 0) || - ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0)) - SWITicks = (19 + memoryWait[(reg[1].I>>24) & 0xF]) * len; - } - BIOS_LZ77UnCompVram(); - break; - case 0x13: - { - u32 len = CPUReadMemory(reg[0].I) >> 8; - if(!(((reg[0].I & 0xe000000) == 0) || - ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0)) - SWITicks = (29 + (memoryWait[(reg[0].I>>24) & 0xF]<<1)) * len; - } - BIOS_HuffUnComp(); - break; - case 0x14: - { - u32 len = CPUReadMemory(reg[0].I) >> 8; - if(!(((reg[0].I & 0xe000000) == 0) || - ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0)) - SWITicks = (11 + memoryWait[(reg[0].I>>24) & 0xF] + - memoryWait[(reg[1].I>>24) & 0xF]) * len; - } - BIOS_RLUnCompWram(); - break; - case 0x15: - { - u32 len = CPUReadMemory(reg[0].I) >> 9; - if(!(((reg[0].I & 0xe000000) == 0) || - ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0)) - SWITicks = (34 + (memoryWait[(reg[0].I>>24) & 0xF] << 1) + - memoryWait[(reg[1].I>>24) & 0xF]) * len; - } - BIOS_RLUnCompVram(); - break; - case 0x16: - { - u32 len = CPUReadMemory(reg[0].I) >> 8; - if(!(((reg[0].I & 0xe000000) == 0) || - ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0)) - SWITicks = (13 + memoryWait[(reg[0].I>>24) & 0xF] + - memoryWait[(reg[1].I>>24) & 0xF]) * len; - } - BIOS_Diff8bitUnFilterWram(); - break; - case 0x17: - { - u32 len = CPUReadMemory(reg[0].I) >> 9; - if(!(((reg[0].I & 0xe000000) == 0) || - ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0)) - SWITicks = (39 + (memoryWait[(reg[0].I>>24) & 0xF]<<1) + - memoryWait[(reg[1].I>>24) & 0xF]) * len; - } - BIOS_Diff8bitUnFilterVram(); - break; - case 0x18: - { - u32 len = CPUReadMemory(reg[0].I) >> 9; - if(!(((reg[0].I & 0xe000000) == 0) || - ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0)) - SWITicks = (13 + memoryWait[(reg[0].I>>24) & 0xF] + - memoryWait[(reg[1].I>>24) & 0xF]) * len; - } - BIOS_Diff16bitUnFilter(); - break; - case 0x19: -#ifdef GBA_LOGGING - if(systemVerbose & VERBOSE_SWI) { - log("SoundBiasSet: 0x%08x (VCOUNT = %2d)\n", - reg[0].I, - VCOUNT); - } #endif - if(reg[0].I) - soundPause(); - else - soundResume(); - break; - case 0x1A: - BIOS_SndDriverInit(); - SWITicks = 252000; - break; - case 0x1B: - BIOS_SndDriverMode(); - SWITicks = 280000; - break; - case 0x1C: - BIOS_SndDriverMain(); - SWITicks = 11050;//avg - break; - case 0x1D: - BIOS_SndDriverVSync(); - SWITicks = 44; - break; - case 0x1E: - BIOS_SndChannelClear(); - break; - case 0x28: - BIOS_SndDriverVSyncOff(); - break; - case 0x1F: - BIOS_MidiKey2Freq(); - break; - case 0xE0: - case 0xE1: - case 0xE2: - case 0xE3: - case 0xE4: - case 0xE5: - case 0xE6: - case 0xE7: - if (CheckEReaderRegion()) - BIOS_EReader_ScanCard(comment); - break; - case 0x2A: - BIOS_SndDriverJmpTableCopy(); + holdState = true; + holdType = -1; + stopState = true; + cpuNextEvent = cpuTotalTicks; + break; + case 0x04: +#ifdef GBA_LOGGING + if (systemVerbose & VERBOSE_SWI) { + log("IntrWait: 0x%08x,0x%08x (VCOUNT = %2d)\n", + reg[0].I, + reg[1].I, + VCOUNT); + } +#endif + CPUSoftwareInterrupt(); + break; + case 0x05: +#ifdef GBA_LOGGING + if (systemVerbose & VERBOSE_SWI) { + log("VBlankIntrWait: (VCOUNT = %2d)\n", + VCOUNT); + } +#endif + CPUSoftwareInterrupt(); + break; + case 0x06: + CPUSoftwareInterrupt(); + break; + case 0x07: + CPUSoftwareInterrupt(); + break; + case 0x08: + BIOS_Sqrt(); + break; + case 0x09: + BIOS_ArcTan(); + break; + case 0x0A: + BIOS_ArcTan2(); + break; + case 0x0B: { + int len = (reg[2].I & 0x1FFFFF) >> 1; + if (!(((reg[0].I & 0xe000000) == 0) || ((reg[0].I + len) & 0xe000000) == 0)) { + if ((reg[2].I >> 24) & 1) { + if ((reg[2].I >> 26) & 1) + SWITicks = (7 + memoryWait32[(reg[1].I >> 24) & 0xF]) * (len >> 1); + else + SWITicks = (8 + memoryWait[(reg[1].I >> 24) & 0xF]) * (len); + } else { + if ((reg[2].I >> 26) & 1) + SWITicks = (10 + memoryWait32[(reg[0].I >> 24) & 0xF] + memoryWait32[(reg[1].I >> 24) & 0xF]) * (len >> 1); + else + SWITicks = (11 + memoryWait[(reg[0].I >> 24) & 0xF] + memoryWait[(reg[1].I >> 24) & 0xF]) * len; + } + } + } + BIOS_CpuSet(); + break; + case 0x0C: { + int len = (reg[2].I & 0x1FFFFF) >> 5; + if (!(((reg[0].I & 0xe000000) == 0) || ((reg[0].I + len) & 0xe000000) == 0)) { + if ((reg[2].I >> 24) & 1) + SWITicks = (6 + memoryWait32[(reg[1].I >> 24) & 0xF] + 7 * (memoryWaitSeq32[(reg[1].I >> 24) & 0xF] + 1)) * len; + else + SWITicks = (9 + memoryWait32[(reg[0].I >> 24) & 0xF] + memoryWait32[(reg[1].I >> 24) & 0xF] + 7 * (memoryWaitSeq32[(reg[0].I >> 24) & 0xF] + memoryWaitSeq32[(reg[1].I >> 24) & 0xF] + 2)) * len; + } + } + BIOS_CpuFastSet(); + break; + case 0x0D: + BIOS_GetBiosChecksum(); + break; + case 0x0E: + BIOS_BgAffineSet(); + break; + case 0x0F: + BIOS_ObjAffineSet(); + break; + case 0x10: { + int len = CPUReadHalfWord(reg[2].I); + if (!(((reg[0].I & 0xe000000) == 0) || ((reg[0].I + len) & 0xe000000) == 0)) + SWITicks = (32 + memoryWait[(reg[0].I >> 24) & 0xF]) * len; + } + BIOS_BitUnPack(); + break; + case 0x11: { + u32 len = CPUReadMemory(reg[0].I) >> 8; + if (!(((reg[0].I & 0xe000000) == 0) || ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0)) + SWITicks = (9 + memoryWait[(reg[1].I >> 24) & 0xF]) * len; + } + BIOS_LZ77UnCompWram(); + break; + case 0x12: { + u32 len = CPUReadMemory(reg[0].I) >> 8; + if (!(((reg[0].I & 0xe000000) == 0) || ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0)) + SWITicks = (19 + memoryWait[(reg[1].I >> 24) & 0xF]) * len; + } + BIOS_LZ77UnCompVram(); + break; + case 0x13: { + u32 len = CPUReadMemory(reg[0].I) >> 8; + if (!(((reg[0].I & 0xe000000) == 0) || ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0)) + SWITicks = (29 + (memoryWait[(reg[0].I >> 24) & 0xF] << 1)) * len; + } + BIOS_HuffUnComp(); + break; + case 0x14: { + u32 len = CPUReadMemory(reg[0].I) >> 8; + if (!(((reg[0].I & 0xe000000) == 0) || ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0)) + SWITicks = (11 + memoryWait[(reg[0].I >> 24) & 0xF] + memoryWait[(reg[1].I >> 24) & 0xF]) * len; + } + BIOS_RLUnCompWram(); + break; + case 0x15: { + u32 len = CPUReadMemory(reg[0].I) >> 9; + if (!(((reg[0].I & 0xe000000) == 0) || ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0)) + SWITicks = (34 + (memoryWait[(reg[0].I >> 24) & 0xF] << 1) + memoryWait[(reg[1].I >> 24) & 0xF]) * len; + } + BIOS_RLUnCompVram(); + break; + case 0x16: { + u32 len = CPUReadMemory(reg[0].I) >> 8; + if (!(((reg[0].I & 0xe000000) == 0) || ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0)) + SWITicks = (13 + memoryWait[(reg[0].I >> 24) & 0xF] + memoryWait[(reg[1].I >> 24) & 0xF]) * len; + } + BIOS_Diff8bitUnFilterWram(); + break; + case 0x17: { + u32 len = CPUReadMemory(reg[0].I) >> 9; + if (!(((reg[0].I & 0xe000000) == 0) || ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0)) + SWITicks = (39 + (memoryWait[(reg[0].I >> 24) & 0xF] << 1) + memoryWait[(reg[1].I >> 24) & 0xF]) * len; + } + BIOS_Diff8bitUnFilterVram(); + break; + case 0x18: { + u32 len = CPUReadMemory(reg[0].I) >> 9; + if (!(((reg[0].I & 0xe000000) == 0) || ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0)) + SWITicks = (13 + memoryWait[(reg[0].I >> 24) & 0xF] + memoryWait[(reg[1].I >> 24) & 0xF]) * len; + } + BIOS_Diff16bitUnFilter(); + break; + case 0x19: +#ifdef GBA_LOGGING + if (systemVerbose & VERBOSE_SWI) { + log("SoundBiasSet: 0x%08x (VCOUNT = %2d)\n", + reg[0].I, + VCOUNT); + } +#endif + if (reg[0].I) + soundPause(); + else + soundResume(); + break; + case 0x1A: + BIOS_SndDriverInit(); + SWITicks = 252000; + break; + case 0x1B: + BIOS_SndDriverMode(); + SWITicks = 280000; + break; + case 0x1C: + BIOS_SndDriverMain(); + SWITicks = 11050; //avg + break; + case 0x1D: + BIOS_SndDriverVSync(); + SWITicks = 44; + break; + case 0x1E: + BIOS_SndChannelClear(); + break; + case 0x28: + BIOS_SndDriverVSyncOff(); + break; + case 0x1F: + BIOS_MidiKey2Freq(); + break; + case 0xE0: + case 0xE1: + case 0xE2: + case 0xE3: + case 0xE4: + case 0xE5: + case 0xE6: + case 0xE7: + if (CheckEReaderRegion()) + BIOS_EReader_ScanCard(comment); + break; + case 0x2A: + BIOS_SndDriverJmpTableCopy(); // let it go, because we don't really emulate this function - default: + default: #ifdef GBA_LOGGING - if(systemVerbose & VERBOSE_SWI) { - log("SWI: %08x at %08x (0x%08x,0x%08x,0x%08x,VCOUNT = %2d)\n", comment, - armState ? armNextPC - 4: armNextPC -2, - reg[0].I, - reg[1].I, - reg[2].I, - VCOUNT); - } + if (systemVerbose & VERBOSE_SWI) { + log("SWI: %08x at %08x (0x%08x,0x%08x,0x%08x,VCOUNT = %2d)\n", comment, + armState ? armNextPC - 4 : armNextPC - 2, + reg[0].I, + reg[1].I, + reg[2].I, + VCOUNT); + } #endif - if(!disableMessage) { - systemMessage(MSG_UNSUPPORTED_BIOS_FUNCTION, - N_("Unsupported BIOS function %02x called from %08x. A BIOS file is needed in order to get correct behaviour."), - comment, - armMode ? armNextPC - 4: armNextPC - 2); - disableMessage = true; + if (!disableMessage) { + systemMessage(MSG_UNSUPPORTED_BIOS_FUNCTION, + N_("Unsupported BIOS function %02x called from %08x. A BIOS file is needed in order to get correct behaviour."), + comment, + armMode ? armNextPC - 4 : armNextPC - 2); + disableMessage = true; + } + break; } - break; - } } void CPUCompareVCOUNT() { - if(VCOUNT == (DISPSTAT >> 8)) { - DISPSTAT |= 4; - UPDATE_REG(0x04, DISPSTAT); + if (VCOUNT == (DISPSTAT >> 8)) { + DISPSTAT |= 4; + UPDATE_REG(0x04, DISPSTAT); - if(DISPSTAT & 0x20) { - IF |= 4; - UPDATE_REG(0x202, IF); + if (DISPSTAT & 0x20) { + IF |= 4; + UPDATE_REG(0x202, IF); + } + } else { + DISPSTAT &= 0xFFFB; + UPDATE_REG(0x4, DISPSTAT); + } + if (layerEnableDelay > 0) { + layerEnableDelay--; + if (layerEnableDelay == 1) + layerEnable = layerSettings & DISPCNT; } - } else { - DISPSTAT &= 0xFFFB; - UPDATE_REG(0x4, DISPSTAT); - } - if (layerEnableDelay>0) - { - layerEnableDelay--; - if (layerEnableDelay==1) - layerEnable = layerSettings & DISPCNT; - } - } -void doDMA(u32 &s, u32 &d, u32 si, u32 di, u32 c, int transfer32) +void doDMA(u32& s, u32& d, u32 si, u32 di, u32 c, int transfer32) { - int sm = s >> 24; - int dm = d >> 24; - int sw = 0; - int dw = 0; - int sc = c; + int sm = s >> 24; + int dm = d >> 24; + int sw = 0; + int dw = 0; + int sc = c; - cpuDmaHack = true; - cpuDmaCount = c; - // This is done to get the correct waitstates. - if (sm>15) - sm=15; - if (dm>15) - dm=15; + cpuDmaHack = true; + cpuDmaCount = c; + // This is done to get the correct waitstates. + if (sm > 15) + sm = 15; + if (dm > 15) + dm = 15; - //if ((sm>=0x05) && (sm<=0x07) || (dm>=0x05) && (dm <=0x07)) - // blank = (((DISPSTAT | ((DISPSTAT>>1)&1))==1) ? true : false); + //if ((sm>=0x05) && (sm<=0x07) || (dm>=0x05) && (dm <=0x07)) + // blank = (((DISPSTAT | ((DISPSTAT>>1)&1))==1) ? true : false); - if(transfer32) { - s &= 0xFFFFFFFC; - if(s < 0x02000000 && (reg[15].I >> 24)) { - while(c != 0) { - CPUWriteMemory(d, 0); - d += di; - c--; - } + if (transfer32) { + s &= 0xFFFFFFFC; + if (s < 0x02000000 && (reg[15].I >> 24)) { + while (c != 0) { + CPUWriteMemory(d, 0); + d += di; + c--; + } + } else { + while (c != 0) { + cpuDmaLast = CPUReadMemory(s); + CPUWriteMemory(d, cpuDmaLast); + d += di; + s += si; + c--; + } + } } else { - while(c != 0) { - cpuDmaLast = CPUReadMemory(s); - CPUWriteMemory(d, cpuDmaLast); - d += di; - s += si; - c--; - } + s &= 0xFFFFFFFE; + si = (int)si >> 1; + di = (int)di >> 1; + if (s < 0x02000000 && (reg[15].I >> 24)) { + while (c != 0) { + CPUWriteHalfWord(d, 0); + d += di; + c--; + } + } else { + while (c != 0) { + cpuDmaLast = CPUReadHalfWord(s); + CPUWriteHalfWord(d, cpuDmaLast); + cpuDmaLast |= (cpuDmaLast << 16); + d += di; + s += si; + c--; + } + } } - } else { - s &= 0xFFFFFFFE; - si = (int)si >> 1; - di = (int)di >> 1; - if(s < 0x02000000 && (reg[15].I >> 24)) { - while(c != 0) { - CPUWriteHalfWord(d, 0); - d += di; - c--; - } + + cpuDmaCount = 0; + + int totalTicks = 0; + + if (transfer32) { + sw = 1 + memoryWaitSeq32[sm & 15]; + dw = 1 + memoryWaitSeq32[dm & 15]; + totalTicks = (sw + dw) * (sc - 1) + 6 + memoryWait32[sm & 15] + memoryWaitSeq32[dm & 15]; } else { - while(c != 0) { - cpuDmaLast = CPUReadHalfWord(s); - CPUWriteHalfWord(d, cpuDmaLast); - cpuDmaLast |= (cpuDmaLast<<16); - d += di; - s += si; - c--; - } + sw = 1 + memoryWaitSeq[sm & 15]; + dw = 1 + memoryWaitSeq[dm & 15]; + totalTicks = (sw + dw) * (sc - 1) + 6 + memoryWait[sm & 15] + memoryWaitSeq[dm & 15]; } - } - cpuDmaCount = 0; - - int totalTicks = 0; - - if(transfer32) { - sw =1+memoryWaitSeq32[sm & 15]; - dw =1+memoryWaitSeq32[dm & 15]; - totalTicks = (sw+dw)*(sc-1) + 6 + memoryWait32[sm & 15] + - memoryWaitSeq32[dm & 15]; - } - else - { - sw = 1+memoryWaitSeq[sm & 15]; - dw = 1+memoryWaitSeq[dm & 15]; - totalTicks = (sw+dw)*(sc-1) + 6 + memoryWait[sm & 15] + - memoryWaitSeq[dm & 15]; - } - - cpuDmaTicksToUpdate += totalTicks; - cpuDmaHack = false; + cpuDmaTicksToUpdate += totalTicks; + cpuDmaHack = false; } void CPUCheckDMA(int reason, int dmamask) { - // DMA 0 - if((DM0CNT_H & 0x8000) && (dmamask & 1)) { - if(((DM0CNT_H >> 12) & 3) == reason) { - u32 sourceIncrement = 4; - u32 destIncrement = 4; - switch((DM0CNT_H >> 7) & 3) { - case 0: - break; - case 1: - sourceIncrement = (u32)-4; - break; - case 2: - sourceIncrement = 0; - break; - } - switch((DM0CNT_H >> 5) & 3) { - case 0: - break; - case 1: - destIncrement = (u32)-4; - break; - case 2: - destIncrement = 0; - break; - } + // DMA 0 + if ((DM0CNT_H & 0x8000) && (dmamask & 1)) { + if (((DM0CNT_H >> 12) & 3) == reason) { + u32 sourceIncrement = 4; + u32 destIncrement = 4; + switch ((DM0CNT_H >> 7) & 3) { + case 0: + break; + case 1: + sourceIncrement = (u32)-4; + break; + case 2: + sourceIncrement = 0; + break; + } + switch ((DM0CNT_H >> 5) & 3) { + case 0: + break; + case 1: + destIncrement = (u32)-4; + break; + case 2: + destIncrement = 0; + break; + } #ifdef GBA_LOGGING - if(systemVerbose & VERBOSE_DMA0) { - int count = (DM0CNT_L ? DM0CNT_L : 0x4000) << 1; - if(DM0CNT_H & 0x0400) - count <<= 1; - log("DMA0: s=%08x d=%08x c=%04x count=%08x\n", dma0Source, dma0Dest, - DM0CNT_H, - count); - } + if (systemVerbose & VERBOSE_DMA0) { + int count = (DM0CNT_L ? DM0CNT_L : 0x4000) << 1; + if (DM0CNT_H & 0x0400) + count <<= 1; + log("DMA0: s=%08x d=%08x c=%04x count=%08x\n", dma0Source, dma0Dest, + DM0CNT_H, + count); + } #endif - doDMA(dma0Source, dma0Dest, sourceIncrement, destIncrement, - DM0CNT_L ? DM0CNT_L : 0x4000, - DM0CNT_H & 0x0400); + doDMA(dma0Source, dma0Dest, sourceIncrement, destIncrement, + DM0CNT_L ? DM0CNT_L : 0x4000, + DM0CNT_H & 0x0400); - if(DM0CNT_H & 0x4000) { - IF |= 0x0100; - UPDATE_REG(0x202, IF); - cpuNextEvent = cpuTotalTicks; - } + if (DM0CNT_H & 0x4000) { + IF |= 0x0100; + UPDATE_REG(0x202, IF); + cpuNextEvent = cpuTotalTicks; + } - if(((DM0CNT_H >> 5) & 3) == 3) { - dma0Dest = DM0DAD_L | (DM0DAD_H << 16); - } + if (((DM0CNT_H >> 5) & 3) == 3) { + dma0Dest = DM0DAD_L | (DM0DAD_H << 16); + } - if(!(DM0CNT_H & 0x0200) || (reason == 0)) { - DM0CNT_H &= 0x7FFF; - UPDATE_REG(0xBA, DM0CNT_H); - } - } - } - - // DMA 1 - if((DM1CNT_H & 0x8000) && (dmamask & 2)) { - if(((DM1CNT_H >> 12) & 3) == reason) { - u32 sourceIncrement = 4; - u32 destIncrement = 4; - switch((DM1CNT_H >> 7) & 3) { - case 0: - break; - case 1: - sourceIncrement = (u32)-4; - break; - case 2: - sourceIncrement = 0; - break; - } - switch((DM1CNT_H >> 5) & 3) { - case 0: - break; - case 1: - destIncrement = (u32)-4; - break; - case 2: - destIncrement = 0; - break; - } - if(reason == 3) { -#ifdef GBA_LOGGING - if(systemVerbose & VERBOSE_DMA1) { - log("DMA1: s=%08x d=%08x c=%04x count=%08x\n", dma1Source, dma1Dest, - DM1CNT_H, - 16); + if (!(DM0CNT_H & 0x0200) || (reason == 0)) { + DM0CNT_H &= 0x7FFF; + UPDATE_REG(0xBA, DM0CNT_H); + } } -#endif - doDMA(dma1Source, dma1Dest, sourceIncrement, 0, 4, - 0x0400); - } else { -#ifdef GBA_LOGGING - if(systemVerbose & VERBOSE_DMA1) { - int count = (DM1CNT_L ? DM1CNT_L : 0x4000) << 1; - if(DM1CNT_H & 0x0400) - count <<= 1; - log("DMA1: s=%08x d=%08x c=%04x count=%08x\n", dma1Source, dma1Dest, - DM1CNT_H, - count); - } -#endif - doDMA(dma1Source, dma1Dest, sourceIncrement, destIncrement, - DM1CNT_L ? DM1CNT_L : 0x4000, - DM1CNT_H & 0x0400); - } - - if(DM1CNT_H & 0x4000) { - IF |= 0x0200; - UPDATE_REG(0x202, IF); - cpuNextEvent = cpuTotalTicks; - } - - if(((DM1CNT_H >> 5) & 3) == 3) { - dma1Dest = DM1DAD_L | (DM1DAD_H << 16); - } - - if(!(DM1CNT_H & 0x0200) || (reason == 0)) { - DM1CNT_H &= 0x7FFF; - UPDATE_REG(0xC6, DM1CNT_H); - } } - } - // DMA 2 - if((DM2CNT_H & 0x8000) && (dmamask & 4)) { - if(((DM2CNT_H >> 12) & 3) == reason) { - u32 sourceIncrement = 4; - u32 destIncrement = 4; - switch((DM2CNT_H >> 7) & 3) { - case 0: - break; - case 1: - sourceIncrement = (u32)-4; - break; - case 2: - sourceIncrement = 0; - break; - } - switch((DM2CNT_H >> 5) & 3) { - case 0: - break; - case 1: - destIncrement = (u32)-4; - break; - case 2: - destIncrement = 0; - break; - } - if(reason == 3) { + // DMA 1 + if ((DM1CNT_H & 0x8000) && (dmamask & 2)) { + if (((DM1CNT_H >> 12) & 3) == reason) { + u32 sourceIncrement = 4; + u32 destIncrement = 4; + switch ((DM1CNT_H >> 7) & 3) { + case 0: + break; + case 1: + sourceIncrement = (u32)-4; + break; + case 2: + sourceIncrement = 0; + break; + } + switch ((DM1CNT_H >> 5) & 3) { + case 0: + break; + case 1: + destIncrement = (u32)-4; + break; + case 2: + destIncrement = 0; + break; + } + if (reason == 3) { #ifdef GBA_LOGGING - if(systemVerbose & VERBOSE_DMA2) { - int count = (4) << 2; - log("DMA2: s=%08x d=%08x c=%04x count=%08x\n", dma2Source, dma2Dest, - DM2CNT_H, - count); + if (systemVerbose & VERBOSE_DMA1) { + log("DMA1: s=%08x d=%08x c=%04x count=%08x\n", dma1Source, dma1Dest, + DM1CNT_H, + 16); + } +#endif + doDMA(dma1Source, dma1Dest, sourceIncrement, 0, 4, + 0x0400); + } else { +#ifdef GBA_LOGGING + if (systemVerbose & VERBOSE_DMA1) { + int count = (DM1CNT_L ? DM1CNT_L : 0x4000) << 1; + if (DM1CNT_H & 0x0400) + count <<= 1; + log("DMA1: s=%08x d=%08x c=%04x count=%08x\n", dma1Source, dma1Dest, + DM1CNT_H, + count); + } +#endif + doDMA(dma1Source, dma1Dest, sourceIncrement, destIncrement, + DM1CNT_L ? DM1CNT_L : 0x4000, + DM1CNT_H & 0x0400); + } + + if (DM1CNT_H & 0x4000) { + IF |= 0x0200; + UPDATE_REG(0x202, IF); + cpuNextEvent = cpuTotalTicks; + } + + if (((DM1CNT_H >> 5) & 3) == 3) { + dma1Dest = DM1DAD_L | (DM1DAD_H << 16); + } + + if (!(DM1CNT_H & 0x0200) || (reason == 0)) { + DM1CNT_H &= 0x7FFF; + UPDATE_REG(0xC6, DM1CNT_H); + } } -#endif - doDMA(dma2Source, dma2Dest, sourceIncrement, 0, 4, - 0x0400); - } else { + } + + // DMA 2 + if ((DM2CNT_H & 0x8000) && (dmamask & 4)) { + if (((DM2CNT_H >> 12) & 3) == reason) { + u32 sourceIncrement = 4; + u32 destIncrement = 4; + switch ((DM2CNT_H >> 7) & 3) { + case 0: + break; + case 1: + sourceIncrement = (u32)-4; + break; + case 2: + sourceIncrement = 0; + break; + } + switch ((DM2CNT_H >> 5) & 3) { + case 0: + break; + case 1: + destIncrement = (u32)-4; + break; + case 2: + destIncrement = 0; + break; + } + if (reason == 3) { #ifdef GBA_LOGGING - if(systemVerbose & VERBOSE_DMA2) { - int count = (DM2CNT_L ? DM2CNT_L : 0x4000) << 1; - if(DM2CNT_H & 0x0400) - count <<= 1; - log("DMA2: s=%08x d=%08x c=%04x count=%08x\n", dma2Source, dma2Dest, - DM2CNT_H, - count); + if (systemVerbose & VERBOSE_DMA2) { + int count = (4) << 2; + log("DMA2: s=%08x d=%08x c=%04x count=%08x\n", dma2Source, dma2Dest, + DM2CNT_H, + count); + } +#endif + doDMA(dma2Source, dma2Dest, sourceIncrement, 0, 4, + 0x0400); + } else { +#ifdef GBA_LOGGING + if (systemVerbose & VERBOSE_DMA2) { + int count = (DM2CNT_L ? DM2CNT_L : 0x4000) << 1; + if (DM2CNT_H & 0x0400) + count <<= 1; + log("DMA2: s=%08x d=%08x c=%04x count=%08x\n", dma2Source, dma2Dest, + DM2CNT_H, + count); + } +#endif + doDMA(dma2Source, dma2Dest, sourceIncrement, destIncrement, + DM2CNT_L ? DM2CNT_L : 0x4000, + DM2CNT_H & 0x0400); + } + + if (DM2CNT_H & 0x4000) { + IF |= 0x0400; + UPDATE_REG(0x202, IF); + cpuNextEvent = cpuTotalTicks; + } + + if (((DM2CNT_H >> 5) & 3) == 3) { + dma2Dest = DM2DAD_L | (DM2DAD_H << 16); + } + + if (!(DM2CNT_H & 0x0200) || (reason == 0)) { + DM2CNT_H &= 0x7FFF; + UPDATE_REG(0xD2, DM2CNT_H); + } } -#endif - doDMA(dma2Source, dma2Dest, sourceIncrement, destIncrement, - DM2CNT_L ? DM2CNT_L : 0x4000, - DM2CNT_H & 0x0400); - } - - if(DM2CNT_H & 0x4000) { - IF |= 0x0400; - UPDATE_REG(0x202, IF); - cpuNextEvent = cpuTotalTicks; - } - - if(((DM2CNT_H >> 5) & 3) == 3) { - dma2Dest = DM2DAD_L | (DM2DAD_H << 16); - } - - if(!(DM2CNT_H & 0x0200) || (reason == 0)) { - DM2CNT_H &= 0x7FFF; - UPDATE_REG(0xD2, DM2CNT_H); - } } - } - // DMA 3 - if((DM3CNT_H & 0x8000) && (dmamask & 8)) { - if(((DM3CNT_H >> 12) & 3) == reason) { - u32 sourceIncrement = 4; - u32 destIncrement = 4; - switch((DM3CNT_H >> 7) & 3) { - case 0: - break; - case 1: - sourceIncrement = (u32)-4; - break; - case 2: - sourceIncrement = 0; - break; - } - switch((DM3CNT_H >> 5) & 3) { - case 0: - break; - case 1: - destIncrement = (u32)-4; - break; - case 2: - destIncrement = 0; - break; - } + // DMA 3 + if ((DM3CNT_H & 0x8000) && (dmamask & 8)) { + if (((DM3CNT_H >> 12) & 3) == reason) { + u32 sourceIncrement = 4; + u32 destIncrement = 4; + switch ((DM3CNT_H >> 7) & 3) { + case 0: + break; + case 1: + sourceIncrement = (u32)-4; + break; + case 2: + sourceIncrement = 0; + break; + } + switch ((DM3CNT_H >> 5) & 3) { + case 0: + break; + case 1: + destIncrement = (u32)-4; + break; + case 2: + destIncrement = 0; + break; + } #ifdef GBA_LOGGING - if(systemVerbose & VERBOSE_DMA3) { - int count = (DM3CNT_L ? DM3CNT_L : 0x10000) << 1; - if(DM3CNT_H & 0x0400) - count <<= 1; - log("DMA3: s=%08x d=%08x c=%04x count=%08x\n", dma3Source, dma3Dest, - DM3CNT_H, - count); - } + if (systemVerbose & VERBOSE_DMA3) { + int count = (DM3CNT_L ? DM3CNT_L : 0x10000) << 1; + if (DM3CNT_H & 0x0400) + count <<= 1; + log("DMA3: s=%08x d=%08x c=%04x count=%08x\n", dma3Source, dma3Dest, + DM3CNT_H, + count); + } #endif - doDMA(dma3Source, dma3Dest, sourceIncrement, destIncrement, - DM3CNT_L ? DM3CNT_L : 0x10000, - DM3CNT_H & 0x0400); + doDMA(dma3Source, dma3Dest, sourceIncrement, destIncrement, + DM3CNT_L ? DM3CNT_L : 0x10000, + DM3CNT_H & 0x0400); - if(DM3CNT_H & 0x4000) { - IF |= 0x0800; - UPDATE_REG(0x202, IF); - cpuNextEvent = cpuTotalTicks; - } + if (DM3CNT_H & 0x4000) { + IF |= 0x0800; + UPDATE_REG(0x202, IF); + cpuNextEvent = cpuTotalTicks; + } - if(((DM3CNT_H >> 5) & 3) == 3) { - dma3Dest = DM3DAD_L | (DM3DAD_H << 16); - } + if (((DM3CNT_H >> 5) & 3) == 3) { + dma3Dest = DM3DAD_L | (DM3DAD_H << 16); + } - if(!(DM3CNT_H & 0x0200) || (reason == 0)) { - DM3CNT_H &= 0x7FFF; - UPDATE_REG(0xDE, DM3CNT_H); - } + if (!(DM3CNT_H & 0x0200) || (reason == 0)) { + DM3CNT_H &= 0x7FFF; + UPDATE_REG(0xDE, DM3CNT_H); + } + } } - } } void CPUUpdateRegister(u32 address, u16 value) { - switch(address) - { - case 0x00: - { // we need to place the following code in { } because we declare & initialize variables in a case statement - if((value & 7) > 5) { - // display modes above 0-5 are prohibited - DISPCNT = (value & 7); - } - bool change = (0 != ((DISPCNT ^ value) & 0x80)); - bool changeBG = (0 != ((DISPCNT ^ value) & 0x0F00)); - u16 changeBGon = ((~DISPCNT) & value) & 0x0F00; // these layers are being activated - - DISPCNT = (value & 0xFFF7); // bit 3 can only be accessed by the BIOS to enable GBC mode - UPDATE_REG(0x00, DISPCNT); - - if(changeBGon) { - layerEnableDelay = 4; - layerEnable = layerSettings & value & (~changeBGon); - } else { - layerEnable = layerSettings & value; - // CPUUpdateTicks(); - } - - windowOn = (layerEnable & 0x6000) ? true : false; - if(change && !((value & 0x80))) { - if(!(DISPSTAT & 1)) { - //lcdTicks = 1008; - // VCOUNT = 0; - // UPDATE_REG(0x06, VCOUNT); - DISPSTAT &= 0xFFFC; - UPDATE_REG(0x04, DISPSTAT); - CPUCompareVCOUNT(); + switch (address) { + case 0x00: { // we need to place the following code in { } because we declare & initialize variables in a case statement + if ((value & 7) > 5) { + // display modes above 0-5 are prohibited + DISPCNT = (value & 7); } - // (*renderLine)(); - } - CPUUpdateRender(); - // we only care about changes in BG0-BG3 - if(changeBG) { - CPUUpdateRenderBuffers(false); - } - break; + bool change = (0 != ((DISPCNT ^ value) & 0x80)); + bool changeBG = (0 != ((DISPCNT ^ value) & 0x0F00)); + u16 changeBGon = ((~DISPCNT) & value) & 0x0F00; // these layers are being activated + + DISPCNT = (value & 0xFFF7); // bit 3 can only be accessed by the BIOS to enable GBC mode + UPDATE_REG(0x00, DISPCNT); + + if (changeBGon) { + layerEnableDelay = 4; + layerEnable = layerSettings & value & (~changeBGon); + } else { + layerEnable = layerSettings & value; + // CPUUpdateTicks(); + } + + windowOn = (layerEnable & 0x6000) ? true : false; + if (change && !((value & 0x80))) { + if (!(DISPSTAT & 1)) { + //lcdTicks = 1008; + // VCOUNT = 0; + // UPDATE_REG(0x06, VCOUNT); + DISPSTAT &= 0xFFFC; + UPDATE_REG(0x04, DISPSTAT); + CPUCompareVCOUNT(); + } + // (*renderLine)(); + } + CPUUpdateRender(); + // we only care about changes in BG0-BG3 + if (changeBG) { + CPUUpdateRenderBuffers(false); + } + break; } - case 0x04: - DISPSTAT = (value & 0xFF38) | (DISPSTAT & 7); - UPDATE_REG(0x04, DISPSTAT); - break; - case 0x06: - // not writable - break; - case 0x08: - BG0CNT = (value & 0xDFCF); - UPDATE_REG(0x08, BG0CNT); - break; - case 0x0A: - BG1CNT = (value & 0xDFCF); - UPDATE_REG(0x0A, BG1CNT); - break; - case 0x0C: - BG2CNT = (value & 0xFFCF); - UPDATE_REG(0x0C, BG2CNT); - break; - case 0x0E: - BG3CNT = (value & 0xFFCF); - UPDATE_REG(0x0E, BG3CNT); - break; - case 0x10: - BG0HOFS = value & 511; - UPDATE_REG(0x10, BG0HOFS); - break; - case 0x12: - BG0VOFS = value & 511; - UPDATE_REG(0x12, BG0VOFS); - break; - case 0x14: - BG1HOFS = value & 511; - UPDATE_REG(0x14, BG1HOFS); - break; - case 0x16: - BG1VOFS = value & 511; - UPDATE_REG(0x16, BG1VOFS); - break; - case 0x18: - BG2HOFS = value & 511; - UPDATE_REG(0x18, BG2HOFS); - break; - case 0x1A: - BG2VOFS = value & 511; - UPDATE_REG(0x1A, BG2VOFS); - break; - case 0x1C: - BG3HOFS = value & 511; - UPDATE_REG(0x1C, BG3HOFS); - break; - case 0x1E: - BG3VOFS = value & 511; - UPDATE_REG(0x1E, BG3VOFS); - break; - case 0x20: - BG2PA = value; - UPDATE_REG(0x20, BG2PA); - break; - case 0x22: - BG2PB = value; - UPDATE_REG(0x22, BG2PB); - break; - case 0x24: - BG2PC = value; - UPDATE_REG(0x24, BG2PC); - break; - case 0x26: - BG2PD = value; - UPDATE_REG(0x26, BG2PD); - break; - case 0x28: - BG2X_L = value; - UPDATE_REG(0x28, BG2X_L); - gfxBG2Changed |= 1; - break; - case 0x2A: - BG2X_H = (value & 0xFFF); - UPDATE_REG(0x2A, BG2X_H); - gfxBG2Changed |= 1; - break; - case 0x2C: - BG2Y_L = value; - UPDATE_REG(0x2C, BG2Y_L); - gfxBG2Changed |= 2; - break; - case 0x2E: - BG2Y_H = value & 0xFFF; - UPDATE_REG(0x2E, BG2Y_H); - gfxBG2Changed |= 2; - break; - case 0x30: - BG3PA = value; - UPDATE_REG(0x30, BG3PA); - break; - case 0x32: - BG3PB = value; - UPDATE_REG(0x32, BG3PB); - break; - case 0x34: - BG3PC = value; - UPDATE_REG(0x34, BG3PC); - break; - case 0x36: - BG3PD = value; - UPDATE_REG(0x36, BG3PD); - break; - case 0x38: - BG3X_L = value; - UPDATE_REG(0x38, BG3X_L); - gfxBG3Changed |= 1; - break; - case 0x3A: - BG3X_H = value & 0xFFF; - UPDATE_REG(0x3A, BG3X_H); - gfxBG3Changed |= 1; - break; - case 0x3C: - BG3Y_L = value; - UPDATE_REG(0x3C, BG3Y_L); - gfxBG3Changed |= 2; - break; - case 0x3E: - BG3Y_H = value & 0xFFF; - UPDATE_REG(0x3E, BG3Y_H); - gfxBG3Changed |= 2; - break; - case 0x40: - WIN0H = value; - UPDATE_REG(0x40, WIN0H); - CPUUpdateWindow0(); - break; - case 0x42: - WIN1H = value; - UPDATE_REG(0x42, WIN1H); - CPUUpdateWindow1(); - break; - case 0x44: - WIN0V = value; - UPDATE_REG(0x44, WIN0V); - break; - case 0x46: - WIN1V = value; - UPDATE_REG(0x46, WIN1V); - break; - case 0x48: - WININ = value & 0x3F3F; - UPDATE_REG(0x48, WININ); - break; - case 0x4A: - WINOUT = value & 0x3F3F; - UPDATE_REG(0x4A, WINOUT); - break; - case 0x4C: - MOSAIC = value; - UPDATE_REG(0x4C, MOSAIC); - break; - case 0x50: - BLDMOD = value & 0x3FFF; - UPDATE_REG(0x50, BLDMOD); - fxOn = ((BLDMOD>>6)&3) != 0; - CPUUpdateRender(); - break; - case 0x52: - COLEV = value & 0x1F1F; - UPDATE_REG(0x52, COLEV); - break; - case 0x54: - COLY = value & 0x1F; - UPDATE_REG(0x54, COLY); - break; - case 0x60: - case 0x62: - case 0x64: - case 0x68: - case 0x6c: - case 0x70: - case 0x72: - case 0x74: - case 0x78: - case 0x7c: - case 0x80: - case 0x84: - soundEvent(address&0xFF, (u8)(value & 0xFF)); - soundEvent((address&0xFF)+1, (u8)(value>>8)); - break; - case 0x82: - case 0x88: - case 0xa0: - case 0xa2: - case 0xa4: - case 0xa6: - case 0x90: - case 0x92: - case 0x94: - case 0x96: - case 0x98: - case 0x9a: - case 0x9c: - case 0x9e: - soundEvent(address&0xFF, value); - break; - case 0xB0: - DM0SAD_L = value; - UPDATE_REG(0xB0, DM0SAD_L); - break; - case 0xB2: - DM0SAD_H = value & 0x07FF; - UPDATE_REG(0xB2, DM0SAD_H); - break; - case 0xB4: - DM0DAD_L = value; - UPDATE_REG(0xB4, DM0DAD_L); - break; - case 0xB6: - DM0DAD_H = value & 0x07FF; - UPDATE_REG(0xB6, DM0DAD_H); - break; - case 0xB8: - DM0CNT_L = value & 0x3FFF; - UPDATE_REG(0xB8, 0); - break; - case 0xBA: - { - bool start = ((DM0CNT_H ^ value) & 0x8000) ? true : false; - value &= 0xF7E0; + case 0x04: + DISPSTAT = (value & 0xFF38) | (DISPSTAT & 7); + UPDATE_REG(0x04, DISPSTAT); + break; + case 0x06: + // not writable + break; + case 0x08: + BG0CNT = (value & 0xDFCF); + UPDATE_REG(0x08, BG0CNT); + break; + case 0x0A: + BG1CNT = (value & 0xDFCF); + UPDATE_REG(0x0A, BG1CNT); + break; + case 0x0C: + BG2CNT = (value & 0xFFCF); + UPDATE_REG(0x0C, BG2CNT); + break; + case 0x0E: + BG3CNT = (value & 0xFFCF); + UPDATE_REG(0x0E, BG3CNT); + break; + case 0x10: + BG0HOFS = value & 511; + UPDATE_REG(0x10, BG0HOFS); + break; + case 0x12: + BG0VOFS = value & 511; + UPDATE_REG(0x12, BG0VOFS); + break; + case 0x14: + BG1HOFS = value & 511; + UPDATE_REG(0x14, BG1HOFS); + break; + case 0x16: + BG1VOFS = value & 511; + UPDATE_REG(0x16, BG1VOFS); + break; + case 0x18: + BG2HOFS = value & 511; + UPDATE_REG(0x18, BG2HOFS); + break; + case 0x1A: + BG2VOFS = value & 511; + UPDATE_REG(0x1A, BG2VOFS); + break; + case 0x1C: + BG3HOFS = value & 511; + UPDATE_REG(0x1C, BG3HOFS); + break; + case 0x1E: + BG3VOFS = value & 511; + UPDATE_REG(0x1E, BG3VOFS); + break; + case 0x20: + BG2PA = value; + UPDATE_REG(0x20, BG2PA); + break; + case 0x22: + BG2PB = value; + UPDATE_REG(0x22, BG2PB); + break; + case 0x24: + BG2PC = value; + UPDATE_REG(0x24, BG2PC); + break; + case 0x26: + BG2PD = value; + UPDATE_REG(0x26, BG2PD); + break; + case 0x28: + BG2X_L = value; + UPDATE_REG(0x28, BG2X_L); + gfxBG2Changed |= 1; + break; + case 0x2A: + BG2X_H = (value & 0xFFF); + UPDATE_REG(0x2A, BG2X_H); + gfxBG2Changed |= 1; + break; + case 0x2C: + BG2Y_L = value; + UPDATE_REG(0x2C, BG2Y_L); + gfxBG2Changed |= 2; + break; + case 0x2E: + BG2Y_H = value & 0xFFF; + UPDATE_REG(0x2E, BG2Y_H); + gfxBG2Changed |= 2; + break; + case 0x30: + BG3PA = value; + UPDATE_REG(0x30, BG3PA); + break; + case 0x32: + BG3PB = value; + UPDATE_REG(0x32, BG3PB); + break; + case 0x34: + BG3PC = value; + UPDATE_REG(0x34, BG3PC); + break; + case 0x36: + BG3PD = value; + UPDATE_REG(0x36, BG3PD); + break; + case 0x38: + BG3X_L = value; + UPDATE_REG(0x38, BG3X_L); + gfxBG3Changed |= 1; + break; + case 0x3A: + BG3X_H = value & 0xFFF; + UPDATE_REG(0x3A, BG3X_H); + gfxBG3Changed |= 1; + break; + case 0x3C: + BG3Y_L = value; + UPDATE_REG(0x3C, BG3Y_L); + gfxBG3Changed |= 2; + break; + case 0x3E: + BG3Y_H = value & 0xFFF; + UPDATE_REG(0x3E, BG3Y_H); + gfxBG3Changed |= 2; + break; + case 0x40: + WIN0H = value; + UPDATE_REG(0x40, WIN0H); + CPUUpdateWindow0(); + break; + case 0x42: + WIN1H = value; + UPDATE_REG(0x42, WIN1H); + CPUUpdateWindow1(); + break; + case 0x44: + WIN0V = value; + UPDATE_REG(0x44, WIN0V); + break; + case 0x46: + WIN1V = value; + UPDATE_REG(0x46, WIN1V); + break; + case 0x48: + WININ = value & 0x3F3F; + UPDATE_REG(0x48, WININ); + break; + case 0x4A: + WINOUT = value & 0x3F3F; + UPDATE_REG(0x4A, WINOUT); + break; + case 0x4C: + MOSAIC = value; + UPDATE_REG(0x4C, MOSAIC); + break; + case 0x50: + BLDMOD = value & 0x3FFF; + UPDATE_REG(0x50, BLDMOD); + fxOn = ((BLDMOD >> 6) & 3) != 0; + CPUUpdateRender(); + break; + case 0x52: + COLEV = value & 0x1F1F; + UPDATE_REG(0x52, COLEV); + break; + case 0x54: + COLY = value & 0x1F; + UPDATE_REG(0x54, COLY); + break; + case 0x60: + case 0x62: + case 0x64: + case 0x68: + case 0x6c: + case 0x70: + case 0x72: + case 0x74: + case 0x78: + case 0x7c: + case 0x80: + case 0x84: + soundEvent(address & 0xFF, (u8)(value & 0xFF)); + soundEvent((address & 0xFF) + 1, (u8)(value >> 8)); + break; + case 0x82: + case 0x88: + case 0xa0: + case 0xa2: + case 0xa4: + case 0xa6: + case 0x90: + case 0x92: + case 0x94: + case 0x96: + case 0x98: + case 0x9a: + case 0x9c: + case 0x9e: + soundEvent(address & 0xFF, value); + break; + case 0xB0: + DM0SAD_L = value; + UPDATE_REG(0xB0, DM0SAD_L); + break; + case 0xB2: + DM0SAD_H = value & 0x07FF; + UPDATE_REG(0xB2, DM0SAD_H); + break; + case 0xB4: + DM0DAD_L = value; + UPDATE_REG(0xB4, DM0DAD_L); + break; + case 0xB6: + DM0DAD_H = value & 0x07FF; + UPDATE_REG(0xB6, DM0DAD_H); + break; + case 0xB8: + DM0CNT_L = value & 0x3FFF; + UPDATE_REG(0xB8, 0); + break; + case 0xBA: { + bool start = ((DM0CNT_H ^ value) & 0x8000) ? true : false; + value &= 0xF7E0; - DM0CNT_H = value; - UPDATE_REG(0xBA, DM0CNT_H); + DM0CNT_H = value; + UPDATE_REG(0xBA, DM0CNT_H); - if(start && (value & 0x8000)) { - dma0Source = DM0SAD_L | (DM0SAD_H << 16); - dma0Dest = DM0DAD_L | (DM0DAD_H << 16); - CPUCheckDMA(0, 1); - } - } - break; - case 0xBC: - DM1SAD_L = value; - UPDATE_REG(0xBC, DM1SAD_L); - break; - case 0xBE: - DM1SAD_H = value & 0x0FFF; - UPDATE_REG(0xBE, DM1SAD_H); - break; - case 0xC0: - DM1DAD_L = value; - UPDATE_REG(0xC0, DM1DAD_L); - break; - case 0xC2: - DM1DAD_H = value & 0x07FF; - UPDATE_REG(0xC2, DM1DAD_H); - break; - case 0xC4: - DM1CNT_L = value & 0x3FFF; - UPDATE_REG(0xC4, 0); - break; - case 0xC6: - { - bool start = ((DM1CNT_H ^ value) & 0x8000) ? true : false; - value &= 0xF7E0; + if (start && (value & 0x8000)) { + dma0Source = DM0SAD_L | (DM0SAD_H << 16); + dma0Dest = DM0DAD_L | (DM0DAD_H << 16); + CPUCheckDMA(0, 1); + } + } break; + case 0xBC: + DM1SAD_L = value; + UPDATE_REG(0xBC, DM1SAD_L); + break; + case 0xBE: + DM1SAD_H = value & 0x0FFF; + UPDATE_REG(0xBE, DM1SAD_H); + break; + case 0xC0: + DM1DAD_L = value; + UPDATE_REG(0xC0, DM1DAD_L); + break; + case 0xC2: + DM1DAD_H = value & 0x07FF; + UPDATE_REG(0xC2, DM1DAD_H); + break; + case 0xC4: + DM1CNT_L = value & 0x3FFF; + UPDATE_REG(0xC4, 0); + break; + case 0xC6: { + bool start = ((DM1CNT_H ^ value) & 0x8000) ? true : false; + value &= 0xF7E0; - DM1CNT_H = value; - UPDATE_REG(0xC6, DM1CNT_H); + DM1CNT_H = value; + UPDATE_REG(0xC6, DM1CNT_H); - if(start && (value & 0x8000)) { - dma1Source = DM1SAD_L | (DM1SAD_H << 16); - dma1Dest = DM1DAD_L | (DM1DAD_H << 16); - CPUCheckDMA(0, 2); - } - } - break; - case 0xC8: - DM2SAD_L = value; - UPDATE_REG(0xC8, DM2SAD_L); - break; - case 0xCA: - DM2SAD_H = value & 0x0FFF; - UPDATE_REG(0xCA, DM2SAD_H); - break; - case 0xCC: - DM2DAD_L = value; - UPDATE_REG(0xCC, DM2DAD_L); - break; - case 0xCE: - DM2DAD_H = value & 0x07FF; - UPDATE_REG(0xCE, DM2DAD_H); - break; - case 0xD0: - DM2CNT_L = value & 0x3FFF; - UPDATE_REG(0xD0, 0); - break; - case 0xD2: - { - bool start = ((DM2CNT_H ^ value) & 0x8000) ? true : false; + if (start && (value & 0x8000)) { + dma1Source = DM1SAD_L | (DM1SAD_H << 16); + dma1Dest = DM1DAD_L | (DM1DAD_H << 16); + CPUCheckDMA(0, 2); + } + } break; + case 0xC8: + DM2SAD_L = value; + UPDATE_REG(0xC8, DM2SAD_L); + break; + case 0xCA: + DM2SAD_H = value & 0x0FFF; + UPDATE_REG(0xCA, DM2SAD_H); + break; + case 0xCC: + DM2DAD_L = value; + UPDATE_REG(0xCC, DM2DAD_L); + break; + case 0xCE: + DM2DAD_H = value & 0x07FF; + UPDATE_REG(0xCE, DM2DAD_H); + break; + case 0xD0: + DM2CNT_L = value & 0x3FFF; + UPDATE_REG(0xD0, 0); + break; + case 0xD2: { + bool start = ((DM2CNT_H ^ value) & 0x8000) ? true : false; - value &= 0xF7E0; + value &= 0xF7E0; - DM2CNT_H = value; - UPDATE_REG(0xD2, DM2CNT_H); + DM2CNT_H = value; + UPDATE_REG(0xD2, DM2CNT_H); - if(start && (value & 0x8000)) { - dma2Source = DM2SAD_L | (DM2SAD_H << 16); - dma2Dest = DM2DAD_L | (DM2DAD_H << 16); + if (start && (value & 0x8000)) { + dma2Source = DM2SAD_L | (DM2SAD_H << 16); + dma2Dest = DM2DAD_L | (DM2DAD_H << 16); - CPUCheckDMA(0, 4); - } - } - break; - case 0xD4: - DM3SAD_L = value; - UPDATE_REG(0xD4, DM3SAD_L); - break; - case 0xD6: - DM3SAD_H = value & 0x0FFF; - UPDATE_REG(0xD6, DM3SAD_H); - break; - case 0xD8: - DM3DAD_L = value; - UPDATE_REG(0xD8, DM3DAD_L); - break; - case 0xDA: - DM3DAD_H = value & 0x0FFF; - UPDATE_REG(0xDA, DM3DAD_H); - break; - case 0xDC: - DM3CNT_L = value; - UPDATE_REG(0xDC, 0); - break; - case 0xDE: - { - bool start = ((DM3CNT_H ^ value) & 0x8000) ? true : false; + CPUCheckDMA(0, 4); + } + } break; + case 0xD4: + DM3SAD_L = value; + UPDATE_REG(0xD4, DM3SAD_L); + break; + case 0xD6: + DM3SAD_H = value & 0x0FFF; + UPDATE_REG(0xD6, DM3SAD_H); + break; + case 0xD8: + DM3DAD_L = value; + UPDATE_REG(0xD8, DM3DAD_L); + break; + case 0xDA: + DM3DAD_H = value & 0x0FFF; + UPDATE_REG(0xDA, DM3DAD_H); + break; + case 0xDC: + DM3CNT_L = value; + UPDATE_REG(0xDC, 0); + break; + case 0xDE: { + bool start = ((DM3CNT_H ^ value) & 0x8000) ? true : false; - value &= 0xFFE0; + value &= 0xFFE0; - DM3CNT_H = value; - UPDATE_REG(0xDE, DM3CNT_H); - - if(start && (value & 0x8000)) { - dma3Source = DM3SAD_L | (DM3SAD_H << 16); - dma3Dest = DM3DAD_L | (DM3DAD_H << 16); - CPUCheckDMA(0,8); - } - } - break; - case 0x100: - timer0Reload = value; - interp_rate(); - break; - case 0x102: - timer0Value = value; - timerOnOffDelay|=1; - cpuNextEvent = cpuTotalTicks; - break; - case 0x104: - timer1Reload = value; - interp_rate(); - break; - case 0x106: - timer1Value = value; - timerOnOffDelay|=2; - cpuNextEvent = cpuTotalTicks; - break; - case 0x108: - timer2Reload = value; - break; - case 0x10A: - timer2Value = value; - timerOnOffDelay|=4; - cpuNextEvent = cpuTotalTicks; - break; - case 0x10C: - timer3Reload = value; - break; - case 0x10E: - timer3Value = value; - timerOnOffDelay|=8; - cpuNextEvent = cpuTotalTicks; - break; + DM3CNT_H = value; + UPDATE_REG(0xDE, DM3CNT_H); + if (start && (value & 0x8000)) { + dma3Source = DM3SAD_L | (DM3SAD_H << 16); + dma3Dest = DM3DAD_L | (DM3DAD_H << 16); + CPUCheckDMA(0, 8); + } + } break; + case 0x100: + timer0Reload = value; + interp_rate(); + break; + case 0x102: + timer0Value = value; + timerOnOffDelay |= 1; + cpuNextEvent = cpuTotalTicks; + break; + case 0x104: + timer1Reload = value; + interp_rate(); + break; + case 0x106: + timer1Value = value; + timerOnOffDelay |= 2; + cpuNextEvent = cpuTotalTicks; + break; + case 0x108: + timer2Reload = value; + break; + case 0x10A: + timer2Value = value; + timerOnOffDelay |= 4; + cpuNextEvent = cpuTotalTicks; + break; + case 0x10C: + timer3Reload = value; + break; + case 0x10E: + timer3Value = value; + timerOnOffDelay |= 8; + cpuNextEvent = cpuTotalTicks; + break; #ifndef NO_LINK - case COMM_SIOCNT: - StartLink(value); - break; + case COMM_SIOCNT: + StartLink(value); + break; - case COMM_SIODATA8: - UPDATE_REG(COMM_SIODATA8, value); - break; + case COMM_SIODATA8: + UPDATE_REG(COMM_SIODATA8, value); + break; #endif - case 0x130: - P1 |= (value & 0x3FF); - UPDATE_REG(0x130, P1); - break; + case 0x130: + P1 |= (value & 0x3FF); + UPDATE_REG(0x130, P1); + break; - case 0x132: - UPDATE_REG(0x132, value & 0xC3FF); - break; + case 0x132: + UPDATE_REG(0x132, value & 0xC3FF); + break; #ifndef NO_LINK - case COMM_RCNT: - StartGPLink(value); - break; + case COMM_RCNT: + StartGPLink(value); + break; - case COMM_JOYCNT: - { - u16 cur = READ16LE(&ioMem[COMM_JOYCNT]); + case COMM_JOYCNT: { + u16 cur = READ16LE(&ioMem[COMM_JOYCNT]); - if (value & JOYCNT_RESET) cur &= ~JOYCNT_RESET; - if (value & JOYCNT_RECV_COMPLETE) cur &= ~JOYCNT_RECV_COMPLETE; - if (value & JOYCNT_SEND_COMPLETE) cur &= ~JOYCNT_SEND_COMPLETE; - if (value & JOYCNT_INT_ENABLE) cur |= JOYCNT_INT_ENABLE; + if (value & JOYCNT_RESET) + cur &= ~JOYCNT_RESET; + if (value & JOYCNT_RECV_COMPLETE) + cur &= ~JOYCNT_RECV_COMPLETE; + if (value & JOYCNT_SEND_COMPLETE) + cur &= ~JOYCNT_SEND_COMPLETE; + if (value & JOYCNT_INT_ENABLE) + cur |= JOYCNT_INT_ENABLE; - UPDATE_REG(COMM_JOYCNT, cur); - } - break; + UPDATE_REG(COMM_JOYCNT, cur); + } break; - case COMM_JOY_RECV_L: - UPDATE_REG(COMM_JOY_RECV_L, value); - break; - case COMM_JOY_RECV_H: - UPDATE_REG(COMM_JOY_RECV_H, value); - break; + case COMM_JOY_RECV_L: + UPDATE_REG(COMM_JOY_RECV_L, value); + break; + case COMM_JOY_RECV_H: + UPDATE_REG(COMM_JOY_RECV_H, value); + break; - case COMM_JOY_TRANS_L: - UPDATE_REG(COMM_JOY_TRANS_L, value); - UPDATE_REG(COMM_JOYSTAT, READ16LE(&ioMem[COMM_JOYSTAT]) | JOYSTAT_SEND); - break; - case COMM_JOY_TRANS_H: - UPDATE_REG(COMM_JOY_TRANS_H, value); - UPDATE_REG(COMM_JOYSTAT, READ16LE(&ioMem[COMM_JOYSTAT]) | JOYSTAT_SEND); - break; + case COMM_JOY_TRANS_L: + UPDATE_REG(COMM_JOY_TRANS_L, value); + UPDATE_REG(COMM_JOYSTAT, READ16LE(&ioMem[COMM_JOYSTAT]) | JOYSTAT_SEND); + break; + case COMM_JOY_TRANS_H: + UPDATE_REG(COMM_JOY_TRANS_H, value); + UPDATE_REG(COMM_JOYSTAT, READ16LE(&ioMem[COMM_JOYSTAT]) | JOYSTAT_SEND); + break; - case COMM_JOYSTAT: - UPDATE_REG(COMM_JOYSTAT, (READ16LE(&ioMem[COMM_JOYSTAT]) & 0x0a) | (value & ~0x0a)); - break; + case COMM_JOYSTAT: + UPDATE_REG(COMM_JOYSTAT, (READ16LE(&ioMem[COMM_JOYSTAT]) & 0x0a) | (value & ~0x0a)); + break; #endif - case 0x200: - IE = value & 0x3FFF; - UPDATE_REG(0x200, IE); - if ((IME & 1) && (IF & IE) && armIrqEnable) - cpuNextEvent = cpuTotalTicks; - break; - case 0x202: - IF ^= (value & IF); - UPDATE_REG(0x202, IF); - break; - case 0x204: - { - memoryWait[0x0e] = memoryWaitSeq[0x0e] = gamepakRamWaitState[value & 3]; + case 0x200: + IE = value & 0x3FFF; + UPDATE_REG(0x200, IE); + if ((IME & 1) && (IF & IE) && armIrqEnable) + cpuNextEvent = cpuTotalTicks; + break; + case 0x202: + IF ^= (value & IF); + UPDATE_REG(0x202, IF); + break; + case 0x204: { + memoryWait[0x0e] = memoryWaitSeq[0x0e] = gamepakRamWaitState[value & 3]; - if(!speedHack) { - memoryWait[0x08] = memoryWait[0x09] = gamepakWaitState[(value >> 2) & 3]; - memoryWaitSeq[0x08] = memoryWaitSeq[0x09] = - gamepakWaitState0[(value >> 4) & 1]; + if (!speedHack) { + memoryWait[0x08] = memoryWait[0x09] = gamepakWaitState[(value >> 2) & 3]; + memoryWaitSeq[0x08] = memoryWaitSeq[0x09] = gamepakWaitState0[(value >> 4) & 1]; - memoryWait[0x0a] = memoryWait[0x0b] = gamepakWaitState[(value >> 5) & 3]; - memoryWaitSeq[0x0a] = memoryWaitSeq[0x0b] = - gamepakWaitState1[(value >> 7) & 1]; + memoryWait[0x0a] = memoryWait[0x0b] = gamepakWaitState[(value >> 5) & 3]; + memoryWaitSeq[0x0a] = memoryWaitSeq[0x0b] = gamepakWaitState1[(value >> 7) & 1]; - memoryWait[0x0c] = memoryWait[0x0d] = gamepakWaitState[(value >> 8) & 3]; - memoryWaitSeq[0x0c] = memoryWaitSeq[0x0d] = - gamepakWaitState2[(value >> 10) & 1]; - } else { - memoryWait[0x08] = memoryWait[0x09] = 3; - memoryWaitSeq[0x08] = memoryWaitSeq[0x09] = 1; + memoryWait[0x0c] = memoryWait[0x0d] = gamepakWaitState[(value >> 8) & 3]; + memoryWaitSeq[0x0c] = memoryWaitSeq[0x0d] = gamepakWaitState2[(value >> 10) & 1]; + } else { + memoryWait[0x08] = memoryWait[0x09] = 3; + memoryWaitSeq[0x08] = memoryWaitSeq[0x09] = 1; - memoryWait[0x0a] = memoryWait[0x0b] = 3; - memoryWaitSeq[0x0a] = memoryWaitSeq[0x0b] = 1; + memoryWait[0x0a] = memoryWait[0x0b] = 3; + memoryWaitSeq[0x0a] = memoryWaitSeq[0x0b] = 1; - memoryWait[0x0c] = memoryWait[0x0d] = 3; - memoryWaitSeq[0x0c] = memoryWaitSeq[0x0d] = 1; - } + memoryWait[0x0c] = memoryWait[0x0d] = 3; + memoryWaitSeq[0x0c] = memoryWaitSeq[0x0d] = 1; + } - for(int i = 8; i < 15; i++) { - memoryWait32[i] = memoryWait[i] + memoryWaitSeq[i] + 1; - memoryWaitSeq32[i] = memoryWaitSeq[i]*2 + 1; - } + for (int i = 8; i < 15; i++) { + memoryWait32[i] = memoryWait[i] + memoryWaitSeq[i] + 1; + memoryWaitSeq32[i] = memoryWaitSeq[i] * 2 + 1; + } - if((value & 0x4000) == 0x4000) { - busPrefetchEnable = true; - busPrefetch = false; - busPrefetchCount = 0; - } else { - busPrefetchEnable = false; - busPrefetch = false; - busPrefetchCount = 0; - } - UPDATE_REG(0x204, value & 0x7FFF); + if ((value & 0x4000) == 0x4000) { + busPrefetchEnable = true; + busPrefetch = false; + busPrefetchCount = 0; + } else { + busPrefetchEnable = false; + busPrefetch = false; + busPrefetchCount = 0; + } + UPDATE_REG(0x204, value & 0x7FFF); + } break; + case 0x208: + IME = value & 1; + UPDATE_REG(0x208, IME); + if ((IME & 1) && (IF & IE) && armIrqEnable) + cpuNextEvent = cpuTotalTicks; + break; + case 0x300: + if (value != 0) + value &= 0xFFFE; + UPDATE_REG(0x300, value); + break; + default: + UPDATE_REG(address & 0x3FE, value); + break; } - break; - case 0x208: - IME = value & 1; - UPDATE_REG(0x208, IME); - if ((IME & 1) && (IF & IE) && armIrqEnable) - cpuNextEvent = cpuTotalTicks; - break; - case 0x300: - if(value != 0) - value &= 0xFFFE; - UPDATE_REG(0x300, value); - break; - default: - UPDATE_REG(address&0x3FE, value); - break; - } } -void applyTimer () +void applyTimer() { - if (timerOnOffDelay & 1) - { - timer0ClockReload = TIMER_TICKS[timer0Value & 3]; - if(!timer0On && (timer0Value & 0x80)) { - // reload the counter - TM0D = timer0Reload; - timer0Ticks = (0x10000 - TM0D) << timer0ClockReload; - UPDATE_REG(0x100, TM0D); + if (timerOnOffDelay & 1) { + timer0ClockReload = TIMER_TICKS[timer0Value & 3]; + if (!timer0On && (timer0Value & 0x80)) { + // reload the counter + TM0D = timer0Reload; + timer0Ticks = (0x10000 - TM0D) << timer0ClockReload; + UPDATE_REG(0x100, TM0D); + } + timer0On = timer0Value & 0x80 ? true : false; + TM0CNT = timer0Value & 0xC7; + interp_rate(); + UPDATE_REG(0x102, TM0CNT); + // CPUUpdateTicks(); } - timer0On = timer0Value & 0x80 ? true : false; - TM0CNT = timer0Value & 0xC7; - interp_rate(); - UPDATE_REG(0x102, TM0CNT); - // CPUUpdateTicks(); - } - if (timerOnOffDelay & 2) - { - timer1ClockReload = TIMER_TICKS[timer1Value & 3]; - if(!timer1On && (timer1Value & 0x80)) { - // reload the counter - TM1D = timer1Reload; - timer1Ticks = (0x10000 - TM1D) << timer1ClockReload; - UPDATE_REG(0x104, TM1D); + if (timerOnOffDelay & 2) { + timer1ClockReload = TIMER_TICKS[timer1Value & 3]; + if (!timer1On && (timer1Value & 0x80)) { + // reload the counter + TM1D = timer1Reload; + timer1Ticks = (0x10000 - TM1D) << timer1ClockReload; + UPDATE_REG(0x104, TM1D); + } + timer1On = timer1Value & 0x80 ? true : false; + TM1CNT = timer1Value & 0xC7; + interp_rate(); + UPDATE_REG(0x106, TM1CNT); } - timer1On = timer1Value & 0x80 ? true : false; - TM1CNT = timer1Value & 0xC7; - interp_rate(); - UPDATE_REG(0x106, TM1CNT); - } - if (timerOnOffDelay & 4) - { - timer2ClockReload = TIMER_TICKS[timer2Value & 3]; - if(!timer2On && (timer2Value & 0x80)) { - // reload the counter - TM2D = timer2Reload; - timer2Ticks = (0x10000 - TM2D) << timer2ClockReload; - UPDATE_REG(0x108, TM2D); + if (timerOnOffDelay & 4) { + timer2ClockReload = TIMER_TICKS[timer2Value & 3]; + if (!timer2On && (timer2Value & 0x80)) { + // reload the counter + TM2D = timer2Reload; + timer2Ticks = (0x10000 - TM2D) << timer2ClockReload; + UPDATE_REG(0x108, TM2D); + } + timer2On = timer2Value & 0x80 ? true : false; + TM2CNT = timer2Value & 0xC7; + UPDATE_REG(0x10A, TM2CNT); } - timer2On = timer2Value & 0x80 ? true : false; - TM2CNT = timer2Value & 0xC7; - UPDATE_REG(0x10A, TM2CNT); - } - if (timerOnOffDelay & 8) - { - timer3ClockReload = TIMER_TICKS[timer3Value & 3]; - if(!timer3On && (timer3Value & 0x80)) { - // reload the counter - TM3D = timer3Reload; - timer3Ticks = (0x10000 - TM3D) << timer3ClockReload; - UPDATE_REG(0x10C, TM3D); + if (timerOnOffDelay & 8) { + timer3ClockReload = TIMER_TICKS[timer3Value & 3]; + if (!timer3On && (timer3Value & 0x80)) { + // reload the counter + TM3D = timer3Reload; + timer3Ticks = (0x10000 - TM3D) << timer3ClockReload; + UPDATE_REG(0x10C, TM3D); + } + timer3On = timer3Value & 0x80 ? true : false; + TM3CNT = timer3Value & 0xC7; + UPDATE_REG(0x10E, TM3CNT); } - timer3On = timer3Value & 0x80 ? true : false; - TM3CNT = timer3Value & 0xC7; - UPDATE_REG(0x10E, TM3CNT); - } - cpuNextEvent = CPUUpdateTicks(); - timerOnOffDelay = 0; + cpuNextEvent = CPUUpdateTicks(); + timerOnOffDelay = 0; } u8 cpuBitsSet[256]; u8 cpuLowestBitSet[256]; -void CPUInit(const char *biosFileName, bool useBiosFile) +void CPUInit(const char* biosFileName, bool useBiosFile) { #ifdef WORDS_BIGENDIAN - if(!cpuBiosSwapped) { - for(unsigned int i = 0; i < sizeof(myROM)/4; i++) { - WRITE32LE(&myROM[i], myROM[i]); + if (!cpuBiosSwapped) { + for (unsigned int i = 0; i < sizeof(myROM) / 4; i++) { + WRITE32LE(&myROM[i], myROM[i]); + } + cpuBiosSwapped = true; } - cpuBiosSwapped = true; - } #endif - gbaSaveType = 0; - eepromInUse = 0; - useBios = false; + gbaSaveType = 0; + eepromInUse = 0; + useBios = false; - if(useBiosFile && strlen(biosFileName) > 0) { - int size = 0x4000; - if(utilLoad(biosFileName, + if (useBiosFile && strlen(biosFileName) > 0) { + int size = 0x4000; + if (utilLoad(biosFileName, CPUIsGBABios, bios, size)) { - if(size == 0x4000) - useBios = true; - else - systemMessage(MSG_INVALID_BIOS_FILE_SIZE, N_("Invalid BIOS file size")); + if (size == 0x4000) + useBios = true; + else + systemMessage(MSG_INVALID_BIOS_FILE_SIZE, N_("Invalid BIOS file size")); + } } - } - if(!useBios) { - memcpy(bios, myROM, sizeof(myROM)); - } + if (!useBios) { + memcpy(bios, myROM, sizeof(myROM)); + } - int i = 0; + int i = 0; - biosProtected[0] = 0x00; - biosProtected[1] = 0xf0; - biosProtected[2] = 0x29; - biosProtected[3] = 0xe1; + biosProtected[0] = 0x00; + biosProtected[1] = 0xf0; + biosProtected[2] = 0x29; + biosProtected[3] = 0xe1; - for(i = 0; i < 256; i++) { - int count = 0; - int j; - for(j = 0; j < 8; j++) - if(i & (1 << j)) - count++; - cpuBitsSet[i] = count; + for (i = 0; i < 256; i++) { + int count = 0; + int j; + for (j = 0; j < 8; j++) + if (i & (1 << j)) + count++; + cpuBitsSet[i] = count; - for(j = 0; j < 8; j++) - if(i & (1 << j)) - break; - cpuLowestBitSet[i] = j; - } + for (j = 0; j < 8; j++) + if (i & (1 << j)) + break; + cpuLowestBitSet[i] = j; + } - for(i = 0; i < 0x400; i++) - ioReadable[i] = true; - for(i = 0x10; i < 0x48; i++) - ioReadable[i] = false; - for(i = 0x4c; i < 0x50; i++) - ioReadable[i] = false; - for(i = 0x54; i < 0x60; i++) - ioReadable[i] = false; - for(i = 0x8c; i < 0x90; i++) - ioReadable[i] = false; - for(i = 0xa0; i < 0xb8; i++) - ioReadable[i] = false; - for(i = 0xbc; i < 0xc4; i++) - ioReadable[i] = false; - for(i = 0xc8; i < 0xd0; i++) - ioReadable[i] = false; - for(i = 0xd4; i < 0xdc; i++) - ioReadable[i] = false; - for(i = 0xe0; i < 0x100; i++) - ioReadable[i] = false; - for(i = 0x110; i < 0x120; i++) - ioReadable[i] = false; - for(i = 0x12c; i < 0x130; i++) - ioReadable[i] = false; - for(i = 0x138; i < 0x140; i++) - ioReadable[i] = false; - for(i = 0x144; i < 0x150; i++) - ioReadable[i] = false; - for(i = 0x15c; i < 0x200; i++) - ioReadable[i] = false; - for(i = 0x20c; i < 0x300; i++) - ioReadable[i] = false; - for(i = 0x304; i < 0x400; i++) - ioReadable[i] = false; + for (i = 0; i < 0x400; i++) + ioReadable[i] = true; + for (i = 0x10; i < 0x48; i++) + ioReadable[i] = false; + for (i = 0x4c; i < 0x50; i++) + ioReadable[i] = false; + for (i = 0x54; i < 0x60; i++) + ioReadable[i] = false; + for (i = 0x8c; i < 0x90; i++) + ioReadable[i] = false; + for (i = 0xa0; i < 0xb8; i++) + ioReadable[i] = false; + for (i = 0xbc; i < 0xc4; i++) + ioReadable[i] = false; + for (i = 0xc8; i < 0xd0; i++) + ioReadable[i] = false; + for (i = 0xd4; i < 0xdc; i++) + ioReadable[i] = false; + for (i = 0xe0; i < 0x100; i++) + ioReadable[i] = false; + for (i = 0x110; i < 0x120; i++) + ioReadable[i] = false; + for (i = 0x12c; i < 0x130; i++) + ioReadable[i] = false; + for (i = 0x138; i < 0x140; i++) + ioReadable[i] = false; + for (i = 0x144; i < 0x150; i++) + ioReadable[i] = false; + for (i = 0x15c; i < 0x200; i++) + ioReadable[i] = false; + for (i = 0x20c; i < 0x300; i++) + ioReadable[i] = false; + for (i = 0x304; i < 0x400; i++) + ioReadable[i] = false; - if(romSize < 0x1fe2000) { - *((u16 *)&rom[0x1fe209c]) = 0xdffa; // SWI 0xFA - *((u16 *)&rom[0x1fe209e]) = 0x4770; // BX LR - } else { - agbPrintEnable(false); - } + if (romSize < 0x1fe2000) { + *((u16*)&rom[0x1fe209c]) = 0xdffa; // SWI 0xFA + *((u16*)&rom[0x1fe209e]) = 0x4770; // BX LR + } else { + agbPrintEnable(false); + } } void SetSaveType(int st) { - switch (st) { - case 0: // automatic - cpuSramEnabled = true; - cpuFlashEnabled = true; - cpuEEPROMEnabled = true; - cpuEEPROMSensorEnabled = false; - gbaSaveType = 0; - cpuSaveGameFunc = flashSaveDecide; - break; - case 1: // EEPROM - eepromReset(); - cpuSramEnabled = false; - cpuFlashEnabled = false; - cpuEEPROMEnabled = true; - cpuEEPROMSensorEnabled = false; - gbaSaveType = 3; - // EEPROM usage is automatically detected - break; - case 2: // SRAM - cpuSramEnabled = true; - cpuFlashEnabled = false; - cpuEEPROMEnabled = false; - cpuEEPROMSensorEnabled = false; - cpuSaveGameFunc = sramDelayedWrite; // to insure we detect the write - gbaSaveType = 1; - break; - case 3: // FLASH - flashReset(); - cpuSramEnabled = false; - cpuFlashEnabled = true; - cpuEEPROMEnabled = false; - cpuEEPROMSensorEnabled = false; - cpuSaveGameFunc = flashDelayedWrite; // to insure we detect the write - gbaSaveType = 2; - break; - case 4: // EEPROM+Sensor - cpuSramEnabled = false; - cpuFlashEnabled = false; - cpuEEPROMEnabled = true; - cpuEEPROMSensorEnabled = true; - // EEPROM usage is automatically detected - gbaSaveType = 3; - break; - case 5: // NONE - cpuSramEnabled = false; - cpuFlashEnabled = false; - cpuEEPROMEnabled = false; - cpuEEPROMSensorEnabled = false; - // no save at all - gbaSaveType = 5; - break; - } + switch (st) { + case 0: // automatic + cpuSramEnabled = true; + cpuFlashEnabled = true; + cpuEEPROMEnabled = true; + cpuEEPROMSensorEnabled = false; + gbaSaveType = 0; + cpuSaveGameFunc = flashSaveDecide; + break; + case 1: // EEPROM + eepromReset(); + cpuSramEnabled = false; + cpuFlashEnabled = false; + cpuEEPROMEnabled = true; + cpuEEPROMSensorEnabled = false; + gbaSaveType = 3; + // EEPROM usage is automatically detected + break; + case 2: // SRAM + cpuSramEnabled = true; + cpuFlashEnabled = false; + cpuEEPROMEnabled = false; + cpuEEPROMSensorEnabled = false; + cpuSaveGameFunc = sramDelayedWrite; // to insure we detect the write + gbaSaveType = 1; + break; + case 3: // FLASH + flashReset(); + cpuSramEnabled = false; + cpuFlashEnabled = true; + cpuEEPROMEnabled = false; + cpuEEPROMSensorEnabled = false; + cpuSaveGameFunc = flashDelayedWrite; // to insure we detect the write + gbaSaveType = 2; + break; + case 4: // EEPROM+Sensor + cpuSramEnabled = false; + cpuFlashEnabled = false; + cpuEEPROMEnabled = true; + cpuEEPROMSensorEnabled = true; + // EEPROM usage is automatically detected + gbaSaveType = 3; + break; + case 5: // NONE + cpuSramEnabled = false; + cpuFlashEnabled = false; + cpuEEPROMEnabled = false; + cpuEEPROMSensorEnabled = false; + // no save at all + gbaSaveType = 5; + break; + } } void CPUReset() { - if(gbaSaveType == 0) { - if(eepromInUse) - gbaSaveType = 3; - else - switch(saveType) { - case 2: - gbaSaveType = 1; - break; - case 3: - gbaSaveType = 2; - break; - } - } - switch (CheckEReaderRegion()) - { - case 1: //US - EReaderWriteMemory(0x8009134, 0x46C0DFE0); - break; - case 2: - EReaderWriteMemory(0x8008A8C, 0x46C0DFE0); - break; - case 3: - EReaderWriteMemory(0x80091A8, 0x46C0DFE0); - break; - } - rtcReset(); - // clean registers - memset(®[0], 0, sizeof(reg)); - // clean OAM - memset(oam, 0, 0x400); - // clean palette - memset(paletteRAM, 0, 0x400); - // clean picture - memset(pix, 0, 4*160*240); - // clean vram - memset(vram, 0, 0x20000); - // clean io memory - memset(ioMem, 0, 0x400); - - DISPCNT = 0x0080; - DISPSTAT = 0x0000; - VCOUNT = (useBios && !skipBios) ? 0 :0x007E; - BG0CNT = 0x0000; - BG1CNT = 0x0000; - BG2CNT = 0x0000; - BG3CNT = 0x0000; - BG0HOFS = 0x0000; - BG0VOFS = 0x0000; - BG1HOFS = 0x0000; - BG1VOFS = 0x0000; - BG2HOFS = 0x0000; - BG2VOFS = 0x0000; - BG3HOFS = 0x0000; - BG3VOFS = 0x0000; - BG2PA = 0x0100; - BG2PB = 0x0000; - BG2PC = 0x0000; - BG2PD = 0x0100; - BG2X_L = 0x0000; - BG2X_H = 0x0000; - BG2Y_L = 0x0000; - BG2Y_H = 0x0000; - BG3PA = 0x0100; - BG3PB = 0x0000; - BG3PC = 0x0000; - BG3PD = 0x0100; - BG3X_L = 0x0000; - BG3X_H = 0x0000; - BG3Y_L = 0x0000; - BG3Y_H = 0x0000; - WIN0H = 0x0000; - WIN1H = 0x0000; - WIN0V = 0x0000; - WIN1V = 0x0000; - WININ = 0x0000; - WINOUT = 0x0000; - MOSAIC = 0x0000; - BLDMOD = 0x0000; - COLEV = 0x0000; - COLY = 0x0000; - DM0SAD_L = 0x0000; - DM0SAD_H = 0x0000; - DM0DAD_L = 0x0000; - DM0DAD_H = 0x0000; - DM0CNT_L = 0x0000; - DM0CNT_H = 0x0000; - DM1SAD_L = 0x0000; - DM1SAD_H = 0x0000; - DM1DAD_L = 0x0000; - DM1DAD_H = 0x0000; - DM1CNT_L = 0x0000; - DM1CNT_H = 0x0000; - DM2SAD_L = 0x0000; - DM2SAD_H = 0x0000; - DM2DAD_L = 0x0000; - DM2DAD_H = 0x0000; - DM2CNT_L = 0x0000; - DM2CNT_H = 0x0000; - DM3SAD_L = 0x0000; - DM3SAD_H = 0x0000; - DM3DAD_L = 0x0000; - DM3DAD_H = 0x0000; - DM3CNT_L = 0x0000; - DM3CNT_H = 0x0000; - TM0D = 0x0000; - TM0CNT = 0x0000; - TM1D = 0x0000; - TM1CNT = 0x0000; - TM2D = 0x0000; - TM2CNT = 0x0000; - TM3D = 0x0000; - TM3CNT = 0x0000; - P1 = 0x03FF; - IE = 0x0000; - IF = 0x0000; - IME = 0x0000; - - armMode = 0x1F; - - if(cpuIsMultiBoot) { - reg[13].I = 0x03007F00; - reg[15].I = 0x02000000; - reg[16].I = 0x00000000; - reg[R13_IRQ].I = 0x03007FA0; - reg[R13_SVC].I = 0x03007FE0; - armIrqEnable = true; - } else { - if(useBios && !skipBios) { - reg[15].I = 0x00000000; - armMode = 0x13; - armIrqEnable = false; - } else { - reg[13].I = 0x03007F00; - reg[15].I = 0x08000000; - reg[16].I = 0x00000000; - reg[R13_IRQ].I = 0x03007FA0; - reg[R13_SVC].I = 0x03007FE0; - armIrqEnable = true; + if (gbaSaveType == 0) { + if (eepromInUse) + gbaSaveType = 3; + else + switch (saveType) { + case 2: + gbaSaveType = 1; + break; + case 3: + gbaSaveType = 2; + break; + } } - } - armState = true; - C_FLAG = V_FLAG = N_FLAG = Z_FLAG = false; - UPDATE_REG(0x00, DISPCNT); - UPDATE_REG(0x06, VCOUNT); - UPDATE_REG(0x20, BG2PA); - UPDATE_REG(0x26, BG2PD); - UPDATE_REG(0x30, BG3PA); - UPDATE_REG(0x36, BG3PD); - UPDATE_REG(0x130, P1); - UPDATE_REG(0x88, 0x200); + switch (CheckEReaderRegion()) { + case 1: //US + EReaderWriteMemory(0x8009134, 0x46C0DFE0); + break; + case 2: + EReaderWriteMemory(0x8008A8C, 0x46C0DFE0); + break; + case 3: + EReaderWriteMemory(0x80091A8, 0x46C0DFE0); + break; + } + rtcReset(); + // clean registers + memset(®[0], 0, sizeof(reg)); + // clean OAM + memset(oam, 0, 0x400); + // clean palette + memset(paletteRAM, 0, 0x400); + // clean picture + memset(pix, 0, 4 * 160 * 240); + // clean vram + memset(vram, 0, 0x20000); + // clean io memory + memset(ioMem, 0, 0x400); - // disable FIQ - reg[16].I |= 0x40; + DISPCNT = 0x0080; + DISPSTAT = 0x0000; + VCOUNT = (useBios && !skipBios) ? 0 : 0x007E; + BG0CNT = 0x0000; + BG1CNT = 0x0000; + BG2CNT = 0x0000; + BG3CNT = 0x0000; + BG0HOFS = 0x0000; + BG0VOFS = 0x0000; + BG1HOFS = 0x0000; + BG1VOFS = 0x0000; + BG2HOFS = 0x0000; + BG2VOFS = 0x0000; + BG3HOFS = 0x0000; + BG3VOFS = 0x0000; + BG2PA = 0x0100; + BG2PB = 0x0000; + BG2PC = 0x0000; + BG2PD = 0x0100; + BG2X_L = 0x0000; + BG2X_H = 0x0000; + BG2Y_L = 0x0000; + BG2Y_H = 0x0000; + BG3PA = 0x0100; + BG3PB = 0x0000; + BG3PC = 0x0000; + BG3PD = 0x0100; + BG3X_L = 0x0000; + BG3X_H = 0x0000; + BG3Y_L = 0x0000; + BG3Y_H = 0x0000; + WIN0H = 0x0000; + WIN1H = 0x0000; + WIN0V = 0x0000; + WIN1V = 0x0000; + WININ = 0x0000; + WINOUT = 0x0000; + MOSAIC = 0x0000; + BLDMOD = 0x0000; + COLEV = 0x0000; + COLY = 0x0000; + DM0SAD_L = 0x0000; + DM0SAD_H = 0x0000; + DM0DAD_L = 0x0000; + DM0DAD_H = 0x0000; + DM0CNT_L = 0x0000; + DM0CNT_H = 0x0000; + DM1SAD_L = 0x0000; + DM1SAD_H = 0x0000; + DM1DAD_L = 0x0000; + DM1DAD_H = 0x0000; + DM1CNT_L = 0x0000; + DM1CNT_H = 0x0000; + DM2SAD_L = 0x0000; + DM2SAD_H = 0x0000; + DM2DAD_L = 0x0000; + DM2DAD_H = 0x0000; + DM2CNT_L = 0x0000; + DM2CNT_H = 0x0000; + DM3SAD_L = 0x0000; + DM3SAD_H = 0x0000; + DM3DAD_L = 0x0000; + DM3DAD_H = 0x0000; + DM3CNT_L = 0x0000; + DM3CNT_H = 0x0000; + TM0D = 0x0000; + TM0CNT = 0x0000; + TM1D = 0x0000; + TM1CNT = 0x0000; + TM2D = 0x0000; + TM2CNT = 0x0000; + TM3D = 0x0000; + TM3CNT = 0x0000; + P1 = 0x03FF; + IE = 0x0000; + IF = 0x0000; + IME = 0x0000; - CPUUpdateCPSR(); + armMode = 0x1F; - armNextPC = reg[15].I; - reg[15].I += 4; + if (cpuIsMultiBoot) { + reg[13].I = 0x03007F00; + reg[15].I = 0x02000000; + reg[16].I = 0x00000000; + reg[R13_IRQ].I = 0x03007FA0; + reg[R13_SVC].I = 0x03007FE0; + armIrqEnable = true; + } else { + if (useBios && !skipBios) { + reg[15].I = 0x00000000; + armMode = 0x13; + armIrqEnable = false; + } else { + reg[13].I = 0x03007F00; + reg[15].I = 0x08000000; + reg[16].I = 0x00000000; + reg[R13_IRQ].I = 0x03007FA0; + reg[R13_SVC].I = 0x03007FE0; + armIrqEnable = true; + } + } + armState = true; + C_FLAG = V_FLAG = N_FLAG = Z_FLAG = false; + UPDATE_REG(0x00, DISPCNT); + UPDATE_REG(0x06, VCOUNT); + UPDATE_REG(0x20, BG2PA); + UPDATE_REG(0x26, BG2PD); + UPDATE_REG(0x30, BG3PA); + UPDATE_REG(0x36, BG3PD); + UPDATE_REG(0x130, P1); + UPDATE_REG(0x88, 0x200); - // reset internal state - holdState = false; - holdType = 0; + // disable FIQ + reg[16].I |= 0x40; - biosProtected[0] = 0x00; - biosProtected[1] = 0xf0; - biosProtected[2] = 0x29; - biosProtected[3] = 0xe1; + CPUUpdateCPSR(); - lcdTicks = (useBios && !skipBios) ? 1008 : 208; - timer0On = false; - timer0Ticks = 0; - timer0Reload = 0; - timer0ClockReload = 0; - timer1On = false; - timer1Ticks = 0; - timer1Reload = 0; - timer1ClockReload = 0; - timer2On = false; - timer2Ticks = 0; - timer2Reload = 0; - timer2ClockReload = 0; - timer3On = false; - timer3Ticks = 0; - timer3Reload = 0; - timer3ClockReload = 0; - dma0Source = 0; - dma0Dest = 0; - dma1Source = 0; - dma1Dest = 0; - dma2Source = 0; - dma2Dest = 0; - dma3Source = 0; - dma3Dest = 0; - renderLine = mode0RenderLine; - fxOn = false; - windowOn = false; - frameCount = 0; - layerEnable = DISPCNT & layerSettings; + armNextPC = reg[15].I; + reg[15].I += 4; - CPUUpdateRenderBuffers(true); + // reset internal state + holdState = false; + holdType = 0; - for(int i = 0; i < 256; i++) { - map[i].address = (u8 *)&dummyAddress; - map[i].mask = 0; - } + biosProtected[0] = 0x00; + biosProtected[1] = 0xf0; + biosProtected[2] = 0x29; + biosProtected[3] = 0xe1; - map[0].address = bios; - map[2].address = workRAM; - map[3].address = internalRAM; - map[4].address = ioMem; - map[5].address = paletteRAM; - map[6].address = vram; - map[7].address = oam; - map[8].address = rom; - map[9].address = rom; - map[10].address = rom; - map[12].address = rom; - map[14].address = flashSaveMemory; + lcdTicks = (useBios && !skipBios) ? 1008 : 208; + timer0On = false; + timer0Ticks = 0; + timer0Reload = 0; + timer0ClockReload = 0; + timer1On = false; + timer1Ticks = 0; + timer1Reload = 0; + timer1ClockReload = 0; + timer2On = false; + timer2Ticks = 0; + timer2Reload = 0; + timer2ClockReload = 0; + timer3On = false; + timer3Ticks = 0; + timer3Reload = 0; + timer3ClockReload = 0; + dma0Source = 0; + dma0Dest = 0; + dma1Source = 0; + dma1Dest = 0; + dma2Source = 0; + dma2Dest = 0; + dma3Source = 0; + dma3Dest = 0; + renderLine = mode0RenderLine; + fxOn = false; + windowOn = false; + frameCount = 0; + layerEnable = DISPCNT & layerSettings; - SetMapMasks(); + CPUUpdateRenderBuffers(true); - soundReset(); + for (int i = 0; i < 256; i++) { + map[i].address = (u8*)&dummyAddress; + map[i].mask = 0; + } - CPUUpdateWindow0(); - CPUUpdateWindow1(); + map[0].address = bios; + map[2].address = workRAM; + map[3].address = internalRAM; + map[4].address = ioMem; + map[5].address = paletteRAM; + map[6].address = vram; + map[7].address = oam; + map[8].address = rom; + map[9].address = rom; + map[10].address = rom; + map[12].address = rom; + map[14].address = flashSaveMemory; - // make sure registers are correctly initialized if not using BIOS - if(!useBios) { - if(cpuIsMultiBoot) - BIOS_RegisterRamReset(0xfe); - else - BIOS_RegisterRamReset(0xff); - } else { - if(cpuIsMultiBoot) - BIOS_RegisterRamReset(0xfe); - } + SetMapMasks(); - SetSaveType(saveType); + soundReset(); - ARM_PREFETCH; + CPUUpdateWindow0(); + CPUUpdateWindow1(); - systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED; + // make sure registers are correctly initialized if not using BIOS + if (!useBios) { + if (cpuIsMultiBoot) + BIOS_RegisterRamReset(0xfe); + else + BIOS_RegisterRamReset(0xff); + } else { + if (cpuIsMultiBoot) + BIOS_RegisterRamReset(0xfe); + } - cpuDmaHack = false; + SetSaveType(saveType); - lastTime = systemGetClock(); + ARM_PREFETCH; - SWITicks = 0; + systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED; + + cpuDmaHack = false; + + lastTime = systemGetClock(); + + SWITicks = 0; } void CPUInterrupt() { - u32 PC = reg[15].I; - bool savedState = armState; - CPUSwitchMode(0x12, true, false); - reg[14].I = PC; - if(!savedState) - reg[14].I += 2; - reg[15].I = 0x18; - armState = true; - armIrqEnable = false; + u32 PC = reg[15].I; + bool savedState = armState; + CPUSwitchMode(0x12, true, false); + reg[14].I = PC; + if (!savedState) + reg[14].I += 2; + reg[15].I = 0x18; + armState = true; + armIrqEnable = false; - armNextPC = reg[15].I; - reg[15].I += 4; - ARM_PREFETCH; + armNextPC = reg[15].I; + reg[15].I += 4; + ARM_PREFETCH; - // if(!holdState) - biosProtected[0] = 0x02; - biosProtected[1] = 0xc0; - biosProtected[2] = 0x5e; - biosProtected[3] = 0xe5; + // if(!holdState) + biosProtected[0] = 0x02; + biosProtected[1] = 0xc0; + biosProtected[2] = 0x5e; + biosProtected[3] = 0xe5; } void CPULoop(int ticks) { - int clockTicks; - int timerOverflow = 0; - u32 memAddr = 0; - // variable used by the CPU core - cpuTotalTicks = 0; + int clockTicks; + int timerOverflow = 0; + u32 memAddr = 0; + // variable used by the CPU core + cpuTotalTicks = 0; #ifndef NO_LINK - // shuffle2: what's the purpose? - //if(GetLinkMode() != LINK_DISCONNECTED) - //cpuNextEvent = 1; +// shuffle2: what's the purpose? +//if(GetLinkMode() != LINK_DISCONNECTED) +//cpuNextEvent = 1; #endif - cpuBreakLoop = false; - cpuNextEvent = CPUUpdateTicks(); - if(cpuNextEvent > ticks) - cpuNextEvent = ticks; - - - for(;;) { - if(!holdState && !SWITicks) { - if(armState) { - armOpcodeCount++; - if (!armExecute()) - return; - if (debugger) - return; - } else { - thumbOpcodeCount++; - if (!thumbExecute()) - return; - if (debugger) - return; - } - clockTicks = 0; - } else - clockTicks = CPUUpdateTicks(); - - cpuTotalTicks += clockTicks; - - if (rtcIsEnabled()) - rtcUpdateTime(cpuTotalTicks); - - if(cpuTotalTicks >= cpuNextEvent) { - int remainingTicks = cpuTotalTicks - cpuNextEvent; - - if (SWITicks) - { - SWITicks-=clockTicks; - if (SWITicks<0) - SWITicks = 0; - } - - clockTicks = cpuNextEvent; - cpuTotalTicks = 0; - - updateLoop: - - if (IRQTicks) - { - IRQTicks -= clockTicks; - if (IRQTicks<0) - IRQTicks = 0; - } - - lcdTicks -= clockTicks; - - - if(lcdTicks <= 0) { - if(DISPSTAT & 1) { // V-BLANK - // if in V-Blank mode, keep computing... - if(DISPSTAT & 2) { - lcdTicks += 1008; - VCOUNT++; - UPDATE_REG(0x06, VCOUNT); - DISPSTAT &= 0xFFFD; - UPDATE_REG(0x04, DISPSTAT); - CPUCompareVCOUNT(); - } else { - lcdTicks += 224; - DISPSTAT |= 2; - UPDATE_REG(0x04, DISPSTAT); - if(DISPSTAT & 16) { - IF |= 2; - UPDATE_REG(0x202, IF); - } - } - - if(VCOUNT > 227) { //Reaching last line - DISPSTAT &= 0xFFFC; - UPDATE_REG(0x04, DISPSTAT); - VCOUNT = 0; - UPDATE_REG(0x06, VCOUNT); - CPUCompareVCOUNT(); - } - } else { - int framesToSkip = systemFrameSkip; - if(speedup) - framesToSkip = 9; // try 6 FPS during speedup - - if(DISPSTAT & 2) { - // if in H-Blank, leave it and move to drawing mode - VCOUNT++; - UPDATE_REG(0x06, VCOUNT); - - lcdTicks += 1008; - DISPSTAT &= 0xFFFD; - if(VCOUNT == 160) { - count++; - systemFrame(); - - if((count % 10) == 0) { - system10Frames(60); - } - if(count == 60) { - u32 time = systemGetClock(); - if(time != lastTime) { - u32 t = 100000/(time - lastTime); - systemShowSpeed(t); - } else - systemShowSpeed(0); - lastTime = time; - count = 0; - } - u32 joy = 0; - // update joystick information - if(systemReadJoypads()) - // read default joystick - joy = systemReadJoypad(-1); - P1 = 0x03FF ^ (joy & 0x3FF); - systemUpdateMotionSensor(); - UPDATE_REG(0x130, P1); - u16 P1CNT = READ16LE(((u16 *)&ioMem[0x132])); - // this seems wrong, but there are cases where the game - // can enter the stop state without requesting an IRQ from - // the joypad. - if((P1CNT & 0x4000) || stopState) { - u16 p1 = (0x3FF ^ P1) & 0x3FF; - if(P1CNT & 0x8000) { - if(p1 == (P1CNT & 0x3FF)) { - IF |= 0x1000; - UPDATE_REG(0x202, IF); - } - } else { - if(p1 & P1CNT) { - IF |= 0x1000; - UPDATE_REG(0x202, IF); - } - } - } - - u32 ext = (joy >> 10); - // If no (m) code is enabled, apply the cheats at each LCDline - if((cheatsEnabled) && (mastercode==0)) - remainingTicks += cheatsCheckKeys(P1^0x3FF, ext); - speedup = (ext & 1) ? true : false; - capture = (ext & 2) ? true : false; - - if(capture && !capturePrevious) { - captureNumber++; - systemScreenCapture(captureNumber); - } - capturePrevious = capture; - - DISPSTAT |= 1; - DISPSTAT &= 0xFFFD; - UPDATE_REG(0x04, DISPSTAT); - if(DISPSTAT & 0x0008) { - IF |= 1; - UPDATE_REG(0x202, IF); - } - CPUCheckDMA(1, 0x0f); - if(frameCount >= framesToSkip) { - systemDrawScreen(); - frameCount = 0; - } else - frameCount++; - if(systemPauseOnFrame()) - ticks = 0; - } - - UPDATE_REG(0x04, DISPSTAT); - CPUCompareVCOUNT(); - - } else { - if(frameCount >= framesToSkip) - { - (*renderLine)(); - switch(systemColorDepth) { - case 16: - { -#ifdef __LIBRETRO__ - u16 *dest = (u16 *)pix + 240 * VCOUNT; -#else - u16 *dest = (u16 *)pix + 242 * (VCOUNT+1); -#endif - for(int x = 0; x < 240;) { - *dest++ = systemColorMap16[lineMix[x++]&0xFFFF]; - *dest++ = systemColorMap16[lineMix[x++]&0xFFFF]; - *dest++ = systemColorMap16[lineMix[x++]&0xFFFF]; - *dest++ = systemColorMap16[lineMix[x++]&0xFFFF]; - - *dest++ = systemColorMap16[lineMix[x++]&0xFFFF]; - *dest++ = systemColorMap16[lineMix[x++]&0xFFFF]; - *dest++ = systemColorMap16[lineMix[x++]&0xFFFF]; - *dest++ = systemColorMap16[lineMix[x++]&0xFFFF]; - - *dest++ = systemColorMap16[lineMix[x++]&0xFFFF]; - *dest++ = systemColorMap16[lineMix[x++]&0xFFFF]; - *dest++ = systemColorMap16[lineMix[x++]&0xFFFF]; - *dest++ = systemColorMap16[lineMix[x++]&0xFFFF]; - - *dest++ = systemColorMap16[lineMix[x++]&0xFFFF]; - *dest++ = systemColorMap16[lineMix[x++]&0xFFFF]; - *dest++ = systemColorMap16[lineMix[x++]&0xFFFF]; - *dest++ = systemColorMap16[lineMix[x++]&0xFFFF]; - } - // for filters that read past the screen -#ifndef __LIBRETRO__ - *dest++ = 0; -#endif - } - break; - case 24: - { - u8 *dest = (u8 *)pix + 240 * VCOUNT * 3; - for(int x = 0; x < 240;) { - *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; - dest += 3; - *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; - dest += 3; - *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; - dest += 3; - *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; - dest += 3; - - *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; - dest += 3; - *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; - dest += 3; - *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; - dest += 3; - *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; - dest += 3; - - *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; - dest += 3; - *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; - dest += 3; - *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; - dest += 3; - *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; - dest += 3; - - *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; - dest += 3; - *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; - dest += 3; - *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; - dest += 3; - *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; - dest += 3; - } - } - break; - case 32: - { -#ifdef __LIBRETRO__ - u32 *dest = (u32 *)pix + 240 * VCOUNT; -#else - u32 *dest = (u32 *)pix + 241 * (VCOUNT+1); -#endif - for(int x = 0; x < 240; ) { - *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; - *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; - *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; - *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; - - *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; - *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; - *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; - *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; - - *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; - *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; - *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; - *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; - - *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; - *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; - *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; - *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; - } - } - break; - } - } - // entering H-Blank - DISPSTAT |= 2; - UPDATE_REG(0x04, DISPSTAT); - lcdTicks += 224; - CPUCheckDMA(2, 0x0f); - if(DISPSTAT & 16) { - IF |= 2; - UPDATE_REG(0x202, IF); - } - } - } - } - - // we shouldn't be doing sound in stop state, but we loose synchronization - // if sound is disabled, so in stop state, soundTick will just produce - // mute sound - soundTicks -= clockTicks; - if(soundTicks <= 0) { - psoundTickfn(); - soundTicks += SOUND_CLOCK_TICKS; - } - - if(!stopState) { - if(timer0On) { - timer0Ticks -= clockTicks; - if(timer0Ticks <= 0) { - timer0Ticks += (0x10000 - timer0Reload) << timer0ClockReload; - timerOverflow |= 1; - soundTimerOverflow(0); - if(TM0CNT & 0x40) { - IF |= 0x08; - UPDATE_REG(0x202, IF); - } - } - TM0D = 0xFFFF - (timer0Ticks >> timer0ClockReload); - UPDATE_REG(0x100, TM0D); - } - - if(timer1On) { - if(TM1CNT & 4) { - if(timerOverflow & 1) { - TM1D++; - if(TM1D == 0) { - TM1D += timer1Reload; - timerOverflow |= 2; - soundTimerOverflow(1); - if(TM1CNT & 0x40) { - IF |= 0x10; - UPDATE_REG(0x202, IF); - } - } - UPDATE_REG(0x104, TM1D); - } - } else { - timer1Ticks -= clockTicks; - if(timer1Ticks <= 0) { - timer1Ticks += (0x10000 - timer1Reload) << timer1ClockReload; - timerOverflow |= 2; - soundTimerOverflow(1); - if(TM1CNT & 0x40) { - IF |= 0x10; - UPDATE_REG(0x202, IF); - } - } - TM1D = 0xFFFF - (timer1Ticks >> timer1ClockReload); - UPDATE_REG(0x104, TM1D); - } - } - - if(timer2On) { - if(TM2CNT & 4) { - if(timerOverflow & 2) { - TM2D++; - if(TM2D == 0) { - TM2D += timer2Reload; - timerOverflow |= 4; - if(TM2CNT & 0x40) { - IF |= 0x20; - UPDATE_REG(0x202, IF); - } - } - UPDATE_REG(0x108, TM2D); - } - } else { - timer2Ticks -= clockTicks; - if(timer2Ticks <= 0) { - timer2Ticks += (0x10000 - timer2Reload) << timer2ClockReload; - timerOverflow |= 4; - if(TM2CNT & 0x40) { - IF |= 0x20; - UPDATE_REG(0x202, IF); - } - } - TM2D = 0xFFFF - (timer2Ticks >> timer2ClockReload); - UPDATE_REG(0x108, TM2D); - } - } - - if(timer3On) { - if(TM3CNT & 4) { - if(timerOverflow & 4) { - TM3D++; - if(TM3D == 0) { - TM3D += timer3Reload; - if(TM3CNT & 0x40) { - IF |= 0x40; - UPDATE_REG(0x202, IF); - } - } - UPDATE_REG(0x10C, TM3D); - } - } else { - timer3Ticks -= clockTicks; - if(timer3Ticks <= 0) { - timer3Ticks += (0x10000 - timer3Reload) << timer3ClockReload; - if(TM3CNT & 0x40) { - IF |= 0x40; - UPDATE_REG(0x202, IF); - } - } - TM3D = 0xFFFF - (timer3Ticks >> timer3ClockReload); - UPDATE_REG(0x10C, TM3D); - } - } - } - - timerOverflow = 0; - - - -#ifdef PROFILING - profilingTicks -= clockTicks; - if(profilingTicks <= 0) { - profilingTicks += profilingTicksReload; - if(profilSegment) { - profile_segment *seg = profilSegment; - do { - u16 *b = (u16 *)seg->sbuf; - int pc = ((reg[15].I - seg->s_lowpc) * seg->s_scale)/0x10000; - if(pc >= 0 && pc < seg->ssiz) { - b[pc]++; - break; - } - - seg = seg->next; - } while(seg); - } - } -#endif - - ticks -= clockTicks; - -#ifndef NO_LINK - if (GetLinkMode() != LINK_DISCONNECTED) - LinkUpdate(clockTicks); -#endif - - cpuNextEvent = CPUUpdateTicks(); - - if(cpuDmaTicksToUpdate > 0) { - if(cpuDmaTicksToUpdate > cpuNextEvent) - clockTicks = cpuNextEvent; - else - clockTicks = cpuDmaTicksToUpdate; - cpuDmaTicksToUpdate -= clockTicks; - if(cpuDmaTicksToUpdate < 0) - cpuDmaTicksToUpdate = 0; - goto updateLoop; - } - -#ifndef NO_LINK - // shuffle2: what's the purpose? - if (GetLinkMode() != LINK_DISCONNECTED || gba_joybus_active) - cpuNextEvent = 1; -#endif - - if(IF && (IME & 1) && armIrqEnable) { - int res = IF & IE; - if(stopState) - res &= 0x3080; - if(res) { - if (intState) - { - if (!IRQTicks) - { - CPUInterrupt(); - intState = false; - holdState = false; - stopState = false; - holdType = 0; - } - } - else - { - if (!holdState) - { - intState = true; - IRQTicks=7; - if (cpuNextEvent> IRQTicks) - cpuNextEvent = IRQTicks; - } - else - { - CPUInterrupt(); - holdState = false; - stopState = false; - holdType = 0; - } - } - - // Stops the SWI Ticks emulation if an IRQ is executed - //(to avoid problems with nested IRQ/SWI) - if (SWITicks) - SWITicks = 0; - } - } - - if(remainingTicks > 0) { - if(remainingTicks > cpuNextEvent) - clockTicks = cpuNextEvent; - else - clockTicks = remainingTicks; - remainingTicks -= clockTicks; - if(remainingTicks < 0) - remainingTicks = 0; - goto updateLoop; - } - - if (timerOnOffDelay) - applyTimer(); - - if(cpuNextEvent > ticks) + cpuBreakLoop = false; + cpuNextEvent = CPUUpdateTicks(); + if (cpuNextEvent > ticks) cpuNextEvent = ticks; - if(ticks <= 0 || cpuBreakLoop) - break; + for (;;) { + if (!holdState && !SWITicks) { + if (armState) { + armOpcodeCount++; + if (!armExecute()) + return; + if (debugger) + return; + } else { + thumbOpcodeCount++; + if (!thumbExecute()) + return; + if (debugger) + return; + } + clockTicks = 0; + } else + clockTicks = CPUUpdateTicks(); + + cpuTotalTicks += clockTicks; + + if (rtcIsEnabled()) + rtcUpdateTime(cpuTotalTicks); + + if (cpuTotalTicks >= cpuNextEvent) { + int remainingTicks = cpuTotalTicks - cpuNextEvent; + + if (SWITicks) { + SWITicks -= clockTicks; + if (SWITicks < 0) + SWITicks = 0; + } + + clockTicks = cpuNextEvent; + cpuTotalTicks = 0; + + updateLoop: + + if (IRQTicks) { + IRQTicks -= clockTicks; + if (IRQTicks < 0) + IRQTicks = 0; + } + + lcdTicks -= clockTicks; + + if (lcdTicks <= 0) { + if (DISPSTAT & 1) { // V-BLANK + // if in V-Blank mode, keep computing... + if (DISPSTAT & 2) { + lcdTicks += 1008; + VCOUNT++; + UPDATE_REG(0x06, VCOUNT); + DISPSTAT &= 0xFFFD; + UPDATE_REG(0x04, DISPSTAT); + CPUCompareVCOUNT(); + } else { + lcdTicks += 224; + DISPSTAT |= 2; + UPDATE_REG(0x04, DISPSTAT); + if (DISPSTAT & 16) { + IF |= 2; + UPDATE_REG(0x202, IF); + } + } + + if (VCOUNT > 227) { //Reaching last line + DISPSTAT &= 0xFFFC; + UPDATE_REG(0x04, DISPSTAT); + VCOUNT = 0; + UPDATE_REG(0x06, VCOUNT); + CPUCompareVCOUNT(); + } + } else { + int framesToSkip = systemFrameSkip; + if (speedup) + framesToSkip = 9; // try 6 FPS during speedup + + if (DISPSTAT & 2) { + // if in H-Blank, leave it and move to drawing mode + VCOUNT++; + UPDATE_REG(0x06, VCOUNT); + + lcdTicks += 1008; + DISPSTAT &= 0xFFFD; + if (VCOUNT == 160) { + count++; + systemFrame(); + + if ((count % 10) == 0) { + system10Frames(60); + } + if (count == 60) { + u32 time = systemGetClock(); + if (time != lastTime) { + u32 t = 100000 / (time - lastTime); + systemShowSpeed(t); + } else + systemShowSpeed(0); + lastTime = time; + count = 0; + } + u32 joy = 0; + // update joystick information + if (systemReadJoypads()) + // read default joystick + joy = systemReadJoypad(-1); + P1 = 0x03FF ^ (joy & 0x3FF); + systemUpdateMotionSensor(); + UPDATE_REG(0x130, P1); + u16 P1CNT = READ16LE(((u16*)&ioMem[0x132])); + // this seems wrong, but there are cases where the game + // can enter the stop state without requesting an IRQ from + // the joypad. + if ((P1CNT & 0x4000) || stopState) { + u16 p1 = (0x3FF ^ P1) & 0x3FF; + if (P1CNT & 0x8000) { + if (p1 == (P1CNT & 0x3FF)) { + IF |= 0x1000; + UPDATE_REG(0x202, IF); + } + } else { + if (p1 & P1CNT) { + IF |= 0x1000; + UPDATE_REG(0x202, IF); + } + } + } + + u32 ext = (joy >> 10); + // If no (m) code is enabled, apply the cheats at each LCDline + if ((cheatsEnabled) && (mastercode == 0)) + remainingTicks += cheatsCheckKeys(P1 ^ 0x3FF, ext); + speedup = (ext & 1) ? true : false; + capture = (ext & 2) ? true : false; + + if (capture && !capturePrevious) { + captureNumber++; + systemScreenCapture(captureNumber); + } + capturePrevious = capture; + + DISPSTAT |= 1; + DISPSTAT &= 0xFFFD; + UPDATE_REG(0x04, DISPSTAT); + if (DISPSTAT & 0x0008) { + IF |= 1; + UPDATE_REG(0x202, IF); + } + CPUCheckDMA(1, 0x0f); + if (frameCount >= framesToSkip) { + systemDrawScreen(); + frameCount = 0; + } else + frameCount++; + if (systemPauseOnFrame()) + ticks = 0; + } + + UPDATE_REG(0x04, DISPSTAT); + CPUCompareVCOUNT(); + + } else { + if (frameCount >= framesToSkip) { + (*renderLine)(); + switch (systemColorDepth) { + case 16: { +#ifdef __LIBRETRO__ + u16* dest = (u16*)pix + 240 * VCOUNT; +#else + u16* dest = (u16*)pix + 242 * (VCOUNT + 1); +#endif + for (int x = 0; x < 240;) { + *dest++ = systemColorMap16[lineMix[x++] & 0xFFFF]; + *dest++ = systemColorMap16[lineMix[x++] & 0xFFFF]; + *dest++ = systemColorMap16[lineMix[x++] & 0xFFFF]; + *dest++ = systemColorMap16[lineMix[x++] & 0xFFFF]; + + *dest++ = systemColorMap16[lineMix[x++] & 0xFFFF]; + *dest++ = systemColorMap16[lineMix[x++] & 0xFFFF]; + *dest++ = systemColorMap16[lineMix[x++] & 0xFFFF]; + *dest++ = systemColorMap16[lineMix[x++] & 0xFFFF]; + + *dest++ = systemColorMap16[lineMix[x++] & 0xFFFF]; + *dest++ = systemColorMap16[lineMix[x++] & 0xFFFF]; + *dest++ = systemColorMap16[lineMix[x++] & 0xFFFF]; + *dest++ = systemColorMap16[lineMix[x++] & 0xFFFF]; + + *dest++ = systemColorMap16[lineMix[x++] & 0xFFFF]; + *dest++ = systemColorMap16[lineMix[x++] & 0xFFFF]; + *dest++ = systemColorMap16[lineMix[x++] & 0xFFFF]; + *dest++ = systemColorMap16[lineMix[x++] & 0xFFFF]; + } +// for filters that read past the screen +#ifndef __LIBRETRO__ + *dest++ = 0; +#endif + } break; + case 24: { + u8* dest = (u8*)pix + 240 * VCOUNT * 3; + for (int x = 0; x < 240;) { + *((u32*)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; + dest += 3; + *((u32*)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; + dest += 3; + *((u32*)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; + dest += 3; + *((u32*)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; + dest += 3; + + *((u32*)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; + dest += 3; + *((u32*)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; + dest += 3; + *((u32*)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; + dest += 3; + *((u32*)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; + dest += 3; + + *((u32*)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; + dest += 3; + *((u32*)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; + dest += 3; + *((u32*)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; + dest += 3; + *((u32*)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; + dest += 3; + + *((u32*)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; + dest += 3; + *((u32*)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; + dest += 3; + *((u32*)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; + dest += 3; + *((u32*)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; + dest += 3; + } + } break; + case 32: { +#ifdef __LIBRETRO__ + u32* dest = (u32*)pix + 240 * VCOUNT; +#else + u32* dest = (u32*)pix + 241 * (VCOUNT + 1); +#endif + for (int x = 0; x < 240;) { + *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; + *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; + *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; + *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; + + *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; + *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; + *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; + *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; + + *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; + *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; + *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; + *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; + + *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; + *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; + *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; + *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; + } + } break; + } + } + // entering H-Blank + DISPSTAT |= 2; + UPDATE_REG(0x04, DISPSTAT); + lcdTicks += 224; + CPUCheckDMA(2, 0x0f); + if (DISPSTAT & 16) { + IF |= 2; + UPDATE_REG(0x202, IF); + } + } + } + } + + // we shouldn't be doing sound in stop state, but we loose synchronization + // if sound is disabled, so in stop state, soundTick will just produce + // mute sound + soundTicks -= clockTicks; + if (soundTicks <= 0) { + psoundTickfn(); + soundTicks += SOUND_CLOCK_TICKS; + } + + if (!stopState) { + if (timer0On) { + timer0Ticks -= clockTicks; + if (timer0Ticks <= 0) { + timer0Ticks += (0x10000 - timer0Reload) << timer0ClockReload; + timerOverflow |= 1; + soundTimerOverflow(0); + if (TM0CNT & 0x40) { + IF |= 0x08; + UPDATE_REG(0x202, IF); + } + } + TM0D = 0xFFFF - (timer0Ticks >> timer0ClockReload); + UPDATE_REG(0x100, TM0D); + } + + if (timer1On) { + if (TM1CNT & 4) { + if (timerOverflow & 1) { + TM1D++; + if (TM1D == 0) { + TM1D += timer1Reload; + timerOverflow |= 2; + soundTimerOverflow(1); + if (TM1CNT & 0x40) { + IF |= 0x10; + UPDATE_REG(0x202, IF); + } + } + UPDATE_REG(0x104, TM1D); + } + } else { + timer1Ticks -= clockTicks; + if (timer1Ticks <= 0) { + timer1Ticks += (0x10000 - timer1Reload) << timer1ClockReload; + timerOverflow |= 2; + soundTimerOverflow(1); + if (TM1CNT & 0x40) { + IF |= 0x10; + UPDATE_REG(0x202, IF); + } + } + TM1D = 0xFFFF - (timer1Ticks >> timer1ClockReload); + UPDATE_REG(0x104, TM1D); + } + } + + if (timer2On) { + if (TM2CNT & 4) { + if (timerOverflow & 2) { + TM2D++; + if (TM2D == 0) { + TM2D += timer2Reload; + timerOverflow |= 4; + if (TM2CNT & 0x40) { + IF |= 0x20; + UPDATE_REG(0x202, IF); + } + } + UPDATE_REG(0x108, TM2D); + } + } else { + timer2Ticks -= clockTicks; + if (timer2Ticks <= 0) { + timer2Ticks += (0x10000 - timer2Reload) << timer2ClockReload; + timerOverflow |= 4; + if (TM2CNT & 0x40) { + IF |= 0x20; + UPDATE_REG(0x202, IF); + } + } + TM2D = 0xFFFF - (timer2Ticks >> timer2ClockReload); + UPDATE_REG(0x108, TM2D); + } + } + + if (timer3On) { + if (TM3CNT & 4) { + if (timerOverflow & 4) { + TM3D++; + if (TM3D == 0) { + TM3D += timer3Reload; + if (TM3CNT & 0x40) { + IF |= 0x40; + UPDATE_REG(0x202, IF); + } + } + UPDATE_REG(0x10C, TM3D); + } + } else { + timer3Ticks -= clockTicks; + if (timer3Ticks <= 0) { + timer3Ticks += (0x10000 - timer3Reload) << timer3ClockReload; + if (TM3CNT & 0x40) { + IF |= 0x40; + UPDATE_REG(0x202, IF); + } + } + TM3D = 0xFFFF - (timer3Ticks >> timer3ClockReload); + UPDATE_REG(0x10C, TM3D); + } + } + } + + timerOverflow = 0; + +#ifdef PROFILING + profilingTicks -= clockTicks; + if (profilingTicks <= 0) { + profilingTicks += profilingTicksReload; + if (profilSegment) { + profile_segment* seg = profilSegment; + do { + u16* b = (u16*)seg->sbuf; + int pc = ((reg[15].I - seg->s_lowpc) * seg->s_scale) / 0x10000; + if (pc >= 0 && pc < seg->ssiz) { + b[pc]++; + break; + } + + seg = seg->next; + } while (seg); + } + } +#endif + + ticks -= clockTicks; - } - } #ifndef NO_LINK - if (GetLinkMode() != LINK_DISCONNECTED) - CheckLinkConnection(); + if (GetLinkMode() != LINK_DISCONNECTED) + LinkUpdate(clockTicks); +#endif + + cpuNextEvent = CPUUpdateTicks(); + + if (cpuDmaTicksToUpdate > 0) { + if (cpuDmaTicksToUpdate > cpuNextEvent) + clockTicks = cpuNextEvent; + else + clockTicks = cpuDmaTicksToUpdate; + cpuDmaTicksToUpdate -= clockTicks; + if (cpuDmaTicksToUpdate < 0) + cpuDmaTicksToUpdate = 0; + goto updateLoop; + } + +#ifndef NO_LINK + // shuffle2: what's the purpose? + if (GetLinkMode() != LINK_DISCONNECTED || gba_joybus_active) + cpuNextEvent = 1; +#endif + + if (IF && (IME & 1) && armIrqEnable) { + int res = IF & IE; + if (stopState) + res &= 0x3080; + if (res) { + if (intState) { + if (!IRQTicks) { + CPUInterrupt(); + intState = false; + holdState = false; + stopState = false; + holdType = 0; + } + } else { + if (!holdState) { + intState = true; + IRQTicks = 7; + if (cpuNextEvent > IRQTicks) + cpuNextEvent = IRQTicks; + } else { + CPUInterrupt(); + holdState = false; + stopState = false; + holdType = 0; + } + } + + // Stops the SWI Ticks emulation if an IRQ is executed + //(to avoid problems with nested IRQ/SWI) + if (SWITicks) + SWITicks = 0; + } + } + + if (remainingTicks > 0) { + if (remainingTicks > cpuNextEvent) + clockTicks = cpuNextEvent; + else + clockTicks = remainingTicks; + remainingTicks -= clockTicks; + if (remainingTicks < 0) + remainingTicks = 0; + goto updateLoop; + } + + if (timerOnOffDelay) + applyTimer(); + + if (cpuNextEvent > ticks) + cpuNextEvent = ticks; + + if (ticks <= 0 || cpuBreakLoop) + break; + } + } +#ifndef NO_LINK + if (GetLinkMode() != LINK_DISCONNECTED) + CheckLinkConnection(); #endif } #ifdef TILED_RENDERING -union u8h -{ - struct - { - /* 0*/ unsigned lo:4; - /* 4*/ unsigned hi:4; - } __attribute__ ((packed)); - u8 val; +union u8h { + struct + { + /* 0*/ unsigned lo : 4; + /* 4*/ unsigned hi : 4; + } __attribute__((packed)); + u8 val; }; -union TileEntry -{ - struct - { - /* 0*/ unsigned tileNum:10; - /*12*/ unsigned hFlip:1; - /*13*/ unsigned vFlip:1; - /*14*/ unsigned palette:4; - }; - u16 val; +union TileEntry { + struct + { + /* 0*/ unsigned tileNum : 10; + /*12*/ unsigned hFlip : 1; + /*13*/ unsigned vFlip : 1; + /*14*/ unsigned palette : 4; + }; + u16 val; }; -struct TileLine -{ - u32 pixels[8]; +struct TileLine { + u32 pixels[8]; }; -typedef const TileLine (*TileReader) (const u16 *, const int, const u8 *, u16 *, const u32); +typedef const TileLine (*TileReader)(const u16*, const int, const u8*, u16*, const u32); -static inline void gfxDrawPixel(u32 *dest, const u8 color, const u16 *palette, const u32 prio) +static inline void gfxDrawPixel(u32* dest, const u8 color, const u16* palette, const u32 prio) { - *dest = color ? (READ16LE(&palette[color]) | prio): 0x80000000; + *dest = color ? (READ16LE(&palette[color]) | prio) : 0x80000000; } -inline const TileLine gfxReadTile(const u16 *screenSource, const int yyy, const u8 *charBase, u16 *palette, const u32 prio) +inline const TileLine gfxReadTile(const u16* screenSource, const int yyy, const u8* charBase, u16* palette, const u32 prio) { - TileEntry tile; - tile.val = READ16LE(screenSource); + TileEntry tile; + tile.val = READ16LE(screenSource); - int tileY = yyy & 7; - if (tile.vFlip) tileY = 7 - tileY; - TileLine tileLine; + int tileY = yyy & 7; + if (tile.vFlip) + tileY = 7 - tileY; + TileLine tileLine; - const u8 *tileBase = &charBase[tile.tileNum * 64 + tileY * 8]; + const u8* tileBase = &charBase[tile.tileNum * 64 + tileY * 8]; - if (!tile.hFlip) - { - gfxDrawPixel(&tileLine.pixels[0], tileBase[0], palette, prio); - gfxDrawPixel(&tileLine.pixels[1], tileBase[1], palette, prio); - gfxDrawPixel(&tileLine.pixels[2], tileBase[2], palette, prio); - gfxDrawPixel(&tileLine.pixels[3], tileBase[3], palette, prio); - gfxDrawPixel(&tileLine.pixels[4], tileBase[4], palette, prio); - gfxDrawPixel(&tileLine.pixels[5], tileBase[5], palette, prio); - gfxDrawPixel(&tileLine.pixels[6], tileBase[6], palette, prio); - gfxDrawPixel(&tileLine.pixels[7], tileBase[7], palette, prio); - } - else - { - gfxDrawPixel(&tileLine.pixels[0], tileBase[7], palette, prio); - gfxDrawPixel(&tileLine.pixels[1], tileBase[6], palette, prio); - gfxDrawPixel(&tileLine.pixels[2], tileBase[5], palette, prio); - gfxDrawPixel(&tileLine.pixels[3], tileBase[4], palette, prio); - gfxDrawPixel(&tileLine.pixels[4], tileBase[3], palette, prio); - gfxDrawPixel(&tileLine.pixels[5], tileBase[2], palette, prio); - gfxDrawPixel(&tileLine.pixels[6], tileBase[1], palette, prio); - gfxDrawPixel(&tileLine.pixels[7], tileBase[0], palette, prio); - } + if (!tile.hFlip) { + gfxDrawPixel(&tileLine.pixels[0], tileBase[0], palette, prio); + gfxDrawPixel(&tileLine.pixels[1], tileBase[1], palette, prio); + gfxDrawPixel(&tileLine.pixels[2], tileBase[2], palette, prio); + gfxDrawPixel(&tileLine.pixels[3], tileBase[3], palette, prio); + gfxDrawPixel(&tileLine.pixels[4], tileBase[4], palette, prio); + gfxDrawPixel(&tileLine.pixels[5], tileBase[5], palette, prio); + gfxDrawPixel(&tileLine.pixels[6], tileBase[6], palette, prio); + gfxDrawPixel(&tileLine.pixels[7], tileBase[7], palette, prio); + } else { + gfxDrawPixel(&tileLine.pixels[0], tileBase[7], palette, prio); + gfxDrawPixel(&tileLine.pixels[1], tileBase[6], palette, prio); + gfxDrawPixel(&tileLine.pixels[2], tileBase[5], palette, prio); + gfxDrawPixel(&tileLine.pixels[3], tileBase[4], palette, prio); + gfxDrawPixel(&tileLine.pixels[4], tileBase[3], palette, prio); + gfxDrawPixel(&tileLine.pixels[5], tileBase[2], palette, prio); + gfxDrawPixel(&tileLine.pixels[6], tileBase[1], palette, prio); + gfxDrawPixel(&tileLine.pixels[7], tileBase[0], palette, prio); + } - return tileLine; + return tileLine; } -inline const TileLine gfxReadTilePal(const u16 *screenSource, const int yyy, const u8 *charBase, u16 *palette, const u32 prio) +inline const TileLine gfxReadTilePal(const u16* screenSource, const int yyy, const u8* charBase, u16* palette, const u32 prio) { - TileEntry tile; - tile.val = READ16LE(screenSource); + TileEntry tile; + tile.val = READ16LE(screenSource); - int tileY = yyy & 7; - if (tile.vFlip) tileY = 7 - tileY; - palette += tile.palette * 16; - TileLine tileLine; + int tileY = yyy & 7; + if (tile.vFlip) + tileY = 7 - tileY; + palette += tile.palette * 16; + TileLine tileLine; - const u8h *tileBase = (u8h*) &charBase[tile.tileNum * 32 + tileY * 4]; + const u8h* tileBase = (u8h*)&charBase[tile.tileNum * 32 + tileY * 4]; - if (!tile.hFlip) - { - gfxDrawPixel(&tileLine.pixels[0], tileBase[0].lo, palette, prio); - gfxDrawPixel(&tileLine.pixels[1], tileBase[0].hi, palette, prio); - gfxDrawPixel(&tileLine.pixels[2], tileBase[1].lo, palette, prio); - gfxDrawPixel(&tileLine.pixels[3], tileBase[1].hi, palette, prio); - gfxDrawPixel(&tileLine.pixels[4], tileBase[2].lo, palette, prio); - gfxDrawPixel(&tileLine.pixels[5], tileBase[2].hi, palette, prio); - gfxDrawPixel(&tileLine.pixels[6], tileBase[3].lo, palette, prio); - gfxDrawPixel(&tileLine.pixels[7], tileBase[3].hi, palette, prio); - } - else - { - gfxDrawPixel(&tileLine.pixels[0], tileBase[3].hi, palette, prio); - gfxDrawPixel(&tileLine.pixels[1], tileBase[3].lo, palette, prio); - gfxDrawPixel(&tileLine.pixels[2], tileBase[2].hi, palette, prio); - gfxDrawPixel(&tileLine.pixels[3], tileBase[2].lo, palette, prio); - gfxDrawPixel(&tileLine.pixels[4], tileBase[1].hi, palette, prio); - gfxDrawPixel(&tileLine.pixels[5], tileBase[1].lo, palette, prio); - gfxDrawPixel(&tileLine.pixels[6], tileBase[0].hi, palette, prio); - gfxDrawPixel(&tileLine.pixels[7], tileBase[0].lo, palette, prio); - } + if (!tile.hFlip) { + gfxDrawPixel(&tileLine.pixels[0], tileBase[0].lo, palette, prio); + gfxDrawPixel(&tileLine.pixels[1], tileBase[0].hi, palette, prio); + gfxDrawPixel(&tileLine.pixels[2], tileBase[1].lo, palette, prio); + gfxDrawPixel(&tileLine.pixels[3], tileBase[1].hi, palette, prio); + gfxDrawPixel(&tileLine.pixels[4], tileBase[2].lo, palette, prio); + gfxDrawPixel(&tileLine.pixels[5], tileBase[2].hi, palette, prio); + gfxDrawPixel(&tileLine.pixels[6], tileBase[3].lo, palette, prio); + gfxDrawPixel(&tileLine.pixels[7], tileBase[3].hi, palette, prio); + } else { + gfxDrawPixel(&tileLine.pixels[0], tileBase[3].hi, palette, prio); + gfxDrawPixel(&tileLine.pixels[1], tileBase[3].lo, palette, prio); + gfxDrawPixel(&tileLine.pixels[2], tileBase[2].hi, palette, prio); + gfxDrawPixel(&tileLine.pixels[3], tileBase[2].lo, palette, prio); + gfxDrawPixel(&tileLine.pixels[4], tileBase[1].hi, palette, prio); + gfxDrawPixel(&tileLine.pixels[5], tileBase[1].lo, palette, prio); + gfxDrawPixel(&tileLine.pixels[6], tileBase[0].hi, palette, prio); + gfxDrawPixel(&tileLine.pixels[7], tileBase[0].lo, palette, prio); + } - return tileLine; + return tileLine; } -static inline void gfxDrawTile(const TileLine &tileLine, u32 *line) +static inline void gfxDrawTile(const TileLine& tileLine, u32* line) { - memcpy(line, tileLine.pixels, sizeof(tileLine.pixels)); + memcpy(line, tileLine.pixels, sizeof(tileLine.pixels)); } -static inline void gfxDrawTileClipped(const TileLine &tileLine, u32 *line, const int start, int w) +static inline void gfxDrawTileClipped(const TileLine& tileLine, u32* line, const int start, int w) { - memcpy(line, tileLine.pixels + start, w * sizeof(u32)); + memcpy(line, tileLine.pixels + start, w * sizeof(u32)); } -template +template static void gfxDrawTextScreen(u16 control, u16 hofs, u16 vofs, - u32 *line) + u32* line) { - u16 *palette = (u16 *)paletteRAM; - u8 *charBase = &vram[((control >> 2) & 0x03) * 0x4000]; - u16 *screenBase = (u16 *)&vram[((control >> 8) & 0x1f) * 0x800]; - u32 prio = ((control & 3)<<25) + 0x1000000; - int sizeX = 256; - int sizeY = 256; - switch ((control >> 14) & 3) - { - case 0: - break; - case 1: - sizeX = 512; - break; - case 2: - sizeY = 512; - break; - case 3: - sizeX = 512; - sizeY = 512; - break; - } + u16* palette = (u16*)paletteRAM; + u8* charBase = &vram[((control >> 2) & 0x03) * 0x4000]; + u16* screenBase = (u16*)&vram[((control >> 8) & 0x1f) * 0x800]; + u32 prio = ((control & 3) << 25) + 0x1000000; + int sizeX = 256; + int sizeY = 256; + switch ((control >> 14) & 3) { + case 0: + break; + case 1: + sizeX = 512; + break; + case 2: + sizeY = 512; + break; + case 3: + sizeX = 512; + sizeY = 512; + break; + } - int maskX = sizeX-1; - int maskY = sizeY-1; + int maskX = sizeX - 1; + int maskY = sizeY - 1; - bool mosaicOn = (control & 0x40) ? true : false; + bool mosaicOn = (control & 0x40) ? true : false; - int xxx = hofs & maskX; - int yyy = (vofs + VCOUNT) & maskY; - int mosaicX = (MOSAIC & 0x000F)+1; - int mosaicY = ((MOSAIC & 0x00F0)>>4)+1; + int xxx = hofs & maskX; + int yyy = (vofs + VCOUNT) & maskY; + int mosaicX = (MOSAIC & 0x000F) + 1; + int mosaicY = ((MOSAIC & 0x00F0) >> 4) + 1; - if (mosaicOn) - { - if ((VCOUNT % mosaicY) != 0) - { - mosaicY = VCOUNT - (VCOUNT % mosaicY); - yyy = (vofs + mosaicY) & maskY; - } - } + if (mosaicOn) { + if ((VCOUNT % mosaicY) != 0) { + mosaicY = VCOUNT - (VCOUNT % mosaicY); + yyy = (vofs + mosaicY) & maskY; + } + } - if (yyy > 255 && sizeY > 256) - { - yyy &= 255; - screenBase += 0x400; - if (sizeX > 256) - screenBase += 0x400; - } + if (yyy > 255 && sizeY > 256) { + yyy &= 255; + screenBase += 0x400; + if (sizeX > 256) + screenBase += 0x400; + } - int yshift = ((yyy>>3)<<5); + int yshift = ((yyy >> 3) << 5); - u16 *screenSource = screenBase + 0x400 * (xxx>>8) + ((xxx & 255)>>3) + yshift; - int x = 0; - const int firstTileX = xxx & 7; + u16* screenSource = screenBase + 0x400 * (xxx >> 8) + ((xxx & 255) >> 3) + yshift; + int x = 0; + const int firstTileX = xxx & 7; - // First tile, if clipped - if (firstTileX) - { - gfxDrawTileClipped(readTile(screenSource, yyy, charBase, palette, prio), &line[x], firstTileX, 8 - firstTileX); - screenSource++; - x += 8 - firstTileX; - xxx += 8 - firstTileX; + // First tile, if clipped + if (firstTileX) { + gfxDrawTileClipped(readTile(screenSource, yyy, charBase, palette, prio), &line[x], firstTileX, 8 - firstTileX); + screenSource++; + x += 8 - firstTileX; + xxx += 8 - firstTileX; - if (xxx == 256 && sizeX > 256) - { - screenSource = screenBase + 0x400 + yshift; - } - else if (xxx >= sizeX) - { - xxx = 0; - screenSource = screenBase + yshift; - } - } + if (xxx == 256 && sizeX > 256) { + screenSource = screenBase + 0x400 + yshift; + } else if (xxx >= sizeX) { + xxx = 0; + screenSource = screenBase + yshift; + } + } - // Middle tiles, full - while (x < 240 - firstTileX) - { - gfxDrawTile(readTile(screenSource, yyy, charBase, palette, prio), &line[x]); - screenSource++; - xxx += 8; - x += 8; + // Middle tiles, full + while (x < 240 - firstTileX) { + gfxDrawTile(readTile(screenSource, yyy, charBase, palette, prio), &line[x]); + screenSource++; + xxx += 8; + x += 8; - if (xxx == 256 && sizeX > 256) - { - screenSource = screenBase + 0x400 + yshift; - } - else if (xxx >= sizeX) - { - xxx = 0; - screenSource = screenBase + yshift; - } - } + if (xxx == 256 && sizeX > 256) { + screenSource = screenBase + 0x400 + yshift; + } else if (xxx >= sizeX) { + xxx = 0; + screenSource = screenBase + yshift; + } + } - // Last tile, if clipped - if (firstTileX) - { - gfxDrawTileClipped(readTile(screenSource, yyy, charBase, palette, prio), &line[x], 0, firstTileX); - } + // Last tile, if clipped + if (firstTileX) { + gfxDrawTileClipped(readTile(screenSource, yyy, charBase, palette, prio), &line[x], 0, firstTileX); + } - if (mosaicOn) - { - if (mosaicX > 1) - { - int m = 1; - for (int i = 0; i < 239; i++) - { - line[i+1] = line[i]; - m++; - if (m == mosaicX) - { - m = 1; - i++; + if (mosaicOn) { + if (mosaicX > 1) { + int m = 1; + for (int i = 0; i < 239; i++) { + line[i + 1] = line[i]; + m++; + if (m == mosaicX) { + m = 1; + i++; + } } - } - } - } + } + } } -void gfxDrawTextScreen(u16 control, u16 hofs, u16 vofs, u32 *line) +void gfxDrawTextScreen(u16 control, u16 hofs, u16 vofs, u32* line) { - if (control & 0x80) // 1 pal / 256 col - gfxDrawTextScreen(control, hofs, vofs, line); - else // 16 pal / 16 col - gfxDrawTextScreen(control, hofs, vofs, line); + if (control & 0x80) // 1 pal / 256 col + gfxDrawTextScreen(control, hofs, vofs, line); + else // 16 pal / 16 col + gfxDrawTextScreen(control, hofs, vofs, line); } #endif - struct EmulatedSystem GBASystem = { - // emuMain - CPULoop, - // emuReset - CPUReset, - // emuCleanUp - CPUCleanUp, - // emuReadBattery - CPUReadBatteryFile, - // emuWriteBattery - CPUWriteBatteryFile, - // emuReadState - CPUReadState, - // emuWriteState - CPUWriteState, - // emuReadMemState + // emuMain + CPULoop, + // emuReset + CPUReset, + // emuCleanUp + CPUCleanUp, + // emuReadBattery + CPUReadBatteryFile, + // emuWriteBattery + CPUWriteBatteryFile, + // emuReadState + CPUReadState, + // emuWriteState + CPUWriteState, +// emuReadMemState #ifdef __LIBRETRO__ - NULL, + NULL, #else - CPUReadMemState, + CPUReadMemState, #endif - // emuWriteMemState - CPUWriteMemState, - // emuWritePNG - CPUWritePNGFile, - // emuWriteBMP - CPUWriteBMPFile, - // emuUpdateCPSR - CPUUpdateCPSR, - // emuHasDebugger - true, - // emuCount + // emuWriteMemState + CPUWriteMemState, + // emuWritePNG + CPUWritePNGFile, + // emuWriteBMP + CPUWriteBMPFile, + // emuUpdateCPSR + CPUUpdateCPSR, + // emuHasDebugger + true, +// emuCount #ifdef FINAL_VERSION - 250000 + 250000 #else - 5000 + 5000 #endif }; diff --git a/src/gba/GBA.h b/src/gba/GBA.h index 3152135d..576f0b78 100644 --- a/src/gba/GBA.h +++ b/src/gba/GBA.h @@ -18,43 +18,43 @@ const u64 TICKS_PER_SECOND = 16777216; #define SAVE_GAME_VERSION SAVE_GAME_VERSION_10 typedef struct { - u8 *address; - u32 mask; + u8* address; + u32 mask; #ifdef BKPT_SUPPORT - u8 *breakPoints; - u8 *searchMatch; - u8 *trace; - u32 size; + u8* breakPoints; + u8* searchMatch; + u8* trace; + u32 size; #endif } memoryMap; typedef union { - struct { + struct { #ifdef WORDS_BIGENDIAN - u8 B3; - u8 B2; - u8 B1; - u8 B0; + u8 B3; + u8 B2; + u8 B1; + u8 B0; #else - u8 B0; - u8 B1; - u8 B2; - u8 B3; + u8 B0; + u8 B1; + u8 B2; + u8 B3; #endif - } B; - struct { + } B; + struct { #ifdef WORDS_BIGENDIAN - u16 W1; - u16 W0; + u16 W1; + u16 W0; #else - u16 W0; - u16 W1; + u16 W0; + u16 W1; #endif - } W; + } W; #ifdef WORDS_BIGENDIAN - volatile u32 I; + volatile u32 I; #else - u32 I; + u32 I; #endif } reg_pair; @@ -78,49 +78,49 @@ extern char oldbuffer[10]; extern bool debugger; #endif -extern bool CPUReadGSASnapshot(const char *); -extern bool CPUReadGSASPSnapshot(const char *); -extern bool CPUWriteGSASnapshot(const char *, const char *, const char *, const char *); -extern bool CPUWriteBatteryFile(const char *); -extern bool CPUReadBatteryFile(const char *); -extern bool CPUExportEepromFile(const char *); -extern bool CPUImportEepromFile(const char *); -extern bool CPUWritePNGFile(const char *); -extern bool CPUWriteBMPFile(const char *); +extern bool CPUReadGSASnapshot(const char*); +extern bool CPUReadGSASPSnapshot(const char*); +extern bool CPUWriteGSASnapshot(const char*, const char*, const char*, const char*); +extern bool CPUWriteBatteryFile(const char*); +extern bool CPUReadBatteryFile(const char*); +extern bool CPUExportEepromFile(const char*); +extern bool CPUImportEepromFile(const char*); +extern bool CPUWritePNGFile(const char*); +extern bool CPUWriteBMPFile(const char*); extern void CPUCleanUp(); extern void CPUUpdateRender(); extern void CPUUpdateRenderBuffers(bool); -extern bool CPUReadMemState(char *, int); -extern bool CPUWriteMemState(char *, int); +extern bool CPUReadMemState(char*, int); +extern bool CPUWriteMemState(char*, int); #ifdef __LIBRETRO__ -extern bool CPUReadState(const u8 *, unsigned); -extern unsigned int CPUWriteState(u8 *data, unsigned int size); +extern bool CPUReadState(const u8*, unsigned); +extern unsigned int CPUWriteState(u8* data, unsigned int size); #else -extern bool CPUReadState(const char *); -extern bool CPUWriteState(const char *); +extern bool CPUReadState(const char*); +extern bool CPUWriteState(const char*); #endif -extern int CPULoadRom(const char *); -extern int CPULoadRomData(const char *data, int size); +extern int CPULoadRom(const char*); +extern int CPULoadRomData(const char* data, int size); extern void doMirroring(bool); extern void CPUUpdateRegister(u32, u16); extern void applyTimer(); -extern void CPUInit(const char *, bool); +extern void CPUInit(const char*, bool); void SetSaveType(int st); extern void CPUReset(); extern void CPULoop(int); extern void CPUCheckDMA(int, int); -extern bool CPUIsGBAImage(const char *); -extern bool CPUIsZipFile(const char *); +extern bool CPUIsGBAImage(const char*); +extern bool CPUIsZipFile(const char*); #ifdef PROFILING #include "prof/prof.h" -extern void cpuProfil(profile_segment *seg); +extern void cpuProfil(profile_segment* seg); extern void cpuEnableProfiling(int hz); #endif -const char *GetLoadDotCodeFile(); -const char *GetSaveDotCodeFile(); -void SetLoadDotCodeFile(const char *szFile); -void SetSaveDotCodeFile(const char *szFile); +const char* GetLoadDotCodeFile(); +const char* GetSaveDotCodeFile(); +void SetLoadDotCodeFile(const char* szFile); +void SetSaveDotCodeFile(const char* szFile); extern struct EmulatedSystem GBASystem; diff --git a/src/gba/GBAGfx.cpp b/src/gba/GBAGfx.cpp index 398e2380..8f1a0ad1 100644 --- a/src/gba/GBAGfx.cpp +++ b/src/gba/GBAGfx.cpp @@ -1,8 +1,9 @@ #include "../System.h" int coeff[32] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16}; + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 +}; u32 line0[240]; u32 line1[240]; diff --git a/src/gba/GBAGfx.h b/src/gba/GBAGfx.h index a5860c52..10573cc7 100644 --- a/src/gba/GBAGfx.h +++ b/src/gba/GBAGfx.h @@ -9,21 +9,21 @@ //#define SPRITE_DEBUG #ifdef TILED_RENDERING -extern void gfxDrawTextScreen(u16, u16, u16, u32 *); +extern void gfxDrawTextScreen(u16, u16, u16, u32*); #else -static void gfxDrawTextScreen(u16, u16, u16, u32 *); +static void gfxDrawTextScreen(u16, u16, u16, u32*); #endif -static void gfxDrawRotScreen(u16, u16, u16, u16, u16, u16, u16, u16, u16, int &, int &, int, u32 *); -static void gfxDrawRotScreen16Bit(u16, u16, u16, u16, u16, u16, u16, u16, u16, int &, int &, int, - u32 *); -static void gfxDrawRotScreen256(u16, u16, u16, u16, u16, u16, u16, u16, u16, int &, int &, int, - u32 *); -static void gfxDrawRotScreen16Bit160(u16, u16, u16, u16, u16, u16, u16, u16, u16, int &, int &, int, - u32 *); -static void gfxDrawSprites(u32 *); -static void gfxIncreaseBrightness(u32 *line, int coeff); -static void gfxDecreaseBrightness(u32 *line, int coeff); -static void gfxAlphaBlend(u32 *ta, u32 *tb, int ca, int cb); +static void gfxDrawRotScreen(u16, u16, u16, u16, u16, u16, u16, u16, u16, int&, int&, int, u32*); +static void gfxDrawRotScreen16Bit(u16, u16, u16, u16, u16, u16, u16, u16, u16, int&, int&, int, + u32*); +static void gfxDrawRotScreen256(u16, u16, u16, u16, u16, u16, u16, u16, u16, int&, int&, int, + u32*); +static void gfxDrawRotScreen16Bit160(u16, u16, u16, u16, u16, u16, u16, u16, u16, int&, int&, int, + u32*); +static void gfxDrawSprites(u32*); +static void gfxIncreaseBrightness(u32* line, int coeff); +static void gfxDecreaseBrightness(u32* line, int coeff); +static void gfxAlphaBlend(u32* ta, u32* tb, int ca, int cb); void mode0RenderLine(); void mode0RenderLineNoWindow(); @@ -70,1684 +70,1513 @@ extern int gfxBG3X; extern int gfxBG3Y; extern int gfxLastVCOUNT; -static inline void gfxClearArray(u32 *array) +static inline void gfxClearArray(u32* array) { - for (int i = 0; i < 240; i++) { - *array++ = 0x80000000; - } + for (int i = 0; i < 240; i++) { + *array++ = 0x80000000; + } } #ifndef TILED_RENDERING -static inline void gfxDrawTextScreen(u16 control, u16 hofs, u16 vofs, u32 *line) +static inline void gfxDrawTextScreen(u16 control, u16 hofs, u16 vofs, u32* line) { - u16 *palette = (u16 *)paletteRAM; - u8 *charBase = &vram[((control >> 2) & 0x03) * 0x4000]; - u16 *screenBase = (u16 *)&vram[((control >> 8) & 0x1f) * 0x800]; - u32 prio = ((control & 3) << 25) + 0x1000000; - int sizeX = 256; - int sizeY = 256; - switch ((control >> 14) & 3) { - case 0: - break; - case 1: - sizeX = 512; - break; - case 2: - sizeY = 512; - break; - case 3: - sizeX = 512; - sizeY = 512; - break; + u16* palette = (u16*)paletteRAM; + u8* charBase = &vram[((control >> 2) & 0x03) * 0x4000]; + u16* screenBase = (u16*)&vram[((control >> 8) & 0x1f) * 0x800]; + u32 prio = ((control & 3) << 25) + 0x1000000; + int sizeX = 256; + int sizeY = 256; + switch ((control >> 14) & 3) { + case 0: + break; + case 1: + sizeX = 512; + break; + case 2: + sizeY = 512; + break; + case 3: + sizeX = 512; + sizeY = 512; + break; + } + + int maskX = sizeX - 1; + int maskY = sizeY - 1; + + bool mosaicOn = (control & 0x40) ? true : false; + + int xxx = hofs & maskX; + int yyy = (vofs + VCOUNT) & maskY; + int mosaicX = (MOSAIC & 0x000F) + 1; + int mosaicY = ((MOSAIC & 0x00F0) >> 4) + 1; + + if (mosaicOn) { + if ((VCOUNT % mosaicY) != 0) { + mosaicY = VCOUNT - (VCOUNT % mosaicY); + yyy = (vofs + mosaicY) & maskY; } + } - int maskX = sizeX - 1; - int maskY = sizeY - 1; + if (yyy > 255 && sizeY > 256) { + yyy &= 255; + screenBase += 0x400; + if (sizeX > 256) + screenBase += 0x400; + } - bool mosaicOn = (control & 0x40) ? true : false; + int yshift = ((yyy >> 3) << 5); + if ((control)&0x80) { + u16* screenSource = screenBase + 0x400 * (xxx >> 8) + ((xxx & 255) >> 3) + yshift; + for (int x = 0; x < 240; x++) { + u16 data = READ16LE(screenSource); - int xxx = hofs & maskX; - int yyy = (vofs + VCOUNT) & maskY; - int mosaicX = (MOSAIC & 0x000F) + 1; - int mosaicY = ((MOSAIC & 0x00F0) >> 4) + 1; + int tile = data & 0x3FF; + int tileX = (xxx & 7); + int tileY = yyy & 7; - if (mosaicOn) { - if ((VCOUNT % mosaicY) != 0) { - mosaicY = VCOUNT - (VCOUNT % mosaicY); - yyy = (vofs + mosaicY) & maskY; - } - } + if (tileX == 7) + screenSource++; - if (yyy > 255 && sizeY > 256) { - yyy &= 255; - screenBase += 0x400; + if (data & 0x0400) + tileX = 7 - tileX; + if (data & 0x0800) + tileY = 7 - tileY; + + u8 color = charBase[tile * 64 + tileY * 8 + tileX]; + + line[x] = color ? (READ16LE(&palette[color]) | prio) : 0x80000000; + + xxx++; + if (xxx == 256) { if (sizeX > 256) - screenBase += 0x400; - } - - int yshift = ((yyy >> 3) << 5); - if ((control)&0x80) { - u16 *screenSource = screenBase + 0x400 * (xxx >> 8) + ((xxx & 255) >> 3) + yshift; - for (int x = 0; x < 240; x++) { - u16 data = READ16LE(screenSource); - - int tile = data & 0x3FF; - int tileX = (xxx & 7); - int tileY = yyy & 7; - - if (tileX == 7) - screenSource++; - - if (data & 0x0400) - tileX = 7 - tileX; - if (data & 0x0800) - tileY = 7 - tileY; - - u8 color = charBase[tile * 64 + tileY * 8 + tileX]; - - line[x] = color ? (READ16LE(&palette[color]) | prio) : 0x80000000; - - xxx++; - if (xxx == 256) { - if (sizeX > 256) - screenSource = screenBase + 0x400 + yshift; - else { - screenSource = screenBase + yshift; - xxx = 0; - } - } else if (xxx >= sizeX) { - xxx = 0; - screenSource = screenBase + yshift; - } - } - } else { - u16 *screenSource = screenBase + 0x400 * (xxx >> 8) + ((xxx & 255) >> 3) + yshift; - for (int x = 0; x < 240; x++) { - u16 data = READ16LE(screenSource); - - int tile = data & 0x3FF; - int tileX = (xxx & 7); - int tileY = yyy & 7; - - if (tileX == 7) - screenSource++; - - if (data & 0x0400) - tileX = 7 - tileX; - if (data & 0x0800) - tileY = 7 - tileY; - - u8 color = charBase[(tile << 5) + (tileY << 2) + (tileX >> 1)]; - - if (tileX & 1) { - color = (color >> 4); - } else { - color &= 0x0F; - } - - int pal = (data >> 8) & 0xF0; - line[x] = color ? (READ16LE(&palette[pal + color]) | prio) : 0x80000000; - - xxx++; - if (xxx == 256) { - if (sizeX > 256) - screenSource = screenBase + 0x400 + yshift; - else { - screenSource = screenBase + yshift; - xxx = 0; - } - } else if (xxx >= sizeX) { - xxx = 0; - screenSource = screenBase + yshift; - } + screenSource = screenBase + 0x400 + yshift; + else { + screenSource = screenBase + yshift; + xxx = 0; } + } else if (xxx >= sizeX) { + xxx = 0; + screenSource = screenBase + yshift; + } } - if (mosaicOn) { - if (mosaicX > 1) { - int m = 1; - for (int i = 0; i < 239; i++) { - line[i + 1] = line[i]; - m++; - if (m == mosaicX) { - m = 1; - i++; - } - } + } else { + u16* screenSource = screenBase + 0x400 * (xxx >> 8) + ((xxx & 255) >> 3) + yshift; + for (int x = 0; x < 240; x++) { + u16 data = READ16LE(screenSource); + + int tile = data & 0x3FF; + int tileX = (xxx & 7); + int tileY = yyy & 7; + + if (tileX == 7) + screenSource++; + + if (data & 0x0400) + tileX = 7 - tileX; + if (data & 0x0800) + tileY = 7 - tileY; + + u8 color = charBase[(tile << 5) + (tileY << 2) + (tileX >> 1)]; + + if (tileX & 1) { + color = (color >> 4); + } else { + color &= 0x0F; + } + + int pal = (data >> 8) & 0xF0; + line[x] = color ? (READ16LE(&palette[pal + color]) | prio) : 0x80000000; + + xxx++; + if (xxx == 256) { + if (sizeX > 256) + screenSource = screenBase + 0x400 + yshift; + else { + screenSource = screenBase + yshift; + xxx = 0; } + } else if (xxx >= sizeX) { + xxx = 0; + screenSource = screenBase + yshift; + } } + } + if (mosaicOn) { + if (mosaicX > 1) { + int m = 1; + for (int i = 0; i < 239; i++) { + line[i + 1] = line[i]; + m++; + if (m == mosaicX) { + m = 1; + i++; + } + } + } + } } #endif static inline void gfxDrawRotScreen(u16 control, u16 x_l, u16 x_h, u16 y_l, u16 y_h, u16 pa, u16 pb, - u16 pc, u16 pd, int ¤tX, int ¤tY, int changed, - u32 *line) + u16 pc, u16 pd, int& currentX, int& currentY, int changed, + u32* line) { - u16 *palette = (u16 *)paletteRAM; - u8 *charBase = &vram[((control >> 2) & 0x03) * 0x4000]; - u8 *screenBase = (u8 *)&vram[((control >> 8) & 0x1f) * 0x800]; - int prio = ((control & 3) << 25) + 0x1000000; + u16* palette = (u16*)paletteRAM; + u8* charBase = &vram[((control >> 2) & 0x03) * 0x4000]; + u8* screenBase = (u8*)&vram[((control >> 8) & 0x1f) * 0x800]; + int prio = ((control & 3) << 25) + 0x1000000; - int sizeX = 128; - int sizeY = 128; - switch ((control >> 14) & 3) { - case 0: - break; - case 1: - sizeX = sizeY = 256; - break; - case 2: - sizeX = sizeY = 512; - break; - case 3: - sizeX = sizeY = 1024; - break; + int sizeX = 128; + int sizeY = 128; + switch ((control >> 14) & 3) { + case 0: + break; + case 1: + sizeX = sizeY = 256; + break; + case 2: + sizeX = sizeY = 512; + break; + case 3: + sizeX = sizeY = 1024; + break; + } + + int maskX = sizeX - 1; + int maskY = sizeY - 1; + + int yshift = ((control >> 14) & 3) + 4; + + int dx = pa & 0x7FFF; + if (pa & 0x8000) + dx |= 0xFFFF8000; + int dmx = pb & 0x7FFF; + if (pb & 0x8000) + dmx |= 0xFFFF8000; + int dy = pc & 0x7FFF; + if (pc & 0x8000) + dy |= 0xFFFF8000; + int dmy = pd & 0x7FFF; + if (pd & 0x8000) + dmy |= 0xFFFF8000; + + if (VCOUNT == 0) + changed = 3; + + if (changed & 1) { + currentX = (x_l) | ((x_h & 0x07FF) << 16); + if (x_h & 0x0800) + currentX |= 0xF8000000; + } else { + currentX += dmx; + } + + if (changed & 2) { + currentY = (y_l) | ((y_h & 0x07FF) << 16); + if (y_h & 0x0800) + currentY |= 0xF8000000; + } else { + currentY += dmy; + } + + int realX = currentX; + int realY = currentY; + + if (control & 0x40) { + int mosaicY = ((MOSAIC & 0xF0) >> 4) + 1; + int y = (VCOUNT % mosaicY); + realX -= y * dmx; + realY -= y * dmy; + } + + if (control & 0x2000) { + for (int x = 0; x < 240; x++) { + int xxx = (realX >> 8) & maskX; + int yyy = (realY >> 8) & maskY; + + int tile = screenBase[(xxx >> 3) + ((yyy >> 3) << yshift)]; + + int tileX = (xxx & 7); + int tileY = yyy & 7; + + u8 color = charBase[(tile << 6) + (tileY << 3) + tileX]; + + line[x] = color ? (READ16LE(&palette[color]) | prio) : 0x80000000; + + realX += dx; + realY += dy; } + } else { + for (int x = 0; x < 240; x++) { + int xxx = (realX >> 8); + int yyy = (realY >> 8); - int maskX = sizeX - 1; - int maskY = sizeY - 1; + if (xxx < 0 || yyy < 0 || xxx >= sizeX || yyy >= sizeY) { + line[x] = 0x80000000; + } else { + int tile = screenBase[(xxx >> 3) + ((yyy >> 3) << yshift)]; - int yshift = ((control >> 14) & 3) + 4; + int tileX = (xxx & 7); + int tileY = yyy & 7; - int dx = pa & 0x7FFF; - if (pa & 0x8000) - dx |= 0xFFFF8000; - int dmx = pb & 0x7FFF; - if (pb & 0x8000) - dmx |= 0xFFFF8000; - int dy = pc & 0x7FFF; - if (pc & 0x8000) - dy |= 0xFFFF8000; - int dmy = pd & 0x7FFF; - if (pd & 0x8000) - dmy |= 0xFFFF8000; + u8 color = charBase[(tile << 6) + (tileY << 3) + tileX]; - if (VCOUNT == 0) - changed = 3; - - if (changed & 1) { - currentX = (x_l) | ((x_h & 0x07FF) << 16); - if (x_h & 0x0800) - currentX |= 0xF8000000; - } else { - currentX += dmx; + line[x] = color ? (READ16LE(&palette[color]) | prio) : 0x80000000; + } + realX += dx; + realY += dy; } + } - if (changed & 2) { - currentY = (y_l) | ((y_h & 0x07FF) << 16); - if (y_h & 0x0800) - currentY |= 0xF8000000; - } else { - currentY += dmy; - } - - int realX = currentX; - int realY = currentY; - - if (control & 0x40) { - int mosaicY = ((MOSAIC & 0xF0) >> 4) + 1; - int y = (VCOUNT % mosaicY); - realX -= y * dmx; - realY -= y * dmy; - } - - if (control & 0x2000) { - for (int x = 0; x < 240; x++) { - int xxx = (realX >> 8) & maskX; - int yyy = (realY >> 8) & maskY; - - int tile = screenBase[(xxx >> 3) + ((yyy >> 3) << yshift)]; - - int tileX = (xxx & 7); - int tileY = yyy & 7; - - u8 color = charBase[(tile << 6) + (tileY << 3) + tileX]; - - line[x] = color ? (READ16LE(&palette[color]) | prio) : 0x80000000; - - realX += dx; - realY += dy; - } - } else { - for (int x = 0; x < 240; x++) { - int xxx = (realX >> 8); - int yyy = (realY >> 8); - - if (xxx < 0 || yyy < 0 || xxx >= sizeX || yyy >= sizeY) { - line[x] = 0x80000000; - } else { - int tile = screenBase[(xxx >> 3) + ((yyy >> 3) << yshift)]; - - int tileX = (xxx & 7); - int tileY = yyy & 7; - - u8 color = charBase[(tile << 6) + (tileY << 3) + tileX]; - - line[x] = color ? (READ16LE(&palette[color]) | prio) : 0x80000000; - } - realX += dx; - realY += dy; - } - } - - if (control & 0x40) { - int mosaicX = (MOSAIC & 0xF) + 1; - if (mosaicX > 1) { - int m = 1; - for (int i = 0; i < 239; i++) { - line[i + 1] = line[i]; - m++; - if (m == mosaicX) { - m = 1; - i++; - } - } + if (control & 0x40) { + int mosaicX = (MOSAIC & 0xF) + 1; + if (mosaicX > 1) { + int m = 1; + for (int i = 0; i < 239; i++) { + line[i + 1] = line[i]; + m++; + if (m == mosaicX) { + m = 1; + i++; } + } } + } } static inline void gfxDrawRotScreen16Bit(u16 control, u16 x_l, u16 x_h, u16 y_l, u16 y_h, u16 pa, - u16 pb, u16 pc, u16 pd, int ¤tX, int ¤tY, - int changed, u32 *line) + u16 pb, u16 pc, u16 pd, int& currentX, int& currentY, + int changed, u32* line) { - u16 *screenBase = (u16 *)&vram[0]; - int prio = ((control & 3) << 25) + 0x1000000; - int sizeX = 240; - int sizeY = 160; + u16* screenBase = (u16*)&vram[0]; + int prio = ((control & 3) << 25) + 0x1000000; + int sizeX = 240; + int sizeY = 160; - int startX = (x_l) | ((x_h & 0x07FF) << 16); + int startX = (x_l) | ((x_h & 0x07FF) << 16); + if (x_h & 0x0800) + startX |= 0xF8000000; + int startY = (y_l) | ((y_h & 0x07FF) << 16); + if (y_h & 0x0800) + startY |= 0xF8000000; + + int dx = pa & 0x7FFF; + if (pa & 0x8000) + dx |= 0xFFFF8000; + int dmx = pb & 0x7FFF; + if (pb & 0x8000) + dmx |= 0xFFFF8000; + int dy = pc & 0x7FFF; + if (pc & 0x8000) + dy |= 0xFFFF8000; + int dmy = pd & 0x7FFF; + if (pd & 0x8000) + dmy |= 0xFFFF8000; + + if (VCOUNT == 0) + changed = 3; + + if (changed & 1) { + currentX = (x_l) | ((x_h & 0x07FF) << 16); if (x_h & 0x0800) - startX |= 0xF8000000; - int startY = (y_l) | ((y_h & 0x07FF) << 16); + currentX |= 0xF8000000; + } else + currentX += dmx; + + if (changed & 2) { + currentY = (y_l) | ((y_h & 0x07FF) << 16); if (y_h & 0x0800) - startY |= 0xF8000000; + currentY |= 0xF8000000; + } else { + currentY += dmy; + } - int dx = pa & 0x7FFF; - if (pa & 0x8000) - dx |= 0xFFFF8000; - int dmx = pb & 0x7FFF; - if (pb & 0x8000) - dmx |= 0xFFFF8000; - int dy = pc & 0x7FFF; - if (pc & 0x8000) - dy |= 0xFFFF8000; - int dmy = pd & 0x7FFF; - if (pd & 0x8000) - dmy |= 0xFFFF8000; + int realX = currentX; + int realY = currentY; - if (VCOUNT == 0) - changed = 3; + if (control & 0x40) { + int mosaicY = ((MOSAIC & 0xF0) >> 4) + 1; + int y = (VCOUNT % mosaicY); + realX -= y * dmx; + realY -= y * dmy; + } - if (changed & 1) { - currentX = (x_l) | ((x_h & 0x07FF) << 16); - if (x_h & 0x0800) - currentX |= 0xF8000000; - } else - currentX += dmx; + int xxx = (realX >> 8); + int yyy = (realY >> 8); - if (changed & 2) { - currentY = (y_l) | ((y_h & 0x07FF) << 16); - if (y_h & 0x0800) - currentY |= 0xF8000000; + for (int x = 0; x < 240; x++) { + if (xxx < 0 || yyy < 0 || xxx >= sizeX || yyy >= sizeY) { + line[x] = 0x80000000; } else { - currentY += dmy; + line[x] = (READ16LE(&screenBase[yyy * sizeX + xxx]) | prio); } + realX += dx; + realY += dy; - int realX = currentX; - int realY = currentY; + xxx = (realX >> 8); + yyy = (realY >> 8); + } - if (control & 0x40) { - int mosaicY = ((MOSAIC & 0xF0) >> 4) + 1; - int y = (VCOUNT % mosaicY); - realX -= y * dmx; - realY -= y * dmy; - } - - int xxx = (realX >> 8); - int yyy = (realY >> 8); - - for (int x = 0; x < 240; x++) { - if (xxx < 0 || yyy < 0 || xxx >= sizeX || yyy >= sizeY) { - line[x] = 0x80000000; - } else { - line[x] = (READ16LE(&screenBase[yyy * sizeX + xxx]) | prio); - } - realX += dx; - realY += dy; - - xxx = (realX >> 8); - yyy = (realY >> 8); - } - - if (control & 0x40) { - int mosaicX = (MOSAIC & 0xF) + 1; - if (mosaicX > 1) { - int m = 1; - for (int i = 0; i < 239; i++) { - line[i + 1] = line[i]; - m++; - if (m == mosaicX) { - m = 1; - i++; - } - } + if (control & 0x40) { + int mosaicX = (MOSAIC & 0xF) + 1; + if (mosaicX > 1) { + int m = 1; + for (int i = 0; i < 239; i++) { + line[i + 1] = line[i]; + m++; + if (m == mosaicX) { + m = 1; + i++; } + } } + } } static inline void gfxDrawRotScreen256(u16 control, u16 x_l, u16 x_h, u16 y_l, u16 y_h, u16 pa, - u16 pb, u16 pc, u16 pd, int ¤tX, int ¤tY, - int changed, u32 *line) + u16 pb, u16 pc, u16 pd, int& currentX, int& currentY, + int changed, u32* line) { - u16 *palette = (u16 *)paletteRAM; - u8 *screenBase = (DISPCNT & 0x0010) ? &vram[0xA000] : &vram[0x0000]; - int prio = ((control & 3) << 25) + 0x1000000; - int sizeX = 240; - int sizeY = 160; + u16* palette = (u16*)paletteRAM; + u8* screenBase = (DISPCNT & 0x0010) ? &vram[0xA000] : &vram[0x0000]; + int prio = ((control & 3) << 25) + 0x1000000; + int sizeX = 240; + int sizeY = 160; - int startX = (x_l) | ((x_h & 0x07FF) << 16); + int startX = (x_l) | ((x_h & 0x07FF) << 16); + if (x_h & 0x0800) + startX |= 0xF8000000; + int startY = (y_l) | ((y_h & 0x07FF) << 16); + if (y_h & 0x0800) + startY |= 0xF8000000; + + int dx = pa & 0x7FFF; + if (pa & 0x8000) + dx |= 0xFFFF8000; + int dmx = pb & 0x7FFF; + if (pb & 0x8000) + dmx |= 0xFFFF8000; + int dy = pc & 0x7FFF; + if (pc & 0x8000) + dy |= 0xFFFF8000; + int dmy = pd & 0x7FFF; + if (pd & 0x8000) + dmy |= 0xFFFF8000; + + if (VCOUNT == 0) + changed = 3; + + if (changed & 1) { + currentX = (x_l) | ((x_h & 0x07FF) << 16); if (x_h & 0x0800) - startX |= 0xF8000000; - int startY = (y_l) | ((y_h & 0x07FF) << 16); + currentX |= 0xF8000000; + } else { + currentX += dmx; + } + + if (changed & 2) { + currentY = (y_l) | ((y_h & 0x07FF) << 16); if (y_h & 0x0800) - startY |= 0xF8000000; + currentY |= 0xF8000000; + } else { + currentY += dmy; + } - int dx = pa & 0x7FFF; - if (pa & 0x8000) - dx |= 0xFFFF8000; - int dmx = pb & 0x7FFF; - if (pb & 0x8000) - dmx |= 0xFFFF8000; - int dy = pc & 0x7FFF; - if (pc & 0x8000) - dy |= 0xFFFF8000; - int dmy = pd & 0x7FFF; - if (pd & 0x8000) - dmy |= 0xFFFF8000; + int realX = currentX; + int realY = currentY; - if (VCOUNT == 0) - changed = 3; + if (control & 0x40) { + int mosaicY = ((MOSAIC & 0xF0) >> 4) + 1; + int y = VCOUNT - (VCOUNT % mosaicY); + realX = startX + y * dmx; + realY = startY + y * dmy; + } - if (changed & 1) { - currentX = (x_l) | ((x_h & 0x07FF) << 16); - if (x_h & 0x0800) - currentX |= 0xF8000000; + int xxx = (realX >> 8); + int yyy = (realY >> 8); + + for (int x = 0; x < 240; x++) { + if (xxx < 0 || yyy < 0 || xxx >= sizeX || yyy >= sizeY) { + line[x] = 0x80000000; } else { - currentX += dmx; + u8 color = screenBase[yyy * 240 + xxx]; + + line[x] = color ? (READ16LE(&palette[color]) | prio) : 0x80000000; } + realX += dx; + realY += dy; - if (changed & 2) { - currentY = (y_l) | ((y_h & 0x07FF) << 16); - if (y_h & 0x0800) - currentY |= 0xF8000000; - } else { - currentY += dmy; - } + xxx = (realX >> 8); + yyy = (realY >> 8); + } - int realX = currentX; - int realY = currentY; - - if (control & 0x40) { - int mosaicY = ((MOSAIC & 0xF0) >> 4) + 1; - int y = VCOUNT - (VCOUNT % mosaicY); - realX = startX + y * dmx; - realY = startY + y * dmy; - } - - int xxx = (realX >> 8); - int yyy = (realY >> 8); - - for (int x = 0; x < 240; x++) { - if (xxx < 0 || yyy < 0 || xxx >= sizeX || yyy >= sizeY) { - line[x] = 0x80000000; - } else { - u8 color = screenBase[yyy * 240 + xxx]; - - line[x] = color ? (READ16LE(&palette[color]) | prio) : 0x80000000; - } - realX += dx; - realY += dy; - - xxx = (realX >> 8); - yyy = (realY >> 8); - } - - if (control & 0x40) { - int mosaicX = (MOSAIC & 0xF) + 1; - if (mosaicX > 1) { - int m = 1; - for (int i = 0; i < 239; i++) { - line[i + 1] = line[i]; - m++; - if (m == mosaicX) { - m = 1; - i++; - } - } + if (control & 0x40) { + int mosaicX = (MOSAIC & 0xF) + 1; + if (mosaicX > 1) { + int m = 1; + for (int i = 0; i < 239; i++) { + line[i + 1] = line[i]; + m++; + if (m == mosaicX) { + m = 1; + i++; } + } } + } } static inline void gfxDrawRotScreen16Bit160(u16 control, u16 x_l, u16 x_h, u16 y_l, u16 y_h, u16 pa, - u16 pb, u16 pc, u16 pd, int ¤tX, int ¤tY, - int changed, u32 *line) + u16 pb, u16 pc, u16 pd, int& currentX, int& currentY, + int changed, u32* line) { - u16 *screenBase = (DISPCNT & 0x0010) ? (u16 *)&vram[0xa000] : (u16 *)&vram[0]; - int prio = ((control & 3) << 25) + 0x1000000; - int sizeX = 160; - int sizeY = 128; + u16* screenBase = (DISPCNT & 0x0010) ? (u16*)&vram[0xa000] : (u16*)&vram[0]; + int prio = ((control & 3) << 25) + 0x1000000; + int sizeX = 160; + int sizeY = 128; - int startX = (x_l) | ((x_h & 0x07FF) << 16); + int startX = (x_l) | ((x_h & 0x07FF) << 16); + if (x_h & 0x0800) + startX |= 0xF8000000; + int startY = (y_l) | ((y_h & 0x07FF) << 16); + if (y_h & 0x0800) + startY |= 0xF8000000; + + int dx = pa & 0x7FFF; + if (pa & 0x8000) + dx |= 0xFFFF8000; + int dmx = pb & 0x7FFF; + if (pb & 0x8000) + dmx |= 0xFFFF8000; + int dy = pc & 0x7FFF; + if (pc & 0x8000) + dy |= 0xFFFF8000; + int dmy = pd & 0x7FFF; + if (pd & 0x8000) + dmy |= 0xFFFF8000; + + if (VCOUNT == 0) + changed = 3; + + if (changed & 1) { + currentX = (x_l) | ((x_h & 0x07FF) << 16); if (x_h & 0x0800) - startX |= 0xF8000000; - int startY = (y_l) | ((y_h & 0x07FF) << 16); + currentX |= 0xF8000000; + } else { + currentX += dmx; + } + + if (changed & 2) { + currentY = (y_l) | ((y_h & 0x07FF) << 16); if (y_h & 0x0800) - startY |= 0xF8000000; + currentY |= 0xF8000000; + } else { + currentY += dmy; + } - int dx = pa & 0x7FFF; - if (pa & 0x8000) - dx |= 0xFFFF8000; - int dmx = pb & 0x7FFF; - if (pb & 0x8000) - dmx |= 0xFFFF8000; - int dy = pc & 0x7FFF; - if (pc & 0x8000) - dy |= 0xFFFF8000; - int dmy = pd & 0x7FFF; - if (pd & 0x8000) - dmy |= 0xFFFF8000; + int realX = currentX; + int realY = currentY; - if (VCOUNT == 0) - changed = 3; + if (control & 0x40) { + int mosaicY = ((MOSAIC & 0xF0) >> 4) + 1; + int y = VCOUNT - (VCOUNT % mosaicY); + realX = startX + y * dmx; + realY = startY + y * dmy; + } - if (changed & 1) { - currentX = (x_l) | ((x_h & 0x07FF) << 16); - if (x_h & 0x0800) - currentX |= 0xF8000000; + int xxx = (realX >> 8); + int yyy = (realY >> 8); + + for (int x = 0; x < 240; x++) { + if (xxx < 0 || yyy < 0 || xxx >= sizeX || yyy >= sizeY) { + line[x] = 0x80000000; } else { - currentX += dmx; + line[x] = (READ16LE(&screenBase[yyy * sizeX + xxx]) | prio); } + realX += dx; + realY += dy; - if (changed & 2) { - currentY = (y_l) | ((y_h & 0x07FF) << 16); - if (y_h & 0x0800) - currentY |= 0xF8000000; - } else { - currentY += dmy; - } + xxx = (realX >> 8); + yyy = (realY >> 8); + } - int realX = currentX; - int realY = currentY; - - if (control & 0x40) { - int mosaicY = ((MOSAIC & 0xF0) >> 4) + 1; - int y = VCOUNT - (VCOUNT % mosaicY); - realX = startX + y * dmx; - realY = startY + y * dmy; - } - - int xxx = (realX >> 8); - int yyy = (realY >> 8); - - for (int x = 0; x < 240; x++) { - if (xxx < 0 || yyy < 0 || xxx >= sizeX || yyy >= sizeY) { - line[x] = 0x80000000; - } else { - line[x] = (READ16LE(&screenBase[yyy * sizeX + xxx]) | prio); - } - realX += dx; - realY += dy; - - xxx = (realX >> 8); - yyy = (realY >> 8); - } - - if (control & 0x40) { - int mosaicX = (MOSAIC & 0xF) + 1; - if (mosaicX > 1) { - int m = 1; - for (int i = 0; i < 239; i++) { - line[i + 1] = line[i]; - m++; - if (m == mosaicX) { - m = 1; - i++; - } - } + if (control & 0x40) { + int mosaicX = (MOSAIC & 0xF) + 1; + if (mosaicX > 1) { + int m = 1; + for (int i = 0; i < 239; i++) { + line[i + 1] = line[i]; + m++; + if (m == mosaicX) { + m = 1; + i++; } + } } + } } -static inline void gfxDrawSprites(u32 *lineOBJ) +static inline void gfxDrawSprites(u32* lineOBJ) { - // lineOBJpix is used to keep track of the drawn OBJs - // and to stop drawing them if the 'maximum number of OBJ per line' - // has been reached. - int lineOBJpix = (DISPCNT & 0x20) ? 954 : 1226; - int m = 0; - gfxClearArray(lineOBJ); - if (layerEnable & 0x1000) { - u16 *sprites = (u16 *)oam; - u16 *spritePalette = &((u16 *)paletteRAM)[256]; - int mosaicY = ((MOSAIC & 0xF000) >> 12) + 1; - int mosaicX = ((MOSAIC & 0xF00) >> 8) + 1; - for (int x = 0; x < 128; x++) { - u16 a0 = READ16LE(sprites++); - u16 a1 = READ16LE(sprites++); - u16 a2 = READ16LE(sprites++); - sprites++; + // lineOBJpix is used to keep track of the drawn OBJs + // and to stop drawing them if the 'maximum number of OBJ per line' + // has been reached. + int lineOBJpix = (DISPCNT & 0x20) ? 954 : 1226; + int m = 0; + gfxClearArray(lineOBJ); + if (layerEnable & 0x1000) { + u16* sprites = (u16*)oam; + u16* spritePalette = &((u16*)paletteRAM)[256]; + int mosaicY = ((MOSAIC & 0xF000) >> 12) + 1; + int mosaicX = ((MOSAIC & 0xF00) >> 8) + 1; + for (int x = 0; x < 128; x++) { + u16 a0 = READ16LE(sprites++); + u16 a1 = READ16LE(sprites++); + u16 a2 = READ16LE(sprites++); + sprites++; - lineOBJpixleft[x] = lineOBJpix; + lineOBJpixleft[x] = lineOBJpix; - lineOBJpix -= 2; - if (lineOBJpix <= 0) - continue; + lineOBJpix -= 2; + if (lineOBJpix <= 0) + continue; - if ((a0 & 0x0c00) == 0x0c00) - a0 &= 0xF3FF; + if ((a0 & 0x0c00) == 0x0c00) + a0 &= 0xF3FF; - if ((a0 >> 14) == 3) { - a0 &= 0x3FFF; - a1 &= 0x3FFF; - } + if ((a0 >> 14) == 3) { + a0 &= 0x3FFF; + a1 &= 0x3FFF; + } - int sizeX = 8 << (a1 >> 14); - int sizeY = sizeX; + int sizeX = 8 << (a1 >> 14); + int sizeY = sizeX; - if ((a0 >> 14) & 1) { - if (sizeX < 32) - sizeX <<= 1; - if (sizeY > 8) - sizeY >>= 1; - } else if ((a0 >> 14) & 2) { - if (sizeX > 8) - sizeX >>= 1; - if (sizeY < 32) - sizeY <<= 1; - } + if ((a0 >> 14) & 1) { + if (sizeX < 32) + sizeX <<= 1; + if (sizeY > 8) + sizeY >>= 1; + } else if ((a0 >> 14) & 2) { + if (sizeX > 8) + sizeX >>= 1; + if (sizeY < 32) + sizeY <<= 1; + } #ifdef SPRITE_DEBUG - int maskX = sizeX - 1; - int maskY = sizeY - 1; + int maskX = sizeX - 1; + int maskY = sizeY - 1; #endif - int sy = (a0 & 255); - int sx = (a1 & 0x1FF); + int sy = (a0 & 255); + int sx = (a1 & 0x1FF); - // computes ticks used by OBJ-WIN if OBJWIN is enabled - if (((a0 & 0x0c00) == 0x0800) && (layerEnable & 0x8000)) { - if ((a0 & 0x0300) == 0x0300) { - sizeX <<= 1; - sizeY <<= 1; + // computes ticks used by OBJ-WIN if OBJWIN is enabled + if (((a0 & 0x0c00) == 0x0800) && (layerEnable & 0x8000)) { + if ((a0 & 0x0300) == 0x0300) { + sizeX <<= 1; + sizeY <<= 1; + } + if ((sy + sizeY) > 256) + sy -= 256; + if ((sx + sizeX) > 512) + sx -= 512; + if (sx < 0) { + sizeX += sx; + sx = 0; + } else if ((sx + sizeX) > 240) + sizeX = 240 - sx; + if ((VCOUNT >= sy) && (VCOUNT < sy + sizeY) && (sx < 240)) { + if (a0 & 0x0100) + lineOBJpix -= 8 + 2 * sizeX; + else + lineOBJpix -= sizeX - 2; + } + continue; + } + // else ignores OBJ-WIN if OBJWIN is disabled, and ignored disabled OBJ + else if (((a0 & 0x0c00) == 0x0800) || ((a0 & 0x0300) == 0x0200)) + continue; + + if (lineOBJpix < 0) + continue; + + if (a0 & 0x0100) { + int fieldX = sizeX; + int fieldY = sizeY; + if (a0 & 0x0200) { + fieldX <<= 1; + fieldY <<= 1; + } + if ((sy + fieldY) > 256) + sy -= 256; + int t = VCOUNT - sy; + if ((t >= 0) && (t < fieldY)) { + int startpix = 0; + if ((sx + fieldX) > 512) { + startpix = 512 - sx; + } + if (lineOBJpix > 0) + if ((sx < 240) || startpix) { + lineOBJpix -= 8; + // int t2 = t - (fieldY >> 1); + int rot = (a1 >> 9) & 0x1F; + u16* OAM = (u16*)oam; + int dx = READ16LE(&OAM[3 + (rot << 4)]); + if (dx & 0x8000) + dx |= 0xFFFF8000; + int dmx = READ16LE(&OAM[7 + (rot << 4)]); + if (dmx & 0x8000) + dmx |= 0xFFFF8000; + int dy = READ16LE(&OAM[11 + (rot << 4)]); + if (dy & 0x8000) + dy |= 0xFFFF8000; + int dmy = READ16LE(&OAM[15 + (rot << 4)]); + if (dmy & 0x8000) + dmy |= 0xFFFF8000; + + if (a0 & 0x1000) { + t -= (t % mosaicY); + } + + int realX = ((sizeX) << 7) - (fieldX >> 1) * dx - (fieldY >> 1) * dmx + t * dmx; + int realY = ((sizeY) << 7) - (fieldX >> 1) * dy - (fieldY >> 1) * dmy + t * dmy; + + u32 prio = (((a2 >> 10) & 3) << 25) | ((a0 & 0x0c00) << 6); + + if (a0 & 0x2000) { + int c = (a2 & 0x3FF); + if ((DISPCNT & 7) > 2 && (c < 512)) + continue; + int inc = 32; + if (DISPCNT & 0x40) + inc = sizeX >> 2; + else + c &= 0x3FE; + for (int x = 0; x < fieldX; x++) { + if (x >= startpix) + lineOBJpix -= 2; + if (lineOBJpix < 0) + continue; + int xxx = realX >> 8; + int yyy = realY >> 8; + + if (xxx < 0 || xxx >= sizeX || yyy < 0 || yyy >= sizeY || sx >= 240) + ; + else { + u32 color = vram + [0x10000 + ((((c + (yyy >> 3) * inc) + << 5) + + ((yyy & 7) + << 3) + + ((xxx >> 3) + << 6) + + (xxx & 7)) + & 0x7FFF)]; + if ((color == 0) && (((prio >> 25) & 3) < ((lineOBJ + [sx] + >> 25) + & 3))) { + lineOBJ[sx] = (lineOBJ + [sx] + & 0xF9FFFFFF) + | prio; + if ((a0 & 0x1000) && m) + lineOBJ[sx] = (lineOBJ + [sx - 1] + & 0xF9FFFFFF) + | prio; + } else if ( + (color) && (prio < (lineOBJ[sx] & 0xFF000000))) { + lineOBJ[sx] = READ16LE( + &spritePalette + [color]) + | prio; + if ((a0 & 0x1000) && m) + lineOBJ[sx] = (lineOBJ + [sx - 1] + & 0xF9FFFFFF) + | prio; + } + + if (a0 & 0x1000) { + m++; + if (m == mosaicX) + m = 0; + } +#ifdef SPRITE_DEBUG + if (t == 0 || t == maskY || x == 0 || x == maskX) + lineOBJ[sx] = 0x001F; +#endif + } + sx = (sx + 1) & 511; + realX += dx; + realY += dy; } - if ((sy + sizeY) > 256) - sy -= 256; - if ((sx + sizeX) > 512) - sx -= 512; - if (sx < 0) { - sizeX += sx; - sx = 0; - } else if ((sx + sizeX) > 240) - sizeX = 240 - sx; - if ((VCOUNT >= sy) && (VCOUNT < sy + sizeY) && (sx < 240)) { - if (a0 & 0x0100) - lineOBJpix -= 8 + 2 * sizeX; + } else { + int c = (a2 & 0x3FF); + if ((DISPCNT & 7) > 2 && (c < 512)) + continue; + + int inc = 32; + if (DISPCNT & 0x40) + inc = sizeX >> 3; + int palette = (a2 >> 8) & 0xF0; + for (int x = 0; x < fieldX; x++) { + if (x >= startpix) + lineOBJpix -= 2; + if (lineOBJpix < 0) + continue; + int xxx = realX >> 8; + int yyy = realY >> 8; + if (xxx < 0 || xxx >= sizeX || yyy < 0 || yyy >= sizeY || sx >= 240) + ; + else { + u32 color = vram + [0x10000 + ((((c + (yyy >> 3) * inc) + << 5) + + ((yyy & 7) + << 2) + + ((xxx >> 3) + << 5) + + ((xxx & 7) >> 1)) + & 0x7FFF)]; + if (xxx & 1) + color >>= 4; else - lineOBJpix -= sizeX - 2; - } - continue; - } - // else ignores OBJ-WIN if OBJWIN is disabled, and ignored disabled OBJ - else if (((a0 & 0x0c00) == 0x0800) || ((a0 & 0x0300) == 0x0200)) - continue; + color &= 0x0F; - if (lineOBJpix < 0) - continue; - - if (a0 & 0x0100) { - int fieldX = sizeX; - int fieldY = sizeY; - if (a0 & 0x0200) { - fieldX <<= 1; - fieldY <<= 1; - } - if ((sy + fieldY) > 256) - sy -= 256; - int t = VCOUNT - sy; - if ((t >= 0) && (t < fieldY)) { - int startpix = 0; - if ((sx + fieldX) > 512) { - startpix = 512 - sx; + if ((color == 0) && (((prio >> 25) & 3) < ((lineOBJ + [sx] + >> 25) + & 3))) { + lineOBJ[sx] = (lineOBJ + [sx] + & 0xF9FFFFFF) + | prio; + if ((a0 & 0x1000) && m) + lineOBJ[sx] = (lineOBJ + [sx - 1] + & 0xF9FFFFFF) + | prio; + } else if ( + (color) && (prio < (lineOBJ[sx] & 0xFF000000))) { + lineOBJ[sx] = READ16LE( + &spritePalette + [palette + color]) + | prio; + if ((a0 & 0x1000) && m) + lineOBJ[sx] = (lineOBJ + [sx - 1] + & 0xF9FFFFFF) + | prio; } - if (lineOBJpix > 0) - if ((sx < 240) || startpix) { - lineOBJpix -= 8; - // int t2 = t - (fieldY >> 1); - int rot = (a1 >> 9) & 0x1F; - u16 *OAM = (u16 *)oam; - int dx = READ16LE(&OAM[3 + (rot << 4)]); - if (dx & 0x8000) - dx |= 0xFFFF8000; - int dmx = READ16LE(&OAM[7 + (rot << 4)]); - if (dmx & 0x8000) - dmx |= 0xFFFF8000; - int dy = READ16LE(&OAM[11 + (rot << 4)]); - if (dy & 0x8000) - dy |= 0xFFFF8000; - int dmy = READ16LE(&OAM[15 + (rot << 4)]); - if (dmy & 0x8000) - dmy |= 0xFFFF8000; - - if (a0 & 0x1000) { - t -= (t % mosaicY); - } - - int realX = ((sizeX) << 7) - - (fieldX >> 1) * dx - - (fieldY >> 1) * dmx + t * dmx; - int realY = ((sizeY) << 7) - - (fieldX >> 1) * dy - - (fieldY >> 1) * dmy + t * dmy; - - u32 prio = (((a2 >> 10) & 3) << 25) | - ((a0 & 0x0c00) << 6); - - if (a0 & 0x2000) { - int c = (a2 & 0x3FF); - if ((DISPCNT & 7) > 2 && (c < 512)) - continue; - int inc = 32; - if (DISPCNT & 0x40) - inc = sizeX >> 2; - else - c &= 0x3FE; - for (int x = 0; x < fieldX; x++) { - if (x >= startpix) - lineOBJpix -= 2; - if (lineOBJpix < 0) - continue; - int xxx = realX >> 8; - int yyy = realY >> 8; - - if (xxx < 0 || - xxx >= sizeX || - yyy < 0 || - yyy >= sizeY || - sx >= 240) - ; - else { - u32 color = vram - [0x10000 + - ((((c + - (yyy >> - 3) * - inc) - << 5) + - ((yyy & 7) - << 3) + - ((xxx >> 3) - << 6) + - (xxx & 7)) & - 0x7FFF)]; - if ((color == 0) && - (((prio >> 25) & - 3) < - ((lineOBJ - [sx] >> - 25) & - 3))) { - lineOBJ[sx] = - (lineOBJ - [sx] & - 0xF9FFFFFF) | - prio; - if ((a0 & - 0x1000) && - m) - lineOBJ[sx] = - (lineOBJ - [sx - - 1] & - 0xF9FFFFFF) | - prio; - } else if ( - (color) && - (prio < - (lineOBJ[sx] & - 0xFF000000))) { - lineOBJ[sx] = - READ16LE( - &spritePalette - [color]) | - prio; - if ((a0 & - 0x1000) && - m) - lineOBJ[sx] = - (lineOBJ - [sx - - 1] & - 0xF9FFFFFF) | - prio; - } - - if (a0 & 0x1000) { - m++; - if (m == - mosaicX) - m = 0; - } -#ifdef SPRITE_DEBUG - if (t == 0 || - t == maskY || - x == 0 || - x == maskX) - lineOBJ[sx] = - 0x001F; -#endif - } - sx = (sx + 1) & 511; - realX += dx; - realY += dy; - } - } else { - int c = (a2 & 0x3FF); - if ((DISPCNT & 7) > 2 && (c < 512)) - continue; - - int inc = 32; - if (DISPCNT & 0x40) - inc = sizeX >> 3; - int palette = (a2 >> 8) & 0xF0; - for (int x = 0; x < fieldX; x++) { - if (x >= startpix) - lineOBJpix -= 2; - if (lineOBJpix < 0) - continue; - int xxx = realX >> 8; - int yyy = realY >> 8; - if (xxx < 0 || - xxx >= sizeX || - yyy < 0 || - yyy >= sizeY || - sx >= 240) - ; - else { - u32 color = vram - [0x10000 + - ((((c + - (yyy >> - 3) * - inc) - << 5) + - ((yyy & 7) - << 2) + - ((xxx >> 3) - << 5) + - ((xxx & 7) >> - 1)) & - 0x7FFF)]; - if (xxx & 1) - color >>= 4; - else - color &= - 0x0F; - - if ((color == 0) && - (((prio >> 25) & - 3) < - ((lineOBJ - [sx] >> - 25) & - 3))) { - lineOBJ[sx] = - (lineOBJ - [sx] & - 0xF9FFFFFF) | - prio; - if ((a0 & - 0x1000) && - m) - lineOBJ[sx] = - (lineOBJ - [sx - - 1] & - 0xF9FFFFFF) | - prio; - } else if ( - (color) && - (prio < - (lineOBJ[sx] & - 0xFF000000))) { - lineOBJ[sx] = - READ16LE( - &spritePalette - [palette + - color]) | - prio; - if ((a0 & - 0x1000) && - m) - lineOBJ[sx] = - (lineOBJ - [sx - - 1] & - 0xF9FFFFFF) | - prio; - } - } - if ((a0 & 0x1000) && m) { - m++; - if (m == mosaicX) - m = 0; - } + } + if ((a0 & 0x1000) && m) { + m++; + if (m == mosaicX) + m = 0; + } #ifdef SPRITE_DEBUG - if (t == 0 || t == maskY || - x == 0 || x == maskX) - lineOBJ[sx] = - 0x001F; + if (t == 0 || t == maskY || x == 0 || x == maskX) + lineOBJ[sx] = 0x001F; #endif - sx = (sx + 1) & 511; - realX += dx; - realY += dy; - } - } - } - } - } else { - if (sy + sizeY > 256) - sy -= 256; - int t = VCOUNT - sy; - if ((t >= 0) && (t < sizeY)) { - int startpix = 0; - if ((sx + sizeX) > 512) { - startpix = 512 - sx; - } - if ((sx < 240) || startpix) { - lineOBJpix += 2; - if (a0 & 0x2000) { - if (a1 & 0x2000) - t = sizeY - t - 1; - int c = (a2 & 0x3FF); - if ((DISPCNT & 7) > 2 && (c < 512)) - continue; - - int inc = 32; - if (DISPCNT & 0x40) { - inc = sizeX >> 2; - } else { - c &= 0x3FE; - } - int xxx = 0; - if (a1 & 0x1000) - xxx = sizeX - 1; - - if (a0 & 0x1000) { - t -= (t % mosaicY); - } - - int address = - 0x10000 + - ((((c + (t >> 3) * inc) << 5) + - ((t & 7) << 3) + ((xxx >> 3) << 6) + - (xxx & 7)) & - 0x7FFF); - - if (a1 & 0x1000) - xxx = 7; - u32 prio = (((a2 >> 10) & 3) << 25) | - ((a0 & 0x0c00) << 6); - - for (int xx = 0; xx < sizeX; xx++) { - if (xx >= startpix) - lineOBJpix--; - if (lineOBJpix < 0) - continue; - if (sx < 240) { - u8 color = vram[address]; - if ((color == 0) && - (((prio >> 25) & 3) < - ((lineOBJ[sx] >> 25) & - 3))) { - lineOBJ[sx] = - (lineOBJ[sx] & - 0xF9FFFFFF) | - prio; - if ((a0 & 0x1000) && - m) - lineOBJ[sx] = - (lineOBJ - [sx - - 1] & - 0xF9FFFFFF) | - prio; - } else if ((color) && - (prio < - (lineOBJ[sx] & - 0xFF000000))) { - lineOBJ[sx] = - READ16LE( - &spritePalette - [color]) | - prio; - if ((a0 & 0x1000) && - m) - lineOBJ[sx] = - (lineOBJ - [sx - - 1] & - 0xF9FFFFFF) | - prio; - } - - if (a0 & 0x1000) { - m++; - if (m == mosaicX) - m = 0; - } - -#ifdef SPRITE_DEBUG - if (t == 0 || t == maskY || - xx == 0 || xx == maskX) - lineOBJ[sx] = - 0x001F; -#endif - } - - sx = (sx + 1) & 511; - if (a1 & 0x1000) { - xxx--; - address--; - if (xxx == -1) { - address -= 56; - xxx = 7; - } - if (address < 0x10000) - address += 0x8000; - } else { - xxx++; - address++; - if (xxx == 8) { - address += 56; - xxx = 0; - } - if (address > 0x17fff) - address -= 0x8000; - } - } - } else { - if (a1 & 0x2000) - t = sizeY - t - 1; - int c = (a2 & 0x3FF); - if ((DISPCNT & 7) > 2 && (c < 512)) - continue; - - int inc = 32; - if (DISPCNT & 0x40) { - inc = sizeX >> 3; - } - int xxx = 0; - if (a1 & 0x1000) - xxx = sizeX - 1; - - if (a0 & 0x1000) { - t -= (t % mosaicY); - } - - int address = - 0x10000 + - ((((c + (t >> 3) * inc) << 5) + - ((t & 7) << 2) + ((xxx >> 3) << 5) + - ((xxx & 7) >> 1)) & - 0x7FFF); - u32 prio = (((a2 >> 10) & 3) << 25) | - ((a0 & 0x0c00) << 6); - int palette = (a2 >> 8) & 0xF0; - if (a1 & 0x1000) { - xxx = 7; - for (int xx = sizeX - 1; xx >= 0; - xx--) { - if (xx >= startpix) - lineOBJpix--; - if (lineOBJpix < 0) - continue; - if (sx < 240) { - u8 color = - vram[address]; - if (xx & 1) { - color = - (color >> - 4); - } else - color &= - 0x0F; - - if ((color == 0) && - (((prio >> 25) & - 3) < - ((lineOBJ - [sx] >> - 25) & - 3))) { - lineOBJ[sx] = - (lineOBJ - [sx] & - 0xF9FFFFFF) | - prio; - if ((a0 & - 0x1000) && - m) - lineOBJ[sx] = - (lineOBJ - [sx - - 1] & - 0xF9FFFFFF) | - prio; - } else if ( - (color) && - (prio < - (lineOBJ[sx] & - 0xFF000000))) { - lineOBJ[sx] = - READ16LE( - &spritePalette - [palette + - color]) | - prio; - if ((a0 & - 0x1000) && - m) - lineOBJ[sx] = - (lineOBJ - [sx - - 1] & - 0xF9FFFFFF) | - prio; - } - } - if (a0 & 0x1000) { - m++; - if (m == mosaicX) - m = 0; - } -#ifdef SPRITE_DEBUG - if (t == 0 || t == maskY || - xx == 0 || xx == maskX) - lineOBJ[sx] = - 0x001F; -#endif - sx = (sx + 1) & 511; - xxx--; - if (!(xx & 1)) - address--; - if (xxx == -1) { - xxx = 7; - address -= 28; - } - if (address < 0x10000) - address += 0x8000; - } - } else { - for (int xx = 0; xx < sizeX; xx++) { - if (xx >= startpix) - lineOBJpix--; - if (lineOBJpix < 0) - continue; - if (sx < 240) { - u8 color = - vram[address]; - if (xx & 1) { - color = - (color >> - 4); - } else - color &= - 0x0F; - - if ((color == 0) && - (((prio >> 25) & - 3) < - ((lineOBJ - [sx] >> - 25) & - 3))) { - lineOBJ[sx] = - (lineOBJ - [sx] & - 0xF9FFFFFF) | - prio; - if ((a0 & - 0x1000) && - m) - lineOBJ[sx] = - (lineOBJ - [sx - - 1] & - 0xF9FFFFFF) | - prio; - } else if ( - (color) && - (prio < - (lineOBJ[sx] & - 0xFF000000))) { - lineOBJ[sx] = - READ16LE( - &spritePalette - [palette + - color]) | - prio; - if ((a0 & - 0x1000) && - m) - lineOBJ[sx] = - (lineOBJ - [sx - - 1] & - 0xF9FFFFFF) | - prio; - } - } - if (a0 & 0x1000) { - m++; - if (m == mosaicX) - m = 0; - } -#ifdef SPRITE_DEBUG - if (t == 0 || t == maskY || - xx == 0 || xx == maskX) - lineOBJ[sx] = - 0x001F; -#endif - sx = (sx + 1) & 511; - xxx++; - if (xx & 1) - address++; - if (xxx == 8) { - address += 28; - xxx = 0; - } - if (address > 0x17fff) - address -= 0x8000; - } - } - } - } + sx = (sx + 1) & 511; + realX += dx; + realY += dy; } + } } } + } else { + if (sy + sizeY > 256) + sy -= 256; + int t = VCOUNT - sy; + if ((t >= 0) && (t < sizeY)) { + int startpix = 0; + if ((sx + sizeX) > 512) { + startpix = 512 - sx; + } + if ((sx < 240) || startpix) { + lineOBJpix += 2; + if (a0 & 0x2000) { + if (a1 & 0x2000) + t = sizeY - t - 1; + int c = (a2 & 0x3FF); + if ((DISPCNT & 7) > 2 && (c < 512)) + continue; + + int inc = 32; + if (DISPCNT & 0x40) { + inc = sizeX >> 2; + } else { + c &= 0x3FE; + } + int xxx = 0; + if (a1 & 0x1000) + xxx = sizeX - 1; + + if (a0 & 0x1000) { + t -= (t % mosaicY); + } + + int address = 0x10000 + ((((c + (t >> 3) * inc) << 5) + ((t & 7) << 3) + ((xxx >> 3) << 6) + (xxx & 7)) & 0x7FFF); + + if (a1 & 0x1000) + xxx = 7; + u32 prio = (((a2 >> 10) & 3) << 25) | ((a0 & 0x0c00) << 6); + + for (int xx = 0; xx < sizeX; xx++) { + if (xx >= startpix) + lineOBJpix--; + if (lineOBJpix < 0) + continue; + if (sx < 240) { + u8 color = vram[address]; + if ((color == 0) && (((prio >> 25) & 3) < ((lineOBJ[sx] >> 25) & 3))) { + lineOBJ[sx] = (lineOBJ[sx] & 0xF9FFFFFF) | prio; + if ((a0 & 0x1000) && m) + lineOBJ[sx] = (lineOBJ + [sx - 1] + & 0xF9FFFFFF) + | prio; + } else if ((color) && (prio < (lineOBJ[sx] & 0xFF000000))) { + lineOBJ[sx] = READ16LE( + &spritePalette + [color]) + | prio; + if ((a0 & 0x1000) && m) + lineOBJ[sx] = (lineOBJ + [sx - 1] + & 0xF9FFFFFF) + | prio; + } + + if (a0 & 0x1000) { + m++; + if (m == mosaicX) + m = 0; + } + +#ifdef SPRITE_DEBUG + if (t == 0 || t == maskY || xx == 0 || xx == maskX) + lineOBJ[sx] = 0x001F; +#endif + } + + sx = (sx + 1) & 511; + if (a1 & 0x1000) { + xxx--; + address--; + if (xxx == -1) { + address -= 56; + xxx = 7; + } + if (address < 0x10000) + address += 0x8000; + } else { + xxx++; + address++; + if (xxx == 8) { + address += 56; + xxx = 0; + } + if (address > 0x17fff) + address -= 0x8000; + } + } + } else { + if (a1 & 0x2000) + t = sizeY - t - 1; + int c = (a2 & 0x3FF); + if ((DISPCNT & 7) > 2 && (c < 512)) + continue; + + int inc = 32; + if (DISPCNT & 0x40) { + inc = sizeX >> 3; + } + int xxx = 0; + if (a1 & 0x1000) + xxx = sizeX - 1; + + if (a0 & 0x1000) { + t -= (t % mosaicY); + } + + int address = 0x10000 + ((((c + (t >> 3) * inc) << 5) + ((t & 7) << 2) + ((xxx >> 3) << 5) + ((xxx & 7) >> 1)) & 0x7FFF); + u32 prio = (((a2 >> 10) & 3) << 25) | ((a0 & 0x0c00) << 6); + int palette = (a2 >> 8) & 0xF0; + if (a1 & 0x1000) { + xxx = 7; + for (int xx = sizeX - 1; xx >= 0; + xx--) { + if (xx >= startpix) + lineOBJpix--; + if (lineOBJpix < 0) + continue; + if (sx < 240) { + u8 color = vram[address]; + if (xx & 1) { + color = (color >> 4); + } else + color &= 0x0F; + + if ((color == 0) && (((prio >> 25) & 3) < ((lineOBJ + [sx] + >> 25) + & 3))) { + lineOBJ[sx] = (lineOBJ + [sx] + & 0xF9FFFFFF) + | prio; + if ((a0 & 0x1000) && m) + lineOBJ[sx] = (lineOBJ + [sx - 1] + & 0xF9FFFFFF) + | prio; + } else if ( + (color) && (prio < (lineOBJ[sx] & 0xFF000000))) { + lineOBJ[sx] = READ16LE( + &spritePalette + [palette + color]) + | prio; + if ((a0 & 0x1000) && m) + lineOBJ[sx] = (lineOBJ + [sx - 1] + & 0xF9FFFFFF) + | prio; + } + } + if (a0 & 0x1000) { + m++; + if (m == mosaicX) + m = 0; + } +#ifdef SPRITE_DEBUG + if (t == 0 || t == maskY || xx == 0 || xx == maskX) + lineOBJ[sx] = 0x001F; +#endif + sx = (sx + 1) & 511; + xxx--; + if (!(xx & 1)) + address--; + if (xxx == -1) { + xxx = 7; + address -= 28; + } + if (address < 0x10000) + address += 0x8000; + } + } else { + for (int xx = 0; xx < sizeX; xx++) { + if (xx >= startpix) + lineOBJpix--; + if (lineOBJpix < 0) + continue; + if (sx < 240) { + u8 color = vram[address]; + if (xx & 1) { + color = (color >> 4); + } else + color &= 0x0F; + + if ((color == 0) && (((prio >> 25) & 3) < ((lineOBJ + [sx] + >> 25) + & 3))) { + lineOBJ[sx] = (lineOBJ + [sx] + & 0xF9FFFFFF) + | prio; + if ((a0 & 0x1000) && m) + lineOBJ[sx] = (lineOBJ + [sx - 1] + & 0xF9FFFFFF) + | prio; + } else if ( + (color) && (prio < (lineOBJ[sx] & 0xFF000000))) { + lineOBJ[sx] = READ16LE( + &spritePalette + [palette + color]) + | prio; + if ((a0 & 0x1000) && m) + lineOBJ[sx] = (lineOBJ + [sx - 1] + & 0xF9FFFFFF) + | prio; + } + } + if (a0 & 0x1000) { + m++; + if (m == mosaicX) + m = 0; + } +#ifdef SPRITE_DEBUG + if (t == 0 || t == maskY || xx == 0 || xx == maskX) + lineOBJ[sx] = 0x001F; +#endif + sx = (sx + 1) & 511; + xxx++; + if (xx & 1) + address++; + if (xxx == 8) { + address += 28; + xxx = 0; + } + if (address > 0x17fff) + address -= 0x8000; + } + } + } + } + } + } } + } } -static inline void gfxDrawOBJWin(u32 *lineOBJWin) +static inline void gfxDrawOBJWin(u32* lineOBJWin) { - gfxClearArray(lineOBJWin); - if ((layerEnable & 0x9000) == 0x9000) { - u16 *sprites = (u16 *)oam; - // u16 *spritePalette = &((u16 *)paletteRAM)[256]; - for (int x = 0; x < 128; x++) { - int lineOBJpix = lineOBJpixleft[x]; - u16 a0 = READ16LE(sprites++); - u16 a1 = READ16LE(sprites++); - u16 a2 = READ16LE(sprites++); - sprites++; + gfxClearArray(lineOBJWin); + if ((layerEnable & 0x9000) == 0x9000) { + u16* sprites = (u16*)oam; + // u16 *spritePalette = &((u16 *)paletteRAM)[256]; + for (int x = 0; x < 128; x++) { + int lineOBJpix = lineOBJpixleft[x]; + u16 a0 = READ16LE(sprites++); + u16 a1 = READ16LE(sprites++); + u16 a2 = READ16LE(sprites++); + sprites++; - if (lineOBJpix <= 0) - continue; + if (lineOBJpix <= 0) + continue; - // ignores non OBJ-WIN and disabled OBJ-WIN - if (((a0 & 0x0c00) != 0x0800) || ((a0 & 0x0300) == 0x0200)) - continue; + // ignores non OBJ-WIN and disabled OBJ-WIN + if (((a0 & 0x0c00) != 0x0800) || ((a0 & 0x0300) == 0x0200)) + continue; - if ((a0 & 0x0c00) == 0x0c00) - a0 &= 0xF3FF; + if ((a0 & 0x0c00) == 0x0c00) + a0 &= 0xF3FF; - if ((a0 >> 14) == 3) { - a0 &= 0x3FFF; - a1 &= 0x3FFF; - } + if ((a0 >> 14) == 3) { + a0 &= 0x3FFF; + a1 &= 0x3FFF; + } - int sizeX = 8 << (a1 >> 14); - int sizeY = sizeX; + int sizeX = 8 << (a1 >> 14); + int sizeY = sizeX; - if ((a0 >> 14) & 1) { - if (sizeX < 32) - sizeX <<= 1; - if (sizeY > 8) - sizeY >>= 1; - } else if ((a0 >> 14) & 2) { - if (sizeX > 8) - sizeX >>= 1; - if (sizeY < 32) - sizeY <<= 1; - } + if ((a0 >> 14) & 1) { + if (sizeX < 32) + sizeX <<= 1; + if (sizeY > 8) + sizeY >>= 1; + } else if ((a0 >> 14) & 2) { + if (sizeX > 8) + sizeX >>= 1; + if (sizeY < 32) + sizeY <<= 1; + } - int sy = (a0 & 255); + int sy = (a0 & 255); - if (a0 & 0x0100) { - int fieldX = sizeX; - int fieldY = sizeY; - if (a0 & 0x0200) { - fieldX <<= 1; - fieldY <<= 1; - } - if ((sy + fieldY) > 256) - sy -= 256; - int t = VCOUNT - sy; - if ((t >= 0) && (t < fieldY)) { - int sx = (a1 & 0x1FF); - int startpix = 0; - if ((sx + fieldX) > 512) { - startpix = 512 - sx; - } - if ((sx < 240) || startpix) { - lineOBJpix -= 8; - // int t2 = t - (fieldY >> 1); - int rot = (a1 >> 9) & 0x1F; - u16 *OAM = (u16 *)oam; - int dx = READ16LE(&OAM[3 + (rot << 4)]); - if (dx & 0x8000) - dx |= 0xFFFF8000; - int dmx = READ16LE(&OAM[7 + (rot << 4)]); - if (dmx & 0x8000) - dmx |= 0xFFFF8000; - int dy = READ16LE(&OAM[11 + (rot << 4)]); - if (dy & 0x8000) - dy |= 0xFFFF8000; - int dmy = READ16LE(&OAM[15 + (rot << 4)]); - if (dmy & 0x8000) - dmy |= 0xFFFF8000; - - int realX = ((sizeX) << 7) - (fieldX >> 1) * dx - - (fieldY >> 1) * dmx + t * dmx; - int realY = ((sizeY) << 7) - (fieldX >> 1) * dy - - (fieldY >> 1) * dmy + t * dmy; - - // u32 prio = (((a2 >> 10) & 3) << 25) | ((a0 & - // 0x0c00)<<6); - - if (a0 & 0x2000) { - int c = (a2 & 0x3FF); - if ((DISPCNT & 7) > 2 && (c < 512)) - continue; - int inc = 32; - if (DISPCNT & 0x40) - inc = sizeX >> 2; - else - c &= 0x3FE; - for (int x = 0; x < fieldX; x++) { - if (x >= startpix) - lineOBJpix -= 2; - if (lineOBJpix < 0) - continue; - int xxx = realX >> 8; - int yyy = realY >> 8; - - if (xxx < 0 || xxx >= sizeX || - yyy < 0 || yyy >= sizeY || - sx >= 240) { - } else { - u32 color = vram - [0x10000 + - ((((c + - (yyy >> 3) * inc) - << 5) + - ((yyy & 7) << 3) + - ((xxx >> 3) << 6) + - (xxx & 7)) & - 0x7fff)]; - if (color) { - lineOBJWin[sx] = 1; - } - } - sx = (sx + 1) & 511; - realX += dx; - realY += dy; - } - } else { - int c = (a2 & 0x3FF); - if ((DISPCNT & 7) > 2 && (c < 512)) - continue; - - int inc = 32; - if (DISPCNT & 0x40) - inc = sizeX >> 3; - // int palette = (a2 >> 8) & 0xF0; - for (int x = 0; x < fieldX; x++) { - if (x >= startpix) - lineOBJpix -= 2; - if (lineOBJpix < 0) - continue; - int xxx = realX >> 8; - int yyy = realY >> 8; - - // if(x == 0 || x == - // (sizeX-1) || - // t == 0 || t == - // (sizeY-1)) { - // lineOBJ[sx] = - // 0x001F | prio; - // } else { - if (xxx < 0 || xxx >= sizeX || - yyy < 0 || yyy >= sizeY || - sx >= 240) { - } else { - u32 color = vram - [0x10000 + - ((((c + - (yyy >> 3) * inc) - << 5) + - ((yyy & 7) << 2) + - ((xxx >> 3) << 5) + - ((xxx & 7) >> 1)) & - 0x7fff)]; - if (xxx & 1) - color >>= 4; - else - color &= 0x0F; - - if (color) { - lineOBJWin[sx] = 1; - } - } - // } - sx = (sx + 1) & 511; - realX += dx; - realY += dy; - } - } - } - } - } else { - if ((sy + sizeY) > 256) - sy -= 256; - int t = VCOUNT - sy; - if ((t >= 0) && (t < sizeY)) { - int sx = (a1 & 0x1FF); - int startpix = 0; - if ((sx + sizeX) > 512) { - startpix = 512 - sx; - } - if ((sx < 240) || startpix) { - lineOBJpix += 2; - if (a0 & 0x2000) { - if (a1 & 0x2000) - t = sizeY - t - 1; - int c = (a2 & 0x3FF); - if ((DISPCNT & 7) > 2 && (c < 512)) - continue; - - int inc = 32; - if (DISPCNT & 0x40) { - inc = sizeX >> 2; - } else { - c &= 0x3FE; - } - int xxx = 0; - if (a1 & 0x1000) - xxx = sizeX - 1; - int address = - 0x10000 + - ((((c + (t >> 3) * inc) << 5) + - ((t & 7) << 3) + ((xxx >> 3) << 6) + - (xxx & 7)) & - 0x7fff); - if (a1 & 0x1000) - xxx = 7; - // u32 prio = (((a2 >> 10) & 3) << 25) | - // ((a0 & 0x0c00)<<6); - for (int xx = 0; xx < sizeX; xx++) { - if (xx >= startpix) - lineOBJpix--; - if (lineOBJpix < 0) - continue; - if (sx < 240) { - u8 color = vram[address]; - if (color) { - lineOBJWin[sx] = 1; - } - } - - sx = (sx + 1) & 511; - if (a1 & 0x1000) { - xxx--; - address--; - if (xxx == -1) { - address -= 56; - xxx = 7; - } - if (address < 0x10000) - address += 0x8000; - } else { - xxx++; - address++; - if (xxx == 8) { - address += 56; - xxx = 0; - } - if (address > 0x17fff) - address -= 0x8000; - } - } - } else { - if (a1 & 0x2000) - t = sizeY - t - 1; - int c = (a2 & 0x3FF); - if ((DISPCNT & 7) > 2 && (c < 512)) - continue; - - int inc = 32; - if (DISPCNT & 0x40) { - inc = sizeX >> 3; - } - int xxx = 0; - if (a1 & 0x1000) - xxx = sizeX - 1; - int address = - 0x10000 + - ((((c + (t >> 3) * inc) << 5) + - ((t & 7) << 2) + ((xxx >> 3) << 5) + - ((xxx & 7) >> 1)) & - 0x7fff); - // u32 prio = (((a2 >> 10) & 3) << 25) | - // ((a0 & 0x0c00)<<6); - // int palette = (a2 >> 8) & 0xF0; - if (a1 & 0x1000) { - xxx = 7; - for (int xx = sizeX - 1; xx >= 0; - xx--) { - if (xx >= startpix) - lineOBJpix--; - if (lineOBJpix < 0) - continue; - if (sx < 240) { - u8 color = - vram[address]; - if (xx & 1) { - color = - (color >> - 4); - } else - color &= - 0x0F; - - if (color) { - lineOBJWin - [sx] = - 1; - } - } - sx = (sx + 1) & 511; - xxx--; - if (!(xx & 1)) - address--; - if (xxx == -1) { - xxx = 7; - address -= 28; - } - if (address < 0x10000) - address += 0x8000; - } - } else { - for (int xx = 0; xx < sizeX; xx++) { - if (xx >= startpix) - lineOBJpix--; - if (lineOBJpix < 0) - continue; - if (sx < 240) { - u8 color = - vram[address]; - if (xx & 1) { - color = - (color >> - 4); - } else - color &= - 0x0F; - - if (color) { - lineOBJWin - [sx] = - 1; - } - } - sx = (sx + 1) & 511; - xxx++; - if (xx & 1) - address++; - if (xxx == 8) { - address += 28; - xxx = 0; - } - if (address > 0x17fff) - address -= 0x8000; - } - } - } - } - } - } + if (a0 & 0x0100) { + int fieldX = sizeX; + int fieldY = sizeY; + if (a0 & 0x0200) { + fieldX <<= 1; + fieldY <<= 1; } + if ((sy + fieldY) > 256) + sy -= 256; + int t = VCOUNT - sy; + if ((t >= 0) && (t < fieldY)) { + int sx = (a1 & 0x1FF); + int startpix = 0; + if ((sx + fieldX) > 512) { + startpix = 512 - sx; + } + if ((sx < 240) || startpix) { + lineOBJpix -= 8; + // int t2 = t - (fieldY >> 1); + int rot = (a1 >> 9) & 0x1F; + u16* OAM = (u16*)oam; + int dx = READ16LE(&OAM[3 + (rot << 4)]); + if (dx & 0x8000) + dx |= 0xFFFF8000; + int dmx = READ16LE(&OAM[7 + (rot << 4)]); + if (dmx & 0x8000) + dmx |= 0xFFFF8000; + int dy = READ16LE(&OAM[11 + (rot << 4)]); + if (dy & 0x8000) + dy |= 0xFFFF8000; + int dmy = READ16LE(&OAM[15 + (rot << 4)]); + if (dmy & 0x8000) + dmy |= 0xFFFF8000; + + int realX = ((sizeX) << 7) - (fieldX >> 1) * dx - (fieldY >> 1) * dmx + t * dmx; + int realY = ((sizeY) << 7) - (fieldX >> 1) * dy - (fieldY >> 1) * dmy + t * dmy; + + // u32 prio = (((a2 >> 10) & 3) << 25) | ((a0 & + // 0x0c00)<<6); + + if (a0 & 0x2000) { + int c = (a2 & 0x3FF); + if ((DISPCNT & 7) > 2 && (c < 512)) + continue; + int inc = 32; + if (DISPCNT & 0x40) + inc = sizeX >> 2; + else + c &= 0x3FE; + for (int x = 0; x < fieldX; x++) { + if (x >= startpix) + lineOBJpix -= 2; + if (lineOBJpix < 0) + continue; + int xxx = realX >> 8; + int yyy = realY >> 8; + + if (xxx < 0 || xxx >= sizeX || yyy < 0 || yyy >= sizeY || sx >= 240) { + } else { + u32 color = vram + [0x10000 + ((((c + (yyy >> 3) * inc) + << 5) + + ((yyy & 7) << 3) + ((xxx >> 3) << 6) + (xxx & 7)) + & 0x7fff)]; + if (color) { + lineOBJWin[sx] = 1; + } + } + sx = (sx + 1) & 511; + realX += dx; + realY += dy; + } + } else { + int c = (a2 & 0x3FF); + if ((DISPCNT & 7) > 2 && (c < 512)) + continue; + + int inc = 32; + if (DISPCNT & 0x40) + inc = sizeX >> 3; + // int palette = (a2 >> 8) & 0xF0; + for (int x = 0; x < fieldX; x++) { + if (x >= startpix) + lineOBJpix -= 2; + if (lineOBJpix < 0) + continue; + int xxx = realX >> 8; + int yyy = realY >> 8; + + // if(x == 0 || x == + // (sizeX-1) || + // t == 0 || t == + // (sizeY-1)) { + // lineOBJ[sx] = + // 0x001F | prio; + // } else { + if (xxx < 0 || xxx >= sizeX || yyy < 0 || yyy >= sizeY || sx >= 240) { + } else { + u32 color = vram + [0x10000 + ((((c + (yyy >> 3) * inc) + << 5) + + ((yyy & 7) << 2) + ((xxx >> 3) << 5) + ((xxx & 7) >> 1)) + & 0x7fff)]; + if (xxx & 1) + color >>= 4; + else + color &= 0x0F; + + if (color) { + lineOBJWin[sx] = 1; + } + } + // } + sx = (sx + 1) & 511; + realX += dx; + realY += dy; + } + } + } + } + } else { + if ((sy + sizeY) > 256) + sy -= 256; + int t = VCOUNT - sy; + if ((t >= 0) && (t < sizeY)) { + int sx = (a1 & 0x1FF); + int startpix = 0; + if ((sx + sizeX) > 512) { + startpix = 512 - sx; + } + if ((sx < 240) || startpix) { + lineOBJpix += 2; + if (a0 & 0x2000) { + if (a1 & 0x2000) + t = sizeY - t - 1; + int c = (a2 & 0x3FF); + if ((DISPCNT & 7) > 2 && (c < 512)) + continue; + + int inc = 32; + if (DISPCNT & 0x40) { + inc = sizeX >> 2; + } else { + c &= 0x3FE; + } + int xxx = 0; + if (a1 & 0x1000) + xxx = sizeX - 1; + int address = 0x10000 + ((((c + (t >> 3) * inc) << 5) + ((t & 7) << 3) + ((xxx >> 3) << 6) + (xxx & 7)) & 0x7fff); + if (a1 & 0x1000) + xxx = 7; + // u32 prio = (((a2 >> 10) & 3) << 25) | + // ((a0 & 0x0c00)<<6); + for (int xx = 0; xx < sizeX; xx++) { + if (xx >= startpix) + lineOBJpix--; + if (lineOBJpix < 0) + continue; + if (sx < 240) { + u8 color = vram[address]; + if (color) { + lineOBJWin[sx] = 1; + } + } + + sx = (sx + 1) & 511; + if (a1 & 0x1000) { + xxx--; + address--; + if (xxx == -1) { + address -= 56; + xxx = 7; + } + if (address < 0x10000) + address += 0x8000; + } else { + xxx++; + address++; + if (xxx == 8) { + address += 56; + xxx = 0; + } + if (address > 0x17fff) + address -= 0x8000; + } + } + } else { + if (a1 & 0x2000) + t = sizeY - t - 1; + int c = (a2 & 0x3FF); + if ((DISPCNT & 7) > 2 && (c < 512)) + continue; + + int inc = 32; + if (DISPCNT & 0x40) { + inc = sizeX >> 3; + } + int xxx = 0; + if (a1 & 0x1000) + xxx = sizeX - 1; + int address = 0x10000 + ((((c + (t >> 3) * inc) << 5) + ((t & 7) << 2) + ((xxx >> 3) << 5) + ((xxx & 7) >> 1)) & 0x7fff); + // u32 prio = (((a2 >> 10) & 3) << 25) | + // ((a0 & 0x0c00)<<6); + // int palette = (a2 >> 8) & 0xF0; + if (a1 & 0x1000) { + xxx = 7; + for (int xx = sizeX - 1; xx >= 0; + xx--) { + if (xx >= startpix) + lineOBJpix--; + if (lineOBJpix < 0) + continue; + if (sx < 240) { + u8 color = vram[address]; + if (xx & 1) { + color = (color >> 4); + } else + color &= 0x0F; + + if (color) { + lineOBJWin + [sx] + = 1; + } + } + sx = (sx + 1) & 511; + xxx--; + if (!(xx & 1)) + address--; + if (xxx == -1) { + xxx = 7; + address -= 28; + } + if (address < 0x10000) + address += 0x8000; + } + } else { + for (int xx = 0; xx < sizeX; xx++) { + if (xx >= startpix) + lineOBJpix--; + if (lineOBJpix < 0) + continue; + if (sx < 240) { + u8 color = vram[address]; + if (xx & 1) { + color = (color >> 4); + } else + color &= 0x0F; + + if (color) { + lineOBJWin + [sx] + = 1; + } + } + sx = (sx + 1) & 511; + xxx++; + if (xx & 1) + address++; + if (xxx == 8) { + address += 28; + xxx = 0; + } + if (address > 0x17fff) + address -= 0x8000; + } + } + } + } + } + } } + } } static inline u32 gfxIncreaseBrightness(u32 color, int coeff) { - color &= 0xffff; - color = ((color << 16) | color) & 0x3E07C1F; + color &= 0xffff; + color = ((color << 16) | color) & 0x3E07C1F; - color = color + (((0x3E07C1F - color) * coeff) >> 4); - color &= 0x3E07C1F; + color = color + (((0x3E07C1F - color) * coeff) >> 4); + color &= 0x3E07C1F; - return (color >> 16) | color; + return (color >> 16) | color; } -static inline void gfxIncreaseBrightness(u32 *line, int coeff) +static inline void gfxIncreaseBrightness(u32* line, int coeff) { - for (int x = 0; x < 240; x++) { - u32 color = *line; - int r = (color & 0x1F); - int g = ((color >> 5) & 0x1F); - int b = ((color >> 10) & 0x1F); + for (int x = 0; x < 240; x++) { + u32 color = *line; + int r = (color & 0x1F); + int g = ((color >> 5) & 0x1F); + int b = ((color >> 10) & 0x1F); - r = r + (((31 - r) * coeff) >> 4); - g = g + (((31 - g) * coeff) >> 4); - b = b + (((31 - b) * coeff) >> 4); - if (r > 31) - r = 31; - if (g > 31) - g = 31; - if (b > 31) - b = 31; - *line++ = (color & 0xFFFF0000) | (b << 10) | (g << 5) | r; - } + r = r + (((31 - r) * coeff) >> 4); + g = g + (((31 - g) * coeff) >> 4); + b = b + (((31 - b) * coeff) >> 4); + if (r > 31) + r = 31; + if (g > 31) + g = 31; + if (b > 31) + b = 31; + *line++ = (color & 0xFFFF0000) | (b << 10) | (g << 5) | r; + } } static inline u32 gfxDecreaseBrightness(u32 color, int coeff) { - color &= 0xffff; - color = ((color << 16) | color) & 0x3E07C1F; + color &= 0xffff; + color = ((color << 16) | color) & 0x3E07C1F; - color = color - (((color * coeff) >> 4) & 0x3E07C1F); + color = color - (((color * coeff) >> 4) & 0x3E07C1F); - return (color >> 16) | color; + return (color >> 16) | color; } -static inline void gfxDecreaseBrightness(u32 *line, int coeff) +static inline void gfxDecreaseBrightness(u32* line, int coeff) { - for (int x = 0; x < 240; x++) { - u32 color = *line; - int r = (color & 0x1F); - int g = ((color >> 5) & 0x1F); - int b = ((color >> 10) & 0x1F); + for (int x = 0; x < 240; x++) { + u32 color = *line; + int r = (color & 0x1F); + int g = ((color >> 5) & 0x1F); + int b = ((color >> 10) & 0x1F); - r = r - ((r * coeff) >> 4); - g = g - ((g * coeff) >> 4); - b = b - ((b * coeff) >> 4); - if (r < 0) - r = 0; - if (g < 0) - g = 0; - if (b < 0) - b = 0; - *line++ = (color & 0xFFFF0000) | (b << 10) | (g << 5) | r; - } + r = r - ((r * coeff) >> 4); + g = g - ((g * coeff) >> 4); + b = b - ((b * coeff) >> 4); + if (r < 0) + r = 0; + if (g < 0) + g = 0; + if (b < 0) + b = 0; + *line++ = (color & 0xFFFF0000) | (b << 10) | (g << 5) | r; + } } static inline u32 gfxAlphaBlend(u32 color, u32 color2, int ca, int cb) { - if (color < 0x80000000) { - color &= 0xffff; - color2 &= 0xffff; + if (color < 0x80000000) { + color &= 0xffff; + color2 &= 0xffff; - color = ((color << 16) | color) & 0x03E07C1F; - color2 = ((color2 << 16) | color2) & 0x03E07C1F; - color = ((color * ca) + (color2 * cb)) >> 4; + color = ((color << 16) | color) & 0x03E07C1F; + color2 = ((color2 << 16) | color2) & 0x03E07C1F; + color = ((color * ca) + (color2 * cb)) >> 4; - if ((ca + cb) > 16) { - if (color & 0x20) - color |= 0x1f; - if (color & 0x8000) - color |= 0x7C00; - if (color & 0x4000000) - color |= 0x03E00000; - } - - color &= 0x03E07C1F; - color = (color >> 16) | color; + if ((ca + cb) > 16) { + if (color & 0x20) + color |= 0x1f; + if (color & 0x8000) + color |= 0x7C00; + if (color & 0x4000000) + color |= 0x03E00000; } - return color; + + color &= 0x03E07C1F; + color = (color >> 16) | color; + } + return color; } -static inline void gfxAlphaBlend(u32 *ta, u32 *tb, int ca, int cb) +static inline void gfxAlphaBlend(u32* ta, u32* tb, int ca, int cb) { - for (int x = 0; x < 240; x++) { - u32 color = *ta; - if (color < 0x80000000) { - int r = (color & 0x1F); - int g = ((color >> 5) & 0x1F); - int b = ((color >> 10) & 0x1F); - u32 color2 = (*tb++); - int r0 = (color2 & 0x1F); - int g0 = ((color2 >> 5) & 0x1F); - int b0 = ((color2 >> 10) & 0x1F); + for (int x = 0; x < 240; x++) { + u32 color = *ta; + if (color < 0x80000000) { + int r = (color & 0x1F); + int g = ((color >> 5) & 0x1F); + int b = ((color >> 10) & 0x1F); + u32 color2 = (*tb++); + int r0 = (color2 & 0x1F); + int g0 = ((color2 >> 5) & 0x1F); + int b0 = ((color2 >> 10) & 0x1F); - r = ((r * ca) + (r0 * cb)) >> 4; - g = ((g * ca) + (g0 * cb)) >> 4; - b = ((b * ca) + (b0 * cb)) >> 4; + r = ((r * ca) + (r0 * cb)) >> 4; + g = ((g * ca) + (g0 * cb)) >> 4; + b = ((b * ca) + (b0 * cb)) >> 4; - if (r > 31) - r = 31; - if (g > 31) - g = 31; - if (b > 31) - b = 31; + if (r > 31) + r = 31; + if (g > 31) + g = 31; + if (b > 31) + b = 31; - *ta++ = (color & 0xFFFF0000) | (b << 10) | (g << 5) | r; - } else { - ta++; - tb++; - } + *ta++ = (color & 0xFFFF0000) | (b << 10) | (g << 5) | r; + } else { + ta++; + tb++; } + } } #endif // GFX_H diff --git a/src/gba/GBALink.cpp b/src/gba/GBALink.cpp index 3a800d2c..efb0ae0a 100644 --- a/src/gba/GBALink.cpp +++ b/src/gba/GBALink.cpp @@ -1,7 +1,7 @@ // This file was written by denopqrihg // with major changes by tjm -#include #include +#include // malloc.h does not seem to exist on Mac OS 10.7 #ifdef __APPLE__ @@ -14,50 +14,58 @@ #define snprintf _snprintf #endif -#define UPDATE_REG(address, value) WRITE16LE(((u16 *)&ioMem[address]),value) +#define UPDATE_REG(address, value) WRITE16LE(((u16*)&ioMem[address]), value) static int vbaid = 0; -const char *MakeInstanceFilename(const char *Input) +const char* MakeInstanceFilename(const char* Input) { - if (vbaid == 0) - return Input; + if (vbaid == 0) + return Input; - static char *result = NULL; - if (result != NULL) - free(result); + static char* result = NULL; + if (result != NULL) + free(result); - result = (char *)malloc(strlen(Input) + 3); - char *p = strrchr((char *)Input, '.'); - sprintf(result, "%.*s-%d.%s", (int)(p - Input), Input, vbaid + 1, p + 1); - return result; + result = (char*)malloc(strlen(Input) + 3); + char* p = strrchr((char*)Input, '.'); + sprintf(result, "%.*s-%d.%s", (int)(p - Input), Input, vbaid + 1, p + 1); + return result; } #ifndef NO_LINK -enum -{ - SENDING = false, - RECEIVING = true +enum { + SENDING = false, + RECEIVING = true }; -enum siocnt_lo_32bit -{ - SIO_INT_CLOCK = 0x0001, - SIO_INT_CLOCK_SEL_2MHZ = 0x0002, - SIO_TRANS_FLAG_RECV_ENABLE = 0x0004, - SIO_TRANS_FLAG_SEND_DISABLE = 0x0008, - SIO_TRANS_START = 0x0080, - SIO_TRANS_32BIT = 0x1000, - SIO_IRQ_ENABLE = 0x4000 +enum siocnt_lo_32bit { + SIO_INT_CLOCK = 0x0001, + SIO_INT_CLOCK_SEL_2MHZ = 0x0002, + SIO_TRANS_FLAG_RECV_ENABLE = 0x0004, + SIO_TRANS_FLAG_SEND_DISABLE = 0x0008, + SIO_TRANS_START = 0x0080, + SIO_TRANS_32BIT = 0x1000, + SIO_IRQ_ENABLE = 0x4000 }; // The usual min/max functions for built-in types. // // template T min( T x, T y ) { return x < y ? x : y; } // template T max( T x, T y ) { return x > y ? x : y; } -#define BLARGG_DEF_MIN_MAX( type ) \ - static inline type blargg_min( type x, type y ) { if ( y < x ) x = y; return x; }\ - static inline type blargg_max( type x, type y ) { if ( x < y ) x = y; return x; } +#define BLARGG_DEF_MIN_MAX(type) \ + static inline type blargg_min(type x, type y) \ + { \ + if (y < x) \ + x = y; \ + return x; \ + } \ + static inline type blargg_max(type x, type y) \ + { \ + if (x < y) \ + x = y; \ + return x; \ + } BLARGG_DEF_MIN_MAX(int) BLARGG_DEF_MIN_MAX(unsigned) @@ -66,10 +74,10 @@ BLARGG_DEF_MIN_MAX(unsigned long) BLARGG_DEF_MIN_MAX(float) BLARGG_DEF_MIN_MAX(double) -#undef min +#undef min #define min blargg_min -#undef max +#undef max #define max blargg_max // Joybus @@ -102,30 +110,30 @@ bool speedhack = true; #if (defined __WIN32__ || defined _WIN32) #include #else +#include +#include +#include #include #include -#include -#include -#include - -#define ReleaseSemaphore(sem, nrel, orel) do { \ - for(int i = 0; i < nrel; i++) \ - sem_post(sem); \ -} while(0) +#define ReleaseSemaphore(sem, nrel, orel) \ + do { \ + for (int i = 0; i < nrel; i++) \ + sem_post(sem); \ + } while (0) #define WAIT_TIMEOUT -1 #ifdef HAVE_SEM_TIMEDWAIT -int WaitForSingleObject(sem_t *s, int t) +int WaitForSingleObject(sem_t* s, int t) { - struct timespec ts; - clock_gettime(CLOCK_REALTIME, &ts); - ts.tv_sec += t/1000; - ts.tv_nsec += (t%1000) * 1000000; - do { - if(!sem_timedwait(s, &ts)) - return 0; - } while(errno == EINTR); - return WAIT_TIMEOUT; + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + ts.tv_sec += t / 1000; + ts.tv_nsec += (t % 1000) * 1000000; + do { + if (!sem_timedwait(s, &ts)) + return 0; + } while (errno == EINTR); + return WAIT_TIMEOUT; } // urg.. MacOSX has no sem_timedwait (POSIX) or semtimedop (SYSV) @@ -152,60 +160,59 @@ static void alrmhand(int sig) { } #endif -int WaitForSingleObject(sem_t *s, int t) +int WaitForSingleObject(sem_t* s, int t) { #if !TIMEDWAIT_ALRM - struct timeval ts; - gettimeofday(&ts, NULL); - ts.tv_sec += t/1000; - ts.tv_usec += (t%1000) * 1000; + struct timeval ts; + gettimeofday(&ts, NULL); + ts.tv_sec += t / 1000; + ts.tv_usec += (t % 1000) * 1000; #else - struct sigaction sa, osa; - sigaction(SIGALRM, NULL, &osa); - sa = osa; - sa.sa_flags &= ~SA_RESTART; - sa.sa_handler = alrmhand; - sigaction(SIGALRM, &sa, NULL); - struct itimerval tv, otv; - tv.it_value.tv_sec = t / 1000; - tv.it_value.tv_usec = (t%1000) * 1000; - // this should be 0/0, but in the wait loop, it's possible to - // have the signal fire while not in sem_wait(). This will ensure - // another signal within 1ms - tv.it_interval.tv_sec = 0; - tv.it_interval.tv_usec = 999; - setitimer(ITIMER_REAL, &tv, &otv); + struct sigaction sa, osa; + sigaction(SIGALRM, NULL, &osa); + sa = osa; + sa.sa_flags &= ~SA_RESTART; + sa.sa_handler = alrmhand; + sigaction(SIGALRM, &sa, NULL); + struct itimerval tv, otv; + tv.it_value.tv_sec = t / 1000; + tv.it_value.tv_usec = (t % 1000) * 1000; + // this should be 0/0, but in the wait loop, it's possible to + // have the signal fire while not in sem_wait(). This will ensure + // another signal within 1ms + tv.it_interval.tv_sec = 0; + tv.it_interval.tv_usec = 999; + setitimer(ITIMER_REAL, &tv, &otv); #endif - while(1) { + while (1) { #if !TIMEDWAIT_ALRM - if(!sem_trywait(s)) - return 0; - struct timeval ts2; - gettimeofday(&ts2, NULL); - if(ts2.tv_sec > ts.tv_sec || (ts2.tv_sec == ts.tv_sec && - ts2.tv_usec > ts.tv_usec)) { - return WAIT_TIMEOUT; - } - // is .1 ms short enough? long enough? who knows? - struct timespec ts3; - ts3.tv_sec = 0; - ts3.tv_nsec = 100000; - nanosleep(&ts3, NULL); + if (!sem_trywait(s)) + return 0; + struct timeval ts2; + gettimeofday(&ts2, NULL); + if (ts2.tv_sec > ts.tv_sec || (ts2.tv_sec == ts.tv_sec && ts2.tv_usec > ts.tv_usec)) { + return WAIT_TIMEOUT; + } + // is .1 ms short enough? long enough? who knows? + struct timespec ts3; + ts3.tv_sec = 0; + ts3.tv_nsec = 100000; + nanosleep(&ts3, NULL); #else - if(!sem_wait(s)) { - setitimer(ITIMER_REAL, &otv, NULL); - sigaction(SIGALRM, &osa, NULL); - return 0; - } - getitimer(ITIMER_REAL, &tv); - if(tv.it_value.tv_sec || tv.it_value.tv_usec > 999) - continue; - setitimer(ITIMER_REAL, &otv, NULL); - sigaction(SIGALRM, &osa, NULL); - break; + if (!sem_wait(s)) { + setitimer(ITIMER_REAL, &otv, NULL); + sigaction(SIGALRM, &osa, NULL); + return 0; + } + getitimer(ITIMER_REAL, &tv); + if (tv.it_value.tv_sec || tv.it_value.tv_usec > 999) + continue; + setitimer(ITIMER_REAL, &otv, NULL); + sigaction(SIGALRM, &osa, NULL); + break; #endif - } - return WAIT_TIMEOUT; + } + return WAIT_TIMEOUT; } #endif #endif @@ -221,7 +228,7 @@ int WaitForSingleObject(sem_t *s, int t) static int GetSIOMode(u16, u16); static ConnectionState InitSocket(); static void StartCableSocket(u16 siocnt); -static ConnectionState ConnectUpdateSocket(char * const message, size_t size); +static ConnectionState ConnectUpdateSocket(char* const message, size_t size); static void UpdateCableSocket(int ticks); static void CloseSocket(); @@ -238,7 +245,7 @@ static ConnectionState JoyBusConnect(); static void JoyBusUpdate(int ticks); static void JoyBusShutdown(); -static ConnectionState ConnectUpdateRFUSocket(char * const message, size_t size); +static ConnectionState ConnectUpdateRFUSocket(char* const message, size_t size); static void StartRFUSocket(u16 siocnt); bool LinkRFUUpdateSocket(); static void UpdateRFUSocket(int ticks); @@ -249,71 +256,71 @@ static void UpdateRFUSocket(int ticks); #define RFU_RECV 3 typedef struct { - u16 linkdata[5]; - u16 linkcmd[4]; - u16 numtransfers; - s32 lastlinktime; - u8 numgbas; //# of GBAs (max vbaid value plus 1), used in Single computer - u8 trgbas; - u8 linkflags; + u16 linkdata[5]; + u16 linkcmd[4]; + u16 numtransfers; + s32 lastlinktime; + u8 numgbas; //# of GBAs (max vbaid value plus 1), used in Single computer + u8 trgbas; + u8 linkflags; - u8 rfu_proto[5]; // 0=UDP-like, 1=TCP-like protocols to see whether the data important or not (may or may not be received successfully by the other side) - u16 rfu_qid[5]; - s32 rfu_q[5]; - u32 rfu_signal[5]; - u8 rfu_is_host[5]; //request to join - //u8 rfu_joined[5]; //bool //currenlty joined - u16 rfu_reqid[5]; //id to join - u16 rfu_clientidx[5]; //only used by clients - s32 rfu_linktime[5]; - u32 rfu_broadcastdata[5][7]; //for 0x16/0x1d/0x1e? - u32 rfu_gdata[5]; //for 0x17/0x19?/0x1e? - s32 rfu_state[5]; //0=none, 1=waiting for ACK - u8 rfu_listfront[5]; - u8 rfu_listback[5]; - rfu_datarec rfu_datalist[5][256]; + u8 rfu_proto[5]; // 0=UDP-like, 1=TCP-like protocols to see whether the data important or not (may or may not be received successfully by the other side) + u16 rfu_qid[5]; + s32 rfu_q[5]; + u32 rfu_signal[5]; + u8 rfu_is_host[5]; //request to join + //u8 rfu_joined[5]; //bool //currenlty joined + u16 rfu_reqid[5]; //id to join + u16 rfu_clientidx[5]; //only used by clients + s32 rfu_linktime[5]; + u32 rfu_broadcastdata[5][7]; //for 0x16/0x1d/0x1e? + u32 rfu_gdata[5]; //for 0x17/0x19?/0x1e? + s32 rfu_state[5]; //0=none, 1=waiting for ACK + u8 rfu_listfront[5]; + u8 rfu_listback[5]; + rfu_datarec rfu_datalist[5][256]; - /*u16 rfu_qidlist[5][256]; + /*u16 rfu_qidlist[5][256]; u16 rfu_qlist[5][256]; u32 rfu_datalist[5][256][255]; u32 rfu_timelist[5][256];*/ } LINKDATA; +class RFUServer { + int numbytes; + sf::SocketSelector fdset; + int counter; + int done; + u8 current_host; -class RFUServer{ - int numbytes; - sf::SocketSelector fdset; - int counter; - int done; - u8 current_host; public: - sf::TcpSocket tcpsocket[5]; - sf::IpAddress udpaddr[5]; - RFUServer(void); - sf::Packet& Serialize(sf::Packet& packet, int slave); - void DeSerialize(sf::Packet packet, int slave); - void Send(void); - void Recv(void); - + sf::TcpSocket tcpsocket[5]; + sf::IpAddress udpaddr[5]; + RFUServer(void); + sf::Packet& Serialize(sf::Packet& packet, int slave); + void DeSerialize(sf::Packet packet, int slave); + void Send(void); + void Recv(void); }; -class RFUClient{ - sf::SocketSelector fdset; - int numbytes; +class RFUClient { + sf::SocketSelector fdset; + int numbytes; + public: - sf::IpAddress serveraddr; - unsigned short serverport; - bool transferring; - RFUClient(void); - void Send(void); - void Recv(void); - sf::Packet& Serialize(sf::Packet& packet); - void DeSerialize(sf::Packet packet); - void CheckConn(void); + sf::IpAddress serveraddr; + unsigned short serverport; + bool transferring; + RFUClient(void); + void Send(void); + void Recv(void); + sf::Packet& Serialize(sf::Packet& packet); + void DeSerialize(sf::Packet packet); + void CheckConn(void); }; // RFU crap (except for numtransfers note...should probably check that out) -static LINKDATA *linkmem = NULL; +static LINKDATA* linkmem = NULL; static LINKDATA rfu_data; static u8 rfu_cmd, rfu_qsend, rfu_qrecv_broadcast_data_len; static int rfu_state, rfu_polarity, rfu_counter, rfu_masterq; @@ -368,22 +375,22 @@ static void CloseIPC(); #endif struct LinkDriver { - typedef ConnectionState (ConnectFunc)(); - typedef ConnectionState (ConnectUpdateFunc)(char * const message, size_t size); - typedef void (StartFunc)(u16 siocnt); - typedef void (UpdateFunc)(int ticks); - typedef void (CloseFunc)(); + typedef ConnectionState(ConnectFunc)(); + typedef ConnectionState(ConnectUpdateFunc)(char* const message, size_t size); + typedef void(StartFunc)(u16 siocnt); + typedef void(UpdateFunc)(int ticks); + typedef void(CloseFunc)(); - LinkMode mode; - ConnectFunc *connect; - ConnectUpdateFunc *connectUpdate; - StartFunc *start; - UpdateFunc *update; - CloseFunc *close; - bool uses_socket; + LinkMode mode; + ConnectFunc* connect; + ConnectUpdateFunc* connectUpdate; + StartFunc* start; + UpdateFunc* update; + CloseFunc* close; + bool uses_socket; }; -static const LinkDriver *linkDriver = NULL; +static const LinkDriver* linkDriver = NULL; static ConnectionState gba_connection_state = LINK_OK; static int linktime = 0; @@ -391,76 +398,76 @@ static int linktime = 0; static GBASockClient* dol = NULL; static sf::IpAddress joybusHostAddr = sf::IpAddress::LocalHost; -static const LinkDriver linkDrivers[] = -{ +static const LinkDriver linkDrivers[] = { #if (defined __WIN32__ || defined _WIN32) - { LINK_CABLE_IPC, InitIPC, NULL, StartCableIPC, UpdateCableIPC, CloseIPC, false }, - { LINK_RFU_IPC, InitIPC, NULL, StartRFU, UpdateRFUIPC, CloseIPC, false }, - { LINK_GAMEBOY_IPC, InitIPC, NULL, NULL, NULL, CloseIPC, false }, + { LINK_CABLE_IPC, InitIPC, NULL, StartCableIPC, UpdateCableIPC, CloseIPC, false }, + { LINK_RFU_IPC, InitIPC, NULL, StartRFU, UpdateRFUIPC, CloseIPC, false }, + { LINK_GAMEBOY_IPC, InitIPC, NULL, NULL, NULL, CloseIPC, false }, #endif - { LINK_CABLE_SOCKET, InitSocket, ConnectUpdateSocket, StartCableSocket, UpdateCableSocket, CloseSocket, true }, - { LINK_RFU_SOCKET, InitSocket, ConnectUpdateRFUSocket, StartRFUSocket, UpdateRFUSocket, CloseSocket, true }, - { LINK_GAMECUBE_DOLPHIN, JoyBusConnect, NULL, NULL, JoyBusUpdate, JoyBusShutdown, false }, - { LINK_GAMEBOY_SOCKET, InitSocket, ConnectUpdateSocket, NULL, NULL, CloseSocket, true }, + { LINK_CABLE_SOCKET, InitSocket, ConnectUpdateSocket, StartCableSocket, UpdateCableSocket, CloseSocket, true }, + { LINK_RFU_SOCKET, InitSocket, ConnectUpdateRFUSocket, StartRFUSocket, UpdateRFUSocket, CloseSocket, true }, + { LINK_GAMECUBE_DOLPHIN, JoyBusConnect, NULL, NULL, JoyBusUpdate, JoyBusShutdown, false }, + { LINK_GAMEBOY_SOCKET, InitSocket, ConnectUpdateSocket, NULL, NULL, CloseSocket, true }, }; -enum -{ - JOY_CMD_RESET = 0xff, - JOY_CMD_STATUS = 0x00, - JOY_CMD_READ = 0x14, - JOY_CMD_WRITE = 0x15 +enum { + JOY_CMD_RESET = 0xff, + JOY_CMD_STATUS = 0x00, + JOY_CMD_READ = 0x14, + JOY_CMD_WRITE = 0x15 }; typedef struct { - sf::TcpSocket tcpsocket; - sf::TcpListener tcplistener; - int numslaves; - int connectedSlaves; - int type; - bool server; - bool speed; //speedhack + sf::TcpSocket tcpsocket; + sf::TcpListener tcplistener; + int numslaves; + int connectedSlaves; + int type; + bool server; + bool speed; //speedhack } LANLINKDATA; -class CableServer{ - int numbytes; - sf::SocketSelector fdset; - //timeval udptimeout; - char inbuffer[256], outbuffer[256]; - s32 *intinbuffer; - u16 *u16inbuffer; - s32 *intoutbuffer; - u16 *u16outbuffer; - int counter; - int done; +class CableServer { + int numbytes; + sf::SocketSelector fdset; + //timeval udptimeout; + char inbuffer[256], outbuffer[256]; + s32* intinbuffer; + u16* u16inbuffer; + s32* intoutbuffer; + u16* u16outbuffer; + int counter; + int done; + public: - sf::TcpSocket tcpsocket[4]; - sf::IpAddress udpaddr[4]; - CableServer(void); - void Send(void); - void Recv(void); - void SendGB(void); - bool RecvGB(void); + sf::TcpSocket tcpsocket[4]; + sf::IpAddress udpaddr[4]; + CableServer(void); + void Send(void); + void Recv(void); + void SendGB(void); + bool RecvGB(void); }; -class CableClient{ - sf::SocketSelector fdset; - char inbuffer[256], outbuffer[256]; - s32 *intinbuffer; - u16 *u16inbuffer; - s32 *intoutbuffer; - u16 *u16outbuffer; - int numbytes; +class CableClient { + sf::SocketSelector fdset; + char inbuffer[256], outbuffer[256]; + s32* intinbuffer; + u16* u16inbuffer; + s32* intoutbuffer; + u16* u16outbuffer; + int numbytes; + public: - sf::IpAddress serveraddr; - unsigned short serverport; - bool transferring; - CableClient(void); - void Send(void); - void Recv(void); - void SendGB(void); - bool RecvGB(void); - void CheckConn(void); + sf::IpAddress serveraddr; + unsigned short serverport; + bool transferring; + CableClient(void); + void Send(void); + void Recv(void); + void SendGB(void); + bool RecvGB(void); + void CheckConn(void); }; static int i, j; @@ -474,11 +481,11 @@ static CableClient lc; // time to end of single GBA's transfer, in 16.78 MHz clock ticks // first index is GBA # static const int trtimedata[4][4] = { - // 9600 38400 57600 115200 - { 34080, 8520, 5680, 2840 }, - { 65536, 16384, 10923, 5461 }, - { 99609, 24903, 16602, 8301 }, - { 133692, 33423, 22282, 11141 } + // 9600 38400 57600 115200 + { 34080, 8520, 5680, 2840 }, + { 65536, 16384, 10923, 5461 }, + { 99609, 24903, 16602, 8301 }, + { 133692, 33423, 22282, 11141 } }; // time to end of transfer @@ -487,10 +494,10 @@ static const int trtimedata[4][4] = { // of start bit from next slave // first index is (# of slaves) - 1 static const int trtimeend[3][4] = { - // 9600 38400 57600 115200 - { 72527, 18132, 12088, 6044 }, - { 106608, 26652, 17768, 8884 }, - { 133692, 33423, 22282, 11141 } + // 9600 38400 57600 115200 + { 72527, 18132, 12088, 6044 }, + { 106608, 26652, 17768, 8884 }, + { 133692, 33423, 22282, 11141 } }; // Hodgepodge @@ -500,7 +507,7 @@ static int linkid = 0; #if (defined __WIN32__ || defined _WIN32) static HANDLE linksync[4]; #else -static sem_t *linksync[4]; +static sem_t* linksync[4]; #endif static int transfer_start_time_from_master = 0; #if (defined __WIN32__ || defined _WIN32) @@ -510,132 +517,138 @@ static int mmf = -1; #endif static char linkevent[] = #if !(defined __WIN32__ || defined _WIN32) - "/" + "/" #endif - "VBA link event "; + "VBA link event "; inline static int GetSIOMode(u16 siocnt, u16 rcnt) { - if (!(rcnt & 0x8000)) - { - switch (siocnt & 0x3000) { - case 0x0000: return NORMAL8; - case 0x1000: return NORMAL32; - case 0x2000: return MULTIPLAYER; - case 0x3000: return UART; - } - } + if (!(rcnt & 0x8000)) { + switch (siocnt & 0x3000) { + case 0x0000: + return NORMAL8; + case 0x1000: + return NORMAL32; + case 0x2000: + return MULTIPLAYER; + case 0x3000: + return UART; + } + } - if (rcnt & 0x4000) - return JOYBUS; + if (rcnt & 0x4000) + return JOYBUS; - return GP; + return GP; } -LinkMode GetLinkMode() { - if (linkDriver && gba_connection_state == LINK_OK) - return linkDriver->mode; - else - return LINK_DISCONNECTED; -} - -void GetLinkServerHost(char * const host, size_t size) { - if (host == NULL || size == 0) - return; - - host[0] = '\0'; - - if (linkDriver && linkDriver->mode == LINK_GAMECUBE_DOLPHIN) - strncpy(host, joybusHostAddr.toString().c_str(), size); - else if (lanlink.server) - strncpy(host, sf::IpAddress::getLocalAddress().toString().c_str(), size); - else - strncpy(host, lc.serveraddr.toString().c_str(), size); -} - -bool SetLinkServerHost(const char *host) { - sf::IpAddress addr = sf::IpAddress(host); - - lc.serveraddr = addr; - joybusHostAddr = addr; - - return addr != sf::IpAddress::None; -} - -int GetLinkPlayerId() { - if (GetLinkMode() == LINK_DISCONNECTED) { - return -1; - } else if (linkid > 0) { - return linkid; - } else { - return vbaid; - } -} - -void SetLinkTimeout(int value) { - linktimeout = value; -} - -void EnableLinkServer(bool enable, int numSlaves) { - lanlink.server = enable; - lanlink.numslaves = numSlaves; -} - -void EnableSpeedHacks(bool enable) { - lanlink.speed = enable; -} - -void BootLink(int m_type, const char *hostAddr, int timeout, bool m_hacks, int m_numplayers) +LinkMode GetLinkMode() { - if (linkDriver) { - // Connection has already been established - return; - } - - LinkMode mode = (LinkMode)m_type; - - if (mode == LINK_DISCONNECTED || mode == LINK_CABLE_SOCKET || mode == LINK_RFU_SOCKET || mode == LINK_GAMEBOY_SOCKET) { - return; - } - - // Close any previous link - CloseLink(); - - bool needsServerHost = (mode == LINK_GAMECUBE_DOLPHIN); - - if (needsServerHost) { - bool valid = SetLinkServerHost(hostAddr); - if (!valid) { - return; - } - } - - SetLinkTimeout(timeout); - EnableSpeedHacks(m_hacks); - - // Init link - ConnectionState state = InitLink(mode); - - if (!linkDriver->uses_socket) - { - // The user canceled the connection attempt - if (state == LINK_ABORT) { - CloseLink(); - return; - } - - // Something failed during init - if (state == LINK_ERROR) { - return; - } - } - else - { - CloseLink(); - return; - } + if (linkDriver && gba_connection_state == LINK_OK) + return linkDriver->mode; + else + return LINK_DISCONNECTED; } +void GetLinkServerHost(char* const host, size_t size) +{ + if (host == NULL || size == 0) + return; + + host[0] = '\0'; + + if (linkDriver && linkDriver->mode == LINK_GAMECUBE_DOLPHIN) + strncpy(host, joybusHostAddr.toString().c_str(), size); + else if (lanlink.server) + strncpy(host, sf::IpAddress::getLocalAddress().toString().c_str(), size); + else + strncpy(host, lc.serveraddr.toString().c_str(), size); +} + +bool SetLinkServerHost(const char* host) +{ + sf::IpAddress addr = sf::IpAddress(host); + + lc.serveraddr = addr; + joybusHostAddr = addr; + + return addr != sf::IpAddress::None; +} + +int GetLinkPlayerId() +{ + if (GetLinkMode() == LINK_DISCONNECTED) { + return -1; + } else if (linkid > 0) { + return linkid; + } else { + return vbaid; + } +} + +void SetLinkTimeout(int value) +{ + linktimeout = value; +} + +void EnableLinkServer(bool enable, int numSlaves) +{ + lanlink.server = enable; + lanlink.numslaves = numSlaves; +} + +void EnableSpeedHacks(bool enable) +{ + lanlink.speed = enable; +} + +void BootLink(int m_type, const char* hostAddr, int timeout, bool m_hacks, int m_numplayers) +{ + if (linkDriver) { + // Connection has already been established + return; + } + + LinkMode mode = (LinkMode)m_type; + + if (mode == LINK_DISCONNECTED || mode == LINK_CABLE_SOCKET || mode == LINK_RFU_SOCKET || mode == LINK_GAMEBOY_SOCKET) { + return; + } + + // Close any previous link + CloseLink(); + + bool needsServerHost = (mode == LINK_GAMECUBE_DOLPHIN); + + if (needsServerHost) { + bool valid = SetLinkServerHost(hostAddr); + if (!valid) { + return; + } + } + + SetLinkTimeout(timeout); + EnableSpeedHacks(m_hacks); + + // Init link + ConnectionState state = InitLink(mode); + + if (!linkDriver->uses_socket) { + // The user canceled the connection attempt + if (state == LINK_ABORT) { + CloseLink(); + return; + } + + // Something failed during init + if (state == LINK_ERROR) { + return; + } + } else { + CloseLink(); + return; + } +} ////////////////////////////////////////////////////////////////////////// // Probably from here down needs to be replaced with SFML goodness :) @@ -643,626 +656,628 @@ void BootLink(int m_type, const char *hostAddr, int timeout, bool m_hacks, int m ConnectionState InitLink(LinkMode mode) { - if (mode == LINK_DISCONNECTED) - return LINK_ABORT; + if (mode == LINK_DISCONNECTED) + return LINK_ABORT; - // Do nothing if we are already connected - if (GetLinkMode() != LINK_DISCONNECTED) { - systemMessage(0, N_("Error, link already connected")); - return LINK_ERROR; - } + // Do nothing if we are already connected + if (GetLinkMode() != LINK_DISCONNECTED) { + systemMessage(0, N_("Error, link already connected")); + return LINK_ERROR; + } - // Find the link driver - linkDriver = NULL; - for (u8 i = 0; i < sizeof(linkDrivers) / sizeof(linkDrivers[0]); i++) { - if (linkDrivers[i].mode == mode) { - linkDriver = &linkDrivers[i]; - break; - } - } + // Find the link driver + linkDriver = NULL; + for (u8 i = 0; i < sizeof(linkDrivers) / sizeof(linkDrivers[0]); i++) { + if (linkDrivers[i].mode == mode) { + linkDriver = &linkDrivers[i]; + break; + } + } - if (!linkDriver || !linkDriver->connect) { - systemMessage(0, N_("Unable to find link driver")); - return LINK_ERROR; - } + if (!linkDriver || !linkDriver->connect) { + systemMessage(0, N_("Unable to find link driver")); + return LINK_ERROR; + } - // Connect the link - gba_connection_state = linkDriver->connect(); + // Connect the link + gba_connection_state = linkDriver->connect(); - if (gba_connection_state == LINK_ERROR) { - CloseLink(); - } - - return gba_connection_state; + if (gba_connection_state == LINK_ERROR) { + CloseLink(); + } + + return gba_connection_state; } void StartLink(u16 siocnt) { - if (!linkDriver || !linkDriver->start) { - return; - } + if (!linkDriver || !linkDriver->start) { + return; + } - linkDriver->start(siocnt); + linkDriver->start(siocnt); } -ConnectionState ConnectLinkUpdate(char * const message, size_t size) +ConnectionState ConnectLinkUpdate(char* const message, size_t size) { - message[0] = '\0'; + message[0] = '\0'; - if (!linkDriver || !linkDriver->connectUpdate || gba_connection_state != LINK_NEEDS_UPDATE) { - gba_connection_state = LINK_ERROR; - snprintf(message, size, N_("Link connection does not need updates.")); + if (!linkDriver || !linkDriver->connectUpdate || gba_connection_state != LINK_NEEDS_UPDATE) { + gba_connection_state = LINK_ERROR; + snprintf(message, size, N_("Link connection does not need updates.")); - return LINK_ERROR; - } + return LINK_ERROR; + } - gba_connection_state = linkDriver->connectUpdate(message, size); + gba_connection_state = linkDriver->connectUpdate(message, size); - return gba_connection_state; + return gba_connection_state; } void StartGPLink(u16 value) { - UPDATE_REG(COMM_RCNT, value); + UPDATE_REG(COMM_RCNT, value); - if (!value) - return; + if (!value) + return; - switch (GetSIOMode(READ16LE(&ioMem[COMM_SIOCNT]), value)) { - case MULTIPLAYER: - value &= 0xc0f0; - value |= 3; - if (linkid) - value |= 4; - UPDATE_REG(COMM_SIOCNT, ((READ16LE(&ioMem[COMM_SIOCNT])&0xff8b)|(linkid ? 0xc : 8)|(linkid<<4))); - break; + switch (GetSIOMode(READ16LE(&ioMem[COMM_SIOCNT]), value)) { + case MULTIPLAYER: + value &= 0xc0f0; + value |= 3; + if (linkid) + value |= 4; + UPDATE_REG(COMM_SIOCNT, ((READ16LE(&ioMem[COMM_SIOCNT]) & 0xff8b) | (linkid ? 0xc : 8) | (linkid << 4))); + break; - case GP: + case GP: #if (defined __WIN32__ || defined _WIN32) - if (GetLinkMode() == LINK_RFU_IPC) - rfu_state = RFU_INIT; + if (GetLinkMode() == LINK_RFU_IPC) + rfu_state = RFU_INIT; #endif - break; - } + break; + } } void LinkUpdate(int ticks) { - if (!linkDriver || !linkDriver->update) { - return; - } + if (!linkDriver || !linkDriver->update) { + return; + } - // this actually gets called every single instruction, so keep default - // path as short as possible + // this actually gets called every single instruction, so keep default + // path as short as possible - linktime += ticks; + linktime += ticks; - linkDriver->update(ticks); + linkDriver->update(ticks); } -void CheckLinkConnection() { - if (GetLinkMode() == LINK_CABLE_SOCKET) { - if (linkid && !lc.transferring) { - lc.CheckConn(); - } - } +void CheckLinkConnection() +{ + if (GetLinkMode() == LINK_CABLE_SOCKET) { + if (linkid && !lc.transferring) { + lc.CheckConn(); + } + } } -void CloseLink(void) { - if (!linkDriver || !linkDriver->close) { - return; // Nothing to do - } +void CloseLink(void) +{ + if (!linkDriver || !linkDriver->close) { + return; // Nothing to do + } - linkDriver->close(); - linkDriver = NULL; + linkDriver->close(); + linkDriver = NULL; - return; + return; } // Server -CableServer::CableServer(void) { - intinbuffer = (s32*)inbuffer; - u16inbuffer = (u16*)inbuffer; - intoutbuffer = (s32*)outbuffer; - u16outbuffer = (u16*)outbuffer; +CableServer::CableServer(void) +{ + intinbuffer = (s32*)inbuffer; + u16inbuffer = (u16*)inbuffer; + intoutbuffer = (s32*)outbuffer; + u16outbuffer = (u16*)outbuffer; } -void CableServer::Send(void) { - if(lanlink.type==0) { // TCP - outbuffer[1] = tspeed; - WRITE16LE(&u16outbuffer[1], cable_data[0]); - WRITE32LE(&intoutbuffer[1], transfer_start_time_from_master); +void CableServer::Send(void) +{ + if (lanlink.type == 0) { // TCP + outbuffer[1] = tspeed; + WRITE16LE(&u16outbuffer[1], cable_data[0]); + WRITE32LE(&intoutbuffer[1], transfer_start_time_from_master); - if(lanlink.numslaves==1) { - if(lanlink.type==0) { - outbuffer[0] = 8; - tcpsocket[1].send(outbuffer, 8); - } - } - else if(lanlink.numslaves==2) { - WRITE16LE(&u16outbuffer[4], cable_data[2]); - if(lanlink.type==0) { - outbuffer[0] = 10; - tcpsocket[1].send(outbuffer, 10); - WRITE16LE(&u16outbuffer[4], cable_data[1]); - tcpsocket[2].send(outbuffer, 10); - } - } else { - if(lanlink.type==0) { - outbuffer[0] = 12; - WRITE16LE(&u16outbuffer[4], cable_data[2]); - WRITE16LE(&u16outbuffer[5], cable_data[3]); - tcpsocket[1].send(outbuffer, 12); - WRITE16LE(&u16outbuffer[4], cable_data[1]); - tcpsocket[2].send(outbuffer, 12); - WRITE16LE(&u16outbuffer[5], cable_data[2]); - tcpsocket[3].send(outbuffer, 12); - } - } - } - return; + if (lanlink.numslaves == 1) { + if (lanlink.type == 0) { + outbuffer[0] = 8; + tcpsocket[1].send(outbuffer, 8); + } + } else if (lanlink.numslaves == 2) { + WRITE16LE(&u16outbuffer[4], cable_data[2]); + if (lanlink.type == 0) { + outbuffer[0] = 10; + tcpsocket[1].send(outbuffer, 10); + WRITE16LE(&u16outbuffer[4], cable_data[1]); + tcpsocket[2].send(outbuffer, 10); + } + } else { + if (lanlink.type == 0) { + outbuffer[0] = 12; + WRITE16LE(&u16outbuffer[4], cable_data[2]); + WRITE16LE(&u16outbuffer[5], cable_data[3]); + tcpsocket[1].send(outbuffer, 12); + WRITE16LE(&u16outbuffer[4], cable_data[1]); + tcpsocket[2].send(outbuffer, 12); + WRITE16LE(&u16outbuffer[5], cable_data[2]); + tcpsocket[3].send(outbuffer, 12); + } + } + } + return; } // Receive data from all slaves to master -void CableServer::Recv(void) { - int numbytes; - if(lanlink.type==0) { // TCP - fdset.clear(); +void CableServer::Recv(void) +{ + int numbytes; + if (lanlink.type == 0) { // TCP + fdset.clear(); - for(i=0;i 0) - cable_gb_data[i + 1] = recv_byte; - } - } + if (inbuffer[1] == -32) { + char message[30]; + sprintf(message, _("Player %d disconnected."), i + 2); + systemScreenMessage(message); + for (i = 1; i < lanlink.numslaves; i++) { + tcpsocket[i].disconnect(); + } + CloseLink(); + return false; + } + if (numbytes > 0) + cable_gb_data[i + 1] = recv_byte; + } + } - return numbytes != 0; + return numbytes != 0; } // Client -CableClient::CableClient(void) { - intinbuffer = (s32*)inbuffer; - u16inbuffer = (u16*)inbuffer; - intoutbuffer = (s32*)outbuffer; - u16outbuffer = (u16*)outbuffer; - transferring = false; - return; +CableClient::CableClient(void) +{ + intinbuffer = (s32*)inbuffer; + u16inbuffer = (u16*)inbuffer; + intoutbuffer = (s32*)outbuffer; + u16outbuffer = (u16*)outbuffer; + transferring = false; + return; } -void CableClient::CheckConn(void) { - size_t nr; - lanlink.tcpsocket.receive(inbuffer, 1, nr); - numbytes = nr; - if(numbytes>0) { - while(numbytes 0) { + while (numbytes < inbuffer[0]) { + lanlink.tcpsocket.receive(inbuffer + numbytes, inbuffer[0] - numbytes, nr); + numbytes += nr; + } + if (inbuffer[1] == -32) { + outbuffer[0] = 4; + lanlink.tcpsocket.send(outbuffer, 4); + systemScreenMessage(_("Server disconnected.")); + CloseLink(); + return; + } + transferring = true; + transfer_start_time_from_master = 0; + cable_data[0] = READ16LE(&u16inbuffer[1]); + tspeed = inbuffer[1] & 3; + for (i = 1, numbytes = 4; i <= lanlink.numslaves; i++) + if (i != linkid) { + cable_data[i] = READ16LE(&u16inbuffer[numbytes]); + numbytes++; + } + } + return; } -bool CableClient::RecvGB(void) { - if (!transferring) - return false; +bool CableClient::RecvGB(void) +{ + if (!transferring) + return false; - fdset.clear(); - // old code used socket # instead of mask again - fdset.add(lanlink.tcpsocket); - // old code stripped off ms again - if (fdset.wait(sf::milliseconds(1)) == 0) - { - return false; - } - numbytes = 0; - size_t nr; - u8 recv_byte = 0; + fdset.clear(); + // old code used socket # instead of mask again + fdset.add(lanlink.tcpsocket); + // old code stripped off ms again + if (fdset.wait(sf::milliseconds(1)) == 0) { + return false; + } + numbytes = 0; + size_t nr; + u8 recv_byte = 0; - lanlink.tcpsocket.receive(&recv_byte, 1, nr); - numbytes += nr; + lanlink.tcpsocket.receive(&recv_byte, 1, nr); + numbytes += nr; - if (numbytes != 0) - transferring = false; + if (numbytes != 0) + transferring = false; - if(inbuffer[1]==-32) { - systemScreenMessage(_("Server disconnected.")); - CloseLink(); - return false; - } - if (numbytes > 0) - cable_gb_data[0] = recv_byte; + if (inbuffer[1] == -32) { + systemScreenMessage(_("Server disconnected.")); + CloseLink(); + return false; + } + if (numbytes > 0) + cable_gb_data[0] = recv_byte; - return numbytes != 0; + return numbytes != 0; } -void CableClient::SendGB() { - if (transferring) - return; +void CableClient::SendGB() +{ + if (transferring) + return; - lanlink.tcpsocket.send(&cable_gb_data[1], 1); + lanlink.tcpsocket.send(&cable_gb_data[1], 1); - transferring = true; + transferring = true; } - -void CableClient::Recv(void) { - fdset.clear(); - // old code used socket # instead of mask again - fdset.add(lanlink.tcpsocket); - // old code stripped off ms again - if (fdset.wait(sf::milliseconds(50)) == 0) - { - transferring = false; - return; - } - numbytes = 0; - inbuffer[0] = 1; - size_t nr; - while (numbytesShowServerIP(sf::IpAddress::getLocalAddress()); + if (lanlink.server) { + lanlink.connectedSlaves = 0; + // should probably use GetPublicAddress() + //sid->ShowServerIP(sf::IpAddress::getLocalAddress()); - // too bad Listen() doesn't take an address as well - // then again, old code used INADDR_ANY anyway - if (lanlink.tcplistener.listen(IP_LINK_PORT) == sf::Socket::Error) - // Note: old code closed socket & retried once on bind failure - return LINK_ERROR; // FIXME: error code? - else - return LINK_NEEDS_UPDATE; - } else { - lc.serverport = IP_LINK_PORT; + // too bad Listen() doesn't take an address as well + // then again, old code used INADDR_ANY anyway + if (lanlink.tcplistener.listen(IP_LINK_PORT) == sf::Socket::Error) + // Note: old code closed socket & retried once on bind failure + return LINK_ERROR; // FIXME: error code? + else + return LINK_NEEDS_UPDATE; + } else { + lc.serverport = IP_LINK_PORT; - if (lc.serveraddr == sf::IpAddress::None) { - return LINK_ERROR; - } else { - lanlink.tcpsocket.setBlocking(false); - sf::Socket::Status status = lanlink.tcpsocket.connect(lc.serveraddr, lc.serverport); + if (lc.serveraddr == sf::IpAddress::None) { + return LINK_ERROR; + } else { + lanlink.tcpsocket.setBlocking(false); + sf::Socket::Status status = lanlink.tcpsocket.connect(lc.serveraddr, lc.serverport); - if (status == sf::Socket::Error || status == sf::Socket::Disconnected) - return LINK_ERROR; - else - return LINK_NEEDS_UPDATE; - } - } + if (status == sf::Socket::Error || status == sf::Socket::Disconnected) + return LINK_ERROR; + else + return LINK_NEEDS_UPDATE; + } + } } -static ConnectionState ConnectUpdateSocket(char * const message, size_t size) { - ConnectionState newState = LINK_NEEDS_UPDATE; +static ConnectionState ConnectUpdateSocket(char* const message, size_t size) +{ + ConnectionState newState = LINK_NEEDS_UPDATE; - if (lanlink.server) { - sf::SocketSelector fdset; - fdset.add(lanlink.tcplistener); + if (lanlink.server) { + sf::SocketSelector fdset; + fdset.add(lanlink.tcplistener); - if (fdset.wait(sf::milliseconds(150))) { - int nextSlave = lanlink.connectedSlaves + 1; + if (fdset.wait(sf::milliseconds(150))) { + int nextSlave = lanlink.connectedSlaves + 1; - sf::Socket::Status st = lanlink.tcplistener.accept(ls.tcpsocket[nextSlave]); + sf::Socket::Status st = lanlink.tcplistener.accept(ls.tcpsocket[nextSlave]); - if (st == sf::Socket::Error) { - for (int j = 1; j < nextSlave; j++) - ls.tcpsocket[j].disconnect(); + if (st == sf::Socket::Error) { + for (int j = 1; j < nextSlave; j++) + ls.tcpsocket[j].disconnect(); - snprintf(message, size, N_("Network error.")); - newState = LINK_ERROR; - } else { - sf::Packet packet; - packet << static_cast(nextSlave) - << static_cast(lanlink.numslaves); + snprintf(message, size, N_("Network error.")); + newState = LINK_ERROR; + } else { + sf::Packet packet; + packet << static_cast(nextSlave) + << static_cast(lanlink.numslaves); - ls.tcpsocket[nextSlave].send(packet); + ls.tcpsocket[nextSlave].send(packet); - snprintf(message, size, N_("Player %d connected"), nextSlave); + snprintf(message, size, N_("Player %d connected"), nextSlave); - lanlink.connectedSlaves++; - } - } + lanlink.connectedSlaves++; + } + } - if (lanlink.numslaves == lanlink.connectedSlaves) { - for (int i = 1; i <= lanlink.numslaves; i++) { - sf::Packet packet; - packet << true; + if (lanlink.numslaves == lanlink.connectedSlaves) { + for (int i = 1; i <= lanlink.numslaves; i++) { + sf::Packet packet; + packet << true; - ls.tcpsocket[i].send(packet); - } + ls.tcpsocket[i].send(packet); + } - snprintf(message, size, N_("All players connected")); - newState = LINK_OK; - } - } else { + snprintf(message, size, N_("All players connected")); + newState = LINK_OK; + } + } else { - sf::Packet packet; - sf::Socket::Status status = lanlink.tcpsocket.receive(packet); + sf::Packet packet; + sf::Socket::Status status = lanlink.tcpsocket.receive(packet); - if (status == sf::Socket::Error || status == sf::Socket::Disconnected) { - snprintf(message, size, N_("Network error.")); - newState = LINK_ERROR; - } else if (status == sf::Socket::Done) { + if (status == sf::Socket::Error || status == sf::Socket::Disconnected) { + snprintf(message, size, N_("Network error.")); + newState = LINK_ERROR; + } else if (status == sf::Socket::Done) { - if (linkid == 0) { - sf::Uint16 receivedId, receivedSlaves; - packet >> receivedId >> receivedSlaves; + if (linkid == 0) { + sf::Uint16 receivedId, receivedSlaves; + packet >> receivedId >> receivedSlaves; - if (packet) { - linkid = receivedId; - lanlink.numslaves = receivedSlaves; + if (packet) { + linkid = receivedId; + lanlink.numslaves = receivedSlaves; - snprintf(message, size, N_("Connected as #%d, Waiting for %d players to join"), - linkid + 1, lanlink.numslaves - linkid); - } - } else { - bool gameReady; - packet >> gameReady; + snprintf(message, size, N_("Connected as #%d, Waiting for %d players to join"), + linkid + 1, lanlink.numslaves - linkid); + } + } else { + bool gameReady; + packet >> gameReady; - if (packet && gameReady) { - newState = LINK_OK; - snprintf(message, size, N_("All players joined.")); - } - } + if (packet && gameReady) { + newState = LINK_OK; + snprintf(message, size, N_("All players joined.")); + } + } - sf::SocketSelector fdset; - fdset.add(lanlink.tcpsocket); - fdset.wait(sf::milliseconds(150)); - } - } + sf::SocketSelector fdset; + fdset.add(lanlink.tcpsocket); + fdset.wait(sf::milliseconds(150)); + } + } - return newState; + return newState; } void StartCableSocket(u16 value) { - switch (GetSIOMode(value, READ16LE(&ioMem[COMM_RCNT]))) { - case MULTIPLAYER: { - bool start = (value & 0x80) && !linkid && !transfer_direction; - // clear start, seqno, si (RO on slave, start = pulse on master) - value &= 0xff4b; - // get current si. This way, on slaves, it is low during xfer - if(linkid) { - if(!transfer_direction) - value |= 4; - else - value |= READ16LE(&ioMem[COMM_SIOCNT]) & 4; - } - if (start) { - cable_data[0] = READ16LE(&ioMem[COMM_SIODATA8]); - transfer_start_time_from_master = linktime; - tspeed = value & 3; - ls.Send(); - transfer_direction = RECEIVING; - linktime = 0; - UPDATE_REG(COMM_SIOMULTI0, cable_data[0]); - UPDATE_REG(COMM_SIOMULTI1, 0xffff); - WRITE32LE(&ioMem[COMM_SIOMULTI2], 0xffffffff); - value &= ~0x40; - } - value |= (transfer_direction ? 1 : 0) << 7; - value |= (linkid && !transfer_direction) ? 0x0c : 0x08; // set SD (high), SI (low on master) - value |= linkid << 4; // set seq - UPDATE_REG(COMM_SIOCNT, value); - if (linkid) - // SC low -> transfer in progress - // not sure why SO is low - UPDATE_REG(COMM_RCNT, transfer_direction ? 6 : 7); - else - // SI is always low on master - // SO, SC always low during transfer - // not sure why SO low otherwise - UPDATE_REG(COMM_RCNT, transfer_direction ? 2 : 3); - break; - } - case NORMAL8: - case NORMAL32: - case UART: - default: - UPDATE_REG(COMM_SIOCNT, value); - break; - } + switch (GetSIOMode(value, READ16LE(&ioMem[COMM_RCNT]))) { + case MULTIPLAYER: { + bool start = (value & 0x80) && !linkid && !transfer_direction; + // clear start, seqno, si (RO on slave, start = pulse on master) + value &= 0xff4b; + // get current si. This way, on slaves, it is low during xfer + if (linkid) { + if (!transfer_direction) + value |= 4; + else + value |= READ16LE(&ioMem[COMM_SIOCNT]) & 4; + } + if (start) { + cable_data[0] = READ16LE(&ioMem[COMM_SIODATA8]); + transfer_start_time_from_master = linktime; + tspeed = value & 3; + ls.Send(); + transfer_direction = RECEIVING; + linktime = 0; + UPDATE_REG(COMM_SIOMULTI0, cable_data[0]); + UPDATE_REG(COMM_SIOMULTI1, 0xffff); + WRITE32LE(&ioMem[COMM_SIOMULTI2], 0xffffffff); + value &= ~0x40; + } + value |= (transfer_direction ? 1 : 0) << 7; + value |= (linkid && !transfer_direction) ? 0x0c : 0x08; // set SD (high), SI (low on master) + value |= linkid << 4; // set seq + UPDATE_REG(COMM_SIOCNT, value); + if (linkid) + // SC low -> transfer in progress + // not sure why SO is low + UPDATE_REG(COMM_RCNT, transfer_direction ? 6 : 7); + else + // SI is always low on master + // SO, SC always low during transfer + // not sure why SO low otherwise + UPDATE_REG(COMM_RCNT, transfer_direction ? 2 : 3); + break; + } + case NORMAL8: + case NORMAL32: + case UART: + default: + UPDATE_REG(COMM_SIOCNT, value); + break; + } } static void UpdateCableSocket(int ticks) { - if (linkid && transfer_direction == SENDING && lc.transferring && linktime >= transfer_start_time_from_master) - { - cable_data[linkid] = READ16LE(&ioMem[COMM_SIODATA8]); + if (linkid && transfer_direction == SENDING && lc.transferring && linktime >= transfer_start_time_from_master) { + cable_data[linkid] = READ16LE(&ioMem[COMM_SIODATA8]); - lc.Send(); - UPDATE_REG(COMM_SIODATA32_L, cable_data[0]); - UPDATE_REG(COMM_SIOCNT, READ16LE(&ioMem[COMM_SIOCNT]) | 0x80); - transfer_direction = RECEIVING; - linktime = 0; - } + lc.Send(); + UPDATE_REG(COMM_SIODATA32_L, cable_data[0]); + UPDATE_REG(COMM_SIOCNT, READ16LE(&ioMem[COMM_SIOCNT]) | 0x80); + transfer_direction = RECEIVING; + linktime = 0; + } - if (transfer_direction == RECEIVING && linktime >= trtimeend[lanlink.numslaves-1][tspeed]) - { - if (READ16LE(&ioMem[COMM_SIOCNT]) & 0x4000) - { - IF |= 0x80; - UPDATE_REG(0x202, IF); - } + if (transfer_direction == RECEIVING && linktime >= trtimeend[lanlink.numslaves - 1][tspeed]) { + if (READ16LE(&ioMem[COMM_SIOCNT]) & 0x4000) { + IF |= 0x80; + UPDATE_REG(0x202, IF); + } - UPDATE_REG(COMM_SIOCNT, (READ16LE(&ioMem[COMM_SIOCNT]) & 0xff0f) | (linkid << 4)); - transfer_direction = SENDING; - linktime -= trtimeend[lanlink.numslaves-1][tspeed]; + UPDATE_REG(COMM_SIOCNT, (READ16LE(&ioMem[COMM_SIOCNT]) & 0xff0f) | (linkid << 4)); + transfer_direction = SENDING; + linktime -= trtimeend[lanlink.numslaves - 1][tspeed]; - if (linkid) - { - lc.transferring = true; - lc.Recv(); - } - else - { - ls.Recv(); // Receive data from all of the slaves - } - UPDATE_REG(COMM_SIOMULTI1, cable_data[1]); - UPDATE_REG(COMM_SIOMULTI2, cable_data[2]); - UPDATE_REG(COMM_SIOMULTI3, cable_data[3]); - } + if (linkid) { + lc.transferring = true; + lc.Recv(); + } else { + ls.Recv(); // Receive data from all of the slaves + } + UPDATE_REG(COMM_SIOMULTI1, cable_data[1]); + UPDATE_REG(COMM_SIOMULTI2, cable_data[2]); + UPDATE_REG(COMM_SIOMULTI3, cable_data[3]); + } } - -static void CloseSocket() { - if(linkid) { - char outbuffer[4]; - outbuffer[0] = 4; - outbuffer[1] = -32; - if(lanlink.type==0) lanlink.tcpsocket.send(outbuffer, 4); - } else { - char outbuffer[12]; - int i; - outbuffer[0] = 12; - outbuffer[1] = -32; - for(i=1;i<=lanlink.numslaves;i++) { - if(lanlink.type==0) { - ls.tcpsocket[i].send(outbuffer, 12); - } - ls.tcpsocket[i].disconnect(); - } - } - lanlink.tcpsocket.disconnect(); +static void CloseSocket() +{ + if (linkid) { + char outbuffer[4]; + outbuffer[0] = 4; + outbuffer[1] = -32; + if (lanlink.type == 0) + lanlink.tcpsocket.send(outbuffer, 4); + } else { + char outbuffer[12]; + int i; + outbuffer[0] = 12; + outbuffer[1] = -32; + for (i = 1; i <= lanlink.numslaves; i++) { + if (lanlink.type == 0) { + ls.tcpsocket[i].send(outbuffer, 12); + } + ls.tcpsocket[i].disconnect(); + } + } + lanlink.tcpsocket.disconnect(); } // call this to clean up crashed program's shared state @@ -1271,2083 +1286,1988 @@ static void CloseSocket() { void CleanLocalLink() { #if !(defined __WIN32__ || defined _WIN32) - shm_unlink("/" LOCAL_LINK_NAME); - for(int i = 0; i < 4; i++) { - linkevent[sizeof(linkevent) - 2] = '1' + i; - sem_unlink(linkevent); - } + shm_unlink("/" LOCAL_LINK_NAME); + for (int i = 0; i < 4; i++) { + linkevent[sizeof(linkevent) - 2] = '1' + i; + sem_unlink(linkevent); + } #endif } static ConnectionState JoyBusConnect() { - delete dol; - dol = NULL; + delete dol; + dol = NULL; - dol = new GBASockClient(joybusHostAddr); - if (dol) { - return LINK_OK; - } - else { - return LINK_ERROR; - } + dol = new GBASockClient(joybusHostAddr); + if (dol) { + return LINK_OK; + } else { + return LINK_ERROR; + } } static void JoyBusUpdate(int ticks) { - lastjoybusupdate += ticks; - lastcommand += ticks; + lastjoybusupdate += ticks; + lastcommand += ticks; - bool joybus_activated = ((READ16LE(&ioMem[COMM_RCNT])) >> 14) == 3; - gba_joybus_active = dol && gba_joybus_enabled && joybus_activated; + bool joybus_activated = ((READ16LE(&ioMem[COMM_RCNT])) >> 14) == 3; + gba_joybus_active = dol && gba_joybus_enabled && joybus_activated; - if ((lastjoybusupdate > nextjoybusupdate)) - { - if (!joybus_activated) - { - if (dol && booted) - { - JoyBusShutdown(); - } + if ((lastjoybusupdate > nextjoybusupdate)) { + if (!joybus_activated) { + if (dol && booted) { + JoyBusShutdown(); + } - lastjoybusupdate = 0; - nextjoybusupdate = 0; - lastcommand = 0; - return; - } + lastjoybusupdate = 0; + nextjoybusupdate = 0; + lastcommand = 0; + return; + } - if (!dol) - { - booted = false; - JoyBusConnect(); - } + if (!dol) { + booted = false; + JoyBusConnect(); + } - dol->ReceiveClock(false); + dol->ReceiveClock(false); - if (dol->IsDisconnected()) - { - JoyBusShutdown(); - nextjoybusupdate = TICKS_PER_SECOND * 2; // try to connect after 2 seconds - lastjoybusupdate = 0; - lastcommand = 0; - return; - } + if (dol->IsDisconnected()) { + JoyBusShutdown(); + nextjoybusupdate = TICKS_PER_SECOND * 2; // try to connect after 2 seconds + lastjoybusupdate = 0; + lastcommand = 0; + return; + } - dol->ClockSync(lastjoybusupdate); + dol->ClockSync(lastjoybusupdate); - char data[5] = { 0x10, 0, 0, 0, 0 }; // init with invalid cmd - std::vector resp; - u8 cmd = 0x10; + char data[5] = { 0x10, 0, 0, 0, 0 }; // init with invalid cmd + std::vector resp; + u8 cmd = 0x10; - if (lastcommand > (TICKS_PER_FRAME * 4)) - { - cmd = dol->ReceiveCmd(data, true); - } - else - { - cmd = dol->ReceiveCmd(data, false); - } + if (lastcommand > (TICKS_PER_FRAME * 4)) { + cmd = dol->ReceiveCmd(data, true); + } else { + cmd = dol->ReceiveCmd(data, false); + } - switch (cmd) { - case JOY_CMD_RESET: - UPDATE_REG(COMM_JOYCNT, READ16LE(&ioMem[COMM_JOYCNT]) | JOYCNT_RESET); - resp.push_back(0x00); // GBA device ID - resp.push_back(0x04); - nextjoybusupdate = TICKS_PER_SECOND / BYTES_PER_SECOND; - break; + switch (cmd) { + case JOY_CMD_RESET: + UPDATE_REG(COMM_JOYCNT, READ16LE(&ioMem[COMM_JOYCNT]) | JOYCNT_RESET); + resp.push_back(0x00); // GBA device ID + resp.push_back(0x04); + nextjoybusupdate = TICKS_PER_SECOND / BYTES_PER_SECOND; + break; - case JOY_CMD_STATUS: - resp.push_back(0x00); // GBA device ID - resp.push_back(0x04); + case JOY_CMD_STATUS: + resp.push_back(0x00); // GBA device ID + resp.push_back(0x04); - nextjoybusupdate = TICKS_PER_SECOND / BYTES_PER_SECOND; - break; + nextjoybusupdate = TICKS_PER_SECOND / BYTES_PER_SECOND; + break; - case JOY_CMD_READ: - resp.push_back((u8)(READ16LE(&ioMem[COMM_JOY_TRANS_L]) & 0xff)); - resp.push_back((u8)(READ16LE(&ioMem[COMM_JOY_TRANS_L]) >> 8)); - resp.push_back((u8)(READ16LE(&ioMem[COMM_JOY_TRANS_H]) & 0xff)); - resp.push_back((u8)(READ16LE(&ioMem[COMM_JOY_TRANS_H]) >> 8)); + case JOY_CMD_READ: + resp.push_back((u8)(READ16LE(&ioMem[COMM_JOY_TRANS_L]) & 0xff)); + resp.push_back((u8)(READ16LE(&ioMem[COMM_JOY_TRANS_L]) >> 8)); + resp.push_back((u8)(READ16LE(&ioMem[COMM_JOY_TRANS_H]) & 0xff)); + resp.push_back((u8)(READ16LE(&ioMem[COMM_JOY_TRANS_H]) >> 8)); - UPDATE_REG(COMM_JOYCNT, READ16LE(&ioMem[COMM_JOYCNT]) | JOYCNT_SEND_COMPLETE); - nextjoybusupdate = TICKS_PER_SECOND / BYTES_PER_SECOND; - booted = true; - break; + UPDATE_REG(COMM_JOYCNT, READ16LE(&ioMem[COMM_JOYCNT]) | JOYCNT_SEND_COMPLETE); + nextjoybusupdate = TICKS_PER_SECOND / BYTES_PER_SECOND; + booted = true; + break; - case JOY_CMD_WRITE: - UPDATE_REG(COMM_JOY_RECV_L, (u16)((u16)data[2] << 8) | (u8)data[1]); - UPDATE_REG(COMM_JOY_RECV_H, (u16)((u16)data[4] << 8) | (u8)data[3]); - UPDATE_REG(COMM_JOYSTAT, READ16LE(&ioMem[COMM_JOYSTAT]) | JOYSTAT_RECV); - UPDATE_REG(COMM_JOYCNT, READ16LE(&ioMem[COMM_JOYCNT]) | JOYCNT_RECV_COMPLETE); - nextjoybusupdate = TICKS_PER_SECOND / BYTES_PER_SECOND; - booted = true; - break; + case JOY_CMD_WRITE: + UPDATE_REG(COMM_JOY_RECV_L, (u16)((u16)data[2] << 8) | (u8)data[1]); + UPDATE_REG(COMM_JOY_RECV_H, (u16)((u16)data[4] << 8) | (u8)data[3]); + UPDATE_REG(COMM_JOYSTAT, READ16LE(&ioMem[COMM_JOYSTAT]) | JOYSTAT_RECV); + UPDATE_REG(COMM_JOYCNT, READ16LE(&ioMem[COMM_JOYCNT]) | JOYCNT_RECV_COMPLETE); + nextjoybusupdate = TICKS_PER_SECOND / BYTES_PER_SECOND; + booted = true; + break; - default: - nextjoybusupdate = TICKS_PER_SECOND / 40000; - lastjoybusupdate = 0; - return; // ignore - } + default: + nextjoybusupdate = TICKS_PER_SECOND / 40000; + lastjoybusupdate = 0; + return; // ignore + } - lastjoybusupdate = 0; - resp.push_back((u8)READ16LE(&ioMem[COMM_JOYSTAT])); + lastjoybusupdate = 0; + resp.push_back((u8)READ16LE(&ioMem[COMM_JOYSTAT])); - if (cmd == JOY_CMD_READ) - { - UPDATE_REG(COMM_JOYSTAT, READ16LE(&ioMem[COMM_JOYSTAT]) & ~JOYSTAT_SEND); - } + if (cmd == JOY_CMD_READ) { + UPDATE_REG(COMM_JOYSTAT, READ16LE(&ioMem[COMM_JOYSTAT]) & ~JOYSTAT_SEND); + } - dol->Send(resp); + dol->Send(resp); - // Generate SIO interrupt if we can - if (((cmd == JOY_CMD_RESET) || (cmd == JOY_CMD_READ) || (cmd == JOY_CMD_WRITE)) - && (READ16LE(&ioMem[COMM_JOYCNT]) & JOYCNT_INT_ENABLE) ) - { - IF |= 0x80; - UPDATE_REG(0x202, IF); - } + // Generate SIO interrupt if we can + if (((cmd == JOY_CMD_RESET) || (cmd == JOY_CMD_READ) || (cmd == JOY_CMD_WRITE)) + && (READ16LE(&ioMem[COMM_JOYCNT]) & JOYCNT_INT_ENABLE)) { + IF |= 0x80; + UPDATE_REG(0x202, IF); + } - lastcommand = 0; - } + lastcommand = 0; + } } static void JoyBusShutdown() { - delete dol; - dol = NULL; + delete dol; + dol = NULL; } #define MAX_CLIENTS lanlink.numslaves + 1 // Server -RFUServer::RFUServer(void) { - for (int j = 0; j < 5; j++) - rfu_data.rfu_signal[j] = 0; +RFUServer::RFUServer(void) +{ + for (int j = 0; j < 5; j++) + rfu_data.rfu_signal[j] = 0; } sf::Packet& RFUServer::Serialize(sf::Packet& packet, int slave) { - for (int i = 0; i < MAX_CLIENTS; i++) - { - if (i != slave) - { - packet << (i == current_host); - packet << rfu_data.rfu_reqid[i]; - if (i == current_host) - { - for (int j = 0; j < 7; j++) - packet << rfu_data.rfu_broadcastdata[i][j]; - } - } + for (int i = 0; i < MAX_CLIENTS; i++) { + if (i != slave) { + packet << (i == current_host); + packet << rfu_data.rfu_reqid[i]; + if (i == current_host) { + for (int j = 0; j < 7; j++) + packet << rfu_data.rfu_broadcastdata[i][j]; + } + } - if (i == slave) - { - packet << rfu_data.rfu_clientidx[i]; - packet << rfu_data.rfu_is_host[i]; - packet << rfu_data.rfu_listback[i]; + if (i == slave) { + packet << rfu_data.rfu_clientidx[i]; + packet << rfu_data.rfu_is_host[i]; + packet << rfu_data.rfu_listback[i]; - if (rfu_data.rfu_listback[i] > 0) - log("num_data_packets from %d to %d = %d\n", linkid, i, rfu_data.rfu_listback[i]); + if (rfu_data.rfu_listback[i] > 0) + log("num_data_packets from %d to %d = %d\n", linkid, i, rfu_data.rfu_listback[i]); - for (int j = 0; j <= rfu_data.rfu_listback[i]; j++) - { - packet << rfu_data.rfu_datalist[i][j & 0xff].len; + for (int j = 0; j <= rfu_data.rfu_listback[i]; j++) { + packet << rfu_data.rfu_datalist[i][j & 0xff].len; - for (int k = 0; k < rfu_data.rfu_datalist[i][j & 0xff].len; k++) - packet << rfu_data.rfu_datalist[i][j & 0xff].data[k]; + for (int k = 0; k < rfu_data.rfu_datalist[i][j & 0xff].len; k++) + packet << rfu_data.rfu_datalist[i][j & 0xff].data[k]; - packet << rfu_data.rfu_datalist[i][j & 0xff].gbaid; - } - } - } + packet << rfu_data.rfu_datalist[i][j & 0xff].gbaid; + } + } + } - packet << linktime; // Synchronise clocks by setting slave clock to master clock - return packet; + packet << linktime; // Synchronise clocks by setting slave clock to master clock + return packet; } void RFUServer::DeSerialize(sf::Packet packet, int slave) { - bool slave_is_host = false; - packet >> slave_is_host; - packet >> rfu_data.rfu_reqid[slave]; - if (slave_is_host) - { - current_host = slave; - for (int j = 0; j < 7; j++) - packet >> rfu_data.rfu_broadcastdata[slave][j]; - } + bool slave_is_host = false; + packet >> slave_is_host; + packet >> rfu_data.rfu_reqid[slave]; + if (slave_is_host) { + current_host = slave; + for (int j = 0; j < 7; j++) + packet >> rfu_data.rfu_broadcastdata[slave][j]; + } - for (int i = 0; i < MAX_CLIENTS; i++) - { - if (i != slave) - { - u8 num_data_sent = 0; - packet >> rfu_data.rfu_clientidx[i]; - packet >> rfu_data.rfu_is_host[i]; - packet >> num_data_sent; + for (int i = 0; i < MAX_CLIENTS; i++) { + if (i != slave) { + u8 num_data_sent = 0; + packet >> rfu_data.rfu_clientidx[i]; + packet >> rfu_data.rfu_is_host[i]; + packet >> num_data_sent; - for (int j = rfu_data.rfu_listback[i]; j <= (rfu_data.rfu_listback[i] + num_data_sent); j++) - { - packet >> rfu_data.rfu_datalist[i][j & 0xff].len; + for (int j = rfu_data.rfu_listback[i]; j <= (rfu_data.rfu_listback[i] + num_data_sent); j++) { + packet >> rfu_data.rfu_datalist[i][j & 0xff].len; - for (int k = 0; k < rfu_data.rfu_datalist[i][j & 0xff].len; k++) - packet >> rfu_data.rfu_datalist[i][j & 0xff].data[k]; + for (int k = 0; k < rfu_data.rfu_datalist[i][j & 0xff].len; k++) + packet >> rfu_data.rfu_datalist[i][j & 0xff].data[k]; - packet >> rfu_data.rfu_datalist[i][j & 0xff].gbaid; - } + packet >> rfu_data.rfu_datalist[i][j & 0xff].gbaid; + } - rfu_data.rfu_listback[i] = (rfu_data.rfu_listback[i] + num_data_sent) & 0xff; - } - } + rfu_data.rfu_listback[i] = (rfu_data.rfu_listback[i] + num_data_sent) & 0xff; + } + } } -void RFUServer::Send(void) { - if (lanlink.type == 0) { // TCP - sf::Packet packet; - if (lanlink.numslaves == 1) { - if (lanlink.type == 0) { - tcpsocket[1].send(Serialize(packet, 1)); - } - } - else if (lanlink.numslaves == 2) { - if (lanlink.type == 0) { - tcpsocket[1].send(Serialize(packet, 1)); - tcpsocket[2].send(Serialize(packet, 2)); - } - } - else { - if (lanlink.type == 0) { - tcpsocket[1].send(Serialize(packet, 1)); - tcpsocket[2].send(Serialize(packet, 2)); - tcpsocket[3].send(Serialize(packet, 3)); - } - } - } +void RFUServer::Send(void) +{ + if (lanlink.type == 0) { // TCP + sf::Packet packet; + if (lanlink.numslaves == 1) { + if (lanlink.type == 0) { + tcpsocket[1].send(Serialize(packet, 1)); + } + } else if (lanlink.numslaves == 2) { + if (lanlink.type == 0) { + tcpsocket[1].send(Serialize(packet, 1)); + tcpsocket[2].send(Serialize(packet, 2)); + } + } else { + if (lanlink.type == 0) { + tcpsocket[1].send(Serialize(packet, 1)); + tcpsocket[2].send(Serialize(packet, 2)); + tcpsocket[3].send(Serialize(packet, 3)); + } + } + } } // Receive data from all slaves to master -void RFUServer::Recv(void) { - //int numbytes; - if (lanlink.type == 0) { // TCP - fdset.clear(); +void RFUServer::Recv(void) +{ + //int numbytes; + if (lanlink.type == 0) { // TCP + fdset.clear(); - for (i = 0; i < lanlink.numslaves; i++) - fdset.add(tcpsocket[i + 1]); + for (i = 0; i < lanlink.numslaves; i++) + fdset.add(tcpsocket[i + 1]); - //bool all_ready = false; - //while (!all_ready) - //{ - // fdset.wait(sf::milliseconds(1)); - // int count = 0; - // for (int sl = 0; sl < lanlink.numslaves; sl++) - // { - // if (fdset.isReady(tcpsocket[sl + 1])) - // count++; - // } - // if (count == lanlink.numslaves) - // all_ready = true; - //} + //bool all_ready = false; + //while (!all_ready) + //{ + // fdset.wait(sf::milliseconds(1)); + // int count = 0; + // for (int sl = 0; sl < lanlink.numslaves; sl++) + // { + // if (fdset.isReady(tcpsocket[sl + 1])) + // count++; + // } + // if (count == lanlink.numslaves) + // all_ready = true; + //} - for (i = 0; i < lanlink.numslaves; i++) { - sf::Packet packet; - tcpsocket[i + 1].setBlocking(false); - sf::Socket::Status status = tcpsocket[i + 1].receive(packet); - if (status == sf::Socket::Disconnected) { - char message[30]; - sprintf(message, _("Player %d disconnected."), i + 1); - systemScreenMessage(message); - //tcpsocket[i + 1].disconnect(); - //CloseLink(); - //return; - } - DeSerialize(packet, i + 1); - } - } + for (i = 0; i < lanlink.numslaves; i++) { + sf::Packet packet; + tcpsocket[i + 1].setBlocking(false); + sf::Socket::Status status = tcpsocket[i + 1].receive(packet); + if (status == sf::Socket::Disconnected) { + char message[30]; + sprintf(message, _("Player %d disconnected."), i + 1); + systemScreenMessage(message); + //tcpsocket[i + 1].disconnect(); + //CloseLink(); + //return; + } + DeSerialize(packet, i + 1); + } + } } // Client -RFUClient::RFUClient(void) { - transferring = false; +RFUClient::RFUClient(void) +{ + transferring = false; - for (int j = 0; j < 5; j++) - rfu_data.rfu_signal[j] = 0; + for (int j = 0; j < 5; j++) + rfu_data.rfu_signal[j] = 0; } sf::Packet& RFUClient::Serialize(sf::Packet& packet) { - packet << rfu_ishost; - packet << rfu_data.rfu_reqid[linkid]; - if (rfu_ishost) - { - for (int j = 0; j < 7; j++) - packet << rfu_data.rfu_broadcastdata[linkid][j]; - } + packet << rfu_ishost; + packet << rfu_data.rfu_reqid[linkid]; + if (rfu_ishost) { + for (int j = 0; j < 7; j++) + packet << rfu_data.rfu_broadcastdata[linkid][j]; + } - for (int i = 0; i < MAX_CLIENTS; i++) - { - if (i != linkid) - { - packet << rfu_data.rfu_clientidx[i]; - packet << rfu_data.rfu_is_host[i]; - packet << rfu_data.rfu_listback[i]; + for (int i = 0; i < MAX_CLIENTS; i++) { + if (i != linkid) { + packet << rfu_data.rfu_clientidx[i]; + packet << rfu_data.rfu_is_host[i]; + packet << rfu_data.rfu_listback[i]; - if (rfu_data.rfu_listback[i] > 0) - log("num_data_packets from %d to %d = %d\n", linkid, i, rfu_data.rfu_listback[i]); + if (rfu_data.rfu_listback[i] > 0) + log("num_data_packets from %d to %d = %d\n", linkid, i, rfu_data.rfu_listback[i]); - for (int j = 0; j <= rfu_data.rfu_listback[i]; j++) - { - packet << rfu_data.rfu_datalist[i][j].len; + for (int j = 0; j <= rfu_data.rfu_listback[i]; j++) { + packet << rfu_data.rfu_datalist[i][j].len; - for (int k = 0; k < rfu_data.rfu_datalist[i][j].len; k++) - packet << rfu_data.rfu_datalist[i][j].data[k]; + for (int k = 0; k < rfu_data.rfu_datalist[i][j].len; k++) + packet << rfu_data.rfu_datalist[i][j].data[k]; - packet << rfu_data.rfu_datalist[i][j].gbaid; - } - } - } - return packet; + packet << rfu_data.rfu_datalist[i][j].gbaid; + } + } + } + return packet; } void RFUClient::DeSerialize(sf::Packet packet) { - bool is_current_host = false; - for (int i = 0; i < MAX_CLIENTS; i++) - { - if (i != linkid) - { - packet >> is_current_host; - packet >> rfu_data.rfu_reqid[i]; - if (is_current_host) - { - for (int j = 0; j < 7; j++) - packet >> rfu_data.rfu_broadcastdata[i][j]; - } - } + bool is_current_host = false; + for (int i = 0; i < MAX_CLIENTS; i++) { + if (i != linkid) { + packet >> is_current_host; + packet >> rfu_data.rfu_reqid[i]; + if (is_current_host) { + for (int j = 0; j < 7; j++) + packet >> rfu_data.rfu_broadcastdata[i][j]; + } + } - if (i == linkid) - { - u8 num_data_sent = 0; - packet >> rfu_data.rfu_clientidx[i]; - packet >> rfu_data.rfu_is_host[i]; - packet >> num_data_sent; + if (i == linkid) { + u8 num_data_sent = 0; + packet >> rfu_data.rfu_clientidx[i]; + packet >> rfu_data.rfu_is_host[i]; + packet >> num_data_sent; - for (int j = rfu_data.rfu_listback[i]; j <= (rfu_data.rfu_listback[i] + num_data_sent); j++) - { - packet >> rfu_data.rfu_datalist[i][j & 0xff].len; + for (int j = rfu_data.rfu_listback[i]; j <= (rfu_data.rfu_listback[i] + num_data_sent); j++) { + packet >> rfu_data.rfu_datalist[i][j & 0xff].len; - for (int k = 0; k < rfu_data.rfu_datalist[i][j & 0xff].len; k++) - packet >> rfu_data.rfu_datalist[i][j & 0xff].data[k]; + for (int k = 0; k < rfu_data.rfu_datalist[i][j & 0xff].len; k++) + packet >> rfu_data.rfu_datalist[i][j & 0xff].data[k]; - packet >> rfu_data.rfu_datalist[i][j & 0xff].gbaid; - } + packet >> rfu_data.rfu_datalist[i][j & 0xff].gbaid; + } - rfu_data.rfu_listback[i] = (rfu_data.rfu_listback[i] + num_data_sent) & 0xff; - } - } + rfu_data.rfu_listback[i] = (rfu_data.rfu_listback[i] + num_data_sent) & 0xff; + } + } - packet >> linktime; // Synchronise clocks by setting slave clock to master clock + packet >> linktime; // Synchronise clocks by setting slave clock to master clock } -void RFUClient::Send() { - sf::Packet packet; - lanlink.tcpsocket.send(Serialize(packet)); +void RFUClient::Send() +{ + sf::Packet packet; + lanlink.tcpsocket.send(Serialize(packet)); } +void RFUClient::Recv(void) +{ + if (rfu_data.numgbas < 2) + return; -void RFUClient::Recv(void) { - if (rfu_data.numgbas < 2) - return; - - fdset.clear(); - // old code used socket # instead of mask again - lanlink.tcpsocket.setBlocking(false); - fdset.add(lanlink.tcpsocket); - if (fdset.wait(sf::milliseconds(166)) == 0) - { - systemScreenMessage(_("Server timed out.")); - //transferring = false; - //return; - } - size_t nr; - sf::Packet packet; - sf::Socket::Status status = lanlink.tcpsocket.receive(packet); - if (status == sf::Socket::Disconnected) { - systemScreenMessage(_("Server disconnected.")); - CloseLink(); - return; - } - DeSerialize(packet); + fdset.clear(); + // old code used socket # instead of mask again + lanlink.tcpsocket.setBlocking(false); + fdset.add(lanlink.tcpsocket); + if (fdset.wait(sf::milliseconds(166)) == 0) { + systemScreenMessage(_("Server timed out.")); + //transferring = false; + //return; + } + size_t nr; + sf::Packet packet; + sf::Socket::Status status = lanlink.tcpsocket.receive(packet); + if (status == sf::Socket::Disconnected) { + systemScreenMessage(_("Server disconnected.")); + CloseLink(); + return; + } + DeSerialize(packet); } -static ConnectionState ConnectUpdateRFUSocket(char * const message, size_t size) { - ConnectionState newState = LINK_NEEDS_UPDATE; +static ConnectionState ConnectUpdateRFUSocket(char* const message, size_t size) +{ + ConnectionState newState = LINK_NEEDS_UPDATE; - if (lanlink.server) { - sf::SocketSelector fdset; - fdset.add(lanlink.tcplistener); + if (lanlink.server) { + sf::SocketSelector fdset; + fdset.add(lanlink.tcplistener); - if (fdset.wait(sf::milliseconds(150))) { - int nextSlave = lanlink.connectedSlaves + 1; + if (fdset.wait(sf::milliseconds(150))) { + int nextSlave = lanlink.connectedSlaves + 1; - sf::Socket::Status st = lanlink.tcplistener.accept(rfu_server.tcpsocket[nextSlave]); + sf::Socket::Status st = lanlink.tcplistener.accept(rfu_server.tcpsocket[nextSlave]); - if (st == sf::Socket::Error) { - for (int j = 1; j < nextSlave; j++) - rfu_server.tcpsocket[j].disconnect(); + if (st == sf::Socket::Error) { + for (int j = 1; j < nextSlave; j++) + rfu_server.tcpsocket[j].disconnect(); - snprintf(message, size, N_("Network error.")); - newState = LINK_ERROR; - } - else { - sf::Packet packet; - packet << static_cast(nextSlave) - << static_cast(lanlink.numslaves); + snprintf(message, size, N_("Network error.")); + newState = LINK_ERROR; + } else { + sf::Packet packet; + packet << static_cast(nextSlave) + << static_cast(lanlink.numslaves); - rfu_server.tcpsocket[nextSlave].send(packet); + rfu_server.tcpsocket[nextSlave].send(packet); - snprintf(message, size, N_("Player %d connected"), nextSlave); - lanlink.connectedSlaves++; - } - } + snprintf(message, size, N_("Player %d connected"), nextSlave); + lanlink.connectedSlaves++; + } + } - if (lanlink.numslaves == lanlink.connectedSlaves) { - for (int i = 1; i <= lanlink.numslaves; i++) { - sf::Packet packet; - packet << true; + if (lanlink.numslaves == lanlink.connectedSlaves) { + for (int i = 1; i <= lanlink.numslaves; i++) { + sf::Packet packet; + packet << true; - rfu_server.tcpsocket[i].send(packet); - rfu_server.tcpsocket[i].setBlocking(false); - } + rfu_server.tcpsocket[i].send(packet); + rfu_server.tcpsocket[i].setBlocking(false); + } - snprintf(message, size, N_("All players connected")); - newState = LINK_OK; - } - } - else { + snprintf(message, size, N_("All players connected")); + newState = LINK_OK; + } + } else { - sf::Packet packet; - lanlink.tcpsocket.setBlocking(false); - sf::Socket::Status status = lanlink.tcpsocket.receive(packet); + sf::Packet packet; + lanlink.tcpsocket.setBlocking(false); + sf::Socket::Status status = lanlink.tcpsocket.receive(packet); - if (status == sf::Socket::Error || status == sf::Socket::Disconnected) { - snprintf(message, size, N_("Network error.")); - newState = LINK_ERROR; - } - else if (status == sf::Socket::Done) { + if (status == sf::Socket::Error || status == sf::Socket::Disconnected) { + snprintf(message, size, N_("Network error.")); + newState = LINK_ERROR; + } else if (status == sf::Socket::Done) { - if (linkid == 0) { - sf::Uint16 receivedId, receivedSlaves; - packet >> receivedId >> receivedSlaves; + if (linkid == 0) { + sf::Uint16 receivedId, receivedSlaves; + packet >> receivedId >> receivedSlaves; - if (packet) { - linkid = receivedId; - lanlink.numslaves = receivedSlaves; + if (packet) { + linkid = receivedId; + lanlink.numslaves = receivedSlaves; - snprintf(message, size, N_("Connected as #%d, Waiting for %d players to join"), - linkid + 1, lanlink.numslaves - linkid); - } - } - else { - bool gameReady; - packet >> gameReady; + snprintf(message, size, N_("Connected as #%d, Waiting for %d players to join"), + linkid + 1, lanlink.numslaves - linkid); + } + } else { + bool gameReady; + packet >> gameReady; - if (packet && gameReady) { - newState = LINK_OK; - snprintf(message, size, N_("All players joined.")); - } - } + if (packet && gameReady) { + newState = LINK_OK; + snprintf(message, size, N_("All players joined.")); + } + } - sf::SocketSelector fdset; - fdset.add(lanlink.tcpsocket); - fdset.wait(sf::milliseconds(150)); - } - } + sf::SocketSelector fdset; + fdset.add(lanlink.tcpsocket); + fdset.wait(sf::milliseconds(150)); + } + } - rfu_data.numgbas = lanlink.numslaves + 1; - log("num gbas: %d\n", rfu_data.numgbas); + rfu_data.numgbas = lanlink.numslaves + 1; + log("num gbas: %d\n", rfu_data.numgbas); - return newState; + return newState; } // The GBA wireless RFU (see adapter3.txt) static void StartRFUSocket(u16 value) { - int siomode = GetSIOMode(value, READ16LE(&ioMem[COMM_RCNT])); + int siomode = GetSIOMode(value, READ16LE(&ioMem[COMM_RCNT])); - if (value) - rfu_enabled = (siomode == NORMAL32); + if (value) + rfu_enabled = (siomode == NORMAL32); - if (((READ16LE(&ioMem[COMM_SIOCNT]) & 0x5080) == SIO_TRANS_32BIT) && ((value & 0x5080) == (SIO_TRANS_32BIT | SIO_IRQ_ENABLE | SIO_TRANS_START))) { //RFU Reset, may also occur before cable link started - rfu_data.rfu_listfront[linkid] = 0; - rfu_data.rfu_listback[linkid] = 0; - } + if (((READ16LE(&ioMem[COMM_SIOCNT]) & 0x5080) == SIO_TRANS_32BIT) && ((value & 0x5080) == (SIO_TRANS_32BIT | SIO_IRQ_ENABLE | SIO_TRANS_START))) { //RFU Reset, may also occur before cable link started + rfu_data.rfu_listfront[linkid] = 0; + rfu_data.rfu_listback[linkid] = 0; + } - if (!rfu_enabled) - { - if ((value & 0x5080) == (SIO_TRANS_32BIT | SIO_IRQ_ENABLE | SIO_TRANS_START)) { //0x5083 //game tried to send wireless command but w/o the adapter - if (READ16LE(&ioMem[COMM_SIOCNT]) & SIO_IRQ_ENABLE) //IRQ Enable - { - IF |= 0x80; //Serial Communication - UPDATE_REG(0x202, IF); //Interrupt Request Flags / IRQ Acknowledge - } - value &= ~SIO_TRANS_START; //Start bit.7 reset //may cause the game to retry sending again - value |= SIO_TRANS_FLAG_SEND_DISABLE; //SO bit.3 set automatically upon transfer completion - transfer_direction = SENDING; - } - return; - } + if (!rfu_enabled) { + if ((value & 0x5080) == (SIO_TRANS_32BIT | SIO_IRQ_ENABLE | SIO_TRANS_START)) { //0x5083 //game tried to send wireless command but w/o the adapter + if (READ16LE(&ioMem[COMM_SIOCNT]) & SIO_IRQ_ENABLE) //IRQ Enable + { + IF |= 0x80; //Serial Communication + UPDATE_REG(0x202, IF); //Interrupt Request Flags / IRQ Acknowledge + } + value &= ~SIO_TRANS_START; //Start bit.7 reset //may cause the game to retry sending again + value |= SIO_TRANS_FLAG_SEND_DISABLE; //SO bit.3 set automatically upon transfer completion + transfer_direction = SENDING; + } + return; + } - static bool logstartd; - u32 CurCOM = 0, CurDAT = 0; - bool rfulogd = (READ16LE(&ioMem[COMM_SIOCNT]) != value); + static bool logstartd; + u32 CurCOM = 0, CurDAT = 0; + bool rfulogd = (READ16LE(&ioMem[COMM_SIOCNT]) != value); - switch (GetSIOMode(value, READ16LE(&ioMem[COMM_RCNT]))) { - case NORMAL8: - rfu_polarity = 0; - UPDATE_REG(COMM_SIOCNT, value); - return; - break; - case NORMAL32: - //don't do anything if previous cmd aren't sent yet, may fix Boktai2 Not Detecting wireless adapter - //if (transfer_direction == RECEIVING) - //{ - // UPDATE_REG(COMM_SIOCNT, value); - // return; - //} + switch (GetSIOMode(value, READ16LE(&ioMem[COMM_RCNT]))) { + case NORMAL8: + rfu_polarity = 0; + UPDATE_REG(COMM_SIOCNT, value); + return; + break; + case NORMAL32: + //don't do anything if previous cmd aren't sent yet, may fix Boktai2 Not Detecting wireless adapter + //if (transfer_direction == RECEIVING) + //{ + // UPDATE_REG(COMM_SIOCNT, value); + // return; + //} - //Moving this to the bottom might prevent Mario Golf Adv from Occasionally Not Detecting wireless adapter - if (value & SIO_TRANS_FLAG_SEND_DISABLE) //Transfer Enable Flag Send (SO.bit.3, 1=Disable Transfer/Not Ready) - value &= ~SIO_TRANS_FLAG_RECV_ENABLE; //Transfer enable flag receive (0=Enable Transfer/Ready, SI.bit.2=SO.bit.3 of otherside) // A kind of acknowledge procedure - else //(SO.Bit.3, 0=Enable Transfer/Ready) - value |= SIO_TRANS_FLAG_RECV_ENABLE; //SI.bit.2=1 (otherside is Not Ready) + //Moving this to the bottom might prevent Mario Golf Adv from Occasionally Not Detecting wireless adapter + if (value & SIO_TRANS_FLAG_SEND_DISABLE) //Transfer Enable Flag Send (SO.bit.3, 1=Disable Transfer/Not Ready) + value &= ~SIO_TRANS_FLAG_RECV_ENABLE; //Transfer enable flag receive (0=Enable Transfer/Ready, SI.bit.2=SO.bit.3 of otherside) // A kind of acknowledge procedure + else //(SO.Bit.3, 0=Enable Transfer/Ready) + value |= SIO_TRANS_FLAG_RECV_ENABLE; //SI.bit.2=1 (otherside is Not Ready) - if ((value & (SIO_INT_CLOCK | SIO_TRANS_FLAG_RECV_ENABLE)) == SIO_INT_CLOCK) - value |= SIO_INT_CLOCK_SEL_2MHZ; //wireless always use 2Mhz speed right? this will fix MarioGolfAdv Not Detecting wireless + if ((value & (SIO_INT_CLOCK | SIO_TRANS_FLAG_RECV_ENABLE)) == SIO_INT_CLOCK) + value |= SIO_INT_CLOCK_SEL_2MHZ; //wireless always use 2Mhz speed right? this will fix MarioGolfAdv Not Detecting wireless - if (value & SIO_TRANS_START) //start/busy bit - { - if ((value & (SIO_INT_CLOCK | SIO_INT_CLOCK_SEL_2MHZ)) == SIO_INT_CLOCK) - rfu_transfer_end = 2048; - else - rfu_transfer_end = 256; + if (value & SIO_TRANS_START) //start/busy bit + { + if ((value & (SIO_INT_CLOCK | SIO_INT_CLOCK_SEL_2MHZ)) == SIO_INT_CLOCK) + rfu_transfer_end = 2048; + else + rfu_transfer_end = 256; - u16 siodata_h = READ16LE(&ioMem[COMM_SIODATA32_H]); - switch (rfu_state) { - case RFU_INIT: - if (READ32LE(&ioMem[COMM_SIODATA32_L]) == 0xb0bb8001) - { - rfu_state = RFU_COMM; // end of startup - rfu_initialized = true; - value &= ~SIO_TRANS_FLAG_RECV_ENABLE; //0xff7b; //Bit.2 need to be 0 to indicate a finished initialization to fix MarioGolfAdv from occasionally Not Detecting wireless adapter (prevent it from sending 0x7FFE8001 comm)? - rfu_polarity = 0; //not needed? - } - rfu_buf = (READ16LE(&ioMem[COMM_SIODATA32_L]) << 16) | siodata_h; - break; - case RFU_COMM: - CurCOM = READ32LE(&ioMem[COMM_SIODATA32_L]); - if (siodata_h == 0x9966) //initialize cmd - { - u8 tmpcmd = CurCOM; - if (tmpcmd != 0x10 && tmpcmd != 0x11 && tmpcmd != 0x13 && tmpcmd != 0x14 && tmpcmd != 0x16 && tmpcmd != 0x17 && tmpcmd != 0x19 && tmpcmd != 0x1a && tmpcmd != 0x1b && tmpcmd != 0x1c && tmpcmd != 0x1d && tmpcmd != 0x1e && tmpcmd != 0x1f && tmpcmd != 0x20 && tmpcmd != 0x21 && tmpcmd != 0x24 && tmpcmd != 0x25 && tmpcmd != 0x26 && tmpcmd != 0x27 && tmpcmd != 0x30 && tmpcmd != 0x32 && tmpcmd != 0x33 && tmpcmd != 0x34 && tmpcmd != 0x3d && tmpcmd != 0xa8 && tmpcmd != 0xee) { - } - rfu_counter = 0; - if ((rfu_qsend2 = rfu_qsend = ioMem[0x121]) != 0) { //COMM_SIODATA32_L+1, following data [to send] - rfu_state = RFU_SEND; - } - if (ioMem[COMM_SIODATA32_L] == 0xee) { //0xee cmd shouldn't override previous cmd - rfu_lastcmd = rfu_cmd2; - rfu_cmd2 = ioMem[COMM_SIODATA32_L]; - } - else{ - rfu_lastcmd = rfu_cmd; - rfu_cmd = ioMem[COMM_SIODATA32_L]; - rfu_cmd2 = 0; - int maskid; - if (rfu_cmd == 0x27 || rfu_cmd == 0x37) { - rfu_lastcmd2 = rfu_cmd; - rfu_lasttime = linktime; - } - else - if (rfu_cmd == 0x24) { //non-important data shouldn't overwrite important data from 0x25 - rfu_lastcmd2 = rfu_cmd; - rfu_cansend = false; - if (rfu_ishost) - maskid = ~rfu_data.rfu_is_host[linkid]; - else - maskid = ~(1 << gbaid); - //previous important data need to be received successfully before sending another important data - rfu_lasttime = linktime; //just to mark the last time a data being sent - if (rfu_data.rfu_q[linkid] < 2) - { //can overwrite now - rfu_cansend = true; - rfu_data.rfu_q[linkid] = 0; //rfu_qsend; - rfu_data.rfu_qid[linkid] = 0; - } - else if (!speedhack)rfu_waiting = true; //don't wait with speedhack - } - else - if (rfu_cmd == 0x25 || rfu_cmd == 0x35) { - rfu_lastcmd2 = rfu_cmd; - rfu_cansend = false; - if (rfu_ishost) - maskid = ~rfu_data.rfu_is_host[linkid]; else - maskid = ~(1 << gbaid); - //previous important data need to be received successfully before sending another important data - rfu_lasttime = linktime; - if (rfu_data.rfu_q[linkid] < 2) { - rfu_cansend = true; - rfu_data.rfu_q[linkid] = 0; //rfu_qsend; - rfu_data.rfu_qid[linkid] = 0; - } - else if (!speedhack)rfu_waiting = true; //don't wait with speedhack - } - else - if (rfu_cmd == 0xa8 || rfu_cmd == 0xb6) { - //wait for [important] data when previously sent is important data, might only need to wait for the 1st 0x25 cmd - bool ok = false; - } - else - if (rfu_cmd == 0x11 || rfu_cmd == 0x1a || rfu_cmd == 0x26) { - if (rfu_lastcmd2 == 0x24) - rfu_waiting = true; - } - } - if (rfu_waiting) - rfu_buf = READ32LE(&ioMem[COMM_SIODATA32_L]); - else - rfu_buf = 0x80000000; - } - else if (siodata_h == 0x8000) //finalize cmd, the game will send this when polarity reversed (expecting something) - { - rfu_qrecv_broadcast_data_len = 0; - if (rfu_cmd2 == 0xee) { - if (rfu_masterdata[0] == 2) //is this value of 2 related to polarity? - rfu_polarity = 0; //to normalize polarity after finalize looks more proper - rfu_buf = 0x99660000 | (rfu_qrecv_broadcast_data_len << 8) | (rfu_cmd2 ^ 0x80); - } - else{ - switch (rfu_cmd) { - case 0x1a: // check if someone joined - if (rfu_data.rfu_is_host[linkid]) { - gbaidx = gbaid; + u16 siodata_h = READ16LE(&ioMem[COMM_SIODATA32_H]); + switch (rfu_state) { + case RFU_INIT: + if (READ32LE(&ioMem[COMM_SIODATA32_L]) == 0xb0bb8001) { + rfu_state = RFU_COMM; // end of startup + rfu_initialized = true; + value &= ~SIO_TRANS_FLAG_RECV_ENABLE; //0xff7b; //Bit.2 need to be 0 to indicate a finished initialization to fix MarioGolfAdv from occasionally Not Detecting wireless adapter (prevent it from sending 0x7FFE8001 comm)? + rfu_polarity = 0; //not needed? + } + rfu_buf = (READ16LE(&ioMem[COMM_SIODATA32_L]) << 16) | siodata_h; + break; + case RFU_COMM: + CurCOM = READ32LE(&ioMem[COMM_SIODATA32_L]); + if (siodata_h == 0x9966) //initialize cmd + { + u8 tmpcmd = CurCOM; + if (tmpcmd != 0x10 && tmpcmd != 0x11 && tmpcmd != 0x13 && tmpcmd != 0x14 && tmpcmd != 0x16 && tmpcmd != 0x17 && tmpcmd != 0x19 && tmpcmd != 0x1a && tmpcmd != 0x1b && tmpcmd != 0x1c && tmpcmd != 0x1d && tmpcmd != 0x1e && tmpcmd != 0x1f && tmpcmd != 0x20 && tmpcmd != 0x21 && tmpcmd != 0x24 && tmpcmd != 0x25 && tmpcmd != 0x26 && tmpcmd != 0x27 && tmpcmd != 0x30 && tmpcmd != 0x32 && tmpcmd != 0x33 && tmpcmd != 0x34 && tmpcmd != 0x3d && tmpcmd != 0xa8 && tmpcmd != 0xee) { + } + rfu_counter = 0; + if ((rfu_qsend2 = rfu_qsend = ioMem[0x121]) != 0) { //COMM_SIODATA32_L+1, following data [to send] + rfu_state = RFU_SEND; + } + if (ioMem[COMM_SIODATA32_L] == 0xee) { //0xee cmd shouldn't override previous cmd + rfu_lastcmd = rfu_cmd2; + rfu_cmd2 = ioMem[COMM_SIODATA32_L]; + } else { + rfu_lastcmd = rfu_cmd; + rfu_cmd = ioMem[COMM_SIODATA32_L]; + rfu_cmd2 = 0; + int maskid; + if (rfu_cmd == 0x27 || rfu_cmd == 0x37) { + rfu_lastcmd2 = rfu_cmd; + rfu_lasttime = linktime; + } else if (rfu_cmd == 0x24) { //non-important data shouldn't overwrite important data from 0x25 + rfu_lastcmd2 = rfu_cmd; + rfu_cansend = false; + if (rfu_ishost) + maskid = ~rfu_data.rfu_is_host[linkid]; + else + maskid = ~(1 << gbaid); + //previous important data need to be received successfully before sending another important data + rfu_lasttime = linktime; //just to mark the last time a data being sent + if (rfu_data.rfu_q[linkid] < 2) { //can overwrite now + rfu_cansend = true; + rfu_data.rfu_q[linkid] = 0; //rfu_qsend; + rfu_data.rfu_qid[linkid] = 0; + } else if (!speedhack) + rfu_waiting = true; //don't wait with speedhack + } else if (rfu_cmd == 0x25 || rfu_cmd == 0x35) { + rfu_lastcmd2 = rfu_cmd; + rfu_cansend = false; + if (rfu_ishost) + maskid = ~rfu_data.rfu_is_host[linkid]; + else + maskid = ~(1 << gbaid); + //previous important data need to be received successfully before sending another important data + rfu_lasttime = linktime; + if (rfu_data.rfu_q[linkid] < 2) { + rfu_cansend = true; + rfu_data.rfu_q[linkid] = 0; //rfu_qsend; + rfu_data.rfu_qid[linkid] = 0; + } else if (!speedhack) + rfu_waiting = true; //don't wait with speedhack + } else if (rfu_cmd == 0xa8 || rfu_cmd == 0xb6) { + //wait for [important] data when previously sent is important data, might only need to wait for the 1st 0x25 cmd + bool ok = false; + } else if (rfu_cmd == 0x11 || rfu_cmd == 0x1a || rfu_cmd == 0x26) { + if (rfu_lastcmd2 == 0x24) + rfu_waiting = true; + } + } + if (rfu_waiting) + rfu_buf = READ32LE(&ioMem[COMM_SIODATA32_L]); + else + rfu_buf = 0x80000000; + } else if (siodata_h == 0x8000) //finalize cmd, the game will send this when polarity reversed (expecting something) + { + rfu_qrecv_broadcast_data_len = 0; + if (rfu_cmd2 == 0xee) { + if (rfu_masterdata[0] == 2) //is this value of 2 related to polarity? + rfu_polarity = 0; //to normalize polarity after finalize looks more proper + rfu_buf = 0x99660000 | (rfu_qrecv_broadcast_data_len << 8) | (rfu_cmd2 ^ 0x80); + } else { + switch (rfu_cmd) { + case 0x1a: // check if someone joined + if (rfu_data.rfu_is_host[linkid]) { + gbaidx = gbaid; - do - { - gbaidx = (gbaidx + 1) % rfu_data.numgbas; // check this numgbas = 3, gbaid = 0, gbaidx = 1, - if (gbaidx != linkid && rfu_data.rfu_reqid[gbaidx] == (linkid << 3) + 0x61f1) - { - rfu_masterdata[rfu_qrecv_broadcast_data_len++] = (gbaidx << 3) + 0x61f1; - } - } while (gbaidx != gbaid&&rfu_data.numgbas >= 2); + do { + gbaidx = (gbaidx + 1) % rfu_data.numgbas; // check this numgbas = 3, gbaid = 0, gbaidx = 1, + if (gbaidx != linkid && rfu_data.rfu_reqid[gbaidx] == (linkid << 3) + 0x61f1) { + rfu_masterdata[rfu_qrecv_broadcast_data_len++] = (gbaidx << 3) + 0x61f1; + } + } while (gbaidx != gbaid && rfu_data.numgbas >= 2); - if (rfu_qrecv_broadcast_data_len > 0) { - bool ok = false; - for (int i = 0; i < rfu_numclients; i++) - if ((rfu_clientlist[i] & 0xffff) == rfu_masterdata[0]) { ok = true; break; } - if (!ok) { - rfu_curclient = rfu_numclients; - rfu_data.rfu_clientidx[(rfu_masterdata[0] - 0x61f1) >> 3] = rfu_numclients; - rfu_clientlist[rfu_numclients] = rfu_masterdata[0] | (rfu_numclients++ << 16); - gbaid = (rfu_masterdata[0] - 0x61f1) >> 3; - rfu_data.rfu_signal[gbaid] = 0xffffffff >> ((3 - (rfu_numclients - 1)) << 3); - } - if (gbaid == linkid) { - gbaid = (rfu_masterdata[0] - 0x61f1) >> 3; - } - rfu_state = RFU_RECV; - } - } - if (rfu_numclients > 0) { - for (int i = 0; i < rfu_numclients; i++)rfu_masterdata[i] = rfu_clientlist[i]; - } - rfu_id = (gbaid << 3) + 0x61f1; - rfu_cmd ^= 0x80; - break; - case 0x1f: // join a room as client - // TODO: to fix infinte send&recv w/o giving much cance to update the screen when both side acting as client - // on MarioGolfAdv lobby(might be due to leftover data when switching from host to join mode at the same time?) - rfu_id = rfu_masterdata[0]; - gbaid = (rfu_id - 0x61f1) >> 3; - rfu_idx = rfu_id; - gbaidx = gbaid; - rfu_lastcmd2 = 0; - numtransfers = 0; - rfu_data.rfu_q[linkid] = 0; //to prevent leftover data from previous session received immediately in the new session - rfu_data.rfu_reqid[linkid] = rfu_id; - // TODO:might failed to reset rfu_request when being accessed by otherside at the same time, sometimes both acting - // as client but one of them still have request[linkid]!=0 //to prevent both GBAs from acting as Host, client can't - // be a host at the same time - rfu_data.rfu_is_host[linkid] = 0; - if (linkid != gbaid) { - rfu_data.rfu_signal[linkid] = 0x00ff; - rfu_data.rfu_is_host[gbaid] |= 1 << linkid; // tells the other GBA(a host) that someone(a client) is joining - log("%09d: joining room: signal: %d linkid: %d gbaid: %d\n", linktime, rfu_data.rfu_signal[linkid], linkid, gbaid); - } - rfu_cmd ^= 0x80; - break; - case 0x1e: // receive broadcast data - numtransfers = 0; - rfu_numclients = 0; - rfu_data.rfu_is_host[linkid] = 0; //to prevent both GBAs from acting as Host and thinking both of them have Client? - rfu_data.rfu_q[linkid] = 0; //to prevent leftover data from previous session received immediately in the new session - case 0x1d: // no visible difference - rfu_data.rfu_is_host[linkid] = 0; - memset(rfu_masterdata, 0, sizeof(rfu_data.rfu_broadcastdata[linkid])); - rfu_qrecv_broadcast_data_len = 0; - for (int i = 0; i < rfu_data.numgbas; i++) - { - if (i != linkid&&rfu_data.rfu_broadcastdata[i][0]) { - memcpy(&rfu_masterdata[rfu_qrecv_broadcast_data_len], rfu_data.rfu_broadcastdata[i], sizeof(rfu_data.rfu_broadcastdata[i])); - rfu_qrecv_broadcast_data_len += 7; - } - } - // is this needed? to prevent MarioGolfAdv from joining it's own room when switching - // from host to client mode due to left over room data in the game buffer? - // if(rfu_qrecv==0) rfu_qrecv = 7; - if (rfu_qrecv_broadcast_data_len > 0) - { - log("%09d: switching to RFU_RECV (broadcast)\n", linktime); - rfu_state = RFU_RECV; - } - rfu_polarity = 0; - rfu_counter = 0; - rfu_cmd ^= 0x80; - break; - case 0x16: // send broadcast data (ie. room name) - //start broadcasting here may cause client to join other client in pokemon coloseum - rfu_cmd ^= 0x80; - break; - case 0x11: // get signal strength - //Switch remote id - //check signal - if (rfu_data.numgbas >= 2 && (rfu_data.rfu_is_host[linkid] | rfu_data.rfu_is_host[gbaid])) //signal only good when connected - if (rfu_ishost) { //update, just incase there are leaving clients - u8 rfureq = rfu_data.rfu_is_host[linkid]; - u8 oldnum = rfu_numclients; - rfu_numclients = 0; - for (int i = 0; i<8; i++) { - if (rfureq & 1)rfu_numclients++; - rfureq >>= 1; - } - if (rfu_numclients>oldnum)rfu_numclients = oldnum; //must not be higher than old value, which means the new client haven't been processed by 0x1a cmd yet - rfu_data.rfu_signal[linkid] = 0xffffffff >> ((4 - rfu_numclients) << 3); - } - else rfu_data.rfu_signal[linkid] = rfu_data.rfu_signal[gbaid]; - else rfu_data.rfu_signal[linkid] = 0; - if (rfu_qrecv_broadcast_data_len == 0) { - rfu_qrecv_broadcast_data_len = 1; - rfu_masterdata[0] = (u32)rfu_data.rfu_signal[linkid]; - } - if (rfu_qrecv_broadcast_data_len > 0) { - rfu_state = RFU_RECV; - rfu_masterdata[rfu_qrecv_broadcast_data_len - 1] = (u32)rfu_data.rfu_signal[gbaid]; - } - rfu_cmd ^= 0x80; - break; - case 0x33: // rejoin status check? - if (rfu_data.rfu_signal[linkid] || numtransfers == 0) - rfu_masterdata[0] = 0; else //0=success - rfu_masterdata[0] = (u32)-1; //0xffffffff; //1=failed, 2++ = reserved/invalid, we use invalid value to let the game retries 0x33 until signal restored - rfu_cmd ^= 0x80; - rfu_state = RFU_RECV; - rfu_qrecv_broadcast_data_len = 1; - break; - case 0x14: // reset current client index and error check? - if ((rfu_data.rfu_signal[linkid] || numtransfers == 0) && gbaid != linkid) - rfu_masterdata[0] = ((!rfu_ishost ? 0x100 : 0 + rfu_data.rfu_clientidx[gbaid]) << 16) | ((gbaid << 3) + 0x61f1); - rfu_masterdata[0] = 0; //0=error, non-zero=good? - rfu_cmd ^= 0x80; - rfu_state = RFU_RECV; - rfu_qrecv_broadcast_data_len = 1; - break; - case 0x13: // error check? - if (rfu_data.rfu_signal[linkid] || numtransfers == 0 || rfu_initialized) - { - rfu_masterdata[0] = ((rfu_ishost ? 0x100 : 0 + rfu_data.rfu_clientidx[linkid]) << 16) | ((linkid << 3) + 0x61f1); - } - else //high word should be 0x0200 ? is 0x0200 means 1st client and 0x4000 means 2nd client? - { - log("%09d: error status\n", linktime); - rfu_masterdata[0] = 0; //0=error, non-zero=good? - } - rfu_cmd ^= 0x80; - rfu_state = RFU_RECV; - rfu_qrecv_broadcast_data_len = 1; - break; - case 0x20: // client, this has something to do with 0x1f - rfu_masterdata[0] = (rfu_data.rfu_clientidx[linkid]) << 16; //needed for client - rfu_masterdata[0] |= (linkid << 3) + 0x61f1; //0x1234; //0x641b; //max id value? Encryption key or Station Mode? (0xFBD9/0xDEAD=Access Point mode?) - rfu_data.rfu_q[linkid] = 0; //to prevent leftover data from previous session received immediately in the new session - rfu_data.rfu_is_host[linkid] = 0; //TODO:may not works properly, sometimes both acting as client but one of them still have request[linkid]!=0 //to prevent both GBAs from acting as Host, client can't be a host at the same time - if (rfu_data.rfu_signal[gbaid] < rfu_data.rfu_signal[linkid]) - rfu_data.rfu_signal[gbaid] = rfu_data.rfu_signal[linkid]; + if (rfu_qrecv_broadcast_data_len > 0) { + bool ok = false; + for (int i = 0; i < rfu_numclients; i++) + if ((rfu_clientlist[i] & 0xffff) == rfu_masterdata[0]) { + ok = true; + break; + } + if (!ok) { + rfu_curclient = rfu_numclients; + rfu_data.rfu_clientidx[(rfu_masterdata[0] - 0x61f1) >> 3] = rfu_numclients; + rfu_clientlist[rfu_numclients] = rfu_masterdata[0] | (rfu_numclients++ << 16); + gbaid = (rfu_masterdata[0] - 0x61f1) >> 3; + rfu_data.rfu_signal[gbaid] = 0xffffffff >> ((3 - (rfu_numclients - 1)) << 3); + } + if (gbaid == linkid) { + gbaid = (rfu_masterdata[0] - 0x61f1) >> 3; + } + rfu_state = RFU_RECV; + } + } + if (rfu_numclients > 0) { + for (int i = 0; i < rfu_numclients; i++) + rfu_masterdata[i] = rfu_clientlist[i]; + } + rfu_id = (gbaid << 3) + 0x61f1; + rfu_cmd ^= 0x80; + break; + case 0x1f: // join a room as client + // TODO: to fix infinte send&recv w/o giving much cance to update the screen when both side acting as client + // on MarioGolfAdv lobby(might be due to leftover data when switching from host to join mode at the same time?) + rfu_id = rfu_masterdata[0]; + gbaid = (rfu_id - 0x61f1) >> 3; + rfu_idx = rfu_id; + gbaidx = gbaid; + rfu_lastcmd2 = 0; + numtransfers = 0; + rfu_data.rfu_q[linkid] = 0; //to prevent leftover data from previous session received immediately in the new session + rfu_data.rfu_reqid[linkid] = rfu_id; + // TODO:might failed to reset rfu_request when being accessed by otherside at the same time, sometimes both acting + // as client but one of them still have request[linkid]!=0 //to prevent both GBAs from acting as Host, client can't + // be a host at the same time + rfu_data.rfu_is_host[linkid] = 0; + if (linkid != gbaid) { + rfu_data.rfu_signal[linkid] = 0x00ff; + rfu_data.rfu_is_host[gbaid] |= 1 << linkid; // tells the other GBA(a host) that someone(a client) is joining + log("%09d: joining room: signal: %d linkid: %d gbaid: %d\n", linktime, rfu_data.rfu_signal[linkid], linkid, gbaid); + } + rfu_cmd ^= 0x80; + break; + case 0x1e: // receive broadcast data + numtransfers = 0; + rfu_numclients = 0; + rfu_data.rfu_is_host[linkid] = 0; //to prevent both GBAs from acting as Host and thinking both of them have Client? + rfu_data.rfu_q[linkid] = 0; //to prevent leftover data from previous session received immediately in the new session + case 0x1d: // no visible difference + rfu_data.rfu_is_host[linkid] = 0; + memset(rfu_masterdata, 0, sizeof(rfu_data.rfu_broadcastdata[linkid])); + rfu_qrecv_broadcast_data_len = 0; + for (int i = 0; i < rfu_data.numgbas; i++) { + if (i != linkid && rfu_data.rfu_broadcastdata[i][0]) { + memcpy(&rfu_masterdata[rfu_qrecv_broadcast_data_len], rfu_data.rfu_broadcastdata[i], sizeof(rfu_data.rfu_broadcastdata[i])); + rfu_qrecv_broadcast_data_len += 7; + } + } + // is this needed? to prevent MarioGolfAdv from joining it's own room when switching + // from host to client mode due to left over room data in the game buffer? + // if(rfu_qrecv==0) rfu_qrecv = 7; + if (rfu_qrecv_broadcast_data_len > 0) { + log("%09d: switching to RFU_RECV (broadcast)\n", linktime); + rfu_state = RFU_RECV; + } + rfu_polarity = 0; + rfu_counter = 0; + rfu_cmd ^= 0x80; + break; + case 0x16: // send broadcast data (ie. room name) + //start broadcasting here may cause client to join other client in pokemon coloseum + rfu_cmd ^= 0x80; + break; + case 0x11: // get signal strength + //Switch remote id + //check signal + if (rfu_data.numgbas >= 2 && (rfu_data.rfu_is_host[linkid] | rfu_data.rfu_is_host[gbaid])) //signal only good when connected + if (rfu_ishost) { //update, just incase there are leaving clients + u8 rfureq = rfu_data.rfu_is_host[linkid]; + u8 oldnum = rfu_numclients; + rfu_numclients = 0; + for (int i = 0; i < 8; i++) { + if (rfureq & 1) + rfu_numclients++; + rfureq >>= 1; + } + if (rfu_numclients > oldnum) + rfu_numclients = oldnum; //must not be higher than old value, which means the new client haven't been processed by 0x1a cmd yet + rfu_data.rfu_signal[linkid] = 0xffffffff >> ((4 - rfu_numclients) << 3); + } else + rfu_data.rfu_signal[linkid] = rfu_data.rfu_signal[gbaid]; + else + rfu_data.rfu_signal[linkid] = 0; + if (rfu_qrecv_broadcast_data_len == 0) { + rfu_qrecv_broadcast_data_len = 1; + rfu_masterdata[0] = (u32)rfu_data.rfu_signal[linkid]; + } + if (rfu_qrecv_broadcast_data_len > 0) { + rfu_state = RFU_RECV; + rfu_masterdata[rfu_qrecv_broadcast_data_len - 1] = (u32)rfu_data.rfu_signal[gbaid]; + } + rfu_cmd ^= 0x80; + break; + case 0x33: // rejoin status check? + if (rfu_data.rfu_signal[linkid] || numtransfers == 0) + rfu_masterdata[0] = 0; + else //0=success + rfu_masterdata[0] = (u32)-1; //0xffffffff; //1=failed, 2++ = reserved/invalid, we use invalid value to let the game retries 0x33 until signal restored + rfu_cmd ^= 0x80; + rfu_state = RFU_RECV; + rfu_qrecv_broadcast_data_len = 1; + break; + case 0x14: // reset current client index and error check? + if ((rfu_data.rfu_signal[linkid] || numtransfers == 0) && gbaid != linkid) + rfu_masterdata[0] = ((!rfu_ishost ? 0x100 : 0 + rfu_data.rfu_clientidx[gbaid]) << 16) | ((gbaid << 3) + 0x61f1); + rfu_masterdata[0] = 0; //0=error, non-zero=good? + rfu_cmd ^= 0x80; + rfu_state = RFU_RECV; + rfu_qrecv_broadcast_data_len = 1; + break; + case 0x13: // error check? + if (rfu_data.rfu_signal[linkid] || numtransfers == 0 || rfu_initialized) { + rfu_masterdata[0] = ((rfu_ishost ? 0x100 : 0 + rfu_data.rfu_clientidx[linkid]) << 16) | ((linkid << 3) + 0x61f1); + } else //high word should be 0x0200 ? is 0x0200 means 1st client and 0x4000 means 2nd client? + { + log("%09d: error status\n", linktime); + rfu_masterdata[0] = 0; //0=error, non-zero=good? + } + rfu_cmd ^= 0x80; + rfu_state = RFU_RECV; + rfu_qrecv_broadcast_data_len = 1; + break; + case 0x20: // client, this has something to do with 0x1f + rfu_masterdata[0] = (rfu_data.rfu_clientidx[linkid]) << 16; //needed for client + rfu_masterdata[0] |= (linkid << 3) + 0x61f1; //0x1234; //0x641b; //max id value? Encryption key or Station Mode? (0xFBD9/0xDEAD=Access Point mode?) + rfu_data.rfu_q[linkid] = 0; //to prevent leftover data from previous session received immediately in the new session + rfu_data.rfu_is_host[linkid] = 0; //TODO:may not works properly, sometimes both acting as client but one of them still have request[linkid]!=0 //to prevent both GBAs from acting as Host, client can't be a host at the same time + if (rfu_data.rfu_signal[gbaid] < rfu_data.rfu_signal[linkid]) + rfu_data.rfu_signal[gbaid] = rfu_data.rfu_signal[linkid]; - rfu_polarity = 0; - rfu_state = RFU_RECV; - rfu_qrecv_broadcast_data_len = 1; - rfu_cmd ^= 0x80; - break; - case 0x21: // client, this too - rfu_masterdata[0] = (rfu_data.rfu_clientidx[linkid]) << 16; //not needed? - rfu_masterdata[0] |= (linkid << 3) + 0x61f1; //0x641b; //max id value? Encryption key or Station Mode? (0xFBD9/0xDEAD=Access Point mode?) - rfu_data.rfu_q[linkid] = 0; //to prevent leftover data from previous session received immediately in the new session - rfu_data.rfu_is_host[linkid] = 0; //TODO:may not works properly, sometimes both acting as client but one of them still have request[linkid]!=0 //to prevent both GBAs from acting as Host, client can't be a host at the same time - rfu_polarity = 0; - rfu_state = RFU_RECV; //3; - rfu_qrecv_broadcast_data_len = 1; - rfu_cmd ^= 0x80; - break; + rfu_polarity = 0; + rfu_state = RFU_RECV; + rfu_qrecv_broadcast_data_len = 1; + rfu_cmd ^= 0x80; + break; + case 0x21: // client, this too + rfu_masterdata[0] = (rfu_data.rfu_clientidx[linkid]) << 16; //not needed? + rfu_masterdata[0] |= (linkid << 3) + 0x61f1; //0x641b; //max id value? Encryption key or Station Mode? (0xFBD9/0xDEAD=Access Point mode?) + rfu_data.rfu_q[linkid] = 0; //to prevent leftover data from previous session received immediately in the new session + rfu_data.rfu_is_host[linkid] = 0; //TODO:may not works properly, sometimes both acting as client but one of them still have request[linkid]!=0 //to prevent both GBAs from acting as Host, client can't be a host at the same time + rfu_polarity = 0; + rfu_state = RFU_RECV; //3; + rfu_qrecv_broadcast_data_len = 1; + rfu_cmd ^= 0x80; + break; - case 0x19: // server bind/start listening for client to join, may be used in the middle of host<->client communication w/o causing clients to dc? - rfu_data.rfu_q[linkid] = 0; //to prevent leftover data from previous session received immediately in the new session - rfu_data.rfu_broadcastdata[linkid][0] = (linkid << 3) + 0x61f1; //start broadcasting room name - rfu_data.rfu_clientidx[linkid] = 0; - rfu_ishost = true; - rfu_cmd ^= 0x80; - break; + case 0x19: // server bind/start listening for client to join, may be used in the middle of host<->client communication w/o causing clients to dc? + rfu_data.rfu_q[linkid] = 0; //to prevent leftover data from previous session received immediately in the new session + rfu_data.rfu_broadcastdata[linkid][0] = (linkid << 3) + 0x61f1; //start broadcasting room name + rfu_data.rfu_clientidx[linkid] = 0; + rfu_ishost = true; + rfu_cmd ^= 0x80; + break; - case 0x1c: //client, might reset some data? - rfu_ishost = false; //TODO: prevent both GBAs act as client but one of them have rfu_request[linkid]!=0 on MarioGolfAdv lobby - rfu_numclients = 0; - rfu_curclient = 0; - rfu_data.rfu_listfront[linkid] = 0; - rfu_data.rfu_listback[linkid] = 0; - rfu_data.rfu_q[linkid] = 0; //to prevent leftover data from previous session received immediately in the new session - case 0x1b: //host, might reset some data? may be used in the middle of host<->client communication w/o causing clients to dc? - rfu_data.rfu_broadcastdata[linkid][0] = 0; //0 may cause player unable to join in pokemon union room? - rfu_cmd ^= 0x80; - break; + case 0x1c: //client, might reset some data? + rfu_ishost = false; //TODO: prevent both GBAs act as client but one of them have rfu_request[linkid]!=0 on MarioGolfAdv lobby + rfu_numclients = 0; + rfu_curclient = 0; + rfu_data.rfu_listfront[linkid] = 0; + rfu_data.rfu_listback[linkid] = 0; + rfu_data.rfu_q[linkid] = 0; //to prevent leftover data from previous session received immediately in the new session + case 0x1b: //host, might reset some data? may be used in the middle of host<->client communication w/o causing clients to dc? + rfu_data.rfu_broadcastdata[linkid][0] = 0; //0 may cause player unable to join in pokemon union room? + rfu_cmd ^= 0x80; + break; - case 0x30: //reset some data - if (linkid != gbaid) { //(rfu_data.numgbas >= 2) - rfu_data.rfu_is_host[gbaid] &= ~(1 << linkid); //rfu_data.rfu_request[gbaid] = 0; - } - while (rfu_data.rfu_signal[linkid]) { - rfu_data.rfu_signal[linkid] = 0; - rfu_data.rfu_is_host[linkid] = 0; //There is a possibility where rfu_request/signal didn't get zeroed here when it's being read by the other GBA at the same time - } - rfu_data.rfu_listfront[linkid] = 0; - rfu_data.rfu_listback[linkid] = 0; - rfu_data.rfu_q[linkid] = 0; //to prevent leftover data from previous session received immediately in the new session - rfu_data.rfu_proto[linkid] = 0; - rfu_data.rfu_reqid[linkid] = 0; - rfu_data.rfu_linktime[linkid] = 0; - rfu_data.rfu_gdata[linkid] = 0; - rfu_data.rfu_broadcastdata[linkid][0] = 0; - rfu_polarity = 0; //is this included? - numtransfers = 0; - rfu_numclients = 0; - rfu_curclient = 0; - rfu_cmd ^= 0x80; - break; + case 0x30: //reset some data + if (linkid != gbaid) { //(rfu_data.numgbas >= 2) + rfu_data.rfu_is_host[gbaid] &= ~(1 << linkid); //rfu_data.rfu_request[gbaid] = 0; + } + while (rfu_data.rfu_signal[linkid]) { + rfu_data.rfu_signal[linkid] = 0; + rfu_data.rfu_is_host[linkid] = 0; //There is a possibility where rfu_request/signal didn't get zeroed here when it's being read by the other GBA at the same time + } + rfu_data.rfu_listfront[linkid] = 0; + rfu_data.rfu_listback[linkid] = 0; + rfu_data.rfu_q[linkid] = 0; //to prevent leftover data from previous session received immediately in the new session + rfu_data.rfu_proto[linkid] = 0; + rfu_data.rfu_reqid[linkid] = 0; + rfu_data.rfu_linktime[linkid] = 0; + rfu_data.rfu_gdata[linkid] = 0; + rfu_data.rfu_broadcastdata[linkid][0] = 0; + rfu_polarity = 0; //is this included? + numtransfers = 0; + rfu_numclients = 0; + rfu_curclient = 0; + rfu_cmd ^= 0x80; + break; - case 0x3d: // init/reset rfu data - rfu_initialized = false; - case 0x10: // init/reset rfu data - if (linkid != gbaid) { //(rfu_data.numgbas >= 2) - rfu_data.rfu_is_host[gbaid] &= ~(1 << linkid); //rfu_data.rfu_request[gbaid] = 0; - } - while (rfu_data.rfu_signal[linkid]) { - rfu_data.rfu_signal[linkid] = 0; - rfu_data.rfu_is_host[linkid] = 0; //There is a possibility where rfu_request/signal didn't get zeroed here when it's being read by the other GBA at the same time - } - rfu_data.rfu_listfront[linkid] = 0; - rfu_data.rfu_listback[linkid] = 0; - rfu_data.rfu_q[linkid] = 0; //to prevent leftover data from previous session received immediately in the new session - rfu_data.rfu_proto[linkid] = 0; - rfu_data.rfu_reqid[linkid] = 0; - rfu_data.rfu_linktime[linkid] = 0; - rfu_data.rfu_gdata[linkid] = 0; - rfu_data.rfu_broadcastdata[linkid][0] = 0; - rfu_polarity = 0; //is this included? - numtransfers = 0; - rfu_numclients = 0; - rfu_curclient = 0; - rfu_id = 0; - rfu_idx = 0; - gbaid = linkid; - gbaidx = gbaid; - rfu_ishost = false; - rfu_qrecv_broadcast_data_len = 0; - rfu_cmd ^= 0x80; - break; + case 0x3d: // init/reset rfu data + rfu_initialized = false; + case 0x10: // init/reset rfu data + if (linkid != gbaid) { //(rfu_data.numgbas >= 2) + rfu_data.rfu_is_host[gbaid] &= ~(1 << linkid); //rfu_data.rfu_request[gbaid] = 0; + } + while (rfu_data.rfu_signal[linkid]) { + rfu_data.rfu_signal[linkid] = 0; + rfu_data.rfu_is_host[linkid] = 0; //There is a possibility where rfu_request/signal didn't get zeroed here when it's being read by the other GBA at the same time + } + rfu_data.rfu_listfront[linkid] = 0; + rfu_data.rfu_listback[linkid] = 0; + rfu_data.rfu_q[linkid] = 0; //to prevent leftover data from previous session received immediately in the new session + rfu_data.rfu_proto[linkid] = 0; + rfu_data.rfu_reqid[linkid] = 0; + rfu_data.rfu_linktime[linkid] = 0; + rfu_data.rfu_gdata[linkid] = 0; + rfu_data.rfu_broadcastdata[linkid][0] = 0; + rfu_polarity = 0; //is this included? + numtransfers = 0; + rfu_numclients = 0; + rfu_curclient = 0; + rfu_id = 0; + rfu_idx = 0; + gbaid = linkid; + gbaidx = gbaid; + rfu_ishost = false; + rfu_qrecv_broadcast_data_len = 0; + rfu_cmd ^= 0x80; + break; - case 0x36: //does it expect data returned? - case 0x26: - //Switch remote id to available data - bool ok; - int ctr; - ctr = 0; - if (rfu_data.rfu_listfront[linkid] != rfu_data.rfu_listback[linkid]) //data existed - do { - u8 qdata_len = rfu_data.rfu_datalist[linkid][rfu_data.rfu_listfront[linkid]].len; //(u8)rfu_data.rfu_qlist[linkid][rfu_data.rfu_listfront[linkid]]; - ok = false; - if (qdata_len != rfu_qrecv_broadcast_data_len) ok = true; else - for (int i = 0; i 1) - { - if (rfu_qrecv_broadcast_data_len>1) { //stop here if next data is different than currently unprocessed non-ping data - //break; - } + //if (ok) //next data is not a duplicate of currently unprocessed data + if (rfu_qrecv_broadcast_data_len < 2 || qdata_len > 1) { + if (rfu_qrecv_broadcast_data_len > 1) { //stop here if next data is different than currently unprocessed non-ping data + //break; + } - if (qdata_len >= rfu_qrecv_broadcast_data_len) { - rfu_masterq = rfu_qrecv_broadcast_data_len = qdata_len; - gbaid = rfu_data.rfu_datalist[linkid][rfu_data.rfu_listfront[linkid]].gbaid; - rfu_id = (gbaid << 3) + 0x61f1; - if (rfu_ishost) - { - rfu_curclient = (u8)rfu_data.rfu_clientidx[gbaid]; - } - if (rfu_qrecv_broadcast_data_len != 0) { //data size > 0 - memcpy(rfu_masterdata, rfu_data.rfu_datalist[linkid][rfu_data.rfu_listfront[linkid]].data, std::min(rfu_masterq << 2, (int)sizeof(rfu_masterdata))); - } - } - } + if (qdata_len >= rfu_qrecv_broadcast_data_len) { + rfu_masterq = rfu_qrecv_broadcast_data_len = qdata_len; + gbaid = rfu_data.rfu_datalist[linkid][rfu_data.rfu_listfront[linkid]].gbaid; + rfu_id = (gbaid << 3) + 0x61f1; + if (rfu_ishost) { + rfu_curclient = (u8)rfu_data.rfu_clientidx[gbaid]; + } + if (rfu_qrecv_broadcast_data_len != 0) { //data size > 0 + memcpy(rfu_masterdata, rfu_data.rfu_datalist[linkid][rfu_data.rfu_listfront[linkid]].data, std::min(rfu_masterq << 2, (int)sizeof(rfu_masterdata))); + } + } + } - rfu_data.rfu_listfront[linkid]++; ctr++; + rfu_data.rfu_listfront[linkid]++; + ctr++; - ok = (rfu_data.rfu_listfront[linkid] != rfu_data.rfu_listback[linkid] && rfu_data.rfu_datalist[linkid][rfu_data.rfu_listfront[linkid]].gbaid == gbaid); - } while (ok); + ok = (rfu_data.rfu_listfront[linkid] != rfu_data.rfu_listback[linkid] && rfu_data.rfu_datalist[linkid][rfu_data.rfu_listfront[linkid]].gbaid == gbaid); + } while (ok); - if (rfu_qrecv_broadcast_data_len > 0) { //data was available - rfu_state = RFU_RECV; - rfu_counter = 0; - rfu_lastcmd2 = 0; + if (rfu_qrecv_broadcast_data_len > 0) { //data was available + rfu_state = RFU_RECV; + rfu_counter = 0; + rfu_lastcmd2 = 0; - //Switch remote id to next remote id - } - rfu_cmd ^= 0x80; - break; + //Switch remote id to next remote id + } + rfu_cmd ^= 0x80; + break; - case 0x24: // send [non-important] data (used by server often) - rfu_data.rfu_linktime[linkid] = linktime; //save the ticks before reseted to zero + case 0x24: // send [non-important] data (used by server often) + rfu_data.rfu_linktime[linkid] = linktime; //save the ticks before reseted to zero - if (rfu_cansend && rfu_qsend2 >= 0) { - if (rfu_ishost) { - for (int j = 0; j= 0) { + if (rfu_ishost) { + for (int j = 0; j < rfu_data.numgbas; j++) + if (j != linkid) { + memcpy(rfu_data.rfu_datalist[j][rfu_data.rfu_listback[j]].data, rfu_masterdata, 4 * rfu_qsend2); + rfu_data.rfu_datalist[j][rfu_data.rfu_listback[j]].gbaid = linkid; + rfu_data.rfu_datalist[j][rfu_data.rfu_listback[j]].len = rfu_qsend2; + rfu_data.rfu_datalist[j][rfu_data.rfu_listback[j]].time = linktime; + rfu_data.rfu_listback[j]++; + } + } else if (linkid != gbaid) { + memcpy(rfu_data.rfu_datalist[gbaid][rfu_data.rfu_listback[gbaid]].data, rfu_masterdata, 4 * rfu_qsend2); + rfu_data.rfu_datalist[gbaid][rfu_data.rfu_listback[gbaid]].gbaid = linkid; + rfu_data.rfu_datalist[gbaid][rfu_data.rfu_listback[gbaid]].len = rfu_qsend2; + rfu_data.rfu_datalist[gbaid][rfu_data.rfu_listback[gbaid]].time = linktime; + rfu_data.rfu_listback[gbaid]++; + } + } else { + log("IgnoredSend[%02X] %d\n", rfu_cmd, rfu_qsend2); + } + rfu_cmd ^= 0x80; + break; - case 0x25: // send [important] data & wait for [important?] reply data - case 0x35: // send [important] data & wait for [important?] reply data - rfu_data.rfu_linktime[linkid] = linktime; //save the ticks before changed to synchronize performance + case 0x25: // send [important] data & wait for [important?] reply data + case 0x35: // send [important] data & wait for [important?] reply data + rfu_data.rfu_linktime[linkid] = linktime; //save the ticks before changed to synchronize performance - if (rfu_cansend && rfu_qsend2 > 0) { - if (rfu_ishost) { - for (int j = 0; j 0) { + if (rfu_ishost) { + for (int j = 0; j < rfu_data.numgbas; j++) + if (j != linkid) { + memcpy(rfu_data.rfu_datalist[j][rfu_data.rfu_listback[j]].data, rfu_masterdata, 4 * rfu_qsend2); + rfu_data.rfu_datalist[j][rfu_data.rfu_listback[j]].gbaid = linkid; + rfu_data.rfu_datalist[j][rfu_data.rfu_listback[j]].len = rfu_qsend2; + rfu_data.rfu_datalist[j][rfu_data.rfu_listback[j]].time = linktime; + rfu_data.rfu_listback[j]++; + } + } else if (linkid != gbaid) { + memcpy(rfu_data.rfu_datalist[gbaid][rfu_data.rfu_listback[gbaid]].data, rfu_masterdata, 4 * rfu_qsend2); + rfu_data.rfu_datalist[gbaid][rfu_data.rfu_listback[gbaid]].gbaid = linkid; + rfu_data.rfu_datalist[gbaid][rfu_data.rfu_listback[gbaid]].len = rfu_qsend2; + rfu_data.rfu_datalist[gbaid][rfu_data.rfu_listback[gbaid]].time = linktime; + rfu_data.rfu_listback[gbaid]++; + } + } else { + log("IgnoredSend[%02X] %d\n", rfu_cmd, rfu_qsend2); + } + //TODO: there is still a chance for 0x25 to be used at the same time on both GBA (both GBAs acting as client but keep sending & receiving using 0x25 & 0x26 for infinity w/o updating the screen much) + //Waiting here for previous data to be received might be too late! as new data already sent before finalization cmd + case 0x27: // wait for data ? + case 0x37: // wait for data ? + rfu_data.rfu_linktime[linkid] = linktime; //save the ticks before changed to synchronize performance - if (rfu_ishost) { - for (int j = 0; j> 24) != 0x7ff) - rfu_state = RFU_INIT; //to prevent the next reinit words from getting in finalization processing (here), may cause MarioGolfAdv to show Linking error when this occurs instead of continuing with COMM cmd - rfu_buf = (READ16LE(&ioMem[COMM_SIODATA32_L]) << 16) | siodata_h; - } - break; + break; + } + if (!rfu_waiting) + rfu_buf = 0x99660000 | (rfu_qrecv_broadcast_data_len << 8) | rfu_cmd; + else + rfu_buf = READ32LE(&ioMem[COMM_SIODATA32_L]); + } + } else { //unknown COMM word //in MarioGolfAdv (when a player/client exiting lobby), There is a possibility COMM = 0x7FFE8001, PrevVAL = 0x5087, PrevCOM = 0, is this part of initialization? + log("%09d: UnkCOM %08X %04X %08X %08X\n", linktime, READ32LE(&ioMem[COMM_SIODATA32_L]), PrevVAL, PrevCOM, PrevDAT); + if ((READ32LE(&ioMem[COMM_SIODATA32_L]) >> 24) != 0x7ff) + rfu_state = RFU_INIT; //to prevent the next reinit words from getting in finalization processing (here), may cause MarioGolfAdv to show Linking error when this occurs instead of continuing with COMM cmd + rfu_buf = (READ16LE(&ioMem[COMM_SIODATA32_L]) << 16) | siodata_h; + } + break; - case RFU_SEND: //data following after initialize cmd - CurDAT = READ32LE(&ioMem[COMM_SIODATA32_L]); - if (--rfu_qsend == 0) { - rfu_state = RFU_COMM; - } + case RFU_SEND: //data following after initialize cmd + CurDAT = READ32LE(&ioMem[COMM_SIODATA32_L]); + if (--rfu_qsend == 0) { + rfu_state = RFU_COMM; + } - switch (rfu_cmd) { - case 0x16: - rfu_data.rfu_broadcastdata[linkid][1 + rfu_counter++] = READ32LE(&ioMem[COMM_SIODATA32_L]); - break; + switch (rfu_cmd) { + case 0x16: + rfu_data.rfu_broadcastdata[linkid][1 + rfu_counter++] = READ32LE(&ioMem[COMM_SIODATA32_L]); + break; - case 0x17: - rfu_masterdata[rfu_counter++] = READ32LE(&ioMem[COMM_SIODATA32_L]); - break; + case 0x17: + rfu_masterdata[rfu_counter++] = READ32LE(&ioMem[COMM_SIODATA32_L]); + break; - case 0x1f: - rfu_masterdata[rfu_counter++] = READ32LE(&ioMem[COMM_SIODATA32_L]); - break; + case 0x1f: + rfu_masterdata[rfu_counter++] = READ32LE(&ioMem[COMM_SIODATA32_L]); + break; - case 0x24: - //if(rfu_data.rfu_proto[linkid]) break; //important data from 0x25 shouldn't be overwritten by 0x24 - case 0x25: - case 0x35: - rfu_masterdata[rfu_counter++] = READ32LE(&ioMem[COMM_SIODATA32_L]); - break; + case 0x24: + //if(rfu_data.rfu_proto[linkid]) break; //important data from 0x25 shouldn't be overwritten by 0x24 + case 0x25: + case 0x35: + rfu_masterdata[rfu_counter++] = READ32LE(&ioMem[COMM_SIODATA32_L]); + break; - default: - rfu_masterdata[rfu_counter++] = READ32LE(&ioMem[COMM_SIODATA32_L]); - break; - } - rfu_buf = 0x80000000; - break; + default: + rfu_masterdata[rfu_counter++] = READ32LE(&ioMem[COMM_SIODATA32_L]); + break; + } + rfu_buf = 0x80000000; + break; - case RFU_RECV: //data following after finalize cmd - if (--rfu_qrecv_broadcast_data_len == 0) - { - rfu_state = RFU_COMM; - } + case RFU_RECV: //data following after finalize cmd + if (--rfu_qrecv_broadcast_data_len == 0) { + rfu_state = RFU_COMM; + } - switch (rfu_cmd) { - case 0x9d: - case 0x9e: - rfu_buf = rfu_masterdata[rfu_counter++]; - break; + switch (rfu_cmd) { + case 0x9d: + case 0x9e: + rfu_buf = rfu_masterdata[rfu_counter++]; + break; - case 0xb6: - case 0xa6: - rfu_buf = rfu_masterdata[rfu_counter++]; - break; + case 0xb6: + case 0xa6: + rfu_buf = rfu_masterdata[rfu_counter++]; + break; - case 0x91: //signal strength - rfu_buf = rfu_masterdata[rfu_counter++]; - break; + case 0x91: //signal strength + rfu_buf = rfu_masterdata[rfu_counter++]; + break; - case 0xb3: //rejoin error code? - case 0x94: //last error code? //it seems like the game doesn't care about this value - case 0x93: //last error code? //it seems like the game doesn't care about this value - rfu_buf = rfu_masterdata[rfu_counter++]; - break; + case 0xb3: //rejoin error code? + case 0x94: //last error code? //it seems like the game doesn't care about this value + case 0x93: //last error code? //it seems like the game doesn't care about this value + rfu_buf = rfu_masterdata[rfu_counter++]; + break; - case 0xa0: - //max id value? Encryption key or Station Mode? (0xFBD9/0xDEAD=Access Point mode?) - //high word 0 = a success indication? - rfu_buf = rfu_masterdata[rfu_counter++]; - break; - case 0xa1: - //max id value? the same with 0xa0 cmd? - //high word 0 = a success indication? - rfu_buf = rfu_masterdata[rfu_counter++]; - break; + case 0xa0: + //max id value? Encryption key or Station Mode? (0xFBD9/0xDEAD=Access Point mode?) + //high word 0 = a success indication? + rfu_buf = rfu_masterdata[rfu_counter++]; + break; + case 0xa1: + //max id value? the same with 0xa0 cmd? + //high word 0 = a success indication? + rfu_buf = rfu_masterdata[rfu_counter++]; + break; - case 0x9a: - rfu_buf = rfu_masterdata[rfu_counter++]; - break; + case 0x9a: + rfu_buf = rfu_masterdata[rfu_counter++]; + break; - default: //unknown data (should use 0 or -1 as default), usually returning 0 might cause the game to think there is something wrong with the connection (ie. 0x11/0x13 cmd) - //0x0173 //not 0x0000 as default? - //0x0000 - //rfu_buf = 0xffffffff; //rfu_masterdata[rfu_counter++]; - rfu_buf = rfu_masterdata[rfu_counter++]; - break; - } - break; - } - transfer_direction = RECEIVING; + default: //unknown data (should use 0 or -1 as default), usually returning 0 might cause the game to think there is something wrong with the connection (ie. 0x11/0x13 cmd) + //0x0173 //not 0x0000 as default? + //0x0000 + //rfu_buf = 0xffffffff; //rfu_masterdata[rfu_counter++]; + rfu_buf = rfu_masterdata[rfu_counter++]; + break; + } + break; + } + transfer_direction = RECEIVING; - PrevVAL = value; - PrevDAT = CurDAT; - PrevCOM = CurCOM; - } + PrevVAL = value; + PrevDAT = CurDAT; + PrevCOM = CurCOM; + } - if (rfu_polarity) - value ^= 4; // sometimes it's the other way around - default: - UPDATE_REG(COMM_SIOCNT, value); - return; - } - UPDATE_REG(COMM_SIOCNT, value); + if (rfu_polarity) + value ^= 4; // sometimes it's the other way around + default: + UPDATE_REG(COMM_SIOCNT, value); + return; + } + UPDATE_REG(COMM_SIOCNT, value); } bool LinkRFUUpdateSocket() { - if (rfu_enabled) { - if (transfer_direction == RECEIVING && rfu_transfer_end <= 0) - { - if (rfu_waiting) { - bool ok = false; - if (rfu_state != RFU_INIT) - { - if (rfu_cmd == 0x24 || rfu_cmd == 0x25 || rfu_cmd == 0x35) { - if (rfu_data.rfu_q[linkid] < 2 || rfu_qsend>1) - { - rfu_cansend = true; - rfu_data.rfu_q[linkid] = 0; - rfu_data.rfu_qid[linkid] = 0; - } - rfu_buf = 0x80000000; - } - else{ - if (rfu_cmd == 0xa5 || rfu_cmd == 0xa7 || rfu_cmd == 0xb5 || rfu_cmd == 0xb7 || rfu_cmd == 0xee) - rfu_polarity = 1; - if (rfu_cmd == 0xa5 || rfu_cmd == 0xa7) - rfu_cmd = 0x28; - else if (rfu_cmd == 0xb5 || rfu_cmd == 0xb7) - rfu_cmd = 0x36; + if (rfu_enabled) { + if (transfer_direction == RECEIVING && rfu_transfer_end <= 0) { + if (rfu_waiting) { + bool ok = false; + if (rfu_state != RFU_INIT) { + if (rfu_cmd == 0x24 || rfu_cmd == 0x25 || rfu_cmd == 0x35) { + if (rfu_data.rfu_q[linkid] < 2 || rfu_qsend > 1) { + rfu_cansend = true; + rfu_data.rfu_q[linkid] = 0; + rfu_data.rfu_qid[linkid] = 0; + } + rfu_buf = 0x80000000; + } else { + if (rfu_cmd == 0xa5 || rfu_cmd == 0xa7 || rfu_cmd == 0xb5 || rfu_cmd == 0xb7 || rfu_cmd == 0xee) + rfu_polarity = 1; + if (rfu_cmd == 0xa5 || rfu_cmd == 0xa7) + rfu_cmd = 0x28; + else if (rfu_cmd == 0xb5 || rfu_cmd == 0xb7) + rfu_cmd = 0x36; - if (READ32LE(&ioMem[COMM_SIODATA32_L]) == 0x80000000) - rfu_buf = 0x99660000 | (rfu_qrecv_broadcast_data_len << 8) | rfu_cmd; - else - rfu_buf = 0x80000000; - } - rfu_waiting = false; - } - } - UPDATE_REG(COMM_SIODATA32_L, rfu_buf); - UPDATE_REG(COMM_SIODATA32_H, rfu_buf >> 16); - } - } - return true; + if (READ32LE(&ioMem[COMM_SIODATA32_L]) == 0x80000000) + rfu_buf = 0x99660000 | (rfu_qrecv_broadcast_data_len << 8) | rfu_cmd; + else + rfu_buf = 0x80000000; + } + rfu_waiting = false; + } + } + UPDATE_REG(COMM_SIODATA32_L, rfu_buf); + UPDATE_REG(COMM_SIODATA32_H, rfu_buf >> 16); + } + } + return true; } static void UpdateRFUSocket(int ticks) { - rfu_last_broadcast_time -= ticks; + rfu_last_broadcast_time -= ticks; - if (rfu_last_broadcast_time < 0) - { - if (linkid == 0) - { - linktime = 0; - rfu_server.Recv(); // recv broadcast data - rfu_server.Send(); // send broadcast data - } - else - { - rfu_client.Send(); // send broadcast data - rfu_client.Recv(); // recv broadcast data - } - { - for (int i = 0; i < MAX_CLIENTS; i++) - { - if (i != linkid) - { - rfu_data.rfu_listback[i] = 0; // Flush the queue - } - } - } - rfu_transfer_end = 0; + if (rfu_last_broadcast_time < 0) { + if (linkid == 0) { + linktime = 0; + rfu_server.Recv(); // recv broadcast data + rfu_server.Send(); // send broadcast data + } else { + rfu_client.Send(); // send broadcast data + rfu_client.Recv(); // recv broadcast data + } + { + for (int i = 0; i < MAX_CLIENTS; i++) { + if (i != linkid) { + rfu_data.rfu_listback[i] = 0; // Flush the queue + } + } + } + rfu_transfer_end = 0; - if (rfu_last_broadcast_time < 0) - rfu_last_broadcast_time = 3000; - //rfu_last_broadcast_time = 5600; // Upper physical limit of 5600? 3000 packets/sec - } + if (rfu_last_broadcast_time < 0) + rfu_last_broadcast_time = 3000; + //rfu_last_broadcast_time = 5600; // Upper physical limit of 5600? 3000 packets/sec + } - if (rfu_enabled) - { - if (LinkRFUUpdateSocket()) - { - if (transfer_direction == RECEIVING && rfu_transfer_end <= 0) - { - transfer_direction = SENDING; - u16 value = READ16LE(&ioMem[COMM_SIOCNT]); - if (value & SIO_IRQ_ENABLE) - { - IF |= 0x80; - UPDATE_REG(0x202, IF); - } + if (rfu_enabled) { + if (LinkRFUUpdateSocket()) { + if (transfer_direction == RECEIVING && rfu_transfer_end <= 0) { + transfer_direction = SENDING; + u16 value = READ16LE(&ioMem[COMM_SIOCNT]); + if (value & SIO_IRQ_ENABLE) { + IF |= 0x80; + UPDATE_REG(0x202, IF); + } - //if (rfu_polarity) value ^= 4; - value &= ~SIO_TRANS_FLAG_RECV_ENABLE; - value |= (value & 1) << 2; //this will automatically set the correct polarity, even w/o rfu_polarity since the game will be the one who change the polarity instead of the adapter + //if (rfu_polarity) value ^= 4; + value &= ~SIO_TRANS_FLAG_RECV_ENABLE; + value |= (value & 1) << 2; //this will automatically set the correct polarity, even w/o rfu_polarity since the game will be the one who change the polarity instead of the adapter - UPDATE_REG(COMM_SIOCNT, (value & ~SIO_TRANS_START) | SIO_TRANS_FLAG_SEND_DISABLE); //Start bit.7 reset, SO bit.3 set automatically upon transfer completion? - } - return; - } - } + UPDATE_REG(COMM_SIOCNT, (value & ~SIO_TRANS_START) | SIO_TRANS_FLAG_SEND_DISABLE); //Start bit.7 reset, SO bit.3 set automatically upon transfer completion? + } + return; + } + } } - void gbInitLink() { - if (GetLinkMode() == LINK_GAMEBOY_IPC) - { + if (GetLinkMode() == LINK_GAMEBOY_IPC) { #if (defined __WIN32__ || defined _WIN32) - gbInitLinkIPC(); + gbInitLinkIPC(); #endif - } - else - { - LinkIsWaiting = false; - LinkFirstTime = true; - } + } else { + LinkIsWaiting = false; + LinkFirstTime = true; + } } u8 gbStartLink(u8 b) //used on internal clock { - u8 dat = 0xff; //master (w/ internal clock) will gets 0xff if slave is turned off (or not ready yet also?) - //if(linkid) return 0xff; //b; //Slave shouldn't be sending from here - //int gbSerialOn = (gbMemory[0xff02] & 0x80); //not needed? - gba_link_enabled = true; //(gbMemory[0xff02]!=0); //not needed? - rfu_enabled = false; + u8 dat = 0xff; //master (w/ internal clock) will gets 0xff if slave is turned off (or not ready yet also?) + //if(linkid) return 0xff; //b; //Slave shouldn't be sending from here + //int gbSerialOn = (gbMemory[0xff02] & 0x80); //not needed? + gba_link_enabled = true; //(gbMemory[0xff02]!=0); //not needed? + rfu_enabled = false; - if (!gba_link_enabled) return 0xff; + if (!gba_link_enabled) + return 0xff; - //Single Computer - if (GetLinkMode() == LINK_GAMEBOY_IPC) - { + //Single Computer + if (GetLinkMode() == LINK_GAMEBOY_IPC) { #if (defined __WIN32__ || defined _WIN32) - dat = gbStartLinkIPC(b); + dat = gbStartLinkIPC(b); #endif - } - else - { - if (lanlink.numslaves == 1) { - if (lanlink.server) { - cable_gb_data[0] = b; - ls.SendGB(); + } else { + if (lanlink.numslaves == 1) { + if (lanlink.server) { + cable_gb_data[0] = b; + ls.SendGB(); - if (ls.RecvGB()) - dat = cable_gb_data[1]; - } - else - { - cable_gb_data[1] = b; - lc.SendGB(); + if (ls.RecvGB()) + dat = cable_gb_data[1]; + } else { + cable_gb_data[1] = b; + lc.SendGB(); - if (lc.RecvGB()) - dat = cable_gb_data[0]; - } + if (lc.RecvGB()) + dat = cable_gb_data[0]; + } - LinkIsWaiting = false; - LinkFirstTime = true; - if (dat != 0xff/*||b==0x00||dat==0x00*/) - LinkFirstTime = false; - } - } - return dat; + LinkIsWaiting = false; + LinkFirstTime = true; + if (dat != 0xff /*||b==0x00||dat==0x00*/) + LinkFirstTime = false; + } + } + return dat; } u16 gbLinkUpdate(u8 b, int gbSerialOn) //used on external clock { - u8 dat = b; //0xff; //slave (w/ external clocks) won't be getting 0xff if master turned off - u8 recvd = 0; - int idx = 0; + u8 dat = b; //0xff; //slave (w/ external clocks) won't be getting 0xff if master turned off + u8 recvd = 0; + int idx = 0; - gba_link_enabled = true; //(gbMemory[0xff02]!=0); - rfu_enabled = false; + gba_link_enabled = true; //(gbMemory[0xff02]!=0); + rfu_enabled = false; - if (gbSerialOn) { - if (gba_link_enabled) - //Single Computer - if (GetLinkMode() == LINK_GAMEBOY_IPC) - { + if (gbSerialOn) { + if (gba_link_enabled) + //Single Computer + if (GetLinkMode() == LINK_GAMEBOY_IPC) { #if (defined __WIN32__ || defined _WIN32) - return gbLinkUpdateIPC(b, gbSerialOn); + return gbLinkUpdateIPC(b, gbSerialOn); #endif - } - else - { - if (lanlink.numslaves == 1) { - if (lanlink.server) { - recvd = ls.RecvGB() ? 1 : 0; - if (recvd) - { - dat = cable_gb_data[1]; - LinkIsWaiting = false; - } - else - LinkIsWaiting = true; + } else { + if (lanlink.numslaves == 1) { + if (lanlink.server) { + recvd = ls.RecvGB() ? 1 : 0; + if (recvd) { + dat = cable_gb_data[1]; + LinkIsWaiting = false; + } else + LinkIsWaiting = true; - if (!LinkIsWaiting) - { - cable_gb_data[0] = b; - ls.SendGB(); - } - } - else - { - recvd = lc.RecvGB() ? 1 : 0; - if (recvd) - { - dat = cable_gb_data[0]; - LinkIsWaiting = false; - } - else - LinkIsWaiting = true; + if (!LinkIsWaiting) { + cable_gb_data[0] = b; + ls.SendGB(); + } + } else { + recvd = lc.RecvGB() ? 1 : 0; + if (recvd) { + dat = cable_gb_data[0]; + LinkIsWaiting = false; + } else + LinkIsWaiting = true; - if (!LinkIsWaiting) - { - cable_gb_data[1] = b; - lc.SendGB(); - } - } - } - } + if (!LinkIsWaiting) { + cable_gb_data[1] = b; + lc.SendGB(); + } + } + } + } - if (dat == 0xff/*||dat==0x00||b==0x00*/) //dat==0xff||dat==0x00 - LinkFirstTime = true; - } - return ((dat << 8) | (recvd & (u8)0xff)); + if (dat == 0xff /*||dat==0x00||b==0x00*/) //dat==0xff||dat==0x00 + LinkFirstTime = true; + } + return ((dat << 8) | (recvd & (u8)0xff)); } #if (defined __WIN32__ || defined _WIN32) -static ConnectionState InitIPC() { - linkid = 0; +static ConnectionState InitIPC() +{ + linkid = 0; #if (defined __WIN32__ || defined _WIN32) - if((mmf=CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(LINKDATA), LOCAL_LINK_NAME))==NULL) { - systemMessage(0, N_("Error creating file mapping")); - return LINK_ERROR; - } + if ((mmf = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(LINKDATA), LOCAL_LINK_NAME)) == NULL) { + systemMessage(0, N_("Error creating file mapping")); + return LINK_ERROR; + } - if(GetLastError() == ERROR_ALREADY_EXISTS) - vbaid = 1; - else - vbaid = 0; + if (GetLastError() == ERROR_ALREADY_EXISTS) + vbaid = 1; + else + vbaid = 0; - - if((linkmem=(LINKDATA *)MapViewOfFile(mmf, FILE_MAP_WRITE, 0, 0, sizeof(LINKDATA)))==NULL) { - CloseHandle(mmf); - systemMessage(0, N_("Error mapping file")); - return LINK_ERROR; - } + if ((linkmem = (LINKDATA*)MapViewOfFile(mmf, FILE_MAP_WRITE, 0, 0, sizeof(LINKDATA))) == NULL) { + CloseHandle(mmf); + systemMessage(0, N_("Error mapping file")); + return LINK_ERROR; + } #else - if((mmf = shm_open("/" LOCAL_LINK_NAME, O_RDWR|O_CREAT|O_EXCL, 0777)) < 0) { - vbaid = 1; - mmf = shm_open("/" LOCAL_LINK_NAME, O_RDWR, 0); - } else - vbaid = 0; - if(mmf < 0 || ftruncate(mmf, sizeof(LINKDATA)) < 0 || - !(linkmem = (LINKDATA *)mmap(NULL, sizeof(LINKDATA), - PROT_READ|PROT_WRITE, MAP_SHARED, - mmf, 0))) { - systemMessage(0, N_("Error creating file mapping")); - if(mmf) { - if(!vbaid) - shm_unlink("/" LOCAL_LINK_NAME); - close(mmf); - } - } + if ((mmf = shm_open("/" LOCAL_LINK_NAME, O_RDWR | O_CREAT | O_EXCL, 0777)) < 0) { + vbaid = 1; + mmf = shm_open("/" LOCAL_LINK_NAME, O_RDWR, 0); + } else + vbaid = 0; + if (mmf < 0 || ftruncate(mmf, sizeof(LINKDATA)) < 0 || !(linkmem = (LINKDATA*)mmap(NULL, sizeof(LINKDATA), PROT_READ | PROT_WRITE, MAP_SHARED, mmf, 0))) { + systemMessage(0, N_("Error creating file mapping")); + if (mmf) { + if (!vbaid) + shm_unlink("/" LOCAL_LINK_NAME); + close(mmf); + } + } #endif - // get lowest-numbered available machine slot - bool firstone = !vbaid; - if(firstone) { - linkmem->linkflags = 1; - linkmem->numgbas = 1; - linkmem->numtransfers=0; - for(i=0;i<4;i++) - linkmem->linkdata[i] = 0xffff; - } else { - // FIXME: this should be done while linkmem is locked - // (no xfer in progress, no other vba trying to connect) - int n = linkmem->numgbas; - int f = linkmem->linkflags; - for(int i = 0; i <= n; i++) - if(!(f & (1 << i))) { - vbaid = i; - break; - } - if(vbaid == 4) { + // get lowest-numbered available machine slot + bool firstone = !vbaid; + if (firstone) { + linkmem->linkflags = 1; + linkmem->numgbas = 1; + linkmem->numtransfers = 0; + for (i = 0; i < 4; i++) + linkmem->linkdata[i] = 0xffff; + } else { + // FIXME: this should be done while linkmem is locked + // (no xfer in progress, no other vba trying to connect) + int n = linkmem->numgbas; + int f = linkmem->linkflags; + for (int i = 0; i <= n; i++) + if (!(f & (1 << i))) { + vbaid = i; + break; + } + if (vbaid == 4) { #if (defined __WIN32__ || defined _WIN32) - UnmapViewOfFile(linkmem); - CloseHandle(mmf); + UnmapViewOfFile(linkmem); + CloseHandle(mmf); #else - munmap(linkmem, sizeof(LINKDATA)); - if(!vbaid) - shm_unlink("/" LOCAL_LINK_NAME); - close(mmf); + munmap(linkmem, sizeof(LINKDATA)); + if (!vbaid) + shm_unlink("/" LOCAL_LINK_NAME); + close(mmf); #endif - systemMessage(0, N_("5 or more GBAs not supported.")); - return LINK_ERROR; - } - if(vbaid == n) - linkmem->numgbas = n + 1; - linkmem->linkflags = f | (1 << vbaid); - } - linkid = vbaid; + systemMessage(0, N_("5 or more GBAs not supported.")); + return LINK_ERROR; + } + if (vbaid == n) + linkmem->numgbas = n + 1; + linkmem->linkflags = f | (1 << vbaid); + } + linkid = vbaid; - for(i=0;i<4;i++) { - linkevent[sizeof(linkevent)-2]=(char)i+'1'; + for (i = 0; i < 4; i++) { + linkevent[sizeof(linkevent) - 2] = (char)i + '1'; #if (defined __WIN32__ || defined _WIN32) - linksync[i] = firstone ? - CreateSemaphore(NULL, 0, 4, linkevent) : - OpenSemaphore(SEMAPHORE_ALL_ACCESS, false, linkevent); - if(linksync[i] == NULL) { - UnmapViewOfFile(linkmem); - CloseHandle(mmf); - for(j=0;jnumgbas > 1) - { - // find first active attached GBA - // doing this first reduces the potential - // race window size for new connections - int n = linkmem->numgbas + 1; - int f = linkmem->linkflags; - int m; - do { - n--; - m = (1 << n) - 1; - } while((f & m) != m); - linkmem->trgbas = n; + switch (GetSIOMode(value, READ16LE(&ioMem[COMM_RCNT]))) { + case MULTIPLAYER: { + bool start = (value & 0x80) && !linkid && !transfer_direction; + // clear start, seqno, si (RO on slave, start = pulse on master) + value &= 0xff4b; + // get current si. This way, on slaves, it is low during xfer + if (linkid) { + if (!transfer_direction) + value |= 4; + else + value |= READ16LE(&ioMem[COMM_SIOCNT]) & 4; + } + if (start) { + if (linkmem->numgbas > 1) { + // find first active attached GBA + // doing this first reduces the potential + // race window size for new connections + int n = linkmem->numgbas + 1; + int f = linkmem->linkflags; + int m; + do { + n--; + m = (1 << n) - 1; + } while ((f & m) != m); + linkmem->trgbas = n; - // before starting xfer, make pathetic attempt - // at clearing out any previous stuck xfer - // this will fail if a slave was stuck for - // too long - for(int i = 0; i < 4; i++) - while(WaitForSingleObject(linksync[i], 0) != WAIT_TIMEOUT); + // before starting xfer, make pathetic attempt + // at clearing out any previous stuck xfer + // this will fail if a slave was stuck for + // too long + for (int i = 0; i < 4; i++) + while (WaitForSingleObject(linksync[i], 0) != WAIT_TIMEOUT) + ; - // transmit first value - linkmem->linkcmd[0] = ('M' << 8) + (value & 3); - linkmem->linkdata[0] = READ16LE(&ioMem[COMM_SIODATA8]); + // transmit first value + linkmem->linkcmd[0] = ('M' << 8) + (value & 3); + linkmem->linkdata[0] = READ16LE(&ioMem[COMM_SIODATA8]); - // start up slaves & sync clocks - numtransfers = linkmem->numtransfers; - if (numtransfers != 0) - linkmem->lastlinktime = linktime; - else - linkmem->lastlinktime = 0; + // start up slaves & sync clocks + numtransfers = linkmem->numtransfers; + if (numtransfers != 0) + linkmem->lastlinktime = linktime; + else + linkmem->lastlinktime = 0; - if ((++numtransfers) == 0) - linkmem->numtransfers = 2; - else - linkmem->numtransfers = numtransfers; + if ((++numtransfers) == 0) + linkmem->numtransfers = 2; + else + linkmem->numtransfers = numtransfers; - transfer_direction = 1; - linktime = 0; - tspeed = value & 3; - WRITE32LE(&ioMem[COMM_SIOMULTI0], 0xffffffff); - WRITE32LE(&ioMem[COMM_SIOMULTI2], 0xffffffff); - value &= ~0x40; - } else { - value |= 0x40; // comm error - } - } - value |= (transfer_direction != 0) << 7; - value |= (linkid && !transfer_direction ? 0xc : 8); // set SD (high), SI (low on master) - value |= linkid << 4; // set seq - UPDATE_REG(COMM_SIOCNT, value); - if (linkid) - // SC low -> transfer in progress - // not sure why SO is low - UPDATE_REG(COMM_RCNT, transfer_direction ? 6 : 7); - else - // SI is always low on master - // SO, SC always low during transfer - // not sure why SO low otherwise - UPDATE_REG(COMM_RCNT, transfer_direction ? 2 : 3); - break; - } - case NORMAL8: - case NORMAL32: - case UART: - default: - UPDATE_REG(COMM_SIOCNT, value); - break; - } + transfer_direction = 1; + linktime = 0; + tspeed = value & 3; + WRITE32LE(&ioMem[COMM_SIOMULTI0], 0xffffffff); + WRITE32LE(&ioMem[COMM_SIOMULTI2], 0xffffffff); + value &= ~0x40; + } else { + value |= 0x40; // comm error + } + } + value |= (transfer_direction != 0) << 7; + value |= (linkid && !transfer_direction ? 0xc : 8); // set SD (high), SI (low on master) + value |= linkid << 4; // set seq + UPDATE_REG(COMM_SIOCNT, value); + if (linkid) + // SC low -> transfer in progress + // not sure why SO is low + UPDATE_REG(COMM_RCNT, transfer_direction ? 6 : 7); + else + // SI is always low on master + // SO, SC always low during transfer + // not sure why SO low otherwise + UPDATE_REG(COMM_RCNT, transfer_direction ? 2 : 3); + break; + } + case NORMAL8: + case NORMAL32: + case UART: + default: + UPDATE_REG(COMM_SIOCNT, value); + break; + } } static void ReconnectCableIPC() { - int f = linkmem->linkflags; - int n = linkmem->numgbas; - if(f & (1 << linkid)) { - systemMessage(0, N_("Lost link; reinitialize to reconnect")); - return; - } - linkmem->linkflags |= 1 << linkid; - if(n < linkid + 1) - linkmem->numgbas = linkid + 1; - numtransfers = linkmem->numtransfers; - systemScreenMessage(_("Lost link; reconnected")); + int f = linkmem->linkflags; + int n = linkmem->numgbas; + if (f & (1 << linkid)) { + systemMessage(0, N_("Lost link; reinitialize to reconnect")); + return; + } + linkmem->linkflags |= 1 << linkid; + if (n < linkid + 1) + linkmem->numgbas = linkid + 1; + numtransfers = linkmem->numtransfers; + systemScreenMessage(_("Lost link; reconnected")); } static void UpdateCableIPC(int ticks) { - if (((READ16LE(&ioMem[COMM_RCNT])) >> 14) == 3) - return; + if (((READ16LE(&ioMem[COMM_RCNT])) >> 14) == 3) + return; - // slave startup depends on detecting change in numtransfers - // and syncing clock with master (after first transfer) - // this will fail if > ~2 minutes have passed since last transfer due - // to integer overflow - if(!transfer_direction && numtransfers && linktime < 0) { - linktime = 0; - // there is a very, very, small chance that this will abort - // a transfer that was just started - linkmem->numtransfers = numtransfers = 0; - } - if (linkid && !transfer_direction && linktime >= linkmem->lastlinktime && - linkmem->numtransfers != numtransfers) - { - numtransfers = linkmem->numtransfers; - if(!numtransfers) - return; + // slave startup depends on detecting change in numtransfers + // and syncing clock with master (after first transfer) + // this will fail if > ~2 minutes have passed since last transfer due + // to integer overflow + if (!transfer_direction && numtransfers && linktime < 0) { + linktime = 0; + // there is a very, very, small chance that this will abort + // a transfer that was just started + linkmem->numtransfers = numtransfers = 0; + } + if (linkid && !transfer_direction && linktime >= linkmem->lastlinktime && linkmem->numtransfers != numtransfers) { + numtransfers = linkmem->numtransfers; + if (!numtransfers) + return; - // if this or any previous machine was dropped, no transfer - // can take place - if(linkmem->trgbas <= linkid) { - transfer_direction = 0; - numtransfers = 0; - // if this is the one that was dropped, reconnect - if(!(linkmem->linkflags & (1 << linkid))) - ReconnectCableIPC(); - return; - } + // if this or any previous machine was dropped, no transfer + // can take place + if (linkmem->trgbas <= linkid) { + transfer_direction = 0; + numtransfers = 0; + // if this is the one that was dropped, reconnect + if (!(linkmem->linkflags & (1 << linkid))) + ReconnectCableIPC(); + return; + } - // sync clock - if (numtransfers == 1) - linktime = 0; - else - linktime -= linkmem->lastlinktime; + // sync clock + if (numtransfers == 1) + linktime = 0; + else + linktime -= linkmem->lastlinktime; - // there's really no point to this switch; 'M' is the only - // possible command. +// there's really no point to this switch; 'M' is the only +// possible command. #if 0 switch ((linkmem->linkcmd) >> 8) { case 'M': #endif - tspeed = linkmem->linkcmd[0] & 3; - transfer_direction = 1; - WRITE32LE(&ioMem[COMM_SIOMULTI0], 0xffffffff); - WRITE32LE(&ioMem[COMM_SIOMULTI2], 0xffffffff); - UPDATE_REG(COMM_SIOCNT, READ16LE(&ioMem[COMM_SIOCNT]) & ~0x40 | 0x80); + tspeed = linkmem->linkcmd[0] & 3; + transfer_direction = 1; + WRITE32LE(&ioMem[COMM_SIOMULTI0], 0xffffffff); + WRITE32LE(&ioMem[COMM_SIOMULTI2], 0xffffffff); + UPDATE_REG(COMM_SIOCNT, READ16LE(&ioMem[COMM_SIOCNT]) & ~0x40 | 0x80); #if 0 break; } #endif - } + } - if (!transfer_direction) - return; + if (!transfer_direction) + return; - if (transfer_direction <= linkmem->trgbas && linktime >= trtimedata[transfer_direction-1][tspeed]) - { - // transfer #n -> wait for value n - 1 - if(transfer_direction > 1 && linkid != transfer_direction - 1) { - if(WaitForSingleObject(linksync[transfer_direction - 1], linktimeout) == WAIT_TIMEOUT) { - // assume slave has dropped off if timed out - if(!linkid) { - linkmem->trgbas = transfer_direction - 1; - int f = linkmem->linkflags; - f &= ~(1 << (transfer_direction - 1)); - linkmem->linkflags = f; - if(f < (1 << transfer_direction) - 1) - linkmem->numgbas = transfer_direction - 1; - char message[30]; - sprintf(message, _("Player %d disconnected."), transfer_direction - 1); - systemScreenMessage(message); - } - transfer_direction = linkmem->trgbas + 1; - // next cycle, transfer will finish up - return; - } - } - // now that value is available, store it - UPDATE_REG((COMM_SIOMULTI0 - 2) + (transfer_direction << 1), linkmem->linkdata[transfer_direction - 1]); + if (transfer_direction <= linkmem->trgbas && linktime >= trtimedata[transfer_direction - 1][tspeed]) { + // transfer #n -> wait for value n - 1 + if (transfer_direction > 1 && linkid != transfer_direction - 1) { + if (WaitForSingleObject(linksync[transfer_direction - 1], linktimeout) == WAIT_TIMEOUT) { + // assume slave has dropped off if timed out + if (!linkid) { + linkmem->trgbas = transfer_direction - 1; + int f = linkmem->linkflags; + f &= ~(1 << (transfer_direction - 1)); + linkmem->linkflags = f; + if (f < (1 << transfer_direction) - 1) + linkmem->numgbas = transfer_direction - 1; + char message[30]; + sprintf(message, _("Player %d disconnected."), transfer_direction - 1); + systemScreenMessage(message); + } + transfer_direction = linkmem->trgbas + 1; + // next cycle, transfer will finish up + return; + } + } + // now that value is available, store it + UPDATE_REG((COMM_SIOMULTI0 - 2) + (transfer_direction << 1), linkmem->linkdata[transfer_direction - 1]); - // transfer machine's value at start of its transfer cycle - if(linkid == transfer_direction) { - // skip if dropped - if(linkmem->trgbas <= linkid) { - transfer_direction = 0; - numtransfers = 0; - // if this is the one that was dropped, reconnect - if(!(linkmem->linkflags & (1 << linkid))) - ReconnectCableIPC(); - return; - } - // SI becomes low - UPDATE_REG(COMM_SIOCNT, READ16LE(&ioMem[COMM_SIOCNT]) & ~4); - UPDATE_REG(COMM_RCNT, 10); - linkmem->linkdata[linkid] = READ16LE(&ioMem[COMM_SIODATA8]); - ReleaseSemaphore(linksync[linkid], linkmem->numgbas-1, NULL); - } - if(linkid == transfer_direction - 1) { - // SO becomes low to begin next trasnfer - // may need to set DDR as well - UPDATE_REG(COMM_RCNT, 0x22); - } + // transfer machine's value at start of its transfer cycle + if (linkid == transfer_direction) { + // skip if dropped + if (linkmem->trgbas <= linkid) { + transfer_direction = 0; + numtransfers = 0; + // if this is the one that was dropped, reconnect + if (!(linkmem->linkflags & (1 << linkid))) + ReconnectCableIPC(); + return; + } + // SI becomes low + UPDATE_REG(COMM_SIOCNT, READ16LE(&ioMem[COMM_SIOCNT]) & ~4); + UPDATE_REG(COMM_RCNT, 10); + linkmem->linkdata[linkid] = READ16LE(&ioMem[COMM_SIODATA8]); + ReleaseSemaphore(linksync[linkid], linkmem->numgbas - 1, NULL); + } + if (linkid == transfer_direction - 1) { + // SO becomes low to begin next trasnfer + // may need to set DDR as well + UPDATE_REG(COMM_RCNT, 0x22); + } - // next cycle - transfer_direction++; - } + // next cycle + transfer_direction++; + } - if (transfer_direction > linkmem->trgbas && linktime >= trtimeend[transfer_direction-3][tspeed]) - { - // wait for slaves to finish - // this keeps unfinished slaves from screwing up last xfer - // not strictly necessary; may just slow things down - if(!linkid) { - for(int i = 2; i < transfer_direction; i++) - if(WaitForSingleObject(linksync[0], linktimeout) == WAIT_TIMEOUT) { - // impossible to determine which slave died - // so leave them alone for now - systemScreenMessage(_("Unknown slave timed out; resetting comm")); - linkmem->numtransfers = numtransfers = 0; - break; - } - } else if(linkmem->trgbas > linkid) - // signal master that this slave is finished - ReleaseSemaphore(linksync[0], 1, NULL); - linktime -= trtimeend[transfer_direction - 3][tspeed]; - transfer_direction = 0; - u16 value = READ16LE(&ioMem[COMM_SIOCNT]); - if(!linkid) - value |= 4; // SI becomes high on slaves after xfer - UPDATE_REG(COMM_SIOCNT, (value & 0xff0f) | (linkid << 4)); - // SC/SI high after transfer - UPDATE_REG(COMM_RCNT, linkid ? 15 : 11); - if (value & 0x4000) - { - IF |= 0x80; - UPDATE_REG(0x202, IF); - } - } + if (transfer_direction > linkmem->trgbas && linktime >= trtimeend[transfer_direction - 3][tspeed]) { + // wait for slaves to finish + // this keeps unfinished slaves from screwing up last xfer + // not strictly necessary; may just slow things down + if (!linkid) { + for (int i = 2; i < transfer_direction; i++) + if (WaitForSingleObject(linksync[0], linktimeout) == WAIT_TIMEOUT) { + // impossible to determine which slave died + // so leave them alone for now + systemScreenMessage(_("Unknown slave timed out; resetting comm")); + linkmem->numtransfers = numtransfers = 0; + break; + } + } else if (linkmem->trgbas > linkid) + // signal master that this slave is finished + ReleaseSemaphore(linksync[0], 1, NULL); + linktime -= trtimeend[transfer_direction - 3][tspeed]; + transfer_direction = 0; + u16 value = READ16LE(&ioMem[COMM_SIOCNT]); + if (!linkid) + value |= 4; // SI becomes high on slaves after xfer + UPDATE_REG(COMM_SIOCNT, (value & 0xff0f) | (linkid << 4)); + // SC/SI high after transfer + UPDATE_REG(COMM_RCNT, linkid ? 15 : 11); + if (value & 0x4000) { + IF |= 0x80; + UPDATE_REG(0x202, IF); + } + } } // The GBA wireless RFU (see adapter3.txt) static void StartRFU(u16 value) { - int siomode = GetSIOMode(value, READ16LE(&ioMem[COMM_RCNT])); + int siomode = GetSIOMode(value, READ16LE(&ioMem[COMM_RCNT])); - if (value) - rfu_enabled = (siomode == NORMAL32); + if (value) + rfu_enabled = (siomode == NORMAL32); - if (((READ16LE(&ioMem[COMM_SIOCNT]) & 0x5080) == 0x1000) && ((value & 0x5080) == 0x5080)) { //RFU Reset, may also occur before cable link started - log("RFU Reset2 : %04X %04X %d\n", READ16LE(&ioMem[COMM_RCNT]), READ16LE(&ioMem[COMM_SIOCNT]), GetTickCount()); - linkmem->rfu_listfront[vbaid] = 0; - linkmem->rfu_listback[vbaid] = 0; - } + if (((READ16LE(&ioMem[COMM_SIOCNT]) & 0x5080) == 0x1000) && ((value & 0x5080) == 0x5080)) { //RFU Reset, may also occur before cable link started + log("RFU Reset2 : %04X %04X %d\n", READ16LE(&ioMem[COMM_RCNT]), READ16LE(&ioMem[COMM_SIOCNT]), GetTickCount()); + linkmem->rfu_listfront[vbaid] = 0; + linkmem->rfu_listback[vbaid] = 0; + } - if (!rfu_enabled) - { - if ((value & 0x5080) == 0x5080) { //0x5083 //game tried to send wireless command but w/o the adapter - /*if (value & 8) //Transfer Enable Flag Send (bit.3, 1=Disable Transfer/Not Ready) + if (!rfu_enabled) { + if ((value & 0x5080) == 0x5080) { //0x5083 //game tried to send wireless command but w/o the adapter + /*if (value & 8) //Transfer Enable Flag Send (bit.3, 1=Disable Transfer/Not Ready) value &= 0xfffb; //Transfer enable flag receive (0=Enable Transfer/Ready, bit.2=bit.3 of otherside) // A kind of acknowledge procedure else //(Bit.3, 0=Enable Transfer/Ready) value |= 4; //bit.2=1 (otherside is Not Ready)*/ - if (READ16LE(&ioMem[COMM_SIOCNT]) & 0x4000) //IRQ Enable - { - IF |= 0x80; //Serial Communication - UPDATE_REG(0x202, IF); //Interrupt Request Flags / IRQ Acknowledge - } - value &= 0xff7f; //Start bit.7 reset //may cause the game to retry sending again - //value |= 0x0008; //SO bit.3 set automatically upon transfer completion - transfer_direction = 0; - } - return; - } + if (READ16LE(&ioMem[COMM_SIOCNT]) & 0x4000) //IRQ Enable + { + IF |= 0x80; //Serial Communication + UPDATE_REG(0x202, IF); //Interrupt Request Flags / IRQ Acknowledge + } + value &= 0xff7f; //Start bit.7 reset //may cause the game to retry sending again + //value |= 0x0008; //SO bit.3 set automatically upon transfer completion + transfer_direction = 0; + } + return; + } + linktimeout = 1; - linktimeout = 1; + static bool logstartd; + u32 CurCOM = 0, CurDAT = 0; + bool rfulogd = (READ16LE(&ioMem[COMM_SIOCNT]) != value); - static bool logstartd; - u32 CurCOM = 0, CurDAT = 0; - bool rfulogd = (READ16LE(&ioMem[COMM_SIOCNT]) != value); + switch (GetSIOMode(value, READ16LE(&ioMem[COMM_RCNT]))) { + case NORMAL8: + rfu_polarity = 0; + UPDATE_REG(COMM_SIOCNT, value); + return; + break; + case NORMAL32: + //don't do anything if previous cmd aren't sent yet, may fix Boktai2 Not Detecting wireless adapter + if (transfer_direction) { + UPDATE_REG(COMM_SIOCNT, value); + return; + } - switch (GetSIOMode(value, READ16LE(&ioMem[COMM_RCNT]))) { - case NORMAL8: - rfu_polarity = 0; - UPDATE_REG(COMM_SIOCNT, value); - return; - break; - case NORMAL32: - //don't do anything if previous cmd aren't sent yet, may fix Boktai2 Not Detecting wireless adapter - if (transfer_direction) - { - UPDATE_REG(COMM_SIOCNT, value); - return; - } + //Moving this to the bottom might prevent Mario Golf Adv from Occasionally Not Detecting wireless adapter + if (value & 8) //Transfer Enable Flag Send (SO.bit.3, 1=Disable Transfer/Not Ready) + value &= 0xfffb; //Transfer enable flag receive (0=Enable Transfer/Ready, SI.bit.2=SO.bit.3 of otherside) // A kind of acknowledge procedure + else //(SO.Bit.3, 0=Enable Transfer/Ready) + value |= 4; //SI.bit.2=1 (otherside is Not Ready) - //Moving this to the bottom might prevent Mario Golf Adv from Occasionally Not Detecting wireless adapter - if (value & 8) //Transfer Enable Flag Send (SO.bit.3, 1=Disable Transfer/Not Ready) - value &= 0xfffb; //Transfer enable flag receive (0=Enable Transfer/Ready, SI.bit.2=SO.bit.3 of otherside) // A kind of acknowledge procedure - else //(SO.Bit.3, 0=Enable Transfer/Ready) - value |= 4; //SI.bit.2=1 (otherside is Not Ready) + if ((value & 5) == 1) + value |= 0x02; //wireless always use 2Mhz speed right? this will fix MarioGolfAdv Not Detecting wireless - if ((value & 5) == 1) - value |= 0x02; //wireless always use 2Mhz speed right? this will fix MarioGolfAdv Not Detecting wireless - - if (value & 0x80) //start/busy bit - { - if ((value & 3) == 1) - rfu_transfer_end = 2048; - else - rfu_transfer_end = 256; - u16 siodata_h = READ16LE(&ioMem[COMM_SIODATA32_H]); - switch (rfu_state) { - case RFU_INIT: - if (READ32LE(&ioMem[COMM_SIODATA32_L]) == 0xb0bb8001) - { - rfu_state = RFU_COMM; // end of startup - rfu_initialized = true; - value &= 0xfffb; //0xff7b; //Bit.2 need to be 0 to indicate a finished initialization to fix MarioGolfAdv from occasionally Not Detecting wireless adapter (prevent it from sending 0x7FFE8001 comm)? - rfu_polarity = 0; //not needed? - } - rfu_buf = (READ16LE(&ioMem[COMM_SIODATA32_L]) << 16) | siodata_h; - break; - case RFU_COMM: - CurCOM = READ32LE(&ioMem[COMM_SIODATA32_L]); - if (siodata_h == 0x9966) //initialize cmd - { - u8 tmpcmd = CurCOM; - if (tmpcmd != 0x10 && tmpcmd != 0x11 && tmpcmd != 0x13 && tmpcmd != 0x14 && tmpcmd != 0x16 && tmpcmd != 0x17 && tmpcmd != 0x19 && tmpcmd != 0x1a && tmpcmd != 0x1b && tmpcmd != 0x1c && tmpcmd != 0x1d && tmpcmd != 0x1e && tmpcmd != 0x1f && tmpcmd != 0x20 && tmpcmd != 0x21 && tmpcmd != 0x24 && tmpcmd != 0x25 && tmpcmd != 0x26 && tmpcmd != 0x27 && tmpcmd != 0x30 && tmpcmd != 0x32 && tmpcmd != 0x33 && tmpcmd != 0x34 && tmpcmd != 0x3d && tmpcmd != 0xa8 && tmpcmd != 0xee) { - log("%08X : UnkCMD %08X %04X %08X %08X\n", GetTickCount(), CurCOM, PrevVAL, PrevCOM, PrevDAT); - } - rfu_counter = 0; - if ((rfu_qsend2 = rfu_qsend = ioMem[0x121]) != 0) { //COMM_SIODATA32_L+1, following data [to send] - rfu_state = RFU_SEND; - } - if (ioMem[COMM_SIODATA32_L] == 0xee) { //0xee cmd shouldn't override previous cmd - rfu_lastcmd = rfu_cmd2; - rfu_cmd2 = ioMem[COMM_SIODATA32_L]; - //rfu_polarity = 0; //when polarity back to normal the game can initiate a new cmd even when 0xee hasn't been finalized, but it looks improper isn't? - } - else{ - rfu_lastcmd = rfu_cmd; - rfu_cmd = ioMem[COMM_SIODATA32_L]; - rfu_cmd2 = 0; - int maskid; - if (rfu_cmd == 0x27 || rfu_cmd == 0x37) { - rfu_lastcmd2 = rfu_cmd; - rfu_lasttime = GetTickCount(); - } - else - if (rfu_cmd == 0x24) { //non-important data shouldn't overwrite important data from 0x25 - rfu_lastcmd2 = rfu_cmd; - rfu_cansend = false; - if (rfu_ishost) - maskid = ~linkmem->rfu_is_host[vbaid]; else - maskid = ~(1 << gbaid); - //previous important data need to be received successfully before sending another important data - rfu_lasttime = GetTickCount(); //just to mark the last time a data being sent - if (!speedhack) { - while (linkmem->numgbas >= 2 && - linkmem->rfu_q[vbaid] > 1 && - vbaid != gbaid && - linkmem->rfu_signal[vbaid] && - linkmem->rfu_signal[gbaid] && - (GetTickCount() - rfu_lasttime) < (DWORD)linktimeout) { - if (!rfu_ishost) - SetEvent(linksync[gbaid]); else //unlock other gba, allow other gba to move (sending their data) //is max value of vbaid=1 ? - for (int j = 0; j < linkmem->numgbas; j++) - if (j != vbaid)SetEvent(linksync[j]); - WaitForSingleObject(linksync[vbaid], 1); //linktimeout //wait until this gba allowed to move (to prevent both GBAs from using 0x25 at the same time) - ResetEvent(linksync[vbaid]); //lock this gba, don't allow this gba to move (prevent sending another data too fast w/o giving the other side chances to read it) - if (!rfu_ishost&&linkmem->rfu_is_host[vbaid]) { linkmem->rfu_is_host[vbaid] = 0; break; } //workaround for a bug where rfu_request failed to reset when GBA act as client - } - } - //SetEvent(linksync[vbaid]); //set again to reduce the lag since it will be waited again during finalization cmd - else{ - if (linkmem->numgbas >= 2 && gbaid != vbaid&&linkmem->rfu_q[vbaid] > 1 && linkmem->rfu_signal[vbaid] && linkmem->rfu_signal[gbaid]) { - if (!rfu_ishost) - SetEvent(linksync[gbaid]); else //unlock other gba, allow other gba to move (sending their data) //is max value of vbaid=1 ? - for (int j = 0; j < linkmem->numgbas; j++) - if (j != vbaid)SetEvent(linksync[j]); - WaitForSingleObject(linksync[vbaid], speedhack ? 1 : linktimeout); //wait until this gba allowed to move - ResetEvent(linksync[vbaid]); //lock this gba, don't allow this gba to move (prevent sending another data too fast w/o giving the other side chances to read it) - } - } - if (linkmem->rfu_q[vbaid] < 2) { //can overwrite now - rfu_cansend = true; - linkmem->rfu_q[vbaid] = 0; //rfu_qsend; - linkmem->rfu_qid[vbaid] = 0; - } - else if (!speedhack)rfu_waiting = true; //don't wait with speedhack - } - else - if (rfu_cmd == 0x25 || rfu_cmd == 0x35) { - rfu_lastcmd2 = rfu_cmd; - rfu_cansend = false; - if (rfu_ishost) - maskid = ~linkmem->rfu_is_host[vbaid]; else - maskid = ~(1 << gbaid); - //previous important data need to be received successfully before sending another important data - rfu_lasttime = GetTickCount(); - if (!speedhack) { - //2 players connected - while (linkmem->numgbas >= 2 && - linkmem->rfu_q[vbaid] > 1 && - vbaid != gbaid&&linkmem->rfu_signal[vbaid] && - linkmem->rfu_signal[gbaid] && - (GetTickCount() - rfu_lasttime) < (DWORD)linktimeout) { - if (!rfu_ishost) - SetEvent(linksync[gbaid]); //unlock other gba, allow other gba to move (sending their data) //is max value of vbaid=1 ? - else - for (int j = 0; j < linkmem->numgbas; j++) - if (j != vbaid)SetEvent(linksync[j]); - WaitForSingleObject(linksync[vbaid], 1); //linktimeout //wait until this gba allowed to move (to prevent both GBAs from using 0x25 at the same time) - ResetEvent(linksync[vbaid]); //lock this gba, don't allow this gba to move (prevent sending another data too fast w/o giving the other side chances to read it) - if (!rfu_ishost&&linkmem->rfu_is_host[vbaid]) { linkmem->rfu_is_host[vbaid] = 0; break; } //workaround for a bug where rfu_request failed to reset when GBA act as client - } - } - //SetEvent(linksync[vbaid]); //set again to reduce the lag since it will be waited again during finalization cmd - else{ - //2 players connected - if (linkmem->numgbas >= 2 && gbaid != vbaid&&linkmem->rfu_q[vbaid] > 1 && linkmem->rfu_signal[vbaid] && linkmem->rfu_signal[gbaid]) { - if (!rfu_ishost) - SetEvent(linksync[gbaid]); else //unlock other gba, allow other gba to move (sending their data) //is max value of vbaid=1 ? - for (int j = 0; j < linkmem->numgbas; j++) - if (j != vbaid)SetEvent(linksync[j]); - WaitForSingleObject(linksync[vbaid], speedhack ? 1 : linktimeout); //wait until this gba allowed to move - ResetEvent(linksync[vbaid]); //lock this gba, don't allow this gba to move (prevent sending another data too fast w/o giving the other side chances to read it) - } - } - if (linkmem->rfu_q[vbaid] < 2) { - rfu_cansend = true; - linkmem->rfu_q[vbaid] = 0; //rfu_qsend; - linkmem->rfu_qid[vbaid] = 0; //don't wait with speedhack - } - else if (!speedhack)rfu_waiting = true; - } - else - if (rfu_cmd == 0xa8 || rfu_cmd == 0xb6) { - //wait for [important] data when previously sent is important data, might only need to wait for the 1st 0x25 cmd - bool ok = false; - } - else - if (rfu_cmd == 0x11 || rfu_cmd == 0x1a || rfu_cmd == 0x26) { - if (rfu_lastcmd2 == 0x24) - rfu_waiting = true; - } - } - if (rfu_waiting)rfu_buf = READ32LE(&ioMem[COMM_SIODATA32_L]); else - rfu_buf = 0x80000000; - } - else if (siodata_h == 0x8000) //finalize cmd, the game will send this when polarity reversed (expecting something) - { - rfu_qrecv_broadcast_data_len = 0; - if (rfu_cmd2 == 0xee) { - if (rfu_masterdata[0] == 2) //is this value of 2 related to polarity? - rfu_polarity = 0; //to normalize polarity after finalize looks more proper - rfu_buf = 0x99660000 | (rfu_qrecv_broadcast_data_len << 8) | (rfu_cmd2 ^ 0x80); - } - else{ - switch (rfu_cmd) { - case 0x1a: // check if someone joined - if (linkmem->rfu_is_host[vbaid]) { - gbaidx = gbaid; - do{ - gbaidx = (gbaidx + 1) % linkmem->numgbas; - if (gbaidx != vbaid&&linkmem->rfu_reqid[gbaidx] == (vbaid << 3) + 0x61f1)rfu_masterdata[rfu_qrecv_broadcast_data_len++] = (gbaidx << 3) + 0x61f1; - log("qrecv++ %d\n", rfu_qrecv_broadcast_data_len); - } while (gbaidx != gbaid&&linkmem->numgbas >= 2); - if (rfu_qrecv_broadcast_data_len > 0) { - bool ok = false; - for (int i = 0; i < rfu_numclients; i++) - if ((rfu_clientlist[i] & 0xffff) == rfu_masterdata[0]) { ok = true; break; } - if (!ok) { - rfu_curclient = rfu_numclients; - linkmem->rfu_clientidx[(rfu_masterdata[0] - 0x61f1) >> 3] = rfu_numclients; - rfu_clientlist[rfu_numclients] = rfu_masterdata[0] | (rfu_numclients++ << 16); - gbaid = (rfu_masterdata[0] - 0x61f1) >> 3; - linkmem->rfu_signal[gbaid] = 0xffffffff >> ((3 - (rfu_numclients - 1)) << 3); - } - if (gbaid == vbaid) { - gbaid = (rfu_masterdata[0] - 0x61f1) >> 3; - } - rfu_state = RFU_RECV; - } - } - if (rfu_numclients > 0) { - for (int i = 0; i < rfu_numclients; i++)rfu_masterdata[i] = rfu_clientlist[i]; - } - rfu_id = (gbaid << 3) + 0x61f1; - rfu_cmd ^= 0x80; - break; - case 0x1f: // join a room as client - // TODO: to fix infinte send&recv w/o giving much cance to update the screen when both side acting as client - // on MarioGolfAdv lobby(might be due to leftover data when switching from host to join mode at the same time?) - rfu_id = rfu_masterdata[0]; - gbaid = (rfu_id - 0x61f1) >> 3; - rfu_idx = rfu_id; - gbaidx = gbaid; - rfu_lastcmd2 = 0; - numtransfers = 0; - linkmem->rfu_q[vbaid] = 0; //to prevent leftover data from previous session received immediately in the new session - linkmem->rfu_reqid[vbaid] = rfu_id; - // TODO:might failed to reset rfu_request when being accessed by otherside at the same time, sometimes both acting - // as client but one of them still have request[vbaid]!=0 //to prevent both GBAs from acting as Host, client can't - // be a host at the same time - linkmem->rfu_is_host[vbaid] = 0; - if (vbaid != gbaid) { - linkmem->rfu_signal[vbaid] = 0x00ff; - linkmem->rfu_is_host[gbaid] |= 1 << vbaid; // tells the other GBA(a host) that someone(a client) is joining - } - rfu_cmd ^= 0x80; - break; - case 0x1e: // receive broadcast data - numtransfers = 0; - rfu_numclients = 0; - linkmem->rfu_is_host[vbaid] = 0; //to prevent both GBAs from acting as Host and thinking both of them have Client? - linkmem->rfu_q[vbaid] = 0; //to prevent leftover data from previous session received immediately in the new session - case 0x1d: // no visible difference - linkmem->rfu_is_host[vbaid] = 0; - memset(rfu_masterdata, 0, sizeof(linkmem->rfu_broadcastdata[vbaid])); - rfu_qrecv_broadcast_data_len = 0; - for (int i = 0; i < linkmem->numgbas; i++) - { - if (i != vbaid&&linkmem->rfu_broadcastdata[i][0]) { - memcpy(&rfu_masterdata[rfu_qrecv_broadcast_data_len], linkmem->rfu_broadcastdata[i], sizeof(linkmem->rfu_broadcastdata[i])); - rfu_qrecv_broadcast_data_len += 7; - } - } - // is this needed? to prevent MarioGolfAdv from joining it's own room when switching - // from host to client mode due to left over room data in the game buffer? - // if(rfu_qrecv==0) rfu_qrecv = 7; - if (rfu_qrecv_broadcast_data_len > 0) - rfu_state = RFU_RECV; - rfu_polarity = 0; - rfu_counter = 0; - rfu_cmd ^= 0x80; - break; - case 0x16: // send broadcast data (ie. room name) - //start broadcasting here may cause client to join other client in pokemon coloseum - //linkmem->rfu_bdata[vbaid][0] = (vbaid<<3)+0x61f1; - //linkmem->rfu_q[vbaid] = 0; - rfu_cmd ^= 0x80; - break; - case 0x11: // get signal strength - //Switch remote id - if (linkmem->rfu_is_host[vbaid]) { //is a host - /*//gbaid = 1-vbaid; //linkmem->rfu_request[vbaid] & 1; + if (value & 0x80) //start/busy bit + { + if ((value & 3) == 1) + rfu_transfer_end = 2048; + else + rfu_transfer_end = 256; + u16 siodata_h = READ16LE(&ioMem[COMM_SIODATA32_H]); + switch (rfu_state) { + case RFU_INIT: + if (READ32LE(&ioMem[COMM_SIODATA32_L]) == 0xb0bb8001) { + rfu_state = RFU_COMM; // end of startup + rfu_initialized = true; + value &= 0xfffb; //0xff7b; //Bit.2 need to be 0 to indicate a finished initialization to fix MarioGolfAdv from occasionally Not Detecting wireless adapter (prevent it from sending 0x7FFE8001 comm)? + rfu_polarity = 0; //not needed? + } + rfu_buf = (READ16LE(&ioMem[COMM_SIODATA32_L]) << 16) | siodata_h; + break; + case RFU_COMM: + CurCOM = READ32LE(&ioMem[COMM_SIODATA32_L]); + if (siodata_h == 0x9966) //initialize cmd + { + u8 tmpcmd = CurCOM; + if (tmpcmd != 0x10 && tmpcmd != 0x11 && tmpcmd != 0x13 && tmpcmd != 0x14 && tmpcmd != 0x16 && tmpcmd != 0x17 && tmpcmd != 0x19 && tmpcmd != 0x1a && tmpcmd != 0x1b && tmpcmd != 0x1c && tmpcmd != 0x1d && tmpcmd != 0x1e && tmpcmd != 0x1f && tmpcmd != 0x20 && tmpcmd != 0x21 && tmpcmd != 0x24 && tmpcmd != 0x25 && tmpcmd != 0x26 && tmpcmd != 0x27 && tmpcmd != 0x30 && tmpcmd != 0x32 && tmpcmd != 0x33 && tmpcmd != 0x34 && tmpcmd != 0x3d && tmpcmd != 0xa8 && tmpcmd != 0xee) { + log("%08X : UnkCMD %08X %04X %08X %08X\n", GetTickCount(), CurCOM, PrevVAL, PrevCOM, PrevDAT); + } + rfu_counter = 0; + if ((rfu_qsend2 = rfu_qsend = ioMem[0x121]) != 0) { //COMM_SIODATA32_L+1, following data [to send] + rfu_state = RFU_SEND; + } + if (ioMem[COMM_SIODATA32_L] == 0xee) { //0xee cmd shouldn't override previous cmd + rfu_lastcmd = rfu_cmd2; + rfu_cmd2 = ioMem[COMM_SIODATA32_L]; + //rfu_polarity = 0; //when polarity back to normal the game can initiate a new cmd even when 0xee hasn't been finalized, but it looks improper isn't? + } else { + rfu_lastcmd = rfu_cmd; + rfu_cmd = ioMem[COMM_SIODATA32_L]; + rfu_cmd2 = 0; + int maskid; + if (rfu_cmd == 0x27 || rfu_cmd == 0x37) { + rfu_lastcmd2 = rfu_cmd; + rfu_lasttime = GetTickCount(); + } else if (rfu_cmd == 0x24) { //non-important data shouldn't overwrite important data from 0x25 + rfu_lastcmd2 = rfu_cmd; + rfu_cansend = false; + if (rfu_ishost) + maskid = ~linkmem->rfu_is_host[vbaid]; + else + maskid = ~(1 << gbaid); + //previous important data need to be received successfully before sending another important data + rfu_lasttime = GetTickCount(); //just to mark the last time a data being sent + if (!speedhack) { + while (linkmem->numgbas >= 2 && linkmem->rfu_q[vbaid] > 1 && vbaid != gbaid && linkmem->rfu_signal[vbaid] && linkmem->rfu_signal[gbaid] && (GetTickCount() - rfu_lasttime) < (DWORD)linktimeout) { + if (!rfu_ishost) + SetEvent(linksync[gbaid]); + else //unlock other gba, allow other gba to move (sending their data) //is max value of vbaid=1 ? + for (int j = 0; j < linkmem->numgbas; j++) + if (j != vbaid) + SetEvent(linksync[j]); + WaitForSingleObject(linksync[vbaid], 1); //linktimeout //wait until this gba allowed to move (to prevent both GBAs from using 0x25 at the same time) + ResetEvent(linksync[vbaid]); //lock this gba, don't allow this gba to move (prevent sending another data too fast w/o giving the other side chances to read it) + if (!rfu_ishost && linkmem->rfu_is_host[vbaid]) { + linkmem->rfu_is_host[vbaid] = 0; + break; + } //workaround for a bug where rfu_request failed to reset when GBA act as client + } + } + //SetEvent(linksync[vbaid]); //set again to reduce the lag since it will be waited again during finalization cmd + else { + if (linkmem->numgbas >= 2 && gbaid != vbaid && linkmem->rfu_q[vbaid] > 1 && linkmem->rfu_signal[vbaid] && linkmem->rfu_signal[gbaid]) { + if (!rfu_ishost) + SetEvent(linksync[gbaid]); + else //unlock other gba, allow other gba to move (sending their data) //is max value of vbaid=1 ? + for (int j = 0; j < linkmem->numgbas; j++) + if (j != vbaid) + SetEvent(linksync[j]); + WaitForSingleObject(linksync[vbaid], speedhack ? 1 : linktimeout); //wait until this gba allowed to move + ResetEvent(linksync[vbaid]); //lock this gba, don't allow this gba to move (prevent sending another data too fast w/o giving the other side chances to read it) + } + } + if (linkmem->rfu_q[vbaid] < 2) { //can overwrite now + rfu_cansend = true; + linkmem->rfu_q[vbaid] = 0; //rfu_qsend; + linkmem->rfu_qid[vbaid] = 0; + } else if (!speedhack) + rfu_waiting = true; //don't wait with speedhack + } else if (rfu_cmd == 0x25 || rfu_cmd == 0x35) { + rfu_lastcmd2 = rfu_cmd; + rfu_cansend = false; + if (rfu_ishost) + maskid = ~linkmem->rfu_is_host[vbaid]; + else + maskid = ~(1 << gbaid); + //previous important data need to be received successfully before sending another important data + rfu_lasttime = GetTickCount(); + if (!speedhack) { + //2 players connected + while (linkmem->numgbas >= 2 && linkmem->rfu_q[vbaid] > 1 && vbaid != gbaid && linkmem->rfu_signal[vbaid] && linkmem->rfu_signal[gbaid] && (GetTickCount() - rfu_lasttime) < (DWORD)linktimeout) { + if (!rfu_ishost) + SetEvent(linksync[gbaid]); //unlock other gba, allow other gba to move (sending their data) //is max value of vbaid=1 ? + else + for (int j = 0; j < linkmem->numgbas; j++) + if (j != vbaid) + SetEvent(linksync[j]); + WaitForSingleObject(linksync[vbaid], 1); //linktimeout //wait until this gba allowed to move (to prevent both GBAs from using 0x25 at the same time) + ResetEvent(linksync[vbaid]); //lock this gba, don't allow this gba to move (prevent sending another data too fast w/o giving the other side chances to read it) + if (!rfu_ishost && linkmem->rfu_is_host[vbaid]) { + linkmem->rfu_is_host[vbaid] = 0; + break; + } //workaround for a bug where rfu_request failed to reset when GBA act as client + } + } + //SetEvent(linksync[vbaid]); //set again to reduce the lag since it will be waited again during finalization cmd + else { + //2 players connected + if (linkmem->numgbas >= 2 && gbaid != vbaid && linkmem->rfu_q[vbaid] > 1 && linkmem->rfu_signal[vbaid] && linkmem->rfu_signal[gbaid]) { + if (!rfu_ishost) + SetEvent(linksync[gbaid]); + else //unlock other gba, allow other gba to move (sending their data) //is max value of vbaid=1 ? + for (int j = 0; j < linkmem->numgbas; j++) + if (j != vbaid) + SetEvent(linksync[j]); + WaitForSingleObject(linksync[vbaid], speedhack ? 1 : linktimeout); //wait until this gba allowed to move + ResetEvent(linksync[vbaid]); //lock this gba, don't allow this gba to move (prevent sending another data too fast w/o giving the other side chances to read it) + } + } + if (linkmem->rfu_q[vbaid] < 2) { + rfu_cansend = true; + linkmem->rfu_q[vbaid] = 0; //rfu_qsend; + linkmem->rfu_qid[vbaid] = 0; //don't wait with speedhack + } else if (!speedhack) + rfu_waiting = true; + } else if (rfu_cmd == 0xa8 || rfu_cmd == 0xb6) { + //wait for [important] data when previously sent is important data, might only need to wait for the 1st 0x25 cmd + bool ok = false; + } else if (rfu_cmd == 0x11 || rfu_cmd == 0x1a || rfu_cmd == 0x26) { + if (rfu_lastcmd2 == 0x24) + rfu_waiting = true; + } + } + if (rfu_waiting) + rfu_buf = READ32LE(&ioMem[COMM_SIODATA32_L]); + else + rfu_buf = 0x80000000; + } else if (siodata_h == 0x8000) //finalize cmd, the game will send this when polarity reversed (expecting something) + { + rfu_qrecv_broadcast_data_len = 0; + if (rfu_cmd2 == 0xee) { + if (rfu_masterdata[0] == 2) //is this value of 2 related to polarity? + rfu_polarity = 0; //to normalize polarity after finalize looks more proper + rfu_buf = 0x99660000 | (rfu_qrecv_broadcast_data_len << 8) | (rfu_cmd2 ^ 0x80); + } else { + switch (rfu_cmd) { + case 0x1a: // check if someone joined + if (linkmem->rfu_is_host[vbaid]) { + gbaidx = gbaid; + do { + gbaidx = (gbaidx + 1) % linkmem->numgbas; + if (gbaidx != vbaid && linkmem->rfu_reqid[gbaidx] == (vbaid << 3) + 0x61f1) + rfu_masterdata[rfu_qrecv_broadcast_data_len++] = (gbaidx << 3) + 0x61f1; + log("qrecv++ %d\n", rfu_qrecv_broadcast_data_len); + } while (gbaidx != gbaid && linkmem->numgbas >= 2); + if (rfu_qrecv_broadcast_data_len > 0) { + bool ok = false; + for (int i = 0; i < rfu_numclients; i++) + if ((rfu_clientlist[i] & 0xffff) == rfu_masterdata[0]) { + ok = true; + break; + } + if (!ok) { + rfu_curclient = rfu_numclients; + linkmem->rfu_clientidx[(rfu_masterdata[0] - 0x61f1) >> 3] = rfu_numclients; + rfu_clientlist[rfu_numclients] = rfu_masterdata[0] | (rfu_numclients++ << 16); + gbaid = (rfu_masterdata[0] - 0x61f1) >> 3; + linkmem->rfu_signal[gbaid] = 0xffffffff >> ((3 - (rfu_numclients - 1)) << 3); + } + if (gbaid == vbaid) { + gbaid = (rfu_masterdata[0] - 0x61f1) >> 3; + } + rfu_state = RFU_RECV; + } + } + if (rfu_numclients > 0) { + for (int i = 0; i < rfu_numclients; i++) + rfu_masterdata[i] = rfu_clientlist[i]; + } + rfu_id = (gbaid << 3) + 0x61f1; + rfu_cmd ^= 0x80; + break; + case 0x1f: // join a room as client + // TODO: to fix infinte send&recv w/o giving much cance to update the screen when both side acting as client + // on MarioGolfAdv lobby(might be due to leftover data when switching from host to join mode at the same time?) + rfu_id = rfu_masterdata[0]; + gbaid = (rfu_id - 0x61f1) >> 3; + rfu_idx = rfu_id; + gbaidx = gbaid; + rfu_lastcmd2 = 0; + numtransfers = 0; + linkmem->rfu_q[vbaid] = 0; //to prevent leftover data from previous session received immediately in the new session + linkmem->rfu_reqid[vbaid] = rfu_id; + // TODO:might failed to reset rfu_request when being accessed by otherside at the same time, sometimes both acting + // as client but one of them still have request[vbaid]!=0 //to prevent both GBAs from acting as Host, client can't + // be a host at the same time + linkmem->rfu_is_host[vbaid] = 0; + if (vbaid != gbaid) { + linkmem->rfu_signal[vbaid] = 0x00ff; + linkmem->rfu_is_host[gbaid] |= 1 << vbaid; // tells the other GBA(a host) that someone(a client) is joining + } + rfu_cmd ^= 0x80; + break; + case 0x1e: // receive broadcast data + numtransfers = 0; + rfu_numclients = 0; + linkmem->rfu_is_host[vbaid] = 0; //to prevent both GBAs from acting as Host and thinking both of them have Client? + linkmem->rfu_q[vbaid] = 0; //to prevent leftover data from previous session received immediately in the new session + case 0x1d: // no visible difference + linkmem->rfu_is_host[vbaid] = 0; + memset(rfu_masterdata, 0, sizeof(linkmem->rfu_broadcastdata[vbaid])); + rfu_qrecv_broadcast_data_len = 0; + for (int i = 0; i < linkmem->numgbas; i++) { + if (i != vbaid && linkmem->rfu_broadcastdata[i][0]) { + memcpy(&rfu_masterdata[rfu_qrecv_broadcast_data_len], linkmem->rfu_broadcastdata[i], sizeof(linkmem->rfu_broadcastdata[i])); + rfu_qrecv_broadcast_data_len += 7; + } + } + // is this needed? to prevent MarioGolfAdv from joining it's own room when switching + // from host to client mode due to left over room data in the game buffer? + // if(rfu_qrecv==0) rfu_qrecv = 7; + if (rfu_qrecv_broadcast_data_len > 0) + rfu_state = RFU_RECV; + rfu_polarity = 0; + rfu_counter = 0; + rfu_cmd ^= 0x80; + break; + case 0x16: // send broadcast data (ie. room name) + //start broadcasting here may cause client to join other client in pokemon coloseum + //linkmem->rfu_bdata[vbaid][0] = (vbaid<<3)+0x61f1; + //linkmem->rfu_q[vbaid] = 0; + rfu_cmd ^= 0x80; + break; + case 0x11: // get signal strength + //Switch remote id + if (linkmem->rfu_is_host[vbaid]) { //is a host + /*//gbaid = 1-vbaid; //linkmem->rfu_request[vbaid] & 1; gbaidx = gbaid; do { gbaidx = (gbaidx+1) % linkmem->numgbas; @@ -3356,41 +3276,44 @@ static void StartRFU(u16 value) gbaid = gbaidx; rfu_id = (gbaid<<3)+0x61f1; }*/ - /*if(rfu_numclients>0) { + /*if(rfu_numclients>0) { rfu_curclient = (rfu_curclient+1) % rfu_numclients; rfu_id = rfu_clientlist[rfu_curclient]; gbaid = (rfu_id-0x61f1)>>3; }*/ - } - //check signal - if (linkmem->numgbas >= 2 && (linkmem->rfu_is_host[vbaid] | linkmem->rfu_is_host[gbaid])) //signal only good when connected - if (rfu_ishost) { //update, just incase there are leaving clients - u8 rfureq = linkmem->rfu_is_host[vbaid]; - u8 oldnum = rfu_numclients; - rfu_numclients = 0; - for (int i = 0; i<8; i++) { - if (rfureq & 1)rfu_numclients++; - rfureq >>= 1; - } - if (rfu_numclients>oldnum)rfu_numclients = oldnum; //must not be higher than old value, which means the new client haven't been processed by 0x1a cmd yet - linkmem->rfu_signal[vbaid] = 0xffffffff >> ((4 - rfu_numclients) << 3); - } - else linkmem->rfu_signal[vbaid] = linkmem->rfu_signal[gbaid]; - else linkmem->rfu_signal[vbaid] = 0; - if (rfu_ishost) { - //linkmem->rfu_signal[vbaid] = 0x00ff; //host should have signal to prevent it from canceling the room? (may cause Digimon Racing host not knowing when a client leaving the room) - /*for (int i=0;inumgbas;i++) + } + //check signal + if (linkmem->numgbas >= 2 && (linkmem->rfu_is_host[vbaid] | linkmem->rfu_is_host[gbaid])) //signal only good when connected + if (rfu_ishost) { //update, just incase there are leaving clients + u8 rfureq = linkmem->rfu_is_host[vbaid]; + u8 oldnum = rfu_numclients; + rfu_numclients = 0; + for (int i = 0; i < 8; i++) { + if (rfureq & 1) + rfu_numclients++; + rfureq >>= 1; + } + if (rfu_numclients > oldnum) + rfu_numclients = oldnum; //must not be higher than old value, which means the new client haven't been processed by 0x1a cmd yet + linkmem->rfu_signal[vbaid] = 0xffffffff >> ((4 - rfu_numclients) << 3); + } else + linkmem->rfu_signal[vbaid] = linkmem->rfu_signal[gbaid]; + else + linkmem->rfu_signal[vbaid] = 0; + if (rfu_ishost) { + //linkmem->rfu_signal[vbaid] = 0x00ff; //host should have signal to prevent it from canceling the room? (may cause Digimon Racing host not knowing when a client leaving the room) + /*for (int i=0;inumgbas;i++) if (i!=vbaid && linkmem->rfu_reqid[i]==(vbaid<<3)+0x61f1) { rfu_masterdata[rfu_qrecv++] = linkmem->rfu_signal[i]; }*/ - //int j = 0; - /*int i = gbaid; + //int j = 0; + /*int i = gbaid; if (linkmem->numgbas>=2) do { if (i!=vbaid && linkmem->rfu_reqid[i]==(vbaid<<3)+0x61f1) rfu_masterdata[rfu_qrecv++] = linkmem->rfu_signal[i]; i = (i+1) % linkmem->numgbas; } while (i!=gbaid);*/ - /*if(rfu_numclients>0) + /*if(rfu_numclients>0) for(int i=0; i=0x61f1) { @@ -3398,22 +3321,23 @@ static void StartRFU(u16 value) rfu_masterdata[rfu_qrecv++] = linkmem->rfu_signal[cid] = 0xffffffff>>((3-linkmem->rfu_clientidx[cid])<<3); //0x0ff << (linkmem->rfu_clientidx[cid]<<3); } }*/ - //rfu_masterdata[0] = (u32)linkmem->rfu_signal[vbaid]; - } - if (rfu_qrecv_broadcast_data_len == 0) { - rfu_qrecv_broadcast_data_len = 1; - rfu_masterdata[0] = (u32)linkmem->rfu_signal[vbaid]; - } - if (rfu_qrecv_broadcast_data_len > 0) { - rfu_state = RFU_RECV; - int hid = vbaid; - if (!rfu_ishost)hid = gbaid; - rfu_masterdata[rfu_qrecv_broadcast_data_len - 1] = (u32)linkmem->rfu_signal[hid]; - } - rfu_cmd ^= 0x80; - //rfu_polarity = 0; - //rfu_transfer_end = 2048; //make it longer, giving time for data to come (since 0x26 usually used after 0x11) - /*//linktime = -2048; //1; //0; + //rfu_masterdata[0] = (u32)linkmem->rfu_signal[vbaid]; + } + if (rfu_qrecv_broadcast_data_len == 0) { + rfu_qrecv_broadcast_data_len = 1; + rfu_masterdata[0] = (u32)linkmem->rfu_signal[vbaid]; + } + if (rfu_qrecv_broadcast_data_len > 0) { + rfu_state = RFU_RECV; + int hid = vbaid; + if (!rfu_ishost) + hid = gbaid; + rfu_masterdata[rfu_qrecv_broadcast_data_len - 1] = (u32)linkmem->rfu_signal[hid]; + } + rfu_cmd ^= 0x80; + //rfu_polarity = 0; + //rfu_transfer_end = 2048; //make it longer, giving time for data to come (since 0x26 usually used after 0x11) + /*//linktime = -2048; //1; //0; //numtransfers++; //not needed, just to keep track if ((numtransfers++) == 0) linktime = 1; //0; //might be needed to synchronize both performance? //numtransfers used to reset linktime to prevent it from reaching beyond max value of integer? //seems to be needed? otherwise data can't be received properly? //related to 0x24? linkmem->rfu_linktime[vbaid] = linktime; //save the ticks before changed to synchronize performance @@ -3421,175 +3345,177 @@ static void StartRFU(u16 value) if (rfu_transfer_end < 256) //lower/unlimited = faster client but slower host rfu_transfer_end = 256; //need to be positive for balanced performance in both GBAs? linktime = -rfu_transfer_end; //needed to synchronize performance on both side*/ - break; - case 0x33: // rejoin status check? - if (linkmem->rfu_signal[vbaid] || numtransfers == 0) - rfu_masterdata[0] = 0; else //0=success - rfu_masterdata[0] = (u32)-1; //0xffffffff; //1=failed, 2++ = reserved/invalid, we use invalid value to let the game retries 0x33 until signal restored - rfu_cmd ^= 0x80; - rfu_state = RFU_RECV; - rfu_qrecv_broadcast_data_len = 1; - break; - case 0x14: // reset current client index and error check? - if ((linkmem->rfu_signal[vbaid] || numtransfers == 0) && gbaid != vbaid) - rfu_masterdata[0] = ((!rfu_ishost ? 0x100 : 0 + linkmem->rfu_clientidx[gbaid]) << 16) | ((gbaid << 3) + 0x61f1); - rfu_masterdata[0] = 0; //0=error, non-zero=good? - rfu_cmd ^= 0x80; - rfu_state = RFU_RECV; - rfu_qrecv_broadcast_data_len = 1; - break; - case 0x13: // error check? - if (linkmem->rfu_signal[vbaid] || numtransfers == 0 || rfu_initialized) - rfu_masterdata[0] = ((rfu_ishost ? 0x100 : 0 + linkmem->rfu_clientidx[vbaid]) << 16) | ((vbaid << 3) + 0x61f1); else //high word should be 0x0200 ? is 0x0200 means 1st client and 0x4000 means 2nd client? - rfu_masterdata[0] = 0; //0=error, non-zero=good? - rfu_cmd ^= 0x80; - rfu_state = RFU_RECV; - rfu_qrecv_broadcast_data_len = 1; - break; - case 0x20: // client, this has something to do with 0x1f - rfu_masterdata[0] = (linkmem->rfu_clientidx[vbaid]) << 16; //needed for client - rfu_masterdata[0] |= (vbaid << 3) + 0x61f1; //0x1234; //0x641b; //max id value? Encryption key or Station Mode? (0xFBD9/0xDEAD=Access Point mode?) - linkmem->rfu_q[vbaid] = 0; //to prevent leftover data from previous session received immediately in the new session - linkmem->rfu_is_host[vbaid] = 0; //TODO:may not works properly, sometimes both acting as client but one of them still have request[vbaid]!=0 //to prevent both GBAs from acting as Host, client can't be a host at the same time - if (linkmem->rfu_signal[gbaid] < linkmem->rfu_signal[vbaid]) - linkmem->rfu_signal[gbaid] = linkmem->rfu_signal[vbaid]; - rfu_polarity = 0; - rfu_state = RFU_RECV; - rfu_qrecv_broadcast_data_len = 1; - rfu_cmd ^= 0x80; - break; - case 0x21: // client, this too - rfu_masterdata[0] = (linkmem->rfu_clientidx[vbaid]) << 16; //not needed? - rfu_masterdata[0] |= (vbaid << 3) + 0x61f1; //0x641b; //max id value? Encryption key or Station Mode? (0xFBD9/0xDEAD=Access Point mode?) - linkmem->rfu_q[vbaid] = 0; //to prevent leftover data from previous session received immediately in the new session - linkmem->rfu_is_host[vbaid] = 0; //TODO:may not works properly, sometimes both acting as client but one of them still have request[vbaid]!=0 //to prevent both GBAs from acting as Host, client can't be a host at the same time - rfu_polarity = 0; - rfu_state = RFU_RECV; //3; - rfu_qrecv_broadcast_data_len = 1; - rfu_cmd ^= 0x80; - break; + break; + case 0x33: // rejoin status check? + if (linkmem->rfu_signal[vbaid] || numtransfers == 0) + rfu_masterdata[0] = 0; + else //0=success + rfu_masterdata[0] = (u32)-1; //0xffffffff; //1=failed, 2++ = reserved/invalid, we use invalid value to let the game retries 0x33 until signal restored + rfu_cmd ^= 0x80; + rfu_state = RFU_RECV; + rfu_qrecv_broadcast_data_len = 1; + break; + case 0x14: // reset current client index and error check? + if ((linkmem->rfu_signal[vbaid] || numtransfers == 0) && gbaid != vbaid) + rfu_masterdata[0] = ((!rfu_ishost ? 0x100 : 0 + linkmem->rfu_clientidx[gbaid]) << 16) | ((gbaid << 3) + 0x61f1); + rfu_masterdata[0] = 0; //0=error, non-zero=good? + rfu_cmd ^= 0x80; + rfu_state = RFU_RECV; + rfu_qrecv_broadcast_data_len = 1; + break; + case 0x13: // error check? + if (linkmem->rfu_signal[vbaid] || numtransfers == 0 || rfu_initialized) + rfu_masterdata[0] = ((rfu_ishost ? 0x100 : 0 + linkmem->rfu_clientidx[vbaid]) << 16) | ((vbaid << 3) + 0x61f1); + else //high word should be 0x0200 ? is 0x0200 means 1st client and 0x4000 means 2nd client? + rfu_masterdata[0] = 0; //0=error, non-zero=good? + rfu_cmd ^= 0x80; + rfu_state = RFU_RECV; + rfu_qrecv_broadcast_data_len = 1; + break; + case 0x20: // client, this has something to do with 0x1f + rfu_masterdata[0] = (linkmem->rfu_clientidx[vbaid]) << 16; //needed for client + rfu_masterdata[0] |= (vbaid << 3) + 0x61f1; //0x1234; //0x641b; //max id value? Encryption key or Station Mode? (0xFBD9/0xDEAD=Access Point mode?) + linkmem->rfu_q[vbaid] = 0; //to prevent leftover data from previous session received immediately in the new session + linkmem->rfu_is_host[vbaid] = 0; //TODO:may not works properly, sometimes both acting as client but one of them still have request[vbaid]!=0 //to prevent both GBAs from acting as Host, client can't be a host at the same time + if (linkmem->rfu_signal[gbaid] < linkmem->rfu_signal[vbaid]) + linkmem->rfu_signal[gbaid] = linkmem->rfu_signal[vbaid]; + rfu_polarity = 0; + rfu_state = RFU_RECV; + rfu_qrecv_broadcast_data_len = 1; + rfu_cmd ^= 0x80; + break; + case 0x21: // client, this too + rfu_masterdata[0] = (linkmem->rfu_clientidx[vbaid]) << 16; //not needed? + rfu_masterdata[0] |= (vbaid << 3) + 0x61f1; //0x641b; //max id value? Encryption key or Station Mode? (0xFBD9/0xDEAD=Access Point mode?) + linkmem->rfu_q[vbaid] = 0; //to prevent leftover data from previous session received immediately in the new session + linkmem->rfu_is_host[vbaid] = 0; //TODO:may not works properly, sometimes both acting as client but one of them still have request[vbaid]!=0 //to prevent both GBAs from acting as Host, client can't be a host at the same time + rfu_polarity = 0; + rfu_state = RFU_RECV; //3; + rfu_qrecv_broadcast_data_len = 1; + rfu_cmd ^= 0x80; + break; - case 0x19: // server bind/start listening for client to join, may be used in the middle of host<->client communication w/o causing clients to dc? - //linkmem->rfu_request[vbaid] = 0; //to prevent both GBAs from acting as Host and thinking both of them have Client? - linkmem->rfu_q[vbaid] = 0; //to prevent leftover data from previous session received immediately in the new session - linkmem->rfu_broadcastdata[vbaid][0] = (vbaid << 3) + 0x61f1; //start broadcasting room name - linkmem->rfu_clientidx[vbaid] = 0; - //numtransfers = 0; - //rfu_numclients = 0; - //rfu_curclient = 0; - //rfu_lastcmd2 = 0; - //rfu_polarity = 0; - rfu_ishost = true; - rfu_cmd ^= 0x80; - break; + case 0x19: // server bind/start listening for client to join, may be used in the middle of host<->client communication w/o causing clients to dc? + //linkmem->rfu_request[vbaid] = 0; //to prevent both GBAs from acting as Host and thinking both of them have Client? + linkmem->rfu_q[vbaid] = 0; //to prevent leftover data from previous session received immediately in the new session + linkmem->rfu_broadcastdata[vbaid][0] = (vbaid << 3) + 0x61f1; //start broadcasting room name + linkmem->rfu_clientidx[vbaid] = 0; + //numtransfers = 0; + //rfu_numclients = 0; + //rfu_curclient = 0; + //rfu_lastcmd2 = 0; + //rfu_polarity = 0; + rfu_ishost = true; + rfu_cmd ^= 0x80; + break; - case 0x1c: //client, might reset some data? - //linkmem->rfu_request[vbaid] = 0; //to prevent both GBAs from acting as Host and thinking both of them have Client - //linkmem->rfu_bdata[vbaid][0] = 0; //stop broadcasting room name - rfu_ishost = false; //TODO: prevent both GBAs act as client but one of them have rfu_request[vbaid]!=0 on MarioGolfAdv lobby - //rfu_polarity = 0; - rfu_numclients = 0; - rfu_curclient = 0; - //c_s.Lock(); - linkmem->rfu_listfront[vbaid] = 0; - linkmem->rfu_listback[vbaid] = 0; - linkmem->rfu_q[vbaid] = 0; //to prevent leftover data from previous session received immediately in the new session - //DATALIST.clear(); - //c_s.Unlock(); - case 0x1b: //host, might reset some data? may be used in the middle of host<->client communication w/o causing clients to dc? - //linkmem->rfu_request[vbaid] = 0; //to prevent both GBAs from acting as Client and thinking one of them is a Host? - linkmem->rfu_broadcastdata[vbaid][0] = 0; //0 may cause player unable to join in pokemon union room? - //numtransfers = 0; - //linktime = 1; - rfu_cmd ^= 0x80; - break; + case 0x1c: //client, might reset some data? + //linkmem->rfu_request[vbaid] = 0; //to prevent both GBAs from acting as Host and thinking both of them have Client + //linkmem->rfu_bdata[vbaid][0] = 0; //stop broadcasting room name + rfu_ishost = false; //TODO: prevent both GBAs act as client but one of them have rfu_request[vbaid]!=0 on MarioGolfAdv lobby + //rfu_polarity = 0; + rfu_numclients = 0; + rfu_curclient = 0; + //c_s.Lock(); + linkmem->rfu_listfront[vbaid] = 0; + linkmem->rfu_listback[vbaid] = 0; + linkmem->rfu_q[vbaid] = 0; //to prevent leftover data from previous session received immediately in the new session + //DATALIST.clear(); + //c_s.Unlock(); + case 0x1b: //host, might reset some data? may be used in the middle of host<->client communication w/o causing clients to dc? + //linkmem->rfu_request[vbaid] = 0; //to prevent both GBAs from acting as Client and thinking one of them is a Host? + linkmem->rfu_broadcastdata[vbaid][0] = 0; //0 may cause player unable to join in pokemon union room? + //numtransfers = 0; + //linktime = 1; + rfu_cmd ^= 0x80; + break; - case 0x30: //reset some data - if (vbaid != gbaid) { //(linkmem->numgbas >= 2) - //linkmem->rfu_signal[gbaid] = 0; - linkmem->rfu_is_host[gbaid] &= ~(1 << vbaid); //linkmem->rfu_request[gbaid] = 0; - SetEvent(linksync[gbaid]); //allow other gba to move - } - //WaitForSingleObject(linksync[vbaid], 40/*linktimeout*/); - while (linkmem->rfu_signal[vbaid]) { - WaitForSingleObject(linksync[vbaid], 1/*linktimeout*/); - linkmem->rfu_signal[vbaid] = 0; - linkmem->rfu_is_host[vbaid] = 0; //There is a possibility where rfu_request/signal didn't get zeroed here when it's being read by the other GBA at the same time - //SleepEx(1,true); - } - //c_s.Lock(); - linkmem->rfu_listfront[vbaid] = 0; - linkmem->rfu_listback[vbaid] = 0; - linkmem->rfu_q[vbaid] = 0; //to prevent leftover data from previous session received immediately in the new session - //DATALIST.clear(); - linkmem->rfu_proto[vbaid] = 0; - linkmem->rfu_reqid[vbaid] = 0; - linkmem->rfu_linktime[vbaid] = 0; - linkmem->rfu_gdata[vbaid] = 0; - linkmem->rfu_broadcastdata[vbaid][0] = 0; - //c_s.Unlock(); - rfu_polarity = 0; //is this included? - //linkid = -1; //0; - numtransfers = 0; - rfu_numclients = 0; - rfu_curclient = 0; - linktime = 1; //0; //reset here instead of at 0x24/0xa5/0xa7 - /*rfu_id = 0; + case 0x30: //reset some data + if (vbaid != gbaid) { //(linkmem->numgbas >= 2) + //linkmem->rfu_signal[gbaid] = 0; + linkmem->rfu_is_host[gbaid] &= ~(1 << vbaid); //linkmem->rfu_request[gbaid] = 0; + SetEvent(linksync[gbaid]); //allow other gba to move + } + //WaitForSingleObject(linksync[vbaid], 40/*linktimeout*/); + while (linkmem->rfu_signal[vbaid]) { + WaitForSingleObject(linksync[vbaid], 1 /*linktimeout*/); + linkmem->rfu_signal[vbaid] = 0; + linkmem->rfu_is_host[vbaid] = 0; //There is a possibility where rfu_request/signal didn't get zeroed here when it's being read by the other GBA at the same time + //SleepEx(1,true); + } + //c_s.Lock(); + linkmem->rfu_listfront[vbaid] = 0; + linkmem->rfu_listback[vbaid] = 0; + linkmem->rfu_q[vbaid] = 0; //to prevent leftover data from previous session received immediately in the new session + //DATALIST.clear(); + linkmem->rfu_proto[vbaid] = 0; + linkmem->rfu_reqid[vbaid] = 0; + linkmem->rfu_linktime[vbaid] = 0; + linkmem->rfu_gdata[vbaid] = 0; + linkmem->rfu_broadcastdata[vbaid][0] = 0; + //c_s.Unlock(); + rfu_polarity = 0; //is this included? + //linkid = -1; //0; + numtransfers = 0; + rfu_numclients = 0; + rfu_curclient = 0; + linktime = 1; //0; //reset here instead of at 0x24/0xa5/0xa7 + /*rfu_id = 0; rfu_idx = 0; gbaid = vbaid; gbaidx = gbaid; rfu_ishost = false; rfu_isfirst = false;*/ - rfu_cmd ^= 0x80; - SetEvent(linksync[vbaid]); //may not be needed - break; + rfu_cmd ^= 0x80; + SetEvent(linksync[vbaid]); //may not be needed + break; - case 0x3d: // init/reset rfu data - rfu_initialized = false; - case 0x10: // init/reset rfu data - if (vbaid != gbaid) { //(linkmem->numgbas >= 2) - //linkmem->rfu_signal[gbaid] = 0; - linkmem->rfu_is_host[gbaid] &= ~(1 << vbaid); //linkmem->rfu_request[gbaid] = 0; - SetEvent(linksync[gbaid]); //allow other gba to move - } - //WaitForSingleObject(linksync[vbaid], 40/*linktimeout*/); - while (linkmem->rfu_signal[vbaid]) { - WaitForSingleObject(linksync[vbaid], 1/*linktimeout*/); - linkmem->rfu_signal[vbaid] = 0; - linkmem->rfu_is_host[vbaid] = 0; //There is a possibility where rfu_request/signal didn't get zeroed here when it's being read by the other GBA at the same time - //SleepEx(1,true); - } - //c_s.Lock(); - linkmem->rfu_listfront[vbaid] = 0; - linkmem->rfu_listback[vbaid] = 0; - linkmem->rfu_q[vbaid] = 0; //to prevent leftover data from previous session received immediately in the new session - //DATALIST.clear(); - linkmem->rfu_proto[vbaid] = 0; - linkmem->rfu_reqid[vbaid] = 0; - linkmem->rfu_linktime[vbaid] = 0; - linkmem->rfu_gdata[vbaid] = 0; - linkmem->rfu_broadcastdata[vbaid][0] = 0; - //c_s.Unlock(); - rfu_polarity = 0; //is this included? - //linkid = -1; //0; - numtransfers = 0; - rfu_numclients = 0; - rfu_curclient = 0; - linktime = 1; //0; //reset here instead of at 0x24/0xa5/0xa7 - rfu_id = 0; - rfu_idx = 0; - gbaid = vbaid; - gbaidx = gbaid; - rfu_ishost = false; - rfu_qrecv_broadcast_data_len = 0; - SetEvent(linksync[vbaid]); //may not be needed - rfu_cmd ^= 0x80; - break; + case 0x3d: // init/reset rfu data + rfu_initialized = false; + case 0x10: // init/reset rfu data + if (vbaid != gbaid) { //(linkmem->numgbas >= 2) + //linkmem->rfu_signal[gbaid] = 0; + linkmem->rfu_is_host[gbaid] &= ~(1 << vbaid); //linkmem->rfu_request[gbaid] = 0; + SetEvent(linksync[gbaid]); //allow other gba to move + } + //WaitForSingleObject(linksync[vbaid], 40/*linktimeout*/); + while (linkmem->rfu_signal[vbaid]) { + WaitForSingleObject(linksync[vbaid], 1 /*linktimeout*/); + linkmem->rfu_signal[vbaid] = 0; + linkmem->rfu_is_host[vbaid] = 0; //There is a possibility where rfu_request/signal didn't get zeroed here when it's being read by the other GBA at the same time + //SleepEx(1,true); + } + //c_s.Lock(); + linkmem->rfu_listfront[vbaid] = 0; + linkmem->rfu_listback[vbaid] = 0; + linkmem->rfu_q[vbaid] = 0; //to prevent leftover data from previous session received immediately in the new session + //DATALIST.clear(); + linkmem->rfu_proto[vbaid] = 0; + linkmem->rfu_reqid[vbaid] = 0; + linkmem->rfu_linktime[vbaid] = 0; + linkmem->rfu_gdata[vbaid] = 0; + linkmem->rfu_broadcastdata[vbaid][0] = 0; + //c_s.Unlock(); + rfu_polarity = 0; //is this included? + //linkid = -1; //0; + numtransfers = 0; + rfu_numclients = 0; + rfu_curclient = 0; + linktime = 1; //0; //reset here instead of at 0x24/0xa5/0xa7 + rfu_id = 0; + rfu_idx = 0; + gbaid = vbaid; + gbaidx = gbaid; + rfu_ishost = false; + rfu_qrecv_broadcast_data_len = 0; + SetEvent(linksync[vbaid]); //may not be needed + rfu_cmd ^= 0x80; + break; - case 0x36: //does it expect data returned? - case 0x26: - //Switch remote id to available data - /*//if(vbaid==gbaid) { + case 0x36: //does it expect data returned? + case 0x26: + //Switch remote id to available data + /*//if(vbaid==gbaid) { if(linkmem->numgbas>=2) if((linkmem->rfu_q[gbaid]<=0) || !(linkmem->rfu_qid[gbaid] & (1<numgbas>=2 && linkmem->rfu_signal[gbaid] && linkmem->rfu_q[gbaid]<=0 && linkmem->rfu_q[vbaid]>0 && (GetTickCount()-rfu_lasttime)<1); //(DWORD)linktimeout }*/ - //Wait for data + //Wait for data - //Read data when available - /*if((linkmem->rfu_qid[gbaid] & (1<rfu_qid[gbaid] & (1<rfu_q[gbaid])!=0) { //data size > 0 memcpy(rfu_masterdata, linkmem->linkdata[gbaid], min(rfu_masterq<<2,sizeof(rfu_masterdata))); //128 //read data from other GBA linkmem->rfu_qid[gbaid] &= ~(1<rfu_listfront[vbaid] != linkmem->rfu_listback[vbaid]) //data existed - do { - u8 tmpq = linkmem->rfu_datalist[vbaid][linkmem->rfu_listfront[vbaid]].len; //(u8)linkmem->rfu_qlist[vbaid][linkmem->rfu_listfront[vbaid]]; - ok = false; - if (tmpq != rfu_qrecv_broadcast_data_len) ok = true; else - for (int i = 0; irfu_datalist[vbaid][linkmem->rfu_listfront[vbaid]].data[i] != rfu_masterdata[i]) { ok = true; break; } + bool ok; + int ctr; + ctr = 0; + //WaitForSingleObject(linksync[vbaid], linktimeout); //wait until unlocked + //ResetEvent(linksync[vbaid]); //lock it so noone can access it + if (linkmem->rfu_listfront[vbaid] != linkmem->rfu_listback[vbaid]) //data existed + do { + u8 tmpq = linkmem->rfu_datalist[vbaid][linkmem->rfu_listfront[vbaid]].len; //(u8)linkmem->rfu_qlist[vbaid][linkmem->rfu_listfront[vbaid]]; + ok = false; + if (tmpq != rfu_qrecv_broadcast_data_len) + ok = true; + else + for (int i = 0; i < tmpq; i++) + if (linkmem->rfu_datalist[vbaid][linkmem->rfu_listfront[vbaid]].data[i] != rfu_masterdata[i]) { + ok = true; + break; + } - if (tmpq == 0 && ctr == 0) ok = true; //0-size data + if (tmpq == 0 && ctr == 0) + ok = true; //0-size data - if (ok) //next data is not a duplicate of currently unprocessed data - if (rfu_qrecv_broadcast_data_len<2 || tmpq>1) - { - if (rfu_qrecv_broadcast_data_len>1) { //stop here if next data is different than currently unprocessed non-ping data - linkmem->rfu_linktime[gbaid] = linkmem->rfu_datalist[vbaid][linkmem->rfu_listfront[vbaid]].time; - break; - } + if (ok) //next data is not a duplicate of currently unprocessed data + if (rfu_qrecv_broadcast_data_len < 2 || tmpq > 1) { + if (rfu_qrecv_broadcast_data_len > 1) { //stop here if next data is different than currently unprocessed non-ping data + linkmem->rfu_linktime[gbaid] = linkmem->rfu_datalist[vbaid][linkmem->rfu_listfront[vbaid]].time; + break; + } - if (tmpq >= rfu_qrecv_broadcast_data_len) { - rfu_masterq = rfu_qrecv_broadcast_data_len = tmpq; - gbaid = linkmem->rfu_datalist[vbaid][linkmem->rfu_listfront[vbaid]].gbaid; - rfu_id = (gbaid << 3) + 0x61f1; - if (rfu_ishost) - rfu_curclient = (u8)linkmem->rfu_clientidx[gbaid]; - if (rfu_qrecv_broadcast_data_len != 0) { //data size > 0 - memcpy(rfu_masterdata, linkmem->rfu_datalist[vbaid][linkmem->rfu_listfront[vbaid]].data, std::min(rfu_masterq << 2, (int)sizeof(rfu_masterdata))); - } - } - } //else log("%08X CMD26 Skip: %d %d %d\n",GetTickCount(),rfu_qrecv,linkmem->rfu_q[gbaid],tmpq); + if (tmpq >= rfu_qrecv_broadcast_data_len) { + rfu_masterq = rfu_qrecv_broadcast_data_len = tmpq; + gbaid = linkmem->rfu_datalist[vbaid][linkmem->rfu_listfront[vbaid]].gbaid; + rfu_id = (gbaid << 3) + 0x61f1; + if (rfu_ishost) + rfu_curclient = (u8)linkmem->rfu_clientidx[gbaid]; + if (rfu_qrecv_broadcast_data_len != 0) { //data size > 0 + memcpy(rfu_masterdata, linkmem->rfu_datalist[vbaid][linkmem->rfu_listfront[vbaid]].data, std::min(rfu_masterq << 2, (int)sizeof(rfu_masterdata))); + } + } + } //else log("%08X CMD26 Skip: %d %d %d\n",GetTickCount(),rfu_qrecv,linkmem->rfu_q[gbaid],tmpq); - linkmem->rfu_listfront[vbaid]++; ctr++; + linkmem->rfu_listfront[vbaid]++; + ctr++; - ok = (linkmem->rfu_listfront[vbaid] != linkmem->rfu_listback[vbaid] && linkmem->rfu_datalist[vbaid][linkmem->rfu_listfront[vbaid]].gbaid == gbaid); - } while (ok); - //SetEvent(linksync[vbaid]); //unlock it so anyone can access it + ok = (linkmem->rfu_listfront[vbaid] != linkmem->rfu_listback[vbaid] && linkmem->rfu_datalist[vbaid][linkmem->rfu_listfront[vbaid]].gbaid == gbaid); + } while (ok); + //SetEvent(linksync[vbaid]); //unlock it so anyone can access it - if (rfu_qrecv_broadcast_data_len>0) { //data was available - rfu_state = RFU_RECV; - rfu_counter = 0; - rfu_lastcmd2 = 0; + if (rfu_qrecv_broadcast_data_len > 0) { //data was available + rfu_state = RFU_RECV; + rfu_counter = 0; + rfu_lastcmd2 = 0; - //Switch remote id to next remote id - /*if (linkmem->rfu_request[vbaid]) { //is a host + //Switch remote id to next remote id + /*if (linkmem->rfu_request[vbaid]) { //is a host if(rfu_numclients>0) { rfu_curclient = (rfu_curclient+1) % rfu_numclients; rfu_id = rfu_clientlist[rfu_curclient]; @@ -3681,570 +3613,560 @@ static void StartRFU(u16 value) //log("%d SwitchNext%02X:%d\n",GetTickCount(),rfu_cmd,gbaid); } }*/ - } - /*if(vbaid!=gbaid && linkmem->rfu_request[vbaid] && linkmem->rfu_request[gbaid]) + } + /*if(vbaid!=gbaid && linkmem->rfu_request[vbaid] && linkmem->rfu_request[gbaid]) MessageBox(0,_T("Both GBAs are Host!"),_T("Warning"),0);*/ - rfu_cmd ^= 0x80; - break; + rfu_cmd ^= 0x80; + break; - case 0x24: // send [non-important] data (used by server often) - //numtransfers++; //not needed, just to keep track - if ((numtransfers++) == 0) linktime = 1; //needed to synchronize both performance and for Digimon Racing's client to join successfully //numtransfers used to reset linktime to prevent it from reaching beyond max value of integer? //numtransfers doesn't seems to be used? - //linkmem->rfu_linktime[vbaid] = linktime; //save the ticks before reseted to zero + case 0x24: // send [non-important] data (used by server often) + //numtransfers++; //not needed, just to keep track + if ((numtransfers++) == 0) + linktime = 1; //needed to synchronize both performance and for Digimon Racing's client to join successfully //numtransfers used to reset linktime to prevent it from reaching beyond max value of integer? //numtransfers doesn't seems to be used? + //linkmem->rfu_linktime[vbaid] = linktime; //save the ticks before reseted to zero - if (rfu_cansend && rfu_qsend2 >= 0) { - /*memcpy(linkmem->rfu_data[vbaid],rfu_masterdata,4*rfu_qsend2); + if (rfu_cansend && rfu_qsend2 >= 0) { + /*memcpy(linkmem->rfu_data[vbaid],rfu_masterdata,4*rfu_qsend2); linkmem->rfu_proto[vbaid] = 0; //UDP-like if(rfu_ishost) linkmem->rfu_qid[vbaid] = linkmem->rfu_request[vbaid]; else linkmem->rfu_qid[vbaid] |= 1<rfu_q[vbaid] = rfu_qsend2;*/ - if (rfu_ishost) { - for (int j = 0; jnumgbas; j++) - if (j != vbaid) - { - WaitForSingleObject(linksync[j], linktimeout); //wait until unlocked - ResetEvent(linksync[j]); //lock it so noone can access it - memcpy(linkmem->rfu_datalist[j][linkmem->rfu_listback[j]].data, rfu_masterdata, 4 * rfu_qsend2); - linkmem->rfu_datalist[j][linkmem->rfu_listback[j]].gbaid = vbaid; - linkmem->rfu_datalist[j][linkmem->rfu_listback[j]].len = rfu_qsend2; - linkmem->rfu_datalist[j][linkmem->rfu_listback[j]].time = linktime; - linkmem->rfu_listback[j]++; - SetEvent(linksync[j]); //unlock it so anyone can access it - } - } - else - if (vbaid != gbaid) { - WaitForSingleObject(linksync[gbaid], linktimeout); //wait until unlocked - ResetEvent(linksync[gbaid]); //lock it so noone can access it - memcpy(linkmem->rfu_datalist[gbaid][linkmem->rfu_listback[gbaid]].data, rfu_masterdata, 4 * rfu_qsend2); - linkmem->rfu_datalist[gbaid][linkmem->rfu_listback[gbaid]].gbaid = vbaid; - linkmem->rfu_datalist[gbaid][linkmem->rfu_listback[gbaid]].len = rfu_qsend2; - linkmem->rfu_datalist[gbaid][linkmem->rfu_listback[gbaid]].time = linktime; - linkmem->rfu_listback[gbaid]++; - SetEvent(linksync[gbaid]); //unlock it so anyone can access it - } - } - else { - //log("%08X : IgnoredSend[%02X] %d\n", GetTickCount(), rfu_cmd, rfu_qsend2); - } + if (rfu_ishost) { + for (int j = 0; j < linkmem->numgbas; j++) + if (j != vbaid) { + WaitForSingleObject(linksync[j], linktimeout); //wait until unlocked + ResetEvent(linksync[j]); //lock it so noone can access it + memcpy(linkmem->rfu_datalist[j][linkmem->rfu_listback[j]].data, rfu_masterdata, 4 * rfu_qsend2); + linkmem->rfu_datalist[j][linkmem->rfu_listback[j]].gbaid = vbaid; + linkmem->rfu_datalist[j][linkmem->rfu_listback[j]].len = rfu_qsend2; + linkmem->rfu_datalist[j][linkmem->rfu_listback[j]].time = linktime; + linkmem->rfu_listback[j]++; + SetEvent(linksync[j]); //unlock it so anyone can access it + } + } else if (vbaid != gbaid) { + WaitForSingleObject(linksync[gbaid], linktimeout); //wait until unlocked + ResetEvent(linksync[gbaid]); //lock it so noone can access it + memcpy(linkmem->rfu_datalist[gbaid][linkmem->rfu_listback[gbaid]].data, rfu_masterdata, 4 * rfu_qsend2); + linkmem->rfu_datalist[gbaid][linkmem->rfu_listback[gbaid]].gbaid = vbaid; + linkmem->rfu_datalist[gbaid][linkmem->rfu_listback[gbaid]].len = rfu_qsend2; + linkmem->rfu_datalist[gbaid][linkmem->rfu_listback[gbaid]].time = linktime; + linkmem->rfu_listback[gbaid]++; + SetEvent(linksync[gbaid]); //unlock it so anyone can access it + } + } else { + //log("%08X : IgnoredSend[%02X] %d\n", GetTickCount(), rfu_cmd, rfu_qsend2); + } - linktime = 0; //need to zeroed when sending? //0 might cause slowdown in performance - rfu_cmd ^= 0x80; - //linkid = -1; //not needed? - break; + linktime = 0; //need to zeroed when sending? //0 might cause slowdown in performance + rfu_cmd ^= 0x80; + //linkid = -1; //not needed? + break; - case 0x25: // send [important] data & wait for [important?] reply data - case 0x35: // send [important] data & wait for [important?] reply data - //numtransfers++; //not needed, just to keep track - if ((numtransfers++) == 0) linktime = 1; //0; //might be needed to synchronize both performance? //numtransfers used to reset linktime to prevent it from reaching beyond max value of integer? //seems to be needed? otherwise data can't be received properly? //related to 0x24? - //linktime = 0; - //linkmem->rfu_linktime[vbaid] = linktime; //save the ticks before changed to synchronize performance + case 0x25: // send [important] data & wait for [important?] reply data + case 0x35: // send [important] data & wait for [important?] reply data + //numtransfers++; //not needed, just to keep track + if ((numtransfers++) == 0) + linktime = 1; //0; //might be needed to synchronize both performance? //numtransfers used to reset linktime to prevent it from reaching beyond max value of integer? //seems to be needed? otherwise data can't be received properly? //related to 0x24? + //linktime = 0; + //linkmem->rfu_linktime[vbaid] = linktime; //save the ticks before changed to synchronize performance - if (rfu_cansend && rfu_qsend2 > 0) { - /*memcpy(linkmem->rfu_data[vbaid],rfu_masterdata,4*rfu_qsend2); + if (rfu_cansend && rfu_qsend2 > 0) { + /*memcpy(linkmem->rfu_data[vbaid],rfu_masterdata,4*rfu_qsend2); linkmem->rfu_proto[vbaid] = 1; //TCP-like if(rfu_ishost) linkmem->rfu_qid[vbaid] = linkmem->rfu_request[vbaid]; else linkmem->rfu_qid[vbaid] |= 1<rfu_q[vbaid] = rfu_qsend2;*/ - if (rfu_ishost) { - for (int j = 0; jnumgbas; j++) - if (j != vbaid) - { - WaitForSingleObject(linksync[j], linktimeout); //wait until unlocked - ResetEvent(linksync[j]); //lock it so noone can access it - memcpy(linkmem->rfu_datalist[j][linkmem->rfu_listback[j]].data, rfu_masterdata, 4 * rfu_qsend2); - linkmem->rfu_datalist[j][linkmem->rfu_listback[j]].gbaid = vbaid; - linkmem->rfu_datalist[j][linkmem->rfu_listback[j]].len = rfu_qsend2; - linkmem->rfu_datalist[j][linkmem->rfu_listback[j]].time = linktime; - linkmem->rfu_listback[j]++; - SetEvent(linksync[j]); //unlock it so anyone can access it - } - } - else - if (vbaid != gbaid) { - WaitForSingleObject(linksync[gbaid], linktimeout); //wait until unlocked - ResetEvent(linksync[gbaid]); //lock it so noone can access it - memcpy(linkmem->rfu_datalist[gbaid][linkmem->rfu_listback[gbaid]].data, rfu_masterdata, 4 * rfu_qsend2); - linkmem->rfu_datalist[gbaid][linkmem->rfu_listback[gbaid]].gbaid = vbaid; - linkmem->rfu_datalist[gbaid][linkmem->rfu_listback[gbaid]].len = rfu_qsend2; - linkmem->rfu_datalist[gbaid][linkmem->rfu_listback[gbaid]].time = linktime; - linkmem->rfu_listback[gbaid]++; - SetEvent(linksync[gbaid]); //unlock it so anyone can access it - } - } - else { - //log("%08X : IgnoredSend[%02X] %d\n", GetTickCount(), rfu_cmd, rfu_qsend2); - } - //numtransfers++; //not needed, just to keep track - //if((numtransfers++)==0) linktime = 1; //may not be needed here? - //linkmem->rfu_linktime[vbaid] = linktime; //may not be needed here? save the ticks before reseted to zero - //linktime = 0; //may not be needed here? //need to zeroed when sending? //0 might cause slowdown in performance - //TODO: there is still a chance for 0x25 to be used at the same time on both GBA (both GBAs acting as client but keep sending & receiving using 0x25 & 0x26 for infinity w/o updating the screen much) - //Waiting here for previous data to be received might be too late! as new data already sent before finalization cmd - case 0x27: // wait for data ? - case 0x37: // wait for data ? - //numtransfers++; //not needed, just to keep track - if ((numtransfers++) == 0) linktime = 1; //0; //might be needed to synchronize both performance? //numtransfers used to reset linktime to prevent it from reaching beyond max value of integer? //seems to be needed? otherwise data can't be received properly? //related to 0x24? - //linktime = 0; - //linkmem->rfu_linktime[vbaid] = linktime; //save the ticks before changed to synchronize performance + if (rfu_ishost) { + for (int j = 0; j < linkmem->numgbas; j++) + if (j != vbaid) { + WaitForSingleObject(linksync[j], linktimeout); //wait until unlocked + ResetEvent(linksync[j]); //lock it so noone can access it + memcpy(linkmem->rfu_datalist[j][linkmem->rfu_listback[j]].data, rfu_masterdata, 4 * rfu_qsend2); + linkmem->rfu_datalist[j][linkmem->rfu_listback[j]].gbaid = vbaid; + linkmem->rfu_datalist[j][linkmem->rfu_listback[j]].len = rfu_qsend2; + linkmem->rfu_datalist[j][linkmem->rfu_listback[j]].time = linktime; + linkmem->rfu_listback[j]++; + SetEvent(linksync[j]); //unlock it so anyone can access it + } + } else if (vbaid != gbaid) { + WaitForSingleObject(linksync[gbaid], linktimeout); //wait until unlocked + ResetEvent(linksync[gbaid]); //lock it so noone can access it + memcpy(linkmem->rfu_datalist[gbaid][linkmem->rfu_listback[gbaid]].data, rfu_masterdata, 4 * rfu_qsend2); + linkmem->rfu_datalist[gbaid][linkmem->rfu_listback[gbaid]].gbaid = vbaid; + linkmem->rfu_datalist[gbaid][linkmem->rfu_listback[gbaid]].len = rfu_qsend2; + linkmem->rfu_datalist[gbaid][linkmem->rfu_listback[gbaid]].time = linktime; + linkmem->rfu_listback[gbaid]++; + SetEvent(linksync[gbaid]); //unlock it so anyone can access it + } + } else { + //log("%08X : IgnoredSend[%02X] %d\n", GetTickCount(), rfu_cmd, rfu_qsend2); + } + //numtransfers++; //not needed, just to keep track + //if((numtransfers++)==0) linktime = 1; //may not be needed here? + //linkmem->rfu_linktime[vbaid] = linktime; //may not be needed here? save the ticks before reseted to zero + //linktime = 0; //may not be needed here? //need to zeroed when sending? //0 might cause slowdown in performance + //TODO: there is still a chance for 0x25 to be used at the same time on both GBA (both GBAs acting as client but keep sending & receiving using 0x25 & 0x26 for infinity w/o updating the screen much) + //Waiting here for previous data to be received might be too late! as new data already sent before finalization cmd + case 0x27: // wait for data ? + case 0x37: // wait for data ? + //numtransfers++; //not needed, just to keep track + if ((numtransfers++) == 0) + linktime = 1; //0; //might be needed to synchronize both performance? //numtransfers used to reset linktime to prevent it from reaching beyond max value of integer? //seems to be needed? otherwise data can't be received properly? //related to 0x24? + //linktime = 0; + //linkmem->rfu_linktime[vbaid] = linktime; //save the ticks before changed to synchronize performance - if (rfu_ishost) { - for (int j = 0; jnumgbas; j++) - if (j != vbaid) - { - WaitForSingleObject(linksync[j], linktimeout); //wait until unlocked - ResetEvent(linksync[j]); //lock it so noone can access it - //memcpy(linkmem->rfu_datalist[j][linkmem->rfu_listback[j]].data,rfu_masterdata,4*rfu_qsend2); - linkmem->rfu_datalist[j][linkmem->rfu_listback[j]].gbaid = vbaid; - linkmem->rfu_datalist[j][linkmem->rfu_listback[j]].len = 0; //rfu_qsend2; - linkmem->rfu_datalist[j][linkmem->rfu_listback[j]].time = linktime; - linkmem->rfu_listback[j]++; - SetEvent(linksync[j]); //unlock it so anyone can access it - } - } - else - if (vbaid != gbaid) { - WaitForSingleObject(linksync[gbaid], linktimeout); //wait until unlocked - ResetEvent(linksync[gbaid]); //lock it so noone can access it - //memcpy(linkmem->rfu_datalist[gbaid][linkmem->rfu_listback[gbaid]].data,rfu_masterdata,4*rfu_qsend2); - linkmem->rfu_datalist[gbaid][linkmem->rfu_listback[gbaid]].gbaid = vbaid; - linkmem->rfu_datalist[gbaid][linkmem->rfu_listback[gbaid]].len = 0; //rfu_qsend2; - linkmem->rfu_datalist[gbaid][linkmem->rfu_listback[gbaid]].time = linktime; - linkmem->rfu_listback[gbaid]++; - SetEvent(linksync[gbaid]); //unlock it so anyone can access it - } - //} - rfu_cmd ^= 0x80; - break; + if (rfu_ishost) { + for (int j = 0; j < linkmem->numgbas; j++) + if (j != vbaid) { + WaitForSingleObject(linksync[j], linktimeout); //wait until unlocked + ResetEvent(linksync[j]); //lock it so noone can access it + //memcpy(linkmem->rfu_datalist[j][linkmem->rfu_listback[j]].data,rfu_masterdata,4*rfu_qsend2); + linkmem->rfu_datalist[j][linkmem->rfu_listback[j]].gbaid = vbaid; + linkmem->rfu_datalist[j][linkmem->rfu_listback[j]].len = 0; //rfu_qsend2; + linkmem->rfu_datalist[j][linkmem->rfu_listback[j]].time = linktime; + linkmem->rfu_listback[j]++; + SetEvent(linksync[j]); //unlock it so anyone can access it + } + } else if (vbaid != gbaid) { + WaitForSingleObject(linksync[gbaid], linktimeout); //wait until unlocked + ResetEvent(linksync[gbaid]); //lock it so noone can access it + //memcpy(linkmem->rfu_datalist[gbaid][linkmem->rfu_listback[gbaid]].data,rfu_masterdata,4*rfu_qsend2); + linkmem->rfu_datalist[gbaid][linkmem->rfu_listback[gbaid]].gbaid = vbaid; + linkmem->rfu_datalist[gbaid][linkmem->rfu_listback[gbaid]].len = 0; //rfu_qsend2; + linkmem->rfu_datalist[gbaid][linkmem->rfu_listback[gbaid]].time = linktime; + linkmem->rfu_listback[gbaid]++; + SetEvent(linksync[gbaid]); //unlock it so anyone can access it + } + //} + rfu_cmd ^= 0x80; + break; - case 0xee: //is this need to be processed? - rfu_cmd ^= 0x80; - rfu_polarity = 1; - break; + case 0xee: //is this need to be processed? + rfu_cmd ^= 0x80; + rfu_polarity = 1; + break; - case 0x17: // setup or something ? - default: - rfu_cmd ^= 0x80; - break; + case 0x17: // setup or something ? + default: + rfu_cmd ^= 0x80; + break; - case 0xa5: // 2nd part of send&wait function 0x25 - case 0xa7: // 2nd part of wait function 0x27 - case 0xb5: // 2nd part of send&wait function 0x35? - case 0xb7: // 2nd part of wait function 0x37? - if (linkmem->rfu_listfront[vbaid] != linkmem->rfu_listback[vbaid]) { - rfu_polarity = 1; //reverse polarity to make the game send 0x80000000 command word (to be replied with 0x99660028 later by the adapter) - if (rfu_cmd == 0xa5 || rfu_cmd == 0xa7) rfu_cmd = 0x28; else rfu_cmd = 0x36; //there might be 0x29 also //don't return 0x28 yet until there is incoming data (or until 500ms-6sec timeout? may reset RFU after timeout) - } - else - rfu_waiting = true; + case 0xa5: // 2nd part of send&wait function 0x25 + case 0xa7: // 2nd part of wait function 0x27 + case 0xb5: // 2nd part of send&wait function 0x35? + case 0xb7: // 2nd part of wait function 0x37? + if (linkmem->rfu_listfront[vbaid] != linkmem->rfu_listback[vbaid]) { + rfu_polarity = 1; //reverse polarity to make the game send 0x80000000 command word (to be replied with 0x99660028 later by the adapter) + if (rfu_cmd == 0xa5 || rfu_cmd == 0xa7) + rfu_cmd = 0x28; + else + rfu_cmd = 0x36; //there might be 0x29 also //don't return 0x28 yet until there is incoming data (or until 500ms-6sec timeout? may reset RFU after timeout) + } else + rfu_waiting = true; - /*//numtransfers++; //not needed, just to keep track + /*//numtransfers++; //not needed, just to keep track if ((numtransfers++) == 0) linktime = 1; //0; //might be needed to synchronize both performance? //numtransfers used to reset linktime to prevent it from reaching beyond max value of integer? //seems to be needed? otherwise data can't be received properly? //related to 0x24? //linktime = 0; //if (rfu_cmd==0xa5) linkmem->rfu_linktime[vbaid] = linktime; //save the ticks before changed to synchronize performance */ - //prevent GBAs from sending data at the same time (which may cause waiting at the same time in the case of 0x25), also gives time for the other side to read the data - //if (linkmem->numgbas>=2 && linkmem->rfu_signal[vbaid] && linkmem->rfu_signal[gbaid]) { - // SetEvent(linksync[gbaid]); //allow other gba to move (sending their data) - // WaitForSingleObject(linksync[vbaid], 1); //linktimeout //wait until this gba allowed to move - // //if(rfu_cmd==0xa5) - // ResetEvent(linksync[vbaid]); //don't allow this gba to move (prevent sending another data too fast w/o giving the other side chances to read it) - //} + //prevent GBAs from sending data at the same time (which may cause waiting at the same time in the case of 0x25), also gives time for the other side to read the data + //if (linkmem->numgbas>=2 && linkmem->rfu_signal[vbaid] && linkmem->rfu_signal[gbaid]) { + // SetEvent(linksync[gbaid]); //allow other gba to move (sending their data) + // WaitForSingleObject(linksync[vbaid], 1); //linktimeout //wait until this gba allowed to move + // //if(rfu_cmd==0xa5) + // ResetEvent(linksync[vbaid]); //don't allow this gba to move (prevent sending another data too fast w/o giving the other side chances to read it) + //} - rfu_transfer_end = linkmem->rfu_linktime[gbaid] - linktime + 1; //256; //waiting ticks = ticks difference between GBAs send/recv? //is max value of vbaid=1 ? + rfu_transfer_end = linkmem->rfu_linktime[gbaid] - linktime + 1; //256; //waiting ticks = ticks difference between GBAs send/recv? //is max value of vbaid=1 ? - if (rfu_transfer_end > 2560) //may need to cap the max ticks to prevent some games (ie. pokemon) from getting in-game timeout due to executing too many opcodes (too fast) - rfu_transfer_end = 2560; //10240; + if (rfu_transfer_end > 2560) //may need to cap the max ticks to prevent some games (ie. pokemon) from getting in-game timeout due to executing too many opcodes (too fast) + rfu_transfer_end = 2560; //10240; - if (rfu_transfer_end < 256) //lower/unlimited = faster client but slower host - rfu_transfer_end = 256; //need to be positive for balanced performance in both GBAs? + if (rfu_transfer_end < 256) //lower/unlimited = faster client but slower host + rfu_transfer_end = 256; //need to be positive for balanced performance in both GBAs? - linktime = -rfu_transfer_end; //needed to synchronize performance on both side - break; - } - if (!rfu_waiting) - rfu_buf = 0x99660000 | (rfu_qrecv_broadcast_data_len << 8) | rfu_cmd; - else rfu_buf = READ32LE(&ioMem[COMM_SIODATA32_L]); - } - } - else { //unknown COMM word //in MarioGolfAdv (when a player/client exiting lobby), There is a possibility COMM = 0x7FFE8001, PrevVAL = 0x5087, PrevCOM = 0, is this part of initialization? - log("%08X : UnkCOM %08X %04X %08X %08X\n", GetTickCount(), READ32LE(&ioMem[COMM_SIODATA32_L]), PrevVAL, PrevCOM, PrevDAT); - /*rfu_cmd ^= 0x80; + linktime = -rfu_transfer_end; //needed to synchronize performance on both side + break; + } + if (!rfu_waiting) + rfu_buf = 0x99660000 | (rfu_qrecv_broadcast_data_len << 8) | rfu_cmd; + else + rfu_buf = READ32LE(&ioMem[COMM_SIODATA32_L]); + } + } else { //unknown COMM word //in MarioGolfAdv (when a player/client exiting lobby), There is a possibility COMM = 0x7FFE8001, PrevVAL = 0x5087, PrevCOM = 0, is this part of initialization? + log("%08X : UnkCOM %08X %04X %08X %08X\n", GetTickCount(), READ32LE(&ioMem[COMM_SIODATA32_L]), PrevVAL, PrevCOM, PrevDAT); + /*rfu_cmd ^= 0x80; UPDATE_REG(COMM_SIODATA32_L, 0); UPDATE_REG(COMM_SIODATA32_H, 0x8000);*/ - rfu_state = RFU_INIT; //to prevent the next reinit words from getting in finalization processing (here), may cause MarioGolfAdv to show Linking error when this occurs instead of continuing with COMM cmd - //UPDATE_REG(COMM_SIODATA32_H, READ16LE(&ioMem[COMM_SIODATA32_L])); //replying with reversed words may cause MarioGolfAdv to reinit RFU when COMM = 0x7FFE8001 - //UPDATE_REG(COMM_SIODATA32_L, a); - rfu_buf = (READ16LE(&ioMem[COMM_SIODATA32_L]) << 16) | siodata_h; - } - break; + rfu_state = RFU_INIT; //to prevent the next reinit words from getting in finalization processing (here), may cause MarioGolfAdv to show Linking error when this occurs instead of continuing with COMM cmd + //UPDATE_REG(COMM_SIODATA32_H, READ16LE(&ioMem[COMM_SIODATA32_L])); //replying with reversed words may cause MarioGolfAdv to reinit RFU when COMM = 0x7FFE8001 + //UPDATE_REG(COMM_SIODATA32_L, a); + rfu_buf = (READ16LE(&ioMem[COMM_SIODATA32_L]) << 16) | siodata_h; + } + break; - case RFU_SEND: //data following after initialize cmd - //if(rfu_qsend==0) {rfu_state = RFU_COMM; break;} - CurDAT = READ32LE(&ioMem[COMM_SIODATA32_L]); - if (--rfu_qsend == 0) { - rfu_state = RFU_COMM; - } + case RFU_SEND: //data following after initialize cmd + //if(rfu_qsend==0) {rfu_state = RFU_COMM; break;} + CurDAT = READ32LE(&ioMem[COMM_SIODATA32_L]); + if (--rfu_qsend == 0) { + rfu_state = RFU_COMM; + } - switch (rfu_cmd) { - case 0x16: - linkmem->rfu_broadcastdata[vbaid][1 + rfu_counter++] = READ32LE(&ioMem[COMM_SIODATA32_L]); - break; + switch (rfu_cmd) { + case 0x16: + linkmem->rfu_broadcastdata[vbaid][1 + rfu_counter++] = READ32LE(&ioMem[COMM_SIODATA32_L]); + break; - case 0x17: - //linkid = 1; - rfu_masterdata[rfu_counter++] = READ32LE(&ioMem[COMM_SIODATA32_L]); - break; + case 0x17: + //linkid = 1; + rfu_masterdata[rfu_counter++] = READ32LE(&ioMem[COMM_SIODATA32_L]); + break; - case 0x1f: - rfu_masterdata[rfu_counter++] = READ32LE(&ioMem[COMM_SIODATA32_L]); - break; + case 0x1f: + rfu_masterdata[rfu_counter++] = READ32LE(&ioMem[COMM_SIODATA32_L]); + break; - case 0x24: - //if(linkmem->rfu_proto[vbaid]) break; //important data from 0x25 shouldn't be overwritten by 0x24 - case 0x25: - case 0x35: - //if(rfu_cansend) - //linkmem->rfu_data[vbaid][rfu_counter++] = READ32LE(&ioMem[COMM_SIODATA32_L]); - rfu_masterdata[rfu_counter++] = READ32LE(&ioMem[COMM_SIODATA32_L]); - break; + case 0x24: + //if(linkmem->rfu_proto[vbaid]) break; //important data from 0x25 shouldn't be overwritten by 0x24 + case 0x25: + case 0x35: + //if(rfu_cansend) + //linkmem->rfu_data[vbaid][rfu_counter++] = READ32LE(&ioMem[COMM_SIODATA32_L]); + rfu_masterdata[rfu_counter++] = READ32LE(&ioMem[COMM_SIODATA32_L]); + break; - default: - rfu_masterdata[rfu_counter++] = READ32LE(&ioMem[COMM_SIODATA32_L]); - break; - } - rfu_buf = 0x80000000; - break; + default: + rfu_masterdata[rfu_counter++] = READ32LE(&ioMem[COMM_SIODATA32_L]); + break; + } + rfu_buf = 0x80000000; + break; - case RFU_RECV: //data following after finalize cmd - //if(rfu_qrecv==0) {rfu_state = RFU_COMM; break;} - if (--rfu_qrecv_broadcast_data_len == 0) - rfu_state = RFU_COMM; + case RFU_RECV: //data following after finalize cmd + //if(rfu_qrecv==0) {rfu_state = RFU_COMM; break;} + if (--rfu_qrecv_broadcast_data_len == 0) + rfu_state = RFU_COMM; - switch (rfu_cmd) { - case 0x9d: - case 0x9e: - rfu_buf = rfu_masterdata[rfu_counter++]; - break; + switch (rfu_cmd) { + case 0x9d: + case 0x9e: + rfu_buf = rfu_masterdata[rfu_counter++]; + break; - case 0xb6: - case 0xa6: - rfu_buf = rfu_masterdata[rfu_counter++]; - break; + case 0xb6: + case 0xa6: + rfu_buf = rfu_masterdata[rfu_counter++]; + break; - case 0x91: //signal strength - rfu_buf = rfu_masterdata[rfu_counter++]; - break; + case 0x91: //signal strength + rfu_buf = rfu_masterdata[rfu_counter++]; + break; - case 0xb3: //rejoin error code? - /*UPDATE_REG(COMM_SIODATA32_L, 2); //0 = success, 1 = failed, 0x2++ = invalid + case 0xb3: //rejoin error code? + /*UPDATE_REG(COMM_SIODATA32_L, 2); //0 = success, 1 = failed, 0x2++ = invalid UPDATE_REG(COMM_SIODATA32_H, 0x0000); //high word 0 = a success indication? break;*/ - case 0x94: //last error code? //it seems like the game doesn't care about this value - case 0x93: //last error code? //it seems like the game doesn't care about this value - /*if(linkmem->rfu_signal[vbaid] || linkmem->numgbas>=2) { + case 0x94: //last error code? //it seems like the game doesn't care about this value + case 0x93: //last error code? //it seems like the game doesn't care about this value + /*if(linkmem->rfu_signal[vbaid] || linkmem->numgbas>=2) { UPDATE_REG(COMM_SIODATA32_L, 0x1234); // put anything in here UPDATE_REG(COMM_SIODATA32_H, 0x0200); // also here, but it should be 0200 } else { UPDATE_REG(COMM_SIODATA32_L, 0); // put anything in here UPDATE_REG(COMM_SIODATA32_H, 0x0000); }*/ - rfu_buf = rfu_masterdata[rfu_counter++]; - break; + rfu_buf = rfu_masterdata[rfu_counter++]; + break; - case 0xa0: - //max id value? Encryption key or Station Mode? (0xFBD9/0xDEAD=Access Point mode?) - //high word 0 = a success indication? - rfu_buf = rfu_masterdata[rfu_counter++]; - break; - case 0xa1: - //max id value? the same with 0xa0 cmd? - //high word 0 = a success indication? - rfu_buf = rfu_masterdata[rfu_counter++]; - break; + case 0xa0: + //max id value? Encryption key or Station Mode? (0xFBD9/0xDEAD=Access Point mode?) + //high word 0 = a success indication? + rfu_buf = rfu_masterdata[rfu_counter++]; + break; + case 0xa1: + //max id value? the same with 0xa0 cmd? + //high word 0 = a success indication? + rfu_buf = rfu_masterdata[rfu_counter++]; + break; - case 0x9a: - rfu_buf = rfu_masterdata[rfu_counter++]; - break; + case 0x9a: + rfu_buf = rfu_masterdata[rfu_counter++]; + break; - default: //unknown data (should use 0 or -1 as default), usually returning 0 might cause the game to think there is something wrong with the connection (ie. 0x11/0x13 cmd) - //0x0173 //not 0x0000 as default? - //0x0000 - rfu_buf = 0xffffffff; //rfu_masterdata[rfu_counter++]; - break; - } - break; - } - transfer_direction = 1; + default: //unknown data (should use 0 or -1 as default), usually returning 0 might cause the game to think there is something wrong with the connection (ie. 0x11/0x13 cmd) + //0x0173 //not 0x0000 as default? + //0x0000 + rfu_buf = 0xffffffff; //rfu_masterdata[rfu_counter++]; + break; + } + break; + } + transfer_direction = 1; - PrevVAL = value; - PrevDAT = CurDAT; - PrevCOM = CurCOM; - } + PrevVAL = value; + PrevDAT = CurDAT; + PrevCOM = CurCOM; + } - //Moved from the top to fix Mario Golf Adv from Occasionally Not Detecting wireless adapter - /*if (value & 8) //Transfer Enable Flag Send (bit.3, 1=Disable Transfer/Not Ready) + //Moved from the top to fix Mario Golf Adv from Occasionally Not Detecting wireless adapter + /*if (value & 8) //Transfer Enable Flag Send (bit.3, 1=Disable Transfer/Not Ready) value &= 0xfffb; //Transfer enable flag receive (0=Enable Transfer/Ready, bit.2=bit.3 of otherside) // A kind of acknowledge procedure else //(Bit.3, 0=Enable Transfer/Ready) value |= 4; //bit.2=1 (otherside is Not Ready)*/ - /*if (value & 1) + /*if (value & 1) value |= 0x02; //wireless always use 2Mhz speed right? this will fix MarioGolfAdv Not Detecting wireless*/ - if (rfu_polarity) - value ^= 4; // sometimes it's the other way around - /*value &= 0xfffb; + if (rfu_polarity) + value ^= 4; // sometimes it's the other way around + /*value &= 0xfffb; value |= (value & 1)<<2;*/ - default: - UPDATE_REG(COMM_SIOCNT, value); - return; - } - UPDATE_REG(COMM_SIOCNT, value); + default: + UPDATE_REG(COMM_SIOCNT, value); + return; + } + UPDATE_REG(COMM_SIOCNT, value); } bool LinkRFUUpdate() { - //if (IsLinkConnected()) { - //} - if (rfu_enabled) { - if (transfer_direction&&rfu_transfer_end <= 0) - { - if (rfu_waiting) { - bool ok = false; - u8 oldcmd = rfu_cmd; - u8 oldq = linkmem->rfu_q[vbaid]; - u32 tmout = linktimeout; - //if ((!lanlink.active&&speedhack) || (lanlink.speed&&IsLinkConnected()))tmout = 16; - if (rfu_state != RFU_INIT) - { - if (rfu_cmd == 0x24 || rfu_cmd == 0x25 || rfu_cmd == 0x35) { - //c_s.Lock(); - ok = linkmem->rfu_signal[vbaid] && linkmem->rfu_q[vbaid] > 1 && rfu_qsend > 1; - //c_s.Unlock(); - if (ok && (GetTickCount() - rfu_lasttime) < (DWORD)linktimeout) { return false; } - if (linkmem->rfu_q[vbaid] < 2 || rfu_qsend>1) - { - rfu_cansend = true; - //c_s.Lock(); - linkmem->rfu_q[vbaid] = 0; - linkmem->rfu_qid[vbaid] = 0; - //c_s.Unlock(); - } - rfu_buf = 0x80000000; - } - else{ + //if (IsLinkConnected()) { + //} + if (rfu_enabled) { + if (transfer_direction && rfu_transfer_end <= 0) { + if (rfu_waiting) { + bool ok = false; + u8 oldcmd = rfu_cmd; + u8 oldq = linkmem->rfu_q[vbaid]; + u32 tmout = linktimeout; + //if ((!lanlink.active&&speedhack) || (lanlink.speed&&IsLinkConnected()))tmout = 16; + if (rfu_state != RFU_INIT) { + if (rfu_cmd == 0x24 || rfu_cmd == 0x25 || rfu_cmd == 0x35) { + //c_s.Lock(); + ok = linkmem->rfu_signal[vbaid] && linkmem->rfu_q[vbaid] > 1 && rfu_qsend > 1; + //c_s.Unlock(); + if (ok && (GetTickCount() - rfu_lasttime) < (DWORD)linktimeout) { + return false; + } + if (linkmem->rfu_q[vbaid] < 2 || rfu_qsend > 1) { + rfu_cansend = true; + //c_s.Lock(); + linkmem->rfu_q[vbaid] = 0; + linkmem->rfu_qid[vbaid] = 0; + //c_s.Unlock(); + } + rfu_buf = 0x80000000; + } else { - if (((rfu_cmd == 0x11 || rfu_cmd == 0x1a || rfu_cmd == 0x26) && (GetTickCount() - rfu_lasttime) < 16) || - ((rfu_cmd == 0xa5 || rfu_cmd == 0xb5) && (GetTickCount() - rfu_lasttime) < 16) || - ((rfu_cmd == 0xa7 || rfu_cmd == 0xb7) && (GetTickCount() - rfu_lasttime) < (DWORD)linktimeout)) - { - //c_s.Lock(); - ok = (linkmem->rfu_listfront[vbaid] != linkmem->rfu_listback[vbaid]); - //c_s.Unlock(); - if (!ok) - for (int i = 0; i < linkmem->numgbas; i++) - if (i != vbaid) - if (linkmem->rfu_q[i] && (linkmem->rfu_qid[i] & (1 << vbaid))) { ok = true; break; } - if (!linkmem->rfu_signal[vbaid])ok = true; - if (!ok) { return false; } - } - if (rfu_cmd == 0xa5 || rfu_cmd == 0xa7 || rfu_cmd == 0xb5 || rfu_cmd == 0xb7 || rfu_cmd == 0xee) - rfu_polarity = 1; - if (rfu_cmd == 0xa5 || rfu_cmd == 0xa7) - rfu_cmd = 0x28; - else if (rfu_cmd == 0xb5 || rfu_cmd == 0xb7) - rfu_cmd = 0x36; + if (((rfu_cmd == 0x11 || rfu_cmd == 0x1a || rfu_cmd == 0x26) && (GetTickCount() - rfu_lasttime) < 16) || ((rfu_cmd == 0xa5 || rfu_cmd == 0xb5) && (GetTickCount() - rfu_lasttime) < 16) || ((rfu_cmd == 0xa7 || rfu_cmd == 0xb7) && (GetTickCount() - rfu_lasttime) < (DWORD)linktimeout)) { + //c_s.Lock(); + ok = (linkmem->rfu_listfront[vbaid] != linkmem->rfu_listback[vbaid]); + //c_s.Unlock(); + if (!ok) + for (int i = 0; i < linkmem->numgbas; i++) + if (i != vbaid) + if (linkmem->rfu_q[i] && (linkmem->rfu_qid[i] & (1 << vbaid))) { + ok = true; + break; + } + if (!linkmem->rfu_signal[vbaid]) + ok = true; + if (!ok) { + return false; + } + } + if (rfu_cmd == 0xa5 || rfu_cmd == 0xa7 || rfu_cmd == 0xb5 || rfu_cmd == 0xb7 || rfu_cmd == 0xee) + rfu_polarity = 1; + if (rfu_cmd == 0xa5 || rfu_cmd == 0xa7) + rfu_cmd = 0x28; + else if (rfu_cmd == 0xb5 || rfu_cmd == 0xb7) + rfu_cmd = 0x36; - if (READ32LE(&ioMem[COMM_SIODATA32_L]) == 0x80000000) - rfu_buf = 0x99660000 | (rfu_qrecv_broadcast_data_len << 8) | rfu_cmd; - else - rfu_buf = 0x80000000; - } - rfu_waiting = false; - } - } - UPDATE_REG(COMM_SIODATA32_L, rfu_buf); - UPDATE_REG(COMM_SIODATA32_H, rfu_buf >> 16); - } - } - return true; + if (READ32LE(&ioMem[COMM_SIODATA32_L]) == 0x80000000) + rfu_buf = 0x99660000 | (rfu_qrecv_broadcast_data_len << 8) | rfu_cmd; + else + rfu_buf = 0x80000000; + } + rfu_waiting = false; + } + } + UPDATE_REG(COMM_SIODATA32_L, rfu_buf); + UPDATE_REG(COMM_SIODATA32_H, rfu_buf >> 16); + } + } + return true; } static void UpdateRFUIPC(int ticks) { - if (rfu_enabled) - { - rfu_transfer_end -= ticks; + if (rfu_enabled) { + rfu_transfer_end -= ticks; - if (LinkRFUUpdate()) - { - if (transfer_direction && rfu_transfer_end <= 0) - { - transfer_direction = 0; - u16 value = READ16LE(&ioMem[COMM_SIOCNT]); - if (value & 0x4000) - { - IF |= 0x80; - UPDATE_REG(0x202, IF); - } + if (LinkRFUUpdate()) { + if (transfer_direction && rfu_transfer_end <= 0) { + transfer_direction = 0; + u16 value = READ16LE(&ioMem[COMM_SIOCNT]); + if (value & 0x4000) { + IF |= 0x80; + UPDATE_REG(0x202, IF); + } - //if (rfu_polarity) value ^= 4; - value &= 0xfffb; - value |= (value & 1) << 2; //this will automatically set the correct polarity, even w/o rfu_polarity since the game will be the one who change the polarity instead of the adapter + //if (rfu_polarity) value ^= 4; + value &= 0xfffb; + value |= (value & 1) << 2; //this will automatically set the correct polarity, even w/o rfu_polarity since the game will be the one who change the polarity instead of the adapter - //UPDATE_REG(COMM_SIOCNT, READ16LE(&ioMem[COMM_SIOCNT]) & 0xff7f); - UPDATE_REG(COMM_SIOCNT, (value & 0xff7f) | 0x0008); //Start bit.7 reset, SO bit.3 set automatically upon transfer completion? - //log("SIOn32 : %04X %04X %08X (VCOUNT = %d) %d %d\n", READ16LE(&ioMem[COMM_RCNT]), READ16LE(&ioMem[COMM_SIOCNT]), READ32LE(&ioMem[COMM_SIODATA32_L]), VCOUNT); - } - return; - } - } + //UPDATE_REG(COMM_SIOCNT, READ16LE(&ioMem[COMM_SIOCNT]) & 0xff7f); + UPDATE_REG(COMM_SIOCNT, (value & 0xff7f) | 0x0008); //Start bit.7 reset, SO bit.3 set automatically upon transfer completion? + //log("SIOn32 : %04X %04X %08X (VCOUNT = %d) %d %d\n", READ16LE(&ioMem[COMM_RCNT]), READ16LE(&ioMem[COMM_SIOCNT]), READ32LE(&ioMem[COMM_SIODATA32_L]), VCOUNT); + } + return; + } + } } void gbInitLinkIPC() { - LinkIsWaiting = false; - LinkFirstTime = true; - linkmem->linkcmd[linkid] = 0; - linkmem->linkdata[linkid] = 0xff; + LinkIsWaiting = false; + LinkFirstTime = true; + linkmem->linkcmd[linkid] = 0; + linkmem->linkdata[linkid] = 0xff; } u8 gbStartLinkIPC(u8 b) //used on internal clock { - u8 dat = 0xff; //master (w/ internal clock) will gets 0xff if slave is turned off (or not ready yet also?) - //if(linkid) return 0xff; //b; //Slave shouldn't be sending from here - BOOL sent = false; - //int gbSerialOn = (gbMemory[0xff02] & 0x80); //not needed? - gba_link_enabled = true; //(gbMemory[0xff02]!=0); //not needed? - rfu_enabled = false; + u8 dat = 0xff; //master (w/ internal clock) will gets 0xff if slave is turned off (or not ready yet also?) + //if(linkid) return 0xff; //b; //Slave shouldn't be sending from here + BOOL sent = false; + //int gbSerialOn = (gbMemory[0xff02] & 0x80); //not needed? + gba_link_enabled = true; //(gbMemory[0xff02]!=0); //not needed? + rfu_enabled = false; - if (!gba_link_enabled) return 0xff; + if (!gba_link_enabled) + return 0xff; - //Single Computer - if (GetLinkMode() == LINK_GAMEBOY_IPC) - { - u32 tm = GetTickCount(); - do { - WaitForSingleObject(linksync[linkid], 1); - ResetEvent(linksync[linkid]); - } while (linkmem->linkcmd[linkid] && (GetTickCount() - tm)<(u32)linktimeout); - linkmem->linkdata[linkid] = b; - linkmem->linkcmd[linkid] = 1; - SetEvent(linksync[linkid]); + //Single Computer + if (GetLinkMode() == LINK_GAMEBOY_IPC) { + u32 tm = GetTickCount(); + do { + WaitForSingleObject(linksync[linkid], 1); + ResetEvent(linksync[linkid]); + } while (linkmem->linkcmd[linkid] && (GetTickCount() - tm) < (u32)linktimeout); + linkmem->linkdata[linkid] = b; + linkmem->linkcmd[linkid] = 1; + SetEvent(linksync[linkid]); - LinkIsWaiting = false; - tm = GetTickCount(); - do { - WaitForSingleObject(linksync[1 - linkid], 1); - ResetEvent(linksync[1 - linkid]); - } while (!linkmem->linkcmd[1 - linkid] && (GetTickCount() - tm)<(u32)linktimeout); - if (linkmem->linkcmd[1 - linkid]) { - dat = (u8)linkmem->linkdata[1 - linkid]; - linkmem->linkcmd[1 - linkid] = 0; - } //else LinkIsWaiting = true; - SetEvent(linksync[1 - linkid]); + LinkIsWaiting = false; + tm = GetTickCount(); + do { + WaitForSingleObject(linksync[1 - linkid], 1); + ResetEvent(linksync[1 - linkid]); + } while (!linkmem->linkcmd[1 - linkid] && (GetTickCount() - tm) < (u32)linktimeout); + if (linkmem->linkcmd[1 - linkid]) { + dat = (u8)linkmem->linkdata[1 - linkid]; + linkmem->linkcmd[1 - linkid] = 0; + } //else LinkIsWaiting = true; + SetEvent(linksync[1 - linkid]); - LinkFirstTime = true; - if (dat != 0xff/*||b==0x00||dat==0x00*/) - LinkFirstTime = false; + LinkFirstTime = true; + if (dat != 0xff /*||b==0x00||dat==0x00*/) + LinkFirstTime = false; - return dat; - } - return dat; + return dat; + } + return dat; } u16 gbLinkUpdateIPC(u8 b, int gbSerialOn) //used on external clock { - u8 dat = b; //0xff; //slave (w/ external clocks) won't be getting 0xff if master turned off - BOOL recvd = false; - int idx = 0; + u8 dat = b; //0xff; //slave (w/ external clocks) won't be getting 0xff if master turned off + BOOL recvd = false; + int idx = 0; - gba_link_enabled = true; //(gbMemory[0xff02]!=0); - rfu_enabled = false; + gba_link_enabled = true; //(gbMemory[0xff02]!=0); + rfu_enabled = false; - if (gbSerialOn) { - if (gba_link_enabled) - //Single Computer - if (GetLinkMode() == LINK_GAMEBOY_IPC) - { - u32 tm;// = GetTickCount(); - //do { - WaitForSingleObject(linksync[1 - linkid], linktimeout); - ResetEvent(linksync[1 - linkid]); - //} while (!linkmem->linkcmd[1-linkid] && (GetTickCount()-tm)<(u32)linktimeout); - if (linkmem->linkcmd[1 - linkid]) { - dat = (u8)linkmem->linkdata[1 - linkid]; - linkmem->linkcmd[1 - linkid] = 0; - recvd = true; - LinkIsWaiting = false; - } - else LinkIsWaiting = true; - SetEvent(linksync[1 - linkid]); + if (gbSerialOn) { + if (gba_link_enabled) + //Single Computer + if (GetLinkMode() == LINK_GAMEBOY_IPC) { + u32 tm; // = GetTickCount(); + //do { + WaitForSingleObject(linksync[1 - linkid], linktimeout); + ResetEvent(linksync[1 - linkid]); + //} while (!linkmem->linkcmd[1-linkid] && (GetTickCount()-tm)<(u32)linktimeout); + if (linkmem->linkcmd[1 - linkid]) { + dat = (u8)linkmem->linkdata[1 - linkid]; + linkmem->linkcmd[1 - linkid] = 0; + recvd = true; + LinkIsWaiting = false; + } else + LinkIsWaiting = true; + SetEvent(linksync[1 - linkid]); - if (!LinkIsWaiting) { - tm = GetTickCount(); - do { - WaitForSingleObject(linksync[linkid], 1); - ResetEvent(linksync[linkid]); - } while (linkmem->linkcmd[1 - linkid] && (GetTickCount() - tm)<(u32)linktimeout); - if (!linkmem->linkcmd[linkid]) { - linkmem->linkdata[linkid] = b; - linkmem->linkcmd[linkid] = 1; - } - SetEvent(linksync[linkid]); - } + if (!LinkIsWaiting) { + tm = GetTickCount(); + do { + WaitForSingleObject(linksync[linkid], 1); + ResetEvent(linksync[linkid]); + } while (linkmem->linkcmd[1 - linkid] && (GetTickCount() - tm) < (u32)linktimeout); + if (!linkmem->linkcmd[linkid]) { + linkmem->linkdata[linkid] = b; + linkmem->linkcmd[linkid] = 1; + } + SetEvent(linksync[linkid]); + } + } - } - - if (dat == 0xff/*||dat==0x00||b==0x00*/) //dat==0xff||dat==0x00 - LinkFirstTime = true; - } - return ((dat << 8) | (recvd & (u8)0xff)); + if (dat == 0xff /*||dat==0x00||b==0x00*/) //dat==0xff||dat==0x00 + LinkFirstTime = true; + } + return ((dat << 8) | (recvd & (u8)0xff)); } -static void CloseIPC() { - int f = linkmem->linkflags; - f &= ~(1 << linkid); - if(f & 0xf) { - linkmem->linkflags = f; - int n = linkmem->numgbas; - for(int i = 0; i < n; i--) - if(f <= (1 << (i + 1)) - 1) { - linkmem->numgbas = i + 1; - break; - } - } +static void CloseIPC() +{ + int f = linkmem->linkflags; + f &= ~(1 << linkid); + if (f & 0xf) { + linkmem->linkflags = f; + int n = linkmem->numgbas; + for (int i = 0; i < n; i--) + if (f <= (1 << (i + 1)) - 1) { + linkmem->numgbas = i + 1; + break; + } + } - for(i=0;i<4;i++) { - if(linksync[i]!=NULL) { + for (i = 0; i < 4; i++) { + if (linksync[i] != NULL) { #if (defined __WIN32__ || defined _WIN32) - ReleaseSemaphore(linksync[i], 1, NULL); - CloseHandle(linksync[i]); + ReleaseSemaphore(linksync[i], 1, NULL); + CloseHandle(linksync[i]); #else - sem_close(linksync[i]); - if(!(f & 0xf)) { - linkevent[sizeof(linkevent)-2]=(char)i+'1'; - sem_unlink(linkevent); - } + sem_close(linksync[i]); + if (!(f & 0xf)) { + linkevent[sizeof(linkevent) - 2] = (char)i + '1'; + sem_unlink(linkevent); + } #endif - } - } + } + } #if (defined __WIN32__ || defined _WIN32) - CloseHandle(mmf); - UnmapViewOfFile(linkmem); + CloseHandle(mmf); + UnmapViewOfFile(linkmem); - // FIXME: move to caller - // (but there are no callers, so why bother?) - //regSetDwordValue("LAN", lanlink.active); +// FIXME: move to caller +// (but there are no callers, so why bother?) +//regSetDwordValue("LAN", lanlink.active); #else - if(!(f & 0xf)) - shm_unlink("/" LOCAL_LINK_NAME); - munmap(linkmem, sizeof(LINKDATA)); - close(mmf); + if (!(f & 0xf)) + shm_unlink("/" LOCAL_LINK_NAME); + munmap(linkmem, sizeof(LINKDATA)); + close(mmf); #endif } diff --git a/src/gba/GBALink.h b/src/gba/GBALink.h index ba8725d1..4ba965b0 100644 --- a/src/gba/GBALink.h +++ b/src/gba/GBALink.h @@ -5,20 +5,23 @@ * Link modes to be passed to InitLink */ enum LinkMode { - LINK_DISCONNECTED, - LINK_CABLE_IPC, - LINK_CABLE_SOCKET, - LINK_RFU_IPC, - LINK_RFU_SOCKET, - LINK_GAMECUBE_DOLPHIN, - LINK_GAMEBOY_IPC, - LINK_GAMEBOY_SOCKET + LINK_DISCONNECTED, + LINK_CABLE_IPC, + LINK_CABLE_SOCKET, + LINK_RFU_IPC, + LINK_RFU_SOCKET, + LINK_GAMECUBE_DOLPHIN, + LINK_GAMEBOY_IPC, + LINK_GAMEBOY_SOCKET }; /** * State of the connection attempt */ -enum ConnectionState { LINK_OK, LINK_ERROR, LINK_NEEDS_UPDATE, LINK_ABORT }; +enum ConnectionState { LINK_OK, + LINK_ERROR, + LINK_NEEDS_UPDATE, + LINK_ABORT }; /** * Initialize GBA linking @@ -34,7 +37,7 @@ extern ConnectionState InitLink(LinkMode mode); * @param message Information message * @param size Maximum message size */ -extern ConnectionState ConnectLinkUpdate(char *const message, size_t size); +extern ConnectionState ConnectLinkUpdate(char* const message, size_t size); /** * Get the currently enabled link mode @@ -63,7 +66,7 @@ extern void EnableSpeedHacks(bool enable); * * @return false if the address is invalid */ -extern bool SetLinkServerHost(const char *host); +extern bool SetLinkServerHost(const char* host); /** * Get the host relevant to context @@ -73,7 +76,7 @@ extern bool SetLinkServerHost(const char *host); * If in gamecube mode, returns the IP adress of the dolphin host * */ -extern void GetLinkServerHost(char *const host, size_t size); +extern void GetLinkServerHost(char* const host, size_t size); /** * Set the value in milliseconds of the timeout after which a connection is @@ -131,20 +134,20 @@ extern void CleanLocalLink(); * @return completed filename */ -extern const char *MakeInstanceFilename(const char *Input); +extern const char* MakeInstanceFilename(const char* Input); // register definitions #define COMM_SIODATA32_L 0x120 // Lower 16bit on Normal mode #define COMM_SIODATA32_H 0x122 // Higher 16bit on Normal mode #define COMM_SIOCNT 0x128 -#define COMM_SIODATA8 0x12a // 8bit on Normal/UART mode, (up to 4x8bit with FIFO) +#define COMM_SIODATA8 0x12a // 8bit on Normal/UART mode, (up to 4x8bit with FIFO) #define COMM_SIOMLT_SEND 0x12a // SIOMLT_SEND (16bit R/W) on MultiPlayer mode (local outgoing) -#define COMM_SIOMULTI0 0x120 // SIOMULTI0 (16bit) on MultiPlayer mode (Parent/Master) -#define COMM_SIOMULTI1 0x122 // SIOMULTI1 (16bit) on MultiPlayer mode (Child1/Slave1) -#define COMM_SIOMULTI2 0x124 // SIOMULTI2 (16bit) on MultiPlayer mode (Child2/Slave2) -#define COMM_SIOMULTI3 0x126 // SIOMULTI3 (16bit) on MultiPlayer mode (Child3/Slave3) -#define COMM_RCNT 0x134 // SIO Mode (4bit data) on GeneralPurpose mode -#define COMM_IR 0x136 // Infrared Register (16bit) 1bit data at a time(LED On/Off)? +#define COMM_SIOMULTI0 0x120 // SIOMULTI0 (16bit) on MultiPlayer mode (Parent/Master) +#define COMM_SIOMULTI1 0x122 // SIOMULTI1 (16bit) on MultiPlayer mode (Child1/Slave1) +#define COMM_SIOMULTI2 0x124 // SIOMULTI2 (16bit) on MultiPlayer mode (Child2/Slave2) +#define COMM_SIOMULTI3 0x126 // SIOMULTI3 (16bit) on MultiPlayer mode (Child3/Slave3) +#define COMM_RCNT 0x134 // SIO Mode (4bit data) on GeneralPurpose mode +#define COMM_IR 0x136 // Infrared Register (16bit) 1bit data at a time(LED On/Off)? #define COMM_JOYCNT 0x140 #define COMM_JOY_RECV_L 0x150 // Send/Receive 8bit Lower first then 8bit Higher #define COMM_JOY_RECV_H 0x152 @@ -176,16 +179,16 @@ extern const char *MakeInstanceFilename(const char *Input); #define RFU_SEND 2 #define RFU_RECV 3 -#define RF_RECVCMD \ - 0x278 // Unknown, Seems to be related to Wireless Adapter(RF_RCNT or armMode/CPSR or CMD - // sent by the adapter when RF_SIOCNT=0x83 or when RCNT=0x80aX?) +#define RF_RECVCMD \ + 0x278 // Unknown, Seems to be related to Wireless Adapter(RF_RCNT or armMode/CPSR or CMD +// sent by the adapter when RF_SIOCNT=0x83 or when RCNT=0x80aX?) #define RF_CNT 0x27a // Unknown, Seems to be related to Wireless Adapter(RF_SIOCNT?) typedef struct { - u8 len; // data len in 32bit words - u8 gbaid; // source id - u32 time; // linktime - u32 data[255]; + u8 len; // data len in 32bit words + u8 gbaid; // source id + u32 time; // linktime + u32 data[255]; } rfu_datarec; extern u8 gbSIO_SC; @@ -199,6 +202,6 @@ extern void gbInitLinkIPC(); extern u8 gbStartLinkIPC(u8 b); extern u16 gbLinkUpdateIPC(u8 b, int gbSerialOn); -extern void BootLink(int m_type, const char *host, int timeout, bool m_hacks, int m_numplayers); +extern void BootLink(int m_type, const char* host, int timeout, bool m_hacks, int m_numplayers); #endif /* GBA_GBALINK_H */ diff --git a/src/gba/GBASockClient.cpp b/src/gba/GBASockClient.cpp index c7daeb4b..17e94891 100644 --- a/src/gba/GBASockClient.cpp +++ b/src/gba/GBASockClient.cpp @@ -6,94 +6,92 @@ GBASockClient::GBASockClient(sf::IpAddress _server_addr) { - if (_server_addr == sf::IpAddress::None) - server_addr = sf::IpAddress::LocalHost; - else - server_addr = _server_addr; + if (_server_addr == sf::IpAddress::None) + server_addr = sf::IpAddress::LocalHost; + else + server_addr = _server_addr; - client.connect(server_addr, 0xd6ba); - client.setBlocking(false); + client.connect(server_addr, 0xd6ba); + client.setBlocking(false); - clock_client.connect(server_addr, 0xc10c); - clock_client.setBlocking(false); + clock_client.connect(server_addr, 0xc10c); + clock_client.setBlocking(false); - clock_sync = 0; - is_disconnected = false; + clock_sync = 0; + is_disconnected = false; } GBASockClient::~GBASockClient() { - client.disconnect(); - clock_client.disconnect(); + client.disconnect(); + clock_client.disconnect(); } u32 clock_sync_ticks = 0; void GBASockClient::Send(std::vector data) { - char* plain_data = new char[data.size()]; - std::copy(data.begin(), data.end(), plain_data); + char* plain_data = new char[data.size()]; + std::copy(data.begin(), data.end(), plain_data); - client.send(plain_data, data.size()); + client.send(plain_data, data.size()); - delete[] plain_data; + delete[] plain_data; } // Returns cmd for convenience char GBASockClient::ReceiveCmd(char* data_in, bool block) { - if (IsDisconnected()) - return data_in[0]; + if (IsDisconnected()) + return data_in[0]; - std::size_t num_received = 0; - if (block || clock_sync == 0) - { - sf::SocketSelector Selector; - Selector.add(client); - Selector.wait(sf::seconds(6)); - } - if (client.receive(data_in, 5, num_received) == sf::Socket::Disconnected) - Disconnect(); + std::size_t num_received = 0; + if (block || clock_sync == 0) { + sf::SocketSelector Selector; + Selector.add(client); + Selector.wait(sf::seconds(6)); + } + if (client.receive(data_in, 5, num_received) == sf::Socket::Disconnected) + Disconnect(); - return data_in[0]; + return data_in[0]; } void GBASockClient::ReceiveClock(bool block) { - if (IsDisconnected()) - return; + if (IsDisconnected()) + return; - char sync_ticks[4] = { 0, 0, 0, 0 }; - std::size_t num_received = 0; - if (clock_client.receive(sync_ticks, 4, num_received) == sf::Socket::Disconnected) - Disconnect(); + char sync_ticks[4] = { 0, 0, 0, 0 }; + std::size_t num_received = 0; + if (clock_client.receive(sync_ticks, 4, num_received) == sf::Socket::Disconnected) + Disconnect(); - if (num_received == 4) - { - clock_sync_ticks = 0; - for (int i = 0; i < 4; i++) - clock_sync_ticks |= (u8)(sync_ticks[i]) << ((3 - i) * 8); - clock_sync += clock_sync_ticks; - } + if (num_received == 4) { + clock_sync_ticks = 0; + for (int i = 0; i < 4; i++) + clock_sync_ticks |= (u8)(sync_ticks[i]) << ((3 - i) * 8); + clock_sync += clock_sync_ticks; + } } void GBASockClient::ClockSync(u32 ticks) { - if (clock_sync > (s32)ticks) - clock_sync -= (s32)ticks; - else - clock_sync = 0; + if (clock_sync > (s32)ticks) + clock_sync -= (s32)ticks; + else + clock_sync = 0; } void GBASockClient::Disconnect() { - is_disconnected = true; - client.disconnect(); - clock_client.disconnect(); + is_disconnected = true; + client.disconnect(); + clock_client.disconnect(); } bool GBASockClient::IsDisconnected() { - return is_disconnected; + return is_disconnected; } #endif // NO_LINK diff --git a/src/gba/GBASockClient.h b/src/gba/GBASockClient.h index 73252029..15e8b25b 100644 --- a/src/gba/GBASockClient.h +++ b/src/gba/GBASockClient.h @@ -3,26 +3,25 @@ #include "../common/Types.h" #include -class GBASockClient -{ - public: - GBASockClient(sf::IpAddress _server_addr); - ~GBASockClient(); +class GBASockClient { +public: + GBASockClient(sf::IpAddress _server_addr); + ~GBASockClient(); - bool Connect(sf::IpAddress server_addr); - void Send(std::vector data); - char ReceiveCmd(char *data_in, bool block); - void ReceiveClock(bool block); + bool Connect(sf::IpAddress server_addr); + void Send(std::vector data); + char ReceiveCmd(char* data_in, bool block); + void ReceiveClock(bool block); - void ClockSync(u32 ticks); - void Disconnect(); - bool IsDisconnected(); + void ClockSync(u32 ticks); + void Disconnect(); + bool IsDisconnected(); - private: - sf::IpAddress server_addr; - sf::TcpSocket client; - sf::TcpSocket clock_client; +private: + sf::IpAddress server_addr; + sf::TcpSocket client; + sf::TcpSocket clock_client; - s32 clock_sync; - bool is_disconnected; + s32 clock_sync; + bool is_disconnected; }; diff --git a/src/gba/GBAcpu.h b/src/gba/GBAcpu.h index dc651cd3..e48852c1 100644 --- a/src/gba/GBAcpu.h +++ b/src/gba/GBAcpu.h @@ -18,22 +18,22 @@ extern int thumbExecute(); #define UNLIKELY(x) (x) #endif -#define UPDATE_REG(address, value) \ - { \ - WRITE16LE(((u16 *)&ioMem[address]), value); \ - } +#define UPDATE_REG(address, value) \ + { \ + WRITE16LE(((u16*)&ioMem[address]), value); \ + } -#define ARM_PREFETCH \ - { \ - cpuPrefetch[0] = CPUReadMemoryQuick(armNextPC); \ - cpuPrefetch[1] = CPUReadMemoryQuick(armNextPC + 4); \ - } +#define ARM_PREFETCH \ + { \ + cpuPrefetch[0] = CPUReadMemoryQuick(armNextPC); \ + cpuPrefetch[1] = CPUReadMemoryQuick(armNextPC + 4); \ + } -#define THUMB_PREFETCH \ - { \ - cpuPrefetch[0] = CPUReadHalfWordQuick(armNextPC); \ - cpuPrefetch[1] = CPUReadHalfWordQuick(armNextPC + 2); \ - } +#define THUMB_PREFETCH \ + { \ + cpuPrefetch[0] = CPUReadHalfWordQuick(armNextPC); \ + cpuPrefetch[1] = CPUReadHalfWordQuick(armNextPC + 2); \ + } #define ARM_PREFETCH_NEXT cpuPrefetch[1] = CPUReadMemoryQuick(armNextPC + 4); @@ -66,179 +66,172 @@ extern void CPUSoftwareInterrupt(int comment); // Waitstates when accessing data inline int dataTicksAccess16(u32 address) // DATA 8/16bits NON SEQ { - int addr = (address >> 24) & 15; - int value = memoryWait[addr]; + int addr = (address >> 24) & 15; + int value = memoryWait[addr]; - if ((addr >= 0x08) || (addr < 0x02)) { - busPrefetchCount = 0; - busPrefetch = false; - } else if (busPrefetch) { - int waitState = value; - if (!waitState) - waitState = 1; - busPrefetchCount = ((busPrefetchCount + 1) << waitState) - 1; - } + if ((addr >= 0x08) || (addr < 0x02)) { + busPrefetchCount = 0; + busPrefetch = false; + } else if (busPrefetch) { + int waitState = value; + if (!waitState) + waitState = 1; + busPrefetchCount = ((busPrefetchCount + 1) << waitState) - 1; + } - return value; + return value; } inline int dataTicksAccess32(u32 address) // DATA 32bits NON SEQ { - int addr = (address >> 24) & 15; - int value = memoryWait32[addr]; + int addr = (address >> 24) & 15; + int value = memoryWait32[addr]; - if ((addr >= 0x08) || (addr < 0x02)) { - busPrefetchCount = 0; - busPrefetch = false; - } else if (busPrefetch) { - int waitState = value; - if (!waitState) - waitState = 1; - busPrefetchCount = ((busPrefetchCount + 1) << waitState) - 1; - } + if ((addr >= 0x08) || (addr < 0x02)) { + busPrefetchCount = 0; + busPrefetch = false; + } else if (busPrefetch) { + int waitState = value; + if (!waitState) + waitState = 1; + busPrefetchCount = ((busPrefetchCount + 1) << waitState) - 1; + } - return value; + return value; } inline int dataTicksAccessSeq16(u32 address) // DATA 8/16bits SEQ { - int addr = (address >> 24) & 15; - int value = memoryWaitSeq[addr]; + int addr = (address >> 24) & 15; + int value = memoryWaitSeq[addr]; - if ((addr >= 0x08) || (addr < 0x02)) { - busPrefetchCount = 0; - busPrefetch = false; - } else if (busPrefetch) { - int waitState = value; - if (!waitState) - waitState = 1; - busPrefetchCount = ((busPrefetchCount + 1) << waitState) - 1; - } + if ((addr >= 0x08) || (addr < 0x02)) { + busPrefetchCount = 0; + busPrefetch = false; + } else if (busPrefetch) { + int waitState = value; + if (!waitState) + waitState = 1; + busPrefetchCount = ((busPrefetchCount + 1) << waitState) - 1; + } - return value; + return value; } inline int dataTicksAccessSeq32(u32 address) // DATA 32bits SEQ { - int addr = (address >> 24) & 15; - int value = memoryWaitSeq32[addr]; + int addr = (address >> 24) & 15; + int value = memoryWaitSeq32[addr]; - if ((addr >= 0x08) || (addr < 0x02)) { - busPrefetchCount = 0; - busPrefetch = false; - } else if (busPrefetch) { - int waitState = value; - if (!waitState) - waitState = 1; - busPrefetchCount = ((busPrefetchCount + 1) << waitState) - 1; - } + if ((addr >= 0x08) || (addr < 0x02)) { + busPrefetchCount = 0; + busPrefetch = false; + } else if (busPrefetch) { + int waitState = value; + if (!waitState) + waitState = 1; + busPrefetchCount = ((busPrefetchCount + 1) << waitState) - 1; + } - return value; + return value; } // Waitstates when executing opcode inline int codeTicksAccess16(u32 address) // THUMB NON SEQ { - int addr = (address >> 24) & 15; + int addr = (address >> 24) & 15; - if ((addr >= 0x08) && (addr <= 0x0D)) { - if (busPrefetchCount & 0x1) { - if (busPrefetchCount & 0x2) { - busPrefetchCount = ((busPrefetchCount & 0xFF) >> 2) | - (busPrefetchCount & 0xFFFFFF00); - return 0; - } - busPrefetchCount = - ((busPrefetchCount & 0xFF) >> 1) | (busPrefetchCount & 0xFFFFFF00); - return memoryWaitSeq[addr] - 1; - } else { - busPrefetchCount = 0; - return memoryWait[addr]; - } + if ((addr >= 0x08) && (addr <= 0x0D)) { + if (busPrefetchCount & 0x1) { + if (busPrefetchCount & 0x2) { + busPrefetchCount = ((busPrefetchCount & 0xFF) >> 2) | (busPrefetchCount & 0xFFFFFF00); + return 0; + } + busPrefetchCount = ((busPrefetchCount & 0xFF) >> 1) | (busPrefetchCount & 0xFFFFFF00); + return memoryWaitSeq[addr] - 1; } else { - busPrefetchCount = 0; - return memoryWait[addr]; + busPrefetchCount = 0; + return memoryWait[addr]; } + } else { + busPrefetchCount = 0; + return memoryWait[addr]; + } } inline int codeTicksAccess32(u32 address) // ARM NON SEQ { - int addr = (address >> 24) & 15; + int addr = (address >> 24) & 15; - if ((addr >= 0x08) && (addr <= 0x0D)) { - if (busPrefetchCount & 0x1) { - if (busPrefetchCount & 0x2) { - busPrefetchCount = ((busPrefetchCount & 0xFF) >> 2) | - (busPrefetchCount & 0xFFFFFF00); - return 0; - } - busPrefetchCount = - ((busPrefetchCount & 0xFF) >> 1) | (busPrefetchCount & 0xFFFFFF00); - return memoryWaitSeq[addr] - 1; - } else { - busPrefetchCount = 0; - return memoryWait32[addr]; - } + if ((addr >= 0x08) && (addr <= 0x0D)) { + if (busPrefetchCount & 0x1) { + if (busPrefetchCount & 0x2) { + busPrefetchCount = ((busPrefetchCount & 0xFF) >> 2) | (busPrefetchCount & 0xFFFFFF00); + return 0; + } + busPrefetchCount = ((busPrefetchCount & 0xFF) >> 1) | (busPrefetchCount & 0xFFFFFF00); + return memoryWaitSeq[addr] - 1; } else { - busPrefetchCount = 0; - return memoryWait32[addr]; + busPrefetchCount = 0; + return memoryWait32[addr]; } + } else { + busPrefetchCount = 0; + return memoryWait32[addr]; + } } inline int codeTicksAccessSeq16(u32 address) // THUMB SEQ { - int addr = (address >> 24) & 15; + int addr = (address >> 24) & 15; - if ((addr >= 0x08) && (addr <= 0x0D)) { - if (busPrefetchCount & 0x1) { - busPrefetchCount = - ((busPrefetchCount & 0xFF) >> 1) | (busPrefetchCount & 0xFFFFFF00); - return 0; - } else if (busPrefetchCount > 0xFF) { - busPrefetchCount = 0; - return memoryWait[addr]; - } else - return memoryWaitSeq[addr]; - } else { - busPrefetchCount = 0; - return memoryWaitSeq[addr]; - } + if ((addr >= 0x08) && (addr <= 0x0D)) { + if (busPrefetchCount & 0x1) { + busPrefetchCount = ((busPrefetchCount & 0xFF) >> 1) | (busPrefetchCount & 0xFFFFFF00); + return 0; + } else if (busPrefetchCount > 0xFF) { + busPrefetchCount = 0; + return memoryWait[addr]; + } else + return memoryWaitSeq[addr]; + } else { + busPrefetchCount = 0; + return memoryWaitSeq[addr]; + } } inline int codeTicksAccessSeq32(u32 address) // ARM SEQ { - int addr = (address >> 24) & 15; + int addr = (address >> 24) & 15; - if ((addr >= 0x08) && (addr <= 0x0D)) { - if (busPrefetchCount & 0x1) { - if (busPrefetchCount & 0x2) { - busPrefetchCount = ((busPrefetchCount & 0xFF) >> 2) | - (busPrefetchCount & 0xFFFFFF00); - return 0; - } - busPrefetchCount = - ((busPrefetchCount & 0xFF) >> 1) | (busPrefetchCount & 0xFFFFFF00); - return memoryWaitSeq[addr]; - } else if (busPrefetchCount > 0xFF) { - busPrefetchCount = 0; - return memoryWait32[addr]; - } else - return memoryWaitSeq32[addr]; - } else { - return memoryWaitSeq32[addr]; - } + if ((addr >= 0x08) && (addr <= 0x0D)) { + if (busPrefetchCount & 0x1) { + if (busPrefetchCount & 0x2) { + busPrefetchCount = ((busPrefetchCount & 0xFF) >> 2) | (busPrefetchCount & 0xFFFFFF00); + return 0; + } + busPrefetchCount = ((busPrefetchCount & 0xFF) >> 1) | (busPrefetchCount & 0xFFFFFF00); + return memoryWaitSeq[addr]; + } else if (busPrefetchCount > 0xFF) { + busPrefetchCount = 0; + return memoryWait32[addr]; + } else + return memoryWaitSeq32[addr]; + } else { + return memoryWaitSeq32[addr]; + } } // Emulates the Cheat System (m) code inline void cpuMasterCodeCheck() { - if ((mastercode) && (mastercode == armNextPC)) { - u32 joy = 0; - if (systemReadJoypads()) - joy = systemReadJoypad(-1); - u32 ext = (joy >> 10); - cpuTotalTicks += cheatsCheckKeys(P1 ^ 0x3FF, ext); - } + if ((mastercode) && (mastercode == armNextPC)) { + u32 joy = 0; + if (systemReadJoypads()) + joy = systemReadJoypad(-1); + u32 ext = (joy >> 10); + cpuTotalTicks += cheatsCheckKeys(P1 ^ 0x3FF, ext); + } } #endif // GBACPU_H diff --git a/src/gba/GBAinline.h b/src/gba/GBAinline.h index 22ee01c6..b17641e3 100644 --- a/src/gba/GBAinline.h +++ b/src/gba/GBAinline.h @@ -38,784 +38,777 @@ extern int cpuTotalTicks; #define CPUReadByteQuick(addr) map[(addr) >> 24].address[(addr)&map[(addr) >> 24].mask] -#define CPUReadHalfWordQuick(addr) \ - READ16LE(((u16 *)&map[(addr) >> 24].address[(addr)&map[(addr) >> 24].mask])) +#define CPUReadHalfWordQuick(addr) \ + READ16LE(((u16*)&map[(addr) >> 24].address[(addr)&map[(addr) >> 24].mask])) -#define CPUReadMemoryQuick(addr) \ - READ32LE(((u32 *)&map[(addr) >> 24].address[(addr)&map[(addr) >> 24].mask])) +#define CPUReadMemoryQuick(addr) \ + READ32LE(((u32*)&map[(addr) >> 24].address[(addr)&map[(addr) >> 24].mask])) extern u32 myROM[]; static inline u32 CPUReadMemory(u32 address) { #ifdef BKPT_SUPPORT - memoryMap *m = &map[address >> 24]; - if (m->breakPoints && BreakReadCheck(m->breakPoints, address & m->mask)) { - if (debuggerBreakOnRead(address, 2)) { - // CPU_BREAK_LOOP_2; - } + memoryMap* m = &map[address >> 24]; + if (m->breakPoints && BreakReadCheck(m->breakPoints, address & m->mask)) { + if (debuggerBreakOnRead(address, 2)) { + // CPU_BREAK_LOOP_2; } + } #endif - u32 value; - u32 oldAddress = address; + u32 value; + u32 oldAddress = address; - if (address & 3) { - address &= ~0x03; - } + if (address & 3) { + address &= ~0x03; + } - switch (address >> 24) { - case 0: - if (reg[15].I >> 24) { - if (address < 0x4000) { -#ifdef GBA_LOGGING - if (systemVerbose & VERBOSE_ILLEGAL_READ) { - log("Illegal word read from bios: %08x at %08x\n", - address, - armMode ? armNextPC - 4 : armNextPC - 2); - } -#endif - - value = READ32LE(((u32 *)&biosProtected)); - } else - goto unreadable; - } else - value = READ32LE(((u32 *)&bios[address & 0x3FFC])); - break; - case 2: - value = READ32LE(((u32 *)&workRAM[address & 0x3FFFC])); - break; - case 3: - value = READ32LE(((u32 *)&internalRAM[address & 0x7ffC])); - break; - case 4: - if ((address < 0x4000400) && ioReadable[address & 0x3fc]) { - if (ioReadable[(address & 0x3fc) + 2]) { - value = READ32LE(((u32 *)&ioMem[address & 0x3fC])); - if ((address & 0x3fc) == COMM_JOY_RECV_L) - UPDATE_REG(COMM_JOYSTAT, - READ16LE(&ioMem[COMM_JOYSTAT]) & ~JOYSTAT_RECV); - } else { - value = READ16LE(((u16 *)&ioMem[address & 0x3fc])); - } - } else - goto unreadable; - break; - case 5: - value = READ32LE(((u32 *)&paletteRAM[address & 0x3fC])); - break; - case 6: - address = (address & 0x1fffc); - if (((DISPCNT & 7) > 2) && ((address & 0x1C000) == 0x18000)) { - value = 0; - break; - } - if ((address & 0x18000) == 0x18000) - address &= 0x17fff; - value = READ32LE(((u32 *)&vram[address])); - break; - case 7: - value = READ32LE(((u32 *)&oam[address & 0x3FC])); - break; - case 8: - case 9: - case 10: - case 11: - case 12: - value = READ32LE(((u32 *)&rom[address & 0x1FFFFFC])); - break; - case 13: - if (cpuEEPROMEnabled) - // no need to swap this - return eepromRead(address); - goto unreadable; - case 14: - case 15: - if (cpuFlashEnabled | cpuSramEnabled) { // no need to swap this -#ifdef __libretro__ - return flashRead(address); -#else - value = flashRead(address) * 0x01010101; -#endif - } - break; - // default - default: - unreadable: + switch (address >> 24) { + case 0: + if (reg[15].I >> 24) { + if (address < 0x4000) { #ifdef GBA_LOGGING if (systemVerbose & VERBOSE_ILLEGAL_READ) { - log("Illegal word read: %08x at %08x\n", - address, - armMode ? armNextPC - 4 : armNextPC - 2); + log("Illegal word read from bios: %08x at %08x\n", + address, + armMode ? armNextPC - 4 : armNextPC - 2); } #endif - if (cpuDmaHack) { - value = cpuDmaLast; - } else { - if (armState) { - return CPUReadMemoryQuick(reg[15].I); - } else { - return CPUReadHalfWordQuick(reg[15].I) | - CPUReadHalfWordQuick(reg[15].I) << 16; - } - } - break; - } - if (oldAddress & 3) { + value = READ32LE(((u32*)&biosProtected)); + } else + goto unreadable; + } else + value = READ32LE(((u32*)&bios[address & 0x3FFC])); + break; + case 2: + value = READ32LE(((u32*)&workRAM[address & 0x3FFFC])); + break; + case 3: + value = READ32LE(((u32*)&internalRAM[address & 0x7ffC])); + break; + case 4: + if ((address < 0x4000400) && ioReadable[address & 0x3fc]) { + if (ioReadable[(address & 0x3fc) + 2]) { + value = READ32LE(((u32*)&ioMem[address & 0x3fC])); + if ((address & 0x3fc) == COMM_JOY_RECV_L) + UPDATE_REG(COMM_JOYSTAT, + READ16LE(&ioMem[COMM_JOYSTAT]) & ~JOYSTAT_RECV); + } else { + value = READ16LE(((u16*)&ioMem[address & 0x3fc])); + } + } else + goto unreadable; + break; + case 5: + value = READ32LE(((u32*)&paletteRAM[address & 0x3fC])); + break; + case 6: + address = (address & 0x1fffc); + if (((DISPCNT & 7) > 2) && ((address & 0x1C000) == 0x18000)) { + value = 0; + break; + } + if ((address & 0x18000) == 0x18000) + address &= 0x17fff; + value = READ32LE(((u32*)&vram[address])); + break; + case 7: + value = READ32LE(((u32*)&oam[address & 0x3FC])); + break; + case 8: + case 9: + case 10: + case 11: + case 12: + value = READ32LE(((u32*)&rom[address & 0x1FFFFFC])); + break; + case 13: + if (cpuEEPROMEnabled) + // no need to swap this + return eepromRead(address); + goto unreadable; + case 14: + case 15: + if (cpuFlashEnabled | cpuSramEnabled) { // no need to swap this +#ifdef __libretro__ + return flashRead(address); +#else + value = flashRead(address) * 0x01010101; +#endif + } + break; + // default + default: + unreadable: +#ifdef GBA_LOGGING + if (systemVerbose & VERBOSE_ILLEGAL_READ) { + log("Illegal word read: %08x at %08x\n", + address, + armMode ? armNextPC - 4 : armNextPC - 2); + } +#endif + if (cpuDmaHack) { + value = cpuDmaLast; + } else { + if (armState) { + return CPUReadMemoryQuick(reg[15].I); + } else { + return CPUReadHalfWordQuick(reg[15].I) | CPUReadHalfWordQuick(reg[15].I) << 16; + } + } + break; + } + + if (oldAddress & 3) { #ifdef C_CORE - int shift = (oldAddress & 3) << 3; - value = (value >> shift) | (value << (32 - shift)); + int shift = (oldAddress & 3) << 3; + value = (value >> shift) | (value << (32 - shift)); #else #ifdef __GNUC__ - asm("and $3, %%ecx;" - "shl $3 ,%%ecx;" - "ror %%cl, %0" - : "=r"(value) - : "r"(value), "c"(oldAddress)); + asm("and $3, %%ecx;" + "shl $3 ,%%ecx;" + "ror %%cl, %0" + : "=r"(value) + : "r"(value), "c"(oldAddress)); #else - __asm { + __asm { mov ecx, oldAddress; and ecx, 3; shl ecx, 3; ror [dword ptr value], cl; - } -#endif -#endif } +#endif +#endif + } #ifdef GBA_LOGGING - if (oldAddress & 3) { - if (systemVerbose & VERBOSE_UNALIGNED_MEMORY) { - log("Unaligned word read from: %08x at %08x (%08x)\n", - oldAddress, - armMode ? armNextPC - 4 : armNextPC - 2, - value); - } + if (oldAddress & 3) { + if (systemVerbose & VERBOSE_UNALIGNED_MEMORY) { + log("Unaligned word read from: %08x at %08x (%08x)\n", + oldAddress, + armMode ? armNextPC - 4 : armNextPC - 2, + value); } + } #endif - return value; + return value; } static inline u32 CPUReadHalfWord(u32 address) { #ifdef BKPT_SUPPORT - memoryMap *m = &map[address >> 24]; - if (m->breakPoints && BreakReadCheck(m->breakPoints, address & m->mask)) { - if (debuggerBreakOnRead(address, 1)) { - // CPU_BREAK_LOOP_2; - } + memoryMap* m = &map[address >> 24]; + if (m->breakPoints && BreakReadCheck(m->breakPoints, address & m->mask)) { + if (debuggerBreakOnRead(address, 1)) { + // CPU_BREAK_LOOP_2; } + } #endif - u32 value; - u32 oldAddress = address; + u32 value; + u32 oldAddress = address; - if (address & 1) { - address &= ~0x01; - } + if (address & 1) { + address &= ~0x01; + } - switch (address >> 24) { - case 0: - if (reg[15].I >> 24) { - if (address < 0x4000) { -#ifdef GBA_LOGGING - if (systemVerbose & VERBOSE_ILLEGAL_READ) { - log("Illegal halfword read from bios: %08x at %08x\n", - oldAddress, - armMode ? armNextPC - 4 : armNextPC - 2); - } -#endif - value = READ16LE(((u16 *)&biosProtected[address & 2])); - } else - goto unreadable; - } else - value = READ16LE(((u16 *)&bios[address & 0x3FFE])); - break; - case 2: - value = READ16LE(((u16 *)&workRAM[address & 0x3FFFE])); - break; - case 3: - value = READ16LE(((u16 *)&internalRAM[address & 0x7ffe])); - break; - case 4: - if ((address < 0x4000400) && ioReadable[address & 0x3fe]) { - value = READ16LE(((u16 *)&ioMem[address & 0x3fe])); - if (((address & 0x3fe) > 0xFF) && ((address & 0x3fe) < 0x10E)) { - if (((address & 0x3fe) == 0x100) && timer0On) - value = 0xFFFF - ((timer0Ticks - cpuTotalTicks) >> - timer0ClockReload); - else if (((address & 0x3fe) == 0x104) && timer1On && !(TM1CNT & 4)) - value = 0xFFFF - ((timer1Ticks - cpuTotalTicks) >> - timer1ClockReload); - else if (((address & 0x3fe) == 0x108) && timer2On && !(TM2CNT & 4)) - value = 0xFFFF - ((timer2Ticks - cpuTotalTicks) >> - timer2ClockReload); - else if (((address & 0x3fe) == 0x10C) && timer3On && !(TM3CNT & 4)) - value = 0xFFFF - ((timer3Ticks - cpuTotalTicks) >> - timer3ClockReload); - } - } else if ((address < 0x4000400) && ioReadable[address & 0x3fc]) { - value = 0; - } else - goto unreadable; - break; - case 5: - value = READ16LE(((u16 *)&paletteRAM[address & 0x3fe])); - break; - case 6: - address = (address & 0x1fffe); - if (((DISPCNT & 7) > 2) && ((address & 0x1C000) == 0x18000)) { - value = 0; - break; - } - if ((address & 0x18000) == 0x18000) - address &= 0x17fff; - value = READ16LE(((u16 *)&vram[address])); - break; - case 7: - value = READ16LE(((u16 *)&oam[address & 0x3fe])); - break; - case 8: - case 9: - case 10: - case 11: - case 12: - if (address == 0x80000c4 || address == 0x80000c6 || address == 0x80000c8) - value = rtcRead(address); - else - value = READ16LE(((u16 *)&rom[address & 0x1FFFFFE])); - break; - case 13: - if (cpuEEPROMEnabled) - // no need to swap this - return eepromRead(address); - goto unreadable; - case 14: - case 15: - if (cpuFlashEnabled | cpuSramEnabled) - // no need to swap this - { -#ifdef __libretro__ - return flashRead(address); -#else - value = flashRead(address) * 0x0101; -#endif - } - // default - default: - unreadable: - if (cpuDmaHack) { - value = cpuDmaLast & 0xFFFF; - } else { - if (armState) { - value = CPUReadHalfWordQuick(reg[15].I + (address & 2)); - } else { - value = CPUReadHalfWordQuick(reg[15].I); - } - } + switch (address >> 24) { + case 0: + if (reg[15].I >> 24) { + if (address < 0x4000) { #ifdef GBA_LOGGING if (systemVerbose & VERBOSE_ILLEGAL_READ) { - log("Illegal halfword read: %08x at %08x (%08x)\n", - oldAddress, - reg[15].I, - value); + log("Illegal halfword read from bios: %08x at %08x\n", + oldAddress, + armMode ? armNextPC - 4 : armNextPC - 2); } #endif - return value; + value = READ16LE(((u16*)&biosProtected[address & 2])); + } else + goto unreadable; + } else + value = READ16LE(((u16*)&bios[address & 0x3FFE])); + break; + case 2: + value = READ16LE(((u16*)&workRAM[address & 0x3FFFE])); + break; + case 3: + value = READ16LE(((u16*)&internalRAM[address & 0x7ffe])); + break; + case 4: + if ((address < 0x4000400) && ioReadable[address & 0x3fe]) { + value = READ16LE(((u16*)&ioMem[address & 0x3fe])); + if (((address & 0x3fe) > 0xFF) && ((address & 0x3fe) < 0x10E)) { + if (((address & 0x3fe) == 0x100) && timer0On) + value = 0xFFFF - ((timer0Ticks - cpuTotalTicks) >> timer0ClockReload); + else if (((address & 0x3fe) == 0x104) && timer1On && !(TM1CNT & 4)) + value = 0xFFFF - ((timer1Ticks - cpuTotalTicks) >> timer1ClockReload); + else if (((address & 0x3fe) == 0x108) && timer2On && !(TM2CNT & 4)) + value = 0xFFFF - ((timer2Ticks - cpuTotalTicks) >> timer2ClockReload); + else if (((address & 0x3fe) == 0x10C) && timer3On && !(TM3CNT & 4)) + value = 0xFFFF - ((timer3Ticks - cpuTotalTicks) >> timer3ClockReload); + } + } else if ((address < 0x4000400) && ioReadable[address & 0x3fc]) { + value = 0; + } else + goto unreadable; + break; + case 5: + value = READ16LE(((u16*)&paletteRAM[address & 0x3fe])); + break; + case 6: + address = (address & 0x1fffe); + if (((DISPCNT & 7) > 2) && ((address & 0x1C000) == 0x18000)) { + value = 0; + break; + } + if ((address & 0x18000) == 0x18000) + address &= 0x17fff; + value = READ16LE(((u16*)&vram[address])); + break; + case 7: + value = READ16LE(((u16*)&oam[address & 0x3fe])); + break; + case 8: + case 9: + case 10: + case 11: + case 12: + if (address == 0x80000c4 || address == 0x80000c6 || address == 0x80000c8) + value = rtcRead(address); + else + value = READ16LE(((u16*)&rom[address & 0x1FFFFFE])); + break; + case 13: + if (cpuEEPROMEnabled) + // no need to swap this + return eepromRead(address); + goto unreadable; + case 14: + case 15: + if (cpuFlashEnabled | cpuSramEnabled) + // no need to swap this + { +#ifdef __libretro__ + return flashRead(address); +#else + value = flashRead(address) * 0x0101; +#endif + } + // default + default: + unreadable: + if (cpuDmaHack) { + value = cpuDmaLast & 0xFFFF; + } else { + if (armState) { + value = CPUReadHalfWordQuick(reg[15].I + (address & 2)); + } else { + value = CPUReadHalfWordQuick(reg[15].I); + } } - - if (oldAddress & 1) { - value = (value >> 8) | (value << 24); #ifdef GBA_LOGGING - if (systemVerbose & VERBOSE_UNALIGNED_MEMORY) { - log("Unaligned halfword read from: %08x at %08x (%08x)\n", - oldAddress, - armMode ? armNextPC - 4 : armNextPC - 2, - value); - } -#endif + if (systemVerbose & VERBOSE_ILLEGAL_READ) { + log("Illegal halfword read: %08x at %08x (%08x)\n", + oldAddress, + reg[15].I, + value); } - +#endif return value; + } + + if (oldAddress & 1) { + value = (value >> 8) | (value << 24); +#ifdef GBA_LOGGING + if (systemVerbose & VERBOSE_UNALIGNED_MEMORY) { + log("Unaligned halfword read from: %08x at %08x (%08x)\n", + oldAddress, + armMode ? armNextPC - 4 : armNextPC - 2, + value); + } +#endif + } + + return value; } static inline s16 CPUReadHalfWordSigned(u32 address) { - s32 value = (s32)CPUReadHalfWord(address); - if ((address & 1)) { + s32 value = (s32)CPUReadHalfWord(address); + if ((address & 1)) { #ifdef GBA_LOGGING - if (systemVerbose & VERBOSE_UNALIGNED_MEMORY) { - log("Unaligned signed halfword read from: %08x at %08x (%08x)\n", - address, - armMode ? armNextPC - 4 : armNextPC - 2, - value); - } -#endif + if (systemVerbose & VERBOSE_UNALIGNED_MEMORY) { + log("Unaligned signed halfword read from: %08x at %08x (%08x)\n", + address, + armMode ? armNextPC - 4 : armNextPC - 2, + value); } - return (s16)value; +#endif + } + return (s16)value; } static inline u8 CPUReadByte(u32 address) { #ifdef BKPT_SUPPORT - memoryMap *m = &map[address >> 24]; - if (m->breakPoints && BreakReadCheck(m->breakPoints, address & m->mask)) { - if (debuggerBreakOnRead(address, 0)) { - // CPU_BREAK_LOOP_2; - } + memoryMap* m = &map[address >> 24]; + if (m->breakPoints && BreakReadCheck(m->breakPoints, address & m->mask)) { + if (debuggerBreakOnRead(address, 0)) { + // CPU_BREAK_LOOP_2; } + } #endif - switch (address >> 24) { - case 0: - if (reg[15].I >> 24) { - if (address < 0x4000) { -#ifdef GBA_LOGGING - if (systemVerbose & VERBOSE_ILLEGAL_READ) { - log("Illegal byte read from bios: %08x at %08x\n", - address, - armMode ? armNextPC - 4 : armNextPC - 2); - } -#endif - return biosProtected[address & 3]; - } else - goto unreadable; - } - return bios[address & 0x3FFF]; - case 2: - return workRAM[address & 0x3FFFF]; - case 3: - return internalRAM[address & 0x7fff]; - case 4: - if ((address < 0x4000400) && ioReadable[address & 0x3ff]) - return ioMem[address & 0x3ff]; - else - goto unreadable; - case 5: - return paletteRAM[address & 0x3ff]; - case 6: - address = (address & 0x1ffff); - if (((DISPCNT & 7) > 2) && ((address & 0x1C000) == 0x18000)) - return 0; - if ((address & 0x18000) == 0x18000) - address &= 0x17fff; - return vram[address]; - case 7: - return oam[address & 0x3ff]; - case 8: - case 9: - case 10: - case 11: - case 12: - return rom[address & 0x1FFFFFF]; - case 13: - if (cpuEEPROMEnabled) - return eepromRead(address); - goto unreadable; - case 14: - case 15: - if (cpuSramEnabled | cpuFlashEnabled) - return flashRead(address); - - switch (address & 0x00008f00) { - case 0x8200: - return systemGetSensorX() & 255; - case 0x8300: - return (systemGetSensorX() >> 8) | 0x80; - case 0x8400: - return systemGetSensorY() & 255; - case 0x8500: - return systemGetSensorY() >> 8; - } - // default - default: - unreadable: + switch (address >> 24) { + case 0: + if (reg[15].I >> 24) { + if (address < 0x4000) { #ifdef GBA_LOGGING if (systemVerbose & VERBOSE_ILLEGAL_READ) { - log("Illegal byte read: %08x at %08x\n", - address, - armMode ? armNextPC - 4 : armNextPC - 2); + log("Illegal byte read from bios: %08x at %08x\n", + address, + armMode ? armNextPC - 4 : armNextPC - 2); } #endif - if (cpuDmaHack) { - return cpuDmaLast & 0xFF; - } else { - if (armState) { - return CPUReadByteQuick(reg[15].I + (address & 3)); - } else { - return CPUReadByteQuick(reg[15].I + (address & 1)); - } - } + return biosProtected[address & 3]; + } else + goto unreadable; } + return bios[address & 0x3FFF]; + case 2: + return workRAM[address & 0x3FFFF]; + case 3: + return internalRAM[address & 0x7fff]; + case 4: + if ((address < 0x4000400) && ioReadable[address & 0x3ff]) + return ioMem[address & 0x3ff]; + else + goto unreadable; + case 5: + return paletteRAM[address & 0x3ff]; + case 6: + address = (address & 0x1ffff); + if (((DISPCNT & 7) > 2) && ((address & 0x1C000) == 0x18000)) + return 0; + if ((address & 0x18000) == 0x18000) + address &= 0x17fff; + return vram[address]; + case 7: + return oam[address & 0x3ff]; + case 8: + case 9: + case 10: + case 11: + case 12: + return rom[address & 0x1FFFFFF]; + case 13: + if (cpuEEPROMEnabled) + return eepromRead(address); + goto unreadable; + case 14: + case 15: + if (cpuSramEnabled | cpuFlashEnabled) + return flashRead(address); + + switch (address & 0x00008f00) { + case 0x8200: + return systemGetSensorX() & 255; + case 0x8300: + return (systemGetSensorX() >> 8) | 0x80; + case 0x8400: + return systemGetSensorY() & 255; + case 0x8500: + return systemGetSensorY() >> 8; + } + // default + default: + unreadable: +#ifdef GBA_LOGGING + if (systemVerbose & VERBOSE_ILLEGAL_READ) { + log("Illegal byte read: %08x at %08x\n", + address, + armMode ? armNextPC - 4 : armNextPC - 2); + } +#endif + if (cpuDmaHack) { + return cpuDmaLast & 0xFF; + } else { + if (armState) { + return CPUReadByteQuick(reg[15].I + (address & 3)); + } else { + return CPUReadByteQuick(reg[15].I + (address & 1)); + } + } + } } static inline void CPUWriteMemory(u32 address, u32 value) { #ifdef GBA_LOGGING - if (address & 3) { - if (systemVerbose & VERBOSE_UNALIGNED_MEMORY) { - log("Unaligned word write: %08x to %08x from %08x\n", - value, - address, - armMode ? armNextPC - 4 : armNextPC - 2); - } + if (address & 3) { + if (systemVerbose & VERBOSE_UNALIGNED_MEMORY) { + log("Unaligned word write: %08x to %08x from %08x\n", + value, + address, + armMode ? armNextPC - 4 : armNextPC - 2); } + } #endif #ifdef BKPT_SUPPORT - memoryMap *m = &map[address >> 24]; - if (m->breakPoints && BreakWriteCheck(m->breakPoints, address & m->mask)) { - if (debuggerBreakOnWrite(address, value, 1)) { - // CPU_BREAK_LOOP_2; - } + memoryMap* m = &map[address >> 24]; + if (m->breakPoints && BreakWriteCheck(m->breakPoints, address & m->mask)) { + if (debuggerBreakOnWrite(address, value, 1)) { + // CPU_BREAK_LOOP_2; } + } #endif - address &= 0xFFFFFFFC; + address &= 0xFFFFFFFC; - switch (address >> 24) { - case 0x02: + switch (address >> 24) { + case 0x02: #ifdef BKPT_SUPPORT - if (*((u32 *)&freezeWorkRAM[address & 0x3FFFC])) - cheatsWriteMemory(address & 0x203FFFC, value); - else + if (*((u32*)&freezeWorkRAM[address & 0x3FFFC])) + cheatsWriteMemory(address & 0x203FFFC, value); + else #endif - WRITE32LE(((u32 *)&workRAM[address & 0x3FFFC]), value); - break; - case 0x03: + WRITE32LE(((u32*)&workRAM[address & 0x3FFFC]), value); + break; + case 0x03: #ifdef BKPT_SUPPORT - if (*((u32 *)&freezeInternalRAM[address & 0x7ffc])) - cheatsWriteMemory(address & 0x3007FFC, value); - else + if (*((u32*)&freezeInternalRAM[address & 0x7ffc])) + cheatsWriteMemory(address & 0x3007FFC, value); + else #endif - WRITE32LE(((u32 *)&internalRAM[address & 0x7ffC]), value); - break; - case 0x04: - if (address < 0x4000400) { - CPUUpdateRegister((address & 0x3FC), value & 0xFFFF); - CPUUpdateRegister((address & 0x3FC) + 2, (value >> 16)); - } else - goto unwritable; - break; - case 0x05: + WRITE32LE(((u32*)&internalRAM[address & 0x7ffC]), value); + break; + case 0x04: + if (address < 0x4000400) { + CPUUpdateRegister((address & 0x3FC), value & 0xFFFF); + CPUUpdateRegister((address & 0x3FC) + 2, (value >> 16)); + } else + goto unwritable; + break; + case 0x05: #ifdef BKPT_SUPPORT - if (*((u32 *)&freezePRAM[address & 0x3fc])) - cheatsWriteMemory(address & 0x70003FC, value); - else + if (*((u32*)&freezePRAM[address & 0x3fc])) + cheatsWriteMemory(address & 0x70003FC, value); + else #endif - WRITE32LE(((u32 *)&paletteRAM[address & 0x3FC]), value); - break; - case 0x06: - address = (address & 0x1fffc); - if (((DISPCNT & 7) > 2) && ((address & 0x1C000) == 0x18000)) - return; - if ((address & 0x18000) == 0x18000) - address &= 0x17fff; + WRITE32LE(((u32*)&paletteRAM[address & 0x3FC]), value); + break; + case 0x06: + address = (address & 0x1fffc); + if (((DISPCNT & 7) > 2) && ((address & 0x1C000) == 0x18000)) + return; + if ((address & 0x18000) == 0x18000) + address &= 0x17fff; #ifdef BKPT_SUPPORT - if (*((u32 *)&freezeVRAM[address])) - cheatsWriteMemory(address + 0x06000000, value); - else + if (*((u32*)&freezeVRAM[address])) + cheatsWriteMemory(address + 0x06000000, value); + else #endif - WRITE32LE(((u32 *)&vram[address]), value); - break; - case 0x07: + WRITE32LE(((u32*)&vram[address]), value); + break; + case 0x07: #ifdef BKPT_SUPPORT - if (*((u32 *)&freezeOAM[address & 0x3fc])) - cheatsWriteMemory(address & 0x70003FC, value); - else + if (*((u32*)&freezeOAM[address & 0x3fc])) + cheatsWriteMemory(address & 0x70003FC, value); + else #endif - WRITE32LE(((u32 *)&oam[address & 0x3fc]), value); - break; - case 0x0D: - if (cpuEEPROMEnabled) { - eepromWrite(address, value); - break; - } - goto unwritable; - case 0x0E: - case 0x0F: - if ((!eepromInUse) | cpuSramEnabled | cpuFlashEnabled) { - (*cpuSaveGameFunc)(address, (u8)value); - break; - } - // default - default: - unwritable: + WRITE32LE(((u32*)&oam[address & 0x3fc]), value); + break; + case 0x0D: + if (cpuEEPROMEnabled) { + eepromWrite(address, value); + break; + } + goto unwritable; + case 0x0E: + case 0x0F: + if ((!eepromInUse) | cpuSramEnabled | cpuFlashEnabled) { + (*cpuSaveGameFunc)(address, (u8)value); + break; + } + // default + default: + unwritable: #ifdef GBA_LOGGING - if (systemVerbose & VERBOSE_ILLEGAL_WRITE) { - log("Illegal word write: %08x to %08x from %08x\n", - value, - address, - armMode ? armNextPC - 4 : armNextPC - 2); - } -#endif - break; + if (systemVerbose & VERBOSE_ILLEGAL_WRITE) { + log("Illegal word write: %08x to %08x from %08x\n", + value, + address, + armMode ? armNextPC - 4 : armNextPC - 2); } +#endif + break; + } } static inline void CPUWriteHalfWord(u32 address, u16 value) { #ifdef GBA_LOGGING - if (address & 1) { - if (systemVerbose & VERBOSE_UNALIGNED_MEMORY) { - log("Unaligned halfword write: %04x to %08x from %08x\n", - value, - address, - armMode ? armNextPC - 4 : armNextPC - 2); - } + if (address & 1) { + if (systemVerbose & VERBOSE_UNALIGNED_MEMORY) { + log("Unaligned halfword write: %04x to %08x from %08x\n", + value, + address, + armMode ? armNextPC - 4 : armNextPC - 2); } + } #endif #ifdef BKPT_SUPPORT - memoryMap *m = &map[address >> 24]; - if (m->breakPoints && BreakWriteCheck(m->breakPoints, address & m->mask)) { - if (debuggerBreakOnWrite(address, value, 1)) { - // CPU_BREAK_LOOP_2; - } + memoryMap* m = &map[address >> 24]; + if (m->breakPoints && BreakWriteCheck(m->breakPoints, address & m->mask)) { + if (debuggerBreakOnWrite(address, value, 1)) { + // CPU_BREAK_LOOP_2; } + } #endif - address &= 0xFFFFFFFE; + address &= 0xFFFFFFFE; - switch (address >> 24) { - case 2: + switch (address >> 24) { + case 2: #ifdef BKPT_SUPPORT - if (*((u16 *)&freezeWorkRAM[address & 0x3FFFE])) - cheatsWriteHalfWord(address & 0x203FFFE, value); - else + if (*((u16*)&freezeWorkRAM[address & 0x3FFFE])) + cheatsWriteHalfWord(address & 0x203FFFE, value); + else #endif - WRITE16LE(((u16 *)&workRAM[address & 0x3FFFE]), value); - break; - case 3: + WRITE16LE(((u16*)&workRAM[address & 0x3FFFE]), value); + break; + case 3: #ifdef BKPT_SUPPORT - if (*((u16 *)&freezeInternalRAM[address & 0x7ffe])) - cheatsWriteHalfWord(address & 0x3007ffe, value); - else + if (*((u16*)&freezeInternalRAM[address & 0x7ffe])) + cheatsWriteHalfWord(address & 0x3007ffe, value); + else #endif - WRITE16LE(((u16 *)&internalRAM[address & 0x7ffe]), value); - break; - case 4: - if (address < 0x4000400) - CPUUpdateRegister(address & 0x3fe, value); - else - goto unwritable; - break; - case 5: + WRITE16LE(((u16*)&internalRAM[address & 0x7ffe]), value); + break; + case 4: + if (address < 0x4000400) + CPUUpdateRegister(address & 0x3fe, value); + else + goto unwritable; + break; + case 5: #ifdef BKPT_SUPPORT - if (*((u16 *)&freezePRAM[address & 0x03fe])) - cheatsWriteHalfWord(address & 0x70003fe, value); - else + if (*((u16*)&freezePRAM[address & 0x03fe])) + cheatsWriteHalfWord(address & 0x70003fe, value); + else #endif - WRITE16LE(((u16 *)&paletteRAM[address & 0x3fe]), value); - break; - case 6: - address = (address & 0x1fffe); - if (((DISPCNT & 7) > 2) && ((address & 0x1C000) == 0x18000)) - return; - if ((address & 0x18000) == 0x18000) - address &= 0x17fff; + WRITE16LE(((u16*)&paletteRAM[address & 0x3fe]), value); + break; + case 6: + address = (address & 0x1fffe); + if (((DISPCNT & 7) > 2) && ((address & 0x1C000) == 0x18000)) + return; + if ((address & 0x18000) == 0x18000) + address &= 0x17fff; #ifdef BKPT_SUPPORT - if (*((u16 *)&freezeVRAM[address])) - cheatsWriteHalfWord(address + 0x06000000, value); - else + if (*((u16*)&freezeVRAM[address])) + cheatsWriteHalfWord(address + 0x06000000, value); + else #endif - WRITE16LE(((u16 *)&vram[address]), value); - break; - case 7: + WRITE16LE(((u16*)&vram[address]), value); + break; + case 7: #ifdef BKPT_SUPPORT - if (*((u16 *)&freezeOAM[address & 0x03fe])) - cheatsWriteHalfWord(address & 0x70003fe, value); - else + if (*((u16*)&freezeOAM[address & 0x03fe])) + cheatsWriteHalfWord(address & 0x70003fe, value); + else #endif - WRITE16LE(((u16 *)&oam[address & 0x3fe]), value); - break; - case 8: - case 9: - if (address == 0x80000c4 || address == 0x80000c6 || address == 0x80000c8) { - if (!rtcWrite(address, value)) - goto unwritable; - } else if (!agbPrintWrite(address, value)) - goto unwritable; - break; - case 13: - if (cpuEEPROMEnabled) { - eepromWrite(address, (u8)value); - break; - } + WRITE16LE(((u16*)&oam[address & 0x3fe]), value); + break; + case 8: + case 9: + if (address == 0x80000c4 || address == 0x80000c6 || address == 0x80000c8) { + if (!rtcWrite(address, value)) goto unwritable; - case 14: - case 15: - if ((!eepromInUse) | cpuSramEnabled | cpuFlashEnabled) { - (*cpuSaveGameFunc)(address, (u8)value); - break; - } - goto unwritable; - default: - unwritable: + } else if (!agbPrintWrite(address, value)) + goto unwritable; + break; + case 13: + if (cpuEEPROMEnabled) { + eepromWrite(address, (u8)value); + break; + } + goto unwritable; + case 14: + case 15: + if ((!eepromInUse) | cpuSramEnabled | cpuFlashEnabled) { + (*cpuSaveGameFunc)(address, (u8)value); + break; + } + goto unwritable; + default: + unwritable: #ifdef GBA_LOGGING - if (systemVerbose & VERBOSE_ILLEGAL_WRITE) { - log("Illegal halfword write: %04x to %08x from %08x\n", - value, - address, - armMode ? armNextPC - 4 : armNextPC - 2); - } -#endif - break; + if (systemVerbose & VERBOSE_ILLEGAL_WRITE) { + log("Illegal halfword write: %04x to %08x from %08x\n", + value, + address, + armMode ? armNextPC - 4 : armNextPC - 2); } +#endif + break; + } } static inline void CPUWriteByte(u32 address, u8 b) { #ifdef BKPT_SUPPORT - memoryMap *m = &map[address >> 24]; - if (m->breakPoints && BreakWriteCheck(m->breakPoints, address & m->mask)) { - if (debuggerBreakOnWrite(address, b, 1)) { - // CPU_BREAK_LOOP_2; - } + memoryMap* m = &map[address >> 24]; + if (m->breakPoints && BreakWriteCheck(m->breakPoints, address & m->mask)) { + if (debuggerBreakOnWrite(address, b, 1)) { + // CPU_BREAK_LOOP_2; } + } #endif - switch (address >> 24) { - case 2: + switch (address >> 24) { + case 2: #ifdef BKPT_SUPPORT - if (freezeWorkRAM[address & 0x3FFFF]) - cheatsWriteByte(address & 0x203FFFF, b); - else + if (freezeWorkRAM[address & 0x3FFFF]) + cheatsWriteByte(address & 0x203FFFF, b); + else #endif - workRAM[address & 0x3FFFF] = b; - break; - case 3: + workRAM[address & 0x3FFFF] = b; + break; + case 3: #ifdef BKPT_SUPPORT - if (freezeInternalRAM[address & 0x7fff]) - cheatsWriteByte(address & 0x3007fff, b); - else + if (freezeInternalRAM[address & 0x7fff]) + cheatsWriteByte(address & 0x3007fff, b); + else #endif - internalRAM[address & 0x7fff] = b; + internalRAM[address & 0x7fff] = b; + break; + case 4: + if (address < 0x4000400) { + switch (address & 0x3FF) { + case 0x60: + case 0x61: + case 0x62: + case 0x63: + case 0x64: + case 0x65: + case 0x68: + case 0x69: + case 0x6c: + case 0x6d: + case 0x70: + case 0x71: + case 0x72: + case 0x73: + case 0x74: + case 0x75: + case 0x78: + case 0x79: + case 0x7c: + case 0x7d: + case 0x80: + case 0x81: + case 0x84: + case 0x85: + case 0x90: + case 0x91: + case 0x92: + case 0x93: + case 0x94: + case 0x95: + case 0x96: + case 0x97: + case 0x98: + case 0x99: + case 0x9a: + case 0x9b: + case 0x9c: + case 0x9d: + case 0x9e: + case 0x9f: + soundEvent(address & 0xFF, b); break; - case 4: - if (address < 0x4000400) { - switch (address & 0x3FF) { - case 0x60: - case 0x61: - case 0x62: - case 0x63: - case 0x64: - case 0x65: - case 0x68: - case 0x69: - case 0x6c: - case 0x6d: - case 0x70: - case 0x71: - case 0x72: - case 0x73: - case 0x74: - case 0x75: - case 0x78: - case 0x79: - case 0x7c: - case 0x7d: - case 0x80: - case 0x81: - case 0x84: - case 0x85: - case 0x90: - case 0x91: - case 0x92: - case 0x93: - case 0x94: - case 0x95: - case 0x96: - case 0x97: - case 0x98: - case 0x99: - case 0x9a: - case 0x9b: - case 0x9c: - case 0x9d: - case 0x9e: - case 0x9f: - soundEvent(address & 0xFF, b); - break; - case 0x301: // HALTCNT, undocumented - if (b == 0x80) - stopState = true; - holdState = 1; - holdType = -1; - cpuNextEvent = cpuTotalTicks; - break; - default: // every other register - u32 lowerBits = address & 0x3fe; - if (address & 1) { - CPUUpdateRegister(lowerBits, - (READ16LE(&ioMem[lowerBits]) & 0x00FF) | - (b << 8)); - } else { - CPUUpdateRegister(lowerBits, - (READ16LE(&ioMem[lowerBits]) & 0xFF00) | - b); - } - } - break; - } else - goto unwritable; + case 0x301: // HALTCNT, undocumented + if (b == 0x80) + stopState = true; + holdState = 1; + holdType = -1; + cpuNextEvent = cpuTotalTicks; break; - case 5: - // no need to switch - *((u16 *)&paletteRAM[address & 0x3FE]) = (b << 8) | b; - break; - case 6: - address = (address & 0x1fffe); - if (((DISPCNT & 7) > 2) && ((address & 0x1C000) == 0x18000)) - return; - if ((address & 0x18000) == 0x18000) - address &= 0x17fff; + default: // every other register + u32 lowerBits = address & 0x3fe; + if (address & 1) { + CPUUpdateRegister(lowerBits, + (READ16LE(&ioMem[lowerBits]) & 0x00FF) | (b << 8)); + } else { + CPUUpdateRegister(lowerBits, + (READ16LE(&ioMem[lowerBits]) & 0xFF00) | b); + } + } + break; + } else + goto unwritable; + break; + case 5: + // no need to switch + *((u16*)&paletteRAM[address & 0x3FE]) = (b << 8) | b; + break; + case 6: + address = (address & 0x1fffe); + if (((DISPCNT & 7) > 2) && ((address & 0x1C000) == 0x18000)) + return; + if ((address & 0x18000) == 0x18000) + address &= 0x17fff; - // no need to switch - // byte writes to OBJ VRAM are ignored - if ((address) < objTilesAddress[((DISPCNT & 7) + 1) >> 2]) { + // no need to switch + // byte writes to OBJ VRAM are ignored + if ((address) < objTilesAddress[((DISPCNT & 7) + 1) >> 2]) { #ifdef BKPT_SUPPORT - if (freezeVRAM[address]) - cheatsWriteByte(address + 0x06000000, b); - else + if (freezeVRAM[address]) + cheatsWriteByte(address + 0x06000000, b); + else #endif - *((u16 *)&vram[address]) = (b << 8) | b; - } - break; - case 7: - // no need to switch - // byte writes to OAM are ignored - // *((u16 *)&oam[address & 0x3FE]) = (b << 8) | b; - break; - case 13: - if (cpuEEPROMEnabled) { - eepromWrite(address, b); - break; - } - goto unwritable; - case 14: - case 15: - if ((saveType != 5) && ((!eepromInUse) | cpuSramEnabled | cpuFlashEnabled)) { - // if(!cpuEEPROMEnabled && (cpuSramEnabled | cpuFlashEnabled)) { + *((u16*)&vram[address]) = (b << 8) | b; + } + break; + case 7: + // no need to switch + // byte writes to OAM are ignored + // *((u16 *)&oam[address & 0x3FE]) = (b << 8) | b; + break; + case 13: + if (cpuEEPROMEnabled) { + eepromWrite(address, b); + break; + } + goto unwritable; + case 14: + case 15: + if ((saveType != 5) && ((!eepromInUse) | cpuSramEnabled | cpuFlashEnabled)) { + // if(!cpuEEPROMEnabled && (cpuSramEnabled | cpuFlashEnabled)) { - (*cpuSaveGameFunc)(address, b); - break; - } - // default - default: - unwritable: + (*cpuSaveGameFunc)(address, b); + break; + } + // default + default: + unwritable: #ifdef GBA_LOGGING - if (systemVerbose & VERBOSE_ILLEGAL_WRITE) { - log("Illegal byte write: %02x to %08x from %08x\n", - b, - address, - armMode ? armNextPC - 4 : armNextPC - 2); - } -#endif - break; + if (systemVerbose & VERBOSE_ILLEGAL_WRITE) { + log("Illegal byte write: %02x to %08x from %08x\n", + b, + address, + armMode ? armNextPC - 4 : armNextPC - 2); } +#endif + break; + } } #endif // GBAINLINE_H diff --git a/src/gba/Globals.cpp b/src/gba/Globals.cpp index a28d0ecc..17897f19 100644 --- a/src/gba/Globals.cpp +++ b/src/gba/Globals.cpp @@ -1,7 +1,7 @@ #include "GBA.h" #ifdef BKPT_SUPPORT -int oldreg[18]; +int oldreg[18]; char oldbuffer[10]; #endif @@ -23,57 +23,57 @@ u32 stop = 0x08000568; // 0x0000 to 0x7FFF: set custom 15 bit color int customBackdropColor = -1; -u8 *bios = 0; -u8 *rom = 0; -u8 *internalRAM = 0; -u8 *workRAM = 0; -u8 *paletteRAM = 0; -u8 *vram = 0; -u8 *pix = 0; -u8 *oam = 0; -u8 *ioMem = 0; +u8* bios = 0; +u8* rom = 0; +u8* internalRAM = 0; +u8* workRAM = 0; +u8* paletteRAM = 0; +u8* vram = 0; +u8* pix = 0; +u8* oam = 0; +u8* ioMem = 0; -u16 DISPCNT = 0x0080; +u16 DISPCNT = 0x0080; u16 DISPSTAT = 0x0000; -u16 VCOUNT = 0x0000; -u16 BG0CNT = 0x0000; -u16 BG1CNT = 0x0000; -u16 BG2CNT = 0x0000; -u16 BG3CNT = 0x0000; -u16 BG0HOFS = 0x0000; -u16 BG0VOFS = 0x0000; -u16 BG1HOFS = 0x0000; -u16 BG1VOFS = 0x0000; -u16 BG2HOFS = 0x0000; -u16 BG2VOFS = 0x0000; -u16 BG3HOFS = 0x0000; -u16 BG3VOFS = 0x0000; -u16 BG2PA = 0x0100; -u16 BG2PB = 0x0000; -u16 BG2PC = 0x0000; -u16 BG2PD = 0x0100; -u16 BG2X_L = 0x0000; -u16 BG2X_H = 0x0000; -u16 BG2Y_L = 0x0000; -u16 BG2Y_H = 0x0000; -u16 BG3PA = 0x0100; -u16 BG3PB = 0x0000; -u16 BG3PC = 0x0000; -u16 BG3PD = 0x0100; -u16 BG3X_L = 0x0000; -u16 BG3X_H = 0x0000; -u16 BG3Y_L = 0x0000; -u16 BG3Y_H = 0x0000; -u16 WIN0H = 0x0000; -u16 WIN1H = 0x0000; -u16 WIN0V = 0x0000; -u16 WIN1V = 0x0000; -u16 WININ = 0x0000; -u16 WINOUT = 0x0000; -u16 MOSAIC = 0x0000; -u16 BLDMOD = 0x0000; -u16 COLEV = 0x0000; -u16 COLY = 0x0000; +u16 VCOUNT = 0x0000; +u16 BG0CNT = 0x0000; +u16 BG1CNT = 0x0000; +u16 BG2CNT = 0x0000; +u16 BG3CNT = 0x0000; +u16 BG0HOFS = 0x0000; +u16 BG0VOFS = 0x0000; +u16 BG1HOFS = 0x0000; +u16 BG1VOFS = 0x0000; +u16 BG2HOFS = 0x0000; +u16 BG2VOFS = 0x0000; +u16 BG3HOFS = 0x0000; +u16 BG3VOFS = 0x0000; +u16 BG2PA = 0x0100; +u16 BG2PB = 0x0000; +u16 BG2PC = 0x0000; +u16 BG2PD = 0x0100; +u16 BG2X_L = 0x0000; +u16 BG2X_H = 0x0000; +u16 BG2Y_L = 0x0000; +u16 BG2Y_H = 0x0000; +u16 BG3PA = 0x0100; +u16 BG3PB = 0x0000; +u16 BG3PC = 0x0000; +u16 BG3PD = 0x0100; +u16 BG3X_L = 0x0000; +u16 BG3X_H = 0x0000; +u16 BG3Y_L = 0x0000; +u16 BG3Y_H = 0x0000; +u16 WIN0H = 0x0000; +u16 WIN1H = 0x0000; +u16 WIN0V = 0x0000; +u16 WIN1V = 0x0000; +u16 WININ = 0x0000; +u16 WINOUT = 0x0000; +u16 MOSAIC = 0x0000; +u16 BLDMOD = 0x0000; +u16 COLEV = 0x0000; +u16 COLY = 0x0000; u16 DM0SAD_L = 0x0000; u16 DM0SAD_H = 0x0000; u16 DM0DAD_L = 0x0000; @@ -98,15 +98,15 @@ u16 DM3DAD_L = 0x0000; u16 DM3DAD_H = 0x0000; u16 DM3CNT_L = 0x0000; u16 DM3CNT_H = 0x0000; -u16 TM0D = 0x0000; -u16 TM0CNT = 0x0000; -u16 TM1D = 0x0000; -u16 TM1CNT = 0x0000; -u16 TM2D = 0x0000; -u16 TM2CNT = 0x0000; -u16 TM3D = 0x0000; -u16 TM3CNT = 0x0000; -u16 P1 = 0xFFFF; -u16 IE = 0x0000; -u16 IF = 0x0000; -u16 IME = 0x0000; +u16 TM0D = 0x0000; +u16 TM0CNT = 0x0000; +u16 TM1D = 0x0000; +u16 TM1CNT = 0x0000; +u16 TM2D = 0x0000; +u16 TM2CNT = 0x0000; +u16 TM3D = 0x0000; +u16 TM3CNT = 0x0000; +u16 P1 = 0xFFFF; +u16 IE = 0x0000; +u16 IF = 0x0000; +u16 IME = 0x0000; diff --git a/src/gba/Globals.h b/src/gba/Globals.h index e460d85d..a8975b27 100644 --- a/src/gba/Globals.h +++ b/src/gba/Globals.h @@ -36,15 +36,15 @@ extern int layerEnable; extern int cpuSaveType; extern int customBackdropColor; -extern u8 *bios; -extern u8 *rom; -extern u8 *internalRAM; -extern u8 *workRAM; -extern u8 *paletteRAM; -extern u8 *vram; -extern u8 *pix; -extern u8 *oam; -extern u8 *ioMem; +extern u8* bios; +extern u8* rom; +extern u8* internalRAM; +extern u8* workRAM; +extern u8* paletteRAM; +extern u8* vram; +extern u8* pix; +extern u8* oam; +extern u8* ioMem; extern u16 DISPCNT; extern u16 DISPSTAT; diff --git a/src/gba/Mode0.cpp b/src/gba/Mode0.cpp index da02f8df..b4afe2b4 100644 --- a/src/gba/Mode0.cpp +++ b/src/gba/Mode0.cpp @@ -1,506 +1,501 @@ #include "GBA.h" -#include "Globals.h" #include "GBAGfx.h" +#include "Globals.h" void mode0RenderLine() { - u16 *palette = (u16 *)paletteRAM; + u16* palette = (u16*)paletteRAM; - if(DISPCNT & 0x80) { - for(int x = 0; x < 240; x++) { - lineMix[x] = 0x7fff; - } - return; - } - - if(layerEnable & 0x0100) { - gfxDrawTextScreen(BG0CNT, BG0HOFS, BG0VOFS, line0); - } - - if(layerEnable & 0x0200) { - gfxDrawTextScreen(BG1CNT, BG1HOFS, BG1VOFS, line1); - } - - if(layerEnable & 0x0400) { - gfxDrawTextScreen(BG2CNT, BG2HOFS, BG2VOFS, line2); - } - - if(layerEnable & 0x0800) { - gfxDrawTextScreen(BG3CNT, BG3HOFS, BG3VOFS, line3); - } - - gfxDrawSprites(lineOBJ); - - u32 backdrop; - if(customBackdropColor == -1) { - backdrop = (READ16LE(&palette[0]) | 0x30000000); - } else { - backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000); - } - - for(int x = 0; x < 240; x++) { - u32 color = backdrop; - u8 top = 0x20; - - if(line0[x] < color) { - color = line0[x]; - top = 0x01; - } - - if((u8)(line1[x]>>24) < (u8)(color >> 24)) { - color = line1[x]; - top = 0x02; - } - - if((u8)(line2[x]>>24) < (u8)(color >> 24)) { - color = line2[x]; - top = 0x04; - } - - if((u8)(line3[x]>>24) < (u8)(color >> 24)) { - color = line3[x]; - top = 0x08; - } - - if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) { - color = lineOBJ[x]; - top = 0x10; - } - - if((top & 0x10) && (color & 0x00010000)) { - // semi-transparent OBJ - u32 back = backdrop; - u8 top2 = 0x20; - - if((u8)(line0[x]>>24) < (u8)(back >> 24)) { - back = line0[x]; - top2 = 0x01; - } - - if((u8)(line1[x]>>24) < (u8)(back >> 24)) { - back = line1[x]; - top2 = 0x02; - } - - if((u8)(line2[x]>>24) < (u8)(back >> 24)) { - back = line2[x]; - top2 = 0x04; - } - - if((u8)(line3[x]>>24) < (u8)(back >> 24)) { - back = line3[x]; - top2 = 0x08; - } - - if(top2 & (BLDMOD>>8)) - color = gfxAlphaBlend(color, back, - coeff[COLEV & 0x1F], - coeff[(COLEV >> 8) & 0x1F]); - else { - switch((BLDMOD >> 6) & 3) { - case 2: - if(BLDMOD & top) - color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); - break; - case 3: - if(BLDMOD & top) - color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); - break; + if (DISPCNT & 0x80) { + for (int x = 0; x < 240; x++) { + lineMix[x] = 0x7fff; } - } + return; } - lineMix[x] = color; - } + if (layerEnable & 0x0100) { + gfxDrawTextScreen(BG0CNT, BG0HOFS, BG0VOFS, line0); + } + + if (layerEnable & 0x0200) { + gfxDrawTextScreen(BG1CNT, BG1HOFS, BG1VOFS, line1); + } + + if (layerEnable & 0x0400) { + gfxDrawTextScreen(BG2CNT, BG2HOFS, BG2VOFS, line2); + } + + if (layerEnable & 0x0800) { + gfxDrawTextScreen(BG3CNT, BG3HOFS, BG3VOFS, line3); + } + + gfxDrawSprites(lineOBJ); + + u32 backdrop; + if (customBackdropColor == -1) { + backdrop = (READ16LE(&palette[0]) | 0x30000000); + } else { + backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000); + } + + for (int x = 0; x < 240; x++) { + u32 color = backdrop; + u8 top = 0x20; + + if (line0[x] < color) { + color = line0[x]; + top = 0x01; + } + + if ((u8)(line1[x] >> 24) < (u8)(color >> 24)) { + color = line1[x]; + top = 0x02; + } + + if ((u8)(line2[x] >> 24) < (u8)(color >> 24)) { + color = line2[x]; + top = 0x04; + } + + if ((u8)(line3[x] >> 24) < (u8)(color >> 24)) { + color = line3[x]; + top = 0x08; + } + + if ((u8)(lineOBJ[x] >> 24) < (u8)(color >> 24)) { + color = lineOBJ[x]; + top = 0x10; + } + + if ((top & 0x10) && (color & 0x00010000)) { + // semi-transparent OBJ + u32 back = backdrop; + u8 top2 = 0x20; + + if ((u8)(line0[x] >> 24) < (u8)(back >> 24)) { + back = line0[x]; + top2 = 0x01; + } + + if ((u8)(line1[x] >> 24) < (u8)(back >> 24)) { + back = line1[x]; + top2 = 0x02; + } + + if ((u8)(line2[x] >> 24) < (u8)(back >> 24)) { + back = line2[x]; + top2 = 0x04; + } + + if ((u8)(line3[x] >> 24) < (u8)(back >> 24)) { + back = line3[x]; + top2 = 0x08; + } + + if (top2 & (BLDMOD >> 8)) + color = gfxAlphaBlend(color, back, + coeff[COLEV & 0x1F], + coeff[(COLEV >> 8) & 0x1F]); + else { + switch ((BLDMOD >> 6) & 3) { + case 2: + if (BLDMOD & top) + color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); + break; + case 3: + if (BLDMOD & top) + color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); + break; + } + } + } + + lineMix[x] = color; + } } void mode0RenderLineNoWindow() { - u16 *palette = (u16 *)paletteRAM; + u16* palette = (u16*)paletteRAM; - if(DISPCNT & 0x80) { - for(int x = 0; x < 240; x++) { - lineMix[x] = 0x7fff; - } - return; - } - - if(layerEnable & 0x0100) { - gfxDrawTextScreen(BG0CNT, BG0HOFS, BG0VOFS, line0); - } - - if(layerEnable & 0x0200) { - gfxDrawTextScreen(BG1CNT, BG1HOFS, BG1VOFS, line1); - } - - if(layerEnable & 0x0400) { - gfxDrawTextScreen(BG2CNT, BG2HOFS, BG2VOFS, line2); - } - - if(layerEnable & 0x0800) { - gfxDrawTextScreen(BG3CNT, BG3HOFS, BG3VOFS, line3); - } - - gfxDrawSprites(lineOBJ); - - u32 backdrop; - if(customBackdropColor == -1) { - backdrop = (READ16LE(&palette[0]) | 0x30000000); - } else { - backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000); - } - - int effect = (BLDMOD >> 6) & 3; - - for(int x = 0; x < 240; x++) { - u32 color = backdrop; - u8 top = 0x20; - - if(line0[x] < color) { - color = line0[x]; - top = 0x01; + if (DISPCNT & 0x80) { + for (int x = 0; x < 240; x++) { + lineMix[x] = 0x7fff; + } + return; } - if(line1[x] < (color & 0xFF000000)) { - color = line1[x]; - top = 0x02; + if (layerEnable & 0x0100) { + gfxDrawTextScreen(BG0CNT, BG0HOFS, BG0VOFS, line0); } - if(line2[x] < (color & 0xFF000000)) { - color = line2[x]; - top = 0x04; + if (layerEnable & 0x0200) { + gfxDrawTextScreen(BG1CNT, BG1HOFS, BG1VOFS, line1); } - if(line3[x] < (color & 0xFF000000)) { - color = line3[x]; - top = 0x08; + if (layerEnable & 0x0400) { + gfxDrawTextScreen(BG2CNT, BG2HOFS, BG2VOFS, line2); } - if(lineOBJ[x] < (color & 0xFF000000)) { - color = lineOBJ[x]; - top = 0x10; + if (layerEnable & 0x0800) { + gfxDrawTextScreen(BG3CNT, BG3HOFS, BG3VOFS, line3); } - if(!(color & 0x00010000)) { - switch(effect) { - case 0: - break; - case 1: - { - if(top & BLDMOD) { + gfxDrawSprites(lineOBJ); + + u32 backdrop; + if (customBackdropColor == -1) { + backdrop = (READ16LE(&palette[0]) | 0x30000000); + } else { + backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000); + } + + int effect = (BLDMOD >> 6) & 3; + + for (int x = 0; x < 240; x++) { + u32 color = backdrop; + u8 top = 0x20; + + if (line0[x] < color) { + color = line0[x]; + top = 0x01; + } + + if (line1[x] < (color & 0xFF000000)) { + color = line1[x]; + top = 0x02; + } + + if (line2[x] < (color & 0xFF000000)) { + color = line2[x]; + top = 0x04; + } + + if (line3[x] < (color & 0xFF000000)) { + color = line3[x]; + top = 0x08; + } + + if (lineOBJ[x] < (color & 0xFF000000)) { + color = lineOBJ[x]; + top = 0x10; + } + + if (!(color & 0x00010000)) { + switch (effect) { + case 0: + break; + case 1: { + if (top & BLDMOD) { + u32 back = backdrop; + u8 top2 = 0x20; + if (line0[x] < back) { + if (top != 0x01) { + back = line0[x]; + top2 = 0x01; + } + } + + if (line1[x] < (back & 0xFF000000)) { + if (top != 0x02) { + back = line1[x]; + top2 = 0x02; + } + } + + if (line2[x] < (back & 0xFF000000)) { + if (top != 0x04) { + back = line2[x]; + top2 = 0x04; + } + } + + if (line3[x] < (back & 0xFF000000)) { + if (top != 0x08) { + back = line3[x]; + top2 = 0x08; + } + } + + if (lineOBJ[x] < (back & 0xFF000000)) { + if (top != 0x10) { + back = lineOBJ[x]; + top2 = 0x10; + } + } + + if (top2 & (BLDMOD >> 8)) + color = gfxAlphaBlend(color, back, + coeff[COLEV & 0x1F], + coeff[(COLEV >> 8) & 0x1F]); + } + } break; + case 2: + if (BLDMOD & top) + color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); + break; + case 3: + if (BLDMOD & top) + color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); + break; + } + } else { + // semi-transparent OBJ u32 back = backdrop; u8 top2 = 0x20; - if(line0[x] < back) { - if(top != 0x01) { + + if (line0[x] < back) { back = line0[x]; top2 = 0x01; - } } - if(line1[x] < (back & 0xFF000000)) { - if(top != 0x02) { + if (line1[x] < (back & 0xFF000000)) { back = line1[x]; top2 = 0x02; - } } - if(line2[x] < (back & 0xFF000000)) { - if(top != 0x04) { + if (line2[x] < (back & 0xFF000000)) { back = line2[x]; top2 = 0x04; - } } - if(line3[x] < (back & 0xFF000000)) { - if(top != 0x08) { + if (line3[x] < (back & 0xFF000000)) { back = line3[x]; top2 = 0x08; - } } - if(lineOBJ[x] < (back & 0xFF000000)) { - if(top != 0x10) { - back = lineOBJ[x]; - top2 = 0x10; - } + if (top2 & (BLDMOD >> 8)) + color = gfxAlphaBlend(color, back, + coeff[COLEV & 0x1F], + coeff[(COLEV >> 8) & 0x1F]); + else { + switch ((BLDMOD >> 6) & 3) { + case 2: + if (BLDMOD & top) + color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); + break; + case 3: + if (BLDMOD & top) + color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); + break; + } } - - if(top2 & (BLDMOD>>8)) - color = gfxAlphaBlend(color, back, - coeff[COLEV & 0x1F], - coeff[(COLEV >> 8) & 0x1F]); - - } } - break; - case 2: - if(BLDMOD & top) - color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); - break; - case 3: - if(BLDMOD & top) - color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); - break; - } - } else { - // semi-transparent OBJ - u32 back = backdrop; - u8 top2 = 0x20; - if(line0[x] < back) { - back = line0[x]; - top2 = 0x01; - } - - if(line1[x] < (back & 0xFF000000)) { - back = line1[x]; - top2 = 0x02; - } - - if(line2[x] < (back & 0xFF000000)) { - back = line2[x]; - top2 = 0x04; - } - - if(line3[x] < (back & 0xFF000000)) { - back = line3[x]; - top2 = 0x08; - } - - if(top2 & (BLDMOD>>8)) - color = gfxAlphaBlend(color, back, - coeff[COLEV & 0x1F], - coeff[(COLEV >> 8) & 0x1F]); - else { - switch((BLDMOD >> 6) & 3) { - case 2: - if(BLDMOD & top) - color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); - break; - case 3: - if(BLDMOD & top) - color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); - break; - } - } + lineMix[x] = color; } - - lineMix[x] = color; - } } void mode0RenderLineAll() { - u16 *palette = (u16 *)paletteRAM; + u16* palette = (u16*)paletteRAM; - if(DISPCNT & 0x80) { - for(int x = 0; x < 240; x++) { - lineMix[x] = 0x7fff; - } - return; - } - - bool inWindow0 = false; - bool inWindow1 = false; - - if(layerEnable & 0x2000) { - u8 v0 = WIN0V >> 8; - u8 v1 = WIN0V & 255; - inWindow0 = ((v0 == v1) && (v0 >= 0xe8)); - if(v1 >= v0) - inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1); - else - inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1); - } - if(layerEnable & 0x4000) { - u8 v0 = WIN1V >> 8; - u8 v1 = WIN1V & 255; - inWindow1 = ((v0 == v1) && (v0 >= 0xe8)); - if(v1 >= v0) - inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1); - else - inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1); - } - - if((layerEnable & 0x0100)) { - gfxDrawTextScreen(BG0CNT, BG0HOFS, BG0VOFS, line0); - } - - if((layerEnable & 0x0200)) { - gfxDrawTextScreen(BG1CNT, BG1HOFS, BG1VOFS, line1); - } - - if((layerEnable & 0x0400)) { - gfxDrawTextScreen(BG2CNT, BG2HOFS, BG2VOFS, line2); - } - - if((layerEnable & 0x0800)) { - gfxDrawTextScreen(BG3CNT, BG3HOFS, BG3VOFS, line3); - } - - gfxDrawSprites(lineOBJ); - gfxDrawOBJWin(lineOBJWin); - - u32 backdrop; - if(customBackdropColor == -1) { - backdrop = (READ16LE(&palette[0]) | 0x30000000); - } else { - backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000); - } - - u8 inWin0Mask = WININ & 0xFF; - u8 inWin1Mask = WININ >> 8; - u8 outMask = WINOUT & 0xFF; - - for(int x = 0; x < 240; x++) { - u32 color = backdrop; - u8 top = 0x20; - u8 mask = outMask; - - if(!(lineOBJWin[x] & 0x80000000)) { - mask = WINOUT >> 8; - } - - if(inWindow1) { - if(gfxInWin1[x]) - mask = inWin1Mask; - } - - if(inWindow0) { - if(gfxInWin0[x]) { - mask = inWin0Mask; - } - } - - if((mask & 1) && (line0[x] < color)) { - color = line0[x]; - top = 0x01; - } - - if((mask & 2) && ((u8)(line1[x]>>24) < (u8)(color >> 24))) { - color = line1[x]; - top = 0x02; - } - - if((mask & 4) && ((u8)(line2[x]>>24) < (u8)(color >> 24))) { - color = line2[x]; - top = 0x04; - } - - if((mask & 8) && ((u8)(line3[x]>>24) < (u8)(color >> 24))) { - color = line3[x]; - top = 0x08; - } - - if((mask & 16) && ((u8)(lineOBJ[x]>>24) < (u8)(color >> 24))) { - color = lineOBJ[x]; - top = 0x10; - } - - if(color & 0x00010000) { - // semi-transparent OBJ - u32 back = backdrop; - u8 top2 = 0x20; - - if((mask & 1) && ((u8)(line0[x]>>24) < (u8)(back >> 24))) { - back = line0[x]; - top2 = 0x01; - } - - if((mask & 2) && ((u8)(line1[x]>>24) < (u8)(back >> 24))) { - back = line1[x]; - top2 = 0x02; - } - - if((mask & 4) && ((u8)(line2[x]>>24) < (u8)(back >> 24))) { - back = line2[x]; - top2 = 0x04; - } - - if((mask & 8) && ((u8)(line3[x]>>24) < (u8)(back >> 24))) { - back = line3[x]; - top2 = 0x08; - } - - if(top2 & (BLDMOD>>8)) - color = gfxAlphaBlend(color, back, - coeff[COLEV & 0x1F], - coeff[(COLEV >> 8) & 0x1F]); - else { - switch((BLDMOD >> 6) & 3) { - case 2: - if(BLDMOD & top) - color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); - break; - case 3: - if(BLDMOD & top) - color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); - break; + if (DISPCNT & 0x80) { + for (int x = 0; x < 240; x++) { + lineMix[x] = 0x7fff; } - } - } else if(mask & 32) { - // special FX on in the window - switch((BLDMOD >> 6) & 3) { - case 0: - break; - case 1: - { - if(top & BLDMOD) { + return; + } + + bool inWindow0 = false; + bool inWindow1 = false; + + if (layerEnable & 0x2000) { + u8 v0 = WIN0V >> 8; + u8 v1 = WIN0V & 255; + inWindow0 = ((v0 == v1) && (v0 >= 0xe8)); + if (v1 >= v0) + inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1); + else + inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1); + } + if (layerEnable & 0x4000) { + u8 v0 = WIN1V >> 8; + u8 v1 = WIN1V & 255; + inWindow1 = ((v0 == v1) && (v0 >= 0xe8)); + if (v1 >= v0) + inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1); + else + inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1); + } + + if ((layerEnable & 0x0100)) { + gfxDrawTextScreen(BG0CNT, BG0HOFS, BG0VOFS, line0); + } + + if ((layerEnable & 0x0200)) { + gfxDrawTextScreen(BG1CNT, BG1HOFS, BG1VOFS, line1); + } + + if ((layerEnable & 0x0400)) { + gfxDrawTextScreen(BG2CNT, BG2HOFS, BG2VOFS, line2); + } + + if ((layerEnable & 0x0800)) { + gfxDrawTextScreen(BG3CNT, BG3HOFS, BG3VOFS, line3); + } + + gfxDrawSprites(lineOBJ); + gfxDrawOBJWin(lineOBJWin); + + u32 backdrop; + if (customBackdropColor == -1) { + backdrop = (READ16LE(&palette[0]) | 0x30000000); + } else { + backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000); + } + + u8 inWin0Mask = WININ & 0xFF; + u8 inWin1Mask = WININ >> 8; + u8 outMask = WINOUT & 0xFF; + + for (int x = 0; x < 240; x++) { + u32 color = backdrop; + u8 top = 0x20; + u8 mask = outMask; + + if (!(lineOBJWin[x] & 0x80000000)) { + mask = WINOUT >> 8; + } + + if (inWindow1) { + if (gfxInWin1[x]) + mask = inWin1Mask; + } + + if (inWindow0) { + if (gfxInWin0[x]) { + mask = inWin0Mask; + } + } + + if ((mask & 1) && (line0[x] < color)) { + color = line0[x]; + top = 0x01; + } + + if ((mask & 2) && ((u8)(line1[x] >> 24) < (u8)(color >> 24))) { + color = line1[x]; + top = 0x02; + } + + if ((mask & 4) && ((u8)(line2[x] >> 24) < (u8)(color >> 24))) { + color = line2[x]; + top = 0x04; + } + + if ((mask & 8) && ((u8)(line3[x] >> 24) < (u8)(color >> 24))) { + color = line3[x]; + top = 0x08; + } + + if ((mask & 16) && ((u8)(lineOBJ[x] >> 24) < (u8)(color >> 24))) { + color = lineOBJ[x]; + top = 0x10; + } + + if (color & 0x00010000) { + // semi-transparent OBJ u32 back = backdrop; u8 top2 = 0x20; - if((mask & 1) && (u8)(line0[x]>>24) < (u8)(back >> 24)) { - if(top != 0x01) { + + if ((mask & 1) && ((u8)(line0[x] >> 24) < (u8)(back >> 24))) { back = line0[x]; top2 = 0x01; - } } - if((mask & 2) && (u8)(line1[x]>>24) < (u8)(back >> 24)) { - if(top != 0x02) { + if ((mask & 2) && ((u8)(line1[x] >> 24) < (u8)(back >> 24))) { back = line1[x]; top2 = 0x02; - } } - if((mask & 4) && (u8)(line2[x]>>24) < (u8)(back >> 24)) { - if(top != 0x04) { + if ((mask & 4) && ((u8)(line2[x] >> 24) < (u8)(back >> 24))) { back = line2[x]; top2 = 0x04; - } } - if((mask & 8) && (u8)(line3[x]>>24) < (u8)(back >> 24)) { - if(top != 0x08) { + if ((mask & 8) && ((u8)(line3[x] >> 24) < (u8)(back >> 24))) { back = line3[x]; top2 = 0x08; - } } - if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { - if(top != 0x10) { - back = lineOBJ[x]; - top2 = 0x10; - } + if (top2 & (BLDMOD >> 8)) + color = gfxAlphaBlend(color, back, + coeff[COLEV & 0x1F], + coeff[(COLEV >> 8) & 0x1F]); + else { + switch ((BLDMOD >> 6) & 3) { + case 2: + if (BLDMOD & top) + color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); + break; + case 3: + if (BLDMOD & top) + color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); + break; + } } + } else if (mask & 32) { + // special FX on in the window + switch ((BLDMOD >> 6) & 3) { + case 0: + break; + case 1: { + if (top & BLDMOD) { + u32 back = backdrop; + u8 top2 = 0x20; + if ((mask & 1) && (u8)(line0[x] >> 24) < (u8)(back >> 24)) { + if (top != 0x01) { + back = line0[x]; + top2 = 0x01; + } + } - if(top2 & (BLDMOD>>8)) - color = gfxAlphaBlend(color, back, - coeff[COLEV & 0x1F], - coeff[(COLEV >> 8) & 0x1F]); - } + if ((mask & 2) && (u8)(line1[x] >> 24) < (u8)(back >> 24)) { + if (top != 0x02) { + back = line1[x]; + top2 = 0x02; + } + } + + if ((mask & 4) && (u8)(line2[x] >> 24) < (u8)(back >> 24)) { + if (top != 0x04) { + back = line2[x]; + top2 = 0x04; + } + } + + if ((mask & 8) && (u8)(line3[x] >> 24) < (u8)(back >> 24)) { + if (top != 0x08) { + back = line3[x]; + top2 = 0x08; + } + } + + if ((mask & 16) && (u8)(lineOBJ[x] >> 24) < (u8)(back >> 24)) { + if (top != 0x10) { + back = lineOBJ[x]; + top2 = 0x10; + } + } + + if (top2 & (BLDMOD >> 8)) + color = gfxAlphaBlend(color, back, + coeff[COLEV & 0x1F], + coeff[(COLEV >> 8) & 0x1F]); + } + } break; + case 2: + if (BLDMOD & top) + color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); + break; + case 3: + if (BLDMOD & top) + color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); + break; + } } - break; - case 2: - if(BLDMOD & top) - color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); - break; - case 3: - if(BLDMOD & top) - color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); - break; - } - } - lineMix[x] = color; - } + lineMix[x] = color; + } } diff --git a/src/gba/Mode1.cpp b/src/gba/Mode1.cpp index 4d49a94f..0867f40a 100644 --- a/src/gba/Mode1.cpp +++ b/src/gba/Mode1.cpp @@ -1,473 +1,468 @@ #include "GBA.h" -#include "Globals.h" #include "GBAGfx.h" +#include "Globals.h" void mode1RenderLine() { - u16 *palette = (u16 *)paletteRAM; + u16* palette = (u16*)paletteRAM; - if(DISPCNT & 0x80) { - for(int x = 0; x < 240; x++) { - lineMix[x] = 0x7fff; - } - gfxLastVCOUNT = VCOUNT; - return; - } - - if(layerEnable & 0x0100) { - gfxDrawTextScreen(BG0CNT, BG0HOFS, BG0VOFS, line0); - } - - if(layerEnable & 0x0200) { - gfxDrawTextScreen(BG1CNT, BG1HOFS, BG1VOFS, line1); - } - - if(layerEnable & 0x0400) { - int changed = gfxBG2Changed; - if(gfxLastVCOUNT > VCOUNT) - changed = 3; - gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H, - BG2PA, BG2PB, BG2PC, BG2PD, - gfxBG2X, gfxBG2Y, changed, line2); - } - - gfxDrawSprites(lineOBJ); - - u32 backdrop; - if(customBackdropColor == -1) { - backdrop = (READ16LE(&palette[0]) | 0x30000000); - } else { - backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000); - } - - for(int x = 0; x < 240; x++) { - u32 color = backdrop; - u8 top = 0x20; - - if(line0[x] < color) { - color = line0[x]; - top = 0x01; - } - - if((u8)(line1[x]>>24) < (u8)(color >> 24)) { - color = line1[x]; - top = 0x02; - } - - if((u8)(line2[x]>>24) < (u8)(color >> 24)) { - color = line2[x]; - top = 0x04; - } - - if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) { - color = lineOBJ[x]; - top = 0x10; - } - - if((top & 0x10) && (color & 0x00010000)) { - // semi-transparent OBJ - u32 back = backdrop; - u8 top2 = 0x20; - - if((u8)(line0[x]>>24) < (u8)(back >> 24)) { - back = line0[x]; - top2 = 0x01; - } - - if((u8)(line1[x]>>24) < (u8)(back >> 24)) { - back = line1[x]; - top2 = 0x02; - } - - if((u8)(line2[x]>>24) < (u8)(back >> 24)) { - back = line2[x]; - top2 = 0x04; - } - - if(top2 & (BLDMOD>>8)) - color = gfxAlphaBlend(color, back, - coeff[COLEV & 0x1F], - coeff[(COLEV >> 8) & 0x1F]); - else { - switch((BLDMOD >> 6) & 3) { - case 2: - if(BLDMOD & top) - color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); - break; - case 3: - if(BLDMOD & top) - color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); - break; + if (DISPCNT & 0x80) { + for (int x = 0; x < 240; x++) { + lineMix[x] = 0x7fff; } - } + gfxLastVCOUNT = VCOUNT; + return; } - lineMix[x] = color; - } - gfxBG2Changed = 0; - gfxLastVCOUNT = VCOUNT; + if (layerEnable & 0x0100) { + gfxDrawTextScreen(BG0CNT, BG0HOFS, BG0VOFS, line0); + } + + if (layerEnable & 0x0200) { + gfxDrawTextScreen(BG1CNT, BG1HOFS, BG1VOFS, line1); + } + + if (layerEnable & 0x0400) { + int changed = gfxBG2Changed; + if (gfxLastVCOUNT > VCOUNT) + changed = 3; + gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H, + BG2PA, BG2PB, BG2PC, BG2PD, + gfxBG2X, gfxBG2Y, changed, line2); + } + + gfxDrawSprites(lineOBJ); + + u32 backdrop; + if (customBackdropColor == -1) { + backdrop = (READ16LE(&palette[0]) | 0x30000000); + } else { + backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000); + } + + for (int x = 0; x < 240; x++) { + u32 color = backdrop; + u8 top = 0x20; + + if (line0[x] < color) { + color = line0[x]; + top = 0x01; + } + + if ((u8)(line1[x] >> 24) < (u8)(color >> 24)) { + color = line1[x]; + top = 0x02; + } + + if ((u8)(line2[x] >> 24) < (u8)(color >> 24)) { + color = line2[x]; + top = 0x04; + } + + if ((u8)(lineOBJ[x] >> 24) < (u8)(color >> 24)) { + color = lineOBJ[x]; + top = 0x10; + } + + if ((top & 0x10) && (color & 0x00010000)) { + // semi-transparent OBJ + u32 back = backdrop; + u8 top2 = 0x20; + + if ((u8)(line0[x] >> 24) < (u8)(back >> 24)) { + back = line0[x]; + top2 = 0x01; + } + + if ((u8)(line1[x] >> 24) < (u8)(back >> 24)) { + back = line1[x]; + top2 = 0x02; + } + + if ((u8)(line2[x] >> 24) < (u8)(back >> 24)) { + back = line2[x]; + top2 = 0x04; + } + + if (top2 & (BLDMOD >> 8)) + color = gfxAlphaBlend(color, back, + coeff[COLEV & 0x1F], + coeff[(COLEV >> 8) & 0x1F]); + else { + switch ((BLDMOD >> 6) & 3) { + case 2: + if (BLDMOD & top) + color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); + break; + case 3: + if (BLDMOD & top) + color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); + break; + } + } + } + + lineMix[x] = color; + } + gfxBG2Changed = 0; + gfxLastVCOUNT = VCOUNT; } void mode1RenderLineNoWindow() { - u16 *palette = (u16 *)paletteRAM; + u16* palette = (u16*)paletteRAM; - if(DISPCNT & 0x80) { - for(int x = 0; x < 240; x++) { - lineMix[x] = 0x7fff; - } - gfxLastVCOUNT = VCOUNT; - return; - } - - if(layerEnable & 0x0100) { - gfxDrawTextScreen(BG0CNT, BG0HOFS, BG0VOFS, line0); - } - - - if(layerEnable & 0x0200) { - gfxDrawTextScreen(BG1CNT, BG1HOFS, BG1VOFS, line1); - } - - if(layerEnable & 0x0400) { - int changed = gfxBG2Changed; - if(gfxLastVCOUNT > VCOUNT) - changed = 3; - gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H, - BG2PA, BG2PB, BG2PC, BG2PD, - gfxBG2X, gfxBG2Y, changed, line2); - } - - gfxDrawSprites(lineOBJ); - - u32 backdrop; - if(customBackdropColor == -1) { - backdrop = (READ16LE(&palette[0]) | 0x30000000); - } else { - backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000); - } - - for(int x = 0; x < 240; x++) { - u32 color = backdrop; - u8 top = 0x20; - - if(line0[x] < color) { - color = line0[x]; - top = 0x01; + if (DISPCNT & 0x80) { + for (int x = 0; x < 240; x++) { + lineMix[x] = 0x7fff; + } + gfxLastVCOUNT = VCOUNT; + return; } - if((u8)(line1[x]>>24) < (u8)(color >> 24)) { - color = line1[x]; - top = 0x02; + if (layerEnable & 0x0100) { + gfxDrawTextScreen(BG0CNT, BG0HOFS, BG0VOFS, line0); } - if((u8)(line2[x]>>24) < (u8)(color >> 24)) { - color = line2[x]; - top = 0x04; + if (layerEnable & 0x0200) { + gfxDrawTextScreen(BG1CNT, BG1HOFS, BG1VOFS, line1); } - if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) { - color = lineOBJ[x]; - top = 0x10; + if (layerEnable & 0x0400) { + int changed = gfxBG2Changed; + if (gfxLastVCOUNT > VCOUNT) + changed = 3; + gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H, + BG2PA, BG2PB, BG2PC, BG2PD, + gfxBG2X, gfxBG2Y, changed, line2); } - if(!(color & 0x00010000)) { - switch((BLDMOD >> 6) & 3) { - case 0: - break; - case 1: - { - if(top & BLDMOD) { + gfxDrawSprites(lineOBJ); + + u32 backdrop; + if (customBackdropColor == -1) { + backdrop = (READ16LE(&palette[0]) | 0x30000000); + } else { + backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000); + } + + for (int x = 0; x < 240; x++) { + u32 color = backdrop; + u8 top = 0x20; + + if (line0[x] < color) { + color = line0[x]; + top = 0x01; + } + + if ((u8)(line1[x] >> 24) < (u8)(color >> 24)) { + color = line1[x]; + top = 0x02; + } + + if ((u8)(line2[x] >> 24) < (u8)(color >> 24)) { + color = line2[x]; + top = 0x04; + } + + if ((u8)(lineOBJ[x] >> 24) < (u8)(color >> 24)) { + color = lineOBJ[x]; + top = 0x10; + } + + if (!(color & 0x00010000)) { + switch ((BLDMOD >> 6) & 3) { + case 0: + break; + case 1: { + if (top & BLDMOD) { + u32 back = backdrop; + u8 top2 = 0x20; + if ((u8)(line0[x] >> 24) < (u8)(back >> 24)) { + if (top != 0x01) { + back = line0[x]; + top2 = 0x01; + } + } + + if ((u8)(line1[x] >> 24) < (u8)(back >> 24)) { + if (top != 0x02) { + back = line1[x]; + top2 = 0x02; + } + } + + if ((u8)(line2[x] >> 24) < (u8)(back >> 24)) { + if (top != 0x04) { + back = line2[x]; + top2 = 0x04; + } + } + + if ((u8)(lineOBJ[x] >> 24) < (u8)(back >> 24)) { + if (top != 0x10) { + back = lineOBJ[x]; + top2 = 0x10; + } + } + + if (top2 & (BLDMOD >> 8)) + color = gfxAlphaBlend(color, back, + coeff[COLEV & 0x1F], + coeff[(COLEV >> 8) & 0x1F]); + } + } break; + case 2: + if (BLDMOD & top) + color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); + break; + case 3: + if (BLDMOD & top) + color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); + break; + } + } else { + // semi-transparent OBJ u32 back = backdrop; u8 top2 = 0x20; - if((u8)(line0[x]>>24) < (u8)(back >> 24)) { - if(top != 0x01) { + + if ((u8)(line0[x] >> 24) < (u8)(back >> 24)) { back = line0[x]; top2 = 0x01; - } } - if((u8)(line1[x]>>24) < (u8)(back >> 24)) { - if(top != 0x02) { + if ((u8)(line1[x] >> 24) < (u8)(back >> 24)) { back = line1[x]; top2 = 0x02; - } } - if((u8)(line2[x]>>24) < (u8)(back >> 24)) { - if(top != 0x04) { + if ((u8)(line2[x] >> 24) < (u8)(back >> 24)) { back = line2[x]; top2 = 0x04; - } } - if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { - if(top != 0x10) { - back = lineOBJ[x]; - top2 = 0x10; - } + if (top2 & (BLDMOD >> 8)) + color = gfxAlphaBlend(color, back, + coeff[COLEV & 0x1F], + coeff[(COLEV >> 8) & 0x1F]); + else { + switch ((BLDMOD >> 6) & 3) { + case 2: + if (BLDMOD & top) + color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); + break; + case 3: + if (BLDMOD & top) + color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); + break; + } } - - if(top2 & (BLDMOD>>8)) - color = gfxAlphaBlend(color, back, - coeff[COLEV & 0x1F], - coeff[(COLEV >> 8) & 0x1F]); - } } - break; - case 2: - if(BLDMOD & top) - color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); - break; - case 3: - if(BLDMOD & top) - color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); - break; - } - } else { - // semi-transparent OBJ - u32 back = backdrop; - u8 top2 = 0x20; - if((u8)(line0[x]>>24) < (u8)(back >> 24)) { - back = line0[x]; - top2 = 0x01; - } - - if((u8)(line1[x]>>24) < (u8)(back >> 24)) { - back = line1[x]; - top2 = 0x02; - } - - if((u8)(line2[x]>>24) < (u8)(back >> 24)) { - back = line2[x]; - top2 = 0x04; - } - - if(top2 & (BLDMOD>>8)) - color = gfxAlphaBlend(color, back, - coeff[COLEV & 0x1F], - coeff[(COLEV >> 8) & 0x1F]); - else { - switch((BLDMOD >> 6) & 3) { - case 2: - if(BLDMOD & top) - color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); - break; - case 3: - if(BLDMOD & top) - color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); - break; - } - } + lineMix[x] = color; } - - lineMix[x] = color; - } - gfxBG2Changed = 0; - gfxLastVCOUNT = VCOUNT; + gfxBG2Changed = 0; + gfxLastVCOUNT = VCOUNT; } void mode1RenderLineAll() { - u16 *palette = (u16 *)paletteRAM; + u16* palette = (u16*)paletteRAM; - if(DISPCNT & 0x80) { - for(int x = 0; x < 240; x++) { - lineMix[x] = 0x7fff; - } - gfxLastVCOUNT = VCOUNT; - return; - } - - bool inWindow0 = false; - bool inWindow1 = false; - - if(layerEnable & 0x2000) { - u8 v0 = WIN0V >> 8; - u8 v1 = WIN0V & 255; - inWindow0 = ((v0 == v1) && (v0 >= 0xe8)); - if(v1 >= v0) - inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1); - else - inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1); - } - if(layerEnable & 0x4000) { - u8 v0 = WIN1V >> 8; - u8 v1 = WIN1V & 255; - inWindow1 = ((v0 == v1) && (v0 >= 0xe8)); - if(v1 >= v0) - inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1); - else - inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1); - } - - if(layerEnable & 0x0100) { - gfxDrawTextScreen(BG0CNT, BG0HOFS, BG0VOFS, line0); - } - - if(layerEnable & 0x0200) { - gfxDrawTextScreen(BG1CNT, BG1HOFS, BG1VOFS, line1); - } - - if(layerEnable & 0x0400) { - int changed = gfxBG2Changed; - if(gfxLastVCOUNT > VCOUNT) - changed = 3; - gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H, - BG2PA, BG2PB, BG2PC, BG2PD, - gfxBG2X, gfxBG2Y, changed, line2); - } - - gfxDrawSprites(lineOBJ); - gfxDrawOBJWin(lineOBJWin); - - u32 backdrop; - if(customBackdropColor == -1) { - backdrop = (READ16LE(&palette[0]) | 0x30000000); - } else { - backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000); - } - - u8 inWin0Mask = WININ & 0xFF; - u8 inWin1Mask = WININ >> 8; - u8 outMask = WINOUT & 0xFF; - - for(int x = 0; x < 240; x++) { - u32 color = backdrop; - u8 top = 0x20; - u8 mask = outMask; - - if(!(lineOBJWin[x] & 0x80000000)) { - mask = WINOUT >> 8; - } - - if(inWindow1) { - if(gfxInWin1[x]) - mask = inWin1Mask; - } - - if(inWindow0) { - if(gfxInWin0[x]) { - mask = inWin0Mask; - } - } - - if(line0[x] < color && (mask & 1)) { - color = line0[x]; - top = 0x01; - } - - if((u8)(line1[x]>>24) < (u8)(color >> 24) && (mask & 2)) { - color = line1[x]; - top = 0x02; - } - - if((u8)(line2[x]>>24) < (u8)(color >> 24) && (mask & 4)) { - color = line2[x]; - top = 0x04; - } - - if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24) && (mask & 16)) { - color = lineOBJ[x]; - top = 0x10; - } - - if(color & 0x00010000) { - // semi-transparent OBJ - u32 back = backdrop; - u8 top2 = 0x20; - - if((mask & 1) && (u8)(line0[x]>>24) < (u8)(back >> 24)) { - back = line0[x]; - top2 = 0x01; - } - - if((mask & 2) && (u8)(line1[x]>>24) < (u8)(back >> 24)) { - back = line1[x]; - top2 = 0x02; - } - - if((mask & 4) && (u8)(line2[x]>>24) < (u8)(back >> 24)) { - back = line2[x]; - top2 = 0x04; - } - - if(top2 & (BLDMOD>>8)) - color = gfxAlphaBlend(color, back, - coeff[COLEV & 0x1F], - coeff[(COLEV >> 8) & 0x1F]); - else { - switch((BLDMOD >> 6) & 3) { - case 2: - if(BLDMOD & top) - color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); - break; - case 3: - if(BLDMOD & top) - color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); - break; + if (DISPCNT & 0x80) { + for (int x = 0; x < 240; x++) { + lineMix[x] = 0x7fff; } - } - } else if(mask & 32) { - // special FX on the window - switch((BLDMOD >> 6) & 3) { - case 0: - break; - case 1: - { - if(top & BLDMOD) { + gfxLastVCOUNT = VCOUNT; + return; + } + + bool inWindow0 = false; + bool inWindow1 = false; + + if (layerEnable & 0x2000) { + u8 v0 = WIN0V >> 8; + u8 v1 = WIN0V & 255; + inWindow0 = ((v0 == v1) && (v0 >= 0xe8)); + if (v1 >= v0) + inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1); + else + inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1); + } + if (layerEnable & 0x4000) { + u8 v0 = WIN1V >> 8; + u8 v1 = WIN1V & 255; + inWindow1 = ((v0 == v1) && (v0 >= 0xe8)); + if (v1 >= v0) + inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1); + else + inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1); + } + + if (layerEnable & 0x0100) { + gfxDrawTextScreen(BG0CNT, BG0HOFS, BG0VOFS, line0); + } + + if (layerEnable & 0x0200) { + gfxDrawTextScreen(BG1CNT, BG1HOFS, BG1VOFS, line1); + } + + if (layerEnable & 0x0400) { + int changed = gfxBG2Changed; + if (gfxLastVCOUNT > VCOUNT) + changed = 3; + gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H, + BG2PA, BG2PB, BG2PC, BG2PD, + gfxBG2X, gfxBG2Y, changed, line2); + } + + gfxDrawSprites(lineOBJ); + gfxDrawOBJWin(lineOBJWin); + + u32 backdrop; + if (customBackdropColor == -1) { + backdrop = (READ16LE(&palette[0]) | 0x30000000); + } else { + backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000); + } + + u8 inWin0Mask = WININ & 0xFF; + u8 inWin1Mask = WININ >> 8; + u8 outMask = WINOUT & 0xFF; + + for (int x = 0; x < 240; x++) { + u32 color = backdrop; + u8 top = 0x20; + u8 mask = outMask; + + if (!(lineOBJWin[x] & 0x80000000)) { + mask = WINOUT >> 8; + } + + if (inWindow1) { + if (gfxInWin1[x]) + mask = inWin1Mask; + } + + if (inWindow0) { + if (gfxInWin0[x]) { + mask = inWin0Mask; + } + } + + if (line0[x] < color && (mask & 1)) { + color = line0[x]; + top = 0x01; + } + + if ((u8)(line1[x] >> 24) < (u8)(color >> 24) && (mask & 2)) { + color = line1[x]; + top = 0x02; + } + + if ((u8)(line2[x] >> 24) < (u8)(color >> 24) && (mask & 4)) { + color = line2[x]; + top = 0x04; + } + + if ((u8)(lineOBJ[x] >> 24) < (u8)(color >> 24) && (mask & 16)) { + color = lineOBJ[x]; + top = 0x10; + } + + if (color & 0x00010000) { + // semi-transparent OBJ u32 back = backdrop; u8 top2 = 0x20; - if((mask & 1) && (u8)(line0[x]>>24) < (u8)(back >> 24)) { - if(top != 0x01) { + if ((mask & 1) && (u8)(line0[x] >> 24) < (u8)(back >> 24)) { back = line0[x]; top2 = 0x01; - } } - if((mask & 2) && (u8)(line1[x]>>24) < (u8)(back >> 24)) { - if(top != 0x02) { + if ((mask & 2) && (u8)(line1[x] >> 24) < (u8)(back >> 24)) { back = line1[x]; top2 = 0x02; - } } - if((mask & 4) && (u8)(line2[x]>>24) < (u8)(back >> 24)) { - if(top != 0x04) { + if ((mask & 4) && (u8)(line2[x] >> 24) < (u8)(back >> 24)) { back = line2[x]; top2 = 0x04; - } } - if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { - if(top != 0x10) { - back = lineOBJ[x]; - top2 = 0x10; - } + if (top2 & (BLDMOD >> 8)) + color = gfxAlphaBlend(color, back, + coeff[COLEV & 0x1F], + coeff[(COLEV >> 8) & 0x1F]); + else { + switch ((BLDMOD >> 6) & 3) { + case 2: + if (BLDMOD & top) + color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); + break; + case 3: + if (BLDMOD & top) + color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); + break; + } } + } else if (mask & 32) { + // special FX on the window + switch ((BLDMOD >> 6) & 3) { + case 0: + break; + case 1: { + if (top & BLDMOD) { + u32 back = backdrop; + u8 top2 = 0x20; - if(top2 & (BLDMOD>>8)) - color = gfxAlphaBlend(color, back, - coeff[COLEV & 0x1F], - coeff[(COLEV >> 8) & 0x1F]); - } + if ((mask & 1) && (u8)(line0[x] >> 24) < (u8)(back >> 24)) { + if (top != 0x01) { + back = line0[x]; + top2 = 0x01; + } + } + + if ((mask & 2) && (u8)(line1[x] >> 24) < (u8)(back >> 24)) { + if (top != 0x02) { + back = line1[x]; + top2 = 0x02; + } + } + + if ((mask & 4) && (u8)(line2[x] >> 24) < (u8)(back >> 24)) { + if (top != 0x04) { + back = line2[x]; + top2 = 0x04; + } + } + + if ((mask & 16) && (u8)(lineOBJ[x] >> 24) < (u8)(back >> 24)) { + if (top != 0x10) { + back = lineOBJ[x]; + top2 = 0x10; + } + } + + if (top2 & (BLDMOD >> 8)) + color = gfxAlphaBlend(color, back, + coeff[COLEV & 0x1F], + coeff[(COLEV >> 8) & 0x1F]); + } + } break; + case 2: + if (BLDMOD & top) + color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); + break; + case 3: + if (BLDMOD & top) + color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); + break; + } } - break; - case 2: - if(BLDMOD & top) - color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); - break; - case 3: - if(BLDMOD & top) - color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); - break; - } - } - lineMix[x] = color; - } - gfxBG2Changed = 0; - gfxLastVCOUNT = VCOUNT; + lineMix[x] = color; + } + gfxBG2Changed = 0; + gfxLastVCOUNT = VCOUNT; } diff --git a/src/gba/Mode2.cpp b/src/gba/Mode2.cpp index c5aafd2e..8bd20a39 100644 --- a/src/gba/Mode2.cpp +++ b/src/gba/Mode2.cpp @@ -1,443 +1,437 @@ #include "GBA.h" -#include "Globals.h" #include "GBAGfx.h" +#include "Globals.h" void mode2RenderLine() { - u16 *palette = (u16 *)paletteRAM; + u16* palette = (u16*)paletteRAM; - if(DISPCNT & 0x80) { - for(int x = 0; x < 240; x++) { - lineMix[x] = 0x7fff; - } - gfxLastVCOUNT = VCOUNT; - return; - } - - if(layerEnable & 0x0400) { - int changed = gfxBG2Changed; - if(gfxLastVCOUNT > VCOUNT) - changed = 3; - - gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H, - BG2PA, BG2PB, BG2PC, BG2PD, gfxBG2X, gfxBG2Y, - changed, line2); - } - - if(layerEnable & 0x0800) { - int changed = gfxBG3Changed; - if(gfxLastVCOUNT > VCOUNT) - changed = 3; - - gfxDrawRotScreen(BG3CNT, BG3X_L, BG3X_H, BG3Y_L, BG3Y_H, - BG3PA, BG3PB, BG3PC, BG3PD, gfxBG3X, gfxBG3Y, - changed, line3); - } - - gfxDrawSprites(lineOBJ); - - u32 backdrop; - if(customBackdropColor == -1) { - backdrop = (READ16LE(&palette[0]) | 0x30000000); - } else { - backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000); - } - - for(int x = 0; x < 240; x++) { - u32 color = backdrop; - u8 top = 0x20; - - - if((u8)(line2[x]>>24) < (u8)(color >> 24)) { - color = line2[x]; - top = 0x04; - } - - if((u8)(line3[x]>>24) < (u8)(color >> 24)) { - color = line3[x]; - top = 0x08; - } - - if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) { - color = lineOBJ[x]; - top = 0x10; - } - - if((top & 0x10) && (color & 0x00010000)) { - // semi-transparent OBJ - u32 back = backdrop; - u8 top2 = 0x20; - - if((u8)(line2[x]>>24) < (u8)(back >> 24)) { - back = line2[x]; - top2 = 0x04; - } - - if((u8)(line3[x]>>24) < (u8)(back >> 24)) { - back = line3[x]; - top2 = 0x08; - } - - if(top2 & (BLDMOD>>8)) - color = gfxAlphaBlend(color, back, - coeff[COLEV & 0x1F], - coeff[(COLEV >> 8) & 0x1F]); - else { - switch((BLDMOD >> 6) & 3) { - case 2: - if(BLDMOD & top) - color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); - break; - case 3: - if(BLDMOD & top) - color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); - break; + if (DISPCNT & 0x80) { + for (int x = 0; x < 240; x++) { + lineMix[x] = 0x7fff; } - } + gfxLastVCOUNT = VCOUNT; + return; } - lineMix[x] = color; - } - gfxBG2Changed = 0; - gfxBG3Changed = 0; - gfxLastVCOUNT = VCOUNT; + if (layerEnable & 0x0400) { + int changed = gfxBG2Changed; + if (gfxLastVCOUNT > VCOUNT) + changed = 3; + + gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H, + BG2PA, BG2PB, BG2PC, BG2PD, gfxBG2X, gfxBG2Y, + changed, line2); + } + + if (layerEnable & 0x0800) { + int changed = gfxBG3Changed; + if (gfxLastVCOUNT > VCOUNT) + changed = 3; + + gfxDrawRotScreen(BG3CNT, BG3X_L, BG3X_H, BG3Y_L, BG3Y_H, + BG3PA, BG3PB, BG3PC, BG3PD, gfxBG3X, gfxBG3Y, + changed, line3); + } + + gfxDrawSprites(lineOBJ); + + u32 backdrop; + if (customBackdropColor == -1) { + backdrop = (READ16LE(&palette[0]) | 0x30000000); + } else { + backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000); + } + + for (int x = 0; x < 240; x++) { + u32 color = backdrop; + u8 top = 0x20; + + if ((u8)(line2[x] >> 24) < (u8)(color >> 24)) { + color = line2[x]; + top = 0x04; + } + + if ((u8)(line3[x] >> 24) < (u8)(color >> 24)) { + color = line3[x]; + top = 0x08; + } + + if ((u8)(lineOBJ[x] >> 24) < (u8)(color >> 24)) { + color = lineOBJ[x]; + top = 0x10; + } + + if ((top & 0x10) && (color & 0x00010000)) { + // semi-transparent OBJ + u32 back = backdrop; + u8 top2 = 0x20; + + if ((u8)(line2[x] >> 24) < (u8)(back >> 24)) { + back = line2[x]; + top2 = 0x04; + } + + if ((u8)(line3[x] >> 24) < (u8)(back >> 24)) { + back = line3[x]; + top2 = 0x08; + } + + if (top2 & (BLDMOD >> 8)) + color = gfxAlphaBlend(color, back, + coeff[COLEV & 0x1F], + coeff[(COLEV >> 8) & 0x1F]); + else { + switch ((BLDMOD >> 6) & 3) { + case 2: + if (BLDMOD & top) + color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); + break; + case 3: + if (BLDMOD & top) + color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); + break; + } + } + } + + lineMix[x] = color; + } + gfxBG2Changed = 0; + gfxBG3Changed = 0; + gfxLastVCOUNT = VCOUNT; } void mode2RenderLineNoWindow() { - u16 *palette = (u16 *)paletteRAM; + u16* palette = (u16*)paletteRAM; - if(DISPCNT & 0x80) { - for(int x = 0; x < 240; x++) { - lineMix[x] = 0x7fff; - } - gfxLastVCOUNT = VCOUNT; - return; - } - - if(layerEnable & 0x0400) { - int changed = gfxBG2Changed; - if(gfxLastVCOUNT > VCOUNT) - changed = 3; - - gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H, - BG2PA, BG2PB, BG2PC, BG2PD, gfxBG2X, gfxBG2Y, - changed, line2); - } - - if(layerEnable & 0x0800) { - int changed = gfxBG3Changed; - if(gfxLastVCOUNT > VCOUNT) - changed = 3; - - gfxDrawRotScreen(BG3CNT, BG3X_L, BG3X_H, BG3Y_L, BG3Y_H, - BG3PA, BG3PB, BG3PC, BG3PD, gfxBG3X, gfxBG3Y, - changed, line3); - } - - gfxDrawSprites(lineOBJ); - - u32 backdrop; - if(customBackdropColor == -1) { - backdrop = (READ16LE(&palette[0]) | 0x30000000); - } else { - backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000); - } - - for(int x = 0; x < 240; x++) { - u32 color = backdrop; - u8 top = 0x20; - - - if((u8)(line2[x]>>24) < (u8)(color >> 24)) { - color = line2[x]; - top = 0x04; + if (DISPCNT & 0x80) { + for (int x = 0; x < 240; x++) { + lineMix[x] = 0x7fff; + } + gfxLastVCOUNT = VCOUNT; + return; } - if((u8)(line3[x]>>24) < (u8)(color >> 24)) { - color = line3[x]; - top = 0x08; + if (layerEnable & 0x0400) { + int changed = gfxBG2Changed; + if (gfxLastVCOUNT > VCOUNT) + changed = 3; + + gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H, + BG2PA, BG2PB, BG2PC, BG2PD, gfxBG2X, gfxBG2Y, + changed, line2); } - if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) { - color = lineOBJ[x]; - top = 0x10; + if (layerEnable & 0x0800) { + int changed = gfxBG3Changed; + if (gfxLastVCOUNT > VCOUNT) + changed = 3; + + gfxDrawRotScreen(BG3CNT, BG3X_L, BG3X_H, BG3Y_L, BG3Y_H, + BG3PA, BG3PB, BG3PC, BG3PD, gfxBG3X, gfxBG3Y, + changed, line3); } - if(!(color & 0x00010000)) { - switch((BLDMOD >> 6) & 3) { - case 0: - break; - case 1: - { - if(top & BLDMOD) { + gfxDrawSprites(lineOBJ); + + u32 backdrop; + if (customBackdropColor == -1) { + backdrop = (READ16LE(&palette[0]) | 0x30000000); + } else { + backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000); + } + + for (int x = 0; x < 240; x++) { + u32 color = backdrop; + u8 top = 0x20; + + if ((u8)(line2[x] >> 24) < (u8)(color >> 24)) { + color = line2[x]; + top = 0x04; + } + + if ((u8)(line3[x] >> 24) < (u8)(color >> 24)) { + color = line3[x]; + top = 0x08; + } + + if ((u8)(lineOBJ[x] >> 24) < (u8)(color >> 24)) { + color = lineOBJ[x]; + top = 0x10; + } + + if (!(color & 0x00010000)) { + switch ((BLDMOD >> 6) & 3) { + case 0: + break; + case 1: { + if (top & BLDMOD) { + u32 back = backdrop; + u8 top2 = 0x20; + + if ((u8)(line2[x] >> 24) < (u8)(back >> 24)) { + if (top != 0x04) { + back = line2[x]; + top2 = 0x04; + } + } + + if ((u8)(line3[x] >> 24) < (u8)(back >> 24)) { + if (top != 0x08) { + back = line3[x]; + top2 = 0x08; + } + } + + if ((u8)(lineOBJ[x] >> 24) < (u8)(back >> 24)) { + if (top != 0x10) { + back = lineOBJ[x]; + top2 = 0x10; + } + } + + if (top2 & (BLDMOD >> 8)) + color = gfxAlphaBlend(color, back, + coeff[COLEV & 0x1F], + coeff[(COLEV >> 8) & 0x1F]); + } + } break; + case 2: + if (BLDMOD & top) + color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); + break; + case 3: + if (BLDMOD & top) + color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); + break; + } + } else { + // semi-transparent OBJ u32 back = backdrop; u8 top2 = 0x20; - if((u8)(line2[x]>>24) < (u8)(back >> 24)) { - if(top != 0x04) { + if ((u8)(line2[x] >> 24) < (u8)(back >> 24)) { back = line2[x]; top2 = 0x04; - } } - if((u8)(line3[x]>>24) < (u8)(back >> 24)) { - if(top != 0x08) { + if ((u8)(line3[x] >> 24) < (u8)(back >> 24)) { back = line3[x]; top2 = 0x08; - } } - if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { - if(top != 0x10) { - back = lineOBJ[x]; - top2 = 0x10; - } + if (top2 & (BLDMOD >> 8)) + color = gfxAlphaBlend(color, back, + coeff[COLEV & 0x1F], + coeff[(COLEV >> 8) & 0x1F]); + else { + switch ((BLDMOD >> 6) & 3) { + case 2: + if (BLDMOD & top) + color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); + break; + case 3: + if (BLDMOD & top) + color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); + break; + } } - - if(top2 & (BLDMOD>>8)) - color = gfxAlphaBlend(color, back, - coeff[COLEV & 0x1F], - coeff[(COLEV >> 8) & 0x1F]); - } } - break; - case 2: - if(BLDMOD & top) - color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); - break; - case 3: - if(BLDMOD & top) - color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); - break; - } - } else { - // semi-transparent OBJ - u32 back = backdrop; - u8 top2 = 0x20; - if((u8)(line2[x]>>24) < (u8)(back >> 24)) { - back = line2[x]; - top2 = 0x04; - } - - if((u8)(line3[x]>>24) < (u8)(back >> 24)) { - back = line3[x]; - top2 = 0x08; - } - - if(top2 & (BLDMOD>>8)) - color = gfxAlphaBlend(color, back, - coeff[COLEV & 0x1F], - coeff[(COLEV >> 8) & 0x1F]); - else { - switch((BLDMOD >> 6) & 3) { - case 2: - if(BLDMOD & top) - color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); - break; - case 3: - if(BLDMOD & top) - color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); - break; - } - } + lineMix[x] = color; } - - lineMix[x] = color; - } - gfxBG2Changed = 0; - gfxBG3Changed = 0; - gfxLastVCOUNT = VCOUNT; + gfxBG2Changed = 0; + gfxBG3Changed = 0; + gfxLastVCOUNT = VCOUNT; } void mode2RenderLineAll() { - u16 *palette = (u16 *)paletteRAM; + u16* palette = (u16*)paletteRAM; - if(DISPCNT & 0x80) { - for(int x = 0; x < 240; x++) { - lineMix[x] = 0x7fff; - } - gfxLastVCOUNT = VCOUNT; - return; - } - - bool inWindow0 = false; - bool inWindow1 = false; - - if(layerEnable & 0x2000) { - u8 v0 = WIN0V >> 8; - u8 v1 = WIN0V & 255; - inWindow0 = ((v0 == v1) && (v0 >= 0xe8)); - if(v1 >= v0) - inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1); - else - inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1); - } - if(layerEnable & 0x4000) { - u8 v0 = WIN1V >> 8; - u8 v1 = WIN1V & 255; - inWindow1 = ((v0 == v1) && (v0 >= 0xe8)); - if(v1 >= v0) - inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1); - else - inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1); - } - - if(layerEnable & 0x0400) { - int changed = gfxBG2Changed; - if(gfxLastVCOUNT > VCOUNT) - changed = 3; - - gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H, - BG2PA, BG2PB, BG2PC, BG2PD, gfxBG2X, gfxBG2Y, - changed, line2); - } - - if(layerEnable & 0x0800) { - int changed = gfxBG3Changed; - if(gfxLastVCOUNT > VCOUNT) - changed = 3; - - gfxDrawRotScreen(BG3CNT, BG3X_L, BG3X_H, BG3Y_L, BG3Y_H, - BG3PA, BG3PB, BG3PC, BG3PD, gfxBG3X, gfxBG3Y, - changed, line3); - } - - gfxDrawSprites(lineOBJ); - gfxDrawOBJWin(lineOBJWin); - - u32 backdrop; - if(customBackdropColor == -1) { - backdrop = (READ16LE(&palette[0]) | 0x30000000); - } else { - backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000); - } - - u8 inWin0Mask = WININ & 0xFF; - u8 inWin1Mask = WININ >> 8; - u8 outMask = WINOUT & 0xFF; - - for(int x = 0; x < 240; x++) { - u32 color = backdrop; - u8 top = 0x20; - u8 mask = outMask; - - if(!(lineOBJWin[x] & 0x80000000)) { - mask = WINOUT >> 8; - } - - if(inWindow1) { - if(gfxInWin1[x]) - mask = inWin1Mask; - } - - if(inWindow0) { - if(gfxInWin0[x]) { - mask = inWin0Mask; - } - } - - if(line2[x] < color && (mask & 4)) { - color = line2[x]; - top = 0x04; - } - - if((u8)(line3[x]>>24) < (u8)(color >> 24) && (mask & 8)) { - color = line3[x]; - top = 0x08; - } - - if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24) && (mask & 16)) { - color = lineOBJ[x]; - top = 0x10; - } - - if(color & 0x00010000) { - // semi-transparent OBJ - u32 back = backdrop; - u8 top2 = 0x20; - - if((mask & 4) && line2[x] < back) { - back = line2[x]; - top2 = 0x04; - } - - if((mask & 8) && (u8)(line3[x]>>24) < (u8)(back >> 24)) { - back = line3[x]; - top2 = 0x08; - } - - if(top2 & (BLDMOD>>8)) - color = gfxAlphaBlend(color, back, - coeff[COLEV & 0x1F], - coeff[(COLEV >> 8) & 0x1F]); - else { - switch((BLDMOD >> 6) & 3) { - case 2: - if(BLDMOD & top) - color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); - break; - case 3: - if(BLDMOD & top) - color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); - break; + if (DISPCNT & 0x80) { + for (int x = 0; x < 240; x++) { + lineMix[x] = 0x7fff; } - } - } else if(mask & 32) { - // special FX on the window - switch((BLDMOD >> 6) & 3) { - case 0: - break; - case 1: - { - if(top & BLDMOD) { + gfxLastVCOUNT = VCOUNT; + return; + } + + bool inWindow0 = false; + bool inWindow1 = false; + + if (layerEnable & 0x2000) { + u8 v0 = WIN0V >> 8; + u8 v1 = WIN0V & 255; + inWindow0 = ((v0 == v1) && (v0 >= 0xe8)); + if (v1 >= v0) + inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1); + else + inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1); + } + if (layerEnable & 0x4000) { + u8 v0 = WIN1V >> 8; + u8 v1 = WIN1V & 255; + inWindow1 = ((v0 == v1) && (v0 >= 0xe8)); + if (v1 >= v0) + inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1); + else + inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1); + } + + if (layerEnable & 0x0400) { + int changed = gfxBG2Changed; + if (gfxLastVCOUNT > VCOUNT) + changed = 3; + + gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H, + BG2PA, BG2PB, BG2PC, BG2PD, gfxBG2X, gfxBG2Y, + changed, line2); + } + + if (layerEnable & 0x0800) { + int changed = gfxBG3Changed; + if (gfxLastVCOUNT > VCOUNT) + changed = 3; + + gfxDrawRotScreen(BG3CNT, BG3X_L, BG3X_H, BG3Y_L, BG3Y_H, + BG3PA, BG3PB, BG3PC, BG3PD, gfxBG3X, gfxBG3Y, + changed, line3); + } + + gfxDrawSprites(lineOBJ); + gfxDrawOBJWin(lineOBJWin); + + u32 backdrop; + if (customBackdropColor == -1) { + backdrop = (READ16LE(&palette[0]) | 0x30000000); + } else { + backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000); + } + + u8 inWin0Mask = WININ & 0xFF; + u8 inWin1Mask = WININ >> 8; + u8 outMask = WINOUT & 0xFF; + + for (int x = 0; x < 240; x++) { + u32 color = backdrop; + u8 top = 0x20; + u8 mask = outMask; + + if (!(lineOBJWin[x] & 0x80000000)) { + mask = WINOUT >> 8; + } + + if (inWindow1) { + if (gfxInWin1[x]) + mask = inWin1Mask; + } + + if (inWindow0) { + if (gfxInWin0[x]) { + mask = inWin0Mask; + } + } + + if (line2[x] < color && (mask & 4)) { + color = line2[x]; + top = 0x04; + } + + if ((u8)(line3[x] >> 24) < (u8)(color >> 24) && (mask & 8)) { + color = line3[x]; + top = 0x08; + } + + if ((u8)(lineOBJ[x] >> 24) < (u8)(color >> 24) && (mask & 16)) { + color = lineOBJ[x]; + top = 0x10; + } + + if (color & 0x00010000) { + // semi-transparent OBJ u32 back = backdrop; u8 top2 = 0x20; - if((mask & 4) && line2[x] < back) { - if(top != 0x04) { + if ((mask & 4) && line2[x] < back) { back = line2[x]; top2 = 0x04; - } } - if((mask & 8) && (u8)(line3[x]>>24) < (u8)(back >> 24)) { - if(top != 0x08) { + if ((mask & 8) && (u8)(line3[x] >> 24) < (u8)(back >> 24)) { back = line3[x]; top2 = 0x08; - } } - if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { - if(top != 0x10) { - back = lineOBJ[x]; - top2 = 0x10; - } + if (top2 & (BLDMOD >> 8)) + color = gfxAlphaBlend(color, back, + coeff[COLEV & 0x1F], + coeff[(COLEV >> 8) & 0x1F]); + else { + switch ((BLDMOD >> 6) & 3) { + case 2: + if (BLDMOD & top) + color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); + break; + case 3: + if (BLDMOD & top) + color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); + break; + } } + } else if (mask & 32) { + // special FX on the window + switch ((BLDMOD >> 6) & 3) { + case 0: + break; + case 1: { + if (top & BLDMOD) { + u32 back = backdrop; + u8 top2 = 0x20; - if(top2 & (BLDMOD>>8)) - color = gfxAlphaBlend(color, back, - coeff[COLEV & 0x1F], - coeff[(COLEV >> 8) & 0x1F]); - } + if ((mask & 4) && line2[x] < back) { + if (top != 0x04) { + back = line2[x]; + top2 = 0x04; + } + } + + if ((mask & 8) && (u8)(line3[x] >> 24) < (u8)(back >> 24)) { + if (top != 0x08) { + back = line3[x]; + top2 = 0x08; + } + } + + if ((mask & 16) && (u8)(lineOBJ[x] >> 24) < (u8)(back >> 24)) { + if (top != 0x10) { + back = lineOBJ[x]; + top2 = 0x10; + } + } + + if (top2 & (BLDMOD >> 8)) + color = gfxAlphaBlend(color, back, + coeff[COLEV & 0x1F], + coeff[(COLEV >> 8) & 0x1F]); + } + } break; + case 2: + if (BLDMOD & top) + color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); + break; + case 3: + if (BLDMOD & top) + color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); + break; + } } - break; - case 2: - if(BLDMOD & top) - color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); - break; - case 3: - if(BLDMOD & top) - color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); - break; - } - } - lineMix[x] = color; - } - gfxBG2Changed = 0; - gfxBG3Changed = 0; - gfxLastVCOUNT = VCOUNT; + lineMix[x] = color; + } + gfxBG2Changed = 0; + gfxBG3Changed = 0; + gfxLastVCOUNT = VCOUNT; } diff --git a/src/gba/Mode3.cpp b/src/gba/Mode3.cpp index c7445243..9814ab21 100644 --- a/src/gba/Mode3.cpp +++ b/src/gba/Mode3.cpp @@ -1,374 +1,368 @@ #include "GBA.h" -#include "Globals.h" #include "GBAGfx.h" +#include "Globals.h" void mode3RenderLine() { - u16 *palette = (u16 *)paletteRAM; + u16* palette = (u16*)paletteRAM; - if(DISPCNT & 0x80) { - for(int x = 0; x < 240; x++) { - lineMix[x] = 0x7fff; - } - gfxLastVCOUNT = VCOUNT; - return; - } - - if(layerEnable & 0x0400) { - int changed = gfxBG2Changed; - - if(gfxLastVCOUNT > VCOUNT) - changed = 3; - - gfxDrawRotScreen16Bit(BG2CNT, BG2X_L, BG2X_H, - BG2Y_L, BG2Y_H, BG2PA, BG2PB, - BG2PC, BG2PD, - gfxBG2X, gfxBG2Y, changed, - line2); - } - - gfxDrawSprites(lineOBJ); - - u32 background; - if(customBackdropColor == -1) { - background = (READ16LE(&palette[0]) | 0x30000000); - } else { - background = ((customBackdropColor & 0x7FFF) | 0x30000000); - } - - for(int x = 0; x < 240; x++) { - u32 color = background; - u8 top = 0x20; - - if(line2[x] < color) { - color = line2[x]; - top = 0x04; - } - - if((u8)(lineOBJ[x]>>24) < (u8)(color >>24)) { - color = lineOBJ[x]; - top = 0x10; - } - - if((top & 0x10) && (color & 0x00010000)) { - // semi-transparent OBJ - u32 back = background; - u8 top2 = 0x20; - - if(line2[x] < back) { - back = line2[x]; - top2 = 0x04; - } - - if(top2 & (BLDMOD>>8)) - color = gfxAlphaBlend(color, back, - coeff[COLEV & 0x1F], - coeff[(COLEV >> 8) & 0x1F]); - else { - switch((BLDMOD >> 6) & 3) { - case 2: - if(BLDMOD & top) - color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); - break; - case 3: - if(BLDMOD & top) - color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); - break; + if (DISPCNT & 0x80) { + for (int x = 0; x < 240; x++) { + lineMix[x] = 0x7fff; } - } + gfxLastVCOUNT = VCOUNT; + return; } - lineMix[x] = color; - } - gfxBG2Changed = 0; - gfxLastVCOUNT = VCOUNT; + if (layerEnable & 0x0400) { + int changed = gfxBG2Changed; + + if (gfxLastVCOUNT > VCOUNT) + changed = 3; + + gfxDrawRotScreen16Bit(BG2CNT, BG2X_L, BG2X_H, + BG2Y_L, BG2Y_H, BG2PA, BG2PB, + BG2PC, BG2PD, + gfxBG2X, gfxBG2Y, changed, + line2); + } + + gfxDrawSprites(lineOBJ); + + u32 background; + if (customBackdropColor == -1) { + background = (READ16LE(&palette[0]) | 0x30000000); + } else { + background = ((customBackdropColor & 0x7FFF) | 0x30000000); + } + + for (int x = 0; x < 240; x++) { + u32 color = background; + u8 top = 0x20; + + if (line2[x] < color) { + color = line2[x]; + top = 0x04; + } + + if ((u8)(lineOBJ[x] >> 24) < (u8)(color >> 24)) { + color = lineOBJ[x]; + top = 0x10; + } + + if ((top & 0x10) && (color & 0x00010000)) { + // semi-transparent OBJ + u32 back = background; + u8 top2 = 0x20; + + if (line2[x] < back) { + back = line2[x]; + top2 = 0x04; + } + + if (top2 & (BLDMOD >> 8)) + color = gfxAlphaBlend(color, back, + coeff[COLEV & 0x1F], + coeff[(COLEV >> 8) & 0x1F]); + else { + switch ((BLDMOD >> 6) & 3) { + case 2: + if (BLDMOD & top) + color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); + break; + case 3: + if (BLDMOD & top) + color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); + break; + } + } + } + + lineMix[x] = color; + } + gfxBG2Changed = 0; + gfxLastVCOUNT = VCOUNT; } void mode3RenderLineNoWindow() { - u16 *palette = (u16 *)paletteRAM; + u16* palette = (u16*)paletteRAM; - if(DISPCNT & 0x80) { - for(int x = 0; x < 240; x++) { - lineMix[x] = 0x7fff; - } - gfxLastVCOUNT = VCOUNT; - return; - } - - if(layerEnable & 0x0400) { - int changed = gfxBG2Changed; - - if(gfxLastVCOUNT > VCOUNT) - changed = 3; - - gfxDrawRotScreen16Bit(BG2CNT, BG2X_L, BG2X_H, - BG2Y_L, BG2Y_H, BG2PA, BG2PB, - BG2PC, BG2PD, - gfxBG2X, gfxBG2Y, changed, - line2); - } - - gfxDrawSprites(lineOBJ); - - u32 background; - if(customBackdropColor == -1) { - background = (READ16LE(&palette[0]) | 0x30000000); - } else { - background = ((customBackdropColor & 0x7FFF) | 0x30000000); - } - - for(int x = 0; x < 240; x++) { - u32 color = background; - u8 top = 0x20; - - if(line2[x] < color) { - color = line2[x]; - top = 0x04; + if (DISPCNT & 0x80) { + for (int x = 0; x < 240; x++) { + lineMix[x] = 0x7fff; + } + gfxLastVCOUNT = VCOUNT; + return; } - if((u8)(lineOBJ[x]>>24) < (u8)(color >>24)) { - color = lineOBJ[x]; - top = 0x10; + if (layerEnable & 0x0400) { + int changed = gfxBG2Changed; + + if (gfxLastVCOUNT > VCOUNT) + changed = 3; + + gfxDrawRotScreen16Bit(BG2CNT, BG2X_L, BG2X_H, + BG2Y_L, BG2Y_H, BG2PA, BG2PB, + BG2PC, BG2PD, + gfxBG2X, gfxBG2Y, changed, + line2); } - if(!(color & 0x00010000)) { - switch((BLDMOD >> 6) & 3) { - case 0: - break; - case 1: - { - if(top & BLDMOD) { + gfxDrawSprites(lineOBJ); + + u32 background; + if (customBackdropColor == -1) { + background = (READ16LE(&palette[0]) | 0x30000000); + } else { + background = ((customBackdropColor & 0x7FFF) | 0x30000000); + } + + for (int x = 0; x < 240; x++) { + u32 color = background; + u8 top = 0x20; + + if (line2[x] < color) { + color = line2[x]; + top = 0x04; + } + + if ((u8)(lineOBJ[x] >> 24) < (u8)(color >> 24)) { + color = lineOBJ[x]; + top = 0x10; + } + + if (!(color & 0x00010000)) { + switch ((BLDMOD >> 6) & 3) { + case 0: + break; + case 1: { + if (top & BLDMOD) { + u32 back = background; + u8 top2 = 0x20; + + if (line2[x] < back) { + if (top != 0x04) { + back = line2[x]; + top2 = 0x04; + } + } + + if ((u8)(lineOBJ[x] >> 24) < (u8)(back >> 24)) { + if (top != 0x10) { + back = lineOBJ[x]; + top2 = 0x10; + } + } + + if (top2 & (BLDMOD >> 8)) + color = gfxAlphaBlend(color, back, + coeff[COLEV & 0x1F], + coeff[(COLEV >> 8) & 0x1F]); + } + } break; + case 2: + if (BLDMOD & top) + color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); + break; + case 3: + if (BLDMOD & top) + color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); + break; + } + } else { + // semi-transparent OBJ u32 back = background; u8 top2 = 0x20; - if(line2[x] < back) { - if(top != 0x04) { + if (line2[x] < back) { back = line2[x]; top2 = 0x04; - } } - if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { - if(top != 0x10) { - back = lineOBJ[x]; - top2 = 0x10; - } + if (top2 & (BLDMOD >> 8)) + color = gfxAlphaBlend(color, back, + coeff[COLEV & 0x1F], + coeff[(COLEV >> 8) & 0x1F]); + else { + switch ((BLDMOD >> 6) & 3) { + case 2: + if (BLDMOD & top) + color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); + break; + case 3: + if (BLDMOD & top) + color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); + break; + } } - - if(top2 & (BLDMOD>>8)) - color = gfxAlphaBlend(color, back, - coeff[COLEV & 0x1F], - coeff[(COLEV >> 8) & 0x1F]); - - } } - break; - case 2: - if(BLDMOD & top) - color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); - break; - case 3: - if(BLDMOD & top) - color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); - break; - } - } else { - // semi-transparent OBJ - u32 back = background; - u8 top2 = 0x20; - if(line2[x] < back) { - back = line2[x]; - top2 = 0x04; - } - - if(top2 & (BLDMOD>>8)) - color = gfxAlphaBlend(color, back, - coeff[COLEV & 0x1F], - coeff[(COLEV >> 8) & 0x1F]); - else { - switch((BLDMOD >> 6) & 3) { - case 2: - if(BLDMOD & top) - color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); - break; - case 3: - if(BLDMOD & top) - color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); - break; - } - } + lineMix[x] = color; } - - lineMix[x] = color; - } - gfxBG2Changed = 0; - gfxLastVCOUNT = VCOUNT; + gfxBG2Changed = 0; + gfxLastVCOUNT = VCOUNT; } void mode3RenderLineAll() { - u16 *palette = (u16 *)paletteRAM; + u16* palette = (u16*)paletteRAM; - if(DISPCNT & 0x80) { - for(int x = 0; x < 240; x++) { - lineMix[x] = 0x7fff; - } - gfxLastVCOUNT = VCOUNT; - return; - } - - bool inWindow0 = false; - bool inWindow1 = false; - - if(layerEnable & 0x2000) { - u8 v0 = WIN0V >> 8; - u8 v1 = WIN0V & 255; - inWindow0 = ((v0 == v1) && (v0 >= 0xe8)); - if(v1 >= v0) - inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1); - else - inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1); - } - if(layerEnable & 0x4000) { - u8 v0 = WIN1V >> 8; - u8 v1 = WIN1V & 255; - inWindow1 = ((v0 == v1) && (v0 >= 0xe8)); - if(v1 >= v0) - inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1); - else - inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1); - } - - if(layerEnable & 0x0400) { - int changed = gfxBG2Changed; - - if(gfxLastVCOUNT > VCOUNT) - changed = 3; - - gfxDrawRotScreen16Bit(BG2CNT, BG2X_L, BG2X_H, - BG2Y_L, BG2Y_H, BG2PA, BG2PB, - BG2PC, BG2PD, - gfxBG2X, gfxBG2Y, changed, - line2); - } - - gfxDrawSprites(lineOBJ); - gfxDrawOBJWin(lineOBJWin); - - u8 inWin0Mask = WININ & 0xFF; - u8 inWin1Mask = WININ >> 8; - u8 outMask = WINOUT & 0xFF; - - u32 background; - if(customBackdropColor == -1) { - background = (READ16LE(&palette[0]) | 0x30000000); - } else { - background = ((customBackdropColor & 0x7FFF) | 0x30000000); - } - - for(int x = 0; x < 240; x++) { - u32 color = background; - u8 top = 0x20; - u8 mask = outMask; - - if(!(lineOBJWin[x] & 0x80000000)) { - mask = WINOUT >> 8; - } - - if(inWindow1) { - if(gfxInWin1[x]) - mask = inWin1Mask; - } - - if(inWindow0) { - if(gfxInWin0[x]) { - mask = inWin0Mask; - } - } - - if((mask & 4) && (line2[x] < color)) { - color = line2[x]; - top = 0x04; - } - - if((mask & 16) && ((u8)(lineOBJ[x]>>24) < (u8)(color >>24))) { - color = lineOBJ[x]; - top = 0x10; - } - - if(color & 0x00010000) { - // semi-transparent OBJ - u32 back = background; - u8 top2 = 0x20; - - if((mask & 4) && line2[x] < back) { - back = line2[x]; - top2 = 0x04; - } - - if(top2 & (BLDMOD>>8)) - color = gfxAlphaBlend(color, back, - coeff[COLEV & 0x1F], - coeff[(COLEV >> 8) & 0x1F]); - else { - switch((BLDMOD >> 6) & 3) { - case 2: - if(BLDMOD & top) - color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); - break; - case 3: - if(BLDMOD & top) - color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); - break; + if (DISPCNT & 0x80) { + for (int x = 0; x < 240; x++) { + lineMix[x] = 0x7fff; } - } - } else if(mask & 32) { - switch((BLDMOD >> 6) & 3) { - case 0: - break; - case 1: - { - if(top & BLDMOD) { + gfxLastVCOUNT = VCOUNT; + return; + } + + bool inWindow0 = false; + bool inWindow1 = false; + + if (layerEnable & 0x2000) { + u8 v0 = WIN0V >> 8; + u8 v1 = WIN0V & 255; + inWindow0 = ((v0 == v1) && (v0 >= 0xe8)); + if (v1 >= v0) + inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1); + else + inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1); + } + if (layerEnable & 0x4000) { + u8 v0 = WIN1V >> 8; + u8 v1 = WIN1V & 255; + inWindow1 = ((v0 == v1) && (v0 >= 0xe8)); + if (v1 >= v0) + inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1); + else + inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1); + } + + if (layerEnable & 0x0400) { + int changed = gfxBG2Changed; + + if (gfxLastVCOUNT > VCOUNT) + changed = 3; + + gfxDrawRotScreen16Bit(BG2CNT, BG2X_L, BG2X_H, + BG2Y_L, BG2Y_H, BG2PA, BG2PB, + BG2PC, BG2PD, + gfxBG2X, gfxBG2Y, changed, + line2); + } + + gfxDrawSprites(lineOBJ); + gfxDrawOBJWin(lineOBJWin); + + u8 inWin0Mask = WININ & 0xFF; + u8 inWin1Mask = WININ >> 8; + u8 outMask = WINOUT & 0xFF; + + u32 background; + if (customBackdropColor == -1) { + background = (READ16LE(&palette[0]) | 0x30000000); + } else { + background = ((customBackdropColor & 0x7FFF) | 0x30000000); + } + + for (int x = 0; x < 240; x++) { + u32 color = background; + u8 top = 0x20; + u8 mask = outMask; + + if (!(lineOBJWin[x] & 0x80000000)) { + mask = WINOUT >> 8; + } + + if (inWindow1) { + if (gfxInWin1[x]) + mask = inWin1Mask; + } + + if (inWindow0) { + if (gfxInWin0[x]) { + mask = inWin0Mask; + } + } + + if ((mask & 4) && (line2[x] < color)) { + color = line2[x]; + top = 0x04; + } + + if ((mask & 16) && ((u8)(lineOBJ[x] >> 24) < (u8)(color >> 24))) { + color = lineOBJ[x]; + top = 0x10; + } + + if (color & 0x00010000) { + // semi-transparent OBJ u32 back = background; u8 top2 = 0x20; - if((mask & 4) && line2[x] < back) { - if(top != 0x04) { + if ((mask & 4) && line2[x] < back) { back = line2[x]; top2 = 0x04; - } } - if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { - if(top != 0x10) { - back = lineOBJ[x]; - top2 = 0x10; - } + if (top2 & (BLDMOD >> 8)) + color = gfxAlphaBlend(color, back, + coeff[COLEV & 0x1F], + coeff[(COLEV >> 8) & 0x1F]); + else { + switch ((BLDMOD >> 6) & 3) { + case 2: + if (BLDMOD & top) + color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); + break; + case 3: + if (BLDMOD & top) + color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); + break; + } } + } else if (mask & 32) { + switch ((BLDMOD >> 6) & 3) { + case 0: + break; + case 1: { + if (top & BLDMOD) { + u32 back = background; + u8 top2 = 0x20; - if(top2 & (BLDMOD>>8)) - color = gfxAlphaBlend(color, back, - coeff[COLEV & 0x1F], - coeff[(COLEV >> 8) & 0x1F]); + if ((mask & 4) && line2[x] < back) { + if (top != 0x04) { + back = line2[x]; + top2 = 0x04; + } + } - } + if ((mask & 16) && (u8)(lineOBJ[x] >> 24) < (u8)(back >> 24)) { + if (top != 0x10) { + back = lineOBJ[x]; + top2 = 0x10; + } + } + + if (top2 & (BLDMOD >> 8)) + color = gfxAlphaBlend(color, back, + coeff[COLEV & 0x1F], + coeff[(COLEV >> 8) & 0x1F]); + } + } break; + case 2: + if (BLDMOD & top) + color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); + break; + case 3: + if (BLDMOD & top) + color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); + break; + } } - break; - case 2: - if(BLDMOD & top) - color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); - break; - case 3: - if(BLDMOD & top) - color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); - break; - } - } - lineMix[x] = color; - } - gfxBG2Changed = 0; - gfxLastVCOUNT = VCOUNT; + lineMix[x] = color; + } + gfxBG2Changed = 0; + gfxLastVCOUNT = VCOUNT; } diff --git a/src/gba/Mode4.cpp b/src/gba/Mode4.cpp index 01e8b1e5..e47c9cac 100644 --- a/src/gba/Mode4.cpp +++ b/src/gba/Mode4.cpp @@ -4,368 +4,362 @@ void mode4RenderLine() { - u16 *palette = (u16 *)paletteRAM; + u16* palette = (u16*)paletteRAM; - if(DISPCNT & 0x0080) { - for(int x = 0; x < 240; x++) { - lineMix[x] = 0x7fff; - } - gfxLastVCOUNT = VCOUNT; - return; - } - - if(layerEnable & 0x400) { - int changed = gfxBG2Changed; - - if(gfxLastVCOUNT > VCOUNT) - changed = 3; - - gfxDrawRotScreen256(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H, - BG2PA, BG2PB, BG2PC, BG2PD, - gfxBG2X, gfxBG2Y, changed, - line2); - } - - gfxDrawSprites(lineOBJ); - - u32 backdrop; - if(customBackdropColor == -1) { - backdrop = (READ16LE(&palette[0]) | 0x30000000); - } else { - backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000); - } - - for(int x = 0; x < 240; x++) { - u32 color = backdrop; - u8 top = 0x20; - - if(line2[x] < color) { - color = line2[x]; - top = 0x04; - } - - if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) { - color = lineOBJ[x]; - top = 0x10; - } - - if((top & 0x10) && (color & 0x00010000)) { - // semi-transparent OBJ - u32 back = backdrop; - u8 top2 = 0x20; - - if(line2[x] < back) { - back = line2[x]; - top2 = 0x04; - } - - if(top2 & (BLDMOD>>8)) - color = gfxAlphaBlend(color, back, - coeff[COLEV & 0x1F], - coeff[(COLEV >> 8) & 0x1F]); - else { - switch((BLDMOD >> 6) & 3) { - case 2: - if(BLDMOD & top) - color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); - break; - case 3: - if(BLDMOD & top) - color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); - break; + if (DISPCNT & 0x0080) { + for (int x = 0; x < 240; x++) { + lineMix[x] = 0x7fff; } - } + gfxLastVCOUNT = VCOUNT; + return; } - lineMix[x] = color; - } - gfxBG2Changed = 0; - gfxLastVCOUNT = VCOUNT; + if (layerEnable & 0x400) { + int changed = gfxBG2Changed; + + if (gfxLastVCOUNT > VCOUNT) + changed = 3; + + gfxDrawRotScreen256(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H, + BG2PA, BG2PB, BG2PC, BG2PD, + gfxBG2X, gfxBG2Y, changed, + line2); + } + + gfxDrawSprites(lineOBJ); + + u32 backdrop; + if (customBackdropColor == -1) { + backdrop = (READ16LE(&palette[0]) | 0x30000000); + } else { + backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000); + } + + for (int x = 0; x < 240; x++) { + u32 color = backdrop; + u8 top = 0x20; + + if (line2[x] < color) { + color = line2[x]; + top = 0x04; + } + + if ((u8)(lineOBJ[x] >> 24) < (u8)(color >> 24)) { + color = lineOBJ[x]; + top = 0x10; + } + + if ((top & 0x10) && (color & 0x00010000)) { + // semi-transparent OBJ + u32 back = backdrop; + u8 top2 = 0x20; + + if (line2[x] < back) { + back = line2[x]; + top2 = 0x04; + } + + if (top2 & (BLDMOD >> 8)) + color = gfxAlphaBlend(color, back, + coeff[COLEV & 0x1F], + coeff[(COLEV >> 8) & 0x1F]); + else { + switch ((BLDMOD >> 6) & 3) { + case 2: + if (BLDMOD & top) + color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); + break; + case 3: + if (BLDMOD & top) + color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); + break; + } + } + } + + lineMix[x] = color; + } + gfxBG2Changed = 0; + gfxLastVCOUNT = VCOUNT; } void mode4RenderLineNoWindow() { - u16 *palette = (u16 *)paletteRAM; + u16* palette = (u16*)paletteRAM; - if(DISPCNT & 0x0080) { - for(int x = 0; x < 240; x++) { - lineMix[x] = 0x7fff; - } - gfxLastVCOUNT = VCOUNT; - return; - } - - if(layerEnable & 0x400) { - int changed = gfxBG2Changed; - - if(gfxLastVCOUNT > VCOUNT) - changed = 3; - - gfxDrawRotScreen256(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H, - BG2PA, BG2PB, BG2PC, BG2PD, - gfxBG2X, gfxBG2Y, changed, - line2); - } - - gfxDrawSprites(lineOBJ); - - u32 backdrop; - if(customBackdropColor == -1) { - backdrop = (READ16LE(&palette[0]) | 0x30000000); - } else { - backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000); - } - - for(int x = 0; x < 240; x++) { - u32 color = backdrop; - u8 top = 0x20; - - if(line2[x] < color) { - color = line2[x]; - top = 0x04; + if (DISPCNT & 0x0080) { + for (int x = 0; x < 240; x++) { + lineMix[x] = 0x7fff; + } + gfxLastVCOUNT = VCOUNT; + return; } - if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) { - color = lineOBJ[x]; - top = 0x10; + if (layerEnable & 0x400) { + int changed = gfxBG2Changed; + + if (gfxLastVCOUNT > VCOUNT) + changed = 3; + + gfxDrawRotScreen256(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H, + BG2PA, BG2PB, BG2PC, BG2PD, + gfxBG2X, gfxBG2Y, changed, + line2); } - if(!(color & 0x00010000)) { - switch((BLDMOD >> 6) & 3) { - case 0: - break; - case 1: - { - if(top & BLDMOD) { + gfxDrawSprites(lineOBJ); + + u32 backdrop; + if (customBackdropColor == -1) { + backdrop = (READ16LE(&palette[0]) | 0x30000000); + } else { + backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000); + } + + for (int x = 0; x < 240; x++) { + u32 color = backdrop; + u8 top = 0x20; + + if (line2[x] < color) { + color = line2[x]; + top = 0x04; + } + + if ((u8)(lineOBJ[x] >> 24) < (u8)(color >> 24)) { + color = lineOBJ[x]; + top = 0x10; + } + + if (!(color & 0x00010000)) { + switch ((BLDMOD >> 6) & 3) { + case 0: + break; + case 1: { + if (top & BLDMOD) { + u32 back = backdrop; + u8 top2 = 0x20; + + if (line2[x] < back) { + if (top != 0x04) { + back = line2[x]; + top2 = 0x04; + } + } + + if ((u8)(lineOBJ[x] >> 24) < (u8)(back >> 24)) { + if (top != 0x10) { + back = lineOBJ[x]; + top2 = 0x10; + } + } + + if (top2 & (BLDMOD >> 8)) + color = gfxAlphaBlend(color, back, + coeff[COLEV & 0x1F], + coeff[(COLEV >> 8) & 0x1F]); + } + } break; + case 2: + if (BLDMOD & top) + color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); + break; + case 3: + if (BLDMOD & top) + color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); + break; + } + } else { + // semi-transparent OBJ u32 back = backdrop; u8 top2 = 0x20; - if(line2[x] < back) { - if(top != 0x04) { + if (line2[x] < back) { back = line2[x]; top2 = 0x04; - } } - if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { - if(top != 0x10) { - back = lineOBJ[x]; - top2 = 0x10; - } + if (top2 & (BLDMOD >> 8)) + color = gfxAlphaBlend(color, back, + coeff[COLEV & 0x1F], + coeff[(COLEV >> 8) & 0x1F]); + else { + switch ((BLDMOD >> 6) & 3) { + case 2: + if (BLDMOD & top) + color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); + break; + case 3: + if (BLDMOD & top) + color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); + break; + } } - - if(top2 & (BLDMOD>>8)) - color = gfxAlphaBlend(color, back, - coeff[COLEV & 0x1F], - coeff[(COLEV >> 8) & 0x1F]); - - } } - break; - case 2: - if(BLDMOD & top) - color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); - break; - case 3: - if(BLDMOD & top) - color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); - break; - } - } else { - // semi-transparent OBJ - u32 back = backdrop; - u8 top2 = 0x20; - if(line2[x] < back) { - back = line2[x]; - top2 = 0x04; - } - - if(top2 & (BLDMOD>>8)) - color = gfxAlphaBlend(color, back, - coeff[COLEV & 0x1F], - coeff[(COLEV >> 8) & 0x1F]); - else { - switch((BLDMOD >> 6) & 3) { - case 2: - if(BLDMOD & top) - color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); - break; - case 3: - if(BLDMOD & top) - color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); - break; - } - } + lineMix[x] = color; } - - lineMix[x] = color; - } - gfxBG2Changed = 0; - gfxLastVCOUNT = VCOUNT; + gfxBG2Changed = 0; + gfxLastVCOUNT = VCOUNT; } void mode4RenderLineAll() { - u16 *palette = (u16 *)paletteRAM; + u16* palette = (u16*)paletteRAM; - if(DISPCNT & 0x0080) { - for(int x = 0; x < 240; x++) { - lineMix[x] = 0x7fff; - } - gfxLastVCOUNT = VCOUNT; - return; - } - - bool inWindow0 = false; - bool inWindow1 = false; - - if(layerEnable & 0x2000) { - u8 v0 = WIN0V >> 8; - u8 v1 = WIN0V & 255; - inWindow0 = ((v0 == v1) && (v0 >= 0xe8)); - if(v1 >= v0) - inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1); - else - inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1); - } - if(layerEnable & 0x4000) { - u8 v0 = WIN1V >> 8; - u8 v1 = WIN1V & 255; - inWindow1 = ((v0 == v1) && (v0 >= 0xe8)); - if(v1 >= v0) - inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1); - else - inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1); - } - - if(layerEnable & 0x400) { - int changed = gfxBG2Changed; - - if(gfxLastVCOUNT > VCOUNT) - changed = 3; - - gfxDrawRotScreen256(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H, - BG2PA, BG2PB, BG2PC, BG2PD, - gfxBG2X, gfxBG2Y, changed, - line2); - } - - gfxDrawSprites(lineOBJ); - gfxDrawOBJWin(lineOBJWin); - - u32 backdrop; - if(customBackdropColor == -1) { - backdrop = (READ16LE(&palette[0]) | 0x30000000); - } else { - backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000); - } - - u8 inWin0Mask = WININ & 0xFF; - u8 inWin1Mask = WININ >> 8; - u8 outMask = WINOUT & 0xFF; - - for(int x = 0; x < 240; x++) { - u32 color = backdrop; - u8 top = 0x20; - u8 mask = outMask; - - if(!(lineOBJWin[x] & 0x80000000)) { - mask = WINOUT >> 8; - } - - if(inWindow1) { - if(gfxInWin1[x]) - mask = inWin1Mask; - } - - if(inWindow0) { - if(gfxInWin0[x]) { - mask = inWin0Mask; - } - } - - if((mask & 4) && (line2[x] < color)) { - color = line2[x]; - top = 0x04; - } - - if((mask & 16) && ((u8)(lineOBJ[x]>>24) < (u8)(color >>24))) { - color = lineOBJ[x]; - top = 0x10; - } - - if(color & 0x00010000) { - // semi-transparent OBJ - u32 back = backdrop; - u8 top2 = 0x20; - - if((mask & 4) && line2[x] < back) { - back = line2[x]; - top2 = 0x04; - } - - if(top2 & (BLDMOD>>8)) - color = gfxAlphaBlend(color, back, - coeff[COLEV & 0x1F], - coeff[(COLEV >> 8) & 0x1F]); - else { - switch((BLDMOD >> 6) & 3) { - case 2: - if(BLDMOD & top) - color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); - break; - case 3: - if(BLDMOD & top) - color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); - break; + if (DISPCNT & 0x0080) { + for (int x = 0; x < 240; x++) { + lineMix[x] = 0x7fff; } - } - } else if(mask & 32) { - switch((BLDMOD >> 6) & 3) { - case 0: - break; - case 1: - { - if(top & BLDMOD) { + gfxLastVCOUNT = VCOUNT; + return; + } + + bool inWindow0 = false; + bool inWindow1 = false; + + if (layerEnable & 0x2000) { + u8 v0 = WIN0V >> 8; + u8 v1 = WIN0V & 255; + inWindow0 = ((v0 == v1) && (v0 >= 0xe8)); + if (v1 >= v0) + inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1); + else + inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1); + } + if (layerEnable & 0x4000) { + u8 v0 = WIN1V >> 8; + u8 v1 = WIN1V & 255; + inWindow1 = ((v0 == v1) && (v0 >= 0xe8)); + if (v1 >= v0) + inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1); + else + inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1); + } + + if (layerEnable & 0x400) { + int changed = gfxBG2Changed; + + if (gfxLastVCOUNT > VCOUNT) + changed = 3; + + gfxDrawRotScreen256(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H, + BG2PA, BG2PB, BG2PC, BG2PD, + gfxBG2X, gfxBG2Y, changed, + line2); + } + + gfxDrawSprites(lineOBJ); + gfxDrawOBJWin(lineOBJWin); + + u32 backdrop; + if (customBackdropColor == -1) { + backdrop = (READ16LE(&palette[0]) | 0x30000000); + } else { + backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000); + } + + u8 inWin0Mask = WININ & 0xFF; + u8 inWin1Mask = WININ >> 8; + u8 outMask = WINOUT & 0xFF; + + for (int x = 0; x < 240; x++) { + u32 color = backdrop; + u8 top = 0x20; + u8 mask = outMask; + + if (!(lineOBJWin[x] & 0x80000000)) { + mask = WINOUT >> 8; + } + + if (inWindow1) { + if (gfxInWin1[x]) + mask = inWin1Mask; + } + + if (inWindow0) { + if (gfxInWin0[x]) { + mask = inWin0Mask; + } + } + + if ((mask & 4) && (line2[x] < color)) { + color = line2[x]; + top = 0x04; + } + + if ((mask & 16) && ((u8)(lineOBJ[x] >> 24) < (u8)(color >> 24))) { + color = lineOBJ[x]; + top = 0x10; + } + + if (color & 0x00010000) { + // semi-transparent OBJ u32 back = backdrop; u8 top2 = 0x20; - if((mask & 4) && line2[x] < back) { - if(top != 0x04) { + if ((mask & 4) && line2[x] < back) { back = line2[x]; top2 = 0x04; - } } - if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { - if(top != 0x10) { - back = lineOBJ[x]; - top2 = 0x10; - } + if (top2 & (BLDMOD >> 8)) + color = gfxAlphaBlend(color, back, + coeff[COLEV & 0x1F], + coeff[(COLEV >> 8) & 0x1F]); + else { + switch ((BLDMOD >> 6) & 3) { + case 2: + if (BLDMOD & top) + color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); + break; + case 3: + if (BLDMOD & top) + color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); + break; + } } + } else if (mask & 32) { + switch ((BLDMOD >> 6) & 3) { + case 0: + break; + case 1: { + if (top & BLDMOD) { + u32 back = backdrop; + u8 top2 = 0x20; - if(top2 & (BLDMOD>>8)) - color = gfxAlphaBlend(color, back, - coeff[COLEV & 0x1F], - coeff[(COLEV >> 8) & 0x1F]); + if ((mask & 4) && line2[x] < back) { + if (top != 0x04) { + back = line2[x]; + top2 = 0x04; + } + } - } + if ((mask & 16) && (u8)(lineOBJ[x] >> 24) < (u8)(back >> 24)) { + if (top != 0x10) { + back = lineOBJ[x]; + top2 = 0x10; + } + } + + if (top2 & (BLDMOD >> 8)) + color = gfxAlphaBlend(color, back, + coeff[COLEV & 0x1F], + coeff[(COLEV >> 8) & 0x1F]); + } + } break; + case 2: + if (BLDMOD & top) + color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); + break; + case 3: + if (BLDMOD & top) + color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); + break; + } } - break; - case 2: - if(BLDMOD & top) - color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); - break; - case 3: - if(BLDMOD & top) - color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); - break; - } - } - lineMix[x] = color; - } - gfxBG2Changed = 0; - gfxLastVCOUNT = VCOUNT; + lineMix[x] = color; + } + gfxBG2Changed = 0; + gfxLastVCOUNT = VCOUNT; } diff --git a/src/gba/Mode5.cpp b/src/gba/Mode5.cpp index 11f49db8..e491f6fe 100644 --- a/src/gba/Mode5.cpp +++ b/src/gba/Mode5.cpp @@ -1,374 +1,368 @@ #include "GBA.h" -#include "Globals.h" #include "GBAGfx.h" +#include "Globals.h" void mode5RenderLine() { - if(DISPCNT & 0x0080) { - for(int x = 0; x < 240; x++) { - lineMix[x] = 0x7fff; - } - gfxLastVCOUNT = VCOUNT; - return; - } - - u16 *palette = (u16 *)paletteRAM; - - if(layerEnable & 0x0400) { - int changed = gfxBG2Changed; - - if(gfxLastVCOUNT > VCOUNT) - changed = 3; - - gfxDrawRotScreen16Bit160(BG2CNT, BG2X_L, BG2X_H, - BG2Y_L, BG2Y_H, BG2PA, BG2PB, - BG2PC, BG2PD, - gfxBG2X, gfxBG2Y, changed, - line2); - } - - gfxDrawSprites(lineOBJ); - - u32 background; - if(customBackdropColor == -1) { - background = (READ16LE(&palette[0]) | 0x30000000); - } else { - background = ((customBackdropColor & 0x7FFF) | 0x30000000); - } - - for(int x = 0; x < 240; x++) { - u32 color = background; - u8 top = 0x20; - - if(line2[x] < color) { - color = line2[x]; - top = 0x04; - } - - if((u8)(lineOBJ[x]>>24) < (u8)(color >>24)) { - color = lineOBJ[x]; - top = 0x10; - } - - if((top & 0x10) && (color & 0x00010000)) { - // semi-transparent OBJ - u32 back = background; - u8 top2 = 0x20; - - if(line2[x] < back) { - back = line2[x]; - top2 = 0x04; - } - - if(top2 & (BLDMOD>>8)) - color = gfxAlphaBlend(color, back, - coeff[COLEV & 0x1F], - coeff[(COLEV >> 8) & 0x1F]); - else { - switch((BLDMOD >> 6) & 3) { - case 2: - if(BLDMOD & top) - color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); - break; - case 3: - if(BLDMOD & top) - color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); - break; + if (DISPCNT & 0x0080) { + for (int x = 0; x < 240; x++) { + lineMix[x] = 0x7fff; } - } + gfxLastVCOUNT = VCOUNT; + return; } - lineMix[x] = color; - } - gfxBG2Changed = 0; - gfxLastVCOUNT = VCOUNT; + u16* palette = (u16*)paletteRAM; + + if (layerEnable & 0x0400) { + int changed = gfxBG2Changed; + + if (gfxLastVCOUNT > VCOUNT) + changed = 3; + + gfxDrawRotScreen16Bit160(BG2CNT, BG2X_L, BG2X_H, + BG2Y_L, BG2Y_H, BG2PA, BG2PB, + BG2PC, BG2PD, + gfxBG2X, gfxBG2Y, changed, + line2); + } + + gfxDrawSprites(lineOBJ); + + u32 background; + if (customBackdropColor == -1) { + background = (READ16LE(&palette[0]) | 0x30000000); + } else { + background = ((customBackdropColor & 0x7FFF) | 0x30000000); + } + + for (int x = 0; x < 240; x++) { + u32 color = background; + u8 top = 0x20; + + if (line2[x] < color) { + color = line2[x]; + top = 0x04; + } + + if ((u8)(lineOBJ[x] >> 24) < (u8)(color >> 24)) { + color = lineOBJ[x]; + top = 0x10; + } + + if ((top & 0x10) && (color & 0x00010000)) { + // semi-transparent OBJ + u32 back = background; + u8 top2 = 0x20; + + if (line2[x] < back) { + back = line2[x]; + top2 = 0x04; + } + + if (top2 & (BLDMOD >> 8)) + color = gfxAlphaBlend(color, back, + coeff[COLEV & 0x1F], + coeff[(COLEV >> 8) & 0x1F]); + else { + switch ((BLDMOD >> 6) & 3) { + case 2: + if (BLDMOD & top) + color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); + break; + case 3: + if (BLDMOD & top) + color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); + break; + } + } + } + + lineMix[x] = color; + } + gfxBG2Changed = 0; + gfxLastVCOUNT = VCOUNT; } void mode5RenderLineNoWindow() { - if(DISPCNT & 0x0080) { - for(int x = 0; x < 240; x++) { - lineMix[x] = 0x7fff; - } - gfxLastVCOUNT = VCOUNT; - return; - } - - u16 *palette = (u16 *)paletteRAM; - - if(layerEnable & 0x0400) { - int changed = gfxBG2Changed; - - if(gfxLastVCOUNT > VCOUNT) - changed = 3; - - gfxDrawRotScreen16Bit160(BG2CNT, BG2X_L, BG2X_H, - BG2Y_L, BG2Y_H, BG2PA, BG2PB, - BG2PC, BG2PD, - gfxBG2X, gfxBG2Y, changed, - line2); - } - - gfxDrawSprites(lineOBJ); - - u32 background; - if(customBackdropColor == -1) { - background = (READ16LE(&palette[0]) | 0x30000000); - } else { - background = ((customBackdropColor & 0x7FFF) | 0x30000000); - } - - for(int x = 0; x < 240; x++) { - u32 color = background; - u8 top = 0x20; - - if(line2[x] < color) { - color = line2[x]; - top = 0x04; + if (DISPCNT & 0x0080) { + for (int x = 0; x < 240; x++) { + lineMix[x] = 0x7fff; + } + gfxLastVCOUNT = VCOUNT; + return; } - if((u8)(lineOBJ[x]>>24) < (u8)(color >>24)) { - color = lineOBJ[x]; - top = 0x10; + u16* palette = (u16*)paletteRAM; + + if (layerEnable & 0x0400) { + int changed = gfxBG2Changed; + + if (gfxLastVCOUNT > VCOUNT) + changed = 3; + + gfxDrawRotScreen16Bit160(BG2CNT, BG2X_L, BG2X_H, + BG2Y_L, BG2Y_H, BG2PA, BG2PB, + BG2PC, BG2PD, + gfxBG2X, gfxBG2Y, changed, + line2); } - if(!(color & 0x00010000)) { - switch((BLDMOD >> 6) & 3) { - case 0: - break; - case 1: - { - if(top & BLDMOD) { + gfxDrawSprites(lineOBJ); + + u32 background; + if (customBackdropColor == -1) { + background = (READ16LE(&palette[0]) | 0x30000000); + } else { + background = ((customBackdropColor & 0x7FFF) | 0x30000000); + } + + for (int x = 0; x < 240; x++) { + u32 color = background; + u8 top = 0x20; + + if (line2[x] < color) { + color = line2[x]; + top = 0x04; + } + + if ((u8)(lineOBJ[x] >> 24) < (u8)(color >> 24)) { + color = lineOBJ[x]; + top = 0x10; + } + + if (!(color & 0x00010000)) { + switch ((BLDMOD >> 6) & 3) { + case 0: + break; + case 1: { + if (top & BLDMOD) { + u32 back = background; + u8 top2 = 0x20; + + if (line2[x] < back) { + if (top != 0x04) { + back = line2[x]; + top2 = 0x04; + } + } + + if ((u8)(lineOBJ[x] >> 24) < (u8)(back >> 24)) { + if (top != 0x10) { + back = lineOBJ[x]; + top2 = 0x10; + } + } + + if (top2 & (BLDMOD >> 8)) + color = gfxAlphaBlend(color, back, + coeff[COLEV & 0x1F], + coeff[(COLEV >> 8) & 0x1F]); + } + } break; + case 2: + if (BLDMOD & top) + color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); + break; + case 3: + if (BLDMOD & top) + color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); + break; + } + } else { + // semi-transparent OBJ u32 back = background; u8 top2 = 0x20; - if(line2[x] < back) { - if(top != 0x04) { + if (line2[x] < back) { back = line2[x]; top2 = 0x04; - } } - if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { - if(top != 0x10) { - back = lineOBJ[x]; - top2 = 0x10; - } + if (top2 & (BLDMOD >> 8)) + color = gfxAlphaBlend(color, back, + coeff[COLEV & 0x1F], + coeff[(COLEV >> 8) & 0x1F]); + else { + switch ((BLDMOD >> 6) & 3) { + case 2: + if (BLDMOD & top) + color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); + break; + case 3: + if (BLDMOD & top) + color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); + break; + } } - - if(top2 & (BLDMOD>>8)) - color = gfxAlphaBlend(color, back, - coeff[COLEV & 0x1F], - coeff[(COLEV >> 8) & 0x1F]); - - } } - break; - case 2: - if(BLDMOD & top) - color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); - break; - case 3: - if(BLDMOD & top) - color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); - break; - } - } else { - // semi-transparent OBJ - u32 back = background; - u8 top2 = 0x20; - if(line2[x] < back) { - back = line2[x]; - top2 = 0x04; - } - - if(top2 & (BLDMOD>>8)) - color = gfxAlphaBlend(color, back, - coeff[COLEV & 0x1F], - coeff[(COLEV >> 8) & 0x1F]); - else { - switch((BLDMOD >> 6) & 3) { - case 2: - if(BLDMOD & top) - color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); - break; - case 3: - if(BLDMOD & top) - color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); - break; - } - } + lineMix[x] = color; } - - lineMix[x] = color; - } - gfxBG2Changed = 0; - gfxLastVCOUNT = VCOUNT; + gfxBG2Changed = 0; + gfxLastVCOUNT = VCOUNT; } void mode5RenderLineAll() { - if(DISPCNT & 0x0080) { - for(int x = 0; x < 240; x++) { - lineMix[x] = 0x7fff; - } - gfxLastVCOUNT = VCOUNT; - return; - } - - u16 *palette = (u16 *)paletteRAM; - - if(layerEnable & 0x0400) { - int changed = gfxBG2Changed; - - if(gfxLastVCOUNT > VCOUNT) - changed = 3; - - gfxDrawRotScreen16Bit160(BG2CNT, BG2X_L, BG2X_H, - BG2Y_L, BG2Y_H, BG2PA, BG2PB, - BG2PC, BG2PD, - gfxBG2X, gfxBG2Y, changed, - line2); - } - - gfxDrawSprites(lineOBJ); - gfxDrawOBJWin(lineOBJWin); - - bool inWindow0 = false; - bool inWindow1 = false; - - if(layerEnable & 0x2000) { - u8 v0 = WIN0V >> 8; - u8 v1 = WIN0V & 255; - inWindow0 = ((v0 == v1) && (v0 >= 0xe8)); - if(v1 >= v0) - inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1); - else - inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1); - } - if(layerEnable & 0x4000) { - u8 v0 = WIN1V >> 8; - u8 v1 = WIN1V & 255; - inWindow1 = ((v0 == v1) && (v0 >= 0xe8)); - if(v1 >= v0) - inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1); - else - inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1); - } - - u8 inWin0Mask = WININ & 0xFF; - u8 inWin1Mask = WININ >> 8; - u8 outMask = WINOUT & 0xFF; - - u32 background; - if(customBackdropColor == -1) { - background = (READ16LE(&palette[0]) | 0x30000000); - } else { - background = ((customBackdropColor & 0x7FFF) | 0x30000000); - } - - for(int x = 0; x < 240; x++) { - u32 color = background; - u8 top = 0x20; - u8 mask = outMask; - - if(!(lineOBJWin[x] & 0x80000000)) { - mask = WINOUT >> 8; - } - - if(inWindow1) { - if(gfxInWin1[x]) - mask = inWin1Mask; - } - - if(inWindow0) { - if(gfxInWin0[x]) { - mask = inWin0Mask; - } - } - - if((mask & 4) && (line2[x] < color)) { - color = line2[x]; - top = 0x04; - } - - if((mask & 16) && ((u8)(lineOBJ[x]>>24) < (u8)(color >>24))) { - color = lineOBJ[x]; - top = 0x10; - } - - if(color & 0x00010000) { - // semi-transparent OBJ - u32 back = background; - u8 top2 = 0x20; - - if((mask & 4) && line2[x] < back) { - back = line2[x]; - top2 = 0x04; - } - - if(top2 & (BLDMOD>>8)) - color = gfxAlphaBlend(color, back, - coeff[COLEV & 0x1F], - coeff[(COLEV >> 8) & 0x1F]); - else { - switch((BLDMOD >> 6) & 3) { - case 2: - if(BLDMOD & top) - color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); - break; - case 3: - if(BLDMOD & top) - color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); - break; + if (DISPCNT & 0x0080) { + for (int x = 0; x < 240; x++) { + lineMix[x] = 0x7fff; } - } - } else if(mask & 32) { - switch((BLDMOD >> 6) & 3) { - case 0: - break; - case 1: - { - if(top & BLDMOD) { + gfxLastVCOUNT = VCOUNT; + return; + } + + u16* palette = (u16*)paletteRAM; + + if (layerEnable & 0x0400) { + int changed = gfxBG2Changed; + + if (gfxLastVCOUNT > VCOUNT) + changed = 3; + + gfxDrawRotScreen16Bit160(BG2CNT, BG2X_L, BG2X_H, + BG2Y_L, BG2Y_H, BG2PA, BG2PB, + BG2PC, BG2PD, + gfxBG2X, gfxBG2Y, changed, + line2); + } + + gfxDrawSprites(lineOBJ); + gfxDrawOBJWin(lineOBJWin); + + bool inWindow0 = false; + bool inWindow1 = false; + + if (layerEnable & 0x2000) { + u8 v0 = WIN0V >> 8; + u8 v1 = WIN0V & 255; + inWindow0 = ((v0 == v1) && (v0 >= 0xe8)); + if (v1 >= v0) + inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1); + else + inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1); + } + if (layerEnable & 0x4000) { + u8 v0 = WIN1V >> 8; + u8 v1 = WIN1V & 255; + inWindow1 = ((v0 == v1) && (v0 >= 0xe8)); + if (v1 >= v0) + inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1); + else + inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1); + } + + u8 inWin0Mask = WININ & 0xFF; + u8 inWin1Mask = WININ >> 8; + u8 outMask = WINOUT & 0xFF; + + u32 background; + if (customBackdropColor == -1) { + background = (READ16LE(&palette[0]) | 0x30000000); + } else { + background = ((customBackdropColor & 0x7FFF) | 0x30000000); + } + + for (int x = 0; x < 240; x++) { + u32 color = background; + u8 top = 0x20; + u8 mask = outMask; + + if (!(lineOBJWin[x] & 0x80000000)) { + mask = WINOUT >> 8; + } + + if (inWindow1) { + if (gfxInWin1[x]) + mask = inWin1Mask; + } + + if (inWindow0) { + if (gfxInWin0[x]) { + mask = inWin0Mask; + } + } + + if ((mask & 4) && (line2[x] < color)) { + color = line2[x]; + top = 0x04; + } + + if ((mask & 16) && ((u8)(lineOBJ[x] >> 24) < (u8)(color >> 24))) { + color = lineOBJ[x]; + top = 0x10; + } + + if (color & 0x00010000) { + // semi-transparent OBJ u32 back = background; u8 top2 = 0x20; - if((mask & 4) && line2[x] < back) { - if(top != 0x04) { + if ((mask & 4) && line2[x] < back) { back = line2[x]; top2 = 0x04; - } } - if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { - if(top != 0x10) { - back = lineOBJ[x]; - top2 = 0x10; - } + if (top2 & (BLDMOD >> 8)) + color = gfxAlphaBlend(color, back, + coeff[COLEV & 0x1F], + coeff[(COLEV >> 8) & 0x1F]); + else { + switch ((BLDMOD >> 6) & 3) { + case 2: + if (BLDMOD & top) + color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); + break; + case 3: + if (BLDMOD & top) + color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); + break; + } } + } else if (mask & 32) { + switch ((BLDMOD >> 6) & 3) { + case 0: + break; + case 1: { + if (top & BLDMOD) { + u32 back = background; + u8 top2 = 0x20; - if(top2 & (BLDMOD>>8)) - color = gfxAlphaBlend(color, back, - coeff[COLEV & 0x1F], - coeff[(COLEV >> 8) & 0x1F]); + if ((mask & 4) && line2[x] < back) { + if (top != 0x04) { + back = line2[x]; + top2 = 0x04; + } + } - } + if ((mask & 16) && (u8)(lineOBJ[x] >> 24) < (u8)(back >> 24)) { + if (top != 0x10) { + back = lineOBJ[x]; + top2 = 0x10; + } + } + + if (top2 & (BLDMOD >> 8)) + color = gfxAlphaBlend(color, back, + coeff[COLEV & 0x1F], + coeff[(COLEV >> 8) & 0x1F]); + } + } break; + case 2: + if (BLDMOD & top) + color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); + break; + case 3: + if (BLDMOD & top) + color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); + break; + } } - break; - case 2: - if(BLDMOD & top) - color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); - break; - case 3: - if(BLDMOD & top) - color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); - break; - } - } - lineMix[x] = color; - } - gfxBG2Changed = 0; - gfxLastVCOUNT = VCOUNT; + lineMix[x] = color; + } + gfxBG2Changed = 0; + gfxLastVCOUNT = VCOUNT; } diff --git a/src/gba/RTC.cpp b/src/gba/RTC.cpp index 5acbce5f..bfbffae5 100644 --- a/src/gba/RTC.cpp +++ b/src/gba/RTC.cpp @@ -1,36 +1,35 @@ +#include "../NLS.h" #include "../System.h" +#include "../Util.h" +#include "../common/Port.h" #include "GBA.h" #include "Globals.h" -#include "../common/Port.h" -#include "../Util.h" -#include "../NLS.h" -#include #include #include +#include -enum RTCSTATE -{ - IDLE = 0, - COMMAND, - DATA, - READDATA +enum RTCSTATE { + IDLE = 0, + COMMAND, + DATA, + READDATA }; typedef struct { - u8 byte0; - u8 select; - u8 enable; - u8 command; - int dataLen; - int bits; - RTCSTATE state; - u8 data[12]; - // reserved variables for future - u8 reserved[12]; - bool reserved2; - u32 reserved3; + u8 byte0; + u8 select; + u8 enable; + u8 command; + int dataLen; + int bits; + RTCSTATE state; + u8 data[12]; + // reserved variables for future + u8 reserved[12]; + bool reserved2; + u32 reserved3; } RTCCLOCKDATA; struct tm gba_time; @@ -42,330 +41,287 @@ u32 countTicks = 0; void rtcEnable(bool e) { - rtcClockEnabled = e; + rtcClockEnabled = e; } bool rtcIsEnabled() { - return rtcClockEnabled; + return rtcClockEnabled; } void rtcEnableRumble(bool e) { - rtcRumbleEnabled = e; + rtcRumbleEnabled = e; } u16 rtcRead(u32 address) { - int res = 0; + int res = 0; - switch (address) - { - case 0x80000c8: - return rtcClockData.enable; - break; + switch (address) { + case 0x80000c8: + return rtcClockData.enable; + break; - case 0x80000c6: - return rtcClockData.select; - break; + case 0x80000c6: + return rtcClockData.select; + break; - case 0x80000c4: - if (!(rtcClockData.enable & 1)) - { - return 0; - } + case 0x80000c4: + if (!(rtcClockData.enable & 1)) { + return 0; + } - // Boktai Solar Sensor - if (rtcClockData.select == 0x07) - { - if (rtcClockData.reserved[11] >= systemGetSensorDarkness()) - { - res |= 8; - } - } + // Boktai Solar Sensor + if (rtcClockData.select == 0x07) { + if (rtcClockData.reserved[11] >= systemGetSensorDarkness()) { + res |= 8; + } + } - // WarioWare Twisted Tilt Sensor - if (rtcClockData.select == 0x0b) - { - u16 v = systemGetSensorZ(); - v = 0x6C0 + v; - res |= ((v >> rtcClockData.reserved[11]) & 1) << 2; - } + // WarioWare Twisted Tilt Sensor + if (rtcClockData.select == 0x0b) { + u16 v = systemGetSensorZ(); + v = 0x6C0 + v; + res |= ((v >> rtcClockData.reserved[11]) & 1) << 2; + } - // Real Time Clock - if (rtcClockEnabled && (rtcClockData.select & 0x04)) - { - res |= rtcClockData.byte0; - } + // Real Time Clock + if (rtcClockEnabled && (rtcClockData.select & 0x04)) { + res |= rtcClockData.byte0; + } - return res; - break; - } + return res; + break; + } - return READ16LE((&rom[address & 0x1FFFFFE])); + return READ16LE((&rom[address & 0x1FFFFFE])); } static u8 toBCD(u8 value) { - value = value % 100; - int l = value % 10; - int h = value / 10; - return h * 16 + l; + value = value % 100; + int l = value % 10; + int h = value / 10; + return h * 16 + l; } void SetGBATime() { - time_t long_time; - time(&long_time); /* Get time as long integer. */ - gba_time = *localtime(&long_time); /* Convert to local time. */ + time_t long_time; + time(&long_time); /* Get time as long integer. */ + gba_time = *localtime(&long_time); /* Convert to local time. */ } void rtcUpdateTime(int ticks) { - countTicks += ticks; + countTicks += ticks; - if (countTicks > TICKS_PER_SECOND) - { - countTicks -= TICKS_PER_SECOND; - gba_time.tm_sec++; - mktime(&gba_time); - } + if (countTicks > TICKS_PER_SECOND) { + countTicks -= TICKS_PER_SECOND; + gba_time.tm_sec++; + mktime(&gba_time); + } } bool rtcWrite(u32 address, u16 value) { - if (address == 0x80000c8) - { - rtcClockData.enable = (u8)value; // bit 0 = enable reading from 0x80000c4 c6 and c8 - } - else if (address == 0x80000c6) - { - rtcClockData.select = (u8)value; // 0=read/1=write (for each of 4 low bits) + if (address == 0x80000c8) { + rtcClockData.enable = (u8)value; // bit 0 = enable reading from 0x80000c4 c6 and c8 + } else if (address == 0x80000c6) { + rtcClockData.select = (u8)value; // 0=read/1=write (for each of 4 low bits) - // rumble is off when not writing to that pin - if (rtcRumbleEnabled && !(value & 8)) systemCartridgeRumble(false); - } - else if (address == 0x80000c4) // 4 bits of I/O Port Data (upper bits not used) - { - // WarioWare Twisted rumble - if (rtcRumbleEnabled && (rtcClockData.select & 0x08)) - { - systemCartridgeRumble(value & 8); - } + // rumble is off when not writing to that pin + if (rtcRumbleEnabled && !(value & 8)) + systemCartridgeRumble(false); + } else if (address == 0x80000c4) // 4 bits of I/O Port Data (upper bits not used) + { + // WarioWare Twisted rumble + if (rtcRumbleEnabled && (rtcClockData.select & 0x08)) { + systemCartridgeRumble(value & 8); + } - // Boktai solar sensor - if (rtcClockData.select == 0x07) - { - if (value & 2) - { - // reset counter to 0 - rtcClockData.reserved[11] = 0; - } + // Boktai solar sensor + if (rtcClockData.select == 0x07) { + if (value & 2) { + // reset counter to 0 + rtcClockData.reserved[11] = 0; + } - if ((value & 1) && !(rtcClockData.reserved[10] & 1)) - { - // increase counter, ready to do another read - if (rtcClockData.reserved[11] < 255) - { - rtcClockData.reserved[11]++; - } - else - { - rtcClockData.reserved[11] = 0; - } - } + if ((value & 1) && !(rtcClockData.reserved[10] & 1)) { + // increase counter, ready to do another read + if (rtcClockData.reserved[11] < 255) { + rtcClockData.reserved[11]++; + } else { + rtcClockData.reserved[11] = 0; + } + } - rtcClockData.reserved[10] = value & rtcClockData.select; - } + rtcClockData.reserved[10] = value & rtcClockData.select; + } - // WarioWare Twisted rotation sensor - if (rtcClockData.select == 0x0b) - { - if (value & 2) - { - // clock goes high in preperation for reading a bit - rtcClockData.reserved[11]--; - } + // WarioWare Twisted rotation sensor + if (rtcClockData.select == 0x0b) { + if (value & 2) { + // clock goes high in preperation for reading a bit + rtcClockData.reserved[11]--; + } - if (value & 1) - { - // start ADC conversion - rtcClockData.reserved[11] = 15; - } + if (value & 1) { + // start ADC conversion + rtcClockData.reserved[11] = 15; + } - rtcClockData.byte0 = value & rtcClockData.select; - } + rtcClockData.byte0 = value & rtcClockData.select; + } - // Real Time Clock - if (rtcClockData.select & 4) - { - if (rtcClockData.state == IDLE && rtcClockData.byte0 == 1 && value == 5) - { - rtcClockData.state = COMMAND; - rtcClockData.bits = 0; - rtcClockData.command = 0; - } - else if (!(rtcClockData.byte0 & 1) && (value & 1)) // bit transfer - { - rtcClockData.byte0 = (u8)value; + // Real Time Clock + if (rtcClockData.select & 4) { + if (rtcClockData.state == IDLE && rtcClockData.byte0 == 1 && value == 5) { + rtcClockData.state = COMMAND; + rtcClockData.bits = 0; + rtcClockData.command = 0; + } else if (!(rtcClockData.byte0 & 1) && (value & 1)) // bit transfer + { + rtcClockData.byte0 = (u8)value; - switch (rtcClockData.state) - { - case COMMAND: - rtcClockData.command |= ((value & 2) >> 1) << (7 - rtcClockData.bits); - rtcClockData.bits++; + switch (rtcClockData.state) { + case COMMAND: + rtcClockData.command |= ((value & 2) >> 1) << (7 - rtcClockData.bits); + rtcClockData.bits++; - if (rtcClockData.bits == 8) - { - rtcClockData.bits = 0; + if (rtcClockData.bits == 8) { + rtcClockData.bits = 0; - switch (rtcClockData.command) - { - case 0x60: - // not sure what this command does but it doesn't take parameters - // maybe it is a reset or stop - rtcClockData.state = IDLE; - rtcClockData.bits = 0; - break; + switch (rtcClockData.command) { + case 0x60: + // not sure what this command does but it doesn't take parameters + // maybe it is a reset or stop + rtcClockData.state = IDLE; + rtcClockData.bits = 0; + break; - case 0x62: - // this sets the control state but not sure what those values are - rtcClockData.state = READDATA; - rtcClockData.dataLen = 1; - break; + case 0x62: + // this sets the control state but not sure what those values are + rtcClockData.state = READDATA; + rtcClockData.dataLen = 1; + break; - case 0x63: - rtcClockData.dataLen = 1; - rtcClockData.data[0] = 0x40; - rtcClockData.state = DATA; - break; + case 0x63: + rtcClockData.dataLen = 1; + rtcClockData.data[0] = 0x40; + rtcClockData.state = DATA; + break; - case 0x64: - break; + case 0x64: + break; - case 0x65: - { - if (rtcEnabled) - SetGBATime(); + case 0x65: { + if (rtcEnabled) + SetGBATime(); - rtcClockData.dataLen = 7; - rtcClockData.data[0] = toBCD(gba_time.tm_year); - rtcClockData.data[1] = toBCD(gba_time.tm_mon + 1); - rtcClockData.data[2] = toBCD(gba_time.tm_mday); - rtcClockData.data[3] = toBCD(gba_time.tm_wday); - rtcClockData.data[4] = toBCD(gba_time.tm_hour); - rtcClockData.data[5] = toBCD(gba_time.tm_min); - rtcClockData.data[6] = toBCD(gba_time.tm_sec); - rtcClockData.state = DATA; - } - break; + rtcClockData.dataLen = 7; + rtcClockData.data[0] = toBCD(gba_time.tm_year); + rtcClockData.data[1] = toBCD(gba_time.tm_mon + 1); + rtcClockData.data[2] = toBCD(gba_time.tm_mday); + rtcClockData.data[3] = toBCD(gba_time.tm_wday); + rtcClockData.data[4] = toBCD(gba_time.tm_hour); + rtcClockData.data[5] = toBCD(gba_time.tm_min); + rtcClockData.data[6] = toBCD(gba_time.tm_sec); + rtcClockData.state = DATA; + } break; - case 0x67: - { - if (rtcEnabled) - SetGBATime(); + case 0x67: { + if (rtcEnabled) + SetGBATime(); - rtcClockData.dataLen = 3; - rtcClockData.data[0] = toBCD(gba_time.tm_hour); - rtcClockData.data[1] = toBCD(gba_time.tm_min); - rtcClockData.data[2] = toBCD(gba_time.tm_sec); - rtcClockData.state = DATA; - } - break; + rtcClockData.dataLen = 3; + rtcClockData.data[0] = toBCD(gba_time.tm_hour); + rtcClockData.data[1] = toBCD(gba_time.tm_min); + rtcClockData.data[2] = toBCD(gba_time.tm_sec); + rtcClockData.state = DATA; + } break; - default: - log(N_("Unknown RTC command %02x"), rtcClockData.command); - rtcClockData.state = IDLE; - break; - } - } + default: + log(N_("Unknown RTC command %02x"), rtcClockData.command); + rtcClockData.state = IDLE; + break; + } + } - break; + break; - case DATA: - if (rtcClockData.select & 2) - { - } - else if (rtcClockData.select & 4) - { - rtcClockData.byte0 = (rtcClockData.byte0 & ~2) | - ((rtcClockData.data[rtcClockData.bits >> 3] >> - (rtcClockData.bits & 7)) & 1) * 2; - rtcClockData.bits++; + case DATA: + if (rtcClockData.select & 2) { + } else if (rtcClockData.select & 4) { + rtcClockData.byte0 = (rtcClockData.byte0 & ~2) | ((rtcClockData.data[rtcClockData.bits >> 3] >> (rtcClockData.bits & 7)) & 1) * 2; + rtcClockData.bits++; - if (rtcClockData.bits == 8 * rtcClockData.dataLen) - { - rtcClockData.bits = 0; - rtcClockData.state = IDLE; - } - } + if (rtcClockData.bits == 8 * rtcClockData.dataLen) { + rtcClockData.bits = 0; + rtcClockData.state = IDLE; + } + } - break; + break; - case READDATA: - if (!(rtcClockData.select & 2)) - { - } - else - { - rtcClockData.data[rtcClockData.bits >> 3] = - (rtcClockData.data[rtcClockData.bits >> 3] >> 1) | - ((value << 6) & 128); - rtcClockData.bits++; + case READDATA: + if (!(rtcClockData.select & 2)) { + } else { + rtcClockData.data[rtcClockData.bits >> 3] = (rtcClockData.data[rtcClockData.bits >> 3] >> 1) | ((value << 6) & 128); + rtcClockData.bits++; - if (rtcClockData.bits == 8 * rtcClockData.dataLen) - { - rtcClockData.bits = 0; - rtcClockData.state = IDLE; - } - } + if (rtcClockData.bits == 8 * rtcClockData.dataLen) { + rtcClockData.bits = 0; + rtcClockData.state = IDLE; + } + } - break; + break; - default: - break; - } - } - else - rtcClockData.byte0 = (u8)value; - } - } + default: + break; + } + } else + rtcClockData.byte0 = (u8)value; + } + } - return true; + return true; } void rtcReset() { - memset(&rtcClockData, 0, sizeof(rtcClockData)); - rtcClockData.byte0 = 0; - rtcClockData.select = 0; - rtcClockData.enable = 0; - rtcClockData.command = 0; - rtcClockData.dataLen = 0; - rtcClockData.bits = 0; - rtcClockData.state = IDLE; - rtcClockData.reserved[11] = 0; - SetGBATime(); + memset(&rtcClockData, 0, sizeof(rtcClockData)); + rtcClockData.byte0 = 0; + rtcClockData.select = 0; + rtcClockData.enable = 0; + rtcClockData.command = 0; + rtcClockData.dataLen = 0; + rtcClockData.bits = 0; + rtcClockData.state = IDLE; + rtcClockData.reserved[11] = 0; + SetGBATime(); } #ifdef __LIBRETRO__ -void rtcSaveGame(u8* &data) +void rtcSaveGame(u8*& data) { - utilWriteMem(data, &rtcClockData, sizeof(rtcClockData)); + utilWriteMem(data, &rtcClockData, sizeof(rtcClockData)); } -void rtcReadGame(const u8* &data) +void rtcReadGame(const u8*& data) { - utilReadMem(&rtcClockData, data, sizeof(rtcClockData)); + utilReadMem(&rtcClockData, data, sizeof(rtcClockData)); } #else void rtcSaveGame(gzFile gzFile) { - utilGzWrite(gzFile, &rtcClockData, sizeof(rtcClockData)); + utilGzWrite(gzFile, &rtcClockData, sizeof(rtcClockData)); } void rtcReadGame(gzFile gzFile) { - utilGzRead(gzFile, &rtcClockData, sizeof(rtcClockData)); + utilGzRead(gzFile, &rtcClockData, sizeof(rtcClockData)); } #endif diff --git a/src/gba/RTC.h b/src/gba/RTC.h index 95a142c8..6fee9289 100644 --- a/src/gba/RTC.h +++ b/src/gba/RTC.h @@ -10,8 +10,8 @@ bool rtcIsEnabled(); void rtcReset(); #ifdef __LIBRETRO__ -void rtcReadGame(const u8 *&data); -void rtcSaveGame(u8 *&data); +void rtcReadGame(const u8*& data); +void rtcSaveGame(u8*& data); #else void rtcReadGame(gzFile gzFile); void rtcSaveGame(gzFile gzFile); diff --git a/src/gba/Sound.cpp b/src/gba/Sound.cpp index 03ea4bd4..dfb3b3ab 100644 --- a/src/gba/Sound.cpp +++ b/src/gba/Sound.cpp @@ -2,10 +2,10 @@ #include "Sound.h" -#include "GBA.h" -#include "Globals.h" #include "../Util.h" #include "../common/Port.h" +#include "GBA.h" +#include "Globals.h" #include "../apu/Gb_Apu.h" #include "../apu/Multi_Buffer.h" @@ -34,811 +34,791 @@ #define NR51 0x81 #define NR52 0x84 -SoundDriver * soundDriver = 0; +SoundDriver* soundDriver = 0; -extern bool stopState; // TODO: silence sound when true +extern bool stopState; // TODO: silence sound when true int const SOUND_CLOCK_TICKS_ = 167772; // 1/100 second -static u16 soundFinalWave [1600]; -long soundSampleRate = 44100; -bool soundInterpolation = true; -bool soundPaused = true; -float soundFiltering = 0.5f; -int SOUND_CLOCK_TICKS = SOUND_CLOCK_TICKS_; -int soundTicks = SOUND_CLOCK_TICKS_; +static u16 soundFinalWave[1600]; +long soundSampleRate = 44100; +bool soundInterpolation = true; +bool soundPaused = true; +float soundFiltering = 0.5f; +int SOUND_CLOCK_TICKS = SOUND_CLOCK_TICKS_; +int soundTicks = SOUND_CLOCK_TICKS_; -static float soundVolume = 1.0f; -static int soundEnableFlag = 0x3ff; // emulator channels enabled +static float soundVolume = 1.0f; +static int soundEnableFlag = 0x3ff; // emulator channels enabled static float soundFiltering_ = -1; -static float soundVolume_ = -1; +static float soundVolume_ = -1; -void interp_rate() { /* empty for now */ } +void interp_rate() { /* empty for now */} class Gba_Pcm { public: - void init(); - void apply_control( int idx ); - void update( int dac ); - void end_frame( blip_time_t ); + void init(); + void apply_control(int idx); + void update(int dac); + void end_frame(blip_time_t); private: - Blip_Buffer* output; - blip_time_t last_time; - int last_amp; - int shift; + Blip_Buffer* output; + blip_time_t last_time; + int last_amp; + int shift; }; class Gba_Pcm_Fifo { public: - int which; - Gba_Pcm pcm; + int which; + Gba_Pcm pcm; - void write_control( int data ); - void write_fifo( int data ); - void timer_overflowed( int which_timer ); + void write_control(int data); + void write_fifo(int data); + void timer_overflowed(int which_timer); + + // public only so save state routines can access it + int readIndex; + int count; + int writeIndex; + u8 fifo[32]; + int dac; - // public only so save state routines can access it - int readIndex; - int count; - int writeIndex; - u8 fifo [32]; - int dac; private: - - int timer; - bool enabled; + int timer; + bool enabled; }; -static Gba_Pcm_Fifo pcm [2]; -static Gb_Apu* gb_apu; -static Stereo_Buffer* stereo_buffer; +static Gba_Pcm_Fifo pcm[2]; +static Gb_Apu* gb_apu; +static Stereo_Buffer* stereo_buffer; -static Blip_Synth pcm_synth [3]; // 32 kHz, 16 kHz, 8 kHz +static Blip_Synth pcm_synth[3]; // 32 kHz, 16 kHz, 8 kHz static inline blip_time_t blip_time() { - return SOUND_CLOCK_TICKS - soundTicks; + return SOUND_CLOCK_TICKS - soundTicks; } void Gba_Pcm::init() { - output = 0; - last_time = 0; - last_amp = 0; - shift = 0; + output = 0; + last_time = 0; + last_amp = 0; + shift = 0; } -void Gba_Pcm::apply_control( int idx ) +void Gba_Pcm::apply_control(int idx) { - shift = ~ioMem [SGCNT0_H] >> (2 + idx) & 1; + shift = ~ioMem[SGCNT0_H] >> (2 + idx) & 1; - int ch = 0; - if ( (soundEnableFlag >> idx & 0x100) && (ioMem [NR52] & 0x80) ) - ch = ioMem [SGCNT0_H+1] >> (idx * 4) & 3; + int ch = 0; + if ((soundEnableFlag >> idx & 0x100) && (ioMem[NR52] & 0x80)) + ch = ioMem[SGCNT0_H + 1] >> (idx * 4) & 3; - Blip_Buffer* out = 0; - switch ( ch ) - { - case 1: out = stereo_buffer->right(); break; - case 2: out = stereo_buffer->left(); break; - case 3: out = stereo_buffer->center(); break; - } + Blip_Buffer* out = 0; + switch (ch) { + case 1: + out = stereo_buffer->right(); + break; + case 2: + out = stereo_buffer->left(); + break; + case 3: + out = stereo_buffer->center(); + break; + } - if ( output != out ) - { - if ( output ) - { - output->set_modified(); - pcm_synth [0].offset( blip_time(), -last_amp, output ); - } - last_amp = 0; - output = out; - } + if (output != out) { + if (output) { + output->set_modified(); + pcm_synth[0].offset(blip_time(), -last_amp, output); + } + last_amp = 0; + output = out; + } } -void Gba_Pcm::end_frame( blip_time_t time ) +void Gba_Pcm::end_frame(blip_time_t time) { - last_time -= time; - if ( last_time < -2048 ) - last_time = -2048; + last_time -= time; + if (last_time < -2048) + last_time = -2048; - if ( output ) - output->set_modified(); + if (output) + output->set_modified(); } -void Gba_Pcm::update( int dac ) +void Gba_Pcm::update(int dac) { - if ( output ) - { - blip_time_t time = blip_time(); + if (output) { + blip_time_t time = blip_time(); - dac = (s8) dac >> shift; - int delta = dac - last_amp; - if ( delta ) - { - last_amp = dac; + dac = (s8)dac >> shift; + int delta = dac - last_amp; + if (delta) { + last_amp = dac; - int filter = 0; - if ( soundInterpolation ) - { - // base filtering on how long since last sample was output - int period = time - last_time; + int filter = 0; + if (soundInterpolation) { + // base filtering on how long since last sample was output + int period = time - last_time; - int idx = (unsigned) period / 512; - if ( idx >= 3 ) - idx = 3; + int idx = (unsigned)period / 512; + if (idx >= 3) + idx = 3; - static int const filters [4] = { 0, 0, 1, 2 }; - filter = filters [idx]; - } + static int const filters[4] = { 0, 0, 1, 2 }; + filter = filters[idx]; + } - pcm_synth [filter].offset( time, delta, output ); - } - last_time = time; - } + pcm_synth[filter].offset(time, delta, output); + } + last_time = time; + } } -void Gba_Pcm_Fifo::timer_overflowed( int which_timer ) +void Gba_Pcm_Fifo::timer_overflowed(int which_timer) { - if ( which_timer == timer && enabled ) - { - /* Mother 3 fix, refined to not break Metroid Fusion */ - if ( count == 16 || count == 0 ) - { - // Need to fill FIFO - int saved_count = count; - CPUCheckDMA( 3, which ? 4 : 2 ); - if ( saved_count == 0 && count == 16 ) - CPUCheckDMA( 3, which ? 4 : 2 ); - if ( count == 0 ) - { - // Not filled by DMA, so fill with 16 bytes of silence - int reg = which ? FIFOB_L : FIFOA_L; - for ( int n = 8; n--; ) - { - soundEvent(reg , (u16)0); - soundEvent(reg+2, (u16)0); - } - } - } + if (which_timer == timer && enabled) { + /* Mother 3 fix, refined to not break Metroid Fusion */ + if (count == 16 || count == 0) { + // Need to fill FIFO + int saved_count = count; + CPUCheckDMA(3, which ? 4 : 2); + if (saved_count == 0 && count == 16) + CPUCheckDMA(3, which ? 4 : 2); + if (count == 0) { + // Not filled by DMA, so fill with 16 bytes of silence + int reg = which ? FIFOB_L : FIFOA_L; + for (int n = 8; n--;) { + soundEvent(reg, (u16)0); + soundEvent(reg + 2, (u16)0); + } + } + } - // Read next sample from FIFO - count--; - dac = fifo [readIndex]; - readIndex = (readIndex + 1) & 31; - pcm.update( dac ); - } + // Read next sample from FIFO + count--; + dac = fifo[readIndex]; + readIndex = (readIndex + 1) & 31; + pcm.update(dac); + } } -void Gba_Pcm_Fifo::write_control( int data ) +void Gba_Pcm_Fifo::write_control(int data) { - enabled = (data & 0x0300) ? true : false; - timer = (data & 0x0400) ? 1 : 0; + enabled = (data & 0x0300) ? true : false; + timer = (data & 0x0400) ? 1 : 0; - if ( data & 0x0800 ) - { - // Reset - writeIndex = 0; - readIndex = 0; - count = 0; - dac = 0; - memset( fifo, 0, sizeof fifo ); - } + if (data & 0x0800) { + // Reset + writeIndex = 0; + readIndex = 0; + count = 0; + dac = 0; + memset(fifo, 0, sizeof fifo); + } - pcm.apply_control( which ); - pcm.update( dac ); + pcm.apply_control(which); + pcm.update(dac); } -void Gba_Pcm_Fifo::write_fifo( int data ) +void Gba_Pcm_Fifo::write_fifo(int data) { - fifo [writeIndex ] = data & 0xFF; - fifo [writeIndex+1] = data >> 8; - count += 2; - writeIndex = (writeIndex + 2) & 31; + fifo[writeIndex] = data & 0xFF; + fifo[writeIndex + 1] = data >> 8; + count += 2; + writeIndex = (writeIndex + 2) & 31; } static void apply_control() { - pcm [0].pcm.apply_control( 0 ); - pcm [1].pcm.apply_control( 1 ); + pcm[0].pcm.apply_control(0); + pcm[1].pcm.apply_control(1); } -static int gba_to_gb_sound( int addr ) +static int gba_to_gb_sound(int addr) { - static const int table [0x40] = - { - 0xFF10, 0,0xFF11,0xFF12,0xFF13,0xFF14, 0, 0, - 0xFF16,0xFF17, 0, 0,0xFF18,0xFF19, 0, 0, - 0xFF1A, 0,0xFF1B,0xFF1C,0xFF1D,0xFF1E, 0, 0, - 0xFF20,0xFF21, 0, 0,0xFF22,0xFF23, 0, 0, - 0xFF24,0xFF25, 0, 0,0xFF26, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0xFF30,0xFF31,0xFF32,0xFF33,0xFF34,0xFF35,0xFF36,0xFF37, - 0xFF38,0xFF39,0xFF3A,0xFF3B,0xFF3C,0xFF3D,0xFF3E,0xFF3F, - }; - if ( addr >= 0x60 && addr < 0xA0 ) - return table [addr - 0x60]; - return 0; + static const int table[0x40] = { + 0xFF10, 0, 0xFF11, 0xFF12, 0xFF13, 0xFF14, 0, 0, + 0xFF16, 0xFF17, 0, 0, 0xFF18, 0xFF19, 0, 0, + 0xFF1A, 0, 0xFF1B, 0xFF1C, 0xFF1D, 0xFF1E, 0, 0, + 0xFF20, 0xFF21, 0, 0, 0xFF22, 0xFF23, 0, 0, + 0xFF24, 0xFF25, 0, 0, 0xFF26, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0xFF30, 0xFF31, 0xFF32, 0xFF33, 0xFF34, 0xFF35, 0xFF36, 0xFF37, + 0xFF38, 0xFF39, 0xFF3A, 0xFF3B, 0xFF3C, 0xFF3D, 0xFF3E, 0xFF3F, + }; + if (addr >= 0x60 && addr < 0xA0) + return table[addr - 0x60]; + return 0; } void soundEvent(u32 address, u8 data) { - int gb_addr = gba_to_gb_sound( address ); - if ( gb_addr ) - { - ioMem[address] = data; - gb_apu->write_register( blip_time(), gb_addr, data ); + int gb_addr = gba_to_gb_sound(address); + if (gb_addr) { + ioMem[address] = data; + gb_apu->write_register(blip_time(), gb_addr, data); - if ( address == NR52 ) - apply_control(); - } + if (address == NR52) + apply_control(); + } - // TODO: what about byte writes to SGCNT0_H etc.? + // TODO: what about byte writes to SGCNT0_H etc.? } -static void apply_volume( bool apu_only = false ) +static void apply_volume(bool apu_only = false) { - if ( !apu_only ) - soundVolume_ = soundVolume; + if (!apu_only) + soundVolume_ = soundVolume; - if ( gb_apu ) - { - static float const apu_vols [4] = { 0.25, 0.5, 1, 0.25 }; - gb_apu->volume( soundVolume_ * apu_vols [ioMem [SGCNT0_H] & 3] ); - } + if (gb_apu) { + static float const apu_vols[4] = { 0.25, 0.5, 1, 0.25 }; + gb_apu->volume(soundVolume_ * apu_vols[ioMem[SGCNT0_H] & 3]); + } - if ( !apu_only ) - { - for ( int i = 0; i < 3; i++ ) - pcm_synth [i].volume( 0.66 / 256 * soundVolume_ ); - } + if (!apu_only) { + for (int i = 0; i < 3; i++) + pcm_synth[i].volume(0.66 / 256 * soundVolume_); + } } -static void write_SGCNT0_H( int data ) +static void write_SGCNT0_H(int data) { - WRITE16LE( &ioMem [SGCNT0_H], data & 0x770F ); - pcm [0].write_control( data ); - pcm [1].write_control( data >> 4 ); - apply_volume( true ); + WRITE16LE(&ioMem[SGCNT0_H], data & 0x770F); + pcm[0].write_control(data); + pcm[1].write_control(data >> 4); + apply_volume(true); } void soundEvent(u32 address, u16 data) { - switch ( address ) - { - case SGCNT0_H: - write_SGCNT0_H( data ); - break; + switch (address) { + case SGCNT0_H: + write_SGCNT0_H(data); + break; - case FIFOA_L: - case FIFOA_H: - pcm [0].write_fifo( data ); - WRITE16LE( &ioMem[address], data ); - break; + case FIFOA_L: + case FIFOA_H: + pcm[0].write_fifo(data); + WRITE16LE(&ioMem[address], data); + break; - case FIFOB_L: - case FIFOB_H: - pcm [1].write_fifo( data ); - WRITE16LE( &ioMem[address], data ); - break; + case FIFOB_L: + case FIFOB_H: + pcm[1].write_fifo(data); + WRITE16LE(&ioMem[address], data); + break; - case 0x88: - data &= 0xC3FF; - WRITE16LE( &ioMem[address], data ); - break; + case 0x88: + data &= 0xC3FF; + WRITE16LE(&ioMem[address], data); + break; - default: - soundEvent( address & ~1, (u8) (data ) ); // even - soundEvent( address | 1, (u8) (data >> 8) ); // odd - break; - } + default: + soundEvent(address & ~1, (u8)(data)); // even + soundEvent(address | 1, (u8)(data >> 8)); // odd + break; + } } void soundTimerOverflow(int timer) { - pcm [0].timer_overflowed( timer ); - pcm [1].timer_overflowed( timer ); + pcm[0].timer_overflowed(timer); + pcm[1].timer_overflowed(timer); } -static void end_frame( blip_time_t time ) +static void end_frame(blip_time_t time) { - pcm [0].pcm.end_frame( time ); - pcm [1].pcm.end_frame( time ); + pcm[0].pcm.end_frame(time); + pcm[1].pcm.end_frame(time); - gb_apu ->end_frame( time ); - stereo_buffer->end_frame( time ); + gb_apu->end_frame(time); + stereo_buffer->end_frame(time); } -void flush_samples(Multi_Buffer * buffer) +void flush_samples(Multi_Buffer* buffer) { #ifdef __LIBRETRO__ - int numSamples = buffer->read_samples( (blip_sample_t*) soundFinalWave, buffer->samples_avail() ); - soundDriver->write(soundFinalWave, numSamples); - systemOnWriteDataToSoundBuffer(soundFinalWave, numSamples); + int numSamples = buffer->read_samples((blip_sample_t*)soundFinalWave, buffer->samples_avail()); + soundDriver->write(soundFinalWave, numSamples); + systemOnWriteDataToSoundBuffer(soundFinalWave, numSamples); #else - // We want to write the data frame by frame to support legacy audio drivers - // that don't use the length parameter of the write method. - // TODO: Update the Win32 audio drivers (DS, OAL, XA2), and flush all the - // samples at once to help reducing the audio delay on all platforms. - int soundBufferLen = ( soundSampleRate / 60 ) * 4; + // We want to write the data frame by frame to support legacy audio drivers + // that don't use the length parameter of the write method. + // TODO: Update the Win32 audio drivers (DS, OAL, XA2), and flush all the + // samples at once to help reducing the audio delay on all platforms. + int soundBufferLen = (soundSampleRate / 60) * 4; - // soundBufferLen should have a whole number of sample pairs - assert( soundBufferLen % (2 * sizeof *soundFinalWave) == 0 ); + // soundBufferLen should have a whole number of sample pairs + assert(soundBufferLen % (2 * sizeof *soundFinalWave) == 0); - // number of samples in output buffer - int const out_buf_size = soundBufferLen / sizeof *soundFinalWave; + // number of samples in output buffer + int const out_buf_size = soundBufferLen / sizeof *soundFinalWave; - // Keep filling and writing soundFinalWave until it can't be fully filled - while ( buffer->samples_avail() >= out_buf_size ) - { - buffer->read_samples( (blip_sample_t*) soundFinalWave, out_buf_size ); - if(soundPaused) - soundResume(); + // Keep filling and writing soundFinalWave until it can't be fully filled + while (buffer->samples_avail() >= out_buf_size) { + buffer->read_samples((blip_sample_t*)soundFinalWave, out_buf_size); + if (soundPaused) + soundResume(); - soundDriver->write(soundFinalWave, soundBufferLen); - systemOnWriteDataToSoundBuffer(soundFinalWave, soundBufferLen); - } + soundDriver->write(soundFinalWave, soundBufferLen); + systemOnWriteDataToSoundBuffer(soundFinalWave, soundBufferLen); + } #endif } static void apply_filtering() { - soundFiltering_ = soundFiltering; + soundFiltering_ = soundFiltering; - int const base_freq = (int) (32768 - soundFiltering_ * 16384); - int const nyquist = stereo_buffer->sample_rate() / 2; + int const base_freq = (int)(32768 - soundFiltering_ * 16384); + int const nyquist = stereo_buffer->sample_rate() / 2; - for ( int i = 0; i < 3; i++ ) - { - int cutoff = base_freq >> i; - if ( cutoff > nyquist ) - cutoff = nyquist; - pcm_synth [i].treble_eq( blip_eq_t( 0, 0, stereo_buffer->sample_rate(), cutoff ) ); - } + for (int i = 0; i < 3; i++) { + int cutoff = base_freq >> i; + if (cutoff > nyquist) + cutoff = nyquist; + pcm_synth[i].treble_eq(blip_eq_t(0, 0, stereo_buffer->sample_rate(), cutoff)); + } } void psoundTickfn() { - if ( gb_apu && stereo_buffer ) - { - // Run sound hardware to present - end_frame( SOUND_CLOCK_TICKS ); + if (gb_apu && stereo_buffer) { + // Run sound hardware to present + end_frame(SOUND_CLOCK_TICKS); - flush_samples(stereo_buffer); + flush_samples(stereo_buffer); - if ( soundFiltering_ != soundFiltering ) - apply_filtering(); + if (soundFiltering_ != soundFiltering) + apply_filtering(); - if ( soundVolume_ != soundVolume ) - apply_volume(); - } + if (soundVolume_ != soundVolume) + apply_volume(); + } } static void apply_muting() { - if ( !stereo_buffer || !ioMem ) - return; + if (!stereo_buffer || !ioMem) + return; - // PCM - apply_control(); + // PCM + apply_control(); - if ( gb_apu ) - { - // APU - for ( int i = 0; i < 4; i++ ) - { - if ( soundEnableFlag >> i & 1 ) - gb_apu->set_output( stereo_buffer->center(), - stereo_buffer->left(), stereo_buffer->right(), i ); - else - gb_apu->set_output( 0, 0, 0, i ); - } - } + if (gb_apu) { + // APU + for (int i = 0; i < 4; i++) { + if (soundEnableFlag >> i & 1) + gb_apu->set_output(stereo_buffer->center(), + stereo_buffer->left(), stereo_buffer->right(), i); + else + gb_apu->set_output(0, 0, 0, i); + } + } } static void reset_apu() { - gb_apu->reset( gb_apu->mode_agb, true ); + gb_apu->reset(gb_apu->mode_agb, true); - if ( stereo_buffer ) - stereo_buffer->clear(); + if (stereo_buffer) + stereo_buffer->clear(); - soundTicks = SOUND_CLOCK_TICKS; + soundTicks = SOUND_CLOCK_TICKS; } static void remake_stereo_buffer() { - if ( !ioMem ) - return; + if (!ioMem) + return; - // Clears pointers kept to old stereo_buffer - pcm [0].pcm.init(); - pcm [1].pcm.init(); + // Clears pointers kept to old stereo_buffer + pcm[0].pcm.init(); + pcm[1].pcm.init(); - // APU - if ( !gb_apu ) - { - gb_apu = new Gb_Apu; // TODO: handle out of memory - reset_apu(); - } + // APU + if (!gb_apu) { + gb_apu = new Gb_Apu; // TODO: handle out of memory + reset_apu(); + } - // Stereo_Buffer - delete stereo_buffer; - stereo_buffer = 0; + // Stereo_Buffer + delete stereo_buffer; + stereo_buffer = 0; - stereo_buffer = new Stereo_Buffer; // TODO: handle out of memory - stereo_buffer->set_sample_rate( soundSampleRate ); // TODO: handle out of memory - stereo_buffer->clock_rate( gb_apu->clock_rate ); + stereo_buffer = new Stereo_Buffer; // TODO: handle out of memory + stereo_buffer->set_sample_rate(soundSampleRate); // TODO: handle out of memory + stereo_buffer->clock_rate(gb_apu->clock_rate); - // PCM - pcm [0].which = 0; - pcm [1].which = 1; - apply_filtering(); + // PCM + pcm[0].which = 0; + pcm[1].which = 1; + apply_filtering(); - // Volume Level - apply_muting(); - apply_volume(); + // Volume Level + apply_muting(); + apply_volume(); } void soundShutdown() { - if (soundDriver) - { - delete soundDriver; - soundDriver = 0; - } + if (soundDriver) { + delete soundDriver; + soundDriver = 0; + } - systemOnSoundShutdown(); + systemOnSoundShutdown(); - delete stereo_buffer; - stereo_buffer = 0; - - delete gb_apu; - gb_apu = 0; + delete stereo_buffer; + stereo_buffer = 0; + + delete gb_apu; + gb_apu = 0; } void soundPause() { - soundPaused = true; - if (soundDriver) - soundDriver->pause(); + soundPaused = true; + if (soundDriver) + soundDriver->pause(); } void soundResume() { - soundPaused = false; - if (soundDriver) - soundDriver->resume(); + soundPaused = false; + if (soundDriver) + soundDriver->resume(); } -void soundSetVolume( float volume ) +void soundSetVolume(float volume) { - soundVolume = volume; + soundVolume = volume; } float soundGetVolume() { - return soundVolume; + return soundVolume; } void soundSetEnable(int channels) { - soundEnableFlag = channels; - apply_muting(); + soundEnableFlag = channels; + apply_muting(); } int soundGetEnable() { - return (soundEnableFlag & 0x30f); + return (soundEnableFlag & 0x30f); } void soundReset() { - soundDriver->reset(); + soundDriver->reset(); - remake_stereo_buffer(); - reset_apu(); + remake_stereo_buffer(); + reset_apu(); - soundPaused = true; - SOUND_CLOCK_TICKS = SOUND_CLOCK_TICKS_; - soundTicks = SOUND_CLOCK_TICKS_; + soundPaused = true; + SOUND_CLOCK_TICKS = SOUND_CLOCK_TICKS_; + soundTicks = SOUND_CLOCK_TICKS_; - soundEvent( NR52, (u8) 0x80 ); + soundEvent(NR52, (u8)0x80); } bool soundInit() { - soundDriver = systemSoundInit(); - if ( !soundDriver ) - return false; + soundDriver = systemSoundInit(); + if (!soundDriver) + return false; - if (!soundDriver->init(soundSampleRate)) - return false; + if (!soundDriver->init(soundSampleRate)) + return false; - soundPaused = true; - return true; + soundPaused = true; + return true; } void soundSetThrottle(unsigned short _throttle) { - if(!soundDriver) - return; - soundDriver->setThrottle(_throttle); + if (!soundDriver) + return; + soundDriver->setThrottle(_throttle); } long soundGetSampleRate() { - return soundSampleRate; + return soundSampleRate; } void soundSetSampleRate(long sampleRate) { - if ( soundSampleRate != sampleRate ) - { - if ( systemCanChangeSoundQuality() ) - { - soundShutdown(); - soundSampleRate = sampleRate; - soundInit(); - } - else - { - soundSampleRate = sampleRate; - } + if (soundSampleRate != sampleRate) { + if (systemCanChangeSoundQuality()) { + soundShutdown(); + soundSampleRate = sampleRate; + soundInit(); + } else { + soundSampleRate = sampleRate; + } - remake_stereo_buffer(); - } + remake_stereo_buffer(); + } } -static int dummy_state [16]; +static int dummy_state[16]; -#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) \ + } static struct { - gb_apu_state_t apu; + gb_apu_state_t apu; - // old state - u8 soundDSAValue; - int soundDSBValue; + // old state + u8 soundDSAValue; + int soundDSBValue; } state; // Old GBA sound state format -static variable_desc old_gba_state [] = -{ - SKIP( int, soundPaused ), - SKIP( int, soundPlay ), - SKIP( int, soundTicks ), - SKIP( int, SOUND_CLOCK_TICKS ), - SKIP( int, soundLevel1 ), - SKIP( int, soundLevel2 ), - SKIP( int, soundBalance ), - SKIP( int, soundMasterOn ), - SKIP( int, soundIndex ), - SKIP( int, sound1On ), - SKIP( int, sound1ATL ), - SKIP( int, sound1Skip ), - SKIP( int, sound1Index ), - SKIP( int, sound1Continue ), - SKIP( int, sound1EnvelopeVolume ), - SKIP( int, sound1EnvelopeATL ), - SKIP( int, sound1EnvelopeATLReload ), - SKIP( int, sound1EnvelopeUpDown ), - SKIP( int, sound1SweepATL ), - SKIP( int, sound1SweepATLReload ), - SKIP( int, sound1SweepSteps ), - SKIP( int, sound1SweepUpDown ), - SKIP( int, sound1SweepStep ), - SKIP( int, sound2On ), - SKIP( int, sound2ATL ), - SKIP( int, sound2Skip ), - SKIP( int, sound2Index ), - SKIP( int, sound2Continue ), - SKIP( int, sound2EnvelopeVolume ), - SKIP( int, sound2EnvelopeATL ), - SKIP( int, sound2EnvelopeATLReload ), - SKIP( int, sound2EnvelopeUpDown ), - SKIP( int, sound3On ), - SKIP( int, sound3ATL ), - SKIP( int, sound3Skip ), - SKIP( int, sound3Index ), - SKIP( int, sound3Continue ), - SKIP( int, sound3OutputLevel ), - SKIP( int, sound4On ), - SKIP( int, sound4ATL ), - SKIP( int, sound4Skip ), - SKIP( int, sound4Index ), - SKIP( int, sound4Clock ), - SKIP( int, sound4ShiftRight ), - SKIP( int, sound4ShiftSkip ), - SKIP( int, sound4ShiftIndex ), - SKIP( int, sound4NSteps ), - SKIP( int, sound4CountDown ), - SKIP( int, sound4Continue ), - SKIP( int, sound4EnvelopeVolume ), - SKIP( int, sound4EnvelopeATL ), - SKIP( int, sound4EnvelopeATLReload ), - SKIP( int, sound4EnvelopeUpDown ), - LOAD( int, soundEnableFlag ), - SKIP( int, soundControl ), - LOAD( int, pcm [0].readIndex ), - LOAD( int, pcm [0].count ), - LOAD( int, pcm [0].writeIndex ), - SKIP( u8, soundDSAEnabled ), // was bool, which was one byte on MS compiler - SKIP( int, soundDSATimer ), - LOAD( u8 [32], pcm [0].fifo ), - LOAD( u8, state.soundDSAValue ), - LOAD( int, pcm [1].readIndex ), - LOAD( int, pcm [1].count ), - LOAD( int, pcm [1].writeIndex ), - SKIP( int, soundDSBEnabled ), - SKIP( int, soundDSBTimer ), - LOAD( u8 [32], pcm [1].fifo ), - LOAD( int, state.soundDSBValue ), +static variable_desc old_gba_state[] = { + SKIP(int, soundPaused), + SKIP(int, soundPlay), + SKIP(int, soundTicks), + SKIP(int, SOUND_CLOCK_TICKS), + SKIP(int, soundLevel1), + SKIP(int, soundLevel2), + SKIP(int, soundBalance), + SKIP(int, soundMasterOn), + SKIP(int, soundIndex), + SKIP(int, sound1On), + SKIP(int, sound1ATL), + SKIP(int, sound1Skip), + SKIP(int, sound1Index), + SKIP(int, sound1Continue), + SKIP(int, sound1EnvelopeVolume), + SKIP(int, sound1EnvelopeATL), + SKIP(int, sound1EnvelopeATLReload), + SKIP(int, sound1EnvelopeUpDown), + SKIP(int, sound1SweepATL), + SKIP(int, sound1SweepATLReload), + SKIP(int, sound1SweepSteps), + SKIP(int, sound1SweepUpDown), + SKIP(int, sound1SweepStep), + SKIP(int, sound2On), + SKIP(int, sound2ATL), + SKIP(int, sound2Skip), + SKIP(int, sound2Index), + SKIP(int, sound2Continue), + SKIP(int, sound2EnvelopeVolume), + SKIP(int, sound2EnvelopeATL), + SKIP(int, sound2EnvelopeATLReload), + SKIP(int, sound2EnvelopeUpDown), + SKIP(int, sound3On), + SKIP(int, sound3ATL), + SKIP(int, sound3Skip), + SKIP(int, sound3Index), + SKIP(int, sound3Continue), + SKIP(int, sound3OutputLevel), + SKIP(int, sound4On), + SKIP(int, sound4ATL), + SKIP(int, sound4Skip), + SKIP(int, sound4Index), + SKIP(int, sound4Clock), + SKIP(int, sound4ShiftRight), + SKIP(int, sound4ShiftSkip), + SKIP(int, sound4ShiftIndex), + SKIP(int, sound4NSteps), + SKIP(int, sound4CountDown), + SKIP(int, sound4Continue), + SKIP(int, sound4EnvelopeVolume), + SKIP(int, sound4EnvelopeATL), + SKIP(int, sound4EnvelopeATLReload), + SKIP(int, sound4EnvelopeUpDown), + LOAD(int, soundEnableFlag), + SKIP(int, soundControl), + LOAD(int, pcm[0].readIndex), + LOAD(int, pcm[0].count), + LOAD(int, pcm[0].writeIndex), + SKIP(u8, soundDSAEnabled), // was bool, which was one byte on MS compiler + SKIP(int, soundDSATimer), + LOAD(u8[32], pcm[0].fifo), + LOAD(u8, state.soundDSAValue), + LOAD(int, pcm[1].readIndex), + LOAD(int, pcm[1].count), + LOAD(int, pcm[1].writeIndex), + SKIP(int, soundDSBEnabled), + SKIP(int, soundDSBTimer), + LOAD(u8[32], pcm[1].fifo), + LOAD(int, state.soundDSBValue), - // skipped manually - //LOAD( int, soundBuffer[0][0], 6*735 }, - //LOAD( int, soundFinalWave[0], 2*735 }, - { NULL, 0 } + // skipped manually + //LOAD( int, soundBuffer[0][0], 6*735 }, + //LOAD( int, soundFinalWave[0], 2*735 }, + { NULL, 0 } }; -variable_desc old_gba_state2 [] = -{ - LOAD( u8 [0x20], state.apu.regs [0x20] ), - SKIP( int, sound3Bank ), - SKIP( int, sound3DataSize ), - SKIP( int, sound3ForcedOutput ), - { NULL, 0 } +variable_desc old_gba_state2[] = { + LOAD(u8[0x20], state.apu.regs[0x20]), + SKIP(int, sound3Bank), + SKIP(int, sound3DataSize), + SKIP(int, sound3ForcedOutput), + { NULL, 0 } }; // New state format -static variable_desc gba_state [] = -{ - // PCM - LOAD( int, pcm [0].readIndex ), - LOAD( int, pcm [0].count ), - LOAD( int, pcm [0].writeIndex ), - LOAD(u8[32],pcm[0].fifo ), - LOAD( int, pcm [0].dac ), +static variable_desc gba_state[] = { + // PCM + LOAD(int, pcm[0].readIndex), + LOAD(int, pcm[0].count), + LOAD(int, pcm[0].writeIndex), + LOAD(u8[32], pcm[0].fifo), + LOAD(int, pcm[0].dac), - SKIP( int [4], room_for_expansion ), + SKIP(int[4], room_for_expansion), - LOAD( int, pcm [1].readIndex ), - LOAD( int, pcm [1].count ), - LOAD( int, pcm [1].writeIndex ), - LOAD(u8[32],pcm[1].fifo ), - LOAD( int, pcm [1].dac ), + LOAD(int, pcm[1].readIndex), + LOAD(int, pcm[1].count), + LOAD(int, pcm[1].writeIndex), + LOAD(u8[32], pcm[1].fifo), + LOAD(int, pcm[1].dac), - SKIP( int [4], room_for_expansion ), + SKIP(int[4], room_for_expansion), - // APU - 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_phase ), // next step frame sequencer will run + // APU + 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_phase), // next step frame sequencer will run - 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_enabled ), - LOAD( int, state.apu.sweep_neg ), // obscure internal flag - LOAD( int, state.apu.noise_divider ), - LOAD( int, state.apu.wave_buf ), // last read byte of wave RAM + 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_enabled), + LOAD(int, state.apu.sweep_neg), // obscure internal flag + LOAD(int, state.apu.noise_divider), + 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.length_ctr ), - 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.delay), // clocks until next channel action + LOAD(int[4], state.apu.length_ctr), + LOAD(int[4], state.apu.phase), // square/wave phase, noise LFSR + 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_volume ), - LOAD( int [3], state.apu.env_enabled ), + 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_enabled), - SKIP( int [13], room_for_expansion ), + SKIP(int[13], room_for_expansion), - // Emulator - LOAD( int, soundEnableFlag ), + // Emulator + LOAD(int, soundEnableFlag), - SKIP( int [15], room_for_expansion ), + SKIP(int[15], room_for_expansion), - { NULL, 0 } + { NULL, 0 } }; - #ifdef __LIBRETRO__ -void soundSaveGame( u8 *&out ) +void soundSaveGame(u8*& out) #else -void soundSaveGame( gzFile out ) +void soundSaveGame(gzFile out) #endif { - gb_apu->save_state( &state.apu ); + gb_apu->save_state(&state.apu); - // Be sure areas for expansion get written as zero - memset( dummy_state, 0, sizeof dummy_state ); + // Be sure areas for expansion get written as zero + memset(dummy_state, 0, sizeof dummy_state); #ifdef __LIBRETRO__ - utilWriteDataMem( out, gba_state ); + utilWriteDataMem(out, gba_state); #else - utilWriteData( out, gba_state ); + utilWriteData(out, gba_state); #endif } #ifndef __LIBRETRO__ // Reads and discards count bytes from in -static void skip_read( gzFile in, int count ) +static void skip_read(gzFile in, int count) { - char buf [512]; + char buf[512]; - while ( count ) - { - int n = sizeof buf; - if ( n > count ) - n = count; + while (count) { + int n = sizeof buf; + if (n > count) + n = count; - count -= n; - utilGzRead( in, buf, n ); - } + count -= n; + utilGzRead(in, buf, n); + } } -static void soundReadGameOld( gzFile in, int version ) +static void soundReadGameOld(gzFile in, int version) { - // Read main data - utilReadData( in, old_gba_state ); - skip_read( in, 6*735 + 2*735 ); + // Read main data + utilReadData(in, old_gba_state); + skip_read(in, 6 * 735 + 2 * 735); - // Copy APU regs - static int const regs_to_copy [] = { - NR10, NR11, NR12, NR13, NR14, - NR21, NR22, NR23, NR24, - NR30, NR31, NR32, NR33, NR34, - NR41, NR42, NR43, NR44, - NR50, NR51, NR52, -1 - }; + // Copy APU regs + static int const regs_to_copy[] = { + NR10, NR11, NR12, NR13, NR14, + NR21, NR22, NR23, NR24, + NR30, NR31, NR32, NR33, NR34, + NR41, NR42, NR43, NR44, + NR50, NR51, NR52, -1 + }; - ioMem [NR52] |= 0x80; // old sound played even when this wasn't set (power on) + ioMem[NR52] |= 0x80; // old sound played even when this wasn't set (power on) - for ( int i = 0; regs_to_copy [i] >= 0; i++ ) - state.apu.regs [gba_to_gb_sound( regs_to_copy [i] ) - 0xFF10] = ioMem [regs_to_copy [i]]; + for (int i = 0; regs_to_copy[i] >= 0; i++) + state.apu.regs[gba_to_gb_sound(regs_to_copy[i]) - 0xFF10] = ioMem[regs_to_copy[i]]; - // Copy wave RAM to both banks - memcpy( &state.apu.regs [0x20], &ioMem [0x90], 0x10 ); - memcpy( &state.apu.regs [0x30], &ioMem [0x90], 0x10 ); + // Copy wave RAM to both banks + memcpy(&state.apu.regs[0x20], &ioMem[0x90], 0x10); + memcpy(&state.apu.regs[0x30], &ioMem[0x90], 0x10); - // Read both banks of wave RAM if available - if ( version >= SAVE_GAME_VERSION_3 ) - utilReadData( in, old_gba_state2 ); + // Read both banks of wave RAM if available + if (version >= SAVE_GAME_VERSION_3) + utilReadData(in, old_gba_state2); - // Restore PCM - pcm [0].dac = state.soundDSAValue; - pcm [1].dac = state.soundDSBValue; + // Restore PCM + pcm[0].dac = state.soundDSAValue; + pcm[1].dac = state.soundDSBValue; - (void) utilReadInt( in ); // ignore quality + (void)utilReadInt(in); // ignore quality } #endif #include #ifdef __LIBRETRO__ -void soundReadGame(const u8*& in, int version ) +void soundReadGame(const u8*& in, int version) #else -void soundReadGame( gzFile in, int version ) +void soundReadGame(gzFile in, int version) #endif { - // Prepare APU and default state - reset_apu(); - gb_apu->save_state( &state.apu ); + // Prepare APU and default state + reset_apu(); + gb_apu->save_state(&state.apu); - if ( version > SAVE_GAME_VERSION_9 ) + if (version > SAVE_GAME_VERSION_9) #ifdef __LIBRETRO__ - utilReadDataMem( in, gba_state ); + utilReadDataMem(in, gba_state); #else - utilReadData( in, gba_state ); - else - soundReadGameOld( in, version ); + utilReadData(in, gba_state); + else + soundReadGameOld(in, version); #endif - gb_apu->load_state( state.apu ); - write_SGCNT0_H( READ16LE( &ioMem [SGCNT0_H] ) & 0x770F ); + gb_apu->load_state(state.apu); + write_SGCNT0_H(READ16LE(&ioMem[SGCNT0_H]) & 0x770F); - apply_muting(); + apply_muting(); } diff --git a/src/gba/Sound.h b/src/gba/Sound.h index e916169e..e8d0bc37 100644 --- a/src/gba/Sound.h +++ b/src/gba/Sound.h @@ -43,7 +43,7 @@ void soundSetSampleRate(long sampleRate); // Sound settings extern bool soundInterpolation; // 1 if PCM should have low-pass filtering -extern float soundFiltering; // 0.0 = none, 1.0 = max +extern float soundFiltering; // 0.0 = none, 1.0 = max //// GBA sound emulation @@ -70,12 +70,12 @@ void interp_rate(); // Notifies emulator that SOUND_CLOCK_TICKS clocks have passed void psoundTickfn(); extern int SOUND_CLOCK_TICKS; // Number of 16.8 MHz clocks between calls to soundTick() -extern int soundTicks; // Number of 16.8 MHz clocks until soundTick() will be called +extern int soundTicks; // Number of 16.8 MHz clocks until soundTick() will be called // Saves/loads emulator state #ifdef __LIBRETRO__ -void soundSaveGame(u8 *&); -void soundReadGame(const u8 *&in, int version); +void soundSaveGame(u8*&); +void soundReadGame(const u8*& in, int version); #else void soundSaveGame(gzFile); void soundReadGame(gzFile, int version); @@ -83,6 +83,6 @@ void soundReadGame(gzFile, int version); class Multi_Buffer; -void flush_samples(Multi_Buffer *buffer); +void flush_samples(Multi_Buffer* buffer); #endif // SOUND_H diff --git a/src/gba/Sram.cpp b/src/gba/Sram.cpp index fa1c301e..7c70e54a 100644 --- a/src/gba/Sram.cpp +++ b/src/gba/Sram.cpp @@ -1,21 +1,21 @@ +#include "Sram.h" +#include "Flash.h" #include "GBA.h" #include "Globals.h" -#include "Flash.h" -#include "Sram.h" u8 sramRead(u32 address) { - return flashSaveMemory[address & 0xFFFF]; + return flashSaveMemory[address & 0xFFFF]; } void sramDelayedWrite(u32 address, u8 byte) { - saveType = 2; - cpuSaveGameFunc = sramWrite; - sramWrite(address, byte); + saveType = 2; + cpuSaveGameFunc = sramWrite; + sramWrite(address, byte); } void sramWrite(u32 address, u8 byte) { - flashSaveMemory[address & 0xFFFF] = byte; - systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED; + flashSaveMemory[address & 0xFFFF] = byte; + systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED; } diff --git a/src/gba/agbprint.cpp b/src/gba/agbprint.cpp index 290eef79..2a98646e 100644 --- a/src/gba/agbprint.cpp +++ b/src/gba/agbprint.cpp @@ -1,80 +1,79 @@ #include #include +#include "../System.h" +#include "../common/Port.h" #include "GBA.h" #include "Globals.h" -#include "../common/Port.h" -#include "../System.h" #define debuggerWriteHalfWord(addr, value) \ - WRITE16LE((u16*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask], (value)) + WRITE16LE((u16*)&map[(addr) >> 24].address[(addr)&map[(addr) >> 24].mask], (value)) #define debuggerReadHalfWord(addr) \ - READ16LE(((u16*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask])) + READ16LE(((u16*)&map[(addr) >> 24].address[(addr)&map[(addr) >> 24].mask])) static bool agbPrintEnabled = false; static bool agbPrintProtect = false; bool agbPrintWrite(u32 address, u16 value) { - if(agbPrintEnabled) { - if(address == 0x9fe2ffe) { // protect - agbPrintProtect = (value != 0); - debuggerWriteHalfWord(address, value); - return true; - } else { - if(agbPrintProtect && - ((address >= 0x9fe20f8 && address <= 0x9fe20ff) // control structure - || (address >= 0x8fd0000 && address <= 0x8fdffff) - || (address >= 0x9fd0000 && address <= 0x9fdffff))) { - debuggerWriteHalfWord(address, value); - return true; - } + if (agbPrintEnabled) { + if (address == 0x9fe2ffe) { // protect + agbPrintProtect = (value != 0); + debuggerWriteHalfWord(address, value); + return true; + } else { + if (agbPrintProtect && ((address >= 0x9fe20f8 && address <= 0x9fe20ff) // control structure + || (address >= 0x8fd0000 && address <= 0x8fdffff) + || (address >= 0x9fd0000 && address <= 0x9fdffff))) { + debuggerWriteHalfWord(address, value); + return true; + } + } } - } - return false; + return false; } void agbPrintReset() { - agbPrintProtect = false; + agbPrintProtect = false; } void agbPrintEnable(bool enable) { - agbPrintEnabled = enable; + agbPrintEnabled = enable; } bool agbPrintIsEnabled() { - return agbPrintEnabled; + return agbPrintEnabled; } void agbPrintFlush() { - u16 get = debuggerReadHalfWord(0x9fe20fc); - u16 put = debuggerReadHalfWord(0x9fe20fe); + u16 get = debuggerReadHalfWord(0x9fe20fc); + u16 put = debuggerReadHalfWord(0x9fe20fe); - u32 address = (debuggerReadHalfWord(0x9fe20fa) << 16); - if(address != 0xfd0000 && address != 0x1fd0000) { - dbgOutput("Did you forget to call AGBPrintInit?\n", 0); - // get rid of the text otherwise we will continue to be called - debuggerWriteHalfWord(0x9fe20fc, put); - return; - } + u32 address = (debuggerReadHalfWord(0x9fe20fa) << 16); + if (address != 0xfd0000 && address != 0x1fd0000) { + dbgOutput("Did you forget to call AGBPrintInit?\n", 0); + // get rid of the text otherwise we will continue to be called + debuggerWriteHalfWord(0x9fe20fc, put); + return; + } - u8 *data = &rom[address]; + u8* data = &rom[address]; - while(get != put) { - char c = data[get++]; - char s[2]; - s[0] = c; - s[1] = 0; + while (get != put) { + char c = data[get++]; + char s[2]; + s[0] = c; + s[1] = 0; - if(systemVerbose & VERBOSE_AGBPRINT) - dbgOutput(s, 0); - if(c == '\n') - break; - } - debuggerWriteHalfWord(0x9fe20fc, get); + if (systemVerbose & VERBOSE_AGBPRINT) + dbgOutput(s, 0); + if (c == '\n') + break; + } + debuggerWriteHalfWord(0x9fe20fc, get); } diff --git a/src/gba/armdis.cpp b/src/gba/armdis.cpp index a40ed0e4..66781893 100644 --- a/src/gba/armdis.cpp +++ b/src/gba/armdis.cpp @@ -10,715 +10,702 @@ #include "elf.h" struct Opcodes { - u32 mask; - u32 cval; - const char *mnemonic; + u32 mask; + u32 cval; + const char* mnemonic; }; #define debuggerReadMemory(addr) \ - READ32LE(((u32*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask])) + READ32LE(((u32*)&map[(addr) >> 24].address[(addr)&map[(addr) >> 24].mask])) #define debuggerReadHalfWord(addr) \ - READ16LE(((u16*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask])) + READ16LE(((u16*)&map[(addr) >> 24].address[(addr)&map[(addr) >> 24].mask])) #define debuggerReadByte(addr) \ - map[(addr)>>24].address[(addr) & map[(addr)>>24].mask] + map[(addr) >> 24].address[(addr)&map[(addr) >> 24].mask] const char hdig[] = "0123456789abcdef"; -const char *decVals[16] = { - "0","1","2","3","4","5","6","7","8", - "9","10","11","12","13","14","15" +const char* decVals[16] = { + "0", "1", "2", "3", "4", "5", "6", "7", "8", + "9", "10", "11", "12", "13", "14", "15" }; -const char *regs[16] = { - "r0","r1","r2","r3","r4","r5","r6","r7", - "r8","r9","r10","r11","r12","sp","lr","pc" +const char* regs[16] = { + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc" }; -const char *conditions[16] = { - "eq","ne","cs","cc","mi","pl","vs","vc", - "hi","ls","ge","lt","gt","le","","nv" +const char* conditions[16] = { + "eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc", + "hi", "ls", "ge", "lt", "gt", "le", "", "nv" }; -const char *shifts[5] = { - "lsl","lsr","asr","ror","rrx" +const char* shifts[5] = { + "lsl", "lsr", "asr", "ror", "rrx" }; -const char *armMultLoadStore[12] = { - // non-stack - "da","ia","db","ib", - // stack store - "ed","ea","fd","fa", - // stack load - "fa","fd","ea","ed" +const char* armMultLoadStore[12] = { + // non-stack + "da", "ia", "db", "ib", + // stack store + "ed", "ea", "fd", "fa", + // stack load + "fa", "fd", "ea", "ed" }; const Opcodes thumbOpcodes[] = { - // Format 1 - {0xf800, 0x0000, "lsl %r0, %r3, %o"}, - {0xf800, 0x0800, "lsr %r0, %r3, %o"}, - {0xf800, 0x1000, "asr %r0, %r3, %o"}, - // Format 2 - {0xfe00, 0x1800, "add %r0, %r3, %r6"}, - {0xfe00, 0x1a00, "sub %r0, %r3, %r6"}, - {0xfe00, 0x1c00, "add %r0, %r3, %i"}, - {0xfe00, 0x1e00, "sub %r0, %r3, %i"}, - // Format 3 - {0xf800, 0x2000, "mov %r8, %O"}, - {0xf800, 0x2800, "cmp %r8, %O"}, - {0xf800, 0x3000, "add %r8, %O"}, - {0xf800, 0x3800, "sub %r8, %O"}, - // Format 4 - {0xffc0, 0x4000, "and %r0, %r3"}, - {0xffc0, 0x4040, "eor %r0, %r3"}, - {0xffc0, 0x4080, "lsl %r0, %r3"}, - {0xffc0, 0x40c0, "lsr %r0, %r3"}, - {0xffc0, 0x4100, "asr %r0, %r3"}, - {0xffc0, 0x4140, "adc %r0, %r3"}, - {0xffc0, 0x4180, "sbc %r0, %r3"}, - {0xffc0, 0x41c0, "ror %r0, %r3"}, - {0xffc0, 0x4200, "tst %r0, %r3"}, - {0xffc0, 0x4240, "neg %r0, %r3"}, - {0xffc0, 0x4280, "cmp %r0, %r3"}, - {0xffc0, 0x42c0, "cmn %r0, %r3"}, - {0xffc0, 0x4300, "orr %r0, %r3"}, - {0xffc0, 0x4340, "mul %r0, %r3"}, - {0xffc0, 0x4380, "bic %r0, %r3"}, - {0xffc0, 0x43c0, "mvn %r0, %r3"}, - // Format 5 - {0xff80, 0x4700, "bx %h36"}, - {0xfcc0, 0x4400, "[ ??? ]"}, - {0xff00, 0x4400, "add %h07, %h36"}, - {0xff00, 0x4500, "cmp %h07, %h36"}, - {0xff00, 0x4600, "mov %h07, %h36"}, - // Format 6 - {0xf800, 0x4800, "ldr %r8, [%I] (=%J)"}, - // Format 7 - {0xfa00, 0x5000, "str%b %r0, [%r3, %r6]"}, - {0xfa00, 0x5800, "ldr%b %r0, [%r3, %r6]"}, - // Format 8 - {0xfe00, 0x5200, "strh %r0, [%r3, %r6]"}, - {0xfe00, 0x5600, "ldsb %r0, [%r3, %r6]"}, - {0xfe00, 0x5a00, "ldrh %r0, [%r3, %r6]"}, - {0xfe00, 0x5e00, "ldsh %r0, [%r3, %r6]"}, - // Format 9 - {0xe800, 0x6000, "str%B %r0, [%r3, %p]"}, - {0xe800, 0x6800, "ldr%B %r0, [%r3, %p]"}, - // Format 10 - {0xf800, 0x8000, "strh %r0, [%r3, %e]"}, - {0xf800, 0x8800, "ldrh %r0, [%r3, %e]"}, - // Format 11 - {0xf800, 0x9000, "str %r8, [sp, %w]"}, - {0xf800, 0x9800, "ldr %r8, [sp, %w]"}, - // Format 12 - {0xf800, 0xa000, "add %r8, pc, %w (=%K)"}, - {0xf800, 0xa800, "add %r8, sp, %w"}, - // Format 13 - {0xff00, 0xb000, "add sp, %s"}, - // Format 14 - {0xffff, 0xb500, "push {lr}"}, - {0xff00, 0xb400, "push {%l}"}, - {0xff00, 0xb500, "push {%l,lr}"}, - {0xffff, 0xbd00, "pop {pc}"}, - {0xff00, 0xbd00, "pop {%l,pc}"}, - {0xff00, 0xbc00, "pop {%l}"}, - // Format 15 - {0xf800, 0xc000, "stmia %r8!, {%l}"}, - {0xf800, 0xc800, "ldmia %r8!, {%l}"}, - // Format 17 - {0xff00, 0xdf00, "swi %m"}, - // Format 16 - {0xf000, 0xd000, "b%c %W"}, - // Format 18 - {0xf800, 0xe000, "b %a"}, - // Format 19 - {0xf800, 0xf000, "bl %A"}, - {0xf800, 0xf800, "blh %Z"}, - {0xff00, 0xbe00, "bkpt %O"}, - // Unknown - {0x0000, 0x0000, "[ ??? ]"} + // Format 1 + { 0xf800, 0x0000, "lsl %r0, %r3, %o" }, + { 0xf800, 0x0800, "lsr %r0, %r3, %o" }, + { 0xf800, 0x1000, "asr %r0, %r3, %o" }, + // Format 2 + { 0xfe00, 0x1800, "add %r0, %r3, %r6" }, + { 0xfe00, 0x1a00, "sub %r0, %r3, %r6" }, + { 0xfe00, 0x1c00, "add %r0, %r3, %i" }, + { 0xfe00, 0x1e00, "sub %r0, %r3, %i" }, + // Format 3 + { 0xf800, 0x2000, "mov %r8, %O" }, + { 0xf800, 0x2800, "cmp %r8, %O" }, + { 0xf800, 0x3000, "add %r8, %O" }, + { 0xf800, 0x3800, "sub %r8, %O" }, + // Format 4 + { 0xffc0, 0x4000, "and %r0, %r3" }, + { 0xffc0, 0x4040, "eor %r0, %r3" }, + { 0xffc0, 0x4080, "lsl %r0, %r3" }, + { 0xffc0, 0x40c0, "lsr %r0, %r3" }, + { 0xffc0, 0x4100, "asr %r0, %r3" }, + { 0xffc0, 0x4140, "adc %r0, %r3" }, + { 0xffc0, 0x4180, "sbc %r0, %r3" }, + { 0xffc0, 0x41c0, "ror %r0, %r3" }, + { 0xffc0, 0x4200, "tst %r0, %r3" }, + { 0xffc0, 0x4240, "neg %r0, %r3" }, + { 0xffc0, 0x4280, "cmp %r0, %r3" }, + { 0xffc0, 0x42c0, "cmn %r0, %r3" }, + { 0xffc0, 0x4300, "orr %r0, %r3" }, + { 0xffc0, 0x4340, "mul %r0, %r3" }, + { 0xffc0, 0x4380, "bic %r0, %r3" }, + { 0xffc0, 0x43c0, "mvn %r0, %r3" }, + // Format 5 + { 0xff80, 0x4700, "bx %h36" }, + { 0xfcc0, 0x4400, "[ ??? ]" }, + { 0xff00, 0x4400, "add %h07, %h36" }, + { 0xff00, 0x4500, "cmp %h07, %h36" }, + { 0xff00, 0x4600, "mov %h07, %h36" }, + // Format 6 + { 0xf800, 0x4800, "ldr %r8, [%I] (=%J)" }, + // Format 7 + { 0xfa00, 0x5000, "str%b %r0, [%r3, %r6]" }, + { 0xfa00, 0x5800, "ldr%b %r0, [%r3, %r6]" }, + // Format 8 + { 0xfe00, 0x5200, "strh %r0, [%r3, %r6]" }, + { 0xfe00, 0x5600, "ldsb %r0, [%r3, %r6]" }, + { 0xfe00, 0x5a00, "ldrh %r0, [%r3, %r6]" }, + { 0xfe00, 0x5e00, "ldsh %r0, [%r3, %r6]" }, + // Format 9 + { 0xe800, 0x6000, "str%B %r0, [%r3, %p]" }, + { 0xe800, 0x6800, "ldr%B %r0, [%r3, %p]" }, + // Format 10 + { 0xf800, 0x8000, "strh %r0, [%r3, %e]" }, + { 0xf800, 0x8800, "ldrh %r0, [%r3, %e]" }, + // Format 11 + { 0xf800, 0x9000, "str %r8, [sp, %w]" }, + { 0xf800, 0x9800, "ldr %r8, [sp, %w]" }, + // Format 12 + { 0xf800, 0xa000, "add %r8, pc, %w (=%K)" }, + { 0xf800, 0xa800, "add %r8, sp, %w" }, + // Format 13 + { 0xff00, 0xb000, "add sp, %s" }, + // Format 14 + { 0xffff, 0xb500, "push {lr}" }, + { 0xff00, 0xb400, "push {%l}" }, + { 0xff00, 0xb500, "push {%l,lr}" }, + { 0xffff, 0xbd00, "pop {pc}" }, + { 0xff00, 0xbd00, "pop {%l,pc}" }, + { 0xff00, 0xbc00, "pop {%l}" }, + // Format 15 + { 0xf800, 0xc000, "stmia %r8!, {%l}" }, + { 0xf800, 0xc800, "ldmia %r8!, {%l}" }, + // Format 17 + { 0xff00, 0xdf00, "swi %m" }, + // Format 16 + { 0xf000, 0xd000, "b%c %W" }, + // Format 18 + { 0xf800, 0xe000, "b %a" }, + // Format 19 + { 0xf800, 0xf000, "bl %A" }, + { 0xf800, 0xf800, "blh %Z" }, + { 0xff00, 0xbe00, "bkpt %O" }, + // Unknown + { 0x0000, 0x0000, "[ ??? ]" } }; const Opcodes armOpcodes[] = { - // Undefined - {0x0e000010, 0x06000010, "[ undefined ]"}, - // Branch instructions - {0x0ff000f0, 0x01200010, "bx%c %r0"}, - {0x0f000000, 0x0a000000, "b%c %o"}, - {0x0f000000, 0x0b000000, "bl%c %o"}, - {0x0f000000, 0x0f000000, "swi%c %q"}, - // PSR transfer - {0x0fbf0fff, 0x010f0000, "mrs%c %r3, %p"}, - {0x0db0f000, 0x0120f000, "msr%c %p, %i"}, - // Multiply instructions - {0x0fe000f0, 0x00000090, "mul%c%s %r4, %r0, %r2"}, - {0x0fe000f0, 0x00200090, "mla%c%s %r4, %r0, %r2, %r3"}, - {0x0fa000f0, 0x00800090, "%umull%c%s %r3, %r4, %r0, %r2"}, - {0x0fa000f0, 0x00a00090, "%umlal%c%s %r3, %r4, %r0, %r2"}, - // Load/Store instructions - {0x0fb00ff0, 0x01000090, "swp%c%b %r3, %r0, [%r4]"}, - {0x0fb000f0, 0x01000090, "[ ??? ]"}, - {0x0c100000, 0x04000000, "str%c%b%t %r3, %a"}, - {0x0c100000, 0x04100000, "ldr%c%b%t %r3, %a"}, - {0x0e100090, 0x00000090, "str%c%h %r3, %a"}, - {0x0e100090, 0x00100090, "ldr%c%h %r3, %a"}, - {0x0e100000, 0x08000000, "stm%c%m %r4%l"}, - {0x0e100000, 0x08100000, "ldm%c%m %r4%l"}, - // Data processing - {0x0de00000, 0x00000000, "and%c%s %r3, %r4, %i"}, - {0x0de00000, 0x00200000, "eor%c%s %r3, %r4, %i"}, - {0x0de00000, 0x00400000, "sub%c%s %r3, %r4, %i"}, - {0x0de00000, 0x00600000, "rsb%c%s %r3, %r4, %i"}, - {0x0de00000, 0x00800000, "add%c%s %r3, %r4, %i"}, - {0x0de00000, 0x00a00000, "adc%c%s %r3, %r4, %i"}, - {0x0de00000, 0x00c00000, "sbc%c%s %r3, %r4, %i"}, - {0x0de00000, 0x00e00000, "rsc%c%s %r3, %r4, %i"}, - {0x0de00000, 0x01000000, "tst%c%s %r4, %i"}, - {0x0de00000, 0x01200000, "teq%c%s %r4, %i"}, - {0x0de00000, 0x01400000, "cmp%c%s %r4, %i"}, - {0x0de00000, 0x01600000, "cmn%c%s %r4, %i"}, - {0x0de00000, 0x01800000, "orr%c%s %r3, %r4, %i"}, - {0x0de00000, 0x01a00000, "mov%c%s %r3, %i"}, - {0x0de00000, 0x01c00000, "bic%c%s %r3, %r4, %i"}, - {0x0de00000, 0x01e00000, "mvn%c%s %r3, %i"}, - // Coprocessor operations - {0x0f000010, 0x0e000000, "cdp%c %P, %N, %r3, %R4, %R0%V"}, - {0x0e100000, 0x0c000000, "stc%c%L %P, %r3, %A"}, - {0x0f100010, 0x0e000010, "mcr%c %P, %N, %r3, %R4, %R0%V"}, - {0x0f100010, 0x0e100010, "mrc%c %P, %N, %r3, %R4, %R0%V"}, - // Unknown - {0x00000000, 0x00000000, "[ ??? ]"} + // Undefined + { 0x0e000010, 0x06000010, "[ undefined ]" }, + // Branch instructions + { 0x0ff000f0, 0x01200010, "bx%c %r0" }, + { 0x0f000000, 0x0a000000, "b%c %o" }, + { 0x0f000000, 0x0b000000, "bl%c %o" }, + { 0x0f000000, 0x0f000000, "swi%c %q" }, + // PSR transfer + { 0x0fbf0fff, 0x010f0000, "mrs%c %r3, %p" }, + { 0x0db0f000, 0x0120f000, "msr%c %p, %i" }, + // Multiply instructions + { 0x0fe000f0, 0x00000090, "mul%c%s %r4, %r0, %r2" }, + { 0x0fe000f0, 0x00200090, "mla%c%s %r4, %r0, %r2, %r3" }, + { 0x0fa000f0, 0x00800090, "%umull%c%s %r3, %r4, %r0, %r2" }, + { 0x0fa000f0, 0x00a00090, "%umlal%c%s %r3, %r4, %r0, %r2" }, + // Load/Store instructions + { 0x0fb00ff0, 0x01000090, "swp%c%b %r3, %r0, [%r4]" }, + { 0x0fb000f0, 0x01000090, "[ ??? ]" }, + { 0x0c100000, 0x04000000, "str%c%b%t %r3, %a" }, + { 0x0c100000, 0x04100000, "ldr%c%b%t %r3, %a" }, + { 0x0e100090, 0x00000090, "str%c%h %r3, %a" }, + { 0x0e100090, 0x00100090, "ldr%c%h %r3, %a" }, + { 0x0e100000, 0x08000000, "stm%c%m %r4%l" }, + { 0x0e100000, 0x08100000, "ldm%c%m %r4%l" }, + // Data processing + { 0x0de00000, 0x00000000, "and%c%s %r3, %r4, %i" }, + { 0x0de00000, 0x00200000, "eor%c%s %r3, %r4, %i" }, + { 0x0de00000, 0x00400000, "sub%c%s %r3, %r4, %i" }, + { 0x0de00000, 0x00600000, "rsb%c%s %r3, %r4, %i" }, + { 0x0de00000, 0x00800000, "add%c%s %r3, %r4, %i" }, + { 0x0de00000, 0x00a00000, "adc%c%s %r3, %r4, %i" }, + { 0x0de00000, 0x00c00000, "sbc%c%s %r3, %r4, %i" }, + { 0x0de00000, 0x00e00000, "rsc%c%s %r3, %r4, %i" }, + { 0x0de00000, 0x01000000, "tst%c%s %r4, %i" }, + { 0x0de00000, 0x01200000, "teq%c%s %r4, %i" }, + { 0x0de00000, 0x01400000, "cmp%c%s %r4, %i" }, + { 0x0de00000, 0x01600000, "cmn%c%s %r4, %i" }, + { 0x0de00000, 0x01800000, "orr%c%s %r3, %r4, %i" }, + { 0x0de00000, 0x01a00000, "mov%c%s %r3, %i" }, + { 0x0de00000, 0x01c00000, "bic%c%s %r3, %r4, %i" }, + { 0x0de00000, 0x01e00000, "mvn%c%s %r3, %i" }, + // Coprocessor operations + { 0x0f000010, 0x0e000000, "cdp%c %P, %N, %r3, %R4, %R0%V" }, + { 0x0e100000, 0x0c000000, "stc%c%L %P, %r3, %A" }, + { 0x0f100010, 0x0e000010, "mcr%c %P, %N, %r3, %R4, %R0%V" }, + { 0x0f100010, 0x0e100010, "mrc%c %P, %N, %r3, %R4, %R0%V" }, + // Unknown + { 0x00000000, 0x00000000, "[ ??? ]" } }; -char* addStr(char *dest, const char *src){ - while (*src){ - *dest++ = *src++; - } - return dest; +char* addStr(char* dest, const char* src) +{ + while (*src) { + *dest++ = *src++; + } + return dest; } -char* addHex(char *dest, int siz, u32 val){ - if (siz==0){ - siz = 28; - while ( (((val>>siz)&15)==0) && (siz>=4) ) - siz -= 4; - siz += 4; - } - while (siz>0){ - siz -= 4; - *dest++ = hdig[(val>>siz)&15]; - } - return dest; +char* addHex(char* dest, int siz, u32 val) +{ + if (siz == 0) { + siz = 28; + while ((((val >> siz) & 15) == 0) && (siz >= 4)) + siz -= 4; + siz += 4; + } + while (siz > 0) { + siz -= 4; + *dest++ = hdig[(val >> siz) & 15]; + } + return dest; } -int disArm(u32 offset, char *dest, int flags){ - u32 opcode = debuggerReadMemory(offset); +int disArm(u32 offset, char* dest, int flags) +{ + u32 opcode = debuggerReadMemory(offset); - const Opcodes *sp = armOpcodes; - while( sp->cval != (opcode & sp->mask) ) - sp++; + const Opcodes* sp = armOpcodes; + while (sp->cval != (opcode & sp->mask)) + sp++; - if (flags&DIS_VIEW_ADDRESS){ - dest = addHex(dest, 32, offset); - *dest++ = ' '; - } - if (flags&DIS_VIEW_CODE){ - dest = addHex(dest, 32, opcode); - *dest++ = ' '; - } + if (flags & DIS_VIEW_ADDRESS) { + dest = addHex(dest, 32, offset); + *dest++ = ' '; + } + if (flags & DIS_VIEW_CODE) { + dest = addHex(dest, 32, opcode); + *dest++ = ' '; + } - const char *src = sp->mnemonic; - while (*src){ - if (*src!='%') - *dest++ = *src++; - else{ - src++; - switch (*src){ - case 'c': - dest = addStr(dest, conditions[opcode>>28]); - break; - case 'r': - dest = addStr(dest, regs[(opcode>>((*(++src)-'0')*4))&15]); - break; - case 'o': - { - *dest++ = '$'; - int off = opcode&0xffffff; - if (off&0x800000) - off |= 0xff000000; - off <<= 2; - dest = addHex(dest, 32, offset+8+off); - } - break; - case 'i': - if (opcode&(1<<25)){ - dest = addStr(dest, "#0x"); - int imm = opcode&0xff; - int rot = (opcode&0xf00)>>7; - int val = (imm<<(32-rot))|(imm>>rot); - dest = addHex(dest, 0, val); - } else{ - dest = addStr(dest, regs[opcode&0x0f]); - int shi = (opcode>>5)&3; - int sdw = (opcode>>7)&0x1f; - if ((sdw==0)&&(shi==3)) - shi = 4; - if ( (sdw) || (opcode&0x10) || (shi)) { - dest = addStr(dest, ", "); - dest = addStr(dest, shifts[shi]); - if (opcode&0x10){ - *dest++ = ' '; - dest = addStr(dest, regs[(opcode>>8)&15]); - } else { - if (sdw==0 && ( (shi==1) || (shi==2) )) - sdw = 32; - if(shi != 4) { - dest = addStr(dest, " #0x"); - dest = addHex(dest, 8, sdw); - } - } - } - } - break; - case 'p': - if (opcode&(1<<22)) - dest = addStr(dest, "spsr"); - else - dest = addStr(dest, "cpsr"); - if(opcode & 0x00F00000) { - *dest++ = '_'; - if(opcode & 0x00080000) - *dest++ = 'f'; - if(opcode & 0x00040000) - *dest++ = 's'; - if(opcode & 0x00020000) - *dest++ = 'x'; - if(opcode & 0x00010000) - *dest++ = 'c'; - } - break; - case 's': - if (opcode&(1<<20)) - *dest++ = 's'; - break; - case 'S': - if (opcode&(1<<22)) - *dest++ = 's'; - break; - case 'u': - if (opcode&(1<<22)) - *dest++ = 's'; - else - *dest++ = 'u'; - break; - case 'b': - if (opcode&(1<<22)) - *dest++ = 'b'; - break; - case 'a': - if ((opcode&0x076f0000)==0x004f0000){ - *dest++ = '['; - *dest++ = '$'; - int adr = offset+8; - int add = (opcode&15)|((opcode>>8)&0xf0); - if (opcode&(1<<23)) - adr += add; - else - adr -= add; - dest = addHex(dest, 32, adr); - *dest++ = ']'; - dest = addStr(dest, " (="); - *dest++ = '$'; - dest = addHex(dest ,32, debuggerReadMemory(adr)); - *dest++=')'; - } - if ((opcode&0x072f0000)==0x050f0000){ - *dest++ = '['; - *dest++ = '$'; - int adr = offset+8; - if (opcode&(1<<23)) - adr += opcode&0xfff; - else - adr -= opcode&0xfff; - dest = addHex(dest, 32, adr); - *dest++ = ']'; - dest = addStr(dest, " (="); - *dest++ = '$'; - dest = addHex(dest ,32, debuggerReadMemory(adr)); - *dest++=')'; - } else { - int reg = (opcode>>16)&15; - *dest++ = '['; - dest = addStr(dest, regs[reg]); - if (!(opcode&(1<<24))) - *dest++ = ']'; - if ( ((opcode&(1<<25))&&(opcode&(1<<26))) || (!(opcode&(1<<22))&&!(opcode&(1<<26))) ){ - dest = addStr(dest, ", "); - if (!(opcode&(1<<23))) - *dest++ = '-'; - dest = addStr(dest, regs[opcode&0x0f]); - int shi = (opcode>>5)&3; - if (opcode&(1<<26)){ - if ( ((opcode>>7)&0x1f) || (opcode&0x10) || (shi==1) || (shi==2)){ - dest = addStr(dest, ", "); - dest = addStr(dest, shifts[shi]); - if (opcode&0x10){ - *dest++ = ' '; - dest = addStr(dest, regs[(opcode>>8)&15]); + const char* src = sp->mnemonic; + while (*src) { + if (*src != '%') + *dest++ = *src++; + else { + src++; + switch (*src) { + case 'c': + dest = addStr(dest, conditions[opcode >> 28]); + break; + case 'r': + dest = addStr(dest, regs[(opcode >> ((*(++src) - '0') * 4)) & 15]); + break; + case 'o': { + *dest++ = '$'; + int off = opcode & 0xffffff; + if (off & 0x800000) + off |= 0xff000000; + off <<= 2; + dest = addHex(dest, 32, offset + 8 + off); + } break; + case 'i': + if (opcode & (1 << 25)) { + dest = addStr(dest, "#0x"); + int imm = opcode & 0xff; + int rot = (opcode & 0xf00) >> 7; + int val = (imm << (32 - rot)) | (imm >> rot); + dest = addHex(dest, 0, val); } else { - int sdw = (opcode>>7)&0x1f; - if (sdw==0 && ( (shi==1) || (shi==2) )) - sdw = 32; - dest = addStr(dest, " #0x"); - dest = addHex(dest, 8, sdw); + dest = addStr(dest, regs[opcode & 0x0f]); + int shi = (opcode >> 5) & 3; + int sdw = (opcode >> 7) & 0x1f; + if ((sdw == 0) && (shi == 3)) + shi = 4; + if ((sdw) || (opcode & 0x10) || (shi)) { + dest = addStr(dest, ", "); + dest = addStr(dest, shifts[shi]); + if (opcode & 0x10) { + *dest++ = ' '; + dest = addStr(dest, regs[(opcode >> 8) & 15]); + } else { + if (sdw == 0 && ((shi == 1) || (shi == 2))) + sdw = 32; + if (shi != 4) { + dest = addStr(dest, " #0x"); + dest = addHex(dest, 8, sdw); + } + } + } } - } - } - } else { - int off; - if (opcode&(1<<26)) - off = opcode&0xfff; - else - off = (opcode&15)|((opcode>>4)&0xf0); - if (off){ - dest = addStr(dest, ", "); - if (!(opcode&(1<<23))) - *dest++ = '-'; - dest = addStr(dest, "#0x"); - dest = addHex(dest, 0, off); - } - } - if (opcode&(1<<24)){ - *dest++ = ']'; - if (opcode&(1<<21)) - *dest++ = '!'; - } - } - break; - case 't': - if ((opcode&0x01200000)==0x01200000) - *dest++ = 't'; - break; - case 'h': - if (opcode&(1<<6)) - *dest++ = 's'; - if (opcode&(1<<5)) - *dest++ = 'h'; - else - *dest++ = 'b'; - break; - case 'm': - if (((opcode>>16)&15)==13) { - if(opcode & 0x00100000) - dest = addStr(dest, armMultLoadStore[8+((opcode>>23)&3)]); - else - dest = addStr(dest, armMultLoadStore[4+((opcode>>23)&3)]); - } else - dest = addStr(dest, armMultLoadStore[(opcode>>23)&3]); - break; - case 'l': - if (opcode&(1<<21)) - *dest++ = '!'; - dest = addStr(dest, ", {"); - { - int rlst = opcode&0xffff; - int msk = 0; - int not_first = 0; - while (msk<16){ - if (rlst&(1<> 8) & 0xf0); + if (opcode & (1 << 23)) + adr += add; + else + adr -= add; + dest = addHex(dest, 32, adr); + *dest++ = ']'; + dest = addStr(dest, " (="); + *dest++ = '$'; + dest = addHex(dest, 32, debuggerReadMemory(adr)); + *dest++ = ')'; + } + if ((opcode & 0x072f0000) == 0x050f0000) { + *dest++ = '['; + *dest++ = '$'; + int adr = offset + 8; + if (opcode & (1 << 23)) + adr += opcode & 0xfff; + else + adr -= opcode & 0xfff; + dest = addHex(dest, 32, adr); + *dest++ = ']'; + dest = addStr(dest, " (="); + *dest++ = '$'; + dest = addHex(dest, 32, debuggerReadMemory(adr)); + *dest++ = ')'; + } else { + int reg = (opcode >> 16) & 15; + *dest++ = '['; + dest = addStr(dest, regs[reg]); + if (!(opcode & (1 << 24))) + *dest++ = ']'; + if (((opcode & (1 << 25)) && (opcode & (1 << 26))) || (!(opcode & (1 << 22)) && !(opcode & (1 << 26)))) { + dest = addStr(dest, ", "); + if (!(opcode & (1 << 23))) + *dest++ = '-'; + dest = addStr(dest, regs[opcode & 0x0f]); + int shi = (opcode >> 5) & 3; + if (opcode & (1 << 26)) { + if (((opcode >> 7) & 0x1f) || (opcode & 0x10) || (shi == 1) || (shi == 2)) { + dest = addStr(dest, ", "); + dest = addStr(dest, shifts[shi]); + if (opcode & 0x10) { + *dest++ = ' '; + dest = addStr(dest, regs[(opcode >> 8) & 15]); + } else { + int sdw = (opcode >> 7) & 0x1f; + if (sdw == 0 && ((shi == 1) || (shi == 2))) + sdw = 32; + dest = addStr(dest, " #0x"); + dest = addHex(dest, 8, sdw); + } + } + } + } else { + int off; + if (opcode & (1 << 26)) + off = opcode & 0xfff; + else + off = (opcode & 15) | ((opcode >> 4) & 0xf0); + if (off) { + dest = addStr(dest, ", "); + if (!(opcode & (1 << 23))) + *dest++ = '-'; + dest = addStr(dest, "#0x"); + dest = addHex(dest, 0, off); + } + } + if (opcode & (1 << 24)) { + *dest++ = ']'; + if (opcode & (1 << 21)) + *dest++ = '!'; + } + } + break; + case 't': + if ((opcode & 0x01200000) == 0x01200000) + *dest++ = 't'; + break; + case 'h': + if (opcode & (1 << 6)) + *dest++ = 's'; + if (opcode & (1 << 5)) + *dest++ = 'h'; + else + *dest++ = 'b'; + break; + case 'm': + if (((opcode >> 16) & 15) == 13) { + if (opcode & 0x00100000) + dest = addStr(dest, armMultLoadStore[8 + ((opcode >> 23) & 3)]); + else + dest = addStr(dest, armMultLoadStore[4 + ((opcode >> 23) & 3)]); + } else + dest = addStr(dest, armMultLoadStore[(opcode >> 23) & 3]); + break; + case 'l': + if (opcode & (1 << 21)) + *dest++ = '!'; + dest = addStr(dest, ", {"); + { + int rlst = opcode & 0xffff; + int msk = 0; + int not_first = 0; + while (msk < 16) { + if (rlst & (1 << msk)) { + int fr = msk; + while (rlst & (1 << msk)) + msk++; + int to = msk - 1; + if (not_first) + //dest = addStr(dest, ", "); + *dest++ = ','; + dest = addStr(dest, regs[fr]); + if (fr != to) { + if (fr == to - 1) + //dest = addStr(", "); + *dest++ = ','; + else + *dest++ = '-'; + dest = addStr(dest, regs[to]); + } + not_first = 1; + } else + msk++; + } + *dest++ = '}'; + if (opcode & (1 << 22)) + *dest++ = '^'; + } + break; + case 'q': + *dest++ = '$'; + dest = addHex(dest, 24, opcode & 0xffffff); + break; + case 'P': + *dest++ = 'p'; + dest = addStr(dest, decVals[(opcode >> 8) & 15]); + break; + case 'N': + if (opcode & 0x10) + dest = addStr(dest, decVals[(opcode >> 21) & 7]); + else + dest = addStr(dest, decVals[(opcode >> 20) & 15]); + break; + case 'R': { + src++; + int reg = 4 * (*src - '0'); + *dest++ = 'c'; + dest = addStr(dest, decVals[(opcode >> reg) & 15]); + } break; + case 'V': { + int val = (opcode >> 5) & 7; + if (val) { + dest = addStr(dest, ", "); + dest = addStr(dest, decVals[val]); + } + } break; + case 'L': + if (opcode & (1 << 22)) + *dest++ = 'l'; + break; + case 'A': + if ((opcode & 0x012f0000) == 0x010f0000) { + int adr = offset + 8; + int add = (opcode & 0xff) << 2; + if (opcode & (1 << 23)) + adr += add; + else + adr -= add; + *dest++ = '$'; + addHex(dest, 32, adr); + } else { + *dest++ = '['; + dest = addStr(dest, regs[(opcode >> 16) & 15]); + if (!(opcode & (1 << 24))) + *dest++ = ']'; + int off = (opcode & 0xff) << 2; + if (off) { + dest = addStr(dest, ", "); + if (!(opcode & (1 << 23))) + *dest++ = '-'; + dest = addStr(dest, "#0x"); + dest = addHex(dest, 0, off); + } + if (opcode & (1 << 24)) { + *dest++ = ']'; + if (opcode & (1 << 21)) + *dest++ = '!'; + } + } + break; + } + src++; } - break; - case 'q': - *dest++ = '$'; - dest = addHex(dest, 24, opcode&0xffffff); - break; - case 'P': - *dest++ = 'p'; - dest = addStr(dest, decVals[(opcode>>8)&15]); - break; - case 'N': - if (opcode&0x10) - dest = addStr(dest, decVals[(opcode>>21)&7]); - else - dest = addStr(dest, decVals[(opcode>>20)&15]); - break; - case 'R': - { - src++; - int reg = 4*(*src-'0'); - *dest++ = 'c'; - dest = addStr(dest, decVals[(opcode>>reg)&15]); - } - break; - case 'V': - { - int val = (opcode>>5)&7; - if (val){ - dest = addStr(dest, ", "); - dest = addStr(dest, decVals[val]); - } - } - break; - case 'L': - if (opcode&(1<<22)) - *dest++ = 'l'; - break; - case 'A': - if ((opcode&0x012f0000)==0x010f0000){ - int adr = offset+8; - int add = (opcode&0xff)<<2; - if (opcode&(1<<23)) - adr += add; - else - adr -= add; - *dest++ = '$'; - addHex(dest, 32, adr); - } else { - *dest++ = '['; - dest = addStr(dest, regs[(opcode>>16)&15]); - if (!(opcode&(1<<24))) - *dest++ = ']'; - int off = (opcode&0xff)<<2; - if (off){ - dest = addStr(dest, ", "); - if (!(opcode&(1<<23))) - *dest++ = '-'; - dest = addStr(dest, "#0x"); - dest = addHex(dest, 0, off); - } - if (opcode&(1<<24)){ - *dest++ = ']'; - if (opcode&(1<<21)) - *dest++ = '!'; - } - } - break; - } - src++; } - } - *dest++ = 0; + *dest++ = 0; - return 4; + return 4; } -int disThumb(u32 offset, char *dest, int flags){ - u32 opcode = debuggerReadHalfWord(offset); +int disThumb(u32 offset, char* dest, int flags) +{ + u32 opcode = debuggerReadHalfWord(offset); - const Opcodes *sp = thumbOpcodes; - int ret = 2; - while( sp->cval != (opcode & sp->mask) ) - sp++; + const Opcodes* sp = thumbOpcodes; + int ret = 2; + while (sp->cval != (opcode & sp->mask)) + sp++; - if (flags&DIS_VIEW_ADDRESS){ - dest = addHex(dest, 32, offset); - *dest++ = ' '; - } - if (flags&DIS_VIEW_CODE){ - dest = addHex(dest, 16, opcode); - *dest++ = ' '; - } - - const char *src = sp->mnemonic; - while (*src){ - if (*src!='%') - *dest++ = *src++; - else { - src++; - switch (*src){ - case 'r': - src++; - dest = addStr(dest, regs[(opcode>>(*src-'0'))&7]); - break; - case 'o': - dest = addStr(dest, "#0x"); - { - int val = (opcode>>6)&0x1f; - dest = addHex(dest, 8, val); - } - break; - case 'p': - dest = addStr(dest, "#0x"); - { - int val = (opcode>>6)&0x1f; - if (!(opcode&(1<<12))) - val <<= 2; - dest = addHex(dest, 0, val); - } - break; - case 'e': - dest = addStr(dest, "#0x"); - dest = addHex(dest, 0, ((opcode>>6)&0x1f)<<1); - break; - case 'i': - dest = addStr(dest, "#0x"); - dest = addHex(dest, 0, (opcode>>6)&7); - break; - case 'h': - { - src++; - int reg = (opcode>>(*src-'0'))&7; - src++; - if (opcode&(1<<(*src-'0'))) - reg += 8; - dest = addStr(dest, regs[reg]); - } - break; - case 'O': - dest = addStr(dest, "#0x"); - dest = addHex(dest, 0, (opcode&0xff)); - break; - case 'I': - *dest++ = '$'; - dest = addHex(dest, 32, (offset&0xfffffffc)+4+((opcode&0xff)<<2)); - break; - case 'J': - { - u32 value = debuggerReadMemory((offset&0xfffffffc)+4+ - ((opcode & 0xff)<<2)); - *dest++ = '$'; - dest = addHex(dest, 32, value); - const char *s = elfGetAddressSymbol(value); - if(*s) { - *dest++ = ' '; - dest = addStr(dest, s); - } - } - break; - case 'K': - { - u32 value = (offset&0xfffffffc)+4+((opcode & 0xff)<<2); - *dest++ = '$'; - dest = addHex(dest, 32, value); - const char *s = elfGetAddressSymbol(value); - if(*s) { - *dest++ = ' '; - dest = addStr(dest, s); - } - } - break; - case 'b': - if (opcode&(1<<10)) - *dest++ = 'b'; - break; - case 'B': - if (opcode&(1<<12)) - *dest++ = 'b'; - break; - case 'w': - dest = addStr(dest, "#0x"); - dest = addHex(dest, 0, (opcode&0xff)<<2); - break; - case 'W': - *dest++ = '$'; - { - int add = opcode&0xff; - if (add&0x80) - add |= 0xffffff00; - dest = addHex(dest, 32, (offset&0xfffffffe)+4+(add<<1)); - } - break; - case 'c': - dest = addStr(dest, conditions[(opcode>>8)&15]); - break; - case 's': - if (opcode&(1<<7)) - *dest++ = '-'; - dest = addStr(dest, "#0x"); - dest = addHex(dest, 0, (opcode&0x7f)<<2); - break; - case 'l': - { - int rlst = opcode&0xff; - int msk = 0; - int not_first = 0; - while (msk<8){ - if (rlst&(1<mnemonic; + while (*src) { + if (*src != '%') + *dest++ = *src++; + else { + src++; + switch (*src) { + case 'r': + src++; + dest = addStr(dest, regs[(opcode >> (*src - '0')) & 7]); + break; + case 'o': + dest = addStr(dest, "#0x"); + { + int val = (opcode >> 6) & 0x1f; + dest = addHex(dest, 8, val); + } + break; + case 'p': + dest = addStr(dest, "#0x"); + { + int val = (opcode >> 6) & 0x1f; + if (!(opcode & (1 << 12))) + val <<= 2; + dest = addHex(dest, 0, val); + } + break; + case 'e': + dest = addStr(dest, "#0x"); + dest = addHex(dest, 0, ((opcode >> 6) & 0x1f) << 1); + break; + case 'i': + dest = addStr(dest, "#0x"); + dest = addHex(dest, 0, (opcode >> 6) & 7); + break; + case 'h': { + src++; + int reg = (opcode >> (*src - '0')) & 7; + src++; + if (opcode & (1 << (*src - '0'))) + reg += 8; + dest = addStr(dest, regs[reg]); + } break; + case 'O': + dest = addStr(dest, "#0x"); + dest = addHex(dest, 0, (opcode & 0xff)); + break; + case 'I': + *dest++ = '$'; + dest = addHex(dest, 32, (offset & 0xfffffffc) + 4 + ((opcode & 0xff) << 2)); + break; + case 'J': { + u32 value = debuggerReadMemory((offset & 0xfffffffc) + 4 + ((opcode & 0xff) << 2)); + *dest++ = '$'; + dest = addHex(dest, 32, value); + const char* s = elfGetAddressSymbol(value); + if (*s) { + *dest++ = ' '; + dest = addStr(dest, s); + } + } break; + case 'K': { + u32 value = (offset & 0xfffffffc) + 4 + ((opcode & 0xff) << 2); + *dest++ = '$'; + dest = addHex(dest, 32, value); + const char* s = elfGetAddressSymbol(value); + if (*s) { + *dest++ = ' '; + dest = addStr(dest, s); + } + } break; + case 'b': + if (opcode & (1 << 10)) + *dest++ = 'b'; + break; + case 'B': + if (opcode & (1 << 12)) + *dest++ = 'b'; + break; + case 'w': + dest = addStr(dest, "#0x"); + dest = addHex(dest, 0, (opcode & 0xff) << 2); + break; + case 'W': + *dest++ = '$'; + { + int add = opcode & 0xff; + if (add & 0x80) + add |= 0xffffff00; + dest = addHex(dest, 32, (offset & 0xfffffffe) + 4 + (add << 1)); + } + break; + case 'c': + dest = addStr(dest, conditions[(opcode >> 8) & 15]); + break; + case 's': + if (opcode & (1 << 7)) + *dest++ = '-'; + dest = addStr(dest, "#0x"); + dest = addHex(dest, 0, (opcode & 0x7f) << 2); + break; + case 'l': { + int rlst = opcode & 0xff; + int msk = 0; + int not_first = 0; + while (msk < 8) { + if (rlst & (1 << msk)) { + int fr = msk; + while (rlst & (1 << msk)) + msk++; + int to = msk - 1; + if (not_first) + *dest++ = ','; + dest = addStr(dest, regs[fr]); + if (fr != to) { + if (fr == to - 1) + *dest++ = ','; + else + *dest++ = '-'; + dest = addStr(dest, regs[to]); + } + not_first = 1; + } else + msk++; + } + } break; + case 'm': + *dest++ = '$'; + dest = addHex(dest, 8, opcode & 0xff); + break; + case 'Z': + *dest++ = '$'; + dest = addHex(dest, 16, (opcode & 0x7ff) << 1); + break; + case 'a': + *dest++ = '$'; + { + int add = opcode & 0x07ff; + if (add & 0x400) + add |= 0xfffff800; + add <<= 1; + dest = addHex(dest, 32, offset + 4 + add); + } + break; + case 'A': { + int nopcode = debuggerReadHalfWord(offset + 2); + int add = opcode & 0x7ff; + if (add & 0x400) + add |= 0xfff800; + add = (add << 12) | ((nopcode & 0x7ff) << 1); + *dest++ = '$'; + dest = addHex(dest, 32, offset + 4 + add); + const char* s = elfGetAddressSymbol(offset + 4 + add); + if (*s) { + *dest++ = ' '; + *dest++ = '('; + dest = addStr(dest, s); + *dest++ = ')'; + } + ret = 4; + } break; + } + src++; + } + } + *dest++ = 0; + return ret; } diff --git a/src/gba/armdis.h b/src/gba/armdis.h index f8d67a02..f87da528 100644 --- a/src/gba/armdis.h +++ b/src/gba/armdis.h @@ -8,7 +8,7 @@ #define DIS_VIEW_ADDRESS 1 #define DIS_VIEW_CODE 2 -int disThumb(u32 offset, char *dest, int flags); -int disArm(u32 offset, char *dest, int flags); +int disThumb(u32 offset, char* dest, int flags); +int disArm(u32 offset, char* dest, int flags); #endif // __ARMDIS_H__ diff --git a/src/gba/bios.cpp b/src/gba/bios.cpp index b0539eb2..e2a2e46e 100644 --- a/src/gba/bios.cpp +++ b/src/gba/bios.cpp @@ -3,1108 +3,1097 @@ #include #include "GBA.h" -#include "bios.h" #include "GBAinline.h" #include "Globals.h" +#include "bios.h" s16 sineTable[256] = { - (s16)0x0000, (s16)0x0192, (s16)0x0323, (s16)0x04B5, (s16)0x0645, (s16)0x07D5, (s16)0x0964, (s16)0x0AF1, - (s16)0x0C7C, (s16)0x0E05, (s16)0x0F8C, (s16)0x1111, (s16)0x1294, (s16)0x1413, (s16)0x158F, (s16)0x1708, - (s16)0x187D, (s16)0x19EF, (s16)0x1B5D, (s16)0x1CC6, (s16)0x1E2B, (s16)0x1F8B, (s16)0x20E7, (s16)0x223D, - (s16)0x238E, (s16)0x24DA, (s16)0x261F, (s16)0x275F, (s16)0x2899, (s16)0x29CD, (s16)0x2AFA, (s16)0x2C21, - (s16)0x2D41, (s16)0x2E5A, (s16)0x2F6B, (s16)0x3076, (s16)0x3179, (s16)0x3274, (s16)0x3367, (s16)0x3453, - (s16)0x3536, (s16)0x3612, (s16)0x36E5, (s16)0x37AF, (s16)0x3871, (s16)0x392A, (s16)0x39DA, (s16)0x3A82, - (s16)0x3B20, (s16)0x3BB6, (s16)0x3C42, (s16)0x3CC5, (s16)0x3D3E, (s16)0x3DAE, (s16)0x3E14, (s16)0x3E71, - (s16)0x3EC5, (s16)0x3F0E, (s16)0x3F4E, (s16)0x3F84, (s16)0x3FB1, (s16)0x3FD3, (s16)0x3FEC, (s16)0x3FFB, - (s16)0x4000, (s16)0x3FFB, (s16)0x3FEC, (s16)0x3FD3, (s16)0x3FB1, (s16)0x3F84, (s16)0x3F4E, (s16)0x3F0E, - (s16)0x3EC5, (s16)0x3E71, (s16)0x3E14, (s16)0x3DAE, (s16)0x3D3E, (s16)0x3CC5, (s16)0x3C42, (s16)0x3BB6, - (s16)0x3B20, (s16)0x3A82, (s16)0x39DA, (s16)0x392A, (s16)0x3871, (s16)0x37AF, (s16)0x36E5, (s16)0x3612, - (s16)0x3536, (s16)0x3453, (s16)0x3367, (s16)0x3274, (s16)0x3179, (s16)0x3076, (s16)0x2F6B, (s16)0x2E5A, - (s16)0x2D41, (s16)0x2C21, (s16)0x2AFA, (s16)0x29CD, (s16)0x2899, (s16)0x275F, (s16)0x261F, (s16)0x24DA, - (s16)0x238E, (s16)0x223D, (s16)0x20E7, (s16)0x1F8B, (s16)0x1E2B, (s16)0x1CC6, (s16)0x1B5D, (s16)0x19EF, - (s16)0x187D, (s16)0x1708, (s16)0x158F, (s16)0x1413, (s16)0x1294, (s16)0x1111, (s16)0x0F8C, (s16)0x0E05, - (s16)0x0C7C, (s16)0x0AF1, (s16)0x0964, (s16)0x07D5, (s16)0x0645, (s16)0x04B5, (s16)0x0323, (s16)0x0192, - (s16)0x0000, (s16)0xFE6E, (s16)0xFCDD, (s16)0xFB4B, (s16)0xF9BB, (s16)0xF82B, (s16)0xF69C, (s16)0xF50F, - (s16)0xF384, (s16)0xF1FB, (s16)0xF074, (s16)0xEEEF, (s16)0xED6C, (s16)0xEBED, (s16)0xEA71, (s16)0xE8F8, - (s16)0xE783, (s16)0xE611, (s16)0xE4A3, (s16)0xE33A, (s16)0xE1D5, (s16)0xE075, (s16)0xDF19, (s16)0xDDC3, - (s16)0xDC72, (s16)0xDB26, (s16)0xD9E1, (s16)0xD8A1, (s16)0xD767, (s16)0xD633, (s16)0xD506, (s16)0xD3DF, - (s16)0xD2BF, (s16)0xD1A6, (s16)0xD095, (s16)0xCF8A, (s16)0xCE87, (s16)0xCD8C, (s16)0xCC99, (s16)0xCBAD, - (s16)0xCACA, (s16)0xC9EE, (s16)0xC91B, (s16)0xC851, (s16)0xC78F, (s16)0xC6D6, (s16)0xC626, (s16)0xC57E, - (s16)0xC4E0, (s16)0xC44A, (s16)0xC3BE, (s16)0xC33B, (s16)0xC2C2, (s16)0xC252, (s16)0xC1EC, (s16)0xC18F, - (s16)0xC13B, (s16)0xC0F2, (s16)0xC0B2, (s16)0xC07C, (s16)0xC04F, (s16)0xC02D, (s16)0xC014, (s16)0xC005, - (s16)0xC000, (s16)0xC005, (s16)0xC014, (s16)0xC02D, (s16)0xC04F, (s16)0xC07C, (s16)0xC0B2, (s16)0xC0F2, - (s16)0xC13B, (s16)0xC18F, (s16)0xC1EC, (s16)0xC252, (s16)0xC2C2, (s16)0xC33B, (s16)0xC3BE, (s16)0xC44A, - (s16)0xC4E0, (s16)0xC57E, (s16)0xC626, (s16)0xC6D6, (s16)0xC78F, (s16)0xC851, (s16)0xC91B, (s16)0xC9EE, - (s16)0xCACA, (s16)0xCBAD, (s16)0xCC99, (s16)0xCD8C, (s16)0xCE87, (s16)0xCF8A, (s16)0xD095, (s16)0xD1A6, - (s16)0xD2BF, (s16)0xD3DF, (s16)0xD506, (s16)0xD633, (s16)0xD767, (s16)0xD8A1, (s16)0xD9E1, (s16)0xDB26, - (s16)0xDC72, (s16)0xDDC3, (s16)0xDF19, (s16)0xE075, (s16)0xE1D5, (s16)0xE33A, (s16)0xE4A3, (s16)0xE611, - (s16)0xE783, (s16)0xE8F8, (s16)0xEA71, (s16)0xEBED, (s16)0xED6C, (s16)0xEEEF, (s16)0xF074, (s16)0xF1FB, - (s16)0xF384, (s16)0xF50F, (s16)0xF69C, (s16)0xF82B, (s16)0xF9BB, (s16)0xFB4B, (s16)0xFCDD, (s16)0xFE6E + (s16)0x0000, (s16)0x0192, (s16)0x0323, (s16)0x04B5, (s16)0x0645, (s16)0x07D5, (s16)0x0964, (s16)0x0AF1, + (s16)0x0C7C, (s16)0x0E05, (s16)0x0F8C, (s16)0x1111, (s16)0x1294, (s16)0x1413, (s16)0x158F, (s16)0x1708, + (s16)0x187D, (s16)0x19EF, (s16)0x1B5D, (s16)0x1CC6, (s16)0x1E2B, (s16)0x1F8B, (s16)0x20E7, (s16)0x223D, + (s16)0x238E, (s16)0x24DA, (s16)0x261F, (s16)0x275F, (s16)0x2899, (s16)0x29CD, (s16)0x2AFA, (s16)0x2C21, + (s16)0x2D41, (s16)0x2E5A, (s16)0x2F6B, (s16)0x3076, (s16)0x3179, (s16)0x3274, (s16)0x3367, (s16)0x3453, + (s16)0x3536, (s16)0x3612, (s16)0x36E5, (s16)0x37AF, (s16)0x3871, (s16)0x392A, (s16)0x39DA, (s16)0x3A82, + (s16)0x3B20, (s16)0x3BB6, (s16)0x3C42, (s16)0x3CC5, (s16)0x3D3E, (s16)0x3DAE, (s16)0x3E14, (s16)0x3E71, + (s16)0x3EC5, (s16)0x3F0E, (s16)0x3F4E, (s16)0x3F84, (s16)0x3FB1, (s16)0x3FD3, (s16)0x3FEC, (s16)0x3FFB, + (s16)0x4000, (s16)0x3FFB, (s16)0x3FEC, (s16)0x3FD3, (s16)0x3FB1, (s16)0x3F84, (s16)0x3F4E, (s16)0x3F0E, + (s16)0x3EC5, (s16)0x3E71, (s16)0x3E14, (s16)0x3DAE, (s16)0x3D3E, (s16)0x3CC5, (s16)0x3C42, (s16)0x3BB6, + (s16)0x3B20, (s16)0x3A82, (s16)0x39DA, (s16)0x392A, (s16)0x3871, (s16)0x37AF, (s16)0x36E5, (s16)0x3612, + (s16)0x3536, (s16)0x3453, (s16)0x3367, (s16)0x3274, (s16)0x3179, (s16)0x3076, (s16)0x2F6B, (s16)0x2E5A, + (s16)0x2D41, (s16)0x2C21, (s16)0x2AFA, (s16)0x29CD, (s16)0x2899, (s16)0x275F, (s16)0x261F, (s16)0x24DA, + (s16)0x238E, (s16)0x223D, (s16)0x20E7, (s16)0x1F8B, (s16)0x1E2B, (s16)0x1CC6, (s16)0x1B5D, (s16)0x19EF, + (s16)0x187D, (s16)0x1708, (s16)0x158F, (s16)0x1413, (s16)0x1294, (s16)0x1111, (s16)0x0F8C, (s16)0x0E05, + (s16)0x0C7C, (s16)0x0AF1, (s16)0x0964, (s16)0x07D5, (s16)0x0645, (s16)0x04B5, (s16)0x0323, (s16)0x0192, + (s16)0x0000, (s16)0xFE6E, (s16)0xFCDD, (s16)0xFB4B, (s16)0xF9BB, (s16)0xF82B, (s16)0xF69C, (s16)0xF50F, + (s16)0xF384, (s16)0xF1FB, (s16)0xF074, (s16)0xEEEF, (s16)0xED6C, (s16)0xEBED, (s16)0xEA71, (s16)0xE8F8, + (s16)0xE783, (s16)0xE611, (s16)0xE4A3, (s16)0xE33A, (s16)0xE1D5, (s16)0xE075, (s16)0xDF19, (s16)0xDDC3, + (s16)0xDC72, (s16)0xDB26, (s16)0xD9E1, (s16)0xD8A1, (s16)0xD767, (s16)0xD633, (s16)0xD506, (s16)0xD3DF, + (s16)0xD2BF, (s16)0xD1A6, (s16)0xD095, (s16)0xCF8A, (s16)0xCE87, (s16)0xCD8C, (s16)0xCC99, (s16)0xCBAD, + (s16)0xCACA, (s16)0xC9EE, (s16)0xC91B, (s16)0xC851, (s16)0xC78F, (s16)0xC6D6, (s16)0xC626, (s16)0xC57E, + (s16)0xC4E0, (s16)0xC44A, (s16)0xC3BE, (s16)0xC33B, (s16)0xC2C2, (s16)0xC252, (s16)0xC1EC, (s16)0xC18F, + (s16)0xC13B, (s16)0xC0F2, (s16)0xC0B2, (s16)0xC07C, (s16)0xC04F, (s16)0xC02D, (s16)0xC014, (s16)0xC005, + (s16)0xC000, (s16)0xC005, (s16)0xC014, (s16)0xC02D, (s16)0xC04F, (s16)0xC07C, (s16)0xC0B2, (s16)0xC0F2, + (s16)0xC13B, (s16)0xC18F, (s16)0xC1EC, (s16)0xC252, (s16)0xC2C2, (s16)0xC33B, (s16)0xC3BE, (s16)0xC44A, + (s16)0xC4E0, (s16)0xC57E, (s16)0xC626, (s16)0xC6D6, (s16)0xC78F, (s16)0xC851, (s16)0xC91B, (s16)0xC9EE, + (s16)0xCACA, (s16)0xCBAD, (s16)0xCC99, (s16)0xCD8C, (s16)0xCE87, (s16)0xCF8A, (s16)0xD095, (s16)0xD1A6, + (s16)0xD2BF, (s16)0xD3DF, (s16)0xD506, (s16)0xD633, (s16)0xD767, (s16)0xD8A1, (s16)0xD9E1, (s16)0xDB26, + (s16)0xDC72, (s16)0xDDC3, (s16)0xDF19, (s16)0xE075, (s16)0xE1D5, (s16)0xE33A, (s16)0xE4A3, (s16)0xE611, + (s16)0xE783, (s16)0xE8F8, (s16)0xEA71, (s16)0xEBED, (s16)0xED6C, (s16)0xEEEF, (s16)0xF074, (s16)0xF1FB, + (s16)0xF384, (s16)0xF50F, (s16)0xF69C, (s16)0xF82B, (s16)0xF9BB, (s16)0xFB4B, (s16)0xFCDD, (s16)0xFE6E }; void BIOS_ArcTan() { #ifdef GBA_LOGGING - if(systemVerbose & VERBOSE_SWI) { - log("ArcTan: %08x (VCOUNT=%2d)\n", - reg[0].I, - VCOUNT); - } + if (systemVerbose & VERBOSE_SWI) { + log("ArcTan: %08x (VCOUNT=%2d)\n", + reg[0].I, + VCOUNT); + } #endif - s32 a = -(((s32)(reg[0].I*reg[0].I)) >> 14); - s32 b = ((0xA9 * a) >> 14) + 0x390; - b = ((b * a) >> 14) + 0x91C; - b = ((b * a) >> 14) + 0xFB6; - b = ((b * a) >> 14) + 0x16AA; - b = ((b * a) >> 14) + 0x2081; - b = ((b * a) >> 14) + 0x3651; - b = ((b * a) >> 14) + 0xA2F9; - a = ((s32)reg[0].I * b) >> 16; - reg[0].I = a; + s32 a = -(((s32)(reg[0].I * reg[0].I)) >> 14); + s32 b = ((0xA9 * a) >> 14) + 0x390; + b = ((b * a) >> 14) + 0x91C; + b = ((b * a) >> 14) + 0xFB6; + b = ((b * a) >> 14) + 0x16AA; + b = ((b * a) >> 14) + 0x2081; + b = ((b * a) >> 14) + 0x3651; + b = ((b * a) >> 14) + 0xA2F9; + a = ((s32)reg[0].I * b) >> 16; + reg[0].I = a; #ifdef GBA_LOGGING - if(systemVerbose & VERBOSE_SWI) { - log("ArcTan: return=%08x\n", - reg[0].I); - } + if (systemVerbose & VERBOSE_SWI) { + log("ArcTan: return=%08x\n", + reg[0].I); + } #endif } void BIOS_ArcTan2() { #ifdef GBA_LOGGING - if(systemVerbose & VERBOSE_SWI) { - log("ArcTan2: %08x,%08x (VCOUNT=%2d)\n", - reg[0].I, - reg[1].I, - VCOUNT); - } + if (systemVerbose & VERBOSE_SWI) { + log("ArcTan2: %08x,%08x (VCOUNT=%2d)\n", + reg[0].I, + reg[1].I, + VCOUNT); + } #endif - s32 x = reg[0].I; - s32 y = reg[1].I; - u32 res = 0; - if (y == 0) { - res = ((x>>16) & 0x8000); - } else { - if (x == 0) { - res = ((y>>16) & 0x8000) + 0x4000; + s32 x = reg[0].I; + s32 y = reg[1].I; + u32 res = 0; + if (y == 0) { + res = ((x >> 16) & 0x8000); } else { - if ((abs(x) > abs(y)) || ((abs(x) == abs(y)) && (!((x<0) && (y<0))))) { - reg[1].I = x; - reg[0].I = y << 14; - BIOS_Div(); - BIOS_ArcTan(); - if (x < 0) - res = 0x8000 + reg[0].I; - else - res = (((y>>16) & 0x8000)<<1) + reg[0].I; - } else { - reg[0].I = x << 14; - BIOS_Div(); - BIOS_ArcTan(); - res = (0x4000 + ((y>>16) & 0x8000)) - reg[0].I; - } + if (x == 0) { + res = ((y >> 16) & 0x8000) + 0x4000; + } else { + if ((abs(x) > abs(y)) || ((abs(x) == abs(y)) && (!((x < 0) && (y < 0))))) { + reg[1].I = x; + reg[0].I = y << 14; + BIOS_Div(); + BIOS_ArcTan(); + if (x < 0) + res = 0x8000 + reg[0].I; + else + res = (((y >> 16) & 0x8000) << 1) + reg[0].I; + } else { + reg[0].I = x << 14; + BIOS_Div(); + BIOS_ArcTan(); + res = (0x4000 + ((y >> 16) & 0x8000)) - reg[0].I; + } + } } - } - reg[0].I = res; + reg[0].I = res; #ifdef GBA_LOGGING - if(systemVerbose & VERBOSE_SWI) { - log("ArcTan2: return=%08x\n", - reg[0].I); - } + if (systemVerbose & VERBOSE_SWI) { + log("ArcTan2: return=%08x\n", + reg[0].I); + } #endif } void BIOS_BitUnPack() { #ifdef GBA_LOGGING - if(systemVerbose & VERBOSE_SWI) { - log("BitUnPack: %08x,%08x,%08x (VCOUNT=%2d)\n", - reg[0].I, - reg[1].I, - reg[2].I, - VCOUNT); - } + if (systemVerbose & VERBOSE_SWI) { + log("BitUnPack: %08x,%08x,%08x (VCOUNT=%2d)\n", + reg[0].I, + reg[1].I, + reg[2].I, + VCOUNT); + } #endif - u32 source = reg[0].I; - u32 dest = reg[1].I; - u32 header = reg[2].I; + u32 source = reg[0].I; + u32 dest = reg[1].I; + u32 header = reg[2].I; - int len = CPUReadHalfWord(header); + int len = CPUReadHalfWord(header); // check address - if(((source & 0xe000000) == 0) || - ((source + len) & 0xe000000) == 0) - return; + if (((source & 0xe000000) == 0) || ((source + len) & 0xe000000) == 0) + return; - int bits = CPUReadByte(header+2); - int revbits = 8 - bits; - // u32 value = 0; - u32 base = CPUReadMemory(header+4); - bool addBase = (base & 0x80000000) ? true : false; - base &= 0x7fffffff; - int dataSize = CPUReadByte(header+3); + int bits = CPUReadByte(header + 2); + int revbits = 8 - bits; + // u32 value = 0; + u32 base = CPUReadMemory(header + 4); + bool addBase = (base & 0x80000000) ? true : false; + base &= 0x7fffffff; + int dataSize = CPUReadByte(header + 3); - int data = 0; - int bitwritecount = 0; - while(1) { - len -= 1; - if(len < 0) - break; - int mask = 0xff >> revbits; - u8 b = CPUReadByte(source); - source++; - int bitcount = 0; - while(1) { - if(bitcount >= 8) - break; - u32 d = b & mask; - u32 temp = d >> bitcount; - if(d || addBase) { - temp += base; - } - data |= temp << bitwritecount; - bitwritecount += dataSize; - if(bitwritecount >= 32) { - CPUWriteMemory(dest, data); - dest += 4; - data = 0; - bitwritecount = 0; - } - mask <<= bits; - bitcount += bits; + int data = 0; + int bitwritecount = 0; + while (1) { + len -= 1; + if (len < 0) + break; + int mask = 0xff >> revbits; + u8 b = CPUReadByte(source); + source++; + int bitcount = 0; + while (1) { + if (bitcount >= 8) + break; + u32 d = b & mask; + u32 temp = d >> bitcount; + if (d || addBase) { + temp += base; + } + data |= temp << bitwritecount; + bitwritecount += dataSize; + if (bitwritecount >= 32) { + CPUWriteMemory(dest, data); + dest += 4; + data = 0; + bitwritecount = 0; + } + mask <<= bits; + bitcount += bits; + } } - } } void BIOS_GetBiosChecksum() { - reg[0].I=0xBAAE187F; + reg[0].I = 0xBAAE187F; } void BIOS_BgAffineSet() { #ifdef GBA_LOGGING - if(systemVerbose & VERBOSE_SWI) { - log("BgAffineSet: %08x,%08x,%08x (VCOUNT=%2d)\n", - reg[0].I, - reg[1].I, - reg[2].I, - VCOUNT); - } + if (systemVerbose & VERBOSE_SWI) { + log("BgAffineSet: %08x,%08x,%08x (VCOUNT=%2d)\n", + reg[0].I, + reg[1].I, + reg[2].I, + VCOUNT); + } #endif - u32 src = reg[0].I; - u32 dest = reg[1].I; - int num = reg[2].I; + u32 src = reg[0].I; + u32 dest = reg[1].I; + int num = reg[2].I; - for(int i = 0; i < num; i++) { - s32 cx = CPUReadMemory(src); - src+=4; - s32 cy = CPUReadMemory(src); - src+=4; - s16 dispx = CPUReadHalfWord(src); - src+=2; - s16 dispy = CPUReadHalfWord(src); - src+=2; - s16 rx = CPUReadHalfWord(src); - src+=2; - s16 ry = CPUReadHalfWord(src); - src+=2; - u16 theta = CPUReadHalfWord(src)>>8; - src+=4; // keep structure alignment - s32 a = sineTable[(theta+0x40)&255]; - s32 b = sineTable[theta]; + for (int i = 0; i < num; i++) { + s32 cx = CPUReadMemory(src); + src += 4; + s32 cy = CPUReadMemory(src); + src += 4; + s16 dispx = CPUReadHalfWord(src); + src += 2; + s16 dispy = CPUReadHalfWord(src); + src += 2; + s16 rx = CPUReadHalfWord(src); + src += 2; + s16 ry = CPUReadHalfWord(src); + src += 2; + u16 theta = CPUReadHalfWord(src) >> 8; + src += 4; // keep structure alignment + s32 a = sineTable[(theta + 0x40) & 255]; + s32 b = sineTable[theta]; - s16 dx = (rx * a)>>14; - s16 dmx = (rx * b)>>14; - s16 dy = (ry * b)>>14; - s16 dmy = (ry * a)>>14; + s16 dx = (rx * a) >> 14; + s16 dmx = (rx * b) >> 14; + s16 dy = (ry * b) >> 14; + s16 dmy = (ry * a) >> 14; - CPUWriteHalfWord(dest, dx); - dest += 2; - CPUWriteHalfWord(dest, -dmx); - dest += 2; - CPUWriteHalfWord(dest, dy); - dest += 2; - CPUWriteHalfWord(dest, dmy); - dest += 2; + CPUWriteHalfWord(dest, dx); + dest += 2; + CPUWriteHalfWord(dest, -dmx); + dest += 2; + CPUWriteHalfWord(dest, dy); + dest += 2; + CPUWriteHalfWord(dest, dmy); + dest += 2; - s32 startx = cx - dx * dispx + dmx * dispy; - s32 starty = cy - dy * dispx - dmy * dispy; + s32 startx = cx - dx * dispx + dmx * dispy; + s32 starty = cy - dy * dispx - dmy * dispy; - CPUWriteMemory(dest, startx); - dest += 4; - CPUWriteMemory(dest, starty); - dest += 4; - } + CPUWriteMemory(dest, startx); + dest += 4; + CPUWriteMemory(dest, starty); + dest += 4; + } } void BIOS_CpuSet() { #ifdef GBA_LOGGING - if(systemVerbose & VERBOSE_SWI) { - log("CpuSet: 0x%08x,0x%08x,0x%08x (VCOUNT=%d)\n", reg[0].I, reg[1].I, - reg[2].I, VCOUNT); - } + if (systemVerbose & VERBOSE_SWI) { + log("CpuSet: 0x%08x,0x%08x,0x%08x (VCOUNT=%d)\n", reg[0].I, reg[1].I, + reg[2].I, VCOUNT); + } #endif - u32 source = reg[0].I; - u32 dest = reg[1].I; - u32 cnt = reg[2].I; + u32 source = reg[0].I; + u32 dest = reg[1].I; + u32 cnt = reg[2].I; - if(((source & 0xe000000) == 0) || - ((source + (((cnt << 11)>>9) & 0x1fffff)) & 0xe000000) == 0) - return; + if (((source & 0xe000000) == 0) || ((source + (((cnt << 11) >> 9) & 0x1fffff)) & 0xe000000) == 0) + return; - int count = cnt & 0x1FFFFF; + int count = cnt & 0x1FFFFF; - // 32-bit ? - if((cnt >> 26) & 1) { - // needed for 32-bit mode! - source &= 0xFFFFFFFC; - dest &= 0xFFFFFFFC; - // fill ? - if((cnt >> 24) & 1) { - u32 value = (source>0x0EFFFFFF ? 0x1CAD1CAD : CPUReadMemory(source)); - while(count) { - CPUWriteMemory(dest, value); - dest += 4; - count--; - } + // 32-bit ? + if ((cnt >> 26) & 1) { + // needed for 32-bit mode! + source &= 0xFFFFFFFC; + dest &= 0xFFFFFFFC; + // fill ? + if ((cnt >> 24) & 1) { + u32 value = (source > 0x0EFFFFFF ? 0x1CAD1CAD : CPUReadMemory(source)); + while (count) { + CPUWriteMemory(dest, value); + dest += 4; + count--; + } + } else { + // copy + while (count) { + CPUWriteMemory(dest, (source > 0x0EFFFFFF ? 0x1CAD1CAD : CPUReadMemory(source))); + source += 4; + dest += 4; + count--; + } + } } else { - // copy - while(count) { - CPUWriteMemory(dest, (source>0x0EFFFFFF ? 0x1CAD1CAD : CPUReadMemory(source))); - source += 4; - dest += 4; - count--; - } + // 16-bit fill? + if ((cnt >> 24) & 1) { + u16 value = (source > 0x0EFFFFFF ? 0x1CAD : CPUReadHalfWord(source)); + while (count) { + CPUWriteHalfWord(dest, value); + dest += 2; + count--; + } + } else { + // copy + while (count) { + CPUWriteHalfWord(dest, (source > 0x0EFFFFFF ? 0x1CAD : CPUReadHalfWord(source))); + source += 2; + dest += 2; + count--; + } + } } - } else { - // 16-bit fill? - if((cnt >> 24) & 1) { - u16 value = (source>0x0EFFFFFF ? 0x1CAD : CPUReadHalfWord(source)); - while(count) { - CPUWriteHalfWord(dest, value); - dest += 2; - count--; - } - } else { - // copy - while(count) { - CPUWriteHalfWord(dest, (source>0x0EFFFFFF ? 0x1CAD : CPUReadHalfWord(source))); - source += 2; - dest += 2; - count--; - } - } - } } void BIOS_CpuFastSet() { #ifdef GBA_LOGGING - if(systemVerbose & VERBOSE_SWI) { - log("CpuFastSet: 0x%08x,0x%08x,0x%08x (VCOUNT=%d)\n", reg[0].I, reg[1].I, - reg[2].I, VCOUNT); - } + if (systemVerbose & VERBOSE_SWI) { + log("CpuFastSet: 0x%08x,0x%08x,0x%08x (VCOUNT=%d)\n", reg[0].I, reg[1].I, + reg[2].I, VCOUNT); + } #endif - u32 source = reg[0].I; - u32 dest = reg[1].I; - u32 cnt = reg[2].I; + u32 source = reg[0].I; + u32 dest = reg[1].I; + u32 cnt = reg[2].I; - if(((source & 0xe000000) == 0) || - ((source + (((cnt << 11)>>9) & 0x1fffff)) & 0xe000000) == 0) - return; + if (((source & 0xe000000) == 0) || ((source + (((cnt << 11) >> 9) & 0x1fffff)) & 0xe000000) == 0) + return; - // needed for 32-bit mode! - source &= 0xFFFFFFFC; - dest &= 0xFFFFFFFC; + // needed for 32-bit mode! + source &= 0xFFFFFFFC; + dest &= 0xFFFFFFFC; - int count = cnt & 0x1FFFFF; + int count = cnt & 0x1FFFFF; - // fill? - if((cnt >> 24) & 1) { - while(count > 0) { - // BIOS always transfers 32 bytes at a time - u32 value = (source>0x0EFFFFFF ? 0xBAFFFFFB : CPUReadMemory(source)); - for(int i = 0; i < 8; i++) { - CPUWriteMemory(dest, value); - dest += 4; - } - count -= 8; + // fill? + if ((cnt >> 24) & 1) { + while (count > 0) { + // BIOS always transfers 32 bytes at a time + u32 value = (source > 0x0EFFFFFF ? 0xBAFFFFFB : CPUReadMemory(source)); + for (int i = 0; i < 8; i++) { + CPUWriteMemory(dest, value); + dest += 4; + } + count -= 8; + } + } else { + // copy + while (count > 0) { + // BIOS always transfers 32 bytes at a time + for (int i = 0; i < 8; i++) { + CPUWriteMemory(dest, (source > 0x0EFFFFFF ? 0xBAFFFFFB : CPUReadMemory(source))); + source += 4; + dest += 4; + } + count -= 8; + } } - } else { - // copy - while(count > 0) { - // BIOS always transfers 32 bytes at a time - for(int i = 0; i < 8; i++) { - CPUWriteMemory(dest, (source>0x0EFFFFFF ? 0xBAFFFFFB :CPUReadMemory(source))); - source += 4; - dest += 4; - } - count -= 8; - } - } } void BIOS_Diff8bitUnFilterWram() { #ifdef GBA_LOGGING - if(systemVerbose & VERBOSE_SWI) { - log("Diff8bitUnFilterWram: 0x%08x,0x%08x (VCOUNT=%d)\n", reg[0].I, - reg[1].I, VCOUNT); - } + if (systemVerbose & VERBOSE_SWI) { + log("Diff8bitUnFilterWram: 0x%08x,0x%08x (VCOUNT=%d)\n", reg[0].I, + reg[1].I, VCOUNT); + } #endif - u32 source = reg[0].I; - u32 dest = reg[1].I; + u32 source = reg[0].I; + u32 dest = reg[1].I; - u32 header = CPUReadMemory(source); - source += 4; + u32 header = CPUReadMemory(source); + source += 4; - if(((source & 0xe000000) == 0) || - (((source + ((header >> 8) & 0x1fffff)) & 0xe000000) == 0)) - return; + if (((source & 0xe000000) == 0) || (((source + ((header >> 8) & 0x1fffff)) & 0xe000000) == 0)) + return; - int len = header >> 8; + int len = header >> 8; - u8 data = CPUReadByte(source++); - CPUWriteByte(dest++, data); - len--; - - while(len > 0) { - u8 diff = CPUReadByte(source++); - data += diff; + u8 data = CPUReadByte(source++); CPUWriteByte(dest++, data); len--; - } + + while (len > 0) { + u8 diff = CPUReadByte(source++); + data += diff; + CPUWriteByte(dest++, data); + len--; + } } void BIOS_Diff8bitUnFilterVram() { #ifdef GBA_LOGGING - if(systemVerbose & VERBOSE_SWI) { - log("Diff8bitUnFilterVram: 0x%08x,0x%08x (VCOUNT=%d)\n", reg[0].I, - reg[1].I, VCOUNT); - } + if (systemVerbose & VERBOSE_SWI) { + log("Diff8bitUnFilterVram: 0x%08x,0x%08x (VCOUNT=%d)\n", reg[0].I, + reg[1].I, VCOUNT); + } #endif - u32 source = reg[0].I; - u32 dest = reg[1].I; + u32 source = reg[0].I; + u32 dest = reg[1].I; - u32 header = CPUReadMemory(source); - source += 4; + u32 header = CPUReadMemory(source); + source += 4; - if(((source & 0xe000000) == 0) || - ((source + ((header >> 8) & 0x1fffff)) & 0xe000000) == 0) - return; + if (((source & 0xe000000) == 0) || ((source + ((header >> 8) & 0x1fffff)) & 0xe000000) == 0) + return; - int len = header >> 8; + int len = header >> 8; - u8 data = CPUReadByte(source++); - u16 writeData = data; - int shift = 8; - int bytes = 1; + u8 data = CPUReadByte(source++); + u16 writeData = data; + int shift = 8; + int bytes = 1; - while(len >= 2) { - u8 diff = CPUReadByte(source++); - data += diff; - writeData |= (data << shift); - bytes++; - shift += 8; - if(bytes == 2) { - CPUWriteHalfWord(dest, writeData); - dest += 2; - len -= 2; - bytes = 0; - writeData = 0; - shift = 0; + while (len >= 2) { + u8 diff = CPUReadByte(source++); + data += diff; + writeData |= (data << shift); + bytes++; + shift += 8; + if (bytes == 2) { + CPUWriteHalfWord(dest, writeData); + dest += 2; + len -= 2; + bytes = 0; + writeData = 0; + shift = 0; + } } - } } void BIOS_Diff16bitUnFilter() { #ifdef GBA_LOGGING - if(systemVerbose & VERBOSE_SWI) { - log("Diff16bitUnFilter: 0x%08x,0x%08x (VCOUNT=%d)\n", reg[0].I, - reg[1].I, VCOUNT); - } + if (systemVerbose & VERBOSE_SWI) { + log("Diff16bitUnFilter: 0x%08x,0x%08x (VCOUNT=%d)\n", reg[0].I, + reg[1].I, VCOUNT); + } #endif - u32 source = reg[0].I; - u32 dest = reg[1].I; + u32 source = reg[0].I; + u32 dest = reg[1].I; - u32 header = CPUReadMemory(source); - source += 4; + u32 header = CPUReadMemory(source); + source += 4; - if(((source & 0xe000000) == 0) || - ((source + ((header >> 8) & 0x1fffff)) & 0xe000000) == 0) - return; + if (((source & 0xe000000) == 0) || ((source + ((header >> 8) & 0x1fffff)) & 0xe000000) == 0) + return; - int len = header >> 8; + int len = header >> 8; - u16 data = CPUReadHalfWord(source); - source += 2; - CPUWriteHalfWord(dest, data); - dest += 2; - len -= 2; - - while(len >= 2) { - u16 diff = CPUReadHalfWord(source); + u16 data = CPUReadHalfWord(source); source += 2; - data += diff; CPUWriteHalfWord(dest, data); dest += 2; len -= 2; - } + + while (len >= 2) { + u16 diff = CPUReadHalfWord(source); + source += 2; + data += diff; + CPUWriteHalfWord(dest, data); + dest += 2; + len -= 2; + } } void BIOS_Div() { #ifdef GBA_LOGGING - if(systemVerbose & VERBOSE_SWI) { - log("Div: 0x%08x,0x%08x (VCOUNT=%d)\n", - reg[0].I, - reg[1].I, - VCOUNT); - } + if (systemVerbose & VERBOSE_SWI) { + log("Div: 0x%08x,0x%08x (VCOUNT=%d)\n", + reg[0].I, + reg[1].I, + VCOUNT); + } #endif - int number = reg[0].I; - int denom = reg[1].I; + int number = reg[0].I; + int denom = reg[1].I; - if(denom != 0) { - reg[0].I = number / denom; - reg[1].I = number % denom; - s32 temp = (s32)reg[0].I; - reg[3].I = temp < 0 ? (u32)-temp : (u32)temp; - } + if (denom != 0) { + reg[0].I = number / denom; + reg[1].I = number % denom; + s32 temp = (s32)reg[0].I; + reg[3].I = temp < 0 ? (u32)-temp : (u32)temp; + } #ifdef GBA_LOGGING - if(systemVerbose & VERBOSE_SWI) { - log("Div: return=0x%08x,0x%08x,0x%08x\n", - reg[0].I, - reg[1].I, - reg[3].I); - } + if (systemVerbose & VERBOSE_SWI) { + log("Div: return=0x%08x,0x%08x,0x%08x\n", + reg[0].I, + reg[1].I, + reg[3].I); + } #endif } void BIOS_DivARM() { #ifdef GBA_LOGGING - if(systemVerbose & VERBOSE_SWI) { - log("DivARM: 0x%08x, (VCOUNT=%d)\n", - reg[0].I, - VCOUNT); - } + if (systemVerbose & VERBOSE_SWI) { + log("DivARM: 0x%08x, (VCOUNT=%d)\n", + reg[0].I, + VCOUNT); + } #endif - u32 temp = reg[0].I; - reg[0].I = reg[1].I; - reg[1].I = temp; - BIOS_Div(); + u32 temp = reg[0].I; + reg[0].I = reg[1].I; + reg[1].I = temp; + BIOS_Div(); } void BIOS_HuffUnComp() { #ifdef GBA_LOGGING - if(systemVerbose & VERBOSE_SWI) { - log("HuffUnComp: 0x%08x,0x%08x (VCOUNT=%d)\n", - reg[0].I, - reg[1].I, - VCOUNT); - } + if (systemVerbose & VERBOSE_SWI) { + log("HuffUnComp: 0x%08x,0x%08x (VCOUNT=%d)\n", + reg[0].I, + reg[1].I, + VCOUNT); + } #endif - u32 source = reg[0].I; - u32 dest = reg[1].I; + u32 source = reg[0].I; + u32 dest = reg[1].I; - u32 header = CPUReadMemory(source); - source += 4; + u32 header = CPUReadMemory(source); + source += 4; - if(((source & 0xe000000) == 0) || - ((source + ((header >> 8) & 0x1fffff)) & 0xe000000) == 0) - return; + if (((source & 0xe000000) == 0) || ((source + ((header >> 8) & 0x1fffff)) & 0xe000000) == 0) + return; - u8 treeSize = CPUReadByte(source++); + u8 treeSize = CPUReadByte(source++); - u32 treeStart = source; + u32 treeStart = source; - source += ((treeSize+1)<<1)-1; // minus because we already skipped one byte + source += ((treeSize + 1) << 1) - 1; // minus because we already skipped one byte - int len = header >> 8; + int len = header >> 8; - u32 mask = 0x80000000; - u32 data = CPUReadMemory(source); - source += 4; + u32 mask = 0x80000000; + u32 data = CPUReadMemory(source); + source += 4; - int pos = 0; - u8 rootNode = CPUReadByte(treeStart); - u8 currentNode = rootNode; - bool writeData = false; - int byteShift = 0; - int byteCount = 0; - u32 writeValue = 0; + int pos = 0; + u8 rootNode = CPUReadByte(treeStart); + u8 currentNode = rootNode; + bool writeData = false; + int byteShift = 0; + int byteCount = 0; + u32 writeValue = 0; - if((header & 0x0F) == 8) { - while(len > 0) { - // take left - if(pos == 0) - pos++; - else - pos += (((currentNode & 0x3F)+1)<<1); + if ((header & 0x0F) == 8) { + while (len > 0) { + // take left + if (pos == 0) + pos++; + else + pos += (((currentNode & 0x3F) + 1) << 1); - if(data & mask) { - // right - if(currentNode & 0x40) - writeData = true; - currentNode = CPUReadByte(treeStart+pos+1); - } else { - // left - if(currentNode & 0x80) - writeData = true; - currentNode = CPUReadByte(treeStart+pos); - } + if (data & mask) { + // right + if (currentNode & 0x40) + writeData = true; + currentNode = CPUReadByte(treeStart + pos + 1); + } else { + // left + if (currentNode & 0x80) + writeData = true; + currentNode = CPUReadByte(treeStart + pos); + } - if(writeData) { - writeValue |= (currentNode << byteShift); - byteCount++; - byteShift += 8; + if (writeData) { + writeValue |= (currentNode << byteShift); + byteCount++; + byteShift += 8; - pos = 0; - currentNode = rootNode; - writeData = false; + pos = 0; + currentNode = rootNode; + writeData = false; - if(byteCount == 4) { - byteCount = 0; - byteShift = 0; - CPUWriteMemory(dest, writeValue); - writeValue = 0; - dest += 4; - len -= 4; + if (byteCount == 4) { + byteCount = 0; + byteShift = 0; + CPUWriteMemory(dest, writeValue); + writeValue = 0; + dest += 4; + len -= 4; + } + } + mask >>= 1; + if (mask == 0) { + mask = 0x80000000; + data = CPUReadMemory(source); + source += 4; + } } - } - mask >>= 1; - if(mask == 0) { - mask = 0x80000000; - data = CPUReadMemory(source); - source += 4; - } - } - } else { - int halfLen = 0; - int value = 0; - while(len > 0) { - // take left - if(pos == 0) - pos++; - else - pos += (((currentNode & 0x3F)+1)<<1); + } else { + int halfLen = 0; + int value = 0; + while (len > 0) { + // take left + if (pos == 0) + pos++; + else + pos += (((currentNode & 0x3F) + 1) << 1); - if((data & mask)) { - // right - if(currentNode & 0x40) - writeData = true; - currentNode = CPUReadByte(treeStart+pos+1); - } else { - // left - if(currentNode & 0x80) - writeData = true; - currentNode = CPUReadByte(treeStart+pos); - } + if ((data & mask)) { + // right + if (currentNode & 0x40) + writeData = true; + currentNode = CPUReadByte(treeStart + pos + 1); + } else { + // left + if (currentNode & 0x80) + writeData = true; + currentNode = CPUReadByte(treeStart + pos); + } - if(writeData) { - if(halfLen == 0) - value |= currentNode; - else - value |= (currentNode<<4); + if (writeData) { + if (halfLen == 0) + value |= currentNode; + else + value |= (currentNode << 4); - halfLen += 4; - if(halfLen == 8) { - writeValue |= (value << byteShift); - byteCount++; - byteShift += 8; + halfLen += 4; + if (halfLen == 8) { + writeValue |= (value << byteShift); + byteCount++; + byteShift += 8; - halfLen = 0; - value = 0; + halfLen = 0; + value = 0; - if(byteCount == 4) { - byteCount = 0; - byteShift = 0; - CPUWriteMemory(dest, writeValue); - dest += 4; - writeValue = 0; - len -= 4; - } + if (byteCount == 4) { + byteCount = 0; + byteShift = 0; + CPUWriteMemory(dest, writeValue); + dest += 4; + writeValue = 0; + len -= 4; + } + } + pos = 0; + currentNode = rootNode; + writeData = false; + } + mask >>= 1; + if (mask == 0) { + mask = 0x80000000; + data = CPUReadMemory(source); + source += 4; + } } - pos = 0; - currentNode = rootNode; - writeData = false; - } - mask >>= 1; - if(mask == 0) { - mask = 0x80000000; - data = CPUReadMemory(source); - source += 4; - } } - } } void BIOS_LZ77UnCompVram() { #ifdef GBA_LOGGING - if(systemVerbose & VERBOSE_SWI) { - log("LZ77UnCompVram: 0x%08x,0x%08x (VCOUNT=%d)\n", - reg[0].I, - reg[1].I, - VCOUNT); - } + if (systemVerbose & VERBOSE_SWI) { + log("LZ77UnCompVram: 0x%08x,0x%08x (VCOUNT=%d)\n", + reg[0].I, + reg[1].I, + VCOUNT); + } #endif - u32 source = reg[0].I; - u32 dest = reg[1].I; + u32 source = reg[0].I; + u32 dest = reg[1].I; - u32 header = CPUReadMemory(source); - source += 4; + u32 header = CPUReadMemory(source); + source += 4; - if(((source & 0xe000000) == 0) || - ((source + ((header >> 8) & 0x1fffff)) & 0xe000000) == 0) - return; + if (((source & 0xe000000) == 0) || ((source + ((header >> 8) & 0x1fffff)) & 0xe000000) == 0) + return; - int byteCount = 0; - int byteShift = 0; - u32 writeValue = 0; + int byteCount = 0; + int byteShift = 0; + u32 writeValue = 0; - int len = header >> 8; + int len = header >> 8; - while(len > 0) { - u8 d = CPUReadByte(source++); + while (len > 0) { + u8 d = CPUReadByte(source++); - if(d) { - for(int i = 0; i < 8; i++) { - if(d & 0x80) { - u16 data = CPUReadByte(source++) << 8; - data |= CPUReadByte(source++); - int length = (data >> 12) + 3; - int offset = (data & 0x0FFF); - u32 windowOffset = dest + byteCount - offset - 1; - for(int i2 = 0; i2 < length; i2++) { - writeValue |= (CPUReadByte(windowOffset++) << byteShift); - byteShift += 8; - byteCount++; + if (d) { + for (int i = 0; i < 8; i++) { + if (d & 0x80) { + u16 data = CPUReadByte(source++) << 8; + data |= CPUReadByte(source++); + int length = (data >> 12) + 3; + int offset = (data & 0x0FFF); + u32 windowOffset = dest + byteCount - offset - 1; + for (int i2 = 0; i2 < length; i2++) { + writeValue |= (CPUReadByte(windowOffset++) << byteShift); + byteShift += 8; + byteCount++; - if(byteCount == 2) { - CPUWriteHalfWord(dest, writeValue); - dest += 2; - byteCount = 0; - byteShift = 0; - writeValue = 0; + if (byteCount == 2) { + CPUWriteHalfWord(dest, writeValue); + dest += 2; + byteCount = 0; + byteShift = 0; + writeValue = 0; + } + len--; + if (len == 0) + return; + } + } else { + writeValue |= (CPUReadByte(source++) << byteShift); + byteShift += 8; + byteCount++; + if (byteCount == 2) { + CPUWriteHalfWord(dest, writeValue); + dest += 2; + byteCount = 0; + byteShift = 0; + writeValue = 0; + } + len--; + if (len == 0) + return; + } + d <<= 1; } - len--; - if(len == 0) - return; - } } else { - writeValue |= (CPUReadByte(source++) << byteShift); - byteShift += 8; - byteCount++; - if(byteCount == 2) { - CPUWriteHalfWord(dest, writeValue); - dest += 2; - byteCount = 0; - byteShift = 0; - writeValue = 0; - } - len--; - if(len == 0) - return; + for (int i = 0; i < 8; i++) { + writeValue |= (CPUReadByte(source++) << byteShift); + byteShift += 8; + byteCount++; + if (byteCount == 2) { + CPUWriteHalfWord(dest, writeValue); + dest += 2; + byteShift = 0; + byteCount = 0; + writeValue = 0; + } + len--; + if (len == 0) + return; + } } - d <<= 1; - } - } else { - for(int i = 0; i < 8; i++) { - writeValue |= (CPUReadByte(source++) << byteShift); - byteShift += 8; - byteCount++; - if(byteCount == 2) { - CPUWriteHalfWord(dest, writeValue); - dest += 2; - byteShift = 0; - byteCount = 0; - writeValue = 0; - } - len--; - if(len == 0) - return; - } } - } } void BIOS_LZ77UnCompWram() { #ifdef GBA_LOGGING - if(systemVerbose & VERBOSE_SWI) { - log("LZ77UnCompWram: 0x%08x,0x%08x (VCOUNT=%d)\n", reg[0].I, reg[1].I, - VCOUNT); - } + if (systemVerbose & VERBOSE_SWI) { + log("LZ77UnCompWram: 0x%08x,0x%08x (VCOUNT=%d)\n", reg[0].I, reg[1].I, + VCOUNT); + } #endif - u32 source = reg[0].I; - u32 dest = reg[1].I; + u32 source = reg[0].I; + u32 dest = reg[1].I; - u32 header = CPUReadMemory(source); - source += 4; + u32 header = CPUReadMemory(source); + source += 4; - if(((source & 0xe000000) == 0) || - ((source + ((header >> 8) & 0x1fffff)) & 0xe000000) == 0) - return; + if (((source & 0xe000000) == 0) || ((source + ((header >> 8) & 0x1fffff)) & 0xe000000) == 0) + return; - int len = header >> 8; + int len = header >> 8; - while(len > 0) { - u8 d = CPUReadByte(source++); + while (len > 0) { + u8 d = CPUReadByte(source++); - if(d) { - for(int i = 0; i < 8; i++) { - if(d & 0x80) { - u16 data = CPUReadByte(source++) << 8; - data |= CPUReadByte(source++); - int length = (data >> 12) + 3; - int offset = (data & 0x0FFF); - u32 windowOffset = dest - offset - 1; - for(int i2 = 0; i2 < length; i2++) { - CPUWriteByte(dest++, CPUReadByte(windowOffset++)); - len--; - if(len == 0) - return; - } + if (d) { + for (int i = 0; i < 8; i++) { + if (d & 0x80) { + u16 data = CPUReadByte(source++) << 8; + data |= CPUReadByte(source++); + int length = (data >> 12) + 3; + int offset = (data & 0x0FFF); + u32 windowOffset = dest - offset - 1; + for (int i2 = 0; i2 < length; i2++) { + CPUWriteByte(dest++, CPUReadByte(windowOffset++)); + len--; + if (len == 0) + return; + } + } else { + CPUWriteByte(dest++, CPUReadByte(source++)); + len--; + if (len == 0) + return; + } + d <<= 1; + } } else { - CPUWriteByte(dest++, CPUReadByte(source++)); - len--; - if(len == 0) - return; + for (int i = 0; i < 8; i++) { + CPUWriteByte(dest++, CPUReadByte(source++)); + len--; + if (len == 0) + return; + } } - d <<= 1; - } - } else { - for(int i = 0; i < 8; i++) { - CPUWriteByte(dest++, CPUReadByte(source++)); - len--; - if(len == 0) - return; - } } - } } void BIOS_ObjAffineSet() { #ifdef GBA_LOGGING - if(systemVerbose & VERBOSE_SWI) { - log("ObjAffineSet: 0x%08x,0x%08x,0x%08x,0x%08x (VCOUNT=%d)\n", - reg[0].I, - reg[1].I, - reg[2].I, - reg[3].I, - VCOUNT); - } + if (systemVerbose & VERBOSE_SWI) { + log("ObjAffineSet: 0x%08x,0x%08x,0x%08x,0x%08x (VCOUNT=%d)\n", + reg[0].I, + reg[1].I, + reg[2].I, + reg[3].I, + VCOUNT); + } #endif - u32 src = reg[0].I; - u32 dest = reg[1].I; - int num = reg[2].I; - int offset = reg[3].I; + u32 src = reg[0].I; + u32 dest = reg[1].I; + int num = reg[2].I; + int offset = reg[3].I; - for(int i = 0; i < num; i++) { - s16 rx = CPUReadHalfWord(src); - src+=2; - s16 ry = CPUReadHalfWord(src); - src+=2; - u16 theta = CPUReadHalfWord(src)>>8; - src+=4; // keep structure alignment + for (int i = 0; i < num; i++) { + s16 rx = CPUReadHalfWord(src); + src += 2; + s16 ry = CPUReadHalfWord(src); + src += 2; + u16 theta = CPUReadHalfWord(src) >> 8; + src += 4; // keep structure alignment - s32 a = (s32)sineTable[(theta+0x40)&255]; - s32 b = (s32)sineTable[theta]; + s32 a = (s32)sineTable[(theta + 0x40) & 255]; + s32 b = (s32)sineTable[theta]; - s16 dx = ((s32)rx * a)>>14; - s16 dmx = ((s32)rx * b)>>14; - s16 dy = ((s32)ry * b)>>14; - s16 dmy = ((s32)ry * a)>>14; + s16 dx = ((s32)rx * a) >> 14; + s16 dmx = ((s32)rx * b) >> 14; + s16 dy = ((s32)ry * b) >> 14; + s16 dmy = ((s32)ry * a) >> 14; - CPUWriteHalfWord(dest, dx); - dest += offset; - CPUWriteHalfWord(dest, -dmx); - dest += offset; - CPUWriteHalfWord(dest, dy); - dest += offset; - CPUWriteHalfWord(dest, dmy); - dest += offset; - } + CPUWriteHalfWord(dest, dx); + dest += offset; + CPUWriteHalfWord(dest, -dmx); + dest += offset; + CPUWriteHalfWord(dest, dy); + dest += offset; + CPUWriteHalfWord(dest, dmy); + dest += offset; + } } void BIOS_RegisterRamReset(u32 flags) { - // no need to trace here. this is only called directly from GBA.cpp - // to emulate bios initialization + // no need to trace here. this is only called directly from GBA.cpp + // to emulate bios initialization - CPUUpdateRegister(0x0, 0x80); + CPUUpdateRegister(0x0, 0x80); - if(flags) { - if(flags & 0x01) { - // clear work RAM - memset(workRAM, 0, 0x40000); + if (flags) { + if (flags & 0x01) { + // clear work RAM + memset(workRAM, 0, 0x40000); + } + if (flags & 0x02) { + // clear internal RAM + memset(internalRAM, 0, 0x7e00); // don't clear 0x7e00-0x7fff + } + if (flags & 0x04) { + // clear palette RAM + memset(paletteRAM, 0, 0x400); + } + if (flags & 0x08) { + // clear VRAM + memset(vram, 0, 0x18000); + } + if (flags & 0x10) { + // clean OAM + memset(oam, 0, 0x400); + } + + if (flags & 0x80) { + int i; + for (i = 0; i < 0x10; i++) + CPUUpdateRegister(0x200 + i * 2, 0); + + for (i = 0; i < 0xF; i++) + CPUUpdateRegister(0x4 + i * 2, 0); + + for (i = 0; i < 0x20; i++) + CPUUpdateRegister(0x20 + i * 2, 0); + + for (i = 0; i < 0x18; i++) + CPUUpdateRegister(0xb0 + i * 2, 0); + + CPUUpdateRegister(0x130, 0); + CPUUpdateRegister(0x20, 0x100); + CPUUpdateRegister(0x30, 0x100); + CPUUpdateRegister(0x26, 0x100); + CPUUpdateRegister(0x36, 0x100); + } + + if (flags & 0x20) { + int i; + for (i = 0; i < 8; i++) + CPUUpdateRegister(0x110 + i * 2, 0); + CPUUpdateRegister(0x134, 0x8000); + for (i = 0; i < 7; i++) + CPUUpdateRegister(0x140 + i * 2, 0); + } + + if (flags & 0x40) { + int i; + CPUWriteByte(0x4000084, 0); + CPUWriteByte(0x4000084, 0x80); + CPUWriteMemory(0x4000080, 0x880e0000); + CPUUpdateRegister(0x88, CPUReadHalfWord(0x4000088) & 0x3ff); + CPUWriteByte(0x4000070, 0x70); + for (i = 0; i < 8; i++) + CPUUpdateRegister(0x90 + i * 2, 0); + CPUWriteByte(0x4000070, 0); + for (i = 0; i < 8; i++) + CPUUpdateRegister(0x90 + i * 2, 0); + CPUWriteByte(0x4000084, 0); + } } - if(flags & 0x02) { - // clear internal RAM - memset(internalRAM, 0, 0x7e00); // don't clear 0x7e00-0x7fff - } - if(flags & 0x04) { - // clear palette RAM - memset(paletteRAM, 0, 0x400); - } - if(flags & 0x08) { - // clear VRAM - memset(vram, 0, 0x18000); - } - if(flags & 0x10) { - // clean OAM - memset(oam, 0, 0x400); - } - - if(flags & 0x80) { - int i; - for(i = 0; i < 0x10; i++) - CPUUpdateRegister(0x200+i*2, 0); - - for(i = 0; i < 0xF; i++) - CPUUpdateRegister(0x4+i*2, 0); - - for(i = 0; i < 0x20; i++) - CPUUpdateRegister(0x20+i*2, 0); - - for(i = 0; i < 0x18; i++) - CPUUpdateRegister(0xb0+i*2, 0); - - CPUUpdateRegister(0x130, 0); - CPUUpdateRegister(0x20, 0x100); - CPUUpdateRegister(0x30, 0x100); - CPUUpdateRegister(0x26, 0x100); - CPUUpdateRegister(0x36, 0x100); - } - - if(flags & 0x20) { - int i; - for(i = 0; i < 8; i++) - CPUUpdateRegister(0x110+i*2, 0); - CPUUpdateRegister(0x134, 0x8000); - for(i = 0; i < 7; i++) - CPUUpdateRegister(0x140+i*2, 0); - } - - if(flags & 0x40) { - int i; - CPUWriteByte(0x4000084, 0); - CPUWriteByte(0x4000084, 0x80); - CPUWriteMemory(0x4000080, 0x880e0000); - CPUUpdateRegister(0x88, CPUReadHalfWord(0x4000088)&0x3ff); - CPUWriteByte(0x4000070, 0x70); - for(i = 0; i < 8; i++) - CPUUpdateRegister(0x90+i*2, 0); - CPUWriteByte(0x4000070, 0); - for(i = 0; i < 8; i++) - CPUUpdateRegister(0x90+i*2, 0); - CPUWriteByte(0x4000084, 0); - } - } } void BIOS_RegisterRamReset() { #ifdef GBA_LOGGING - if(systemVerbose & VERBOSE_SWI) { - log("RegisterRamReset: 0x%08x (VCOUNT=%d)\n", - reg[0].I, - VCOUNT); - } + if (systemVerbose & VERBOSE_SWI) { + log("RegisterRamReset: 0x%08x (VCOUNT=%d)\n", + reg[0].I, + VCOUNT); + } #endif - BIOS_RegisterRamReset(reg[0].I); + BIOS_RegisterRamReset(reg[0].I); } void BIOS_RLUnCompVram() { #ifdef GBA_LOGGING - if(systemVerbose & VERBOSE_SWI) { - log("RLUnCompVram: 0x%08x,0x%08x (VCOUNT=%d)\n", - reg[0].I, - reg[1].I, - VCOUNT); - } + if (systemVerbose & VERBOSE_SWI) { + log("RLUnCompVram: 0x%08x,0x%08x (VCOUNT=%d)\n", + reg[0].I, + reg[1].I, + VCOUNT); + } #endif - u32 source = reg[0].I; - u32 dest = reg[1].I; + u32 source = reg[0].I; + u32 dest = reg[1].I; - u32 header = CPUReadMemory(source & 0xFFFFFFFC); - source += 4; + u32 header = CPUReadMemory(source & 0xFFFFFFFC); + source += 4; - if(((source & 0xe000000) == 0) || - ((source + ((header >> 8) & 0x1fffff)) & 0xe000000) == 0) - return; + if (((source & 0xe000000) == 0) || ((source + ((header >> 8) & 0x1fffff)) & 0xe000000) == 0) + return; - int len = header >> 8; - int byteCount = 0; - int byteShift = 0; - u32 writeValue = 0; + int len = header >> 8; + int byteCount = 0; + int byteShift = 0; + u32 writeValue = 0; - while(len > 0) { - u8 d = CPUReadByte(source++); - int l = d & 0x7F; - if(d & 0x80) { - u8 data = CPUReadByte(source++); - l += 3; - for(int i = 0;i < l; i++) { - writeValue |= (data << byteShift); - byteShift += 8; - byteCount++; + while (len > 0) { + u8 d = CPUReadByte(source++); + int l = d & 0x7F; + if (d & 0x80) { + u8 data = CPUReadByte(source++); + l += 3; + for (int i = 0; i < l; i++) { + writeValue |= (data << byteShift); + byteShift += 8; + byteCount++; - if(byteCount == 2) { - CPUWriteHalfWord(dest, writeValue); - dest += 2; - byteCount = 0; - byteShift = 0; - writeValue = 0; + if (byteCount == 2) { + CPUWriteHalfWord(dest, writeValue); + dest += 2; + byteCount = 0; + byteShift = 0; + writeValue = 0; + } + len--; + if (len == 0) + return; + } + } else { + l++; + for (int i = 0; i < l; i++) { + writeValue |= (CPUReadByte(source++) << byteShift); + byteShift += 8; + byteCount++; + if (byteCount == 2) { + CPUWriteHalfWord(dest, writeValue); + dest += 2; + byteCount = 0; + byteShift = 0; + writeValue = 0; + } + len--; + if (len == 0) + return; + } } - len--; - if(len == 0) - return; - } - } else { - l++; - for(int i = 0; i < l; i++) { - writeValue |= (CPUReadByte(source++) << byteShift); - byteShift += 8; - byteCount++; - if(byteCount == 2) { - CPUWriteHalfWord(dest, writeValue); - dest += 2; - byteCount = 0; - byteShift = 0; - writeValue = 0; - } - len--; - if(len == 0) - return; - } } - } } void BIOS_RLUnCompWram() { #ifdef GBA_LOGGING - if(systemVerbose & VERBOSE_SWI) { - log("RLUnCompWram: 0x%08x,0x%08x (VCOUNT=%d)\n", - reg[0].I, - reg[1].I, - VCOUNT); - } + if (systemVerbose & VERBOSE_SWI) { + log("RLUnCompWram: 0x%08x,0x%08x (VCOUNT=%d)\n", + reg[0].I, + reg[1].I, + VCOUNT); + } #endif - u32 source = reg[0].I; - u32 dest = reg[1].I; + u32 source = reg[0].I; + u32 dest = reg[1].I; - u32 header = CPUReadMemory(source & 0xFFFFFFFC); - source += 4; + u32 header = CPUReadMemory(source & 0xFFFFFFFC); + source += 4; - if(((source & 0xe000000) == 0) || - ((source + ((header >> 8) & 0x1fffff)) & 0xe000000) == 0) - return; + if (((source & 0xe000000) == 0) || ((source + ((header >> 8) & 0x1fffff)) & 0xe000000) == 0) + return; - int len = header >> 8; + int len = header >> 8; - while(len > 0) { - u8 d = CPUReadByte(source++); - int l = d & 0x7F; - if(d & 0x80) { - u8 data = CPUReadByte(source++); - l += 3; - for(int i = 0;i < l; i++) { - CPUWriteByte(dest++, data); - len--; - if(len == 0) - return; - } - } else { - l++; - for(int i = 0; i < l; i++) { - CPUWriteByte(dest++, CPUReadByte(source++)); - len--; - if(len == 0) - return; - } + while (len > 0) { + u8 d = CPUReadByte(source++); + int l = d & 0x7F; + if (d & 0x80) { + u8 data = CPUReadByte(source++); + l += 3; + for (int i = 0; i < l; i++) { + CPUWriteByte(dest++, data); + len--; + if (len == 0) + return; + } + } else { + l++; + for (int i = 0; i < l; i++) { + CPUWriteByte(dest++, CPUReadByte(source++)); + len--; + if (len == 0) + return; + } + } } - } } void BIOS_SoftReset() { #ifdef GBA_LOGGING - if(systemVerbose & VERBOSE_SWI) { - log("SoftReset: (VCOUNT=%d)\n", VCOUNT); - } + if (systemVerbose & VERBOSE_SWI) { + log("SoftReset: (VCOUNT=%d)\n", VCOUNT); + } #endif - armState = true; - armMode = 0x1F; - armIrqEnable = false; - C_FLAG = V_FLAG = N_FLAG = Z_FLAG = false; - reg[13].I = 0x03007F00; - reg[14].I = 0x00000000; - reg[16].I = 0x00000000; - reg[R13_IRQ].I = 0x03007FA0; - reg[R14_IRQ].I = 0x00000000; - reg[SPSR_IRQ].I = 0x00000000; - reg[R13_SVC].I = 0x03007FE0; - reg[R14_SVC].I = 0x00000000; - reg[SPSR_SVC].I = 0x00000000; - u8 b = internalRAM[0x7ffa]; + armState = true; + armMode = 0x1F; + armIrqEnable = false; + C_FLAG = V_FLAG = N_FLAG = Z_FLAG = false; + reg[13].I = 0x03007F00; + reg[14].I = 0x00000000; + reg[16].I = 0x00000000; + reg[R13_IRQ].I = 0x03007FA0; + reg[R14_IRQ].I = 0x00000000; + reg[SPSR_IRQ].I = 0x00000000; + reg[R13_SVC].I = 0x03007FE0; + reg[R14_SVC].I = 0x00000000; + reg[SPSR_SVC].I = 0x00000000; + u8 b = internalRAM[0x7ffa]; - memset(&internalRAM[0x7e00], 0, 0x200); + memset(&internalRAM[0x7e00], 0, 0x200); - if(b) { - armNextPC = 0x02000000; - reg[15].I = 0x02000004; - } else { - armNextPC = 0x08000000; - reg[15].I = 0x08000004; - } + if (b) { + armNextPC = 0x02000000; + reg[15].I = 0x02000004; + } else { + armNextPC = 0x08000000; + reg[15].I = 0x08000004; + } } void BIOS_Sqrt() { #ifdef GBA_LOGGING - if(systemVerbose & VERBOSE_SWI) { - log("Sqrt: %08x (VCOUNT=%2d)\n", - reg[0].I, - VCOUNT); - } + if (systemVerbose & VERBOSE_SWI) { + log("Sqrt: %08x (VCOUNT=%2d)\n", + reg[0].I, + VCOUNT); + } #endif - reg[0].I = (u32)sqrt((double)reg[0].I); + reg[0].I = (u32)sqrt((double)reg[0].I); #ifdef GBA_LOGGING - if(systemVerbose & VERBOSE_SWI) { - log("Sqrt: return=%08x\n", - reg[0].I); - } + if (systemVerbose & VERBOSE_SWI) { + log("Sqrt: return=%08x\n", + reg[0].I); + } #endif } @@ -1114,8 +1103,7 @@ u32 const base2 = 0x04000080; static bool BIOS_SndDriver_ba4(u32 r0, u32 r4r12) // 0xba4 { - if (r4r12) - { + if (r4r12) { r4r12 = r4r12 & ~0xFE000000; r4r12 += r0; if (!((r0 & 0x0E000000) && (r4r12 & 0x0E000000))) @@ -1146,23 +1134,19 @@ static void BIOS_SndDriver_b4c(u32 r0, u32 r1, u32 r2) // 0xb4c #endif // 0b56 - if ( !ok ) - { - u32 r5 = 0; //v8 - if ( r2 >= (1<<(27-1)) ) //v6 - { - r5 = r1 + r4; - if ( r2 >= (1<<(25-1)) ) - { - u32 r3 = CPUReadMemory(r0); - while ( r1 < r5 ) - { - CPUWriteMemory(r1, r3); - r1 += 4; - } - } - else // @todo 0b6e + if (!ok) { + u32 r5 = 0; //v8 + if (r2 >= (1 << (27 - 1))) //v6 { + r5 = r1 + r4; + if (r2 >= (1 << (25 - 1))) { + u32 r3 = CPUReadMemory(r0); + while (r1 < r5) { + CPUWriteMemory(r1, r3); + r1 += 4; + } + } else // @todo 0b6e + { #if 0 while ( v5 < v9 ) { @@ -1172,10 +1156,9 @@ static void BIOS_SndDriver_b4c(u32 r0, u32 r1, u32 r2) // 0xb4c v5 += 4; } #endif - } - } - else // @todo 0b78 - { + } + } else // @todo 0b78 + { #if 0 v12 = (unsigned int)v3 >> 1; if ( __CFSHR__(v6, 25) ) @@ -1196,7 +1179,7 @@ static void BIOS_SndDriver_b4c(u32 r0, u32 r1, u32 r2) // 0xb4c } } #endif - } + } } // 0x0b96 } @@ -1210,31 +1193,29 @@ static s32 BIOS_SndDriver_3e4(u32 const r0a, u32 const r1a) // 0x3e4 s32 r2; bool gtr; - if ( (r1 & 0x80000000 & 0x80000000) != 0 ) + if ((r1 & 0x80000000 & 0x80000000) != 0) r1 = -r1; r12 = r0; //v5 ^ (r0 >> 32); - if ( r0 < 0 ) + if (r0 < 0) r0 = -r0; r2 = r1; - do - { + do { gtr = (r2 >= r0 >> 1); - if ( r2 <= r0 >> 1 ) + if (r2 <= r0 >> 1) r2 *= 2; - } while ( !gtr ); + } while (!gtr); - while ( 1 ) - { + while (1) { v5 += (r0 >= (u32)r2) + v5; - if ( r0 >= (u32)r2 ) + if (r0 >= (u32)r2) r0 -= r2; - if ( r2 == r1 ) + if (r2 == r1) break; r2 = (u32)r2 >> 1; } - if ( !(r12 << 1) ) + if (!(r12 << 1)) return -v5; else return v5; @@ -1246,113 +1227,110 @@ static void BIOS_SndDriverSub1(u32 p1) // 0x170a u32 const puser1 = CPUReadMemory(0x3007FF0); // 7FC0 + 0x30 // Store something - CPUWriteByte(puser1+8, local1); + CPUWriteByte(puser1 + 8, local1); u32 r0 = (0x31e8 + (local1 << 1)) - 0x20; // @todo read from bios region - if (r0 == 0x31D0) - { + if (r0 == 0x31D0) { r0 = 0xE0; - } - else if (r0 == 0x31E0) - { + } else if (r0 == 0x31E0) { r0 = 0x2C0; - } - else r0 = CPUReadHalfWord(r0+0x1E); - CPUWriteMemory(puser1+0x10, r0); + } else + r0 = CPUReadHalfWord(r0 + 0x1E); + CPUWriteMemory(puser1 + 0x10, r0); u32 r1 = 0x630; u32 const r4 = r0; - // 0x172c + // 0x172c r0 = BIOS_SndDriver_3e4(r0, r1); - CPUWriteByte(puser1+0xB, r0); + CPUWriteByte(puser1 + 0xB, r0); - u32 x = 0x91d1b * r4; - r1 = x + 0x1388; - r0 = 0x1388 << 1; - r0 = BIOS_SndDriver_3e4(r0, r1); - CPUWriteMemory(puser1+0x14, r0); + u32 x = 0x91d1b * r4; + r1 = x + 0x1388; + r0 = 0x1388 << 1; + r0 = BIOS_SndDriver_3e4(r0, r1); + CPUWriteMemory(puser1 + 0x14, r0); - r1 = 1 << 24; - r0 = BIOS_SndDriver_3e4(r0, r1) + 1; - r0 /= 2; - CPUWriteMemory(puser1+0x18, r0); + r1 = 1 << 24; + r0 = BIOS_SndDriver_3e4(r0, r1) + 1; + r0 /= 2; + CPUWriteMemory(puser1 + 0x18, r0); - // 0x1750 - u32 r4basesnd = 0x4000100; - r0 = r4; - r1 = 0x44940; - CPUWriteHalfWord(r4basesnd+2, 0); - r0 = BIOS_SndDriver_3e4(r0, r1); - r0 = (1<<16)-r0; - CPUWriteHalfWord(r4basesnd+0, r0); + // 0x1750 + u32 r4basesnd = 0x4000100; + r0 = r4; + r1 = 0x44940; + CPUWriteHalfWord(r4basesnd + 2, 0); + r0 = BIOS_SndDriver_3e4(r0, r1); + r0 = (1 << 16) - r0; + CPUWriteHalfWord(r4basesnd + 0, r0); - // sub 0x18c8 is unrolled here - r1 = 0x5b << 9; - CPUWriteHalfWord(base1+6 , r1); - CPUWriteHalfWord(base1+12 , r1); + // sub 0x18c8 is unrolled here + r1 = 0x5b << 9; + CPUWriteHalfWord(base1 + 6, r1); + CPUWriteHalfWord(base1 + 12, r1); - // 0x176a, @todo busy loop here - r0 = 0x4000000; - //do - { - r1 = CPUReadByte(r0+6); - } //while (r1 != 0x9F); + // 0x176a, @todo busy loop here + r0 = 0x4000000; + //do + { + r1 = CPUReadByte(r0 + 6); + } //while (r1 != 0x9F); - CPUWriteHalfWord(r4basesnd+2, 0x80); + CPUWriteHalfWord(r4basesnd + 2, 0x80); } void BIOS_SndDriverInit() // 0x166a { #ifdef GBA_LOGGING - if(systemVerbose & VERBOSE_SWI) { - log("SndDriverInit: WaveData=%08x mk=%08x fp=%08x\n", - reg[0].I, - reg[1].I, - reg[2].I); - } + if (systemVerbose & VERBOSE_SWI) { + log("SndDriverInit: WaveData=%08x mk=%08x fp=%08x\n", + reg[0].I, + reg[1].I, + reg[2].I); + } #endif - // 7FC0 + 0x30 + // 7FC0 + 0x30 u32 const puser1 = 0x3007FF0; u32 const user1 = reg[0].I; u32 base3 = 0x040000BC; //u32 base4 = 0x03007FF0; - CPUWriteHalfWord(base1+6 , 0); - CPUWriteHalfWord(base1+12, 0); + CPUWriteHalfWord(base1 + 6, 0); + CPUWriteHalfWord(base1 + 12, 0); - CPUWriteHalfWord(base2+4, 0x8F); - CPUWriteHalfWord(base2+2, 0xA90E); + CPUWriteHalfWord(base2 + 4, 0x8F); + CPUWriteHalfWord(base2 + 2, 0xA90E); - u16 val9 = CPUReadHalfWord(base2+9); - CPUWriteHalfWord(base2+9, val9&ADBITS_MASK); // DA? + u16 val9 = CPUReadHalfWord(base2 + 9); + CPUWriteHalfWord(base2 + 9, val9 & ADBITS_MASK); // DA? - CPUWriteMemory(base3+0, (user1 + 0x350)); //0x350, 640int - CPUWriteMemory(base1+0, 0x40000A0); - CPUWriteMemory(base1+8, 2224); //0x980 - CPUWriteMemory(base1+12, 0x40000A4); + CPUWriteMemory(base3 + 0, (user1 + 0x350)); //0x350, 640int + CPUWriteMemory(base1 + 0, 0x40000A0); + CPUWriteMemory(base1 + 8, 2224); //0x980 + CPUWriteMemory(base1 + 12, 0x40000A4); CPUWriteMemory(puser1, user1); u32 const r2 = 0x050003EC; u32 const sp = reg[13].I; // 0x03003c98; CPUWriteMemory(sp, 0); - BIOS_SndDriver_b4c(sp, user1, r2); + BIOS_SndDriver_b4c(sp, user1, r2); - // 0x16b0 - CPUWriteByte(user1+0x6, 0x8); - CPUWriteByte(user1+0x7, 0xF); - CPUWriteMemory(user1+0x38, 0x2425); - CPUWriteMemory(user1+0x28, 0x1709); - CPUWriteMemory(user1+0x2C, 0x1709); - CPUWriteMemory(user1+0x30, 0x1709); - CPUWriteMemory(user1+0x3C, 0x1709); - CPUWriteMemory(user1+0x34, 0x3738); + // 0x16b0 + CPUWriteByte(user1 + 0x6, 0x8); + CPUWriteByte(user1 + 0x7, 0xF); + CPUWriteMemory(user1 + 0x38, 0x2425); + CPUWriteMemory(user1 + 0x28, 0x1709); + CPUWriteMemory(user1 + 0x2C, 0x1709); + CPUWriteMemory(user1 + 0x30, 0x1709); + CPUWriteMemory(user1 + 0x3C, 0x1709); + CPUWriteMemory(user1 + 0x34, 0x3738); - BIOS_SndDriverSub1(0x40000); + BIOS_SndDriverSub1(0x40000); CPUWriteMemory(user1, 0x68736D53); // this ret is common among funcs } @@ -1363,50 +1341,43 @@ void BIOS_SndDriverMode() //0x179c u32 const puser1 = CPUReadMemory(0x3007FF0); // 7FC0 + 0x30 u32 user1 = CPUReadMemory(puser1); - if ( user1 == 0x68736D53 ) - { + if (user1 == 0x68736D53) { CPUWriteMemory(puser1, (++user1)); // this guard is common for funcs, unify // reverb values at bits 0...7 u8 revb = (input & 0xFF); - if ( revb ) - { - revb>>=1; // shift out the 7th enable bit - CPUWriteByte(puser1+5, revb); + if (revb) { + revb >>= 1; // shift out the 7th enable bit + CPUWriteByte(puser1 + 5, revb); } // direct sound multi channels at bits 8...11 - u8 chc = (input & 0xF00)>>8; - if ( chc > 0 ) - { - CPUWriteByte(puser1+6, chc); + u8 chc = (input & 0xF00) >> 8; + if (chc > 0) { + CPUWriteByte(puser1 + 6, chc); u32 puser2 = puser1 + 7 + 0x49; - int count=12; - while (count--) - { + int count = 12; + while (count--) { CPUWriteByte(puser2, 0); - puser2+=0x40; + puser2 += 0x40; } } // direct sound master volume at bits 12...15 - u8 chv = (input & 0xF000)>>12; - if ( chv > 0 ) - { - CPUWriteByte(puser1+7, chv); + u8 chv = (input & 0xF000) >> 12; + if (chv > 0) { + CPUWriteByte(puser1 + 7, chv); } // DA converter bits at bits 20...23 u32 dab = (input & 0x00B00000); - if ( dab ) - { + if (dab) { dab &= 0x00300000; dab >>= 0xE; - u8 adv = CPUReadByte(puser1+9) & ADBITS_MASK; // @todo verify offset + u8 adv = CPUReadByte(puser1 + 9) & ADBITS_MASK; // @todo verify offset dab |= adv; - CPUWriteByte(puser1+9, dab); + CPUWriteByte(puser1 + 9, dab); } // Playback frequency at bits 16...19 u32 pbf = (input & 0x000F0000); - if ( pbf ) - { + if (pbf) { // Modifies puser1/user1 BIOS_SndDriverVSyncOff(); @@ -1423,85 +1394,86 @@ void BIOS_SndDriverMain() // 0x1dc4 -> 0x08004024 phantasy star u32 const puser1 = CPUReadMemory(0x3007FF0); // 7FC0 + 0x30, //@+sp14 u32 user1 = CPUReadMemory(puser1); - if ( user1 != 0x68736D53 ) + if (user1 != 0x68736D53) return; // main CPUWriteMemory(puser1, (++user1)); // this guard is common for funcs, unify int const user2 = CPUReadMemory(puser1 + 0x20); - if ( user2 ) - { + if (user2) { int const par1 = CPUReadMemory(puser1 + 0x24); // Call 0x2102 sub_16A8 - -> param r1 } - int const userfunc = CPUReadMemory(puser1 + 0x28); - switch (userfunc) - { - case 0x1709: //phantasy star - default: - break; - } + int const userfunc = CPUReadMemory(puser1 + 0x28); + switch (userfunc) { + case 0x1709: //phantasy star + default: + break; + } u32 const v2 = CPUReadMemory(puser1 + 0x10); //r8 - u8 const user4 = CPUReadByte(puser1+4) - 1; - u32 user41 = 0; + u8 const user4 = CPUReadByte(puser1 + 4) - 1; + u32 user41 = 0; - if ( user4 > 0 ) - { + if (user4 > 0) { user41 = CPUReadByte(puser1 + 0x0B); user41 -= user4; user41 *= v2; } u32 r5; - u32 const r5c = puser1 + 0x350 + user41; //r5 @sp+8 - int user6 = r5c + 0x630; //r6 + u32 const r5c = puser1 + 0x350 + user41; //r5 @sp+8 + int user6 = r5c + 0x630; //r6 int user5 = CPUReadByte(puser1 + 0x5); //r3 - if ( user5 ) - { + if (user5) { // @todo 0x1e1a - } - else // 0x1e74 + } else // 0x1e74 { - r5 = r5c; - int count = v2>>4; //r1...v13 - if ( !(v2 >> 3) ) - { + r5 = r5c; + int count = v2 >> 4; //r1...v13 + if (!(v2 >> 3)) { CPUWriteMemory(r5, 0); CPUWriteMemory(user6, 0); - r5+=4; user6+=4; + r5 += 4; + user6 += 4; } - if ( !(v2 >> 1) ) //0x1e7c + if (!(v2 >> 1)) //0x1e7c { CPUWriteMemory(r5, 0); CPUWriteMemory(user6, 0); - r5+=4; user6+=4; + r5 += 4; + user6 += 4; CPUWriteMemory(r5, 0); CPUWriteMemory(user6, 0); - r5+=4; user6+=4; + r5 += 4; + user6 += 4; } do // 0x1e8e { // @todo optimize this memset CPUWriteMemory(r5, 0); CPUWriteMemory(user6, 0); - r5+=4; user6+=4; + r5 += 4; + user6 += 4; CPUWriteMemory(r5, 0); CPUWriteMemory(user6, 0); - r5+=4; user6+=4; + r5 += 4; + user6 += 4; CPUWriteMemory(r5, 0); CPUWriteMemory(user6, 0); - r5+=4; user6+=4; + r5 += 4; + user6 += 4; CPUWriteMemory(r5, 0); CPUWriteMemory(user6, 0); - r5+=4; user6+=4; + r5 += 4; + user6 += 4; count -= 1; } while (count > 0); @@ -1509,203 +1481,182 @@ void BIOS_SndDriverMain() // 0x1dc4 -> 0x08004024 phantasy star //0x1ea2 u32 r4 = puser1; // apparenty ch ptr? - int r9 = CPUReadMemory(r4+0x14); - int r12 = CPUReadMemory(r4+0x18); - u32 i = CPUReadByte(r4+0x6); + int r9 = CPUReadMemory(r4 + 0x14); + int r12 = CPUReadMemory(r4 + 0x18); + u32 i = CPUReadByte(r4 + 0x6); - for (r4+=0x10; i > 0; i-- ) - { - r4+=0x40; -/*lbl_0x1eb0:*/ - u32 r3 = CPUReadMemory(r4+0x24); + for (r4 += 0x10; i > 0; i--) { + r4 += 0x40; + /*lbl_0x1eb0:*/ + u32 r3 = CPUReadMemory(r4 + 0x24); u8 r6 = CPUReadByte(r4); - if ( (r6 & 0xC7) == 0 ) // 0x1ebc + if ((r6 & 0xC7) == 0) // 0x1ebc continue; //goto lbl_20e4; - if ( (r6 & 0x80) && ((r6 & 0x40) == 0) ) // 0x1ec4 + if ((r6 & 0x80) && ((r6 & 0x40) == 0)) // 0x1ec4 { r6 = 0x3; - CPUWriteByte(r4, r6); - CPUWriteMemory(r4+0x28, r3+0x10); + CPUWriteByte(r4, r6); + CPUWriteMemory(r4 + 0x28, r3 + 0x10); - int r0t1 = CPUReadMemory(r3+0xC); - CPUWriteMemory(r4+0x18, r0t1); + int r0t1 = CPUReadMemory(r3 + 0xC); + CPUWriteMemory(r4 + 0x18, r0t1); - r5=0; - CPUWriteByte(r4+0x9, 0); - CPUWriteMemory(r4+0x1c, 0); + r5 = 0; + CPUWriteByte(r4 + 0x9, 0); + CPUWriteMemory(r4 + 0x1c, 0); - u8 r2a = CPUReadByte(r3+0x3); // seems to be LABEL_20e4 - if ((r2a & 0xC0)) // 1ee4 - { - - } + u8 r2a = CPUReadByte(r3 + 0x3); // seems to be LABEL_20e4 + if ((r2a & 0xC0)) // 1ee4 + { + } goto lbl_0x1f46; - } - else - { -//lbl_0x1eee: - r5 = CPUReadByte(r4+0x9); // - if ( (r6 & 0x4) != 0) // @todo 0x1ef4 - { + } else { + //lbl_0x1eee: + r5 = CPUReadByte(r4 + 0x9); // + if ((r6 & 0x4) != 0) // @todo 0x1ef4 + { + } - } + if ((r6 & 0x40) != 0) // @todo 0x1f08 + { + } - if ( (r6 & 0x40) != 0) // @todo 0x1f08 - { + if ((r6 & 0x03) == 2) // 0x1f2a + { + u8 mul1 = CPUReadByte(r4 + 0x5); + r5 *= mul1; + r5 >>= 8; - } - - if ( (r6 & 0x03) == 2) // 0x1f2a - { - u8 mul1 = CPUReadByte(r4+0x5); - r5*=mul1; - r5>>=8; - - u8 cmp1 = CPUReadByte(r4+0x6); - if (r5 <= cmp1) - { - r5=cmp1; + u8 cmp1 = CPUReadByte(r4 + 0x6); + if (r5 <= cmp1) { + r5 = cmp1; // @todo beq @ 0x1f3a -> ?? - r6--; - CPUWriteByte(r4, r6); - } - } - else if ( (r6 & 0x03) == 3) // 0x1f44 - { -lbl_0x1f46: //@todo check if there is really another path to here - u8 add1 = CPUReadByte(r4+0x4); - r5+=add1; + r6--; + CPUWriteByte(r4, r6); + } + } else if ((r6 & 0x03) == 3) // 0x1f44 + { + lbl_0x1f46: //@todo check if there is really another path to here + u8 add1 = CPUReadByte(r4 + 0x4); + r5 += add1; - if (r5>=0xff) - { - r6--; - r5=0xff; - CPUWriteByte(r4, r6); - } - } - } - { -//lbl_0x1f54: - CPUWriteByte(r4+0x9, r5); + if (r5 >= 0xff) { + r6--; + r5 = 0xff; + CPUWriteByte(r4, r6); + } + } + } + { + //lbl_0x1f54: + CPUWriteByte(r4 + 0x9, r5); - u32 user0 = CPUReadByte(puser1+0x7); // @sp+10 - user0++; - user0*=r5; - r5=user0>>4; + u32 user0 = CPUReadByte(puser1 + 0x7); // @sp+10 + user0++; + user0 *= r5; + r5 = user0 >> 4; - user0 = CPUReadByte(r4+0x2); - user0*=r5; - user0>>=8; - CPUWriteByte(r4+0xA, user0); + user0 = CPUReadByte(r4 + 0x2); + user0 *= r5; + user0 >>= 8; + CPUWriteByte(r4 + 0xA, user0); - user0 = CPUReadByte(r4+0x3); - user0*=r5; - user0>>=8; - CPUWriteByte(r4+0xB, user0); + user0 = CPUReadByte(r4 + 0x3); + user0 *= r5; + user0 >>= 8; + CPUWriteByte(r4 + 0xB, user0); - user0 = r6&0x10; - if ( user0 != 0) // @todo 0x1f76 - { + user0 = r6 & 0x10; + if (user0 != 0) // @todo 0x1f76 + { + } - } + r5 = r5c; // @todo below r5 is used and updated + u32 r2 = CPUReadMemory(r4 + 0x18); + r3 = CPUReadMemory(r4 + 0x28); - r5 = r5c; // @todo below r5 is used and updated - u32 r2 = CPUReadMemory(r4+0x18); - r3 = CPUReadMemory(r4+0x28); + u32 r8 = v2; - u32 r8 = v2; + u8 r10 = CPUReadByte(r4 + 0xA); + u8 r11 = CPUReadByte(r4 + 0xB); + u8 r0a = CPUReadByte(r4 + 0x1); + if ((r0a & 8)) //@todo 0x1fa8 + { + } - u8 r10 = CPUReadByte(r4+0xA); - u8 r11 = CPUReadByte(r4+0xB); - u8 r0a = CPUReadByte(r4+0x1); - if ((r0a & 8)) //@todo 0x1fa8 - { + u32 r7 = CPUReadMemory(r4 + 0x1c); + u32 r14 = CPUReadMemory(r4 + 0x20); - } - - u32 r7 = CPUReadMemory(r4+0x1c); - u32 r14 = CPUReadMemory(r4+0x20); - -lbl_0x2004:// LABEL_52: - while ( r7 >= 4 * r9 ) - { - if ( r2 <= 4 )// @todo 0x2008, no phant - goto lbl_204c; - r2 -= 4; - r3 += 4; - r7 -= 4 * r9; - } - if ( r7 >= 2 * r9 ) - { - if ( r2 <= 2 ) // @todo 0x2008, no phant - goto lbl_204c; - r2 -= 2; - r3 += 2; - r7 -= 2 * r9; - } - if ( r7 < r9 ) - goto lbl_207c; - do - { -lbl_204c: // LABEL_59: - --r2; - if ( r2 ) - { - ++r3; - } - else - { - r2 = user0; //0x2054 - if ( r2 ) - { - r3 = CPUReadMemory(reg[13].I+0xC); // @todo stack pull 0x205c - } - else - { + lbl_0x2004: // LABEL_52: + while (r7 >= 4 * r9) { + if (r2 <= 4) // @todo 0x2008, no phant + goto lbl_204c; + r2 -= 4; + r3 += 4; + r7 -= 4 * r9; + } + if (r7 >= 2 * r9) { + if (r2 <= 2) // @todo 0x2008, no phant + goto lbl_204c; + r2 -= 2; + r3 += 2; + r7 -= 2 * r9; + } + if (r7 < r9) + goto lbl_207c; + do { + lbl_204c: // LABEL_59: + --r2; + if (r2) { + ++r3; + } else { + r2 = user0; //0x2054 + if (r2) { + r3 = CPUReadMemory(reg[13].I + 0xC); // @todo stack pull 0x205c + } else { CPUWriteByte(r4, r2); goto lbl_20e4; } - } - r7 -= r9; - } while ( r7 >= r9 ); -lbl_207c: - while ( 1 ) - { - s32 r0a = CPUReadByte(r3); - s32 r1a = CPUReadByte(r3+0x1); + } + r7 -= r9; + } while (r7 >= r9); + lbl_207c: + while (1) { + s32 r0a = CPUReadByte(r3); + s32 r1a = CPUReadByte(r3 + 0x1); - r1a-=r0a; - s32 r6a = r1a*(s32)r7; - r1a = r6a * r12; // 208c - r6a = (r0a + ((s8)(r1a>>23))); + r1a -= r0a; + s32 r6a = r1a * (s32)r7; + r1a = r6a * r12; // 208c + r6a = (r0a + ((s8)(r1a >> 23))); - r1a = r6a * (s32)r11; + r1a = r6a * (s32)r11; - r0a = CPUReadByte(r5 + 0x630); - r0a = (r0a + ((s8)(r1a>>8))); + r0a = CPUReadByte(r5 + 0x630); + r0a = (r0a + ((s8)(r1a >> 8))); CPUWriteByte(r5 + 0x630, r0a); r1a = r6a * (s32)r10; r0a = CPUReadByte(r5); - r0a = (r0a + ((s8)(r1a>>8))); + r0a = (r0a + ((s8)(r1a >> 8))); CPUWriteByte(r5++, r0a); //ptr inc +1 not +4 - r7+=r14; - --r8; - if ( !r8 ) - break; - if ( r7 >= r9 ) - goto lbl_0x2004; - } + r7 += r14; + --r8; + if (!r8) + break; + if (r7 >= r9) + goto lbl_0x2004; + } - CPUWriteMemory(r4+0x1c, r7); -//lbl_20cc: - CPUWriteMemory(r4+0x18, r2); - CPUWriteMemory(r4+0x28, r3); - } -lbl_20e4: + CPUWriteMemory(r4 + 0x1c, r7); + //lbl_20cc: + CPUWriteMemory(r4 + 0x18, r2); + CPUWriteMemory(r4 + 0x28, r3); + } + lbl_20e4: (void)r5; - } + } // 0x20EE CPUWriteMemory(puser1, 0x68736D53); // this guard is common for funcs, unify @@ -1717,20 +1668,18 @@ void BIOS_SndDriverVSync() u32 const puser1 = CPUReadMemory(0x3007FF0); // @todo some sound area, make it common. u32 const user1 = CPUReadMemory(puser1); - if ( user1 == 0x68736D53 ) - { - u8 v1 = CPUReadByte(puser1+4); - s8 v1i = v1-1; - CPUWriteByte(puser1+4, v1i); - if ( v1 <= 1 ) - { - u8 v2 = CPUReadByte(puser1+0xB); //11 + if (user1 == 0x68736D53) { + u8 v1 = CPUReadByte(puser1 + 4); + s8 v1i = v1 - 1; + CPUWriteByte(puser1 + 4, v1i); + if (v1 <= 1) { + u8 v2 = CPUReadByte(puser1 + 0xB); //11 u32 base2 = 0x040000D2; - CPUWriteByte(puser1+4, v2); + CPUWriteByte(puser1 + 4, v2); - CPUWriteHalfWord(base1+0x6 , 0); + CPUWriteHalfWord(base1 + 0x6, 0); CPUWriteHalfWord(base2, 0); - CPUWriteHalfWord(base1+0x6 , 0xB600); + CPUWriteHalfWord(base1 + 0x6, 0xB600); CPUWriteHalfWord(base2, 0xB600); //-18944 } } @@ -1741,22 +1690,21 @@ void BIOS_SndDriverVSyncOff() // 0x1878 u32 const puser1 = CPUReadMemory(0x3007FF0); // 7FC0 + 0x30 u32 user1 = CPUReadMemory(puser1); - if ( user1 == 0x68736D53 || user1 == 0x68736D54 ) - { + if (user1 == 0x68736D53 || user1 == 0x68736D54) { CPUWriteMemory(puser1, (++user1)); // this guard is common for funcs, unify - CPUWriteHalfWord(base1+0x6 , 0); - CPUWriteHalfWord(base1+0x12 , 0); - CPUWriteByte(puser1+4, 0); + CPUWriteHalfWord(base1 + 0x6, 0); + CPUWriteHalfWord(base1 + 0x12, 0); + CPUWriteByte(puser1 + 4, 0); - u32 r1 = puser1+0x350; + u32 r1 = puser1 + 0x350; u32 r2 = 0x05000318; u32 sp = reg[13].I; //0x03003c94; CPUWriteMemory(sp, 0); BIOS_SndDriver_b4c(sp, r1, r2); - user1 = CPUReadMemory(puser1); // 0x18aa + user1 = CPUReadMemory(puser1); // 0x18aa CPUWriteMemory(puser1, (--user1)); // this ret is common among funcs } //0x18b0 @@ -1770,40 +1718,36 @@ void BIOS_SndChannelClear() //0x1824 u32 const puser1 = CPUReadMemory(0x3007FF0); // 7FC0 + 0x30 u32 user1 = CPUReadMemory(puser1); - if ( user1 == 0x68736D53 ) - { + if (user1 == 0x68736D53) { CPUWriteMemory(puser1, (++user1)); u32 puser2 = puser1 + 0x7 + 0x49; - int count=12; - while (count--) - { + int count = 12; + while (count--) { CPUWriteByte(puser2, 0); - puser2+=0x40; + puser2 += 0x40; } reg[4].I = CPUReadMemory(puser1 + 0x1c); //r5 -> some user thing - if ( reg[4].I != 0 ) - { + if (reg[4].I != 0) { reg[3].I = 1; // r4 -> channel counter? int puser4 = puser1 + 0x2c; //reg[0].I = reg[3].I = 1; // r0 & r4 => 1 - while (reg[3].I <= 4) - { - // @todo does user func modify these? - reg[0].I = reg[3].I << 24; - reg[0].I >>= 24; + while (reg[3].I <= 4) { + // @todo does user func modify these? + reg[0].I = reg[3].I << 24; + reg[0].I >>= 24; - // Get ptr to user func - reg[1].I = CPUReadMemory(puser4); + // Get ptr to user func + reg[1].I = CPUReadMemory(puser4); - // @todo here we jump where r1 points; user func? - // @todo might modify r6 also? + // @todo here we jump where r1 points; user func? + // @todo might modify r6 also? - // After call routines - reg[3].I += 1; // r4 -> channel counter? - reg[4].I += 0x40;// r5 -> some user thing + // After call routines + reg[3].I += 1; // r4 -> channel counter? + reg[4].I += 0x40; // r5 -> some user thing } CPUWriteByte(reg[4].I, 0); // terminating record? } @@ -1814,37 +1758,37 @@ void BIOS_SndChannelClear() //0x1824 void BIOS_MidiKey2Freq() { #ifdef GBA_LOGGING - if(systemVerbose & VERBOSE_SWI) { - log("MidiKey2Freq: WaveData=%08x mk=%08x fp=%08x\n", - reg[0].I, - reg[1].I, - reg[2].I); - } + if (systemVerbose & VERBOSE_SWI) { + log("MidiKey2Freq: WaveData=%08x mk=%08x fp=%08x\n", + reg[0].I, + reg[1].I, + reg[2].I); + } #endif - int freq = CPUReadMemory(reg[0].I+4); - double tmp; - tmp = ((double)(180 - reg[1].I)) - ((double)reg[2].I / 256.f); - tmp = pow((double)2.f, tmp / 12.f); - reg[0].I = (int)((double)freq / tmp); + int freq = CPUReadMemory(reg[0].I + 4); + double tmp; + tmp = ((double)(180 - reg[1].I)) - ((double)reg[2].I / 256.f); + tmp = pow((double)2.f, tmp / 12.f); + reg[0].I = (int)((double)freq / tmp); #ifdef GBA_LOGGING - if(systemVerbose & VERBOSE_SWI) { - log("MidiKey2Freq: return %08x\n", - reg[0].I); - } + if (systemVerbose & VERBOSE_SWI) { + log("MidiKey2Freq: return %08x\n", + reg[0].I); + } #endif } void BIOS_SndDriverJmpTableCopy() { #ifdef GBA_LOGGING - if(systemVerbose & VERBOSE_SWI) { - log("SndDriverJmpTableCopy: dest=%08x\n", - reg[0].I); - } + if (systemVerbose & VERBOSE_SWI) { + log("SndDriverJmpTableCopy: dest=%08x\n", + reg[0].I); + } #endif - for(int i = 0; i < 0x24; i++) { - CPUWriteMemory(reg[0].I, 0x9c); - reg[0].I += 4; - } + for (int i = 0; i < 0x24; i++) { + CPUWriteMemory(reg[0].I, 0x9c); + reg[0].I += 4; + } } diff --git a/src/gba/debugger-expr-lex.cpp b/src/gba/debugger-expr-lex.cpp index d9ec84bb..e3b97b64 100644 --- a/src/gba/debugger-expr-lex.cpp +++ b/src/gba/debugger-expr-lex.cpp @@ -2,7 +2,7 @@ #line 4 "debugger-expr-lex.cpp" -#define YY_INT_ALIGNED short int +#define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ @@ -36,10 +36,10 @@ /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ -#include -#include #include +#include #include +#include #if (defined __WIN32__ || defined _WIN32) #define fileno _fileno @@ -54,7 +54,7 @@ /* C99 systems have . Non-C99 systems may or may not. */ -#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. @@ -74,37 +74,37 @@ typedef uint32_t flex_uint32_t; typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; -typedef unsigned char flex_uint8_t; +typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; /* Limits of integral types. */ #ifndef INT8_MIN -#define INT8_MIN (-128) +#define INT8_MIN (-128) #endif #ifndef INT16_MIN -#define INT16_MIN (-32767-1) +#define INT16_MIN (-32767 - 1) #endif #ifndef INT32_MIN -#define INT32_MIN (-2147483647-1) +#define INT32_MIN (-2147483647 - 1) #endif #ifndef INT8_MAX -#define INT8_MAX (127) +#define INT8_MAX (127) #endif #ifndef INT16_MAX -#define INT16_MAX (32767) +#define INT16_MAX (32767) #endif #ifndef INT32_MAX -#define INT32_MAX (2147483647) +#define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX -#define UINT8_MAX (255U) +#define UINT8_MAX (255U) #endif #ifndef UINT16_MAX -#define UINT16_MAX (65535U) +#define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX -#define UINT32_MAX (4294967295U) +#define UINT32_MAX (4294967295U) #endif #endif /* ! C99 */ @@ -116,15 +116,15 @@ typedef unsigned int flex_uint32_t; /* The "const" storage-class-modifier is valid. */ #define YY_USE_CONST -#else /* ! __cplusplus */ +#else /* ! __cplusplus */ /* C99 requires __STDC__ to be defined as 1. */ -#if defined (__STDC__) +#if defined(__STDC__) #define YY_USE_CONST -#endif /* defined (__STDC__) */ -#endif /* ! __cplusplus */ +#endif /* defined (__STDC__) */ +#endif /* ! __cplusplus */ #ifdef YY_USE_CONST #define yyconst const @@ -140,7 +140,7 @@ typedef unsigned int flex_uint32_t; * we want to instead treat it as an 8-bit unsigned char, hence the * double cast. */ -#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) +#define YY_SC_TO_UI(c) ((unsigned int)(unsigned char)c) /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less @@ -152,14 +152,14 @@ typedef unsigned int flex_uint32_t; * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ -#define YY_START (((yy_start) - 1) / 2) +#define YY_START (((yy_start)-1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ -#define YY_NEW_FILE dexp_restart(dexp_in ) +#define YY_NEW_FILE dexp_restart(dexp_in) #define YY_END_OF_BUFFER_CHAR 0 @@ -178,11 +178,11 @@ typedef unsigned int flex_uint32_t; /* The state buf must be large enough to hold one state per character in the main buffer. */ -#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE -typedef struct yy_buffer_state *YY_BUFFER_STATE; +typedef struct yy_buffer_state* YY_BUFFER_STATE; #endif extern int dexp_leng; @@ -193,23 +193,20 @@ extern FILE *dexp_in, *dexp_out; #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 - #define YY_LESS_LINENO(n) - -/* Return all but the first "n" matched characters back to the input stream. */ -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up dexp_text. */ \ - int yyless_macro_arg = (n); \ - YY_LESS_LINENO(yyless_macro_arg);\ - *yy_cp = (yy_hold_char); \ - YY_RESTORE_YY_MORE_OFFSET \ - (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ - YY_DO_BEFORE_ACTION; /* set up dexp_text again */ \ - } \ - while ( 0 ) +#define YY_LESS_LINENO(n) -#define unput(c) yyunput( c, (yytext_ptr) ) +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do { \ + /* Undo effects of setting up dexp_text. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg); \ + *yy_cp = (yy_hold_char); \ + YY_RESTORE_YY_MORE_OFFSET(yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up dexp_text again */ \ + } while (0) + +#define unput(c) yyunput(c, (yytext_ptr)) #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T @@ -218,55 +215,54 @@ typedef size_t yy_size_t; #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE -struct yy_buffer_state - { - FILE *yy_input_file; +struct yy_buffer_state { + FILE* yy_input_file; - char *yy_ch_buf; /* input buffer */ - char *yy_buf_pos; /* current position in input buffer */ + char* yy_ch_buf; /* input buffer */ + char* yy_buf_pos; /* current position in input buffer */ - /* Size of input buffer in bytes, not including room for EOB + /* Size of input buffer in bytes, not including room for EOB * characters. */ - yy_size_t yy_buf_size; + yy_size_t yy_buf_size; - /* Number of characters read into yy_ch_buf, not including EOB + /* Number of characters read into yy_ch_buf, not including EOB * characters. */ - int yy_n_chars; + int yy_n_chars; - /* Whether we "own" the buffer - i.e., we know we created it, + /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ - int yy_is_our_buffer; + int yy_is_our_buffer; - /* Whether this is an "interactive" input source; if so, and + /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ - int yy_is_interactive; + int yy_is_interactive; - /* Whether we're considered to be at the beginning of a line. + /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ - int yy_at_bol; + int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ - - /* Whether to try to fill the input buffer when we reach the + + /* Whether to try to fill the input buffer when we reach the * end of it. */ - int yy_fill_buffer; + int yy_fill_buffer; - int yy_buffer_status; + int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 - /* When an EOF's been seen but there's still some text to process +/* When an EOF's been seen but there's still some text to process * then we mark the buffer as YY_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of @@ -277,14 +273,13 @@ struct yy_buffer_state * just pointing dexp_in at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 - - }; +}; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ /* Stack of input buffers. */ static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ -static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ +static YY_BUFFER_STATE* yy_buffer_stack = 0; /**< Stack as an array. */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general @@ -292,9 +287,9 @@ static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ * * Returns the top of the stack, or NULL. */ -#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ - ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ - : NULL) +#define YY_CURRENT_BUFFER ((yy_buffer_stack) \ + ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ + : NULL) /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. @@ -303,62 +298,60 @@ static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ /* yy_hold_char holds the character lost when dexp_text is formed. */ static char yy_hold_char; -static int yy_n_chars; /* number of characters read into yy_ch_buf */ +static int yy_n_chars; /* number of characters read into yy_ch_buf */ int dexp_leng; /* Points to current character in buffer. */ -static char *yy_c_buf_p = (char *) 0; -static int yy_init = 0; /* whether we need to initialize */ -static int yy_start = 0; /* start state number */ +static char* yy_c_buf_p = (char*)0; +static int yy_init = 0; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ /* Flag which is used to allow dexp_wrap()'s to do buffer switches * instead of setting up a fresh dexp_in. A bit of a hack ... */ static int yy_did_buffer_switch_on_eof; -void dexp_restart (FILE *input_file ); -void dexp__switch_to_buffer (YY_BUFFER_STATE new_buffer ); -YY_BUFFER_STATE dexp__create_buffer (FILE *file,int size ); -void dexp__delete_buffer (YY_BUFFER_STATE b ); -void dexp__flush_buffer (YY_BUFFER_STATE b ); -void dexp_push_buffer_state (YY_BUFFER_STATE new_buffer ); -void dexp_pop_buffer_state (void ); +void dexp_restart(FILE* input_file); +void dexp__switch_to_buffer(YY_BUFFER_STATE new_buffer); +YY_BUFFER_STATE dexp__create_buffer(FILE* file, int size); +void dexp__delete_buffer(YY_BUFFER_STATE b); +void dexp__flush_buffer(YY_BUFFER_STATE b); +void dexp_push_buffer_state(YY_BUFFER_STATE new_buffer); +void dexp_pop_buffer_state(void); -static void dexp_ensure_buffer_stack (void ); -static void dexp__load_buffer_state (void ); -static void dexp__init_buffer (YY_BUFFER_STATE b,FILE *file ); +static void dexp_ensure_buffer_stack(void); +static void dexp__load_buffer_state(void); +static void dexp__init_buffer(YY_BUFFER_STATE b, FILE* file); -#define YY_FLUSH_BUFFER dexp__flush_buffer(YY_CURRENT_BUFFER ) +#define YY_FLUSH_BUFFER dexp__flush_buffer(YY_CURRENT_BUFFER) -YY_BUFFER_STATE dexp__scan_buffer (char *base,yy_size_t size ); -YY_BUFFER_STATE dexp__scan_string (yyconst char *yy_str ); -YY_BUFFER_STATE dexp__scan_bytes (yyconst char *bytes,int len ); +YY_BUFFER_STATE dexp__scan_buffer(char* base, yy_size_t size); +YY_BUFFER_STATE dexp__scan_string(yyconst char* yy_str); +YY_BUFFER_STATE dexp__scan_bytes(yyconst char* bytes, int len); -void *dexp_alloc (yy_size_t ); -void *dexp_realloc (void *,yy_size_t ); -void dexp_free (void * ); +void* dexp_alloc(yy_size_t); +void* dexp_realloc(void*, yy_size_t); +void dexp_free(void*); #define yy_new_buffer dexp__create_buffer -#define yy_set_interactive(is_interactive) \ - { \ - if ( ! YY_CURRENT_BUFFER ){ \ - dexp_ensure_buffer_stack (); \ - YY_CURRENT_BUFFER_LVALUE = \ - dexp__create_buffer(dexp_in,YY_BUF_SIZE ); \ - } \ - YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ - } +#define yy_set_interactive(is_interactive) \ + { \ + if (!YY_CURRENT_BUFFER) { \ + dexp_ensure_buffer_stack(); \ + YY_CURRENT_BUFFER_LVALUE = dexp__create_buffer(dexp_in, YY_BUF_SIZE); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } -#define yy_set_bol(at_bol) \ - { \ - if ( ! YY_CURRENT_BUFFER ){\ - dexp_ensure_buffer_stack (); \ - YY_CURRENT_BUFFER_LVALUE = \ - dexp__create_buffer(dexp_in,YY_BUF_SIZE ); \ - } \ - YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ - } +#define yy_set_bol(at_bol) \ + { \ + if (!YY_CURRENT_BUFFER) { \ + dexp_ensure_buffer_stack(); \ + YY_CURRENT_BUFFER_LVALUE = dexp__create_buffer(dexp_in, YY_BUF_SIZE); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) @@ -369,7 +362,7 @@ void dexp_free (void * ); typedef unsigned char YY_CHAR; -FILE *dexp_in = (FILE *) 0, *dexp_out = (FILE *) 0; +FILE *dexp_in = (FILE *)0, *dexp_out = (FILE *)0; typedef int yy_state_type; @@ -377,136 +370,121 @@ extern int dexp_lineno; int dexp_lineno = 1; -extern char *dexp_text; +extern char* dexp_text; #define yytext_ptr dexp_text -static yy_state_type yy_get_previous_state (void ); -static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); -static int yy_get_next_buffer (void ); -static void yy_fatal_error (yyconst char msg[] ); +static yy_state_type yy_get_previous_state(void); +static yy_state_type yy_try_NUL_trans(yy_state_type current_state); +static int yy_get_next_buffer(void); +static void yy_fatal_error(yyconst char msg[]); /* Done after the current pattern has been matched and before the * corresponding action - sets up dexp_text. */ -#define YY_DO_BEFORE_ACTION \ - (yytext_ptr) = yy_bp; \ - dexp_leng = (size_t) (yy_cp - yy_bp); \ - (yy_hold_char) = *yy_cp; \ - *yy_cp = '\0'; \ - (yy_c_buf_p) = yy_cp; +#define YY_DO_BEFORE_ACTION \ + (yytext_ptr) = yy_bp; \ + dexp_leng = (size_t)(yy_cp - yy_bp); \ + (yy_hold_char) = *yy_cp; \ + *yy_cp = '\0'; \ + (yy_c_buf_p) = yy_cp; #define YY_NUM_RULES 30 #define YY_END_OF_BUFFER 31 /* This struct is not used in this scanner, but its presence is necessary. */ -struct yy_trans_info - { - flex_int32_t yy_verify; - flex_int32_t yy_nxt; - }; -static yyconst flex_int16_t yy_accept[51] = - { 0, - 0, 0, 31, 28, 30, 27, 25, 28, 23, 20, - 21, 17, 14, 15, 16, 11, 10, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 9, 8, 24, 28, - 22, 26, 13, 11, 0, 10, 18, 19, 29, 5, - 6, 3, 4, 2, 7, 1, 1, 1, 12, 0 - } ; +struct yy_trans_info { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; +}; +static yyconst flex_int16_t yy_accept[51] = { 0, + 0, 0, 31, 28, 30, 27, 25, 28, 23, 20, + 21, 17, 14, 15, 16, 11, 10, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 9, 8, 24, 28, + 22, 26, 13, 11, 0, 10, 18, 19, 29, 5, + 6, 3, 4, 2, 7, 1, 1, 1, 12, 0 }; -static yyconst flex_int32_t yy_ec[256] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 3, 4, 1, 1, 5, 1, 6, 1, 7, - 8, 9, 10, 1, 11, 1, 12, 13, 14, 15, - 15, 15, 15, 16, 16, 16, 16, 1, 1, 17, - 1, 18, 1, 1, 19, 20, 21, 19, 19, 19, - 22, 23, 22, 22, 22, 24, 22, 22, 22, 25, - 22, 26, 27, 22, 22, 22, 28, 29, 22, 22, - 30, 1, 31, 32, 22, 1, 19, 20, 21, 19, +static yyconst flex_int32_t yy_ec[256] = { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 3, 4, 1, 1, 5, 1, 6, 1, 7, + 8, 9, 10, 1, 11, 1, 12, 13, 14, 15, + 15, 15, 15, 16, 16, 16, 16, 1, 1, 17, + 1, 18, 1, 1, 19, 20, 21, 19, 19, 19, + 22, 23, 22, 22, 22, 24, 22, 22, 22, 25, + 22, 26, 27, 22, 22, 22, 28, 29, 22, 22, + 30, 1, 31, 32, 22, 1, 19, 20, 21, 19, - 19, 19, 22, 23, 22, 22, 22, 24, 22, 22, - 22, 25, 22, 33, 27, 22, 22, 22, 28, 29, - 22, 22, 1, 34, 1, 35, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 19, 19, 22, 23, 22, 22, 22, 24, 22, 22, + 22, 25, 22, 33, 27, 22, 22, 22, 28, 29, + 22, 22, 1, 34, 1, 35, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1 - } ; + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 }; -static yyconst flex_int32_t yy_meta[36] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 2, 2, 2, 2, 1, 1, 2, 2, - 2, 3, 3, 3, 3, 3, 3, 3, 4, 1, - 1, 1, 3, 1, 1 - } ; +static yyconst flex_int32_t yy_meta[36] = { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 2, 2, 2, 2, 1, 1, 2, 2, + 2, 3, 3, 3, 3, 3, 3, 3, 4, 1, + 1, 1, 3, 1, 1 }; -static yyconst flex_int16_t yy_base[55] = - { 0, - 0, 0, 71, 72, 72, 72, 72, 0, 72, 72, - 72, 72, 72, 72, 72, 41, 23, 52, 50, 0, - 37, 36, 14, 44, 39, 33, 72, 72, 72, 28, - 72, 72, 0, 33, 0, 35, 72, 72, 0, 72, - 72, 0, 0, 0, 72, 32, 39, 0, 0, 72, - 55, 54, 57, 52 - } ; +static yyconst flex_int16_t yy_base[55] = { 0, + 0, 0, 71, 72, 72, 72, 72, 0, 72, 72, + 72, 72, 72, 72, 72, 41, 23, 52, 50, 0, + 37, 36, 14, 44, 39, 33, 72, 72, 72, 28, + 72, 72, 0, 33, 0, 35, 72, 72, 0, 72, + 72, 0, 0, 0, 72, 32, 39, 0, 0, 72, + 55, 54, 57, 52 }; -static yyconst flex_int16_t yy_def[55] = - { 0, - 50, 1, 50, 50, 50, 50, 50, 51, 50, 50, - 50, 50, 50, 50, 50, 52, 50, 50, 50, 53, - 53, 53, 53, 53, 53, 53, 50, 50, 50, 53, - 50, 50, 51, 52, 54, 50, 50, 50, 53, 50, - 50, 53, 53, 53, 50, 30, 30, 53, 54, 0, - 50, 50, 50, 50 - } ; +static yyconst flex_int16_t yy_def[55] = { 0, + 50, 1, 50, 50, 50, 50, 50, 51, 50, 50, + 50, 50, 50, 50, 50, 52, 50, 50, 50, 53, + 53, 53, 53, 53, 53, 53, 50, 50, 50, 53, + 50, 50, 51, 52, 54, 50, 50, 50, 53, 50, + 50, 53, 53, 53, 50, 30, 30, 53, 54, 0, + 50, 50, 50, 50 }; -static yyconst flex_int16_t yy_nxt[108] = - { 0, - 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 17, 17, 17, 18, 19, 20, 21, - 20, 20, 22, 23, 24, 20, 25, 26, 20, 27, - 28, 29, 30, 31, 32, 36, 36, 36, 36, 42, - 46, 47, 48, 48, 48, 48, 42, 36, 36, 36, - 36, 48, 48, 49, 39, 34, 33, 34, 39, 39, - 39, 50, 45, 44, 43, 41, 40, 38, 37, 35, - 50, 3, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, +static yyconst flex_int16_t yy_nxt[108] = { 0, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17, 17, 17, 18, 19, 20, 21, + 20, 20, 22, 23, 24, 20, 25, 26, 20, 27, + 28, 29, 30, 31, 32, 36, 36, 36, 36, 42, + 46, 47, 48, 48, 48, 48, 42, 36, 36, 36, + 36, 48, 48, 49, 39, 34, 33, 34, 39, 39, + 39, 50, 45, 44, 43, 41, 40, 38, 37, 35, + 50, 3, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50 - } ; + 50, 50, 50, 50, 50, 50, 50 }; -static yyconst flex_int16_t yy_chk[108] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 17, 17, 17, 17, 23, - 30, 30, 30, 30, 46, 46, 23, 36, 36, 36, - 36, 47, 47, 54, 47, 52, 51, 52, 53, 53, - 53, 34, 26, 25, 24, 22, 21, 19, 18, 16, - 3, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, +static yyconst flex_int16_t yy_chk[108] = { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 17, 17, 17, 17, 23, + 30, 30, 30, 30, 46, 46, 23, 36, 36, 36, + 36, 47, 47, 54, 47, 52, 51, 52, 53, 53, + 53, 34, 26, 25, 24, 22, 21, 19, 18, 16, + 3, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50 - } ; + 50, 50, 50, 50, 50, 50, 50 }; static yy_state_type yy_last_accepting_state; -static char *yy_last_accepting_cpos; +static char* yy_last_accepting_cpos; extern int dexp__flex_debug; int dexp__flex_debug = 0; @@ -518,12 +496,12 @@ int dexp__flex_debug = 0; #define yymore() yymore_used_but_not_detected #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET -char *dexp_text; +char* dexp_text; #line 1 "debugger-expr.l" #line 2 "debugger-expr.l" +#include "debugger-expr-yacc.hpp" #include #include -#include "debugger-expr-yacc.hpp" #ifdef _MSC_VER #define YY_NO_UNISTD_H @@ -533,14 +511,14 @@ char *dexp_text; extern YYSTYPE dexp_lval; -char *dexprString; +char* dexprString; int dexprCol; -#define YY_INPUT(buf,result,max_size) \ - { \ - int c = *dexprString++; \ - dexprCol++;\ - result = (c == 0) ? YY_NULL : (buf[0] = c, 1); \ +#define YY_INPUT(buf, result, max_size) \ + { \ + int c = *dexprString++; \ + dexprCol++; \ + result = (c == 0) ? YY_NULL : (buf[0] = c, 1); \ } #line 543 "debugger-expr-lex.cpp" @@ -556,39 +534,39 @@ int dexprCol; #endif #ifndef YY_EXTRA_TYPE -#define YY_EXTRA_TYPE void * +#define YY_EXTRA_TYPE void* #endif -static int yy_init_globals (void ); +static int yy_init_globals(void); /* Accessor methods to globals. These are made visible to non-reentrant scanners for convenience. */ -int dexp_lex_destroy (void ); +int dexp_lex_destroy(void); -int dexp_get_debug (void ); +int dexp_get_debug(void); -void dexp_set_debug (int debug_flag ); +void dexp_set_debug(int debug_flag); -YY_EXTRA_TYPE dexp_get_extra (void ); +YY_EXTRA_TYPE dexp_get_extra(void); -void dexp_set_extra (YY_EXTRA_TYPE user_defined ); +void dexp_set_extra(YY_EXTRA_TYPE user_defined); -FILE *dexp_get_in (void ); +FILE* dexp_get_in(void); -void dexp_set_in (FILE * in_str ); +void dexp_set_in(FILE* in_str); -FILE *dexp_get_out (void ); +FILE* dexp_get_out(void); -void dexp_set_out (FILE * out_str ); +void dexp_set_out(FILE* out_str); -int dexp_get_leng (void ); +int dexp_get_leng(void); -char *dexp_get_text (void ); +char* dexp_get_text(void); -int dexp_get_lineno (void ); +int dexp_get_lineno(void); -void dexp_set_lineno (int line_number ); +void dexp_set_lineno(int line_number); /* Macros after this point can all be overridden by user definitions in * section 1. @@ -596,28 +574,28 @@ void dexp_set_lineno (int line_number ); #ifndef YY_SKIP_YYWRAP #ifdef __cplusplus -extern "C" int dexp_wrap (void ); +extern "C" int dexp_wrap(void); #else -extern int dexp_wrap (void ); +extern int dexp_wrap(void); #endif #endif - static void yyunput (int c,char *buf_ptr ); - +static void yyunput(int c, char* buf_ptr); + #ifndef yytext_ptr -static void yy_flex_strncpy (char *,yyconst char *,int ); +static void yy_flex_strncpy(char*, yyconst char*, int); #endif #ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * ); +static int yy_flex_strlen(yyconst char*); #endif #ifndef YY_NO_INPUT #ifdef __cplusplus -static int yyinput (void ); +static int yyinput(void); #else -static int input (void ); +static int input(void); #endif #endif @@ -637,42 +615,39 @@ static int input (void ); /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ -#define ECHO do { if (fwrite( dexp_text, dexp_leng, 1, dexp_out )) {} } while (0) +#define ECHO \ + do { \ + if (fwrite(dexp_text, dexp_leng, 1, dexp_out)) { \ + } \ + } while (0) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ #ifndef YY_INPUT -#define YY_INPUT(buf,result,max_size) \ - if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ - { \ - int c = '*'; \ - size_t n; \ - for ( n = 0; n < max_size && \ - (c = getc( dexp_in )) != EOF && c != '\n'; ++n ) \ - buf[n] = (char) c; \ - if ( c == '\n' ) \ - buf[n++] = (char) c; \ - if ( c == EOF && ferror( dexp_in ) ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - result = n; \ - } \ - else \ - { \ - errno=0; \ - while ( (result = fread(buf, 1, max_size, dexp_in))==0 && ferror(dexp_in)) \ - { \ - if( errno != EINTR) \ - { \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - break; \ - } \ - errno=0; \ - clearerr(dexp_in); \ - } \ - }\ -\ +#define YY_INPUT(buf, result, max_size) \ + if (YY_CURRENT_BUFFER_LVALUE->yy_is_interactive) { \ + int c = '*'; \ + size_t n; \ + for (n = 0; n < max_size && (c = getc(dexp_in)) != EOF && c != '\n'; ++n) \ + buf[n] = (char)c; \ + if (c == '\n') \ + buf[n++] = (char)c; \ + if (c == EOF && ferror(dexp_in)) \ + YY_FATAL_ERROR("input in flex scanner failed"); \ + result = n; \ + } else { \ + errno = 0; \ + while ((result = fread(buf, 1, max_size, dexp_in)) == 0 && ferror(dexp_in)) { \ + if (errno != EINTR) { \ + YY_FATAL_ERROR("input in flex scanner failed"); \ + break; \ + } \ + errno = 0; \ + clearerr(dexp_in); \ + } \ + } #endif @@ -691,7 +666,7 @@ static int input (void ); /* Report a fatal error. */ #ifndef YY_FATAL_ERROR -#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +#define YY_FATAL_ERROR(msg) yy_fatal_error(msg) #endif /* end tables serialization structures and prototypes */ @@ -702,9 +677,9 @@ static int input (void ); #ifndef YY_DECL #define YY_DECL_IS_OURS 1 -extern int dexp_lex (void); +extern int dexp_lex(void); -#define YY_DECL int dexp_lex (void) +#define YY_DECL int dexp_lex(void) #endif /* !YY_DECL */ /* Code executed at the beginning of each rule, after dexp_text and dexp_leng @@ -720,267 +695,266 @@ extern int dexp_lex (void); #endif #define YY_RULE_SETUP \ - YY_USER_ACTION + YY_USER_ACTION /** The main scanner function which does all the work. */ YY_DECL { - register yy_state_type yy_current_state; - register char *yy_cp, *yy_bp; - register int yy_act; - + register yy_state_type yy_current_state; + register char *yy_cp, *yy_bp; + register int yy_act; + #line 31 "debugger-expr.l" #line 732 "debugger-expr-lex.cpp" - if ( !(yy_init) ) - { - (yy_init) = 1; + if (!(yy_init)) { + (yy_init) = 1; #ifdef YY_USER_INIT - YY_USER_INIT; + YY_USER_INIT; #endif - if ( ! (yy_start) ) - (yy_start) = 1; /* first start state */ + if (!(yy_start)) + (yy_start) = 1; /* first start state */ - if ( ! dexp_in ) - dexp_in = stdin; + if (!dexp_in) + dexp_in = stdin; - if ( ! dexp_out ) - dexp_out = stdout; + if (!dexp_out) + dexp_out = stdout; - if ( ! YY_CURRENT_BUFFER ) { - dexp_ensure_buffer_stack (); - YY_CURRENT_BUFFER_LVALUE = - dexp__create_buffer(dexp_in,YY_BUF_SIZE ); - } + if (!YY_CURRENT_BUFFER) { + dexp_ensure_buffer_stack(); + YY_CURRENT_BUFFER_LVALUE = dexp__create_buffer(dexp_in, YY_BUF_SIZE); + } - dexp__load_buffer_state( ); - } + dexp__load_buffer_state(); + } - while ( 1 ) /* loops until end-of-file is reached */ - { - yy_cp = (yy_c_buf_p); + while (1) /* loops until end-of-file is reached */ + { + yy_cp = (yy_c_buf_p); - /* Support of dexp_text. */ - *yy_cp = (yy_hold_char); + /* Support of dexp_text. */ + *yy_cp = (yy_hold_char); - /* yy_bp points to the position in yy_ch_buf of the start of + /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ - yy_bp = yy_cp; + yy_bp = yy_cp; - yy_current_state = (yy_start); -yy_match: - do - { - register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; - if ( yy_accept[yy_current_state] ) - { - (yy_last_accepting_state) = yy_current_state; - (yy_last_accepting_cpos) = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 51 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - ++yy_cp; - } - while ( yy_base[yy_current_state] != 72 ); + yy_current_state = (yy_start); + yy_match: + do { + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + if (yy_accept[yy_current_state]) { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while (yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state) { + yy_current_state = (int)yy_def[yy_current_state]; + if (yy_current_state >= 51) + yy_c = yy_meta[(unsigned int)yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int)yy_c]; + ++yy_cp; + } while (yy_base[yy_current_state] != 72); -yy_find_action: - yy_act = yy_accept[yy_current_state]; - if ( yy_act == 0 ) - { /* have to back up */ - yy_cp = (yy_last_accepting_cpos); - yy_current_state = (yy_last_accepting_state); - yy_act = yy_accept[yy_current_state]; - } + yy_find_action: + yy_act = yy_accept[yy_current_state]; + if (yy_act == 0) { /* have to back up */ + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + yy_act = yy_accept[yy_current_state]; + } - YY_DO_BEFORE_ACTION; + YY_DO_BEFORE_ACTION; -do_action: /* This label is used only to access EOF actions. */ + do_action: /* This label is used only to access EOF actions. */ - switch ( yy_act ) - { /* beginning of action switch */ - case 0: /* must back up */ - /* undo the effects of YY_DO_BEFORE_ACTION */ - *yy_cp = (yy_hold_char); - yy_cp = (yy_last_accepting_cpos); - yy_current_state = (yy_last_accepting_state); - goto yy_find_action; + switch (yy_act) { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = (yy_hold_char); + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + goto yy_find_action; -case 1: -YY_RULE_SETUP + case 1: + YY_RULE_SETUP #line 32 "debugger-expr.l" -dexp_lval.number=atoi((char *)(dexp_text+1)); return TOK_REGISTER; - YY_BREAK -case 2: -YY_RULE_SETUP + dexp_lval.number = atoi((char*)(dexp_text + 1)); + return TOK_REGISTER; + YY_BREAK + case 2: + YY_RULE_SETUP #line 33 "debugger-expr.l" -dexp_lval.number = 13; return TOK_REGISTER; - YY_BREAK -case 3: -YY_RULE_SETUP + dexp_lval.number = 13; + return TOK_REGISTER; + YY_BREAK + case 3: + YY_RULE_SETUP #line 34 "debugger-expr.l" -dexp_lval.number = 14; return TOK_REGISTER; - YY_BREAK -case 4: -YY_RULE_SETUP + dexp_lval.number = 14; + return TOK_REGISTER; + YY_BREAK + case 4: + YY_RULE_SETUP #line 35 "debugger-expr.l" -dexp_lval.number = 15; return TOK_REGISTER; - YY_BREAK -case 5: -YY_RULE_SETUP + dexp_lval.number = 15; + return TOK_REGISTER; + YY_BREAK + case 5: + YY_RULE_SETUP #line 36 "debugger-expr.l" -return TOK_BBRACKET; - YY_BREAK -case 6: -YY_RULE_SETUP + return TOK_BBRACKET; + YY_BREAK + case 6: + YY_RULE_SETUP #line 37 "debugger-expr.l" -return TOK_HBRACKET; - YY_BREAK -case 7: -YY_RULE_SETUP + return TOK_HBRACKET; + YY_BREAK + case 7: + YY_RULE_SETUP #line 38 "debugger-expr.l" -return TOK_WBRACKET; - YY_BREAK -case 8: -YY_RULE_SETUP + return TOK_WBRACKET; + YY_BREAK + case 8: + YY_RULE_SETUP #line 39 "debugger-expr.l" -return TOK_RBRACKET; - YY_BREAK -case 9: -YY_RULE_SETUP + return TOK_RBRACKET; + YY_BREAK + case 9: + YY_RULE_SETUP #line 40 "debugger-expr.l" -return TOK_LBRACKET; - YY_BREAK -case 10: -YY_RULE_SETUP + return TOK_LBRACKET; + YY_BREAK + case 10: + YY_RULE_SETUP #line 41 "debugger-expr.l" -dexp_lval.number=atoi(dexp_text); return TOK_NUMBER; - YY_BREAK -case 11: -YY_RULE_SETUP + dexp_lval.number = atoi(dexp_text); + return TOK_NUMBER; + YY_BREAK + case 11: + YY_RULE_SETUP #line 42 "debugger-expr.l" -sscanf(dexp_text, "%x", &dexp_lval.number); return TOK_NUMBER; - YY_BREAK -case 12: -YY_RULE_SETUP + sscanf(dexp_text, "%x", &dexp_lval.number); + return TOK_NUMBER; + YY_BREAK + case 12: + YY_RULE_SETUP #line 43 "debugger-expr.l" -sscanf((char *)(dexp_text + 2), "%x", &dexp_lval.number); return TOK_NUMBER; - YY_BREAK -case 13: -YY_RULE_SETUP + sscanf((char*)(dexp_text + 2), "%x", &dexp_lval.number); + return TOK_NUMBER; + YY_BREAK + case 13: + YY_RULE_SETUP #line 44 "debugger-expr.l" -sscanf((char *)(dexp_text + 1), "%x", &dexp_lval.number); return TOK_NUMBER; - YY_BREAK -case 14: -YY_RULE_SETUP + sscanf((char*)(dexp_text + 1), "%x", &dexp_lval.number); + return TOK_NUMBER; + YY_BREAK + case 14: + YY_RULE_SETUP #line 45 "debugger-expr.l" -return TOK_PLUS; - YY_BREAK -case 15: -YY_RULE_SETUP + return TOK_PLUS; + YY_BREAK + case 15: + YY_RULE_SETUP #line 46 "debugger-expr.l" -return TOK_MINUS; - YY_BREAK -case 16: -YY_RULE_SETUP + return TOK_MINUS; + YY_BREAK + case 16: + YY_RULE_SETUP #line 47 "debugger-expr.l" -return TOK_DIVIDE; - YY_BREAK -case 17: -YY_RULE_SETUP + return TOK_DIVIDE; + YY_BREAK + case 17: + YY_RULE_SETUP #line 48 "debugger-expr.l" -return TOK_MULTIPLY; - YY_BREAK -case 18: -YY_RULE_SETUP + return TOK_MULTIPLY; + YY_BREAK + case 18: + YY_RULE_SETUP #line 49 "debugger-expr.l" -return TOK_LSHIFT; - YY_BREAK -case 19: -YY_RULE_SETUP + return TOK_LSHIFT; + YY_BREAK + case 19: + YY_RULE_SETUP #line 50 "debugger-expr.l" -return TOK_RSHIFT; - YY_BREAK -case 20: -YY_RULE_SETUP + return TOK_RSHIFT; + YY_BREAK + case 20: + YY_RULE_SETUP #line 51 "debugger-expr.l" -return TOK_LPAREN; - YY_BREAK -case 21: -YY_RULE_SETUP + return TOK_LPAREN; + YY_BREAK + case 21: + YY_RULE_SETUP #line 52 "debugger-expr.l" -return TOK_RPAREN; - YY_BREAK -case 22: -YY_RULE_SETUP + return TOK_RPAREN; + YY_BREAK + case 22: + YY_RULE_SETUP #line 53 "debugger-expr.l" -return TOK_OR; - YY_BREAK -case 23: -YY_RULE_SETUP + return TOK_OR; + YY_BREAK + case 23: + YY_RULE_SETUP #line 54 "debugger-expr.l" -return TOK_AND; - YY_BREAK -case 24: -YY_RULE_SETUP + return TOK_AND; + YY_BREAK + case 24: + YY_RULE_SETUP #line 55 "debugger-expr.l" -return TOK_XOR; - YY_BREAK -case 25: -YY_RULE_SETUP + return TOK_XOR; + YY_BREAK + case 25: + YY_RULE_SETUP #line 56 "debugger-expr.l" -return TOK_NEGATE; - YY_BREAK -case 26: -YY_RULE_SETUP + return TOK_NEGATE; + YY_BREAK + case 26: + YY_RULE_SETUP #line 57 "debugger-expr.l" -return TOK_NEGATE; - YY_BREAK -case 27: -YY_RULE_SETUP + return TOK_NEGATE; + YY_BREAK + case 27: + YY_RULE_SETUP #line 58 "debugger-expr.l" -; - YY_BREAK -case 28: -YY_RULE_SETUP + ; + YY_BREAK + case 28: + YY_RULE_SETUP #line 59 "debugger-expr.l" -printf("Unrecognised token: %s\n", dexp_text); - YY_BREAK -case 29: -YY_RULE_SETUP + printf("Unrecognised token: %s\n", dexp_text); + YY_BREAK + case 29: + YY_RULE_SETUP #line 60 "debugger-expr.l" -dexp_lval.string=dexp_text; return TOK_ID; - YY_BREAK -case 30: -YY_RULE_SETUP + dexp_lval.string = dexp_text; + return TOK_ID; + YY_BREAK + case 30: + YY_RULE_SETUP #line 62 "debugger-expr.l" -ECHO; - YY_BREAK + ECHO; + YY_BREAK #line 965 "debugger-expr-lex.cpp" -case YY_STATE_EOF(INITIAL): - yyterminate(); + case YY_STATE_EOF(INITIAL): + yyterminate(); - case YY_END_OF_BUFFER: - { - /* Amount of text matched not including the EOB char. */ - int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; + case YY_END_OF_BUFFER: { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int)(yy_cp - (yytext_ptr)) - 1; - /* Undo the effects of YY_DO_BEFORE_ACTION. */ - *yy_cp = (yy_hold_char); - YY_RESTORE_YY_MORE_OFFSET + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = (yy_hold_char); + YY_RESTORE_YY_MORE_OFFSET - if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) - { - /* We're scanning a new file or input source. It's + if (YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW) { + /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed dexp_in at a new source and called * dexp_lex(). If so, then we have to assure @@ -989,27 +963,26 @@ case YY_STATE_EOF(INITIAL): * this is the first action (other than possibly a * back-up) that will match for the new input source. */ - (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; - YY_CURRENT_BUFFER_LVALUE->yy_input_file = dexp_in; - YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; - } + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = dexp_in; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } - /* Note that here we test for yy_c_buf_p "<=" to the position + /* Note that here we test for yy_c_buf_p "<=" to the position * of the first EOB in the buffer, since yy_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ - if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) - { /* This was really a NUL. */ - yy_state_type yy_next_state; + if ((yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]) { /* This was really a NUL. */ + yy_state_type yy_next_state; - (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; + (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; - yy_current_state = yy_get_previous_state( ); + yy_current_state = yy_get_previous_state(); - /* Okay, we're now positioned to make the NUL + /* Okay, we're now positioned to make the NUL * transition. We couldn't have * yy_get_previous_state() go ahead and do it * for us because it doesn't know how to deal @@ -1018,34 +991,30 @@ case YY_STATE_EOF(INITIAL): * will run more slowly). */ - yy_next_state = yy_try_NUL_trans( yy_current_state ); + yy_next_state = yy_try_NUL_trans(yy_current_state); - yy_bp = (yytext_ptr) + YY_MORE_ADJ; + yy_bp = (yytext_ptr) + YY_MORE_ADJ; - if ( yy_next_state ) - { - /* Consume the NUL. */ - yy_cp = ++(yy_c_buf_p); - yy_current_state = yy_next_state; - goto yy_match; - } + if (yy_next_state) { + /* Consume the NUL. */ + yy_cp = ++(yy_c_buf_p); + yy_current_state = yy_next_state; + goto yy_match; + } - else - { - yy_cp = (yy_c_buf_p); - goto yy_find_action; - } - } + else { + yy_cp = (yy_c_buf_p); + goto yy_find_action; + } + } - else switch ( yy_get_next_buffer( ) ) - { - case EOB_ACT_END_OF_FILE: - { - (yy_did_buffer_switch_on_eof) = 0; + else + switch (yy_get_next_buffer()) { + case EOB_ACT_END_OF_FILE: { + (yy_did_buffer_switch_on_eof) = 0; - if ( dexp_wrap( ) ) - { - /* Note: because we've taken care in + if (dexp_wrap()) { + /* Note: because we've taken care in * yy_get_next_buffer() to have set up * dexp_text, we can now set up * yy_c_buf_p so that if some total @@ -1054,48 +1023,45 @@ case YY_STATE_EOF(INITIAL): * YY_NULL, it'll still work - another * YY_NULL will get returned. */ - (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; + (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; - yy_act = YY_STATE_EOF(YY_START); - goto do_action; - } + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } - else - { - if ( ! (yy_did_buffer_switch_on_eof) ) - YY_NEW_FILE; - } - break; - } + else { + if (!(yy_did_buffer_switch_on_eof)) + YY_NEW_FILE; + } + break; + } - case EOB_ACT_CONTINUE_SCAN: - (yy_c_buf_p) = - (yytext_ptr) + yy_amount_of_matched_text; + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; - yy_current_state = yy_get_previous_state( ); + yy_current_state = yy_get_previous_state(); - yy_cp = (yy_c_buf_p); - yy_bp = (yytext_ptr) + YY_MORE_ADJ; - goto yy_match; + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_match; - case EOB_ACT_LAST_MATCH: - (yy_c_buf_p) = - &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; + case EOB_ACT_LAST_MATCH: + (yy_c_buf_p) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; - yy_current_state = yy_get_previous_state( ); + yy_current_state = yy_get_previous_state(); - yy_cp = (yy_c_buf_p); - yy_bp = (yytext_ptr) + YY_MORE_ADJ; - goto yy_find_action; - } - break; - } + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } - default: - YY_FATAL_ERROR( - "fatal flex scanner internal error--no action found" ); - } /* end of action switch */ - } /* end of scanning one token */ + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found"); + } /* end of action switch */ + } /* end of scanning one token */ } /* end of dexp_lex */ /* yy_get_next_buffer - try to read in a new buffer @@ -1105,165 +1071,147 @@ case YY_STATE_EOF(INITIAL): * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ -static int yy_get_next_buffer (void) +static int yy_get_next_buffer(void) { - register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; - register char *source = (yytext_ptr); - register int number_to_move, i; - int ret_val; + register char* dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + register char* source = (yytext_ptr); + register int number_to_move, i; + int ret_val; - if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) - YY_FATAL_ERROR( - "fatal flex scanner internal error--end of buffer missed" ); + if ((yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1]) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed"); - if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) - { /* Don't try to fill the buffer, so this is an EOF. */ - if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) - { - /* We matched a single character, the EOB, so + if (YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0) { /* Don't try to fill the buffer, so this is an EOF. */ + if ((yy_c_buf_p) - (yytext_ptr)-YY_MORE_ADJ == 1) { + /* We matched a single character, the EOB, so * treat this as a final EOF. */ - return EOB_ACT_END_OF_FILE; - } + return EOB_ACT_END_OF_FILE; + } - else - { - /* We matched some text prior to the EOB, first + else { + /* We matched some text prior to the EOB, first * process it. */ - return EOB_ACT_LAST_MATCH; - } - } + return EOB_ACT_LAST_MATCH; + } + } - /* Try to read more data. */ + /* Try to read more data. */ - /* First move last chars to start of buffer. */ - number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; + /* First move last chars to start of buffer. */ + number_to_move = (int)((yy_c_buf_p) - (yytext_ptr)) - 1; - for ( i = 0; i < number_to_move; ++i ) - *(dest++) = *(source++); + for (i = 0; i < number_to_move; ++i) + *(dest++) = *(source++); - if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) - /* don't do the read, it's not guaranteed to return an EOF, + if (YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING) + /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; - else - { - int num_to_read = - YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + else { + int num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; - while ( num_to_read <= 0 ) - { /* Not enough room in the buffer - grow it. */ + while (num_to_read <= 0) { /* Not enough room in the buffer - grow it. */ - /* just a shorter name for the current buffer */ - YY_BUFFER_STATE b = YY_CURRENT_BUFFER; + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = YY_CURRENT_BUFFER; - int yy_c_buf_p_offset = - (int) ((yy_c_buf_p) - b->yy_ch_buf); + int yy_c_buf_p_offset = (int)((yy_c_buf_p)-b->yy_ch_buf); - if ( b->yy_is_our_buffer ) - { - int new_size = b->yy_buf_size * 2; + if (b->yy_is_our_buffer) { + int new_size = b->yy_buf_size * 2; - if ( new_size <= 0 ) - b->yy_buf_size += b->yy_buf_size / 8; - else - b->yy_buf_size *= 2; + if (new_size <= 0) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; - b->yy_ch_buf = (char *) - /* Include room in for 2 EOB chars. */ - dexp_realloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); - } - else - /* Can't grow it, we don't own it. */ - b->yy_ch_buf = 0; + b->yy_ch_buf = (char*) + /* Include room in for 2 EOB chars. */ + dexp_realloc((void*)b->yy_ch_buf, b->yy_buf_size + 2); + } else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( - "fatal error - scanner input buffer overflow" ); + if (!b->yy_ch_buf) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow"); - (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; + (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; - num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - - number_to_move - 1; + num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + } - } + if (num_to_read > YY_READ_BUF_SIZE) + num_to_read = YY_READ_BUF_SIZE; - if ( num_to_read > YY_READ_BUF_SIZE ) - num_to_read = YY_READ_BUF_SIZE; + /* Read in more data. */ + YY_INPUT((&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + (yy_n_chars), (size_t)num_to_read); - /* Read in more data. */ - YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), - (yy_n_chars), (size_t) num_to_read ); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); - } + if ((yy_n_chars) == 0) { + if (number_to_move == YY_MORE_ADJ) { + ret_val = EOB_ACT_END_OF_FILE; + dexp_restart(dexp_in); + } - if ( (yy_n_chars) == 0 ) - { - if ( number_to_move == YY_MORE_ADJ ) - { - ret_val = EOB_ACT_END_OF_FILE; - dexp_restart(dexp_in ); - } + else { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; + } + } - else - { - ret_val = EOB_ACT_LAST_MATCH; - YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = - YY_BUFFER_EOF_PENDING; - } - } + else + ret_val = EOB_ACT_CONTINUE_SCAN; - else - ret_val = EOB_ACT_CONTINUE_SCAN; + if ((yy_size_t)((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + /* Extend the array by 50%, plus the number we really need. */ + yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char*)dexp_realloc((void*)YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, new_size); + if (!YY_CURRENT_BUFFER_LVALUE->yy_ch_buf) + YY_FATAL_ERROR("out of dynamic memory in yy_get_next_buffer()"); + } - if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { - /* Extend the array by 50%, plus the number we really need. */ - yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) dexp_realloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); - if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); - } + (yy_n_chars) += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; - (yy_n_chars) += number_to_move; - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; + (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; - (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; - - return ret_val; + return ret_val; } /* yy_get_previous_state - get the state just before the EOB char was reached */ - static yy_state_type yy_get_previous_state (void) +static yy_state_type yy_get_previous_state(void) { - register yy_state_type yy_current_state; - register char *yy_cp; - - yy_current_state = (yy_start); + register yy_state_type yy_current_state; + register char* yy_cp; - for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) - { - register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); - if ( yy_accept[yy_current_state] ) - { - (yy_last_accepting_state) = yy_current_state; - (yy_last_accepting_cpos) = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 51 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - } + yy_current_state = (yy_start); - return yy_current_state; + for (yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp) { + register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if (yy_accept[yy_current_state]) { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while (yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state) { + yy_current_state = (int)yy_def[yy_current_state]; + if (yy_current_state >= 51) + yy_c = yy_meta[(unsigned int)yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int)yy_c]; + } + + return yy_current_state; } /* yy_try_NUL_trans - try to make a transition on the NUL character @@ -1271,97 +1219,88 @@ static int yy_get_next_buffer (void) * synopsis * next_state = yy_try_NUL_trans( current_state ); */ - static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) +static yy_state_type yy_try_NUL_trans(yy_state_type yy_current_state) { - register int yy_is_jam; - register char *yy_cp = (yy_c_buf_p); + register int yy_is_jam; + register char* yy_cp = (yy_c_buf_p); - register YY_CHAR yy_c = 1; - if ( yy_accept[yy_current_state] ) - { - (yy_last_accepting_state) = yy_current_state; - (yy_last_accepting_cpos) = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 51 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 50); + register YY_CHAR yy_c = 1; + if (yy_accept[yy_current_state]) { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while (yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state) { + yy_current_state = (int)yy_def[yy_current_state]; + if (yy_current_state >= 51) + yy_c = yy_meta[(unsigned int)yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int)yy_c]; + yy_is_jam = (yy_current_state == 50); - return yy_is_jam ? 0 : yy_current_state; + return yy_is_jam ? 0 : yy_current_state; } - static void yyunput (int c, register char * yy_bp ) +static void yyunput(int c, register char* yy_bp) { - register char *yy_cp; - + register char* yy_cp; + yy_cp = (yy_c_buf_p); - /* undo effects of setting up dexp_text */ - *yy_cp = (yy_hold_char); + /* undo effects of setting up dexp_text */ + *yy_cp = (yy_hold_char); - if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) - { /* need to shift things up to make room */ - /* +2 for EOB chars. */ - register int number_to_move = (yy_n_chars) + 2; - register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ - YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; - register char *source = - &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; + if (yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2) { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + register int number_to_move = (yy_n_chars) + 2; + register char* dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; + register char* source = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; - while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) - *--dest = *--source; + while (source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf) + *--dest = *--source; - yy_cp += (int) (dest - source); - yy_bp += (int) (dest - source); - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = - (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; + yy_cp += (int)(dest - source); + yy_bp += (int)(dest - source); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; - if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) - YY_FATAL_ERROR( "flex scanner push-back overflow" ); - } + if (yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2) + YY_FATAL_ERROR("flex scanner push-back overflow"); + } - *--yy_cp = (char) c; + *--yy_cp = (char)c; - (yytext_ptr) = yy_bp; - (yy_hold_char) = *yy_cp; - (yy_c_buf_p) = yy_cp; + (yytext_ptr) = yy_bp; + (yy_hold_char) = *yy_cp; + (yy_c_buf_p) = yy_cp; } #ifndef YY_NO_INPUT #ifdef __cplusplus - static int yyinput (void) +static int yyinput(void) #else - static int input (void) +static int input(void) #endif { - int c; - - *(yy_c_buf_p) = (yy_hold_char); + int c; - if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) - { - /* yy_c_buf_p now points to the character we want to return. + *(yy_c_buf_p) = (yy_hold_char); + + if (*(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR) { + /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ - if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) - /* This was really a NUL. */ - *(yy_c_buf_p) = '\0'; + if ((yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]) + /* This was really a NUL. */ + *(yy_c_buf_p) = '\0'; - else - { /* need more input */ - int offset = (yy_c_buf_p) - (yytext_ptr); - ++(yy_c_buf_p); + else { /* need more input */ + int offset = (yy_c_buf_p) - (yytext_ptr); + ++(yy_c_buf_p); - switch ( yy_get_next_buffer( ) ) - { - case EOB_ACT_LAST_MATCH: - /* This happens because yy_g_n_b() + switch (yy_get_next_buffer()) { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before @@ -1371,99 +1310,96 @@ static int yy_get_next_buffer (void) * to EOB_ACT_END_OF_FILE. */ - /* Reset buffer status. */ - dexp_restart(dexp_in ); + /* Reset buffer status. */ + dexp_restart(dexp_in); - /*FALLTHROUGH*/ + /*FALLTHROUGH*/ - case EOB_ACT_END_OF_FILE: - { - if ( dexp_wrap( ) ) - return EOF; + case EOB_ACT_END_OF_FILE: { + if (dexp_wrap()) + return EOF; - if ( ! (yy_did_buffer_switch_on_eof) ) - YY_NEW_FILE; + if (!(yy_did_buffer_switch_on_eof)) + YY_NEW_FILE; #ifdef __cplusplus - return yyinput(); + return yyinput(); #else - return input(); + return input(); #endif - } + } - case EOB_ACT_CONTINUE_SCAN: - (yy_c_buf_p) = (yytext_ptr) + offset; - break; - } - } - } + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = (yytext_ptr) + offset; + break; + } + } + } - c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ - *(yy_c_buf_p) = '\0'; /* preserve dexp_text */ - (yy_hold_char) = *++(yy_c_buf_p); + c = *(unsigned char*)(yy_c_buf_p); /* cast for 8-bit char's */ + *(yy_c_buf_p) = '\0'; /* preserve dexp_text */ + (yy_hold_char) = *++(yy_c_buf_p); - return c; + return c; } -#endif /* ifndef YY_NO_INPUT */ +#endif /* ifndef YY_NO_INPUT */ /** Immediately switch to a different input stream. * @param input_file A readable stream. * * @note This function does not reset the start condition to @c INITIAL . */ - void dexp_restart (FILE * input_file ) +void dexp_restart(FILE* input_file) { - - if ( ! YY_CURRENT_BUFFER ){ - dexp_ensure_buffer_stack (); - YY_CURRENT_BUFFER_LVALUE = - dexp__create_buffer(dexp_in,YY_BUF_SIZE ); - } - dexp__init_buffer(YY_CURRENT_BUFFER,input_file ); - dexp__load_buffer_state( ); + if (!YY_CURRENT_BUFFER) { + dexp_ensure_buffer_stack(); + YY_CURRENT_BUFFER_LVALUE = dexp__create_buffer(dexp_in, YY_BUF_SIZE); + } + + dexp__init_buffer(YY_CURRENT_BUFFER, input_file); + dexp__load_buffer_state(); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * */ - void dexp__switch_to_buffer (YY_BUFFER_STATE new_buffer ) +void dexp__switch_to_buffer(YY_BUFFER_STATE new_buffer) { - - /* TODO. We should be able to replace this entire function body + + /* TODO. We should be able to replace this entire function body * with * dexp_pop_buffer_state(); * dexp_push_buffer_state(new_buffer); */ - dexp_ensure_buffer_stack (); - if ( YY_CURRENT_BUFFER == new_buffer ) - return; + dexp_ensure_buffer_stack(); + if (YY_CURRENT_BUFFER == new_buffer) + return; - if ( YY_CURRENT_BUFFER ) - { - /* Flush out information for old buffer. */ - *(yy_c_buf_p) = (yy_hold_char); - YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); - } + if (YY_CURRENT_BUFFER) { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } - YY_CURRENT_BUFFER_LVALUE = new_buffer; - dexp__load_buffer_state( ); + YY_CURRENT_BUFFER_LVALUE = new_buffer; + dexp__load_buffer_state(); - /* We don't actually know whether we did this switch during + /* We don't actually know whether we did this switch during * EOF (dexp_wrap()) processing, but the only time this flag * is looked at is after dexp_wrap() is called, so it's safe * to go ahead and always set it. */ - (yy_did_buffer_switch_on_eof) = 1; + (yy_did_buffer_switch_on_eof) = 1; } -static void dexp__load_buffer_state (void) +static void dexp__load_buffer_state(void) { - (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; - (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; - dexp_in = YY_CURRENT_BUFFER_LVALUE->yy_input_file; - (yy_hold_char) = *(yy_c_buf_p); + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + dexp_in = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + (yy_hold_char) = *(yy_c_buf_p); } /** Allocate and initialize an input buffer state. @@ -1472,106 +1408,106 @@ static void dexp__load_buffer_state (void) * * @return the allocated buffer state. */ - YY_BUFFER_STATE dexp__create_buffer (FILE * file, int size ) +YY_BUFFER_STATE dexp__create_buffer(FILE* file, int size) { - YY_BUFFER_STATE b; - - b = (YY_BUFFER_STATE) dexp_alloc(sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in dexp__create_buffer()" ); + YY_BUFFER_STATE b; - b->yy_buf_size = size; + b = (YY_BUFFER_STATE)dexp_alloc(sizeof(struct yy_buffer_state)); + if (!b) + YY_FATAL_ERROR("out of dynamic memory in dexp__create_buffer()"); - /* yy_ch_buf has to be 2 characters longer than the size given because + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ - b->yy_ch_buf = (char *) dexp_alloc(b->yy_buf_size + 2 ); - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in dexp__create_buffer()" ); + b->yy_ch_buf = (char*)dexp_alloc(b->yy_buf_size + 2); + if (!b->yy_ch_buf) + YY_FATAL_ERROR("out of dynamic memory in dexp__create_buffer()"); - b->yy_is_our_buffer = 1; + b->yy_is_our_buffer = 1; - dexp__init_buffer(b,file ); + dexp__init_buffer(b, file); - return b; + return b; } /** Destroy the buffer. * @param b a buffer created with dexp__create_buffer() * */ - void dexp__delete_buffer (YY_BUFFER_STATE b ) +void dexp__delete_buffer(YY_BUFFER_STATE b) { - - if ( ! b ) - return; - if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ - YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + if (!b) + return; - if ( b->yy_is_our_buffer ) - dexp_free((void *) b->yy_ch_buf ); + if (b == YY_CURRENT_BUFFER) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE)0; - dexp_free((void *) b ); + if (b->yy_is_our_buffer) + dexp_free((void*)b->yy_ch_buf); + + dexp_free((void*)b); } #ifndef __cplusplus -extern int isatty (int ); +extern int isatty(int); #endif /* __cplusplus */ - + /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a dexp_restart() or at EOF. */ - static void dexp__init_buffer (YY_BUFFER_STATE b, FILE * file ) +static void dexp__init_buffer(YY_BUFFER_STATE b, FILE* file) { - int oerrno = errno; - - dexp__flush_buffer(b ); + int oerrno = errno; - b->yy_input_file = file; - b->yy_fill_buffer = 1; + dexp__flush_buffer(b); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; /* If b is the current buffer, then dexp__init_buffer was _probably_ * called from dexp_restart() or through yy_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ - if (b != YY_CURRENT_BUFFER){ + if (b != YY_CURRENT_BUFFER) { b->yy_bs_lineno = 1; b->yy_bs_column = 0; } - b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; - - errno = oerrno; + b->yy_is_interactive = file ? (isatty(fileno(file)) > 0) : 0; + + errno = oerrno; } /** Discard all buffered characters. On the next scan, YY_INPUT will be called. * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * */ - void dexp__flush_buffer (YY_BUFFER_STATE b ) +void dexp__flush_buffer(YY_BUFFER_STATE b) { - if ( ! b ) - return; + if (!b) + return; - b->yy_n_chars = 0; + b->yy_n_chars = 0; - /* We always need two end-of-buffer characters. The first causes + /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ - b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; - b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; - b->yy_buf_pos = &b->yy_ch_buf[0]; + b->yy_buf_pos = &b->yy_ch_buf[0]; - b->yy_at_bol = 1; - b->yy_buffer_status = YY_BUFFER_NEW; + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; - if ( b == YY_CURRENT_BUFFER ) - dexp__load_buffer_state( ); + if (b == YY_CURRENT_BUFFER) + dexp__load_buffer_state(); } /** Pushes the new state onto the stack. The new state becomes @@ -1580,96 +1516,91 @@ extern int isatty (int ); * @param new_buffer The new state. * */ -void dexp_push_buffer_state (YY_BUFFER_STATE new_buffer ) +void dexp_push_buffer_state(YY_BUFFER_STATE new_buffer) { - if (new_buffer == NULL) - return; + if (new_buffer == NULL) + return; - dexp_ensure_buffer_stack(); + dexp_ensure_buffer_stack(); - /* This block is copied from dexp__switch_to_buffer. */ - if ( YY_CURRENT_BUFFER ) - { - /* Flush out information for old buffer. */ - *(yy_c_buf_p) = (yy_hold_char); - YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); - } + /* This block is copied from dexp__switch_to_buffer. */ + if (YY_CURRENT_BUFFER) { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } - /* Only push if top exists. Otherwise, replace top. */ - if (YY_CURRENT_BUFFER) - (yy_buffer_stack_top)++; - YY_CURRENT_BUFFER_LVALUE = new_buffer; + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + (yy_buffer_stack_top)++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; - /* copied from dexp__switch_to_buffer. */ - dexp__load_buffer_state( ); - (yy_did_buffer_switch_on_eof) = 1; + /* copied from dexp__switch_to_buffer. */ + dexp__load_buffer_state(); + (yy_did_buffer_switch_on_eof) = 1; } /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. * */ -void dexp_pop_buffer_state (void) +void dexp_pop_buffer_state(void) { - if (!YY_CURRENT_BUFFER) - return; + if (!YY_CURRENT_BUFFER) + return; - dexp__delete_buffer(YY_CURRENT_BUFFER ); - YY_CURRENT_BUFFER_LVALUE = NULL; - if ((yy_buffer_stack_top) > 0) - --(yy_buffer_stack_top); + dexp__delete_buffer(YY_CURRENT_BUFFER); + YY_CURRENT_BUFFER_LVALUE = NULL; + if ((yy_buffer_stack_top) > 0) + --(yy_buffer_stack_top); - if (YY_CURRENT_BUFFER) { - dexp__load_buffer_state( ); - (yy_did_buffer_switch_on_eof) = 1; - } + if (YY_CURRENT_BUFFER) { + dexp__load_buffer_state(); + (yy_did_buffer_switch_on_eof) = 1; + } } /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ -static void dexp_ensure_buffer_stack (void) +static void dexp_ensure_buffer_stack(void) { - int num_to_alloc; - - if (!(yy_buffer_stack)) { + int num_to_alloc; - /* First allocation is just for 2 elements, since we don't know if this + if (!(yy_buffer_stack)) { + + /* First allocation is just for 2 elements, since we don't know if this * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ - num_to_alloc = 1; - (yy_buffer_stack) = (struct yy_buffer_state**)dexp_alloc - (num_to_alloc * sizeof(struct yy_buffer_state*) - ); - if ( ! (yy_buffer_stack) ) - YY_FATAL_ERROR( "out of dynamic memory in dexp_ensure_buffer_stack()" ); - - memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); - - (yy_buffer_stack_max) = num_to_alloc; - (yy_buffer_stack_top) = 0; - return; - } + num_to_alloc = 1; + (yy_buffer_stack) = (struct yy_buffer_state**)dexp_alloc(num_to_alloc * sizeof(struct yy_buffer_state*)); + if (!(yy_buffer_stack)) + YY_FATAL_ERROR("out of dynamic memory in dexp_ensure_buffer_stack()"); - if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ + memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); - /* Increase the buffer to prepare for a possible push. */ - int grow_size = 8 /* arbitrary grow size */; + (yy_buffer_stack_max) = num_to_alloc; + (yy_buffer_stack_top) = 0; + return; + } - num_to_alloc = (yy_buffer_stack_max) + grow_size; - (yy_buffer_stack) = (struct yy_buffer_state**)dexp_realloc - ((yy_buffer_stack), - num_to_alloc * sizeof(struct yy_buffer_state*) - ); - if ( ! (yy_buffer_stack) ) - YY_FATAL_ERROR( "out of dynamic memory in dexp_ensure_buffer_stack()" ); + if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1) { - /* zero only the new slots.*/ - memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); - (yy_buffer_stack_max) = num_to_alloc; - } + /* Increase the buffer to prepare for a possible push. */ + int grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = (yy_buffer_stack_max) + grow_size; + (yy_buffer_stack) = (struct yy_buffer_state**)dexp_realloc((yy_buffer_stack), + num_to_alloc * sizeof(struct yy_buffer_state*)); + if (!(yy_buffer_stack)) + YY_FATAL_ERROR("out of dynamic memory in dexp_ensure_buffer_stack()"); + + /* zero only the new slots.*/ + memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); + (yy_buffer_stack_max) = num_to_alloc; + } } /** Setup the input buffer state to scan directly from a user-specified character buffer. @@ -1678,33 +1609,31 @@ static void dexp_ensure_buffer_stack (void) * * @return the newly allocated buffer state object. */ -YY_BUFFER_STATE dexp__scan_buffer (char * base, yy_size_t size ) +YY_BUFFER_STATE dexp__scan_buffer(char* base, yy_size_t size) { - YY_BUFFER_STATE b; - - if ( size < 2 || - base[size-2] != YY_END_OF_BUFFER_CHAR || - base[size-1] != YY_END_OF_BUFFER_CHAR ) - /* They forgot to leave room for the EOB's. */ - return 0; + YY_BUFFER_STATE b; - b = (YY_BUFFER_STATE) dexp_alloc(sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in dexp__scan_buffer()" ); + if (size < 2 || base[size - 2] != YY_END_OF_BUFFER_CHAR || base[size - 1] != YY_END_OF_BUFFER_CHAR) + /* They forgot to leave room for the EOB's. */ + return 0; - b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ - b->yy_buf_pos = b->yy_ch_buf = base; - b->yy_is_our_buffer = 0; - b->yy_input_file = 0; - b->yy_n_chars = b->yy_buf_size; - b->yy_is_interactive = 0; - b->yy_at_bol = 1; - b->yy_fill_buffer = 0; - b->yy_buffer_status = YY_BUFFER_NEW; + b = (YY_BUFFER_STATE)dexp_alloc(sizeof(struct yy_buffer_state)); + if (!b) + YY_FATAL_ERROR("out of dynamic memory in dexp__scan_buffer()"); - dexp__switch_to_buffer(b ); + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; - return b; + dexp__switch_to_buffer(b); + + return b; } /** Setup the input buffer state to scan a string. The next call to dexp_lex() will @@ -1715,10 +1644,10 @@ YY_BUFFER_STATE dexp__scan_buffer (char * base, yy_size_t size ) * @note If you want to scan bytes that may contain NUL values, then use * dexp__scan_bytes() instead. */ -YY_BUFFER_STATE dexp__scan_string (yyconst char * yystr ) +YY_BUFFER_STATE dexp__scan_string(yyconst char* yystr) { - - return dexp__scan_bytes(yystr,strlen(yystr) ); + + return dexp__scan_bytes(yystr, strlen(yystr)); } /** Setup the input buffer state to scan the given bytes. The next call to dexp_lex() will @@ -1728,114 +1657,112 @@ YY_BUFFER_STATE dexp__scan_string (yyconst char * yystr ) * * @return the newly allocated buffer state object. */ -YY_BUFFER_STATE dexp__scan_bytes (yyconst char * yybytes, int _yybytes_len ) +YY_BUFFER_STATE dexp__scan_bytes(yyconst char* yybytes, int _yybytes_len) { - YY_BUFFER_STATE b; - char *buf; - yy_size_t n; - int i; - - /* Get memory for full buffer, including space for trailing EOB's. */ - n = _yybytes_len + 2; - buf = (char *) dexp_alloc(n ); - if ( ! buf ) - YY_FATAL_ERROR( "out of dynamic memory in dexp__scan_bytes()" ); + YY_BUFFER_STATE b; + char* buf; + yy_size_t n; + int i; - for ( i = 0; i < _yybytes_len; ++i ) - buf[i] = yybytes[i]; + /* Get memory for full buffer, including space for trailing EOB's. */ + n = _yybytes_len + 2; + buf = (char*)dexp_alloc(n); + if (!buf) + YY_FATAL_ERROR("out of dynamic memory in dexp__scan_bytes()"); - buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; + for (i = 0; i < _yybytes_len; ++i) + buf[i] = yybytes[i]; - b = dexp__scan_buffer(buf,n ); - if ( ! b ) - YY_FATAL_ERROR( "bad buffer in dexp__scan_bytes()" ); + buf[_yybytes_len] = buf[_yybytes_len + 1] = YY_END_OF_BUFFER_CHAR; - /* It's okay to grow etc. this buffer, and we should throw it + b = dexp__scan_buffer(buf, n); + if (!b) + YY_FATAL_ERROR("bad buffer in dexp__scan_bytes()"); + + /* It's okay to grow etc. this buffer, and we should throw it * away when we're done. */ - b->yy_is_our_buffer = 1; + b->yy_is_our_buffer = 1; - return b; + return b; } #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif -static void yy_fatal_error (yyconst char* msg ) +static void yy_fatal_error(yyconst char* msg) { - (void) fprintf( stderr, "%s\n", msg ); - exit( YY_EXIT_FAILURE ); + (void)fprintf(stderr, "%s\n", msg); + exit(YY_EXIT_FAILURE); } /* Redefine yyless() so it works in section 3 code. */ #undef yyless -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up dexp_text. */ \ - int yyless_macro_arg = (n); \ - YY_LESS_LINENO(yyless_macro_arg);\ - dexp_text[dexp_leng] = (yy_hold_char); \ - (yy_c_buf_p) = dexp_text + yyless_macro_arg; \ - (yy_hold_char) = *(yy_c_buf_p); \ - *(yy_c_buf_p) = '\0'; \ - dexp_leng = yyless_macro_arg; \ - } \ - while ( 0 ) +#define yyless(n) \ + do { \ + /* Undo effects of setting up dexp_text. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg); \ + dexp_text[dexp_leng] = (yy_hold_char); \ + (yy_c_buf_p) = dexp_text + yyless_macro_arg; \ + (yy_hold_char) = *(yy_c_buf_p); \ + *(yy_c_buf_p) = '\0'; \ + dexp_leng = yyless_macro_arg; \ + } while (0) /* Accessor methods (get/set functions) to struct members. */ /** Get the current line number. * */ -int dexp_get_lineno (void) +int dexp_get_lineno(void) { - + return dexp_lineno; } /** Get the input stream. * */ -FILE *dexp_get_in (void) +FILE* dexp_get_in(void) { - return dexp_in; + return dexp_in; } /** Get the output stream. * */ -FILE *dexp_get_out (void) +FILE* dexp_get_out(void) { - return dexp_out; + return dexp_out; } /** Get the length of the current token. * */ -int dexp_get_leng (void) +int dexp_get_leng(void) { - return dexp_leng; + return dexp_leng; } /** Get the current token. * */ -char *dexp_get_text (void) +char* dexp_get_text(void) { - return dexp_text; + return dexp_text; } /** Set the current line number. * @param line_number * */ -void dexp_set_lineno (int line_number ) +void dexp_set_lineno(int line_number) { - + dexp_lineno = line_number; } @@ -1845,36 +1772,36 @@ void dexp_set_lineno (int line_number ) * * @see dexp__switch_to_buffer */ -void dexp_set_in (FILE * in_str ) +void dexp_set_in(FILE* in_str) { - dexp_in = in_str ; + dexp_in = in_str; } -void dexp_set_out (FILE * out_str ) +void dexp_set_out(FILE* out_str) { - dexp_out = out_str ; + dexp_out = out_str; } -int dexp_get_debug (void) +int dexp_get_debug(void) { - return dexp__flex_debug; + return dexp__flex_debug; } -void dexp_set_debug (int bdebug ) +void dexp_set_debug(int bdebug) { - dexp__flex_debug = bdebug ; + dexp__flex_debug = bdebug; } -static int yy_init_globals (void) +static int yy_init_globals(void) { - /* Initialization is the same as for the non-reentrant scanner. + /* Initialization is the same as for the non-reentrant scanner. * This function is called from dexp_lex_destroy(), so don't allocate here. */ (yy_buffer_stack) = 0; (yy_buffer_stack_top) = 0; (yy_buffer_stack_max) = 0; - (yy_c_buf_p) = (char *) 0; + (yy_c_buf_p) = (char*)0; (yy_init) = 0; (yy_start) = 0; @@ -1883,8 +1810,8 @@ static int yy_init_globals (void) dexp_in = stdin; dexp_out = stdout; #else - dexp_in = (FILE *) 0; - dexp_out = (FILE *) 0; + dexp_in = (FILE*)0; + dexp_out = (FILE*)0; #endif /* For future reference: Set errno on error, since we are called by @@ -1894,23 +1821,23 @@ static int yy_init_globals (void) } /* dexp_lex_destroy is for both reentrant and non-reentrant scanners. */ -int dexp_lex_destroy (void) +int dexp_lex_destroy(void) { - - /* Pop the buffer stack, destroying each element. */ - while(YY_CURRENT_BUFFER){ - dexp__delete_buffer(YY_CURRENT_BUFFER ); - YY_CURRENT_BUFFER_LVALUE = NULL; - dexp_pop_buffer_state(); - } - /* Destroy the stack itself. */ - dexp_free((yy_buffer_stack) ); - (yy_buffer_stack) = NULL; + /* Pop the buffer stack, destroying each element. */ + while (YY_CURRENT_BUFFER) { + dexp__delete_buffer(YY_CURRENT_BUFFER); + YY_CURRENT_BUFFER_LVALUE = NULL; + dexp_pop_buffer_state(); + } + + /* Destroy the stack itself. */ + dexp_free((yy_buffer_stack)); + (yy_buffer_stack) = NULL; /* Reset the globals. This is important in a non-reentrant scanner so the next time * dexp_lex() is called, initialization will occur. */ - yy_init_globals( ); + yy_init_globals(); return 0; } @@ -1920,55 +1847,52 @@ int dexp_lex_destroy (void) */ #ifndef yytext_ptr -static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) +static void yy_flex_strncpy(char* s1, yyconst char* s2, int n) { - register int i; - for ( i = 0; i < n; ++i ) - s1[i] = s2[i]; + register int i; + for (i = 0; i < n; ++i) + s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * s ) +static int yy_flex_strlen(yyconst char* s) { - register int n; - for ( n = 0; s[n]; ++n ) - ; + register int n; + for (n = 0; s[n]; ++n) + ; - return n; + return n; } #endif -void *dexp_alloc (yy_size_t size ) +void* dexp_alloc(yy_size_t size) { - return (void *) malloc( size ); + return (void*)malloc(size); } -void *dexp_realloc (void * ptr, yy_size_t size ) +void* dexp_realloc(void* ptr, yy_size_t size) { - /* The cast to (char *) in the following accommodates both + /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ - return (void *) realloc( (char *) ptr, size ); + return (void*)realloc((char*)ptr, size); } -void dexp_free (void * ptr ) +void dexp_free(void* ptr) { - free( (char *) ptr ); /* see dexp_realloc() for (char *) cast */ + free((char*)ptr); /* see dexp_realloc() for (char *) cast */ } #define YYTABLES_NAME "yytables" #line 62 "debugger-expr.l" - - void dexp_flush() { - dexp__flush_buffer(YY_CURRENT_BUFFER); + dexp__flush_buffer(YY_CURRENT_BUFFER); } - diff --git a/src/gba/debugger-expr-yacc.cpp b/src/gba/debugger-expr-yacc.cpp index 35bbf145..3e4dc65c 100644 --- a/src/gba/debugger-expr-yacc.cpp +++ b/src/gba/debugger-expr-yacc.cpp @@ -59,40 +59,40 @@ #define YYLSP_NEEDED 0 #define yyparse dexp_parse -#define yylex dexp_lex +#define yylex dexp_lex #define yyerror dexp_error -#define yylval dexp_lval -#define yychar dexp_char +#define yylval dexp_lval +#define yychar dexp_char #define yydebug dexp_debug #define yynerrs dexp_nerrs /* Tokens. */ #ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers +#define YYTOKENTYPE +/* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ - enum yytokentype { - TOK_PLUS = 258, - TOK_MINUS = 259, - TOK_DIVIDE = 260, - TOK_MULTIPLY = 261, - TOK_LSHIFT = 262, - TOK_RSHIFT = 263, - TOK_LPAREN = 264, - TOK_RPAREN = 265, - TOK_OR = 266, - TOK_AND = 267, - TOK_XOR = 268, - TOK_NEGATE = 269, - TOK_BBRACKET = 270, - TOK_HBRACKET = 271, - TOK_WBRACKET = 272, - TOK_LBRACKET = 273, - TOK_RBRACKET = 274, - TOK_REGISTER = 275, - TOK_NUMBER = 276, - TOK_ID = 277 - }; +enum yytokentype { + TOK_PLUS = 258, + TOK_MINUS = 259, + TOK_DIVIDE = 260, + TOK_MULTIPLY = 261, + TOK_LSHIFT = 262, + TOK_RSHIFT = 263, + TOK_LPAREN = 264, + TOK_RPAREN = 265, + TOK_OR = 266, + TOK_AND = 267, + TOK_XOR = 268, + TOK_NEGATE = 269, + TOK_BBRACKET = 270, + TOK_HBRACKET = 271, + TOK_WBRACKET = 272, + TOK_LBRACKET = 273, + TOK_RBRACKET = 274, + TOK_REGISTER = 275, + TOK_NUMBER = 276, + TOK_ID = 277 +}; #endif /* Tokens. */ #define TOK_PLUS 258 @@ -116,84 +116,75 @@ #define TOK_NUMBER 276 #define TOK_ID 277 - - - /* Copy the first part of user declarations. */ #line 1 "src/sdl/debugger-expr.y" #include - -#include "../System.h" -#include "GBA.h" -#include "../common/Port.h" -#include -#include +#include "../System.h" +#include "../common/Port.h" +#include "GBA.h" + #include +#include +#include unsigned int dexp_result = 0; -extern int dexp_error(char *); +extern int dexp_error(char*); extern int dexp_lex(); -extern char *dexp_text; +extern char* dexp_text; std::map dexp_vars; #define readWord(addr) \ - READ32LE((&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask])) + READ32LE((&map[(addr) >> 24].address[(addr)&map[(addr) >> 24].mask])) #define readHalfWord(addr) \ - READ16LE((&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask])) + READ16LE((&map[(addr) >> 24].address[(addr)&map[(addr) >> 24].mask])) #define readByte(addr) \ - map[(addr)>>24].address[(addr) & map[(addr)>>24].mask] - - - + map[(addr) >> 24].address[(addr)&map[(addr) >> 24].mask] /* Enabling traces. */ #ifndef YYDEBUG -# define YYDEBUG 0 +#define YYDEBUG 0 #endif /* Enabling verbose error messages. */ #ifdef YYERROR_VERBOSE -# undef YYERROR_VERBOSE -# define YYERROR_VERBOSE 1 +#undef YYERROR_VERBOSE +#define YYERROR_VERBOSE 1 #else -# define YYERROR_VERBOSE 0 +#define YYERROR_VERBOSE 0 #endif /* Enabling the token table. */ #ifndef YYTOKEN_TABLE -# define YYTOKEN_TABLE 0 +#define YYTOKEN_TABLE 0 #endif -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +#if !defined YYSTYPE && !defined YYSTYPE_IS_DECLARED typedef union YYSTYPE #line 44 "src/sdl/debugger-expr.y" { - unsigned int number; - char *string; + unsigned int number; + char* string; } /* Line 187 of yacc.c. */ #line 175 "src/sdl/debugger-expr-yacc.cpp" - YYSTYPE; -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -# define YYSTYPE_IS_TRIVIAL 1 +YYSTYPE; +#define yystype YYSTYPE /* obsolescent; will be withdrawn */ +#define YYSTYPE_IS_DECLARED 1 +#define YYSTYPE_IS_TRIVIAL 1 #endif - - /* Copy the second part of user declarations. */ - /* Line 216 of yacc.c. */ #line 188 "src/sdl/debugger-expr-yacc.cpp" #ifdef short -# undef short +#undef short #endif #ifdef YYTYPE_UINT8 @@ -205,7 +196,7 @@ typedef unsigned char yytype_uint8; #ifdef YYTYPE_INT8 typedef YYTYPE_INT8 yytype_int8; #elif (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) + || defined __cplusplus || defined _MSC_VER) typedef signed char yytype_int8; #else typedef short int yytype_int8; @@ -224,344 +215,328 @@ typedef short int yytype_int16; #endif #ifndef YYSIZE_T -# ifdef __SIZE_TYPE__ -# define YYSIZE_T __SIZE_TYPE__ -# elif defined size_t -# define YYSIZE_T size_t -# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -# include /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# else -# define YYSIZE_T unsigned int -# endif +#ifdef __SIZE_TYPE__ +#define YYSIZE_T __SIZE_TYPE__ +#elif defined size_t +#define YYSIZE_T size_t +#elif !defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +#include /* INFRINGES ON USER NAME SPACE */ +#define YYSIZE_T size_t +#else +#define YYSIZE_T unsigned int +#endif #endif -#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) +#define YYSIZE_MAXIMUM ((YYSIZE_T)-1) #ifndef YY_ -# if YYENABLE_NLS -# if ENABLE_NLS -# include /* INFRINGES ON USER NAME SPACE */ -# define YY_(msgid) dgettext ("bison-runtime", msgid) -# endif -# endif -# ifndef YY_ -# define YY_(msgid) msgid -# endif +#if YYENABLE_NLS +#if ENABLE_NLS +#include /* INFRINGES ON USER NAME SPACE */ +#define YY_(msgid) dgettext("bison-runtime", msgid) +#endif +#endif +#ifndef YY_ +#define YY_(msgid) msgid +#endif #endif /* Suppress unused-variable warnings by "using" E. */ -#if ! defined lint || defined __GNUC__ -# define YYUSE(e) ((void) (e)) +#if !defined lint || defined __GNUC__ +#define YYUSE(e) ((void)(e)) #else -# define YYUSE(e) /* empty */ +#define YYUSE(e) /* empty */ #endif /* Identity function, used to suppress warnings about constant conditions. */ #ifndef lint -# define YYID(n) (n) +#define YYID(n) (n) #else #if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) + || defined __cplusplus || defined _MSC_VER) static int -YYID (int i) +YYID(int i) #else static int -YYID (i) - int i; + YYID(i) int i; #endif { - return i; + return i; } #endif -#if ! defined yyoverflow || YYERROR_VERBOSE +#if !defined yyoverflow || YYERROR_VERBOSE /* The parser invokes alloca or malloc; define the necessary symbols. */ -# ifdef YYSTACK_USE_ALLOCA -# if YYSTACK_USE_ALLOCA -# ifdef __GNUC__ -# define YYSTACK_ALLOC __builtin_alloca -# elif defined __BUILTIN_VA_ARG_INCR -# include /* INFRINGES ON USER NAME SPACE */ -# elif defined _AIX -# define YYSTACK_ALLOC __alloca -# elif defined _MSC_VER -# include /* INFRINGES ON USER NAME SPACE */ -# define alloca _alloca -# else -# define YYSTACK_ALLOC alloca -# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -# include /* INFRINGES ON USER NAME SPACE */ -# ifndef _STDLIB_H -# define _STDLIB_H 1 -# endif -# endif -# endif -# endif -# endif +#ifdef YYSTACK_USE_ALLOCA +#if YYSTACK_USE_ALLOCA +#ifdef __GNUC__ +#define YYSTACK_ALLOC __builtin_alloca +#elif defined __BUILTIN_VA_ARG_INCR +#include /* INFRINGES ON USER NAME SPACE */ +#elif defined _AIX +#define YYSTACK_ALLOC __alloca +#elif defined _MSC_VER +#include /* INFRINGES ON USER NAME SPACE */ +#define alloca _alloca +#else +#define YYSTACK_ALLOC alloca +#if !defined _ALLOCA_H && !defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +#include /* INFRINGES ON USER NAME SPACE */ +#ifndef _STDLIB_H +#define _STDLIB_H 1 +#endif +#endif +#endif +#endif +#endif -# ifdef YYSTACK_ALLOC - /* Pacify GCC's `empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) -# ifndef YYSTACK_ALLOC_MAXIMUM - /* The OS might guarantee only one guard page at the bottom of the stack, +#ifdef YYSTACK_ALLOC +/* Pacify GCC's `empty if-body' warning. */ +#define YYSTACK_FREE(Ptr) \ + do { /* empty */ \ + ; \ + } while (YYID(0)) +#ifndef YYSTACK_ALLOC_MAXIMUM +/* The OS might guarantee only one guard page at the bottom of the stack, and a page size can be as small as 4096 bytes. So we cannot safely invoke alloca (N) if N exceeds 4096. Use a slightly smaller number to allow for a few compiler-allocated temporary stack slots. */ -# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ -# endif -# else -# define YYSTACK_ALLOC YYMALLOC -# define YYSTACK_FREE YYFREE -# ifndef YYSTACK_ALLOC_MAXIMUM -# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM -# endif -# if (defined __cplusplus && ! defined _STDLIB_H \ - && ! ((defined YYMALLOC || defined malloc) \ - && (defined YYFREE || defined free))) -# include /* INFRINGES ON USER NAME SPACE */ -# ifndef _STDLIB_H -# define _STDLIB_H 1 -# endif -# endif -# ifndef YYMALLOC -# define YYMALLOC malloc -# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# ifndef YYFREE -# define YYFREE free -# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -void free (void *); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# endif +#define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +#endif +#else +#define YYSTACK_ALLOC YYMALLOC +#define YYSTACK_FREE YYFREE +#ifndef YYSTACK_ALLOC_MAXIMUM +#define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +#endif +#if (defined __cplusplus && !defined _STDLIB_H \ + && !((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +#include /* INFRINGES ON USER NAME SPACE */ +#ifndef _STDLIB_H +#define _STDLIB_H 1 +#endif +#endif +#ifndef YYMALLOC +#define YYMALLOC malloc +#if !defined malloc && !defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void* malloc(YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +#endif +#endif +#ifndef YYFREE +#define YYFREE free +#if !defined free && !defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void free(void*); /* INFRINGES ON USER NAME SPACE */ +#endif +#endif +#endif #endif /* ! defined yyoverflow || YYERROR_VERBOSE */ - -#if (! defined yyoverflow \ - && (! defined __cplusplus \ - || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) +#if (!defined yyoverflow \ + && (!defined __cplusplus \ + || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ -union yyalloc -{ - yytype_int16 yyss; - YYSTYPE yyvs; - }; +union yyalloc { + yytype_int16 yyss; + YYSTYPE yyvs; +}; /* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) +#define YYSTACK_GAP_MAXIMUM (sizeof(union yyalloc) - 1) /* The size of an array large to enough to hold all stacks, each with N elements. */ -# define YYSTACK_BYTES(N) \ - ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ - + YYSTACK_GAP_MAXIMUM) +#define YYSTACK_BYTES(N) \ + ((N) * (sizeof(yytype_int16) + sizeof(YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) /* Copy COUNT objects from FROM to TO. The source and destination do not overlap. */ -# ifndef YYCOPY -# if defined __GNUC__ && 1 < __GNUC__ -# define YYCOPY(To, From, Count) \ - __builtin_memcpy (To, From, (Count) * sizeof (*(From))) -# else -# define YYCOPY(To, From, Count) \ - do \ - { \ - YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (To)[yyi] = (From)[yyi]; \ - } \ - while (YYID (0)) -# endif -# endif +#ifndef YYCOPY +#if defined __GNUC__ && 1 < __GNUC__ +#define YYCOPY(To, From, Count) \ + __builtin_memcpy(To, From, (Count) * sizeof(*(From))) +#else +#define YYCOPY(To, From, Count) \ + do { \ + YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } while (YYID(0)) +#endif +#endif /* Relocate STACK from its old location to the new one. The local variables YYSIZE and YYSTACKSIZE give the old and new number of elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ -# define YYSTACK_RELOCATE(Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack, Stack, yysize); \ - Stack = &yyptr->Stack; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ - while (YYID (0)) +#define YYSTACK_RELOCATE(Stack) \ + do { \ + YYSIZE_T yynewbytes; \ + YYCOPY(&yyptr->Stack, Stack, yysize); \ + Stack = &yyptr->Stack; \ + yynewbytes = yystacksize * sizeof(*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof(*yyptr); \ + } while (YYID(0)) #endif /* YYFINAL -- State number of the termination state. */ -#define YYFINAL 20 +#define YYFINAL 20 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 135 +#define YYLAST 135 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 23 +#define YYNTOKENS 23 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 3 +#define YYNNTS 3 /* YYNRULES -- Number of rules. */ -#define YYNRULES 21 +#define YYNRULES 21 /* YYNRULES -- Number of states. */ -#define YYNSTATES 44 +#define YYNSTATES 44 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ -#define YYUNDEFTOK 2 -#define YYMAXUTOK 277 +#define YYUNDEFTOK 2 +#define YYMAXUTOK 277 -#define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) +#define YYTRANSLATE(YYX) \ + ((unsigned int)(YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ -static const yytype_uint8 yytranslate[] = -{ - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22 +static const yytype_uint8 yytranslate[] = { + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22 }; #if YYDEBUG /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in YYRHS. */ -static const yytype_uint8 yyprhs[] = -{ - 0, 0, 3, 5, 7, 9, 13, 17, 20, 23, - 27, 31, 35, 39, 43, 47, 51, 55, 57, 61, - 65, 69 +static const yytype_uint8 yyprhs[] = { + 0, 0, 3, 5, 7, 9, 13, 17, 20, 23, + 27, 31, 35, 39, 43, 47, 51, 55, 57, 61, + 65, 69 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ -static const yytype_int8 yyrhs[] = -{ - 24, 0, -1, 25, -1, 21, -1, 22, -1, 25, - 3, 25, -1, 25, 4, 25, -1, 4, 25, -1, - 14, 25, -1, 25, 5, 25, -1, 25, 6, 25, - -1, 25, 7, 25, -1, 25, 8, 25, -1, 9, - 25, 10, -1, 25, 12, 25, -1, 25, 11, 25, - -1, 25, 13, 25, -1, 20, -1, 15, 25, 19, - -1, 16, 25, 19, -1, 17, 25, 19, -1, 18, - 25, 19, -1 +static const yytype_int8 yyrhs[] = { + 24, 0, -1, 25, -1, 21, -1, 22, -1, 25, + 3, 25, -1, 25, 4, 25, -1, 4, 25, -1, + 14, 25, -1, 25, 5, 25, -1, 25, 6, 25, + -1, 25, 7, 25, -1, 25, 8, 25, -1, 9, + 25, 10, -1, 25, 12, 25, -1, 25, 11, 25, + -1, 25, 13, 25, -1, 20, -1, 15, 25, 19, + -1, 16, 25, 19, -1, 17, 25, 19, -1, 18, + 25, 19, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -static const yytype_uint8 yyrline[] = -{ - 0, 56, 56, 59, 60, 68, 69, 70, 71, 72, - 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, - 83, 84 +static const yytype_uint8 yyrline[] = { + 0, 56, 56, 59, 60, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, + 83, 84 }; #endif #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -static const char *const yytname[] = -{ - "$end", "error", "$undefined", "TOK_PLUS", "TOK_MINUS", "TOK_DIVIDE", - "TOK_MULTIPLY", "TOK_LSHIFT", "TOK_RSHIFT", "TOK_LPAREN", "TOK_RPAREN", - "TOK_OR", "TOK_AND", "TOK_XOR", "TOK_NEGATE", "TOK_BBRACKET", - "TOK_HBRACKET", "TOK_WBRACKET", "TOK_LBRACKET", "TOK_RBRACKET", - "TOK_REGISTER", "TOK_NUMBER", "TOK_ID", "$accept", "final", "exp", 0 +static const char* const yytname[] = { + "$end", "error", "$undefined", "TOK_PLUS", "TOK_MINUS", "TOK_DIVIDE", + "TOK_MULTIPLY", "TOK_LSHIFT", "TOK_RSHIFT", "TOK_LPAREN", "TOK_RPAREN", + "TOK_OR", "TOK_AND", "TOK_XOR", "TOK_NEGATE", "TOK_BBRACKET", + "TOK_HBRACKET", "TOK_WBRACKET", "TOK_LBRACKET", "TOK_RBRACKET", + "TOK_REGISTER", "TOK_NUMBER", "TOK_ID", "$accept", "final", "exp", 0 }; #endif -# ifdef YYPRINT +#ifdef YYPRINT /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to token YYLEX-NUM. */ -static const yytype_uint16 yytoknum[] = -{ - 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, 276, 277 +static const yytype_uint16 yytoknum[] = { + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277 }; -# endif +#endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const yytype_uint8 yyr1[] = -{ - 0, 23, 24, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25 +static const yytype_uint8 yyr1[] = { + 0, 23, 24, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -static const yytype_uint8 yyr2[] = -{ - 0, 2, 1, 1, 1, 3, 3, 2, 2, 3, - 3, 3, 3, 3, 3, 3, 3, 1, 3, 3, - 3, 3 +static const yytype_uint8 yyr2[] = { + 0, 2, 1, 1, 1, 3, 3, 2, 2, 3, + 3, 3, 3, 3, 3, 3, 3, 1, 3, 3, + 3, 3 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state STATE-NUM when YYTABLE doesn't specify something else to do. Zero means the default is an error. */ -static const yytype_uint8 yydefact[] = -{ - 0, 0, 0, 0, 0, 0, 0, 0, 17, 3, - 4, 0, 2, 7, 0, 8, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 13, 18, 19, 20, 21, 5, 6, 9, 10, 11, - 12, 15, 14, 16 +static const yytype_uint8 yydefact[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 17, 3, + 4, 0, 2, 7, 0, 8, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 13, 18, 19, 20, 21, 5, 6, 9, 10, 11, + 12, 15, 14, 16 }; /* YYDEFGOTO[NTERM-NUM]. */ -static const yytype_int8 yydefgoto[] = -{ - -1, 11, 12 +static const yytype_int8 yydefgoto[] = { + -1, 11, 12 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ #define YYPACT_NINF -2 -static const yytype_int8 yypact[] = -{ - 25, 25, 25, 25, 25, 25, 25, 25, -2, -2, - -2, 13, 113, 122, 4, 122, 45, 62, 79, 96, - -2, 25, 25, 25, 25, 25, 25, 25, 25, 25, - -2, -2, -2, -2, -2, 122, 122, 24, 24, 48, - 48, 6, 17, -2 +static const yytype_int8 yypact[] = { + 25, 25, 25, 25, 25, 25, 25, 25, -2, -2, + -2, 13, 113, 122, 4, 122, 45, 62, 79, 96, + -2, 25, 25, 25, 25, 25, 25, 25, 25, 25, + -2, -2, -2, -2, -2, 122, 122, 24, 24, 48, + 48, 6, 17, -2 }; /* YYPGOTO[NTERM-NUM]. */ -static const yytype_int8 yypgoto[] = -{ - -2, -2, -1 +static const yytype_int8 yypgoto[] = { + -2, -2, -1 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If @@ -569,92 +544,87 @@ static const yytype_int8 yypgoto[] = number is the opposite. If zero, do what YYDEFACT says. If YYTABLE_NINF, syntax error. */ #define YYTABLE_NINF -1 -static const yytype_uint8 yytable[] = -{ - 13, 14, 15, 16, 17, 18, 19, 21, 22, 23, - 24, 25, 26, 20, 30, 27, 28, 29, 28, 29, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 1, - 29, 25, 26, 0, 2, 27, 28, 29, 0, 3, - 4, 5, 6, 7, 0, 8, 9, 10, 21, 22, - 23, 24, 25, 26, 0, 0, 27, 28, 29, 27, - 28, 29, 0, 0, 31, 21, 22, 23, 24, 25, - 26, 0, 0, 27, 28, 29, 0, 0, 0, 0, - 0, 32, 21, 22, 23, 24, 25, 26, 0, 0, - 27, 28, 29, 0, 0, 0, 0, 0, 33, 21, - 22, 23, 24, 25, 26, 0, 0, 27, 28, 29, - 0, 0, 0, 0, 0, 34, 21, 22, 23, 24, - 25, 26, 0, 0, 27, 28, 29, 23, 24, 25, - 26, 0, 0, 27, 28, 29 +static const yytype_uint8 yytable[] = { + 13, 14, 15, 16, 17, 18, 19, 21, 22, 23, + 24, 25, 26, 20, 30, 27, 28, 29, 28, 29, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 1, + 29, 25, 26, 0, 2, 27, 28, 29, 0, 3, + 4, 5, 6, 7, 0, 8, 9, 10, 21, 22, + 23, 24, 25, 26, 0, 0, 27, 28, 29, 27, + 28, 29, 0, 0, 31, 21, 22, 23, 24, 25, + 26, 0, 0, 27, 28, 29, 0, 0, 0, 0, + 0, 32, 21, 22, 23, 24, 25, 26, 0, 0, + 27, 28, 29, 0, 0, 0, 0, 0, 33, 21, + 22, 23, 24, 25, 26, 0, 0, 27, 28, 29, + 0, 0, 0, 0, 0, 34, 21, 22, 23, 24, + 25, 26, 0, 0, 27, 28, 29, 23, 24, 25, + 26, 0, 0, 27, 28, 29 }; -static const yytype_int8 yycheck[] = -{ - 1, 2, 3, 4, 5, 6, 7, 3, 4, 5, - 6, 7, 8, 0, 10, 11, 12, 13, 12, 13, - 21, 22, 23, 24, 25, 26, 27, 28, 29, 4, - 13, 7, 8, -1, 9, 11, 12, 13, -1, 14, - 15, 16, 17, 18, -1, 20, 21, 22, 3, 4, - 5, 6, 7, 8, -1, -1, 11, 12, 13, 11, - 12, 13, -1, -1, 19, 3, 4, 5, 6, 7, - 8, -1, -1, 11, 12, 13, -1, -1, -1, -1, - -1, 19, 3, 4, 5, 6, 7, 8, -1, -1, - 11, 12, 13, -1, -1, -1, -1, -1, 19, 3, - 4, 5, 6, 7, 8, -1, -1, 11, 12, 13, - -1, -1, -1, -1, -1, 19, 3, 4, 5, 6, - 7, 8, -1, -1, 11, 12, 13, 5, 6, 7, - 8, -1, -1, 11, 12, 13 +static const yytype_int8 yycheck[] = { + 1, 2, 3, 4, 5, 6, 7, 3, 4, 5, + 6, 7, 8, 0, 10, 11, 12, 13, 12, 13, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 4, + 13, 7, 8, -1, 9, 11, 12, 13, -1, 14, + 15, 16, 17, 18, -1, 20, 21, 22, 3, 4, + 5, 6, 7, 8, -1, -1, 11, 12, 13, 11, + 12, 13, -1, -1, 19, 3, 4, 5, 6, 7, + 8, -1, -1, 11, 12, 13, -1, -1, -1, -1, + -1, 19, 3, 4, 5, 6, 7, 8, -1, -1, + 11, 12, 13, -1, -1, -1, -1, -1, 19, 3, + 4, 5, 6, 7, 8, -1, -1, 11, 12, 13, + -1, -1, -1, -1, -1, 19, 3, 4, 5, 6, + 7, 8, -1, -1, 11, 12, 13, 5, 6, 7, + 8, -1, -1, 11, 12, 13 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ -static const yytype_uint8 yystos[] = -{ - 0, 4, 9, 14, 15, 16, 17, 18, 20, 21, - 22, 24, 25, 25, 25, 25, 25, 25, 25, 25, - 0, 3, 4, 5, 6, 7, 8, 11, 12, 13, - 10, 19, 19, 19, 19, 25, 25, 25, 25, 25, - 25, 25, 25, 25 +static const yytype_uint8 yystos[] = { + 0, 4, 9, 14, 15, 16, 17, 18, 20, 21, + 22, 24, 25, 25, 25, 25, 25, 25, 25, 25, + 0, 3, 4, 5, 6, 7, 8, 11, 12, 13, + 10, 19, 19, 19, 19, 25, 25, 25, 25, 25, + 25, 25, 25, 25 }; -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) -#define YYEOF 0 - -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrorlab +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab /* Like YYERROR except do call yyerror. This remains here temporarily to ease the transition to the new meaning of YYERROR, for GCC. Once GCC version 2 has supplanted version 1, this can go. */ -#define YYFAIL goto yyerrlab +#define YYFAIL goto yyerrlab -#define YYRECOVERING() (!!yyerrstatus) +#define YYRECOVERING() (!!yyerrstatus) -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY && yylen == 1) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - yytoken = YYTRANSLATE (yychar); \ - YYPOPSTACK (1); \ - goto yybackup; \ - } \ - else \ - { \ - yyerror (YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ -while (YYID (0)) - - -#define YYTERROR 1 -#define YYERRCODE 256 +#define YYBACKUP(Token, Value) \ + \ +do if (yychar == YYEMPTY && yylen == 1) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + yytoken = YYTRANSLATE(yychar); \ + YYPOPSTACK(1); \ + goto yybackup; \ + } \ + else \ + { \ + yyerror(YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ + \ +while(YYID(0)) +#define YYTERROR 1 +#define YYERRCODE 256 /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. If N is 0, then set CURRENT to the empty location which ends @@ -662,75 +632,74 @@ while (YYID (0)) #define YYRHSLOC(Rhs, K) ((Rhs)[K]) #ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - do \ - if (YYID (N)) \ - { \ - (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ - (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ - (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ - (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ - } \ - else \ - { \ - (Current).first_line = (Current).last_line = \ - YYRHSLOC (Rhs, 0).last_line; \ - (Current).first_column = (Current).last_column = \ - YYRHSLOC (Rhs, 0).last_column; \ - } \ - while (YYID (0)) +#define YYLLOC_DEFAULT(Current, Rhs, N) \ + do \ + if (YYID(N)) { \ + (Current).first_line = YYRHSLOC(Rhs, 1).first_line; \ + (Current).first_column = YYRHSLOC(Rhs, 1).first_column; \ + (Current).last_line = YYRHSLOC(Rhs, N).last_line; \ + (Current).last_column = YYRHSLOC(Rhs, N).last_column; \ + } else { \ + (Current).first_line = (Current).last_line = YYRHSLOC(Rhs, 0).last_line; \ + (Current).first_column = (Current).last_column = YYRHSLOC(Rhs, 0).last_column; \ + } \ + while (YYID(0)) #endif - /* YY_LOCATION_PRINT -- Print the location on the stream. This macro was not mandated originally: define only if we know we won't break user code: when these are the locations we know. */ #ifndef YY_LOCATION_PRINT -# if YYLTYPE_IS_TRIVIAL -# define YY_LOCATION_PRINT(File, Loc) \ - fprintf (File, "%d.%d-%d.%d", \ - (Loc).first_line, (Loc).first_column, \ - (Loc).last_line, (Loc).last_column) -# else -# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -# endif +#if YYLTYPE_IS_TRIVIAL +#define YY_LOCATION_PRINT(File, Loc) \ + fprintf(File, "%d.%d-%d.%d", \ + (Loc).first_line, (Loc).first_column, \ + (Loc).last_line, (Loc).last_column) +#else +#define YY_LOCATION_PRINT(File, Loc) ((void)0) +#endif #endif - /* YYLEX -- calling `yylex' with the right arguments. */ #ifdef YYLEX_PARAM -# define YYLEX yylex (YYLEX_PARAM) +#define YYLEX yylex(YYLEX_PARAM) #else -# define YYLEX yylex () +#define YYLEX yylex() #endif /* Enable debugging if requested. */ #if YYDEBUG -# ifndef YYFPRINTF -# include /* INFRINGES ON USER NAME SPACE */ -# define YYFPRINTF fprintf -# endif +#ifndef YYFPRINTF +#include /* INFRINGES ON USER NAME SPACE */ +#define YYFPRINTF fprintf +#endif -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (YYID (0)) - -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yy_symbol_print (stderr, \ - Type, Value); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (YYID (0)) +#define YYDPRINTF(Args) \ + \ +do \ + { \ + if (yydebug) \ + YYFPRINTF Args; \ + \ +} \ + while (YYID(0)) +#define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ + \ +do \ + { \ + if (yydebug) { \ + YYFPRINTF(stderr, "%s ", Title); \ + yy_symbol_print(stderr, \ + Type, Value); \ + YYFPRINTF(stderr, "\n"); \ + } \ + \ +} \ + while (YYID(0)) /*--------------------------------. | Print this symbol on YYOUTPUT. | @@ -738,56 +707,54 @@ do { \ /*ARGSUSED*/ #if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) + || defined __cplusplus || defined _MSC_VER) static void -yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +yy_symbol_value_print(FILE* yyoutput, int yytype, YYSTYPE const* const yyvaluep) #else static void -yy_symbol_value_print (yyoutput, yytype, yyvaluep) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; + yy_symbol_value_print(yyoutput, yytype, yyvaluep) + FILE* yyoutput; +int yytype; +YYSTYPE const* const yyvaluep; #endif { - if (!yyvaluep) - return; -# ifdef YYPRINT - if (yytype < YYNTOKENS) - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -# else - YYUSE (yyoutput); -# endif - switch (yytype) - { - default: - break; + if (!yyvaluep) + return; +#ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT(yyoutput, yytoknum[yytype], *yyvaluep); +#else + YYUSE(yyoutput); +#endif + switch (yytype) { + default: + break; } } - /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) + || defined __cplusplus || defined _MSC_VER) static void -yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +yy_symbol_print(FILE* yyoutput, int yytype, YYSTYPE const* const yyvaluep) #else static void -yy_symbol_print (yyoutput, yytype, yyvaluep) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; + yy_symbol_print(yyoutput, yytype, yyvaluep) + FILE* yyoutput; +int yytype; +YYSTYPE const* const yyvaluep; #endif { - if (yytype < YYNTOKENS) - YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); - else - YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + if (yytype < YYNTOKENS) + YYFPRINTF(yyoutput, "token %s (", yytname[yytype]); + else + YYFPRINTF(yyoutput, "nterm %s (", yytname[yytype]); - yy_symbol_value_print (yyoutput, yytype, yyvaluep); - YYFPRINTF (yyoutput, ")"); + yy_symbol_value_print(yyoutput, yytype, yyvaluep); + YYFPRINTF(yyoutput, ")"); } /*------------------------------------------------------------------. @@ -796,80 +763,84 @@ yy_symbol_print (yyoutput, yytype, yyvaluep) `------------------------------------------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) + || defined __cplusplus || defined _MSC_VER) static void -yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) +yy_stack_print(yytype_int16* bottom, yytype_int16* top) #else static void -yy_stack_print (bottom, top) - yytype_int16 *bottom; - yytype_int16 *top; + yy_stack_print(bottom, top) + yytype_int16* bottom; +yytype_int16* top; #endif { - YYFPRINTF (stderr, "Stack now"); - for (; bottom <= top; ++bottom) - YYFPRINTF (stderr, " %d", *bottom); - YYFPRINTF (stderr, "\n"); + YYFPRINTF(stderr, "Stack now"); + for (; bottom <= top; ++bottom) + YYFPRINTF(stderr, " %d", *bottom); + YYFPRINTF(stderr, "\n"); } -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (YYID (0)) - +#define YY_STACK_PRINT(Bottom, Top) \ + \ +do \ + { \ + if (yydebug) \ + yy_stack_print((Bottom), (Top)); \ + \ +} \ + while (YYID(0)) /*------------------------------------------------. | Report that the YYRULE is going to be reduced. | `------------------------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) + || defined __cplusplus || defined _MSC_VER) static void -yy_reduce_print (YYSTYPE *yyvsp, int yyrule) +yy_reduce_print(YYSTYPE* yyvsp, int yyrule) #else static void -yy_reduce_print (yyvsp, yyrule) - YYSTYPE *yyvsp; - int yyrule; + yy_reduce_print(yyvsp, yyrule) + YYSTYPE* yyvsp; +int yyrule; #endif { - int yynrhs = yyr2[yyrule]; - int yyi; - unsigned long int yylno = yyrline[yyrule]; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", - yyrule - 1, yylno); - /* The symbols being reduced. */ - for (yyi = 0; yyi < yynrhs; yyi++) - { - fprintf (stderr, " $%d = ", yyi + 1); - yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], - &(yyvsp[(yyi + 1) - (yynrhs)]) - ); - fprintf (stderr, "\n"); + int yynrhs = yyr2[yyrule]; + int yyi; + unsigned long int yylno = yyrline[yyrule]; + YYFPRINTF(stderr, "Reducing stack by rule %d (line %lu):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) { + fprintf(stderr, " $%d = ", yyi + 1); + yy_symbol_print(stderr, yyrhs[yyprhs[yyrule] + yyi], + &(yyvsp[(yyi + 1) - (yynrhs)])); + fprintf(stderr, "\n"); } } -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (yyvsp, Rule); \ -} while (YYID (0)) +#define YY_REDUCE_PRINT(Rule) \ + \ +do \ + { \ + if (yydebug) \ + yy_reduce_print(yyvsp, Rule); \ + \ +} \ + while (YYID(0)) /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ int yydebug; #else /* !YYDEBUG */ -# define YYDPRINTF(Args) -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) -# define YY_STACK_PRINT(Bottom, Top) -# define YY_REDUCE_PRINT(Rule) +#define YYDPRINTF(Args) +#define YY_SYMBOL_PRINT(Title, Type, Value, Location) +#define YY_STACK_PRINT(Bottom, Top) +#define YY_REDUCE_PRINT(Rule) #endif /* !YYDEBUG */ - /* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH -# define YYINITDEPTH 200 +#ifndef YYINITDEPTH +#define YYINITDEPTH 200 #endif /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only @@ -880,65 +851,62 @@ int yydebug; evaluated with infinite-precision integer arithmetic. */ #ifndef YYMAXDEPTH -# define YYMAXDEPTH 10000 +#define YYMAXDEPTH 10000 #endif - - #if YYERROR_VERBOSE -# ifndef yystrlen -# if defined __GLIBC__ && defined _STRING_H -# define yystrlen strlen -# else +#ifndef yystrlen +#if defined __GLIBC__ && defined _STRING_H +#define yystrlen strlen +#else /* Return the length of YYSTR. */ #if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) + || defined __cplusplus || defined _MSC_VER) static YYSIZE_T -yystrlen (const char *yystr) +yystrlen(const char* yystr) #else static YYSIZE_T -yystrlen (yystr) - const char *yystr; + yystrlen(yystr) + const char* yystr; #endif { - YYSIZE_T yylen; - for (yylen = 0; yystr[yylen]; yylen++) - continue; - return yylen; + YYSIZE_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) + continue; + return yylen; } -# endif -# endif +#endif +#endif -# ifndef yystpcpy -# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE -# define yystpcpy stpcpy -# else +#ifndef yystpcpy +#if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +#define yystpcpy stpcpy +#else /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in YYDEST. */ #if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static char * -yystpcpy (char *yydest, const char *yysrc) + || defined __cplusplus || defined _MSC_VER) +static char* +yystpcpy(char* yydest, const char* yysrc) #else -static char * -yystpcpy (yydest, yysrc) - char *yydest; - const char *yysrc; +static char* + yystpcpy(yydest, yysrc) char* yydest; +const char* yysrc; #endif { - char *yyd = yydest; - const char *yys = yysrc; + char* yyd = yydest; + const char* yys = yysrc; - while ((*yyd++ = *yys++) != '\0') - continue; + while ((*yyd++ = *yys++) != '\0') + continue; - return yyd - 1; + return yyd - 1; } -# endif -# endif +#endif +#endif -# ifndef yytnamerr +#ifndef yytnamerr /* Copy to YYRES the contents of YYSTR after stripping away unnecessary quotes and backslashes, so that it's suitable for yyerror. The heuristic is that double-quoting is unnecessary unless the string @@ -947,44 +915,42 @@ yystpcpy (yydest, yysrc) null, do not copy; instead, return the length of what the result would have been. */ static YYSIZE_T -yytnamerr (char *yyres, const char *yystr) +yytnamerr(char* yyres, const char* yystr) { - if (*yystr == '"') - { - YYSIZE_T yyn = 0; - char const *yyp = yystr; + if (*yystr == '"') { + YYSIZE_T yyn = 0; + char const* yyp = yystr; - for (;;) - switch (*++yyp) - { - case '\'': - case ',': - goto do_not_strip_quotes; + for (;;) + switch (*++yyp) { + case '\'': + case ',': + goto do_not_strip_quotes; - case '\\': - if (*++yyp != '\\') - goto do_not_strip_quotes; - /* Fall through. */ - default: - if (yyres) - yyres[yyn] = *yyp; - yyn++; - break; + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; - case '"': - if (yyres) - yyres[yyn] = '\0'; - return yyn; - } - do_not_strip_quotes: ; + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } + do_not_strip_quotes:; } - if (! yyres) - return yystrlen (yystr); + if (!yyres) + return yystrlen(yystr); - return yystpcpy (yyres, yystr) - yyres; + return yystpcpy(yyres, yystr) - yyres; } -# endif +#endif /* Copy into YYRESULT an error message about the unexpected token YYCHAR while in state YYSTATE. Return the number of bytes copied, @@ -994,24 +960,23 @@ yytnamerr (char *yyres, const char *yystr) message will do. Return YYSIZE_MAXIMUM if overflow occurs during size calculation. */ static YYSIZE_T -yysyntax_error (char *yyresult, int yystate, int yychar) +yysyntax_error(char* yyresult, int yystate, int yychar) { - int yyn = yypact[yystate]; + int yyn = yypact[yystate]; - if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) - return 0; - else - { - int yytype = YYTRANSLATE (yychar); - YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); - YYSIZE_T yysize = yysize0; - YYSIZE_T yysize1; - int yysize_overflow = 0; - enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; - char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; - int yyx; + if (!(YYPACT_NINF < yyn && yyn <= YYLAST)) + return 0; + else { + int yytype = YYTRANSLATE(yychar); + YYSIZE_T yysize0 = yytnamerr(0, yytname[yytype]); + YYSIZE_T yysize = yysize0; + YYSIZE_T yysize1; + int yysize_overflow = 0; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + char const* yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + int yyx; -# if 0 +#if 0 /* This is so xgettext sees the translatable formats that are constructed on the fly. */ YY_("syntax error, unexpected %s"); @@ -1019,82 +984,74 @@ yysyntax_error (char *yyresult, int yystate, int yychar) YY_("syntax error, unexpected %s, expecting %s or %s"); YY_("syntax error, unexpected %s, expecting %s or %s or %s"); YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); -# endif - char *yyfmt; - char const *yyf; - static char const yyunexpected[] = "syntax error, unexpected %s"; - static char const yyexpecting[] = ", expecting %s"; - static char const yyor[] = " or %s"; - char yyformat[sizeof yyunexpected - + sizeof yyexpecting - 1 - + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) - * (sizeof yyor - 1))]; - char const *yyprefix = yyexpecting; +#endif + char* yyfmt; + char const* yyf; + static char const yyunexpected[] = "syntax error, unexpected %s"; + static char const yyexpecting[] = ", expecting %s"; + static char const yyor[] = " or %s"; + char yyformat[sizeof yyunexpected + + sizeof yyexpecting - 1 + + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) + * (sizeof yyor - 1))]; + char const* yyprefix = yyexpecting; - /* Start YYX at -YYN if negative to avoid negative indexes in + /* Start YYX at -YYN if negative to avoid negative indexes in YYCHECK. */ - int yyxbegin = yyn < 0 ? -yyn : 0; + int yyxbegin = yyn < 0 ? -yyn : 0; - /* Stay within bounds of both yycheck and yytname. */ - int yychecklim = YYLAST - yyn + 1; - int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; - int yycount = 1; + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yycount = 1; - yyarg[0] = yytname[yytype]; - yyfmt = yystpcpy (yyformat, yyunexpected); + yyarg[0] = yytname[yytype]; + yyfmt = yystpcpy(yyformat, yyunexpected); - for (yyx = yyxbegin; yyx < yyxend; ++yyx) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) - { - if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) - { - yycount = 1; - yysize = yysize0; - yyformat[sizeof yyunexpected - 1] = '\0'; - break; - } - yyarg[yycount++] = yytname[yyx]; - yysize1 = yysize + yytnamerr (0, yytname[yyx]); - yysize_overflow |= (yysize1 < yysize); - yysize = yysize1; - yyfmt = yystpcpy (yyfmt, yyprefix); - yyprefix = yyor; - } + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) { + yycount = 1; + yysize = yysize0; + yyformat[sizeof yyunexpected - 1] = '\0'; + break; + } + yyarg[yycount++] = yytname[yyx]; + yysize1 = yysize + yytnamerr(0, yytname[yyx]); + yysize_overflow |= (yysize1 < yysize); + yysize = yysize1; + yyfmt = yystpcpy(yyfmt, yyprefix); + yyprefix = yyor; + } - yyf = YY_(yyformat); - yysize1 = yysize + yystrlen (yyf); - yysize_overflow |= (yysize1 < yysize); - yysize = yysize1; + yyf = YY_(yyformat); + yysize1 = yysize + yystrlen(yyf); + yysize_overflow |= (yysize1 < yysize); + yysize = yysize1; - if (yysize_overflow) - return YYSIZE_MAXIMUM; + if (yysize_overflow) + return YYSIZE_MAXIMUM; - if (yyresult) - { - /* Avoid sprintf, as that infringes on the user's name space. + if (yyresult) { + /* Avoid sprintf, as that infringes on the user's name space. Don't have undefined behavior even if the translation produced a string with the wrong number of "%s"s. */ - char *yyp = yyresult; - int yyi = 0; - while ((*yyp = *yyf) != '\0') - { - if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) - { - yyp += yytnamerr (yyp, yyarg[yyi++]); - yyf += 2; - } - else - { - yyp++; - yyf++; - } - } - } - return yysize; + char* yyp = yyresult; + int yyi = 0; + while ((*yyp = *yyf) != '\0') { + if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) { + yyp += yytnamerr(yyp, yyarg[yyi++]); + yyf += 2; + } else { + yyp++; + yyf++; + } + } + } + return yysize; } } #endif /* YYERROR_VERBOSE */ - /*-----------------------------------------------. | Release the memory associated to this symbol. | @@ -1102,50 +1059,46 @@ yysyntax_error (char *yyresult, int yystate, int yychar) /*ARGSUSED*/ #if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) + || defined __cplusplus || defined _MSC_VER) static void -yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) +yydestruct(const char* yymsg, int yytype, YYSTYPE* yyvaluep) #else static void -yydestruct (yymsg, yytype, yyvaluep) - const char *yymsg; - int yytype; - YYSTYPE *yyvaluep; + yydestruct(yymsg, yytype, yyvaluep) + const char* yymsg; +int yytype; +YYSTYPE* yyvaluep; #endif { - YYUSE (yyvaluep); + YYUSE(yyvaluep); - if (!yymsg) - yymsg = "Deleting"; - YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT(yymsg, yytype, yyvaluep, yylocationp); - switch (yytype) - { + switch (yytype) { - default: - break; + default: + break; } } - /* Prevent warnings from -Wmissing-prototypes. */ #ifdef YYPARSE_PARAM #if defined __STDC__ || defined __cplusplus -int yyparse (void *YYPARSE_PARAM); +int yyparse(void* YYPARSE_PARAM); #else -int yyparse (); +int yyparse(); #endif #else /* ! YYPARSE_PARAM */ #if defined __STDC__ || defined __cplusplus -int yyparse (void); +int yyparse(void); #else -int yyparse (); +int yyparse(); #endif #endif /* ! YYPARSE_PARAM */ - - /* The look-ahead symbol. */ int yychar; @@ -1155,50 +1108,44 @@ YYSTYPE yylval; /* Number of syntax errors so far. */ int yynerrs; - - /*----------. | yyparse. | `----------*/ #ifdef YYPARSE_PARAM #if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -int -yyparse (void *YYPARSE_PARAM) + || defined __cplusplus || defined _MSC_VER) +int yyparse(void* YYPARSE_PARAM) #else int -yyparse (YYPARSE_PARAM) - void *YYPARSE_PARAM; + yyparse(YYPARSE_PARAM) void* YYPARSE_PARAM; #endif #else /* ! YYPARSE_PARAM */ #if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -int -yyparse (void) + || defined __cplusplus || defined _MSC_VER) +int yyparse(void) #else -int -yyparse () +int yyparse() #endif #endif { - - int yystate; - int yyn; - int yyresult; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - /* Look-ahead token as an internal (translated) token number. */ - int yytoken = 0; + + int yystate; + int yyn; + int yyresult; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + /* Look-ahead token as an internal (translated) token number. */ + int yytoken = 0; #if YYERROR_VERBOSE - /* Buffer for error messages, and its allocated size. */ - char yymsgbuf[128]; - char *yymsg = yymsgbuf; - YYSIZE_T yymsg_alloc = sizeof yymsgbuf; + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char* yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; #endif - /* Three stacks and their tools: + /* Three stacks and their tools: `yyss': related to states, `yyvs': related to semantic values, `yyls': related to locations. @@ -1206,214 +1153,200 @@ yyparse () Refer to the stacks thru separate pointers, to allow yyoverflow to reallocate them elsewhere. */ - /* The state stack. */ - yytype_int16 yyssa[YYINITDEPTH]; - yytype_int16 *yyss = yyssa; - yytype_int16 *yyssp; + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16* yyss = yyssa; + yytype_int16* yyssp; - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs = yyvsa; - YYSTYPE *yyvsp; + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE* yyvs = yyvsa; + YYSTYPE* yyvsp; +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + YYSIZE_T yystacksize = YYINITDEPTH; -#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) - - YYSIZE_T yystacksize = YYINITDEPTH; - - /* The variables used to return semantic value and location from the + /* The variables used to return semantic value and location from the action routines. */ - YYSTYPE yyval; + YYSTYPE yyval; - - /* The number of symbols on the RHS of the reduced rule. + /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ - int yylen = 0; + int yylen = 0; - YYDPRINTF ((stderr, "Starting parse\n")); + YYDPRINTF((stderr, "Starting parse\n")); - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ - /* Initialize stack pointers. + /* Initialize stack pointers. Waste one element of value and location stack so that they stay on the same level as the state stack. The wasted elements are never initialized. */ - yyssp = yyss; - yyvsp = yyvs; + yyssp = yyss; + yyvsp = yyvs; - goto yysetstate; + goto yysetstate; /*------------------------------------------------------------. | yynewstate -- Push a new state, which is found in yystate. | `------------------------------------------------------------*/ - yynewstate: - /* In all cases, when you get here, the value and location stacks +yynewstate: + /* In all cases, when you get here, the value and location stacks have just been pushed. So pushing a state here evens the stacks. */ - yyssp++; + yyssp++; - yysetstate: - *yyssp = yystate; +yysetstate: + *yyssp = yystate; - if (yyss + yystacksize - 1 <= yyssp) - { - /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = yyssp - yyss + 1; + if (yyss + yystacksize - 1 <= yyssp) { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; #ifdef yyoverflow - { - /* Give user a chance to reallocate the stack. Use copies of + { + /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into memory. */ - YYSTYPE *yyvs1 = yyvs; - yytype_int16 *yyss1 = yyss; + YYSTYPE* yyvs1 = yyvs; + yytype_int16* yyss1 = yyss; - - /* Each stack pointer address is followed by the size of the + /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ - yyoverflow (YY_("memory exhausted"), - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), + yyoverflow(YY_("memory exhausted"), + &yyss1, yysize * sizeof(*yyssp), + &yyvs1, yysize * sizeof(*yyvsp), - &yystacksize); + &yystacksize); - yyss = yyss1; - yyvs = yyvs1; - } + yyss = yyss1; + yyvs = yyvs1; + } #else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyexhaustedlab; -# else - /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) - goto yyexhaustedlab; - yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; +#ifndef YYSTACK_RELOCATE + goto yyexhaustedlab; +#else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; - { - yytype_int16 *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss); - YYSTACK_RELOCATE (yyvs); + { + yytype_int16* yyss1 = yyss; + union yyalloc* yyptr = (union yyalloc*)YYSTACK_ALLOC(YYSTACK_BYTES(yystacksize)); + if (!yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE(yyss); + YYSTACK_RELOCATE(yyvs); -# undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); - } -# endif +#undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE(yyss1); + } +#endif #endif /* no yyoverflow */ - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1; + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + YYDPRINTF((stderr, "Stack size increased to %lu\n", + (unsigned long int)yystacksize)); - YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); - - if (yyss + yystacksize - 1 <= yyssp) - YYABORT; + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; } - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + YYDPRINTF((stderr, "Entering state %d\n", yystate)); - goto yybackup; + goto yybackup; /*-----------. | yybackup. | `-----------*/ yybackup: - /* Do appropriate processing given the current state. Read a + /* Do appropriate processing given the current state. Read a look-ahead token if we need one and don't already have one. */ - /* First try to decide what to do without reference to look-ahead token. */ - yyn = yypact[yystate]; - if (yyn == YYPACT_NINF) - goto yydefault; + /* First try to decide what to do without reference to look-ahead token. */ + yyn = yypact[yystate]; + if (yyn == YYPACT_NINF) + goto yydefault; - /* Not known => get a look-ahead token if don't already have one. */ + /* Not known => get a look-ahead token if don't already have one. */ - /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ - if (yychar == YYEMPTY) - { - YYDPRINTF ((stderr, "Reading a token: ")); - yychar = YYLEX; + /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ + if (yychar == YYEMPTY) { + YYDPRINTF((stderr, "Reading a token: ")); + yychar = YYLEX; } - if (yychar <= YYEOF) - { - yychar = yytoken = YYEOF; - YYDPRINTF ((stderr, "Now at end of input.\n")); - } - else - { - yytoken = YYTRANSLATE (yychar); - YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + if (yychar <= YYEOF) { + yychar = yytoken = YYEOF; + YYDPRINTF((stderr, "Now at end of input.\n")); + } else { + yytoken = YYTRANSLATE(yychar); + YY_SYMBOL_PRINT("Next token is", yytoken, &yylval, &yylloc); } - /* If the proper action on seeing token YYTOKEN is to reduce or to + /* If the proper action on seeing token YYTOKEN is to reduce or to detect an error, take that action. */ - yyn += yytoken; - if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) - goto yydefault; - yyn = yytable[yyn]; - if (yyn <= 0) - { - if (yyn == 0 || yyn == YYTABLE_NINF) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) { + if (yyn == 0 || yyn == YYTABLE_NINF) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; } - if (yyn == YYFINAL) - YYACCEPT; + if (yyn == YYFINAL) + YYACCEPT; - /* Count tokens shifted since error; after three, turn off error + /* Count tokens shifted since error; after three, turn off error status. */ - if (yyerrstatus) - yyerrstatus--; + if (yyerrstatus) + yyerrstatus--; - /* Shift the look-ahead token. */ - YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + /* Shift the look-ahead token. */ + YY_SYMBOL_PRINT("Shifting", yytoken, &yylval, &yylloc); - /* Discard the shifted token unless it is eof. */ - if (yychar != YYEOF) - yychar = YYEMPTY; + /* Discard the shifted token unless it is eof. */ + if (yychar != YYEOF) + yychar = YYEMPTY; - yystate = yyn; - *++yyvsp = yylval; - - goto yynewstate; + yystate = yyn; + *++yyvsp = yylval; + goto yynewstate; /*-----------------------------------------------------------. | yydefault -- do the default action for the current state. | `-----------------------------------------------------------*/ yydefault: - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - goto yyreduce; - + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; /*-----------------------------. | yyreduce -- Do a reduction. | `-----------------------------*/ yyreduce: - /* yyn is the number of a rule to reduce with. */ - yylen = yyr2[yyn]; + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; - /* If YYLEN is nonzero, implement the default value of the action: + /* If YYLEN is nonzero, implement the default value of the action: `$$ = $1'. Otherwise, the following line sets YYVAL to garbage. @@ -1421,410 +1354,400 @@ yyreduce: users should not rely upon it. Assigning to YYVAL unconditionally makes the parser a bit smaller, and it avoids a GCC warning that YYVAL may be used uninitialized. */ - yyval = yyvsp[1-yylen]; + yyval = yyvsp[1 - yylen]; - - YY_REDUCE_PRINT (yyn); - switch (yyn) - { - case 2: + YY_REDUCE_PRINT(yyn); + switch (yyn) { + case 2: #line 56 "src/sdl/debugger-expr.y" - {dexp_result = (yyvsp[(1) - (1)].number);} - break; + { + dexp_result = (yyvsp[(1) - (1)].number); + } break; - case 3: + case 3: #line 59 "src/sdl/debugger-expr.y" - { (yyval.number) = (yyvsp[(1) - (1)].number); } - break; + { + (yyval.number) = (yyvsp[(1) - (1)].number); + } break; - case 4: + case 4: #line 60 "src/sdl/debugger-expr.y" - { - std::string v((yyvsp[(1) - (1)].string)); - if (dexp_vars.count(v) == 0) { - printf("Variable %s not defined.\n", (yyvsp[(1) - (1)].string)); - YYABORT; - } - (yyval.number) = dexp_vars[v]; -} - break; + { + std::string v((yyvsp[(1) - (1)].string)); + if (dexp_vars.count(v) == 0) { + printf("Variable %s not defined.\n", (yyvsp[(1) - (1)].string)); + YYABORT; + } + (yyval.number) = dexp_vars[v]; + } break; - case 5: + case 5: #line 68 "src/sdl/debugger-expr.y" - { (yyval.number) = (yyvsp[(1) - (3)].number) + (yyvsp[(3) - (3)].number); } - break; + { + (yyval.number) = (yyvsp[(1) - (3)].number) + (yyvsp[(3) - (3)].number); + } break; - case 6: + case 6: #line 69 "src/sdl/debugger-expr.y" - { (yyval.number) = (yyvsp[(1) - (3)].number) - (yyvsp[(3) - (3)].number);} - break; + { + (yyval.number) = (yyvsp[(1) - (3)].number) - (yyvsp[(3) - (3)].number); + } break; - case 7: + case 7: #line 70 "src/sdl/debugger-expr.y" - { (yyval.number) = -(yyvsp[(2) - (2)].number);} - break; + { + (yyval.number) = -(yyvsp[(2) - (2)].number); + } break; - case 8: + case 8: #line 71 "src/sdl/debugger-expr.y" - { (yyval.number) = ~(yyvsp[(2) - (2)].number);} - break; + { + (yyval.number) = ~(yyvsp[(2) - (2)].number); + } break; - case 9: + case 9: #line 72 "src/sdl/debugger-expr.y" - { (yyval.number) = (yyvsp[(1) - (3)].number) / (yyvsp[(3) - (3)].number);} - break; + { + (yyval.number) = (yyvsp[(1) - (3)].number) / (yyvsp[(3) - (3)].number); + } break; - case 10: + case 10: #line 73 "src/sdl/debugger-expr.y" - { (yyval.number) = (yyvsp[(1) - (3)].number) * (yyvsp[(3) - (3)].number);} - break; + { + (yyval.number) = (yyvsp[(1) - (3)].number) * (yyvsp[(3) - (3)].number); + } break; - case 11: + case 11: #line 74 "src/sdl/debugger-expr.y" - { (yyval.number) = (yyvsp[(1) - (3)].number) << (yyvsp[(3) - (3)].number);} - break; + { + (yyval.number) = (yyvsp[(1) - (3)].number) << (yyvsp[(3) - (3)].number); + } break; - case 12: + case 12: #line 75 "src/sdl/debugger-expr.y" - { (yyval.number) = (yyvsp[(1) - (3)].number) >> (yyvsp[(3) - (3)].number);} - break; + { + (yyval.number) = (yyvsp[(1) - (3)].number) >> (yyvsp[(3) - (3)].number); + } break; - case 13: + case 13: #line 76 "src/sdl/debugger-expr.y" - { (yyval.number)=(yyvsp[(2) - (3)].number);} - break; + { + (yyval.number) = (yyvsp[(2) - (3)].number); + } break; - case 14: + case 14: #line 77 "src/sdl/debugger-expr.y" - { (yyval.number) = (yyvsp[(1) - (3)].number) & (yyvsp[(3) - (3)].number);} - break; + { + (yyval.number) = (yyvsp[(1) - (3)].number) & (yyvsp[(3) - (3)].number); + } break; - case 15: + case 15: #line 78 "src/sdl/debugger-expr.y" - { (yyval.number) = (yyvsp[(1) - (3)].number) | (yyvsp[(3) - (3)].number);} - break; + { + (yyval.number) = (yyvsp[(1) - (3)].number) | (yyvsp[(3) - (3)].number); + } break; - case 16: + case 16: #line 79 "src/sdl/debugger-expr.y" - { (yyval.number) = (yyvsp[(1) - (3)].number) ^ (yyvsp[(3) - (3)].number); } - break; + { + (yyval.number) = (yyvsp[(1) - (3)].number) ^ (yyvsp[(3) - (3)].number); + } break; - case 17: + case 17: #line 80 "src/sdl/debugger-expr.y" - { (yyval.number) = reg[(yyvsp[(1) - (1)].number)].I; } - break; + { + (yyval.number) = reg[(yyvsp[(1) - (1)].number)].I; + } break; - case 18: + case 18: #line 81 "src/sdl/debugger-expr.y" - { (yyval.number) = readByte((yyvsp[(2) - (3)].number)); } - break; + { + (yyval.number) = readByte((yyvsp[(2) - (3)].number)); + } break; - case 19: + case 19: #line 82 "src/sdl/debugger-expr.y" - { (yyval.number) = readHalfWord((yyvsp[(2) - (3)].number)); } - break; + { + (yyval.number) = readHalfWord((yyvsp[(2) - (3)].number)); + } break; - case 20: + case 20: #line 83 "src/sdl/debugger-expr.y" - { (yyval.number) = readWord((yyvsp[(2) - (3)].number)); } - break; + { + (yyval.number) = readWord((yyvsp[(2) - (3)].number)); + } break; - case 21: + case 21: #line 84 "src/sdl/debugger-expr.y" - { (yyval.number) = readWord((yyvsp[(2) - (3)].number)); } - break; - + { + (yyval.number) = readWord((yyvsp[(2) - (3)].number)); + } break; /* Line 1267 of yacc.c. */ #line 1534 "src/sdl/debugger-expr-yacc.cpp" - default: break; + default: + break; } - YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + YY_SYMBOL_PRINT("-> $$ =", yyr1[yyn], &yyval, &yyloc); - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); + YYPOPSTACK(yylen); + yylen = 0; + YY_STACK_PRINT(yyss, yyssp); - *++yyvsp = yyval; + *++yyvsp = yyval; - - /* Now `shift' the result of the reduction. Determine what state + /* Now `shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ - yyn = yyr1[yyn]; + yyn = yyr1[yyn]; - yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; - if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTOKENS]; - - goto yynewstate; + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + goto yynewstate; /*------------------------------------. | yyerrlab -- here on detecting error | `------------------------------------*/ yyerrlab: - /* If not already recovering from an error, report this error. */ - if (!yyerrstatus) - { - ++yynerrs; -#if ! YYERROR_VERBOSE - yyerror (YY_("syntax error")); + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) { + ++yynerrs; +#if !YYERROR_VERBOSE + yyerror(YY_("syntax error")); #else - { - YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); - if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) - { - YYSIZE_T yyalloc = 2 * yysize; - if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) - yyalloc = YYSTACK_ALLOC_MAXIMUM; - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); - yymsg = (char *) YYSTACK_ALLOC (yyalloc); - if (yymsg) - yymsg_alloc = yyalloc; - else - { - yymsg = yymsgbuf; - yymsg_alloc = sizeof yymsgbuf; - } - } + { + YYSIZE_T yysize = yysyntax_error(0, yystate, yychar); + if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) { + YYSIZE_T yyalloc = 2 * yysize; + if (!(yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) + yyalloc = YYSTACK_ALLOC_MAXIMUM; + if (yymsg != yymsgbuf) + YYSTACK_FREE(yymsg); + yymsg = (char*)YYSTACK_ALLOC(yyalloc); + if (yymsg) + yymsg_alloc = yyalloc; + else { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + } + } - if (0 < yysize && yysize <= yymsg_alloc) - { - (void) yysyntax_error (yymsg, yystate, yychar); - yyerror (yymsg); - } - else - { - yyerror (YY_("syntax error")); - if (yysize != 0) - goto yyexhaustedlab; - } - } + if (0 < yysize && yysize <= yymsg_alloc) { + (void)yysyntax_error(yymsg, yystate, yychar); + yyerror(yymsg); + } else { + yyerror(YY_("syntax error")); + if (yysize != 0) + goto yyexhaustedlab; + } + } #endif } - - - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse look-ahead token after an + if (yyerrstatus == 3) { + /* If just tried and failed to reuse look-ahead token after an error, discard it. */ - if (yychar <= YYEOF) - { - /* Return failure if at end of input. */ - if (yychar == YYEOF) - YYABORT; - } - else - { - yydestruct ("Error: discarding", - yytoken, &yylval); - yychar = YYEMPTY; - } + if (yychar <= YYEOF) { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } else { + yydestruct("Error: discarding", + yytoken, &yylval); + yychar = YYEMPTY; + } } - /* Else will try to reuse look-ahead token after shifting the error + /* Else will try to reuse look-ahead token after shifting the error token. */ - goto yyerrlab1; - + goto yyerrlab1; /*---------------------------------------------------. | yyerrorlab -- error raised explicitly by YYERROR. | `---------------------------------------------------*/ yyerrorlab: - /* Pacify compilers like GCC when the user code never invokes + /* Pacify compilers like GCC when the user code never invokes YYERROR and the label yyerrorlab therefore never appears in user code. */ - if (/*CONSTCOND*/ 0) - goto yyerrorlab; + if (/*CONSTCOND*/ 0) + goto yyerrorlab; - /* Do not reclaim the symbols of the rule which action triggered + /* Do not reclaim the symbols of the rule which action triggered this YYERROR. */ - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - yystate = *yyssp; - goto yyerrlab1; - + YYPOPSTACK(yylen); + yylen = 0; + YY_STACK_PRINT(yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; /*-------------------------------------------------------------. | yyerrlab1 -- common code for both syntax error and YYERROR. | `-------------------------------------------------------------*/ yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ + yyerrstatus = 3; /* Each real token shifted decrements this. */ - for (;;) - { - yyn = yypact[yystate]; - if (yyn != YYPACT_NINF) - { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } + for (;;) { + yyn = yypact[yystate]; + if (yyn != YYPACT_NINF) { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } - /* Pop the current state because it cannot handle the error token. */ - if (yyssp == yyss) - YYABORT; + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; - - yydestruct ("Error: popping", - yystos[yystate], yyvsp); - YYPOPSTACK (1); - yystate = *yyssp; - YY_STACK_PRINT (yyss, yyssp); + yydestruct("Error: popping", + yystos[yystate], yyvsp); + YYPOPSTACK(1); + yystate = *yyssp; + YY_STACK_PRINT(yyss, yyssp); } - if (yyn == YYFINAL) - YYACCEPT; + if (yyn == YYFINAL) + YYACCEPT; - *++yyvsp = yylval; + *++yyvsp = yylval; + /* Shift the error token. */ + YY_SYMBOL_PRINT("Shifting", yystos[yyn], yyvsp, yylsp); - /* Shift the error token. */ - YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); - - yystate = yyn; - goto yynewstate; - + yystate = yyn; + goto yynewstate; /*-------------------------------------. | yyacceptlab -- YYACCEPT comes here. | `-------------------------------------*/ yyacceptlab: - yyresult = 0; - goto yyreturn; + yyresult = 0; + goto yyreturn; /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ yyabortlab: - yyresult = 1; - goto yyreturn; + yyresult = 1; + goto yyreturn; #ifndef yyoverflow /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ yyexhaustedlab: - yyerror (YY_("memory exhausted")); - yyresult = 2; - /* Fall through. */ + yyerror(YY_("memory exhausted")); + yyresult = 2; +/* Fall through. */ #endif yyreturn: - if (yychar != YYEOF && yychar != YYEMPTY) - yydestruct ("Cleanup: discarding lookahead", - yytoken, &yylval); - /* Do not reclaim the symbols of the rule which action triggered + if (yychar != YYEOF && yychar != YYEMPTY) + yydestruct("Cleanup: discarding lookahead", + yytoken, &yylval); + /* Do not reclaim the symbols of the rule which action triggered this YYABORT or YYACCEPT. */ - YYPOPSTACK (yylen); - YY_STACK_PRINT (yyss, yyssp); - while (yyssp != yyss) - { - yydestruct ("Cleanup: popping", - yystos[*yyssp], yyvsp); - YYPOPSTACK (1); + YYPOPSTACK(yylen); + YY_STACK_PRINT(yyss, yyssp); + while (yyssp != yyss) { + yydestruct("Cleanup: popping", + yystos[*yyssp], yyvsp); + YYPOPSTACK(1); } #ifndef yyoverflow - if (yyss != yyssa) - YYSTACK_FREE (yyss); + if (yyss != yyssa) + YYSTACK_FREE(yyss); #endif #if YYERROR_VERBOSE - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); + if (yymsg != yymsgbuf) + YYSTACK_FREE(yymsg); #endif - /* Make sure YYID is used. */ - return YYID (yyresult); + /* Make sure YYID is used. */ + return YYID(yyresult); } - #line 86 "src/sdl/debugger-expr.y" - -bool dexp_eval(char *expr, u32 *result) +bool dexp_eval(char* expr, u32* result) { - extern void dexp_flush(); - extern char *dexprString; - extern int dexprCol; + extern void dexp_flush(); + extern char* dexprString; + extern int dexprCol; - dexp_flush(); - - - dexprString = expr; - dexprCol = 0; - - if(!dexp_parse()) { - *result = dexp_result; - return true; - } else { - return false; - } + dexp_flush(); + + dexprString = expr; + dexprCol = 0; + + if (!dexp_parse()) { + *result = dexp_result; + return true; + } else { + return false; + } } -int dexp_error(char *s) +int dexp_error(char* s) { - return 0; + return 0; } -void dexp_setVar(char *name, u32 value) +void dexp_setVar(char* name, u32 value) { - std::string a(name); - dexp_vars[a] = value; + std::string a(name); + dexp_vars[a] = value; } void dexp_listVars() { - std::map::iterator iter; + std::map::iterator iter; - for (iter = dexp_vars.begin(); iter != dexp_vars.end(); iter++) { - printf("%s = %08X\n", iter->first.c_str(), iter->second); - } -} - -void dexp_saveVars(char *file) -{ - std::map::iterator iter; - - FILE *f = fopen(file, "w"); - if (!f) { - printf("Could not open file %s\n", file); - return; - } - - for (iter = dexp_vars.begin(); iter != dexp_vars.end(); iter++) { - fprintf(f, "%s = %08X\n", iter->first.c_str(), iter->second); - } - fclose(f); -} - -void dexp_loadVars(char *file) -{ - std::map::iterator iter; - char buffer[500]; - char name[500]; - u32 val; - - FILE *f = fopen(file, "r"); - if (!f) { - printf("Could not open file %s\n", file); - return; - } - - while (fgets(buffer, 500, f) != NULL) { - if (sscanf(buffer, "%s = %x",name,&val) == 2) { - dexp_setVar(name, val); + for (iter = dexp_vars.begin(); iter != dexp_vars.end(); iter++) { + printf("%s = %08X\n", iter->first.c_str(), iter->second); + } +} + +void dexp_saveVars(char* file) +{ + std::map::iterator iter; + + FILE* f = fopen(file, "w"); + if (!f) { + printf("Could not open file %s\n", file); + return; + } + + for (iter = dexp_vars.begin(); iter != dexp_vars.end(); iter++) { + fprintf(f, "%s = %08X\n", iter->first.c_str(), iter->second); + } + fclose(f); +} + +void dexp_loadVars(char* file) +{ + std::map::iterator iter; + char buffer[500]; + char name[500]; + u32 val; + + FILE* f = fopen(file, "r"); + if (!f) { + printf("Could not open file %s\n", file); + return; + } + + while (fgets(buffer, 500, f) != NULL) { + if (sscanf(buffer, "%s = %x", name, &val) == 2) { + dexp_setVar(name, val); + } } - } } diff --git a/src/gba/elf.cpp b/src/gba/elf.cpp index 27331858..529ae88b 100644 --- a/src/gba/elf.cpp +++ b/src/gba/elf.cpp @@ -2,2982 +2,2908 @@ #include #include -#include "GBA.h" -#include "../common/Port.h" -#include "elf.h" #include "../NLS.h" +#include "../common/Port.h" +#include "GBA.h" +#include "elf.h" #define elfReadMemory(addr) \ - READ32LE((&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask])) + READ32LE((&map[(addr) >> 24].address[(addr)&map[(addr) >> 24].mask])) -#define DW_TAG_array_type 0x01 -#define DW_TAG_enumeration_type 0x04 -#define DW_TAG_formal_parameter 0x05 -#define DW_TAG_label 0x0a -#define DW_TAG_lexical_block 0x0b -#define DW_TAG_member 0x0d -#define DW_TAG_pointer_type 0x0f -#define DW_TAG_reference_type 0x10 -#define DW_TAG_compile_unit 0x11 -#define DW_TAG_structure_type 0x13 -#define DW_TAG_subroutine_type 0x15 -#define DW_TAG_typedef 0x16 -#define DW_TAG_union_type 0x17 +#define DW_TAG_array_type 0x01 +#define DW_TAG_enumeration_type 0x04 +#define DW_TAG_formal_parameter 0x05 +#define DW_TAG_label 0x0a +#define DW_TAG_lexical_block 0x0b +#define DW_TAG_member 0x0d +#define DW_TAG_pointer_type 0x0f +#define DW_TAG_reference_type 0x10 +#define DW_TAG_compile_unit 0x11 +#define DW_TAG_structure_type 0x13 +#define DW_TAG_subroutine_type 0x15 +#define DW_TAG_typedef 0x16 +#define DW_TAG_union_type 0x17 #define DW_TAG_unspecified_parameters 0x18 -#define DW_TAG_inheritance 0x1c -#define DW_TAG_inlined_subroutine 0x1d -#define DW_TAG_subrange_type 0x21 -#define DW_TAG_base_type 0x24 -#define DW_TAG_const_type 0x26 -#define DW_TAG_enumerator 0x28 -#define DW_TAG_subprogram 0x2e -#define DW_TAG_variable 0x34 -#define DW_TAG_volatile_type 0x35 +#define DW_TAG_inheritance 0x1c +#define DW_TAG_inlined_subroutine 0x1d +#define DW_TAG_subrange_type 0x21 +#define DW_TAG_base_type 0x24 +#define DW_TAG_const_type 0x26 +#define DW_TAG_enumerator 0x28 +#define DW_TAG_subprogram 0x2e +#define DW_TAG_variable 0x34 +#define DW_TAG_volatile_type 0x35 -#define DW_AT_sibling 0x01 -#define DW_AT_location 0x02 -#define DW_AT_name 0x03 -#define DW_AT_byte_size 0x0b -#define DW_AT_bit_offset 0x0c -#define DW_AT_bit_size 0x0d -#define DW_AT_stmt_list 0x10 -#define DW_AT_low_pc 0x11 -#define DW_AT_high_pc 0x12 -#define DW_AT_language 0x13 -#define DW_AT_compdir 0x1b -#define DW_AT_const_value 0x1c -#define DW_AT_containing_type 0x1d -#define DW_AT_inline 0x20 -#define DW_AT_producer 0x25 -#define DW_AT_prototyped 0x27 -#define DW_AT_upper_bound 0x2f -#define DW_AT_abstract_origin 0x31 -#define DW_AT_accessibility 0x32 -#define DW_AT_artificial 0x34 +#define DW_AT_sibling 0x01 +#define DW_AT_location 0x02 +#define DW_AT_name 0x03 +#define DW_AT_byte_size 0x0b +#define DW_AT_bit_offset 0x0c +#define DW_AT_bit_size 0x0d +#define DW_AT_stmt_list 0x10 +#define DW_AT_low_pc 0x11 +#define DW_AT_high_pc 0x12 +#define DW_AT_language 0x13 +#define DW_AT_compdir 0x1b +#define DW_AT_const_value 0x1c +#define DW_AT_containing_type 0x1d +#define DW_AT_inline 0x20 +#define DW_AT_producer 0x25 +#define DW_AT_prototyped 0x27 +#define DW_AT_upper_bound 0x2f +#define DW_AT_abstract_origin 0x31 +#define DW_AT_accessibility 0x32 +#define DW_AT_artificial 0x34 #define DW_AT_data_member_location 0x38 -#define DW_AT_decl_file 0x3a -#define DW_AT_decl_line 0x3b -#define DW_AT_declaration 0x3c -#define DW_AT_encoding 0x3e -#define DW_AT_external 0x3f -#define DW_AT_frame_base 0x40 -#define DW_AT_macro_info 0x43 -#define DW_AT_specification 0x47 -#define DW_AT_type 0x49 -#define DW_AT_virtuality 0x4c +#define DW_AT_decl_file 0x3a +#define DW_AT_decl_line 0x3b +#define DW_AT_declaration 0x3c +#define DW_AT_encoding 0x3e +#define DW_AT_external 0x3f +#define DW_AT_frame_base 0x40 +#define DW_AT_macro_info 0x43 +#define DW_AT_specification 0x47 +#define DW_AT_type 0x49 +#define DW_AT_virtuality 0x4c #define DW_AT_vtable_elem_location 0x4d // DWARF 2.1/3.0 extensions -#define DW_AT_entry_pc 0x52 -#define DW_AT_ranges 0x55 +#define DW_AT_entry_pc 0x52 +#define DW_AT_ranges 0x55 // ARM Compiler extensions -#define DW_AT_proc_body 0x2000 -#define DW_AT_save_offset 0x2001 -#define DW_AT_user_2002 0x2002 +#define DW_AT_proc_body 0x2000 +#define DW_AT_save_offset 0x2001 +#define DW_AT_user_2002 0x2002 // MIPS extensions -#define DW_AT_MIPS_linkage_name 0x2007 +#define DW_AT_MIPS_linkage_name 0x2007 -#define DW_FORM_addr 0x01 -#define DW_FORM_data2 0x05 -#define DW_FORM_data4 0x06 -#define DW_FORM_string 0x08 -#define DW_FORM_block 0x09 -#define DW_FORM_block1 0x0a -#define DW_FORM_data1 0x0b -#define DW_FORM_flag 0x0c -#define DW_FORM_sdata 0x0d -#define DW_FORM_strp 0x0e -#define DW_FORM_udata 0x0f -#define DW_FORM_ref_addr 0x10 -#define DW_FORM_ref4 0x13 +#define DW_FORM_addr 0x01 +#define DW_FORM_data2 0x05 +#define DW_FORM_data4 0x06 +#define DW_FORM_string 0x08 +#define DW_FORM_block 0x09 +#define DW_FORM_block1 0x0a +#define DW_FORM_data1 0x0b +#define DW_FORM_flag 0x0c +#define DW_FORM_sdata 0x0d +#define DW_FORM_strp 0x0e +#define DW_FORM_udata 0x0f +#define DW_FORM_ref_addr 0x10 +#define DW_FORM_ref4 0x13 #define DW_FORM_ref_udata 0x15 -#define DW_FORM_indirect 0x16 +#define DW_FORM_indirect 0x16 -#define DW_OP_addr 0x03 +#define DW_OP_addr 0x03 #define DW_OP_plus_uconst 0x23 -#define DW_OP_reg0 0x50 -#define DW_OP_reg1 0x51 -#define DW_OP_reg2 0x52 -#define DW_OP_reg3 0x53 -#define DW_OP_reg4 0x54 -#define DW_OP_reg5 0x55 -#define DW_OP_reg6 0x56 -#define DW_OP_reg7 0x57 -#define DW_OP_reg8 0x58 -#define DW_OP_reg9 0x59 -#define DW_OP_reg10 0x5a -#define DW_OP_reg11 0x5b -#define DW_OP_reg12 0x5c -#define DW_OP_reg13 0x5d -#define DW_OP_reg14 0x5e -#define DW_OP_reg15 0x5f -#define DW_OP_fbreg 0x91 +#define DW_OP_reg0 0x50 +#define DW_OP_reg1 0x51 +#define DW_OP_reg2 0x52 +#define DW_OP_reg3 0x53 +#define DW_OP_reg4 0x54 +#define DW_OP_reg5 0x55 +#define DW_OP_reg6 0x56 +#define DW_OP_reg7 0x57 +#define DW_OP_reg8 0x58 +#define DW_OP_reg9 0x59 +#define DW_OP_reg10 0x5a +#define DW_OP_reg11 0x5b +#define DW_OP_reg12 0x5c +#define DW_OP_reg13 0x5d +#define DW_OP_reg14 0x5e +#define DW_OP_reg15 0x5f +#define DW_OP_fbreg 0x91 -#define DW_LNS_extended_op 0x00 -#define DW_LNS_copy 0x01 -#define DW_LNS_advance_pc 0x02 -#define DW_LNS_advance_line 0x03 -#define DW_LNS_set_file 0x04 -#define DW_LNS_set_column 0x05 -#define DW_LNS_negate_stmt 0x06 -#define DW_LNS_set_basic_block 0x07 -#define DW_LNS_const_add_pc 0x08 +#define DW_LNS_extended_op 0x00 +#define DW_LNS_copy 0x01 +#define DW_LNS_advance_pc 0x02 +#define DW_LNS_advance_line 0x03 +#define DW_LNS_set_file 0x04 +#define DW_LNS_set_column 0x05 +#define DW_LNS_negate_stmt 0x06 +#define DW_LNS_set_basic_block 0x07 +#define DW_LNS_const_add_pc 0x08 #define DW_LNS_fixed_advance_pc 0x09 #define DW_LNE_end_sequence 0x01 -#define DW_LNE_set_address 0x02 -#define DW_LNE_define_file 0x03 +#define DW_LNE_set_address 0x02 +#define DW_LNE_define_file 0x03 -#define DW_CFA_advance_loc 0x01 -#define DW_CFA_offset 0x02 -#define DW_CFA_restore 0x03 -#define DW_CFA_set_loc 0x01 -#define DW_CFA_advance_loc1 0x02 -#define DW_CFA_advance_loc2 0x03 -#define DW_CFA_advance_loc4 0x04 -#define DW_CFA_offset_extended 0x05 +#define DW_CFA_advance_loc 0x01 +#define DW_CFA_offset 0x02 +#define DW_CFA_restore 0x03 +#define DW_CFA_set_loc 0x01 +#define DW_CFA_advance_loc1 0x02 +#define DW_CFA_advance_loc2 0x03 +#define DW_CFA_advance_loc4 0x04 +#define DW_CFA_offset_extended 0x05 #define DW_CFA_restore_extended 0x06 -#define DW_CFA_undefined 0x07 -#define DW_CFA_same_value 0x08 -#define DW_CFA_register 0x09 -#define DW_CFA_remember_state 0x0a -#define DW_CFA_restore_state 0x0b -#define DW_CFA_def_cfa 0x0c +#define DW_CFA_undefined 0x07 +#define DW_CFA_same_value 0x08 +#define DW_CFA_register 0x09 +#define DW_CFA_remember_state 0x0a +#define DW_CFA_restore_state 0x0b +#define DW_CFA_def_cfa 0x0c #define DW_CFA_def_cfa_register 0x0d -#define DW_CFA_def_cfa_offset 0x0e -#define DW_CFA_nop 0x00 +#define DW_CFA_def_cfa_offset 0x0e +#define DW_CFA_nop 0x00 -#define CASE_TYPE_TAG \ - case DW_TAG_const_type:\ - case DW_TAG_volatile_type:\ - case DW_TAG_pointer_type:\ - case DW_TAG_base_type:\ - case DW_TAG_array_type:\ - case DW_TAG_structure_type:\ - case DW_TAG_union_type:\ - case DW_TAG_typedef:\ - case DW_TAG_subroutine_type:\ - case DW_TAG_enumeration_type:\ - case DW_TAG_enumerator:\ +#define CASE_TYPE_TAG \ + case DW_TAG_const_type: \ + case DW_TAG_volatile_type: \ + case DW_TAG_pointer_type: \ + case DW_TAG_base_type: \ + case DW_TAG_array_type: \ + case DW_TAG_structure_type: \ + case DW_TAG_union_type: \ + case DW_TAG_typedef: \ + case DW_TAG_subroutine_type: \ + case DW_TAG_enumeration_type: \ + case DW_TAG_enumerator: \ case DW_TAG_reference_type struct ELFcie { - ELFcie *next; - u32 offset; - u8 *augmentation; - u32 codeAlign; - s32 dataAlign; - int returnAddress; - u8 *data; - u32 dataLen; + ELFcie* next; + u32 offset; + u8* augmentation; + u32 codeAlign; + s32 dataAlign; + int returnAddress; + u8* data; + u32 dataLen; }; struct ELFfde { - ELFcie *cie; - u32 address; - u32 end; - u8 *data; - u32 dataLen; + ELFcie* cie; + u32 address; + u32 end; + u8* data; + u32 dataLen; }; enum ELFRegMode { - REG_NOT_SET, - REG_OFFSET, - REG_REGISTER + REG_NOT_SET, + REG_OFFSET, + REG_REGISTER }; - struct ELFFrameStateRegister { - ELFRegMode mode; - int reg; - s32 offset; + ELFRegMode mode; + int reg; + s32 offset; }; struct ELFFrameStateRegisters { - ELFFrameStateRegister regs[16]; - ELFFrameStateRegisters *previous; + ELFFrameStateRegister regs[16]; + ELFFrameStateRegisters* previous; }; enum ELFCfaMode { - CFA_NOT_SET, - CFA_REG_OFFSET + CFA_NOT_SET, + CFA_REG_OFFSET }; struct ELFFrameState { - ELFFrameStateRegisters registers; + ELFFrameStateRegisters registers; - ELFCfaMode cfaMode; - int cfaRegister; - s32 cfaOffset; + ELFCfaMode cfaMode; + int cfaRegister; + s32 cfaOffset; - u32 pc; + u32 pc; - int dataAlign; - int codeAlign; - int returnAddress; + int dataAlign; + int codeAlign; + int returnAddress; }; extern bool cpuIsMultiBoot; -Symbol *elfSymbols = NULL; -char *elfSymbolsStrTab = NULL; +Symbol* elfSymbols = NULL; +char* elfSymbolsStrTab = NULL; int elfSymbolsCount = 0; -ELFSectionHeader **elfSectionHeaders = NULL; -char *elfSectionHeadersStringTable = NULL; +ELFSectionHeader** elfSectionHeaders = NULL; +char* elfSectionHeadersStringTable = NULL; int elfSectionHeadersCount = 0; -u8 *elfFileData = NULL; +u8* elfFileData = NULL; -CompileUnit *elfCompileUnits = NULL; -DebugInfo *elfDebugInfo = NULL; -char *elfDebugStrings = NULL; +CompileUnit* elfCompileUnits = NULL; +DebugInfo* elfDebugInfo = NULL; +char* elfDebugStrings = NULL; -ELFcie *elfCies = NULL; -ELFfde **elfFdes = NULL; +ELFcie* elfCies = NULL; +ELFfde** elfFdes = NULL; int elfFdeCount = 0; -CompileUnit *elfCurrentUnit = NULL; +CompileUnit* elfCurrentUnit = NULL; -u32 elfRead4Bytes(u8 *); -u16 elfRead2Bytes(u8 *); +u32 elfRead4Bytes(u8*); +u16 elfRead2Bytes(u8*); -CompileUnit *elfGetCompileUnit(u32 addr) +CompileUnit* elfGetCompileUnit(u32 addr) { - if(elfCompileUnits) { - CompileUnit *unit = elfCompileUnits; - while(unit) { - if(unit->lowPC) { - if(addr >= unit->lowPC && addr < unit->highPC) - return unit; - } else { - ARanges *r = unit->ranges; - if(r) { - int count = r->count; - for(int j = 0; j < count; j++) { - if(addr >= r->ranges[j].lowPC && addr < r->ranges[j].highPC) - return unit; - } + if (elfCompileUnits) { + CompileUnit* unit = elfCompileUnits; + while (unit) { + if (unit->lowPC) { + if (addr >= unit->lowPC && addr < unit->highPC) + return unit; + } else { + ARanges* r = unit->ranges; + if (r) { + int count = r->count; + for (int j = 0; j < count; j++) { + if (addr >= r->ranges[j].lowPC && addr < r->ranges[j].highPC) + return unit; + } + } + } + unit = unit->next; } - } - unit = unit->next; } - } - return NULL; + return NULL; } -const char *elfGetAddressSymbol(u32 addr) +const char* elfGetAddressSymbol(u32 addr) { - static char buffer[256]; + static char buffer[256]; - CompileUnit *unit = elfGetCompileUnit(addr); - // found unit, need to find function - if(unit) { - Function *func = unit->functions; - while(func) { - if(addr >= func->lowPC && addr < func->highPC) { - int offset = addr - func->lowPC; - const char *name = func->name; - if(!name) - name = ""; - if(offset) - sprintf(buffer, "%s+%d", name, offset); - else - strcpy(buffer, name); - return buffer; - } - func = func->next; - } - } - - if(elfSymbolsCount) { - for(int i = 0; i < elfSymbolsCount; i++) { - Symbol *s = &elfSymbols[i]; - if((addr >= s->value) && addr < (s->value+s->size)) { - int offset = addr-s->value; - const char *name = s->name; - if(name == NULL) - name = ""; - if(offset) - sprintf(buffer, "%s+%d", name, addr-s->value); - else - strcpy(buffer, name); - return buffer; - } else if(addr == s->value) { - if(s->name) - strcpy(buffer, s->name); - else - strcpy(buffer, ""); - return buffer; - } - } - } - - return ""; -} - -bool elfFindLineInModule(u32 *addr, const char *name, int line) -{ - CompileUnit *unit = elfCompileUnits; - - while(unit) { - if(unit->lineInfoTable) { - int i; - int count = unit->lineInfoTable->fileCount; - char *found = NULL; - for(i = 0; i < count; i++) { - if(strcmp(name, unit->lineInfoTable->files[i]) == 0) { - found = unit->lineInfoTable->files[i]; - break; + CompileUnit* unit = elfGetCompileUnit(addr); + // found unit, need to find function + if (unit) { + Function* func = unit->functions; + while (func) { + if (addr >= func->lowPC && addr < func->highPC) { + int offset = addr - func->lowPC; + const char* name = func->name; + if (!name) + name = ""; + if (offset) + sprintf(buffer, "%s+%d", name, offset); + else + strcpy(buffer, name); + return buffer; + } + func = func->next; } - } - // found a matching filename... try to find line now - if(found) { - LineInfoItem *table = unit->lineInfoTable->lines; - count = unit->lineInfoTable->number; - for(i = 0; i < count; i++) { - if(table[i].file == found && table[i].line == line) { - *addr = table[i].address; - return true; - } + } + + if (elfSymbolsCount) { + for (int i = 0; i < elfSymbolsCount; i++) { + Symbol* s = &elfSymbols[i]; + if ((addr >= s->value) && addr < (s->value + s->size)) { + int offset = addr - s->value; + const char* name = s->name; + if (name == NULL) + name = ""; + if (offset) + sprintf(buffer, "%s+%d", name, addr - s->value); + else + strcpy(buffer, name); + return buffer; + } else if (addr == s->value) { + if (s->name) + strcpy(buffer, s->name); + else + strcpy(buffer, ""); + return buffer; + } } - // we can only find a single match - return false; - } } - unit = unit->next; - } - return false; + + return ""; } -int elfFindLine(CompileUnit *unit, Function * /* func */, u32 addr, const char **f) +bool elfFindLineInModule(u32* addr, const char* name, int line) { - int currentLine = -1; - if(unit->hasLineInfo) { - int count = unit->lineInfoTable->number; - LineInfoItem *table = unit->lineInfoTable->lines; - int i; - for(i = 0; i < count; i++) { - if(addr <= table[i].address) - break; - } - if(i == count) - i--; - *f = table[i].file; - currentLine = table[i].line; - } - return currentLine; -} + CompileUnit* unit = elfCompileUnits; -bool elfFindLineInUnit(u32 *addr, CompileUnit *unit, int line) -{ - if(unit->hasLineInfo) { - int count = unit->lineInfoTable->number; - LineInfoItem *table = unit->lineInfoTable->lines; - int i; - for(i = 0; i < count; i++) { - if(line == table[i].line) { - *addr = table[i].address; - return true; - } - } - } - return false; -} - -bool elfGetCurrentFunction(u32 addr, Function **f, CompileUnit **u) -{ - CompileUnit *unit = elfGetCompileUnit(addr); - // found unit, need to find function - if(unit) { - Function *func = unit->functions; - while(func) { - if(addr >= func->lowPC && addr < func->highPC) { - *f = func; - *u = unit; - return true; - } - func = func->next; - } - } - return false; -} - -bool elfGetObject(const char *name, Function *f, CompileUnit *u, Object **o) -{ - if(f && u) { - Object *v = f->variables; - - while(v) { - if(strcmp(name, v->name) == 0) { - *o = v; - return true; - } - v = v->next; - } - v = f->parameters; - while(v) { - if(strcmp(name, v->name) == 0) { - *o = v; - return true; - } - v = v->next; - } - v = u->variables; - while(v) { - if(strcmp(name, v->name) == 0) { - *o = v; - return true; - } - v = v->next; - } - } - - CompileUnit *c = elfCompileUnits; - - while(c) { - if(c != u) { - Object *v = c->variables; - while(v) { - if(strcmp(name, v->name) == 0) { - *o = v; - return true; + while (unit) { + if (unit->lineInfoTable) { + int i; + int count = unit->lineInfoTable->fileCount; + char* found = NULL; + for (i = 0; i < count; i++) { + if (strcmp(name, unit->lineInfoTable->files[i]) == 0) { + found = unit->lineInfoTable->files[i]; + break; + } + } + // found a matching filename... try to find line now + if (found) { + LineInfoItem* table = unit->lineInfoTable->lines; + count = unit->lineInfoTable->number; + for (i = 0; i < count; i++) { + if (table[i].file == found && table[i].line == line) { + *addr = table[i].address; + return true; + } + } + // we can only find a single match + return false; + } } - v = v->next; - } + unit = unit->next; } - c = c->next; - } - - return false; + return false; } -const char *elfGetSymbol(int i, u32 *value, u32 *size, int *type) +int elfFindLine(CompileUnit* unit, Function* /* func */, u32 addr, const char** f) { - if(i < elfSymbolsCount) { - Symbol *s = &elfSymbols[i]; - *value = s->value; - *size = s->size; - *type = s->type; - return s->name; - } - return NULL; + int currentLine = -1; + if (unit->hasLineInfo) { + int count = unit->lineInfoTable->number; + LineInfoItem* table = unit->lineInfoTable->lines; + int i; + for (i = 0; i < count; i++) { + if (addr <= table[i].address) + break; + } + if (i == count) + i--; + *f = table[i].file; + currentLine = table[i].line; + } + return currentLine; } -bool elfGetSymbolAddress(const char *sym, u32 *addr, u32 *size, int *type) +bool elfFindLineInUnit(u32* addr, CompileUnit* unit, int line) { - if(elfSymbolsCount) { - for(int i = 0; i < elfSymbolsCount; i++) { - Symbol *s = &elfSymbols[i]; - if(strcmp(sym, s->name) == 0) { - *addr = s->value; + if (unit->hasLineInfo) { + int count = unit->lineInfoTable->number; + LineInfoItem* table = unit->lineInfoTable->lines; + int i; + for (i = 0; i < count; i++) { + if (line == table[i].line) { + *addr = table[i].address; + return true; + } + } + } + return false; +} + +bool elfGetCurrentFunction(u32 addr, Function** f, CompileUnit** u) +{ + CompileUnit* unit = elfGetCompileUnit(addr); + // found unit, need to find function + if (unit) { + Function* func = unit->functions; + while (func) { + if (addr >= func->lowPC && addr < func->highPC) { + *f = func; + *u = unit; + return true; + } + func = func->next; + } + } + return false; +} + +bool elfGetObject(const char* name, Function* f, CompileUnit* u, Object** o) +{ + if (f && u) { + Object* v = f->variables; + + while (v) { + if (strcmp(name, v->name) == 0) { + *o = v; + return true; + } + v = v->next; + } + v = f->parameters; + while (v) { + if (strcmp(name, v->name) == 0) { + *o = v; + return true; + } + v = v->next; + } + v = u->variables; + while (v) { + if (strcmp(name, v->name) == 0) { + *o = v; + return true; + } + v = v->next; + } + } + + CompileUnit* c = elfCompileUnits; + + while (c) { + if (c != u) { + Object* v = c->variables; + while (v) { + if (strcmp(name, v->name) == 0) { + *o = v; + return true; + } + v = v->next; + } + } + c = c->next; + } + + return false; +} + +const char* elfGetSymbol(int i, u32* value, u32* size, int* type) +{ + if (i < elfSymbolsCount) { + Symbol* s = &elfSymbols[i]; + *value = s->value; *size = s->size; *type = s->type; - return true; - } + return s->name; } - } - return false; + return NULL; } -ELFfde *elfGetFde(u32 address) +bool elfGetSymbolAddress(const char* sym, u32* addr, u32* size, int* type) { - if(elfFdes) { - int i; - for(i = 0; i < elfFdeCount; i++) { - if(address >= elfFdes[i]->address && - address < elfFdes[i]->end) { - return elfFdes[i]; - } - } - } - - return NULL; -} - -void elfExecuteCFAInstructions(ELFFrameState *state, u8 *data, u32 len, - u32 pc) -{ - u8 *end = data + len; - int bytes; - int reg; - ELFFrameStateRegisters *fs; - - while(data < end && state->pc < pc) { - u8 op = *data++; - - switch(op >> 6) { - case DW_CFA_advance_loc: - state->pc += (op & 0x3f) * state->codeAlign; - break; - case DW_CFA_offset: - reg = op & 0x3f; - state->registers.regs[reg].mode = REG_OFFSET; - state->registers.regs[reg].offset = state->dataAlign * - (s32)elfReadLEB128(data, &bytes); - data += bytes; - break; - case DW_CFA_restore: - // we don't care much about the other possible settings, - // so just setting to unset is enough for now - state->registers.regs[op & 0x3f].mode = REG_NOT_SET; - break; - case 0: - switch(op & 0x3f) { - case DW_CFA_nop: - break; - case DW_CFA_advance_loc1: - state->pc += state->codeAlign * (*data++); - break; - case DW_CFA_advance_loc2: - state->pc += state->codeAlign * elfRead2Bytes(data); - data += 2; - break; - case DW_CFA_advance_loc4: - state->pc += state->codeAlign * elfRead4Bytes(data); - data += 4; - break; - case DW_CFA_offset_extended: - reg = elfReadLEB128(data, &bytes); - data += bytes; - state->registers.regs[reg].mode = REG_OFFSET; - state->registers.regs[reg].offset = state->dataAlign * - (s32)elfReadLEB128(data, &bytes); - data += bytes; - break; - case DW_CFA_restore_extended: - case DW_CFA_undefined: - case DW_CFA_same_value: - reg = elfReadLEB128(data, &bytes); - data += bytes; - state->registers.regs[reg].mode = REG_NOT_SET; - break; - case DW_CFA_register: - reg = elfReadLEB128(data, &bytes); - data += bytes; - state->registers.regs[reg].mode = REG_REGISTER; - state->registers.regs[reg].reg = elfReadLEB128(data, &bytes); - data += bytes; - break; - case DW_CFA_remember_state: - fs = (ELFFrameStateRegisters *)calloc(1, - sizeof(ELFFrameStateRegisters)); - memcpy(fs, &state->registers, sizeof(ELFFrameStateRegisters)); - state->registers.previous = fs; - break; - case DW_CFA_restore_state: - if(state->registers.previous == NULL) { - printf("Error: previous frame state is NULL.\n"); - return; + if (elfSymbolsCount) { + for (int i = 0; i < elfSymbolsCount; i++) { + Symbol* s = &elfSymbols[i]; + if (strcmp(sym, s->name) == 0) { + *addr = s->value; + *size = s->size; + *type = s->type; + return true; + } } - fs = state->registers.previous; - memcpy(&state->registers, fs, sizeof(ELFFrameStateRegisters)); - free(fs); - break; - case DW_CFA_def_cfa: - state->cfaRegister = elfReadLEB128(data, &bytes); - data += bytes; - state->cfaOffset = (s32)elfReadLEB128(data, &bytes); - data += bytes; - state->cfaMode = CFA_REG_OFFSET; - break; - case DW_CFA_def_cfa_register: - state->cfaRegister = elfReadLEB128(data, &bytes); - data += bytes; - state->cfaMode = CFA_REG_OFFSET; - break; - case DW_CFA_def_cfa_offset: - state->cfaOffset = (s32)elfReadLEB128(data, &bytes); - data += bytes; - state->cfaMode = CFA_REG_OFFSET; - break; - default: - printf("Unknown CFA opcode %08x\n", op); - return; - } - break; - default: - printf("Unknown CFA opcode %08x\n", op); - return; } - } + return false; } -ELFFrameState *elfGetFrameState(ELFfde *fde, u32 address) +ELFfde* elfGetFde(u32 address) { - ELFFrameState *state = (ELFFrameState *)calloc(1, sizeof(ELFFrameState)); - state->pc = fde->address; - state->dataAlign = fde->cie->dataAlign; - state->codeAlign = fde->cie->codeAlign; - state->returnAddress = fde->cie->returnAddress; + if (elfFdes) { + int i; + for (i = 0; i < elfFdeCount; i++) { + if (address >= elfFdes[i]->address && address < elfFdes[i]->end) { + return elfFdes[i]; + } + } + } - elfExecuteCFAInstructions(state, - fde->cie->data, - fde->cie->dataLen, - 0xffffffff); - elfExecuteCFAInstructions(state, - fde->data, - fde->dataLen, - address); + return NULL; +} - return state; +void elfExecuteCFAInstructions(ELFFrameState* state, u8* data, u32 len, + u32 pc) +{ + u8* end = data + len; + int bytes; + int reg; + ELFFrameStateRegisters* fs; + + while (data < end && state->pc < pc) { + u8 op = *data++; + + switch (op >> 6) { + case DW_CFA_advance_loc: + state->pc += (op & 0x3f) * state->codeAlign; + break; + case DW_CFA_offset: + reg = op & 0x3f; + state->registers.regs[reg].mode = REG_OFFSET; + state->registers.regs[reg].offset = state->dataAlign * (s32)elfReadLEB128(data, &bytes); + data += bytes; + break; + case DW_CFA_restore: + // we don't care much about the other possible settings, + // so just setting to unset is enough for now + state->registers.regs[op & 0x3f].mode = REG_NOT_SET; + break; + case 0: + switch (op & 0x3f) { + case DW_CFA_nop: + break; + case DW_CFA_advance_loc1: + state->pc += state->codeAlign * (*data++); + break; + case DW_CFA_advance_loc2: + state->pc += state->codeAlign * elfRead2Bytes(data); + data += 2; + break; + case DW_CFA_advance_loc4: + state->pc += state->codeAlign * elfRead4Bytes(data); + data += 4; + break; + case DW_CFA_offset_extended: + reg = elfReadLEB128(data, &bytes); + data += bytes; + state->registers.regs[reg].mode = REG_OFFSET; + state->registers.regs[reg].offset = state->dataAlign * (s32)elfReadLEB128(data, &bytes); + data += bytes; + break; + case DW_CFA_restore_extended: + case DW_CFA_undefined: + case DW_CFA_same_value: + reg = elfReadLEB128(data, &bytes); + data += bytes; + state->registers.regs[reg].mode = REG_NOT_SET; + break; + case DW_CFA_register: + reg = elfReadLEB128(data, &bytes); + data += bytes; + state->registers.regs[reg].mode = REG_REGISTER; + state->registers.regs[reg].reg = elfReadLEB128(data, &bytes); + data += bytes; + break; + case DW_CFA_remember_state: + fs = (ELFFrameStateRegisters*)calloc(1, + sizeof(ELFFrameStateRegisters)); + memcpy(fs, &state->registers, sizeof(ELFFrameStateRegisters)); + state->registers.previous = fs; + break; + case DW_CFA_restore_state: + if (state->registers.previous == NULL) { + printf("Error: previous frame state is NULL.\n"); + return; + } + fs = state->registers.previous; + memcpy(&state->registers, fs, sizeof(ELFFrameStateRegisters)); + free(fs); + break; + case DW_CFA_def_cfa: + state->cfaRegister = elfReadLEB128(data, &bytes); + data += bytes; + state->cfaOffset = (s32)elfReadLEB128(data, &bytes); + data += bytes; + state->cfaMode = CFA_REG_OFFSET; + break; + case DW_CFA_def_cfa_register: + state->cfaRegister = elfReadLEB128(data, &bytes); + data += bytes; + state->cfaMode = CFA_REG_OFFSET; + break; + case DW_CFA_def_cfa_offset: + state->cfaOffset = (s32)elfReadLEB128(data, &bytes); + data += bytes; + state->cfaMode = CFA_REG_OFFSET; + break; + default: + printf("Unknown CFA opcode %08x\n", op); + return; + } + break; + default: + printf("Unknown CFA opcode %08x\n", op); + return; + } + } +} + +ELFFrameState* elfGetFrameState(ELFfde* fde, u32 address) +{ + ELFFrameState* state = (ELFFrameState*)calloc(1, sizeof(ELFFrameState)); + state->pc = fde->address; + state->dataAlign = fde->cie->dataAlign; + state->codeAlign = fde->cie->codeAlign; + state->returnAddress = fde->cie->returnAddress; + + elfExecuteCFAInstructions(state, + fde->cie->data, + fde->cie->dataLen, + 0xffffffff); + elfExecuteCFAInstructions(state, + fde->data, + fde->dataLen, + address); + + return state; } void elfPrintCallChain(u32 address) { - int count = 1; + int count = 1; - reg_pair regs[15]; - reg_pair newRegs[15]; + reg_pair regs[15]; + reg_pair newRegs[15]; - memcpy(®s[0], ®[0], sizeof(reg_pair) * 15); + memcpy(®s[0], ®[0], sizeof(reg_pair) * 15); - while(count < 20) { - const char *addr = elfGetAddressSymbol(address); - if(*addr == 0) - addr = "???"; + while (count < 20) { + const char* addr = elfGetAddressSymbol(address); + if (*addr == 0) + addr = "???"; - printf("%08x %s\n", address, addr); + printf("%08x %s\n", address, addr); - ELFfde *fde = elfGetFde(address); + ELFfde* fde = elfGetFde(address); - if(fde == NULL) { - break; - } - - ELFFrameState *state = elfGetFrameState(fde, address); - - if(!state) { - break; - } - - if(state->cfaMode == CFA_REG_OFFSET) { - memcpy(&newRegs[0], ®s[0], sizeof(reg_pair) * 15); - u32 addr = 0; - for(int i = 0; i < 15; i++) { - ELFFrameStateRegister *r = &state->registers. - regs[i]; - - switch(r->mode) { - case REG_NOT_SET: - newRegs[i].I = regs[i].I; - break; - case REG_OFFSET: - newRegs[i].I = elfReadMemory(regs[state->cfaRegister].I + - state->cfaOffset + - r->offset); - break; - case REG_REGISTER: - newRegs[i].I = regs[r->reg].I; - break; - default: - printf("Unknown register mode: %d\n", r->mode); - break; + if (fde == NULL) { + break; } - } - memcpy(regs, newRegs, sizeof(reg_pair)*15); - addr = newRegs[14].I; - addr &= 0xfffffffe; - address = addr; - count++; - } else { - printf("CFA not set\n"); - break; - } - if(state->registers.previous) { - ELFFrameStateRegisters *prev = state->registers.previous; - while(prev) { - ELFFrameStateRegisters *p = prev->previous; - free(prev); - prev = p; - } + ELFFrameState* state = elfGetFrameState(fde, address); + + if (!state) { + break; + } + + if (state->cfaMode == CFA_REG_OFFSET) { + memcpy(&newRegs[0], ®s[0], sizeof(reg_pair) * 15); + u32 addr = 0; + for (int i = 0; i < 15; i++) { + ELFFrameStateRegister* r = &state->registers.regs[i]; + + switch (r->mode) { + case REG_NOT_SET: + newRegs[i].I = regs[i].I; + break; + case REG_OFFSET: + newRegs[i].I = elfReadMemory(regs[state->cfaRegister].I + state->cfaOffset + r->offset); + break; + case REG_REGISTER: + newRegs[i].I = regs[r->reg].I; + break; + default: + printf("Unknown register mode: %d\n", r->mode); + break; + } + } + memcpy(regs, newRegs, sizeof(reg_pair) * 15); + addr = newRegs[14].I; + addr &= 0xfffffffe; + address = addr; + count++; + } else { + printf("CFA not set\n"); + break; + } + if (state->registers.previous) { + ELFFrameStateRegisters* prev = state->registers.previous; + + while (prev) { + ELFFrameStateRegisters* p = prev->previous; + free(prev); + prev = p; + } + } + free(state); } - free(state); - } } -u32 elfDecodeLocation(Function *f, ELFBlock *o, LocationType *type, u32 base) +u32 elfDecodeLocation(Function* f, ELFBlock* o, LocationType* type, u32 base) { - u32 framebase = 0; - if(f && f->frameBase) { - ELFBlock *b = f->frameBase; - switch(*b->data) { - case DW_OP_reg0: - case DW_OP_reg1: - case DW_OP_reg2: - case DW_OP_reg3: - case DW_OP_reg4: - case DW_OP_reg5: - case DW_OP_reg6: - case DW_OP_reg7: - case DW_OP_reg8: - case DW_OP_reg9: - case DW_OP_reg10: - case DW_OP_reg11: - case DW_OP_reg12: - case DW_OP_reg13: - case DW_OP_reg14: - case DW_OP_reg15: - framebase = reg[*b->data-0x50].I; - break; - default: - fprintf(stderr, "Unknown frameBase %02x\n", *b->data); - break; + u32 framebase = 0; + if (f && f->frameBase) { + ELFBlock* b = f->frameBase; + switch (*b->data) { + case DW_OP_reg0: + case DW_OP_reg1: + case DW_OP_reg2: + case DW_OP_reg3: + case DW_OP_reg4: + case DW_OP_reg5: + case DW_OP_reg6: + case DW_OP_reg7: + case DW_OP_reg8: + case DW_OP_reg9: + case DW_OP_reg10: + case DW_OP_reg11: + case DW_OP_reg12: + case DW_OP_reg13: + case DW_OP_reg14: + case DW_OP_reg15: + framebase = reg[*b->data - 0x50].I; + break; + default: + fprintf(stderr, "Unknown frameBase %02x\n", *b->data); + break; + } } - } - ELFBlock *loc = o; - u32 location = 0; - int bytes = 0; - if(loc) { - switch(*loc->data) { - case DW_OP_addr: - location = elfRead4Bytes(loc->data+1); - *type = LOCATION_memory; - break; - case DW_OP_plus_uconst: - location = base + elfReadLEB128(loc->data+1, &bytes); - *type = LOCATION_memory; - break; - case DW_OP_reg0: - case DW_OP_reg1: - case DW_OP_reg2: - case DW_OP_reg3: - case DW_OP_reg4: - case DW_OP_reg5: - case DW_OP_reg6: - case DW_OP_reg7: - case DW_OP_reg8: - case DW_OP_reg9: - case DW_OP_reg10: - case DW_OP_reg11: - case DW_OP_reg12: - case DW_OP_reg13: - case DW_OP_reg14: - case DW_OP_reg15: - location = *loc->data - 0x50; - *type = LOCATION_register; - break; - case DW_OP_fbreg: - { - int bytes; - s32 off = elfReadSignedLEB128(loc->data+1, &bytes); - location = framebase + off; - *type = LOCATION_memory; - } - break; - default: - fprintf(stderr, "Unknown location %02x\n", *loc->data); - break; + ELFBlock* loc = o; + u32 location = 0; + int bytes = 0; + if (loc) { + switch (*loc->data) { + case DW_OP_addr: + location = elfRead4Bytes(loc->data + 1); + *type = LOCATION_memory; + break; + case DW_OP_plus_uconst: + location = base + elfReadLEB128(loc->data + 1, &bytes); + *type = LOCATION_memory; + break; + case DW_OP_reg0: + case DW_OP_reg1: + case DW_OP_reg2: + case DW_OP_reg3: + case DW_OP_reg4: + case DW_OP_reg5: + case DW_OP_reg6: + case DW_OP_reg7: + case DW_OP_reg8: + case DW_OP_reg9: + case DW_OP_reg10: + case DW_OP_reg11: + case DW_OP_reg12: + case DW_OP_reg13: + case DW_OP_reg14: + case DW_OP_reg15: + location = *loc->data - 0x50; + *type = LOCATION_register; + break; + case DW_OP_fbreg: { + int bytes; + s32 off = elfReadSignedLEB128(loc->data + 1, &bytes); + location = framebase + off; + *type = LOCATION_memory; + } break; + default: + fprintf(stderr, "Unknown location %02x\n", *loc->data); + break; + } } - } - return location; + return location; } -u32 elfDecodeLocation(Function *f, ELFBlock *o, LocationType *type) +u32 elfDecodeLocation(Function* f, ELFBlock* o, LocationType* type) { - return elfDecodeLocation(f, o, type, 0); + return elfDecodeLocation(f, o, type, 0); } // reading function -u32 elfRead4Bytes(u8 *data) +u32 elfRead4Bytes(u8* data) { - u32 value = *data++; - value |= (*data++ << 8); - value |= (*data++ << 16); - value |= (*data << 24); - return value; + u32 value = *data++; + value |= (*data++ << 8); + value |= (*data++ << 16); + value |= (*data << 24); + return value; } -u16 elfRead2Bytes(u8 *data) +u16 elfRead2Bytes(u8* data) { - u16 value = *data++; - value |= (*data << 8); - return value; + u16 value = *data++; + value |= (*data << 8); + return value; } -char *elfReadString(u8 *data, int *bytesRead) +char* elfReadString(u8* data, int* bytesRead) { - if(*data == 0) { - *bytesRead = 1; - return NULL; - } - *bytesRead = (int)strlen((char *)data) + 1; - return (char *)data; -} - -s32 elfReadSignedLEB128(u8 *data, int *bytesRead) -{ - s32 result = 0; - int shift = 0; - int count = 0; - - u8 byte; - do { - byte = *data++; - count++; - result |= (byte & 0x7f) << shift; - shift += 7; - } while(byte & 0x80); - if((shift < 32) && (byte & 0x40)) - result |= -(1 << shift); - *bytesRead = count; - return result; -} - -u32 elfReadLEB128(u8 *data, int *bytesRead) -{ - u32 result = 0; - int shift = 0; - int count = 0; - u8 byte; - do { - byte = *data++; - count++; - result |= (byte & 0x7f) << shift; - shift += 7; - } while(byte & 0x80); - *bytesRead = count; - return result; -} - -u8 *elfReadSection(u8 *data, ELFSectionHeader *sh) -{ - return data + READ32LE(&sh->offset); -} - -ELFSectionHeader *elfGetSectionByName(const char *name) -{ - for(int i = 0; i < elfSectionHeadersCount; i++) { - if(strcmp(name, - &elfSectionHeadersStringTable[READ32LE(&elfSectionHeaders[i]-> - name)]) == 0) { - return elfSectionHeaders[i]; + if (*data == 0) { + *bytesRead = 1; + return NULL; } - } - return NULL; + *bytesRead = (int)strlen((char*)data) + 1; + return (char*)data; } -ELFSectionHeader *elfGetSectionByNumber(int number) +s32 elfReadSignedLEB128(u8* data, int* bytesRead) { - if(number < elfSectionHeadersCount) { - return elfSectionHeaders[number]; - } - return NULL; + s32 result = 0; + int shift = 0; + int count = 0; + + u8 byte; + do { + byte = *data++; + count++; + result |= (byte & 0x7f) << shift; + shift += 7; + } while (byte & 0x80); + if ((shift < 32) && (byte & 0x40)) + result |= -(1 << shift); + *bytesRead = count; + return result; } -CompileUnit *elfGetCompileUnitForData(u8 *data) +u32 elfReadLEB128(u8* data, int* bytesRead) { - u8 *end = elfCurrentUnit->top + 4 + elfCurrentUnit->length; - - if(data >= elfCurrentUnit->top && data < end) - return elfCurrentUnit; - - CompileUnit *unit = elfCompileUnits; - - while(unit) { - end = unit->top + 4 + unit->length; - - if(data >= unit->top && data < end) - return unit; - - unit = unit->next; - } - - printf("Error: cannot find reference to compile unit at offset %08x\n", - (int)(data - elfDebugInfo->infodata)); - exit(-1); + u32 result = 0; + int shift = 0; + int count = 0; + u8 byte; + do { + byte = *data++; + count++; + result |= (byte & 0x7f) << shift; + shift += 7; + } while (byte & 0x80); + *bytesRead = count; + return result; } -u8 *elfReadAttribute(u8 *data, ELFAttr *attr) +u8* elfReadSection(u8* data, ELFSectionHeader* sh) { - int bytes; - int form = attr->form; - start: - switch(form) { - case DW_FORM_addr: - attr->value = elfRead4Bytes(data); - data += 4; - break; - case DW_FORM_data2: - attr->value = elfRead2Bytes(data); - data += 2; - break; - case DW_FORM_data4: - attr->value = elfRead4Bytes(data); - data += 4; - break; - case DW_FORM_string: - attr->string = (char *)data; - data += strlen(attr->string)+1; - break; - case DW_FORM_strp: - attr->string = elfDebugStrings + elfRead4Bytes(data); - data += 4; - break; - case DW_FORM_block: - attr->block = (ELFBlock *)malloc(sizeof(ELFBlock)); - attr->block->length = elfReadLEB128(data, &bytes); - data += bytes; - attr->block->data = data; - data += attr->block->length; - break; - case DW_FORM_block1: - attr->block = (ELFBlock *)malloc(sizeof(ELFBlock)); - attr->block->length = *data++; - attr->block->data = data; - data += attr->block->length; - break; - case DW_FORM_data1: - attr->value = *data++; - break; - case DW_FORM_flag: - attr->flag = (*data++) ? true : false; - break; - case DW_FORM_sdata: - attr->value = elfReadSignedLEB128(data, &bytes); - data += bytes; - break; - case DW_FORM_udata: - attr->value = elfReadLEB128(data, &bytes); - data += bytes; - break; - case DW_FORM_ref_addr: - attr->value = (u32)((elfDebugInfo->infodata + elfRead4Bytes(data)) - elfGetCompileUnitForData(data)->top); - data += 4; - break; - case DW_FORM_ref4: - attr->value = elfRead4Bytes(data); - data += 4; - break; - case DW_FORM_ref_udata: - attr->value = (u32)((elfDebugInfo->infodata + (elfGetCompileUnitForData(data)->top - elfDebugInfo->infodata) + elfReadLEB128(data, &bytes)) - elfCurrentUnit->top); - data += bytes; - break; - case DW_FORM_indirect: - form = elfReadLEB128(data, &bytes); - data += bytes; - goto start; - default: - fprintf(stderr, "Unsupported FORM %02x\n", form); - exit(-1); - } - return data; + return data + READ32LE(&sh->offset); } -ELFAbbrev *elfGetAbbrev(ELFAbbrev **table, u32 number) +ELFSectionHeader* elfGetSectionByName(const char* name) { - int hash = number % 121; - - ELFAbbrev *abbrev = table[hash]; - - while(abbrev) { - if(abbrev->number == number) - return abbrev; - abbrev = abbrev->next; - } - return NULL; -} - -ELFAbbrev **elfReadAbbrevs(u8 *data, u32 offset) -{ - data += offset; - ELFAbbrev **abbrevs = (ELFAbbrev **)calloc(sizeof(ELFAbbrev *)*121,1); - int bytes = 0; - u32 number = elfReadLEB128(data, &bytes); - data += bytes; - while(number) { - ELFAbbrev *abbrev = (ELFAbbrev *)calloc(sizeof(ELFAbbrev),1); - - // read tag information - abbrev->number = number; - abbrev->tag = elfReadLEB128(data, &bytes); - data += bytes; - abbrev->hasChildren = *data++ ? true: false; - - // read attributes - int name = elfReadLEB128(data, &bytes); - data += bytes; - int form = elfReadLEB128(data, &bytes); - data += bytes; - - while(name) { - if((abbrev->numAttrs % 4) == 0) { - abbrev->attrs = (ELFAttr *)realloc(abbrev->attrs, - (abbrev->numAttrs + 4) * - sizeof(ELFAttr)); - } - abbrev->attrs[abbrev->numAttrs].name = name; - abbrev->attrs[abbrev->numAttrs++].form = form; - - name = elfReadLEB128(data, &bytes); - data += bytes; - form = elfReadLEB128(data, &bytes); - data += bytes; - } - - int hash = number % 121; - abbrev->next = abbrevs[hash]; - abbrevs[hash] = abbrev; - - number = elfReadLEB128(data, &bytes); - data += bytes; - - if(elfGetAbbrev(abbrevs, number) != NULL) - break; - } - - return abbrevs; -} - -void elfParseCFA(u8 *top) -{ - ELFSectionHeader *h = elfGetSectionByName(".debug_frame"); - - if(h == NULL) { - return; - } - - u8 *data = elfReadSection(top, h); - - u8 *topOffset = data; - - u8 *end = data + READ32LE(&h->size); - - ELFcie *cies = NULL; - - while(data < end) { - u32 offset = (u32)(data - topOffset); - u32 len = elfRead4Bytes(data); - data += 4; - - u8 *dataEnd = data + len; - - u32 id = elfRead4Bytes(data); - data += 4; - - if(id == 0xffffffff) { - // skip version - (*data)++; - - ELFcie *cie = (ELFcie *)calloc(1, sizeof(ELFcie)); - - cie->next = cies; - cies = cie; - - cie->offset = offset; - - cie->augmentation = data; - while(*data) - data++; - data++; - - if(*cie->augmentation) { - fprintf(stderr, "Error: augmentation not supported\n"); - exit(-1); - } - - int bytes; - cie->codeAlign = elfReadLEB128(data, &bytes); - data += bytes; - - cie->dataAlign = elfReadSignedLEB128(data, &bytes); - data += bytes; - - cie->returnAddress = *data++; - - cie->data = data; - cie->dataLen = (u32)(dataEnd - data); - } else { - ELFfde *fde = (ELFfde *)calloc(1, sizeof(ELFfde)); - - ELFcie *cie = cies; - - while(cie != NULL) { - if(cie->offset == id) - break; - cie = cie->next; - } - - if(!cie) { - fprintf(stderr, "Cannot find CIE %08x\n", id); - exit(-1); - } - - fde->cie = cie; - - fde->address = elfRead4Bytes(data); - data += 4; - - fde->end = fde->address + elfRead4Bytes(data); - data += 4; - - fde->data = data; - fde->dataLen = (u32)(dataEnd - data); - - if((elfFdeCount %10) == 0) { - elfFdes = (ELFfde **)realloc(elfFdes, (elfFdeCount+10) * - sizeof(ELFfde *)); - } - elfFdes[elfFdeCount++] = fde; - } - data = dataEnd; - } - - elfCies = cies; -} - -void elfAddLine(LineInfo *l, u32 a, int file, int line, int *max) -{ - if(l->number == *max) { - *max += 1000; - l->lines = (LineInfoItem *)realloc(l->lines, *max*sizeof(LineInfoItem)); - } - LineInfoItem *li = &l->lines[l->number]; - li->file = l->files[file-1]; - li->address = a; - li->line = line; - l->number++; -} - -void elfParseLineInfo(CompileUnit *unit, u8 *top) -{ - ELFSectionHeader *h = elfGetSectionByName(".debug_line"); - if(h == NULL) { - fprintf(stderr, "No line information found\n"); - return; - } - LineInfo *l = unit->lineInfoTable = (LineInfo *)calloc(1, sizeof(LineInfo)); - l->number = 0; - int max = 1000; - l->lines = (LineInfoItem *)malloc(1000*sizeof(LineInfoItem)); - - u8 *data = elfReadSection(top, h); - data += unit->lineInfo; - u32 totalLen = elfRead4Bytes(data); - data += 4; - u8 *end = data + totalLen; - // u16 version = elfRead2Bytes(data); - data += 2; - // u32 offset = elfRead4Bytes(data); - data += 4; - int minInstrSize = *data++; - int defaultIsStmt = *data++; - int lineBase = (s8)*data++; - int lineRange = *data++; - int opcodeBase = *data++; - u8 *stdOpLen = (u8 *)malloc(opcodeBase * sizeof(u8)); - stdOpLen[0] = 1; - int i; - for(i = 1; i < opcodeBase; i++) - stdOpLen[i] = *data++; - - free(stdOpLen);// todo - int bytes = 0; - - char *s; - while((s = elfReadString(data, &bytes)) != NULL) { - data += bytes; - // fprintf(stderr, "Directory is %s\n", s); - } - data += bytes; - int count = 4; - int index = 0; - l->files = (char **)malloc(sizeof(char *)*count); - - while((s = elfReadString(data, &bytes)) != NULL) { - l->files[index++] = s; - - data += bytes; - // directory - elfReadLEB128(data, &bytes); - data += bytes; - // time - elfReadLEB128(data, &bytes); - data += bytes; - // size - elfReadLEB128(data, &bytes); - data += bytes; - // fprintf(stderr, "File is %s\n", s); - if(index == count) { - count += 4; - l->files = (char **)realloc(l->files, sizeof(char *)*count); - } - } - l->fileCount = index; - data += bytes; - - while(data < end) { - u32 address = 0; - int file = 1; - int line = 1; - int col = 0; - int isStmt = defaultIsStmt; - int basicBlock = 0; - int endSeq = 0; - - while(!endSeq) { - int op = *data++; - switch(op) { - case DW_LNS_extended_op: - { - data++; - op = *data++; - switch(op) { - case DW_LNE_end_sequence: - endSeq = 1; - break; - case DW_LNE_set_address: - address = elfRead4Bytes(data); - data += 4; - break; - default: - fprintf(stderr, "Unknown extended LINE opcode %02x\n", op); - exit(-1); - } + for (int i = 0; i < elfSectionHeadersCount; i++) { + if (strcmp(name, + &elfSectionHeadersStringTable[READ32LE(&elfSectionHeaders[i]->name)]) + == 0) { + return elfSectionHeaders[i]; } + } + return NULL; +} + +ELFSectionHeader* elfGetSectionByNumber(int number) +{ + if (number < elfSectionHeadersCount) { + return elfSectionHeaders[number]; + } + return NULL; +} + +CompileUnit* elfGetCompileUnitForData(u8* data) +{ + u8* end = elfCurrentUnit->top + 4 + elfCurrentUnit->length; + + if (data >= elfCurrentUnit->top && data < end) + return elfCurrentUnit; + + CompileUnit* unit = elfCompileUnits; + + while (unit) { + end = unit->top + 4 + unit->length; + + if (data >= unit->top && data < end) + return unit; + + unit = unit->next; + } + + printf("Error: cannot find reference to compile unit at offset %08x\n", + (int)(data - elfDebugInfo->infodata)); + exit(-1); +} + +u8* elfReadAttribute(u8* data, ELFAttr* attr) +{ + int bytes; + int form = attr->form; +start: + switch (form) { + case DW_FORM_addr: + attr->value = elfRead4Bytes(data); + data += 4; break; - case DW_LNS_copy: - // fprintf(stderr, "Address %08x line %d (%d)\n", address, line, file); - elfAddLine(l, address, file, line, &max); - basicBlock = 0; - break; - case DW_LNS_advance_pc: - address += minInstrSize * elfReadLEB128(data, &bytes); - data += bytes; - break; - case DW_LNS_advance_line: - line += elfReadSignedLEB128(data, &bytes); - data += bytes; - break; - case DW_LNS_set_file: - file = elfReadLEB128(data, &bytes); - data += bytes; - break; - case DW_LNS_set_column: - col = elfReadLEB128(data, &bytes); - data += bytes; - break; - case DW_LNS_negate_stmt: - isStmt = !isStmt; - break; - case DW_LNS_set_basic_block: - basicBlock = 1; - break; - case DW_LNS_const_add_pc: - address += (minInstrSize *((255 - opcodeBase)/lineRange)); - break; - case DW_LNS_fixed_advance_pc: - address += elfRead2Bytes(data); + case DW_FORM_data2: + attr->value = elfRead2Bytes(data); data += 2; break; - default: - op = op - opcodeBase; - address += (op / lineRange) * minInstrSize; - line += lineBase + (op % lineRange); - elfAddLine(l, address, file, line, &max); - // fprintf(stderr, "Address %08x line %d (%d)\n", address, line,file); - basicBlock = 1; + case DW_FORM_data4: + attr->value = elfRead4Bytes(data); + data += 4; break; - } + case DW_FORM_string: + attr->string = (char*)data; + data += strlen(attr->string) + 1; + break; + case DW_FORM_strp: + attr->string = elfDebugStrings + elfRead4Bytes(data); + data += 4; + break; + case DW_FORM_block: + attr->block = (ELFBlock*)malloc(sizeof(ELFBlock)); + attr->block->length = elfReadLEB128(data, &bytes); + data += bytes; + attr->block->data = data; + data += attr->block->length; + break; + case DW_FORM_block1: + attr->block = (ELFBlock*)malloc(sizeof(ELFBlock)); + attr->block->length = *data++; + attr->block->data = data; + data += attr->block->length; + break; + case DW_FORM_data1: + attr->value = *data++; + break; + case DW_FORM_flag: + attr->flag = (*data++) ? true : false; + break; + case DW_FORM_sdata: + attr->value = elfReadSignedLEB128(data, &bytes); + data += bytes; + break; + case DW_FORM_udata: + attr->value = elfReadLEB128(data, &bytes); + data += bytes; + break; + case DW_FORM_ref_addr: + attr->value = (u32)((elfDebugInfo->infodata + elfRead4Bytes(data)) - elfGetCompileUnitForData(data)->top); + data += 4; + break; + case DW_FORM_ref4: + attr->value = elfRead4Bytes(data); + data += 4; + break; + case DW_FORM_ref_udata: + attr->value = (u32)((elfDebugInfo->infodata + (elfGetCompileUnitForData(data)->top - elfDebugInfo->infodata) + elfReadLEB128(data, &bytes)) - elfCurrentUnit->top); + data += bytes; + break; + case DW_FORM_indirect: + form = elfReadLEB128(data, &bytes); + data += bytes; + goto start; + default: + fprintf(stderr, "Unsupported FORM %02x\n", form); + exit(-1); } - } - l->lines = (LineInfoItem *)realloc(l->lines, l->number*sizeof(LineInfoItem)); + return data; } -u8 *elfSkipData(u8 *data, ELFAbbrev *abbrev, ELFAbbrev **abbrevs) +ELFAbbrev* elfGetAbbrev(ELFAbbrev** table, u32 number) { - int i; - int bytes; + int hash = number % 121; - for(i = 0; i < abbrev->numAttrs; i++) { - data = elfReadAttribute(data, &abbrev->attrs[i]); - if(abbrev->attrs[i].form == DW_FORM_block1) - free(abbrev->attrs[i].block); - } + ELFAbbrev* abbrev = table[hash]; - if(abbrev->hasChildren) { - int nesting = 1; - while(nesting) { - u32 abbrevNum = elfReadLEB128(data, &bytes); - data += bytes; - - if(!abbrevNum) { - nesting--; - continue; - } - - abbrev = elfGetAbbrev(abbrevs, abbrevNum); - - for(i = 0; i < abbrev->numAttrs; i++) { - data = elfReadAttribute(data, &abbrev->attrs[i]); - if(abbrev->attrs[i].form == DW_FORM_block1) - free(abbrev->attrs[i].block); - } - - if(abbrev->hasChildren) { - nesting++; - } + while (abbrev) { + if (abbrev->number == number) + return abbrev; + abbrev = abbrev->next; } - } - return data; + return NULL; } -Type *elfParseType(CompileUnit *unit, u32); -u8 *elfParseObject(u8 *data, ELFAbbrev *abbrev, CompileUnit *unit, - Object **object); -u8 *elfParseFunction(u8 *data, ELFAbbrev *abbrev, CompileUnit *unit, - Function **function); -void elfCleanUp(Function *); - -void elfAddType(Type *type, CompileUnit *unit, u32 offset) +ELFAbbrev** elfReadAbbrevs(u8* data, u32 offset) { - if(type->next == NULL) { - if(unit->types != type && type->offset == 0) { - type->offset = offset; - type->next = unit->types; - unit->types = type; - } - } -} + data += offset; + ELFAbbrev** abbrevs = (ELFAbbrev**)calloc(sizeof(ELFAbbrev*) * 121, 1); + int bytes = 0; + u32 number = elfReadLEB128(data, &bytes); + data += bytes; + while (number) { + ELFAbbrev* abbrev = (ELFAbbrev*)calloc(sizeof(ELFAbbrev), 1); -void elfParseType(u8 *data, u32 offset, ELFAbbrev *abbrev, CompileUnit *unit, - Type **type) -{ - switch(abbrev->tag) { - case DW_TAG_typedef: - { - u32 typeref = 0; - char *name = NULL; - for(int i = 0; i < abbrev->numAttrs; i++) { - ELFAttr *attr = &abbrev->attrs[i]; - data = elfReadAttribute(data, attr); - switch(attr->name) { - case DW_AT_name: - name = attr->string; - break; - case DW_AT_type: - typeref = attr->value; - break; - case DW_AT_decl_file: - case DW_AT_decl_line: - break; - default: - fprintf(stderr, "Unknown attribute for typedef %02x\n", attr->name); - break; + // read tag information + abbrev->number = number; + abbrev->tag = elfReadLEB128(data, &bytes); + data += bytes; + abbrev->hasChildren = *data++ ? true : false; + + // read attributes + int name = elfReadLEB128(data, &bytes); + data += bytes; + int form = elfReadLEB128(data, &bytes); + data += bytes; + + while (name) { + if ((abbrev->numAttrs % 4) == 0) { + abbrev->attrs = (ELFAttr*)realloc(abbrev->attrs, + (abbrev->numAttrs + 4) * sizeof(ELFAttr)); + } + abbrev->attrs[abbrev->numAttrs].name = name; + abbrev->attrs[abbrev->numAttrs++].form = form; + + name = elfReadLEB128(data, &bytes); + data += bytes; + form = elfReadLEB128(data, &bytes); + data += bytes; } - } - if(abbrev->hasChildren) - fprintf(stderr, "Unexpected children for typedef\n"); - *type = elfParseType(unit, typeref); - if(name) - (*type)->name = name; - return; + + int hash = number % 121; + abbrev->next = abbrevs[hash]; + abbrevs[hash] = abbrev; + + number = elfReadLEB128(data, &bytes); + data += bytes; + + if (elfGetAbbrev(abbrevs, number) != NULL) + break; } - break; - case DW_TAG_union_type: - case DW_TAG_structure_type: - { - Type *t = (Type *)calloc(sizeof(Type), 1); - if(abbrev->tag == DW_TAG_structure_type) - t->type = TYPE_struct; - else - t->type = TYPE_union; - Struct *s = (Struct *)calloc(sizeof(Struct), 1); - t->structure = s; - elfAddType(t, unit, offset); + return abbrevs; +} - for(int i = 0; i < abbrev->numAttrs; i++) { - ELFAttr *attr = &abbrev->attrs[i]; +void elfParseCFA(u8* top) +{ + ELFSectionHeader* h = elfGetSectionByName(".debug_frame"); + + if (h == NULL) { + return; + } + + u8* data = elfReadSection(top, h); + + u8* topOffset = data; + + u8* end = data + READ32LE(&h->size); + + ELFcie* cies = NULL; + + while (data < end) { + u32 offset = (u32)(data - topOffset); + u32 len = elfRead4Bytes(data); + data += 4; + + u8* dataEnd = data + len; + + u32 id = elfRead4Bytes(data); + data += 4; + + if (id == 0xffffffff) { + // skip version + (*data)++; + + ELFcie* cie = (ELFcie*)calloc(1, sizeof(ELFcie)); + + cie->next = cies; + cies = cie; + + cie->offset = offset; + + cie->augmentation = data; + while (*data) + data++; + data++; + + if (*cie->augmentation) { + fprintf(stderr, "Error: augmentation not supported\n"); + exit(-1); + } + + int bytes; + cie->codeAlign = elfReadLEB128(data, &bytes); + data += bytes; + + cie->dataAlign = elfReadSignedLEB128(data, &bytes); + data += bytes; + + cie->returnAddress = *data++; + + cie->data = data; + cie->dataLen = (u32)(dataEnd - data); + } else { + ELFfde* fde = (ELFfde*)calloc(1, sizeof(ELFfde)); + + ELFcie* cie = cies; + + while (cie != NULL) { + if (cie->offset == id) + break; + cie = cie->next; + } + + if (!cie) { + fprintf(stderr, "Cannot find CIE %08x\n", id); + exit(-1); + } + + fde->cie = cie; + + fde->address = elfRead4Bytes(data); + data += 4; + + fde->end = fde->address + elfRead4Bytes(data); + data += 4; + + fde->data = data; + fde->dataLen = (u32)(dataEnd - data); + + if ((elfFdeCount % 10) == 0) { + elfFdes = (ELFfde**)realloc(elfFdes, (elfFdeCount + 10) * sizeof(ELFfde*)); + } + elfFdes[elfFdeCount++] = fde; + } + data = dataEnd; + } + + elfCies = cies; +} + +void elfAddLine(LineInfo* l, u32 a, int file, int line, int* max) +{ + if (l->number == *max) { + *max += 1000; + l->lines = (LineInfoItem*)realloc(l->lines, *max * sizeof(LineInfoItem)); + } + LineInfoItem* li = &l->lines[l->number]; + li->file = l->files[file - 1]; + li->address = a; + li->line = line; + l->number++; +} + +void elfParseLineInfo(CompileUnit* unit, u8* top) +{ + ELFSectionHeader* h = elfGetSectionByName(".debug_line"); + if (h == NULL) { + fprintf(stderr, "No line information found\n"); + return; + } + LineInfo* l = unit->lineInfoTable = (LineInfo*)calloc(1, sizeof(LineInfo)); + l->number = 0; + int max = 1000; + l->lines = (LineInfoItem*)malloc(1000 * sizeof(LineInfoItem)); + + u8* data = elfReadSection(top, h); + data += unit->lineInfo; + u32 totalLen = elfRead4Bytes(data); + data += 4; + u8* end = data + totalLen; + // u16 version = elfRead2Bytes(data); + data += 2; + // u32 offset = elfRead4Bytes(data); + data += 4; + int minInstrSize = *data++; + int defaultIsStmt = *data++; + int lineBase = (s8)*data++; + int lineRange = *data++; + int opcodeBase = *data++; + u8* stdOpLen = (u8*)malloc(opcodeBase * sizeof(u8)); + stdOpLen[0] = 1; + int i; + for (i = 1; i < opcodeBase; i++) + stdOpLen[i] = *data++; + + free(stdOpLen); // todo + int bytes = 0; + + char* s; + while ((s = elfReadString(data, &bytes)) != NULL) { + data += bytes; + // fprintf(stderr, "Directory is %s\n", s); + } + data += bytes; + int count = 4; + int index = 0; + l->files = (char**)malloc(sizeof(char*) * count); + + while ((s = elfReadString(data, &bytes)) != NULL) { + l->files[index++] = s; + + data += bytes; + // directory + elfReadLEB128(data, &bytes); + data += bytes; + // time + elfReadLEB128(data, &bytes); + data += bytes; + // size + elfReadLEB128(data, &bytes); + data += bytes; + // fprintf(stderr, "File is %s\n", s); + if (index == count) { + count += 4; + l->files = (char**)realloc(l->files, sizeof(char*) * count); + } + } + l->fileCount = index; + data += bytes; + + while (data < end) { + u32 address = 0; + int file = 1; + int line = 1; + int col = 0; + int isStmt = defaultIsStmt; + int basicBlock = 0; + int endSeq = 0; + + while (!endSeq) { + int op = *data++; + switch (op) { + case DW_LNS_extended_op: { + data++; + op = *data++; + switch (op) { + case DW_LNE_end_sequence: + endSeq = 1; + break; + case DW_LNE_set_address: + address = elfRead4Bytes(data); + data += 4; + break; + default: + fprintf(stderr, "Unknown extended LINE opcode %02x\n", op); + exit(-1); + } + } break; + case DW_LNS_copy: + // fprintf(stderr, "Address %08x line %d (%d)\n", address, line, file); + elfAddLine(l, address, file, line, &max); + basicBlock = 0; + break; + case DW_LNS_advance_pc: + address += minInstrSize * elfReadLEB128(data, &bytes); + data += bytes; + break; + case DW_LNS_advance_line: + line += elfReadSignedLEB128(data, &bytes); + data += bytes; + break; + case DW_LNS_set_file: + file = elfReadLEB128(data, &bytes); + data += bytes; + break; + case DW_LNS_set_column: + col = elfReadLEB128(data, &bytes); + data += bytes; + break; + case DW_LNS_negate_stmt: + isStmt = !isStmt; + break; + case DW_LNS_set_basic_block: + basicBlock = 1; + break; + case DW_LNS_const_add_pc: + address += (minInstrSize * ((255 - opcodeBase) / lineRange)); + break; + case DW_LNS_fixed_advance_pc: + address += elfRead2Bytes(data); + data += 2; + break; + default: + op = op - opcodeBase; + address += (op / lineRange) * minInstrSize; + line += lineBase + (op % lineRange); + elfAddLine(l, address, file, line, &max); + // fprintf(stderr, "Address %08x line %d (%d)\n", address, line,file); + basicBlock = 1; + break; + } + } + } + l->lines = (LineInfoItem*)realloc(l->lines, l->number * sizeof(LineInfoItem)); +} + +u8* elfSkipData(u8* data, ELFAbbrev* abbrev, ELFAbbrev** abbrevs) +{ + int i; + int bytes; + + for (i = 0; i < abbrev->numAttrs; i++) { + data = elfReadAttribute(data, &abbrev->attrs[i]); + if (abbrev->attrs[i].form == DW_FORM_block1) + free(abbrev->attrs[i].block); + } + + if (abbrev->hasChildren) { + int nesting = 1; + while (nesting) { + u32 abbrevNum = elfReadLEB128(data, &bytes); + data += bytes; + + if (!abbrevNum) { + nesting--; + continue; + } + + abbrev = elfGetAbbrev(abbrevs, abbrevNum); + + for (i = 0; i < abbrev->numAttrs; i++) { + data = elfReadAttribute(data, &abbrev->attrs[i]); + if (abbrev->attrs[i].form == DW_FORM_block1) + free(abbrev->attrs[i].block); + } + + if (abbrev->hasChildren) { + nesting++; + } + } + } + return data; +} + +Type* elfParseType(CompileUnit* unit, u32); +u8* elfParseObject(u8* data, ELFAbbrev* abbrev, CompileUnit* unit, + Object** object); +u8* elfParseFunction(u8* data, ELFAbbrev* abbrev, CompileUnit* unit, + Function** function); +void elfCleanUp(Function*); + +void elfAddType(Type* type, CompileUnit* unit, u32 offset) +{ + if (type->next == NULL) { + if (unit->types != type && type->offset == 0) { + type->offset = offset; + type->next = unit->types; + unit->types = type; + } + } +} + +void elfParseType(u8* data, u32 offset, ELFAbbrev* abbrev, CompileUnit* unit, + Type** type) +{ + switch (abbrev->tag) { + case DW_TAG_typedef: { + u32 typeref = 0; + char* name = NULL; + for (int i = 0; i < abbrev->numAttrs; i++) { + ELFAttr* attr = &abbrev->attrs[i]; + data = elfReadAttribute(data, attr); + switch (attr->name) { + case DW_AT_name: + name = attr->string; + break; + case DW_AT_type: + typeref = attr->value; + break; + case DW_AT_decl_file: + case DW_AT_decl_line: + break; + default: + fprintf(stderr, "Unknown attribute for typedef %02x\n", attr->name); + break; + } + } + if (abbrev->hasChildren) + fprintf(stderr, "Unexpected children for typedef\n"); + *type = elfParseType(unit, typeref); + if (name) + (*type)->name = name; + return; + } break; + case DW_TAG_union_type: + case DW_TAG_structure_type: { + Type* t = (Type*)calloc(sizeof(Type), 1); + if (abbrev->tag == DW_TAG_structure_type) + t->type = TYPE_struct; + else + t->type = TYPE_union; + + Struct* s = (Struct*)calloc(sizeof(Struct), 1); + t->structure = s; + elfAddType(t, unit, offset); + + for (int i = 0; i < abbrev->numAttrs; i++) { + ELFAttr* attr = &abbrev->attrs[i]; + data = elfReadAttribute(data, attr); + switch (attr->name) { + case DW_AT_name: + t->name = attr->string; + break; + case DW_AT_byte_size: + t->size = attr->value; + break; + case DW_AT_decl_file: + case DW_AT_decl_line: + case DW_AT_sibling: + case DW_AT_containing_type: // todo? + case DW_AT_declaration: + case DW_AT_specification: // TODO: + break; + default: + fprintf(stderr, "Unknown attribute for struct %02x\n", attr->name); + break; + } + } + if (abbrev->hasChildren) { + int bytes; + u32 num = elfReadLEB128(data, &bytes); + data += bytes; + int index = 0; + while (num) { + ELFAbbrev* abbr = elfGetAbbrev(unit->abbrevs, num); + + switch (abbr->tag) { + case DW_TAG_member: { + if ((index % 4) == 0) + s->members = (Member*)realloc(s->members, + sizeof(Member) * (index + 4)); + Member* m = &s->members[index]; + m->location = NULL; + m->bitOffset = 0; + m->bitSize = 0; + m->byteSize = 0; + for (int i = 0; i < abbr->numAttrs; i++) { + ELFAttr* attr = &abbr->attrs[i]; + data = elfReadAttribute(data, attr); + switch (attr->name) { + case DW_AT_name: + m->name = attr->string; + break; + case DW_AT_type: + m->type = elfParseType(unit, attr->value); + break; + case DW_AT_data_member_location: + m->location = attr->block; + break; + case DW_AT_byte_size: + m->byteSize = attr->value; + break; + case DW_AT_bit_offset: + m->bitOffset = attr->value; + break; + case DW_AT_bit_size: + m->bitSize = attr->value; + break; + case DW_AT_decl_file: + case DW_AT_decl_line: + case DW_AT_accessibility: + case DW_AT_artificial: // todo? + break; + default: + fprintf(stderr, "Unknown member attribute %02x\n", + attr->name); + } + } + index++; + } break; + case DW_TAG_subprogram: { + Function* fnc = NULL; + data = elfParseFunction(data, abbr, unit, &fnc); + if (fnc != NULL) { + if (unit->lastFunction) + unit->lastFunction->next = fnc; + else + unit->functions = fnc; + unit->lastFunction = fnc; + } + } break; + case DW_TAG_inheritance: + // TODO: add support + data = elfSkipData(data, abbr, unit->abbrevs); + break; + CASE_TYPE_TAG: + // skip types... parsed only when used + data = elfSkipData(data, abbr, unit->abbrevs); + break; + case DW_TAG_variable: + data = elfSkipData(data, abbr, unit->abbrevs); + break; + default: + fprintf(stderr, "Unknown struct tag %02x %s\n", abbr->tag, t->name); + data = elfSkipData(data, abbr, unit->abbrevs); + break; + } + num = elfReadLEB128(data, &bytes); + data += bytes; + } + s->memberCount = index; + } + *type = t; + return; + } break; + case DW_TAG_base_type: { + Type* t = (Type*)calloc(sizeof(Type), 1); + + t->type = TYPE_base; + elfAddType(t, unit, offset); + for (int i = 0; i < abbrev->numAttrs; i++) { + ELFAttr* attr = &abbrev->attrs[i]; + data = elfReadAttribute(data, attr); + switch (attr->name) { + case DW_AT_name: + t->name = attr->string; + break; + case DW_AT_encoding: + t->encoding = attr->value; + break; + case DW_AT_byte_size: + t->size = attr->value; + break; + case DW_AT_bit_size: + t->bitSize = attr->value; + break; + default: + fprintf(stderr, "Unknown attribute for base type %02x\n", + attr->name); + break; + } + } + if (abbrev->hasChildren) + fprintf(stderr, "Unexpected children for base type\n"); + *type = t; + return; + } break; + case DW_TAG_pointer_type: { + Type* t = (Type*)calloc(sizeof(Type), 1); + + t->type = TYPE_pointer; + + elfAddType(t, unit, offset); + + for (int i = 0; i < abbrev->numAttrs; i++) { + ELFAttr* attr = &abbrev->attrs[i]; + data = elfReadAttribute(data, attr); + switch (attr->name) { + case DW_AT_type: + t->pointer = elfParseType(unit, attr->value); + break; + case DW_AT_byte_size: + t->size = attr->value; + break; + default: + fprintf(stderr, "Unknown pointer type attribute %02x\n", attr->name); + break; + } + } + if (abbrev->hasChildren) + fprintf(stderr, "Unexpected children for pointer type\n"); + *type = t; + return; + } break; + case DW_TAG_reference_type: { + Type* t = (Type*)calloc(sizeof(Type), 1); + + t->type = TYPE_reference; + + elfAddType(t, unit, offset); + + for (int i = 0; i < abbrev->numAttrs; i++) { + ELFAttr* attr = &abbrev->attrs[i]; + data = elfReadAttribute(data, attr); + switch (attr->name) { + case DW_AT_type: + t->pointer = elfParseType(unit, attr->value); + break; + case DW_AT_byte_size: + t->size = attr->value; + break; + default: + fprintf(stderr, "Unknown ref type attribute %02x\n", attr->name); + break; + } + } + if (abbrev->hasChildren) + fprintf(stderr, "Unexpected children for ref type\n"); + *type = t; + return; + } break; + case DW_TAG_volatile_type: { + u32 typeref = 0; + + for (int i = 0; i < abbrev->numAttrs; i++) { + ELFAttr* attr = &abbrev->attrs[i]; + data = elfReadAttribute(data, attr); + switch (attr->name) { + case DW_AT_type: + typeref = attr->value; + break; + default: + fprintf(stderr, "Unknown volatile attribute for type %02x\n", + attr->name); + break; + } + } + if (abbrev->hasChildren) + fprintf(stderr, "Unexpected children for volatile type\n"); + *type = elfParseType(unit, typeref); + return; + } break; + case DW_TAG_const_type: { + u32 typeref = 0; + + for (int i = 0; i < abbrev->numAttrs; i++) { + ELFAttr* attr = &abbrev->attrs[i]; + data = elfReadAttribute(data, attr); + switch (attr->name) { + case DW_AT_type: + typeref = attr->value; + break; + default: + fprintf(stderr, "Unknown const attribute for type %02x\n", + attr->name); + break; + } + } + if (abbrev->hasChildren) + fprintf(stderr, "Unexpected children for const type\n"); + *type = elfParseType(unit, typeref); + return; + } break; + case DW_TAG_enumeration_type: { + Type* t = (Type*)calloc(sizeof(Type), 1); + t->type = TYPE_enum; + Enum* e = (Enum*)calloc(sizeof(Enum), 1); + t->enumeration = e; + elfAddType(t, unit, offset); + int count = 0; + for (int i = 0; i < abbrev->numAttrs; i++) { + ELFAttr* attr = &abbrev->attrs[i]; + data = elfReadAttribute(data, attr); + switch (attr->name) { + case DW_AT_name: + t->name = attr->string; + break; + case DW_AT_byte_size: + t->size = attr->value; + break; + case DW_AT_sibling: + case DW_AT_decl_file: + case DW_AT_decl_line: + break; + default: + fprintf(stderr, "Unknown enum attribute %02x\n", attr->name); + } + } + if (abbrev->hasChildren) { + int bytes; + u32 num = elfReadLEB128(data, &bytes); + data += bytes; + while (num) { + ELFAbbrev* abbr = elfGetAbbrev(unit->abbrevs, num); + + switch (abbr->tag) { + case DW_TAG_enumerator: { + count++; + e->members = (EnumMember*)realloc(e->members, + count * sizeof(EnumMember)); + EnumMember* m = &e->members[count - 1]; + for (int i = 0; i < abbr->numAttrs; i++) { + ELFAttr* attr = &abbr->attrs[i]; + data = elfReadAttribute(data, attr); + switch (attr->name) { + case DW_AT_name: + m->name = attr->string; + break; + case DW_AT_const_value: + m->value = attr->value; + break; + default: + fprintf(stderr, "Unknown sub param attribute %02x\n", + attr->name); + } + } + } break; + default: + fprintf(stderr, "Unknown enum tag %02x\n", abbr->tag); + data = elfSkipData(data, abbr, unit->abbrevs); + break; + } + num = elfReadLEB128(data, &bytes); + data += bytes; + } + } + e->count = count; + *type = t; + return; + } break; + case DW_TAG_subroutine_type: { + Type* t = (Type*)calloc(sizeof(Type), 1); + t->type = TYPE_function; + FunctionType* f = (FunctionType*)calloc(sizeof(FunctionType), 1); + t->function = f; + elfAddType(t, unit, offset); + for (int i = 0; i < abbrev->numAttrs; i++) { + ELFAttr* attr = &abbrev->attrs[i]; + data = elfReadAttribute(data, attr); + switch (attr->name) { + case DW_AT_prototyped: + case DW_AT_sibling: + break; + case DW_AT_type: + f->returnType = elfParseType(unit, attr->value); + break; + default: + fprintf(stderr, "Unknown subroutine attribute %02x\n", attr->name); + } + } + if (abbrev->hasChildren) { + int bytes; + u32 num = elfReadLEB128(data, &bytes); + data += bytes; + Object* lastVar = NULL; + while (num) { + ELFAbbrev* abbr = elfGetAbbrev(unit->abbrevs, num); + + switch (abbr->tag) { + case DW_TAG_formal_parameter: { + Object* o; + data = elfParseObject(data, abbr, unit, &o); + if (f->args) + lastVar->next = o; + else + f->args = o; + lastVar = o; + } break; + case DW_TAG_unspecified_parameters: + // no use in the debugger yet + data = elfSkipData(data, abbr, unit->abbrevs); + break; + CASE_TYPE_TAG: + // skip types... parsed only when used + data = elfSkipData(data, abbr, unit->abbrevs); + break; + default: + fprintf(stderr, "Unknown subroutine tag %02x\n", abbr->tag); + data = elfSkipData(data, abbr, unit->abbrevs); + break; + } + num = elfReadLEB128(data, &bytes); + data += bytes; + } + } + *type = t; + return; + } break; + case DW_TAG_array_type: { + u32 typeref = 0; + int i; + Array* array = (Array*)calloc(sizeof(Array), 1); + Type* t = (Type*)calloc(sizeof(Type), 1); + t->type = TYPE_array; + elfAddType(t, unit, offset); + + for (i = 0; i < abbrev->numAttrs; i++) { + ELFAttr* attr = &abbrev->attrs[i]; + data = elfReadAttribute(data, attr); + switch (attr->name) { + case DW_AT_sibling: + break; + case DW_AT_type: + typeref = attr->value; + array->type = elfParseType(unit, typeref); + break; + default: + fprintf(stderr, "Unknown array attribute %02x\n", attr->name); + } + } + if (abbrev->hasChildren) { + int bytes; + u32 num = elfReadLEB128(data, &bytes); + data += bytes; + int index = 0; + int maxBounds = 0; + while (num) { + ELFAbbrev* abbr = elfGetAbbrev(unit->abbrevs, num); + + switch (abbr->tag) { + case DW_TAG_subrange_type: { + if (maxBounds == index) { + maxBounds += 4; + array->bounds = (int*)realloc(array->bounds, + sizeof(int) * maxBounds); + } + for (int i = 0; i < abbr->numAttrs; i++) { + ELFAttr* attr = &abbr->attrs[i]; + data = elfReadAttribute(data, attr); + switch (attr->name) { + case DW_AT_upper_bound: + array->bounds[index] = attr->value + 1; + break; + case DW_AT_type: // ignore + break; + default: + fprintf(stderr, "Unknown subrange attribute %02x\n", + attr->name); + } + } + index++; + } break; + default: + fprintf(stderr, "Unknown array tag %02x\n", abbr->tag); + data = elfSkipData(data, abbr, unit->abbrevs); + break; + } + num = elfReadLEB128(data, &bytes); + data += bytes; + } + array->maxBounds = index; + } + t->size = array->type->size; + for (i = 0; i < array->maxBounds; i++) + t->size *= array->bounds[i]; + t->array = array; + *type = t; + return; + } break; + default: + fprintf(stderr, "Unknown type TAG %02x\n", abbrev->tag); + exit(-1); + } +} + +Type* elfParseType(CompileUnit* unit, u32 offset) +{ + Type* t = unit->types; + + while (t) { + if (t->offset == offset) + return t; + t = t->next; + } + if (offset == 0) { + Type* t = (Type*)calloc(sizeof(Type), 1); + t->type = TYPE_void; + t->offset = 0; + elfAddType(t, unit, 0); + return t; + } + u8* data = unit->top + offset; + int bytes; + int abbrevNum = elfReadLEB128(data, &bytes); + data += bytes; + Type* type = NULL; + + ELFAbbrev* abbrev = elfGetAbbrev(unit->abbrevs, abbrevNum); + + elfParseType(data, offset, abbrev, unit, &type); + return type; +} + +void elfGetObjectAttributes(CompileUnit* unit, u32 offset, Object* o) +{ + u8* data = unit->top + offset; + int bytes; + u32 abbrevNum = elfReadLEB128(data, &bytes); + data += bytes; + + if (!abbrevNum) { + return; + } + + ELFAbbrev* abbrev = elfGetAbbrev(unit->abbrevs, abbrevNum); + + for (int i = 0; i < abbrev->numAttrs; i++) { + ELFAttr* attr = &abbrev->attrs[i]; data = elfReadAttribute(data, attr); - switch(attr->name) { + switch (attr->name) { + case DW_AT_location: + o->location = attr->block; + break; case DW_AT_name: - t->name = attr->string; - break; - case DW_AT_byte_size: - t->size = attr->value; - break; + if (o->name == NULL) + o->name = attr->string; + break; + case DW_AT_MIPS_linkage_name: + o->name = attr->string; + break; case DW_AT_decl_file: + o->file = attr->value; + break; case DW_AT_decl_line: - case DW_AT_sibling: - case DW_AT_containing_type: // todo? + o->line = attr->value; + break; + case DW_AT_type: + o->type = elfParseType(unit, attr->value); + break; + case DW_AT_external: + o->external = attr->flag; + break; + case DW_AT_const_value: + case DW_AT_abstract_origin: case DW_AT_declaration: - case DW_AT_specification: // TODO: - break; + case DW_AT_artificial: + // todo + break; + case DW_AT_specification: + // TODO: + break; default: - fprintf(stderr, "Unknown attribute for struct %02x\n", attr->name); - break; + fprintf(stderr, "Unknown object attribute %02x\n", attr->name); + break; } - } - if(abbrev->hasChildren) { - int bytes; - u32 num = elfReadLEB128(data, &bytes); - data += bytes; - int index = 0; - while(num) { - ELFAbbrev *abbr = elfGetAbbrev(unit->abbrevs, num); - - switch(abbr->tag) { - case DW_TAG_member: - { - if((index % 4) == 0) - s->members = (Member *)realloc(s->members, - sizeof(Member)*(index+4)); - Member *m = &s->members[index]; - m->location = NULL; - m->bitOffset = 0; - m->bitSize = 0; - m->byteSize = 0; - for(int i = 0; i < abbr->numAttrs; i++) { - ELFAttr *attr = &abbr->attrs[i]; - data = elfReadAttribute(data, attr); - switch(attr->name) { - case DW_AT_name: - m->name = attr->string; - break; - case DW_AT_type: - m->type = elfParseType(unit, attr->value); - break; - case DW_AT_data_member_location: - m->location = attr->block; - break; - case DW_AT_byte_size: - m->byteSize = attr->value; - break; - case DW_AT_bit_offset: - m->bitOffset = attr->value; - break; - case DW_AT_bit_size: - m->bitSize = attr->value; - break; - case DW_AT_decl_file: - case DW_AT_decl_line: - case DW_AT_accessibility: - case DW_AT_artificial: // todo? - break; - default: - fprintf(stderr, "Unknown member attribute %02x\n", - attr->name); - } - } - index++; - } - break; - case DW_TAG_subprogram: - { - Function *fnc = NULL; - data = elfParseFunction(data, abbr, unit, &fnc); - if(fnc != NULL) { - if(unit->lastFunction) - unit->lastFunction->next = fnc; - else - unit->functions = fnc; - unit->lastFunction = fnc; - } - } - break; - case DW_TAG_inheritance: - // TODO: add support - data = elfSkipData(data, abbr, unit->abbrevs); - break; - CASE_TYPE_TAG: - // skip types... parsed only when used - data = elfSkipData(data, abbr, unit->abbrevs); - break; - case DW_TAG_variable: - data = elfSkipData(data, abbr, unit->abbrevs); - break; - default: - fprintf(stderr, "Unknown struct tag %02x %s\n", abbr->tag, t->name); - data = elfSkipData(data, abbr, unit->abbrevs); - break; - } - num = elfReadLEB128(data, &bytes); - data += bytes; - } - s->memberCount = index; - } - *type = t; - return; } - break; - case DW_TAG_base_type: - { - Type *t = (Type *)calloc(sizeof(Type), 1); +} - t->type = TYPE_base; - elfAddType(t, unit, offset); - for(int i = 0; i < abbrev->numAttrs; i++) { - ELFAttr *attr = &abbrev->attrs[i]; +u8* elfParseObject(u8* data, ELFAbbrev* abbrev, CompileUnit* unit, + Object** object) +{ + Object* o = (Object*)calloc(sizeof(Object), 1); + + o->next = NULL; + + for (int i = 0; i < abbrev->numAttrs; i++) { + ELFAttr* attr = &abbrev->attrs[i]; data = elfReadAttribute(data, attr); - switch(attr->name) { + switch (attr->name) { + case DW_AT_location: + o->location = attr->block; + break; case DW_AT_name: - t->name = attr->string; - break; - case DW_AT_encoding: - t->encoding = attr->value; - break; - case DW_AT_byte_size: - t->size = attr->value; - break; - case DW_AT_bit_size: - t->bitSize = attr->value; - break; - default: - fprintf(stderr, "Unknown attribute for base type %02x\n", - attr->name); - break; - } - } - if(abbrev->hasChildren) - fprintf(stderr, "Unexpected children for base type\n"); - *type = t; - return; - } - break; - case DW_TAG_pointer_type: - { - Type *t = (Type *)calloc(sizeof(Type), 1); - - t->type = TYPE_pointer; - - elfAddType(t, unit, offset); - - for(int i = 0; i < abbrev->numAttrs; i++) { - ELFAttr *attr = &abbrev->attrs[i]; - data =elfReadAttribute(data, attr); - switch(attr->name) { - case DW_AT_type: - t->pointer = elfParseType(unit, attr->value); - break; - case DW_AT_byte_size: - t->size = attr->value; - break; - default: - fprintf(stderr, "Unknown pointer type attribute %02x\n", attr->name); - break; - } - } - if(abbrev->hasChildren) - fprintf(stderr, "Unexpected children for pointer type\n"); - *type = t; - return; - } - break; - case DW_TAG_reference_type: - { - Type *t = (Type *)calloc(sizeof(Type), 1); - - t->type = TYPE_reference; - - elfAddType(t, unit, offset); - - for(int i = 0; i < abbrev->numAttrs; i++) { - ELFAttr *attr = &abbrev->attrs[i]; - data =elfReadAttribute(data, attr); - switch(attr->name) { - case DW_AT_type: - t->pointer = elfParseType(unit, attr->value); - break; - case DW_AT_byte_size: - t->size = attr->value; - break; - default: - fprintf(stderr, "Unknown ref type attribute %02x\n", attr->name); - break; - } - } - if(abbrev->hasChildren) - fprintf(stderr, "Unexpected children for ref type\n"); - *type = t; - return; - } - break; - case DW_TAG_volatile_type: - { - u32 typeref = 0; - - for(int i = 0; i < abbrev->numAttrs; i++) { - ELFAttr *attr = &abbrev->attrs[i]; - data = elfReadAttribute(data, attr); - switch(attr->name) { - case DW_AT_type: - typeref = attr->value; - break; - default: - fprintf(stderr, "Unknown volatile attribute for type %02x\n", - attr->name); - break; - } - } - if(abbrev->hasChildren) - fprintf(stderr, "Unexpected children for volatile type\n"); - *type = elfParseType(unit, typeref); - return; - } - break; - case DW_TAG_const_type: - { - u32 typeref = 0; - - for(int i = 0; i < abbrev->numAttrs; i++) { - ELFAttr *attr = &abbrev->attrs[i]; - data = elfReadAttribute(data, attr); - switch(attr->name) { - case DW_AT_type: - typeref = attr->value; - break; - default: - fprintf(stderr, "Unknown const attribute for type %02x\n", - attr->name); - break; - } - } - if(abbrev->hasChildren) - fprintf(stderr, "Unexpected children for const type\n"); - *type = elfParseType(unit, typeref); - return; - } - break; - case DW_TAG_enumeration_type: - { - Type *t = (Type *)calloc(sizeof(Type), 1); - t->type = TYPE_enum; - Enum *e = (Enum *)calloc(sizeof(Enum), 1); - t->enumeration = e; - elfAddType(t, unit, offset); - int count = 0; - for(int i = 0; i < abbrev->numAttrs; i++) { - ELFAttr *attr = &abbrev->attrs[i]; - data = elfReadAttribute(data, attr); - switch(attr->name) { - case DW_AT_name: - t->name = attr->string; - break; - case DW_AT_byte_size: - t->size = attr->value; - break; - case DW_AT_sibling: + if (o->name == NULL) + o->name = attr->string; + break; + case DW_AT_MIPS_linkage_name: + o->name = attr->string; + break; case DW_AT_decl_file: + o->file = attr->value; + break; case DW_AT_decl_line: - break; + o->line = attr->value; + break; + case DW_AT_type: + o->type = elfParseType(unit, attr->value); + break; + case DW_AT_external: + o->external = attr->flag; + break; + case DW_AT_abstract_origin: + elfGetObjectAttributes(unit, attr->value, o); + break; + case DW_AT_const_value: + case DW_AT_declaration: + case DW_AT_artificial: + break; + case DW_AT_specification: + // TODO: + break; default: - fprintf(stderr, "Unknown enum attribute %02x\n", attr->name); - } - } - if(abbrev->hasChildren) { - int bytes; - u32 num = elfReadLEB128(data, &bytes); - data += bytes; - while(num) { - ELFAbbrev *abbr = elfGetAbbrev(unit->abbrevs, num); - - switch(abbr->tag) { - case DW_TAG_enumerator: - { - count++; - e->members = (EnumMember *)realloc(e->members, - count*sizeof(EnumMember)); - EnumMember *m = &e->members[count-1]; - for(int i = 0; i < abbr->numAttrs; i++) { - ELFAttr *attr = &abbr->attrs[i]; - data = elfReadAttribute(data, attr); - switch(attr->name) { - case DW_AT_name: - m->name = attr->string; - break; - case DW_AT_const_value: - m->value = attr->value; - break; - default: - fprintf(stderr, "Unknown sub param attribute %02x\n", - attr->name); - } - } - } + fprintf(stderr, "Unknown object attribute %02x\n", attr->name); break; - default: - fprintf(stderr, "Unknown enum tag %02x\n", abbr->tag); - data = elfSkipData(data, abbr, unit->abbrevs); - break; - } - num = elfReadLEB128(data, &bytes); - data += bytes; } - } - e->count = count; - *type = t; - return; } - break; - case DW_TAG_subroutine_type: - { - Type *t = (Type *)calloc(sizeof(Type), 1); - t->type = TYPE_function; - FunctionType *f = (FunctionType *)calloc(sizeof(FunctionType), 1); - t->function = f; - elfAddType(t, unit, offset); - for(int i = 0; i < abbrev->numAttrs; i++) { - ELFAttr *attr = &abbrev->attrs[i]; + *object = o; + return data; +} + +u8* elfParseBlock(u8* data, ELFAbbrev* abbrev, CompileUnit* unit, + Function* func, Object** lastVar) +{ + int bytes; + u32 start = func->lowPC; + u32 end = func->highPC; + + for (int i = 0; i < abbrev->numAttrs; i++) { + ELFAttr* attr = &abbrev->attrs[i]; data = elfReadAttribute(data, attr); - switch(attr->name) { + switch (attr->name) { + case DW_AT_sibling: + break; + case DW_AT_low_pc: + start = attr->value; + break; + case DW_AT_high_pc: + end = attr->value; + break; + case DW_AT_ranges: // ignore for now + break; + default: + fprintf(stderr, "Unknown block attribute %02x\n", attr->name); + break; + } + } + + if (abbrev->hasChildren) { + int nesting = 1; + + while (nesting) { + u32 abbrevNum = elfReadLEB128(data, &bytes); + data += bytes; + + if (!abbrevNum) { + nesting--; + continue; + } + + abbrev = elfGetAbbrev(unit->abbrevs, abbrevNum); + + switch (abbrev->tag) { + CASE_TYPE_TAG: // types only parsed when used + case DW_TAG_label: // not needed + data = elfSkipData(data, abbrev, unit->abbrevs); + break; + case DW_TAG_lexical_block: + data = elfParseBlock(data, abbrev, unit, func, lastVar); + break; + case DW_TAG_subprogram: { + Function* f = NULL; + data = elfParseFunction(data, abbrev, unit, &f); + if (f != NULL) { + if (unit->lastFunction) + unit->lastFunction->next = f; + else + unit->functions = f; + unit->lastFunction = f; + } + } break; + case DW_TAG_variable: { + Object* o; + data = elfParseObject(data, abbrev, unit, &o); + if (o->startScope == 0) + o->startScope = start; + if (o->endScope == 0) + o->endScope = 0; + if (func->variables) + (*lastVar)->next = o; + else + func->variables = o; + *lastVar = o; + } break; + case DW_TAG_inlined_subroutine: + // TODO: + data = elfSkipData(data, abbrev, unit->abbrevs); + break; + default: { + fprintf(stderr, "Unknown block TAG %02x\n", abbrev->tag); + data = elfSkipData(data, abbrev, unit->abbrevs); + } break; + } + } + } + return data; +} + +void elfGetFunctionAttributes(CompileUnit* unit, u32 offset, Function* func) +{ + u8* data = unit->top + offset; + int bytes; + u32 abbrevNum = elfReadLEB128(data, &bytes); + data += bytes; + + if (!abbrevNum) { + return; + } + + ELFAbbrev* abbrev = elfGetAbbrev(unit->abbrevs, abbrevNum); + + for (int i = 0; i < abbrev->numAttrs; i++) { + ELFAttr* attr = &abbrev->attrs[i]; + data = elfReadAttribute(data, attr); + + switch (attr->name) { + case DW_AT_sibling: + break; + case DW_AT_name: + if (func->name == NULL) + func->name = attr->string; + break; + case DW_AT_MIPS_linkage_name: + func->name = attr->string; + break; + case DW_AT_low_pc: + func->lowPC = attr->value; + break; + case DW_AT_high_pc: + func->highPC = attr->value; + break; + case DW_AT_decl_file: + func->file = attr->value; + break; + case DW_AT_decl_line: + func->line = attr->value; + break; + case DW_AT_external: + func->external = attr->flag; + break; + case DW_AT_frame_base: + func->frameBase = attr->block; + break; + case DW_AT_type: + func->returnType = elfParseType(unit, attr->value); + break; + case DW_AT_inline: + case DW_AT_specification: + case DW_AT_declaration: + case DW_AT_artificial: case DW_AT_prototyped: - case DW_AT_sibling: - break; - case DW_AT_type: - f->returnType = elfParseType(unit, attr->value); - break; + case DW_AT_proc_body: + case DW_AT_save_offset: + case DW_AT_user_2002: + case DW_AT_virtuality: + case DW_AT_containing_type: + case DW_AT_accessibility: + // todo; + break; + case DW_AT_vtable_elem_location: + free(attr->block); + break; default: - fprintf(stderr, "Unknown subroutine attribute %02x\n", attr->name); + fprintf(stderr, "Unknown function attribute %02x\n", attr->name); + break; } - } - if(abbrev->hasChildren) { - int bytes; - u32 num = elfReadLEB128(data, &bytes); - data += bytes; - Object *lastVar = NULL; - while(num) { - ELFAbbrev *abbr = elfGetAbbrev(unit->abbrevs, num); - - switch(abbr->tag) { - case DW_TAG_formal_parameter: - { - Object *o; - data = elfParseObject(data, abbr, unit, &o); - if(f->args) - lastVar->next = o; - else - f->args = o; - lastVar = o; - } - break; - case DW_TAG_unspecified_parameters: - // no use in the debugger yet - data = elfSkipData(data, abbr, unit->abbrevs); - break; - CASE_TYPE_TAG: - // skip types... parsed only when used - data = elfSkipData(data, abbr, unit->abbrevs); - break; - default: - fprintf(stderr, "Unknown subroutine tag %02x\n", abbr->tag); - data = elfSkipData(data, abbr, unit->abbrevs); - break; - } - num = elfReadLEB128(data, &bytes); - data += bytes; - } - } - *type = t; - return; } - break; - case DW_TAG_array_type: - { - u32 typeref = 0; - int i; - Array *array = (Array *)calloc(sizeof(Array), 1); - Type *t = (Type *)calloc(sizeof(Type), 1); - t->type = TYPE_array; - elfAddType(t, unit, offset); - for(i = 0; i < abbrev->numAttrs; i++) { - ELFAttr *attr = &abbrev->attrs[i]; + return; +} + +u8* elfParseFunction(u8* data, ELFAbbrev* abbrev, CompileUnit* unit, + Function** f) +{ + Function* func = (Function*)calloc(sizeof(Function), 1); + *f = func; + + int bytes; + bool mangled = false; + bool declaration = false; + for (int i = 0; i < abbrev->numAttrs; i++) { + ELFAttr* attr = &abbrev->attrs[i]; data = elfReadAttribute(data, attr); - switch(attr->name) { + switch (attr->name) { case DW_AT_sibling: - break; + break; + case DW_AT_name: + if (func->name == NULL) + func->name = attr->string; + break; + case DW_AT_MIPS_linkage_name: + func->name = attr->string; + mangled = true; + break; + case DW_AT_low_pc: + func->lowPC = attr->value; + break; + case DW_AT_high_pc: + func->highPC = attr->value; + break; + case DW_AT_prototyped: + break; + case DW_AT_decl_file: + func->file = attr->value; + break; + case DW_AT_decl_line: + func->line = attr->value; + break; + case DW_AT_external: + func->external = attr->flag; + break; + case DW_AT_frame_base: + func->frameBase = attr->block; + break; case DW_AT_type: - typeref = attr->value; - array->type = elfParseType(unit, typeref); - break; + func->returnType = elfParseType(unit, attr->value); + break; + case DW_AT_abstract_origin: + elfGetFunctionAttributes(unit, attr->value, func); + break; + case DW_AT_declaration: + declaration = attr->flag; + break; + case DW_AT_inline: + case DW_AT_specification: + case DW_AT_artificial: + case DW_AT_proc_body: + case DW_AT_save_offset: + case DW_AT_user_2002: + case DW_AT_virtuality: + case DW_AT_containing_type: + case DW_AT_accessibility: + // todo; + break; + case DW_AT_vtable_elem_location: + free(attr->block); + break; default: - fprintf(stderr, "Unknown array attribute %02x\n", attr->name); + fprintf(stderr, "Unknown function attribute %02x\n", attr->name); + break; } - } - if(abbrev->hasChildren) { - int bytes; - u32 num = elfReadLEB128(data, &bytes); - data += bytes; - int index = 0; - int maxBounds = 0; - while(num) { - ELFAbbrev *abbr = elfGetAbbrev(unit->abbrevs, num); + } - switch(abbr->tag) { - case DW_TAG_subrange_type: - { - if(maxBounds == index) { - maxBounds += 4; - array->bounds = (int *)realloc(array->bounds, - sizeof(int)*maxBounds); - } - for(int i = 0; i < abbr->numAttrs; i++) { - ELFAttr *attr = &abbr->attrs[i]; - data = elfReadAttribute(data, attr); - switch(attr->name) { - case DW_AT_upper_bound: - array->bounds[index] = attr->value+1; - break; - case DW_AT_type: // ignore - break; - default: - fprintf(stderr, "Unknown subrange attribute %02x\n", - attr->name); - } - } - index++; + if (declaration) { + elfCleanUp(func); + free(func); + *f = NULL; + + while (1) { + u32 abbrevNum = elfReadLEB128(data, &bytes); + data += bytes; + + if (!abbrevNum) { + return data; } - break; - default: - fprintf(stderr, "Unknown array tag %02x\n", abbr->tag); - data = elfSkipData(data, abbr, unit->abbrevs); - break; - } - num = elfReadLEB128(data, &bytes); - data += bytes; + + abbrev = elfGetAbbrev(unit->abbrevs, abbrevNum); + + data = elfSkipData(data, abbrev, unit->abbrevs); } - array->maxBounds = index; - } - t->size = array->type->size; - for(i = 0; i < array->maxBounds; i++) - t->size *= array->bounds[i]; - t->array = array; - *type = t; - return; } - break; - default: - fprintf(stderr, "Unknown type TAG %02x\n", abbrev->tag); - exit(-1); - } + + if (abbrev->hasChildren) { + int nesting = 1; + Object* lastParam = NULL; + Object* lastVar = NULL; + + while (nesting) { + u32 abbrevNum = elfReadLEB128(data, &bytes); + data += bytes; + + if (!abbrevNum) { + nesting--; + continue; + } + + abbrev = elfGetAbbrev(unit->abbrevs, abbrevNum); + + switch (abbrev->tag) { + CASE_TYPE_TAG: // no need to parse types. only parsed when used + case DW_TAG_label: // not needed + data = elfSkipData(data, abbrev, unit->abbrevs); + break; + case DW_TAG_subprogram: { + Function* fnc = NULL; + data = elfParseFunction(data, abbrev, unit, &fnc); + if (fnc != NULL) { + if (unit->lastFunction == NULL) + unit->functions = fnc; + else + unit->lastFunction->next = fnc; + unit->lastFunction = fnc; + } + } break; + case DW_TAG_lexical_block: { + data = elfParseBlock(data, abbrev, unit, func, &lastVar); + } break; + case DW_TAG_formal_parameter: { + Object* o; + data = elfParseObject(data, abbrev, unit, &o); + if (func->parameters) + lastParam->next = o; + else + func->parameters = o; + lastParam = o; + } break; + case DW_TAG_variable: { + Object* o; + data = elfParseObject(data, abbrev, unit, &o); + if (func->variables) + lastVar->next = o; + else + func->variables = o; + lastVar = o; + } break; + case DW_TAG_unspecified_parameters: + case DW_TAG_inlined_subroutine: { + // todo + for (int i = 0; i < abbrev->numAttrs; i++) { + data = elfReadAttribute(data, &abbrev->attrs[i]); + if (abbrev->attrs[i].form == DW_FORM_block1) + free(abbrev->attrs[i].block); + } + + if (abbrev->hasChildren) + nesting++; + } break; + default: { + fprintf(stderr, "Unknown function TAG %02x\n", abbrev->tag); + data = elfSkipData(data, abbrev, unit->abbrevs); + } break; + } + } + } + return data; } -Type *elfParseType(CompileUnit *unit, u32 offset) +u8* elfParseUnknownData(u8* data, ELFAbbrev* abbrev, ELFAbbrev** abbrevs) { - Type *t = unit->types; - - while(t) { - if(t->offset == offset) - return t; - t = t->next; - } - if(offset == 0) { - Type *t = (Type *)calloc(sizeof(Type), 1); - t->type = TYPE_void; - t->offset = 0; - elfAddType(t, unit, 0); - return t; - } - u8 *data = unit->top + offset; - int bytes; - int abbrevNum = elfReadLEB128(data, &bytes); - data += bytes; - Type *type = NULL; - - ELFAbbrev *abbrev = elfGetAbbrev(unit->abbrevs, abbrevNum); - - elfParseType(data, offset, abbrev, unit, &type); - return type; -} - -void elfGetObjectAttributes(CompileUnit *unit, u32 offset, Object *o) -{ - u8 *data = unit->top + offset; - int bytes; - u32 abbrevNum = elfReadLEB128(data, &bytes); - data += bytes; - - if(!abbrevNum) { - return; - } - - ELFAbbrev *abbrev = elfGetAbbrev(unit->abbrevs, abbrevNum); - - for(int i = 0; i < abbrev->numAttrs; i++) { - ELFAttr *attr = &abbrev->attrs[i]; - data = elfReadAttribute(data, attr); - switch(attr->name) { - case DW_AT_location: - o->location = attr->block; - break; - case DW_AT_name: - if(o->name == NULL) - o->name = attr->string; - break; - case DW_AT_MIPS_linkage_name: - o->name = attr->string; - break; - case DW_AT_decl_file: - o->file = attr->value; - break; - case DW_AT_decl_line: - o->line = attr->value; - break; - case DW_AT_type: - o->type = elfParseType(unit, attr->value); - break; - case DW_AT_external: - o->external = attr->flag; - break; - case DW_AT_const_value: - case DW_AT_abstract_origin: - case DW_AT_declaration: - case DW_AT_artificial: - // todo - break; - case DW_AT_specification: - // TODO: - break; - default: - fprintf(stderr, "Unknown object attribute %02x\n", attr->name); - break; - } - } -} - -u8 *elfParseObject(u8 *data, ELFAbbrev *abbrev, CompileUnit *unit, - Object **object) -{ - Object *o = (Object *)calloc(sizeof(Object), 1); - - o->next = NULL; - - for(int i = 0; i < abbrev->numAttrs; i++) { - ELFAttr *attr = &abbrev->attrs[i]; - data = elfReadAttribute(data, attr); - switch(attr->name) { - case DW_AT_location: - o->location = attr->block; - break; - case DW_AT_name: - if(o->name == NULL) - o->name = attr->string; - break; - case DW_AT_MIPS_linkage_name: - o->name = attr->string; - break; - case DW_AT_decl_file: - o->file = attr->value; - break; - case DW_AT_decl_line: - o->line = attr->value; - break; - case DW_AT_type: - o->type = elfParseType(unit, attr->value); - break; - case DW_AT_external: - o->external = attr->flag; - break; - case DW_AT_abstract_origin: - elfGetObjectAttributes(unit, attr->value, o); - break; - case DW_AT_const_value: - case DW_AT_declaration: - case DW_AT_artificial: - break; - case DW_AT_specification: - // TODO: - break; - default: - fprintf(stderr, "Unknown object attribute %02x\n", attr->name); - break; - } - } - *object = o; - return data; -} - -u8 *elfParseBlock(u8 *data, ELFAbbrev *abbrev, CompileUnit *unit, - Function *func, Object **lastVar) -{ - int bytes; - u32 start = func->lowPC; - u32 end = func->highPC; - - for(int i = 0; i < abbrev->numAttrs; i++) { - ELFAttr *attr = &abbrev->attrs[i]; - data = elfReadAttribute(data, attr); - switch(attr->name) { - case DW_AT_sibling: - break; - case DW_AT_low_pc: - start = attr->value; - break; - case DW_AT_high_pc: - end = attr->value; - break; - case DW_AT_ranges: // ignore for now - break; - default: - fprintf(stderr, "Unknown block attribute %02x\n", attr->name); - break; - } - } - - if(abbrev->hasChildren) { - int nesting = 1; - - while(nesting) { - u32 abbrevNum = elfReadLEB128(data, &bytes); - data += bytes; - - if(!abbrevNum) { - nesting--; - continue; - } - - abbrev = elfGetAbbrev(unit->abbrevs, abbrevNum); - - switch(abbrev->tag) { - CASE_TYPE_TAG: // types only parsed when used - case DW_TAG_label: // not needed - data = elfSkipData(data, abbrev, unit->abbrevs); - break; - case DW_TAG_lexical_block: - data = elfParseBlock(data, abbrev, unit, func, lastVar); - break; - case DW_TAG_subprogram: - { - Function *f = NULL; - data = elfParseFunction(data, abbrev, unit, &f); - if(f != NULL) { - if(unit->lastFunction) - unit->lastFunction->next = f; - else - unit->functions = f; - unit->lastFunction = f; - } - } - break; - case DW_TAG_variable: - { - Object *o; - data = elfParseObject(data, abbrev, unit, &o); - if(o->startScope == 0) - o->startScope = start; - if(o->endScope == 0) - o->endScope = 0; - if(func->variables) - (*lastVar)->next = o; - else - func->variables = o; - *lastVar = o; - } - break; - case DW_TAG_inlined_subroutine: - // TODO: - data = elfSkipData(data, abbrev, unit->abbrevs); - break; - default: - { - fprintf(stderr, "Unknown block TAG %02x\n", abbrev->tag); - data = elfSkipData(data, abbrev, unit->abbrevs); - } - break; - } - } - } - return data; -} - -void elfGetFunctionAttributes(CompileUnit *unit, u32 offset, Function *func) -{ - u8 *data = unit->top + offset; - int bytes; - u32 abbrevNum = elfReadLEB128(data, &bytes); - data += bytes; - - if(!abbrevNum) { - return; - } - - ELFAbbrev *abbrev = elfGetAbbrev(unit->abbrevs, abbrevNum); - - for(int i = 0; i < abbrev->numAttrs; i++) { - ELFAttr *attr = &abbrev->attrs[i]; - data = elfReadAttribute(data, attr); - - switch(attr->name) { - case DW_AT_sibling: - break; - case DW_AT_name: - if(func->name == NULL) - func->name = attr->string; - break; - case DW_AT_MIPS_linkage_name: - func->name = attr->string; - break; - case DW_AT_low_pc: - func->lowPC = attr->value; - break; - case DW_AT_high_pc: - func->highPC = attr->value; - break; - case DW_AT_decl_file: - func->file = attr->value; - break; - case DW_AT_decl_line: - func->line = attr->value; - break; - case DW_AT_external: - func->external = attr->flag; - break; - case DW_AT_frame_base: - func->frameBase = attr->block; - break; - case DW_AT_type: - func->returnType = elfParseType(unit, attr->value); - break; - case DW_AT_inline: - case DW_AT_specification: - case DW_AT_declaration: - case DW_AT_artificial: - case DW_AT_prototyped: - case DW_AT_proc_body: - case DW_AT_save_offset: - case DW_AT_user_2002: - case DW_AT_virtuality: - case DW_AT_containing_type: - case DW_AT_accessibility: - // todo; - break; - case DW_AT_vtable_elem_location: - free(attr->block); - break; - default: - fprintf(stderr, "Unknown function attribute %02x\n", attr->name); - break; - } - } - - return; -} - -u8 *elfParseFunction(u8 *data, ELFAbbrev *abbrev, CompileUnit *unit, - Function **f) -{ - Function *func = (Function *)calloc(sizeof(Function), 1); - *f = func; - - int bytes; - bool mangled = false; - bool declaration = false; - for(int i = 0; i < abbrev->numAttrs; i++) { - ELFAttr *attr = &abbrev->attrs[i]; - data = elfReadAttribute(data, attr); - switch(attr->name) { - case DW_AT_sibling: - break; - case DW_AT_name: - if(func->name == NULL) - func->name = attr->string; - break; - case DW_AT_MIPS_linkage_name: - func->name = attr->string; - mangled = true; - break; - case DW_AT_low_pc: - func->lowPC = attr->value; - break; - case DW_AT_high_pc: - func->highPC = attr->value; - break; - case DW_AT_prototyped: - break; - case DW_AT_decl_file: - func->file = attr->value; - break; - case DW_AT_decl_line: - func->line = attr->value; - break; - case DW_AT_external: - func->external = attr->flag; - break; - case DW_AT_frame_base: - func->frameBase = attr->block; - break; - case DW_AT_type: - func->returnType = elfParseType(unit, attr->value); - break; - case DW_AT_abstract_origin: - elfGetFunctionAttributes(unit, attr->value, func); - break; - case DW_AT_declaration: - declaration = attr->flag; - break; - case DW_AT_inline: - case DW_AT_specification: - case DW_AT_artificial: - case DW_AT_proc_body: - case DW_AT_save_offset: - case DW_AT_user_2002: - case DW_AT_virtuality: - case DW_AT_containing_type: - case DW_AT_accessibility: - // todo; - break; - case DW_AT_vtable_elem_location: - free(attr->block); - break; - default: - fprintf(stderr, "Unknown function attribute %02x\n", attr->name); - break; - } - } - - if(declaration) { - elfCleanUp(func); - free(func); - *f = NULL; - - while(1) { - u32 abbrevNum = elfReadLEB128(data, &bytes); - data += bytes; - - if(!abbrevNum) { - return data; - } - - abbrev = elfGetAbbrev(unit->abbrevs, abbrevNum); - - data = elfSkipData(data, abbrev, unit->abbrevs); - } - } - - if(abbrev->hasChildren) { - int nesting = 1; - Object *lastParam = NULL; - Object *lastVar = NULL; - - while(nesting) { - u32 abbrevNum = elfReadLEB128(data, &bytes); - data += bytes; - - if(!abbrevNum) { - nesting--; - continue; - } - - abbrev = elfGetAbbrev(unit->abbrevs, abbrevNum); - - switch(abbrev->tag) { - CASE_TYPE_TAG: // no need to parse types. only parsed when used - case DW_TAG_label: // not needed - data = elfSkipData(data, abbrev, unit->abbrevs); - break; - case DW_TAG_subprogram: - { - Function *fnc=NULL; - data = elfParseFunction(data, abbrev, unit, &fnc); - if(fnc != NULL) { - if(unit->lastFunction == NULL) - unit->functions = fnc; - else - unit->lastFunction->next = fnc; - unit->lastFunction = fnc; - } - } - break; - case DW_TAG_lexical_block: - { - data = elfParseBlock(data, abbrev, unit, func, &lastVar); - } - break; - case DW_TAG_formal_parameter: - { - Object *o; - data = elfParseObject(data, abbrev, unit, &o); - if(func->parameters) - lastParam->next = o; - else - func->parameters = o; - lastParam = o; - } - break; - case DW_TAG_variable: - { - Object *o; - data = elfParseObject(data, abbrev, unit, &o); - if(func->variables) - lastVar->next = o; - else - func->variables = o; - lastVar = o; - } - break; - case DW_TAG_unspecified_parameters: - case DW_TAG_inlined_subroutine: - { - // todo - for(int i = 0; i < abbrev->numAttrs; i++) { - data = elfReadAttribute(data, &abbrev->attrs[i]); - if(abbrev->attrs[i].form == DW_FORM_block1) - free(abbrev->attrs[i].block); - } - - if(abbrev->hasChildren) - nesting++; - } - break; - default: - { - fprintf(stderr, "Unknown function TAG %02x\n", abbrev->tag); - data = elfSkipData(data, abbrev, unit->abbrevs); - } - break; - } - } - } - return data; -} - -u8 *elfParseUnknownData(u8 *data, ELFAbbrev *abbrev, ELFAbbrev **abbrevs) -{ - int i; - int bytes; - // switch(abbrev->tag) { - // default: + int i; + int bytes; + // switch(abbrev->tag) { + // default: fprintf(stderr, "Unknown TAG %02x\n", abbrev->tag); - for(i = 0; i < abbrev->numAttrs; i++) { - data = elfReadAttribute(data, &abbrev->attrs[i]); - if(abbrev->attrs[i].form == DW_FORM_block1) - free(abbrev->attrs[i].block); + for (i = 0; i < abbrev->numAttrs; i++) { + data = elfReadAttribute(data, &abbrev->attrs[i]); + if (abbrev->attrs[i].form == DW_FORM_block1) + free(abbrev->attrs[i].block); } - if(abbrev->hasChildren) { - int nesting = 1; - while(nesting) { - u32 abbrevNum = elfReadLEB128(data, &bytes); - data += bytes; + if (abbrev->hasChildren) { + int nesting = 1; + while (nesting) { + u32 abbrevNum = elfReadLEB128(data, &bytes); + data += bytes; - if(!abbrevNum) { - nesting--; - continue; + if (!abbrevNum) { + nesting--; + continue; + } + + abbrev = elfGetAbbrev(abbrevs, abbrevNum); + + fprintf(stderr, "Unknown TAG %02x\n", abbrev->tag); + + for (i = 0; i < abbrev->numAttrs; i++) { + data = elfReadAttribute(data, &abbrev->attrs[i]); + if (abbrev->attrs[i].form == DW_FORM_block1) + free(abbrev->attrs[i].block); + } + + if (abbrev->hasChildren) { + nesting++; + } } - - abbrev = elfGetAbbrev(abbrevs, abbrevNum); - - fprintf(stderr, "Unknown TAG %02x\n", abbrev->tag); - - for(i = 0; i < abbrev->numAttrs; i++) { - data = elfReadAttribute(data, &abbrev->attrs[i]); - if(abbrev->attrs[i].form == DW_FORM_block1) - free(abbrev->attrs[i].block); - } - - if(abbrev->hasChildren) { - nesting++; - } - } } // } - return data; + return data; } -u8 *elfParseCompileUnitChildren(u8 *data, CompileUnit *unit) +u8* elfParseCompileUnitChildren(u8* data, CompileUnit* unit) { - int bytes; - u32 abbrevNum = elfReadLEB128(data, &bytes); - data += bytes; - Object *lastObj = NULL; - while(abbrevNum) { - ELFAbbrev *abbrev = elfGetAbbrev(unit->abbrevs, abbrevNum); - switch(abbrev->tag) { - case DW_TAG_subprogram: - { - Function *func = NULL; - data = elfParseFunction(data, abbrev, unit, &func); - if(func != NULL) { - if(unit->lastFunction) - unit->lastFunction->next = func; - else - unit->functions = func; - unit->lastFunction = func; - } - } - break; - CASE_TYPE_TAG: - data = elfSkipData(data, abbrev, unit->abbrevs); - break; - case DW_TAG_variable: - { - Object *var = NULL; - data = elfParseObject(data, abbrev, unit, &var); - if(lastObj) - lastObj->next = var; - else - unit->variables = var; - lastObj = var; - } - break; - default: - data = elfParseUnknownData(data, abbrev, unit->abbrevs); - break; - } - - abbrevNum = elfReadLEB128(data, &bytes); + int bytes; + u32 abbrevNum = elfReadLEB128(data, &bytes); data += bytes; - } - return data; -} + Object* lastObj = NULL; + while (abbrevNum) { + ELFAbbrev* abbrev = elfGetAbbrev(unit->abbrevs, abbrevNum); + switch (abbrev->tag) { + case DW_TAG_subprogram: { + Function* func = NULL; + data = elfParseFunction(data, abbrev, unit, &func); + if (func != NULL) { + if (unit->lastFunction) + unit->lastFunction->next = func; + else + unit->functions = func; + unit->lastFunction = func; + } + } break; + CASE_TYPE_TAG: + data = elfSkipData(data, abbrev, unit->abbrevs); + break; + case DW_TAG_variable: { + Object* var = NULL; + data = elfParseObject(data, abbrev, unit, &var); + if (lastObj) + lastObj->next = var; + else + unit->variables = var; + lastObj = var; + } break; + default: + data = elfParseUnknownData(data, abbrev, unit->abbrevs); + break; + } - -CompileUnit *elfParseCompUnit(u8 *data, u8 *abbrevData) -{ - int bytes; - u8 *top = data; - - u32 length = elfRead4Bytes(data); - data += 4; - - u16 version = elfRead2Bytes(data); - data += 2; - - u32 offset = elfRead4Bytes(data); - data += 4; - - u8 addrSize = *data++; - - if(version != 2) { - fprintf(stderr, "Unsupported debugging information version %d\n", version); - return NULL; - } - - if(addrSize != 4) { - fprintf(stderr, "Unsupported address size %d\n", addrSize); - return NULL; - } - - ELFAbbrev **abbrevs = elfReadAbbrevs(abbrevData, offset); - - u32 abbrevNum = elfReadLEB128(data, &bytes); - data += bytes; - - ELFAbbrev *abbrev = elfGetAbbrev(abbrevs, abbrevNum); - - CompileUnit *unit = (CompileUnit *)calloc(sizeof(CompileUnit), 1); - unit->top = top; - unit->length = length; - unit->abbrevs = abbrevs; - unit->next = NULL; - - elfCurrentUnit = unit; - - int i; - - for(i = 0; i < abbrev->numAttrs; i++) { - ELFAttr *attr = &abbrev->attrs[i]; - data = elfReadAttribute(data, attr); - - switch(attr->name) { - case DW_AT_name: - unit->name = attr->string; - break; - case DW_AT_stmt_list: - unit->hasLineInfo = true; - unit->lineInfo = attr->value; - break; - case DW_AT_low_pc: - unit->lowPC = attr->value; - break; - case DW_AT_high_pc: - unit->highPC = attr->value; - break; - case DW_AT_compdir: - unit->compdir = attr->string; - break; - // ignore - case DW_AT_language: - case DW_AT_producer: - case DW_AT_macro_info: - case DW_AT_entry_pc: - break; - default: - fprintf(stderr, "Unknown attribute %02x\n", attr->name); - break; + abbrevNum = elfReadLEB128(data, &bytes); + data += bytes; } - } - - if(abbrev->hasChildren) - elfParseCompileUnitChildren(data, unit); - - return unit; + return data; } -void elfParseAranges(u8 *data) +CompileUnit* elfParseCompUnit(u8* data, u8* abbrevData) { - ELFSectionHeader *sh = elfGetSectionByName(".debug_aranges"); - if(sh == NULL) { - fprintf(stderr, "No aranges found\n"); - return; - } + int bytes; + u8* top = data; - data = elfReadSection(data, sh); - u8 *end = data + READ32LE(&sh->size); - - int max = 4; - ARanges *ranges = (ARanges *)calloc(sizeof(ARanges), 4); - - int index = 0; - - while(data < end) { - u32 len = elfRead4Bytes(data); + u32 length = elfRead4Bytes(data); data += 4; - // u16 version = elfRead2Bytes(data); + + u16 version = elfRead2Bytes(data); data += 2; + u32 offset = elfRead4Bytes(data); data += 4; - // u8 addrSize = *data++; - // u8 segSize = *data++; - data += 2; // remove if uncommenting above - data += 4; - ranges[index].count = (len-20)/8; - ranges[index].offset = offset; - ranges[index].ranges = (ARange *)calloc(sizeof(ARange), (len-20)/8); - int i = 0; - while(true) { - u32 addr = elfRead4Bytes(data); - data += 4; - u32 len = elfRead4Bytes(data); - data += 4; - if(addr == 0 && len == 0) - break; - ranges[index].ranges[i].lowPC = addr; - ranges[index].ranges[i].highPC = addr+len; - i++; + + u8 addrSize = *data++; + + if (version != 2) { + fprintf(stderr, "Unsupported debugging information version %d\n", version); + return NULL; } - index++; - if(index == max) { - max += 4; - ranges = (ARanges *)realloc(ranges, max*sizeof(ARanges)); + + if (addrSize != 4) { + fprintf(stderr, "Unsupported address size %d\n", addrSize); + return NULL; } - } - elfDebugInfo->numRanges = index; - elfDebugInfo->ranges = ranges; + + ELFAbbrev** abbrevs = elfReadAbbrevs(abbrevData, offset); + + u32 abbrevNum = elfReadLEB128(data, &bytes); + data += bytes; + + ELFAbbrev* abbrev = elfGetAbbrev(abbrevs, abbrevNum); + + CompileUnit* unit = (CompileUnit*)calloc(sizeof(CompileUnit), 1); + unit->top = top; + unit->length = length; + unit->abbrevs = abbrevs; + unit->next = NULL; + + elfCurrentUnit = unit; + + int i; + + for (i = 0; i < abbrev->numAttrs; i++) { + ELFAttr* attr = &abbrev->attrs[i]; + data = elfReadAttribute(data, attr); + + switch (attr->name) { + case DW_AT_name: + unit->name = attr->string; + break; + case DW_AT_stmt_list: + unit->hasLineInfo = true; + unit->lineInfo = attr->value; + break; + case DW_AT_low_pc: + unit->lowPC = attr->value; + break; + case DW_AT_high_pc: + unit->highPC = attr->value; + break; + case DW_AT_compdir: + unit->compdir = attr->string; + break; + // ignore + case DW_AT_language: + case DW_AT_producer: + case DW_AT_macro_info: + case DW_AT_entry_pc: + break; + default: + fprintf(stderr, "Unknown attribute %02x\n", attr->name); + break; + } + } + + if (abbrev->hasChildren) + elfParseCompileUnitChildren(data, unit); + + return unit; } -void elfReadSymtab(u8 *data) +void elfParseAranges(u8* data) { - ELFSectionHeader *sh = elfGetSectionByName(".symtab"); - int table = READ32LE(&sh->link); - - char *strtable = (char *)elfReadSection(data, elfGetSectionByNumber(table)); - - ELFSymbol *symtab = (ELFSymbol *)elfReadSection(data, sh); - - int count = READ32LE(&sh->size) / sizeof(ELFSymbol); - elfSymbolsCount = 0; - - elfSymbols = (Symbol *)malloc(sizeof(Symbol)*count); - - int i; - - for(i = 0; i < count; i++) { - ELFSymbol *s = &symtab[i]; - int type = s->info & 15; - int binding = s->info >> 4; - - if(binding) { - Symbol *sym = &elfSymbols[elfSymbolsCount]; - sym->name = &strtable[READ32LE(&s->name)]; - sym->binding = binding; - sym->type = type; - sym->value = READ32LE(&s->value); - sym->size = READ32LE(&s->size); - elfSymbolsCount++; + ELFSectionHeader* sh = elfGetSectionByName(".debug_aranges"); + if (sh == NULL) { + fprintf(stderr, "No aranges found\n"); + return; } - } - for(i = 0; i < count; i++) { - ELFSymbol *s = &symtab[i]; - int bind = s->info>>4; - int type = s->info & 15; - if(!bind) { - Symbol *sym = &elfSymbols[elfSymbolsCount]; - sym->name = &strtable[READ32LE(&s->name)]; - sym->binding = (s->info >> 4); - sym->type = type; - sym->value = READ32LE(&s->value); - sym->size = READ32LE(&s->size); - elfSymbolsCount++; + data = elfReadSection(data, sh); + u8* end = data + READ32LE(&sh->size); + + int max = 4; + ARanges* ranges = (ARanges*)calloc(sizeof(ARanges), 4); + + int index = 0; + + while (data < end) { + u32 len = elfRead4Bytes(data); + data += 4; + // u16 version = elfRead2Bytes(data); + data += 2; + u32 offset = elfRead4Bytes(data); + data += 4; + // u8 addrSize = *data++; + // u8 segSize = *data++; + data += 2; // remove if uncommenting above + data += 4; + ranges[index].count = (len - 20) / 8; + ranges[index].offset = offset; + ranges[index].ranges = (ARange*)calloc(sizeof(ARange), (len - 20) / 8); + int i = 0; + while (true) { + u32 addr = elfRead4Bytes(data); + data += 4; + u32 len = elfRead4Bytes(data); + data += 4; + if (addr == 0 && len == 0) + break; + ranges[index].ranges[i].lowPC = addr; + ranges[index].ranges[i].highPC = addr + len; + i++; + } + index++; + if (index == max) { + max += 4; + ranges = (ARanges*)realloc(ranges, max * sizeof(ARanges)); + } } - } - elfSymbolsStrTab = strtable; - // free(symtab); + elfDebugInfo->numRanges = index; + elfDebugInfo->ranges = ranges; } -bool elfReadProgram(ELFHeader *eh, u8 *data, int& size, bool parseDebug) +void elfReadSymtab(u8* data) { - int count = READ16LE(&eh->e_phnum); - int i; + ELFSectionHeader* sh = elfGetSectionByName(".symtab"); + int table = READ32LE(&sh->link); - if(READ32LE(&eh->e_entry) == 0x2000000) - cpuIsMultiBoot = true; + char* strtable = (char*)elfReadSection(data, elfGetSectionByNumber(table)); - // read program headers... should probably move this code down - u8 *p = data + READ32LE(&eh->e_phoff); - size = 0; - for(i = 0; i < count; i++) { - ELFProgramHeader *ph = (ELFProgramHeader *)p; - p += sizeof(ELFProgramHeader); - if(READ16LE(&eh->e_phentsize) != sizeof(ELFProgramHeader)) { - p += READ16LE(&eh->e_phentsize) - sizeof(ELFProgramHeader); - } + ELFSymbol* symtab = (ELFSymbol*)elfReadSection(data, sh); - // printf("PH %d %08x %08x %08x %08x %08x %08x %08x %08x\n", - // i, ph->type, ph->offset, ph->vaddr, ph->paddr, - // ph->filesz, ph->memsz, ph->flags, ph->align); - if(cpuIsMultiBoot) { - if(READ32LE(&ph->paddr) >= 0x2000000 && - READ32LE(&ph->paddr) <= 0x203ffff) { - memcpy(&workRAM[READ32LE(&ph->paddr) & 0x3ffff], - data + READ32LE(&ph->offset), - READ32LE(&ph->filesz)); - size += READ32LE(&ph->filesz); - } - } else { - if(READ32LE(&ph->paddr) >= 0x8000000 && - READ32LE(&ph->paddr) <= 0x9ffffff) { - memcpy(&rom[READ32LE(&ph->paddr) & 0x1ffffff], - data + READ32LE(&ph->offset), - READ32LE(&ph->filesz)); - size += READ32LE(&ph->filesz); - } - } - } + int count = READ32LE(&sh->size) / sizeof(ELFSymbol); + elfSymbolsCount = 0; - char *stringTable = NULL; + elfSymbols = (Symbol*)malloc(sizeof(Symbol) * count); - // read section headers - p = data + READ32LE(&eh->e_shoff); - count = READ16LE(&eh->e_shnum); + int i; - ELFSectionHeader **sh = (ELFSectionHeader **) - malloc(sizeof(ELFSectionHeader *) * count); + for (i = 0; i < count; i++) { + ELFSymbol* s = &symtab[i]; + int type = s->info & 15; + int binding = s->info >> 4; - for(i = 0; i < count; i++) { - sh[i] = (ELFSectionHeader *)p; - p += sizeof(ELFSectionHeader); - if(READ16LE(&eh->e_shentsize) != sizeof(ELFSectionHeader)) - p += READ16LE(&eh->e_shentsize) - sizeof(ELFSectionHeader); - } - - if(READ16LE(&eh->e_shstrndx) != 0) { - stringTable = (char *)elfReadSection(data, - sh[READ16LE(&eh->e_shstrndx)]); - } - - elfSectionHeaders = sh; - elfSectionHeadersStringTable = stringTable; - elfSectionHeadersCount = count; - - for(i = 0; i < count; i++) { - // printf("SH %d %-20s %08x %08x %08x %08x %08x %08x %08x %08x\n", - // i, &stringTable[sh[i]->name], sh[i]->name, sh[i]->type, - // sh[i]->flags, sh[i]->addr, sh[i]->offset, sh[i]->size, - // sh[i]->link, sh[i]->info); - if(READ32LE(&sh[i]->flags) & 2) { // load section - if(cpuIsMultiBoot) { - if(READ32LE(&sh[i]->addr) >= 0x2000000 && - READ32LE(&sh[i]->addr) <= 0x203ffff) { - memcpy(&workRAM[READ32LE(&sh[i]->addr) & 0x3ffff], data + - READ32LE(&sh[i]->offset), - READ32LE(&sh[i]->size)); - size += READ32LE(&sh[i]->size); + if (binding) { + Symbol* sym = &elfSymbols[elfSymbolsCount]; + sym->name = &strtable[READ32LE(&s->name)]; + sym->binding = binding; + sym->type = type; + sym->value = READ32LE(&s->value); + sym->size = READ32LE(&s->size); + elfSymbolsCount++; } - } else { - if(READ32LE(&sh[i]->addr) >= 0x8000000 && - READ32LE(&sh[i]->addr) <= 0x9ffffff) { - memcpy(&rom[READ32LE(&sh[i]->addr) & 0x1ffffff], - data + READ32LE(&sh[i]->offset), - READ32LE(&sh[i]->size)); - size += READ32LE(&sh[i]->size); + } + for (i = 0; i < count; i++) { + ELFSymbol* s = &symtab[i]; + int bind = s->info >> 4; + int type = s->info & 15; + + if (!bind) { + Symbol* sym = &elfSymbols[elfSymbolsCount]; + sym->name = &strtable[READ32LE(&s->name)]; + sym->binding = (s->info >> 4); + sym->type = type; + sym->value = READ32LE(&s->value); + sym->size = READ32LE(&s->size); + elfSymbolsCount++; } - } } - } + elfSymbolsStrTab = strtable; + // free(symtab); +} - if(parseDebug) { - fprintf(stderr, "Parsing debug info\n"); +bool elfReadProgram(ELFHeader* eh, u8* data, int& size, bool parseDebug) +{ + int count = READ16LE(&eh->e_phnum); + int i; - ELFSectionHeader *dbgHeader = elfGetSectionByName(".debug_info"); - if(dbgHeader == NULL) { - fprintf(stderr, "Cannot find debug information\n"); - goto end; - } + if (READ32LE(&eh->e_entry) == 0x2000000) + cpuIsMultiBoot = true; - ELFSectionHeader *h = elfGetSectionByName(".debug_abbrev"); - if(h == NULL) { - fprintf(stderr, "Cannot find abbreviation table\n"); - goto end; - } - - elfDebugInfo = (DebugInfo *)calloc(sizeof(DebugInfo), 1); - u8 *abbrevdata = elfReadSection(data, h); - - h = elfGetSectionByName(".debug_str"); - - if(h == NULL) - elfDebugStrings = NULL; - else - elfDebugStrings = (char *)elfReadSection(data, h); - - u8 *debugdata = elfReadSection(data, dbgHeader); - - elfDebugInfo->debugdata = data; - elfDebugInfo->infodata = debugdata; - - u32 total = READ32LE(&dbgHeader->size); - u8 *end = debugdata + total; - u8 *ddata = debugdata; - - CompileUnit *last = NULL; - CompileUnit *unit = NULL; - - while(ddata < end) { - unit = elfParseCompUnit(ddata, abbrevdata); - unit->offset = (u32)(ddata-debugdata); - elfParseLineInfo(unit, data); - if(last == NULL) - elfCompileUnits = unit; - else - last->next = unit; - last = unit; - ddata += 4 + unit->length; - } - elfParseAranges(data); - CompileUnit *comp = elfCompileUnits; - while(comp) { - ARanges *r = elfDebugInfo->ranges; - for(int i = 0; i < elfDebugInfo->numRanges; i++) - if(r[i].offset == comp->offset) { - comp->ranges = &r[i]; - break; + // read program headers... should probably move this code down + u8* p = data + READ32LE(&eh->e_phoff); + size = 0; + for (i = 0; i < count; i++) { + ELFProgramHeader* ph = (ELFProgramHeader*)p; + p += sizeof(ELFProgramHeader); + if (READ16LE(&eh->e_phentsize) != sizeof(ELFProgramHeader)) { + p += READ16LE(&eh->e_phentsize) - sizeof(ELFProgramHeader); + } + + // printf("PH %d %08x %08x %08x %08x %08x %08x %08x %08x\n", + // i, ph->type, ph->offset, ph->vaddr, ph->paddr, + // ph->filesz, ph->memsz, ph->flags, ph->align); + if (cpuIsMultiBoot) { + if (READ32LE(&ph->paddr) >= 0x2000000 && READ32LE(&ph->paddr) <= 0x203ffff) { + memcpy(&workRAM[READ32LE(&ph->paddr) & 0x3ffff], + data + READ32LE(&ph->offset), + READ32LE(&ph->filesz)); + size += READ32LE(&ph->filesz); + } + } else { + if (READ32LE(&ph->paddr) >= 0x8000000 && READ32LE(&ph->paddr) <= 0x9ffffff) { + memcpy(&rom[READ32LE(&ph->paddr) & 0x1ffffff], + data + READ32LE(&ph->offset), + READ32LE(&ph->filesz)); + size += READ32LE(&ph->filesz); + } } - comp = comp->next; } - elfParseCFA(data); - elfReadSymtab(data); - } - end: - if(sh) { - free(sh); - } - elfSectionHeaders = NULL; - elfSectionHeadersStringTable = NULL; - elfSectionHeadersCount = 0; + char* stringTable = NULL; - return true; + // read section headers + p = data + READ32LE(&eh->e_shoff); + count = READ16LE(&eh->e_shnum); + + ELFSectionHeader** sh = (ELFSectionHeader**) + malloc(sizeof(ELFSectionHeader*) * count); + + for (i = 0; i < count; i++) { + sh[i] = (ELFSectionHeader*)p; + p += sizeof(ELFSectionHeader); + if (READ16LE(&eh->e_shentsize) != sizeof(ELFSectionHeader)) + p += READ16LE(&eh->e_shentsize) - sizeof(ELFSectionHeader); + } + + if (READ16LE(&eh->e_shstrndx) != 0) { + stringTable = (char*)elfReadSection(data, + sh[READ16LE(&eh->e_shstrndx)]); + } + + elfSectionHeaders = sh; + elfSectionHeadersStringTable = stringTable; + elfSectionHeadersCount = count; + + for (i = 0; i < count; i++) { + // printf("SH %d %-20s %08x %08x %08x %08x %08x %08x %08x %08x\n", + // i, &stringTable[sh[i]->name], sh[i]->name, sh[i]->type, + // sh[i]->flags, sh[i]->addr, sh[i]->offset, sh[i]->size, + // sh[i]->link, sh[i]->info); + if (READ32LE(&sh[i]->flags) & 2) { // load section + if (cpuIsMultiBoot) { + if (READ32LE(&sh[i]->addr) >= 0x2000000 && READ32LE(&sh[i]->addr) <= 0x203ffff) { + memcpy(&workRAM[READ32LE(&sh[i]->addr) & 0x3ffff], data + READ32LE(&sh[i]->offset), + READ32LE(&sh[i]->size)); + size += READ32LE(&sh[i]->size); + } + } else { + if (READ32LE(&sh[i]->addr) >= 0x8000000 && READ32LE(&sh[i]->addr) <= 0x9ffffff) { + memcpy(&rom[READ32LE(&sh[i]->addr) & 0x1ffffff], + data + READ32LE(&sh[i]->offset), + READ32LE(&sh[i]->size)); + size += READ32LE(&sh[i]->size); + } + } + } + } + + if (parseDebug) { + fprintf(stderr, "Parsing debug info\n"); + + ELFSectionHeader* dbgHeader = elfGetSectionByName(".debug_info"); + if (dbgHeader == NULL) { + fprintf(stderr, "Cannot find debug information\n"); + goto end; + } + + ELFSectionHeader* h = elfGetSectionByName(".debug_abbrev"); + if (h == NULL) { + fprintf(stderr, "Cannot find abbreviation table\n"); + goto end; + } + + elfDebugInfo = (DebugInfo*)calloc(sizeof(DebugInfo), 1); + u8* abbrevdata = elfReadSection(data, h); + + h = elfGetSectionByName(".debug_str"); + + if (h == NULL) + elfDebugStrings = NULL; + else + elfDebugStrings = (char*)elfReadSection(data, h); + + u8* debugdata = elfReadSection(data, dbgHeader); + + elfDebugInfo->debugdata = data; + elfDebugInfo->infodata = debugdata; + + u32 total = READ32LE(&dbgHeader->size); + u8* end = debugdata + total; + u8* ddata = debugdata; + + CompileUnit* last = NULL; + CompileUnit* unit = NULL; + + while (ddata < end) { + unit = elfParseCompUnit(ddata, abbrevdata); + unit->offset = (u32)(ddata - debugdata); + elfParseLineInfo(unit, data); + if (last == NULL) + elfCompileUnits = unit; + else + last->next = unit; + last = unit; + ddata += 4 + unit->length; + } + elfParseAranges(data); + CompileUnit* comp = elfCompileUnits; + while (comp) { + ARanges* r = elfDebugInfo->ranges; + for (int i = 0; i < elfDebugInfo->numRanges; i++) + if (r[i].offset == comp->offset) { + comp->ranges = &r[i]; + break; + } + comp = comp->next; + } + elfParseCFA(data); + elfReadSymtab(data); + } +end: + if (sh) { + free(sh); + } + + elfSectionHeaders = NULL; + elfSectionHeadersStringTable = NULL; + elfSectionHeadersCount = 0; + + return true; } extern bool parseDebug; -bool elfRead(const char *name, int& siz, FILE *f) +bool elfRead(const char* name, int& siz, FILE* f) { - fseek(f, 0, SEEK_END); - long size = ftell(f); - elfFileData = (u8 *)malloc(size); - fseek(f, 0, SEEK_SET); - int res = fread(elfFileData, 1, size, f); - fclose(f); + fseek(f, 0, SEEK_END); + long size = ftell(f); + elfFileData = (u8*)malloc(size); + fseek(f, 0, SEEK_SET); + int res = fread(elfFileData, 1, size, f); + fclose(f); - if (res < 0) - { - free(elfFileData); - elfFileData = NULL; - return false; - } - - ELFHeader *header = (ELFHeader *)elfFileData; - - if(READ32LE(&header->magic) != 0x464C457F || - READ16LE(&header->e_machine) != 40 || - header->clazz != 1) { - systemMessage(0, N_("Not a valid ELF file %s"), name); - free(elfFileData); - elfFileData = NULL; - return false; - } - - if(!elfReadProgram(header, elfFileData, siz, parseDebug)) { - free(elfFileData); - elfFileData = NULL; - return false; - } - - return true; -} - -void elfCleanUp(Object *o) -{ - free(o->location); -} - -void elfCleanUp(Function *func) -{ - Object *o = func->parameters; - while(o) { - elfCleanUp(o); - Object *next = o->next; - free(o); - o = next; - } - - o = func->variables; - while(o) { - elfCleanUp(o); - Object *next = o->next; - free(o); - o = next; - } - free(func->frameBase); -} - -void elfCleanUp(ELFAbbrev **abbrevs) -{ - for(int i = 0; i < 121; i++) { - ELFAbbrev *abbrev = abbrevs[i]; - - while(abbrev) { - free(abbrev->attrs); - ELFAbbrev *next = abbrev->next; - free(abbrev); - - abbrev = next; + if (res < 0) { + free(elfFileData); + elfFileData = NULL; + return false; } - } + + ELFHeader* header = (ELFHeader*)elfFileData; + + if (READ32LE(&header->magic) != 0x464C457F || READ16LE(&header->e_machine) != 40 || header->clazz != 1) { + systemMessage(0, N_("Not a valid ELF file %s"), name); + free(elfFileData); + elfFileData = NULL; + return false; + } + + if (!elfReadProgram(header, elfFileData, siz, parseDebug)) { + free(elfFileData); + elfFileData = NULL; + return false; + } + + return true; } -void elfCleanUp(Type *t) +void elfCleanUp(Object* o) { - switch(t->type) { - case TYPE_function: - if(t->function) { - Object *o = t->function->args; - while(o) { + free(o->location); +} + +void elfCleanUp(Function* func) +{ + Object* o = func->parameters; + while (o) { elfCleanUp(o); - Object *next = o->next; + Object* next = o->next; free(o); o = next; - } - free(t->function); } - break; - case TYPE_array: - if(t->array) { - free(t->array->bounds); - free(t->array); + + o = func->variables; + while (o) { + elfCleanUp(o); + Object* next = o->next; + free(o); + o = next; } - break; - case TYPE_struct: - case TYPE_union: - if(t->structure) { - for(int i = 0; i < t->structure->memberCount; i++) { - free(t->structure->members[i].location); - } - free(t->structure->members); - free(t->structure); - } - break; - case TYPE_enum: - if(t->enumeration) { - free(t->enumeration->members); - free(t->enumeration); - } - break; - case TYPE_base: - case TYPE_pointer: - case TYPE_void: - case TYPE_reference: - break; // nothing to do - } + free(func->frameBase); } -void elfCleanUp(CompileUnit *comp) +void elfCleanUp(ELFAbbrev** abbrevs) { - elfCleanUp(comp->abbrevs); - free(comp->abbrevs); - Function *func = comp->functions; - while(func) { - elfCleanUp(func); - Function *next = func->next; - free(func); - func = next; - } - Type *t = comp->types; - while(t) { - elfCleanUp(t); - Type *next = t->next; - free(t); - t = next; - } - Object *o = comp->variables; - while(o) { - elfCleanUp(o); - Object *next = o->next; - free(o); - o = next; - } - if(comp->lineInfoTable) { - free(comp->lineInfoTable->lines); - free(comp->lineInfoTable->files); - free(comp->lineInfoTable); - } + for (int i = 0; i < 121; i++) { + ELFAbbrev* abbrev = abbrevs[i]; + + while (abbrev) { + free(abbrev->attrs); + ELFAbbrev* next = abbrev->next; + free(abbrev); + + abbrev = next; + } + } +} + +void elfCleanUp(Type* t) +{ + switch (t->type) { + case TYPE_function: + if (t->function) { + Object* o = t->function->args; + while (o) { + elfCleanUp(o); + Object* next = o->next; + free(o); + o = next; + } + free(t->function); + } + break; + case TYPE_array: + if (t->array) { + free(t->array->bounds); + free(t->array); + } + break; + case TYPE_struct: + case TYPE_union: + if (t->structure) { + for (int i = 0; i < t->structure->memberCount; i++) { + free(t->structure->members[i].location); + } + free(t->structure->members); + free(t->structure); + } + break; + case TYPE_enum: + if (t->enumeration) { + free(t->enumeration->members); + free(t->enumeration); + } + break; + case TYPE_base: + case TYPE_pointer: + case TYPE_void: + case TYPE_reference: + break; // nothing to do + } +} + +void elfCleanUp(CompileUnit* comp) +{ + elfCleanUp(comp->abbrevs); + free(comp->abbrevs); + Function* func = comp->functions; + while (func) { + elfCleanUp(func); + Function* next = func->next; + free(func); + func = next; + } + Type* t = comp->types; + while (t) { + elfCleanUp(t); + Type* next = t->next; + free(t); + t = next; + } + Object* o = comp->variables; + while (o) { + elfCleanUp(o); + Object* next = o->next; + free(o); + o = next; + } + if (comp->lineInfoTable) { + free(comp->lineInfoTable->lines); + free(comp->lineInfoTable->files); + free(comp->lineInfoTable); + } } void elfCleanUp() { - CompileUnit *comp = elfCompileUnits; + CompileUnit* comp = elfCompileUnits; - while(comp) { - elfCleanUp(comp); - CompileUnit *next = comp->next; - free(comp); - comp = next; - } - elfCompileUnits = NULL; - free(elfSymbols); - elfSymbols = NULL; - // free(elfSymbolsStrTab); - elfSymbolsStrTab = NULL; - - elfDebugStrings = NULL; - if(elfDebugInfo) { - int num = elfDebugInfo->numRanges; - int i; - for(i = 0; i < num; i++) { - free(elfDebugInfo->ranges[i].ranges); + while (comp) { + elfCleanUp(comp); + CompileUnit* next = comp->next; + free(comp); + comp = next; } - free(elfDebugInfo->ranges); - free(elfDebugInfo); - elfDebugInfo = NULL; - } + elfCompileUnits = NULL; + free(elfSymbols); + elfSymbols = NULL; + // free(elfSymbolsStrTab); + elfSymbolsStrTab = NULL; - if(elfFdes) { - if(elfFdeCount) { - for(int i = 0; i < elfFdeCount; i++) - free(elfFdes[i]); + elfDebugStrings = NULL; + if (elfDebugInfo) { + int num = elfDebugInfo->numRanges; + int i; + for (i = 0; i < num; i++) { + free(elfDebugInfo->ranges[i].ranges); + } + free(elfDebugInfo->ranges); + free(elfDebugInfo); + elfDebugInfo = NULL; } - free(elfFdes); - elfFdes = NULL; - elfFdeCount = 0; - } + if (elfFdes) { + if (elfFdeCount) { + for (int i = 0; i < elfFdeCount; i++) + free(elfFdes[i]); + } + free(elfFdes); - ELFcie *cie = elfCies; - while(cie) { - ELFcie *next = cie->next; - free(cie); - cie = next; - } - elfCies = NULL; + elfFdes = NULL; + elfFdeCount = 0; + } - if(elfFileData) { - free(elfFileData); - elfFileData = NULL; - } + ELFcie* cie = elfCies; + while (cie) { + ELFcie* next = cie->next; + free(cie); + cie = next; + } + elfCies = NULL; + + if (elfFileData) { + free(elfFileData); + elfFileData = NULL; + } } diff --git a/src/gba/elf.h b/src/gba/elf.h index 4fdab0aa..46636b7a 100644 --- a/src/gba/elf.h +++ b/src/gba/elf.h @@ -1,7 +1,9 @@ #ifndef ELF_H #define ELF_H -enum LocationType { LOCATION_register, LOCATION_memory, LOCATION_value }; +enum LocationType { LOCATION_register, + LOCATION_memory, + LOCATION_value }; #define DW_ATE_boolean 0x02 #define DW_ATE_signed 0x05 @@ -9,253 +11,253 @@ enum LocationType { LOCATION_register, LOCATION_memory, LOCATION_value }; #define DW_ATE_unsigned_char 0x08 struct ELFHeader { - u32 magic; - u8 clazz; - u8 data; - u8 version; - u8 pad[9]; - u16 e_type; - u16 e_machine; - u32 e_version; - u32 e_entry; - u32 e_phoff; - u32 e_shoff; - u32 e_flags; - u16 e_ehsize; - u16 e_phentsize; - u16 e_phnum; - u16 e_shentsize; - u16 e_shnum; - u16 e_shstrndx; + u32 magic; + u8 clazz; + u8 data; + u8 version; + u8 pad[9]; + u16 e_type; + u16 e_machine; + u32 e_version; + u32 e_entry; + u32 e_phoff; + u32 e_shoff; + u32 e_flags; + u16 e_ehsize; + u16 e_phentsize; + u16 e_phnum; + u16 e_shentsize; + u16 e_shnum; + u16 e_shstrndx; }; struct ELFProgramHeader { - u32 type; - u32 offset; - u32 vaddr; - u32 paddr; - u32 filesz; - u32 memsz; - u32 flags; - u32 align; + u32 type; + u32 offset; + u32 vaddr; + u32 paddr; + u32 filesz; + u32 memsz; + u32 flags; + u32 align; }; struct ELFSectionHeader { - u32 name; - u32 type; - u32 flags; - u32 addr; - u32 offset; - u32 size; - u32 link; - u32 info; - u32 addralign; - u32 entsize; + u32 name; + u32 type; + u32 flags; + u32 addr; + u32 offset; + u32 size; + u32 link; + u32 info; + u32 addralign; + u32 entsize; }; struct ELFSymbol { - u32 name; - u32 value; - u32 size; - u8 info; - u8 other; - u16 shndx; + u32 name; + u32 value; + u32 size; + u8 info; + u8 other; + u16 shndx; }; struct ELFBlock { - int length; - u8 *data; + int length; + u8* data; }; struct ELFAttr { - u32 name; - u32 form; - union { - u32 value; - char *string; - u8 *data; - bool flag; - ELFBlock *block; - }; + u32 name; + u32 form; + union { + u32 value; + char* string; + u8* data; + bool flag; + ELFBlock* block; + }; }; struct ELFAbbrev { - u32 number; - u32 tag; - bool hasChildren; - int numAttrs; - ELFAttr *attrs; - ELFAbbrev *next; + u32 number; + u32 tag; + bool hasChildren; + int numAttrs; + ELFAttr* attrs; + ELFAbbrev* next; }; enum TypeEnum { - TYPE_base, - TYPE_pointer, - TYPE_function, - TYPE_void, - TYPE_array, - TYPE_struct, - TYPE_reference, - TYPE_enum, - TYPE_union + TYPE_base, + TYPE_pointer, + TYPE_function, + TYPE_void, + TYPE_array, + TYPE_struct, + TYPE_reference, + TYPE_enum, + TYPE_union }; struct Type; struct Object; struct FunctionType { - Type *returnType; - Object *args; + Type* returnType; + Object* args; }; struct Member { - char *name; - Type *type; - int bitSize; - int bitOffset; - int byteSize; - ELFBlock *location; + char* name; + Type* type; + int bitSize; + int bitOffset; + int byteSize; + ELFBlock* location; }; struct Struct { - int memberCount; - Member *members; + int memberCount; + Member* members; }; struct Array { - Type *type; - int maxBounds; - int *bounds; + Type* type; + int maxBounds; + int* bounds; }; struct EnumMember { - char *name; - u32 value; + char* name; + u32 value; }; struct Enum { - int count; - EnumMember *members; + int count; + EnumMember* members; }; struct Type { - u32 offset; - TypeEnum type; - const char *name; - int encoding; - int size; - int bitSize; - union { - Type *pointer; - FunctionType *function; - Array *array; - Struct *structure; - Enum *enumeration; - }; - Type *next; + u32 offset; + TypeEnum type; + const char* name; + int encoding; + int size; + int bitSize; + union { + Type* pointer; + FunctionType* function; + Array* array; + Struct* structure; + Enum* enumeration; + }; + Type* next; }; struct Object { - char *name; - int file; - int line; - bool external; - Type *type; - ELFBlock *location; - u32 startScope; - u32 endScope; - Object *next; + char* name; + int file; + int line; + bool external; + Type* type; + ELFBlock* location; + u32 startScope; + u32 endScope; + Object* next; }; struct Function { - char *name; - u32 lowPC; - u32 highPC; - int file; - int line; - bool external; - Type *returnType; - Object *parameters; - Object *variables; - ELFBlock *frameBase; - Function *next; + char* name; + u32 lowPC; + u32 highPC; + int file; + int line; + bool external; + Type* returnType; + Object* parameters; + Object* variables; + ELFBlock* frameBase; + Function* next; }; struct LineInfoItem { - u32 address; - char *file; - int line; + u32 address; + char* file; + int line; }; struct LineInfo { - int fileCount; - char **files; - int number; - LineInfoItem *lines; + int fileCount; + char** files; + int number; + LineInfoItem* lines; }; struct ARange { - u32 lowPC; - u32 highPC; + u32 lowPC; + u32 highPC; }; struct ARanges { - u32 offset; - int count; - ARange *ranges; + u32 offset; + int count; + ARange* ranges; }; struct CompileUnit { - u32 length; - u8 *top; - u32 offset; - ELFAbbrev **abbrevs; - ARanges *ranges; - char *name; - char *compdir; - u32 lowPC; - u32 highPC; - bool hasLineInfo; - u32 lineInfo; - LineInfo *lineInfoTable; - Function *functions; - Function *lastFunction; - Object *variables; - Type *types; - CompileUnit *next; + u32 length; + u8* top; + u32 offset; + ELFAbbrev** abbrevs; + ARanges* ranges; + char* name; + char* compdir; + u32 lowPC; + u32 highPC; + bool hasLineInfo; + u32 lineInfo; + LineInfo* lineInfoTable; + Function* functions; + Function* lastFunction; + Object* variables; + Type* types; + CompileUnit* next; }; struct DebugInfo { - u8 *debugfile; - u8 *abbrevdata; - u8 *debugdata; - u8 *infodata; - int numRanges; - ARanges *ranges; + u8* debugfile; + u8* abbrevdata; + u8* debugdata; + u8* infodata; + int numRanges; + ARanges* ranges; }; struct Symbol { - const char *name; - int type; - int binding; - u32 address; - u32 value; - u32 size; + const char* name; + int type; + int binding; + u32 address; + u32 value; + u32 size; }; -extern u32 elfReadLEB128(u8 *, int *); -extern s32 elfReadSignedLEB128(u8 *, int *); -extern bool elfRead(const char *, int &, FILE *f); -extern bool elfGetSymbolAddress(const char *, u32 *, u32 *, int *); -extern const char *elfGetAddressSymbol(u32); -extern const char *elfGetSymbol(int, u32 *, u32 *, int *); +extern u32 elfReadLEB128(u8*, int*); +extern s32 elfReadSignedLEB128(u8*, int*); +extern bool elfRead(const char*, int&, FILE* f); +extern bool elfGetSymbolAddress(const char*, u32*, u32*, int*); +extern const char* elfGetAddressSymbol(u32); +extern const char* elfGetSymbol(int, u32*, u32*, int*); extern void elfCleanUp(); -extern bool elfGetCurrentFunction(u32, Function **, CompileUnit **c); -extern bool elfGetObject(const char *, Function *, CompileUnit *, Object **); -extern bool elfFindLineInUnit(u32 *, CompileUnit *, int); -extern bool elfFindLineInModule(u32 *, const char *, int); -u32 elfDecodeLocation(Function *, ELFBlock *, LocationType *); -u32 elfDecodeLocation(Function *, ELFBlock *, LocationType *, u32); -int elfFindLine(CompileUnit *unit, Function *func, u32 addr, const char **); +extern bool elfGetCurrentFunction(u32, Function**, CompileUnit** c); +extern bool elfGetObject(const char*, Function*, CompileUnit*, Object**); +extern bool elfFindLineInUnit(u32*, CompileUnit*, int); +extern bool elfFindLineInModule(u32*, const char*, int); +u32 elfDecodeLocation(Function*, ELFBlock*, LocationType*); +u32 elfDecodeLocation(Function*, ELFBlock*, LocationType*, u32); +int elfFindLine(CompileUnit* unit, Function* func, u32 addr, const char**); #endif // ELF_H diff --git a/src/gba/ereader.cpp b/src/gba/ereader.cpp index e9d07513..63b4fcf3 100644 --- a/src/gba/ereader.cpp +++ b/src/gba/ereader.cpp @@ -1,5 +1,5 @@ -#include #include +#include #include #include @@ -14,65 +14,63 @@ char JAP_Ereader_plus[19] = "CARDEREADER+PSAJ01"; char rom_info[19]; char Signature[0x29] = "E-Reader Dotcode -Created- by CaitSith2"; - unsigned char ShortDotCodeHeader[0x30] = { - 0x00, 0x30, 0x01, 0x01, - 0x00, 0x01, 0x05, 0x10, - 0x00, 0x00, 0x10, 0x12, //Constant data + 0x00, 0x30, 0x01, 0x01, + 0x00, 0x01, 0x05, 0x10, + 0x00, 0x00, 0x10, 0x12, //Constant data - 0x00, 0x00, //Header First 2 bytes + 0x00, 0x00, //Header First 2 bytes - 0x02, 0x00, //Constant data + 0x02, 0x00, //Constant data - 0x00, 0x00, //Header Second 2 bytes + 0x00, 0x00, //Header Second 2 bytes - 0x10, 0x47, 0xEF, //Global Checksum 1 + 0x10, 0x47, 0xEF, //Global Checksum 1 - 0x19, 0x00, 0x00, 0x00, 0x08, 0x4E, 0x49, - 0x4E, 0x54, 0x45, 0x4E, 0x44, 0x4F, 0x00, 0x22, - 0x00, 0x09, //Constant data + 0x19, 0x00, 0x00, 0x00, 0x08, 0x4E, 0x49, + 0x4E, 0x54, 0x45, 0x4E, 0x44, 0x4F, 0x00, 0x22, + 0x00, 0x09, //Constant data - 0x00, 0x00, //Header, last 8 bytes - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, - 0x00, //Header Checksum - 0x57 //Global Checksum 2 + 0x00, 0x00, //Header, last 8 bytes + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, + 0x00, //Header Checksum + 0x57 //Global Checksum 2 }; unsigned char LongDotCodeHeader[0x30] = { - 0x00, 0x30, 0x01, 0x02, - 0x00, 0x01, 0x08, 0x10, - 0x00, 0x00, 0x10, 0x12, //Constant Data + 0x00, 0x30, 0x01, 0x02, + 0x00, 0x01, 0x08, 0x10, + 0x00, 0x00, 0x10, 0x12, //Constant Data - 0x00, 0x00, //Header, first 2 bytes + 0x00, 0x00, //Header, first 2 bytes - 0x01, 0x00, //Constant data + 0x01, 0x00, //Constant data - 0x00, 0x00, //Header, second 2 bytes - 0x10, 0x9A, 0x99, //Global Checksum 1 + 0x00, 0x00, //Header, second 2 bytes + 0x10, 0x9A, 0x99, //Global Checksum 1 - 0x19, 0x00, 0x00, 0x00, 0x08, 0x4E, 0x49, - 0x4E, 0x54, 0x45, 0x4E, 0x44, 0x4F, 0x00, 0x22, - 0x00, 0x09, //Constant data + 0x19, 0x00, 0x00, 0x00, 0x08, 0x4E, 0x49, + 0x4E, 0x54, 0x45, 0x4E, 0x44, 0x4F, 0x00, 0x22, + 0x00, 0x09, //Constant data - - 0x00, 0x00, //Header, last 8 bytes - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, - 0x00, //Header Checksum - 0x57 //Global Checksum 2 + 0x00, 0x00, //Header, last 8 bytes + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, + 0x00, //Header Checksum + 0x57 //Global Checksum 2 }; unsigned char shortheader[0x18] = { - 0x00, 0x02, 0x00, 0x01, 0x40, 0x10, 0x00, 0x1C, - 0x10, 0x6F, 0x40, 0xDA, 0x39, 0x25, 0x8E, 0xE0, - 0x7B, 0xB5, 0x98, 0xB6, 0x5B, 0xCF, 0x7F, 0x72 + 0x00, 0x02, 0x00, 0x01, 0x40, 0x10, 0x00, 0x1C, + 0x10, 0x6F, 0x40, 0xDA, 0x39, 0x25, 0x8E, 0xE0, + 0x7B, 0xB5, 0x98, 0xB6, 0x5B, 0xCF, 0x7F, 0x72 }; unsigned char longheader[0x18] = { - 0x00, 0x03, 0x00, 0x19, 0x40, 0x10, 0x00, 0x2C, - 0x0E, 0x88, 0xED, 0x82, 0x50, 0x67, 0xFB, 0xD1, - 0x43, 0xEE, 0x03, 0xC6, 0xC6, 0x2B, 0x2C, 0x93 + 0x00, 0x03, 0x00, 0x19, 0x40, 0x10, 0x00, 0x2C, + 0x0E, 0x88, 0xED, 0x82, 0x50, 0x67, 0xFB, 0xD1, + 0x43, 0xEE, 0x03, 0xC6, 0xC6, 0x2B, 0x2C, 0x93 }; unsigned char dotcodeheader[0x48]; @@ -84,7 +82,7 @@ int decodestate; u32 GFpow; -unsigned char *DotCodeData; +unsigned char* DotCodeData; char filebuffer[2048]; int dotcodesize; @@ -95,580 +93,497 @@ int dotcodesize; int CheckEReaderRegion(void) //US = 1, JAP = 2, JAP+ = 3 { - int i; - for(i=0;i<18;i++) - rom_info[i] = rom[0xA0+i]; - rom_info[i] = 0; + int i; + for (i = 0; i < 18; i++) + rom_info[i] = rom[0xA0 + i]; + rom_info[i] = 0; - if (!strcasecmp(rom_info, US_Ereader)) - return 1; - if (!strcasecmp(rom_info, JAP_Ereader)) - return 2; - if (!strcasecmp(rom_info, JAP_Ereader_plus)) - return 3; - - return 0; + if (!strcasecmp(rom_info, US_Ereader)) + return 1; + if (!strcasecmp(rom_info, JAP_Ereader)) + return 2; + if (!strcasecmp(rom_info, JAP_Ereader_plus)) + return 3; + + return 0; } int LoadDotCodeData(int size, u32* DCdata, unsigned long MEM1, unsigned long MEM2, int loadraw) { - u32 temp1; - int i,j; + u32 temp1; + int i, j; - unsigned char scanmap[28]; - int scantotal=0; + unsigned char scanmap[28]; + int scantotal = 0; - for(i=0;i<28;i++) - scanmap[i] = 0; + for (i = 0; i < 28; i++) + scanmap[i] = 0; - unsigned char longdotcodescan[28] = { - 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, - 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, - 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, - 0xF1, 0xF2, 0xB1, 0xB1 - }; - unsigned char shortdotcodescan[18] = { - 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, - 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, - 0xF1, 0xF1, 0xF1, 0xF2, 0xB1, 0xB1 - }; + unsigned char longdotcodescan[28] = { + 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, + 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, + 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, + 0xF1, 0xF2, 0xB1, 0xB1 + }; + unsigned char shortdotcodescan[18] = { + 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, + 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, + 0xF1, 0xF1, 0xF1, 0xF2, 0xB1, 0xB1 + }; - temp1 = CPUReadMemory(MEM1-4); - for(i=0;i<0x60;i+=4) - CPUWriteMemory((MEM2-8)+i,0); - for(i=0;i<0x1860;i+=4) - CPUWriteMemory(temp1+i,0); - if(DCdata != NULL) - { - if(size==0xB60) - { - for(i=0;i<28;i++) - { - for(j=0,scantotal=0;j<0x68;j+=4) - { - scantotal += DCdata[((i*0x68)+j)>>2]; - } - if(scantotal) - scanmap[i] = longdotcodescan[i]; - } - for(i=0;i>2]); - } - } - else if (size==0x750) - { - for(i=0;i<18;i++) - { - if((DCdata[0] == 0x02011394) && (DCdata[1] == 0x0203E110) && (i == 0)) - continue; - for(j=0,scantotal=0;j<0x68;j+=4) - { - scantotal += DCdata[((i*0x68)+j)>>2]; - } - if(scantotal) - scanmap[i] = longdotcodescan[i]; - } - for(i=0;i>2]); - } - } - } - CPUWriteMemory(MEM2-8,0x1860); - CPUWriteMemory(MEM2-4,temp1); + temp1 = CPUReadMemory(MEM1 - 4); + for (i = 0; i < 0x60; i += 4) + CPUWriteMemory((MEM2 - 8) + i, 0); + for (i = 0; i < 0x1860; i += 4) + CPUWriteMemory(temp1 + i, 0); + if (DCdata != NULL) { + if (size == 0xB60) { + for (i = 0; i < 28; i++) { + for (j = 0, scantotal = 0; j < 0x68; j += 4) { + scantotal += DCdata[((i * 0x68) + j) >> 2]; + } + if (scantotal) + scanmap[i] = longdotcodescan[i]; + } + for (i = 0; i < size; i += 4) { + CPUWriteMemory(temp1 + i + 0x9C0, DCdata[i >> 2]); + } + } else if (size == 0x750) { + for (i = 0; i < 18; i++) { + if ((DCdata[0] == 0x02011394) && (DCdata[1] == 0x0203E110) && (i == 0)) + continue; + for (j = 0, scantotal = 0; j < 0x68; j += 4) { + scantotal += DCdata[((i * 0x68) + j) >> 2]; + } + if (scantotal) + scanmap[i] = longdotcodescan[i]; + } + for (i = 0; i < size; i += 4) { + CPUWriteMemory(temp1 + i, DCdata[i >> 2]); + } + } + } + CPUWriteMemory(MEM2 - 8, 0x1860); + CPUWriteMemory(MEM2 - 4, temp1); + if (size == 0xB60) { + if (loadraw) { + for (i = 0; i < 28; i++) + CPUWriteByte(MEM2 + 0x18 + i, scanmap[i]); + } else { + CPUWriteMemory(MEM2 + 0x18, 0xF1F1F1F1); + CPUWriteMemory(MEM2 + 0x18 + 4, 0xF1F1F1F1); + CPUWriteMemory(MEM2 + 0x18 + 8, 0xF1F1F1F1); + CPUWriteMemory(MEM2 + 0x18 + 12, 0xF1F1F1F1); + CPUWriteMemory(MEM2 + 0x18 + 16, 0xF1F1F1F1); + CPUWriteMemory(MEM2 + 0x18 + 20, 0xF1F1F1F1); + CPUWriteMemory(MEM2 + 0x18 + 24, 0xB1B1F2F1); + } + CPUWriteMemory(MEM2 + 0x40, 0x19); + CPUWriteMemory(MEM2 + 0x44, 0x34); + } else if (size == 0x750) { + if (loadraw) { + for (i = 0; i < 18; i++) + CPUWriteByte(MEM2 + i, scanmap[i]); + } else { + CPUWriteMemory(MEM2, 0xF1F1F1F1); + CPUWriteMemory(MEM2 + 4, 0xF1F1F1F1); + CPUWriteMemory(MEM2 + 8, 0xF1F1F1F1); + CPUWriteMemory(MEM2 + 12, 0xF2F1F1F1); + CPUWriteMemory(MEM2 + 16, 0xB1B1); + } + CPUWriteMemory(MEM2 + 0x40, 0x01); + CPUWriteMemory(MEM2 + 0x44, 0x12); + } + CPUWriteMemory(MEM2 + 0x48, 0x3C); + CPUWriteMemory(MEM2 + 0x4C, MEM2); - if(size==0xB60) - { - if(loadraw) - { - for(i=0;i<28;i++) - CPUWriteByte(MEM2+0x18+i,scanmap[i]); - } - else - { - CPUWriteMemory(MEM2+0x18,0xF1F1F1F1); - CPUWriteMemory(MEM2+0x18+4,0xF1F1F1F1); - CPUWriteMemory(MEM2+0x18+8,0xF1F1F1F1); - CPUWriteMemory(MEM2+0x18+12,0xF1F1F1F1); - CPUWriteMemory(MEM2+0x18+16,0xF1F1F1F1); - CPUWriteMemory(MEM2+0x18+20,0xF1F1F1F1); - CPUWriteMemory(MEM2+0x18+24,0xB1B1F2F1); - } - CPUWriteMemory(MEM2+0x40,0x19); - CPUWriteMemory(MEM2+0x44,0x34); - } - else if (size==0x750) - { - if(loadraw) - { - for(i=0;i<18;i++) - CPUWriteByte(MEM2+i,scanmap[i]); - } - else - { - CPUWriteMemory(MEM2,0xF1F1F1F1); - CPUWriteMemory(MEM2+4,0xF1F1F1F1); - CPUWriteMemory(MEM2+8,0xF1F1F1F1); - CPUWriteMemory(MEM2+12,0xF2F1F1F1); - CPUWriteMemory(MEM2+16,0xB1B1); - } - CPUWriteMemory(MEM2+0x40,0x01); - CPUWriteMemory(MEM2+0x44,0x12); - } - CPUWriteMemory(MEM2+0x48,0x3C); - CPUWriteMemory(MEM2+0x4C,MEM2); - - return 0; + return 0; } void EReaderWriteMemory(u32 address, u32 value) { - switch(address >> 24) - { - case 2: - WRITE32LE(((u32 *)&workRAM[address & 0x3FFFF]), value); - break; - case 3: - WRITE32LE(((u32 *)&internalRAM[address & 0x7FFF]), value); - break; - default: - WRITE32LE(((u32 *)&rom[address & 0x1FFFFFF]), value); - //rom[address & 0x1FFFFFF] = data; - break; - } + switch (address >> 24) { + case 2: + WRITE32LE(((u32*)&workRAM[address & 0x3FFFF]), value); + break; + case 3: + WRITE32LE(((u32*)&internalRAM[address & 0x7FFF]), value); + break; + default: + WRITE32LE(((u32*)&rom[address & 0x1FFFFFF]), value); + //rom[address & 0x1FFFFFF] = data; + break; + } } - void BIOS_EReader_ScanCard(int swi_num) { - - int i,j,k; - int dotcodetype; - int global1, global2; + int i, j, k; + int dotcodetype; - FILE *f; + int global1, global2; - //Open dotcode bin/raw + FILE* f; - if(swi_num == 0xE0) - { - dotcodepointer = 0; - dotcodeinterleave = 0; - decodestate = 0; + //Open dotcode bin/raw - const char* loadDotCodeFile = GetLoadDotCodeFile(); + if (swi_num == 0xE0) { + dotcodepointer = 0; + dotcodeinterleave = 0; + decodestate = 0; - if (loadDotCodeFile == 0) - { - reg[0].I = 0x301; - return; - } - f=fopen(loadDotCodeFile,"rb"); - //f=fopen(filebuffer,"rb"); - //f=fopen("dotcode4.raw","rb"); - if(f==NULL) - { - reg[0].I = 0x303; - return; - } - fseek(f,0,SEEK_END); - i=ftell(f); - fseek(f,0,SEEK_SET); - if((i==0xB60) || (i==0x750)) - { - dotcodetype = 0; - } - else if ((i==0x81C) || (i==0x51C)) - { - dotcodetype = 1; - } - else - { - fclose(f); - reg[0].I = 0x303; - return; - } - DotCodeData = (unsigned char*)malloc(i); - if(DotCodeData == NULL) - { - reg[0].I = 0x303; - return; - } - fread(DotCodeData,1,i,f); - fclose(f); + const char* loadDotCodeFile = GetLoadDotCodeFile(); - if(dotcodetype == 0) - { + if (loadDotCodeFile == 0) { + reg[0].I = 0x301; + return; + } + f = fopen(loadDotCodeFile, "rb"); + //f=fopen(filebuffer,"rb"); + //f=fopen("dotcode4.raw","rb"); + if (f == NULL) { + reg[0].I = 0x303; + return; + } + fseek(f, 0, SEEK_END); + i = ftell(f); + fseek(f, 0, SEEK_SET); + if ((i == 0xB60) || (i == 0x750)) { + dotcodetype = 0; + } else if ((i == 0x81C) || (i == 0x51C)) { + dotcodetype = 1; + } else { + fclose(f); + reg[0].I = 0x303; + return; + } + DotCodeData = (unsigned char*)malloc(i); + if (DotCodeData == NULL) { + reg[0].I = 0x303; + return; + } + fread(DotCodeData, 1, i, f); + fclose(f); - switch(CheckEReaderRegion()) - { - case 1: //US - LoadDotCodeData(i,(u32 *)DotCodeData,0x2032D14,0x2028B28,1); - EReaderWriteMemory(0x80091BA,0x46C0DFE2); - break; - case 2: - LoadDotCodeData(i,(u32 *)DotCodeData,0x2006EC4,0x2002478,1); - EReaderWriteMemory(0x8008B12,0x46C0DFE2); - break; - case 3: - LoadDotCodeData(i,(u32 *)DotCodeData,0x202F8A4,0x2031034,1); - EReaderWriteMemory(0x800922E,0x46C0DFE2); - break; - } - reg[0].I = 0; - free(DotCodeData); - } - else - { - //dotcodesize = i; - if(i==0x81C) - dotcodesize = 0xB60; - else - dotcodesize = 0x750; + if (dotcodetype == 0) { + switch (CheckEReaderRegion()) { + case 1: //US + LoadDotCodeData(i, (u32*)DotCodeData, 0x2032D14, 0x2028B28, 1); + EReaderWriteMemory(0x80091BA, 0x46C0DFE2); + break; + case 2: + LoadDotCodeData(i, (u32*)DotCodeData, 0x2006EC4, 0x2002478, 1); + EReaderWriteMemory(0x8008B12, 0x46C0DFE2); + break; + case 3: + LoadDotCodeData(i, (u32*)DotCodeData, 0x202F8A4, 0x2031034, 1); + EReaderWriteMemory(0x800922E, 0x46C0DFE2); + break; + } + reg[0].I = 0; + free(DotCodeData); + } else { + //dotcodesize = i; + if (i == 0x81C) + dotcodesize = 0xB60; + else + dotcodesize = 0x750; - switch(CheckEReaderRegion()) - { - case 1: //US - LoadDotCodeData(dotcodesize,(u32 *)NULL,0x2032D14,0x2028B28,0); - EReaderWriteMemory(0x80091BA,0x46C0DFE1); - break; - case 2: - LoadDotCodeData(dotcodesize,(u32 *)NULL,0x2006EC4,0x2002478,0); - EReaderWriteMemory(0x8008B12,0x46C0DFE1); - break; - case 3: - LoadDotCodeData(dotcodesize,(u32 *)NULL,0x202F8A4,0x2031034,0); - EReaderWriteMemory(0x800922E,0x46C0DFE1); - break; - } - reg[0].I = 0; - dotcodesize = i; - } - } - else if (swi_num == 0xE1) - { - - switch(CheckEReaderRegion()) - { - case 1: //US - EReaderWriteMemory(0x80091BA,0xF8A5F03B); - EReaderWriteMemory(0x3002F7C,0xEFE40000); //Beginning of Reed-Solomon decoder - EReaderWriteMemory(0x3003144,0xCA00002F); //Fix required to Correct 16 "Erasures" - EReaderWriteMemory(0x300338C,0xEFE50000); //End of Reed-Solomon decoder - GFpow = 0x3000A6C; - break; - case 2: - EReaderWriteMemory(0x8008B12,0xFB0BF035); - EReaderWriteMemory(0x3002F88,0xEFE40000); - EReaderWriteMemory(0x3003150,0xCA00002F); - EReaderWriteMemory(0x3003398,0xEFE50000); - GFpow = 0x3000A78; - break; - case 3: - EReaderWriteMemory(0x800922E,0xF94BF04B); - EReaderWriteMemory(0x3002F7C,0xEFE40000); - EReaderWriteMemory(0x3003144,0xCA00002F); - EReaderWriteMemory(0x300338C,0xEFE50000); - GFpow = 0x3000A6C; - break; - } + switch (CheckEReaderRegion()) { + case 1: //US + LoadDotCodeData(dotcodesize, (u32*)NULL, 0x2032D14, 0x2028B28, 0); + EReaderWriteMemory(0x80091BA, 0x46C0DFE1); + break; + case 2: + LoadDotCodeData(dotcodesize, (u32*)NULL, 0x2006EC4, 0x2002478, 0); + EReaderWriteMemory(0x8008B12, 0x46C0DFE1); + break; + case 3: + LoadDotCodeData(dotcodesize, (u32*)NULL, 0x202F8A4, 0x2031034, 0); + EReaderWriteMemory(0x800922E, 0x46C0DFE1); + break; + } + reg[0].I = 0; + dotcodesize = i; + } + } else if (swi_num == 0xE1) { - armNextPC -= 2; - reg[15].I -= 2; - if (armState) - ARM_PREFETCH - else - THUMB_PREFETCH + switch (CheckEReaderRegion()) { + case 1: //US + EReaderWriteMemory(0x80091BA, 0xF8A5F03B); + EReaderWriteMemory(0x3002F7C, 0xEFE40000); //Beginning of Reed-Solomon decoder + EReaderWriteMemory(0x3003144, 0xCA00002F); //Fix required to Correct 16 "Erasures" + EReaderWriteMemory(0x300338C, 0xEFE50000); //End of Reed-Solomon decoder + GFpow = 0x3000A6C; + break; + case 2: + EReaderWriteMemory(0x8008B12, 0xFB0BF035); + EReaderWriteMemory(0x3002F88, 0xEFE40000); + EReaderWriteMemory(0x3003150, 0xCA00002F); + EReaderWriteMemory(0x3003398, 0xEFE50000); + GFpow = 0x3000A78; + break; + case 3: + EReaderWriteMemory(0x800922E, 0xF94BF04B); + EReaderWriteMemory(0x3002F7C, 0xEFE40000); + EReaderWriteMemory(0x3003144, 0xCA00002F); + EReaderWriteMemory(0x300338C, 0xEFE50000); + GFpow = 0x3000A6C; + break; + } - for(i=0,j=0;i<12;i++) - j ^= DotCodeData[i]; - if(dotcodesize == 0x81C) - { - LongDotCodeHeader[0x2E] = j; - LongDotCodeHeader[0x0D] = DotCodeData[0]; - LongDotCodeHeader[0x0C] = DotCodeData[1]; - LongDotCodeHeader[0x11] = DotCodeData[2]; - LongDotCodeHeader[0x10] = DotCodeData[3]; + armNextPC -= 2; + reg[15].I -= 2; + if (armState) + ARM_PREFETCH + else + THUMB_PREFETCH - LongDotCodeHeader[0x26] = DotCodeData[4]; - LongDotCodeHeader[0x27] = DotCodeData[5]; - LongDotCodeHeader[0x28] = DotCodeData[6]; - LongDotCodeHeader[0x29] = DotCodeData[7]; - LongDotCodeHeader[0x2A] = DotCodeData[8]; - LongDotCodeHeader[0x2B] = DotCodeData[9]; - LongDotCodeHeader[0x2C] = DotCodeData[10]; - LongDotCodeHeader[0x2D] = DotCodeData[11]; + for (i = 0, j = 0; i < 12; i++) + j ^= DotCodeData[i]; + if (dotcodesize == 0x81C) { + LongDotCodeHeader[0x2E] = j; + LongDotCodeHeader[0x0D] = DotCodeData[0]; + LongDotCodeHeader[0x0C] = DotCodeData[1]; + LongDotCodeHeader[0x11] = DotCodeData[2]; + LongDotCodeHeader[0x10] = DotCodeData[3]; - - LongDotCodeHeader[0x12] = 0x10; //calculate Global Checksum 1 - LongDotCodeHeader[0x02] = 1; //Do not calculate Global Checksum 2 + LongDotCodeHeader[0x26] = DotCodeData[4]; + LongDotCodeHeader[0x27] = DotCodeData[5]; + LongDotCodeHeader[0x28] = DotCodeData[6]; + LongDotCodeHeader[0x29] = DotCodeData[7]; + LongDotCodeHeader[0x2A] = DotCodeData[8]; + LongDotCodeHeader[0x2B] = DotCodeData[9]; + LongDotCodeHeader[0x2C] = DotCodeData[10]; + LongDotCodeHeader[0x2D] = DotCodeData[11]; - for(i=0x0C,j=0;i<0x81C;i++) - { - if(i&1) - j += DotCodeData[i]; - else - j += (DotCodeData[i] << 8); - } - j &= 0xFFFF; - j ^= 0xFFFF; - LongDotCodeHeader[0x13] = (j & 0xFF00) >> 8; - LongDotCodeHeader[0x14] = (j & 0x00FF); + LongDotCodeHeader[0x12] = 0x10; //calculate Global Checksum 1 + LongDotCodeHeader[0x02] = 1; //Do not calculate Global Checksum 2 - for(i=0,j=0;i<0x2F;i++) - j+=LongDotCodeHeader[i]; - j &= 0xFF; - for(i=1,global2=0;i<0x2C;i++) - { - for(k=0,global1=0;k<0x30;k++) - { - global1 ^= DotCodeData[((i-1)*0x30)+k+0x0C]; - } - global2 += global1; - } - global2 += j; - global2 &= 0xFF; - global2 ^= 0xFF; - LongDotCodeHeader[0x2F] = global2; + for (i = 0x0C, j = 0; i < 0x81C; i++) { + if (i & 1) + j += DotCodeData[i]; + else + j += (DotCodeData[i] << 8); + } + j &= 0xFFFF; + j ^= 0xFFFF; + LongDotCodeHeader[0x13] = (j & 0xFF00) >> 8; + LongDotCodeHeader[0x14] = (j & 0x00FF); + for (i = 0, j = 0; i < 0x2F; i++) + j += LongDotCodeHeader[i]; + j &= 0xFF; + for (i = 1, global2 = 0; i < 0x2C; i++) { + for (k = 0, global1 = 0; k < 0x30; k++) { + global1 ^= DotCodeData[((i - 1) * 0x30) + k + 0x0C]; + } + global2 += global1; + } + global2 += j; + global2 &= 0xFF; + global2 ^= 0xFF; + LongDotCodeHeader[0x2F] = global2; - } - else - { - ShortDotCodeHeader[0x2E] = j; - ShortDotCodeHeader[0x0D] = DotCodeData[0]; - ShortDotCodeHeader[0x0C] = DotCodeData[1]; - ShortDotCodeHeader[0x11] = DotCodeData[2]; - ShortDotCodeHeader[0x10] = DotCodeData[3]; + } else { + ShortDotCodeHeader[0x2E] = j; + ShortDotCodeHeader[0x0D] = DotCodeData[0]; + ShortDotCodeHeader[0x0C] = DotCodeData[1]; + ShortDotCodeHeader[0x11] = DotCodeData[2]; + ShortDotCodeHeader[0x10] = DotCodeData[3]; - ShortDotCodeHeader[0x26] = DotCodeData[4]; - ShortDotCodeHeader[0x27] = DotCodeData[5]; - ShortDotCodeHeader[0x28] = DotCodeData[6]; - ShortDotCodeHeader[0x29] = DotCodeData[7]; - ShortDotCodeHeader[0x2A] = DotCodeData[8]; - ShortDotCodeHeader[0x2B] = DotCodeData[9]; - ShortDotCodeHeader[0x2C] = DotCodeData[10]; - ShortDotCodeHeader[0x2D] = DotCodeData[11]; + ShortDotCodeHeader[0x26] = DotCodeData[4]; + ShortDotCodeHeader[0x27] = DotCodeData[5]; + ShortDotCodeHeader[0x28] = DotCodeData[6]; + ShortDotCodeHeader[0x29] = DotCodeData[7]; + ShortDotCodeHeader[0x2A] = DotCodeData[8]; + ShortDotCodeHeader[0x2B] = DotCodeData[9]; + ShortDotCodeHeader[0x2C] = DotCodeData[10]; + ShortDotCodeHeader[0x2D] = DotCodeData[11]; - ShortDotCodeHeader[0x12] = 0x10; //calculate Global Checksum 1 - ShortDotCodeHeader[0x02] = 1; //Do not calculate Global Checksum 2 + ShortDotCodeHeader[0x12] = 0x10; //calculate Global Checksum 1 + ShortDotCodeHeader[0x02] = 1; //Do not calculate Global Checksum 2 - for(i=0x0C,j=0;i<0x51C;i++) - { - if(i&1) - j += DotCodeData[i]; - else - j += (DotCodeData[i] << 8); - } - j &= 0xFFFF; - j ^= 0xFFFF; - ShortDotCodeHeader[0x13] = (j & 0xFF00) >> 8; - ShortDotCodeHeader[0x14] = (j & 0x00FF); + for (i = 0x0C, j = 0; i < 0x51C; i++) { + if (i & 1) + j += DotCodeData[i]; + else + j += (DotCodeData[i] << 8); + } + j &= 0xFFFF; + j ^= 0xFFFF; + ShortDotCodeHeader[0x13] = (j & 0xFF00) >> 8; + ShortDotCodeHeader[0x14] = (j & 0x00FF); - for(i=0,j=0;i<0x2F;i++) - j+=ShortDotCodeHeader[i]; - j &= 0xFF; - for(i=1,global2=0;i<0x1C;i++) - { - for(k=0,global1=0;k<0x30;k++) - { - global1 ^= DotCodeData[((i-1)*0x30)+k+0x0C]; - } - global2 += global1; - } - global2 += j; - global2 &= 0xFF; - global2 ^= 0xFF; - ShortDotCodeHeader[0x2F] = global2; - } + for (i = 0, j = 0; i < 0x2F; i++) + j += ShortDotCodeHeader[i]; + j &= 0xFF; + for (i = 1, global2 = 0; i < 0x1C; i++) { + for (k = 0, global1 = 0; k < 0x30; k++) { + global1 ^= DotCodeData[((i - 1) * 0x30) + k + 0x0C]; + } + global2 += global1; + } + global2 += j; + global2 &= 0xFF; + global2 ^= 0xFF; + ShortDotCodeHeader[0x2F] = global2; + } - } - else if (swi_num == 0xE2) //Header - { - switch(CheckEReaderRegion()) - { - case 1: //US - EReaderWriteMemory(0x80091BA,0xF8A5F03B); - EReaderWriteMemory(0x300338C,0xEFE30000); - GFpow = 0x3000A6C; - break; - case 2: - EReaderWriteMemory(0x8008B12,0xFB0BF035); - EReaderWriteMemory(0x3003398,0xEFE30000); - GFpow = 0x3000A78; - break; - case 3: - EReaderWriteMemory(0x800922E,0xF94BF04B); - EReaderWriteMemory(0x300338C,0xEFE30000); - GFpow = 0x3000A6C; - break; - } - armNextPC -= 2; - reg[15].I -= 2; - if (armState) - ARM_PREFETCH - else - THUMB_PREFETCH - } - else if ((swi_num == 0xE3) || (swi_num == 0xE5)) //Dotcode data - { - if((reg[0].I >= 0) && (reg[0].I <= 0x10)) - { - if(decodestate == 0) - { - for(i=0x17;i>=0;i--) - { - if((0x17 - i) < 8) - j=CPUReadByte(GFpow + CPUReadByte(GFpow+0x200+i)); - else - j=CPUReadByte(GFpow + CPUReadByte(GFpow+0x200+i)) ^ 0xFF; + } else if (swi_num == 0xE2) //Header + { + switch (CheckEReaderRegion()) { + case 1: //US + EReaderWriteMemory(0x80091BA, 0xF8A5F03B); + EReaderWriteMemory(0x300338C, 0xEFE30000); + GFpow = 0x3000A6C; + break; + case 2: + EReaderWriteMemory(0x8008B12, 0xFB0BF035); + EReaderWriteMemory(0x3003398, 0xEFE30000); + GFpow = 0x3000A78; + break; + case 3: + EReaderWriteMemory(0x800922E, 0xF94BF04B); + EReaderWriteMemory(0x300338C, 0xEFE30000); + GFpow = 0x3000A6C; + break; + } + armNextPC -= 2; + reg[15].I -= 2; + if (armState) + ARM_PREFETCH + else + THUMB_PREFETCH + } else if ((swi_num == 0xE3) || (swi_num == 0xE5)) //Dotcode data + { + if ((reg[0].I >= 0) && (reg[0].I <= 0x10)) { + if (decodestate == 0) { + for (i = 0x17; i >= 0; i--) { + if ((0x17 - i) < 8) + j = CPUReadByte(GFpow + CPUReadByte(GFpow + 0x200 + i)); + else + j = CPUReadByte(GFpow + CPUReadByte(GFpow + 0x200 + i)) ^ 0xFF; - dotcodeheader[(0x17-i)] = j; - dotcodeheader[(0x17-i)+0x18] = j; - dotcodeheader[(0x17-i)+0x30] = j; - } - for(i=0;i<28;i++) - for(j=0;j<2;j++) - dotcodedata[(i*0x68)+j] = dotcodeheader[(i*2)+j]; - dotcodeinterleave = dotcodeheader[7]; - decodestate = 1; - } - else - { - for(i=0x3F;i>=0;i--) - { - if((0x3F - i) < 0x30) - j=CPUReadByte(GFpow + CPUReadByte(GFpow+0x200+i)); - else - j=CPUReadByte(GFpow + CPUReadByte(GFpow+0x200+i)) ^ 0xFF; - dotcodetemp[((0x3F-i)*dotcodeinterleave)+dotcodepointer] = j; - } - dotcodepointer++; + dotcodeheader[(0x17 - i)] = j; + dotcodeheader[(0x17 - i) + 0x18] = j; + dotcodeheader[(0x17 - i) + 0x30] = j; + } + for (i = 0; i < 28; i++) + for (j = 0; j < 2; j++) + dotcodedata[(i * 0x68) + j] = dotcodeheader[(i * 2) + j]; + dotcodeinterleave = dotcodeheader[7]; + decodestate = 1; + } else { + for (i = 0x3F; i >= 0; i--) { + if ((0x3F - i) < 0x30) + j = CPUReadByte(GFpow + CPUReadByte(GFpow + 0x200 + i)); + else + j = CPUReadByte(GFpow + CPUReadByte(GFpow + 0x200 + i)) ^ 0xFF; + dotcodetemp[((0x3F - i) * dotcodeinterleave) + dotcodepointer] = j; + } + dotcodepointer++; - if((dotcodepointer == dotcodeinterleave)) - { - switch(dotcodeinterleave) - { - case 0x1C: - j = 0x724; - k = 0x750 - j; - break; - case 0x2C: - j = 0xB38; - k = 0xB60 - j; - break; - } - dotcodepointer = 0; - for(i=2;i> systemGreenShift) & 0x1f]; - temp[3] = s * influence[3]; - temp[4] = s * influence[4]; - temp[5] = s * influence[5]; + s = curve[(pix >> systemGreenShift) & 0x1f]; + temp[3] = s * influence[3]; + temp[4] = s * influence[4]; + temp[5] = s * influence[5]; - s = curve[(pix >> systemRedShift) & 0x1f]; - temp[0] = s * influence[0]; - temp[1] = s * influence[1]; - temp[2] = s * influence[2]; + s = curve[(pix >> systemRedShift) & 0x1f]; + temp[0] = s * influence[0]; + temp[1] = s * influence[1]; + temp[2] = s * influence[2]; - s = curve[(pix >> systemBlueShift) & 0x1f]; - temp[6] = s * influence[6]; - temp[7] = s * influence[7]; - temp[8] = s * influence[8]; + s = curve[(pix >> systemBlueShift) & 0x1f]; + temp[6] = s * influence[6]; + temp[7] = s * influence[7]; + temp[8] = s * influence[8]; - if (temp[0] < temp[3]) swap(temp[0], temp[3]); - if (temp[0] < temp[6]) swap(temp[0], temp[6]); - if (temp[3] < temp[6]) swap(temp[3], temp[6]); - temp[3] <<= 1; - temp[0] <<= 2; - temp[0] += temp[3] + temp[6]; + if (temp[0] < temp[3]) + swap(temp[0], temp[3]); + if (temp[0] < temp[6]) + swap(temp[0], temp[6]); + if (temp[3] < temp[6]) + swap(temp[3], temp[6]); + temp[3] <<= 1; + temp[0] <<= 2; + temp[0] += temp[3] + temp[6]; - red = ((int(temp[0]) * 160) >> 17) + 4; - if (red > 31) red = 31; + red = ((int(temp[0]) * 160) >> 17) + 4; + if (red > 31) + red = 31; - if (temp[2] < temp[5]) swap(temp[2], temp[5]); - if (temp[2] < temp[8]) swap(temp[2], temp[8]); - if (temp[5] < temp[8]) swap(temp[5], temp[8]); - temp[5] <<= 1; - temp[2] <<= 2; - temp[2] += temp[5] + temp[8]; + if (temp[2] < temp[5]) + swap(temp[2], temp[5]); + if (temp[2] < temp[8]) + swap(temp[2], temp[8]); + if (temp[5] < temp[8]) + swap(temp[5], temp[8]); + temp[5] <<= 1; + temp[2] <<= 2; + temp[2] += temp[5] + temp[8]; - blue = ((int(temp[2]) * 160) >> 17) + 4; - if (blue > 31) blue = 31; + blue = ((int(temp[2]) * 160) >> 17) + 4; + if (blue > 31) + blue = 31; - if (temp[1] < temp[4]) swap(temp[1], temp[4]); - if (temp[1] < temp[7]) swap(temp[1], temp[7]); - if (temp[4] < temp[7]) swap(temp[4], temp[7]); - temp[4] <<= 1; - temp[1] <<= 2; - temp[1] += temp[4] + temp[7]; + if (temp[1] < temp[4]) + swap(temp[1], temp[4]); + if (temp[1] < temp[7]) + swap(temp[1], temp[7]); + if (temp[4] < temp[7]) + swap(temp[4], temp[7]); + temp[4] <<= 1; + temp[1] <<= 2; + temp[1] += temp[4] + temp[7]; - green = ((int(temp[1]) * 160) >> 17) + 4; - if (green > 31) green = 31; + green = ((int(temp[1]) * 160) >> 17) + 4; + if (green > 31) + green = 31; - pix = red << systemRedShift; - pix += green << systemGreenShift; - pix += blue << systemBlueShift; + pix = red << systemRedShift; + pix += green << systemGreenShift; + pix += blue << systemBlueShift; - *buf++ = pix; - } + *buf++ = pix; + } } -void gbafilter_pal32(u32 * buf, int count) +void gbafilter_pal32(u32* buf, int count) { - short temp[3 * 3], s; - unsigned pix; - u8 red, green, blue; + short temp[3 * 3], s; + unsigned pix; + u8 red, green, blue; - while (count--) - { - pix = *buf; + while (count--) { + pix = *buf; - s = curve[(pix >> systemGreenShift) & 0x1f]; - temp[3] = s * influence[3]; - temp[4] = s * influence[4]; - temp[5] = s * influence[5]; + s = curve[(pix >> systemGreenShift) & 0x1f]; + temp[3] = s * influence[3]; + temp[4] = s * influence[4]; + temp[5] = s * influence[5]; - s = curve[(pix >> systemRedShift) & 0x1f]; - temp[0] = s * influence[0]; - temp[1] = s * influence[1]; - temp[2] = s * influence[2]; + s = curve[(pix >> systemRedShift) & 0x1f]; + temp[0] = s * influence[0]; + temp[1] = s * influence[1]; + temp[2] = s * influence[2]; - s = curve[(pix >> systemBlueShift) & 0x1f]; - temp[6] = s * influence[6]; - temp[7] = s * influence[7]; - temp[8] = s * influence[8]; + s = curve[(pix >> systemBlueShift) & 0x1f]; + temp[6] = s * influence[6]; + temp[7] = s * influence[7]; + temp[8] = s * influence[8]; - if (temp[0] < temp[3]) swap(temp[0], temp[3]); - if (temp[0] < temp[6]) swap(temp[0], temp[6]); - if (temp[3] < temp[6]) swap(temp[3], temp[6]); - temp[3] <<= 1; - temp[0] <<= 2; - temp[0] += temp[3] + temp[6]; + if (temp[0] < temp[3]) + swap(temp[0], temp[3]); + if (temp[0] < temp[6]) + swap(temp[0], temp[6]); + if (temp[3] < temp[6]) + swap(temp[3], temp[6]); + temp[3] <<= 1; + temp[0] <<= 2; + temp[0] += temp[3] + temp[6]; - //red = ((int(temp[0]) * 160) >> 17) + 4; - red = ((int(temp[0]) * 160) >> 14) + 32; + //red = ((int(temp[0]) * 160) >> 17) + 4; + red = ((int(temp[0]) * 160) >> 14) + 32; - if (temp[2] < temp[5]) swap(temp[2], temp[5]); - if (temp[2] < temp[8]) swap(temp[2], temp[8]); - if (temp[5] < temp[8]) swap(temp[5], temp[8]); - temp[5] <<= 1; - temp[2] <<= 2; - temp[2] += temp[5] + temp[8]; + if (temp[2] < temp[5]) + swap(temp[2], temp[5]); + if (temp[2] < temp[8]) + swap(temp[2], temp[8]); + if (temp[5] < temp[8]) + swap(temp[5], temp[8]); + temp[5] <<= 1; + temp[2] <<= 2; + temp[2] += temp[5] + temp[8]; - //blue = ((int(temp[2]) * 160) >> 17) + 4; - blue = ((int(temp[2]) * 160) >> 14) + 32; + //blue = ((int(temp[2]) * 160) >> 17) + 4; + blue = ((int(temp[2]) * 160) >> 14) + 32; - if (temp[1] < temp[4]) swap(temp[1], temp[4]); - if (temp[1] < temp[7]) swap(temp[1], temp[7]); - if (temp[4] < temp[7]) swap(temp[4], temp[7]); - temp[4] <<= 1; - temp[1] <<= 2; - temp[1] += temp[4] + temp[7]; + if (temp[1] < temp[4]) + swap(temp[1], temp[4]); + if (temp[1] < temp[7]) + swap(temp[1], temp[7]); + if (temp[4] < temp[7]) + swap(temp[4], temp[7]); + temp[4] <<= 1; + temp[1] <<= 2; + temp[1] += temp[4] + temp[7]; - //green = ((int(temp[1]) * 160) >> 17) + 4; - green = ((int(temp[1]) * 160) >> 14) + 32; + //green = ((int(temp[1]) * 160) >> 17) + 4; + green = ((int(temp[1]) * 160) >> 14) + 32; - //pix = red << redshift; - //pix += green << greenshift; - //pix += blue << blueshift; + //pix = red << redshift; + //pix += green << greenshift; + //pix += blue << blueshift; - pix = red << (systemRedShift - 3); - pix += green << (systemGreenShift - 3); - pix += blue << (systemBlueShift - 3); + pix = red << (systemRedShift - 3); + pix += green << (systemGreenShift - 3); + pix += blue << (systemBlueShift - 3); - *buf++ = pix; - } + *buf++ = pix; + } } // for palette mode to work with the three spoony filters in 32bpp depth -void gbafilter_pad(u8 * buf, int count) +void gbafilter_pad(u8* buf, int count) { - union - { - struct - { - u8 r; - u8 g; - u8 b; - u8 a; - } part; - unsigned whole; - } - mask; + union { + struct + { + u8 r; + u8 g; + u8 b; + u8 a; + } part; + unsigned whole; + } mask; - mask.whole = 0x1f << systemRedShift; - mask.whole += 0x1f << systemGreenShift; - mask.whole += 0x1f << systemBlueShift; + mask.whole = 0x1f << systemRedShift; + mask.whole += 0x1f << systemGreenShift; + mask.whole += 0x1f << systemBlueShift; - switch (systemColorDepth) - { - case 24: - while (count--) - { - *buf++ &= mask.part.r; - *buf++ &= mask.part.g; - *buf++ &= mask.part.b; - } - break; - case 32: - while (count--) - { - *((u32*)buf) &= mask.whole; - buf += 4; - } - } + switch (systemColorDepth) { + case 24: + while (count--) { + *buf++ &= mask.part.r; + *buf++ &= mask.part.g; + *buf++ &= mask.part.b; + } + break; + case 32: + while (count--) { + *((u32*)buf) &= mask.whole; + buf += 4; + } + } } /* diff --git a/src/gba/gbafilter.h b/src/gba/gbafilter.h index 5927aca7..bc6cc6cf 100644 --- a/src/gba/gbafilter.h +++ b/src/gba/gbafilter.h @@ -1,5 +1,5 @@ #include "../System.h" -void gbafilter_pal(u16 *buf, int count); -void gbafilter_pal32(u32 *buf, int count); -void gbafilter_pad(u8 *buf, int count); +void gbafilter_pal(u16* buf, int count); +void gbafilter_pal32(u32* buf, int count); +void gbafilter_pad(u8* buf, int count); diff --git a/src/gba/remote.cpp b/src/gba/remote.cpp index b18f46d5..606f5529 100644 --- a/src/gba/remote.cpp +++ b/src/gba/remote.cpp @@ -1,6 +1,6 @@ #ifndef __LIBRETRO__ -#include #include +#include #include #include @@ -8,34 +8,34 @@ #include #ifndef _WIN32 -# include -# include -# include -# ifdef HAVE_NETINET_IN_H -# include -# endif // HAVE_NETINET_IN_H -# ifdef HAVE_ARPA_INET_H -# include -# else // ! HAVE_ARPA_INET_H -# define socklen_t int -# endif // ! HAVE_ARPA_INET_H -# define SOCKET int +#include +#include +#include +#ifdef HAVE_NETINET_IN_H +#include +#endif // HAVE_NETINET_IN_H +#ifdef HAVE_ARPA_INET_H +#include +#else // ! HAVE_ARPA_INET_H +#define socklen_t int +#endif // ! HAVE_ARPA_INET_H +#define SOCKET int #else // _WIN32 -# include -# include -# define socklen_t int -# define close closesocket -# define read _read -# define write _write +#include +#include +#define socklen_t int +#define close closesocket +#define read _read +#define write _write #define strdup _strdup #endif // _WIN32 -#include "remote.h" #include "BreakpointStructures.h" #include "GBA.h" -#include -#include #include "elf.h" +#include "remote.h" +#include +#include extern bool debugger; extern int emulating; @@ -48,36 +48,36 @@ SOCKET remoteListenSocket = -1; bool remoteConnected = false; bool remoteResumed = false; -int (*remoteSendFnc)(char *, int) = NULL; -int (*remoteRecvFnc)(char *, int) = NULL; +int (*remoteSendFnc)(char*, int) = NULL; +int (*remoteRecvFnc)(char*, int) = NULL; bool (*remoteInitFnc)() = NULL; void (*remoteCleanUpFnc)() = NULL; #ifndef SDL void remoteSetSockets(SOCKET l, SOCKET r) { - remoteSocket = r; - remoteListenSocket = l; + remoteSocket = r; + remoteListenSocket = l; } #endif #define debuggerReadMemory(addr) \ - (*(u32*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask]) + (*(u32*)&map[(addr) >> 24].address[(addr)&map[(addr) >> 24].mask]) #define debuggerReadHalfWord(addr) \ - (*(u16*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask]) + (*(u16*)&map[(addr) >> 24].address[(addr)&map[(addr) >> 24].mask]) #define debuggerReadByte(addr) \ - map[(addr)>>24].address[(addr) & map[(addr)>>24].mask] + map[(addr) >> 24].address[(addr)&map[(addr) >> 24].mask] #define debuggerWriteMemory(addr, value) \ - *(u32*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask] = (value) + *(u32*)&map[(addr) >> 24].address[(addr)&map[(addr) >> 24].mask] = (value) #define debuggerWriteHalfWord(addr, value) \ - *(u16*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask] = (value) + *(u16*)&map[(addr) >> 24].address[(addr)&map[(addr) >> 24].mask] = (value) #define debuggerWriteByte(addr, value) \ - map[(addr)>>24].address[(addr) & map[(addr)>>24].mask] = (value) + map[(addr) >> 24].address[(addr)&map[(addr) >> 24].mask] = (value) bool dontBreakNow = false; int debuggerNumOfDontBreak = 0; @@ -87,25 +87,25 @@ int debuggerRadix = 0; u32 debuggerNoBreakpointList[NUMBEROFDB]; const char* cmdAliasTable[] = { "help", "?", "h", "?", "continue", "c", "next", "n", -"cpyb", "copyb", "cpyh", "copyh", "cpyw", "copyw", -"exe", "execute", "exec", "execute", -NULL, NULL }; + "cpyb", "copyb", "cpyh", "copyh", "cpyw", "copyw", + "exe", "execute", "exec", "execute", + NULL, NULL }; struct DebuggerCommand { - const char *name; - void(*function)(int, char **); - const char *help; - const char *syntax; + const char* name; + void (*function)(int, char**); + const char* help; + const char* syntax; }; char monbuf[1000]; void monprintf(std::string line); -std::string StringToHex(std::string &cmd); -std::string HexToString(char * p); -void debuggerUsage(const char *cmd); -void debuggerHelp(int n, char **args); +std::string StringToHex(std::string& cmd); +std::string HexToString(char* p); +void debuggerUsage(const char* cmd); +void debuggerHelp(int n, char** args); void printFlagHelp(); -void dbgExecute(std::string &cmd); +void dbgExecute(std::string& cmd); extern bool debuggerBreakOnWrite(u32, u32, int); extern bool debuggerBreakOnRegisterCondition(u8, u32, u32, u8); @@ -117,967 +117,1333 @@ u8 medRegBreakCounter[4]; //(r4-r7) u8 highRegBreakCounter[4]; //(r8-r11) u8 statusRegBreakCounter[4]; //(r12-r15) u8* regBreakCounter[4] = { - &lowRegBreakCounter[0], - &medRegBreakCounter[0], - &highRegBreakCounter[0], - &statusRegBreakCounter[0] + &lowRegBreakCounter[0], + &medRegBreakCounter[0], + &highRegBreakCounter[0], + &statusRegBreakCounter[0] }; u32 lastWasBranch = 0; -struct regBreak* getFromBreakRegList(u8 regnum, int location){ - if (location > regBreakCounter[regnum >> 2][regnum & 3]) - return NULL; +struct regBreak* getFromBreakRegList(u8 regnum, int location) +{ + if (location > regBreakCounter[regnum >> 2][regnum & 3]) + return NULL; - struct regBreak* ans = breakRegList[regnum]; - for (int i = 0; i < location && ans; i++){ - ans = ans->next; - } - return ans; + struct regBreak* ans = breakRegList[regnum]; + for (int i = 0; i < location && ans; i++) { + ans = ans->next; + } + return ans; } bool enableRegBreak = false; reg_pair oldReg[16]; u32 regDiff[16]; -void breakReg_check(int i){ - struct regBreak* brkR = breakRegList[i]; - bool notFound = true; - u8 counter = regBreakCounter[i >> 2][i & 3]; - for (int bri = 0; (bri < counter) && notFound; bri++){ - if (!brkR){ - regBreakCounter[i >> 2][i & 3] = (u8)bri; - break; - } - else{ - if (brkR->flags != 0){ - u32 regVal = (i == 15 ? (armState ? reg[15].I - 4 : reg[15].I - 2) : reg[i].I); - if ((brkR->flags & 0x1) && (regVal == brkR->intVal)){ - debuggerBreakOnRegisterCondition(i, brkR->intVal, regVal, 1); - notFound = false; - } - if ((brkR->flags & 0x8)){ - if ((brkR->flags & 0x4) && ((int)regVal < (int)brkR->intVal)){ - debuggerBreakOnRegisterCondition(i, brkR->intVal, regVal, 4); - notFound = false; - } - if ((brkR->flags & 0x2) && ((int)regVal >(int)brkR->intVal)){ - debuggerBreakOnRegisterCondition(i, brkR->intVal, regVal, 5); - notFound = false; - } - } - if ((brkR->flags & 0x4) && (regVal < brkR->intVal)){ - debuggerBreakOnRegisterCondition(i, brkR->intVal, regVal, 2); - notFound = false; - } - if ((brkR->flags & 0x2) && (regVal > brkR->intVal)){ - debuggerBreakOnRegisterCondition(i, brkR->intVal, regVal, 3); - notFound = false; - } - } - brkR = brkR->next; - } - } - if (!notFound){ - //CPU_BREAK_LOOP_2; - } -} - -void clearParticularRegListBreaks(int regNum){ - - while (breakRegList[regNum]){ - struct regBreak* ans = breakRegList[regNum]->next; - free(breakRegList[regNum]); - breakRegList[regNum] = ans; - } - regBreakCounter[regNum >> 2][regNum & 3] = 0; -} - -void clearBreakRegList(){ - for (int i = 0; i<16; i++){ - clearParticularRegListBreaks(i); - } -} - -void deleteFromBreakRegList(u8 regNum, int num){ - int counter = regBreakCounter[regNum >> 2][regNum & 3]; - if (num >= counter){ - return; - } - struct regBreak* ans = breakRegList[regNum]; - struct regBreak* prev = NULL; - for (int i = 0; i < num; i++){ - prev = ans; - ans = ans->next; - } - if (prev){ - prev->next = ans->next; - } - else{ - breakRegList[regNum] = ans->next; - - } - free(ans); - regBreakCounter[regNum >> 2][regNum & 3]--; -} - -void addBreakRegToList(u8 regnum, u8 flags, u32 value){ - struct regBreak* ans = (struct regBreak*)malloc(sizeof(struct regBreak)); - ans->flags = flags; - ans->intVal = value; - ans->next = breakRegList[regnum]; - breakRegList[regnum] = ans; - regBreakCounter[regnum >> 2][regnum & 3]++; -} - -void printBreakRegList(bool verbose){ - const char* flagsToOP[] = { "never", "==", ">", ">=", "<", "<=", "!=", "always" }; - bool anyPrint = false; - for (int i = 0; i<4; i++){ - for (int k = 0; k<4; k++){ - if (regBreakCounter[i][k]){ - if (!anyPrint){ - { sprintf(monbuf, "Register breakpoint list:\n"); monprintf(monbuf); } - { sprintf(monbuf, "-------------------------\n"); monprintf(monbuf); } - anyPrint = true; - } - struct regBreak* tmp = breakRegList[i * 4 + k]; - for (int j = 0; j < regBreakCounter[i][k]; j++){ - if (tmp->flags & 8) - { - sprintf(monbuf, "No. %d:\tBreak if (signed)%s %08x\n", j, flagsToOP[tmp->flags & 7], tmp->intVal); monprintf(monbuf); - } - else - { - sprintf(monbuf, "No. %d:\tBreak if %s %08x\n", j, flagsToOP[tmp->flags], tmp->intVal); monprintf(monbuf); - } - tmp = tmp->next; - } - { sprintf(monbuf, "-------------------------\n"); monprintf(monbuf); } - } - else{ - if (verbose){ - if (!anyPrint){ - { sprintf(monbuf, "Register breakpoint list:\n"); monprintf(monbuf); } - { sprintf(monbuf, "-------------------------\n"); monprintf(monbuf); } - anyPrint = true; - } - { sprintf(monbuf, "No breaks on r%d.\n", i); monprintf(monbuf); } - { sprintf(monbuf, "-------------------------\n"); monprintf(monbuf); } - } - } - } - } - if (!verbose && !anyPrint){ - { sprintf(monbuf, "No Register breaks found.\n"); monprintf(monbuf); } - } - -} - -void debuggerOutput(const char *s, u32 addr) +void breakReg_check(int i) { - if (s) - printf("%s", s); - else { - char c; + struct regBreak* brkR = breakRegList[i]; + bool notFound = true; + u8 counter = regBreakCounter[i >> 2][i & 3]; + for (int bri = 0; (bri < counter) && notFound; bri++) { + if (!brkR) { + regBreakCounter[i >> 2][i & 3] = (u8)bri; + break; + } else { + if (brkR->flags != 0) { + u32 regVal = (i == 15 ? (armState ? reg[15].I - 4 : reg[15].I - 2) : reg[i].I); + if ((brkR->flags & 0x1) && (regVal == brkR->intVal)) { + debuggerBreakOnRegisterCondition(i, brkR->intVal, regVal, 1); + notFound = false; + } + if ((brkR->flags & 0x8)) { + if ((brkR->flags & 0x4) && ((int)regVal < (int)brkR->intVal)) { + debuggerBreakOnRegisterCondition(i, brkR->intVal, regVal, 4); + notFound = false; + } + if ((brkR->flags & 0x2) && ((int)regVal > (int)brkR->intVal)) { + debuggerBreakOnRegisterCondition(i, brkR->intVal, regVal, 5); + notFound = false; + } + } + if ((brkR->flags & 0x4) && (regVal < brkR->intVal)) { + debuggerBreakOnRegisterCondition(i, brkR->intVal, regVal, 2); + notFound = false; + } + if ((brkR->flags & 0x2) && (regVal > brkR->intVal)) { + debuggerBreakOnRegisterCondition(i, brkR->intVal, regVal, 3); + notFound = false; + } + } + brkR = brkR->next; + } + } + if (!notFound) { + //CPU_BREAK_LOOP_2; + } +} - c = debuggerReadByte(addr); - addr++; - while (c) { - putchar(c); - c = debuggerReadByte(addr); - addr++; - } - } +void clearParticularRegListBreaks(int regNum) +{ + + while (breakRegList[regNum]) { + struct regBreak* ans = breakRegList[regNum]->next; + free(breakRegList[regNum]); + breakRegList[regNum] = ans; + } + regBreakCounter[regNum >> 2][regNum & 3] = 0; +} + +void clearBreakRegList() +{ + for (int i = 0; i < 16; i++) { + clearParticularRegListBreaks(i); + } +} + +void deleteFromBreakRegList(u8 regNum, int num) +{ + int counter = regBreakCounter[regNum >> 2][regNum & 3]; + if (num >= counter) { + return; + } + struct regBreak* ans = breakRegList[regNum]; + struct regBreak* prev = NULL; + for (int i = 0; i < num; i++) { + prev = ans; + ans = ans->next; + } + if (prev) { + prev->next = ans->next; + } else { + breakRegList[regNum] = ans->next; + } + free(ans); + regBreakCounter[regNum >> 2][regNum & 3]--; +} + +void addBreakRegToList(u8 regnum, u8 flags, u32 value) +{ + struct regBreak* ans = (struct regBreak*)malloc(sizeof(struct regBreak)); + ans->flags = flags; + ans->intVal = value; + ans->next = breakRegList[regnum]; + breakRegList[regnum] = ans; + regBreakCounter[regnum >> 2][regnum & 3]++; +} + +void printBreakRegList(bool verbose) +{ + const char* flagsToOP[] = { "never", "==", ">", ">=", "<", "<=", "!=", "always" }; + bool anyPrint = false; + for (int i = 0; i < 4; i++) { + for (int k = 0; k < 4; k++) { + if (regBreakCounter[i][k]) { + if (!anyPrint) { + { + sprintf(monbuf, "Register breakpoint list:\n"); + monprintf(monbuf); + } + { + sprintf(monbuf, "-------------------------\n"); + monprintf(monbuf); + } + anyPrint = true; + } + struct regBreak* tmp = breakRegList[i * 4 + k]; + for (int j = 0; j < regBreakCounter[i][k]; j++) { + if (tmp->flags & 8) { + sprintf(monbuf, "No. %d:\tBreak if (signed)%s %08x\n", j, flagsToOP[tmp->flags & 7], tmp->intVal); + monprintf(monbuf); + } else { + sprintf(monbuf, "No. %d:\tBreak if %s %08x\n", j, flagsToOP[tmp->flags], tmp->intVal); + monprintf(monbuf); + } + tmp = tmp->next; + } + { + sprintf(monbuf, "-------------------------\n"); + monprintf(monbuf); + } + } else { + if (verbose) { + if (!anyPrint) { + { + sprintf(monbuf, "Register breakpoint list:\n"); + monprintf(monbuf); + } + { + sprintf(monbuf, "-------------------------\n"); + monprintf(monbuf); + } + anyPrint = true; + } + { + sprintf(monbuf, "No breaks on r%d.\n", i); + monprintf(monbuf); + } + { + sprintf(monbuf, "-------------------------\n"); + monprintf(monbuf); + } + } + } + } + } + if (!verbose && !anyPrint) { + { + sprintf(monbuf, "No Register breaks found.\n"); + monprintf(monbuf); + } + } +} + +void debuggerOutput(const char* s, u32 addr) +{ + if (s) + printf("%s", s); + else { + char c; + + c = debuggerReadByte(addr); + addr++; + while (c) { + putchar(c); + c = debuggerReadByte(addr); + addr++; + } + } } // checks that the given address is in the DB list bool debuggerInDB(u32 address) { - for (int i = 0; i < debuggerNumOfDontBreak; i++) - { - if (debuggerNoBreakpointList[i] == address) - return true; - } - - return false; + for (int i = 0; i < debuggerNumOfDontBreak; i++) { + if (debuggerNoBreakpointList[i] == address) + return true; + } + return false; } -void debuggerDontBreak(int n, char **args) +void debuggerDontBreak(int n, char** args) { - if (n == 2) { - u32 address = 0; - sscanf(args[1], "%x", &address); - int i = debuggerNumOfDontBreak; - if (i > NUMBEROFDB) - { - monprintf("Can't have this many DB entries"); - return; - } - debuggerNoBreakpointList[i] = address; - debuggerNumOfDontBreak++; - { sprintf(monbuf, "Added Don't Break at %08x\n", address); monprintf(monbuf); } - } - else - debuggerUsage("db"); + if (n == 2) { + u32 address = 0; + sscanf(args[1], "%x", &address); + int i = debuggerNumOfDontBreak; + if (i > NUMBEROFDB) { + monprintf("Can't have this many DB entries"); + return; + } + debuggerNoBreakpointList[i] = address; + debuggerNumOfDontBreak++; + { + sprintf(monbuf, "Added Don't Break at %08x\n", address); + monprintf(monbuf); + } + } else + debuggerUsage("db"); } -void debuggerDontBreakClear(int n, char **args) +void debuggerDontBreakClear(int n, char** args) { - if (n == 1) { - debuggerNumOfDontBreak = 0; - { sprintf(monbuf, "Cleared Don't Break list.\n"); monprintf(monbuf); } - } - else - debuggerUsage("dbc"); + if (n == 1) { + debuggerNumOfDontBreak = 0; + { + sprintf(monbuf, "Cleared Don't Break list.\n"); + monprintf(monbuf); + } + } else + debuggerUsage("dbc"); } void debuggerDumpLoad(int n, char** args) { - u32 address; - char *file; - FILE *f; - int c; + u32 address; + char* file; + FILE* f; + int c; - if (n == 3){ - file = args[1]; + if (n == 3) { + file = args[1]; - if (!dexp_eval(args[2], &address)){ - { sprintf(monbuf, "Invalid expression in address.\n"); monprintf(monbuf); } - return; - } + if (!dexp_eval(args[2], &address)) { + { + sprintf(monbuf, "Invalid expression in address.\n"); + monprintf(monbuf); + } + return; + } - f = fopen(file, "rb"); - if (f == NULL){ - { sprintf(monbuf, "Error opening file.\n"); monprintf(monbuf); } - return; - } + f = fopen(file, "rb"); + if (f == NULL) { + { + sprintf(monbuf, "Error opening file.\n"); + monprintf(monbuf); + } + return; + } - fseek(f, 0, SEEK_END); - int size = ftell(f); - fseek(f, 0, SEEK_SET); + fseek(f, 0, SEEK_END); + int size = ftell(f); + fseek(f, 0, SEEK_SET); - for (int i = 0; i= 3) { - u32 address; - u32 value; - if (!dexp_eval(args[1], &address)) { - { sprintf(monbuf, "Invalid expression in address.\n"); monprintf(monbuf); } - return; - } - for (int i = 2; i < n; i++){ - if (!dexp_eval(args[i], &value)) { - { sprintf(monbuf, "Invalid expression in %d value.Ignored.\n", (i - 1)); monprintf(monbuf); } - } - debuggerWriteByte(address, (u16)value); - address++; - } - } - else - debuggerUsage("eb"); + if (n >= 3) { + u32 address; + u32 value; + if (!dexp_eval(args[1], &address)) { + { + sprintf(monbuf, "Invalid expression in address.\n"); + monprintf(monbuf); + } + return; + } + for (int i = 2; i < n; i++) { + if (!dexp_eval(args[i], &value)) { + { + sprintf(monbuf, "Invalid expression in %d value.Ignored.\n", (i - 1)); + monprintf(monbuf); + } + } + debuggerWriteByte(address, (u16)value); + address++; + } + } else + debuggerUsage("eb"); } -void debuggerEditHalfWord(int n, char **args) +void debuggerEditHalfWord(int n, char** args) { - if (n >= 3) { - u32 address; - u32 value; - if (!dexp_eval(args[1], &address)) { - { sprintf(monbuf, "Invalid expression in address.\n"); monprintf(monbuf); } - return; - } - if (address & 1) { - { sprintf(monbuf, "Error: address must be half-word aligned\n"); monprintf(monbuf); } - return; - } - for (int i = 2; i < n; i++){ - if (!dexp_eval(args[i], &value)) { - { sprintf(monbuf, "Invalid expression in %d value.Ignored.\n", (i - 1)); monprintf(monbuf); } - } - debuggerWriteHalfWord(address, (u16)value); - address += 2; - } - } - else - debuggerUsage("eh"); + if (n >= 3) { + u32 address; + u32 value; + if (!dexp_eval(args[1], &address)) { + { + sprintf(monbuf, "Invalid expression in address.\n"); + monprintf(monbuf); + } + return; + } + if (address & 1) { + { + sprintf(monbuf, "Error: address must be half-word aligned\n"); + monprintf(monbuf); + } + return; + } + for (int i = 2; i < n; i++) { + if (!dexp_eval(args[i], &value)) { + { + sprintf(monbuf, "Invalid expression in %d value.Ignored.\n", (i - 1)); + monprintf(monbuf); + } + } + debuggerWriteHalfWord(address, (u16)value); + address += 2; + } + } else + debuggerUsage("eh"); } -void debuggerEditWord(int n, char **args) +void debuggerEditWord(int n, char** args) { - if (n >= 3) { - u32 address; - u32 value; - if (!dexp_eval(args[1], &address)) { - { sprintf(monbuf, "Invalid expression in address.\n"); monprintf(monbuf); } - return; - } - if (address & 3) { - { sprintf(monbuf, "Error: address must be word aligned\n"); monprintf(monbuf); } - return; - } - for (int i = 2; i < n; i++){ - if (!dexp_eval(args[i], &value)) { - { sprintf(monbuf, "Invalid expression in %d value.Ignored.\n", (i - 1)); monprintf(monbuf); } - } - debuggerWriteMemory(address, (u32)value); - address += 4; - } - } - else - debuggerUsage("ew"); + if (n >= 3) { + u32 address; + u32 value; + if (!dexp_eval(args[1], &address)) { + { + sprintf(monbuf, "Invalid expression in address.\n"); + monprintf(monbuf); + } + return; + } + if (address & 3) { + { + sprintf(monbuf, "Error: address must be word aligned\n"); + monprintf(monbuf); + } + return; + } + for (int i = 2; i < n; i++) { + if (!dexp_eval(args[i], &value)) { + { + sprintf(monbuf, "Invalid expression in %d value.Ignored.\n", (i - 1)); + monprintf(monbuf); + } + } + debuggerWriteMemory(address, (u32)value); + address += 4; + } + } else + debuggerUsage("ew"); } -bool debuggerBreakOnRegisterCondition(u8 registerName, u32 compareVal, u32 regVal, u8 type){ - const char* typeName; - switch (type){ - case 1: - typeName = "equal to"; - break; - case 2: - typeName = "greater (unsigned) than"; - break; - case 3: - typeName = "smaller (unsigned) than"; - break; - case 4: - typeName = "greater (signed) than"; - break; - case 5: - typeName = "smaller (signed) than"; - break; - default: - typeName = "unknown"; - } - { sprintf(monbuf, "Breakpoint on R%02d : %08x is %s register content (%08x)\n", registerName, compareVal, typeName, regVal); monprintf(monbuf); } - if (debuggerInDB(armState ? reg[15].I - 4 : reg[15].I - 2)){ - { sprintf(monbuf, "But this address is marked not to break, so skipped\n"); monprintf(monbuf); } - return false; - } - debugger = true; - return true; -} - -void debuggerBreakRegisterList(bool verbose){ - printBreakRegList(verbose); -} - -int getRegisterNumber(char* regName){ - int r = -1; - if (toupper(regName[0]) == 'P' && toupper(regName[1]) == 'C'){ - r = 15; - } - else if (toupper(regName[0]) == 'L' && toupper(regName[1]) == 'R'){ - r = 14; - } - else if (toupper(regName[0]) == 'S' && toupper(regName[1]) == 'P'){ - r = 13; - } - else if (toupper(regName[0]) == 'R') { - sscanf((char *)(regName + 1), "%d", &r); - } - else { - sscanf(regName, "%d", &r); - } - - return r; -} - -void debuggerEditRegister(int n, char **args) +bool debuggerBreakOnRegisterCondition(u8 registerName, u32 compareVal, u32 regVal, u8 type) { - if (n == 3) { - int r = getRegisterNumber(args[1]); - u32 val; - if (r > 16) { - { sprintf(monbuf, "Error: Register must be valid (0-16)\n"); monprintf(monbuf); } - return; - } - if (!dexp_eval(args[2], &val)) { - { sprintf(monbuf, "Invalid expression in value.\n"); monprintf(monbuf); } - return; - } - reg[r].I = val; - { sprintf(monbuf, "R%02d=%08X\n", r, val); monprintf(monbuf); } - } - else - debuggerUsage("er"); + const char* typeName; + switch (type) { + case 1: + typeName = "equal to"; + break; + case 2: + typeName = "greater (unsigned) than"; + break; + case 3: + typeName = "smaller (unsigned) than"; + break; + case 4: + typeName = "greater (signed) than"; + break; + case 5: + typeName = "smaller (signed) than"; + break; + default: + typeName = "unknown"; + } + { + sprintf(monbuf, "Breakpoint on R%02d : %08x is %s register content (%08x)\n", registerName, compareVal, typeName, regVal); + monprintf(monbuf); + } + if (debuggerInDB(armState ? reg[15].I - 4 : reg[15].I - 2)) { + { + sprintf(monbuf, "But this address is marked not to break, so skipped\n"); + monprintf(monbuf); + } + return false; + } + debugger = true; + return true; } -void debuggerEval(int n, char **args) +void debuggerBreakRegisterList(bool verbose) { - if (n == 2) { - u32 result = 0; - if (dexp_eval(args[1], &result)) { - { sprintf(monbuf, " =$%08X\n", result); monprintf(monbuf); } - } - else { - { sprintf(monbuf, "Invalid expression\n"); monprintf(monbuf); } - } - } - else - debuggerUsage("eval"); + printBreakRegList(verbose); } -void debuggerFillByte(int n, char **args) +int getRegisterNumber(char* regName) { - if (n == 4) { - u32 address; - u32 value; - u32 reps; - if (!dexp_eval(args[1], &address)) { - { sprintf(monbuf, "Invalid expression in address.\n"); monprintf(monbuf); } - return; - } - if (!dexp_eval(args[2], &value)) { - { sprintf(monbuf, "Invalid expression in value.\n"); monprintf(monbuf); } - } - if (!dexp_eval(args[3], &reps)) { - { sprintf(monbuf, "Invalid expression in repetition number.\n"); monprintf(monbuf); } - } - for (u32 i = 0; i < reps; i++){ - debuggerWriteByte(address, (u8)value); - address++; - } - } - else - debuggerUsage("fillb"); + int r = -1; + if (toupper(regName[0]) == 'P' && toupper(regName[1]) == 'C') { + r = 15; + } else if (toupper(regName[0]) == 'L' && toupper(regName[1]) == 'R') { + r = 14; + } else if (toupper(regName[0]) == 'S' && toupper(regName[1]) == 'P') { + r = 13; + } else if (toupper(regName[0]) == 'R') { + sscanf((char*)(regName + 1), "%d", &r); + } else { + sscanf(regName, "%d", &r); + } + + return r; } -void debuggerFillHalfWord(int n, char **args) +void debuggerEditRegister(int n, char** args) { - if (n == 4) { - u32 address; - u32 value; - u32 reps; - if (!dexp_eval(args[1], &address)) { - { sprintf(monbuf, "Invalid expression in address.\n"); monprintf(monbuf); } - return; - }/* + if (n == 3) { + int r = getRegisterNumber(args[1]); + u32 val; + if (r > 16) { + { + sprintf(monbuf, "Error: Register must be valid (0-16)\n"); + monprintf(monbuf); + } + return; + } + if (!dexp_eval(args[2], &val)) { + { + sprintf(monbuf, "Invalid expression in value.\n"); + monprintf(monbuf); + } + return; + } + reg[r].I = val; + { + sprintf(monbuf, "R%02d=%08X\n", r, val); + monprintf(monbuf); + } + } else + debuggerUsage("er"); +} + +void debuggerEval(int n, char** args) +{ + if (n == 2) { + u32 result = 0; + if (dexp_eval(args[1], &result)) { + { + sprintf(monbuf, " =$%08X\n", result); + monprintf(monbuf); + } + } else { + { + sprintf(monbuf, "Invalid expression\n"); + monprintf(monbuf); + } + } + } else + debuggerUsage("eval"); +} + +void debuggerFillByte(int n, char** args) +{ + if (n == 4) { + u32 address; + u32 value; + u32 reps; + if (!dexp_eval(args[1], &address)) { + { + sprintf(monbuf, "Invalid expression in address.\n"); + monprintf(monbuf); + } + return; + } + if (!dexp_eval(args[2], &value)) { + { + sprintf(monbuf, "Invalid expression in value.\n"); + monprintf(monbuf); + } + } + if (!dexp_eval(args[3], &reps)) { + { + sprintf(monbuf, "Invalid expression in repetition number.\n"); + monprintf(monbuf); + } + } + for (u32 i = 0; i < reps; i++) { + debuggerWriteByte(address, (u8)value); + address++; + } + } else + debuggerUsage("fillb"); +} + +void debuggerFillHalfWord(int n, char** args) +{ + if (n == 4) { + u32 address; + u32 value; + u32 reps; + if (!dexp_eval(args[1], &address)) { + { + sprintf(monbuf, "Invalid expression in address.\n"); + monprintf(monbuf); + } + return; + } /* if(address & 1) { { sprintf(monbuf, "Error: address must be halfword aligned\n"); monprintf(monbuf); } return; }*/ - if (!dexp_eval(args[2], &value)) { - { sprintf(monbuf, "Invalid expression in value.\n"); monprintf(monbuf); } - } - if (!dexp_eval(args[3], &reps)) { - { sprintf(monbuf, "Invalid expression in repetition number.\n"); monprintf(monbuf); } - } - for (u32 i = 0; i < reps; i++){ - debuggerWriteHalfWord(address, (u16)value); - address += 2; - } - } - else - debuggerUsage("fillh"); + if (!dexp_eval(args[2], &value)) { + { + sprintf(monbuf, "Invalid expression in value.\n"); + monprintf(monbuf); + } + } + if (!dexp_eval(args[3], &reps)) { + { + sprintf(monbuf, "Invalid expression in repetition number.\n"); + monprintf(monbuf); + } + } + for (u32 i = 0; i < reps; i++) { + debuggerWriteHalfWord(address, (u16)value); + address += 2; + } + } else + debuggerUsage("fillh"); } -void debuggerFillWord(int n, char **args) +void debuggerFillWord(int n, char** args) { - if (n == 4) { - u32 address; - u32 value; - u32 reps; - if (!dexp_eval(args[1], &address)) { - { sprintf(monbuf, "Invalid expression in address.\n"); monprintf(monbuf); } - return; - }/* + if (n == 4) { + u32 address; + u32 value; + u32 reps; + if (!dexp_eval(args[1], &address)) { + { + sprintf(monbuf, "Invalid expression in address.\n"); + monprintf(monbuf); + } + return; + } /* if(address & 3) { { sprintf(monbuf, "Error: address must be word aligned\n"); monprintf(monbuf); } return; }*/ - if (!dexp_eval(args[2], &value)) { - { sprintf(monbuf, "Invalid expression in value.\n"); monprintf(monbuf); } - } - if (!dexp_eval(args[3], &reps)) { - { sprintf(monbuf, "Invalid expression in repetition number.\n"); monprintf(monbuf); } - } - for (u32 i = 0; i< reps; i++){ - debuggerWriteMemory(address, (u32)value); - address += 4; - } - } - else - debuggerUsage("fillw"); + if (!dexp_eval(args[2], &value)) { + { + sprintf(monbuf, "Invalid expression in value.\n"); + monprintf(monbuf); + } + } + if (!dexp_eval(args[3], &reps)) { + { + sprintf(monbuf, "Invalid expression in repetition number.\n"); + monprintf(monbuf); + } + } + for (u32 i = 0; i < reps; i++) { + debuggerWriteMemory(address, (u32)value); + address += 4; + } + } else + debuggerUsage("fillw"); } unsigned int SearchStart = 0xFFFFFFFF; unsigned int SearchMaxMatches = 5; -u8 SearchData[64]; // It actually doesn't make much sense to search for more than 64 bytes, does it? +u8 SearchData[64]; // It actually doesn't make much sense to search for more than 64 bytes, does it? unsigned int SearchLength = 0; unsigned int SearchResults; unsigned int AddressToGBA(u8* mem) { - if (mem >= &bios[0] && mem <= &bios[0x3fff]) - return 0x00000000 + (mem - &bios[0]); - else if (mem >= &workRAM[0] && mem <= &workRAM[0x3ffff]) - return 0x02000000 + (mem - &workRAM[0]); - else if (mem >= &internalRAM[0] && mem <= &internalRAM[0x7fff]) - return 0x03000000 + (mem - &internalRAM[0]); - else if (mem >= &ioMem[0] && mem <= &ioMem[0x3ff]) - return 0x04000000 + (mem - &ioMem[0]); - else if (mem >= &paletteRAM[0] && mem <= &paletteRAM[0x3ff]) - return 0x05000000 + (mem - &paletteRAM[0]); - else if (mem >= &vram[0] && mem <= &vram[0x1ffff]) - return 0x06000000 + (mem - &vram[0]); - else if (mem >= &oam[0] && mem <= &oam[0x3ff]) - return 0x07000000 + (mem - &oam[0]); - else if (mem >= &rom[0] && mem <= &rom[0x1ffffff]) - return 0x08000000 + (mem - &rom[0]); - else - return 0xFFFFFFFF; + if (mem >= &bios[0] && mem <= &bios[0x3fff]) + return 0x00000000 + (mem - &bios[0]); + else if (mem >= &workRAM[0] && mem <= &workRAM[0x3ffff]) + return 0x02000000 + (mem - &workRAM[0]); + else if (mem >= &internalRAM[0] && mem <= &internalRAM[0x7fff]) + return 0x03000000 + (mem - &internalRAM[0]); + else if (mem >= &ioMem[0] && mem <= &ioMem[0x3ff]) + return 0x04000000 + (mem - &ioMem[0]); + else if (mem >= &paletteRAM[0] && mem <= &paletteRAM[0x3ff]) + return 0x05000000 + (mem - &paletteRAM[0]); + else if (mem >= &vram[0] && mem <= &vram[0x1ffff]) + return 0x06000000 + (mem - &vram[0]); + else if (mem >= &oam[0] && mem <= &oam[0x3ff]) + return 0x07000000 + (mem - &oam[0]); + else if (mem >= &rom[0] && mem <= &rom[0x1ffffff]) + return 0x08000000 + (mem - &rom[0]); + else + return 0xFFFFFFFF; }; void debuggerDoSearch() { - int count = 0; + int count = 0; - while (true) - { - unsigned int final = SearchStart + SearchLength - 1; - u8* end; - u8* start; + while (true) { + unsigned int final = SearchStart + SearchLength - 1; + u8* end; + u8* start; - switch (SearchStart >> 24) - { - case 0: - if (final > 0x00003FFF) { SearchStart = 0x02000000; continue; } - else { start = bios + (SearchStart & 0x3FFF); end = bios + 0x3FFF; break; }; - case 2: - if (final > 0x0203FFFF) { SearchStart = 0x03000000; continue; } - else { start = workRAM + (SearchStart & 0x3FFFF); end = workRAM + 0x3FFFF; break; }; - case 3: - if (final > 0x03007FFF) { SearchStart = 0x04000000; continue; } - else { start = internalRAM + (SearchStart & 0x7FFF); end = internalRAM + 0x7FFF; break; }; - case 4: - if (final > 0x040003FF) { SearchStart = 0x05000000; continue; } - else { start = ioMem + (SearchStart & 0x3FF); end = ioMem + 0x3FF; break; }; - case 5: - if (final > 0x050003FF) { SearchStart = 0x06000000; continue; } - else { start = paletteRAM + (SearchStart & 0x3FF); end = paletteRAM + 0x3FF; break; }; - case 6: - if (final > 0x0601FFFF) { SearchStart = 0x07000000; continue; } - else { start = vram + (SearchStart & 0x1FFFF); end = vram + 0x1FFFF; break; }; - case 7: - if (final > 0x070003FF) { SearchStart = 0x08000000; continue; } - else { start = oam + (SearchStart & 0x3FF); end = oam + 0x3FF; break; }; - case 8: - case 9: - case 10: - case 11: - case 12: - case 13: - if (final <= 0x09FFFFFF) - { - start = rom + (SearchStart & 0x01FFFFFF); end = rom + 0x01FFFFFF; break; - }; - default: - { sprintf(monbuf, "Search completed.\n"); monprintf(monbuf); } - SearchLength = 0; - return; - }; + switch (SearchStart >> 24) { + case 0: + if (final > 0x00003FFF) { + SearchStart = 0x02000000; + continue; + } else { + start = bios + (SearchStart & 0x3FFF); + end = bios + 0x3FFF; + break; + }; + case 2: + if (final > 0x0203FFFF) { + SearchStart = 0x03000000; + continue; + } else { + start = workRAM + (SearchStart & 0x3FFFF); + end = workRAM + 0x3FFFF; + break; + }; + case 3: + if (final > 0x03007FFF) { + SearchStart = 0x04000000; + continue; + } else { + start = internalRAM + (SearchStart & 0x7FFF); + end = internalRAM + 0x7FFF; + break; + }; + case 4: + if (final > 0x040003FF) { + SearchStart = 0x05000000; + continue; + } else { + start = ioMem + (SearchStart & 0x3FF); + end = ioMem + 0x3FF; + break; + }; + case 5: + if (final > 0x050003FF) { + SearchStart = 0x06000000; + continue; + } else { + start = paletteRAM + (SearchStart & 0x3FF); + end = paletteRAM + 0x3FF; + break; + }; + case 6: + if (final > 0x0601FFFF) { + SearchStart = 0x07000000; + continue; + } else { + start = vram + (SearchStart & 0x1FFFF); + end = vram + 0x1FFFF; + break; + }; + case 7: + if (final > 0x070003FF) { + SearchStart = 0x08000000; + continue; + } else { + start = oam + (SearchStart & 0x3FF); + end = oam + 0x3FF; + break; + }; + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + if (final <= 0x09FFFFFF) { + start = rom + (SearchStart & 0x01FFFFFF); + end = rom + 0x01FFFFFF; + break; + }; + default: { + sprintf(monbuf, "Search completed.\n"); + monprintf(monbuf); + } + SearchLength = 0; + return; + }; - end -= SearchLength - 1; - u8 firstbyte = SearchData[0]; - while (start <= end) - { - while ((start <= end) && (*start != firstbyte)) - start++; + end -= SearchLength - 1; + u8 firstbyte = SearchData[0]; + while (start <= end) { + while ((start <= end) && (*start != firstbyte)) + start++; - if (start > end) - break; + if (start > end) + break; - unsigned int p = 1; - while ((start[p] == SearchData[p]) && (p < SearchLength)) - p++; + unsigned int p = 1; + while ((start[p] == SearchData[p]) && (p < SearchLength)) + p++; - if (p == SearchLength) - { - { sprintf(monbuf, "Search result (%d): %08x\n", count + SearchResults, AddressToGBA(start)); monprintf(monbuf); } - count++; - if (count == SearchMaxMatches) - { - SearchStart = AddressToGBA(start + p); - SearchResults += count; - return; - }; + if (p == SearchLength) { + { + sprintf(monbuf, "Search result (%d): %08x\n", count + SearchResults, AddressToGBA(start)); + monprintf(monbuf); + } + count++; + if (count == SearchMaxMatches) { + SearchStart = AddressToGBA(start + p); + SearchResults += count; + return; + }; - start += p; // assume areas don't overlap; alternative: start++; - } - else - start++; - }; + start += p; // assume areas don't overlap; alternative: start++; + } else + start++; + }; - SearchStart = AddressToGBA(end + SearchLength - 1) + 1; - }; + SearchStart = AddressToGBA(end + SearchLength - 1) + 1; + }; }; -void debuggerFindText(int n, char **args) +void debuggerFindText(int n, char** args) { - if ((n == 4) || (n == 3)) - { - SearchResults = 0; - if (!dexp_eval(args[1], &SearchStart)){ - { sprintf(monbuf, "Invalid expression.\n"); monprintf(monbuf); } - return; - } + if ((n == 4) || (n == 3)) { + SearchResults = 0; + if (!dexp_eval(args[1], &SearchStart)) { + { + sprintf(monbuf, "Invalid expression.\n"); + monprintf(monbuf); + } + return; + } - if (n == 4) - { - sscanf(args[2], "%u", &SearchMaxMatches); - strncpy((char*)SearchData, args[3], 64); - SearchLength = strlen(args[3]); - } - else if (n == 3) - { - strncpy((char*)SearchData, args[2], 64); - SearchLength = strlen(args[2]); - }; + if (n == 4) { + sscanf(args[2], "%u", &SearchMaxMatches); + strncpy((char*)SearchData, args[3], 64); + SearchLength = strlen(args[3]); + } else if (n == 3) { + strncpy((char*)SearchData, args[2], 64); + SearchLength = strlen(args[2]); + }; - if (SearchLength > 64) - { - { sprintf(monbuf, "Entered string (length: %d) is longer than 64 bytes and was cut.\n", SearchLength); monprintf(monbuf); } - SearchLength = 64; - }; + if (SearchLength > 64) { + { + sprintf(monbuf, "Entered string (length: %d) is longer than 64 bytes and was cut.\n", SearchLength); + monprintf(monbuf); + } + SearchLength = 64; + }; - debuggerDoSearch(); + debuggerDoSearch(); - } - else - debuggerUsage("ft"); + } else + debuggerUsage("ft"); }; -void debuggerFindHex(int n, char **args) +void debuggerFindHex(int n, char** args) { - if ((n == 4) || (n == 3)) - { - SearchResults = 0; - if (!dexp_eval(args[1], &SearchStart)){ - { sprintf(monbuf, "Invalid expression.\n"); monprintf(monbuf); } - return; - } + if ((n == 4) || (n == 3)) { + SearchResults = 0; + if (!dexp_eval(args[1], &SearchStart)) { + { + sprintf(monbuf, "Invalid expression.\n"); + monprintf(monbuf); + } + return; + } - char SearchHex[128]; - if (n == 4) - { - sscanf(args[2], "%u", &SearchMaxMatches); - strncpy(SearchHex, args[3], 128); - SearchLength = strlen(args[3]); - } - else if (n == 3) - { - strncpy(SearchHex, args[2], 128); - SearchLength = strlen(args[2]); - }; + char SearchHex[128]; + if (n == 4) { + sscanf(args[2], "%u", &SearchMaxMatches); + strncpy(SearchHex, args[3], 128); + SearchLength = strlen(args[3]); + } else if (n == 3) { + strncpy(SearchHex, args[2], 128); + SearchLength = strlen(args[2]); + }; - if (SearchLength & 1) - { sprintf(monbuf, "Unaligned bytecount: %d,5. Last digit (%c) cut.\n", SearchLength / 2, SearchHex[SearchLength - 1]); monprintf(monbuf); } + if (SearchLength & 1) { + sprintf(monbuf, "Unaligned bytecount: %d,5. Last digit (%c) cut.\n", SearchLength / 2, SearchHex[SearchLength - 1]); + monprintf(monbuf); + } - SearchLength /= 2; + SearchLength /= 2; - if (SearchLength > 64) - { - { sprintf(monbuf, "Entered string (length: %d) is longer than 64 bytes and was cut.\n", SearchLength); monprintf(monbuf); } - SearchLength = 64; - }; + if (SearchLength > 64) { + { + sprintf(monbuf, "Entered string (length: %d) is longer than 64 bytes and was cut.\n", SearchLength); + monprintf(monbuf); + } + SearchLength = 64; + }; - for (unsigned int i = 0; i < SearchLength; i++) - { - unsigned int cbuf = 0; - sscanf(&SearchHex[i << 1], "%02x", &cbuf); - SearchData[i] = cbuf; - }; + for (unsigned int i = 0; i < SearchLength; i++) { + unsigned int cbuf = 0; + sscanf(&SearchHex[i << 1], "%02x", &cbuf); + SearchData[i] = cbuf; + }; - debuggerDoSearch(); + debuggerDoSearch(); - } - else - debuggerUsage("fh"); + } else + debuggerUsage("fh"); }; -void debuggerFindResume(int n, char **args) +void debuggerFindResume(int n, char** args) { - if ((n == 1) || (n == 2)) - { - if (SearchLength == 0) - { - { sprintf(monbuf, "Error: No search in progress. Start a search with ft or fh.\n"); monprintf(monbuf); } - debuggerUsage("fr"); - return; - }; + if ((n == 1) || (n == 2)) { + if (SearchLength == 0) { + { + sprintf(monbuf, "Error: No search in progress. Start a search with ft or fh.\n"); + monprintf(monbuf); + } + debuggerUsage("fr"); + return; + }; - if (n == 2) - sscanf(args[1], "%u", &SearchMaxMatches); + if (n == 2) + sscanf(args[1], "%u", &SearchMaxMatches); - debuggerDoSearch(); + debuggerDoSearch(); - } - else - debuggerUsage("fr"); + } else + debuggerUsage("fr"); }; -void debuggerCopyByte(int n, char **args) +void debuggerCopyByte(int n, char** args) { - u32 source; - u32 dest; - u32 number = 1; - u32 reps = 1; - if (n>5 || n<3){ - debuggerUsage("copyb"); - } + u32 source; + u32 dest; + u32 number = 1; + u32 reps = 1; + if (n > 5 || n < 3) { + debuggerUsage("copyb"); + } - if (n == 5) { - if (!dexp_eval(args[4], &reps)) { - { sprintf(monbuf, "Invalid expression in repetition number.\n"); monprintf(monbuf); } - } - } - if (n > 3){ - if (!dexp_eval(args[3], &number)) { - { sprintf(monbuf, "Invalid expression in number of copy units.\n"); monprintf(monbuf); } - } - } - if (!dexp_eval(args[1], &source)) { - { sprintf(monbuf, "Invalid expression in source address.\n"); monprintf(monbuf); } - return; - } - if (!dexp_eval(args[2], &dest)) { - { sprintf(monbuf, "Invalid expression in destination address.\n"); monprintf(monbuf); } - } + if (n == 5) { + if (!dexp_eval(args[4], &reps)) { + { + sprintf(monbuf, "Invalid expression in repetition number.\n"); + monprintf(monbuf); + } + } + } + if (n > 3) { + if (!dexp_eval(args[3], &number)) { + { + sprintf(monbuf, "Invalid expression in number of copy units.\n"); + monprintf(monbuf); + } + } + } + if (!dexp_eval(args[1], &source)) { + { + sprintf(monbuf, "Invalid expression in source address.\n"); + monprintf(monbuf); + } + return; + } + if (!dexp_eval(args[2], &dest)) { + { + sprintf(monbuf, "Invalid expression in destination address.\n"); + monprintf(monbuf); + } + } - for (u32 j = 0; j < reps; j++){ - for (u32 i = 0; i < number; i++){ - debuggerWriteByte(dest + i, debuggerReadByte(source + i)); - } - dest += number; - } + for (u32 j = 0; j < reps; j++) { + for (u32 i = 0; i < number; i++) { + debuggerWriteByte(dest + i, debuggerReadByte(source + i)); + } + dest += number; + } } -void debuggerCopyHalfWord(int n, char **args) +void debuggerCopyHalfWord(int n, char** args) { - u32 source; - u32 dest; - u32 number = 2; - u32 reps = 1; - if (n>5 || n<3){ - debuggerUsage("copyh"); - } + u32 source; + u32 dest; + u32 number = 2; + u32 reps = 1; + if (n > 5 || n < 3) { + debuggerUsage("copyh"); + } - if (n == 5) { - if (!dexp_eval(args[4], &reps)) { - { sprintf(monbuf, "Invalid expression in repetition number.\n"); monprintf(monbuf); } - } - } - if (n > 3){ - if (!dexp_eval(args[3], &number)) { - { sprintf(monbuf, "Invalid expression in number of copy units.\n"); monprintf(monbuf); } - } - number = number << 1; - } - if (!dexp_eval(args[1], &source)) { - { sprintf(monbuf, "Invalid expression in source address.\n"); monprintf(monbuf); } - return; - } - if (!dexp_eval(args[2], &dest)) { - { sprintf(monbuf, "Invalid expression in destination address.\n"); monprintf(monbuf); } - } + if (n == 5) { + if (!dexp_eval(args[4], &reps)) { + { + sprintf(monbuf, "Invalid expression in repetition number.\n"); + monprintf(monbuf); + } + } + } + if (n > 3) { + if (!dexp_eval(args[3], &number)) { + { + sprintf(monbuf, "Invalid expression in number of copy units.\n"); + monprintf(monbuf); + } + } + number = number << 1; + } + if (!dexp_eval(args[1], &source)) { + { + sprintf(monbuf, "Invalid expression in source address.\n"); + monprintf(monbuf); + } + return; + } + if (!dexp_eval(args[2], &dest)) { + { + sprintf(monbuf, "Invalid expression in destination address.\n"); + monprintf(monbuf); + } + } - for (u32 j = 0; j < reps; j++){ - for (u32 i = 0; i < number; i += 2){ - debuggerWriteHalfWord(dest + i, debuggerReadHalfWord(source + i)); - } - dest += number; - } + for (u32 j = 0; j < reps; j++) { + for (u32 i = 0; i < number; i += 2) { + debuggerWriteHalfWord(dest + i, debuggerReadHalfWord(source + i)); + } + dest += number; + } } -void debuggerCopyWord(int n, char **args) +void debuggerCopyWord(int n, char** args) { - u32 source; - u32 dest; - u32 number = 4; - u32 reps = 1; - if (n>5 || n<3){ - debuggerUsage("copyw"); - } + u32 source; + u32 dest; + u32 number = 4; + u32 reps = 1; + if (n > 5 || n < 3) { + debuggerUsage("copyw"); + } - if (n == 5) { - if (!dexp_eval(args[4], &reps)) { - { sprintf(monbuf, "Invalid expression in repetition number.\n"); monprintf(monbuf); } - } - } - if (n > 3){ - if (!dexp_eval(args[3], &number)) { - { sprintf(monbuf, "Invalid expression in number of copy units.\n"); monprintf(monbuf); } - } - number = number << 2; - } - if (!dexp_eval(args[1], &source)) { - { sprintf(monbuf, "Invalid expression in source address.\n"); monprintf(monbuf); } - return; - } - if (!dexp_eval(args[2], &dest)) { - { sprintf(monbuf, "Invalid expression in destination address.\n"); monprintf(monbuf); } - } + if (n == 5) { + if (!dexp_eval(args[4], &reps)) { + { + sprintf(monbuf, "Invalid expression in repetition number.\n"); + monprintf(monbuf); + } + } + } + if (n > 3) { + if (!dexp_eval(args[3], &number)) { + { + sprintf(monbuf, "Invalid expression in number of copy units.\n"); + monprintf(monbuf); + } + } + number = number << 2; + } + if (!dexp_eval(args[1], &source)) { + { + sprintf(monbuf, "Invalid expression in source address.\n"); + monprintf(monbuf); + } + return; + } + if (!dexp_eval(args[2], &dest)) { + { + sprintf(monbuf, "Invalid expression in destination address.\n"); + monprintf(monbuf); + } + } - for (u32 j = 0; j < reps; j++){ - for (u32 i = 0; i < number; i += 4){ - debuggerWriteMemory(dest + i, debuggerReadMemory(source + i)); - } - dest += number; - } + for (u32 j = 0; j < reps; j++) { + for (u32 i = 0; i < number; i += 4) { + debuggerWriteMemory(dest + i, debuggerReadMemory(source + i)); + } + dest += number; + } } void debuggerIoVideo() { - { sprintf(monbuf, "DISPCNT = %04x\n", DISPCNT); monprintf(monbuf); } - { sprintf(monbuf, "DISPSTAT = %04x\n", DISPSTAT); monprintf(monbuf); } - { sprintf(monbuf, "VCOUNT = %04x\n", VCOUNT); monprintf(monbuf); } - { sprintf(monbuf, "BG0CNT = %04x\n", BG0CNT); monprintf(monbuf); } - { sprintf(monbuf, "BG1CNT = %04x\n", BG1CNT); monprintf(monbuf); } - { sprintf(monbuf, "BG2CNT = %04x\n", BG2CNT); monprintf(monbuf); } - { sprintf(monbuf, "BG3CNT = %04x\n", BG3CNT); monprintf(monbuf); } - { sprintf(monbuf, "WIN0H = %04x\n", WIN0H); monprintf(monbuf); } - { sprintf(monbuf, "WIN0V = %04x\n", WIN0V); monprintf(monbuf); } - { sprintf(monbuf, "WIN1H = %04x\n", WIN1H); monprintf(monbuf); } - { sprintf(monbuf, "WIN1V = %04x\n", WIN1V); monprintf(monbuf); } - { sprintf(monbuf, "WININ = %04x\n", WININ); monprintf(monbuf); } - { sprintf(monbuf, "WINOUT = %04x\n", WINOUT); monprintf(monbuf); } - { sprintf(monbuf, "MOSAIC = %04x\n", MOSAIC); monprintf(monbuf); } - { sprintf(monbuf, "BLDMOD = %04x\n", BLDMOD); monprintf(monbuf); } - { sprintf(monbuf, "COLEV = %04x\n", COLEV); monprintf(monbuf); } - { sprintf(monbuf, "COLY = %04x\n", COLY); monprintf(monbuf); } + { + sprintf(monbuf, "DISPCNT = %04x\n", DISPCNT); + monprintf(monbuf); + } + { + sprintf(monbuf, "DISPSTAT = %04x\n", DISPSTAT); + monprintf(monbuf); + } + { + sprintf(monbuf, "VCOUNT = %04x\n", VCOUNT); + monprintf(monbuf); + } + { + sprintf(monbuf, "BG0CNT = %04x\n", BG0CNT); + monprintf(monbuf); + } + { + sprintf(monbuf, "BG1CNT = %04x\n", BG1CNT); + monprintf(monbuf); + } + { + sprintf(monbuf, "BG2CNT = %04x\n", BG2CNT); + monprintf(monbuf); + } + { + sprintf(monbuf, "BG3CNT = %04x\n", BG3CNT); + monprintf(monbuf); + } + { + sprintf(monbuf, "WIN0H = %04x\n", WIN0H); + monprintf(monbuf); + } + { + sprintf(monbuf, "WIN0V = %04x\n", WIN0V); + monprintf(monbuf); + } + { + sprintf(monbuf, "WIN1H = %04x\n", WIN1H); + monprintf(monbuf); + } + { + sprintf(monbuf, "WIN1V = %04x\n", WIN1V); + monprintf(monbuf); + } + { + sprintf(monbuf, "WININ = %04x\n", WININ); + monprintf(monbuf); + } + { + sprintf(monbuf, "WINOUT = %04x\n", WINOUT); + monprintf(monbuf); + } + { + sprintf(monbuf, "MOSAIC = %04x\n", MOSAIC); + monprintf(monbuf); + } + { + sprintf(monbuf, "BLDMOD = %04x\n", BLDMOD); + monprintf(monbuf); + } + { + sprintf(monbuf, "COLEV = %04x\n", COLEV); + monprintf(monbuf); + } + { + sprintf(monbuf, "COLY = %04x\n", COLY); + monprintf(monbuf); + } } void debuggerIoVideo2() { - { sprintf(monbuf, "BG0HOFS = %04x\n", BG0HOFS); monprintf(monbuf); } - { sprintf(monbuf, "BG0VOFS = %04x\n", BG0VOFS); monprintf(monbuf); } - { sprintf(monbuf, "BG1HOFS = %04x\n", BG1HOFS); monprintf(monbuf); } - { sprintf(monbuf, "BG1VOFS = %04x\n", BG1VOFS); monprintf(monbuf); } - { sprintf(monbuf, "BG2HOFS = %04x\n", BG2HOFS); monprintf(monbuf); } - { sprintf(monbuf, "BG2VOFS = %04x\n", BG2VOFS); monprintf(monbuf); } - { sprintf(monbuf, "BG3HOFS = %04x\n", BG3HOFS); monprintf(monbuf); } - { sprintf(monbuf, "BG3VOFS = %04x\n", BG3VOFS); monprintf(monbuf); } - { sprintf(monbuf, "BG2PA = %04x\n", BG2PA); monprintf(monbuf); } - { sprintf(monbuf, "BG2PB = %04x\n", BG2PB); monprintf(monbuf); } - { sprintf(monbuf, "BG2PC = %04x\n", BG2PC); monprintf(monbuf); } - { sprintf(monbuf, "BG2PD = %04x\n", BG2PD); monprintf(monbuf); } - { sprintf(monbuf, "BG2X = %08x\n", (BG2X_H << 16) | BG2X_L); monprintf(monbuf); } - { sprintf(monbuf, "BG2Y = %08x\n", (BG2Y_H << 16) | BG2Y_L); monprintf(monbuf); } - { sprintf(monbuf, "BG3PA = %04x\n", BG3PA); monprintf(monbuf); } - { sprintf(monbuf, "BG3PB = %04x\n", BG3PB); monprintf(monbuf); } - { sprintf(monbuf, "BG3PC = %04x\n", BG3PC); monprintf(monbuf); } - { sprintf(monbuf, "BG3PD = %04x\n", BG3PD); monprintf(monbuf); } - { sprintf(monbuf, "BG3X = %08x\n", (BG3X_H << 16) | BG3X_L); monprintf(monbuf); } - { sprintf(monbuf, "BG3Y = %08x\n", (BG3Y_H << 16) | BG3Y_L); monprintf(monbuf); } + { + sprintf(monbuf, "BG0HOFS = %04x\n", BG0HOFS); + monprintf(monbuf); + } + { + sprintf(monbuf, "BG0VOFS = %04x\n", BG0VOFS); + monprintf(monbuf); + } + { + sprintf(monbuf, "BG1HOFS = %04x\n", BG1HOFS); + monprintf(monbuf); + } + { + sprintf(monbuf, "BG1VOFS = %04x\n", BG1VOFS); + monprintf(monbuf); + } + { + sprintf(monbuf, "BG2HOFS = %04x\n", BG2HOFS); + monprintf(monbuf); + } + { + sprintf(monbuf, "BG2VOFS = %04x\n", BG2VOFS); + monprintf(monbuf); + } + { + sprintf(monbuf, "BG3HOFS = %04x\n", BG3HOFS); + monprintf(monbuf); + } + { + sprintf(monbuf, "BG3VOFS = %04x\n", BG3VOFS); + monprintf(monbuf); + } + { + sprintf(monbuf, "BG2PA = %04x\n", BG2PA); + monprintf(monbuf); + } + { + sprintf(monbuf, "BG2PB = %04x\n", BG2PB); + monprintf(monbuf); + } + { + sprintf(monbuf, "BG2PC = %04x\n", BG2PC); + monprintf(monbuf); + } + { + sprintf(monbuf, "BG2PD = %04x\n", BG2PD); + monprintf(monbuf); + } + { + sprintf(monbuf, "BG2X = %08x\n", (BG2X_H << 16) | BG2X_L); + monprintf(monbuf); + } + { + sprintf(monbuf, "BG2Y = %08x\n", (BG2Y_H << 16) | BG2Y_L); + monprintf(monbuf); + } + { + sprintf(monbuf, "BG3PA = %04x\n", BG3PA); + monprintf(monbuf); + } + { + sprintf(monbuf, "BG3PB = %04x\n", BG3PB); + monprintf(monbuf); + } + { + sprintf(monbuf, "BG3PC = %04x\n", BG3PC); + monprintf(monbuf); + } + { + sprintf(monbuf, "BG3PD = %04x\n", BG3PD); + monprintf(monbuf); + } + { + sprintf(monbuf, "BG3X = %08x\n", (BG3X_H << 16) | BG3X_L); + monprintf(monbuf); + } + { + sprintf(monbuf, "BG3Y = %08x\n", (BG3Y_H << 16) | BG3Y_L); + monprintf(monbuf); + } } void debuggerIoDMA() { - { sprintf(monbuf, "DM0SAD = %08x\n", (DM0SAD_H << 16) | DM0SAD_L); monprintf(monbuf); } - { sprintf(monbuf, "DM0DAD = %08x\n", (DM0DAD_H << 16) | DM0DAD_L); monprintf(monbuf); } - { sprintf(monbuf, "DM0CNT = %08x\n", (DM0CNT_H << 16) | DM0CNT_L); monprintf(monbuf); } - { sprintf(monbuf, "DM1SAD = %08x\n", (DM1SAD_H << 16) | DM1SAD_L); monprintf(monbuf); } - { sprintf(monbuf, "DM1DAD = %08x\n", (DM1DAD_H << 16) | DM1DAD_L); monprintf(monbuf); } - { sprintf(monbuf, "DM1CNT = %08x\n", (DM1CNT_H << 16) | DM1CNT_L); monprintf(monbuf); } - { sprintf(monbuf, "DM2SAD = %08x\n", (DM2SAD_H << 16) | DM2SAD_L); monprintf(monbuf); } - { sprintf(monbuf, "DM2DAD = %08x\n", (DM2DAD_H << 16) | DM2DAD_L); monprintf(monbuf); } - { sprintf(monbuf, "DM2CNT = %08x\n", (DM2CNT_H << 16) | DM2CNT_L); monprintf(monbuf); } - { sprintf(monbuf, "DM3SAD = %08x\n", (DM3SAD_H << 16) | DM3SAD_L); monprintf(monbuf); } - { sprintf(monbuf, "DM3DAD = %08x\n", (DM3DAD_H << 16) | DM3DAD_L); monprintf(monbuf); } - { sprintf(monbuf, "DM3CNT = %08x\n", (DM3CNT_H << 16) | DM3CNT_L); monprintf(monbuf); } + { + sprintf(monbuf, "DM0SAD = %08x\n", (DM0SAD_H << 16) | DM0SAD_L); + monprintf(monbuf); + } + { + sprintf(monbuf, "DM0DAD = %08x\n", (DM0DAD_H << 16) | DM0DAD_L); + monprintf(monbuf); + } + { + sprintf(monbuf, "DM0CNT = %08x\n", (DM0CNT_H << 16) | DM0CNT_L); + monprintf(monbuf); + } + { + sprintf(monbuf, "DM1SAD = %08x\n", (DM1SAD_H << 16) | DM1SAD_L); + monprintf(monbuf); + } + { + sprintf(monbuf, "DM1DAD = %08x\n", (DM1DAD_H << 16) | DM1DAD_L); + monprintf(monbuf); + } + { + sprintf(monbuf, "DM1CNT = %08x\n", (DM1CNT_H << 16) | DM1CNT_L); + monprintf(monbuf); + } + { + sprintf(monbuf, "DM2SAD = %08x\n", (DM2SAD_H << 16) | DM2SAD_L); + monprintf(monbuf); + } + { + sprintf(monbuf, "DM2DAD = %08x\n", (DM2DAD_H << 16) | DM2DAD_L); + monprintf(monbuf); + } + { + sprintf(monbuf, "DM2CNT = %08x\n", (DM2CNT_H << 16) | DM2CNT_L); + monprintf(monbuf); + } + { + sprintf(monbuf, "DM3SAD = %08x\n", (DM3SAD_H << 16) | DM3SAD_L); + monprintf(monbuf); + } + { + sprintf(monbuf, "DM3DAD = %08x\n", (DM3DAD_H << 16) | DM3DAD_L); + monprintf(monbuf); + } + { + sprintf(monbuf, "DM3CNT = %08x\n", (DM3CNT_H << 16) | DM3CNT_L); + monprintf(monbuf); + } } void debuggerIoTimer() { - { sprintf(monbuf, "TM0D = %04x\n", TM0D); monprintf(monbuf); } - { sprintf(monbuf, "TM0CNT = %04x\n", TM0CNT); monprintf(monbuf); } - { sprintf(monbuf, "TM1D = %04x\n", TM1D); monprintf(monbuf); } - { sprintf(monbuf, "TM1CNT = %04x\n", TM1CNT); monprintf(monbuf); } - { sprintf(monbuf, "TM2D = %04x\n", TM2D); monprintf(monbuf); } - { sprintf(monbuf, "TM2CNT = %04x\n", TM2CNT); monprintf(monbuf); } - { sprintf(monbuf, "TM3D = %04x\n", TM3D); monprintf(monbuf); } - { sprintf(monbuf, "TM3CNT = %04x\n", TM3CNT); monprintf(monbuf); } + { + sprintf(monbuf, "TM0D = %04x\n", TM0D); + monprintf(monbuf); + } + { + sprintf(monbuf, "TM0CNT = %04x\n", TM0CNT); + monprintf(monbuf); + } + { + sprintf(monbuf, "TM1D = %04x\n", TM1D); + monprintf(monbuf); + } + { + sprintf(monbuf, "TM1CNT = %04x\n", TM1CNT); + monprintf(monbuf); + } + { + sprintf(monbuf, "TM2D = %04x\n", TM2D); + monprintf(monbuf); + } + { + sprintf(monbuf, "TM2CNT = %04x\n", TM2CNT); + monprintf(monbuf); + } + { + sprintf(monbuf, "TM3D = %04x\n", TM3D); + monprintf(monbuf); + } + { + sprintf(monbuf, "TM3CNT = %04x\n", TM3CNT); + monprintf(monbuf); + } } void debuggerIoMisc() { - { sprintf(monbuf, "P1 = %04x\n", P1); monprintf(monbuf); } - { sprintf(monbuf, "IE = %04x\n", IE); monprintf(monbuf); } - { sprintf(monbuf, "IF = %04x\n", IF); monprintf(monbuf); } - { sprintf(monbuf, "IME = %04x\n", IME); monprintf(monbuf); } + { + sprintf(monbuf, "P1 = %04x\n", P1); + monprintf(monbuf); + } + { + sprintf(monbuf, "IE = %04x\n", IE); + monprintf(monbuf); + } + { + sprintf(monbuf, "IF = %04x\n", IF); + monprintf(monbuf); + } + { + sprintf(monbuf, "IME = %04x\n", IME); + monprintf(monbuf); + } } -void debuggerIo(int n, char **args) +void debuggerIo(int n, char** args) { - if (n == 1) { - debuggerIoVideo(); - return; - } - if (!strcmp(args[1], "video")) - debuggerIoVideo(); - else if (!strcmp(args[1], "video2")) - debuggerIoVideo2(); - else if (!strcmp(args[1], "dma")) - debuggerIoDMA(); - else if (!strcmp(args[1], "timer")) - debuggerIoTimer(); - else if (!strcmp(args[1], "misc")) - debuggerIoMisc(); - else { sprintf(monbuf, "Unrecognized option %s\n", args[1]); monprintf(monbuf); } + if (n == 1) { + debuggerIoVideo(); + return; + } + if (!strcmp(args[1], "video")) + debuggerIoVideo(); + else if (!strcmp(args[1], "video2")) + debuggerIoVideo2(); + else if (!strcmp(args[1], "dma")) + debuggerIoDMA(); + else if (!strcmp(args[1], "timer")) + debuggerIoTimer(); + else if (!strcmp(args[1], "misc")) + debuggerIoMisc(); + else { + sprintf(monbuf, "Unrecognized option %s\n", args[1]); + monprintf(monbuf); + } } -#define ASCII(c) (c) < 32 ? '.' : (c) > 127 ? '.' : (c) +#define ASCII(c) (c)<32 ? '.' : (c)> 127 ? '.' : (c) bool canUseTbl = true; bool useWordSymbol = false; @@ -1088,618 +1454,768 @@ bool isNewline[256]; bool isTab[256]; u8 largestSymbol = 1; -void freeWordSymbolContents(){ - for (int i = 0; i<256; i++){ - if (wordSymbol[i]) - free(wordSymbol[i]); - wordSymbol[i] = NULL; - isTerminator[i] = false; - isNewline[i] = false; - isTab[i] = false; - } -} - -void freeWordSymbol(){ - useWordSymbol = false; - thereIsATable = false; - free(wordSymbol); - largestSymbol = 1; -} - -void debuggerReadCharTable(int n, char** args){ - if (n == 2){ - if (!canUseTbl){ - { sprintf(monbuf, "Cannot operate over character table, as it was disabled.\n"); monprintf(monbuf); } - return; - } - if (strcmp(args[1], "none") == 0){ - freeWordSymbol(); - { sprintf(monbuf, "Cleared table. Reverted to ASCII.\n"); monprintf(monbuf); } - return; - } - FILE* tlb = fopen(args[1], "r"); - if (!tlb){ - { sprintf(monbuf, "Could not open specified file. Abort.\n"); monprintf(monbuf); } - return; - } - char buffer[30]; - u32 slot; - char* character = (char*)calloc(10, sizeof(char)); - wordSymbol = (char**)calloc(256, sizeof(char*)); - while (fgets(buffer, 30, tlb)){ - - sscanf(buffer, "%02x=%s", &slot, character); - - if (character[0]){ - if (strlen(character) == 4){ - if ((character[0] == '<') && - (character[1] == '\\') && - (character[3] == '>')){ - if (character[2] == '0'){ - isTerminator[slot] = true; - }if (character[2] == 'n'){ - isNewline[slot] = true; - }if (character[2] == 't'){ - isTab[slot] = true; - } - continue; - } - else - wordSymbol[slot] = character; - } - else - wordSymbol[slot] = character; - } - else - wordSymbol[slot] = " "; - - if (largestSymbol < strlen(character)) - largestSymbol = strlen(character); - - character = (char*)malloc(10); - } - useWordSymbol = true; - thereIsATable = true; - - } - else{ - debuggerUsage("tbl"); - } -} - -void printCharGroup(u32 addr, bool useAscii){ - for (int i = 0; i<16; i++){ - if (useWordSymbol && !useAscii){ - char* c = wordSymbol[debuggerReadByte(addr + i)]; - int j; - if (c){ - { sprintf(monbuf, "%s", c); monprintf(monbuf); } - j = strlen(c); - } - else{ - j = 0; - } - while (j')) { + if (character[2] == '0') { + isTerminator[slot] = true; + } + if (character[2] == 'n') { + isNewline[slot] = true; + } + if (character[2] == 't') { + isTab[slot] = true; + } + continue; + } else + wordSymbol[slot] = character; + } else + wordSymbol[slot] = character; + } else + wordSymbol[slot] = " "; + + if (largestSymbol < strlen(character)) + largestSymbol = strlen(character); + + character = (char*)malloc(10); + } + useWordSymbol = true; + thereIsATable = true; + + } else { + debuggerUsage("tbl"); + } } -void debuggerStringRead(int n, char **args){ - if (n == 2) { - u32 addr = 0; - - if (!dexp_eval(args[1], &addr)){ - { sprintf(monbuf, "Invalid expression\n"); monprintf(monbuf); } - return; - } - for (int i = 0; i<512; i++){ - u8 slot = debuggerReadByte(addr + i); - - if (useWordSymbol){ - if (isTerminator[slot]){ - { sprintf(monbuf, "\n"); monprintf(monbuf); } - return; - } - else if (isNewline[slot]) { - { sprintf(monbuf, "\n"); monprintf(monbuf); } - } - else if (isTab[slot]) { - { sprintf(monbuf, "\t"); monprintf(monbuf); } - } - else { - if (wordSymbol[slot]){ - { sprintf(monbuf, "%s", wordSymbol[slot]); monprintf(monbuf); } - } - } - } - else { - { sprintf(monbuf, "%c", ASCII(slot)); monprintf(monbuf); } - } - } - } - else - debuggerUsage("ms"); -} - -void debuggerRegisters(int, char **) +void printCharGroup(u32 addr, bool useAscii) { - { sprintf(monbuf, "R00=%08x R04=%08x R08=%08x R12=%08x\n", reg[0].I, reg[4].I, reg[8].I, reg[12].I); monprintf(monbuf); } - { sprintf(monbuf, "R01=%08x R05=%08x R09=%08x R13=%08x\n", reg[1].I, reg[5].I, reg[9].I, reg[13].I); monprintf(monbuf); } - { sprintf(monbuf, "R02=%08x R06=%08x R10=%08x R14=%08x\n", reg[2].I, reg[6].I, reg[10].I, reg[14].I); monprintf(monbuf); } - { sprintf(monbuf, "R03=%08x R07=%08x R11=%08x R15=%08x\n", reg[3].I, reg[7].I, reg[11].I, reg[15].I); monprintf(monbuf); } - { sprintf(monbuf, "CPSR=%08x (%c%c%c%c%c%c%c Mode: %02x)\n", - reg[16].I, - (N_FLAG ? 'N' : '.'), - (Z_FLAG ? 'Z' : '.'), - (C_FLAG ? 'C' : '.'), - (V_FLAG ? 'V' : '.'), - (armIrqEnable ? '.' : 'I'), - ((!(reg[16].I & 0x40)) ? '.' : 'F'), - (armState ? '.' : 'T'), - armMode); - monprintf(monbuf); } + for (int i = 0; i < 16; i++) { + if (useWordSymbol && !useAscii) { + char* c = wordSymbol[debuggerReadByte(addr + i)]; + int j; + if (c) { + { + sprintf(monbuf, "%s", c); + monprintf(monbuf); + } + j = strlen(c); + } else { + j = 0; + } + while (j < largestSymbol) { + { + sprintf(monbuf, " "); + monprintf(monbuf); + } + j++; + } + } else { + { + sprintf(monbuf, "%c", ASCII(debuggerReadByte(addr + i))); + monprintf(monbuf); + } + } + } } -void debuggerExecuteCommands(int n, char** args){ - if (n == 1){ - { sprintf(monbuf, "%s requires at least one pathname to execute.", args[0]); monprintf(monbuf); } - return; - } - else{ - char buffer[4096]; - n--; - args++; - while (n){ - FILE* toExec = fopen(args[0], "r"); - if (toExec){ - while (fgets(buffer, 4096, toExec)){ - std::string buf(buffer); - dbgExecute(buf); - if (!debugger || !emulating){ - return; - } - } - } - else - { sprintf(monbuf, "Could not open %s. Will not be executed.\n", args[0]); monprintf(monbuf); } - - args++; - n--; - } - } -} - -void debuggerSetRadix(int argc, char **argv) +void debuggerMemoryByte(int n, char** args) { - if (argc != 2) - debuggerUsage(argv[0]); - else { - int r = atoi(argv[1]); + if (n == 2) { + u32 addr = 0; - bool error = false; - switch (r) { - case 10: - debuggerRadix = 0; - break; - case 8: - debuggerRadix = 2; - break; - case 16: - debuggerRadix = 1; - break; - default: - error = true; - { sprintf(monbuf, "Unknown radix %d. Valid values are 8, 10 and 16.\n", r); monprintf(monbuf); } - break; - } - if (!error) - { sprintf(monbuf, "Radix set to %d\n", r); monprintf(monbuf); } - } + if (!dexp_eval(args[1], &addr)) { + { + sprintf(monbuf, "Invalid expression\n"); + monprintf(monbuf); + } + return; + } + for (int loop = 0; loop < 16; loop++) { + { + sprintf(monbuf, "%08x ", addr); + monprintf(monbuf); + } + for (int j = 0; j < 16; j++) { + { + sprintf(monbuf, "%02x ", debuggerReadByte(addr + j)); + monprintf(monbuf); + } + } + printCharGroup(addr, true); + { + sprintf(monbuf, "\n"); + monprintf(monbuf); + } + addr += 16; + } + } else + debuggerUsage("mb"); } -void debuggerSymbols(int argc, char **argv) +void debuggerMemoryHalfWord(int n, char** args) { - int i = 0; - u32 value; - u32 size; - int type; - bool match = false; - int matchSize = 0; - char *matchStr = NULL; + if (n == 2) { + u32 addr = 0; - if (argc == 2) { - match = true; - matchSize = strlen(argv[1]); - matchStr = argv[1]; - } - { sprintf(monbuf, "Symbol Value Size Type \n"); monprintf(monbuf); } - { sprintf(monbuf, "-------------------- ------- -------- -------\n"); monprintf(monbuf); } - const char *s = NULL; - while ((s = elfGetSymbol(i, &value, &size, &type))) { - if (*s) { - if (match) { - if (strncmp(s, matchStr, matchSize) != 0) { - i++; - continue; - } - } - const char *ts = "?"; - switch (type) { - case 2: - ts = "ARM"; - break; - case 0x0d: - ts = "THUMB"; - break; - case 1: - ts = "DATA"; - break; - } - { sprintf(monbuf, "%-20s %08x %08x %-7s\n", s, value, size, ts); monprintf(monbuf); } - } - i++; - } + if (!dexp_eval(args[1], &addr)) { + { + sprintf(monbuf, "Invalid expression\n"); + monprintf(monbuf); + } + return; + } + + addr = addr & 0xfffffffe; + + for (int loop = 0; loop < 16; loop++) { + { + sprintf(monbuf, "%08x ", addr); + monprintf(monbuf); + } + for (int j = 0; j < 16; j += 2) { + { + sprintf(monbuf, "%02x%02x ", debuggerReadByte(addr + j + 1), debuggerReadByte(addr + j)); + monprintf(monbuf); + } + } + printCharGroup(addr, true); + { + sprintf(monbuf, "\n"); + monprintf(monbuf); + } + addr += 16; + } + } else + debuggerUsage("mh"); } -void debuggerWhere(int n, char **args) +void debuggerMemoryWord(int n, char** args) { - void elfPrintCallChain(u32); - elfPrintCallChain(armNextPC); + if (n == 2) { + u32 addr = 0; + if (!dexp_eval(args[1], &addr)) { + { + sprintf(monbuf, "Invalid expression\n"); + monprintf(monbuf); + } + return; + } + addr = addr & 0xfffffffc; + for (int loop = 0; loop < 16; loop++) { + { + sprintf(monbuf, "%08x ", addr); + monprintf(monbuf); + } + for (int j = 0; j < 16; j += 4) { + { + sprintf(monbuf, "%02x%02x%02x%02x ", debuggerReadByte(addr + j + 3), debuggerReadByte(addr + j + 2), debuggerReadByte(addr + j + 1), debuggerReadByte(addr + j)); + monprintf(monbuf); + } + } + printCharGroup(addr, true); + { + sprintf(monbuf, "\n"); + monprintf(monbuf); + } + addr += 16; + } + } else + debuggerUsage("mw"); } -void debuggerVar(int n, char **args) +void debuggerStringRead(int n, char** args) { - u32 val; + if (n == 2) { + u32 addr = 0; - if (n < 2) { - dexp_listVars(); - return; - } + if (!dexp_eval(args[1], &addr)) { + { + sprintf(monbuf, "Invalid expression\n"); + monprintf(monbuf); + } + return; + } + for (int i = 0; i < 512; i++) { + u8 slot = debuggerReadByte(addr + i); - if (strcmp(args[1], "set") == 0) { + if (useWordSymbol) { + if (isTerminator[slot]) { + { + sprintf(monbuf, "\n"); + monprintf(monbuf); + } + return; + } else if (isNewline[slot]) { + { + sprintf(monbuf, "\n"); + monprintf(monbuf); + } + } else if (isTab[slot]) { + { + sprintf(monbuf, "\t"); + monprintf(monbuf); + } + } else { + if (wordSymbol[slot]) { + { + sprintf(monbuf, "%s", wordSymbol[slot]); + monprintf(monbuf); + } + } + } + } else { + { + sprintf(monbuf, "%c", ASCII(slot)); + monprintf(monbuf); + } + } + } + } else + debuggerUsage("ms"); +} - if (n < 4) { - { sprintf(monbuf, "No expression specified.\n"); monprintf(monbuf); } - return; - } +void debuggerRegisters(int, char**) +{ + { + sprintf(monbuf, "R00=%08x R04=%08x R08=%08x R12=%08x\n", reg[0].I, reg[4].I, reg[8].I, reg[12].I); + monprintf(monbuf); + } + { + sprintf(monbuf, "R01=%08x R05=%08x R09=%08x R13=%08x\n", reg[1].I, reg[5].I, reg[9].I, reg[13].I); + monprintf(monbuf); + } + { + sprintf(monbuf, "R02=%08x R06=%08x R10=%08x R14=%08x\n", reg[2].I, reg[6].I, reg[10].I, reg[14].I); + monprintf(monbuf); + } + { + sprintf(monbuf, "R03=%08x R07=%08x R11=%08x R15=%08x\n", reg[3].I, reg[7].I, reg[11].I, reg[15].I); + monprintf(monbuf); + } + { + sprintf(monbuf, "CPSR=%08x (%c%c%c%c%c%c%c Mode: %02x)\n", + reg[16].I, + (N_FLAG ? 'N' : '.'), + (Z_FLAG ? 'Z' : '.'), + (C_FLAG ? 'C' : '.'), + (V_FLAG ? 'V' : '.'), + (armIrqEnable ? '.' : 'I'), + ((!(reg[16].I & 0x40)) ? '.' : 'F'), + (armState ? '.' : 'T'), + armMode); + monprintf(monbuf); + } +} - if (!dexp_eval(args[3], &val)){ - { sprintf(monbuf, "Invalid expression.\n"); monprintf(monbuf); } - return; - } +void debuggerExecuteCommands(int n, char** args) +{ + if (n == 1) { + { + sprintf(monbuf, "%s requires at least one pathname to execute.", args[0]); + monprintf(monbuf); + } + return; + } else { + char buffer[4096]; + n--; + args++; + while (n) { + FILE* toExec = fopen(args[0], "r"); + if (toExec) { + while (fgets(buffer, 4096, toExec)) { + std::string buf(buffer); + dbgExecute(buf); + if (!debugger || !emulating) { + return; + } + } + } else { + sprintf(monbuf, "Could not open %s. Will not be executed.\n", args[0]); + monprintf(monbuf); + } - dexp_setVar(args[2], val); - { sprintf(monbuf, "%s = $%08x\n", args[2], val); monprintf(monbuf); } - return; - } + args++; + n--; + } + } +} - if (strcmp(args[1], "list") == 0) { - dexp_listVars(); - return; - } +void debuggerSetRadix(int argc, char** argv) +{ + if (argc != 2) + debuggerUsage(argv[0]); + else { + int r = atoi(argv[1]); - if (strcmp(args[1], "save") == 0) { - if (n < 3) { - { sprintf(monbuf, "No file specified.\n"); monprintf(monbuf); } - return; - } - dexp_saveVars(args[2]); - return; - } + bool error = false; + switch (r) { + case 10: + debuggerRadix = 0; + break; + case 8: + debuggerRadix = 2; + break; + case 16: + debuggerRadix = 1; + break; + default: + error = true; + { + sprintf(monbuf, "Unknown radix %d. Valid values are 8, 10 and 16.\n", r); + monprintf(monbuf); + } + break; + } + if (!error) { + sprintf(monbuf, "Radix set to %d\n", r); + monprintf(monbuf); + } + } +} - if (strcmp(args[1], "load") == 0) { - if (n < 3){ - { sprintf(monbuf, "No file specified.\n"); monprintf(monbuf); } - return; - } - dexp_loadVars(args[2]); - return; - } +void debuggerSymbols(int argc, char** argv) +{ + int i = 0; + u32 value; + u32 size; + int type; + bool match = false; + int matchSize = 0; + char* matchStr = NULL; - { sprintf(monbuf, "Unrecognized sub-command.\n"); monprintf(monbuf); } + if (argc == 2) { + match = true; + matchSize = strlen(argv[1]); + matchStr = argv[1]; + } + { + sprintf(monbuf, "Symbol Value Size Type \n"); + monprintf(monbuf); + } + { + sprintf(monbuf, "-------------------- ------- -------- -------\n"); + monprintf(monbuf); + } + const char* s = NULL; + while ((s = elfGetSymbol(i, &value, &size, &type))) { + if (*s) { + if (match) { + if (strncmp(s, matchStr, matchSize) != 0) { + i++; + continue; + } + } + const char* ts = "?"; + switch (type) { + case 2: + ts = "ARM"; + break; + case 0x0d: + ts = "THUMB"; + break; + case 1: + ts = "DATA"; + break; + } + { + sprintf(monbuf, "%-20s %08x %08x %-7s\n", s, value, size, ts); + monprintf(monbuf); + } + } + i++; + } +} +void debuggerWhere(int n, char** args) +{ + void elfPrintCallChain(u32); + elfPrintCallChain(armNextPC); +} + +void debuggerVar(int n, char** args) +{ + u32 val; + + if (n < 2) { + dexp_listVars(); + return; + } + + if (strcmp(args[1], "set") == 0) { + + if (n < 4) { + { + sprintf(monbuf, "No expression specified.\n"); + monprintf(monbuf); + } + return; + } + + if (!dexp_eval(args[3], &val)) { + { + sprintf(monbuf, "Invalid expression.\n"); + monprintf(monbuf); + } + return; + } + + dexp_setVar(args[2], val); + { + sprintf(monbuf, "%s = $%08x\n", args[2], val); + monprintf(monbuf); + } + return; + } + + if (strcmp(args[1], "list") == 0) { + dexp_listVars(); + return; + } + + if (strcmp(args[1], "save") == 0) { + if (n < 3) { + { + sprintf(monbuf, "No file specified.\n"); + monprintf(monbuf); + } + return; + } + dexp_saveVars(args[2]); + return; + } + + if (strcmp(args[1], "load") == 0) { + if (n < 3) { + { + sprintf(monbuf, "No file specified.\n"); + monprintf(monbuf); + } + return; + } + dexp_loadVars(args[2]); + return; + } + + { + sprintf(monbuf, "Unrecognized sub-command.\n"); + monprintf(monbuf); + } } bool debuggerBreakOnExecution(u32 address, u8 state) { - if (dontBreakNow) - return false; - if (debuggerInDB(address)) - return false; - if (!doesBreak(address, armState ? 0x44 : 0x88)) - return false; + if (dontBreakNow) + return false; + if (debuggerInDB(address)) + return false; + if (!doesBreak(address, armState ? 0x44 : 0x88)) + return false; - { sprintf(monbuf, "Breakpoint (on %s) address %08x\n", (armState ? "ARM" : "Thumb"), address); monprintf(monbuf); } - debugger = true; - return true; + { + sprintf(monbuf, "Breakpoint (on %s) address %08x\n", (armState ? "ARM" : "Thumb"), address); + monprintf(monbuf); + } + debugger = true; + return true; } bool debuggerBreakOnRead(u32 address, int size) { - if (dontBreakNow) - return false; - if (debuggerInDB(armState ? reg[15].I - 4 : reg[15].I - 2)) - return false; - if (!doesBreak(address, 0x22)) - return false; - //if (size == 2) - // monprintf("Breakpoint (on read) address %08x value:%08x\n", - // address, debuggerReadMemory(address)); - //else if (size == 1) - // monprintf("Breakpoint (on read) address %08x value:%04x\n", - // address, debuggerReadHalfWord(address)); - //else - // monprintf("Breakpoint (on read) address %08x value:%02x\n", - // address, debuggerReadByte(address)); - debugger = true; - return true; - + if (dontBreakNow) + return false; + if (debuggerInDB(armState ? reg[15].I - 4 : reg[15].I - 2)) + return false; + if (!doesBreak(address, 0x22)) + return false; + //if (size == 2) + // monprintf("Breakpoint (on read) address %08x value:%08x\n", + // address, debuggerReadMemory(address)); + //else if (size == 1) + // monprintf("Breakpoint (on read) address %08x value:%04x\n", + // address, debuggerReadHalfWord(address)); + //else + // monprintf("Breakpoint (on read) address %08x value:%02x\n", + // address, debuggerReadByte(address)); + debugger = true; + return true; } bool debuggerBreakOnWrite(u32 address, u32 value, int size) { - if (dontBreakNow) - return false; - if (debuggerInDB(armState ? reg[15].I - 4 : reg[15].I - 2)) - return false; - if (!doesBreak(address, 0x11)) - return false; - //u32 lastValue; - //dexp_eval("old_value", &lastValue); - //if (size == 2) - // monprintf("Breakpoint (on write) address %08x old:%08x new:%08x\n", - // address, lastValue, value); - //else if (size == 1) - // monprintf("Breakpoint (on write) address %08x old:%04x new:%04x\n", - // address, (u16)lastValue, (u16)value); - //else - // monprintf("Breakpoint (on write) address %08x old:%02x new:%02x\n", - // address, (u8)lastValue, (u8)value); - debugger = true; - return true; + if (dontBreakNow) + return false; + if (debuggerInDB(armState ? reg[15].I - 4 : reg[15].I - 2)) + return false; + if (!doesBreak(address, 0x11)) + return false; + //u32 lastValue; + //dexp_eval("old_value", &lastValue); + //if (size == 2) + // monprintf("Breakpoint (on write) address %08x old:%08x new:%08x\n", + // address, lastValue, value); + //else if (size == 1) + // monprintf("Breakpoint (on write) address %08x old:%04x new:%04x\n", + // address, (u16)lastValue, (u16)value); + //else + // monprintf("Breakpoint (on write) address %08x old:%02x new:%02x\n", + // address, (u8)lastValue, (u8)value); + debugger = true; + return true; } -void debuggerBreakOnWrite(u32 address, u32 oldvalue, u32 value, int size, int t) +void debuggerBreakOnWrite(u32 address, u32 oldvalue, u32 value, int size, int t) { - debuggerBreakOnWrite(address, value, size); - //u32 lastValue; - //dexp_eval("old_value", &lastValue); + debuggerBreakOnWrite(address, value, size); + //u32 lastValue; + //dexp_eval("old_value", &lastValue); - //const char *type = "write"; - //if (t == 2) - // type = "change"; + //const char *type = "write"; + //if (t == 2) + // type = "change"; - //if (size == 2) - // monprintf("Breakpoint (on %s) address %08x old:%08x new:%08x\n", - // type, address, oldvalue, value); - //else if (size == 1) - // monprintf("Breakpoint (on %s) address %08x old:%04x new:%04x\n", - // type, address, (u16)oldvalue, (u16)value); - //else - // monprintf("Breakpoint (on %s) address %08x old:%02x new:%02x\n", - // type, address, (u8)oldvalue, (u8)value); - //debugger = true; + //if (size == 2) + // monprintf("Breakpoint (on %s) address %08x old:%08x new:%08x\n", + // type, address, oldvalue, value); + //else if (size == 1) + // monprintf("Breakpoint (on %s) address %08x old:%04x new:%04x\n", + // type, address, (u16)oldvalue, (u16)value); + //else + // monprintf("Breakpoint (on %s) address %08x old:%02x new:%02x\n", + // type, address, (u8)oldvalue, (u8)value); + //debugger = true; } -u8 getFlags(char* flagName){ +u8 getFlags(char* flagName) +{ - for (int i = 0; flagName[i] != '\0'; i++){ - flagName[i] = toupper(flagName[i]); - } + for (int i = 0; flagName[i] != '\0'; i++) { + flagName[i] = toupper(flagName[i]); + } - if (strcmp(flagName, "ALWAYS") == 0){ - return 0x7; - } + if (strcmp(flagName, "ALWAYS") == 0) { + return 0x7; + } - if (strcmp(flagName, "NEVER") == 0){ - return 0x0; - } + if (strcmp(flagName, "NEVER") == 0) { + return 0x0; + } - u8 flag = 0; + u8 flag = 0; - bool negate_flag = false; - - for (int i = 0; flagName[i] != '\0'; i++){ - switch (flagName[i]){ - case 'E': flag |= 1; - break; - case 'G': flag |= 2; - break; - case 'L': flag |= 4; - break; - case 'S': flag |= 8; - break; - case 'U': flag &= 7; - break; - case 'N': negate_flag = (!negate_flag); - break; - } - } - if (negate_flag){ - flag = ((flag & 8) | ((~flag) & 7)); - } - return flag; + bool negate_flag = false; + for (int i = 0; flagName[i] != '\0'; i++) { + switch (flagName[i]) { + case 'E': + flag |= 1; + break; + case 'G': + flag |= 2; + break; + case 'L': + flag |= 4; + break; + case 'S': + flag |= 8; + break; + case 'U': + flag &= 7; + break; + case 'N': + negate_flag = (!negate_flag); + break; + } + } + if (negate_flag) { + flag = ((flag & 8) | ((~flag) & 7)); + } + return flag; } -void debuggerBreakRegister(int n, char** args){ - if (n != 3){ - { sprintf(monbuf, "Incorrect usage of breg. Correct usage is breg {flag} {value}\n"); monprintf(monbuf); } - printFlagHelp(); - return; - } - u8 reg = (u8)getRegisterNumber(args[0]); - u8 flag = getFlags(args[1]); - u32 value; - if (!dexp_eval(args[2], &value)){ - { sprintf(monbuf, "Invalid expression.\n"); monprintf(monbuf); } - return; - } - if (flag != 0){ - addBreakRegToList(reg, flag, value); - { sprintf(monbuf, "Added breakpoint on register R%02d, value %08x\n", reg, value); monprintf(monbuf); } - } - return; +void debuggerBreakRegister(int n, char** args) +{ + if (n != 3) { + { + sprintf(monbuf, "Incorrect usage of breg. Correct usage is breg {flag} {value}\n"); + monprintf(monbuf); + } + printFlagHelp(); + return; + } + u8 reg = (u8)getRegisterNumber(args[0]); + u8 flag = getFlags(args[1]); + u32 value; + if (!dexp_eval(args[2], &value)) { + { + sprintf(monbuf, "Invalid expression.\n"); + monprintf(monbuf); + } + return; + } + if (flag != 0) { + addBreakRegToList(reg, flag, value); + { + sprintf(monbuf, "Added breakpoint on register R%02d, value %08x\n", reg, value); + monprintf(monbuf); + } + } + return; } -void debuggerBreakRegisterClear(int n, char** args){ - if (n > 0){ - int r = getRegisterNumber(args[0]); - if (r >= 0){ - clearParticularRegListBreaks(r); - { sprintf(monbuf, "Cleared all Register breakpoints for %s.\n", args[0]); monprintf(monbuf); } - } - } - else{ - clearBreakRegList(); - { sprintf(monbuf, "Cleared all Register breakpoints.\n"); monprintf(monbuf); } - } +void debuggerBreakRegisterClear(int n, char** args) +{ + if (n > 0) { + int r = getRegisterNumber(args[0]); + if (r >= 0) { + clearParticularRegListBreaks(r); + { + sprintf(monbuf, "Cleared all Register breakpoints for %s.\n", args[0]); + monprintf(monbuf); + } + } + } else { + clearBreakRegList(); + { + sprintf(monbuf, "Cleared all Register breakpoints.\n"); + monprintf(monbuf); + } + } } -void debuggerBreakRegisterDelete(int n, char** args){ - if (n < 2){ - { sprintf(monbuf, "Illegal use of Break register delete:\n Correct usage requires .\n"); monprintf(monbuf); } - return; - } - int r = getRegisterNumber(args[0]); - if ((r < 0) || (r>16)){ - { sprintf(monbuf, "Could not find a correct register number:\n Correct usage requires .\n"); monprintf(monbuf); } - return; - } - u32 num; - if (!dexp_eval(args[1], &num)){ - { sprintf(monbuf, "Could not parse the breakpoint number:\n Correct usage requires .\n"); monprintf(monbuf); } - return; - } - deleteFromBreakRegList(r, num); - { sprintf(monbuf, "Deleted Breakpoint %d of regsiter %s.\n", num, args[0]); monprintf(monbuf); } +void debuggerBreakRegisterDelete(int n, char** args) +{ + if (n < 2) { + { + sprintf(monbuf, "Illegal use of Break register delete:\n Correct usage requires .\n"); + monprintf(monbuf); + } + return; + } + int r = getRegisterNumber(args[0]); + if ((r < 0) || (r > 16)) { + { + sprintf(monbuf, "Could not find a correct register number:\n Correct usage requires .\n"); + monprintf(monbuf); + } + return; + } + u32 num; + if (!dexp_eval(args[1], &num)) { + { + sprintf(monbuf, "Could not parse the breakpoint number:\n Correct usage requires .\n"); + monprintf(monbuf); + } + return; + } + deleteFromBreakRegList(r, num); + { + sprintf(monbuf, "Deleted Breakpoint %d of regsiter %s.\n", num, args[0]); + monprintf(monbuf); + } } //WARNING: Some old particle to new code conversion may convert a single command //into two or more words. Such words are separated by space, so a new tokenizer can //find them. -const char* replaceAlias(const char* lower_cmd, const char** aliasTable){ - for (int i = 0; aliasTable[i]; i = i + 2){ - if (strcmp(lower_cmd, aliasTable[i]) == 0){ - return aliasTable[i + 1]; - } - } - return lower_cmd; +const char* replaceAlias(const char* lower_cmd, const char** aliasTable) +{ + for (int i = 0; aliasTable[i]; i = i + 2) { + if (strcmp(lower_cmd, aliasTable[i]) == 0) { + return aliasTable[i + 1]; + } + } + return lower_cmd; } const char* breakAliasTable[] = { - //actual beginning - "break", "b 0 0", - "breakpoint", "b 0 0", - "bp", "b 0 0", - "b", "b 0 0", + //actual beginning + "break", "b 0 0", + "breakpoint", "b 0 0", + "bp", "b 0 0", + "b", "b 0 0", - //break types - "thumb", "t", - "arm", "a", - "execution", "x", - "exec", "x", - "e", "x", - "exe", "x", - "x", "x", - "read", "r", - "write", "w", - "access", "i", - "acc", "i", - "io", "i", - "register", "g", - "reg", "g", - "any", "*", + //break types + "thumb", "t", + "arm", "a", + "execution", "x", + "exec", "x", + "e", "x", + "exe", "x", + "x", "x", + "read", "r", + "write", "w", + "access", "i", + "acc", "i", + "io", "i", + "register", "g", + "reg", "g", + "any", "*", - //code modifiers - "clear", "c", - "clean", "c", - "cls", "c", - "list", "l", - "lst", "l", - "delete", "d", - "del", "d", - "make", "m", - /* + //code modifiers + "clear", "c", + "clean", "c", + "cls", "c", + "list", "l", + "lst", "l", + "delete", "d", + "del", "d", + "make", "m", + /* //old parts made to look like the new code parts "bt", "b t m", "ba", "b a m", @@ -1711,14 +2227,14 @@ const char* breakAliasTable[] = { "bpwc", "b w c", "bt", "b t m", */ - //and new parts made to look like old parts - "breg", "b g m", - "bregc", "b g c", - "bregd", "b g d", - "bregl", "b g l", + //and new parts made to look like old parts + "breg", "b g m", + "bregc", "b g c", + "bregd", "b g d", + "bregl", "b g l", - "blist", "b * l", - /* + "blist", "b * l", + /* "btc", "b t c", "btd", "b t d", "btl", "b t l", @@ -1742,1069 +2258,1240 @@ const char* breakAliasTable[] = { "brd", "b r d", "brl", "b r l", */ - "bio", "b i m", - "bioc", "b i c", - "biod", "b i d", - "biol", "b i l", + "bio", "b i m", + "bioc", "b i c", + "biod", "b i d", + "biol", "b i l", - "bpio", "b i m", - "bpioc", "b i c", - "bpiod", "b i d", - "bpiol", "b i l", - /* + "bpio", "b i m", + "bpioc", "b i c", + "bpiod", "b i d", + "bpiol", "b i l", + /* "bprd", "b r d", "bprl", "b r l", "bpwd", "b w d", "bpwl", "b w l", */ - NULL, NULL + NULL, NULL }; - -char* breakSymbolCombo(char * command, int* length){ - char * res = (char*)malloc(6); - res[0] = 'b'; - res[1] = ' '; - res[2] = '0'; - res[3] = ' '; - res[4] = '0'; - int i = 1; - if (command[1] == 'p'){ - i++; - } - while (i < *length){ - switch (command[i]){ - case 'l': - case 'c': - case 'd': - case 'm': if (res[4] == '0') - res[4] = command[i]; - else{ - free(res); - return command; - } - break; - case '*': - case 't': - case 'a': - case 'x': - case 'r': - case 'w': - case 'i': if (res[2] == '0') - res[2] = command[i]; - else{ - free(res); - return command; - } - break; - default: - free(res); - return command; - } - i++; - } - if (res[2] == '0') - res[2] = '*'; - if (res[4] == '0') - res[4] = 'm'; - *length = 5; - return res; +char* breakSymbolCombo(char* command, int* length) +{ + char* res = (char*)malloc(6); + res[0] = 'b'; + res[1] = ' '; + res[2] = '0'; + res[3] = ' '; + res[4] = '0'; + int i = 1; + if (command[1] == 'p') { + i++; + } + while (i < *length) { + switch (command[i]) { + case 'l': + case 'c': + case 'd': + case 'm': + if (res[4] == '0') + res[4] = command[i]; + else { + free(res); + return command; + } + break; + case '*': + case 't': + case 'a': + case 'x': + case 'r': + case 'w': + case 'i': + if (res[2] == '0') + res[2] = command[i]; + else { + free(res); + return command; + } + break; + default: + free(res); + return command; + } + i++; + } + if (res[2] == '0') + res[2] = '*'; + if (res[4] == '0') + res[4] = 'm'; + *length = 5; + return res; } const char* typeMapping[] = { "'u8", "'u16", "'u32", "'u32", "'s8", "'s16", "'s32", "'s32" }; const char* compareFlagMapping[] = { "Never", "==", ">", ">=", "<", "<=", "!=", "<=>" }; -struct intToString{ - int value; - const char mapping[20]; +struct intToString { + int value; + const char mapping[20]; }; struct intToString breakFlagMapping[] = { - { 0x80, "Thumb" }, - { 0x40, "ARM" }, - { 0x20, "Read" }, - { 0x10, "Write" }, - { 0x8, "Thumb" }, - { 0x4, "ARM" }, - { 0x2, "Read" }, - { 0x1, "Write" }, - { 0x0, "None" } + { 0x80, "Thumb" }, + { 0x40, "ARM" }, + { 0x20, "Read" }, + { 0x10, "Write" }, + { 0x8, "Thumb" }, + { 0x4, "ARM" }, + { 0x2, "Read" }, + { 0x1, "Write" }, + { 0x0, "None" } }; //printers -void printCondition(struct ConditionalBreakNode* toPrint){ - if (toPrint){ - const char* firstType = typeMapping[toPrint->exp_type_flags & 0x7]; - const char* secondType = typeMapping[(toPrint->exp_type_flags >> 4) & 0x7]; - const char* operand = compareFlagMapping[toPrint->cond_flags & 0x7]; - { sprintf(monbuf, "%s %s %s%s %s %s", firstType, toPrint->address, - ((toPrint->cond_flags & 8) ? "s" : ""), operand, - secondType, toPrint->value); - monprintf(monbuf); } - if (toPrint->next){ - { sprintf(monbuf, " &&\n\t\t"); monprintf(monbuf); } - printCondition(toPrint->next); - } - else{ - { sprintf(monbuf, "\n"); monprintf(monbuf); } - return; - } - } +void printCondition(struct ConditionalBreakNode* toPrint) +{ + if (toPrint) { + const char* firstType = typeMapping[toPrint->exp_type_flags & 0x7]; + const char* secondType = typeMapping[(toPrint->exp_type_flags >> 4) & 0x7]; + const char* operand = compareFlagMapping[toPrint->cond_flags & 0x7]; + { + sprintf(monbuf, "%s %s %s%s %s %s", firstType, toPrint->address, + ((toPrint->cond_flags & 8) ? "s" : ""), operand, + secondType, toPrint->value); + monprintf(monbuf); + } + if (toPrint->next) { + { + sprintf(monbuf, " &&\n\t\t"); + monprintf(monbuf); + } + printCondition(toPrint->next); + } else { + { + sprintf(monbuf, "\n"); + monprintf(monbuf); + } + return; + } + } } -void printConditionalBreak(struct ConditionalBreak* toPrint, bool printAddress){ - if (toPrint){ - if (printAddress) - { sprintf(monbuf, "At %08x, ", toPrint->break_address); monprintf(monbuf); } - if (toPrint->type_flags & 0xf0) - { sprintf(monbuf, "Break Always on"); monprintf(monbuf); } - bool hasPrevCond = false; - u8 flgs = 0x80; - while (flgs != 0){ - if (toPrint->type_flags & flgs){ - if (hasPrevCond) { sprintf(monbuf, ","); monprintf(monbuf); } - for (int i = 0; i < 9; i++){ - if (breakFlagMapping[i].value == flgs){ - { sprintf(monbuf, "\t%s", breakFlagMapping[i].mapping); monprintf(monbuf); } - hasPrevCond = true; - } - } - } - flgs = flgs >> 1; - if ((flgs == 0x8) && (toPrint->type_flags & 0xf)){ - { sprintf(monbuf, "\n\t\tBreak conditional on"); monprintf(monbuf); } - hasPrevCond = false; - } - } - { sprintf(monbuf, "\n"); monprintf(monbuf); } - if (toPrint->type_flags & 0xf && toPrint->firstCond){ - { sprintf(monbuf, "With conditions:\n\t\t"); monprintf(monbuf); } - printCondition(toPrint->firstCond); - } - else if (toPrint->type_flags & 0xf){ - //should not happen - { sprintf(monbuf, "No conditions detected, but conditional. Assumed always by default.\n"); monprintf(monbuf); } - } - } +void printConditionalBreak(struct ConditionalBreak* toPrint, bool printAddress) +{ + if (toPrint) { + if (printAddress) { + sprintf(monbuf, "At %08x, ", toPrint->break_address); + monprintf(monbuf); + } + if (toPrint->type_flags & 0xf0) { + sprintf(monbuf, "Break Always on"); + monprintf(monbuf); + } + bool hasPrevCond = false; + u8 flgs = 0x80; + while (flgs != 0) { + if (toPrint->type_flags & flgs) { + if (hasPrevCond) { + sprintf(monbuf, ","); + monprintf(monbuf); + } + for (int i = 0; i < 9; i++) { + if (breakFlagMapping[i].value == flgs) { + { + sprintf(monbuf, "\t%s", breakFlagMapping[i].mapping); + monprintf(monbuf); + } + hasPrevCond = true; + } + } + } + flgs = flgs >> 1; + if ((flgs == 0x8) && (toPrint->type_flags & 0xf)) { + { + sprintf(monbuf, "\n\t\tBreak conditional on"); + monprintf(monbuf); + } + hasPrevCond = false; + } + } + { + sprintf(monbuf, "\n"); + monprintf(monbuf); + } + if (toPrint->type_flags & 0xf && toPrint->firstCond) { + { + sprintf(monbuf, "With conditions:\n\t\t"); + monprintf(monbuf); + } + printCondition(toPrint->firstCond); + } else if (toPrint->type_flags & 0xf) { + //should not happen + { + sprintf(monbuf, "No conditions detected, but conditional. Assumed always by default.\n"); + monprintf(monbuf); + } + } + } } -void printAllConditionals(){ +void printAllConditionals() +{ - for (int i = 0; i<16; i++){ + for (int i = 0; i < 16; i++) { - if (conditionals[i] != NULL){ - { sprintf(monbuf, "Address range 0x%02x000000 breaks:\n", i); monprintf(monbuf); } - { sprintf(monbuf, "-------------------------\n"); monprintf(monbuf); } - struct ConditionalBreak* base = conditionals[i]; - int count = 1; - u32 lastAddress = base->break_address; - { sprintf(monbuf, "Address %08x\n-------------------------\n", lastAddress); monprintf(monbuf); } - while (base){ - if (lastAddress != base->break_address){ - lastAddress = base->break_address; - count = 1; - { sprintf(monbuf, "-------------------------\n"); monprintf(monbuf); } - { sprintf(monbuf, "Address %08x\n-------------------------\n", lastAddress); monprintf(monbuf); } - } - { sprintf(monbuf, "No.%d\t-->\t", count); monprintf(monbuf); } - printConditionalBreak(base, false); - count++; - base = base->next; - } - } - } + if (conditionals[i] != NULL) { + { + sprintf(monbuf, "Address range 0x%02x000000 breaks:\n", i); + monprintf(monbuf); + } + { + sprintf(monbuf, "-------------------------\n"); + monprintf(monbuf); + } + struct ConditionalBreak* base = conditionals[i]; + int count = 1; + u32 lastAddress = base->break_address; + { + sprintf(monbuf, "Address %08x\n-------------------------\n", lastAddress); + monprintf(monbuf); + } + while (base) { + if (lastAddress != base->break_address) { + lastAddress = base->break_address; + count = 1; + { + sprintf(monbuf, "-------------------------\n"); + monprintf(monbuf); + } + { + sprintf(monbuf, "Address %08x\n-------------------------\n", lastAddress); + monprintf(monbuf); + } + } + { + sprintf(monbuf, "No.%d\t-->\t", count); + monprintf(monbuf); + } + printConditionalBreak(base, false); + count++; + base = base->next; + } + } + } } -u8 printConditionalsFromAddress(u32 address){ - u8 count = 1; - if (conditionals[address >> 24] != NULL){ - struct ConditionalBreak* base = conditionals[address >> 24]; - while (base){ - if (address == base->break_address){ - if (count == 1){ - { sprintf(monbuf, "Address %08x\n-------------------------\n", address); monprintf(monbuf); } - } - { sprintf(monbuf, "No.%d\t-->\t", count); monprintf(monbuf); } - printConditionalBreak(base, false); - count++; - } - if (address < base->break_address) - break; - base = base->next; - } - } - if (count == 1){ - { sprintf(monbuf, "None\n"); monprintf(monbuf); } - } - return count; +u8 printConditionalsFromAddress(u32 address) +{ + u8 count = 1; + if (conditionals[address >> 24] != NULL) { + struct ConditionalBreak* base = conditionals[address >> 24]; + while (base) { + if (address == base->break_address) { + if (count == 1) { + { + sprintf(monbuf, "Address %08x\n-------------------------\n", address); + monprintf(monbuf); + } + } + { + sprintf(monbuf, "No.%d\t-->\t", count); + monprintf(monbuf); + } + printConditionalBreak(base, false); + count++; + } + if (address < base->break_address) + break; + base = base->next; + } + } + if (count == 1) { + { + sprintf(monbuf, "None\n"); + monprintf(monbuf); + } + } + return count; } -void printAllFlagConditionals(u8 flag, bool orMode){ - int count = 1; - int actualCount = 1; - for (int i = 0; i<16; i++){ - if (conditionals[i] != NULL){ - bool isCondStart = true; - struct ConditionalBreak* base = conditionals[i]; +void printAllFlagConditionals(u8 flag, bool orMode) +{ + int count = 1; + int actualCount = 1; + for (int i = 0; i < 16; i++) { + if (conditionals[i] != NULL) { + bool isCondStart = true; + struct ConditionalBreak* base = conditionals[i]; - u32 lastAddress = base->break_address; + u32 lastAddress = base->break_address; - while (base){ - if (lastAddress != base->break_address){ - lastAddress = base->break_address; - count = 1; - actualCount = 1; - } - if (((base->type_flags & flag) == base->type_flags) || (orMode && (base->type_flags & flag))){ - if (actualCount == 1){ - if (isCondStart){ - { sprintf(monbuf, "Address range 0x%02x000000 breaks:\n", i); monprintf(monbuf); } - { sprintf(monbuf, "-------------------------\n"); monprintf(monbuf); } - isCondStart = false; - } - { sprintf(monbuf, "Address %08x\n-------------------------\n", lastAddress); monprintf(monbuf); } - } - { sprintf(monbuf, "No.%d\t-->\t", count); monprintf(monbuf); } - printConditionalBreak(base, false); - actualCount++; - } - base = base->next; - count++; - } - } - } + while (base) { + if (lastAddress != base->break_address) { + lastAddress = base->break_address; + count = 1; + actualCount = 1; + } + if (((base->type_flags & flag) == base->type_flags) || (orMode && (base->type_flags & flag))) { + if (actualCount == 1) { + if (isCondStart) { + { + sprintf(monbuf, "Address range 0x%02x000000 breaks:\n", i); + monprintf(monbuf); + } + { + sprintf(monbuf, "-------------------------\n"); + monprintf(monbuf); + } + isCondStart = false; + } + { + sprintf(monbuf, "Address %08x\n-------------------------\n", lastAddress); + monprintf(monbuf); + } + } + { + sprintf(monbuf, "No.%d\t-->\t", count); + monprintf(monbuf); + } + printConditionalBreak(base, false); + actualCount++; + } + base = base->next; + count++; + } + } + } } -void printAllFlagConditionalsWithAddress(u32 address, u8 flag, bool orMode){ - int count = 1; - int actualCount = 1; - for (int i = 0; i<16; i++){ - if (conditionals[i] != NULL){ - bool isCondStart = true; - struct ConditionalBreak* base = conditionals[i]; +void printAllFlagConditionalsWithAddress(u32 address, u8 flag, bool orMode) +{ + int count = 1; + int actualCount = 1; + for (int i = 0; i < 16; i++) { + if (conditionals[i] != NULL) { + bool isCondStart = true; + struct ConditionalBreak* base = conditionals[i]; - u32 lastAddress = base->break_address; + u32 lastAddress = base->break_address; - while (base){ - if (lastAddress != base->break_address){ - lastAddress = base->break_address; - count = 1; - actualCount = 1; - } - if ((lastAddress == address) && - (((base->type_flags & flag) == base->type_flags) || (orMode && (base->type_flags & flag)))){ - if (actualCount == 1){ - if (isCondStart){ - { sprintf(monbuf, "Address range 0x%02x000000 breaks:\n", i); monprintf(monbuf); } - { sprintf(monbuf, "-------------------------\n"); monprintf(monbuf); } - isCondStart = false; - } - { sprintf(monbuf, "Address %08x\n-------------------------\n", lastAddress); monprintf(monbuf); } - } - { sprintf(monbuf, "No.%d\t-->\t", count); monprintf(monbuf); } - printConditionalBreak(base, false); - actualCount++; - } - base = base->next; - count++; - } - } - } + while (base) { + if (lastAddress != base->break_address) { + lastAddress = base->break_address; + count = 1; + actualCount = 1; + } + if ((lastAddress == address) && (((base->type_flags & flag) == base->type_flags) || (orMode && (base->type_flags & flag)))) { + if (actualCount == 1) { + if (isCondStart) { + { + sprintf(monbuf, "Address range 0x%02x000000 breaks:\n", i); + monprintf(monbuf); + } + { + sprintf(monbuf, "-------------------------\n"); + monprintf(monbuf); + } + isCondStart = false; + } + { + sprintf(monbuf, "Address %08x\n-------------------------\n", lastAddress); + monprintf(monbuf); + } + } + { + sprintf(monbuf, "No.%d\t-->\t", count); + monprintf(monbuf); + } + printConditionalBreak(base, false); + actualCount++; + } + base = base->next; + count++; + } + } + } } -void makeBreak(u32 address, u8 flags, char** expression, int n){ - if (n >= 1){ - if (tolower(expression[0][0]) == 'i' && tolower(expression[0][1]) == 'f'){ - expression = expression + 1; - n--; - if (n != 0){ - parseAndCreateConditionalBreaks(address, flags, expression, n); - return; - } - } - } - else{ - flags = flags << 0x4; - printConditionalBreak(addConditionalBreak(address, flags), true); - return; - } +void makeBreak(u32 address, u8 flags, char** expression, int n) +{ + if (n >= 1) { + if (tolower(expression[0][0]) == 'i' && tolower(expression[0][1]) == 'f') { + expression = expression + 1; + n--; + if (n != 0) { + parseAndCreateConditionalBreaks(address, flags, expression, n); + return; + } + } + } else { + flags = flags << 0x4; + printConditionalBreak(addConditionalBreak(address, flags), true); + return; + } } -void deleteBreak(u32 address, u8 flags, char** expression, int howToDelete){ - bool applyOr = true; - if (howToDelete > 0){ - if (((expression[0][0] == '&') && !expression[0][1]) || - ((tolower(expression[0][0]) == 'o') && (tolower(expression[0][1]) == 'n')) || - ((tolower(expression[0][0]) == 'l') && (tolower(expression[0][1]) == 'y'))){ - applyOr = false; - howToDelete--; - expression++; - } - if (howToDelete > 0){ - u32 number = 0; - if (!dexp_eval(expression[0], &number)){ - { sprintf(monbuf, "Invalid expression for number format.\n"); monprintf(monbuf); } - return; - } - removeFlagFromConditionalBreakNo(address, (u8)number, (flags | (flags >> 4))); - { sprintf(monbuf, "Removed all specified breaks from %08x.\n", address); monprintf(monbuf); } - return; - } - removeConditionalWithAddressAndFlag(address, flags, applyOr); - removeConditionalWithAddressAndFlag(address, flags << 4, applyOr); - { sprintf(monbuf, "Removed all specified breaks from %08x.\n", address); monprintf(monbuf); } - } - else{ - removeConditionalWithAddressAndFlag(address, flags, applyOr); - removeConditionalWithAddressAndFlag(address, flags << 4, applyOr); - { sprintf(monbuf, "Removed all specified breaks from %08x.\n", address); monprintf(monbuf); } - } - return; +void deleteBreak(u32 address, u8 flags, char** expression, int howToDelete) +{ + bool applyOr = true; + if (howToDelete > 0) { + if (((expression[0][0] == '&') && !expression[0][1]) || ((tolower(expression[0][0]) == 'o') && (tolower(expression[0][1]) == 'n')) || ((tolower(expression[0][0]) == 'l') && (tolower(expression[0][1]) == 'y'))) { + applyOr = false; + howToDelete--; + expression++; + } + if (howToDelete > 0) { + u32 number = 0; + if (!dexp_eval(expression[0], &number)) { + { + sprintf(monbuf, "Invalid expression for number format.\n"); + monprintf(monbuf); + } + return; + } + removeFlagFromConditionalBreakNo(address, (u8)number, (flags | (flags >> 4))); + { + sprintf(monbuf, "Removed all specified breaks from %08x.\n", address); + monprintf(monbuf); + } + return; + } + removeConditionalWithAddressAndFlag(address, flags, applyOr); + removeConditionalWithAddressAndFlag(address, flags << 4, applyOr); + { + sprintf(monbuf, "Removed all specified breaks from %08x.\n", address); + monprintf(monbuf); + } + } else { + removeConditionalWithAddressAndFlag(address, flags, applyOr); + removeConditionalWithAddressAndFlag(address, flags << 4, applyOr); + { + sprintf(monbuf, "Removed all specified breaks from %08x.\n", address); + monprintf(monbuf); + } + } + return; } -void clearBreaks(u32 address, u8 flags, char** expression, int howToClear){ - if (howToClear == 2){ - removeConditionalWithFlag(flags, true); - removeConditionalWithFlag(flags << 4, true); - } - else{ - removeConditionalWithFlag(flags, false); - removeConditionalWithFlag(flags << 4, false); - } - { sprintf(monbuf, "Cleared all requested breaks.\n", address); monprintf(monbuf); } - +void clearBreaks(u32 address, u8 flags, char** expression, int howToClear) +{ + if (howToClear == 2) { + removeConditionalWithFlag(flags, true); + removeConditionalWithFlag(flags << 4, true); + } else { + removeConditionalWithFlag(flags, false); + removeConditionalWithFlag(flags << 4, false); + } + { + sprintf(monbuf, "Cleared all requested breaks.\n", address); + monprintf(monbuf); + } } -void listBreaks(u32 address, u8 flags, char** expression, int howToList){ - flags |= (flags << 4); - if (howToList){ - printAllFlagConditionalsWithAddress(address, flags, true); - } - else{ - printAllFlagConditionals(flags, true); - } - { sprintf(monbuf, "\n"); monprintf(monbuf); } +void listBreaks(u32 address, u8 flags, char** expression, int howToList) +{ + flags |= (flags << 4); + if (howToList) { + printAllFlagConditionalsWithAddress(address, flags, true); + } else { + printAllFlagConditionals(flags, true); + } + { + sprintf(monbuf, "\n"); + monprintf(monbuf); + } } -void executeBreakCommands(int n, char** cmd){ - char* command = cmd[0]; - int len = strlen(command); - bool changed = false; - if (len <= 4){ - command = breakSymbolCombo(command, &len); - changed = (len == 5); - }if (!changed){ - command = strdup(replaceAlias(cmd[0], breakAliasTable)); - changed = (strcmp(cmd[0], command)); - } - if (!changed){ - cmd[0][0] = '!'; - return; - } - cmd++; - n--; - void(*operation)(u32, u8, char**, int) = &makeBreak; //the function to be called +void executeBreakCommands(int n, char** cmd) +{ + char* command = cmd[0]; + int len = strlen(command); + bool changed = false; + if (len <= 4) { + command = breakSymbolCombo(command, &len); + changed = (len == 5); + } + if (!changed) { + command = strdup(replaceAlias(cmd[0], breakAliasTable)); + changed = (strcmp(cmd[0], command)); + } + if (!changed) { + cmd[0][0] = '!'; + return; + } + cmd++; + n--; + void (*operation)(u32, u8, char**, int) = &makeBreak; //the function to be called - u8 flag = 0; - u32 address = 0; - //if(strlen(command) == 1){ - //Cannot happen, that would mean cmd[0] != b - //} - char target; - char ope; + u8 flag = 0; + u32 address = 0; + //if(strlen(command) == 1){ + //Cannot happen, that would mean cmd[0] != b + //} + char target; + char ope; - if (command[2] == '0'){ - if (n <= 0){ - { sprintf(monbuf, "Invalid break command.\n"); monprintf(monbuf); } - free(command); - return; - } + if (command[2] == '0') { + if (n <= 0) { + { + sprintf(monbuf, "Invalid break command.\n"); + monprintf(monbuf); + } + free(command); + return; + } - for (int i = 0; cmd[0][i]; i++){ - cmd[0][i] = tolower(cmd[0][i]); - } - const char* replaced = replaceAlias(cmd[0], breakAliasTable); - if (replaced == cmd[0]){ - target = '*'; - } - else{ - target = replaced[0]; - if ((target == 'c') || (target == 'd') || (target == 'l') || (target == 'm')){ - command[4] = target; - target = '*'; - } - cmd++; - n--; - } - command[2] = target; - } + for (int i = 0; cmd[0][i]; i++) { + cmd[0][i] = tolower(cmd[0][i]); + } + const char* replaced = replaceAlias(cmd[0], breakAliasTable); + if (replaced == cmd[0]) { + target = '*'; + } else { + target = replaced[0]; + if ((target == 'c') || (target == 'd') || (target == 'l') || (target == 'm')) { + command[4] = target; + target = '*'; + } + cmd++; + n--; + } + command[2] = target; + } - if (command[4] == '0'){ - if (n <= 0){ - { sprintf(monbuf, "Invalid break command.\n"); monprintf(monbuf); } - free(command); - return; - } + if (command[4] == '0') { + if (n <= 0) { + { + sprintf(monbuf, "Invalid break command.\n"); + monprintf(monbuf); + } + free(command); + return; + } - for (int i = 0; cmd[0][i]; i++){ - cmd[0][i] = tolower(cmd[0][i]); - } - ope = replaceAlias(cmd[0], breakAliasTable)[0]; - if ((ope == 'c') || (ope == 'd') || (ope == 'l') || (ope == 'm')){ - command[4] = ope; - cmd++; - n--; - } - else{ - command[4] = 'm'; - } + for (int i = 0; cmd[0][i]; i++) { + cmd[0][i] = tolower(cmd[0][i]); + } + ope = replaceAlias(cmd[0], breakAliasTable)[0]; + if ((ope == 'c') || (ope == 'd') || (ope == 'l') || (ope == 'm')) { + command[4] = ope; + cmd++; + n--; + } else { + command[4] = 'm'; + } + } + switch (command[4]) { + case 'l': + operation = &listBreaks; + break; + case 'c': + operation = &clearBreaks; + break; + case 'd': + operation = &deleteBreak; + break; - } + case 'm': + default: + operation = &makeBreak; + }; - switch (command[4]){ - case 'l': operation = &listBreaks; break; - case 'c': operation = &clearBreaks; break; - case 'd': operation = &deleteBreak; break; + switch (command[2]) { + case 'g': + switch (command[4]) { + case 'l': + debuggerBreakRegisterList((n > 0) && (tolower(cmd[0][0]) == 'v')); + return; + case 'c': + debuggerBreakRegisterClear(n, cmd); + return; + case 'd': + debuggerBreakRegisterDelete(n, cmd); + return; - case 'm': - default: operation = &makeBreak; - }; + case 'm': + debuggerBreakRegister(n, cmd); + default: + return; + }; + return; + case '*': + flag = 0xf; + break; + case 't': + flag = 0x8; + break; + case 'a': + flag = 0x4; + break; + case 'x': + flag = 0xC; + break; + case 'r': + flag = 0x2; + break; + case 'w': + flag = 0x1; + break; + case 'i': + flag = 0x3; + break; + default: + free(command); + return; + }; - switch (command[2]){ - case 'g': switch (command[4]){ - case 'l': debuggerBreakRegisterList((n>0) && (tolower(cmd[0][0]) == 'v')); return; - case 'c': debuggerBreakRegisterClear(n, cmd); return; - case 'd': debuggerBreakRegisterDelete(n, cmd); return; - - case 'm': debuggerBreakRegister(n, cmd); - default: return; - }; - return; - case '*': flag = 0xf; break; - case 't': flag = 0x8; break; - case 'a': flag = 0x4; break; - case 'x': flag = 0xC; break; - case 'r': flag = 0x2; break; - case 'w': flag = 0x1; break; - case 'i': flag = 0x3; break; - default: free(command); return; - }; - - free(command); - bool hasAddress = false; - if ((n >= 1) && (operation != clearBreaks)){ - if (!dexp_eval(cmd[0], &address)){ - { sprintf(monbuf, "Invalid expression for address format.\n"); monprintf(monbuf); } - return; - } - hasAddress = true; - } - if (operation == listBreaks){ - operation(address, flag, NULL, hasAddress); - return; - } - else if (operation == clearBreaks){ - if (!hasAddress && (n >= 1)){ - if ((cmd[0][0] == '|' && cmd[0][1] == '|') || - ((cmd[0][0] == 'O' || cmd[0][0] == 'o') && - (cmd[0][1] == 'R' || cmd[0][1] == 'r'))) { - operation(address, flag, NULL, 2); - } - else{ - operation(address, flag, NULL, 0); - } - } - else{ - operation(address, flag, NULL, 0); - } - } - else if (!hasAddress && (operation == deleteBreak)){ - { sprintf(monbuf, "Delete breakpoint operation requires at least one address;\n"); monprintf(monbuf); } - { sprintf(monbuf, "Usage: break [type] delete [address] no.[number] --> Deletes breakpoint [number] of [address].\n"); monprintf(monbuf); } - //{ sprintf(monbuf, "Usage: [delete Operand] [address] End [address] --> Deletes range between [address] and [end]\n"); monprintf(monbuf); } - { sprintf(monbuf, "Usage: break [type] delete [address]\n --> Deletes all breakpoints of [type] on [address]."); monprintf(monbuf); } - return; - } - else if (!hasAddress && (operation == makeBreak)){ - { sprintf(monbuf, "Can only create breakpoints if an address is provided"); monprintf(monbuf); } - //print usage here - return; - } - else{ - operation(address, flag, cmd + 1, n - 1); - return; - } + free(command); + bool hasAddress = false; + if ((n >= 1) && (operation != clearBreaks)) { + if (!dexp_eval(cmd[0], &address)) { + { + sprintf(monbuf, "Invalid expression for address format.\n"); + monprintf(monbuf); + } + return; + } + hasAddress = true; + } + if (operation == listBreaks) { + operation(address, flag, NULL, hasAddress); + return; + } else if (operation == clearBreaks) { + if (!hasAddress && (n >= 1)) { + if ((cmd[0][0] == '|' && cmd[0][1] == '|') || ((cmd[0][0] == 'O' || cmd[0][0] == 'o') && (cmd[0][1] == 'R' || cmd[0][1] == 'r'))) { + operation(address, flag, NULL, 2); + } else { + operation(address, flag, NULL, 0); + } + } else { + operation(address, flag, NULL, 0); + } + } else if (!hasAddress && (operation == deleteBreak)) { + { + sprintf(monbuf, "Delete breakpoint operation requires at least one address;\n"); + monprintf(monbuf); + } + { + sprintf(monbuf, "Usage: break [type] delete [address] no.[number] --> Deletes breakpoint [number] of [address].\n"); + monprintf(monbuf); + } + //{ sprintf(monbuf, "Usage: [delete Operand] [address] End [address] --> Deletes range between [address] and [end]\n"); monprintf(monbuf); } + { + sprintf(monbuf, "Usage: break [type] delete [address]\n --> Deletes all breakpoints of [type] on [address]."); + monprintf(monbuf); + } + return; + } else if (!hasAddress && (operation == makeBreak)) { + { + sprintf(monbuf, "Can only create breakpoints if an address is provided"); + monprintf(monbuf); + } + //print usage here + return; + } else { + operation(address, flag, cmd + 1, n - 1); + return; + } brkcmd_special_register: - switch (command[4]){ - case 'l': debuggerBreakRegisterList((n>0) && (tolower(cmd[0][0]) == 'v')); return; - case 'c': debuggerBreakRegisterClear(n, cmd); return; - case 'd': debuggerBreakRegisterDelete(n, cmd); return; + switch (command[4]) { + case 'l': + debuggerBreakRegisterList((n > 0) && (tolower(cmd[0][0]) == 'v')); + return; + case 'c': + debuggerBreakRegisterClear(n, cmd); + return; + case 'd': + debuggerBreakRegisterDelete(n, cmd); + return; - case 'm': debuggerBreakRegister(n, cmd); - default: return; - }; - return; + case 'm': + debuggerBreakRegister(n, cmd); + default: + return; + }; + return; } -void debuggerDisable(int n, char** args){ - if (n >= 3){ - debuggerUsage("disable"); - return; - } - while (n > 1){ - int i = 0; - while (args[3 - n][i]){ - args[3 - n][i] = tolower(args[2 - n][i]); - i++; - } - if (strcmp(args[3 - n], "breg")){ - enableRegBreak = false; - { sprintf(monbuf, "Break on register disabled.\n"); monprintf(monbuf); } - } - else if (strcmp(args[3 - n], "tbl")){ - canUseTbl = false; - useWordSymbol = false; - { sprintf(monbuf, "Symbol table disabled.\n"); monprintf(monbuf); } - } - else{ - { sprintf(monbuf, "Invalid command. Only tbl and breg are accepted as commands\n"); monprintf(monbuf); } - return; - } - n--; - } +void debuggerDisable(int n, char** args) +{ + if (n >= 3) { + debuggerUsage("disable"); + return; + } + while (n > 1) { + int i = 0; + while (args[3 - n][i]) { + args[3 - n][i] = tolower(args[2 - n][i]); + i++; + } + if (strcmp(args[3 - n], "breg")) { + enableRegBreak = false; + { + sprintf(monbuf, "Break on register disabled.\n"); + monprintf(monbuf); + } + } else if (strcmp(args[3 - n], "tbl")) { + canUseTbl = false; + useWordSymbol = false; + { + sprintf(monbuf, "Symbol table disabled.\n"); + monprintf(monbuf); + } + } else { + { + sprintf(monbuf, "Invalid command. Only tbl and breg are accepted as commands\n"); + monprintf(monbuf); + } + return; + } + n--; + } } -void debuggerEnable(int n, char** args){ - if (n >= 3){ - debuggerUsage("enable"); - return; - } - while (n > 1){ - int i = 0; - while (args[3 - n][i]){ - args[3 - n][i] = tolower(args[2 - n][i]); - i++; - } - if (strcmp(args[3 - n], "breg")){ - enableRegBreak = true; - { sprintf(monbuf, "Break on register enabled.\n"); monprintf(monbuf); } - } - else if (strcmp(args[3 - n], "tbl")){ - canUseTbl = true; - useWordSymbol = thereIsATable; - { sprintf(monbuf, "Symbol table enabled.\n"); monprintf(monbuf); } - } - else{ - { sprintf(monbuf, "Invalid command. Only tbl and breg are accepted as commands\n"); monprintf(monbuf); } - return; - } - n--; - } +void debuggerEnable(int n, char** args) +{ + if (n >= 3) { + debuggerUsage("enable"); + return; + } + while (n > 1) { + int i = 0; + while (args[3 - n][i]) { + args[3 - n][i] = tolower(args[2 - n][i]); + i++; + } + if (strcmp(args[3 - n], "breg")) { + enableRegBreak = true; + { + sprintf(monbuf, "Break on register enabled.\n"); + monprintf(monbuf); + } + } else if (strcmp(args[3 - n], "tbl")) { + canUseTbl = true; + useWordSymbol = thereIsATable; + { + sprintf(monbuf, "Symbol table enabled.\n"); + monprintf(monbuf); + } + } else { + { + sprintf(monbuf, "Invalid command. Only tbl and breg are accepted as commands\n"); + monprintf(monbuf); + } + return; + } + n--; + } } DebuggerCommand debuggerCommands[] = { - //simple commands - { "?", debuggerHelp, "Shows this help information. Type ? for command help. Alias 'help', 'h'.", "[]" }, - // { "n", debuggerNext, "Executes the next instruction.", "[]" }, - // { "c", debuggerContinue, "Continues execution", NULL }, - // // Hello command, shows Hello on the board + //simple commands + { "?", debuggerHelp, "Shows this help information. Type ? for command help. Alias 'help', 'h'.", "[]" }, + // { "n", debuggerNext, "Executes the next instruction.", "[]" }, + // { "c", debuggerContinue, "Continues execution", NULL }, + // // Hello command, shows Hello on the board - //{ "br", debuggerBreakRead, "Break on read", "{address} {size}" }, - //{ "bw", debuggerBreakWrite, "Break on write", "{address} {size}" }, - //{ "bt", debuggerBreakWrite, "Break on write", "{address} {size}" }, + //{ "br", debuggerBreakRead, "Break on read", "{address} {size}" }, + //{ "bw", debuggerBreakWrite, "Break on write", "{address} {size}" }, + //{ "bt", debuggerBreakWrite, "Break on write", "{address} {size}" }, - //{ "ba", debuggerBreakArm, "Adds an ARM breakpoint", "{address}" }, - //{ "bd", debuggerBreakDelete, "Deletes a breakpoint", "" }, - //{ "bl", debuggerBreakList, "Lists breakpoints" }, - //{ "bpr", debuggerBreakRead, "Break on read", "{address} {size}" }, - //{ "bprc", debuggerBreakReadClear, "Clear break on read", NULL }, - //{ "bpw", debuggerBreakWrite, "Break on write", "{address} {size}" }, - //{ "bpwc", debuggerBreakWriteClear, "Clear break on write", NULL }, - { "breg", debuggerBreakRegister, "Breaks on a register specified value", " {flag} {value}" }, - { "bregc", debuggerBreakRegisterClear, "Clears all break on register", " {flag} {value}" }, - //{ "bt", debuggerBreakThumb, "Adds a THUMB breakpoint", "{address}" } + //{ "ba", debuggerBreakArm, "Adds an ARM breakpoint", "{address}" }, + //{ "bd", debuggerBreakDelete, "Deletes a breakpoint", "" }, + //{ "bl", debuggerBreakList, "Lists breakpoints" }, + //{ "bpr", debuggerBreakRead, "Break on read", "{address} {size}" }, + //{ "bprc", debuggerBreakReadClear, "Clear break on read", NULL }, + //{ "bpw", debuggerBreakWrite, "Break on write", "{address} {size}" }, + //{ "bpwc", debuggerBreakWriteClear, "Clear break on write", NULL }, + { "breg", debuggerBreakRegister, "Breaks on a register specified value", " {flag} {value}" }, + { "bregc", debuggerBreakRegisterClear, "Clears all break on register", " {flag} {value}" }, + //{ "bt", debuggerBreakThumb, "Adds a THUMB breakpoint", "{address}" } - // //diassemble commands - // { "d", debuggerDisassemble, "Disassembles instructions", "[
[]]" }, - // { "da", debuggerDisassembleArm, "Disassembles ARM instructions", "[{address} [{number}]]" }, - // { "dt", debuggerDisassembleThumb, "Disassembles Thumb instructions", "[{address} [{number}]]" }, + // //diassemble commands + // { "d", debuggerDisassemble, "Disassembles instructions", "[
[]]" }, + // { "da", debuggerDisassembleArm, "Disassembles ARM instructions", "[{address} [{number}]]" }, + // { "dt", debuggerDisassembleThumb, "Disassembles Thumb instructions", "[{address} [{number}]]" }, - { "db", debuggerDontBreak, "Don't break at the following address.", "[{address} [{number}]]" }, - { "dbc", debuggerDontBreakClear, "Clear the Don't Break list.", NULL }, - { "dload", debuggerDumpLoad, "Load raw data dump from file", " {address}" }, - { "dsave", debuggerDumpSave, "Dump raw data to file", " {address} {size}" }, - // { "dn", debuggerDisassembleNear, "Disassembles instructions near PC", "[{number}]" }, + { "db", debuggerDontBreak, "Don't break at the following address.", "[{address} [{number}]]" }, + { "dbc", debuggerDontBreakClear, "Clear the Don't Break list.", NULL }, + { "dload", debuggerDumpLoad, "Load raw data dump from file", " {address}" }, + { "dsave", debuggerDumpSave, "Dump raw data to file", " {address} {size}" }, + // { "dn", debuggerDisassembleNear, "Disassembles instructions near PC", "[{number}]" }, - { "disable", debuggerDisable, "Disables operations.", "tbl|breg" }, - { "enable", debuggerEnable, "Enables operations.", "tbl|breg" }, + { "disable", debuggerDisable, "Disables operations.", "tbl|breg" }, + { "enable", debuggerEnable, "Enables operations.", "tbl|breg" }, - { "eb", debuggerEditByte, "Modify memory location (byte)", "{address} {value}*" }, - { "eh", debuggerEditHalfWord, "Modify memory location (half-word)", "{address} {value}*" }, - { "ew", debuggerEditWord, "Modify memory location (word)", "{address} {value}*" }, - { "er", debuggerEditRegister, "Modify register", " {value}" }, + { "eb", debuggerEditByte, "Modify memory location (byte)", "{address} {value}*" }, + { "eh", debuggerEditHalfWord, "Modify memory location (half-word)", "{address} {value}*" }, + { "ew", debuggerEditWord, "Modify memory location (word)", "{address} {value}*" }, + { "er", debuggerEditRegister, "Modify register", " {value}" }, - { "eval", debuggerEval, "Evaluate expression", "{expression}" }, + { "eval", debuggerEval, "Evaluate expression", "{expression}" }, - { "fillb", debuggerFillByte, "Fills memory location (byte)", "{address} {value} {number of times}" }, - { "fillh", debuggerFillHalfWord, "Fills memory location (half-word)", "{address} {value} {number of times}" }, - { "fillw", debuggerFillWord, "Fills memory location (word)", "{address} {value} {number of times}" }, + { "fillb", debuggerFillByte, "Fills memory location (byte)", "{address} {value} {number of times}" }, + { "fillh", debuggerFillHalfWord, "Fills memory location (half-word)", "{address} {value} {number of times}" }, + { "fillw", debuggerFillWord, "Fills memory location (word)", "{address} {value} {number of times}" }, - { "copyb", debuggerCopyByte, "Copies memory content (byte)", "{address} {second address} {size} optional{repeat}" }, - { "copyh", debuggerCopyHalfWord, "Copies memory content (half-word)", "{address} {second address} {size} optional{repeat}" }, - { "copyw", debuggerCopyWord, "Copies memory content (word)", "{address} {second address} {size} optional{repeat}" }, + { "copyb", debuggerCopyByte, "Copies memory content (byte)", "{address} {second address} {size} optional{repeat}" }, + { "copyh", debuggerCopyHalfWord, "Copies memory content (half-word)", "{address} {second address} {size} optional{repeat}" }, + { "copyw", debuggerCopyWord, "Copies memory content (word)", "{address} {second address} {size} optional{repeat}" }, - { "ft", debuggerFindText, "Search memory for ASCII-string.", " [] " }, - { "fh", debuggerFindHex, "Search memory for hex-string.", " [] " }, - { "fr", debuggerFindResume, "Resume current search.", "[]" }, + { "ft", debuggerFindText, "Search memory for ASCII-string.", " [] " }, + { "fh", debuggerFindHex, "Search memory for hex-string.", " [] " }, + { "fr", debuggerFindResume, "Resume current search.", "[]" }, - { "io", debuggerIo, "Show I/O registers status", "[video|video2|dma|timer|misc]" }, - // { "load", debuggerReadState, "Loads a Fx type savegame", "" }, + { "io", debuggerIo, "Show I/O registers status", "[video|video2|dma|timer|misc]" }, + // { "load", debuggerReadState, "Loads a Fx type savegame", "" }, - { "mb", debuggerMemoryByte, "Shows memory contents (bytes)", "{address}" }, - { "mh", debuggerMemoryHalfWord, "Shows memory contents (half-words)", "{address}" }, - { "mw", debuggerMemoryWord, "Shows memory contents (words)", "{address}" }, - { "ms", debuggerStringRead, "Shows memory contents (table string)", "{address}" }, + { "mb", debuggerMemoryByte, "Shows memory contents (bytes)", "{address}" }, + { "mh", debuggerMemoryHalfWord, "Shows memory contents (half-words)", "{address}" }, + { "mw", debuggerMemoryWord, "Shows memory contents (words)", "{address}" }, + { "ms", debuggerStringRead, "Shows memory contents (table string)", "{address}" }, - { "r", debuggerRegisters, "Shows ARM registers", NULL }, - // { "rt", debuggerRunTo, "Run to address", "{address}" }, - // { "rta", debuggerRunToArm, "Run to address (ARM)", "{address}" }, - // { "rtt", debuggerRunToThumb, "Run to address (Thumb)", "{address}" }, + { "r", debuggerRegisters, "Shows ARM registers", NULL }, + // { "rt", debuggerRunTo, "Run to address", "{address}" }, + // { "rta", debuggerRunToArm, "Run to address (ARM)", "{address}" }, + // { "rtt", debuggerRunToThumb, "Run to address (Thumb)", "{address}" }, - // { "reset", debuggerResetSystem, "Resets the system", NULL }, - // { "reload", debuggerReloadRom, "Reloads the ROM", "optional {rom path}" }, - { "execute", debuggerExecuteCommands, "Executes commands from a text file", "{file path}" }, + // { "reset", debuggerResetSystem, "Resets the system", NULL }, + // { "reload", debuggerReloadRom, "Reloads the ROM", "optional {rom path}" }, + { "execute", debuggerExecuteCommands, "Executes commands from a text file", "{file path}" }, - // { "save", debuggerWriteState, "Creates a Fx type savegame", "" }, - // { "sbreak", debuggerBreak, "Adds a breakpoint on the given function", "||" }, - { "sradix", debuggerSetRadix, "Sets the print radix", "" }, - // { "sprint", debuggerPrint, "Print the value of a expression (if known)", "[/x|/o|/d] " }, - { "ssymbols", debuggerSymbols, "List symbols", "[]" }, - //#ifndef FINAL_VERSION - // { "strace", debuggerDebug, "Sets the trace level", "" }, - //#endif - //#ifdef DEV_VERSION - // { "sverbose", debuggerVerbose, "Change verbose setting", "" }, - //#endif - { "swhere", debuggerWhere, "Shows call chain", NULL }, + // { "save", debuggerWriteState, "Creates a Fx type savegame", "" }, + // { "sbreak", debuggerBreak, "Adds a breakpoint on the given function", "||" }, + { "sradix", debuggerSetRadix, "Sets the print radix", "" }, + // { "sprint", debuggerPrint, "Print the value of a expression (if known)", "[/x|/o|/d] " }, + { "ssymbols", debuggerSymbols, "List symbols", "[]" }, + //#ifndef FINAL_VERSION + // { "strace", debuggerDebug, "Sets the trace level", "" }, + //#endif + //#ifdef DEV_VERSION + // { "sverbose", debuggerVerbose, "Change verbose setting", "" }, + //#endif + { "swhere", debuggerWhere, "Shows call chain", NULL }, - { "tbl", debuggerReadCharTable, "Loads a character table", "" }, + { "tbl", debuggerReadCharTable, "Loads a character table", "" }, - // { "trace", debuggerTrace, "Control tracer", "start|stop|file " }, - { "var", debuggerVar, "Define variables", " {variable}" }, - { NULL, NULL, NULL, NULL } // end marker + // { "trace", debuggerTrace, "Control tracer", "start|stop|file " }, + { "var", debuggerVar, "Define variables", " {variable}" }, + { NULL, NULL, NULL, NULL } // end marker }; void printFlagHelp() { - monprintf("Flags are combinations of six distinct characters:\n"); - monprintf("\t\te --> Equal to;\n"); - monprintf("\t\tg --> Greater than;\n"); - monprintf("\t\tl --> Less than;\n"); - monprintf("\t\ts --> signed;\n"); - monprintf("\t\tu --> unsigned (assumed by ommision);\n"); - monprintf("\t\tn --> not;\n"); - monprintf("Ex: ge -> greater or equal; ne -> not equal; lg --> less or greater (same as not equal);\n"); - monprintf("s and u parts cannot be used in the same line, and are not negated by n;\n"); - monprintf("Special flags: always(all true), never(all false).\n"); + monprintf("Flags are combinations of six distinct characters:\n"); + monprintf("\t\te --> Equal to;\n"); + monprintf("\t\tg --> Greater than;\n"); + monprintf("\t\tl --> Less than;\n"); + monprintf("\t\ts --> signed;\n"); + monprintf("\t\tu --> unsigned (assumed by ommision);\n"); + monprintf("\t\tn --> not;\n"); + monprintf("Ex: ge -> greater or equal; ne -> not equal; lg --> less or greater (same as not equal);\n"); + monprintf("s and u parts cannot be used in the same line, and are not negated by n;\n"); + monprintf("Special flags: always(all true), never(all false).\n"); } -void debuggerUsage(const char *cmd) +void debuggerUsage(const char* cmd) { - if (!strcmp(cmd, "break")){ - monprintf("Break command, composed of three parts:\n"); - monprintf("Break (b, bp or break): Indicates a break command;\n"); - monprintf("Type of break: Indicates the type of break the command applies to;\n"); - monprintf("Command: Indicates the type of command to be applied.\n"); - monprintf("Type Flags:\n\tt (thumb): The Thumb execution mode.\n"); - monprintf("\ta (ARM): The ARM execution mode.\n"); - monprintf("\tx (execution, exe, exec, e): Any execution mode.\n"); - monprintf("\tr (read): When a read occurs.\n"); - monprintf("\tw (write): When a write occurs.\n"); - monprintf("\ti (io, access,acc): When memory access (read or write) occurs.\n"); - monprintf("\tg (register, reg): Special On Register value change break.\n"); - monprintf("\t* (any): On any occasion (except register change).Omission value.\n"); - monprintf("Cmd Flags:\n\tm (make): Create a breakpoint.Default omission value.\n"); - monprintf("\tl (list,lst): Lists all existing breakpoints of the specified type.\n"); - monprintf("\td (delete,del): Deletes a specific breakpoint of the specified type.\n"); - monprintf("\tc (clear, clean, cls): Erases all breakpoints of the specified type.\n"); - monprintf("\n"); - monprintf("All those flags can be combined in order to access the several break functions\n"); - monprintf("EX: btc clears all breaks; bx, bxm creates a breakpoint on any type of execution.\n"); - monprintf("All commands can be built by using [b|bp][TypeFlag][CommandFlag];\n"); - monprintf("All commands can be built by using [b|bp|break] [TypeFlag|alias] [CommandFlag|alias];\n"); - monprintf("Each command has separate arguments from each other.\nFor more details, use help b[reg|m|d|c|l]\n"); - return; - } - if (!strcmp(cmd, "breg")){ - monprintf("Break on register command, special case of the break command.\n"); - monprintf("It allows the user to break when a certain value is inside a register.\n"); - monprintf("All register breaks are conditional.\n"); - monprintf("Usage: breg [regName] [condition] [Expression].\n"); - monprintf("regName is between r0 and r15 (PC, LR and SP included);\n"); - monprintf("expression is an evaluatable expression whose value determines when to break;\n"); - monprintf("condition is the condition to be evaluated in typeFlags.\n"); - printFlagHelp(); - monprintf("---------!!!WARNING!!!---------\n"); - monprintf("Register checking and breaking is extremely expensive for the computer.\n"); - monprintf("On one of the test machines, a maximum value of 600% for speedup collapsed\n"); - monprintf("to 350% just from having them enabled.\n"); - monprintf("If (or while) not needed, you can have a speedup by disabling them, using\n"); - monprintf("disable breg.\n"); - monprintf("Breg is disabled by default. Re-enable them using enable breg.\n"); - monprintf("Use example: breg r0 ne 0x0 --> Breaks as soon as r0 is not 0.\n"); - return; - } - if (!strcmp(cmd, "bm")){ - monprintf("Create breakpoint command. Used to place a breakpoint on a given address.\n"); - monprintf("It allows for breaks on execution(any processor mode) and on access(r/w).\n"); - monprintf("Breaks can be Conditional or Inconditional.\n\n"); - monprintf("Inconditional breaks:\nUsage: [breakTag] [address]\n"); - monprintf("Simplest of the two, the old type of breaks. Creates a breakpoint that, when\n"); - monprintf("the given type flag occurs (like a read, or a run when in thumb mode), halts;\n\n"); - monprintf("Conditional breaks:\n"); - monprintf("Usage:\n\t[breakTag] [address] if {' [expr] [cond] ' [expr] <&&,||>}\n"); - monprintf("Where <> elements are optional, {} are repeateable;\n"); - monprintf("[expression] are evaluatable expressions, in the usual VBA format\n(that is, eval acceptable);\n"); - monprintf("type is the type of that expression. Uses C-like names. Omission means integer.\n"); - monprintf("cond is the condition to be evaluated.\n"); - monprintf("If && or || are not present, the chain of evaluation stops.\n"); - monprintf("&& states the next condition must happen with the previous one, or the break\nfails.\n"); - monprintf("|| states the next condition is independent from the last one, and break\nseparately.\n\n"); - monprintf("Type can be:\n"); - monprintf(" [u8, b, byte],[u16, h, hword, halfword],[u32,w, word]\n"); - monprintf(" [s8, sb, sbyte],[s16, sh, shword, short, shalfword],[s32, int, sw, word]\n"); - monprintf("Types have to be preceded by a ' ex: 'int, 'u8\n\n"); - monprintf("Conditions may be:\n"); - monprintf("C-like:\t\t[<], [<=], [>], [>=] , [==], [!= or <>]\n"); - monprintf("ASM-like:\t[lt], [le], [gt], [ge] , [eq], [ne]\n\n"); - monprintf("EX: bw 0x03005008 if old_value == 'u32 [0x03005008]\n"); - monprintf("Breaks on write from 0x03005008, when the old_value variable, that is assigned\n"); - monprintf("as the previous memory value when a write is performed, is equal to the new\ncontents of 0x03005008.\n\n"); - monprintf("EX: bx 0x08000500 if r0 == 1 || r0 > 1 && r2 == 0 || 'u8 [r7] == 5\n"); - monprintf("Breaks in either thumb or arm execution of 0x08000500, if r0's contents are 1,\n"); - monprintf("or if r0's contents are bigger than 1 and r2 is equal to 0, or the content of\nthe address at r7(as byte) is equal to 5.\n"); - monprintf("It will not break if r0 > 1 and r2 != 0.\n"); - return; - } - if (!strcmp(cmd, "bl")){ - monprintf("List breakpoints command. Used to view breakpoints.\n"); - monprintf("Usage: [breakTag]
\n"); - monprintf("It will list all breaks on the specified type (read, write..).\n"); - monprintf("If (optional) address is included, it will try and list all breaks of that type\n"); - monprintf("for that address.\n"); - monprintf("The numbers shown on that list (No.) are the ones needed to delete it directly.\n"); - monprintf("v option lists all requested values, even if empty.\n"); - return; - } - if (!strcmp(cmd, "bc")){ - monprintf("Clear breakpoints command. Clears all specified breakpoints.\n"); - monprintf("Usage: [breakTag] \n"); - monprintf("It will delete all breaks on all addresses for the specified type.\n"); - monprintf("If (optional) or is included, it will try and delete all breaks associated with\n"); - monprintf("the flags. EX: bic or --> Deletes all breaks on read and all on write.\n"); - return; - } - if (!strcmp(cmd, "bd")){ - monprintf("Delete breakpoint command. Clears the specified breakpoint.\n"); - monprintf("Usage: [breakTag] [address] [number]\n"); - monprintf("It will delete the numbered break on that addresses for the specified type.\n"); - monprintf("If only is included, it will delete only breaks with the specified flag.\n"); - monprintf("EX: bxd 0x8000000 only -->Deletes all breaks on 0x08000000 that break on both\n"); - monprintf("arm and thumb modes. Thumb only or ARM only are unnafected.\n"); - monprintf("EX: btd 0x8000000 5 -->Deletes the thumb break from the 5th break on 0x8000000.\n"); - monprintf("---------!!!WARNING!!!---------\n"); - monprintf("Break numbers are volatile, and may change at any time. before deleting any one\n"); - monprintf("breakpoint, list them to see if the number hasn't changed. The numbers may\n"); - monprintf("change only when you add or delete a breakpoint to that address. Numbers are \n"); - monprintf("internal to each address.\n"); - return; - } + if (!strcmp(cmd, "break")) { + monprintf("Break command, composed of three parts:\n"); + monprintf("Break (b, bp or break): Indicates a break command;\n"); + monprintf("Type of break: Indicates the type of break the command applies to;\n"); + monprintf("Command: Indicates the type of command to be applied.\n"); + monprintf("Type Flags:\n\tt (thumb): The Thumb execution mode.\n"); + monprintf("\ta (ARM): The ARM execution mode.\n"); + monprintf("\tx (execution, exe, exec, e): Any execution mode.\n"); + monprintf("\tr (read): When a read occurs.\n"); + monprintf("\tw (write): When a write occurs.\n"); + monprintf("\ti (io, access,acc): When memory access (read or write) occurs.\n"); + monprintf("\tg (register, reg): Special On Register value change break.\n"); + monprintf("\t* (any): On any occasion (except register change).Omission value.\n"); + monprintf("Cmd Flags:\n\tm (make): Create a breakpoint.Default omission value.\n"); + monprintf("\tl (list,lst): Lists all existing breakpoints of the specified type.\n"); + monprintf("\td (delete,del): Deletes a specific breakpoint of the specified type.\n"); + monprintf("\tc (clear, clean, cls): Erases all breakpoints of the specified type.\n"); + monprintf("\n"); + monprintf("All those flags can be combined in order to access the several break functions\n"); + monprintf("EX: btc clears all breaks; bx, bxm creates a breakpoint on any type of execution.\n"); + monprintf("All commands can be built by using [b|bp][TypeFlag][CommandFlag];\n"); + monprintf("All commands can be built by using [b|bp|break] [TypeFlag|alias] [CommandFlag|alias];\n"); + monprintf("Each command has separate arguments from each other.\nFor more details, use help b[reg|m|d|c|l]\n"); + return; + } + if (!strcmp(cmd, "breg")) { + monprintf("Break on register command, special case of the break command.\n"); + monprintf("It allows the user to break when a certain value is inside a register.\n"); + monprintf("All register breaks are conditional.\n"); + monprintf("Usage: breg [regName] [condition] [Expression].\n"); + monprintf("regName is between r0 and r15 (PC, LR and SP included);\n"); + monprintf("expression is an evaluatable expression whose value determines when to break;\n"); + monprintf("condition is the condition to be evaluated in typeFlags.\n"); + printFlagHelp(); + monprintf("---------!!!WARNING!!!---------\n"); + monprintf("Register checking and breaking is extremely expensive for the computer.\n"); + monprintf("On one of the test machines, a maximum value of 600% for speedup collapsed\n"); + monprintf("to 350% just from having them enabled.\n"); + monprintf("If (or while) not needed, you can have a speedup by disabling them, using\n"); + monprintf("disable breg.\n"); + monprintf("Breg is disabled by default. Re-enable them using enable breg.\n"); + monprintf("Use example: breg r0 ne 0x0 --> Breaks as soon as r0 is not 0.\n"); + return; + } + if (!strcmp(cmd, "bm")) { + monprintf("Create breakpoint command. Used to place a breakpoint on a given address.\n"); + monprintf("It allows for breaks on execution(any processor mode) and on access(r/w).\n"); + monprintf("Breaks can be Conditional or Inconditional.\n\n"); + monprintf("Inconditional breaks:\nUsage: [breakTag] [address]\n"); + monprintf("Simplest of the two, the old type of breaks. Creates a breakpoint that, when\n"); + monprintf("the given type flag occurs (like a read, or a run when in thumb mode), halts;\n\n"); + monprintf("Conditional breaks:\n"); + monprintf("Usage:\n\t[breakTag] [address] if {' [expr] [cond] ' [expr] <&&,||>}\n"); + monprintf("Where <> elements are optional, {} are repeateable;\n"); + monprintf("[expression] are evaluatable expressions, in the usual VBA format\n(that is, eval acceptable);\n"); + monprintf("type is the type of that expression. Uses C-like names. Omission means integer.\n"); + monprintf("cond is the condition to be evaluated.\n"); + monprintf("If && or || are not present, the chain of evaluation stops.\n"); + monprintf("&& states the next condition must happen with the previous one, or the break\nfails.\n"); + monprintf("|| states the next condition is independent from the last one, and break\nseparately.\n\n"); + monprintf("Type can be:\n"); + monprintf(" [u8, b, byte],[u16, h, hword, halfword],[u32,w, word]\n"); + monprintf(" [s8, sb, sbyte],[s16, sh, shword, short, shalfword],[s32, int, sw, word]\n"); + monprintf("Types have to be preceded by a ' ex: 'int, 'u8\n\n"); + monprintf("Conditions may be:\n"); + monprintf("C-like:\t\t[<], [<=], [>], [>=] , [==], [!= or <>]\n"); + monprintf("ASM-like:\t[lt], [le], [gt], [ge] , [eq], [ne]\n\n"); + monprintf("EX: bw 0x03005008 if old_value == 'u32 [0x03005008]\n"); + monprintf("Breaks on write from 0x03005008, when the old_value variable, that is assigned\n"); + monprintf("as the previous memory value when a write is performed, is equal to the new\ncontents of 0x03005008.\n\n"); + monprintf("EX: bx 0x08000500 if r0 == 1 || r0 > 1 && r2 == 0 || 'u8 [r7] == 5\n"); + monprintf("Breaks in either thumb or arm execution of 0x08000500, if r0's contents are 1,\n"); + monprintf("or if r0's contents are bigger than 1 and r2 is equal to 0, or the content of\nthe address at r7(as byte) is equal to 5.\n"); + monprintf("It will not break if r0 > 1 and r2 != 0.\n"); + return; + } + if (!strcmp(cmd, "bl")) { + monprintf("List breakpoints command. Used to view breakpoints.\n"); + monprintf("Usage: [breakTag]
\n"); + monprintf("It will list all breaks on the specified type (read, write..).\n"); + monprintf("If (optional) address is included, it will try and list all breaks of that type\n"); + monprintf("for that address.\n"); + monprintf("The numbers shown on that list (No.) are the ones needed to delete it directly.\n"); + monprintf("v option lists all requested values, even if empty.\n"); + return; + } + if (!strcmp(cmd, "bc")) { + monprintf("Clear breakpoints command. Clears all specified breakpoints.\n"); + monprintf("Usage: [breakTag] \n"); + monprintf("It will delete all breaks on all addresses for the specified type.\n"); + monprintf("If (optional) or is included, it will try and delete all breaks associated with\n"); + monprintf("the flags. EX: bic or --> Deletes all breaks on read and all on write.\n"); + return; + } + if (!strcmp(cmd, "bd")) { + monprintf("Delete breakpoint command. Clears the specified breakpoint.\n"); + monprintf("Usage: [breakTag] [address] [number]\n"); + monprintf("It will delete the numbered break on that addresses for the specified type.\n"); + monprintf("If only is included, it will delete only breaks with the specified flag.\n"); + monprintf("EX: bxd 0x8000000 only -->Deletes all breaks on 0x08000000 that break on both\n"); + monprintf("arm and thumb modes. Thumb only or ARM only are unnafected.\n"); + monprintf("EX: btd 0x8000000 5 -->Deletes the thumb break from the 5th break on 0x8000000.\n"); + monprintf("---------!!!WARNING!!!---------\n"); + monprintf("Break numbers are volatile, and may change at any time. before deleting any one\n"); + monprintf("breakpoint, list them to see if the number hasn't changed. The numbers may\n"); + monprintf("change only when you add or delete a breakpoint to that address. Numbers are \n"); + monprintf("internal to each address.\n"); + return; + } - for (int i = 0;; i++) { - if (debuggerCommands[i].name) { - if (!strcmp(debuggerCommands[i].name, cmd)) { - sprintf(monbuf, "%s %s\t%s\n", - debuggerCommands[i].name, - debuggerCommands[i].syntax ? debuggerCommands[i].syntax : "", - debuggerCommands[i].help); - monprintf(monbuf); - break; - } - } - else { - { sprintf(monbuf, "Unrecognized command '%s'.", cmd); monprintf(monbuf); } - break; - } - } + for (int i = 0;; i++) { + if (debuggerCommands[i].name) { + if (!strcmp(debuggerCommands[i].name, cmd)) { + sprintf(monbuf, "%s %s\t%s\n", + debuggerCommands[i].name, + debuggerCommands[i].syntax ? debuggerCommands[i].syntax : "", + debuggerCommands[i].help); + monprintf(monbuf); + break; + } + } else { + { + sprintf(monbuf, "Unrecognized command '%s'.", cmd); + monprintf(monbuf); + } + break; + } + } } -void debuggerHelp(int n, char **args) +void debuggerHelp(int n, char** args) { - if (n == 2) { - debuggerUsage(args[1]); - } - else { - for (int i = 0;; i++) { - if (debuggerCommands[i].name) { - { sprintf(monbuf, "%-10s%s\n", debuggerCommands[i].name, debuggerCommands[i].help); monprintf(monbuf); } - } - else - break; - } - { sprintf(monbuf, "%-10s%s\n", "break", "Breakpoint commands"); monprintf(monbuf); } - } + if (n == 2) { + debuggerUsage(args[1]); + } else { + for (int i = 0;; i++) { + if (debuggerCommands[i].name) { + { + sprintf(monbuf, "%-10s%s\n", debuggerCommands[i].name, debuggerCommands[i].help); + monprintf(monbuf); + } + } else + break; + } + { + sprintf(monbuf, "%-10s%s\n", "break", "Breakpoint commands"); + monprintf(monbuf); + } + } } char* strqtok(char* string, const char* ctrl) { - static char* nexttoken = NULL; - char* str; + static char* nexttoken = NULL; + char* str; - if (string != NULL) - str = string; - else { - if (nexttoken == NULL) - return NULL; - str = nexttoken; - }; + if (string != NULL) + str = string; + else { + if (nexttoken == NULL) + return NULL; + str = nexttoken; + }; - char deli[32]; - memset(deli, 0, 32 * sizeof(char)); - while (*ctrl) - { - deli[*ctrl >> 3] |= (1 << (*ctrl & 7)); - ctrl++; - }; - // can't allow to be set - deli['"' >> 3] &= ~(1 << ('"' & 7)); + char deli[32]; + memset(deli, 0, 32 * sizeof(char)); + while (*ctrl) { + deli[*ctrl >> 3] |= (1 << (*ctrl & 7)); + ctrl++; + }; + // can't allow to be set + deli['"' >> 3] &= ~(1 << ('"' & 7)); - // jump over leading delimiters - while ((deli[*str >> 3] & (1 << (*str & 7))) && *str) - str++; + // jump over leading delimiters + while ((deli[*str >> 3] & (1 << (*str & 7))) && *str) + str++; - if (*str == '"') - { - string = ++str; + if (*str == '"') { + string = ++str; - // only break if another quote or end of string is found - while ((*str != '"') && *str) - str++; - } - else { - string = str; + // only break if another quote or end of string is found + while ((*str != '"') && *str) + str++; + } else { + string = str; - // break on delimiter - while (!(deli[*str >> 3] & (1 << (*str & 7))) && *str) - str++; - }; + // break on delimiter + while (!(deli[*str >> 3] & (1 << (*str & 7))) && *str) + str++; + }; - if (string == str) - { - nexttoken = NULL; - return NULL; - } - else { - if (*str) - { - *str = 0; - nexttoken = str + 1; - } - else - nexttoken = NULL; + if (string == str) { + nexttoken = NULL; + return NULL; + } else { + if (*str) { + *str = 0; + nexttoken = str + 1; + } else + nexttoken = NULL; - return string; - }; + return string; + }; }; -void dbgExecute(char* toRun){ - char *commands[40]; - int commandCount = 0; - commands[0] = strqtok(toRun, " \t\n"); - if (commands[0] == NULL) - return; - commandCount++; - while ((commands[commandCount] = strqtok(NULL, " \t\n"))) { - commandCount++; - if (commandCount == 40) - break; - } +void dbgExecute(char* toRun) +{ + char* commands[40]; + int commandCount = 0; + commands[0] = strqtok(toRun, " \t\n"); + if (commands[0] == NULL) + return; + commandCount++; + while ((commands[commandCount] = strqtok(NULL, " \t\n"))) { + commandCount++; + if (commandCount == 40) + break; + } - //from here on, new algorithm. - // due to the division of functions, some steps have to be made + //from here on, new algorithm. + // due to the division of functions, some steps have to be made - //first, convert the command name to a standart lowercase form - //if more lowercasing needed, do it on the caller. - for (int i = 0; commands[0][i]; i++){ - commands[0][i] = tolower(commands[0][i]); - } + //first, convert the command name to a standart lowercase form + //if more lowercasing needed, do it on the caller. + for (int i = 0; commands[0][i]; i++) { + commands[0][i] = tolower(commands[0][i]); + } - // checks if it is a quit command, if so quits. - //if (isQuitCommand(commands[0])){ - // if (quitConfirm()){ - // debugger = false; - // emulating = false; - // } - // return; - //} + // checks if it is a quit command, if so quits. + //if (isQuitCommand(commands[0])){ + // if (quitConfirm()){ + // debugger = false; + // emulating = false; + // } + // return; + //} - commands[0] = (char*)replaceAlias(commands[0], cmdAliasTable); + commands[0] = (char*)replaceAlias(commands[0], cmdAliasTable); - if (commands[0][0] == 'b'){ - executeBreakCommands(commandCount, commands); - if (commands[0][0] == '!') - commands[0][0] = 'b'; - else - return; - } + if (commands[0][0] == 'b') { + executeBreakCommands(commandCount, commands); + if (commands[0][0] == '!') + commands[0][0] = 'b'; + else + return; + } - //although it mights seem wierd, the old step is the last one to be executed. - for (int j = 0;; j++) { - bool notFound = false; - if (debuggerCommands[j].name == NULL) { - { sprintf(monbuf, "Unrecognized command %s. Type h for help.\n", commands[0]); monprintf(monbuf); } - return; - } - if (!strcmp(commands[0], debuggerCommands[j].name)) { - debuggerCommands[j].function(commandCount, commands); - return; - } - } + //although it mights seem wierd, the old step is the last one to be executed. + for (int j = 0;; j++) { + bool notFound = false; + if (debuggerCommands[j].name == NULL) { + { + sprintf(monbuf, "Unrecognized command %s. Type h for help.\n", commands[0]); + monprintf(monbuf); + } + return; + } + if (!strcmp(commands[0], debuggerCommands[j].name)) { + debuggerCommands[j].function(commandCount, commands); + return; + } + } } -void dbgExecute(std::string &cmd) +void dbgExecute(std::string& cmd) { - char* dbgCmd = new char[cmd.length() + 1]; - strcpy(dbgCmd, cmd.c_str()); - dbgExecute(dbgCmd); - delete[] dbgCmd; + char* dbgCmd = new char[cmd.length() + 1]; + strcpy(dbgCmd, cmd.c_str()); + dbgExecute(dbgCmd); + delete[] dbgCmd; } -int remoteTcpSend(char *data, int len) +int remoteTcpSend(char* data, int len) { - return send(remoteSocket, data, len, 0); + return send(remoteSocket, data, len, 0); } -int remoteTcpRecv(char *data, int len) +int remoteTcpRecv(char* data, int len) { - return recv(remoteSocket, data, len, 0); + return recv(remoteSocket, data, len, 0); } bool remoteTcpInit() { - if(remoteSocket == -1) { + if (remoteSocket == -1) { #ifdef _WIN32 - WSADATA wsaData; - int error = WSAStartup(MAKEWORD(1,1),&wsaData); + WSADATA wsaData; + int error = WSAStartup(MAKEWORD(1, 1), &wsaData); #endif // _WIN32 - SOCKET s = socket(PF_INET, SOCK_STREAM, 0); + SOCKET s = socket(PF_INET, SOCK_STREAM, 0); - remoteListenSocket = s; + remoteListenSocket = s; - if(s < 0) { - fprintf(stderr,"Error opening socket\n"); - exit(-1); - } - int tmp = 1; - setsockopt (s, SOL_SOCKET, SO_REUSEADDR, (char *) &tmp, sizeof (tmp)); + if (s < 0) { + fprintf(stderr, "Error opening socket\n"); + exit(-1); + } + int tmp = 1; + setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&tmp, sizeof(tmp)); - // char hostname[256]; - // gethostname(hostname, 256); + // char hostname[256]; + // gethostname(hostname, 256); - // hostent *ent = gethostbyname(hostname); - // unsigned long a = *((unsigned long *)ent->h_addr); + // hostent *ent = gethostbyname(hostname); + // unsigned long a = *((unsigned long *)ent->h_addr); - sockaddr_in addr; - addr.sin_family = AF_INET; - addr.sin_port = htons(remotePort); - addr.sin_addr.s_addr = htonl(0); - int count = 0; - while(count < 3) { - if(bind(s, (sockaddr *)&addr, sizeof(addr))) { - addr.sin_port = htons(ntohs(addr.sin_port)+1); - } else - break; - } - if(count == 3) { - fprintf(stderr,"Error binding \n"); - exit(-1); - } + sockaddr_in addr; + addr.sin_family = AF_INET; + addr.sin_port = htons(remotePort); + addr.sin_addr.s_addr = htonl(0); + int count = 0; + while (count < 3) { + if (bind(s, (sockaddr*)&addr, sizeof(addr))) { + addr.sin_port = htons(ntohs(addr.sin_port) + 1); + } else + break; + } + if (count == 3) { + fprintf(stderr, "Error binding \n"); + exit(-1); + } - fprintf(stderr,"Listening for a connection at port %d\n", + fprintf(stderr, "Listening for a connection at port %d\n", ntohs(addr.sin_port)); - if(listen(s, 1)) { - fprintf(stderr, "Error listening\n"); - exit(-1); - } - socklen_t len = sizeof(addr); + if (listen(s, 1)) { + fprintf(stderr, "Error listening\n"); + exit(-1); + } + socklen_t len = sizeof(addr); #ifdef _WIN32 - int flag = 0; - ioctlsocket(s, FIONBIO, (unsigned long *)&flag); + int flag = 0; + ioctlsocket(s, FIONBIO, (unsigned long*)&flag); #endif // _WIN32 - SOCKET s2 = accept(s, (sockaddr *)&addr, &len); - if(s2 > 0) { - fprintf(stderr, "Got a connection from %s %d\n", - inet_ntoa((in_addr)addr.sin_addr), - ntohs(addr.sin_port)); - } else { + SOCKET s2 = accept(s, (sockaddr*)&addr, &len); + if (s2 > 0) { + fprintf(stderr, "Got a connection from %s %d\n", + inet_ntoa((in_addr)addr.sin_addr), + ntohs(addr.sin_port)); + } else { #ifdef _WIN32 - int error = WSAGetLastError(); + int error = WSAGetLastError(); #endif // _WIN32 + } + //char dummy; + //recv(s2, &dummy, 1, 0); + //if(dummy != '+') { + // fprintf(stderr, "ACK not received\n"); + // exit(-1); + //} + remoteSocket = s2; + // close(s); } - //char dummy; - //recv(s2, &dummy, 1, 0); - //if(dummy != '+') { - // fprintf(stderr, "ACK not received\n"); - // exit(-1); - //} - remoteSocket = s2; - // close(s); - } - return true; + return true; } void remoteTcpCleanUp() { - if(remoteSocket > 0) { - fprintf(stderr, "Closing remote socket\n"); - close(remoteSocket); - remoteSocket = -1; - } - if(remoteListenSocket > 0) { - fprintf(stderr, "Closing listen socket\n"); - close(remoteListenSocket); - remoteListenSocket = -1; - } + if (remoteSocket > 0) { + fprintf(stderr, "Closing remote socket\n"); + close(remoteSocket); + remoteSocket = -1; + } + if (remoteListenSocket > 0) { + fprintf(stderr, "Closing listen socket\n"); + close(remoteListenSocket); + remoteListenSocket = -1; + } } -int remotePipeSend(char *data, int len) +int remotePipeSend(char* data, int len) { - int res = write(1, data, len); - return res; + int res = write(1, data, len); + return res; } -int remotePipeRecv(char *data, int len) +int remotePipeRecv(char* data, int len) { - int res = read(0, data, len); - return res; + int res = read(0, data, len); + return res; } bool remotePipeInit() { -// char dummy; -// if (read(0, &dummy, 1) == 1) -// { -// if(dummy != '+') { -// fprintf(stderr, "ACK not received\n"); -// exit(-1); -// } -// } + // char dummy; + // if (read(0, &dummy, 1) == 1) + // { + // if(dummy != '+') { + // fprintf(stderr, "ACK not received\n"); + // exit(-1); + // } + // } - return true; + return true; } void remotePipeCleanUp() @@ -2813,789 +3500,762 @@ void remotePipeCleanUp() void remoteSetPort(int port) { - remotePort = port; + remotePort = port; } void remoteSetProtocol(int p) { - if(p == 0) { - remoteSendFnc = remoteTcpSend; - remoteRecvFnc = remoteTcpRecv; - remoteInitFnc = remoteTcpInit; - remoteCleanUpFnc = remoteTcpCleanUp; - } else { - remoteSendFnc = remotePipeSend; - remoteRecvFnc = remotePipeRecv; - remoteInitFnc = remotePipeInit; - remoteCleanUpFnc = remotePipeCleanUp; - } + if (p == 0) { + remoteSendFnc = remoteTcpSend; + remoteRecvFnc = remoteTcpRecv; + remoteInitFnc = remoteTcpInit; + remoteCleanUpFnc = remoteTcpCleanUp; + } else { + remoteSendFnc = remotePipeSend; + remoteRecvFnc = remotePipeRecv; + remoteInitFnc = remotePipeInit; + remoteCleanUpFnc = remotePipeCleanUp; + } } void remoteInit() { - if(remoteInitFnc) - remoteInitFnc(); + if (remoteInitFnc) + remoteInitFnc(); } -void remotePutPacket(const char *packet) +void remotePutPacket(const char* packet) { - const char *hex = "0123456789abcdef"; - char buffer[1024]; + const char* hex = "0123456789abcdef"; + char buffer[1024]; - size_t count = strlen(packet); + size_t count = strlen(packet); - unsigned char csum = 0; + unsigned char csum = 0; - char *p = buffer; - *p++ = '$'; + char* p = buffer; + *p++ = '$'; - for(size_t i = 0 ;i < count; i++) { - csum += packet[i]; - *p++ = packet[i]; - } - *p++ = '#'; - *p++ = hex[csum>>4]; - *p++ = hex[csum & 15]; - *p++ = 0; - //log("send: %s\n", buffer); + for (size_t i = 0; i < count; i++) { + csum += packet[i]; + *p++ = packet[i]; + } + *p++ = '#'; + *p++ = hex[csum >> 4]; + *p++ = hex[csum & 15]; + *p++ = 0; + //log("send: %s\n", buffer); - char c = 0; - while(c != '+'){ - remoteSendFnc(buffer, (int)count + 4); - if(remoteRecvFnc(&c, 1) < 0) - return; -// fprintf(stderr,"sent:%s recieved:%c\n",buffer,c); - } + char c = 0; + while (c != '+') { + remoteSendFnc(buffer, (int)count + 4); + if (remoteRecvFnc(&c, 1) < 0) + return; + // fprintf(stderr,"sent:%s recieved:%c\n",buffer,c); + } } -void remoteOutput(const char *s, u32 addr) +void remoteOutput(const char* s, u32 addr) { - char buffer[16384]; + char buffer[16384]; - char *d = buffer; - *d++ = 'O'; + char* d = buffer; + *d++ = 'O'; - if(s) { - char c = *s++; - while(c) { - sprintf(d, "%02x", c); - d += 2; - c = *s++; + if (s) { + char c = *s++; + while (c) { + sprintf(d, "%02x", c); + d += 2; + c = *s++; + } + } else { + char c = debuggerReadByte(addr); + addr++; + while (c) { + sprintf(d, "%02x", c); + d += 2; + c = debuggerReadByte(addr); + addr++; + } } - } else { - char c= debuggerReadByte(addr); - addr++; - while(c) { - sprintf(d, "%02x", c); - d += 2; - c = debuggerReadByte(addr); - addr++; - } - } - remotePutPacket(buffer); - // fprintf(stderr, "Output sent %s\n", buffer); + remotePutPacket(buffer); + // fprintf(stderr, "Output sent %s\n", buffer); } void remoteSendSignal() { - char buffer[1024]; - sprintf(buffer, "S%02x", remoteSignal); - remotePutPacket(buffer); + char buffer[1024]; + sprintf(buffer, "S%02x", remoteSignal); + remotePutPacket(buffer); } void remoteSendStatus() { - char buffer[1024]; - sprintf(buffer, "T%02x", remoteSignal); - char *s = buffer; - s += 3; - for(int i = 0; i < 15; i++) { - u32 v = reg[i].I; - sprintf(s, "%02x:%02x%02x%02x%02x;",i, + char buffer[1024]; + sprintf(buffer, "T%02x", remoteSignal); + char* s = buffer; + s += 3; + for (int i = 0; i < 15; i++) { + u32 v = reg[i].I; + sprintf(s, "%02x:%02x%02x%02x%02x;", i, (v & 255), (v >> 8) & 255, (v >> 16) & 255, (v >> 24) & 255); - s += 12; - } - u32 v = armNextPC; - sprintf(s, "0f:%02x%02x%02x%02x;", (v & 255), - (v >> 8) & 255, - (v >> 16) & 255, - (v >> 24) & 255); - s += 12; - CPUUpdateCPSR(); - v = reg[16].I; - sprintf(s, "19:%02x%02x%02x%02x;", (v & 255), - (v >> 8) & 255, - (v >> 16) & 255, - (v >> 24) & 255); - s += 12; - *s = 0; - //log("Sending %s\n", buffer); - remotePutPacket(buffer); -} - -void remoteBinaryWrite(char *p) -{ - u32 address; - int count; - sscanf(p,"%x,%x:", &address, &count); - // monprintf("Binary write for %08x %d\n", address, count); - - p = strchr(p, ':'); - p++; - for(int i = 0; i < count; i++) { - u8 b = *p++; - switch(b) { - case 0x7d: - b = *p++; - debuggerWriteByte(address, (b^0x20)); - address++; - break; - default: - debuggerWriteByte(address, b); - address++; - break; + s += 12; } - } - // monprintf("ROM is %08x\n", debuggerReadMemory(0x8000254)); - remotePutPacket("OK"); + u32 v = armNextPC; + sprintf(s, "0f:%02x%02x%02x%02x;", (v & 255), + (v >> 8) & 255, + (v >> 16) & 255, + (v >> 24) & 255); + s += 12; + CPUUpdateCPSR(); + v = reg[16].I; + sprintf(s, "19:%02x%02x%02x%02x;", (v & 255), + (v >> 8) & 255, + (v >> 16) & 255, + (v >> 24) & 255); + s += 12; + *s = 0; + //log("Sending %s\n", buffer); + remotePutPacket(buffer); } -void remoteMemoryWrite(char *p) +void remoteBinaryWrite(char* p) { - u32 address; - int count; - sscanf(p,"%x,%x:", &address, &count); - // monprintf("Memory write for %08x %d\n", address, count); + u32 address; + int count; + sscanf(p, "%x,%x:", &address, &count); + // monprintf("Binary write for %08x %d\n", address, count); - p = strchr(p, ':'); - p++; - for(int i = 0; i < count; i++) { - u8 v = 0; - char c = *p++; - if(c <= '9') - v = (c - '0') << 4; + p = strchr(p, ':'); + p++; + for (int i = 0; i < count; i++) { + u8 b = *p++; + switch (b) { + case 0x7d: + b = *p++; + debuggerWriteByte(address, (b ^ 0x20)); + address++; + break; + default: + debuggerWriteByte(address, b); + address++; + break; + } + } + // monprintf("ROM is %08x\n", debuggerReadMemory(0x8000254)); + remotePutPacket("OK"); +} + +void remoteMemoryWrite(char* p) +{ + u32 address; + int count; + sscanf(p, "%x,%x:", &address, &count); + // monprintf("Memory write for %08x %d\n", address, count); + + p = strchr(p, ':'); + p++; + for (int i = 0; i < count; i++) { + u8 v = 0; + char c = *p++; + if (c <= '9') + v = (c - '0') << 4; + else + v = (c + 10 - 'a') << 4; + c = *p++; + if (c <= '9') + v += (c - '0'); + else + v += (c + 10 - 'a'); + debuggerWriteByte(address, v); + address++; + } + // monprintf("ROM is %08x\n", debuggerReadMemory(0x8000254)); + remotePutPacket("OK"); +} + +void remoteMemoryRead(char* p) +{ + u32 address; + int count; + sscanf(p, "%x,%x:", &address, &count); + // monprintf("Memory read for %08x %d\n", address, count); + + char buffer[1024]; + + char* s = buffer; + for (int i = 0; i < count; i++) { + u8 b = debuggerReadByte(address); + sprintf(s, "%02x", b); + address++; + s += 2; + } + *s = 0; + remotePutPacket(buffer); +} + +void remoteQuery(char* p) +{ + if (!strncmp(p, "fThreadInfo", 11)) { + remotePutPacket("m-1"); + } else if (!strncmp(p, "sThreadInfo", 11)) { + remotePutPacket("l"); + } else if (!strncmp(p, "Supported", 9)) { + remotePutPacket("PacketSize=1000"); + } else if (!strncmp(p, "Rcmd,", 5)) { + p += 5; + std::string cmd = HexToString(p); + dbgExecute(cmd); + remotePutPacket("OK"); + } else { + remotePutPacket(""); + } +} + +void remoteStepOverRange(char* p) +{ + u32 address; + u32 final; + sscanf(p, "%x,%x", &address, & final); + + remotePutPacket("OK"); + + remoteResumed = true; + do { + CPULoop(1); + if (debugger) + break; + } while (armNextPC >= address && armNextPC < final); + + remoteResumed = false; + + remoteSendStatus(); +} + +void remoteSetBreakPoint(char* p) +{ + u32 address; + int count; + sscanf(p, ",%x,%x#", &address, &count); + + for (int n = 0; n < count; n += 4) + addConditionalBreak(address + n, armState ? 0x04 : 0x08); + + // Out of bounds memory checks + //if (address < 0x2000000 || address > 0x3007fff) { + // remotePutPacket("E01"); + // return; + //} + + //if (address > 0x203ffff && address < 0x3000000) { + // remotePutPacket("E01"); + // return; + //} + + //u32 final = address + count; + + //if (address < 0x2040000 && final > 0x2040000) { + // remotePutPacket("E01"); + // return; + //} + //else if (address < 0x3008000 && final > 0x3008000) { + // remotePutPacket("E01"); + // return; + //} + remotePutPacket("OK"); +} + +void remoteClearBreakPoint(char* p) +{ + int result; + u32 address; + int count; + sscanf(p, ",%x,%x#", &address, &count); + + for (int n = 0; n < count; n += 4) + result = removeConditionalWithAddressAndFlag(address + n, armState ? 0x04 : 0x08, true); + + if (result != -2) + remotePutPacket("OK"); else - v = (c + 10 - 'a') << 4; - c = *p++; - if(c <= '9') - v += (c - '0'); + remotePutPacket(""); +} + +void remoteSetMemoryReadBreakPoint(char* p) +{ + u32 address; + int count; + sscanf(p, ",%x,%x#", &address, &count); + + for (int n = 0; n < count; n++) + addConditionalBreak(address + n, 0x02); + + // Out of bounds memory checks + //if (address < 0x2000000 || address > 0x3007fff) { + // remotePutPacket("E01"); + // return; + //} + + //if (address > 0x203ffff && address < 0x3000000) { + // remotePutPacket("E01"); + // return; + //} + + //u32 final = address + count; + + //if (address < 0x2040000 && final > 0x2040000) { + // remotePutPacket("E01"); + // return; + //} + //else if (address < 0x3008000 && final > 0x3008000) { + // remotePutPacket("E01"); + // return; + //} + remotePutPacket("OK"); +} + +void remoteClearMemoryReadBreakPoint(char* p) +{ + bool error = false; + int result; + u32 address; + int count; + sscanf(p, ",%x,%x#", &address, &count); + + for (int n = 0; n < count; n++) { + result = removeConditionalWithAddressAndFlag(address + n, 0x02, true); + if (result == -2) + error = true; + } + + if (!error) + remotePutPacket("OK"); else - v += (c + 10 - 'a'); - debuggerWriteByte(address, v); - address++; - } - // monprintf("ROM is %08x\n", debuggerReadMemory(0x8000254)); - remotePutPacket("OK"); + remotePutPacket(""); } -void remoteMemoryRead(char *p) +void remoteSetMemoryAccessBreakPoint(char* p) { - u32 address; - int count; - sscanf(p,"%x,%x:", &address, &count); - // monprintf("Memory read for %08x %d\n", address, count); + u32 address; + int count; + sscanf(p, ",%x,%x#", &address, &count); - char buffer[1024]; + for (int n = 0; n < count; n++) + addConditionalBreak(address + n, 0x03); - char *s = buffer; - for(int i = 0; i < count; i++) { - u8 b = debuggerReadByte(address); - sprintf(s, "%02x", b); - address++; - s += 2; - } - *s = 0; - remotePutPacket(buffer); + // Out of bounds memory checks + //if (address < 0x2000000 || address > 0x3007fff) { + // remotePutPacket("E01"); + // return; + //} + + //if (address > 0x203ffff && address < 0x3000000) { + // remotePutPacket("E01"); + // return; + //} + + //u32 final = address + count; + + //if (address < 0x2040000 && final > 0x2040000) { + // remotePutPacket("E01"); + // return; + //} + //else if (address < 0x3008000 && final > 0x3008000) { + // remotePutPacket("E01"); + // return; + //} + remotePutPacket("OK"); } -void remoteQuery(char *p) +void remoteClearMemoryAccessBreakPoint(char* p) { - if (!strncmp(p, "fThreadInfo", 11)) - { - remotePutPacket("m-1"); - } - else if (!strncmp(p, "sThreadInfo", 11)) - { - remotePutPacket("l"); - } - else if (!strncmp(p, "Supported", 9)) - { - remotePutPacket("PacketSize=1000"); - } - else if (!strncmp(p, "Rcmd,", 5)) - { - p += 5; - std::string cmd = HexToString(p); - dbgExecute(cmd); - remotePutPacket("OK"); - } - else - { - remotePutPacket(""); - } + bool error = false; + int result; + u32 address; + int count; + sscanf(p, ",%x,%x#", &address, &count); + + for (int n = 0; n < count; n++) { + result = removeConditionalWithAddressAndFlag(address + n, 0x03, true); + if (result == -2) + error = true; + } + + if (!error) + remotePutPacket("OK"); + else + remotePutPacket(""); } -void remoteStepOverRange(char *p) +void remoteWriteWatch(char* p, bool active) { - u32 address; - u32 final; - sscanf(p, "%x,%x", &address, &final); + u32 address; + int count; + sscanf(p, ",%x,%x#", &address, &count); - remotePutPacket("OK"); + if (active) { + for (int n = 0; n < count; n++) + addConditionalBreak(address + n, 0x01); + } else { + for (int n = 0; n < count; n++) + removeConditionalWithAddressAndFlag(address + n, 0x01, true); + } - remoteResumed = true; - do { - CPULoop(1); - if(debugger) - break; - } while(armNextPC >= address && armNextPC < final); + // Out of bounds memory check + //fprintf(stderr, "Write watch for %08x %d\n", address, count); - remoteResumed = false; + //if(address < 0x2000000 || address > 0x3007fff) { + // remotePutPacket("E01"); + // return; + //} - remoteSendStatus(); -} + //if(address > 0x203ffff && address < 0x3000000) { + // remotePutPacket("E01"); + // return; + //} -void remoteSetBreakPoint(char *p) -{ - u32 address; - int count; - sscanf(p, ",%x,%x#", &address, &count); + u32 final = address + count; - for (int n = 0; n < count; n+=4) - addConditionalBreak(address + n, armState ? 0x04 : 0x08); - - // Out of bounds memory checks - //if (address < 0x2000000 || address > 0x3007fff) { - // remotePutPacket("E01"); - // return; - //} - - //if (address > 0x203ffff && address < 0x3000000) { - // remotePutPacket("E01"); - // return; - //} - - //u32 final = address + count; - - //if (address < 0x2040000 && final > 0x2040000) { - // remotePutPacket("E01"); - // return; - //} - //else if (address < 0x3008000 && final > 0x3008000) { - // remotePutPacket("E01"); - // return; - //} - remotePutPacket("OK"); -} - -void remoteClearBreakPoint(char *p) -{ - int result; - u32 address; - int count; - sscanf(p, ",%x,%x#", &address, &count); - - for (int n = 0; n < count; n+=4) - result = removeConditionalWithAddressAndFlag(address + n, armState ? 0x04 : 0x08, true); - - if (result != -2) - remotePutPacket("OK"); - else - remotePutPacket(""); -} - -void remoteSetMemoryReadBreakPoint(char *p) -{ - u32 address; - int count; - sscanf(p, ",%x,%x#", &address, &count); - - for (int n = 0; n < count; n++) - addConditionalBreak(address + n, 0x02); - - // Out of bounds memory checks - //if (address < 0x2000000 || address > 0x3007fff) { - // remotePutPacket("E01"); - // return; - //} - - //if (address > 0x203ffff && address < 0x3000000) { - // remotePutPacket("E01"); - // return; - //} - - //u32 final = address + count; - - //if (address < 0x2040000 && final > 0x2040000) { - // remotePutPacket("E01"); - // return; - //} - //else if (address < 0x3008000 && final > 0x3008000) { - // remotePutPacket("E01"); - // return; - //} - remotePutPacket("OK"); -} - -void remoteClearMemoryReadBreakPoint(char *p) -{ - bool error = false; - int result; - u32 address; - int count; - sscanf(p, ",%x,%x#", &address, &count); - - for (int n = 0; n < count; n++) - { - result = removeConditionalWithAddressAndFlag(address + n, 0x02, true); - if (result == -2) - error = true; - } - - if (!error) - remotePutPacket("OK"); - else - remotePutPacket(""); -} - -void remoteSetMemoryAccessBreakPoint(char *p) -{ - u32 address; - int count; - sscanf(p, ",%x,%x#", &address, &count); - - for (int n = 0; n < count; n++) - addConditionalBreak(address + n, 0x03); - - // Out of bounds memory checks - //if (address < 0x2000000 || address > 0x3007fff) { - // remotePutPacket("E01"); - // return; - //} - - //if (address > 0x203ffff && address < 0x3000000) { - // remotePutPacket("E01"); - // return; - //} - - //u32 final = address + count; - - //if (address < 0x2040000 && final > 0x2040000) { - // remotePutPacket("E01"); - // return; - //} - //else if (address < 0x3008000 && final > 0x3008000) { - // remotePutPacket("E01"); - // return; - //} - remotePutPacket("OK"); -} - -void remoteClearMemoryAccessBreakPoint(char *p) -{ - bool error = false; - int result; - u32 address; - int count; - sscanf(p, ",%x,%x#", &address, &count); - - for (int n = 0; n < count; n++) - { - result = removeConditionalWithAddressAndFlag(address + n, 0x03, true); - if (result == -2) - error = true; - } - - if (!error) - remotePutPacket("OK"); - else - remotePutPacket(""); -} - -void remoteWriteWatch(char *p, bool active) -{ - u32 address; - int count; - sscanf(p, ",%x,%x#", &address, &count); - - if (active) - { - for (int n = 0; n < count; n++) - addConditionalBreak(address + n, 0x01); - } - else - { - for (int n = 0; n < count; n++) - removeConditionalWithAddressAndFlag(address + n, 0x01, true); - } - - // Out of bounds memory check - //fprintf(stderr, "Write watch for %08x %d\n", address, count); - - //if(address < 0x2000000 || address > 0x3007fff) { - // remotePutPacket("E01"); - // return; - //} - - //if(address > 0x203ffff && address < 0x3000000) { - // remotePutPacket("E01"); - // return; - //} - - u32 final = address + count; - - //if(address < 0x2040000 && final > 0x2040000) { - // remotePutPacket("E01"); - // return; - //} else if(address < 0x3008000 && final > 0x3008000) { - // remotePutPacket("E01"); - // return; - //} +//if(address < 0x2040000 && final > 0x2040000) { +// remotePutPacket("E01"); +// return; +//} else if(address < 0x3008000 && final > 0x3008000) { +// remotePutPacket("E01"); +// return; +//} #ifdef BKPT_SUPPORT - for(int i = 0; i < count; i++) { - if((address >> 24) == 2) - freezeWorkRAM[address & 0x3ffff] = active; - else - freezeInternalRAM[address & 0x7fff] = active; - address++; - } + for (int i = 0; i < count; i++) { + if ((address >> 24) == 2) + freezeWorkRAM[address & 0x3ffff] = active; + else + freezeInternalRAM[address & 0x7fff] = active; + address++; + } #endif - remotePutPacket("OK"); + remotePutPacket("OK"); } -void remoteReadRegister(char *p) +void remoteReadRegister(char* p) { - int r; - sscanf(p, "%x", &r); - char buffer[1024]; - char *s = buffer; - u32 v = reg[r].I; - sprintf(s, "%02x%02x%02x%02x", v & 255, (v >> 8) & 255, - (v >> 16) & 255, (v >> 24) & 255); - remotePutPacket(buffer); + int r; + sscanf(p, "%x", &r); + char buffer[1024]; + char* s = buffer; + u32 v = reg[r].I; + sprintf(s, "%02x%02x%02x%02x", v & 255, (v >> 8) & 255, + (v >> 16) & 255, (v >> 24) & 255); + remotePutPacket(buffer); } -void remoteReadRegisters(char *p) +void remoteReadRegisters(char* p) { - char buffer[1024]; + char buffer[1024]; - char *s = buffer; - int i; - // regular registers - for(i = 0; i < 15; i++) { - u32 v = reg[i].I; - sprintf(s, "%02x%02x%02x%02x", v & 255, (v >> 8) & 255, + char* s = buffer; + int i; + // regular registers + for (i = 0; i < 15; i++) { + u32 v = reg[i].I; + sprintf(s, "%02x%02x%02x%02x", v & 255, (v >> 8) & 255, (v >> 16) & 255, (v >> 24) & 255); + s += 8; + } + // PC + u32 pc = armNextPC; + sprintf(s, "%02x%02x%02x%02x", pc & 255, (pc >> 8) & 255, + (pc >> 16) & 255, (pc >> 24) & 255); s += 8; - } - // PC - u32 pc = armNextPC; - sprintf(s, "%02x%02x%02x%02x", pc & 255, (pc >> 8) & 255, - (pc >> 16) & 255, (pc >> 24) & 255); - s += 8; - // floating point registers (24-bit) - for(i = 0; i < 8; i++) { - sprintf(s, "000000000000000000000000"); - s += 24; - } + // floating point registers (24-bit) + for (i = 0; i < 8; i++) { + sprintf(s, "000000000000000000000000"); + s += 24; + } - // FP status register - sprintf(s, "00000000"); - s += 8; - // CPSR - CPUUpdateCPSR(); - u32 v = reg[16].I; - sprintf(s, "%02x%02x%02x%02x", v & 255, (v >> 8) & 255, - (v >> 16) & 255, (v >> 24) & 255); - s += 8; - *s = 0; - remotePutPacket(buffer); + // FP status register + sprintf(s, "00000000"); + s += 8; + // CPSR + CPUUpdateCPSR(); + u32 v = reg[16].I; + sprintf(s, "%02x%02x%02x%02x", v & 255, (v >> 8) & 255, + (v >> 16) & 255, (v >> 24) & 255); + s += 8; + *s = 0; + remotePutPacket(buffer); } -void remoteWriteRegister(char *p) +void remoteWriteRegister(char* p) { - int r; + int r; - sscanf(p, "%x=", &r); + sscanf(p, "%x=", &r); - p = strchr(p, '='); - p++; + p = strchr(p, '='); + p++; - char c = *p++; + char c = *p++; - u32 v = 0; + u32 v = 0; - u8 data[4] = {0,0,0,0}; + u8 data[4] = { 0, 0, 0, 0 }; - int i = 0; + int i = 0; - while(i < 4) { - u8 b = 0; - if(c <= '9') - b = (c - '0') << 4; - else - b = (c + 10 - 'a') << 4; - c = *p++; - if(c <= '9') - b += (c - '0'); - else - b += (c + 10 - 'a'); - data[i++] = b; - c = *p++; - } + while (i < 4) { + u8 b = 0; + if (c <= '9') + b = (c - '0') << 4; + else + b = (c + 10 - 'a') << 4; + c = *p++; + if (c <= '9') + b += (c - '0'); + else + b += (c + 10 - 'a'); + data[i++] = b; + c = *p++; + } - v = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24); + v = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24); - // monprintf("Write register %d=%08x\n", r, v); - reg[r].I = v; - if(r == 15) { - armNextPC = v; - if(armState) - reg[15].I = v + 4; - else - reg[15].I = v + 2; - } - remotePutPacket("OK"); + // monprintf("Write register %d=%08x\n", r, v); + reg[r].I = v; + if (r == 15) { + armNextPC = v; + if (armState) + reg[15].I = v + 4; + else + reg[15].I = v + 2; + } + remotePutPacket("OK"); } void remoteStubMain() { - if(!debugger) - return; + if (!debugger) + return; - if(remoteResumed) { - remoteSendStatus(); - remoteResumed = false; - } - - const char *hex = "0123456789abcdef"; - while(1) { - char ack; - char buffer[1024]; - int res = remoteRecvFnc(buffer, 1024); - - if(res == -1) { - fprintf(stderr, "GDB connection lost\n"); - debugger = false; - break; - } else if(res == -2) - break; - if(res < 1024){ - buffer[res] = 0; - }else{ - fprintf(stderr, "res=%d\n",res); + if (remoteResumed) { + remoteSendStatus(); + remoteResumed = false; } -// fprintf(stderr, "res=%d Received %s\n",res, buffer); - char c = buffer[0]; - char *p = &buffer[0]; - int i = 0; - unsigned char csum = 0; - while(i < res){ - if(buffer[i] == '$'){ - i++; - csum = 0; - c = buffer[i]; - p = &buffer[i+1]; - while((i>4]) && (buffer[i+2] == hex[csum & 0xf])){ - ack = '+'; - remoteSendFnc(&ack, 1); - //fprintf(stderr, "SentACK c=%c\n",c); - //process message... - char type; - switch(c) { - case '?': - remoteSendSignal(); - break; - case 'D': - remotePutPacket("OK"); - remoteResumed = true; - debugger = false; - return; - case 'e': - remoteStepOverRange(p); - break; - case 'k': - remotePutPacket("OK"); - debugger = false; - emulating = false; - return; - case 'C': - remoteResumed = true; - debugger = false; - return; - case 'c': - remoteResumed = true; - debugger = false; - return; - case 's': - remoteResumed = true; - remoteSignal = 5; - CPULoop(1); - if(remoteResumed) { - remoteResumed = false; - remoteSendStatus(); - } - break; - case 'g': - remoteReadRegisters(p); - break; - case 'p': - remoteReadRegister(p); - break; - case 'P': - remoteWriteRegister(p); - break; - case 'M': - remoteMemoryWrite(p); - break; - case 'm': - remoteMemoryRead(p); - break; - case 'X': - remoteBinaryWrite(p); - break; - case 'H': - remotePutPacket("OK"); - break; - case 'q': - remoteQuery(p); - break; - case 'Z': - type = *p++; - if (type == '0') { - remoteSetBreakPoint(p); - } - else if (type == '1') { - remoteSetBreakPoint(p); - } - else if (type == '2') { - remoteWriteWatch(p, true); - } - else if (type == '3') { - remoteSetMemoryReadBreakPoint(p); - } - else if (type == '4') { - remoteSetMemoryAccessBreakPoint(p); - } - else { - remotePutPacket(""); - } - break; - case 'z': - type = *p++; - if (type == '0') { - remoteClearBreakPoint(p); - } - else if (type == '1') { - remoteClearBreakPoint(p); - } - else if (type == '2') { - remoteWriteWatch(p, false); - } - else if (type == '3') { - remoteClearMemoryReadBreakPoint(p); - } - else if (type == '4') { - remoteClearMemoryAccessBreakPoint(p); - } - else { - remotePutPacket(""); - } - break; - default: - { - fprintf(stderr, "Unknown packet %s\n", --p); - remotePutPacket(""); - } - break; - } - }else{ - fprintf(stderr, "bad chksum csum=%x msg=%c%c\n",csum,buffer[i+1],buffer[i+2]); - ack = '-'; - remoteSendFnc(&ack, 1); - fprintf(stderr, "SentNACK\n"); - }//if - i+=3; - }else{ - fprintf(stderr, "didn't receive chksum i=%d res=%d\n",i,res); - i++; - }//if - }else{ - if(buffer[i] != '+'){ //ingnore ACKs - fprintf(stderr, "not sure what to do with:%c i=%d res=%d\n",buffer[i],i,res); - } - i++; - }//if - }//while - } + + // fprintf(stderr, "res=%d Received %s\n",res, buffer); + char c = buffer[0]; + char* p = &buffer[0]; + int i = 0; + unsigned char csum = 0; + while (i < res) { + if (buffer[i] == '$') { + i++; + csum = 0; + c = buffer[i]; + p = &buffer[i + 1]; + while ((i < res) && (buffer[i] != '#')) { + csum += buffer[i]; + i++; + } + } else if (buffer[i] == '#') { + buffer[i] = 0; + if ((i + 2) < res) { + if ((buffer[i + 1] == hex[csum >> 4]) && (buffer[i + 2] == hex[csum & 0xf])) { + ack = '+'; + remoteSendFnc(&ack, 1); + //fprintf(stderr, "SentACK c=%c\n",c); + //process message... + char type; + switch (c) { + case '?': + remoteSendSignal(); + break; + case 'D': + remotePutPacket("OK"); + remoteResumed = true; + debugger = false; + return; + case 'e': + remoteStepOverRange(p); + break; + case 'k': + remotePutPacket("OK"); + debugger = false; + emulating = false; + return; + case 'C': + remoteResumed = true; + debugger = false; + return; + case 'c': + remoteResumed = true; + debugger = false; + return; + case 's': + remoteResumed = true; + remoteSignal = 5; + CPULoop(1); + if (remoteResumed) { + remoteResumed = false; + remoteSendStatus(); + } + break; + case 'g': + remoteReadRegisters(p); + break; + case 'p': + remoteReadRegister(p); + break; + case 'P': + remoteWriteRegister(p); + break; + case 'M': + remoteMemoryWrite(p); + break; + case 'm': + remoteMemoryRead(p); + break; + case 'X': + remoteBinaryWrite(p); + break; + case 'H': + remotePutPacket("OK"); + break; + case 'q': + remoteQuery(p); + break; + case 'Z': + type = *p++; + if (type == '0') { + remoteSetBreakPoint(p); + } else if (type == '1') { + remoteSetBreakPoint(p); + } else if (type == '2') { + remoteWriteWatch(p, true); + } else if (type == '3') { + remoteSetMemoryReadBreakPoint(p); + } else if (type == '4') { + remoteSetMemoryAccessBreakPoint(p); + } else { + remotePutPacket(""); + } + break; + case 'z': + type = *p++; + if (type == '0') { + remoteClearBreakPoint(p); + } else if (type == '1') { + remoteClearBreakPoint(p); + } else if (type == '2') { + remoteWriteWatch(p, false); + } else if (type == '3') { + remoteClearMemoryReadBreakPoint(p); + } else if (type == '4') { + remoteClearMemoryAccessBreakPoint(p); + } else { + remotePutPacket(""); + } + break; + default: { + fprintf(stderr, "Unknown packet %s\n", --p); + remotePutPacket(""); + } break; + } + } else { + fprintf(stderr, "bad chksum csum=%x msg=%c%c\n", csum, buffer[i + 1], buffer[i + 2]); + ack = '-'; + remoteSendFnc(&ack, 1); + fprintf(stderr, "SentNACK\n"); + } //if + i += 3; + } else { + fprintf(stderr, "didn't receive chksum i=%d res=%d\n", i, res); + i++; + } //if + } else { + if (buffer[i] != '+') { //ingnore ACKs + fprintf(stderr, "not sure what to do with:%c i=%d res=%d\n", buffer[i], i, res); + } + i++; + } //if + } //while + } } void remoteStubSignal(int sig, int number) { - remoteSignal = sig; - remoteResumed = false; - remoteSendStatus(); - debugger = true; + remoteSignal = sig; + remoteResumed = false; + remoteSendStatus(); + debugger = true; } void remoteCleanUp() { - if(remoteCleanUpFnc) - remoteCleanUpFnc(); + if (remoteCleanUpFnc) + remoteCleanUpFnc(); } -std::string HexToString(char * p) +std::string HexToString(char* p) { - std::string hex(p); - std::string cmd; - std::stringstream ss; - u32 offset = 0; - while (offset < hex.length()) { - unsigned int buffer = 0; - ss.clear(); - ss << std::hex << hex.substr(offset, 2); - ss >> std::hex >> buffer; - cmd.push_back(static_cast(buffer)); - offset += 2; - } - return cmd; + std::string hex(p); + std::string cmd; + std::stringstream ss; + u32 offset = 0; + while (offset < hex.length()) { + unsigned int buffer = 0; + ss.clear(); + ss << std::hex << hex.substr(offset, 2); + ss >> std::hex >> buffer; + cmd.push_back(static_cast(buffer)); + offset += 2; + } + return cmd; } -std::string StringToHex(std::string &cmd) +std::string StringToHex(std::string& cmd) { - std::stringstream ss; - ss << std::hex; - for (u32 i = 0; i < cmd.length(); ++i) - ss << std::setw(2) << std::setfill('0') << (int)cmd.c_str()[i]; - return ss.str(); + std::stringstream ss; + ss << std::hex; + for (u32 i = 0; i < cmd.length(); ++i) + ss << std::setw(2) << std::setfill('0') << (int)cmd.c_str()[i]; + return ss.str(); } void monprintf(std::string line) { - std::string output = "O"; - line = StringToHex(line); - output += line; + std::string output = "O"; + line = StringToHex(line); + output += line; - if (output.length() <= 1000) - { - char dbgReply[1000]; - strcpy(dbgReply, output.c_str()); - remotePutPacket(dbgReply); - } + if (output.length() <= 1000) { + char dbgReply[1000]; + strcpy(dbgReply, output.c_str()); + remotePutPacket(dbgReply); + } } #endif diff --git a/src/gba/remote.h b/src/gba/remote.h index 38c7a2fb..3f5ddef2 100644 --- a/src/gba/remote.h +++ b/src/gba/remote.h @@ -4,39 +4,39 @@ #include "../common/Types.h" #include "GBA.h" -#define BitSet(array, bit) ((u8 *)(array))[(bit) >> 3] |= (1 << ((bit)&7)) +#define BitSet(array, bit) ((u8*)(array))[(bit) >> 3] |= (1 << ((bit)&7)) -#define BitClear(array, bit) ((u8 *)(array))[(bit) >> 3] &= ~(1 << ((bit)&7)) +#define BitClear(array, bit) ((u8*)(array))[(bit) >> 3] &= ~(1 << ((bit)&7)) #define BitGet(array, bit) ((u8)((array)[(bit) >> 3]) & (u8)(1 << ((bit)&7))) -#define BreakSet(array, addr, flag) \ - ((u8 *)(array))[(addr) >> 1] |= ((addr & 1) ? (flag << 4) : (flag & 0xf)) +#define BreakSet(array, addr, flag) \ + ((u8*)(array))[(addr) >> 1] |= ((addr & 1) ? (flag << 4) : (flag & 0xf)) -#define BreakClear(array, addr, flag) \ - ((u8 *)(array))[(addr) >> 1] &= ~((addr & 1) ? (flag << 4) : (flag & 0xf)) +#define BreakClear(array, addr, flag) \ + ((u8*)(array))[(addr) >> 1] &= ~((addr & 1) ? (flag << 4) : (flag & 0xf)) // check -#define BreakThumbCheck(array, addr) ((u8 *)(array))[(addr) >> 1] & ((addr & 1) ? 0x80 : 0x8) +#define BreakThumbCheck(array, addr) ((u8*)(array))[(addr) >> 1] & ((addr & 1) ? 0x80 : 0x8) -#define BreakARMCheck(array, addr) ((u8 *)(array))[(addr) >> 1] & ((addr & 1) ? 0x40 : 0x4) +#define BreakARMCheck(array, addr) ((u8*)(array))[(addr) >> 1] & ((addr & 1) ? 0x40 : 0x4) -#define BreakReadCheck(array, addr) ((u8 *)(array))[(addr) >> 1] & ((addr & 1) ? 0x20 : 0x2) +#define BreakReadCheck(array, addr) ((u8*)(array))[(addr) >> 1] & ((addr & 1) ? 0x20 : 0x2) -#define BreakWriteCheck(array, addr) ((u8 *)(array))[(addr) >> 1] & ((addr & 1) ? 0x10 : 0x1) +#define BreakWriteCheck(array, addr) ((u8*)(array))[(addr) >> 1] & ((addr & 1) ? 0x10 : 0x1) -#define BreakCheck(array, addr, flag) \ - ((u8 *)(array))[(addr) >> 1] & ((addr & 1) ? (flag << 4) : (flag & 0xf)) +#define BreakCheck(array, addr, flag) \ + ((u8*)(array))[(addr) >> 1] & ((addr & 1) ? (flag << 4) : (flag & 0xf)) extern bool debugger; -extern bool dexp_eval(char *, u32 *); -extern void dexp_setVar(char *, u32); +extern bool dexp_eval(char*, u32*); +extern void dexp_setVar(char*, u32); extern void dexp_listVars(); -extern void dexp_saveVars(char *); -extern void dexp_loadVars(char *); +extern void dexp_saveVars(char*); +extern void dexp_loadVars(char*); -void debuggerOutput(const char *s, u32 addr); +void debuggerOutput(const char* s, u32 addr); bool debuggerBreakOnExecution(u32 address, u8 state); bool debuggerBreakOnWrite(u32 address, u32 value, int size); @@ -44,25 +44,25 @@ void debuggerBreakOnWrite(u32 address, u32 oldvalue, u32 value, int size, int t) bool debuggerBreakOnRead(u32 address, int size); struct regBreak { - // u8 regNum; /No longer needed - // bit 0 = equal - // bit 1 = greater - // bit 2 = smaller - // bit 3 = signed - u8 flags; - u32 intVal; - struct regBreak *next; + // u8 regNum; /No longer needed + // bit 0 = equal + // bit 1 = greater + // bit 2 = smaller + // bit 3 = signed + u8 flags; + u32 intVal; + struct regBreak* next; }; -extern u8 lowRegBreakCounter[4]; //(r0-r3) -extern u8 medRegBreakCounter[4]; //(r4-r7) -extern u8 highRegBreakCounter[4]; //(r8-r11) +extern u8 lowRegBreakCounter[4]; //(r0-r3) +extern u8 medRegBreakCounter[4]; //(r4-r7) +extern u8 highRegBreakCounter[4]; //(r8-r11) extern u8 statusRegBreakCounter[4]; //(r12-r15) extern bool enableRegBreak; -extern regBreak *breakRegList[16]; +extern regBreak* breakRegList[16]; extern void breakReg_check(int i); -struct regBreak *getFromBreakRegList(u8 regnum, int location); +struct regBreak* getFromBreakRegList(u8 regnum, int location); void clearBreakRegList(); void clearParticularRegListBreaks(int reg); @@ -73,7 +73,7 @@ void printBreakRegList(bool verbose); void remoteStubMain(); void remoteStubSignal(int sig, int number); -void remoteOutput(const char *s, u32 addr); +void remoteOutput(const char* s, u32 addr); void remoteSetProtocol(int p); void remoteSetPort(int port);