OK, decided to upload my code here. It is attached to this message. If you'd like you can have a look at it, Unseen.
It comes with the Xilinx project file. The constraint file used to be for my own FPGA board, but I changed it back to the Pluto IIx board. That also means I had to change the inversion of the Green and Blue TMDS outputs in hdmidirectv:
Code: Select all
TMDS_shift_red_delay<=(videoGuardBandDelayed[1] ? 10'b1011001100 : (dataGuardBandDelayed[1] ? 10'b0100110011 : (tercDataDelayed[1] ? TERC4_red : TMDS_red)));
TMDS_shift_green_delay<=~((dataGuardBandDelayed[1] || videoGuardBandDelayed[1]) ? 10'b0100110011 : (tercDataDelayed[1] ? TERC4_green : TMDS_green));
TMDS_shift_blue_delay<=~(videoGuardBandDelayed[1] ? 10'b1011001100 : (tercDataDelayed[1] ? TERC4_blue : TMDS_blue));
So how does it work? I have changed the blanking_regenerator to generate a pulse of one cycle (HBlankStart) when a blanking period is about to begin. When a blanking period is about to end I also sent a pulse (HBlankEnd):
Code: Select all
-- generate HBlankStart and HBlankEnd
if current_pixel = (hor_active_end-1+7) then -- working: (hor_active_end-1+7)
HBlankStart <= '1';
else
HBlankStart <= '0';
end if;
if current_pixel = (hor_active_start-11+7) then --working: (hor_active_start-11+7)
HBlankEnd <= '1';
else
HBlankEnd <= '0';
end if;
The +7 is because the video signal is delayed by 7 extra cycles while traveling through the scanline generator, osd and yuv to rgb (and an extra cycle is added in the toplevel). The HBlankStart and HBlankEnd go to the hdmidirectv component, which will start counters when a pulse is received. That way it will know when to do the dataguardband, videoguardband, terc4 data etc.
Currently it only seems to work for 576p and 480p signals for me. My TV will not sync to interlaced signals. To display interlaced signals you need to enable the linedoubler. The problem, as already described before, is that my TV will usually not sync to the HDMI signal at all. The TV will say that there is no signal at all. When I turn my cube on and off however, or if I reprogram the GC a few times using JTAG or I turn on and off my TV, it will sometimes successfully sync and display the video with audio just fine. This also means that if you want to try out the code, there is a good chance your TV will not display it at all.
Something interesting: once my TV finally syncs with the signal it will flawlessly accept resolution changes. For instance when going from the linedoubled 576i menu (so 576p over HDMI) to 480p video in Swiss.
I have also added an extra toplevel (toplevel_testpattern_p2x.vhd). If you synthesize that one, a 480p testpattern is displayed instead of the processed gamecube video. For me this pattern works flawless. TV always displays it and it is mixed successfully with the GC's audio to a HDMI signal.
One more thing, currently I always send a 480p 4:3 VIC. My TV will still display 576p signals, even with this VIC. However, I guess some TVs will not like this. So maybe it is a good idea to try this code out with a 480p game. If you use the video testpattern it is not a problem ofcourse.
Hopefully someone else (Unseen?) can have a look at the code as well, so we can get this to work completely stable.