Trying to connect vintage TIM-011 home computer with PS/2 keyboard and VGA using a FPGA developer board
To make the experience fit your profile, pick a username and tell us what interests you.
Load into Mercury + baseboard. Only switch(0) is active - set to on to allow sampling. Buttons move TIM window on VGA screen.
- 146.13 kB - 11/30/2020 at 05:04
Load into Anvyl. Set all switches to off. Button 0 scrolls (direction is switch(0)), button 3 is reset, button 2 is test pattern. Note that the external crystal is now 96MHz!
- 1.42 MB - 11/30/2020 at 05:02
While overall the sampling of TIM-011 video signal works, and is visibly displayed on the screen, it still has problems:
Perhaps not clearly visible, a picture from the VGA screen (generated by sampler + VGA controller):
Now looking at screenshot from GONBES-8200, it has different problems:
So in some ways, both are "worse" but the vertical bar artifacts are very annoying. I haven't tested if those would prevent reading of text on the TIM-011 display.
First, I thought that the image would deteriorate going from left to right, due to the skew between video signal to be sampled and the sampling clock - after all they are synchronized only once per line using hsync signal, and by 512th video signal (or 2048th sampling clock) they could be slightly off. But that is not the case, the quality is evenly good (or bad).
So the artifacts must come from the sampling approach itself. To "debug" it, I feed the sampler with 6 extra signals that control the sampling.
tim: tim_sampler port map ( reset => RESET, clk => freq48M, -- 48MHz (4 times oversample of 12MHz) hsync => TIM_HSYNC, vsync => TIM_VSYNC, v2 => TIM_VIDEO2, v1 => TIM_VIDEO1, a => sampler_a, d => vram_dina, --limit => switch(7 downto 2), -- best result with sampler "algorithm" -- s2 from raising edge sample -- s1 from raising edge sample -- 4 out of 4 sample: on -- 3 out of 4 sample: on -- 2 out of 4 sample: off -- 1 out of 4 sample: off limit => "111100", we_in => we_in, we_out => sampler_wr_nrd );
The two MSB of the (not very well) named "limit" are consumed by the tim_sampler.vhd to select if for the v1, v0 video signals should be captured at the rising or falling edge of the sampling clock (s2 and s1 are 16-bit shift registers, clocked at 4*12MHz rate and ingesting the TIM-011 v1 and v0 video signals):
generate_s: for i in 15 downto 1 generate begin s2(i) <= s2r(i) when (limit(5) = '1') else s2f(i); s1(i) <= s1r(i) when (limit(4) = '1') else s1f(1); end generate; s2(0) <= v2; s1(0) <= v1;
Answer: raising is much better for picture quality.
The 4 LSB are consumed in the "voter" circuit which gets 4 sample bits (per pixel) and has to decide if those 4 indicated "signal on" or off. It does that by looking at the sampled patterns:
with value select vote <= limit(3) when "1111", --4 limit(2) when "1110", --3 limit(2) when "1101", --3 limit(1) when "1100", --2 limit(2) when "1011", --3 limit(1) when "1010", --2 limit(1) when "1001", --2 limit(0) when "1000", --1 limit(2) when "0111", --3 limit(1) when "0110", --2 limit(1) when "0101", --2 limit(0) when "0100", --1 limit(1) when "0011", --2 limit(0) when "0010", --1 limit(0) when "0001", --1 '0' when others; --0
Obviously, if no bit was sampled "1" then the output must be "0" - this is the last, default line. But what if it was sampled one of more times "1"? In that case, the output is controlled by selecting on or off individually each combination with 1, 2, 3, or 4 bits sampled "1" (a simple 16->1 MUX).
Through visual experimentation, turns out the best result is enable 4 and 3 bit "1" sample combinations, but not the 2 and 1 bit ones (1 results in unstable pic, 2 is effectively a no-op).
Converting incompatible video standards especially in retrocomputing field is a well-known problem, for which a whole cottage industry has been created (e.g. GONBES and similar).
|TIM-011||VGA (basic mode)|
|Color info||Digital, 4 level, 2 signals||Analog, 3 signals, theoretically 2^24 colors with 3 8-bit DACs|
|Pixel clock||12MHz||25.125MHz (25Mhz is used for design simplicity)|
As can be seen from the above, any simple or "passive" connectivity between the two won't work. The apparent solution is to:
Read more »
In order to see if the generated video signal is good or not, one simple trick is to pre-populate video RAM with image as if CPU had generated it.
I used two images:
TIM-011 signal generator on Anvyl - my lame MSPaint image:
TIM-011 sampler on Mercury - model students busy learning Basic from original 1988 ad (I hope I am not breaking their copyright!)
Of course, both of these converted to 512*256*4 colors look a bit less impressive...
All FPGAs support initializing RAM/ROM which is part of the design. However, the file format varies. As I was using Xilinx ISE14.7, I needed .coe file to include into project.
Here are steps to generate the .coe:
1. Convert image to .bin file using Img2Tim utility which will:
2. Once we have the .bin file, use file conversion mode of my microcode compiler to generate .coe from .bin
3. Finally, use ISE native tooling to generate the RAM component and point it to .coe file
There are other approaches too - for example, tooling could generate VHDL source code directly that initializes the memory and include that file into the project to be compiled, but such file would be very large and slow down compilation. mcc is able to generate VHDL from .bin file in case non-Xilinx approach is needed.
In order to convert video signal coming from TIM-011 to VGA, one has to first have it... As I don't have a TIM-011, I had to "simulate" one. Key component of this simulation is to re-create the custom graphics system of TIM-011 on FPGA.
Luckily, I had the schematics from the magazine, so I could reverse-engineer it.
First, a bit about TIM-011 graphics implementation:
As a result, following video signal is generated:
There are two interesting facts about TIM-011 video:
To follow description below, refer to this source code file.
(to be updated)
Really low-quality, terrible video, but hopefully illustrating what is working so far:
Anvl-board generates video signal:
Mercury board captures the video signal:
Upcoming project logs will describe these in more details.
Become a member to follow this project and never miss any updates