Motorola M6800
Introducción a la programación con procesador Motorola M6800
Resolución del algoritmo para calular la letra del DNI
Explicación y descarga del simulador SIM6800 (descarga)
manuales varios(Documentación (en castellano), Set de instrucciones, libro (1975))
INTRODUCCIÓN
El microprocesador de motorola m6800 (año 1974), se sabe que este micro es de 8 bit y tenemos dos acumuladores que son AA y AB, además de un puntero X (registro índice) que hace las veces de
contador para los bucles, PC que es el contador de programa, SP, que es el puntero a pila y por supuesto el registro de estados, llamado CCR, donde podemos ver el estado de los flags (carry,cero...).
En el lenguaje ensamblador para este micro debemos saber también que no existen las etiquetas, asi que a la hora de hacer saltos debemos calcular a mano, contando de cuanto va a ser el salto
además todo, tanto como el código de programa, así como las variables que almacenamos , va todo en memoria y de forma hexadecimal.
Para simular el entorno de este micro he utilizado el simulador SIMM6800, el cual lo he probado en Windows XP, vista y Windows 7 sin resultados por problema de compatibilidad, así
que para utilizarlo he tenido que instalar DOSBox, el cual se puede utilizar tanto en Windows como en Linux, para instalarlo en Linux apt-get install dosbox, aunque lo podemos descargar de la pagina oficial:
Una vez explique como instalar el emulador y configurarlo procederé a explicar el algoritmo para la resolución del calculo de la letra del DNI
CONFIGURACION DE DOSBOX
Dosbox es un emulador de ms-dos. La primera vez que se ejecuta nos muestra que estamos en
la unidad Z:, la cual tiene los archivos principales del sistema, ahora bien, si lo que queremos es ejecutar una aplicación ya instalada en nuestro sistema, primero
debemos montar la unidad:
por ejemplo si queremos montar la unidad c: debemos poner:
mount c c:\
Así cuando ahora en la línea de comandos pongamos c: accederemos a nuestro disco duro
Esto hay que hacerlo cada vez que inicialice el programa, para solventarlo debemos editar el archivo de configuración de dosbox, en mi caso lo he hecho en Linux, para ello hay que editar
El archivo /home/user/.dosbox/dosbox-0.74.conf
Dentro buscamos la línea keyboardlayout y cambiamos auto por es, para que este en español, ya que a mí en auto no me lo pone por defecto
Después ya al final del archivo encontramos la línea [autoexec] ponemos debajo algo como esto:
mount e /home/puma/micros/
E:
Ahora guardamos los cambios, y cada vez que inicie dosbox, accederá a la letra e: automáticamente, donde e: accede automáticamente a la ruta home/puma/micros/
que es donde tengo el simulador.
Solo hace falta ya ejecutar nuestro simulador con la orden sim.exe
Para poder subir la velocidad de ciclos en el emulador de Dosbox con cntrl+F11 y cntrl+F12
Explicación de Simulador:
Nada mas empezar nos sale esta pantalla:

-Change execution Format: podemos ejecutar paso a paso (per cycle) o de forma continua (continuous), para volver a mput control damos a mpu control
-Change registers: nos manda a la parte de abajo, deberemos antes de empezar la ejecución del programa poner a 0 los registros AA y AB y X, SP, y PC, para volver a mpu control
le damos a la tecla ESC (más adelante incluiremos las instrucciones necesarias en el código para ponerlos automáticamente a cero)
-Run: Nos lleva a Run Control que es donde le podemos dar a Proceded, para empezar a ejecutar el progama, o le podemos dar a stop para pararlo
-Restart: Reinicia todo, es aconsejable darle siempre antes de empezar a ejecutar
-Edit Memory: Parte fundamental ya que nos va a llevar a la edición de la memora, donde vamos a ordenar en diversas posiciones, tanto el codigo del programa, como la información a la
que necesitamos acceder desde éste.
Cuando salimos del simulador con Exit Simulator, nos deja guardados los cambios en la memoria en un archivo llamado SIM.RAM, dentro del mismo directorio de ejecución.
Estrategia de cálculo
Puesto que este micro carece de divisiones y multiplicaciones, debemos hacer para el caso de las multiplicaciones sumas sucesivas, con ayuda del acarreo, y en el caso de las divisiones, restas
sucesivas con acarreo, todo esto en forma de bucles y saltos para poder repetir las veces que necesitemos:
Para explicar el algoritmo de calculo de la letra del dni, voy a dividir el procedimiento en dos pasos
Uno va a ser el de pasar a hexadecimal el dni (se supone que lo introducimos en memoria en decimal) y la otra parte en la que calculamos la letra propiamente dicha, ósea la parte de las restas.
Supongamos el mayor dni de todos 9999999, esto seria en decimal, pues bien si lo pasamos a hexadecimal se nos queda 30F, (ocupa 2 bytes!, por lo que no nos cabe todo el valor en un solo acumulador).
Para pasar a hexadecimal el numero debemos pensar que el dni tiene 8 letras, imaginemos que el dni es de la forma ABCDEFGH, la solución matemática viene dada de la siguiente manera:
Sabemos que la letra del dni se calcula haciendo el mod 23, pues lo hacemos para cada letra
A*10^7/23 + B*10^6/23 + C*10^5/23 + D*10^4/23 + E*10^3/23 + F*10^2/23 + G*10^1/23 + H*10^0/23
Vemos que la A multiplica a un número, la B a otro... esto nos da una tabla de mods:
A*14 + B*6 + C*19 + D*18 + E*11 + F*8 + 10*G + 1*H
en hexadecimal:
000E 0006 00013 0012 000B 0008 000A 0001
Algoritmo 1º parte
Veamos la 1º parte del algoritmo donde calculamos a partir del dni 99999999 en hexadecimal a 030F (03 en la parte alta FA, y 0F en la parte baja FB):
(la parte que está en negrita es la que debemos editar en la memoria), esto lo hará 8 veces (un bucle por cada mod, es decir la 1º vez 14 veces , la 2º vez 6, así pegamos
en memoria, hasta 8 veces ya que nos resulta muy complicado el hacer bucles anidados, cargando en X, el valor correspondiente a las repeticiones que va a hacer el bucle).
(//--//): Etiquetas ficticias para mejor entendimiento
|
4F CLRA //Limpiamos el registro AA 5F CLRB //Limpiamos el registro AB 97FA STAA 00FAh //Ponemos a 0 la posición de memoria 00FAh 97FB STAA 00FBh //Ponemos a 0 la posición de memoria 00FBh
//--REPETIR 7 VECES--// //No es que hagamos un bucle 7 veces, sino que copiamos y pegamos 7 veces el código hasta (26F9 BNE F9), pero cada vez que pegamos codigo accedemos a la siguiente posición de me- moria , es decir acceder a cada valor de la tabla de mods y así nos ahorramos el hacer un bucle anidado
DEE0 LDX 00EXh //Cargamos en X el primer valor de la tabla de mods 96F0 LDAA 00F0h //Cargamos en AA el primer dígito del DNI D6F0 LDAB 00F0h //Cargamos en AB el primer dígito del DNI
//--BUCLE--//
1B ABA //Sumamos AA=AA+AB 09 DEX //Decrementamos x 8C0001 CPX #0001h //Comprobar que x no sea 1, si no es 1 repetimos 26F9 BNE F9 //Repetimos el bucle
//--COMPROBAR CARRY--//
0C CLC //Ponemos a 0 el bit C de carry
//--ALMACENAMOS--//
99FB ADCA 00FBh //Sumamos lo que hay en A (suma de todo el bucle) a lo que hay en la ( posición de memoria 00FBh) 2402 BCC 02h //Si la suma anterior no produce carry, saltamos a la etiqueta NOSUMA (salta dos posiciones 97fb...) 6CFA INC 00FAh //Incrementamos la posición de memoria 00FAh en 1, para sumarle el carry de la suma anterior.
//--NOSUMA--//
97FB STAA 00FBh //Almacenamos en memoria lo que hay en A
//--FIN--//
01 NOP //acabamos con un no operación para pasar a la 2º parte del código |
Algoritmo 2º parte
Suponiendo que ya tenemos calculada la 1º parte (nos habra guardado en 00FA y 00FB un 03 y un 0F ,( el dni en hexadecimal).
Sabemos que todo este número no cabe en un solo acumulador ya que en AA solo cabe un byte (8bit), con lo que primero debemos almacenar el AA la parte alta 03, y después la parte baja 0F, ya que
en el acumulador AB debemos almacenar el dato a restar.
El algoritmo que he utilizado para esta segunda parte , el cual hace las restas sucesivas del 23 al número devuelto en la 1º parte, para ello debemos restar a la parte baja 23 (17 en hex), y cuando produzca acarreo
restárselo a la parte alta (03), es decir restarle 1 a 03, y así sucesivamente, todo cambio después de una resta, lo almacenaré en la misma posición, FA para la parte alta (03) y FB para la parte baja (0F), donde
machacaremos la información anterior ya que solo nos interesa saber la de la resta actual:
El código del programa es el siguiente (//**// comentado, para posible utilización):
(//--// etiquetas ficticias, para mejor entendimiento)
|
//--INICIO--/ //**//CE00 LDX #0000h //ponemos la x a cero 0C CLC //limpiamos el carry 96FA LDAA 00FAh //cargamos en AA la parte alta para ver si es 0 C600 LDAB #00h //cargamos en AB 0 para comparar 10 SBA //a -b compara a y b y activa el flag z si son iguales 2607 BNE //(RESTA1)si no son iguales (mira si el flag z si es 0), salta a resta1 [+7], es el desplazamiento //--COMPARA2--// //comparamos si la parte baja es menor que 17h(23)
96FB LDAA 00FBh //carga en a parte baja C617 LDAB #17h //cargamos el 23 en b 10 SBA //resta a=a-b 2513 BCS //(FIN)Si hay acarreo salta a FIN y sino sigue en resta1 [+18d->13h]
//--RESTA1--// //resta de la parte baja
96FB LDAA 00FBh //cargamos 1º valor de la parte baja en A C617 LDAB #17h //cargamos en b el 23 10 SBA //hacemos la resta 97FB STAA 00FBh //guardamos resultado en memoria (en la misma pos) 24E9 BCC //(INICIO)si no hay carry saltamos al inicio [-23d -> E9h]
//--RESTA ACARREO--//
96FA LDAA 00FAh //cargo la parte alta en a C601 LDAB #01h //cargo 01 en b para la resta del acarreo 10 SBA //restamos a A el acarreo 97FA STAA 00FAh //guardamos el resultado en memoria (misma pos) 7E0000 JMP //(INICIO) saltamos directamente a la pos de memoria elegida |
Edición de la memoria
Bueno, una vez que tenemos el código listo y comentado veamos como guardarlo en memoria y ejecutarlo:
Captura de la edición de la memoria

Vemos perfectamente como el dni lo hemos incluido desde la dirección 00F0 a 00F8
Antes de ello tenemos el código de programa. Para posicionarnos en una determinada dirección de memoria tenemos la opción de poner en Starting Address desde la dirección que queremos que empiece (0000), quedando así guardada para la próxima vez que entremos en el simulador
Gráficamente está representada de tal manera que empieza en la 0000 y después la siguiente es la 0010, es de diez en diez, pero claro desde la 0000, en el plano horizontal vamos contando hasta 16 posiciones, que equivalen a 16 bytes 0000 hasta 000F, para la 1º posición de memoria, con lo cual si
Visualizamos el archivo SIM.RAM quedaría de la siguiente manera (de 32 en 32):
4F5F97FA97FBDEE096F0D6F01B098C00
0126F90C99FB24026CF997FBDEE296F1
D6F11B098C000126F90C99FB24026CF9
97FBDEE496F2D6F21B098C000126F90C
99FB24026CF997FBDEE696F3D6F31B09
8C000126F90C99FB24026CF997FBDEE8
96F4D6F41B098C000126F90C99FB2402
6CF997FBDEEA96F5D6F51B098C000126
F90C99FB24026CF997FBDEEC96F6D6F6
1B098C000126F90C99FB24026CF997FB
DEEE96F70C99FB24026CF997FB0C96FA
C60010260796FBC61710251396FBC617
1097FB24E996FAC6011097FA7E00AD01
00000000000000000000000000000000
000E000600130012000B0008000A0000
09090909090909090000000000000000
Una vez terminada la ejecución del programa debemos tener en nuestra parte baja de memoria FB, donde guardamos el resultado de las restas un 01 (para el dni 99999999) que se
corresponde con la letra R, para ello tenemos la siguiente tabla que podemos consultar:
|
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
|
T |
R |
W |
A |
G |
M |
Y |
F |
P |
D |
X |
B |
N |
J |
Z |
S |
Q |
V |
H |
L |
C |
K |
E |







