Atariware Wiki: Programar Cartuchos

https://www.atariware.cl/wiki     Versión: 71 (20/01/2026 20:38)

Programar Cartuchos


1. Introducción


Aquí explicaremos de forma fácil cómo programar los cartuchos más comunes para nuestros Atari de 8 bits; partiremos de los más estándar a algunos un poco más complejos.

También es necesario saber ensamblador y conocer un poco del equipo a nivel de Hardware.

Cabe señalar que existieron cartuchos más pequeños de tamaño 2 Kb y 4 Kb en los primeros programas y juegos comerciales, pero nos enfocaremos en los más comunes.

2. Herramientas


Como ensamblador usaremos Mads por su actualización continua y por algunas macros propias que te ahorran líneas de código cuando necesitas instrucciones de ensamblador lda/sta; para editor, dejamos que los usuarios seleccionen el que les sea más cómodo, pero tenemos guías para Notepad++ y VS Code.

También recomendamos leer ciertos libros como Atari Root y el Mapeando el Atari versión actualizada del The Mapping ATARI.

3. Cartucho de 8 Kb


Partiremos con el más común de todos, el de 8 kb; esto quiere decir que la información se podrá acceder en el rango de las posiciones de memoria de $A000 al $BFFF, o sea, vamos a tener 8.192 bytes para nuestros programas. Es importante destacar que esto es de lectura; no podemos cambiar algún valor en este rango en tiempo de ejecución.

Ahora un ejemplo simple y explicaremos más abajo ciertos detalles importantes a tener en cuenta.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
    opt f+h-

    org $A000

dlist
    .by $70,$70,$70,$70,$70,$70,$70,$47
    .wo screen
    .by $7,$70,$6,$41

screen
    .sb "     cartridge      "
    .sb "       8 KB         "
    .sb "  WWW.ATARIWARE.CL  "*

start
    mwa #dlist $230
    jmp *

end 
    rts

    org $BFFA
    .wo start
    .by 0,4
    .wo end

Para generar el archivo ROM, se hace con la siguiente instrucción desde la consola, que es lo más básico :
mads cart_8kb.asm -o:cart_8kb.rom	


Ahora explicaremos las líneas importantes:


El ensamblador usado tiene algunas macros propias para ahorrar tiempo y que sea menos largo el código ensamblador, por ejemplo, la instrucción mwa usada en la línea 16.

Al generar el archivo, el ensamblador lo convierte a las típicas instrucciones:

lda #$00
sta $230
lda #$A0
sta $231


Ahora, lo último a tener en cuenta: como anteriormente se dijo, no vamos a tener acceso a modificar ningún valor desde el rango $A000 hasta $BFFF, ya que esto es ROM. Entonces, si necesitamos cambiar un diseño de pantalla o datos de los bytes, deberá usar la RAM; se recomienda usar el rango $1000 al $9FFF cuando sea para un cartucho de 8 kb y su Atari sea 64 kb de RAM.

Un ejemplo: si necesito definir una pantalla y cambiar una línea de tamaño gráfico, lo normal sería que el diseño esté en la ROM y copiemos los bytes a una nueva posición de memoria en la RAM, hagamos la modificación y, por último, actualicemos la pantalla usando la nueva dirección.

¿Cómo sería en ensamblador aplicando lo descrito anteriormente?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
SDLSTL = $230
CONSOL = $D01F

    opt f+h-

    org $A000

dlist
    .by $70,$70,$70,$70,$70,$70,$70,$47
    .wo screen
    .by $7,$70,$6,$41

screen
    .sb "     cartridge      "
    .sb "       8 KB         "
    .sb "  WWW.ATARIWARE.CL  "*

start
    ldx #0
copy_dlist
    lda dlist,x
    sta $1000,x
    inx 
    cpx #$E
    bne copy_dlist
    mwa #$1000 SDLSTL

key
    lda CONSOL
    cmp #6
    beq key_start
    cmp #5
    beq key_select
    jmp key
key_start
    lda #7
    sta $100C
    jmp key
key_select
    lda #6
    sta $100C
    jmp key

end 
    rts

    org $BFFA
    .wo start
    .by 0,4
    .wo end

Explicaremos lo que agregamos para cambiar una línea de la lista de despliegue :


Con esto concluimos con el tema importante de cómo colocar algunas cosas en la memoria RAM para poder manipularlas después en nuestro programa que se está ejecutando como un cartucho.

4. Cartucho de 16 Kb


Continuamos con el segundo tipo de cartucho de 16kb, esto quiere decir que la información se podrá acceder en el rango de las posiciones de memoria de $8000 al $BFFF, o sea, vamos a tener 16.384 bytes para nuestros programas.

Ahora vamos con el ejemplo; algunas cosas no se explicarán, ya que se aplica lo mismo que se usa en el cartucho de 8 kb.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
SDLSTL = $230

    opt f+h-

    org $8000

dlist
    .by $70,$70,$70,$70,$70,$70,$70,$47
    .wo screen
    .by $7,$70,$6,$41

screen
    .sb "     cartridge      "
    .sb "       16 KB        "
    .sb "  WWW.ATARIWARE.CL  "*

start
    mwa #dlist SDLSTL
    jmp *

end 
    rts

    org $BFFA
    .wo start
    .by 0,4
    .wo end


Esta vez no hay mucho que explicar, ya que todo es igual que el cartucho anterior, solo que ahora la posición inicial cambió a $8000, que es la línea 5.

Solo mencionaremos que estos dos tipos de cartuchos de 8 Kb y 16 Kb son los que maneja el hardware de Atari. Ahora te preguntarás qué pasa con los 32 Kb, 64 Kb, etc. En resumen, debes respetar el mismo formato de 8 kb o 16 kb, solo que usarán bancos de memoria que se irán cambiando para extraer la información y colocarla en la RAM.

5. Cartucho XEGS de 32 Kb


Este sería el tercer tipo más famoso y último que hizo Atari para su familia XL/XE. Como adelantamos, posee bancos de memoria que debes ir cambiando para ir leyendo su contenido. Explicaremos la más pequeña, que es de 32 Kb. Esta posee 4 bancos de memoria de 8 kb, o sea, 8.192 bytes por banco, pero uno de sus bancos es fijo, el cual inicia el cartucho.





La imagen es una ilustración de cómo es la estructura de este formato de cartucho. También se puede aplicar a sus versiones de más memoria de 64 Kb a 1MB; la única diferencia es que aumentan los bancos de memoria disponibles.

Después de la explicación de la estructura, partiremos con el primer ejemplo, el cual está enfocado solo en aprender cómo desde el banco principal hacemos el cambio de los otros bancos en el rango $A000 al $BFFF. Para ello, en cada banco colocaremos un mensaje para saber qué banco se leyó y mostrarlo en pantalla.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
FLPTR  = $FC
CDTMF4 = $22C
COLOR2 = $2C6
CONSOL = $D01F

CPUTREC = $9
ICCOM   = $342
ICBAL   = $344
ICBAH   = $345
ICBLL   = $348
ICBLH   = $349
CIOV    = $E456
SETVBV  = $E45C

    opt h-
    org $8000

    dta c'Leyendo banco 0',$FD,$9B
:8175    .byte $FF

    org $8000

    dta c'Leyendo banco 1',$FD,$9B
:8175    .byte $FF

    org $8000

    dta c'Leyendo banco 2',$FD,$9B
:8175    .byte $FF

    opt f+
    org $A000

start_cart
    lda #0
    sta FLPTR
    sta FLPTR+1
    sta COLOR2
    jsr print
    lda #1
    sta FLPTR+1
read_consol    
    lda CONSOL
    cmp #6
    bne no_consol
    lda FLPTR
    cmp #3
    bne next_bank
    lda #0
    sta FLPTR
next_bank
    inc FLPTR    
    sta $D500
    jsr print
    lda $800E
    rol
    sta COLOR2    
no_consol
    jsr wait
    jmp read_consol

wait
    ldx #0
    ldy #5
    lda #$FF
    sta CDTMF4
    lda #4
    jsr SETVBV
loop
    lda CDTMF4
    bne loop
    rts

print
    ldx #0
    mva #CPUTREC ICCOM,x
    lda FLPTR+1
    cmp #0
    bne print_cart
    mwa #text ICBAL,x
    jmp print_exit
print_cart
    mwa #$8000 ICBAL,x
print_exit
    mwa #$A0 ICBLL,x
    jsr CIOV
    rts    

text
    dta c'presiona ',' START '*,' para ir leyendo los      bancos de memoria del cartucho'
    dta $7F,$7F,$7F,$7F,c'XEGS 32 KB',$7F,$7F,$7F,$7F
    dta c'     www.atariware.cl',$1D,$9B

end_cart
    rts    

    org $BFFA
    .word start_cart
    .by $0,$4
    .word end_cart


Ahora lo explicamos:










Como segundo ejercicio, explicaremos cómo pasar un archivo binario de un juego a nuestro cartucho de 32 KB. Esto tiene unas limitantes por el tipo de cartucho que estamos usando; la más importante es que el juego debe estar entre las zonas de memoria $1000 A $7FFF; es porque el cartucho desde $8000 al $BFFF está activo como ROM.

Tomaremos un clásico juego llamado GORF y lo analizaremos; si es candidato, para ello usaremos el mismo emulador Altirra para activar la consola y arrastrar el juego gorf.xex al emulador.


Si ves la consola, te mostrará los segmentos de memoria que usa al cargar este juego; por lo que se ve, es un segmento largo y continuo de memoria, $2000 al $48E3; entonces usaremos como un banco y un cuarto. También nos indica dónde se inicia el juego con el segmento $02E2 y $02E3, el cual tiene dos bytes, que sería $48D3, que es lo que nos importa.

Ahora viene el proceso de cómo sacar el segmento principal del juego que nos interesa, que sería el del $2000 al $48E3. Usamos la herramienta DIS6502, ya sea su versión antigua o la más nueva; en ambos es lo mismo.


Seleccionamos el segmento y vamos a guardar sin cabecera; con esto dejamos el segmento limpio sin la cabecera de los archivos .xex. Con este paso tenemos el segmento total.

Usaremos otra herramienta llamada HxD que es un editor hexadecimal que nos ayudará a cortar una parte de 8 Kb y otra más pequeña de 2275 bytes. Una vez listos y guardados los archivos, dejaré un zip con los archivos, el ejecutable, segmento total, segmento parte 1 y, por último, segmento parte 2. Ahora pasaremos al ejemplo.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
FLPTR  = $FC

    org $80
mem_orig .ds 2
mem_dest .ds 2

    opt h-
    org $8000
    ins 'gorf_part1.bin'

    org $8000
    ins 'gorf_part2.bin'
:5916    .byte $FF

    org $8000
:8192    .byte $FF

    opt f+
    org $A000

start_cart
    lda #0
    sta $D500
    mwa #$8000 mem_orig
    mwa #$2000 mem_dest
    lda #32
    sta FLPTR
    jsr copy8kb

    lda #1
    sta $D500
    mwa #$8000 mem_orig
    mwa #$4000 mem_dest    
    lda #9
    sta FLPTR
    jsr copy8kb

    jmp $48D3

copy8kb
    lda FLPTR
    tax
    ldy #0
copy_loop
    lda (mem_orig),y
    sta (mem_dest),y
    iny
    bne copy_loop    
    inc mem_orig+1    
    inc mem_dest+1    
    dex        
    bne copy_loop    
    rts

end_cart
    rts    

    org $BFFA
    .word start_cart
    .by $0,$4
    .word end_cart


Ahora lo explicamos:








6. Conclusiones


Como se vio, hemos mostrado cómo programar los diferentes cartuchos que ATARI vendía para su línea de 8 bits; siempre el movimiento de memoria entre el cartucho ROM y la RAM puede ser 8 Kb o 16 Kb, ya que el hardware fue diseñado así. Otra cosa, existe un cartucho conmutado XEGS, pero no estoy seguro si fue algo ideado por ATARI o idea de un tercero; por el momento no se explicará por ese motivo.

Bueno, se pueden hacer cosas entretenidas hoy en día. Si te estás preguntando por la parte electrónica, hay varios diseños para estos cartuchos en PCBWay en la sección proyectos que puedes mandar hacer y armar tu propio cartucho real.