void NesFile::analyzeFile(const uint8_t* const header, const uint32_t filesize, const uint8_t* data) { if(!(header[0] == 'N' && header[1]=='E' && header[2]=='S' && header[3] == 0x1a)){ throw EmulatorException("[FIXME] Invalid header: ") << filename; } this->prgSize = PRG_ROM_PAGE_SIZE * header[4]; this->chrSize = CHR_ROM_PAGE_SIZE * header[5]; this->prgPageCnt = header[4]; this->chrPageCnt = header[5]; this->mapperNo = ((header[6] & 0xf0)>>4) | (header[7] & 0xf0); this->trainerFlag = (header[6] & 0x4) == 0x4; this->sramFlag = (header[6] & 0x2) == 0x2; if((header[6] & 0x8) == 0x8){ this->mirrorType = FOUR_SCREEN; }else{ this->mirrorType = (header[6] & 0x1) == 0x1 ? VERTICAL : HORIZONTAL; } uint32_t fptr = 0; if(this->trainerFlag){ if(fptr + TRAINER_SIZE > filesize){ throw EmulatorException("[FIXME] Invalid file size; too short!: ") << filename; } memcpy(this->trainer, &data[fptr], TRAINER_SIZE); fptr += TRAINER_SIZE; } uint8_t* prgRom = new uint8_t[this->prgSize]; if(fptr + this->prgSize > filesize){ throw EmulatorException("[FIXME] Invalid file size; too short!: ") << filename; } memcpy(prgRom, &data[fptr], this->prgSize); fptr += this->prgSize; this->prgRom = prgRom; uint8_t* chrRom = new uint8_t[this->chrSize]; if(fptr + this->chrSize > filesize){ throw EmulatorException("[FIXME] Invalid file size; too short!: ") << filename; }else if(fptr + this->chrSize < filesize){ throw EmulatorException("[FIXME] Invalid file size; too long!: ") << filename; } memcpy(chrRom, &data[fptr], this->chrSize); fptr += this->chrSize; this->chrRom = chrRom; }
void Mapper21::writeBankLow(uint16_t addr, uint8_t val) { switch(addr & 0xf00f) { case 0x8000: case 0x8002: case 0x8040: case 0x8004: case 0x8080: case 0x8006: case 0x80C0: setPrgBank0(val); break; case 0x9000: case 0x9002: case 0x9040: setMirroring(val); break; case 0x9004: case 0x9080: case 0x9006: case 0x90C0: setSwapMode((val & 2) == 2); break; case 0xA000: case 0xA002: case 0xA040: case 0xA004: case 0xA080: case 0xA006: case 0xA0C0: setPrgBank1(val); break; case 0xB000: setChrBankLow(0,val); break; case 0xB002: case 0xB040: setChrBankHigh(0,val); break; case 0xB004: case 0xB080: setChrBankLow(1,val); break; case 0xB006: case 0xB0C0: setChrBankHigh(1,val); break; default: throw EmulatorException("[Mapper23] Invalid addr!! 0x") << std::hex << addr; } }
void Mapper21::writeBankHigh(uint16_t addr, uint8_t val) { switch(addr & 0xf0C6) { case 0xC000: setChrBankLow(2,val); break; case 0xC002: case 0xC040: setChrBankHigh(2,val); break; case 0xC004: case 0xC080: setChrBankLow(3,val); break; case 0xC006: case 0xC0C0: setChrBankHigh(3,val); break; case 0xD000: setChrBankLow(4,val); break; case 0xD002: case 0xD040: setChrBankHigh(4,val); break; case 0xD004: case 0xD080: setChrBankLow(5,val); break; case 0xD006: case 0xD0C0: setChrBankHigh(5,val); break; case 0xE000: setChrBankLow(6,val); break; case 0xE002: case 0xE040: setChrBankHigh(6,val); break; case 0xE004: case 0xE080: setChrBankLow(7,val); break; case 0xE006: case 0xE0C0: setChrBankHigh(7,val); break; case 0xF000: setIRQlow(val); break; case 0xF002: case 0xF040: setIRQhigh(val); break; case 0xF004: case 0xF080: setIRQmode(val); break; case 0xF006: case 0xF0C0: ackIRQ(); break; default: throw EmulatorException("[Mapper23] Invalid addr!! 0x") << std::hex << addr; } }