Difference between revisions of "Videocart dumper"
(Created page with "Sean Riddle built a dumper for the Videocarts to be able to lure the code out without damaging the cartridges. A portable version was shipped over the world to collect rare d...") |
|||
(15 intermediate revisions by the same user not shown) | |||
Line 2: | Line 2: | ||
A portable version was shipped over the world to collect rare data from even rarer cartridges. | A portable version was shipped over the world to collect rare data from even rarer cartridges. | ||
− | + | Pinout of cartridge: | |
− | + | <pre> | |
+ | 1 ground | ||
+ | 2 ground | ||
+ | 3 D0 | ||
+ | 4 D1 | ||
+ | 5 /INTREQ | ||
+ | 6 ROMC0 | ||
+ | 7 ROMC1 | ||
+ | 8 ROMC2 | ||
+ | 9 D2 | ||
+ | 10 ROMC3 | ||
+ | 11 D3 | ||
+ | 12 ROMC4 | ||
+ | 13 PHI | ||
+ | 14 D4 | ||
+ | 15 WRITE | ||
+ | 16 D5 | ||
+ | 17 D6 | ||
+ | 18 D7 | ||
+ | 19 +5V | ||
+ | 20 +5V | ||
+ | 21 Not Connected | ||
+ | 22 +12V | ||
+ | </pre> | ||
+ | Connect this way: <br> | ||
+ | Port A.0, '''PIC pin 17''', serial data, pair with ground wire to PC (if TTL compatible) serial port, RxD, pin 2 (both 25 pin or 9 pin) serial connector, ground to pin 5 of 9 pin serial, pin 7 if it's a 25 pin. <br> | ||
+ | <br> | ||
+ | Signals going from PIC to cartridge:<br> | ||
+ | Port A.1, '''PIC pin 18''', "f8phi", clock signal, cartridge pin 13<br> | ||
+ | Port A.2, '''PIC pin 1''', "f8write", write signal, cartridge pin 15<br> | ||
+ | Port A.3, '''PIC pin 2''', "f8romc3", ROMC3 signal, cartridge pin 10<br> | ||
+ | <br> | ||
+ | Port B is used for data input D0-D7 from cartridge as follows<br> | ||
+ | D0 to PIC pin 6<br> | ||
+ | D1 to PIC pin 7<br> | ||
+ | D2 to PIC pin 8<br> | ||
+ | D3 to PIC pin 9<br> | ||
+ | D4 to PIC pin 10<br> | ||
+ | D5 to PIC pin 11<br> | ||
+ | D6 to PIC pin 12<br> | ||
+ | D7 to PIC pin 13<br> | ||
+ | <br> | ||
+ | <br> | ||
+ | PIC-processor pinout 16F628:<br> | ||
+ | <br> | ||
+ | [[File:PIC16F628_pinout.png|center]] | ||
+ | <br> | ||
+ | Pinout is the same on the 16C84 and 16F84, no need for hardware changes if you swap between these.<br> | ||
+ | <br> | ||
+ | PC PSU can be used for power, all needed voltages are available on the standard black (ground), red (5V), yellow (12V), black (ground)cable.<br> | ||
+ | <br> | ||
+ | |||
+ | For full compatibility you also need an RS232 level converter as standard says that valid data is supposed to be 3-15V in either direction. However, a lot of modern computers will accept serial data at TTL levels (0 and 5V) which saves some components. A 1k Ohm resistor is recommended between PIC and PC serial port if hooking it directly to a computer serial port. The command DEFINE DEBUG_MODE 1 is required for direct connection to PC. | ||
+ | MAX232 is a popular circuit for level, it does however require five capacitors, see datasheet page 17 and forward for hookup details: | ||
+ | http://datasheets.maximintegrated.com/en/ds/MAX220-MAX249.pdf<br> | ||
+ | <br> | ||
+ | Example schematic for MAX232 (we only need to send data in one direction). | ||
+ | http://blog.sunyday.net/wp-content/uploads/2012/08/Serial-shifter.png | ||
+ | <br> | ||
+ | <br> | ||
+ | |||
+ | The portable dumper mentioned above used a serial eprom to store the data, that's another method if you need some in-between storage before transferring to a computer. | ||
+ | |||
+ | |||
+ | Files for PIC16F84, (PIC16C84) and PIC16F628:<br> | ||
+ | [[https://channelf.se/veswiki/images/e/e6/Dumper_PIC_code.7z PIC processor files]] | ||
+ | |||
+ | |||
+ | |||
+ | Sean Riddle's code (recommended), I changed the buffer size and terminal speed, see comments. | ||
<PRE> | <PRE> | ||
+ | ;Fairchild Channel F cart dumper version 2 | ||
+ | |||
+ | ;2/10/2004 Sean Riddle seanriddle@cox.net | ||
− | ; | + | ; slight modifications by e5frog 15/08/2009 |
− | |||
− | |||
− | |||
− | + | ||
INCLUDE "modedefs.bas" | INCLUDE "modedefs.bas" | ||
− | @ device | + | @ device pic16f84, hs_osc, wdt_off |
+ | |||
− | DEFINE | + | DEFINE OSC 20 ;20 MHz oscillator |
− | DEFINE | + | DEFINE NO_CLRWDT 1 ;watchdog is off |
− | DEFINE | + | DEFINE DEBUG_REG PORTA ;serial output on A.0 |
− | DEFINE | + | DEFINE DEBUG_BIT 0 |
− | DEFINE | + | DEFINE DEBUG_BAUD 9600 ; (was 4800) set terminal program to 9600 8-N-1, log input binary, dump and save the log. |
+ | DEFINE DEBUG_MODE 1 ; for direct output from PIC to serial port (signal to pin 2, GND to pin 5)(no MAX232) | ||
' Set Debug mode: 0 = true, 1 = inverted | ' Set Debug mode: 0 = true, 1 = inverted | ||
− | |||
− | |||
− | |||
− | f8phi | + | BUFSIZE CON 16 ;16-byte buffer |
− | f8write | + | |
− | f8romc3 | + | i VAR BYTE ;general register |
+ | k VAR WORD ;another | ||
+ | |||
+ | buf VAR BYTE ;buffer pointer | ||
+ | rom VAR BYTE[BUFSIZE] ;buffer to store ROM | ||
+ | |||
+ | f8phi VAR PORTA.1 ;clock signal | ||
+ | f8write VAR PORTA.2 ;write signal | ||
+ | f8romc3 VAR PORTA.3 ;ROMC3 signal | ||
− | ; | + | ; CMCON=7 ;turn off comparators, sets digital I/O |
− | OPTION_REG.7=0 | + | OPTION_REG.7=0 ;weak pull ups on port B |
− | TRISB=$FF | + | TRISB=$FF ;port B is all input |
Low f8phi | Low f8phi | ||
Line 43: | Line 119: | ||
Low f8romc3 | Low f8romc3 | ||
− | + | ; Debug "start..." | |
+ | |||
+ | Pause 2000 ;wait a couple of seconds after reset | ||
+ | |||
+ | ; what I do: | ||
+ | ; clear PC0 with ROMC state 8 | ||
+ | ; loop 1024 times (was 256) | ||
+ | ; fetch 16 bytes into buffer with ROMC state 0 | ||
+ | ; dump buffer to serial port | ||
+ | |||
+ | |||
+ | f8phi=1 | ||
+ | f8write=1 | ||
+ | |||
+ | @ nop ;NOPs used to create square waves | ||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8phi=0 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8write=0 | ||
+ | f8phi=1 | ||
+ | f8romc3=0 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8phi=0 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8romc3=0 | ||
+ | f8phi=1 | ||
+ | f8romc3=1 ; this puts us in ROMC state 8 - clear PC0 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8phi=0 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8romc3=1 | ||
+ | f8phi=1 | ||
+ | f8romc3=1 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8phi=0 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | |||
+ | ;;; | ||
+ | |||
+ | |||
+ | f8phi=1 | ||
+ | f8write=1 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8phi=0 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8write=0 | ||
+ | f8phi=1 | ||
+ | f8romc3=0 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8phi=0 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8write=0 | ||
+ | f8phi=1 | ||
+ | f8romc3=0 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8phi=0 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8write=0 | ||
+ | f8phi=1 | ||
+ | f8romc3=0 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8phi=0 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
− | + | f8write=0 | |
− | ; | + | For k=1 TO 1024 ; was 256 |
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | For i=0 TO BUFSIZE-1 | |
− | |||
− | + | f8phi=1 | |
+ | f8write=1 | ||
− | + | @ nop | |
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
− | + | f8phi=0 | |
− | |||
− | + | @ nop | |
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
− | + | f8write=0 | |
− | + | f8phi=1 | |
− | + | f8romc3=0 | |
− | + | @ nop | |
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
− | + | f8phi=0 | |
− | + | @ nop | |
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
− | + | f8write=0 | |
+ | f8phi=1 | ||
+ | f8romc3=0 ;ROMC state 0, fetch instruction | ||
− | + | @ nop | |
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
− | + | f8phi=0 | |
− | |||
− | |||
− | |||
− | |||
− | + | @ nop | |
− | + | @ nop | |
− | + | @ nop | |
+ | @ nop | ||
− | + | f8write=0 | |
+ | f8phi=1 | ||
+ | rom[i]=PORTB ;read databus into buffer | ||
+ | f8phi=0 | ||
− | For k=0 | + | Next i |
+ | |||
+ | For i=0 TO BUFSIZE-1 ;dump the buffer to the serial port | ||
+ | Debug rom[i] | ||
+ | Next i | ||
+ | Next k | ||
+ | |||
+ | |||
+ | |||
+ | End | ||
+ | </PRE> | ||
+ | |||
+ | |||
+ | |||
+ | The following is a slightly modified version that have 100% success rate so far. | ||
+ | Simpler loop, one nop less in the clear PC0 routine. | ||
+ | |||
+ | <pre> | ||
+ | ; Fairchild Channel F cart dumper version 2 | ||
+ | ; 2/10/2004 Sean Riddle seanriddle@cox.net | ||
+ | ; Modified by Fredric "e5frog" Blåholtz | ||
+ | ; Pic BASIC Pro | ||
+ | |||
+ | INCLUDE "modedefs.bas" | ||
+ | |||
+ | @ device pic16f628, protect_off, cpd_off, lvp_off, bod_on, mclr_on, pwrt_on, wdt_off, hs_osc | ||
+ | |||
+ | DEFINE OSC 20 ; 20 MHz oscillator | ||
+ | DEFINE NO_CLRWDT 1 ; watchdog is off | ||
+ | |||
+ | DEFINE DEBUG_REG PORTA ; serial output on A.0 | ||
+ | DEFINE DEBUG_BIT 0 | ||
+ | DEFINE DEBUG_BAUD 9600 | ||
+ | DEFINE DEBUG_MODE 1 | ||
+ | |||
+ | BUFSIZE CON 16 ; 16-byte buffer | ||
+ | |||
+ | k VAR WORD ; another | ||
+ | |||
+ | buf VAR BYTE ; buffer pointer | ||
+ | rom VAR BYTE[BUFSIZE] ; buffer to store ROM | ||
+ | |||
+ | f8phi VAR PORTA.1 ; clock signal | ||
+ | f8write VAR PORTA.2 ; write signal | ||
+ | f8romc3 VAR PORTA.3 ; ROMC3 signal | ||
+ | |||
+ | CMCON = 7 ; Port A = digital I/O | ||
+ | OPTION_REG.7= 0 ; weak pull ups on port B | ||
+ | TRISB = $FF ; port B is all input | ||
+ | VRCON = 0 ; Voltage reference disabled | ||
+ | |||
+ | Low f8phi | ||
+ | Low f8write | ||
+ | Low f8romc3 | ||
+ | |||
+ | ; Debug "start..." | ||
+ | |||
+ | Pause 2000 ; wait a couple of seconds after reset | ||
+ | |||
+ | ; what I do: | ||
+ | ; clear PC0 with ROMC state 8 | ||
+ | ; loop 256 times | ||
+ | ; fetch 16 bytes into buffer with ROMC state 0 | ||
+ | ; dump buffer to serial port | ||
+ | ; clear PC0 | ||
+ | |||
+ | |||
+ | f8phi=1 | ||
+ | f8write=1 | ||
+ | |||
+ | @ nop ;NOPs used to create square waves | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8phi=0 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8write=0 | ||
+ | f8phi=1 | ||
+ | f8romc3=0 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8phi=0 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8romc3=0 | ||
+ | f8phi=1 | ||
+ | f8romc3=1 ; this puts us in ROMC state 8 - clear PC0 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8phi=0 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8romc3=1 | ||
+ | f8phi=1 | ||
+ | f8romc3=1 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8phi=0 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | |||
+ | ;;; | ||
+ | |||
+ | |||
+ | f8phi=1 | ||
+ | f8write=1 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8phi=0 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8write=0 | ||
+ | f8phi=1 | ||
+ | f8romc3=0 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8phi=0 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8write=0 | ||
+ | f8phi=1 | ||
+ | f8romc3=0 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8phi=0 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8write=0 | ||
+ | f8phi=1 | ||
+ | f8romc3=0 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8phi=0 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8write=0 | ||
+ | |||
+ | |||
+ | ; skip $800 bytes | ||
+ | |||
+ | For k=1 TO 2048 | ||
+ | |||
+ | f8phi=1 | ||
+ | f8write=1 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8phi=0 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8write=0 | ||
+ | f8phi=1 | ||
+ | f8romc3=0 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8phi=0 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8write=0 | ||
+ | f8phi=1 | ||
+ | f8romc3=0 ;ROMC state 0, fetch instruction | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8phi=0 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8write=0 | ||
+ | f8phi=1 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8phi=0 | ||
+ | |||
+ | Next k | ||
+ | For k=1 TO 16384 | ||
− | + | f8phi=1 | |
− | + | f8write=1 | |
− | + | @ nop | |
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
− | + | f8phi=0 | |
− | + | @ nop | |
− | + | @ nop | |
+ | @ nop | ||
+ | @ nop | ||
− | + | f8write=0 | |
+ | f8phi=1 | ||
+ | f8romc3=0 | ||
− | + | @ nop | |
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
− | + | f8phi=0 | |
− | |||
− | |||
− | + | @ nop | |
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
− | + | f8write=0 | |
+ | f8phi=1 | ||
+ | f8romc3=0 ;ROMC state 0, fetch instruction | ||
− | + | @ nop | |
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
− | + | f8phi=0 | |
− | + | @ nop | |
− | + | @ nop | |
− | + | @ nop | |
− | + | @ nop | |
− | |||
− | + | f8write=0 | |
− | + | f8phi=1 | |
− | + | rom=PORTB ;read databus into buffer | |
+ | f8phi=0 | ||
− | + | Debug rom ;send byte over serial line | |
Next k | Next k | ||
Line 139: | Line 626: | ||
End | End | ||
+ | </pre> | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | Attempt to run on a 4MHz PIC16C84, worked pretty well, didn't dump everything. | ||
+ | <PRE> | ||
+ | |||
+ | ; Fairchild Channel F cart dumper version 2 | ||
+ | ; 2/10/2004 Sean Riddle seanriddle@cox.net | ||
+ | ; Edited from 16f84 to 16c84 by Fredric Blåholtz 03/08/2009 | ||
+ | ; Pic BASIC Pro | ||
+ | |||
+ | INCLUDE "modedefs.bas" | ||
+ | |||
+ | @ device pic16c84, hs_osc, wdt_off | ||
+ | |||
+ | ;DEFINE OSC 10 ;10 MHz oscillator | ||
+ | ;DEFINE OSC 3 ;3.58... MHz oscillator | ||
+ | DEFINE OSC 4 ;4 MHz oscillator | ||
+ | DEFINE NO_CLRWDT 1 ;don't insert wake up watchdog code | ||
+ | |||
+ | DEFINE DEBUG_REG PORTA ;serial output on A.0 | ||
+ | DEFINE DEBUG_BIT 0 | ||
+ | DEFINE DEBUG_BAUD 9600 ; can be changed to other baud-rates as well 9600-8-N-1 | ||
+ | ' Set Debug mode: 0 = true, 1 = inverted | ||
+ | DEFINE DEBUG_MODE 1 ; needed when dumping directly from pic to serial port pin 2 (pin 5 GND). | ||
+ | |||
+ | k VAR WORD ;variable for loop | ||
+ | rom VAR BYTE ;buffer to store ROM | ||
+ | |||
+ | f8phi VAR PORTA.1 ;clock signal | ||
+ | f8write VAR PORTA.2 ;write signal | ||
+ | f8romc3 VAR PORTA.3 ;ROMC3 signal | ||
+ | |||
+ | OPTION_REG.7=0 ;weak pull ups on port B | ||
+ | TRISB=$FF ;port B pins are all inputs | ||
+ | |||
+ | Low f8phi ; set all signals LOW at startup | ||
+ | Low f8write | ||
+ | Low f8romc3 | ||
+ | |||
+ | Debug "Dumping starts in two seconds..." ; message on serial line - OPTIONAL | ||
+ | |||
+ | Pause 2000 ;wait 2 seconds after a reset | ||
+ | |||
+ | ; what is done: | ||
+ | ; clear PC0 with ROMC state 8 | ||
+ | ; fetch 1 byte into buffer with ROMC state 0 | ||
+ | ; dump buffer to serial port | ||
+ | ; loop 16384 times | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | f8phi=1 | ||
+ | f8write=1 | ||
+ | |||
+ | @ nop ;NOPs used to create square waves | ||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8phi=0 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8write=0 | ||
+ | f8phi=1 | ||
+ | f8romc3=0 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8phi=0 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8romc3=0 | ||
+ | f8phi=1 | ||
+ | f8romc3=1 ; this puts us in ROMC state 8 - clear PC0 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8phi=0 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8romc3=1 | ||
+ | f8phi=1 | ||
+ | f8romc3=1 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8phi=0 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | @ nop ; forgotten in Sean's version? | ||
+ | |||
+ | ;;; | ||
+ | |||
+ | |||
+ | f8phi=1 | ||
+ | f8write=1 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8phi=0 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8write=0 | ||
+ | f8phi=1 | ||
+ | f8romc3=0 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8phi=0 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | f8write=0 | ||
+ | f8phi=1 | ||
+ | f8romc3=0 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8phi=0 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8write=0 | ||
+ | f8phi=1 | ||
+ | f8romc3=0 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8phi=0 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8write=0 | ||
+ | |||
+ | For k=0 TO 16383 | ||
+ | |||
+ | f8phi=1 | ||
+ | f8write=1 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8phi=0 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8write=0 | ||
+ | f8phi=1 | ||
+ | f8romc3=0 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8phi=0 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8write=0 | ||
+ | f8phi=1 | ||
+ | f8romc3=0 ;ROMC state 0, fetch instruction | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8phi=0 | ||
+ | |||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | @ nop | ||
+ | |||
+ | f8write=0 | ||
+ | f8phi=1 | ||
+ | rom=PORTB ;read databus into buffer | ||
+ | f8phi=0 | ||
+ | |||
+ | Debug rom ;send byte over serial line | ||
+ | |||
+ | |||
+ | Next k | ||
+ | |||
+ | |||
+ | |||
+ | End | ||
</PRE> | </PRE> |
Latest revision as of 15:46, 12 April 2022
Sean Riddle built a dumper for the Videocarts to be able to lure the code out without damaging the cartridges. A portable version was shipped over the world to collect rare data from even rarer cartridges.
Pinout of cartridge:
1 ground 2 ground 3 D0 4 D1 5 /INTREQ 6 ROMC0 7 ROMC1 8 ROMC2 9 D2 10 ROMC3 11 D3 12 ROMC4 13 PHI 14 D4 15 WRITE 16 D5 17 D6 18 D7 19 +5V 20 +5V 21 Not Connected 22 +12V
Connect this way:
Port A.0, PIC pin 17, serial data, pair with ground wire to PC (if TTL compatible) serial port, RxD, pin 2 (both 25 pin or 9 pin) serial connector, ground to pin 5 of 9 pin serial, pin 7 if it's a 25 pin.
Signals going from PIC to cartridge:
Port A.1, PIC pin 18, "f8phi", clock signal, cartridge pin 13
Port A.2, PIC pin 1, "f8write", write signal, cartridge pin 15
Port A.3, PIC pin 2, "f8romc3", ROMC3 signal, cartridge pin 10
Port B is used for data input D0-D7 from cartridge as follows
D0 to PIC pin 6
D1 to PIC pin 7
D2 to PIC pin 8
D3 to PIC pin 9
D4 to PIC pin 10
D5 to PIC pin 11
D6 to PIC pin 12
D7 to PIC pin 13
PIC-processor pinout 16F628:
Pinout is the same on the 16C84 and 16F84, no need for hardware changes if you swap between these.
PC PSU can be used for power, all needed voltages are available on the standard black (ground), red (5V), yellow (12V), black (ground)cable.
For full compatibility you also need an RS232 level converter as standard says that valid data is supposed to be 3-15V in either direction. However, a lot of modern computers will accept serial data at TTL levels (0 and 5V) which saves some components. A 1k Ohm resistor is recommended between PIC and PC serial port if hooking it directly to a computer serial port. The command DEFINE DEBUG_MODE 1 is required for direct connection to PC.
MAX232 is a popular circuit for level, it does however require five capacitors, see datasheet page 17 and forward for hookup details:
http://datasheets.maximintegrated.com/en/ds/MAX220-MAX249.pdf
Example schematic for MAX232 (we only need to send data in one direction).
http://blog.sunyday.net/wp-content/uploads/2012/08/Serial-shifter.png
The portable dumper mentioned above used a serial eprom to store the data, that's another method if you need some in-between storage before transferring to a computer.
Files for PIC16F84, (PIC16C84) and PIC16F628:
[PIC processor files]
Sean Riddle's code (recommended), I changed the buffer size and terminal speed, see comments.
;Fairchild Channel F cart dumper version 2 ;2/10/2004 Sean Riddle seanriddle@cox.net ; slight modifications by e5frog 15/08/2009 INCLUDE "modedefs.bas" @ device pic16f84, hs_osc, wdt_off DEFINE OSC 20 ;20 MHz oscillator DEFINE NO_CLRWDT 1 ;watchdog is off DEFINE DEBUG_REG PORTA ;serial output on A.0 DEFINE DEBUG_BIT 0 DEFINE DEBUG_BAUD 9600 ; (was 4800) set terminal program to 9600 8-N-1, log input binary, dump and save the log. DEFINE DEBUG_MODE 1 ; for direct output from PIC to serial port (signal to pin 2, GND to pin 5)(no MAX232) ' Set Debug mode: 0 = true, 1 = inverted BUFSIZE CON 16 ;16-byte buffer i VAR BYTE ;general register k VAR WORD ;another buf VAR BYTE ;buffer pointer rom VAR BYTE[BUFSIZE] ;buffer to store ROM f8phi VAR PORTA.1 ;clock signal f8write VAR PORTA.2 ;write signal f8romc3 VAR PORTA.3 ;ROMC3 signal ; CMCON=7 ;turn off comparators, sets digital I/O OPTION_REG.7=0 ;weak pull ups on port B TRISB=$FF ;port B is all input Low f8phi Low f8write Low f8romc3 ; Debug "start..." Pause 2000 ;wait a couple of seconds after reset ; what I do: ; clear PC0 with ROMC state 8 ; loop 1024 times (was 256) ; fetch 16 bytes into buffer with ROMC state 0 ; dump buffer to serial port f8phi=1 f8write=1 @ nop ;NOPs used to create square waves @ nop @ nop @ nop f8phi=0 @ nop @ nop @ nop @ nop f8write=0 f8phi=1 f8romc3=0 @ nop @ nop @ nop @ nop f8phi=0 @ nop @ nop @ nop @ nop f8romc3=0 f8phi=1 f8romc3=1 ; this puts us in ROMC state 8 - clear PC0 @ nop @ nop @ nop @ nop f8phi=0 @ nop @ nop @ nop @ nop f8romc3=1 f8phi=1 f8romc3=1 @ nop @ nop @ nop @ nop f8phi=0 @ nop @ nop @ nop ;;; f8phi=1 f8write=1 @ nop @ nop @ nop @ nop f8phi=0 @ nop @ nop @ nop @ nop f8write=0 f8phi=1 f8romc3=0 @ nop @ nop @ nop @ nop f8phi=0 @ nop @ nop @ nop @ nop f8write=0 f8phi=1 f8romc3=0 @ nop @ nop @ nop @ nop f8phi=0 @ nop @ nop @ nop @ nop f8write=0 f8phi=1 f8romc3=0 @ nop @ nop @ nop @ nop f8phi=0 @ nop @ nop @ nop @ nop f8write=0 For k=1 TO 1024 ; was 256 For i=0 TO BUFSIZE-1 f8phi=1 f8write=1 @ nop @ nop @ nop @ nop f8phi=0 @ nop @ nop @ nop @ nop f8write=0 f8phi=1 f8romc3=0 @ nop @ nop @ nop @ nop f8phi=0 @ nop @ nop @ nop @ nop f8write=0 f8phi=1 f8romc3=0 ;ROMC state 0, fetch instruction @ nop @ nop @ nop @ nop f8phi=0 @ nop @ nop @ nop @ nop f8write=0 f8phi=1 rom[i]=PORTB ;read databus into buffer f8phi=0 Next i For i=0 TO BUFSIZE-1 ;dump the buffer to the serial port Debug rom[i] Next i Next k End
The following is a slightly modified version that have 100% success rate so far. Simpler loop, one nop less in the clear PC0 routine.
; Fairchild Channel F cart dumper version 2 ; 2/10/2004 Sean Riddle seanriddle@cox.net ; Modified by Fredric "e5frog" Blåholtz ; Pic BASIC Pro INCLUDE "modedefs.bas" @ device pic16f628, protect_off, cpd_off, lvp_off, bod_on, mclr_on, pwrt_on, wdt_off, hs_osc DEFINE OSC 20 ; 20 MHz oscillator DEFINE NO_CLRWDT 1 ; watchdog is off DEFINE DEBUG_REG PORTA ; serial output on A.0 DEFINE DEBUG_BIT 0 DEFINE DEBUG_BAUD 9600 DEFINE DEBUG_MODE 1 BUFSIZE CON 16 ; 16-byte buffer k VAR WORD ; another buf VAR BYTE ; buffer pointer rom VAR BYTE[BUFSIZE] ; buffer to store ROM f8phi VAR PORTA.1 ; clock signal f8write VAR PORTA.2 ; write signal f8romc3 VAR PORTA.3 ; ROMC3 signal CMCON = 7 ; Port A = digital I/O OPTION_REG.7= 0 ; weak pull ups on port B TRISB = $FF ; port B is all input VRCON = 0 ; Voltage reference disabled Low f8phi Low f8write Low f8romc3 ; Debug "start..." Pause 2000 ; wait a couple of seconds after reset ; what I do: ; clear PC0 with ROMC state 8 ; loop 256 times ; fetch 16 bytes into buffer with ROMC state 0 ; dump buffer to serial port ; clear PC0 f8phi=1 f8write=1 @ nop ;NOPs used to create square waves @ nop @ nop f8phi=0 @ nop @ nop @ nop f8write=0 f8phi=1 f8romc3=0 @ nop @ nop @ nop f8phi=0 @ nop @ nop @ nop f8romc3=0 f8phi=1 f8romc3=1 ; this puts us in ROMC state 8 - clear PC0 @ nop @ nop @ nop f8phi=0 @ nop @ nop @ nop f8romc3=1 f8phi=1 f8romc3=1 @ nop @ nop @ nop f8phi=0 @ nop @ nop @ nop ;;; f8phi=1 f8write=1 @ nop @ nop @ nop f8phi=0 @ nop @ nop @ nop f8write=0 f8phi=1 f8romc3=0 @ nop @ nop @ nop f8phi=0 @ nop @ nop @ nop f8write=0 f8phi=1 f8romc3=0 @ nop @ nop @ nop f8phi=0 @ nop @ nop @ nop f8write=0 f8phi=1 f8romc3=0 @ nop @ nop @ nop f8phi=0 @ nop @ nop @ nop f8write=0 ; skip $800 bytes For k=1 TO 2048 f8phi=1 f8write=1 @ nop @ nop @ nop @ nop f8phi=0 @ nop @ nop @ nop @ nop f8write=0 f8phi=1 f8romc3=0 @ nop @ nop @ nop @ nop f8phi=0 @ nop @ nop @ nop @ nop f8write=0 f8phi=1 f8romc3=0 ;ROMC state 0, fetch instruction @ nop @ nop @ nop @ nop f8phi=0 @ nop @ nop @ nop @ nop f8write=0 f8phi=1 @ nop @ nop @ nop @ nop f8phi=0 Next k For k=1 TO 16384 f8phi=1 f8write=1 @ nop @ nop @ nop @ nop f8phi=0 @ nop @ nop @ nop @ nop f8write=0 f8phi=1 f8romc3=0 @ nop @ nop @ nop @ nop f8phi=0 @ nop @ nop @ nop @ nop f8write=0 f8phi=1 f8romc3=0 ;ROMC state 0, fetch instruction @ nop @ nop @ nop @ nop f8phi=0 @ nop @ nop @ nop @ nop f8write=0 f8phi=1 rom=PORTB ;read databus into buffer f8phi=0 Debug rom ;send byte over serial line Next k End
Attempt to run on a 4MHz PIC16C84, worked pretty well, didn't dump everything.
; Fairchild Channel F cart dumper version 2 ; 2/10/2004 Sean Riddle seanriddle@cox.net ; Edited from 16f84 to 16c84 by Fredric Blåholtz 03/08/2009 ; Pic BASIC Pro INCLUDE "modedefs.bas" @ device pic16c84, hs_osc, wdt_off ;DEFINE OSC 10 ;10 MHz oscillator ;DEFINE OSC 3 ;3.58... MHz oscillator DEFINE OSC 4 ;4 MHz oscillator DEFINE NO_CLRWDT 1 ;don't insert wake up watchdog code DEFINE DEBUG_REG PORTA ;serial output on A.0 DEFINE DEBUG_BIT 0 DEFINE DEBUG_BAUD 9600 ; can be changed to other baud-rates as well 9600-8-N-1 ' Set Debug mode: 0 = true, 1 = inverted DEFINE DEBUG_MODE 1 ; needed when dumping directly from pic to serial port pin 2 (pin 5 GND). k VAR WORD ;variable for loop rom VAR BYTE ;buffer to store ROM f8phi VAR PORTA.1 ;clock signal f8write VAR PORTA.2 ;write signal f8romc3 VAR PORTA.3 ;ROMC3 signal OPTION_REG.7=0 ;weak pull ups on port B TRISB=$FF ;port B pins are all inputs Low f8phi ; set all signals LOW at startup Low f8write Low f8romc3 Debug "Dumping starts in two seconds..." ; message on serial line - OPTIONAL Pause 2000 ;wait 2 seconds after a reset ; what is done: ; clear PC0 with ROMC state 8 ; fetch 1 byte into buffer with ROMC state 0 ; dump buffer to serial port ; loop 16384 times f8phi=1 f8write=1 @ nop ;NOPs used to create square waves @ nop @ nop @ nop f8phi=0 @ nop @ nop @ nop @ nop f8write=0 f8phi=1 f8romc3=0 @ nop @ nop @ nop @ nop f8phi=0 @ nop @ nop @ nop @ nop f8romc3=0 f8phi=1 f8romc3=1 ; this puts us in ROMC state 8 - clear PC0 @ nop @ nop @ nop @ nop f8phi=0 @ nop @ nop @ nop @ nop f8romc3=1 f8phi=1 f8romc3=1 @ nop @ nop @ nop @ nop f8phi=0 @ nop @ nop @ nop @ nop ; forgotten in Sean's version? ;;; f8phi=1 f8write=1 @ nop @ nop @ nop @ nop f8phi=0 @ nop @ nop @ nop @ nop f8write=0 f8phi=1 f8romc3=0 @ nop @ nop @ nop @ nop f8phi=0 @ nop @ nop @ nop @ nop f8write=0 f8phi=1 f8romc3=0 @ nop @ nop @ nop @ nop f8phi=0 @ nop @ nop @ nop @ nop f8write=0 f8phi=1 f8romc3=0 @ nop @ nop @ nop @ nop f8phi=0 @ nop @ nop @ nop @ nop f8write=0 For k=0 TO 16383 f8phi=1 f8write=1 @ nop @ nop @ nop @ nop f8phi=0 @ nop @ nop @ nop @ nop f8write=0 f8phi=1 f8romc3=0 @ nop @ nop @ nop @ nop f8phi=0 @ nop @ nop @ nop @ nop f8write=0 f8phi=1 f8romc3=0 ;ROMC state 0, fetch instruction @ nop @ nop @ nop @ nop f8phi=0 @ nop @ nop @ nop @ nop f8write=0 f8phi=1 rom=PORTB ;read databus into buffer f8phi=0 Debug rom ;send byte over serial line Next k End