Continuamos este estudio comparativo del 6502 vs el 6510 en este caso descubriendo la principal diferencia entre el 6510 y el 6502 los pines de Input/Output que posee el 6510 y no posee el 6502.
Les dejo el link al articulo anterior en la serie, y al final como siempre los links a todos los artículos de la misma.
Parte 4 – Primer Programa desde EEPROM
Qué son los I/O Ports
La I/O ports son 6 puertos/pines/registros que pueden funcionar como Input o como Output en el procesador 6510.
P0 a P5 Pines de I/O Port. Este procesador en su más marcada diferencia presenta en estos pines 6 conexiones bidireccionales con periféricos como si fuera un pequeño 6522 VIA o un 6526 CIA.
Cómo se utilizan
Para poder utilizarlos se debe especificar si los vamos a usar como Input o Output. Esto se hace de una forma muy particular. El procesador 6510 a diferencia de todo el resto de la línea 6500 utiliza para sí dos direcciones de memoria que nunca pueden ser parte de la RAM o ROM y son las primeras dos direcciones la $0000 y la $0001.
La dirección $0000 es llamado DATA DIRECTION Register. En este vamos a especificar para cada uno de los seis pines si lo queremos utilizar como Input o como Output. Si el valor es 0 queda como Input y si es 1 queda como output. Si lo vamos utilizar como Input conectarlo con una resistencia a 0 Volts o +5 Volts mientras no se utilice para no tener inputs flotando. Esta especificación se realiza escribiendo un byte a la dirección $0000.
Bit | Pin | Input/Output |
0 | 0 | 0/1 |
1 | 1 | 0/1 |
2 | 2 | 0/1 |
3 | 3 | 0/1 |
4 | 4 | 0/1 |
5 | 5 | 0/1 |
6 | No Utilizado | No Utilizado |
7 | No Utilizado | No Utilizado |
Por ejemplo si quisiéramos habilitar el pin 2 y el 4 como Output y el resto como Inputs deberíamos escribir el número binario %00010100 correspondiente al hexadecimal $18. Podríamos configurar al 6510 con la siguiente instrucción en assembler
lda #%00010100 ; cargamos al acumulador el número en binario
; antecedido por % para indicar que está em binário
; y # para indicar que es un número y no una posición
; de memoria
sta $00 ;guardamos el contenido del acumulador en el
;registro interno de memoria DATA DIRECTION REGISTER
Si ahora queremos leer la información de los I/O registers necesitamos utilizar otra dirección de memoria la $0001 también llamado de I/O port register.
Bit | Pin | Input/Output |
0 | 0 | 0/1 |
1 | 1 | 0/1 |
2 | 2 | 0/1 |
3 | 3 | 0/1 |
4 | 4 | 0/1 |
5 | 5 | 0/1 |
6 | No Utilizado | No Utilizado |
7 | No Utilizado | No Utilizado |
Podemos cargar los valores de este registro al acumulador con el siguiente comando para leer por ejemplo:
Lda $01 ; lee el I/O port register
Sta $0400 ; escribe el contenido del acumulador en la posición
; de memoria $0400
Para poder escribir en este registro y por consecuencia cambiar el valor de los pines con valor 1 a +5 Volts o High usamos el siguiente programa assembler.
lda #%00111111 ;va a escribir todos los bits del I/O port para que
;sus pines sean +5 Volts
sta $01 ;escribir el registro
Cómo funciona en la Commodore 64
La Commodore 64 y su procesador 6510 pueden direccionar hasta 65536 direcciones de memoria, los famosos 64KB, pero ¿cuántos kb tenemos en la Commodore?
Kbytes | Función |
64 | RAM |
8 | BASIC ROM |
8 | KERNAL ROM |
4 | Character Generator |
4 | I/O (Vic II, SID, CIA 1 y 2, Puerto de Cartucho) |
Esto nos da 64+8+8+4+4 = 88Kb para direccionar, lo cual es un problema ya que tendríamos 24Kb que no podrían ser direccionados, ahí entran los I/O Ports para ayudarnos.
Estos cumplen dos funciones: manejar parte del datasette y direccionar esta memoria extra para que puedan caber las 65536 direcciones.
Los puertos en cuanto a su configuración de Input o Output así se encuentran configurados en la Commodore.
Bit | Pin | Input/Output | Nombre en C64 |
0 | 0 | 1 output | LORAM |
1 | 1 | 1 output | HIRAM |
2 | 2 | 1 output | CHAREN |
3 | 3 | 1 output | Cassette Write |
4 | 4 | 0 input | Cassette Sense |
5 | 5 | 1 output | Cassette Motor |
6 | No Utilizado | No Utilizado | No Utilizado |
7 | No Utilizado | No Utilizado | No Utilizado |
Manejo de Memoria
Memorias que se superponen, como vimos anteriormente veamos cómo es que estas memorias se están superponiendo y en qué direcciones.
Nombre | Direcciones | Kbytes | Función 1 | Función 2 | Función 3 |
Low Memory | $0000-$9FFF | 40kb | RAM | ||
BASIC | $A000-$BFFF | 8kb | RAM | BASIC ROM | |
High Memory | $C000-$CFFF | 4kb | RAM | ||
I/O | $D000-$DFFF | 4kb | RAM | I/O | CHAR ROM |
KERNAL | $E000-$FFFF | 8kb | RAM | KERNAL ROM |
Como se superponen estas memorias se controla principalmente con los I/O ports de P0 a P2.
P0 – Bit 0 del registro $0001, LOW RAM. Si este bit es 0 tenemos acceso a la RAM si es 1 a la BASIC ROM. ¿Cuándo lo apago? ,cuando creo un programa en código máquina con lo que aprovecho 8kb extras de ram.
P1 – Bit 1 del registro $0001, HIGH RAM. Si este bit es 0 tenemos acceso a la RAM si es 1 al KERNAL ROM. ¿Cuándo lo apago? ,cuando creo un programa en código máquina y no necesito ninguna rutina del KERNAL con lo que aprovecho 8kb extras de ram
P2 – Bit 2 del registro $0001, LOW RAM. Si este bit es 0 tenemos acceso a los I/O devices (VIC II, SID, CIA, etc) si es 1 a la ROM de character generation donde se almacenan los 2 juegos de caracteres de la commodore. Generalmente nunca debemos acceder a la ROM del CHAR GEN ya que el VIC II puede acceder a esta directamente para dibujar los caracteres en pantalla. Un motivo válido para acceder es leerla para copiarla en memoria y modificar el juego de caracteres.
Aquí tenemos otro gráfico que muestra mejor la configuración de los 3 registros y que efectos tendrían en memoria.
A continuación les incluyo un programa en BASIC que les va a permitir apagar momentáneamente el basic y el kernel escribir y leer en la RAM oculta y volver a activar el basic y el kernel sacado del libro PEEKS & POKES para Commodore 64.
Para leer la RAM escondida usar:
PRINT USR(ADDRESS).
Para escribir haciendo un POKE usar:
SYS 715,ADDRESS,BYTE
Y este es el programa en código máquina con su loader en basic:
10 DATA 165,20,72,165,21,72,32,247,183,120,165,141,252,133
20 DATA 1,160,0,177,20,168,165,1,9,3,133,1,88,104,133,21
30 DATA 104,133,20,76,162,179,32,253,174,32,138,173,32,247
40 DATA 183,32,253,174,32,158,183,165,1,41,252,133,1,138
50 DATA 160,0,145,20,165,1,9,3,133,1,96
60 FOR 1=678 TO 747: READ A: POKE I, A: NEXT I
70 POKE 785,166:POKE 786,2
Manejo de Datasette
El datasette es manejado por 3 puertos del 6510 y la CIA. Los I/O Ports P3 a P5 están conectados a las funciones de CASSETTE Write, CASSETTE Sense, y CASSETTE Motor.
P3 – Bit 3 del registro $0001, Cassette Write. Este puerto es el que se utiliza cuando vamos a grabar información al cassette enviando pulsos con la información a grabar a través de este pin.
P4 – Bit 4 del registro $0001, Cassette Sense. Este puerto mide si alguna tecla fue presionada en el datasette. Cuando vemos el famoso mensaje “PRESS PLAY ON TAPE” el procesador está esperando que presionemos la tecla play en el datasette. Al presionar esta tecla y como el puerto es un input se lee un 0 Volts y el datasette sabe que una tecla fue presionada. Como podemos presionar 3 teclas en el datasette (play, rewind, forward) y sólo tenemos una línea de Casette Sense se produce el efecto curioso de que si presionamos rewind o forward la Commodore piensa que presionamos play y trata de cargar el programa de casette.
P5 – Bit 5 del registro $0001, Cassette Motor. Este puerto activa el motor del datasette cuando se presiona una tecla en el datasette, si alguna vez hicieron la prueba de presionar el botón de play y nada funciona si no está conectado a la Commodore no es sólo por una falta de power sino por que la tecla play no hace nada sólo el pin P5 activa el motor del datasette.
Si estudiamos el circuito exacto conectado a este puerto vemos que en realidad el procesador no prende el motor si no que activa un transistor que switchea 9 Volts para que estos sí vayan al conector del datasette y alimenten el motor
Para completar la discusión del datasette nos falta sólo el puerto de cassette read pero este está conectado al puerto /flag de la CIA1 y está fuera del contexto de los puerto I/O del 6510 y será analizado en un próximo artículo.
Estudiando los I/O Ports visualmente
Para poder estudiar visualmente cómo se conectan y funcionan los I/O ports del 6510 les dejo este video que complementa al artículo.
6502 vs 6510 IO Ports / Processor Ports – Parte 5
Artículos en la serie C64 a Fondo
A continuación les dejo los links a los artículos anteriores de la serie
Parte 3 – Codeando a Mano la Primera Instrucción de Código Máquina
Parte 4 – Primer Programa desde EEPROM
Referencias
A continuación les dejo algunos links donde profundizar el tema:
VIDEOS
Video de la serie 6502 vs 6510 Parte 5 – IO Ports / Processor Ports
6502 vs 6510 IO Ports / Processor Ports – Parte 5
Aquí tiene acceso a toda la serie:
6502 vs 6510 estudio detallado y comparación
PAPERS
The 6510 Processor Port | C64 OS
Y como siempre la serie de Ben Eater del 6502
Build a 6502 computer | Ben Eater
Todos los ejemplos de código de los videos los pueden encontrar en: