El
firmware.
En el esquema podemos ver,
en el conector grande; que a parte de los 12 voltios para la
alimentación del amplificador de sonido y de los 5 voltios para la
alimentación de los circuitos digitales, tenemos varias señales que
van directamente al microcontrolador:
- P1.3 perteneciente al puerto 1.
- P2.4 a P2.7 pertenecientes al puerto 2.
-
INT. Que es la señal de interrupción del microcontrolador y que es activa a nivel bajo.
-
RESET. También activa a nivel bajo que es el reset del microcontrolador.
Como, a pesar de pasar unos
treinta años desde la última vez que programé un micro de la
familia MCS48 de Intel, mi memoria funciona bien... y siendo sincero,
el manual de los MCS48 ayuda mucho; sabemos que el vector de arranque
de este microcontrolador se sitúa en la posición 0x0000; que el
vector de interrupción está en la posición 0x0003 y que en la
posición 0x0007 está el vector de la interrupción del temporizador
(este vector no se utiliza en este firmware).
;; 0x0000 vector de arranque.
0000 04 9B JMP 009BH ; salto a 0x009B
0002 00 NOP
;; 0x0003 vector de interrupción.
0003 E5 SEL MB0 ; MBF = 0. Selecciona banco 0 de memoria.
0004 04 0B JMP 000BH ; Salta a 0x000B
0006 04 9B JMP 009BH ; Salta a 0x009B
0008 00 NOP
0009 04 9B JMP 009BH
;; viene de vector de interrupción.
000B 99 F7 ANL P1,#F7H
000D 8A F0 ORL P2,#F0H ; Configura P2.4 a P2.7 como entradas.
000F 0A IN A,P2 ; Lee valor de P2
0010 53 F0 ANL A,#F0H ; Descarta P2.0 a P2.3, usados en direccionamiento.
; se queda con bits P2.4 a P2.7
0012 47 SWAP A ; Intercambio de nibbles. P2.4 a P2.7 pasa a bits bajos.
0013 A8 MOV R0,A ; Almacena valor en R0
0014 B9 08 MOV R1,#08H ; R1 = 0x08
0016 23 1F MOV A,#1FH ; A = 0x1F
0018 A1 MOV @R1,A ; [ R1 = 0x08 ] = 0x1F. Posición 8 memoria = 0x1F
0019 19 INC R1 ; R1 = 0x09
001A 27 CLR A ; A = 0
001B A1 MOV @R1,A ; [ R1 = 0x09 ] = 0x00. Posición 9 memoria = 0x00
001C 17 INC A ; A = 1
001D D7 MOV PSW,A ; PWS = A = 1 ¡¡¡ OJO !!!
001E 93 RETR ; NO RETORNA. CONTINUA PERO LIMPIA FLAG DE LA INTERRUPCION.
; Qué cabroncete, casi se me pasa esto. :-)
;; saltos según valor leído en P2.4 a P2.7
001F E5 SEL MB0 ; MBF = 0. Selecciona banco 0 de memoria.
0020 F8 MOV A,R0 ; A = R0 = Valor leído de P2.
0021 C6 9B JZ 009BH ; Si = 0x00, salta a 0x009B
0023 23 0F MOV A,#0FH ;
0025 D8 XRL A,R0 ;
0026 C6 98 JZ 0098H ; Si = 0x0F, salta a 0x0098
0028 23 0E MOV A,#0EH ;
002A D8 XRL A,R0 ;
002B C6 96 JZ 0096H ; Si = 0x0E, salta a 0x0096
002D 23 0D MOV A,#0DH ;
002F D8 XRL A,R0 ;
0030 C6 92 JZ 0092H ; Si = 0x0D, salta a 0x0092
0032 23 0C MOV A,#0CH ;
0034 D8 XRL A,R0 ;
0035 C6 8D JZ 008DH ; Si = 0x0C, salta a 0x008D
0037 23 01 MOV A,#01H ;
0039 D8 XRL A,R0 ;
003A C6 70 JZ 0070H ; Si = 0x01, salta a 0x0070
003C 23 02 MOV A,#02H ;
003E D8 XRL A,R0 ;
003F C6 72 JZ 0072H ; Si = 0x02, salta a 0x0072
0041 23 03 MOV A,#03H ;
0043 D8 XRL A,R0 ;
0044 C6 75 JZ 0075H ; Si = 0x03, salta a 0x0075
0046 23 04 MOV A,#04H ;
0048 D8 XRL A,R0 ;
0049 C6 78 JZ 0078H ; Si = 0x04, salta a 0x0078
004B 23 05 MOV A,#05H ;
004D D8 XRL A,R0 ;
004E C6 7A JZ 007AH ; Si = 0x05, salta a 0x007A
0050 23 06 MOV A,#06H ;
0052 D8 XRL A,R0 ;
0053 C6 7D JZ 007DH ; Si = 0x06, salta a 0x007D
0055 23 07 MOV A,#07H ;
0057 D8 XRL A,R0 ;
0058 C6 81 JZ 0081H ; Si = 0x07, salta a 0x0081
005A 23 08 MOV A,#08H ;
005C D8 XRL A,R0 ;
005D C6 83 JZ 0083H ; Si = 0x08, salta a 0x0083
005F 23 09 MOV A,#09H ;
0061 D8 XRL A,R0 ;
0062 C6 85 JZ 0085H ; Si = 0x09, salta a 0x0085
0064 23 0A MOV A,#0AH ;
0066 D8 XRL A,R0 ;
0067 C6 87 JZ 0087H ; Si = 0x0A, salta a 0x0087
0069 23 0B MOV A,#0BH ;
006B D8 XRL A,R0 ;
006C C6 89 JZ 0089H ; Si = 0x0B, salta a 0x0089
|
En un principio me he
centrado en estudiar la parte correspondiente al vector de
interrupción ya que esta señal está disponible en el conector, y
si está ahí, será por algo.
Vemos que en cuanto se
activa la señal INT (a nivel bajo) se selecciona el banco de memoria
0 y entonces el programa salta a la posición 0x000B. A partir de ahí,
se lee el valor presente en el puerto 2, justo el valor presente en
2.4 a 2.7 y entonces el programa salta a distintos puntos del
firmware en función del valor leído en esos pines.
Supuse que activando la
señal INT (a nivel bajo) mientras ponemos un valor en los pines 2.4
a 2.7 quizá consiguiese reproducir distintos sonidos.
El resto del programa,
aunque lo he revisado por partes, no he podido dedicarle demasiado
tiempo; así que a día de hoy, aún no se para que se utiliza la
señal P1.3 ni la señal correspondiente al puente en la placa
marcada como "RECLAMO".
Si nos fijamos en el
esquema, vemos que el pin de dirección A11 de la memoria eprom se
encuentra conectado directamente a 5 voltios. Así que cuando el
microcontrolador direcciona el vector de arranque en la posición
0x0000, en realidad se corresponde con la posición 0x0800 de la
eprom. El microcontrolador nunca llega a acceder al contenido de la
eprom situado en la posición 0x0000 hasta la posición 0x07FF. Lo
curioso es que el contenido entre 0x0000 y 0x07FF es exactamente el
mismo que el que se encuentra en 0x0800 en adelante, cambiando
únicamente los valores de las instrucciones JMP, CALL y resto de
instrucciones de salto y los accesos a valores en la memoria de
programa. Es decir, el firmware está grabado por duplicado en la
eprom.
Empezando con las pruebas.
Para poder hacer pruebas,
preparé un pequeño circuito en placa de prototipos.
Adaptador para pruebas. Esquema. |
A través de este adaptador
se alimenta el amplificador a partir de una fuente exterior de 12
voltios al tiempo que obtenemos una tensión regulada de 5 voltios
para los circuitos digitales.
Cuenta también con varios
puentes con los que variar los valores en los pines P2.4 a P2.7,
poder activar la señal INT y el RESET si es necesario.
Adaptador para pruebas. |
No es necesario el uso de
resistencias en los pines P2.4 a P2.7 ni en la línea de RESET ya que
el microcontrolador cuenta con pull-up's internos. Únicamente es
necesario instalar un pull-up en la línea INT. Y según el manual de
la familia MCS48 un condensador de 1uF en la línea de RESET es
suficiente para que arranque sin problemas.
Variando los puentes de las
señales P2.4 a P2.7 y activando a continuación la señal INT pueden
escucharse los distintos sonidos de la máquina, entre ellos la
famosa canción de los "pajaritos".
Algunos sonidos se
reproducen y paran por si mismos, otros continúan indefinidamente
siendo necesario fijar el valor 0x0 en los puentes y activar a
continuación la señal INT para parar el sonido.
Video.
Me apetecía grabar un video
de la placa reproduciendo los distintos sonidos, pero hacerlo
variando los puentes a mano y activando la señal INT cada vez, era
algo tedioso. Así que para "automatizar" el proceso,
utilicé una placa de Arduino con un pequeño programa (o sketch,
como le llaman ahora) que se encargó de secuenciar los distintos
valores en los pines P2.4 a P2.7 y de activar la señal INT dejándome
la manos libres para sujetar la cámara.
Preparación para el video. |
Conclusión.
Después de tantos años sin
tocar este circuito, ha tenido su gracia, por una parte recordar los
viejos tiempos en que pasaba horas y horas aprendiendo sobre
electrónica y microcontroladores tratando de descifrar el
funcionamiento de placas de este tipo y programando los
microcontroladores de la familia MCS48 y también los de la familia
MCS51 que ya andaban por el mercado (y los Z80, y todo lo que cayera
en mis manos); y por otra parte recordar los tiempos, en que siendo
más joven aún, acompañaba a mi abuelo a tomar "la pinta de
vino" al bar (yo coca-cola, por supuesto) y de fondo llegaba la
musiquita de los "pajaritos" llamando a aquellos que
tuviesen alguna moneda de 25 pesetas que meter por la ranura.
Quizá algún día continúe
hasta saber cuál es la función del pin P1.3 y el puente "RECLAMO"
de la placa, pero de momento, la cosa llega hasta aquí.
Si estás interesado en los
ficheros del firmware, o en los esquemas puedes encontrarlos en el
siguiente enlace de github en distintos formatos (kicad, pdf y jpg).
0 comentarios:
Publicar un comentario