Algunos de los objetivos de esta deconstruccion son:
- -conocer el funcionamiento de este cartucho.
-poder generar nuevos 'videos' con otros software dentro.
-preservar el video original reconstruyendolo/remasterizandolo
-clonar el dispositivo, con un diseño mejor y mas actual (utilizando un CPLD)
-tomar ideas para futuros proyectos de esta misma linea de preservacion de la historia :)
Paso 1: llevar el diseño original a papel.
ZZT me facilito un video cartdrigde, del cual habia el previamente extraido la EPROM, y por suerte este ejemplar no tenia resina.
Utilizando este cartucho busque informacion sobre sus componentes, trace sus pistas y lo lleve a esquematicos.
Una foto referencial del cartucho con es la siguiente:

El listado de componentes es el siguiente:
Código: Seleccionar todo
U1 CD4024 CMOS ripple-carry binary counter/divider
U2 74LS00 Quad 2 input NAND gates
U3 CD4013 CMOS dual D type flip-flop
U4 74LS02 Quad 2 input NOR gates
U5 74LS175 Quad D flip-flop
U6 2764 64K (8K x 8) EPROM (D2764A o MSL2719K)
U7 CD4094 8 stage shift/store register (MC14094BCP)
U8 2N2222A
U9 2N2222A
R1 75
R2 220
R3 220
R4 10K
R5 100K
R6 4.7K
R7 1K
C1 4.7nF
C2 10nF
C3 47pF
C4 0.1uF
C5 10uF (electrolitico)
C6 10uF (electrolitico)
Lo he revisado un monton de veces, pero aun asi puede contener algun error.
Paso 2: leyendo la EPROM
Este paso lo realizo ZZT y la imagen esta disponible en el post de la seccion RETRO-MUSEO.
Paso 3: desensamblando la ROM, lo basico....
La primera parte relevante que hace la ejecucion de este cartucho es copiar 0x792 bytes desde 0xA07F (justo despues del texto de Turbo Software y las iniciales del autor) a 0xD800 y luego salta hacia alla.
en 0xD800 se ejecutan 3 funciones (DAE6,DBDC y DA88) que tienen como objetivo parchar parte del codigo, por que querria parchar el codigo de si mismo??? simple: por ofuscacion.
por ejemplo miremos parte de la funcion 0xDB4B (la principal encargada de leer los datos del video desde el hardware del cartucho)
Código: Seleccionar todo
RAM:DB4B PHA
RAM:DB4C TXA
RAM:DB4D PHA
RAM:DB4E TYA
RAM:DB4F PHA
RAM:DB50 LDA byte_D301 ; en realidad es D505
RAM:DB53 LDX #$14
RAM:DB55 LDA byte_D301 ; en realidad es A000
RAM:DB58 BMI loc_DB53
RAM:DB5A DEX
RAM:DB5B BNE loc_DB55
RAM:DB5D LDA byte_D301 ; en realidad es A000
RAM:DB60 BPL loc_DB5D
RAM:DB62 LDA byte_D301 ; en realidad es A000
RAM:DB65 BMI loc_DB62
RAM:DB67 LDA byte_D301 ; en realidad es D505
RAM:DB6A LDA byte_D301 ; en realidad es A000
RAM:DB6D EOR #$FF
RAM:DB6F TAX
RAM:DB70 STX byte_DBD8
RAM:DB73 STX byte_DBD9
RAM:DB76 LDA $DE84,X
RAM:DB79 BEQ loc_DB7E
RAM:DB7B RTS ; en relidad es JMP loc_DB50
RAM:DB7C BVC loc_DB58+1 ; en relidad es JMP loc_DB50
RAM:DB7E LDA $DC68,X
RAM:DB81 STA byte_45
............
de esta manera algun curioso incauto quedara confundido al tratar de mirar un listado del codigo.
En un principio trate de parchar a mano, pero me aburrí en la mitad porque era una tarea tediosa, asi que busque en internet un "core" de 6502 y comencé a escribir un pequeño emulador para que me ayudara con esto y los pasos que vienen.
aqui esta la salida del emulador y los bytes que son parchados.
Código: Seleccionar todo
@DAE9 patching [DB51] (01) <- 05...
@DAEC patching [DB8B] (01) <- 05...
@DAF2 patching [DB52] (d3) <- d5...
@DAF5 patching [DB8C] (d3) <- d5...
@DAFB patching [DB56] (01) <- 00...
@DAFE patching [DB5E] (01) <- 00...
@DB01 patching [DB63] (01) <- 00...
@DB04 patching [DB6B] (01) <- 00...
@DB07 patching [DB96] (01) <- 00...
@DB0A patching [DB9B] (01) <- 00...
@DB0D patching [DBA3] (01) <- 00...
@DB13 patching [DB57] (d3) <- a0...
@DB16 patching [DB5F] (d3) <- a0...
@DB19 patching [DB64] (d3) <- a0...
@DB1C patching [DB6C] (d3) <- a0...
@DB1F patching [DB97] (d3) <- a0...
@DB22 patching [DB9C] (d3) <- a0...
@DB25 patching [DBA4] (d3) <- a0...
@DB2B patching [DB68] (01) <- 03...
@DB2E patching [DBA0] (01) <- 03...
@DB34 patching [DB69] (d3) <- d5...
@DB37 patching [DBA1] (d3) <- d5...
@DB3C patching [DB7B] (60) <- 4c...
@DB3F patching [DB92] (60) <- 4c...
@DB42 patching [DBB5] (60) <- 4c...
@DB45 patching [DBCD] (60) <- 4c...
@D803 patching [01FF] (d8) <- d8...
@D803 patching [01FE] (02) <- 05...
@DBDE patching [D8D9] (8d) <- 4c...
@DBE1 patching [D8E3] (8d) <- 4c...
@DBE4 patching [D8F5] (8d) <- 4c...
@DBE7 patching [D91A] (8d) <- 4c...
@DBEA patching [DA32] (ad) <- 4c...
@DBEF patching [D850] (d3) <- d5...
@DBF2 patching [DA7C] (d3) <- d5...
@D806 patching [01FF] (d8) <- d8...
@D806 patching [01FE] (05) <- 08...
@DA8A patching [D880] (8f) <- 20...
@DA8D patching [D885] (8f) <- 20...
@DA90 patching [D8A2] (8f) <- 20...
@DA93 patching [D8A8] (8f) <- 20...
@DA96 patching [D8B6] (8f) <- 20...
@DA99 patching [D8DC] (8f) <- 20...
@DA9C patching [D8E6] (8f) <- 20...
@DA9F patching [D8F8] (8f) <- 20...
Paso 4: entendiendo los registros propios de este cart.
Los registros que añade este cart son los siguientes:
D50Xh
donde X corresponde a 4bits cuya funcion es la siguiente
bit0 (LSB): cuando se escribe un 1, la EPROM del cartdridge es deshabilitada, cuando se escribe un 0 se vuelve a habilitar.
bit1: en 1 habilita el shift register (U7), en 0 lo deshabilita.
bit2: en 1 habilita la 'señal de actividad del video', esta señal puede ser leida como el bit7 de A000, 0 la deshabilita.
bit3(MSB): al poner este bit en 1 la señal RD4 del cartridge se pone en baja, al ponerlo en 0 se pone en alta.
Esta informacion fue obtenida mediante el analisis del esquematico y luego comprobada desensamblando y emulando la ROM.
La logica del cartucho solo se habilita tomando las lineas de direccion e ignora las datos, dentro de la ROM este registro activado haciendo lectura, y las unicas combinaciones que utiliza son 0xD503, 0xD505, y 0xD509
Paso 5: Formato en que se reciben los paquetes contenidos en el video
Partamos por la unidad mas pequeña, que en este caso es un paquete de 64 bytes:
00h: direccion que pude ser en los rangos (1 a 7Bh, A0h)
01h....3Eh: datos
3Fh: checksum
el checksum es simplemnte los 8 LSB de la sumatoria de los bytes desde 0 hasta 3Eh y una vez calculado el checksum se procede a negar cada uno de los 64 bytes de un paquete.
Luego se forman bloques que consisten en
3 paquetes con direccion A0h
123 paquetes (desde el 1 al 7Bh)
Los datos de estos paquetes se almacenan temporalemte en un buffer de la siguiente manera:
paquetes con direccion A0: se almacenan en 0xDC04
paquetes con direccion 1 a 7Bh: se almacenan en su buffer con la siguiente formula 0xE100+x*3Eh.
Paso 6: Formato de los datos dentro de los bloques
------
Este post esta en construccion, hasta el momento he desesamblado todo el cart, tambien lo he emulado por soft, pero falta mucho mas... por favor opinen y pregunten lo que estimen en los comentarios.