K-Assembler para ZX-81

dancresp
Mensajes: 5091
Registrado: 13 Nov 2010 02:08
Agradecido : 37 veces
Agradecimiento recibido: 105 veces

K-Assembler para ZX-81

Mensajepor dancresp » 03 Abr 2014 12:53

screen_1.gif
screen_1.gif (41.98 KiB) Visto 1941 veces


EL PROGRAMA
Este programa es un sencillo pero efectivo ensamblador de 375 de los 697 mnemotécnicos del microprocesador Z80.

Por evidentes motivos de memoria, el ensamblador se limita a mostrar por pantalla los códigos, en formato decimal, del mnemotécnico introducido. Este proceso no afecta a la memoria RAM.

El ensamblador reconoce, parcialmente, las siguientes 20 instrucciones:
LD, ADD, ADC, SUB, SBC, AND, XOR, OR, CP, INC, DEC, BIT, RES, SET, PUSH, POP, RL, RR, SLA y SRA.


Limitaciones del ensamblador:
- No ensambla mnemotécnicos con valores numéricos como parámetros, excepto para BIT, RES y SET.
- No ensambla mnemotécnicos con registros dobles (16 bits) como BC, DE y HL excepto el (HL) y en PUSH y POP.
- No ensambla mnemotécnicos con IX, IY, R ó I.
- No se comprueba que la instrucción introducida sea correcta. El resultado puede ser erróneo o provocar un error.
- Solo se comprueban las dos primeras letras del nombre de las instrucciones.
- Solo se comprueba la primera letra de los registros, excepto si empieza por paréntesis que se considera (HL).
- La instrucción ADC se debe introducir como AC para diferenciarla de ADD, por el motivo de las dos letras.
- En las instrucciones BIT, RES y SET se debe cambiar el orden de los parámetros. Primero el registro y después el bit.

El resultado se muestra en pantalla en un par de segundos y queda listo para introducir otro mnemotécnico.

Ejemplos:
ADD A,D : 130
LD A,H : 124
PUSH HL : 229
BIT E,6 : 203 115

Descargar el juego en formato ".Z81" (Snapshot del EightyOne):
K-Assembler.rar
(1.03 KiB) Descargado 98 veces


BLOQUES
He dividido el listado en 5 bloques:

- Inicializar variables principales.
- Procesador de la línea de entrada.
- Identificador de instrucciones.
- Identificador de parámetros.
- Ensamblado de la línea.


COMO FUNCIONA
A continuación detallo, línea por línea, el funcionamiento del programa.

Se utilizan las siguientes variables:
U – Variable que contiene el valor “1”.
I – Variable usada como contador de parámetros.
F – Variable para bucles, o identificador del segundo registro de la instrucción a ensamblar.
O – Variable usada para guardar el identificador de la instrucción a ensamblar.
R – Variable usada para guardar el identificador del primer registro de la instrucción a ensamblar.
A$ - Variable donde se guarda la línea que se ha de procesar.
W$ - Variable donde se guarda el parámetro a procesar.

2 – Guardamos el valor 1 en la variable “U”. Se usará a lo largo del programa y permite ahorrar memoria.
4 – Guardamos el 0 en la variable “I”. Se usa como contador de parámetros.
8 – Introducir en A$ la instrucción a ensamblar.
10 - Se borra la pantalla para ahorrar memoria.
12 - Mostramos en pantalla el mnemotécnico a ensamblar.
14 – Inicio del bucle que analiza la línea de entrada.
16 - Si en una posición de la línea se encuentra un punto o una coma se salta a la línea 20.
18 – Si el bucle no ha llegado al final vuelve a la línea 14.
20 - Guardamos en W$ el valor de A$ hasta el espacio, más un espacio.
22 - Guardamos en A$ desde después del espacio hasta el final de la línea de entrada.
24 - Incrementamos el contador de parámetros (I).
26 - Si I es mayor de 1 salta a la línea 38.
28 - Iniciamos un bucle que identificará la instrucción a ensamblar.
30 – Se comparan los dos primeros caracteres de W$ con la lista de instrucciones aceptadas, y si coincide salta a 34.
32 – Si el bucle no ha llegado al final vuelve a la línea 28.
34 - Guardamos en (O) el número de instrucción que se ha encontrado.
36 - Saltar a la línea 14 para seguir procesando la línea de entrada.
38 - Iniciamos un bucle que identificará el registro usado.
40 - Comparamos el primer carácter de W$ con la lista de registros aceptados, y si coincide salta a la línea 44.
42 – Si el bucle no ha llegado al final vuelve a la línea 38.
44 - Si el contador de parámetros es igual a 2 guardamos el valor de (F) en la variable de registro (R).
46 - Si I es menor de 3 salta a la línea 14 para seguir procesando la línea de entrada.
48 - Si W$ está vacío se iguala la variable (F) a variable de registro (R).
49 – Simula un ON GOTO saltando a una línea múltiplo de 50 del número de instrucción correspondiente guardada en (O).
50 - Fórmula para calcular el código de la instrucción "LD". Se imprime el resultado.
52 - Volver al inicio del programa.
450 - Fórmula para calcular el código de "ADD", "ADC", "SUB", "SBC", "AND", "XOR", "OR" y "CP". Se imprime el resultado.
452 - Volver al inicio del programa.
550 - Fórmula para calcular el código "INC" y "DEC". Se imprime el resultado.
552 - Volver al inicio del programa.
700 - Fórmula para calcular el código "BIT", "RES" y "SET". Se imprime el resultado.
702 - Volver al inicio del programa.
800 - Fórmula para calcular el código "PUSH" y "POP". Se imprime el resultado.
802 - Volver al inicio del programa.
1000 - Fórmula para calcular el código "RL", "RR", "SLA" y "SRA". Se imprime el resultado.
9000 - Volver al inicio del programa.


EL PROGRAMA
listado.gif
listado.gif (62.18 KiB) Visto 1941 veces


APUNTES FINALES
Finalizado el proyecto del intérprete de FORTH en 1K, seguía teniendo en mente el programa “Trans-Compilador 1K” del número 30 de la revista “El Ordenador Personal” (página 135). Es un sencillo compilador que pasa de BASIC a CM, con muchas limitaciones. Satisfecho con el intérprete, quería llegar más lejos. Así que cogí una lista de mnemotécnicos del Z80 y la empecé a analizar. El resultado es este ensamblador.

Al analizar las listas se puede comprobar que, en general, hay unas secuencias y relaciones de códigos de instrucciones según los registros o instrucciones usados. Analizando cada grupo de instrucciones puedes encontrar una fórmula que genera el código correcto de una gran parte de los mnemotécnicos de una instrucción.


Metiendo un ensamblador en 626 bytes y 36 líneas de código BASIC
Una vez más ha sido un trabajo digno de un relojero suizo el conseguir hacer que funcione con las limitadas capacidades del ZX-81 básico. Y aquí ha estado la gracia.

Como siempre, lo primero ha sido introducir una línea con la que voy controlando la memoria que ocupa el programa:
9999 PRINT (PEEK VAL"16396"+VAL"256"*PEEK VAL"16397")-VAL"16509"
Esta línea ocupa 43 bytes, que ganaré al borrarla al finalizar el desarrollo del programa.

He usado los trucos habituales del ZX-81 para ahorrar memoria en el uso de valores numéricos. Así, "NOT PI" es 0, uso de VAL, y como el valor 1 se usa varias veces he asignado ese valor a la variable "U" mediante "SGN PI". He prescindido de CODE para dejar el programa más comprensible, aunque habría conseguido ahorrar unos 12 bytes.

La primera parte del programa ha consistido en hacer el procesador de la línea de entrada. Me he basado en el del intérprete de FORTH aunque en este caso lo he podido simplificar bastante.

La segunda parte ha consistido en identificar los distintos parámetros de la línea y asignarles un valor numérico. Primero para la instrucción, el segundo para el registro y el tercero para un registro o valor numérico.

Para la instrucción me limito a comparar las dos primeras letras del nombre. En una máquina con más memoria se debería ampliar esto porque en este caso me ha limitado el número de instrucciones a reconocer. Lo mismo pasa con el nombre del registro, ya que solo comparo la primera letra, y también limita el ensamblador. Pero con 1K no había otra opción.

La tercera parte empieza con el GOTO de la línea 49, que se encarga de saltar a una línea múltiplo de 50 en función del código de la instrucción. Afortunadamente el BASIC de los SINCLAIR permite esto, y simplifica mucho el código.

Las instrucciones se han numerado de la siguiente forma:
LD (1) - ADD (2) - ADC (3) - SUB (4) - SBC (5) - AND (6) - XOR (7) - OR (8) - CP (9) - INC (10)
DEC (11) - BIT (12) – RES (13) – SET (14) – PUSH (15) – POP (16) – RL (17) – RR (18) - SLA (19) y SRA (20)

Las instrucciones se han agrupado en 6 grupos según la fórmula a aplicar:
1) LD
2) ADD, ADC, SUB, SBC, AND, XOR, OR, CP
3) INC, DEC
4) BIT, RES, SET
5) PUSH, POP
6) RL, RR, SLA, SRA

Los registros se han numerado de la siguiente forma:
B (0) - C (1) - D (2) - E (3) - H (4) - L (5) – (HL) (6) y A (7)

Como el BASIC de los SINCLAIR permite saltar a una línea que no existe, he hecho que la fórmula este en la línea del identificador de instrucción más alto de cada grupo de instrucciones, multiplicado por 50. Así, la fórmula de LD está en la línea 50, la fórmula del grupo 2 (ADD, ADC, etc.) está en la línea 450 (CP = 9*50), etc. Y como no hay que almacenar nada vuelvo al principio del programa con un RUN al finalizar el proceso de ensamblado.

Esta versión del ensamblador es muy simple por una cuestión de memoria, pero el programa está estructurado para que cada instrucción tenga 50 números de línea a su disposición para introducir el código que haga falta para poder tratar los distintos mnemotécnicos de las instrucciones del Z80.


Buscando fórmulas
Analizando la tabla de la instrucción LD de transferencias de 8 bits se puede ver que los códigos están comprendidos entre 40h (64) y 79h (127).

Sin título-1.gif
Sin título-1.gif (41.96 KiB) Visto 1941 veces

Empieza en la columna “B” y acaba en la columna “A”, y cada fila que bajamos se incrementa en 8.A partir de la codificación de registros que he usado, con la fórmula: “64 + 8 * IDreg1 + IDreg2” de la línea 50 del programa podemos ensamblar fácilmente 63 de los 132 mnemotécnicos distintos de la instrucción LD
Para poder ensamblar el resto hace falta más código, aunque en general siempre siguen unos patrones definidos.


Analizando la tabla de las instrucciones “BIT”, “RES” y “SET” se puede ver que los códigos están comprendidos entre 40h (64) y FFh (255) con un CBh (203) delante.

Sin título-2.gif
Sin título-2.gif (92.09 KiB) Visto 1941 veces

Al igual que con la instrucción LD, empieza en la columna “B” y acaba en la columna “A”, y cada fila que bajamos se incrementa en 8.Con la fórmula: “64 * (IDinstruccion - 11) + IDbit * 8 + Idreg1” de la línea 700 del programa podemos ensamblar 192 de los 240 mnemotécnicos de estas instrucciones.

Este mismo criterio lo he seguido en otras tablas de instrucciones hasta conseguir ensamblar 375 de los 697 mnemotécnicos.


Para terminar
Me quedo con la ganas de seguir el proyecto en una máquina más rápida y con más memoria, porque con un poco más de código se puede conseguir ensamblar la mayor parte de los mnemotécnicos del Z80. También se podría incluir un editor para poder usarlo como un ensamblador más “profesional”.

Con todo, el ensamblado funciona perfectamente y es bastante rápido. Así que... Prueba superada ¡!!


Os invito a probarlo.

screen_2.gif
screen_2.gif (41.9 KiB) Visto 1941 veces

screen_3.gif
screen_3.gif (41.93 KiB) Visto 1941 veces

Avatar de Usuario
jojo073
Mensajes: 3166
Registrado: 14 Nov 2010 20:41
Agradecido : 42 veces
Agradecimiento recibido: 106 veces

Re: K-Assembler para ZX-81

Mensajepor jojo073 » 03 Abr 2014 13:03

Interesantisimo...
¿Me pregunto si te importaría que lo pillara para la revista?, a la gente que tenga un zx-81 seguro que le pica la curiosidad de probar...

saludos y gracias

Avatar de Usuario
ron
Mensajes: 17701
Registrado: 28 Oct 2010 14:20
Ubicación: retrocrypta
Agradecido : 697 veces
Agradecimiento recibido: 749 veces

Re: K-Assembler para ZX-81

Mensajepor ron » 03 Abr 2014 19:02

F A N T A S T I C O !!!!

Dancresp !!! Awesome !"" ese Wally liándola parda con el ZX81.

Avatar de Usuario
Chema
Mensajes: 1739
Registrado: 21 Jun 2012 20:13
Ubicación: Gijón
Agradecido : 685 veces
Agradecimiento recibido: 265 veces
Contactar:

Re: K-Assembler para ZX-81

Mensajepor Chema » 03 Abr 2014 19:18

No, si ya te digo que este tío es un monstruo del basic (y de otros lenguajes) Yo lo flipo.

Avatar de Usuario
ron
Mensajes: 17701
Registrado: 28 Oct 2010 14:20
Ubicación: retrocrypta
Agradecido : 697 veces
Agradecimiento recibido: 749 veces

Re: K-Assembler para ZX-81

Mensajepor ron » 03 Abr 2014 19:26

Chema escribió:No, si ya te digo que este tío es un monstruo del basic (y de otros lenguajes) Yo lo flipo.


es un monstruo y un cavernícola ( pero de monstruo que es ), ya lo conocerás, es de los buenos !!! -drinks

FloppySoftware

Re: K-Assembler para ZX-81

Mensajepor FloppySoftware » 04 Abr 2014 21:52

Congratulations! Lo que da de sí un mísero Kb! -thumbup -drinks

dancresp
Mensajes: 5091
Registrado: 13 Nov 2010 02:08
Agradecido : 37 veces
Agradecimiento recibido: 105 veces

Re: K-Assembler para ZX-81

Mensajepor dancresp » 10 Abr 2014 23:08

jojo073 escribió:Interesantisimo...
¿Me pregunto si te importaría que lo pillara para la revista?, a la gente que tenga un zx-81 seguro que le pica la curiosidad de probar...

saludos y gracias

Uix, se me había pasado...

Bueno, es uno de estos proyectos "tan míos" que dedico a las inmensas minorías.
Pero es que me lo paso muy bien haciéndolos. -grin

Ya sabes que por mi parte, a disponer.
Y tan contento !!!

-thumbup

Avatar de Usuario
ron
Mensajes: 17701
Registrado: 28 Oct 2010 14:20
Ubicación: retrocrypta
Agradecido : 697 veces
Agradecimiento recibido: 749 veces

Re: K-Assembler para ZX-81

Mensajepor ron » 10 Abr 2014 23:09

ese es nuestro WALLY !!!

Dancresp no pares colega !!!

dancresp
Mensajes: 5091
Registrado: 13 Nov 2010 02:08
Agradecido : 37 veces
Agradecimiento recibido: 105 veces

Re: K-Assembler para ZX-81

Mensajepor dancresp » 10 Abr 2014 23:15

ron escribió:Dancresp no pares colega !!!

Pues llevo una temporadita que no tengo mucho tiempo libre, pero he seguido el proyecto en Q-BASIC (para aprovechar los viajes en tren) y me estoy currando el ensamblador completo, con un sencillo editor y compilación real con doble pasada para poder usar etiquetas. Aparentemente no parece que tenga que ocupar mucho...

Posteriormente se podrá adaptar a cualquier BASIC, sobretodo a los MICROSOFT, aunque ahora mismo tengo la duda si hacer la versión MSX o Amstrad.
Ya sabéis que a mi, la norma MSX...

Pero bueno, se podrá ver como funciona un ensamblador. -grin


Volver a “Lenguajes de Programación y herramientas Dev”

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado