123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230 |
- map:
- RAM:0x01~0x0f Seed 1 (own key seed)?
- RAM:0x10 send/receive buffer?
- RAM:0x11 Stream ID received from LOCK
- RAM:0x12~0x1f Seed 2 (Stream ID part of lock seed)?
- main:
- goto initstream;
- mainloop:
- a=0x1;
- mainloop2:
- x=a;
- for(x=a; x<16; x++) {
- main_inner1:
- bm=0x0;
- call 34b(0x00+x) // prepare next stream bit (send)
- bm=0x1;
- call 34b(0x10+x) // prepare next stream bit (recv)
- call 131 // bm=1; bl=0; a=P0
- a=P0;
- if(P0.0) die; // WTF? P0.0 is an output!
- if(P0.1) die;
-
- a=0x0;
- a<->RAM[0x10]; // load A with next output stream bit (nibble)
- P0=a; // LSB -> Key output
- nop; // wait
- a=P0; // read from lock
- P0=0; // clear output port
- RAM[0x10]=a; // store next input stream bit in RAM
- bl=3; a=P3 // P3.0, which is usually UNCONNECTED,
- // somehow determines how to deal with
- // the input stream. This is SNES CIC specific.
- // NOTE: For commonly used key operation / pin mapping we must assume
- // that P3.0 is HIGH (1). (otherwise the key would die immediately)
- bl=0
- if(P3.0){
- if(RAM[0x10].1) { // input stream bit set?
- call 159 // bm=0; bl=0; a=P0 // switch "bank"
- if(RAM[0x00].0) { // matches calculated bit?
- goto 13d // then go on
- } else goto 157 // DIE // else gtfo
- } else goto input_stream_bit_clear // input stream bit clear, check
- } else goto 175
-
- input_stream_bit_clear: // input stream bit cleared
- call 159 // bm=0; bl=0; a=P0 // switch "bank"
- if(RAM[0x00].0) { // calculated bit doesn't match?
- goto 157 // DIE // then die
- } else goto 17a // nop; goto 13d // else go on
-
- 175:
- if(RAM[0x10].0) { // this is essentially the same
- call 159 // bm=0; bl=0; a=P0 // as above but
- if(RAM[0x00].1) { // input stream bit is set in
- goto 13d; // RAM[0x10].0 instead of .1 and
- } else goto 157 // DIE // calculated from RAM[0x00].1
- } else { // instead of .0, if P3.0 is 0.
- call 159 // bm=0; bl=0; a=P0
- if(RAM[0x00].1) {
- goto 157 // DIE
- } else goto 17a // nop; goto 13d
- }
-
- 13d: // continue
- a=x;
- a++; // loop to next of 15 stream
- if(!overflow) { // bits, afterwards:
- x=a;
- goto main_inner1;
- }
- } // for x=1 to 15
- (x=0) //
- call 04a // set Resets (dummy for key mode) // output reset levels
- call 370 // "MANGLE BOTH" // calculate new seeds
- call 370 // "MANGLE BOTH" // for both sides
- call 370 // "MANGLE BOTH" // (lock+key) to exchange
- // this is "SNES security": MANGLE is called THREE TIMES!
- // as opposed to only once on the NES CICs.
- a=RAM[0x13];
- RAM[0x13]=RAM[0x17];
- // set P3.0 to LSB of RAM[0x13]
- P3 = (P3 & 0xe) | (RAM[0x13] & 0x1);
- if(a.0==1) {
- goto mainloop (seed offset=0x1)
- } else goto mainloop2 (seed offset=a)
- 04a: // "RUN HOST"
- call 37a // "skip if lock"
- a=0x0;
- P1=a;
- nop
- nop
- nop
- P1=a;
- return
- mangle_both:
- call mangle(bm=0);
- goto mangle(bm=1);
- mangle:
- bl=0xf;
- a=RAM[bm:0xf];
- x=a;
- carry=1;
- bl=0x1;
- a+=RAM[bm:0x1]+1;
- RAM[bm:0x1]=a;
- ==> RAM[bm:0x1]+=RAM[bm:0xf]+1;
- a=RAM[bm:0x1]; bl++;
- a+=RAM[bm:0x2]+1;
- a=~a;
- RAM[bm:0x2]=a; bl++;
- a+=RAM[bm:0x3]+1;
- if(!overflow) {
- RAM[bm:0x3]=a; bl++;
- }
- a+=RAM[bm:0x4];
- RAM[bm:0x4]=a;
- a=RAM[bm:0x4]; bl++;
- carry=0;
- a+=RAM[bm:0x5]+0;
- RAM[bm:0x5]=a; bl++;
- a+=8;
- a+=RAM[bm:0x6]+0;
- RAM[bm:0x6]=a; bl++;
- mangle_inner1:
- a++;
- nop
- a+=RAM[bm:0x7..0xf]+0;
- RAM[bm:0x7..0xf]=a;
- a=RAM[bm:0x7..0xf]; bl++;
- if(!overflow) goto mangle_inner1
- a<->x;
- a+=0xf;
- if(!overflow) return;
- goto mangle
- 131:
- bm=0x0;
- call 37a
- (if(!lock)bm=1);
- return;
- 37a:
-
- 34b: input x='bl'
- // take a nibble out of the seed (indexed by bm:x)
- // and set [bm:0], i.e. RAM[0x00] or RAM[0x10] like this:
- // if(seednibble&1) {
- // result=0b0000;
- // } else {
- // if(P3.0) {
- // result=0b0101;
- // } else {
- // result=0b0010;
- // }
- // }
- bl=x;
- a=RAM[bm:x];
- RAM[bm:0] = RAM[bm:x].0 ? 0x7 : 0x0;
- a=P3; // WTF is P3????
- bl=0;
- if (P3.0==1) {
- RAM[bm:0] &= 0b1101;
- } else {
- RAM[bm:0] &= 0b1010;
- }
- return
- initstream:
- if(P0.3==0) {
- if(P0.3==0) {
- A=RAM[0x11]; RAM[0x11]=0xf
- input_stream_id_bit;
- if !(A.1) RAM[0x11]&=0b0111
- input_stream_id_bit;
- if !(A.1) RAM[0x11]&=0b1110
- input_stream_id_bit;
- if !(A.1) RAM[0x11]&=0b1101
- input_stream_id_bit;
- if !(A.1) RAM[0x11]&=0b1011
- nop
-
- RAM[0x01]=0xb;
- RAM[0x02]=0x1;
- RAM[0x03]=0x4;
- RAM[0x04]=0xf;
- RAM[0x05]=0x4;
- RAM[0x06]=0xb; // 0x6????
- RAM[0x07]=0x5;
- RAM[0x08]=0x7; // 0x8????
- RAM[0x09]=0xf;
- RAM[0x0a]=0xd; // 0xa????
- RAM[0x0b]=0x6;
- RAM[0x0c]=0x1; // 0xc????
- RAM[0x0d]=0xe;
- RAM[0x0e]=0x9;
- RAM[0x0f]=0x8;
- RAM[0x12]=0x9;
- RAM[0x13]=0xa;
- RAM[0x14]=0x1;
- RAM[0x15]=0x8;
- RAM[0x16]=0x5;
- RAM[0x17]=0xf; // 0x7????
- RAM[0x18]=0x1;
- RAM[0x19]=0x1; // 0x9????
- RAM[0x1a]=0xe;
- RAM[0x1b]=0x1; // 0xb????
- RAM[0x1c]=0x0;
- RAM[0x1d]=0xd;
- RAM[0x1e]=0xe;
- RAM[0x1f]=0xc;
- mainloop;
- }
- }
- input_stream_id_bit:
- wait 6 cycles
- A=P0
- ret
|