SuperCIC pair mode. TODO: disable pair mode (key)
This commit is contained in:
parent
92da63754a
commit
14b82b8808
715
cic/supercic/supercic-key.asm
Normal file
715
cic/supercic/supercic-key.asm
Normal file
@ -0,0 +1,715 @@
|
|||||||
|
#include <p12f629.inc>
|
||||||
|
processor p12f629
|
||||||
|
|
||||||
|
; ---------------------------------------------------------------------
|
||||||
|
; SNES CIC clone for PIC Microcontroller (key mode only)
|
||||||
|
;
|
||||||
|
; Copyright (C) 2010 by Maximilian Rehkopf (ikari_01) <otakon@gmx.net>
|
||||||
|
; This software is part of the sd2snes project.
|
||||||
|
;
|
||||||
|
; 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; version 2 of the License only.
|
||||||
|
;
|
||||||
|
; 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
|
||||||
|
;
|
||||||
|
; ---------------------------------------------------------------------
|
||||||
|
;
|
||||||
|
; pin configuration: (cartridge pin) [key CIC pin]
|
||||||
|
;
|
||||||
|
; ,---_---.
|
||||||
|
; +5V (27,58) [16] |1 8| GND (5,36) [8]
|
||||||
|
; CIC clk (56) [6] |2 7| CIC data i/o 0 (55) [2]
|
||||||
|
; status out |3 6| CIC data i/o 1 (24) [1]
|
||||||
|
; nc |4 5| CIC slave reset (25) [7]
|
||||||
|
; `-------'
|
||||||
|
;
|
||||||
|
;
|
||||||
|
; Status out can be connected to a LED. It indicates:
|
||||||
|
;
|
||||||
|
; state | output
|
||||||
|
; -------------------------+----------------------------
|
||||||
|
; OK or no lock CIC | high
|
||||||
|
; error | low
|
||||||
|
; SuperCIC pair mode | high-low alternating @1kHz
|
||||||
|
;
|
||||||
|
; In case lockout fails, the region is switched automatically and
|
||||||
|
; will be used after the next reset.
|
||||||
|
;
|
||||||
|
; memory usage:
|
||||||
|
;
|
||||||
|
; 0x20 buffer for seed calc and transfer
|
||||||
|
; 0x21 - 0x2f seed area (lock seed)
|
||||||
|
; 0x30 buffer for seed calc
|
||||||
|
; 0x31 - 0x3f seed area (key seed; 0x31 filled in by lock)
|
||||||
|
; 0x40 - 0x41 buffer for seed calc
|
||||||
|
; 0x4d buffer for eeprom access
|
||||||
|
; 0x4e loop variable for longwait
|
||||||
|
; 0x4f loop variable for wait
|
||||||
|
;
|
||||||
|
; ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
; -----------------------------------------------------------------------
|
||||||
|
__CONFIG _EC_OSC & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _CPD_OFF
|
||||||
|
|
||||||
|
; -----------------------------------------------------------------------
|
||||||
|
; code memory
|
||||||
|
org 0x0000
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
goto init
|
||||||
|
isr
|
||||||
|
org 0x0004
|
||||||
|
bcf INTCON, 1 ; clear interrupt cause
|
||||||
|
bcf GPIO, 0
|
||||||
|
bcf GPIO, 1
|
||||||
|
bsf GPIO, 4 ; LED on
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
bsf INTCON, 7 ; re-enable interrupts (ISR will continue as main)
|
||||||
|
goto main
|
||||||
|
init
|
||||||
|
org 0x0010
|
||||||
|
banksel GPIO
|
||||||
|
clrf GPIO
|
||||||
|
movlw 0x07 ; GPIO2..0 are digital I/O (not connected to comparator)
|
||||||
|
movwf CMCON
|
||||||
|
movlw 0x90 ; global enable interrupts + enable external interrupt
|
||||||
|
movwf INTCON
|
||||||
|
banksel TRISIO
|
||||||
|
movlw 0x2d ; in out in in out in
|
||||||
|
movwf TRISIO
|
||||||
|
movlw 0x24 ; pullups for reset+clk to avoid errors when no CIC in host
|
||||||
|
movwf WPU
|
||||||
|
movlw 0x00 ; 0x80 for global pullup disable
|
||||||
|
movwf OPTION_REG
|
||||||
|
|
||||||
|
banksel GPIO
|
||||||
|
bsf GPIO, 4 ; LED on
|
||||||
|
idle
|
||||||
|
goto idle ; wait for interrupt from lock
|
||||||
|
|
||||||
|
main
|
||||||
|
banksel TRISIO
|
||||||
|
bsf TRISIO, 0
|
||||||
|
bcf TRISIO, 1
|
||||||
|
banksel GPIO
|
||||||
|
; --------INIT LOCK SEED (what the lock sends)--------
|
||||||
|
movlw 0xb
|
||||||
|
movwf 0x21
|
||||||
|
movlw 0x1
|
||||||
|
movwf 0x22
|
||||||
|
movlw 0x4
|
||||||
|
movwf 0x23
|
||||||
|
movlw 0xf
|
||||||
|
movwf 0x24
|
||||||
|
movlw 0x4
|
||||||
|
movwf 0x25
|
||||||
|
movlw 0xb
|
||||||
|
movwf 0x26
|
||||||
|
movlw 0x5
|
||||||
|
movwf 0x27
|
||||||
|
movlw 0x7
|
||||||
|
movwf 0x28
|
||||||
|
movlw 0xf
|
||||||
|
movwf 0x29
|
||||||
|
movlw 0xd
|
||||||
|
movwf 0x2a
|
||||||
|
movlw 0x6
|
||||||
|
movwf 0x2b
|
||||||
|
movlw 0x1
|
||||||
|
movwf 0x2c
|
||||||
|
movlw 0xe
|
||||||
|
movwf 0x2d
|
||||||
|
movlw 0x9
|
||||||
|
movwf 0x2e
|
||||||
|
movlw 0x8
|
||||||
|
movwf 0x2f
|
||||||
|
|
||||||
|
; --------INIT KEY SEED (what we must send)--------
|
||||||
|
banksel EEADR ; D/F411 and D/F413
|
||||||
|
clrf EEADR ; differ in 2nd seed nibble
|
||||||
|
bsf EECON1, RD ; of key stream,
|
||||||
|
movf EEDAT, w ; restore saved nibble from EEPROM
|
||||||
|
banksel GPIO
|
||||||
|
movwf 0x32
|
||||||
|
movlw 0xa
|
||||||
|
movwf 0x33
|
||||||
|
movlw 0x1
|
||||||
|
movwf 0x34
|
||||||
|
movlw 0x8
|
||||||
|
movwf 0x35
|
||||||
|
movlw 0x5
|
||||||
|
movwf 0x36
|
||||||
|
movlw 0xf
|
||||||
|
movwf 0x37
|
||||||
|
movlw 0x1
|
||||||
|
movwf 0x38
|
||||||
|
movwf 0x39
|
||||||
|
movlw 0xe
|
||||||
|
movwf 0x3a
|
||||||
|
movlw 0x1
|
||||||
|
movwf 0x3b
|
||||||
|
movlw 0x0
|
||||||
|
movwf 0x3c
|
||||||
|
movlw 0xd
|
||||||
|
movwf 0x3d
|
||||||
|
movlw 0xe
|
||||||
|
movwf 0x3e
|
||||||
|
movlw 0xc
|
||||||
|
movwf 0x3f
|
||||||
|
|
||||||
|
; --------wait for stream ID--------
|
||||||
|
movlw 0xb5
|
||||||
|
call wait
|
||||||
|
clrf 0x31 ; clear lock stream ID
|
||||||
|
|
||||||
|
; --------lock sends stream ID. 15 cycles per bit--------
|
||||||
|
; bsf GPIO, 0 ; (debug marker)
|
||||||
|
; bcf GPIO, 0 ;
|
||||||
|
btfsc GPIO, 0 ; check stream ID bit
|
||||||
|
bsf 0x31, 3 ; copy to lock seed
|
||||||
|
movlw 0x2 ; wait=3*W+5
|
||||||
|
call wait ; burn 11 cycles
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
|
||||||
|
; bsf GPIO, 0
|
||||||
|
; bcf GPIO, 0
|
||||||
|
btfsc GPIO, 0 ; check stream ID bit
|
||||||
|
bsf 0x31, 0 ; copy to lock seed
|
||||||
|
movlw 0x2 ;
|
||||||
|
call wait ; burn 11 cycles
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
|
||||||
|
; bsf GPIO, 0
|
||||||
|
; bcf GPIO, 0
|
||||||
|
btfsc GPIO, 0 ; check stream ID bit
|
||||||
|
bsf 0x31, 1 ; copy to lock seed
|
||||||
|
movlw 0x2 ;
|
||||||
|
call wait ; burn 11 cycles
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
|
||||||
|
; bsf GPIO, 0
|
||||||
|
; bcf GPIO, 0
|
||||||
|
btfsc GPIO, 0 ; check stream ID bit
|
||||||
|
bsf 0x31, 2 ; copy to lock seed
|
||||||
|
banksel TRISIO
|
||||||
|
bcf TRISIO, 0
|
||||||
|
bsf TRISIO, 1
|
||||||
|
banksel GPIO
|
||||||
|
nop
|
||||||
|
movlw 0x27 ; "wait" 1
|
||||||
|
call wait ; wait 121
|
||||||
|
; --------main loop--------
|
||||||
|
loop
|
||||||
|
movlw 0x1
|
||||||
|
loop0
|
||||||
|
addlw 0x30 ; key stream
|
||||||
|
movwf FSR ; store in index reg
|
||||||
|
loop1
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
movf INDF, w ; load seed value
|
||||||
|
movwf 0x20
|
||||||
|
bcf 0x20, 1 ; clear bit 1
|
||||||
|
btfsc 0x20, 0 ; copy from bit 0
|
||||||
|
bsf 0x20, 1 ; (if set)
|
||||||
|
bsf 0x20, 4 ; LED on
|
||||||
|
movf 0x20, w
|
||||||
|
movwf GPIO
|
||||||
|
nop
|
||||||
|
movlw 0x10
|
||||||
|
movwf GPIO ; reset GPIO
|
||||||
|
movlw 0x14
|
||||||
|
call wait
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
btfsc GPIO, 0 ; both pins must be low...
|
||||||
|
goto die
|
||||||
|
btfsc GPIO, 1 ; ...when no bit transfer takes place
|
||||||
|
goto die ; if not -> lock cic error state -> die
|
||||||
|
incf FSR, f ; next one
|
||||||
|
movlw 0xf
|
||||||
|
andwf FSR, w
|
||||||
|
btfss STATUS, Z
|
||||||
|
goto loop1
|
||||||
|
call mangle
|
||||||
|
call mangle
|
||||||
|
call mangle
|
||||||
|
movlw 0x2 ; wait 10
|
||||||
|
call wait ;
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
btfsc 0x37, 0
|
||||||
|
goto swap
|
||||||
|
banksel TRISIO
|
||||||
|
bcf TRISIO, 0
|
||||||
|
bsf TRISIO, 1
|
||||||
|
goto swapskip
|
||||||
|
swap
|
||||||
|
banksel TRISIO
|
||||||
|
bsf TRISIO, 0
|
||||||
|
bcf TRISIO, 1
|
||||||
|
nop
|
||||||
|
swapskip
|
||||||
|
banksel GPIO
|
||||||
|
movf 0x37, w
|
||||||
|
andlw 0xf
|
||||||
|
btfss STATUS, Z
|
||||||
|
goto loop0
|
||||||
|
goto loop
|
||||||
|
|
||||||
|
; --------calculate new seeds--------
|
||||||
|
; had to be unrolled because PIC has an inefficient way of handling
|
||||||
|
; indirect access, no post increment, etc.
|
||||||
|
mangle
|
||||||
|
call mangle_lock
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
mangle_key
|
||||||
|
movf 0x2f, w
|
||||||
|
movwf 0x20
|
||||||
|
mangle_key_loop
|
||||||
|
addlw 0x1
|
||||||
|
addwf 0x21, f
|
||||||
|
movf 0x22, w
|
||||||
|
movwf 0x40
|
||||||
|
movf 0x21, w
|
||||||
|
addwf 0x22, f
|
||||||
|
incf 0x22, f
|
||||||
|
comf 0x22, f
|
||||||
|
movf 0x23, w
|
||||||
|
movwf 0x41 ; store 23 to 41
|
||||||
|
movlw 0xf
|
||||||
|
andwf 0x23, f
|
||||||
|
movf 0x40, w ; add 40(22 old)+23+#1 and skip if carry
|
||||||
|
andlw 0xf
|
||||||
|
addwf 0x23, f
|
||||||
|
incf 0x23, f
|
||||||
|
btfsc 0x23, 4
|
||||||
|
goto mangle_key_withskip
|
||||||
|
mangle_key_withoutskip
|
||||||
|
movf 0x41, w ; restore 23
|
||||||
|
addwf 0x24, f ; add to 24
|
||||||
|
movf 0x25, w
|
||||||
|
movwf 0x40 ; save 25 to 40
|
||||||
|
movf 0x24, w
|
||||||
|
addwf 0x25, f
|
||||||
|
movf 0x26, w
|
||||||
|
movwf 0x41 ; save 26 to 41
|
||||||
|
movf 0x40, w ; restore 25
|
||||||
|
andlw 0xf ; mask nibble
|
||||||
|
addlw 0x8 ; add #8 to HIGH nibble
|
||||||
|
movwf 0x40
|
||||||
|
btfss 0x40, 4 ; skip if carry to 5th bit
|
||||||
|
addwf 0x26, w
|
||||||
|
movwf 0x26
|
||||||
|
|
||||||
|
movf 0x41, w ; restore 26
|
||||||
|
addlw 0x1 ; inc
|
||||||
|
addwf 0x27, f ; add to 27
|
||||||
|
|
||||||
|
movf 0x27, w ;
|
||||||
|
addlw 0x1 ; inc
|
||||||
|
addwf 0x28, f ; add to 28
|
||||||
|
|
||||||
|
movf 0x28, w ;
|
||||||
|
addlw 0x1 ; inc
|
||||||
|
addwf 0x29, f ; add to 29
|
||||||
|
|
||||||
|
movf 0x29, w ;
|
||||||
|
addlw 0x1 ; inc
|
||||||
|
addwf 0x2a, f ; add to 2a
|
||||||
|
|
||||||
|
movf 0x2a, w ;
|
||||||
|
addlw 0x1 ; inc
|
||||||
|
addwf 0x2b, f ; add to 2b
|
||||||
|
|
||||||
|
movf 0x2b, w ;
|
||||||
|
addlw 0x1 ; inc
|
||||||
|
addwf 0x2c, f ; add to 2c
|
||||||
|
|
||||||
|
movf 0x2c, w ;
|
||||||
|
addlw 0x1 ; inc
|
||||||
|
addwf 0x2d, f ; add to 2d
|
||||||
|
|
||||||
|
movf 0x2d, w ;
|
||||||
|
addlw 0x1 ; inc
|
||||||
|
addwf 0x2e, f ; add to 2e
|
||||||
|
|
||||||
|
movf 0x2e, w ;
|
||||||
|
addlw 0x1 ; inc
|
||||||
|
addwf 0x2f, f ; add to 2f
|
||||||
|
|
||||||
|
movf 0x20, w ; restore original 0xf
|
||||||
|
andlw 0xf
|
||||||
|
addlw 0xf
|
||||||
|
movwf 0x20
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
btfss 0x20, 4 ; skip if half-byte carry
|
||||||
|
goto mangle_return ; +2 cycles in return
|
||||||
|
nop
|
||||||
|
goto mangle_key_loop
|
||||||
|
; 69 when goto, 69 when return
|
||||||
|
; CIC has 78 -> 9 nops
|
||||||
|
|
||||||
|
mangle_key_withskip
|
||||||
|
movf 0x41, w ; restore 23
|
||||||
|
addwf 0x23, f ; add to 23
|
||||||
|
movf 0x24, w
|
||||||
|
movwf 0x40 ; save 24 to 40
|
||||||
|
movf 0x23, w
|
||||||
|
addwf 0x24, f
|
||||||
|
movf 0x25, w
|
||||||
|
movwf 0x41 ; save 25 to 41
|
||||||
|
movf 0x40, w ; restore 24
|
||||||
|
andlw 0xf ; mask nibble
|
||||||
|
addlw 0x8 ; add #8 to HIGH nibble
|
||||||
|
movwf 0x40
|
||||||
|
btfss 0x40, 4 ; skip if carry to 5th bit
|
||||||
|
addwf 0x25, w
|
||||||
|
movwf 0x25
|
||||||
|
|
||||||
|
movf 0x41, w ; restore 25
|
||||||
|
addlw 0x1 ; inc
|
||||||
|
addwf 0x26, f ; add to 26
|
||||||
|
|
||||||
|
movf 0x26, w ;
|
||||||
|
addlw 0x1 ; inc
|
||||||
|
addwf 0x27, f ; add to 27
|
||||||
|
|
||||||
|
movf 0x27, w ;
|
||||||
|
addlw 0x1 ; inc
|
||||||
|
addwf 0x28, f ; add to 28
|
||||||
|
|
||||||
|
movf 0x28, w ;
|
||||||
|
addlw 0x1 ; inc
|
||||||
|
addwf 0x29, f ; add to 29
|
||||||
|
|
||||||
|
movf 0x29, w ;
|
||||||
|
addlw 0x1 ; inc
|
||||||
|
addwf 0x2a, f ; add to 2a
|
||||||
|
|
||||||
|
movf 0x2a, w ;
|
||||||
|
addlw 0x1 ; inc
|
||||||
|
addwf 0x2b, f ; add to 2b
|
||||||
|
|
||||||
|
movf 0x2b, w ;
|
||||||
|
addlw 0x1 ; inc
|
||||||
|
addwf 0x2c, f ; add to 2c
|
||||||
|
|
||||||
|
movf 0x2c, w ;
|
||||||
|
addlw 0x1 ; inc
|
||||||
|
addwf 0x2d, f ; add to 2d
|
||||||
|
|
||||||
|
movf 0x2d, w ;
|
||||||
|
addlw 0x1 ; inc
|
||||||
|
addwf 0x2e, f ; add to 2e
|
||||||
|
|
||||||
|
movf 0x2e, w ;
|
||||||
|
addlw 0x1 ; inc
|
||||||
|
addwf 0x2f, f ; add to 2f
|
||||||
|
|
||||||
|
movf 0x20, w ; restore original 0xf
|
||||||
|
andlw 0xf
|
||||||
|
addlw 0xf
|
||||||
|
movwf 0x20
|
||||||
|
bcf GPIO, 0
|
||||||
|
movf GPIO, w
|
||||||
|
movwf 0x5e
|
||||||
|
bsf GPIO, 0
|
||||||
|
movf GPIO, w
|
||||||
|
movwf 0x5f
|
||||||
|
bcf GPIO, 0
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
btfss 0x20, 4 ; skip if half-byte carry
|
||||||
|
goto mangle_return ; +2 cycles in return
|
||||||
|
movf 0x20, w ; restore w (previously destroyed)
|
||||||
|
goto mangle_key_loop
|
||||||
|
mangle_return
|
||||||
|
return
|
||||||
|
; 73 when goto, 73 when return
|
||||||
|
; CIC has 84 -> 11 nops
|
||||||
|
|
||||||
|
mangle_lock
|
||||||
|
movf 0x3f, w
|
||||||
|
movwf 0x30
|
||||||
|
mangle_lock_loop
|
||||||
|
addlw 0x1
|
||||||
|
addwf 0x31, f
|
||||||
|
movf 0x32, w
|
||||||
|
movwf 0x40
|
||||||
|
movf 0x31, w
|
||||||
|
addwf 0x32, f
|
||||||
|
incf 0x32, f
|
||||||
|
comf 0x32, f
|
||||||
|
movf 0x33, w
|
||||||
|
movwf 0x41 ; store 33 to 41
|
||||||
|
movlw 0xf
|
||||||
|
andwf 0x33, f
|
||||||
|
movf 0x40, w ; add 40(32 old)+33+#1 and skip if carry
|
||||||
|
andlw 0xf
|
||||||
|
addwf 0x33, f
|
||||||
|
incf 0x33, f
|
||||||
|
btfsc 0x33, 4
|
||||||
|
goto mangle_lock_withskip
|
||||||
|
mangle_lock_withoutskip
|
||||||
|
movf 0x41, w ; restore 33
|
||||||
|
addwf 0x34, f ; add to 34
|
||||||
|
movf 0x35, w
|
||||||
|
movwf 0x40 ; save 35 to 40
|
||||||
|
movf 0x34, w
|
||||||
|
addwf 0x35, f
|
||||||
|
movf 0x36, w
|
||||||
|
movwf 0x41 ; save 36 to 41
|
||||||
|
movf 0x40, w ; restore 35
|
||||||
|
andlw 0xf ; mask nibble
|
||||||
|
addlw 0x8 ; add #8 to HIGH nibble
|
||||||
|
movwf 0x40
|
||||||
|
btfss 0x40, 4 ; skip if carry to 5th bit
|
||||||
|
addwf 0x36, w
|
||||||
|
movwf 0x36
|
||||||
|
|
||||||
|
movf 0x41, w ; restore 36
|
||||||
|
addlw 0x1 ; inc
|
||||||
|
addwf 0x37, f ; add to 37
|
||||||
|
|
||||||
|
movf 0x37, w ;
|
||||||
|
addlw 0x1 ; inc
|
||||||
|
addwf 0x38, f ; add to 38
|
||||||
|
|
||||||
|
movf 0x38, w ;
|
||||||
|
addlw 0x1 ; inc
|
||||||
|
addwf 0x39, f ; add to 39
|
||||||
|
|
||||||
|
movf 0x39, w ;
|
||||||
|
addlw 0x1 ; inc
|
||||||
|
addwf 0x3a, f ; add to 3a
|
||||||
|
|
||||||
|
movf 0x3a, w ;
|
||||||
|
addlw 0x1 ; inc
|
||||||
|
addwf 0x3b, f ; add to 3b
|
||||||
|
|
||||||
|
movf 0x3b, w ;
|
||||||
|
addlw 0x1 ; inc
|
||||||
|
addwf 0x3c, f ; add to 3c
|
||||||
|
|
||||||
|
movf 0x3c, w ;
|
||||||
|
addlw 0x1 ; inc
|
||||||
|
addwf 0x3d, f ; add to 3d
|
||||||
|
|
||||||
|
movf 0x3d, w ;
|
||||||
|
addlw 0x1 ; inc
|
||||||
|
addwf 0x3e, f ; add to 3e
|
||||||
|
|
||||||
|
movf 0x3e, w ;
|
||||||
|
addlw 0x1 ; inc
|
||||||
|
addwf 0x3f, f ; add to 3f
|
||||||
|
|
||||||
|
movf 0x30, w ; restore original 0xf
|
||||||
|
andlw 0xf
|
||||||
|
addlw 0xf
|
||||||
|
movwf 0x30
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
btfss 0x30, 4 ; skip if half-byte carry
|
||||||
|
goto mangle_return
|
||||||
|
nop
|
||||||
|
goto mangle_lock_loop
|
||||||
|
; 69 when goto, 69 when return
|
||||||
|
; CIC has 78 -> 9 nops
|
||||||
|
|
||||||
|
mangle_lock_withskip
|
||||||
|
movf 0x41, w ; restore 33
|
||||||
|
addwf 0x33, f ; add to 33
|
||||||
|
movf 0x34, w
|
||||||
|
movwf 0x40 ; save 34 to 40
|
||||||
|
movf 0x33, w
|
||||||
|
addwf 0x34, f
|
||||||
|
movf 0x35, w
|
||||||
|
movwf 0x41 ; save 35 to 41
|
||||||
|
movf 0x40, w ; restore 34
|
||||||
|
andlw 0xf ; mask nibble
|
||||||
|
addlw 0x8 ; add #8 to HIGH nibble
|
||||||
|
movwf 0x40
|
||||||
|
btfss 0x40, 4 ; skip if carry to 5th bit
|
||||||
|
addwf 0x35, w
|
||||||
|
movwf 0x35
|
||||||
|
|
||||||
|
movf 0x41, w ; restore 35
|
||||||
|
addlw 0x1 ; inc
|
||||||
|
addwf 0x36, f ; add to 36
|
||||||
|
|
||||||
|
movf 0x36, w ;
|
||||||
|
addlw 0x1 ; inc
|
||||||
|
addwf 0x37, f ; add to 37
|
||||||
|
|
||||||
|
movf 0x37, w ;
|
||||||
|
addlw 0x1 ; inc
|
||||||
|
addwf 0x38, f ; add to 38
|
||||||
|
|
||||||
|
movf 0x38, w ;
|
||||||
|
addlw 0x1 ; inc
|
||||||
|
addwf 0x39, f ; add to 39
|
||||||
|
|
||||||
|
movf 0x39, w ;
|
||||||
|
addlw 0x1 ; inc
|
||||||
|
addwf 0x3a, f ; add to 3a
|
||||||
|
|
||||||
|
movf 0x3a, w ;
|
||||||
|
addlw 0x1 ; inc
|
||||||
|
addwf 0x3b, f ; add to 3b
|
||||||
|
|
||||||
|
movf 0x3b, w ;
|
||||||
|
addlw 0x1 ; inc
|
||||||
|
addwf 0x3c, f ; add to 3c
|
||||||
|
|
||||||
|
movf 0x3c, w ;
|
||||||
|
addlw 0x1 ; inc
|
||||||
|
addwf 0x3d, f ; add to 3d
|
||||||
|
|
||||||
|
movf 0x3d, w ;
|
||||||
|
addlw 0x1 ; inc
|
||||||
|
addwf 0x3e, f ; add to 3e
|
||||||
|
|
||||||
|
movf 0x3e, w ;
|
||||||
|
addlw 0x1 ; inc
|
||||||
|
addwf 0x3f, f ; add to 3f
|
||||||
|
|
||||||
|
movf 0x30, w ; restore original 0xf
|
||||||
|
andlw 0xf
|
||||||
|
addlw 0xf
|
||||||
|
movwf 0x30
|
||||||
|
|
||||||
|
btfss 0x5e, 1
|
||||||
|
goto scic_pair_skip1
|
||||||
|
btfsc 0x5f, 1
|
||||||
|
goto scic_pair_skip2
|
||||||
|
goto supercic_pairmode
|
||||||
|
scic_pair_skip1
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
scic_pair_skip2
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
|
||||||
|
btfss 0x30, 4 ; skip if half-byte carry
|
||||||
|
goto mangle_return
|
||||||
|
nop
|
||||||
|
goto mangle_lock_loop
|
||||||
|
; 73 when goto, 73 when return
|
||||||
|
; CIC has 84 -> 11 nops
|
||||||
|
|
||||||
|
; --------wait: 3*(W-1)+7 cycles (including call+return). W=0 -> 256!--------
|
||||||
|
wait
|
||||||
|
movwf 0x4f
|
||||||
|
wait0 decfsz 0x4f, f
|
||||||
|
goto wait0
|
||||||
|
return
|
||||||
|
|
||||||
|
; --------wait long: 8+(3*(w-1))+(772*w). W=0 -> 256!--------
|
||||||
|
longwait
|
||||||
|
movwf 0x4e
|
||||||
|
clrw
|
||||||
|
longwait0
|
||||||
|
call wait
|
||||||
|
decfsz 0x4e, f
|
||||||
|
goto longwait0
|
||||||
|
return
|
||||||
|
|
||||||
|
; --------change region in eeprom and die--------
|
||||||
|
die
|
||||||
|
banksel EEADR
|
||||||
|
clrw
|
||||||
|
movwf EEADR
|
||||||
|
bsf EECON1, RD
|
||||||
|
movf EEDAT, w
|
||||||
|
banksel GPIO
|
||||||
|
movwf 0x4d
|
||||||
|
btfsc 0x4d, 0
|
||||||
|
goto die_reg_6
|
||||||
|
die_reg_9
|
||||||
|
movlw 0x9 ; died with PAL, fall back to NTSC
|
||||||
|
goto die_reg_cont
|
||||||
|
die_reg_6
|
||||||
|
movlw 0x6 ; died with NTSC, fall back to PAL
|
||||||
|
die_reg_cont
|
||||||
|
banksel EEADR
|
||||||
|
movwf EEDAT
|
||||||
|
bsf EECON1, WREN
|
||||||
|
|
||||||
|
die_intloop
|
||||||
|
bcf INTCON, GIE
|
||||||
|
btfsc INTCON, GIE
|
||||||
|
goto die_intloop
|
||||||
|
|
||||||
|
movlw 0x55
|
||||||
|
movwf EECON2
|
||||||
|
movlw 0xaa
|
||||||
|
movwf EECON2
|
||||||
|
bsf EECON1, WR
|
||||||
|
bsf INTCON, GIE
|
||||||
|
|
||||||
|
banksel GPIO
|
||||||
|
bcf GPIO, 4
|
||||||
|
; --------forever: blink status pin--------
|
||||||
|
die_trap
|
||||||
|
goto die_trap
|
||||||
|
; -----------------------------------------------------------------------
|
||||||
|
supercic_pairmode
|
||||||
|
banksel TRISIO
|
||||||
|
bsf TRISIO, 0
|
||||||
|
bsf TRISIO, 1
|
||||||
|
banksel GPIO
|
||||||
|
supercic_pairmode_loop
|
||||||
|
bsf GPIO, 4
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
bcf GPIO, 4
|
||||||
|
goto supercic_pairmode_loop
|
||||||
|
|
||||||
|
; eeprom memory
|
||||||
|
DEEPROM CODE
|
||||||
|
de 0x09 ; D411 (NTSC)
|
||||||
|
end
|
||||||
@ -29,7 +29,7 @@ processor p16f630
|
|||||||
; ,-----_-----.
|
; ,-----_-----.
|
||||||
; +5V (27,58) [18] |1 14| GND (5,36) [9]
|
; +5V (27,58) [18] |1 14| GND (5,36) [9]
|
||||||
; CIC clk (56) [7] |2 A5 A0 13| CIC lock reset in [8]
|
; CIC clk (56) [7] |2 A5 A0 13| CIC lock reset in [8]
|
||||||
; |3 A4 A1 12| 50/60Hz out
|
; D4 out |3 A4 A1 12| 50/60Hz out
|
||||||
; |4 A3 A2 11| host reset out [10]
|
; |4 A3 A2 11| host reset out [10]
|
||||||
; LED out (grn) |5 C5 C0 10| CIC data i/o 0 (55) [1]
|
; LED out (grn) |5 C5 C0 10| CIC data i/o 0 (55) [1]
|
||||||
; LED out (red) |6 C4 C1 9| CIC data i/o 1 (24) [2]
|
; LED out (red) |6 C4 C1 9| CIC data i/o 1 (24) [2]
|
||||||
@ -43,6 +43,11 @@ processor p16f630
|
|||||||
; pin 12 connected to PPU1 pin 24 and PPU2 pin 30 (both isolated from mainboard)
|
; pin 12 connected to PPU1 pin 24 and PPU2 pin 30 (both isolated from mainboard)
|
||||||
; pin 13 connected to reset button
|
; pin 13 connected to reset button
|
||||||
;
|
;
|
||||||
|
; D4 out is always switched to the autodetected region and is not user
|
||||||
|
; overridable. It can be used, by adding an address decoder and a latch,
|
||||||
|
; to override bit 4 of the $213f register (used by games to detect the
|
||||||
|
; console region).
|
||||||
|
;
|
||||||
; Host reset out behaves as follows:
|
; Host reset out behaves as follows:
|
||||||
; After powerup it is held low for a couple of ms to allow the components
|
; After powerup it is held low for a couple of ms to allow the components
|
||||||
; to power-up properly.
|
; to power-up properly.
|
||||||
@ -74,6 +79,14 @@ processor p16f630
|
|||||||
; In case no CIC is present in the game cartridge the user setting is applied
|
; In case no CIC is present in the game cartridge the user setting is applied
|
||||||
; immediately.
|
; immediately.
|
||||||
;
|
;
|
||||||
|
; SuperCIC pair mode: when a SuperCIC lock and SuperCIC key detect each other
|
||||||
|
; they both switch both of the data pins to inputs. The lock then passes through
|
||||||
|
; data i/o 0 to SNES 50/60Hz and data i/o 1 to an optional D4 output (for
|
||||||
|
; overriding the 213f register using additional hardware). This makes it
|
||||||
|
; possible to switch 50/60Hz and D4 from the cartridge slot, e.g. by connecting
|
||||||
|
; an additional MCU to the CIC data lines. Of course, they have to be tristated
|
||||||
|
; for normal (non-passthrough) operation first.
|
||||||
|
;
|
||||||
; Table 1. 50/60Hz output behavior according to user setting and key CIC type.
|
; Table 1. 50/60Hz output behavior according to user setting and key CIC type.
|
||||||
; SuperCIC key CIC "region"
|
; SuperCIC key CIC "region"
|
||||||
; ------------------------------------------------------
|
; ------------------------------------------------------
|
||||||
@ -123,6 +136,9 @@ processor p16f630
|
|||||||
; 0x56 temp LED state
|
; 0x56 temp LED state
|
||||||
; 0x57 detected region (0: 60Hz, 2: 50Hz)
|
; 0x57 detected region (0: 60Hz, 2: 50Hz)
|
||||||
; 0x58 forced region (0: 60Hz, 2: 50Hz)
|
; 0x58 forced region (0: 60Hz, 2: 50Hz)
|
||||||
|
; 0x59 detected D4 (0: 60Hz, 16: 50Hz)
|
||||||
|
; 0x5e SuperCIC pair mode detect (phase 1)
|
||||||
|
; 0x5f SuperCIC pair mode detect (phase 2)
|
||||||
;
|
;
|
||||||
; ---------------------------------------------------------------------
|
; ---------------------------------------------------------------------
|
||||||
|
|
||||||
@ -158,6 +174,9 @@ rst_loop
|
|||||||
clrf 0x53
|
clrf 0x53
|
||||||
clrf 0x54 ; clear user mode
|
clrf 0x54 ; clear user mode
|
||||||
clrf 0x57 ; clear key mode
|
clrf 0x57 ; clear key mode
|
||||||
|
clrf 0x59 ; clear D4
|
||||||
|
clrf 0x5e ;
|
||||||
|
clrf 0x5f ;
|
||||||
banksel EEADR ; fetch current mode from EEPROM
|
banksel EEADR ; fetch current mode from EEPROM
|
||||||
clrf EEADR ; address 0
|
clrf EEADR ; address 0
|
||||||
bsf EECON1, RD ;
|
bsf EECON1, RD ;
|
||||||
@ -166,7 +185,6 @@ rst_loop
|
|||||||
movwf 0x55 ; store saved mode in mode var
|
movwf 0x55 ; store saved mode in mode var
|
||||||
movwf 0x56 ; and temp LED
|
movwf 0x56 ; and temp LED
|
||||||
movwf 0x58
|
movwf 0x58
|
||||||
|
|
||||||
movwf 0x50 ; and final LED
|
movwf 0x50 ; and final LED
|
||||||
movlw 0x3 ; mask
|
movlw 0x3 ; mask
|
||||||
andwf 0x50, f ;
|
andwf 0x50, f ;
|
||||||
@ -181,7 +199,7 @@ rst_loop
|
|||||||
bsf T1CON, 0 ; start the timer
|
bsf T1CON, 0 ; start the timer
|
||||||
goto main ; go go go
|
goto main ; go go go
|
||||||
init
|
init
|
||||||
; PORTA: in in in out out in
|
; PORTA: in out in out out in
|
||||||
; PORTC: out out in out out in
|
; PORTC: out out in out out in
|
||||||
banksel PORTA
|
banksel PORTA
|
||||||
clrf PORTA
|
clrf PORTA
|
||||||
@ -190,7 +208,7 @@ init
|
|||||||
movlw 0x00 ; disable all interrupts
|
movlw 0x00 ; disable all interrupts
|
||||||
movwf INTCON
|
movwf INTCON
|
||||||
banksel TRISA
|
banksel TRISA
|
||||||
movlw 0x39 ; in in in out out in
|
movlw 0x29 ; in out in out out in
|
||||||
movwf TRISA
|
movwf TRISA
|
||||||
movlw 0x09 ; out out in out out in
|
movlw 0x09 ; out out in out out in
|
||||||
movwf TRISC
|
movwf TRISC
|
||||||
@ -352,7 +370,6 @@ loop1
|
|||||||
movwf 0x42 ; store input
|
movwf 0x42 ; store input
|
||||||
movf 0x50, w ; get LED state
|
movf 0x50, w ; get LED state
|
||||||
movwf PORTC ; reset GPIO
|
movwf PORTC ; reset GPIO
|
||||||
nop
|
|
||||||
|
|
||||||
call checkkey
|
call checkkey
|
||||||
|
|
||||||
@ -388,7 +405,6 @@ loop1
|
|||||||
nop
|
nop
|
||||||
nop
|
nop
|
||||||
nop
|
nop
|
||||||
nop
|
|
||||||
btfsc 0x37, 0
|
btfsc 0x37, 0
|
||||||
goto swap
|
goto swap
|
||||||
banksel TRISC
|
banksel TRISC
|
||||||
@ -404,6 +420,7 @@ swapskip
|
|||||||
banksel PORTA
|
banksel PORTA
|
||||||
bsf 0x54, 2 ; run the console
|
bsf 0x54, 2 ; run the console
|
||||||
movf 0x54, w ; read resolved mode
|
movf 0x54, w ; read resolved mode
|
||||||
|
iorwf 0x59, w ; get D4 value
|
||||||
movwf PORTA
|
movwf PORTA
|
||||||
bcf 0x43, 0 ; don't check key region anymore
|
bcf 0x43, 0 ; don't check key region anymore
|
||||||
movf 0x37, w
|
movf 0x37, w
|
||||||
@ -576,10 +593,10 @@ mangle_key_withskip
|
|||||||
addlw 0xf
|
addlw 0xf
|
||||||
movwf 0x20
|
movwf 0x20
|
||||||
bsf PORTC, 1
|
bsf PORTC, 1
|
||||||
movlw PORTC
|
movf PORTC, w
|
||||||
movwf 0x5e
|
movwf 0x5e
|
||||||
bcf PORTC, 1
|
bcf PORTC, 1
|
||||||
movlw PORTC
|
movf PORTC, w
|
||||||
movwf 0x5f
|
movwf 0x5f
|
||||||
nop
|
nop
|
||||||
nop
|
nop
|
||||||
@ -751,17 +768,23 @@ mangle_lock_withskip
|
|||||||
andlw 0xf
|
andlw 0xf
|
||||||
addlw 0xf
|
addlw 0xf
|
||||||
movwf 0x30
|
movwf 0x30
|
||||||
|
|
||||||
|
btfsc 0x5e, 0
|
||||||
|
goto scic_pair_skip1
|
||||||
|
btfss 0x5f, 0
|
||||||
|
goto scic_pair_skip2
|
||||||
|
goto supercic_pairmode
|
||||||
|
scic_pair_skip1
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
scic_pair_skip2
|
||||||
nop
|
nop
|
||||||
nop
|
nop
|
||||||
nop
|
nop
|
||||||
nop
|
nop
|
||||||
nop
|
nop
|
||||||
nop
|
nop
|
||||||
nop
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
btfss 0x30, 4 ; skip if half-byte carry
|
btfss 0x30, 4 ; skip if half-byte carry
|
||||||
goto mangle_return
|
goto mangle_return
|
||||||
nop
|
nop
|
||||||
@ -793,7 +816,7 @@ die
|
|||||||
goto die
|
goto die
|
||||||
|
|
||||||
; --------check the key input and change "region" when appropriate--------
|
; --------check the key input and change "region" when appropriate--------
|
||||||
; --------requires 19 cycles (incl. call+return)
|
; --------requires 20 cycles (incl. call+return)
|
||||||
checkkey
|
checkkey
|
||||||
btfss 0x43, 0 ; first time?
|
btfss 0x43, 0 ; first time?
|
||||||
goto checkkey_nocheck; if not, just burn some cycles
|
goto checkkey_nocheck; if not, just burn some cycles
|
||||||
@ -807,11 +830,13 @@ checkkey
|
|||||||
checkkey_411
|
checkkey_411
|
||||||
nop ; to compensate for untaken branch
|
nop ; to compensate for untaken branch
|
||||||
bcf 0x57, 1 ; set detected mode (60Hz)
|
bcf 0x57, 1 ; set detected mode (60Hz)
|
||||||
|
bcf 0x59, 4 ; set detected D4 mode (60Hz)
|
||||||
bcf 0x54, 1 ; set output mode (60Hz)
|
bcf 0x54, 1 ; set output mode (60Hz)
|
||||||
movlw 0x9
|
movlw 0x9
|
||||||
goto checkkey_save
|
goto checkkey_save
|
||||||
checkkey_413
|
checkkey_413
|
||||||
bsf 0x57, 1 ; set detected mode (50Hz)
|
bsf 0x57, 1 ; set detected mode (50Hz)
|
||||||
|
bsf 0x59, 4 ; set detected D4 mode (50Hz)
|
||||||
bsf 0x54, 1 ; set output mode (50Hz)
|
bsf 0x54, 1 ; set output mode (50Hz)
|
||||||
movlw 0x6
|
movlw 0x6
|
||||||
goto checkkey_save
|
goto checkkey_save
|
||||||
@ -828,6 +853,7 @@ checkkey_nocheck2
|
|||||||
nop
|
nop
|
||||||
nop
|
nop
|
||||||
nop
|
nop
|
||||||
|
nop
|
||||||
goto checkkey_done
|
goto checkkey_done
|
||||||
checkkey_save
|
checkkey_save
|
||||||
movwf 0x32
|
movwf 0x32
|
||||||
@ -974,8 +1000,32 @@ checkrst_0_0_setregion_plus5
|
|||||||
nop
|
nop
|
||||||
goto checkrst_0_0_setregion
|
goto checkrst_0_0_setregion
|
||||||
|
|
||||||
checktmr ; TODO
|
supercic_pairmode
|
||||||
return
|
banksel TRISC
|
||||||
|
bsf TRISC, 0 ; tristate both
|
||||||
|
bsf TRISC, 1 ; data lines
|
||||||
|
banksel PORTC
|
||||||
|
supercic_pairmode_loop
|
||||||
|
clrf 0x5d
|
||||||
|
bsf 0x5d, 2
|
||||||
|
btfsc PORTC, 0
|
||||||
|
bsf 0x5d, 1
|
||||||
|
btfsc PORTC, 1
|
||||||
|
bsf 0x5d, 4
|
||||||
|
btfsc PORTA, 0
|
||||||
|
bcf 0x5d, 2
|
||||||
|
movf 0x5d, w
|
||||||
|
movwf PORTA
|
||||||
|
btfss PORTC, 0
|
||||||
|
goto supercic_pairmode_led_60
|
||||||
|
supercic_pairmode_led_50
|
||||||
|
bcf PORTC, 4
|
||||||
|
bsf PORTC, 5
|
||||||
|
goto supercic_pairmode_loop
|
||||||
|
supercic_pairmode_led_60
|
||||||
|
bsf PORTC, 4
|
||||||
|
bcf PORTC, 5
|
||||||
|
goto supercic_pairmode_loop
|
||||||
; -----------------------------------------------------------------------
|
; -----------------------------------------------------------------------
|
||||||
; eeprom data
|
; eeprom data
|
||||||
DEEPROM CODE
|
DEEPROM CODE
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user