/* Rom Patcher JS - CRC32/MD5/SHA-1/checksums calculators v20210815 - Marc Robledo 2016-2021 - http://www.marcrobledo.com/license */ function padZeroes(intVal, nBytes){ var hexString=intVal.toString(16); while(hexString.length>2]=d[i]+(d[i+1]<<8)+(d[i+2]<<16)+(d[i+3]<<24);return md5blks} function _cmn(q,a,b,x,s,t){a=_add32(_add32(a,q),_add32(x,t));return _add32((a<>>(32-s)),b)} function ff(a,b,c,d,x,s,t){return _cmn((b&c)|((~b)&d),a,b,x,s,t)} function gg(a,b,c,d,x,s,t){return _cmn((b&d)|(c&(~d)),a,b,x,s,t)} function hh(a,b,c,d,x,s,t){return _cmn(b^c^d,a,b,x,s,t)} function ii(a,b,c,d,x,s,t){return _cmn(c^(b|(~d)),a,b,x,s,t)} function md5(marcFile, headerSize){ var data=headerSize? new Uint8Array(marcFile._u8array.buffer, headerSize):marcFile._u8array; var n=data.length,state=[1732584193,-271733879,-1732584194,271733878],i; for(i=64;i<=data.length;i+=64) _md5cycle(state,_md5blk(data.slice(i-64,i))); data=data.slice(i-64); var tail=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]; for(i=0;i>2]|=data[i]<<((i%4)<<3); tail[i>>2]|=0x80<<((i%4)<<3); if(i>55){ _md5cycle(state,tail); for(i=0;i<16;i++)tail[i]=0; } tail[14]=n*8; tail[15]=Math.floor(n/536870912) >>> 0; //if file is bigger than 512Mb*8, value is bigger than 32 bits, so it needs two words to store its length _md5cycle(state,tail); for(var i=0;i>(j*8+4))&0x0f]+HEX_CHR[(state[i]>>(j*8))&0x0f]; state[i]=s; } return state.join('') } /* CRC32 - from Alex - https://stackoverflow.com/a/18639999 */ const CRC32_TABLE=(function(){ var c,crcTable=[]; for(var n=0;n<256;n++){ c=n; for(var k=0;k<8;k++) c=((c&1)?(0xedb88320^(c>>>1)):(c>>>1)); crcTable[n]=c; } return crcTable; }()); function crc32(marcFile, headerSize, ignoreLast4Bytes){ var data=headerSize? new Uint8Array(marcFile._u8array.buffer, headerSize):marcFile._u8array; var crc=0^(-1); var len=ignoreLast4Bytes?data.length-4:data.length; for(var i=0;i>>8)^CRC32_TABLE[(crc^data[i])&0xff]; return ((crc^(-1))>>>0); } /* Adler-32 - https://en.wikipedia.org/wiki/Adler-32#Example_implementation */ const ADLER32_MOD=0xfff1; function adler32(marcFile, offset, len){ var a=1, b=0; for(var i=0; i>>0; } /* CRC16 */ /* const CRC16_TABLE=(function(){ var c,crcTable=[]; for(var n=0;n<256;n++){ c=n; for(var k=0;k<8;k++) c=((c&1)?(0x8408^(c>>>1)):(c>>>1)); crcTable[n]=c; } return crcTable; }()); function crc16(marcFile){ var crc=0^(-1); for(var i=0;i>>8)&0x0ff)^CRC16_TABLE[(crc^marcFile._u8array[i])&0xff]; return ((crc^(-1))>>>0) & 0xffff; } */ /* specific ROM checksums */ /* this is unused code, might be used in a future so ROM checksums can be fixed after patching */ const CONSOLES=[ { title:'Sega Mega Drive/Genesis', MEGADRIVE_LOGO:[0x53, 0x45, 0x47, 0x41, 0x20, 0x4d, 0x45, 0x47, 0x41, 0x20, 0x44, 0x52], GENESIS_LOGO:[0x53, 0x45, 0x47, 0x41, 0x20, 0x47, 0x45, 0x4e, 0x45, 0x53, 0x49, 0x53], checkHeader:function(marcFile){ var megadrive=true; var genesis=true; for(var i=0; i<12 && (megadrive || genesis); i++){ if(marcFile._u8array[0x100+i]!==this.MEGADRIVE_LOGO[i]) megadrive=false; if(marcFile._u8array[0x100+i]!==this.GENESIS_LOGO[i]) genesis=false; } return megadrive || genesis; }, getChecksum:function(marcFile){ return (marcFile._u8array[0x018e]<<8) + marcFile._u8array[0x018f]; }, recalculateChecksum:function(marcFile){ var checksum=0; for(var i=0x200; i>>0)) & 0xffff; return checksum }, updateChecksum:function(marcFile, newChecksum){ marcFile._u8array[0x18e]=newChecksum>>8; marcFile._u8array[0x18f]=newChecksum & 0xff; } },{ title:'Game Boy', NINTENDO_LOGO:[0xce, 0xed, 0x66, 0x66, 0xcc, 0x0d, 0x00, 0x0b, 0x03, 0x73, 0x00, 0x83, 0x00, 0x0c, 0x00, 0x0d], checkHeader:function(marcFile){ for(var i=0; i>> 0) & 0xffff; for(i=0x0150;i>> 0) & 0xffff; if(globalChecksumOld!==globalChecksumNew){ marcFile._u8array[0x014e]=globalChecksumNew>>8; marcFile._u8array[0x014f]=globalChecksumNew & 0xff; } } } ]; function checkConsole(marcFile){ return false; } function fixConsoleChecksum(marcFile){ var system=false; for(var i=0; i