El puñetero T80... pasa olímpicamente de actualizar los flags cuando se ejecuta una instrucción LD A,R o bien LD A,I . Sólo actualiza el flag P. Los demás, no los toca. Sin embargo, según la guía del Z80 Indocumentado, se tocan todos los flags excepto el de acarreo.
¿Y qué pasa? Pues que el King's Valley depende en su lógica de que dicha instrucción funcione correctamente. En un montón de sitios en el programa hay bucles que sólo salen cuando se da esta condición:
Código: Seleccionar todo
LD A,R
RET M
Y claro... El flag de signo jamás se actualiza con la instrucción anterior, y por tanto, el bucle donde esté esto deviene en bucle infinito.
Concretamente, en la descripción de la última versión del T80 publicada en OpenCores te puedes encontrar esto:
Código: Seleccionar todo
if Special_LD(2) = '1' then
case Special_LD(1 downto 0) is
when "00" =>
ACC <= I;
F(Flag_P) <= IntE_FF2;
when "01" =>
ACC <= std_logic_vector(R);
F(Flag_P) <= IntE_FF2;
when "10" =>
I <= ACC;
when others =>
R <= unsigned(ACC);
end case;
end if;
end if;
Esta es la parte de descripción que maneja las cargas "especiales" (desde/hacia los registros I y R). Los dos primeros casos son los que cubren las instrucciones LD A,I y LD A,R respectivamente. ¿No falta algooooooo? Si no lo veis, echad un vistazo a la página 27 del Z80 Undocumented de Sean Young y vereis. Ese trozo de código debería ser así (o si no así, algo parecido):
Código: Seleccionar todo
if Special_LD(2) = '1' then
case Special_LD(1 downto 0) is
when "00" =>
ACC <= I;
F(Flag_P) <= IntE_FF2;
F(Flag_S) <= I(7);
if I(7 downto 0) = "00000000" then
F(Flag_Z) <= '1';
else
F(Flag_Z) <= '0';
end if;
F(Flag_Y) <= I(5);
F(Flag_H) <= '0';
F(Flag_X) <= I(3);
F(Flag_N) <= '0';
when "01" =>
ACC <= std_logic_vector(R);
F(Flag_P) <= IntE_FF2;
F(Flag_S) <= R(7);
if R(7 downto 0) = "00000000" then
F(Flag_Z) <= '1';
else
F(Flag_Z) <= '0';
end if;
F(Flag_Y) <= R(5);
F(Flag_H) <= '0';
F(Flag_X) <= R(3);
F(Flag_N) <= '0';
when "10" =>
I <= ACC;
when others =>
R <= unsigned(ACC);
end case;
end if;
end if;
DIcho y hecho: King's Valley funciona. Cobra funciona (¡¡la primerísima versión, con puerto $FF!!). No echemos aún las campanas al vuelo. Cosas como el ula-test3-modified siguen colgándose, pero vamos, para un enfermito convaleciente es suficiente por hoy


Se ha actualizado el test11 con estos cambios. A sugerencia de Andrew Owen, he puesto en el MCS la versión estable (4.0) de la Open SE.
Nota informativa: en este momento, estamos al 87% de ocupación total de la FPGA.