d411.pseudo 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. map:
  2. RAM:0x01~0x0f Seed 1 (own key seed)?
  3. RAM:0x10 send/receive buffer?
  4. RAM:0x11 Stream ID received from LOCK
  5. RAM:0x12~0x1f Seed 2 (Stream ID part of lock seed)?
  6. main:
  7. goto initstream;
  8. mainloop:
  9. a=0x1;
  10. mainloop2:
  11. x=a;
  12. for(x=a; x<16; x++) {
  13. main_inner1:
  14. bm=0x0;
  15. call 34b(0x00+x) // prepare next stream bit (send)
  16. bm=0x1;
  17. call 34b(0x10+x) // prepare next stream bit (recv)
  18. call 131 // bm=1; bl=0; a=P0
  19. a=P0;
  20. if(P0.0) die; // WTF? P0.0 is an output!
  21. if(P0.1) die;
  22. a=0x0;
  23. a<->RAM[0x10]; // load A with next output stream bit (nibble)
  24. P0=a; // LSB -> Key output
  25. nop; // wait
  26. a=P0; // read from lock
  27. P0=0; // clear output port
  28. RAM[0x10]=a; // store next input stream bit in RAM
  29. bl=3; a=P3 // P3.0, which is usually UNCONNECTED,
  30. // somehow determines how to deal with
  31. // the input stream. This is SNES CIC specific.
  32. // NOTE: For commonly used key operation / pin mapping we must assume
  33. // that P3.0 is HIGH (1). (otherwise the key would die immediately)
  34. bl=0
  35. if(P3.0){
  36. if(RAM[0x10].1) { // input stream bit set?
  37. call 159 // bm=0; bl=0; a=P0 // switch "bank"
  38. if(RAM[0x00].0) { // matches calculated bit?
  39. goto 13d // then go on
  40. } else goto 157 // DIE // else gtfo
  41. } else goto input_stream_bit_clear // input stream bit clear, check
  42. } else goto 175
  43. input_stream_bit_clear: // input stream bit cleared
  44. call 159 // bm=0; bl=0; a=P0 // switch "bank"
  45. if(RAM[0x00].0) { // calculated bit doesn't match?
  46. goto 157 // DIE // then die
  47. } else goto 17a // nop; goto 13d // else go on
  48. 175:
  49. if(RAM[0x10].0) { // this is essentially the same
  50. call 159 // bm=0; bl=0; a=P0 // as above but
  51. if(RAM[0x00].1) { // input stream bit is set in
  52. goto 13d; // RAM[0x10].0 instead of .1 and
  53. } else goto 157 // DIE // calculated from RAM[0x00].1
  54. } else { // instead of .0, if P3.0 is 0.
  55. call 159 // bm=0; bl=0; a=P0
  56. if(RAM[0x00].1) {
  57. goto 157 // DIE
  58. } else goto 17a // nop; goto 13d
  59. }
  60. 13d: // continue
  61. a=x;
  62. a++; // loop to next of 15 stream
  63. if(!overflow) { // bits, afterwards:
  64. x=a;
  65. goto main_inner1;
  66. }
  67. } // for x=1 to 15
  68. (x=0) //
  69. call 04a // set Resets (dummy for key mode) // output reset levels
  70. call 370 // "MANGLE BOTH" // calculate new seeds
  71. call 370 // "MANGLE BOTH" // for both sides
  72. call 370 // "MANGLE BOTH" // (lock+key) to exchange
  73. // this is "SNES security": MANGLE is called THREE TIMES!
  74. // as opposed to only once on the NES CICs.
  75. a=RAM[0x13];
  76. RAM[0x13]=RAM[0x17];
  77. // set P3.0 to LSB of RAM[0x13]
  78. P3 = (P3 & 0xe) | (RAM[0x13] & 0x1);
  79. if(a.0==1) {
  80. goto mainloop (seed offset=0x1)
  81. } else goto mainloop2 (seed offset=a)
  82. 04a: // "RUN HOST"
  83. call 37a // "skip if lock"
  84. a=0x0;
  85. P1=a;
  86. nop
  87. nop
  88. nop
  89. P1=a;
  90. return
  91. mangle_both:
  92. call mangle(bm=0);
  93. goto mangle(bm=1);
  94. mangle:
  95. bl=0xf;
  96. a=RAM[bm:0xf];
  97. x=a;
  98. carry=1;
  99. bl=0x1;
  100. a+=RAM[bm:0x1]+1;
  101. RAM[bm:0x1]=a;
  102. ==> RAM[bm:0x1]+=RAM[bm:0xf]+1;
  103. a=RAM[bm:0x1]; bl++;
  104. a+=RAM[bm:0x2]+1;
  105. a=~a;
  106. RAM[bm:0x2]=a; bl++;
  107. a+=RAM[bm:0x3]+1;
  108. if(!overflow) {
  109. RAM[bm:0x3]=a; bl++;
  110. }
  111. a+=RAM[bm:0x4];
  112. RAM[bm:0x4]=a;
  113. a=RAM[bm:0x4]; bl++;
  114. carry=0;
  115. a+=RAM[bm:0x5]+0;
  116. RAM[bm:0x5]=a; bl++;
  117. a+=8;
  118. a+=RAM[bm:0x6]+0;
  119. RAM[bm:0x6]=a; bl++;
  120. mangle_inner1:
  121. a++;
  122. nop
  123. a+=RAM[bm:0x7..0xf]+0;
  124. RAM[bm:0x7..0xf]=a;
  125. a=RAM[bm:0x7..0xf]; bl++;
  126. if(!overflow) goto mangle_inner1
  127. a<->x;
  128. a+=0xf;
  129. if(!overflow) return;
  130. goto mangle
  131. 131:
  132. bm=0x0;
  133. call 37a
  134. (if(!lock)bm=1);
  135. return;
  136. 37a:
  137. 34b: input x='bl'
  138. // take a nibble out of the seed (indexed by bm:x)
  139. // and set [bm:0], i.e. RAM[0x00] or RAM[0x10] like this:
  140. // if(seednibble&1) {
  141. // result=0b0000;
  142. // } else {
  143. // if(P3.0) {
  144. // result=0b0101;
  145. // } else {
  146. // result=0b0010;
  147. // }
  148. // }
  149. bl=x;
  150. a=RAM[bm:x];
  151. RAM[bm:0] = RAM[bm:x].0 ? 0x7 : 0x0;
  152. a=P3; // WTF is P3????
  153. bl=0;
  154. if (P3.0==1) {
  155. RAM[bm:0] &= 0b1101;
  156. } else {
  157. RAM[bm:0] &= 0b1010;
  158. }
  159. return
  160. initstream:
  161. if(P0.3==0) {
  162. if(P0.3==0) {
  163. A=RAM[0x11]; RAM[0x11]=0xf
  164. input_stream_id_bit;
  165. if !(A.1) RAM[0x11]&=0b0111
  166. input_stream_id_bit;
  167. if !(A.1) RAM[0x11]&=0b1110
  168. input_stream_id_bit;
  169. if !(A.1) RAM[0x11]&=0b1101
  170. input_stream_id_bit;
  171. if !(A.1) RAM[0x11]&=0b1011
  172. nop
  173. RAM[0x01]=0xb;
  174. RAM[0x02]=0x1;
  175. RAM[0x03]=0x4;
  176. RAM[0x04]=0xf;
  177. RAM[0x05]=0x4;
  178. RAM[0x06]=0xb; // 0x6????
  179. RAM[0x07]=0x5;
  180. RAM[0x08]=0x7; // 0x8????
  181. RAM[0x09]=0xf;
  182. RAM[0x0a]=0xd; // 0xa????
  183. RAM[0x0b]=0x6;
  184. RAM[0x0c]=0x1; // 0xc????
  185. RAM[0x0d]=0xe;
  186. RAM[0x0e]=0x9;
  187. RAM[0x0f]=0x8;
  188. RAM[0x12]=0x9;
  189. RAM[0x13]=0xa;
  190. RAM[0x14]=0x1;
  191. RAM[0x15]=0x8;
  192. RAM[0x16]=0x5;
  193. RAM[0x17]=0xf; // 0x7????
  194. RAM[0x18]=0x1;
  195. RAM[0x19]=0x1; // 0x9????
  196. RAM[0x1a]=0xe;
  197. RAM[0x1b]=0x1; // 0xb????
  198. RAM[0x1c]=0x0;
  199. RAM[0x1d]=0xd;
  200. RAM[0x1e]=0xe;
  201. RAM[0x1f]=0xc;
  202. mainloop;
  203. }
  204. }
  205. input_stream_id_bit:
  206. wait 6 cycles
  207. A=P0
  208. ret