mirror of https://github.com/parasyte/alt64
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
108 lines
2.9 KiB
108 lines
2.9 KiB
/* |
|
checksum rom in psram, based on |
|
|
|
chksum64 V1.2, a program to calculate the ROM checksum of Nintendo64 ROMs. |
|
Copyright (C) 1997 Andreas Sterbenz (stan@sbox.tu-graz.ac.at) |
|
|
|
This program is free software; you can redistribute it and/or modify |
|
it under the terms of the GNU General Public License as published by |
|
the Free Software Foundation; either version 2 of the License, or |
|
(at your option) any later version. |
|
|
|
This program is distributed in the hope that it will be useful, |
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
GNU General Public License for more details. |
|
|
|
You should have received a copy of the GNU General Public License |
|
along with this program; if not, write to the Free Software |
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA |
|
*/ |
|
#include <stdio.h> |
|
#include <stdlib.h> |
|
#include <libdragon.h> |
|
|
|
#include "sys.h" |
|
|
|
|
|
#define BUFSIZE 0x8000 |
|
#define SDRAM_START 0xb0000000 |
|
|
|
#define CHECKSUM_START 0x1000 |
|
#define CHECKSUM_LENGTH 0x100000L |
|
#define CHECKSUM_HEADERPOS 0x10 |
|
#define CHECKSUM_END (CHECKSUM_START + CHECKSUM_LENGTH) |
|
|
|
#define CHECKSUM_STARTVALUE 0xf8ca4ddc |
|
|
|
#define ROL(i, b) (((i)<<(b)) | ((i)>>(32-(b)))) |
|
|
|
#define BYTES2LONG(b) ( (((b)[0] & 0xffL) << 24) | \ |
|
(((b)[1] & 0xffL) << 16) | \ |
|
(((b)[2] & 0xffL) << 8) | \ |
|
(((b)[3] & 0xffL)) ) |
|
|
|
#define LONG2BYTES(l, b) (b)[0] = ((l)>>24)&0xff; \ |
|
(b)[1] = ((l)>>16)&0xff; \ |
|
(b)[2] = ((l)>> 8)&0xff; \ |
|
(b)[3] = ((l) )&0xff; |
|
|
|
|
|
static unsigned char __attribute__((aligned(16))) buffer1[BUFSIZE]; |
|
|
|
|
|
void checksum_sdram(void) |
|
{ |
|
unsigned int sum1, sum2, offs; |
|
|
|
{ |
|
unsigned int i; |
|
unsigned int c1, k1, k2; |
|
unsigned int t1, t2, t3, t4; |
|
unsigned int t5, t6; |
|
unsigned int n; |
|
unsigned int clen = CHECKSUM_LENGTH; |
|
|
|
t1 = CHECKSUM_STARTVALUE; |
|
t2 = CHECKSUM_STARTVALUE; |
|
t3 = CHECKSUM_STARTVALUE; |
|
t4 = CHECKSUM_STARTVALUE; |
|
t5 = CHECKSUM_STARTVALUE; |
|
t6 = CHECKSUM_STARTVALUE; |
|
|
|
offs = CHECKSUM_START; |
|
|
|
for( ;; ) { |
|
n = (BUFSIZE < clen) ? BUFSIZE : clen; |
|
dma_read_s(buffer1, SDRAM_START+offs, n); |
|
data_cache_hit_writeback_invalidate(buffer1,n); |
|
|
|
offs += n; |
|
|
|
for( i=0; i<n; i+=4 ) { |
|
c1 = BYTES2LONG(&buffer1[i]); |
|
k1 = t6 + c1; |
|
if( k1 < t6 ) t4++; |
|
t6 = k1; |
|
t3 ^= c1; |
|
k2 = c1 & 0x1f; |
|
k1 = ROL(c1, k2); |
|
t5 += k1; |
|
if( c1 < t2 ) { |
|
t2 ^= k1; |
|
} else { |
|
t2 ^= t6 ^ c1; |
|
} |
|
t1 += c1 ^ t5; |
|
} |
|
clen -= n; |
|
if (!clen) break; |
|
} |
|
sum1 = t6 ^ t4 ^ t3; |
|
sum2 = t5 ^ t2 ^ t1; |
|
} |
|
LONG2BYTES(sum1, &buffer1[0]); |
|
LONG2BYTES(sum2, &buffer1[4]); |
|
dma_write_s(buffer1, SDRAM_START+CHECKSUM_HEADERPOS, 8); |
|
return; |
|
}
|
|
|