Habi Hablóg
Declaro:
XML válidoXHTML válido800x600 +
RSS válidoCSS válidoNavegador digno
  Blog   Archivo   Contacto   Administración  

Acerca de

Matemático, informático, aficionado a la electrónica, friki... y otras cosas que no vienen a cuento ni pasan los filtros de palabras.

¿Queríais un blog? Ahí va.

Red antisocial

¡Me van a volver loca! 2.0
La Fragata Portuguesa

Z
¡Me van a volver loca!

Últimos posts

El expediente X que nadie pidió
eNigma
La cuadratura del píxel
Portando desde Spectrum
Inexorable

Últimos comentarios

Habi
NoSupoResolverLaFuncion
Edu
Habi
EnriqueGG

Calendario

No hay fechas.

Categorías

Chorradas
Paranoias
Posts lúcidos
Tecnoesoterismo
Yuyus

Cenas de Abj

Abj debe 7 cenas.

Frase célebre

Abjurador (porque el mundo me ha hecho así) dice: Vale; pero tú eres homeomorfo a tu madre.

Aclarando cosas

Habi - 22/08/2013 23:07:39 - Tecnoesoterismo

Si alguien se pone a intentar emular un Z80 lo más fielmente posible, al final se encontrará emulando el registro interno MemPTR (también llamado WZ).

Es uno de esos registros internos de los procesadores para efectuar sus operaciones intermedias; el problema es que con cierta instrucción pueden leerse dos bits del mismo en dos flags indocumentados, de ahí que sea "necesaria" su implementación.

Se recomienda una lectura del tema en: [link].

Y este es mi punto de partida, ese documento y su ambigüedad en ciertas cosas. Por ejemplo:

1) En la lista aparecen Ret y RetI, pero no aparece RetN. ¿Acaso su microcodificación es tan diferente (la asignación del Iff correspondiente bien puede hacerse en paralelo, el resto es idéntico)? Resulta extraño creer que RetN no modifique MemPTR.

2) Aunque el documento habla de interrupciones no aclara si es sólo para las mascarables. Internamente las NMIs son bastante bizarras, pues hay un ciclo pseudo fetch (con lectura incorporada) antes de su tratamiento. Sin embargo un salto es un salto, e internamente sólo se pueden saltar a registros, luego debiera estar incluída. Otra cosa a verificar.

3) El documento menciona las instrucciones In A, (C) y Out (C), A. Pero hay un bloque entero de instrucciones In r, (C) y Out (C), r para r en [A, B, C, D, E, H, L, x]. El valor que he marcado con x no está documentado y correspondería como es lógico a (HL), pero dada la estructura del procesador no se puede acceder a memoria. El resultado es que en lectura no se asigna a ningún registro lo leído, y en escritura se pone en el bus externo el contenido del bus interno del procesador ($00 en NMOS, $FF en CMOS para un Z80 estándar).

Desgraciadamente, ningún programa de test mira otras instrucciones que no sean las que aparecen en esa lista (y el caso de la NMI es un tanto rebuscado, lo admito).

La lógica nos dice que debiera haber modificación de MemPTR en los 3 casos aunque las instrucciones no aparezcan en la lista. Y como veremos, es lo correcto.

Hoy que he tenido un rato he decidido despejar todas las dudas; me basta con construir un contraejemplo en cada caso, así que vayamos por partes:

 

Caso 1

Consideremos el siguiente programa rápido (para Spectrum):

	Org	$8000
	Di
	Ld	Hl, Siguiente
	Push	Hl		;Retorno para RetN
	Ld	A, ($FFFE)	;MemPtr=$FFFF
	RetN			;MemPTR = $80xx; bits 13 y 11 a 0
				;HIPÓTESIS
	Siguiente:
	Bit	0, (Hl)	;MemPtr a flags
	Push	Af
	Pop	Bc		;En C
	Ei
	Ld	A, %00101000
	And	C
	Ld	C, A
	Ld	B, 0
	Ret

Haciendo PRINT USR 32768 debiera escribirnos un valor: 40 si MemPTR no se modifica o 0 si lo hace. Como era de esperar, el resultado es 0, luego la lista tiene una errata en ese punto (debieran haber añadido RetN junto a Ret y RetI).

 

Caso 2

Comprobar la NMI es un tema peliagudo: tenemos que tener nuestro código en $66 (ROM por defecto en la mayoría de los ordenadores basados en Z80) y ser capaces de generar una NMI cuando queramos; a ser posible sin hardware externo.

Afortunadamente, hay un ordenador en el que eso es posible: ¡el PCW!

El controlador de disco NEC 765 genera interrupciones; normalmente no se tienen en cuenta en la arquitectura (p.ej. Spectrum +3, Amstrad CPC) pero sí en el caso del PCW. Y aún es más: pueden ser dirigidas a ningún lado (deshabilitadas), a la interrupción enmascarable y a la no enmascarable.

El programa aquí es un tanto más complicado, pues rápidamente deshabilita interrupciones, relocaliza un trozo en la dirección $66 para atender a la NMI, reprograma el Gate Array, y apaga el motor del disco (no lo hará la BIOS pues tenemos deshabilitadas las interrupciones). Al deshabilitarse la rotación del motor un momento después (y por variación de la línea /READY) tenemos nuestra bonita NMI. Simplemente la esperamos con un Halt (y las interrupciones deshabilitadas).

Al no poder imprimir fácilmente números, también hay que incorporar esas rutinas de soporte, restaurar las cosas como estaban, etc. Por todo lo anterior el programa es bastante más largo, así que por razones de longitud no lo listaré aquí.

La conclusión: se modifica MemPTR también. No lo considero una errata, si bien hubiese estado bien añadir una aclaración.

 

Caso 3

De nuevo un programa rapidito en Spectrum:

	Org	$8000
	Di
	Ld	Bc, $FFFE	;No pasa nada por escribir a ULA
	Ld	A, (0)		;MemPtr=1
	Out	(C), C		;MemPtr = $FFFF HIPÓTESIS
	Bit	0, (Hl)	;MemPtr a flags
	Push	Af
	Pop	Bc		;En C
	Ei
	Ld	A, %00101000
	And	C
	Ld	C, A
	Ld	B, 0
	Ret

En este caso haciendo de nuevo PRINT USR 32768 obtenemos un resultado, si bien aquí es al revés: 0 indica que MemPTR no se modifica y 40 que sí lo hizo. Y así sucede, y de nuevo una errata: se debiera cambiar en esas instrucciones la "A" por "r", donde r es un registro de 8 bits. Se cumple para todos los casos (los cambios en el programa son triviales).

 

Moraleja: verificar siempre antes las cosas uno mismo; me toca hacer un par de cambios por haberme fiado. sad


setapeta - 23/08/2013 9:51:54

Y mira que te lo he dicho veces, que no pasa nada por escribir a ULA.



SyX - 18/03/2014 23:10:39

Como no voy a querer pedirte una beta de cierto emulador con Z80, es que me quitas una cantidad de problemas con esa pedazo de emulación de Z80 que se traga todas las perrerias ;)




Post cerrado