NES CIC Lockout Chip

The NES lockout chip, known commonly as the CIC (Checking IC(Integrated Circuit)), was an IC found on NES game cartridges and consoles which served to prevent piracy and strengthen Nintendo’s iron grip on its illegal game monopoly. If no valid CIC chip is present on a game cartridge, or if the game’s contacts were dirty, the console would reset periodically every second indicating communication with the CIC was lost. During the course of the NES’s life, many manufacturers found horrible ways of circumventing the CIC with charge pumps and other hideous circuitry – but one company, Tengen, managed to reverse engineer the CIC algorithm.

None of the information and work presented here would be possible without Segher’s amazing work, found here. Also, a huge thanks to Infinite NES Lives for answering so many of questions about the CIC.

Development

How It Works

The CIC in the console and the cartridge are identical. Pin 4 set to 0V identifies the CIC as in a cartridge (key mode). Pin 4 set to 5V identifies the CIC as in the console (lock mode). The two chips execute the same code and are clocked 4MHz signal. They communicate to each other over two wires; each calculating what the other should be sending. If the input differs from the calculation, the chip lockouts the cartridge and resets the console causing the user to blow in the cartridge.

The CPU

The CIC chip is a 4bit CPU. Well, more accurately an MCU as it contains its own ROM, RAM and I/O ports. I have searched extensively online and found interesting similarities between the instruction set proposed by Segher and a Rockwell PPS-4 CPU.

that original cic chips is the Sharp SM590 and SM595 microcomputers.

Programmer’s Model

8

7

6

5

4

3

2

1

0

C

A

X

BH

BL

PC

Stack[0]

Stack[1]

Stack[2]

Stack[3]

A – 4 bit accumulator

C – carry flag

X – 4 bit general purpose register

BL – lower 4 bits of RAM pointer

BH – upper 2 bits of RAM pointer

PC – program counter

Stack[0..3] – 4 level hardware stack for module calls

Program Counter

The Program Counter in the CIC cpu is quite peculiar. It is 10 bits wide and “increments” by shifting to the right and setting bit 6 if bit 1 and bit 0 are equal. The Program Counter never increments passed a 128 byte boundary; only a transfer module instruction can cause a jump passed a 128 byte boundary.

Of interesting note, the 2 byte Transfer Module opcodes, are not stored sequentially in ROM. Rather, they follow the same increment pattern as the Program Counter described above. Therefore, if we consider the 2 byte Transfer Module call found at address 0x17.

017: 7d 00 tml 200

The first byte, 0x7D, is stored at address 0x17. The second byte, 0x00, is stored at address 0x4B.

Instruction Set

Opcode

Mnemonic

Description

Operation

Notes

0x00 + N

adi N

add immediate skip if overflow

A = A + N

1

0x10 + N

skai N

skip acc immediate

if A = N skip

1

0x20 + N

lbli N

load B low immediate

BL = N

0x30 + N

ldi N

load accumulator immediate

A = N

40

l

load A with *B

A = *B

41

x

exchange A and X

A = X, X = A

42

xi

exchange A and *B, increment BL, skip if overflow

A = *B, *B = A, BL++

1

43

xd

exchange A and *B, decrement BL, skip if underflow

A = *B, *B = A, BL–

1

44

nega

negate accumulator

A = -A

46

out

output A to port number BL

P[BL] = A

47

out0

output 0 to port number BL

P[BL] = 0

48

sc

set carry

C = 1

49

rc

reset carry

C = 0

4A

s

store A to *B

*B = A

4C

rit

return, pop PC from stack

PC = Stack, Stack–

Skipping the next instruction still uses the cycle time of the skipped instruction

Analyzing The Software

Segher has provided a commented disassembly of the CIC software. From this, I have counted the cycles to critical sections and determined the algorithms behaviour in order to port it to the PIC12F629 (work in progress).

Modules

The CPU makes calls to subroutines using an opcode called Transfer Module, therefore I will refer to subroutines as “modules” for consistency.

Module 0x103 – skip next instruction if lock

5 cycles when key

BL = 0

This module tests the P0.3 pin to see if the host is a lock or a key. Since I am only interested in key mode, I can reduce module 0x103 to a 5 cycle burn which sets BL to 0 – never skipping the following instruction.

Module 0x174 – B = other side

10 cycles

BH = 1, BL = 0

This module is actually closely tied to module 0x103 above. The code sets BH to 1, then uses call module 0x103 (skip next instruction if lock) to skip over over 0x11E. In key mode, module 0x103 never skips, therefore we come back from module 0x103 and don’t skip the instruction at 0x11E (lbmi 1). Since I am only interested in key mode, I can reduce module 0x174 to an 10 cycle burn which sets BH to 1 and BL to 0.

Module 0x377 – Input Stream Bit

10 cycles

Input sampled during 7th cycle

This module reads the input stream and stores it to the accumulator. It also sets BL = 0 and its entry and BL = 1 at exit for unknown reasons. The IN instruction at cycle 7 is the time where the input is read.

Related

René

2 thoughts on “NES CIC Lockout Chip”

Is the pic12f629 implementation mature enough to be used in new cartridge designs?

I’ve been unable to get it working on my homemade board so far I compiled it with MPLABX and programmed the PIC using a GQ4-x4 without any issues. The board works fine in a top loader I suspect it may just be that my homemade board is too thin (0.8mm) to work in a front loader.

Before I spend money getting boards of the proper thickness with hard gold plating etc, I’d appreciate it if you could confirm for me that it does work.