Haciendo un cartucho de autoarranque...

Avatar de Usuario
lechuck
Mensajes: 42
Registrado: 02 Sep 2021 22:42
Ubicación: Madrid
Agradecido : 53 veces
Agradecimiento recibido: 46 veces

Haciendo un cartucho de autoarranque...

Mensajepor lechuck » 15 Oct 2021 20:22

Hola a todos,

después de terminar de programar el juego de Space Invaders, me pareció que estaría bien conservarlo en un cartucho, al estilo de los cartuchos de Commodore. Imagino que, viendo el nivel que hay en este foro, esto es muy básico para muchos de vosotros, pero lo dejo aquí por si a alguien le resultara útil.

El proceso consiste, básicamente, en adaptar el código fuente del juego para que se ejecute en el bloque de memoria $A000 (es el bloque donde el Kernal busca los cartuchos de autoarranque), grabarlo en una EPROM y 'pinchar' esta EPROM en una PCB adecuada (puede ser una PCB de otro cartucho o una PCB nueva, como las que venden en TFW8B). En este caso voy a hacer un cartucho de 8kB, más que suficiente para mi juego. Pero el mismo proceso, con pequeñas modificaciones, sería válido, también, para juegos de 16 kB.

Comenzando por la adaptación del código fuente, aparte, lógicamente, de que se cargue en las posiciones de memoria adecuadas, hay que tener en cuenta un par de detalles:

- Si el juego incluye la definición de caracteres personalizados, deberéis almacenar esta definición en alguna parte del bloque $A000 (ya no los podréis poner directamente en su ubicación final porque tienen que quedar en alguna zona de la memoria interna del VIC y ahora el juego se va a ejecutar desde la memoria expandida). Yo necesitaba 1kB para los caracteres personalizados por lo que usé las últimas 4 páginas de ese bloque de memoria ($BC00-$BFFF). Lógicamente, al ejecutar el juego, estos caracteres deberéis moverlos al bloque que hayáis configurado en la posición 36869 (por ejemplo, comenzando en las posiciones de memoria 7168 ó 6144).

- Si tenéis alguna variable definida en el bloque del juego (que vaya a cambiar de valor durante la ejecución), tendréis que pasarla a alguna zona de la RAM (una vez en el cartucho, el juego estará en ROM y por tanto no podréis actualizar el valor de variables que no estén en RAM). En mi caso casi todas las variables estaban en páginza zero, pero había un par de estructuras de datos que tuve que mover a la zona de memoria RAM.

Una vez hayáis hecho estos cambios, tendréis que hacer las modificaciones necesarias para que el cartucho sea de autoarranque. Para ello hay que tener en cuenta que durante la secuencia de inicialización del Kernal, el sistema comprueba si hay memoria cargada en el bloque $A000 y, en caso afirmativo, comprueba si los bytes 5-9 ($A004-$A008) contienen la secuencia de bytes 65 48 195 194 205 (código ASCII de los caracteres "A0CBM", los tres últimos con el bit 7 a 1). En caso de encontrar esa secuencia, el kernal identifica el cartucho como de autoarranque y hace un JMP a la posición de memoria apuntada por $A000 y $A001 (en forma Low Byte / High Byte). De forma que sólo tendríamos que poner en esas posiciones ($A000 y $A001) la posición donde comienza el código de nuestro juego (puesto que necesitamos la cadena A0CBM en los bytes 5-9, esta posición de inicio podría ser $A009 (décimo byte del bloque $A000), por lo que pondríamos, como bytes iniciales de nuestro código, $09 $0A. También hay que tener en cuenta que cuando el kernal hace el JMP a la posición $A000/$A001, todavía no se ha completado su inicialización, por lo que, antes del código del juego, hay que incluir las siguientes instrucciones (son las que le faltan al kernal por ejecutar):

JSR $FD8D (RAM test)
JSR $FD52 (Set vectors)
JSR $FDF9 (Initialize I/O, CLI)
JSR $E518 (Initialize screen)

Si, además, vuestro juego utiliza alguna rutina de BASIC, también tendréis que ejecutar las rutinas que inicializan BASIC:
JSR $E45B (Initialize BASIC vectors)
JSR $E3A4 (Initialize BASIC RAM locations)

En el siguiente hilo de Denial podéis encontrar una interesante discusión sobre el tema (es de donde lo saqué yo :-) ):
http://sleepingelephant.com/ipw-web/bulletin/bb/viewtopic.php?f=2&t=10181

Y, por último, si queréis definir el vector de la rutina de interrupción NMI (lo que se ejecutará cuando presionéis la tecla Restore), la tenéis que poner en las posicions $A002 y $A003 (Lo lógico parecería poner aquí lo mismo que en $A000 y $A001, para que al apretar 'Restore' el juego simplemente se reiniciara, pero si lo hacemos así, estaríamos volviendo a inicializar parte del Kernal y, al menos a mi, se me quedaba el VIC colgado). Por eso, en estas posiciones puse el inicio 'real' del juego (la posición a continuación de las rutinas de inicialización del kernal). Por tanto, en mi caso, los dos primeros bytes del fichero del juego son $09 $A0 (posición donde comienzan las 4 rutinas de inicialización del Kernal) y los bytes 3-4 son $15 $A0 (posición donde comienza el código del juego).

Una vez que hayáis hecho todos estos cambios y tengáis el fichero .prg, podéis comprobar que el juego arranca correctamente, como un cartucho de autoarranque, ejecutándo xvic con:
xvic -cartA <path al fichero .prg>

El siguiente paso, una vez que comprobéis que el juego autoarranca y funciona correctamente, es grabarlo en una EPROM (recordad que al fichero .prg tenéis que borrarle los dos primeros bytes, que incluyen la posición de memoria donde se carga, por defecto, el .prg).

Para la EPROM, podéis utilizar una 27C64 que, de momento, no son difíciles de encontrar. En mi caso he utilizado una ST M27C64A, que se graba correctamente con mi grabador (un TL866II Plus).

Y, una vez que el fichero está grabado en la EPROM, ya 'solo' queda pincharlo en la PCB. En este último paso tenéis, al menos, dos opciones:

- Aprovechar algún cartucho original con un juego de 8 kB, que no os importe destripar (yo he probado con una placa del Mole Attack, que no me funcionaba). Puede parecer que abrir un cartucho es sencillo, pero no lo es. El siguiente hilo de este foro me vino muy bien para abrir los cartuchos sin romperlos:
http://retrowiki.es/viewtopic.php?f=12&t=671

Una vez abierto el cartucho, tendréis que desoldar la ROM existente y poner un zócalo en su lugar.
Imagen

En ese zócalo podréis conectar vuestra EPROM. Pero tendréis un pequeño problema. Las EPROM 2764 tienen 28 pines y las que había en los cartuchos de Commodore (al menos en los que yo he abierto) eran ROMs 2364, de 24 pines. Por tanto necesitaréis un adaptador. Este tema lo podéis encontrar discutido en el siguiente hilo de este foro:
http://retrowiki.es/viewtopic.php?f=12&t=200035126

Para mis pruebas, yo compré estos adaptadores:
https://www.ebay.es/itm/233778951283?hash=item366e4fb473:g:0v0AAOSwRCZfs~u7

El único problema de utilizar esta opción es que una vez montado el adaptador, y enchufada la EPROM, la altura resultante impide, no solo cerrar el cartucho, sino, incluso, enchufarlo en el VIC (incluso con el VIC sin el teclado):
Imagen

Por suerte, en mi Vicky Twenty no puse la placa metálica por encima del puerto de cartuchos y, al menos, pude comprobar que todo funcionaba...
Imagen

La otra opción (si no queréis destripar un cartucho original), es comprar PCBs nuevas. Por ejemplo, podéis utilizar éstas de TFW8B:
https://www.thefuturewas8bit.com/shop/cartridges-pcbs/vic-8k-16k-pcb.html

Con estas PCBs no necesitaréis el adaptador, ya que están preparadas para EPROMS de 28 pines. En estas PCBs veréis que hay una serie de jumpers que nos permiten indicar el tipo de EPROM, la memoria total, y en qué banco de memoria se cargará. En mi caso, con una EPROM 27c64 de 8KB, en el banco A000, los jumpers quedan:
Imagen
(Debajo del condensador, el jumper indica que es una EPROM de 8 kB)

Y, ya con la EPROM puesta:
Imagen

Ya solo queda probar que el juego autoarranca y funciona:
Imagen

En cuanto a la caja, podéis utilizar una original de Commodore (las PCBs de TFW8B encajan perfectamente en las cajas originales), o comprar una caja en la misma web de TFW8B. Yo he reutilizado la caja del Mole Attack, después de limpiarla y quitar la etiqueta original.
Imagen

Y, para que quede más aparente, podemos hacer una etiqueta similar a las originales:
Imagen

(He adjuntado un fichero .svg con esta etiqueta, por si la queréis reutilizar para otros juegos/aplicaciones)

Y la prueba final, con el cartucho cerrado y la etiqueta puesta:
Imagen

Bueno, pués eso es todo. Confío en que le resulte útil a alguien (disculpad si la explicación ha quedado algo liosa, al final resulta más sencillo hacerlo que describir el proceso).

Un saludo
Adjuntos
VIC20Cart.zip
(6.67 KiB) Descargado 70 veces

Avatar de Usuario
minter
Mensajes: 4826
Registrado: 22 Jul 2014 18:51
Agradecido : 6762 veces
Agradecimiento recibido: 2602 veces

Re: Haciendo un cartucho de autoarranque...

Mensajepor minter » 15 Oct 2021 23:03

Que ha quedado un Post la mar de bonito!!! -thumbup

Avatar de Usuario
ron
Mensajes: 21856
Registrado: 28 Oct 2010 14:20
Ubicación: retrocrypta
Agradecido : 3862 veces
Agradecimiento recibido: 4752 veces

Re: Haciendo un cartucho de autoarranque...

Mensajepor ron » 16 Oct 2021 00:22

Enhorabuena por el curro y por el post.
SALUDOS

Avatar de Usuario
Arturo
Mensajes: 132
Registrado: 13 Ene 2013 00:38
Agradecido : 7 veces
Agradecimiento recibido: 23 veces

Re: Haciendo un cartucho de autoarranque...

Mensajepor Arturo » 16 Oct 2021 00:46

No soy usuario de VIC-20 pero aun asi me ha resultado muy interesante.


Volver a “Commodore Vic20”

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 3 invitados