Vistas de página en total

Programar en android TRS-80 y ensamblador Z80 -1

Programar el emulador TRS-80 en android el microprocesador Z80 de la microcomputadora TRS80 III con el editor ensamblador EDTASM del sistema operativo NEWDOS80.
VER VIDEO PZ

Teléfonos Inteligentes e Internet

El TRS-80 emula una línea de microcomputadoras de la compañía TRS de fin de los años de 1970. Inicio con el modelo trs80 I continuo con el trs80 III y terminino con el trs80 IV y después salieron  otros modelos. Los tres modelos utilizaron el microprocesador Z80 de 8 bits. Internamente tiene varios registros, contadores y apuntadores, un sumador y buses para comunicarse internamente.                 
Para comunicarse externamente también utiliza buses de Datos, Direcciones y de Control, con las memorias RAM ROM y los puertos de los dispositivos de entrada y salida I/O como Leds de salida, Switches de entrada y una grabadora de Cassets. Los buses tiene tres estados uno de señal baja activa, otro de señal alta activa y el estado de alta impedancia que no conduce señales.

                                                                  
Señales y Buses del Z80
El chip del Z80 tiene 40 pines con:
1.El bus de direcciones de 16 bits unidireccional
2.El bus de datos de 8 bits bidireccional
3.El bus de control con 16 bits con las siguientes señales:
Control del sistema
M1' Señal de salida negativa, activa indica inicio ciclo de máquina fetch o de operación para obtener una instrucción de memoria.
MREQ' Señal de salida negativa, activa indica un requerimiento de acceso a memoria
IOREQ' Señal de salida negativa, activa indica un requerimiento de entrada-salida
RD' Señal de salida negativa, activa indica una lectura de memoria o de un dispositivo.
WR' Señal de salida negativa, activa indica una escritura a memoria o un dispositivo.
RFSH' Señal de salida negativa, activa indica un refresco de memoria.
Control del CPU
HALT' Señal de salida negativa, activa fue generada por una introducción HALT e indica el alto del cpu.
WAIT' Señal de entrada negativa, activa indica tiempo de espera para memorias lentas
INT' Señal de entrada negativa, activa indica una interrupción enmascarable
NMI' Señal de entrada negativa, activa indica una interrupción no enmascarable
RESET' Señal de entrada negativa, activa inicia el funcionamiento del CPU y genera la dirección 0000 y la envía a la memoria para ejecutar la primera instrucción.
Control del Bus
BUSRQ' Señal de entrada negativa, activa indica el requerimiento de los buses para una transferencia de acceso a memoria directo DMA
BUSACK' Señal de salida negativa, activa indica el reconocimiento del uso de los buses para una transferencia de acceso a memoria directo DMA.
Otras señales
CLK Señal que indica la entrada del reloj externo generado por un oscilador.
+5V Voltaje positivo
GND Tierra


Registros del Z80
El Z80 tiene  los siguientes registros principales de 8 bits que puede manipular el programador.
A, F, B, C, D, E, H, L
Algunos se pueden combinar en pares de 16 bits: BC, DE, HL
El registro F indica el estado de los bits banderas o Flags resultado de las operaciones
       7    6   5   4    3     2     1    0
F= | S | Z | X | H | X | P/V | N | C |
S Bandera Signo o Sign Flag 1:negativo
Z Bandera Cero o Zero Flag 1:cero
H Bandera Medio Acarreo o Half Carry Flag 1: acarreo del bit 3 al 4
P Bandera de Paridad o Parity Flag 1: par
V Bandera de Sobre flujo o Overflow Flag 1:sobreflujo
N Bandera de Operación o Operation Flag 1:operación anterior resta
C Bandera de Acarreo o Carry Flag 1: acarreo 
Los registros alternos de ocho bits para intercambio de los registros en las interrupciones:
A', F', B', C', D', E', H', L'
IX, IY Registros index, para indexar tablas de datos y buscar algún valor.
Adder o Sumador de 8 y 16 bits una entrada es el registro o el acumulador y la salida o resultado de la operación regresa al acumulador A. La otra entrada es de otro registro, memoria o puertos de entrada-salida.
SP Registro apuntador stack o de pila, para guardar valores de rutinas y operaciones de expresiones matemáticas.
PC Contador de programa, lleva el control de la dirección de la siguiente instrucción a ejecutar
INC Es un incrementador o decrementador en  1, lo usa el contador de programa PC y otras instrucciones.
RF Registro refresh o de refresco de la memoria dinámica, solo utiliza 7 bits, las memorias dinámica son hechas de transistores MOS de carga capacitiva y necesitan refrescarse cada determinado tiempo en  milisegs para no perder su valor.
IV Registro de vectores de interrupciones,  se usa para completar el vector de interrupción con la parte enviada por los dispositivos de entrada salida y forman la dirección completa de las rutinas o drivers del servicio de cada dispositivo.
IR Registro de instrucción de 2 bytes o 16 bits, Para instrucciones de un byte su contenido de  un byte de IR se obtiene de memoria con un ciclo fetch o de operación e identifica el codigo de opereración de un byte y en T3 y T4 realiza la operación y si requiere datos realiza un ciclo de memoria o de entrada-salida. Para instrucciones de dos bytes realiza otro ciclo fetch y completa los dos bytes de IR e identifica el código de operación de los dos bytes y en T3 y T4 ejecuta la operación  y si requiere datos realiza un ciclo de memoria.

Sistemas Numéricos
Hay muchos sistemas numéricos, como el decimal que utilizamos, pero el que nos interesa es el binario y hexadécimal para programar en lenguaje ensamblador del Z80.
El sistema binario tiene solo dos digitos de 1 y 0 físicamente se representan el 1 con 5 volts y el 0 con 0 volts. El lenguaje binario es el que entiende las computadoras y está limitado a la  cantidad de bits que pueden manipular  organizados en bytes de 8 bits. 
Un byte con números binarios se escribe como:
11011001B
Con una B al final.
La razón principal del sistema hexadecimal es facilitar la representación binaria en grupos de 4 bits por dígitos parecidos al sistema decimal:
0000-0
0001-1
0010-2
0011-3
0100-4
0101-5
0110-6
0111-7
1000-8
1001-9
1010-A
1011-B
1100-C
1101-D
1110-E
1111-F
El ejemplo anterior binario de un byte de 8 bits:
11011001B
En hexadecimal queda como:
D9H
Colocandose una H al final
Veamos un programita en hexadecimal en memoria:
Dir     Op
7000-3E
7001-02
7002-06
7003-02
7004-80
7005-CD
7006-0D
7007-44
7008-00
Identificamos las instrucciones:
3E02-LD A,2H
0602-LD B,2H
80-    ADD A,B
CD0D44-CALL 440DH
Ahora lo convertimos en Binario
    7       0      0       0        3      E       0      2
0111 0000 0000 0000-0011 1110 0000 0010
    0       6       0       2       8      0       C     D
0000 0110 0000 0010 1000 0000 1100 1101
    0       D      4       4   
0000 1101 0100 0100
Las instrucciones que entiende el Z80 estan en  lenguaje binario de unos 1 de 5 volts y ceros 0 de 0 volts, organizados como bytes de ocho bits almacenados en alguna memoria RAM o ROM. Cada instrucción es de un byte a cuatro bytes, tiene una parte de operación de un byte a dos bytes y la otra parte es la dirección a operandos o datos y puede ser de uno a dos bytes están en la propia instrucción, en los registros, en la memoria o llegan de los puertos de entrada o salen para los puertos de salida.

Direccionamiento del Z80
Las instrucciones para obtener sus datos u operandos utilizan varios modos de direccionamiento.
1.Inmediato de un byte y dos bytes. El dato de un byte o dos bytes esta en la propia instrucción pero almacenados en la memoria.
11)LD C,FFH  ;Carga el registro C con el número FFH.
7500H-LD C,FFH
7501H-FFH
C=33H -> C=FFH
12)LD HL,3456h  ;Carga el par HL con el dato 3456h.
7600H-LD HL,3456H
7601H-56H
7602H-34H
HL=6723 -> HL=3456H
2.Directo a memoria o directo extendido y a la página cero de la memoria, especifica una dirección de memoria donde esta el dato. La primera página 0 contiene los vectores de interrupciones.
21)LD A,(7000H) ;Carga el acumulador con el dato contenido en la dirección 7000H en memoria
7000H=55 -> A=55
22)LD HL,(2345H)  ;Carga el registro L con el  contenido de la dirección 2345H y el registro H con el contenido de la dirección 2346H.
2345H=34
2346H=07 -> HL=0734
Para la página 0 solo se utiliza en la instrucción RST, que salta y continua ejecutando la instrucción contenida en la dirección en página cero cuya dirección se incluye  en la instrucción, que puede ser 0, 8, 10H, 18H, 20H, 28H,  30H y 38H.
23)RST 10H   ;Carga el PC con el valor 0010h, con lo que se ejecutará la instrucción contenida en esa dirección.
10H -> PC -> Salta a ejecutar la instrucción en 10H
3.Relativo. Especifica una dirección relativa al  contador de programa PC o la dirección de la  instrucción actual y se suma el desplazamiento de un rango de -127 posiciones hacia atras y +128 hacia adelante.
31)JR Z,02H  ;Salta, si el resultado anterior fue cero, a la dirección que resulta de sumar al PC actual el número 02H
00FFF-SUB
1000H-JR,02H (-02H)
1001H-LD
1002H-ADD
4.Indexado. Utiliza los registros indexados IX e IY que contienen un dato de 16 bits más  el desplazamiento para obtener la dirección efectiva del dato.
41)SUB (IX+44H)  ;Resta al acumulador el contenido de la dirección de memoria que se obtiene al sumar 44H al contenido del registro IX.
A=43H
IX=1000H
DS=0044H
PC=1044H
1044H=33H -> A=43H-33H=10H
5.Registro y Registro extendido. La  dirección  específica el contenido de un registro y un registro doble.
51)ADD A,B  ;Suma el contenido del registro B en el  acumulador (A) y el resultado queda en el acumulador.
B=22H A=33H -> A=33H+22H=55H
6.Implicado. La instrucción asume un registro, normalmente el registro A o F sin indicarlo.
SCF   ;Activa o coloca a 1 el flag C.
61)F=00H -> F=01H
7.Bit. Las instrucciones afectan a un solo bit de un registro.
71)SET 6, B  ; Activa bit 6 del registro B
B=04H=00000100 -> B=44H

Instrucciones del Z80
Las instrucciones del Z80 contienen un código de operación y los operandos que pueden obtenerse con varios modos de direccionamiento de algún registro, memoria o de dispositivos de entrada-salida. Las instrucciones son:
1.Transferencia
Transferencia o movimiento de 8 bits de un byte, o de 16 bits de dos bytes, del stack y blocks de bytes. El movimiento es entre registros, entre registros y memoria, entre registros y el stack y   movimientos de blocks en memoria. Las trasferencias o movimientos es del segundo operando al primero y no afectan el contenido ni las banderas de estado.
11) LD A, B   ;Mueve el contenido de B en A
A=07H B=02H -> A=02H
LD B, 32H  ;Mueve 32H en B
1000H-LD B,32H
1001H-32H -> B=32H
12) LD HL , 2270H  ;Mueve 2270H de mem en HL
2270H-70H
2271H-22H -> HL=2270H
13) LD A , (2311H)  ; Mueve de mem de la dirección 2311H su contenido al registro A
2311H-66H -> A=66H
14)PUSH BC  ;Coloca o empuja el contenido del par BC en la pila o stack
9008H-11H
9007H-22H
SP=9006H
BC=3344H
PUSH
9008H-11H
9007H-22H
9006H-44H
9005H-33H
SP=9004H
BC=3344H
15)EXX  BC, DE  ;Intercambia el contenido de DE y de BC
BC=2222H DE=3333H -> BC=3333H DE=2222H
2.Arirméticas Lógicas Rotación y Desplazamiento
Aritméticas de un byte y dos bytes. Realiza operaciones aritméticas de suma y resta, incrementos y decrementos entre registros, el resultado siempre queda en el registro A y para registros dobles el resultado queda en el registro par HL. Las operaciones aritméticas son del segundo operando al primero y afectan los contenidos del primer operando y las banderas de estado.
21)ADD A, B ;Suma el contenido de B al acumulador A
B=54H A=34H -> A=34H+54H=84H
22)ADD A, 41H  ;Suma el valor 41H al acumulador
2000H-ADD A,41H-CO
2001H-41H
A=56 -> A=56+41H=97H
23)SUB C   ;Resta el valor de C del valor de A
C=35H A=66H -> A=66H-35H=31H
24)INC B  ;Incrementa en 1 el valor de B
B=77 -> B=77+1=78
25)DEC BC  ;Decrementa en 1 el valor del contenido par de BC
BC=4444H -> BC=4444H-1=4443H
Logicas
Realiza las operaciones lógicas de AND OR XOR entre registros y el resultado queda en el registro A.
26)AND B ; Al valor de B y A se aplica la función Y o AND
B=88H=10001000B
A=28H=00101000B
A=08H=00001000B
Rotación y desplazamientos
Realizan movimientos a la izquierda o derecha de los bits de un registro y afectan el contenido del operando.
27)RLC A ; Rotación a la izquierda de A una posición, el bit 7 pasa al acarreo C y este pasa al bit 0.
C=0 A=88H=10001000B -> C=1 A=00010000=10H
3.Salto
Salto incondicional y condicional. Cambian la secuencia del programa de forma incondicional y condicional a otra dirección para continuar la secuencia del programa.
31)JP 7000H  ; Salto incondicional a la dirección 7000H de la memoria
7000H-ADD
7001H-Instr1
7002H-Instr2
....
7FFFH-InstrN
8000H-JP 7000H  ;7000H -> PC
8001H-SUB
32)JP C, 7000H  ;Salto condicional si la bandera de acarreo C está activa, ve a la dirección 7000H de la memoria
7000H-ADD
7001H-Instr1
7002H-Instr2
....
7FFFH-ADD
8000H-JP C,7000H  ;7000H -> PC
8001H-SUB
Comparación
33)CP 13  ;Compara el valor de 13 con el de A el resultado afecta las banderas de estado y la siguiente instrucción checa las banderas para saltar a otra dirección.
7000H-ADD
7001H-Instr1
7002H-Instr2
....
7FFDH-LD A,13
7FFEH-CP 13
8000H-JP Z,7000H  ;7000H -> PC
8001H-SUB
Instruccioes de Bits
SET 7, B  ;Activa el bit 7 del registro B
RES 2, B  ;Desactiva el bit 2 del registro B
BIT 7, B   ;Checa el bit 7 de B y si esta puesto activa la bandera Z y la siguiente instrucción checa las banderas para saltar a otra dirección.
4.Rutinas
Rutinas del programa o de interrupciones. Las rutinas o subrutinas son secuencia de instrucciones que pueden ser llamadas por el programa varias veces y cuando terminan regresan a continuar la secuencia del programa.
41)CALL 8000H  ;Llama la subrutina localizada en la dirección 8000H
7000H-CALL 8000H
7001H-LD
7002H-Instr2
....
7FFFH-InstrN
8000H-LD
8001H-ADD
.....
8030H-RET
5.Entrada y Salida.
Realizan la transferencia  con los dispositivos de entrada-salida.
51)IN A, (01H) ;Mueve  el dato de un byte del puerto de entrada  01 al registro A
PTO01=33H
A=56H -> A=33H
52)OUT (03H) , A ;Mueve el contenido de A un dato de un byte al puerto de salida 07
PTO07=33H
A=44H -> A=44H PTO07=44H
6.Control.
Realizan operaciones de control como parar el cpu con HALT, NOP no operación y activar o desactivar las interrupciones.

Ejecución de las Instrucciones
El proceso de ejecutar las instrucciones de un programa es un ciclo de instrucción que contiene varios ciclos de máquina con hasta tres o cuatro estados de tiempos por cada instrucción. Un ciclo de instrucción consiste de:
1.Obtener la instrucción de memoria.
2.Decodificación o identificación de la instrucción.
3.Ejecución de la instrucción.
Una instrucción puede ser de uno a cuatro bytes, en algunas el primer byte y en otras también el segundo byte tienen un codigo de operación y los restantes una dirección de los operandos o datos. Podemos identificar para ejecutar las instrucciones los ciclos siguientes:

Ciclo Fetch o de Operación
   
El ciclo de operación inicia al activar la señal ciclo de máquina M1' en T1 con cuatro tiempos para obtener la siguiente instrucción indicada por el contador de programa PC que es colocada en el bus de direcciones al inicio de M1, medio ciclo después de T1 se activa MREQ' y es usada como una señal de chip enable clock para la memoria dinámica RAM. Se activa RD' para permitir al cpu en T2 leer la memoria del bus de datos en el registro de instrucción IR y desactivar MREQ' y RD' en la subida del pulso T3. En T3 y T4 se activa la señal refresh RFSH y junto con el registro R envía 7 bits inferiores al bus de direcciones para refrescar toda la memoria dinámica, también se vuelve activar MREQ' pero no se activa RD'. Debido a la respuesta de memorias lentas se introducen tiempos de espera Tw si es necesario.
Esta parte es la más importante del ciclo de operación pués al mismo tiempo en T3 y T4 se decodifica la instrucción contenida en el registro de instrucción IR y se ejecuta para instrucciones de un byte de operación. Para instrucciones de dos bytes de operación hace otro ciclo de operación para completar e identificar la instruccion de dos bytes de operación. Para las instrucciones de un byte o dos bytes de operación si necesita operandos debe hacer ciclos de memoria o ciclos de entrada-salida para obtener los datos.

Ciclos Memoria de Lectura y Escritura
      
El ciclo de lectura usa tres tiempos, inicia con la señal activa MREQ' en la bajada del pulso  T1 y se utiliza como una señal chip select en la memoria y se desactiva a la bajada del pulso T3, también se activa  RD' a la bajada del pulso T1 y se desactiva a la bajada del pulso T3.  En T2 con MREQ', RD' y el bus de direcciones, los tres activos, lee de memoria un byte y se envía por el bus de datos al cpu.
      
El ciclo de escritura activa MREQ' en la bajada del pulso T1 y se desactiva en baja del pulso  T3 y la señal WR' se activa en la bajada del pulso T2 y se desactiva en bajada del pulso  T3. En T2 con MREQ', WR', el bus de direcciones activos y se escribe en memoria un byte del bus de datos. Para memorias de respuesta lenta el cpu utiliza tiempos de espera Tw en T2 para recibir los datos. La señal WR' se desactiva medio ciclo antes de que la dirección y datos cambien para  satisfacer el traslape de algunas memorias.

Ciclos de Entrada y Salida
      
El ciclo de entrada usa tres tiempos, inicia con la señal activa IORQ' en la bajada del pulso T1 y se desactiva a la bajada del pulso T3, también se activa  RD' a la bajada del pulso T1  y se desactiva a la bajada del pulso T3.  En T2 se introduce un tiempo de espera WAIT para asegurar la respuesta  del dispositivo de salida. También en T2 con IORQ', RD' y el bus de direcciones, los tres activos, lee de memoria un byte y se envía por el bus de datos al puerto de salida. Tiene 256 puertos de entrada.
      
El ciclo de escritura activa IORQ' en la bajada del pulso T1 y se desactiva en baja del pulso T3 y la señal WR' se activa en la bajada del pulso T1 y se desactiva en bajada del pulso T3. En T2 se introduce un tiempo de espera WAIT para asegurar la respuesta del dispositivo de entrada. También en T2 con IORQ', WR', el bus de direcciones, los tres activos,  escribe en memoria un byte del bus de datos que vienen de un puerto de entrada. La señal WR' a veces se utiliza como una señal de reloj para los dispositivos. Tiene 256 puertos de salida.

Ciclo de Interrupción Enmascarable
                  
La cpu reconoce una interrupción  INT' de algún dispositivo, en la subida del último tiempo de la instrucción que se esta ejecutando, la señal no es aceptada si el flip flop IE no está activo o si la señal BUSREQ esta activa. Si la interrupción es acepta se activa un ciclo especial M1 en T1 hasta T3, también se activan MREQ' y IORQ' en el primer tiempo de espera Tw permite que el dispositivo coloque un vector de 8 bits en el bus de datos y dos estados de espera son agregados para facilitar una interrupción de prioridad ripple e identificar el dispositivo que envió el vector de interrupción, MREQ' y IORQ' se desactivan en T3.

Ciclo de Interrupción no Enmascarable                
Es una interrupción de la más alta prioridad y no puede desactivarse por softwate y necesita una respuesta inmediata, por ejemplo la falla de la fuente de alimentación. Es parecido a un ciclo de lectura de memoria, excepto que el bus de datos es ignorado y almacena el contador del programa en un stack externo y salta a la dirección 006H dónde ejecuta una rutina de servicio de interrupciones no enmascarables.
En T1 el contador del programa se envía al bus de direcciones hasta T2 y en T3 inicia un refresh de la memoria y termina en T4. M1 inicia en la subida del pulso T1 y termina en la subida del pulso T3. MREQ' y RD' inician en la bajada del pulso T1 y terminan en la subida del pulso T3. RFSH inicia en la subida del pulso T3 y termina en la bajada del pulso T4.

Ciclo de Acceso a Memoria Directo DMA
                   
La señal BUSREQ' es aceptada en la subida del último tiempo de la ejecución de una instrucción o ciclo de máquina. Cuando es reconocida pone en alta impedancia los buses de direcciones, datos y desactiva las señales RMEM', IOREQ', RD', WR' y RFSH y no puede ser interrumpido por INT o NMI. El cpu envía la señal BUSACK' para reconocimiento de la solcitud aceptada a un dispositivo controlado por acceso a memoria directo DMA, que llevará el control de los buses, así como el refresco de la memoría dinámica si es necesario, hasta que el dispositivo envie otra interrupción del fin de la transferencia de datos.
Ciclo de la Instrucción HALT
Cuando se ejecuta la instrucción HALT también ejecuta instrucciones NOPs hasta que una interrupción INT o NMI llega al cpu y son aceptadas si esta activo el flip flop IE. las interrupciones son capturadas en la subida del pulso T4 y en el siguiente ciclo da un reconocimiento a la interrupción y NMI tiene mayor prioridad que INT. El propósito de ejecutar NOP es mantener activa la señal RFSH. Cada ciclo de HALT es un ciclo M1' excepto que el dato recibido de memoria es ignorado y la instrucción NOP es forzada en el cpu.

Lenguaje Ensamblador Z80
Un programa está constituido por una secuencia de instrucciones para resolver algún problema. El ciclo de instrucción se repite hasta que se encuentre la última instrucción del programa.
El emulador TRS-80 contiene la computadora TRS80 III con un sistema operativo Newdos80,  debe cargarse en la memoria RAM para iniciar su operación y tiene muchos programas y rutinas, al final uno de ellos es el programa de comandos que  entra en un loop o de repetición de una secuencia de instrucciones esperando algún comando que llama otro programa para ejecutarse, por ejemplo el interprete de Basic, el programa editor y ensamblador EDTASM o el programa Debug como veremos más adelante.
Programar en lenguaje binario de unos 1 y ceros 0, sería muy complicado y engorroso, para evitarlo se utilaza un lenguaje ensamblador para codificar el programa y un traductor ensamblador para convertir el programa al lenguaje binario que entiende el Z80.
El lenguaje ensamblador del Z80 tiene un formato en una línea de texto:
Etiqueta          Código de Operación          Operandos o Datos          ;Comentario
Una etiqueta con un nombre, la operación con un nombre o mnemónico, los operandos o datos algunas veces con nombre de los operandos y al final un comentario que inicia con ; punto y coma, pero también se pone al inicio de la línea de texto cuando toda la línea es un comentario.
El lenguaje ensamblador también tiene pseudo instrucciones que no tiene equivalente a una instrucción del Z80. El punto y coma ; indica un comentario. ORG dir Indica la dirección de inicio del programa. EQU define variables del programa, con hasta 6 letras, por facilidad se definen al inicio  del programa, otras como DEFB define una constante de un byte, DEFW define una constante de una palabra de dos bytes, DEFM define una área de memoria para mensajes y DEFS define áreas de trabajo.
END indica el final del programa y siempre debe ser la última instrucción.

 
                      

Microcomputadora TRS80 III
La microcomputadora trs80 III  que utilizaremos para programar en lenguaje ensamblador. Tiene un microprocesador Z80, memoria de hasta 64 Kbytes, la memoria de tipo solo lectura es el ROM II de 12 Kbyte que contiene el interprete Basic. La memoria de escritura y lectura RAM de 4 Kbytes hasta 48 Kbytes. Un teclado o Keyboard como dispositivo de entrada. Un monitor o Video como dispositivo visual de salida. De uno a cuatro unidades de disco flexible o Floppy Disks como dispositivos de entrada y salida, la unidad cero siempre tiene el disco del sistema operativo Newdos80 u otro sistema, los otros tres puden usarse para guardar archivos de  datos y programas.
El disco floppy o flexible puede tener 35 o 40 tracks, cada uno tiene 10 sectores y cada sector tiene 256 bytes. Lógicamente se organizan como granulos de cinco sectores. Los primeros tracks 1 y 2 contiene el sistema operativo, el track 0 y sector 0 contiene el boot del sistema y los demas los módulos sys0, sys1 hasta el sys13. El track 17 contiene el control del asignamiento del espacio utilizado por los archivos, en el sector 0 está la tabla de asignación de granulos GAT para los archivos y en el sector 1 la tabla index hash HIT para la seguridad de los archivos. El sector 2 al 9 contiene la entrada al directorio de archivos primarios FPDE y si es necesaria la entrada a la extensión del directorio de archivos FXDE  cuando es grande el archivo. Cada entrada tiene 32 bytes para cada archivo  hasta un total de 64 archivos. Para utilizar el disco en un programa se debe abrir y asignar un nombre al archivo en un block de control de datos DCB de 32 bytes que tiene varios parámetros. Ahora se pueden hacer operaciones de búsqueda, lectura y escritura al disco, cuando se termina de usar hay que cerrar el archivo. También puede conectarse una impresora y un modem para comunicaciones no incluido en el emulador. Cuando usamos el sistema operativo Newdos80 del disco floppy de la unidad 0 que lo contiene, se carga con el programa boot en la memoria de escritura y lectura RAM usa 16 Kbytes todos los programas, pero solo se cargan sys0 hasta sys6 y todos los demás se cargan cuando se necesiten, en una área de traslape u overlay. Las rutinas son para utilizar los discos flexibles para escribir y leer archivos de programas y datos desde el Basic ROM II o del editor y ensamblador EDTASM que  está incluido en Newdos80.

Usaremos un teléfono inteligente con Android4 para instalar el emulador TRS-80 del  microcomputador TRS80 III que contiene el sistema operativo Newdos80 y tiene el interprete Basic ROM II, también el lenguaje ensamblador EDTASM y este lo usaremos para programar en lenguaje ensamblador del Z80.
Los pasos para instalar y usar el emulador TRS-80 son los siguientes.
1.Buscar en google play el emulador TRS-80 e instalarlo.
2.Presionar el ícono de TRS-80 y aparecen cuatro Modelos del TRS-80 usaremos el último que corresponde a TRS80 III y el sistema operativo Newdos80.

3.Presionamos el menú izquierdo y aparecen  varias opciones, seleccionamos Resume o Start y aparece una pantalla con NEWDOS/80 la fecha y hora, el mensaje Newdos/80 y READY
.
4.El sistema está listo para recibir comandos del sistema operativo, como DIR para ver el directorio de archivos texto y programas. LIST archivo, para desplegar un archivo de texto. FREE para ver los granulos o espacio libre del disco flexible. COPY archivo1 archivo2  para copiar un archivo. RENAME archivo1 archivo2 para cambiar el nombre de un archivo. KILL archivo para eliminar un archivo. Hay muchos más comandos, pero primero introducimos el comando DIR para ver el contenido del disco flexible de la unidad 0  y vemos a EDTASM.

5.Introducimos EDTASM y aparece la pantalla del editor con un asterisco * indicando que puede aceptar comandos de edición: I- Insertar lineas D- Eliminar línea R-Remplazar líneas P-Desplegar líneas. Los comandos utiliza una línea o un rango de líneas, indicado por dos puntos: como D120:150 elimina las líneas 120 hasta la 150. El símbolo gato # significa la primera línea y el asterisco * la última línea.  Por ejemplo P#:* significa desplegar todas las líneas de texto.

6.Crearemos un programa de varias instrucciones. Escribimos solo I para introducir líneas de texto, aparece la línea 100  y se va  incrementando en 10. Ahora introducir el  siguiente programa que hará una simple suma.
100                  ORG       7000H
110 DATO1    EQU    2
120 DATO2    EQU    2
130                  LD          A,DATO1
140                  LD          B,DATO2
150                  ADD       A,B
160                  CALL      440DH
170                  END
ORG es una pseudoinstrucción que indica la dirección 7000H de inicio del programa. EQU asigna valores a las variables DATO1 y DATO2. Las pseudoinstrucciones no generan código.
LD carga el registro A y B con 2.
ADD Suma el registro B a A.
CALL 440DH llama a DEBUGER, programa para ver la memoria y registros del programa.
END termina el programa.
Para salir de insertar instrucciones  presionamos la tecla BREAK.

7.Ahora ensamblaremos el programa con A /NO/WE indicando con NO de no generar el programa objeto y WE que pare en error. Si salen errores de ensamblado se despliegan en la pantalla, hay que corregirlos utilizando R línea  para reemplazar la línea por una  corregida y repetir el paso 7 hasta eliminar todos los errores.
8.Guardamos nuestro archivo de programa fuente sin errores con: W D=PZ/SRC
9.Cuando el programa está sin errores introducir solo A y pide el nombre del archivo del programa objeto PZ/CMD y ahora sale un mensaje de crear el archivo y se pone C.
10.Ahora salimos del EDTASM introduciendo B para regresar al sistema operativo Newdos80 y aparece ready listo para recibir comandos.
11.Introducimos DIR y aparece el directorio con PZ/SRC el programa fuente y PZ/CMD el programa objeto listo para ejecutarse.
12.Introducimos PZ/CMD y se ejecuta el programa objeto, no aparece nada en la pantalla solamente usamos la instrucción load  LD de cargar el registro A y B con 2H y ADD A,B sumando registro B a A e indica una ejecución correcta de otro modo desplegaría un error. Ahora usaremos DEBUG para ver la memoria y los registros del programa.
13.Salimos del sistema y con task manager damos kill al programa TRS-80. Volvemos a entrar a TRS-80 y damos RESUME.

14.Aparece READY e introducimos DEBUG aparece READY e introducimos PZ/CMD ahora aparece la pantalla X de DEBUG con tres areas de  memoria desde la dirección 0000 separadas por los registros.

15.Introducimos el comando D7000 y despliega la memoria desde la dirección 7000 y observamos nuestro programa en hexadécimal:
7000-3E02 0602 80CD 0D44 0000
Identificamos las instrucciones:
3E02-LD A,2H
0602-LD B,2H
80-    ADD A,B
CD0D44-CALL 440DH
Ahora lo convertimos en Binario
    7       0      0        0       3       E      0      2
0111 0000 0000 0000-0011 1110 0000 0010
    0      6        0       2       8      0       C      D
0000 0110 0000 0010 1000 0000 1100 1101
    0      D      4       4   
0000 1101 0100 0100
Es increíble y sorprendente que un programa de una computadora se represente y entienda un lenguaje binario de solo 1 y 0 y físicamente de voltajes de 5 volts y 0 Volts y por lo tanto de corrientes muy pequeñas.

16.Ahora introducimos G7000 y se ejecuta el programa, observamos el registro A con un valor de 4, comprobamos que se realizo la suma de 2+2.
AF=0400

17.Para regresar al sistema operativo introducimos G0000 con esto damos un RESET iniciando la carga del sistema operativo Newdos80.

Es increible y maravilloso que en nuestro teléfono inteligente con Android  que cabe en la palma de la mano, estamos emulando una microcomputadora TRS80 III que fué una de las primeras microcomputadoras, antes que apareciera la PC de IBM, pero no cualquiera podía tener una, era cara y nada fácil de usar, se necesitaban conocimientos de computación. Ahora tenemos la oportunidad de usarla en nuestro teléfono inteligente con el emulador TRS-80. Con esto iniciamos un curso usando el emulador  y veremos en detalle todas las instrucciones del microprocesador Z80 y con el editor ensamblador EDTASM haremos varios programas. También usaremos el programa DEBUG para ver la memoria y registros de los programas. Estudiaremos el funcionamiento interno de la TRS80 III y del sistema operativo Newdos80,  esto es simplemente por gusto e interés de saber cómo funciona el microprocesador Z80 en la microcomputadora TRS80 III con el emulador TRS-80. Todo esto como una base para posteriormente estudiar algo más complejo, el microprocesador ARM que la mayoría de los teléfonos inteligentes lo usan junto con el sistema operativo Android.

No hay comentarios: