snescic-lock-resync.asm 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741
  1. #include <p12f629.inc>
  2. processor p12f629
  3. ; ---------------------------------------------------------------------
  4. ; SNES CIC clone for PIC Microcontroller (lock mode, auto key region detect,
  5. ; error tolerant)
  6. ;
  7. ; Copyright (C) 2010 by Maximilian Rehkopf (ikari_01) <otakon@gmx.net>
  8. ; This software is part of the sd2snes project.
  9. ;
  10. ; This program is free software; you can redistribute it and/or modify
  11. ; it under the terms of the GNU General Public License as published by
  12. ; the Free Software Foundation; version 2 of the License only.
  13. ;
  14. ; This program is distributed in the hope that it will be useful,
  15. ; but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. ; GNU General Public License for more details.
  18. ;
  19. ; You should have received a copy of the GNU General Public License
  20. ; along with this program; if not, write to the Free Software
  21. ; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  22. ;
  23. ; ---------------------------------------------------------------------
  24. ;
  25. ; pin configuration: (cartridge slot pin) [original 18-pin SMD lock CIC pin]
  26. ;
  27. ; ,---_---.
  28. ; +5V (27,58) [18] |1 8| GND (5,36) [9]
  29. ; CIC clk (56) [7] |2 7| CIC data i/o 0 (55) [1]
  30. ; host reset out [10] |3 6| CIC data i/o 1 (24) [2]
  31. ; CIC lock reset in [8] |4 5| CIC slave reset out (25) [11]
  32. ; `-------'
  33. ;
  34. ; pin 3 connected to PPU2 reset in
  35. ; pin 4 connected to reset button
  36. ; pin 5 connected to key CIC pin 7 (or clone CIC pin 5)
  37. ; pin 6 connected to key CIC pin 1 (or clone CIC pin 6)
  38. ; pin 7 connected to key CIC pin 2 (or clone CIC pin 7)
  39. ;
  40. ; Host reset out behaves as follows:
  41. ; After powerup it is held low for a couple of us to properly allow the
  42. ; components to power-up.
  43. ; It is then asserted a high level even if the CIC "auth" should fail at
  44. ; any point, thus enabling homebrew or other cartridges without a CIC or
  45. ; CIC clone to be run properly while maintaining compatibility with CIC
  46. ; demanding cartridges like S-DD1 or SA-1 powered ones.
  47. ; The type of key CIC (411/413) is detected automatically.
  48. ;
  49. ; memory usage:
  50. ;
  51. ; 0x20 buffer for seed calc and transfer
  52. ; 0x21 - 0x2f seed area (lock seed)
  53. ; 0x30 buffer for seed calc
  54. ; 0x31 - 0x3f seed area (key seed; 0x31 filled in by lock)
  55. ; 0x40 - 0x41 buffer for seed calc
  56. ; 0x42 input buffer
  57. ; 0x43 variable for key detect
  58. ; 0x4d buffer for eeprom access
  59. ; 0x4e loop variable for longwait
  60. ; 0x4f loop variable for wait
  61. ;
  62. ; ---------------------------------------------------------------------
  63. ; -----------------------------------------------------------------------
  64. __CONFIG _EC_OSC & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _CPD_OFF
  65. ; -----------------------------------------------------------------------
  66. ; code memory
  67. org 0x0000
  68. nop
  69. nop
  70. nop
  71. goto init
  72. rst ; we jump here after powerup or GPIO3=1
  73. org 0x0004
  74. bcf GPIO, 0 ; clear stream i/o
  75. bcf GPIO, 1 ; clear stream i/o
  76. bcf GPIO, 2 ; disable slave reset
  77. bcf GPIO, 4 ; hold the SNES in reset
  78. rst_loop
  79. btfsc GPIO, 3 ; stay in "reset" as long as GPIO3=1
  80. goto rst_loop
  81. nop
  82. nop
  83. nop
  84. nop
  85. nop
  86. goto main
  87. init
  88. org 0x0010
  89. banksel GPIO
  90. clrf GPIO
  91. movlw 0x07 ; GPIO2..0 are digital I/O (not connected to comparator)
  92. movwf CMCON
  93. movlw 0x00 ; disable all interrupts
  94. movwf INTCON
  95. banksel TRISIO
  96. movlw 0x29 ; in out in OUT out in. slave reset is an output on lock
  97. movwf TRISIO
  98. movlw 0x00 ; no pullups
  99. movwf WPU
  100. movlw 0x80 ; global pullup disable
  101. movwf OPTION_REG
  102. banksel GPIO
  103. bcf GPIO, 4 ; LED off
  104. goto rst
  105. main
  106. movlw 0x40 ; wait a bit before initializing the slave + console
  107. call longwait
  108. bsf GPIO, 4 ; enable console
  109. bsf GPIO, 2 ; trigger the slave
  110. clrf 0x44 ; clear direction
  111. nop
  112. bcf GPIO, 2
  113. banksel TRISIO
  114. bcf TRISIO, 0
  115. bsf TRISIO, 1
  116. banksel GPIO
  117. ; --------INIT LOCK SEED (what we must send)--------
  118. movlw 0xb
  119. movwf 0x21
  120. movlw 0x1
  121. movwf 0x22
  122. movlw 0x4
  123. movwf 0x23
  124. movlw 0xf
  125. movwf 0x24
  126. movlw 0x4
  127. movwf 0x25
  128. movlw 0xb
  129. movwf 0x26
  130. movlw 0x5
  131. movwf 0x27
  132. movlw 0x7
  133. movwf 0x28
  134. movlw 0xf
  135. movwf 0x29
  136. movlw 0xd
  137. movwf 0x2a
  138. movlw 0x6
  139. movwf 0x2b
  140. movlw 0x1
  141. movwf 0x2c
  142. movlw 0xe
  143. movwf 0x2d
  144. movlw 0x9
  145. movwf 0x2e
  146. movlw 0x8
  147. movwf 0x2f
  148. ; --------INIT KEY SEED (what the key sends)--------
  149. movlw 0xf ; we always request the same stream for simplicity
  150. movwf 0x31
  151. movlw 0x0 ; this is filled in by key autodetect
  152. movwf 0x32
  153. movlw 0xa
  154. movwf 0x33
  155. movlw 0x1
  156. movwf 0x34
  157. movlw 0x8
  158. movwf 0x35
  159. movlw 0x5
  160. movwf 0x36
  161. movlw 0xf
  162. movwf 0x37
  163. movlw 0x1
  164. movwf 0x38
  165. movwf 0x39
  166. movlw 0xe
  167. movwf 0x3a
  168. movlw 0x1
  169. movwf 0x3b
  170. movlw 0x0
  171. movwf 0x3c
  172. movlw 0xd
  173. movwf 0x3d
  174. movlw 0xe
  175. movwf 0x3e
  176. movlw 0xc
  177. movwf 0x3f
  178. ; --------wait before sending stream ID--------
  179. movlw 0xba
  180. call wait
  181. nop
  182. nop
  183. ; --------lock sends stream ID. 15 cycles per bit--------
  184. ; bsf GPIO, 0 ; (debug marker)
  185. ; bcf GPIO, 0 ;
  186. btfsc 0x31, 3 ; read stream select bit
  187. bsf GPIO, 0 ; send bit
  188. nop
  189. nop
  190. bcf GPIO, 0
  191. movlw 0x1 ; wait=7
  192. call wait ; burn 10 cycles
  193. nop
  194. nop
  195. ; bsf GPIO, 0
  196. ; bcf GPIO, 0
  197. btfsc 0x31, 0 ; read stream select bit
  198. bsf GPIO, 0 ; send bit
  199. nop
  200. nop
  201. bcf GPIO, 0
  202. movlw 0x1 ; wait=3*W+5
  203. call wait ; burn 11 cycles
  204. nop
  205. nop
  206. ; bsf GPIO, 0
  207. ; bcf GPIO, 0
  208. btfsc 0x31, 1 ; read stream select bit
  209. bsf GPIO, 0 ; send bit
  210. nop
  211. nop
  212. bcf GPIO, 0
  213. movlw 0x1 ; wait=3*W+5
  214. call wait ; burn 11 cycles
  215. nop
  216. nop
  217. ; bsf GPIO, 0
  218. ; bcf GPIO, 0
  219. btfsc 0x31, 2 ; read stream select bit
  220. bsf GPIO, 0 ; send bit
  221. nop
  222. nop
  223. bcf GPIO, 0
  224. movlw 0x1 ; wait=3*0+7
  225. call wait ; burn 10 cycles
  226. banksel TRISIO
  227. bsf TRISIO, 0
  228. bcf TRISIO, 1
  229. banksel GPIO
  230. movlw 0x24 ; "wait" 1
  231. call wait ; wait 112
  232. ; nop
  233. movlw 0x1 ; 'first time' bit
  234. movwf 0x43 ; for key detection
  235. ; --------main loop--------
  236. loop
  237. movlw 0x1
  238. loop0
  239. addlw 0x20 ; lock stream
  240. movwf FSR ; store in index reg
  241. loop1
  242. movf INDF, w ; load seed value
  243. movwf 0x20
  244. bcf 0x20, 1 ; clear bit 1
  245. btfsc 0x20, 0 ; copy from bit 0
  246. bsf 0x20, 1 ; (if set)
  247. bsf 0x20, 4 ; run console
  248. bcf 0x20, 2 ; run slave
  249. movf 0x20, w
  250. movwf GPIO
  251. movf GPIO, w ; read input
  252. movwf 0x42 ; store input
  253. movlw 0x10
  254. movwf GPIO ; reset GPIO
  255. call checkkey
  256. btfsc GPIO, 3 ; poll master reset
  257. goto rst ; (to allow resetting w/o key CIC...)
  258. btfsc 0x44, 0 ; check "direction"
  259. rrf 0x42, f ; shift received bit into place
  260. bsf FSR, 4 ; goto other stream
  261. movf INDF, w ; read
  262. xorwf 0x42, f ; xor received + calculated
  263. bcf FSR, 4 ; back to our own stream
  264. btfsc 0x42, 0 ; equal? then continue
  265. goto main ; else resync key and start over
  266. nop ; wait 1 cycle
  267. nop ; wait 1 cycle
  268. movlw 0xc ; wait 40 cycles
  269. call wait
  270. btfsc GPIO, 0 ; both pins must be low...
  271. goto die
  272. btfsc GPIO, 1 ; ...when no bit transfer takes place
  273. goto die ; if not -> lock cic error state -> die
  274. incf FSR, f ; next one
  275. movlw 0xf
  276. andwf FSR, w
  277. btfss STATUS, Z
  278. goto loop1
  279. movlw 0x1 ; wait 7
  280. call wait ;
  281. call mangle
  282. call mangle
  283. call mangle
  284. movf 0x37, w
  285. movwf 0x44
  286. btfsc 0x37, 0
  287. goto swap
  288. banksel TRISIO
  289. bsf TRISIO, 0
  290. bcf TRISIO, 1
  291. goto swapskip
  292. swap
  293. banksel TRISIO
  294. bcf TRISIO, 0
  295. bsf TRISIO, 1
  296. nop
  297. swapskip
  298. banksel GPIO
  299. btfsc GPIO, 3 ; poll master reset
  300. goto rst
  301. clrf 0x43 ; don't check key region anymore
  302. movf 0x37, w
  303. andlw 0xf
  304. btfss STATUS, Z
  305. goto loop0
  306. goto loop
  307. ; --------calculate new seeds--------
  308. ; had to be unrolled because PIC has an inefficient way of handling
  309. ; indirect access, no post increment, no swap, etc.
  310. mangle
  311. call mangle_lock
  312. nop
  313. nop
  314. mangle_key
  315. movf 0x2f, w
  316. movwf 0x20
  317. mangle_key_loop
  318. addlw 0x1
  319. addwf 0x21, f
  320. movf 0x22, w
  321. movwf 0x40
  322. movf 0x21, w
  323. addwf 0x22, f
  324. incf 0x22, f
  325. comf 0x22, f
  326. movf 0x23, w
  327. movwf 0x41 ; store 23 to 41
  328. movlw 0xf
  329. andwf 0x23, f
  330. movf 0x40, w ; add 40(22 old)+23+#1 and skip if carry
  331. andlw 0xf
  332. addwf 0x23, f
  333. incf 0x23, f
  334. btfsc 0x23, 4
  335. goto mangle_key_withskip
  336. mangle_key_withoutskip
  337. movf 0x41, w ; restore 23
  338. addwf 0x24, f ; add to 24
  339. movf 0x25, w
  340. movwf 0x40 ; save 25 to 40
  341. movf 0x24, w
  342. addwf 0x25, f
  343. movf 0x26, w
  344. movwf 0x41 ; save 26 to 41
  345. movf 0x40, w ; restore 25
  346. andlw 0xf ; mask nibble
  347. addlw 0x8 ; add #8 to HIGH nibble
  348. movwf 0x40
  349. btfss 0x40, 4 ; skip if carry to 5th bit
  350. addwf 0x26, w
  351. movwf 0x26
  352. movf 0x41, w ; restore 26
  353. addlw 0x1 ; inc
  354. addwf 0x27, f ; add to 27
  355. movf 0x27, w ;
  356. addlw 0x1 ; inc
  357. addwf 0x28, f ; add to 28
  358. movf 0x28, w ;
  359. addlw 0x1 ; inc
  360. addwf 0x29, f ; add to 29
  361. movf 0x29, w ;
  362. addlw 0x1 ; inc
  363. addwf 0x2a, f ; add to 2a
  364. movf 0x2a, w ;
  365. addlw 0x1 ; inc
  366. addwf 0x2b, f ; add to 2b
  367. movf 0x2b, w ;
  368. addlw 0x1 ; inc
  369. addwf 0x2c, f ; add to 2c
  370. movf 0x2c, w ;
  371. addlw 0x1 ; inc
  372. addwf 0x2d, f ; add to 2d
  373. movf 0x2d, w ;
  374. addlw 0x1 ; inc
  375. addwf 0x2e, f ; add to 2e
  376. movf 0x2e, w ;
  377. addlw 0x1 ; inc
  378. addwf 0x2f, f ; add to 2f
  379. movf 0x20, w ; restore original 0xf
  380. andlw 0xf
  381. addlw 0xf
  382. movwf 0x20
  383. nop
  384. nop
  385. nop
  386. nop
  387. nop
  388. nop
  389. nop
  390. nop
  391. nop
  392. btfss 0x20, 4 ; skip if half-byte carry
  393. goto mangle_return ; +2 cycles in return
  394. nop
  395. goto mangle_key_loop
  396. ; 69 when goto, 69 when return
  397. ; CIC has 78 -> 9 nops
  398. mangle_key_withskip
  399. movf 0x41, w ; restore 23
  400. addwf 0x23, f ; add to 23
  401. movf 0x24, w
  402. movwf 0x40 ; save 24 to 40
  403. movf 0x23, w
  404. addwf 0x24, f
  405. movf 0x25, w
  406. movwf 0x41 ; save 25 to 41
  407. movf 0x40, w ; restore 24
  408. andlw 0xf ; mask nibble
  409. addlw 0x8 ; add #8 to HIGH nibble
  410. movwf 0x40
  411. btfss 0x40, 4 ; skip if carry to 5th bit
  412. addwf 0x25, w
  413. movwf 0x25
  414. movf 0x41, w ; restore 25
  415. addlw 0x1 ; inc
  416. addwf 0x26, f ; add to 26
  417. movf 0x26, w ;
  418. addlw 0x1 ; inc
  419. addwf 0x27, f ; add to 27
  420. movf 0x27, w ;
  421. addlw 0x1 ; inc
  422. addwf 0x28, f ; add to 28
  423. movf 0x28, w ;
  424. addlw 0x1 ; inc
  425. addwf 0x29, f ; add to 29
  426. movf 0x29, w ;
  427. addlw 0x1 ; inc
  428. addwf 0x2a, f ; add to 2a
  429. movf 0x2a, w ;
  430. addlw 0x1 ; inc
  431. addwf 0x2b, f ; add to 2b
  432. movf 0x2b, w ;
  433. addlw 0x1 ; inc
  434. addwf 0x2c, f ; add to 2c
  435. movf 0x2c, w ;
  436. addlw 0x1 ; inc
  437. addwf 0x2d, f ; add to 2d
  438. movf 0x2d, w ;
  439. addlw 0x1 ; inc
  440. addwf 0x2e, f ; add to 2e
  441. movf 0x2e, w ;
  442. addlw 0x1 ; inc
  443. addwf 0x2f, f ; add to 2f
  444. movf 0x20, w ; restore original 0xf
  445. andlw 0xf
  446. addlw 0xf
  447. movwf 0x20
  448. nop
  449. nop
  450. nop
  451. nop
  452. nop
  453. nop
  454. nop
  455. nop
  456. nop
  457. nop
  458. nop
  459. btfss 0x20, 4 ; skip if half-byte carry
  460. goto mangle_return ; +2 cycles in return
  461. nop
  462. goto mangle_key_loop
  463. mangle_return
  464. return
  465. ; 73 when goto, 73 when return
  466. ; CIC has 84 -> 11 nops
  467. mangle_lock
  468. movf 0x3f, w
  469. movwf 0x30
  470. mangle_lock_loop
  471. addlw 0x1
  472. addwf 0x31, f
  473. movf 0x32, w
  474. movwf 0x40
  475. movf 0x31, w
  476. addwf 0x32, f
  477. incf 0x32, f
  478. comf 0x32, f
  479. movf 0x33, w
  480. movwf 0x41 ; store 33 to 41
  481. movlw 0xf
  482. andwf 0x33, f
  483. movf 0x40, w ; add 40(32 old)+33+#1 and skip if carry
  484. andlw 0xf
  485. addwf 0x33, f
  486. incf 0x33, f
  487. btfsc 0x33, 4
  488. goto mangle_lock_withskip
  489. mangle_lock_withoutskip
  490. movf 0x41, w ; restore 33
  491. addwf 0x34, f ; add to 34
  492. movf 0x35, w
  493. movwf 0x40 ; save 35 to 40
  494. movf 0x34, w
  495. addwf 0x35, f
  496. movf 0x36, w
  497. movwf 0x41 ; save 36 to 41
  498. movf 0x40, w ; restore 35
  499. andlw 0xf ; mask nibble
  500. addlw 0x8 ; add #8 to HIGH nibble
  501. movwf 0x40
  502. btfss 0x40, 4 ; skip if carry to 5th bit
  503. addwf 0x36, w
  504. movwf 0x36
  505. movf 0x41, w ; restore 36
  506. addlw 0x1 ; inc
  507. addwf 0x37, f ; add to 37
  508. movf 0x37, w ;
  509. addlw 0x1 ; inc
  510. addwf 0x38, f ; add to 38
  511. movf 0x38, w ;
  512. addlw 0x1 ; inc
  513. addwf 0x39, f ; add to 39
  514. movf 0x39, w ;
  515. addlw 0x1 ; inc
  516. addwf 0x3a, f ; add to 3a
  517. movf 0x3a, w ;
  518. addlw 0x1 ; inc
  519. addwf 0x3b, f ; add to 3b
  520. movf 0x3b, w ;
  521. addlw 0x1 ; inc
  522. addwf 0x3c, f ; add to 3c
  523. movf 0x3c, w ;
  524. addlw 0x1 ; inc
  525. addwf 0x3d, f ; add to 3d
  526. movf 0x3d, w ;
  527. addlw 0x1 ; inc
  528. addwf 0x3e, f ; add to 3e
  529. movf 0x3e, w ;
  530. addlw 0x1 ; inc
  531. addwf 0x3f, f ; add to 3f
  532. movf 0x30, w ; restore original 0xf
  533. andlw 0xf
  534. addlw 0xf
  535. movwf 0x30
  536. nop
  537. nop
  538. nop
  539. nop
  540. nop
  541. nop
  542. nop
  543. nop
  544. nop
  545. btfss 0x30, 4 ; skip if half-byte carry
  546. goto mangle_return
  547. nop
  548. goto mangle_lock_loop
  549. ; 69 when goto, 69 when return
  550. ; CIC has 78 -> 9 nops
  551. mangle_lock_withskip
  552. movf 0x41, w ; restore 33
  553. addwf 0x33, f ; add to 33
  554. movf 0x34, w
  555. movwf 0x40 ; save 34 to 40
  556. movf 0x33, w
  557. addwf 0x34, f
  558. movf 0x35, w
  559. movwf 0x41 ; save 35 to 41
  560. movf 0x40, w ; restore 34
  561. andlw 0xf ; mask nibble
  562. addlw 0x8 ; add #8 to HIGH nibble
  563. movwf 0x40
  564. btfss 0x40, 4 ; skip if carry to 5th bit
  565. addwf 0x35, w
  566. movwf 0x35
  567. movf 0x41, w ; restore 35
  568. addlw 0x1 ; inc
  569. addwf 0x36, f ; add to 36
  570. movf 0x36, w ;
  571. addlw 0x1 ; inc
  572. addwf 0x37, f ; add to 37
  573. movf 0x37, w ;
  574. addlw 0x1 ; inc
  575. addwf 0x38, f ; add to 38
  576. movf 0x38, w ;
  577. addlw 0x1 ; inc
  578. addwf 0x39, f ; add to 39
  579. movf 0x39, w ;
  580. addlw 0x1 ; inc
  581. addwf 0x3a, f ; add to 3a
  582. movf 0x3a, w ;
  583. addlw 0x1 ; inc
  584. addwf 0x3b, f ; add to 3b
  585. movf 0x3b, w ;
  586. addlw 0x1 ; inc
  587. addwf 0x3c, f ; add to 3c
  588. movf 0x3c, w ;
  589. addlw 0x1 ; inc
  590. addwf 0x3d, f ; add to 3d
  591. movf 0x3d, w ;
  592. addlw 0x1 ; inc
  593. addwf 0x3e, f ; add to 3e
  594. movf 0x3e, w ;
  595. addlw 0x1 ; inc
  596. addwf 0x3f, f ; add to 3f
  597. movf 0x30, w ; restore original 0xf
  598. andlw 0xf
  599. addlw 0xf
  600. movwf 0x30
  601. nop
  602. nop
  603. nop
  604. nop
  605. nop
  606. nop
  607. nop
  608. nop
  609. nop
  610. nop
  611. nop
  612. btfss 0x30, 4 ; skip if half-byte carry
  613. goto mangle_return
  614. nop
  615. goto mangle_lock_loop
  616. ; 73 when goto, 73 when return
  617. ; CIC has 84 -> 11 nops
  618. ; --------wait: 3*(W-1)+7 cycles (including call+return). W=0 -> 256!--------
  619. wait
  620. movwf 0x4f
  621. wait0 decfsz 0x4f, f
  622. goto wait0
  623. return
  624. ; --------wait long: 8+(3*(w-1))+(772*w). W=0 -> 256!--------
  625. longwait
  626. movwf 0x4e
  627. clrw
  628. longwait0
  629. call wait
  630. decfsz 0x4e, f
  631. goto longwait0
  632. return
  633. ; --------die (do nothing, wait for reset)--------
  634. die
  635. btfsc GPIO, 3
  636. goto rst
  637. goto die
  638. ; --------check the key input and change "region" when appropriate--------
  639. ; --------requires 17 cycles (incl. call+return)
  640. checkkey
  641. btfss 0x43, 0 ; first time?
  642. goto checkkey_nocheck ; if not, just burn some cycles
  643. movlw 0x22 ; are we at the correct stream offset?
  644. xorwf FSR, w
  645. btfss STATUS, Z ; if not equal:
  646. goto checkkey_nocheck2 ; burn some cycles less.
  647. ; if equal do the check
  648. btfss 0x42, 0 ; if value from slave is set it's a 411
  649. goto check_413
  650. check_411
  651. nop ; to compensate for untaken branch
  652. movlw 0x9
  653. goto check_save
  654. check_413
  655. movlw 0x6
  656. goto check_save
  657. checkkey_nocheck
  658. nop
  659. nop
  660. nop
  661. nop
  662. checkkey_nocheck2
  663. nop
  664. nop
  665. nop
  666. nop
  667. goto check_done
  668. check_save
  669. movwf 0x32
  670. check_done
  671. return
  672. end
  673. ; ------------------------------------------------------------------------