mcleod_ideafix escribió:mcleod_ideafix escribió:Por cierto, y en aras de colaborar para que JSpeccy sea aún más exacto...
Prueba también esto otro. Es un programa que escribí para gastar una broma, pero en JSpeccy parece que hace mucho más que impedir que NMI funcione: no puedo reiniciar el equipo, ni hacer un reinicio total... y hasta el mensaje que debería aparecer con FLASH, ¡aparece sin él!
Modificando los cores Z80 para evitar ese problema me he encontrado con un error en el tu "broma" o con algo que no veo bien como funciona.
Según creo, la NMI se comprueba en el último ciclo de máquina de la instrucción en curso. Como es una señal activada por flanco negativo, cuando se produce la CPU la almacena en un latch a la espera de que pueda atenderla.
Al final de la instrucción se mira por este orden:
- BUSRQ
- NMI
- INT
Tu programa llena de 0xFD la RAM entre 0x5B00 y 0xFFFF y luego pone en los tres últimos bytes un JMP 0x5B00. Ese es el primer "fallo" del programa, porque el Z80 la trata como una instrucción larguísima acabada en un JMP. Al final del JMP se mira la NMI y se salta a 0x0066 poniendo PC en la pila. Luego la rutina de la ROM guarda con PUSH AF y HL. La pega de eso es que el registro SP está apuntando 32744, lo que machaca 6 de los 0xFD que habías puesto tú. Y pone lo que hay en PC (0x5B00) y lo que hubiera en AF y HL. Cuando la secuencia de 0xFD llega a esas direcciones lo que ejecuta es un truño
que a saber lo que acaba haciendo, podría mirarlo pero no creo que merezca la pena. Y la NMI funciona, ya lo creo que funciona.
La única manera de hacer eso es en el +2a/+3. Llenas las páginas de 0 a 3 con 0xFD, y al final, pones el modo All-ram. Ahí sí se acabó la NMI.
Eso suponiendo que detrás de la NMI haya un latch que resetea la CPU al atender la NMI. Si no, ya no sé cuando y como muestrea NMI.
P.D.: Me extrañaba mucho que el asunto no se volviera loco y empezara a ejecutar cosas al estilo Belén Esteban. Tanto me extrañaba que me he entretenido en ver lo que ejecutaba (y no podía con el depurador de Fuse porque peta al intentar desensamblar una caterva de 0xFD). Y lo que me sale es casi diabólico:
Da igual donde pulses NMI porque saltará en el JMP y la dirección de RETN que meterá en la pila será la de 0x5B00. Como no se trabaja con registros y el único que se toca es el B, y ese no está implicado en la rutina de manejo de NMI de la ROM, siempre mete lo mismo. Pero el registro A tiene el valor 0xC3 (JMP) que es exactamente lo que necesita después para poder ejecutar la dirección de vuelta de RETN. Y como en la variable del sistema NMIADD hay un FDFD, no es cero y por tanto no salta a la dirección cero de la ROM. En resumen, que es un programa que da el pego porque parece que no hace nada, pero la NMI sí funciona y si tienes un Multiface o el propio DivIDE en ZX-Uno, que usan la NMI funcionan.
O es el código más ingenioso de la historia, o el día que lo parió, mcleod debió haber hecho una primitiva en su lugar, ahora estaría doblao a piñas coladas en Copacabana rodeado de pibones para el resto de su vida.