Reading a CIC
D - through hole mounted
F - surface mounted (SuperFX, OBC1, maybe others)
411 - NTSC
413 - PAL
A / B - revision
Known CICs
- D411 (NTSC carts)
- D411A (NTSC carts)
- D411B (NTSC carts)
- D413 (PAL carts)
- D413A (PAL carts)
- D413B (PAL carts)
- F411 (NTSC Console)
- F411A (NTSC carts with SuperFX, OBC1, maybe others)
- F411B (NTSC carts with SPC7110, maybe others)
- F413A (PAL carts with SuperFX, OBC1, maybe others)
CIC Emulation / Simulation
Seeds with _ being the "stream select" bits from the lock in order 3-0-1-2 as usual:
D411
KEY: b14f4b57fd61e98
LCK: _9a185f11e10dec
D413
KEY: b14f4b57fd61e98
LCK: _6a185f11e10dec
A quick hack in C that generates a D411's input and output streams:
#include <stdio.h>
void printseed(unsigned char* data) {
int i;
for(i=1;i<16;i++) {
printf("%x ", data[i]);
}
printf("\n");
}
void printstream(unsigned char* data, int restart) {
int i;
for(i=restart;i<16;i++) {
printf("%d ", data[i]&1);
}
printf("\n");
}
void mangle(unsigned char* data) {
unsigned char a,x,temp,i,offset,carry=0;
a=data[0xf];
do {
x=a;
offset=1;
carry=1;
a+=data[offset]+carry;
data[offset]=a&0xf;
a=data[offset++];
a+=data[offset]+carry;
a=(~a)&0xf;
temp=a; a=data[offset]; data[offset++]=temp&0xf;
a+=data[offset]+carry;
if(a<0x10) {
temp=a; a=data[offset]; data[offset++]=temp&0xf;
}
a+=data[offset];
data[offset]=a&0xf;
a=data[offset++];
carry=0;
a+=data[offset]+carry;
temp=a; a=data[offset]; data[offset++]=temp&0xf;
a+=8;
if(a<0x10) {
a+=data[offset]+carry;
}
temp=a; a=data[offset]; data[offset++]=temp&0xf;
while(offset<0x10) {
a++;
a+=data[offset]+carry;
data[offset]=a&0xf;
a=data[offset++];
}
offset &= 0xf;
a=x;
a+=0xf;
if(a>0x0f) {
a &= 0xf;
carry=1;
} else carry=0;
} while(carry);
}
int main(void) {
unsigned char restart=1;
unsigned char keyseed_data[16]= {0x0, // dummy
0xb,0x1,0x4,0xf,
0x4,0xb,0x5,0x7,
0xf,0xd,0x6,0x1,
0xe,0x9,0x8};
unsigned char lockseed_data[16]={0x0, // dummy
0x0,0x9,0xa,0x1,
0x8,0x5,0xf,0x1,
0x1,0xe,0x1,0x0,
0xd,0xe,0xc};
unsigned char* keyseed=keyseed_data;
unsigned char* lockseed=lockseed_data;
printseed(keyseed);
printseed(lockseed);
printf("\n");
while(1) {
printf("\n");
printstream(keyseed, restart);
printstream(lockseed, restart);
mangle(keyseed);
mangle(keyseed);
mangle(keyseed);
mangle(lockseed);
mangle(lockseed);
mangle(lockseed);
// printseed(keyseed);
// printseed(lockseed);
restart=lockseed_data[7];
if(lockseed_data[7]&1) {
keyseed=lockseed_data;
lockseed=keyseed_data;
} else {
keyseed=keyseed_data;
lockseed=lockseed_data;
}
if(!restart)restart=1;
// printf("send %d-15\n", restart);
}
return 0;
}