@rogloh said:
I haven't seen Tempest 2000 before, no, but in the meantime I'll try full NeoYume with this and report back.
Update: played NeoYume first level of MSlug - audio survived fine.
Just downloaded and installed dependencies, built Tempest etc. Setup HyperRAM on pin 0 of P2 EVAL, USB board on P16, VGA/AV on P24, HDMI on P32.
I was first able to run with VGA output to prove it actually worked, then reconfigured and built for HDMI by enabling this section below. Confusingly it still mentions a VGA_BASEPIN but this mode indicates and uses HDMI on this pin AFAICT when I dug into the code. I could hear analog audio on VGA board the but no video is shown on HDMI. Not sure my plasma TV accepts 800x480 like this. It's pretty restrictive and only likes HDTV resolutions and probably just 640x480, sorry.
Weird, I cloned the from the link above and it doesn't seem to have video-nextgen in the list of branches. git must be messed up there although I do see it listed on GitHub.
❯ pwd
/Users/roger/Code/Propeller2/tempest2k
❯ git branch -l
* p2port
❯ git pull
Already up to date.
3517 ls
3518 git clone https://github.com/Wuerfel21/tempest2k.git
3519 cd tempest2k
3520 ls
3521 git submodule init
3522 git submodule update
3523 cd mac
3524 cd rmac
3525 make
I've found I can easily get this test driver to output simple DVI instead of HDMI encoding format with the handful of following patches done at COG setup time. This is beneficial in that a DVI monitor can still be used to test timing changes and anything unrelated to audio - for me without a HDMI device handy on my desk this is a good thing. It should probably be part of a driver's feature set.
orgh
' hubexec code
dvi_override sets x1, #hsync0 ' use inactive hsync patterns instead of gaurds/preambles
sets x2, #hsync0
sets x3, #hsync0
sets x4, #hsync0
sets x5, #hsync0
sets x6, #hsync0
mov extrapkts, #0 ' no extra sync packets
sets x8, #hsync0
sets x9, #hsync0
mov shrink, #0 ' no shrink of back porch for last vsync line
_ret_ setnib m_hubpkt, #7, #7 ' send immediate mode hsync patterns
Am going to look into VGA+DVI/HDMI output simultaneously now. I'd still kept the hsync1/hsync0 pattern flip and cmodval update or direct vsync pin flip capability in the instruction path for this purpose. This should allow both 4 pin (composite sync) and 5 pin VGA sync modes to be selected. 3 pin VGA (SyncOnGreen) is not going to be possible as the DAC0 channel value is not accessible in TMDS mode AFAIK. There appears to be no way to set that channel up in the streamer commands when immediate 10bit->8bit conversion is happening.
vsyncon xor cmodval, #1 'xor cmodval, #1 (4 pin VGA) or xor vsyncinstr, #1 (5 pin VGA)
decod status, #31 'update status - in vertical sync
setbyte status, fieldcount, #2 '
mov hsync0, sync_001 'vsync on, hsync off
mov hsync1, sync_000 'vsync on, hsync on
patchvsync callpa #V_SYNC-0, #blank_vsync 'send vertical sync blanks
vsyncoff xor cmodval, #1 'vsync pin off
mov hsync0, sync_003 'vsync & hsync off (neg polarity)
mov hsync1, sync_002 'vsync off, hsync on
jmp #fieldloop 'continue on to a new field/frame
@rogloh said:
I've found I can easily get this test driver to output simple DVI instead of HDMI encoding format with the handful of following patches done at COG setup time. This is beneficial in that a DVI monitor can still be used to test timing changes and anything unrelated to audio - for me without a HDMI device handy on my desk this is a good thing. It should probably be part of a driver's feature set.
On my end DVI just doesn't install all the HDMI overlay stuff It of course still needs all the scanfunc pixel doubling stuff.
3 pin VGA (SyncOnGreen) is not going to be possible as the DAC0 channel value is not accessible in TMDS mode AFAIK. There appears to be no way to set that channel up in the streamer commands when immediate 10bit->8bit conversion is happening.
Soggy sync isn't directly possible, yea. DAC0 is accessible (TMDS hooks into pin outputs, DAC outputs are unrelated), the problem is that when sending raw 10b TMDS codes, the bottom 6 bits thereof get sent to DAC0, which is not very useful. The "VGA" cmod mode only uses the LSB of DAC0, that's why it's compatible with the TMDS encoder (which ignores bit 0 in all cases). Note that for all commands that don't send visible color, you need to use X_DACS_X_X_X_0 so that the same problem doesn't happen to the other DAC channels. You also need to make sure that SETDACS is set to sane blanking levels (does this register reset to zero when rebooting the cog?). If you disable DAC output entirely during blanking, you could use carefully placed SETDACS to manually implement soggy sync. Note that obviously the full breadth of the color converter is still active, so if you can do sync-on-green, you can do YPbPr (which i both thus group as "soggy" formats).
@Wuerfel_21 said:
Soggy sync isn't directly possible, yea. DAC0 is accessible (TMDS hooks into pin outputs, DAC outputs are unrelated), the problem is that when sending raw 10b TMDS codes, the bottom 6 bits thereof get sent to DAC0, which is not very useful. The "VGA" cmod mode only uses the LSB of DAC0, that's why it's compatible with the TMDS encoder (which ignores bit 0 in all cases). Note that for all commands that don't send visible color, you need to use X_DACS_X_X_X_0 so that the same problem doesn't happen to the other DAC channels. You also need to make sure that SETDACS is set to sane blanking levels (does this register reset to zero when rebooting the cog?)
Aha this might explain why I can't seem to get simultaneous DVI and VGA working right with the colours tonight. See this post and the page of discussions afterwards .. I'd sort of abandoned the idea back then but am intrigued again after you said it was doable. I might have to play with those DAC settings now during blanking streamer commands.
Yes, sending non-black during blanking WILL mess up the colors. It's very simple really, you use X_DACS_3_2_1_0 ONLY for active video, X_DACS_X_X_X_0 for everything else. The "X-ed out" channels get their value from the SETDACS register instead of the streamer.
Wow, makes a difference. Colours look much better. Not sure if I've got the blanking level setup right below but I'm seeing a pic - will work on it more tomorrow.
Remaining work for the new HDMI driver to be merged into master branches, to my memory (TODO: check earlier post):
Add interlace mode for actual 1X modes (line multiply modes already work with bobbing) - only a blocker for MegaYume
double/triple check that line counter values are correct (on MD there's a useful test ROM for this)
variable framebuffer width - so you can get the full 384x240 buffer from Tempest 2000 when the output is wide enough (I don't know why it's so wide, but it is)
re-add LCD6 interface (only old video format not yet ported)
Bonus:
whatever is needed to make MisoYume's 512x224 mode work (though that's still in beta so there's no branches - also in the future I need to support the 512x239 overscan mode)
LCD6 (for ILI9342 controller in 6 bit RGB+HVSync interface) is working again (in NeoYume)! I foolishly re-implemented the entire init sequence in ASM... Was confused for a while until I realized there was a typo and it wasn't actually setting IFMODE (not to be confused with IFCTL).
Will double check that I didn't break other modes tomorrow, but that was the only thing really holding back the new video driver from merging into specifically NeoYume's master branch (and probably doing a new numbered release to celebrate)
actually, I just noticed that it doesn't seem like it can properly initialize the LCD from cold power up... Will need to be fixed still
actually, I'm just beeg stupeed.
Relatedly, I found a command that replaces the really objectionable column inversion on these LCDs with checkerboard inversion, which is less obnoxious. Really, the ideal way would be to properly calibrate the positve and negative voltages to match, but why don't they do it at the factory???
@Wuerfel_21 I don't see any direct support for sync polarity stuff in your driver. I'm going to try to add it back into my own as that's a feature of my timing. Tried negative sync output for hsync and it's a bit messed up - I think I've got some inconsistencies between my own legacy driver code and the TERC pattern settings from your code. On the scope I see some weird hsync patterns coming out the analog VGA pin. Hsync positive was okay. I did try to flip some of the least significant bits of the patterns when I detect positive or negative hsync but I must have messed some up. For the VGA side I think it should be obtainable just by flipping the CMOD register lsb but it's encoded explicitly in the TERC and lsbs of different patterns. Will have to try flipping a few bits to see what happens.
Is a sync polarity a thing on HDMI? I think it's supposed to be only positive? For VGA only you should be able to flip it through the CMOD bit. In that case, don't change it anywhere else!!! It will get double inverted.
Is there ever a need for specific sync polarities? I don't think it ever mattered in my years of video experimentation.
As for the TERC pattern table, the VGA sync bit in there is set such that it matches the encoded HSync bit on TMDS channel 0. (for the other two channels, only the upper bits are muxed in)
@Wuerfel_21 said:
Is a sync polarity a thing on HDMI? I think it's supposed to be only positive? For VGA only you should be able to flip it through the CMOD bit. In that case, don't change it anywhere else!!! It will get double inverted.
Yeah I've already encountered some double flipping which confuses the matter more.
Is there ever a need for specific sync polarities? I don't think it ever mattered in my years of video experimentation.
If you want to replicate specific dedicated timing for some monitors it may be important. Most modern day monitors couldn't care less though I still like the idea of having control of it.
"Modern day" must stretch quite far back then, never had polarrity matter when comitting atrocities against my Fujitsu-Siemens multisync CRT monitor (the absolute limit is somewhere at 720x540 160Hz... Can also do oddballs like 320x240 120Hz - the OSD glitches because it foolishly asssumes there are at least 400 lines to superimpose on )
I think the ancient non-multisync monitors are the problem ones. EGA might also need specific sync polarities. When I re-integrate my parallel RGB stuff for LCD panels into my driver I still want to try out this driver with old CGA/EGA TTL monitors for a laugh and some extreme nostalgia.
Oh man, just getting this combination HDMI and VGA sync polarity stuff working right is totally doing my head in!
After multiple failed attempts I think I've sort of figured out the following:
1) Analog hsync DAC output is controlled by the lsb of the pattern data sent to DAC[0] and also the lsb of CMOD register which flips it when this CMOD bit[0] is true.
2) All displayed RGB video data forces the DAC[0] bit to zero and we can't control that - this is important as it defines the idle polarity state of the hsync output 0=idle, 1=active, irrespective of the desired hsync polarity . In the end we just need to set the CMOD bit[0] to select the hsync polarity emitted by the DAC0 channel on the pin.
3) Immediate pattern data sent during blanking can control the value of this bit, but it should only ever be set to 1 during the hsync pattern and 0 otherwise.
4) the TERC table 3x10 bit patterns + two bits, of which the LSB also controls this hsync state.
5) the packet_extra register in Ada's code sets up which sync polarity the blue channel's TERC nibble emits, as the two lower bits of this nibble are defined for carrying the vsync and hsync state, however that TERC pattern state is only controlling what the HDMI sink sees, and not for VGA DAC[0]. The lsb of the 30+2 bit pattern in the TERC table is what is used for that.
With this in mind I believe I now need to do the following for either hsync polarity to work right for both VGA and HDMI and will need to try this:
1) Make all inactive hsync patterns (front porch, guard pixels, back porch, preambles) have a 0 in the lsb of the pattern to indicate idle sync state
2) Set CMOD[0] bit to 1 if negative hsync and to 0 for positive hsync - this state is what will control polarity of hsync in the end.
3) Setup the 16 TERC table entry lsb's to be 1 as the packets encoded to these values will be issued during the hsync portion of each line. Encode the first two packets (64 pixels) sent during hsync with the appropriate packet_extra field values for vsync/hsync polarity, with vsync state suitably flipped on VSYNC lines.
4) Flip the TERC table entry pattern lsb's to 0 only for the third and fourth packets encoded and sent out on vsync lines after hsync completes. This will keep the size of the hysnc pulses the same on all lines - I might be able to get away without it but I don't like that. Takes ~68 clocks or so to flip and the same to restore back at the end. The code for this table flipping only ever needs to run on the first vsync lines when we send the Infoframe so there would be enough time to do it in a tight REP loop. It would be part of an overlay so doesn't need to fit in the COGRAM. EDIT: Actually these 3rd and fourth packets are pre-encoded so no need to table flip after startup - bonus!
I'm hoping this will finally sort it out... fingers crossed.
@rogloh said:
3) Setup the 16 TERC table entry lsb's to be 1 as the packets encoded to these values will be issued during the hsync portion of each line. Encode the first two packets (64 pixels) sent during hsync with the appropriate packet_extra field values for vsync/hsync polarity, with vsync state suitably flipped on VSYNC lines.
4) Flip the TERC table entry pattern lsb's to 0 only for the third and fourth packets encoded and sent out on vsync lines after hsync completes. This will keep the size of the hysnc pulses the same on all lines - I might be able to get away without it but I don't like that. Takes ~68 clocks or so to flip and the same to restore back at the end. The code for this table flipping only ever needs to run on the first vsync lines when we send the Infoframe so there would be enough time to do it in a tight REP loop. It would be part of an overlay so doesn't need to fit in the COGRAM. EDIT: Actually these 3rd and fourth packets are pre-encoded so no need to table flip after startup - bonus!
I'm hoping this will finally sort it out... fingers crossed.
No! You don't ever have to change the TERC table dynamically! Remember, bit 0 is copied based on what's in channel 0, which gets the H/Vsync flags from packet_extra. My table is set so that the hsync flag ends up in bit 0. For CSync you just need to set it so that it's hsync xor vsync ONCE AT THE BEGINNING.
Ok, am leaving the TERC table aspect until last. All the other changes will be done then I will see what's left to fix. There are too many competing combinations at play here and I need some sanity before I take the final step. I know if I feed packet_extra correctly I do see that it will select either high or low bit 0 output based on that but it will also impact the DVI's hsync state when I flip the input. With CSYNC I do have to flip the hsync output state on the vsync lines but this is done just for 4 bit VGA only and done using the CMOD register bit 0, the DVI/HDMI side should still sees its normal hsync/vsync conditions.
One other weird thing I noticed on the scope is that there is also some analog voltage variation coming out on DAC 0 pin on the scan lines during the active video line portion. Am wondering if somehow perhaps it's from data in the text palette's LSByte which I may not have cleared? Need to check that but it should be cleared. The other region of my screen is using 24 bit RGB data - actually maybe that's the problem, it's probably random data. Might need to drop the last DAC byte in active video portions, although I can't find a steamer command mode for the dddd bits that does X3 X2 X1 00.
Update: Actually no it is meant to be zero on X0 according to the documentation...
If there's minor noise on it, that's probably just crosstalk. All the RGB modes send $00 to DAC0, but with immediate and LUT modes you need to take care.
@Wuerfel_21 said:
If there's minor noise on it, that's probably just crosstalk. All the RGB modes send $00 to DAC0, but with immediate and LUT modes you need to take care.
Yeah I think it was crosstalk. When I tried again earlier tonight I noticed I could make this issue happen when I moved the scope's ground wire and had a dodgy connection at the grounding post on the P2-Eval. It certainly looked a lot like active video at the time.
I am going to try this change again when I'm feeling more wide awake. There should be a way to get this to work correctly once I nail all the parts down. Am working with old code and new code somewhat hacked together and am taking some shortcuts without examining every little step and detail as I really need to.
Finally making some progress on the sync polarity stuff. I found a bug in my code with an instruction in the wrong place which was invalidating about half my tests yesterday. Fixed that and am now seeing good analog sync polarities for each case. I can now start testing out that the DVI/HDMI sync patterns are still correct too but this is a good foundation to work from. You were right Ada, you only have to set the TERC table once. Basically I xor each table entry's LSB with 1 if the hsync polarity is negative and only do it once at setup time before using the table from then on for encoding. Everything else gets controlled via packet_extra fields.
One thing I did see was a small glitch in the 4 pin VGA (composite sync case) sync output while the guard pixels get sent at the end of the front porch and we change the DAC[0] output polarity. This is happening when the CMOD[0] bit flips at the start of the vsync line pair and back at the start of vertical back porch lines. You get a brief runt pulse at that point when zoomed (see below). I don't think the CMOD change line below can be fully synchronized with the streamer easily. I may have to tweak the position in the skipf sequence but it's tricky to align with the true start of hsync where we are sending TERC encoded hub packets. I wonder if all VGA monitors will like this pulse.
' active vsync blank
blank_vsync skipf skipfmask_vsync ' do vsync line
blank skipf skipfmask_vblank ' | do other blanking line
hsync skipf skipfmask_active ' | | do active line
xzero m_hfp, hsync0 ' * * * send shortened fp before preamble
cmp pa, #1 wz ' | * * z=1 if pa=1 (last sync or blank line)
testb status, #30 wc ' | | * c=1 if doing vertical front porch (VFP)
syn1 if_z_and_c alts alt0, #$00 ' | | * last VFP line builds packet for 1st vsync line
syn2 if_z setbyte packet_extra, #$ff, #1 ' | * * last sync line builds packet for 1st VBP line
cmpsub hdmi_regen_counter, hdmi_regen_period wc
' * * * c=1 if time to send a clock regen pkt
mov pb, pktbuf ' * * * setup base packet buffer address
add pb, #256 ' | * | offset to send in vsync line
if_c add pb, #128 ' * * * offset to send clock regen pkt (c=1)
x3 xcont m_imm8, preamble ' * | * send preamble before island
x4 xcont m_imm8, preamble_vsync ' | * | send preamble before island (vsync line)
call #audio_poll_repo_start ' * * * poll audio now and latch start time
rdfast #2, pb ' * * * prepare fifo data for reading
wrlong status, statusaddr ' * * * update clients with scan status
fblock #0, pktbuf_audio ' * * * setup next packet start address
x5 xcont m_imm2, dataguard ' * | * send leading guard band
x6 xcont m_imm2, dataguard_vsync ' | * | send leading guard band (vsync)
x7 xcont m_hubpkt, hsync1 ' * * * send two packets
vsyncinstr setcmod cmodval ' * * * patched to drvl/drvh or setcmod cmodval
extrapkts if_z xcont m_hubpkt, #0 ' | * | send two more packets
call #load_mouse_palette ' * | | read mouse code & large palette
x8 xcont m_imm2, dataguard ' * | * trailing guard band
xcont m_hbp2, hsync0 ' * | | send shortened back porch before preamble+gb
ret wcz ' * | | return with flags restored for sprite render
x9 xcont m_imm2, dataguard_vsync ' * | trailing guard band sync encoded
xcont m_hbp, hsync0 ' * * only control, no pre+gb for blank/sync lines
shrink if_z altd alt0, #m_vi2 ' * | shrink vsync vis line for extra 64 pixel pkts
xcont m_vi, hsync0 ' * * generate blank line pixels
encode call #\loadencoder ' * * encode next audio pkt & poll audio
_ret_ djnz pa, #blank_vsync ' * | repeat
_ret_ djnz pa, #blank ' * repeat
Comments
Just downloaded and installed dependencies, built Tempest etc. Setup HyperRAM on pin 0 of P2 EVAL, USB board on P16, VGA/AV on P24, HDMI on P32.
I was first able to run with VGA output to prove it actually worked, then reconfigured and built for HDMI by enabling this section below. Confusingly it still mentions a VGA_BASEPIN but this mode indicates and uses HDMI on this pin AFAICT when I dug into the code. I could hear analog audio on VGA board the but no video is shown on HDMI. Not sure my plasma TV accepts 800x480 like this. It's pretty restrictive and only likes HDTV resolutions and probably just 640x480, sorry.
You're not using the new branch
Weird, I cloned the from the link above and it doesn't seem to have video-nextgen in the list of branches. git must be messed up there although I do see it listed on GitHub.
3517 ls
3518 git clone https://github.com/Wuerfel21/tempest2k.git
3519 cd tempest2k
3520 ls
3521 git submodule init
3522 git submodule update
3523 cd mac
3524 cd rmac
3525 make
try checking it out anyways
Yeah doing that right now. It does appear to have different settings in the p2config.spin2 file now at least. Will retest and report in ~5mins.
Update: yeah now audio works okay. Nice pretty colourful game. Can't really play it well though. My USB controller sucks with it.
I've found I can easily get this test driver to output simple DVI instead of HDMI encoding format with the handful of following patches done at COG setup time. This is beneficial in that a DVI monitor can still be used to test timing changes and anything unrelated to audio - for me without a HDMI device handy on my desk this is a good thing. It should probably be part of a driver's feature set.
Am going to look into VGA+DVI/HDMI output simultaneously now. I'd still kept the hsync1/hsync0 pattern flip and cmodval update or direct vsync pin flip capability in the instruction path for this purpose. This should allow both 4 pin (composite sync) and 5 pin VGA sync modes to be selected. 3 pin VGA (SyncOnGreen) is not going to be possible as the DAC0 channel value is not accessible in TMDS mode AFAIK. There appears to be no way to set that channel up in the streamer commands when immediate 10bit->8bit conversion is happening.
On my end DVI just doesn't install all the HDMI overlay stuff It of course still needs all the scanfunc pixel doubling stuff.
Soggy sync isn't directly possible, yea. DAC0 is accessible (TMDS hooks into pin outputs, DAC outputs are unrelated), the problem is that when sending raw 10b TMDS codes, the bottom 6 bits thereof get sent to DAC0, which is not very useful. The "VGA" cmod mode only uses the LSB of DAC0, that's why it's compatible with the TMDS encoder (which ignores bit 0 in all cases). Note that for all commands that don't send visible color, you need to use
X_DACS_X_X_X_0
so that the same problem doesn't happen to the other DAC channels. You also need to make sure that SETDACS is set to sane blanking levels (does this register reset to zero when rebooting the cog?). If you disable DAC output entirely during blanking, you could use carefully placed SETDACS to manually implement soggy sync. Note that obviously the full breadth of the color converter is still active, so if you can do sync-on-green, you can do YPbPr (which i both thus group as "soggy" formats).Aha this might explain why I can't seem to get simultaneous DVI and VGA working right with the colours tonight. See this post and the page of discussions afterwards .. I'd sort of abandoned the idea back then but am intrigued again after you said it was doable. I might have to play with those DAC settings now during blanking streamer commands.
https://forums.parallax.com/discussion/comment/1480497/#Comment_1480497
Yes, sending non-black during blanking WILL mess up the colors. It's very simple really, you use
X_DACS_3_2_1_0
ONLY for active video,X_DACS_X_X_X_0
for everything else. The "X-ed out" channels get their value from the SETDACS register instead of the streamer.(do note that the values from SETDACS will still pass through the color converter!)
This is great news. I'm trying it right now before heading off to sleep.
Wow, makes a difference. Colours look much better. Not sure if I've got the blanking level setup right below but I'm seeing a pic - will work on it more tomorrow.
Much nicer colours with setdacs #0
Remaining work for the new HDMI driver to be merged into master branches, to my memory (TODO: check earlier post):
Bonus:
LCD6 (for ILI9342 controller in 6 bit RGB+HVSync interface) is working again (in NeoYume)! I foolishly re-implemented the entire init sequence in ASM... Was confused for a while until I realized there was a typo and it wasn't actually setting IFMODE (not to be confused with IFCTL).
Will double check that I didn't break other modes tomorrow, but that was the only thing really holding back the new video driver from merging into specifically NeoYume's master branch (and probably doing a new numbered release to celebrate)
actually, I just noticed that it doesn't seem like it can properly initialize the LCD from cold power up... Will need to be fixed still
actually, I'm just beeg stupeed.
Relatedly, I found a command that replaces the really objectionable column inversion on these LCDs with checkerboard inversion, which is less obnoxious. Really, the ideal way would be to properly calibrate the positve and negative voltages to match, but why don't they do it at the factory???
@Wuerfel_21 I don't see any direct support for sync polarity stuff in your driver. I'm going to try to add it back into my own as that's a feature of my timing. Tried negative sync output for hsync and it's a bit messed up - I think I've got some inconsistencies between my own legacy driver code and the TERC pattern settings from your code. On the scope I see some weird hsync patterns coming out the analog VGA pin. Hsync positive was okay. I did try to flip some of the least significant bits of the patterns when I detect positive or negative hsync but I must have messed some up. For the VGA side I think it should be obtainable just by flipping the CMOD register lsb but it's encoded explicitly in the TERC and lsbs of different patterns. Will have to try flipping a few bits to see what happens.
Is a sync polarity a thing on HDMI? I think it's supposed to be only positive? For VGA only you should be able to flip it through the CMOD bit. In that case, don't change it anywhere else!!! It will get double inverted.
Is there ever a need for specific sync polarities? I don't think it ever mattered in my years of video experimentation.
As for the TERC pattern table, the VGA sync bit in there is set such that it matches the encoded HSync bit on TMDS channel 0. (for the other two channels, only the upper bits are muxed in)
Yeah I've already encountered some double flipping which confuses the matter more.
If you want to replicate specific dedicated timing for some monitors it may be important. Most modern day monitors couldn't care less though I still like the idea of having control of it.
"Modern day" must stretch quite far back then, never had polarrity matter when comitting atrocities against my Fujitsu-Siemens multisync CRT monitor (the absolute limit is somewhere at 720x540 160Hz... Can also do oddballs like 320x240 120Hz - the OSD glitches because it foolishly asssumes there are at least 400 lines to superimpose on )
I think the ancient non-multisync monitors are the problem ones. EGA might also need specific sync polarities. When I re-integrate my parallel RGB stuff for LCD panels into my driver I still want to try out this driver with old CGA/EGA TTL monitors for a laugh and some extreme nostalgia.
Oh man, just getting this combination HDMI and VGA sync polarity stuff working right is totally doing my head in!
After multiple failed attempts I think I've sort of figured out the following:
1) Analog hsync DAC output is controlled by the lsb of the pattern data sent to DAC[0] and also the lsb of CMOD register which flips it when this CMOD bit[0] is true.
2) All displayed RGB video data forces the DAC[0] bit to zero and we can't control that - this is important as it defines the idle polarity state of the hsync output 0=idle, 1=active, irrespective of the desired hsync polarity . In the end we just need to set the CMOD bit[0] to select the hsync polarity emitted by the DAC0 channel on the pin.
3) Immediate pattern data sent during blanking can control the value of this bit, but it should only ever be set to 1 during the hsync pattern and 0 otherwise.
4) the TERC table 3x10 bit patterns + two bits, of which the LSB also controls this hsync state.
5) the packet_extra register in Ada's code sets up which sync polarity the blue channel's TERC nibble emits, as the two lower bits of this nibble are defined for carrying the vsync and hsync state, however that TERC pattern state is only controlling what the HDMI sink sees, and not for VGA DAC[0]. The lsb of the 30+2 bit pattern in the TERC table is what is used for that.
With this in mind I believe I now need to do the following for either hsync polarity to work right for both VGA and HDMI and will need to try this:
1) Make all inactive hsync patterns (front porch, guard pixels, back porch, preambles) have a 0 in the lsb of the pattern to indicate idle sync state
2) Set CMOD[0] bit to 1 if negative hsync and to 0 for positive hsync - this state is what will control polarity of hsync in the end.
3) Setup the 16 TERC table entry lsb's to be 1 as the packets encoded to these values will be issued during the hsync portion of each line. Encode the first two packets (64 pixels) sent during hsync with the appropriate packet_extra field values for vsync/hsync polarity, with vsync state suitably flipped on VSYNC lines.
4) Flip the TERC table entry pattern lsb's to 0 only for the third and fourth packets encoded and sent out on vsync lines after hsync completes. This will keep the size of the hysnc pulses the same on all lines - I might be able to get away without it but I don't like that. Takes ~68 clocks or so to flip and the same to restore back at the end. The code for this table flipping only ever needs to run on the first vsync lines when we send the Infoframe so there would be enough time to do it in a tight REP loop. It would be part of an overlay so doesn't need to fit in the COGRAM. EDIT: Actually these 3rd and fourth packets are pre-encoded so no need to table flip after startup - bonus!
I'm hoping this will finally sort it out... fingers crossed.
Fingers crossed here too. Appreciate all the braincell burn going in to this...
No! You don't ever have to change the TERC table dynamically! Remember, bit 0 is copied based on what's in channel 0, which gets the H/Vsync flags from packet_extra. My table is set so that the hsync flag ends up in bit 0. For CSync you just need to set it so that it's hsync xor vsync ONCE AT THE BEGINNING.
Ok, am leaving the TERC table aspect until last. All the other changes will be done then I will see what's left to fix. There are too many competing combinations at play here and I need some sanity before I take the final step. I know if I feed packet_extra correctly I do see that it will select either high or low bit 0 output based on that but it will also impact the DVI's hsync state when I flip the input. With CSYNC I do have to flip the hsync output state on the vsync lines but this is done just for 4 bit VGA only and done using the CMOD register bit 0, the DVI/HDMI side should still sees its normal hsync/vsync conditions.
One other weird thing I noticed on the scope is that there is also some analog voltage variation coming out on DAC 0 pin on the scan lines during the active video line portion. Am wondering if somehow perhaps it's from data in the text palette's LSByte which I may not have cleared? Need to check that but it should be cleared. The other region of my screen is using 24 bit RGB data - actually maybe that's the problem, it's probably random data. Might need to drop the last DAC byte in active video portions, although I can't find a steamer command mode for the dddd bits that does X3 X2 X1 00.
Update: Actually no it is meant to be zero on X0 according to the documentation...
If there's minor noise on it, that's probably just crosstalk. All the RGB modes send $00 to DAC0, but with immediate and LUT modes you need to take care.
Yeah I think it was crosstalk. When I tried again earlier tonight I noticed I could make this issue happen when I moved the scope's ground wire and had a dodgy connection at the grounding post on the P2-Eval. It certainly looked a lot like active video at the time.
I am going to try this change again when I'm feeling more wide awake. There should be a way to get this to work correctly once I nail all the parts down. Am working with old code and new code somewhat hacked together and am taking some shortcuts without examining every little step and detail as I really need to.
Finally making some progress on the sync polarity stuff. I found a bug in my code with an instruction in the wrong place which was invalidating about half my tests yesterday. Fixed that and am now seeing good analog sync polarities for each case. I can now start testing out that the DVI/HDMI sync patterns are still correct too but this is a good foundation to work from. You were right Ada, you only have to set the TERC table once. Basically I xor each table entry's LSB with 1 if the hsync polarity is negative and only do it once at setup time before using the table from then on for encoding. Everything else gets controlled via packet_extra fields.
One thing I did see was a small glitch in the 4 pin VGA (composite sync case) sync output while the guard pixels get sent at the end of the front porch and we change the DAC[0] output polarity. This is happening when the CMOD[0] bit flips at the start of the vsync line pair and back at the start of vertical back porch lines. You get a brief runt pulse at that point when zoomed (see below). I don't think the CMOD change line below can be fully synchronized with the streamer easily. I may have to tweak the position in the skipf sequence but it's tricky to align with the true start of hsync where we are sending TERC encoded hub packets. I wonder if all VGA monitors will like this pulse.