martes, 19 de abril de 2022

Z80 - Programa ensamblador

Página principal

Z80
Ensamblador




Este es el primer artículo de una serie de 3, Ensamblador, Desensamblador, y Simulador.
Los que tenemos unos años, conocimos el microprocesador Z80, era el mas conocido de su época, infinidad de computadoras se basaban en el.  Entre las computadores que llevaban el Z80 estaba el mítico Spectrum, y los famosos MSX, Amstrad.
En su tiempo había realizado alguna que otra práctica con el ensamblador del Z80, he incluso había desarrollado una placa de pruebas con el Z80. z80_boot.html





La mejor ayuda para conocer el Z80 es leer el manual oficial del Z80, son 333 páginas de documentación.
Z80 Microprocessors
Z80 CPU
User Manual
UM008011-0816


En este artículo creo un ensamblador para el Z80.
Este ensamblador es muy mio, sin muchas pretensiones, como ejemplo de lo particular que es, solo admite números decimales.
La búsqueda de nemotécnicos es secuencia, poco eficaz en rapidez, pero lo suficiente en ordenadores actuales.
Este ensamblador es una mezcla de preprocesador y ensamblador.
El preprocesador  transforma todas la letras a mayúsculas, por lo cual no distingue mayúsculas y minúsculas.

Ejemplo:

#inicio   
     ld a,&10
    inc b        /incrementar segundos
    cp b
    jr nz,#salto


Salida:

009 #INICIO          
010  LD A,&10            00006_ 062 010
011  INC B               00008_ 004
012  CP B                00009_ 184
013  JR NZ,#SALTO        00010_ 032 026



Para ensamblar un fichero asm, se realiza con el comando:

./ensam reloj.asm

Si  no se especifica fichero de salida, el nombre del fichero por defecto es: file.bin
Las opciones de ensamblado son:

-pt Salida por pantalla, opción por defecto;
-pb Salida por pantalla binario
-o nombre fichero binario

Reglas del ensamblado.

- Números solo en formato decimal.

- Después de 3 NOP  entiende que son datos de programa en el programa disamble

- Formato:
$variable
  nemotecnico  <- Dos espacios mínimo desde principio de linea

/ o ;  ->comentario
$ variable
# variable de salto
        org    00000h


----------------------------EJEMPLO---- ./ensam reloj.asm -----------------

/Ejemplo reloj minutos y segundos
/reloj.asm
/  ./ensam reloj.asm

    org &0
    ld b,&0
    ld c,&0
    ld d,&0
    ld e,&0
#inicio   
    ld a,&10
    inc b        /incrementar segundos
    cp b
    jr nz,#salto
    ld b,&0
    inc c        /incrementar decimales segundo
    ld a,&6
    cp c
    jr nz,#salto
    inc d        /incrementar minutos
    ld c,&0
    ld a,&10
    cp d
    jr nz,#salto
    ld d,&0
    inc e        /incrementar decimales minutos
    ld a,&6
    cp e
    jr nz,#salto
    ld e,&0
   
#salto
    nop
    jp #inicio



Ensamblador corez80 V3
=======================
--- Preprocesador ---
--- Fin preprocesador ---
Num NEMOS= 698
--- Paser 0 ===Ensamblador===
_FIN__Parser 0
--- Paser 1 ===Ensamblador===
001 /reloj.asm       
002                  
003  ORG &0              00000_______ORG_0
004  LD A,&0             00000_ 062 000
005  LD B,A              00002_ 071
006  LD C,A              00003_ 079
007  LD D,A              00004_ 087
008  LD E,A              00005_ 095
009 #INICIO          
010  LD A,&10            00006_ 062 010
011  INC B               00008_ 004
012  CP B                00009_ 184
013  JR NZ,#SALTO        00010_ 032 026
014  LD B,&0             00012_ 006 000
015  INC C               00014_ 012
016  LD A,&6             00015_ 062 006
017  CP C                00017_ 185
018  JR NZ,#SALTO        00018_ 032 018
019  INC D               00020_ 020
020  LD C,&0             00021_ 014 000
021  LD A,&10            00023_ 062 010
022  CP D                00025_ 186
023  JR NZ,#SALTO        00026_ 032 010
024  LD D,&0             00028_ 022 000
025  INC E               00030_ 028
026  LD A,&6             00031_ 062 006
027  CP E                00033_ 187
028  JR NZ,#SALTO        00034_ 032 002
029  LD E,&0             00036_ 030 000
030                  
031 #SALTO           
032  NOP                 00038_ 000
033  JP #INICIO          00039_ 195 006 000
034  NOP                 00042_ 000
035  NOP                 00043_ 000
036                  
037  END                 00044__FIN__Parser 1

==Variables== NUM=1
00-#INICIO=6        01-#SALTO=38       
Salvando codigo en fichero file.bin   SIZE=44


Podemos observar que nos muestra las variables existentes con su sus valores, tanto como valor numérico como valor de dirección de memoria.

Para ver todos los nemotécnicos admitidos, se pueden ver en los ficheros :
opcodes.txt
z80_code.txt

Espero que sea un principio para que realicéis vuestro propio ensamblador.
Se compila en Linux con make.


PROGRAMAS

Saludos.
Juan Galaz



Bibliografía:
http://www.z80.info/decoding.htm
https://espamatica.com/
http://map.grauw.nl/resources/