-
Notifications
You must be signed in to change notification settings - Fork 18
LOG
Esto son notas en sucio, sobre el desarrollo del proyecto
Hay un problema de lectura de memoria. Lo he conseguido acotar al siguiente prograama mínimo:
org 0x0000
ld a, (0x0000)
out (0x40), a
halt
Carga en el registro A lo que hay en la dirección 0 (que es el opcode de la propia instrucción: 3A), y lo saca por los LEDs. En los LEDs se debería ver 0x3A en binaario: 0011_1010, pero están apagados
El código máquina generado es:
@00000000 3A 00 00 D3 40 76
Que es correcto...
Para buscar el error vamos a partir del ejemplo "hola mundo" que sí funciona: enviar un valor a los LEDs:
org 0x0000
ld a, 0xAA
out (0x40), a
halt
Al cargarlo aparece el valor binario 1010_1010 en los LEDs. OK!
Vamos a usar el analizador lógico para visualizar algunas señales del procesador, y entender bien el core y lo que está ocurriendo. El core original el proyecto Z0mbie sí funciona correctamente, por lo que debe haber alguna errata al pasarlo a Icestudio
Estoy tomando medidas... pero hay algo extraño al arrancar. Parece que la inicialización no se hace bien...
He vuelto a la versión V7, en la que se envía la secuencia 0xF0 y 0x0F. Aquí funciona.. Voy a partir de ella para volver a integrarla en Icestudio y seguir con las pruebas... El firmaware que estoy usando lo dejo "congelado". El fichero de memoria es el siguiente:
@00000000 C3 00 01
@00000008 ED 4D
@00000010 ED 4D
@00000018 ED 4D
@00000020 ED 4D
@00000028 ED 4D
@00000030 ED 4D
@00000038 ED 4D
@00000100 31 FF 9F CD 35 02 CD 1B 02 C3 04 02
@00000200 3E 02 CF C9 3E 00 CF 76 18 FD 11 00 00 21 02 00 39 7B 96 7A 23 9E D0
@00000217 00 13 18 F2 3E 0F D3 40 21 FF FF E5 CD 0A 02 F1 3E F0 D3 40 21 FF FF
@0000022E E5 CD 0A 02 F1 18 E6 C9
Este mismo fichero lo voy a probar en la versión actual de icestudio... Lo renombro a rom.list y lo cargo con icestudio.... ok... NO funciona!!! ok... Vuelvo para atrás a ver dónde está el problema....
¡¡He encontrado un bug!! la lógica de selección de la ram y la rom es incorrecta. Yo estaba pensando que era lógica positiva, pero es negativa. He añadido dos puertas inversoras y ahora el rom.list anterior funciona!
Las buenas noticias son que ese programa usa la pila y llamadas a procedimiento. Ahora la RAM funciona... sin embargo con el programa que hace 2 outs no va. Parece que hay otro bugs.... Voy a seguir indagando
Pruebo con el programa original de sacar 0xAA por los puertos y tiene el mismo problema anerior de que tarda mucho activarse halt. Demasiados ciclos.. Así que vuelvo hacia atrás. Voy a probar con la versión V12 que es la última en C, y que usa Icestudio. Voy a probar diferentes programas de ejemplo sencillos
.module crt0
.area _HEADER (ABS)
;; Reset vector
.org 0
init:
ld a,#0x55
out (0x40),a
halt
Este funciona correctamente, usando el SDCC. El código máquina es:
@00000000 3E 55 D3 40 76
Ahora pruebo con direccioamiento directo, a ver qué pasa...
.module crt0
.area _HEADER (ABS)
;; Reset vector
.org 0
init:
ld a, (0x0000)
out (0x40),a
halt
.area _DATA
El código máquina es:
@00000000 3A 00 00 D3 40 76
Y efectivamente sale 3A por los LEDs... Voy a probar el mismo código máquina en la última versión de github... Joder... sí que funciona.... Y los códigos máquinas generados son los mismos...
Pruebo con otro programa:
.module crt0
.area _HEADER (ABS)
;; Reset vector
.org 0
init:
ld a, (0x0000)
out (0x40),a
inc a
out (0x40),a
halt
.area _DATA
El código máquina es:
@00000000 3A 00 00 D3 40 3C D3 40 76
Este programa debería sacar por los LEDs el número 3B: 00111011
ups... me saca FF.... en la versión V12 hay algo que tampoco va bien...
Voy a seguir avanzando. De momento la lectura de variables de memoria funciona (direccionamiento directo)
He hecho dos releases, la v1.0.0 y la v1.1.0. Ambas tienen los mismo elementos: 8KB ROM, 8KB RAM y un puerto de salida conectado a los LEDs. En la V1.0.0 se mantiene la estructura del proyecto Z0mb1e, pero en la V1.1.0 se han hecho cambios para que sea más fácil de entender: paso a lógica positiva, reorganización de los bloques, etc... Pero esencialmente son similares
El proyecto ha avanzado mucho. Vamos por la release V1.3.0, que tiene una RAM/ROM de 16KB (Direcciones 0x0000 - 0x4000), una uart mapeada, un puerto de salida, uno de entrada que permite leer el pulsador SW2 y lo más importante: carga del firmware a través de un bootloader hardware
He detectado los siguientes problemas:
- El auto-reset a través del DTR no se hace bien algunas veces. Al no funcionar no entra en modo bootloader y no carga
- Al arrancar un terminal, el DTR se activa y entra en modo bootloader. Solución: Bien usar el RTS (hay que comprobar si se activa automáticamente) o bien implementar un timeout
- Si entra en el modo bootloader porque se activa el DTR por la razón que sea, hay que hacer reset manual para salir. Solución: Implementar un timeout
- El cargador python no tiene feedback de lo que está pasando. Solución: usar las otras líneas de control para codificar los estados de Reset ok (modo bootloader on) y carga finalizada
Como primer paso para detectar el problema del reset voy a ver si es debido al cargador (que no baje la señal el tiempo suficiente o cualquier otra cosa). Es problema del software o del hardware?
No consigo reproducir el bug del reset. Ocurre tan aleatoriamente que es difícil... Voy a hacer más programas de prueba del z80, a ver si mientras desarrollo consigo reproducirlo
Me he liado a programar... antes de abordar los bugs voy a probar otra cosa: a ejecutar un programa más complejo, para verificar que el Z80 está bien
Voy a intentar poner en marcha el Tiny Basic que tiene jotego en su github: https://github.com/jotego/jtframe/tree/master/asm/z80
Antes de modificar nada, vamos a analizarlo. Generamos el ejecutable con make. Aparecen dos ficheros: Basic.bin y Basic.lst. Analizando este último vemos que comienza en la dirección 0x0000 (claro) y termina en la 0x075C, es decir, que su tamaño es MENOR a 2K
La disposición original es:
- 0x0000 - 0x0800: ROM (2K)
- 0x8000: Variables
- 0x087FF: PILA (2K)
Yo tengo 16KB. Mi mapa de memoria será el siguiente:
- ROM: 0x0000 - 0x0800 (2K)
- Variables: 0x0800-0x0F00
- Pila: 0x3FFF
Lo he cambiado en el código. Empieza ejecutando la rutina INIT. He hecho que se envíe por los LEDs el valor 0xFF para comprobar que llega hasta ahí.... OK! Se encienden los leds! El basic está cargado!! Ahora tengo que ver cómo hacerlo funcionar....
Voy poco a poco. Al arrancar ya consigo que envíe el CRLF inicial :-)
uuuueeeee ya me envía cadenas! Puedo ver la primera cadena que envía el intérprete:
Z80 TINY BASIC 2.0g
Madre mía, qué épico es esto!!!!!!!
Llego hasta la etiqueta RSTART: aquí es donde realmente empieza el intérprete. Los mensajes que salen hasta aquí son:
Z80 TINY BASIC 2.0g
PORTED BY DOUG GABBARD, 2017
OK
Madre mía... ya me lee el teclado y el intérprete se está ejecutando!!! Puede escribir cosas y reacciona, aunque no tengo ni idea de qué escribir todavía!! :-)
Z80 TINY BASIC 2.0g
PORTED BY DOUG GABBARD, 2017
OK
>test
WHAT?
OK
>hello
WHAT?
OK
>help
WHAT?
OK
>HELP
WHAT?
OK
>:-)
WHAT?
OK
>
Los comandos escritos de manera aislada están funcionando, pero NO la parte de almacenamiento del propio programa. Tengo que revisar qué está pasando... pero... madre mía... es una pasada!!!!
Z80 TINY BASIC 2.0g
PORTED BY DOUG GABBARD, 2017
OK
>LIST
OK
>PRINT "HOLA"
OK
>LET A=100
OK
>PRINT A/100
1
OK
>INPUT B
B:200
OK
>PRINT B
200
OK
>
Estoy depurando pero no llego a ninguna conclusión. He visto el lugar donde aparentemente se hace una llamada a una subrutina de la que nunca retorna. Anteriormente he encontrado otro punto donde hace algo raro. Estos bugs extraños me hacen dudar de si en el micro he cometido algún error al intergrarlo. ¿Todas las instrucciones funcionan como deberían? Necesitaría algún programa de test. Puedo hacer la prueba de ejecutar el TinyBasic en el antiguo Z80, el que tiene los ficheros en verilog, sólo para ver qué ocurre....
He hecho una prueba rápida con el z80 versión verilog... con los mismos resultados... Tengo que pensar otra forma de depurarlo... Se me ocurren dos caminos por donde seguir...
-
Simular el fichero .bin. Hay que buscar un buen depurador/simulador de z80 y probar el código, para aprender bien qué es lo que está haciendo
-
Hacerme elementos de depuración, como la visualización hardware en los 7 segmentos (spi), o enviar por el puerto serie valores de 6 bits...
-
Buscar programa de test para verificar que el z80 va bien...
Empiezo por la opción 1. En este link hay varios enlaces para procesar:
Empiezo por este:
http://www.mathematik.uni-ulm.de/users/ag/yaze-ag/ y luego seguiré por este:
https://www.autometer.de/unix4fun/z80pack/
Es bastante enrevesado... mejor pruebo otro de momento....
He encontrado la versión en github:
https://github.com/udo-munk/z80pack/releases
Me la he bajado. se descomprime y me voy al directorio: z80pack-1.36/z80sim/srcsim
He renombrado makefile.linux ---> makefile y he ejecutado make. Ya tengo el ejecutable
El problema de este simulador es que no funciona con el ensamblador de gnu. El que usan viene en el propio z80pack y también se llama z80asm. Lo he renombrado a Z80ASM
Del simulador he encontardo poca informació. Pero lo más importante es que con el comando ? sale la ayuda. Con eso podría ir tirando...
En este web he encontrado un poquito de información: http://wiki.joanillo.org/index.php/Home-Built_Z-80_Computer
Hay un tio que usa fuse-emulator (es para espectrum). Al fin y al cabo es un z80....
Voy a explorar la vía de los programas de prueba
http://mdfs.net/Software/Z80/Exerciser/
Este enlace nos lo pasó el usuario Martín Ribelotta en la lista de FPGAwars
https://groups.google.com/d/msg/fpga-wars-explorando-el-lado-libre/U5c7-6gQAqQ/GHfuVFTLAAAJ
Empiezo descargando el YAZE.zip
Para hacer pruebas con el simulador. Compilamos con Z80ASM (Ojo! NO es el de GNU. Es el de Z80pack)
Z80ASM test-1-1-sim.s
z80sim -z
####### ##### ### ##### ### # #
# # # # # # # # ## ##
# # # # # # # # # # #
# ##### # # ##### ##### # # # #
# # # # # # # # #
# # # # # # # # # #
####### ##### ### ##### ### # #
Release 1.36, Copyright (C) 1987-2017 by Udo Munk
CPU speed is unlimited
>>> r test-1-1-sim.bin
Loader statistics for file test-1-1-sim.bin:
START : 0000
END : 000b
LOADED: 000c
>>> x
PC A SZHPNC I IFF BC DE HL A'F' B'C' D'E' H'L' IX IY SP
0000 58 110001 00 00 d77f f880 dae1 80ec 5e1f d5e4 01b8 7b12 3f17 d307
>>> l
0000 - LD A,01
0002 - CP 02
0004 - JP Z,0000
0007 - LD A,AA
0009 - OUT (40),A
000b - HALT
000c - LD D,H
000d - LD D,D
000e - LD (HL),A
000f - OUT (4A),A
>>>
¡Ya tengo los test preliminares del YAZE (prelim.s) pasados! El fichero prelim.s es para ensamblador con el make y cargarlo con el bootloader. Una vez pasados todos los test se deja un led moviéndose (rotación a la derecha)
En el prelim-sim.s tengo el mismo código pero para hacer las simulaciones.
Aunque son test preliminares... madre mía! se prueban cantidad de cosas!!! :-)
Ya tengo todos los test migrados y probados. Algunos fallan sólo en el simulador, otros sólo en el z80 real y algunos en ambos. Los resultados preliminares están publicados en la wiki: Tests
Es el momento de sacar una release