This is my first post on this forum, so first of all Hello Everyone!
I am just trying to build simple and cheap VGA output for Amstrad based on Raspberry Pi Pico. So far it is going well, except the limitations caused by low amount of available RAM.
I have a little bit above 256k RAM available and I need to squeeze each output video frame there. I am storing each pixel on one byte (actually using only 6 bits). Output resolution is a standard VGA 640x480 (but I could try to use something bigger) so at this point I am keeping 640x400 pixels in memory - max Amstrad resolution with each line doubled to keep reasonable proportions. That means I use exactly 256k RAM.
But... I would like to add at least part of the screen border. So I have 2 questions to you guys:
1. Is border always filled with one color or there may be multiple colors? I think, during loading from tape there are color lines on border, but maybe at least I can assume one color per line? This way I could easily store border info in remaining RAM.
2. In mode 3, what is the real maximum number of colors on screen? I know there are 2 colors, but maybe border can have different color?
I am asking because if my previous idea would not work, then other option (harder but still doable) would be to read only 320 pixels per line and keep twice more pixels in RAM (with at least part of border) except the case when I detect there is a mode 3, and then detect what are the two colors being used and keep high resolution but 1 bit per pixel.
Thanks, and sorry if the questions are too basic, but I am just starting my adventure with Amstrad.
Greg
You kill all software that uses overscan 768 points per line. Better use 2 x less memory and display two copy one lines.
https://youtu.be/DisL4Gj8Tc0?si=iXomUSOhPJkWkVtm
Im so sorry.
Thanks for quick reply.
yep. I forgot about overscan. How big is the max resolution with overscan? You just said 768 pixels per line. Is it max? And how many max lines can be used in overscan?
Idea with one line displayed twice would be the best option i ntheory, but I just did not find a way to do it yet. I was using some open source library to do VGA on Pico, just modified it to use half brightness, too. The idea is that I just set up DMA that send array with the whole frame to PIO that it just displays it line by line. PIO is really dumb and can't have too much logic, also the timing is really tight. I can't also use chained dmas to have one dma per line, because there is not enough dma channels. I would need to use some trick like two PIO state machines, each of them gets 200 line per frame (I would do the same DMA to both of them) then, synchronize them so it is like, first state machine displays first line, then waits and triggers second one. Second one repeats it and lets the first one display second line etc. Overall it would be great to avoid it... still if it is an only option, that is doable.
OK, but that 125 colors are rather POC to show it is possible, right? Not something I would see in games or demos.
Besides that I think it uses dithering? That I think is a separate thing. Alternative (still much more expensive and bigger) for my solution is e.g. GBS8200 that will not do dithering simulation either.
And... RPI pico could potentially do dithering simulation if I manage to squeeze it better in RAM. At least something simple, like adding 2 more levels of brightness, detecting checkerboard pattern and doing something like average for some pixels. At this point one of my ARM cores does literally nothing, and other almost nothing. All the logic to read amstrad video and output vga is in PIOs.
768x256 but ... i can 1024x480 :-\ but not on original CRT.
768x256 sound reasonable (the other one is scary :) ). I would need less than 200kB if I manage to really keep exactly this resolution in RAM, not the doubled one. I could use e.g. 800x600 output resolution, or even something closer to input resolution if monitors support it.
Thanks a lot for all the info! I will focus now on how to display each line twice. It looks like that is the only reasonable option. I hope it will work.
It should be possible to race the beam with PIOs. That would free up the memory. I have not thought it through totally but it should be possible
Aha, as I said... here is something for the Sinclair QL
Maybe a good starting point
https://forum.tlienhard.com/phpBB3/viewtopic.php?t=4283&sid=13df294b3c7f6cb83516112124a779a6
What you mean by "race a beam? Do you mean converting the input pixel to output ones in a streaming fashion, without storing anything in memory? Or rather do it line by line?
Or something like this - twice more pixels per line on output then on input, read one pixel on input, then write two on output - so we get VGAish timing.
Then PIO need one loop that reads pixel and writes it twice with correct timing. hmmm... It could work.
Thanks for link. I will take a look there
Quote from: SerErris on 18:40, 15 April 24Aha, as I said... here is something for the Sinclair QL
I think that's more or less just a scan-doubler that digitizes the QL output and sends each line twice to the monitor. If I understand gregg correctly he is rather mirroring the screen RAM and listens to the CRTC/GateArray registers.
@gregg in case I am right with that assumption that you are not just digitizing the screen output and replay it again, then you also have to consider double and triple screen buffering. Many games switch the screen address between frames. If you are mirroring the screen contents you also have to keep 2 or 3 screens in the PICO Ram.
Quote from: eto on 18:47, 15 April 24Quote from: SerErris on 18:40, 15 April 24Aha, as I said... here is something for the Sinclair QL
I think that's more or less just a scan-doubler that digitizes the QL output and sends each line twice to the monitor. If I understand gregg correctly he is rather mirroring the screen RAM and listens to the CRTC/GateArray registers.
@gregg in case I am right with that assumption that you are not just digitizing the screen output and replay it again, then you also have to consider double and triple screen buffering. Many games switch the screen address between frames. If you are mirroring the screen contents you also have to keep 2 or 3 screens in the PICO Ram.
Nope... I am more like doing a scandoubler, just the simplified one that assumes Amstrad palette, so it is easy to use just digital pins, voltage comparators on input and 6 resistors on output.
I was considering mirroring the ram, but I got scared :) double and triple buffering is just a beginning. What about reading the palette etc. That's too much for me :D
Do you have a github or a web site with more informations about the state of your work ?
Quote from: gregg on 18:56, 15 April 24Nope... I am more like doing a scandoubler, just the simplified one that assumes Amstrad palette, so it is easy to use just digital pins, voltage comparators on input and 6 resistors on output.
I was considering mirroring the ram, but I got scared :) double and triple buffering is just a beginning. What about reading the palette etc. That's too much for me :D
ah... in that case the QL project might indeed be close to what you want to do.
Well... I am looking forward to it :-)
Quote from: genesis8 on 21:39, 15 April 24Do you have a github or a web site with more informations about the state of your work ?
Nope. I just have a messy code on my pc, and messy electronics on a breadboard. I will for sure put everything on GitHub, especially that my knowledge in electronics is really poor, so I would like to get some feedback. But first I need to clean it up at least to the point when code is readable.
As for current status - output is almost OK. Code works well, I was able to display Amstrad palette, or something close to it. I need to experiment more with resistors values to make colors better, e.g. white is a bit greenish. Input in terms of schematics is much more WIP. I am just going to order some new voltage comparators, because old ones were too slow. So far I was testing with only 1 bit per input. Except those limitations with ram, when I was trying to just use 640x200 with no border, it looks ok - just small details to improve like screen is shifted a bit, or problems with catching sync after resetting Pico with Amstrad running. So it should not be much work left.
If you have time and energy, would it be possible to do a short video on youtube to show your work for us poor hungry for informations ;D ?
It's so more sexy when you can see things.
I envision the process would be implemented as similar to the below (as VGA is 31kHz and input is 15kHz)
Two buffers, 768 pixels each.
Some magic to find out when a scanline starts from VSYNC and HSYNC signals.
Repeat {
Scan-out 768 pixels VGA from buffer A | Read half-scanline display data into buffer B (384 pixels incorporating left border and LHS of screen)
Scan-out 768 pixels VGA from buffer A | Read other half-scanline display data into buffer B (384 pixels incorporating RHS of screen and right border)
Scan-out VGA from buffer B | Read half-scanline display data into buffer A
Scan-out VGA from buffer B | Read other half-scanline display data into buffer A
}
Presumably for an 800 wide VGA screen you'd publish the first pixel 17 times before the rest of the line, and then the final pixel 17 times, to hit 800 pixels. You might want a configurable black border option too here.
You'd also publish X blank lines before and after the display.
The tough thing is sampling at the right rate to get the precise MODE 2 pixel sampling correct.
The above is how OSSC does it, I believe, but that's overkill hardware for a CPC. It's very low latency.
You will need some magic for R3 horizontal scrolling funkery. You can test that using Relentless.
Quote from: genesis8 on 08:26, 16 April 24If you have time and energy, would it be possible to do a short video on youtube to show your work for us poor hungry for informations ;D ?
It's so more sexy when you can see things.
I am just learning electronics (I am software engineer), so I think I could rather learn from videos :) It is also my first project on RPI Pico... actually on any microcontroller. I am doing it mostly to learn. I even don't have an Amstrad yet (testing on a prototype of a replica that I am trying to build), so I don't think such a video would be valuable. First I would rather like to at least see it working.
If you want some more info, it is a short summary:
I connected vsync and hsync to pi's input GPIOs. RGB will go through voltage comparators (now they are just a bunch of resistors and capacitors to adjust voltage levels) to convert it to 6 pins total. Each pair represents one color. There is 00 (no color), 01 or 10 (half brightness) or 11 (full brightness). Pico works in 128Mhz so it makes it really easy to synchronize because one pixel in mode 3 is 7 cycles on Pico. PIO code that reads it just waits for HSYNC to go up, then down, then waits a couple more cycles (will not do it when I will support overscan). After each pixel is read, PIO sends it to queue, then it goes through DMA to host that stores it in an array that represents one line. Once line is done (next HSYNC starts), host copies line to two consecutive lines on output buffer (that will change if I want to store each line only once). I repeat it 312 times and start again from beginning (next frame). (I will rather sync it using VSYNC in future).
On output side, second PIO generates HSYNC, VSYNC and just reads the buffer representing VGA screen that it receives through DMA from host (the one that I was filling so far). For each pixel it sets again 6 output GPIO, using the same format - 00 is no color, 01 or 10 is half brightness, 11 is full brightness. Each GPIO has a resistor, that are connected on other side, so we have "analog" signal there that goes directly to VGA. That's it.
Quote from: gregg on 18:44, 15 April 24What you mean by "race a beam? Do you mean converting the input pixel to output ones in a streaming fashion, without storing anything in memory? Or rather do it line by line?
Or something like this - twice more pixels per line on output then on input, read one pixel on input, then write two on output - so we get VGAish timing.
Then PIO need one loop that reads pixel and writes it twice with correct timing. hmmm... It could work.
Just to fill that answer, as I was away some days:
Race the beam is a programming technique often used in games (ATARI was famous for it). It means, that you actually read only the current pixel and then directly output it. So you do not do anything other than that. This will convert it to a 15khz VGA signal.
If you need a 30khz VGA signal, you would need to buffer a single line, and then output it two times.
gregg has already answered that.
Thanks Guys again and I have some more questions, and some good news.
First a quick question to McArti0 - which exactly 256 lines I should use? I looked at the output from Amstrad with an oscilloscope and I see the following for each frame:
16 lines - hsync signal
10 lines - totally black
46 lines - top border
200 lines - actual screen
40 lines - bottom border
In total 312 lines.
So far I used 200 lines from the actual screen with a similar sized parts of both borders that gave me 256 and I am not 100% sure I am using the right part.
My second question is to everyone. I am getting close to be done with programming (still some electronics work left after that) and I am thinking what else I am missing. One of those is potentially a support for using csync instead of separate vsync and hsync. That may be needed depending on how it will be installed. I am considering a couple options. At this point I need: rgb output from gate array or video connector, hsync and vsync e.g. from gate array pins, 5v for rpi and ground. So I see a couple solutions. Which one would be the best in your opinion:
1. Put everything on a board that is installed outside of amstrad. It would be connected to video port, and it needs 5v. Maybe it could be plugged to both video output port and power input port. Then it would have a connectors for vga input and power adapter input. Something like - power goes into the board, then it powers pico and also goes to power socket in amstrad to power amstrad.
Pros: Simple to install - no need to change anything inside Amstrad or case.
Cons: The board would be bigger. I need to handle csync, that I am not yet 100% sure is doable in Pico.
2. Put it inside, on a board that plugs into Gate Array socket, and Gate Array is plugged into the board. It could be really small especially is we would not use the whole Pico board but rather directly install processor and a couple or parts on our board. I get all the signals from Gate Array. There would be e.g. a pin connector to connect vga socket on a tape that could go to anywhere, even potentially outside of Amstrad through some existing hole in case.
Pros: No need to cut anything in case, or remove any existing socket. I don't need csync. Smaller board. Lower total cost.
Cons: Need to open Amstrad. Need to put vga socket somewhere.
3. The same as 2 but vga socket is installed on the same board close to main board edge. Cut the hole in case for vga socket.
Pros: It is very simple.
Cons: Need to cut hole in case. Separate version for each Amstrad.
4. The same but different board shape so vga socket replaces video socket.
Pros: The same + no modifications to the case.
Cons: Need to remove original video socket. Separate version for each Amstrad.
Which option would be the best? Maybe some other, better solution I did not think about?
In my case it will be simpler because I plan to make it a part of my Amstrad clone board - much simplified to just play some games in living room, but I would like to make it useful for normal Amstrads.
And some good news:
I managed to make Pico double each line using a weird trick with two dmas. The only limitation is that number of lines that goes to VGA must be a power of 2. I am keeping 800x312 screen from Amstrad in memory and then output part of it with doubled lines (800x512) to 800x600 vga (actually I think it is svga) screen. It works well with all the monitors I found at home. The only bad thing are spare black 88 lines on a screen. I will try to do something about them, but I don't have idea yet.
Quote from: gregg on 16:01, 22 April 24First a quick question to McArti0 - which exactly 256 lines I should use?
if you meet a malicious programmer's code, you will have to use 286 lines.
Quote from: McArti0 on 18:02, 22 April 24Quote from: gregg on 16:01, 22 April 24First a quick question to McArti0 - which exactly 256 lines I should use?
if you meet a malicious programmer's code, you will have to use 286 lines.
OK, but if I understand correctly it is some extreme case? How many existing software use 286 lines?
If I understood correctly your previous post, there is quite much software that uses overscan with 256 lines. So my question is just which 256 lines? Is it always the same 256 lines or each software use different ones?
Or maybe I can ask it in a different way - if you turn on Amstrad with original monitor, how many lines and columns do you see and which ones?
I would like use vga monitor and see about the same, and if some software draws anything on a border that would be visible on original Amstrad monitor, I would also like to see it.
Quote from: gregg on 16:01, 22 April 24I need to handle csync, that I am not yet 100% sure is doable in Pico.
You can split sync with a LM1881. That might help.
I would prefer option 1. I have different CPC machine and connect them to different screens. An external solution would be more flexible here.
Option 2-4: Keep in mind that there are 2(3) variations of the GateArray. You would need 2 different PCBs to cover that. And the 40007 GateArray requires to have a heat sink installed. I'm not sure if there is still enough space and if the heat sink can still be mounted with another PCB in between.
Btw: did you do some tests with games and demos that use scrolling and/or overscan? Many scandoublers fail with scrolling. A good test is e.g. Ghosts'n Goblins (easy, many scan doublers work fine) or Super Edge Grinder and Relentless (haven't found a scan doubler yet that works fine). Overscan will reduce/remove the borders so you will get up to 288 lines with content and no more borders.
Quote from: eto on 18:53, 22 April 24Quote from: gregg on 16:01, 22 April 24I need to handle csync, that I am not yet 100% sure is doable in Pico.
You can split sync with a LM1881. That might help.
I would prefer option 1. I have different CPC machine and connect them to different screens. An external solution would be more flexible here.
Option 2-4: Keep in mind that there are 2(3) variations of the GateArray. You would need 2 different PCBs to cover that. And the 40007 GateArray requires to have a heat sink installed. I'm not sure if there is still enough space and if the heat sink can still be mounted with another PCB in between.
Btw: did you do some tests with games and demos that use scrolling and/or overscan? Many scandoublers fail with scrolling. A good test is e.g. Ghosts'n Goblins (easy, many scan doublers work fine) or Super Edge Grinder and Relentless (haven't found a scan doubler yet that works fine). Overscan will reduce/remove the borders so you will get up to 288 lines with content and no more borders.
Idea is LM1881 is great. Thanks. I will do it with if I don't manage to handle it in code.
Yep... forgot about different gate arrays. That would make it complicated.
I am only testing it with start screen and boulderdash that I have in rom. There is no real scroll there, so for sure I will test it with games you suggested. I am a bit afraid of potential screen tearing. What artifacts with scandoublers do you see in those games?
And first I need to fix one more issue with hsync timing. There is some jitter added by Pico that makes lines moving to the sides a little bit sometimes, so that would probably affect those tests.
Quote from: gregg on 19:01, 22 April 24What artifacts with scandoublers do you see in those games?
I don't know how to describe it. They basically become unplayable as the scrolling will have some weird results. The screen is kind of shaking.
Quote from: eto on 19:15, 22 April 24Quote from: gregg on 19:01, 22 April 24What artifacts with scandoublers do you see in those games?
I don't know how to describe it. They basically become unplayable as the scrolling will have some weird results. The screen is kind of shaking.
OK. So first I need to have all timings ok, and I think scrolling will be nice test to check if I read input well.
I see two possible reasons (but I am guessing) for the issue you describe. One would be a screen tearing, that I am afraid I may have, too. I am writing from CPC video output to my array and reading from it to push it to VGA output in totally not synchronized way. Input is 50fps, output is 60fps, so there may be a case when I present half of one frame and half of other. That would cause tearing but only in one line.
Other option is some magic that scandoubler does because it tries to support also interlace that we don't have in Amstrad. That should work well in my solution.
I will test it for sure in a couple days, once I am done with remaining (but small) issues in code. Maybe I would make a short video of my screen so you could say if you still see that issue.
A lot of the more tricky CRTC tricks are around tricking the CRTC to generate signals the monitor won't respond to, but that the rest of the hardware will. That allows you to display multiple "screens" within a single frame of the monitor.
Pushing things to the point that they technically are out of spec, but that the CPC won't notice, is another issue. And finally there are the kinds of things like relying on the analogue response of the monitor to the change in certain registers, letting you do things like put sine waves effects down the screen.
Quote from: gregg on 19:29, 22 April 24nput is 50fps, output is 60fps,
Many VGA screens accept 50Hz input. It would be great to have that at least as an option.
Quote from: eto on 19:39, 22 April 24Quote from: gregg on 19:29, 22 April 24nput is 50fps, output is 60fps,
Many VGA screens accept 50Hz input. It would be great to have that at least as an option.
Yep... but in the first version I wanted to make it working on as many monitors as possible. The most standard resolutions supported on everything are 640x480 and 800x600. First I wanted to use 640x480, but then I would not fit borders and would not allow for overscan. I guess that is quite a limitation, so next option is 800x600. Universally supported framerates for 800x600 (even by old monitors) are 56, 60, 72 and 75, so no 50hz. At some point I made a bug and I had 58 hz. It worked on my quite new Asus monitor, but was showing "not supported" on older tv. So I decided to stick to 60hz. If there will be a problem with tearing, I will try to switch to 50.
Overall I think the best option would be to have switches for multiple resolutions, multiple frame rates, and screen size adjustments just to be able to choose the best option for each use case - e.g. option to get rid of some artifacts at the price of smaller border. But at this point I am trying to have some working minimal usable version, make it tested, stable, publish it on Github or somewhere and then follow with nice-to-haves.
CPC has V-synch freq ..... 50,080(128205) Hz sorry.
Pinball Dream has ~280 line sorry.
Quote from: McArti0 on 20:31, 22 April 24CPC has V-synch freq ..... 50,080(128205) Hz sorry.
Pinball Dream has ~280 line sorry.
Yep. I know it is a bit over 50hz. I took it into account when reading input. And no need to be sorry :D
Thanks for all the examples, but do you know the answer to my original question? For example in Pinball Dreams, which 280 lines are those? That is the most important for me to find how many lines and which of them I need to read. For example if this time it is the whole bottom border and a part of top one, and in other game using 280 lines it will be the whole top border and a part of bottom one, then I can't use 280 lines but I need more. What about those 10 black lines that I see above top border? Does any game use it? Is it visible on original monitor?
I can think about some other trick with dmas to have maybe not 256 lines but 288 (256+32), but I need to know if it makes any sense. If instead of 10% games causing troubles it will be 9% then I think it is not worth doing.
Also if it will look like I need to use every single input line and find solution for that, I don't want to have monitor filled with a lot of stuff that is rarely used, leaving actual screen area much smaller.
Fortunately it is much simpler in horizontal direction. There is just 800 columns between hsync signals so I just copy all of them.
And thanks for all the examples, I did not expect there are so many exception.
I suspect the black lines are just part of VSYNC and never actually visible. As to which ones are visible, that's probably impossible to say because it'll be slightly different depending on the adjustment settings on the monitor. Picking the middle-ish bunch to give roughly even border top and bottom is probably the right approach.
Quote from: andycadley on 21:53, 22 April 24I suspect the black lines are just part of VSYNC and never actually visible. As to which ones are visible, that's probably impossible to say because it'll be slightly different depending on the adjustment settings on the monitor. Picking the middle-ish bunch to give roughly even border top and bottom is probably the right approach.
Thanks. I will do it this way. I will get 200 lines from main screen + 28 from each border.
But if I manage to get over that 256 lines limitation and be able to use 256+32=288 lines then I would have both borders + even 2 spare lines. That would make a lot of sense if it is doable. I need to try.
This is an interesting project, but probably useless if the converter is too academic with the video signal.
Most demos would not be rendered properly when hsync/vsync timings are not correct (on purpose or by programming mistake).
CTM totally accepts that, but not oscc, which make it useless. It would be sad your product suffers of the same issue
Quote from: krusty_benediction on 22:13, 22 April 24This is an interesting project, but probably useless if the converter is too academic with the video signal.
Most demos would not be rendered properly when hsync/vsync timings are not correct (on purpose or by programming mistake).
CTM totally accepts that, but not oscc, which make it useless. It would be sad your product suffers of the same issue
I am sure I am never going to match what exactly CTM can display or even get close to it or even to any CRT monitor. My goal is to have something close to what you can get from a scandoubler, but with the total cost of a couple dollars, much smaller size, but working only with Amstrad and skip support for all the features that other scandoublers have. I would not support interlace, other resolutions and timings than amstrad one, or no other palettes. And even if it will be useless I am doing it first of all to learn stuff, so for me it is a win-win situation :)
Many emulators show the screen as 40+200+32 (+/- 8 lines up or down)
Quote from: McArti0 on 06:18, 23 April 24Many emulators show the screen as 40+200+32 (+/- 8 lines up or down)
Thanks! That is a very useful info!
Maybe this file would be useful
https://www.cpc-power.com/index.php?page=detail&num=16027
Quote from: krusty_benediction on 11:29, 23 April 24Maybe this file would be useful
https://www.cpc-power.com/index.php?page=detail&num=16027
That would be very very useful. Thanks a lot!
I would still do it line by line.
Start from the hsync singnal and scan to the next hsync, then output it twice to the target monitor with double pixel frequency.
That would catch everything the CPC will do, regardless of video modes or anything else.
If you just do that this needs only one line of memory and is never wrong, whatever the demo might do and it is also very fast (no additional delay) in the output. So even any mode switch will be done immediately without any adaption time.
Quote from: SerErris on 10:23, 26 April 24I would still do it line by line.
Start from the hsync singnal and scan to the next hsync, then output it twice to the target monitor with double pixel frequency.
That would catch everything the CPC will do, regardless of video modes or anything else.
If you just do that this needs only one line of memory and is never wrong, whatever the demo might do and it is also very fast (no additional delay) in the output. So even any mode switch will be done immediately without any adaption time.
To be honest that is what I wanted to do first. This way there is for sure no issues with ram or with tearing that could happen when frame in RAM is being displayed and overwritten in the same moment, but there are two main issues I found. First is timing. When reading Amstrad video, it has to be extremely accurate. For VGA output it also has to be quite accurate. That leaves not much space for any extra operations like doubling the line etc. and keeping everything in sync at the same time. Still maybe this potentially could be made at some point.
Other issue is related to possible resolutions and frame rates. In your solution we have to keep the same vertical frequency/frame rate on output as on input. Looking at available frequencies for monitors, like my main one: http://dlcdnet.asus.com/pub/ASUS/LCD%20Monitors/PB277/ASUS_PB277Q_English.pdf the options for available resolutions with 50hz fps is quite limited. When I checked some old TV I have, it was even more limited. Some monitors have so huge tolerance that even when not officially supporting 50hz they would probabaly handle it. Still I don't want to end up with something that works only on a fraction of monitors. When we add requirement about resolution it will be even harder. Actually my only option is 800x600 (or something close) to be able to fit the whole amstrad screen and still be able to send pixels quick enough. That gives even smaller number of possible frame rates.
On the other hand when I think about pros and cons of keeping the whole frame in memory, then first of all it just works and so far I don't see tearing. It could also open the possibilities to do any postprocessing of a frame. In future, I could e.g. handle some special cases, like mentioned earlier smooth scrolling or even try to simulate dithering, getting closer to what can be seen on original monitor rather than on typical scandoubler. All that stuff would be harder having access to one line only.
... and some good news - I managed to work around the limitation of number of lines being the power of 2. So now I have the totally full Amstrad screen displayed, even with a bit of those black lines just after vsync signal. Any overscan should not be a problem. This weekend I plan to finish the electronics part, and then I will follow with more detailed testing to know better what works and what doesn't.
Quote from: SerErris on 10:23, 26 April 24I would still do it line by line.
Start from the hsync singnal and scan to the next hsync, then output it twice to the target monitor with double pixel frequency.
That would catch everything the CPC will do, regardless of video modes or anything else.
If you just do that this needs only one line of memory and is never wrong, whatever the demo might do and it is also very fast (no additional delay) in the output. So even any mode switch will be done immediately without any adaption time.
I might be wrong, but I think some demos force multiple hsyncs per line, to allow multiple modes in a line.
Quote from: Deevee on 16:32, 26 April 24Quote from: SerErris on 10:23, 26 April 24I would still do it line by line.
Start from the hsync singnal and scan to the next hsync, then output it twice to the target monitor with double pixel frequency.
That would catch everything the CPC will do, regardless of video modes or anything else.
If you just do that this needs only one line of memory and is never wrong, whatever the demo might do and it is also very fast (no additional delay) in the output. So even any mode switch will be done immediately without any adaption time.
I might be wrong, but I think some demos force multiple hsyncs per line, to allow multiple modes in a line.
Oh wow! That will be a cool use case to handle. So far my logic is like: wait for hsync to go up, then to go down, then read the line in a loop with constant number of pixels (assuming mode 2, in other case it just reads one pixel multiple time). I will have to change it completely to handle something like that. I can't wait to have it working with basic use cases and start working on cases like that one :)
Quote from: Deevee on 16:32, 26 April 24Quote from: SerErris on 10:23, 26 April 24I would still do it line by line.
Start from the hsync singnal and scan to the next hsync, then output it twice to the target monitor with double pixel frequency.
That would catch everything the CPC will do, regardless of video modes or anything else.
If you just do that this needs only one line of memory and is never wrong, whatever the demo might do and it is also very fast (no additional delay) in the output. So even any mode switch will be done immediately without any adaption time.
I might be wrong, but I think some demos force multiple hsyncs per line, to allow multiple modes in a line.
Yeah, if you want to support that you'd need to make sure to ignore shorter HSYNC pulses. And obviously be aware that Mode could change mid line, but if you're just sampling colours periodically that probably doesn't matter so much.
Quote from: andycadley on 16:40, 26 April 24Quote from: Deevee on 16:32, 26 April 24Quote from: SerErris on 10:23, 26 April 24I would still do it line by line.
Start from the hsync singnal and scan to the next hsync, then output it twice to the target monitor with double pixel frequency.
That would catch everything the CPC will do, regardless of video modes or anything else.
If you just do that this needs only one line of memory and is never wrong, whatever the demo might do and it is also very fast (no additional delay) in the output. So even any mode switch will be done immediately without any adaption time.
I might be wrong, but I think some demos force multiple hsyncs per line, to allow multiple modes in a line.
Yeah, if you want to support that you'd need to make sure to ignore shorter HSYNC pulses. And obviously be aware that Mode could change mid line, but if you're just sampling colours periodically that probably doesn't matter so much.
Sorry, for a dumb question, but I think most of the demos and games that I will need to test are disc only? At this point my self-made frankensteiny Amstrad can only load tapes and roms, so I guess I will need to finally buy real 6128 or 464 with disc interface? (plus gotek or something)
Quote from: gregg on 16:46, 26 April 24Quote from: andycadley on 16:40, 26 April 24Quote from: Deevee on 16:32, 26 April 24Quote from: SerErris on 10:23, 26 April 24I would still do it line by line.
Start from the hsync singnal and scan to the next hsync, then output it twice to the target monitor with double pixel frequency.
That would catch everything the CPC will do, regardless of video modes or anything else.
If you just do that this needs only one line of memory and is never wrong, whatever the demo might do and it is also very fast (no additional delay) in the output. So even any mode switch will be done immediately without any adaption time.
I might be wrong, but I think some demos force multiple hsyncs per line, to allow multiple modes in a line.
Yeah, if you want to support that you'd need to make sure to ignore shorter HSYNC pulses. And obviously be aware that Mode could change mid line, but if you're just sampling colours periodically that probably doesn't matter so much.
Sorry, for a dumb question, but I think most of the demos and games that I will need to test are disc only? At this point my self-made frankensteiny Amstrad can only load tapes and roms, so I guess I will need to finally buy real 6128 or 464 with disc interface? (plus gotek or something)
There are many games on tape, but very few demos (if any?), because of loading shenanigans.
Anyway, if you want to be sure that your adapter works with a CPC, you'll have to test it with a CPC at some point I guess.
Możesz kupić Dandanator mini lub DDI-5.
@eto I did some of the tests you recommended. Could you take a look if it looks OK? Please ignore noise (flickering pixels) and sometimes screen shifted to the right - I am already working on these issues.
IMO Vertical overscan (Ultima Ratio) looks OK. I also tried horizontal overscan with Super Cauldron and it was OK.
Scrolling it much more interesting. I tried Ghost'n'Goblins and I think they are OK, but please take a look, too. Sorry for blurry video, my camera went out of focus.
Smooth vertical scroll (Mission Genocide) also looks OK, but sometimes a little bit choppy. I am not sure if it is expected.
Horizontal smooth scroll totally does not work. I tried Skate Wars, and it was a total mess. I am just reading about tricks with HSync here: https://shaker.logonsystem.eu/ACCC1.7-EN.pdf and I have some ideas how to fix it, but first for sure I will need to use csync from Gate Array instead of Hsync from CRTC.
Besides that I found a lot of issues with how I handle or do not handle syncs. e.g. Mission genocide has less lines (305 it total), so instead of hardcoded value I will need to start actually use VSync. And BTW how I use HSync also sucks - sometimes screen is shifted to the right.
I did not manage to load Relentless yet, but I believe issues will be similar to Skate Wars.
Ghosts'n Goblins looks good.
If you have issues loading Relentles, you can try Edge Grinder and Super Edge Grinder. These are also two candidates that rarely work on anything but a CRT.
@eto I managed to load Relentless, and I think I can see that issue. It is just shaking and I agree it makes it unplayable. I think I know where the issue is, and I will try to fix it. As I understand, what they do is a combination of actually shifting pixels on screen and changing the duration of hsync (the one the is part of c-sync on GA's output, not the one on GA's input). My problem is that I shift twice too much when duration of hsync changes. As a result, instead of shifting one pixel per frame, it shifts by 1 pixel, 2 pixels, 1 pixel, 0 pixels. I probably messed up something with timing when waiting for csync to end.
@eto Does relentless look OK on this video, or do you see the same issue that you have seen on scan doublers? (Sorry I made a video with phone so it may be a bit shaky)
One more horizontal scroll test with Skate Wars:
Quote from: gregg on 08:16, 04 May 24Does relentless look OK on this video, or do you see the same issue that you have seen on scan doublers? (Sorry I made a video with phone so it may be a bit shaky)
I haven't played it for quite some time now so I don't know if it's 100% accurate but it definitely looks better than anything I have ever seen on a LCD.
This is absolutely awesome.
@greggHow did you make the ADC input? Anything additional than the 2040 PCB?
@eto That's great. Thanks a lot for checking it! Actually there are two things still to do. One is that I have 60hz output and I can see it is not 100% smooth (even if not visible on this video), because it doubles the frame from time to time. I am just experimenting with 50.08hz output. It is 100% smooth then but there are other issues and it only works on one monitor out of 3 that I have. Still, I could add a switch so it would be possible to have 60hz that works on every monitor, or 50 that is 100% smooth.
Other thing is how I handle shorter hsync at this point. I need to start scanning .5us earlier for each 1us that hsync is shorter. I only handle 3 and 4 us vsync at this point. After csync goes down, I wait 3.5us whatever csync value is and then wait until csync goes up. If it was 3us hsync, then it is already up, and I start scanning, but if it was 4us, then I wait until full 4us (.5us longer). That gives me .5us shift and makes scroll smooth. But from what I read, there are options (not recommended but I believe still used) to have even shorter hsync. I will need to handle them, too.
@McArti0 I Just used voltage comparators. There are only 3 possible levels of each color in Amstrad so I just made use of it. Of course this solution will be Amstrad only. I tried a couple comparators to find something cheap and fast enough. At this point I sticked to 3x TLV3202. They are $1.50 each and they are fast enough. I had a lot of noise on output but I managed to filter out most of it with capacitors. Some of it may be because I still have it on a some shitty breadboard when comparator's docs say a lot about how accurately it has to be placed on a pcb to avoid noise.
First I wanted to use ADCs in RP2040, but they are just too slow.
The output from comparators (and input to RP2040) are two pins for each color. One is high if there is full brightness, and other is high if there is half or full brightness. That is also how I keep it in memory.
It does look pretty impressive. The 60Hz thing was always going to be a bit of an issue but not insurmountable. 50Hz would be nice and is supported by a lot more displays these days (due to the panels being the same as in TVs).
The colour issue does mean it wouldn't work on a Plus machine though, which is a shame. Although the GX does have Scart output and a slightly adjusted PAL friendly clock, so hooking one of those up to a modern display is less problematic most of the time (especially since Plus only software is probably less likely to use HSYNC hacks).
Quote from: andycadley on 10:15, 05 May 24wouldn't work on a Plus machine
for a Plus version it would probably required to attach the scandoubler internally before the DAC like the RGB2HDMI does.
Quote from: gregg on 03:03, 05 May 24Still, I could add a switch so it would be possible to have 60hz that works on every monitor, or 50 that is 100% smooth.
that would be absolutely amazing.
Guys,
Thanks for all the advices, but I need one more :)
I am just trying to design PCB, and I have no good idea how to make connection to Amstrad. VGA is simple - I will just put a socket. The same with power - micro usb on pico. But connection to Amstrad is more problematic. I was looking for male din-6 socket (or even din-5 because I don't need luma signal) to install on pcb and plug it directly to Amstrad and I think it just doesn't exist :) Other possible options are:
1. Female din-6/din-5 socket on pcb that would be connected to amstrad with male-male din-6 cable. Simple, but when I looked for such cables they are like $10-$20 so IMO a bit expensive.
2. Some other type of socket - maybe "din-6 to something else" cable would be cheaper.
3. Just connect cable with DIN-6 plug directly to pcb (solder it to pcb, or use terminal block or some socket like on GBS), and mount cable it with some clips to make it more stable. Then the pcb would have 2 sockets - power and vga and a cable with a plug that goes to Amstrad. That would look a bit ugly, but that would be cheap.
4. Some other option?
Besides that I am getting close to finish this project, so I hope I will publish it in a couple weeks. In the meantime I managed to get rid of most of the artifacts - flickering pixels, screen moving a bit to the sides. I no longer use Vsync/Hsync but only CSync. There is a 50/60 hz switch. I tested it on 2 different monitors and old tv and it works in both modes on monitors and 60hz only on TV (so not 100% smooth scrolls). I also tested it on couple more games. Prehistorik II was problematic, but now scrolls are 100% smooth at least in standard mode. There is still a couple small issues to fix, and of course much more testing that will probably find more issues.
Thanks for all the help, Guys.
4) I recently made a CPC2VGA adapter that plugs into the monitor port: https://www.cpcwiki.eu/forum/hardware-related/cpc2vga/msg235888/#msg235888
I used a male DIN plug and just made sure, the holes in the PCB are big enough to make it fit ;-) Works fine for my use case with such a small PCB however, for a version with a Raspberry Pico that setup might be too large.
For this project, I would prefer option 3. Especially when the PCB is inside a 3D printed case, it shouldn't matter that the cable is soldered directly and I can decide the optimal length of the cable for my personal set-up. However 1) is also fine as I would expect that I always can solder the cable directly to the footprint of a connector.
Quote from: eto on 16:24, 21 May 244) I recently made a CPC2VGA adapter that plugs into the monitor port: https://www.cpcwiki.eu/forum/hardware-related/cpc2vga/msg235888/#msg235888
I used a male DIN plug and just made sure, the holes in the PCB are big enough to make it fit ;-) Works fine for my use case with such a small PCB however, for a version with a Raspberry Pico that setup might be too large.
For this project, I would prefer option 3. Especially when the PCB is inside a 3D printed case, it shouldn't matter that the cable is soldered directly and I can decide the optimal length of the cable for my personal set-up. However 1) is also fine as I would expect that I always can solder the cable directly to the footprint of a connector.
Awesome. Thanks! 4 sounds like a perfect solution. RPI pico is not so big.
If PCB is going to go vertically on the back of Amstrad, then I just need to design PCB in such a way that it does not interfere with other ports on the back of Amstrad, but that should be doable. Overall pcb size will be about RPI pico x 2. Usb cable may just be in some weird place, like on the top. Maybe I can just add separate power port in more convenient place, and use usb only for software update.
If not then maybe I could also go with something like 1+3, I mean female din-6 socket, plus some solder pads to easily solder cable if needed.
Quote from: gregg on 16:35, 21 May 24I just need to design PCB in such a way that it does not interfere with other ports on the back of Amstrad,
don't forget that there are at least 3 different CPC versions that you need to consider: 464, 664 and 6128. Not sure if the different PCB versions for the 464.
Especially the 6128 does not have a lot of spare area around the monitor port. And the US/German version with its Centronics port is even slightly worse as the Centronics clamps need some extra space.
Quote from: eto on 17:03, 21 May 24Quote from: gregg on 16:35, 21 May 24I just need to design PCB in such a way that it does not interfere with other ports on the back of Amstrad,
don't forget that there are at least 3 different CPC versions that you need to consider: 464, 664 and 6128. Not sure if the different PCB versions for the 464.
Especially the 6128 does not have a lot of spare area around the monitor port. And the US/German version with its Centronics port is even slightly worse as the Centronics clamps need some extra space.
Yep. I just took a look at the photos of each model, and 6128 + centronics is for sure the hardest one. It would actually need to have the width of rpi pico with nothing on the sides. Maybe it would be possible to squeeze everything on the other side of pcb. Other option is to design own minimal rp2040 board and place everything conveniently, but I think that would be too hard for me at this point.
One more tempting option would be to make pcb that covers both video port and power socket. They look to be placed in the same distance in all models (or at least in very similar). There would be two plugs on the pcb so it would be plugged into both - video port and power. Then on the other side I would have vga socket and power adapter socket. Power adapter goes to my board, and through it to Amstrad. Two pros are - I don't need separate power adapter for my pcb, and pcb can be much wider. But I think there would be a lot of troubles, like aligning my plugs to sockets in Amstrad.
Maybe Pimoroni PIM577?
Or Seeed Xiao RP2040
Quote from: McArti0 on 13:55, 22 May 24Maybe Pimoroni PIM577?
Or Seeed Xiao RP2040
Yep. I was considering some other options, but there is always one of two issues. Twice more expensive (like Pimoroni), or not enough GPIO pins (like Seeed Xiao). So I think the only reasonable options are RPi Pico or just own design based on RP2040.
Quote from: gregg on 15:52, 22 May 24not enough GPIO pins (like Seeed Xiao)
How many pins do you need?
2040 Zero has a little more.
Quote from: McArti0 on 17:11, 22 May 24Quote from: gregg on 15:52, 22 May 24not enough GPIO pins (like Seeed Xiao)
How many pins do you need?
2040 Zero has a little more.
20 at this point, but maybe I will need a bit more:
6 for RGB input
6 for RGB output
2 for csync inputs - one for pio one for host, looks like can't be shared
2 for v/hsync outputs
1 for input hsync being extracted from csync by pio
2 for the same hsync going into second pio and host
1 for 50/60hz switch
Actually 2040 zero looks cool. Small, just enough pins (exactly 20), and same price as pico. It has some components on bottom so when installing on a pcb I would have to use pins to install it a bit above, or just make hole in my pcb.
Thanks for advice!
If you anyhow design it, just design a new PICO with the correct ports on the port. It is not very difficult and you then purchase the RP2040 directly and solder it to the board. That would save the space for the large PICO pcb, as you simply do not need it. The only thing you actually need is a 5V to 3.3V converter, so that you can power the RP2040 correctly. And then whatever your PCB design anyhow needs.
Ah and for sure you need a FLASH chip to read the program from. That is more or less it.
Check out this video:
https://www.youtube.com/watch?v=RTIaGyquMR0
That approach makes it harder to be a DIY project. Sure you can order assembled PCBs but they are more expensive and you rely on the availability of all the components. Maybe as an alternative but I would prefer if there is a DIY solution for home-soldering.
@SerErris That is a great idea and I was already thinking about it and read some documentation and looked at existing RP2040 projects. With my shitty skills in electronics I would rather first use RPI Pico, and maybe try to do that in the next step.
@eto Yes I want to make it DIY project, but to be clear - there is no way to avoid using SMD components and do it TH. The comparators are only SMD, and they say in documentation to not use any adapters but put it directly on PCB. I have a plan to use SMD, but not some crazy small. Something that even with my lack of skills and the cheapest 10x microscope is possible to easily build.
In about a week or two I should start putting it on Github. The plan is that first I will put a code and my current schematics. Later I will follow with PCB. In terms of code, I need only to fix VGA part and clean up the code to have some very first testing version. VGA part is crazy. There is a couple timing standards from VESA - DMT, GTF, CVT, CVT RB, and it looks like monitors usually expect the specific one, so I will add one more switch. So far it looks like after testing with my monitors it works like that:
Old Viore TV - Supports only 60hz DMT and says "no support" in every other case
Not so old HP monitor - Supports 60 and 50hz, but GTF only. If I use CVT or DMT the screen is shifted about half the screen to the right
Newer ASUS monitor - Supports 60 and 50hz. Should support CVT and CVT RB v1 according to documentation. DMT is slightly shifted. GTF and CVT is detected as 720x576 (rather than 800x600) so screen is cut a bit and shifted. Sometimes it says it is 1280x600 and is only shifted. That is the last thing I need to fix, and hopefully will works with most monitors then.
Quote from: gregg on 15:49, 28 May 24With my shitty skills in electronics I would rather first use RPI Pico, and maybe try to do that in the next step.
This is the absolute right way to do it. First proove it works, than build a simple prototype and then optimize from there.
I assume proove has been done with breadboarding. Simple prototype will be with PICO. And then optimized would be small pcb just based around the RP2040 chip itself.
Quote from: gregg on 15:49, 28 May 24The comparators are only SMD
Are these comparators really necessary?
That would be great to avoid having comparators but I have no idea how to do it. Overall what I need is to have two pins for each color that have full brightness encoded as 11, half brightness as 10 or 01 and 00 in other case. So I need some very simple ADC. I was trying to do it just with a bunch of resistors and capacitors, to have original signal converted to two signals where one gets just above level considered high by pico when it is full brightness only, and other signal is just above level considered high when it is half or full brightness. The problem was (even when Pico documentation says something different) that I really need to get close to 3.3V for pico to consistently consider signal as high, and close to 0 to be consistently low. There is a really huge voltage interval in the middle, that is interpreted by Pico quite randomly. I always ended up with a lot of random results.
Other option I considered was to use Pico ADC, but it is just too slow. No way to analyze each pixel separately.
If you Guys know any simpler solution then comparators, that would be awesome.
So far I plan to make use of the fact that Pico board is totally flat on bottom side, so I am trying to make small board where pico would be on one side and comparators on other. I don't know if it will work, but that would make it quite small. Board would be the size od Pico + vga connector on a side and something to connect to amstrad on other side.
On some positive note, the code is almost cleaned up. I plan to publish it this weekend on GitHub and follow with the schematics in a day or two. I finally solved the problem with finding output modes that work with most monitors. 800x600x50 was really hacky and monitors had often detected it as 576p, so I ended up with supporting just two modes:
800x600 60hz with DMT timings - works actually on everything even my old TV, but it is not 50.08hz so not 100% smooth
720x576 very close to 50.08hz with horizontal resolution scaled down from 800 to 720 and CEA-861 timings. - It should work on every monitor that supports 50hz. Scaling in horizontal (just using faster clock) makes horizontal overscan work, we don't lose any pixel. In vertical resolution I lost 8 lines on top, but looks like they are always black, I think it is just a back porch.
And I should finally get real Amstrad 6128 in a couple days, so I can do much more testing then. I plan to start with Edge Grinder and other than standard mode in Prehistorik II as I did not manage to load them so far and a bunch of demos that require 128k ram or are disk only.
I published the code: https://github.com/grzegorz-gr/vga4cpc It has a lot of comments, so I hope it is easy to understand. There is also a built uf2 file there.
I know it is quite useless without schematics, but schematics should be there in a couple days once I clean it up.
And here is schematics: https://github.com/grzegorz-gr/vga4cpc/blob/main/schematics_draft.pdf
It is not a final version, but rather what I have on a breadboard now, and what works for me.
I know you Guys have much more knowledge in electronics than me, so please let me know if you see something wrong that I should fix.
Thanks!
Hey Guys,
I have a first version that works quite well. PCB was just a couple dollars in JLCPCB + $15 for all the parts in DigiKey. I put everything on github: https://github.com/grzegorz-gr/vga4cpc - Gerber files, Kicad project, schematics, BOM, instructions, source code and compiled uf2 file.
The board looks like this:
(https://github.com/grzegorz-gr/vga4cpc/blob/main/board.jpg?raw=true)
Here is one more demo:
I tested it on all the games you Guys recommended. I had issues with a couple demos, but besides that it worked fine.
Thanks for all your help!
@gregg nice work! did you try CRTC³ (there is dirty screen changes with the wasp at the end) or From Scratch (not always 50Hz) ?
it may suggest you some leads to handle frequencies variations
Quote from: gregg on 03:11, 22 July 24I put everything on github: https://github.com/grzegorz-gr/vga4cpc (https://github.com/grzegorz-gr/vga4cpc) - Gerber files, Kicad project, schematics, BOM, instructions, source code and compiled uf2 file.
I just ordered it... Looking forward to try it out.
I'll share my experience then.
@roudoudouI did not manage to test them. I think CRTC3 is Amstrad Plus only? My scandoubler unfortunately works with cpc palette only. From Scratch does not work on my 6128. It says something about crtc version.
@eto Good luck. Let me know if it works for you or rather what does not work, so I will try to fix it :) . That's a pity you did not let me know before ordering. I have 4 spare PCBs (JLCPCB requires order of minimum 5), so I could send you one.
Quote from: gregg on 05:02, 29 July 24That's a pity you did not let me know before ordering. I have 4 spare PCBs (JLCPCB requires order of minimum 5), so I could send you one.
No worries - I need at least 2 and I had to order 5 sets at Digikey anyway as it doesn't make sense to order for less than 50€ from Germany (due to high shipping costs for orders below 50€). And I'm sure I can find some people that are very happy to get on of the remaining sets ;-)
Can it operate at 50Hz now? My first desire would be to be able to do 80 character mode on a VGA CRT, maybe even with frequency doubling to 100Hz.
If you want to hook up a flatpanel for games, there is an abundance of SCART LCD TV's that already scale up to various resolutions. Or even a Plasma TV. Most cost less than the adapter.
It can operate on something very close to 50.08Mhz. There is a 50.08/60hz switch. 50.08 worked on 2 out of 3 monitors I tried. One was 100% ok, and one has image always shifted to the left, but gets ok after "auto-adjust" in monitor.
for those displays you will usually need a powered Scart cable which will also cost 20€.
And none of the LCD solutions (Tv or scan doubler) that I know works with games like Relentless. This is the first scan doubler that is capable of that.
Quote from: eto on 16:48, 29 July 24for those displays you will usually need a powered Scart cable which will also cost 20€.
No need for a powered cable. You can perfectly feed the RGB switch signal from sync.
Quote from: retro space on 06:29, 10 August 24No need for a powered cable. You can perfectly feed the RGB switch signal from sync.
Sometimes - but not always.
I tested it with several LCD TV sets and several RGB2HDMI converters and most of them did not work properly with the Sync solution.
Quote from: gregg on 05:02, 29 July 24@eto Good luck. Let me know if it works for you or rather what does not work, so I will try to fix it :) . That's a pity you did not let me know before ordering. I have 4 spare PCBs (JLCPCB requires order of minimum 5), so I could send you one.
sooo... I finally could give it a try - but no success so far. I don't even get the test pattern, just a a black screen with some green border.
I made 2 attempts (two boards) and no change. Any idea what could go wrong that it doesn't even show the test pattern? Based on the green border I would say it creates a signal...
Quote from: eto on 17:46, 28 October 24Quote from: gregg on 05:02, 29 July 24@eto Good luck. Let me know if it works for you or rather what does not work, so I will try to fix it :) . That's a pity you did not let me know before ordering. I have 4 spare PCBs (JLCPCB requires order of minimum 5), so I could send you one.
sooo... I finally could give it a try - but no success so far. I don't even get the test pattern, just a a black screen with some green border.
I made 2 attempts (two boards) and no change. Any idea what could go wrong that it doesn't even show the test pattern? Based on the green border I would say it creates a signal...
Yep. It clearly creates signal. Actually creating test screen should be extremely simple, so I believe it must be something simple. As you said there must be some signal. Can you check in your monitor what resolution and frequency it detects? At least we would know that both sync signals are OK.
One hint that comes to my mind is that that green pattern is possibly in a place where there should be a horizontal sync. So let's go through the color signals. We should have something like (if it would work well):
r,g and b have varialbe values over whole line, then go to 0 during HSYNC
HSYNC is 0 during the line, then goes to +5v during HSYNC (I think I ended up with positive voltage meaning sync)
Here it looks more like r and b stay 0 all the time and green behaves like hsync should.
hmmm.... isn't it something simple like VGA socket being upside down?
Other option... do you use original RPI Pico? Maybe some other board with different pinout?
@eto Could you post a photo of your board? I would compare it with my one. Maybe I messed up something in design, or rather made something misleading.
Quote from: gregg on 18:03, 28 October 24Can you check in your monitor what resolution and frequency it detects? At least we would know that both sync signals are OK.
I get 800x600x60Hz and 720x576x50Hz
The 50Hz screen is completely black, on the 60Hz screen I get the green borders.
Quote from: gregg on 18:03, 28 October 24do you use original RPI Pico?
yes. original Pico
Quote from: gregg on 18:06, 28 October 24or rather made something misleading.
See photo attached. (btw: the orientation of the comparators is misleading as they are upside down - but no indication on the board that this is the case. I killed one board because of that - not a big deal as I had enough stuff but maybe you can add that information to your repository).
@eto I suspect one more thing. In earlier versions I had vga sync signals exactly where green signal is now. I could mess up something and e.g. upload older version of uf2 to github. I will try to find some time today afternoon or in the worst case tomorrow to check it. I will just use current uf2 from github and confirm it works on my board.
@eto Just updates uf2 file on github. As suspected there was a wrong one. Could you try it?
As for comparators, Kicad should put a longer while line next to pin 1. I it not so well visible, maybe I should change it. Is there that line? Or is it upside down?
Quote from: gregg on 19:57, 28 October 24put a longer while line next to pin 1. I it not so well visible
yes it is there but at least to me it was not clear that this means pin 1. Never saw it like that.
also the label for the IC is in the other direction. I guess a note in the instructions would be good enough.
Quote from: gregg on 19:57, 28 October 24Just updates uf2 file on github. As suspected there was a wrong one. Could you try it?
NICE! now I get a picture. However parts of the screen are not perfectly stable. Usually on the left or on the right side of the screen the text is "wobbling". The pixels get stretched/compressed and yellow pixels even shortly appear green. When it's unstable on the left side, it's perfect on the right side - and vice versa.
short video showing the boot screen (in this case it was in the middle, not left or right):
https://www.dropbox.com/scl/fi/2zog66buxzeslm2argv1i/picovga.mp4?rlkey=55pd6ppuk1cptps1q623q2hu9&dl=0
edit: 2 different monitors, same effect, both 50 and 60Hz
I just tried with a few games and I recognized that the colours are not correct.
dark red (3) and darg green (9) appear as black, bright red (6) looks like dark red normally and bright green like dark green.
dark blue (1) and light blue(2) are okay.
Also many colours are identical (probably due to the dark red/green part being black).
@eto As for incorrect colors - does palette on top of test screen look ok, or do you have the same effect? This way we understand if the issue is on output to vga or input from Amstrad. Each color is encoded on 2 bits (both input and output). Dark red would be 01/10, and full red 11. You instead clearly get 00 instead of 01/10 and 01/10 instead of 11. That means one of the output pins is wrong and always set to 0, or on input one of the comparators returns 0 when it should be 1.
The other problem is a big more scary. It looks like it is reading the input value on the border between pixels, so sometimes it has one value and sometimes the other. I will try to play with a couple parameters in the code and prepare a couple of software versions for you. What Amstrad do you have? I was testing it only on my spanish cpc128, maybe there are some differences in input timings?
And overall any of the issues you mentioned happens in games only or also on test screen? If test screen is OK, then at least we know that the problem is input.
aaaa.. Sorry. My bad. I had 2 bad connections between the comparators and the Pico. After I recognized and fixed it, the colours are perfect.
I have a German 6128. The jitter sometimes doesn't exist at all - and sometimes it's clearly visible. It also seems that it gets better after some time. I also did a quick test on a 464 and there was no jitter at all. So it could just be related to my 6128. I'll test some more CPCs and let you know if it's just the one that has an issue. No need to do anything now.
I already tested Relentless and it plays perfectly with this adapter. Really impressive. Thanks a lot for sharing everything.
@eto and BTW - thanks a lot for testing it. That was extremely valuable. So at this point we can say it works except that jitter on one of your Amstrads? I think it is something that I should make code more resilient to.
Let me know about any other issue you catch. Especially that some of those things may be just something I did not test yet and there will be a simple solution for them.
Sure, I hope I find some time to test it more thorougly and will give feedback.
A few things I already recognized:
- It sometimes doesn't properly initialise and the picture shows one line followed by a black line. A quick reset solves the issue. I'll take a picture next time it happens.
- When I turn off the CPC but not the scan doubler the last screen state is still shown. Would it be possible to recognize this and show a black screen?
- The mounting holes on the PCB are not properly aligned.
Btw: any chance to add scanlines? Sure, not everybody likes them, but if it_s possible it would be great to have it as an optional feature.
Here's a little case I made. I also added a power connector so I can connect the 5V to the vga4cpc, which powers the Pico and the CPC, so no need for an additional USB power supply. Also the switch turns off the CPC and the Pico together.
I need to do some minor adjustments and will provide the STL file then.
I added the vga4cpc to the Wiki page about LCD solutions: https://www.cpcwiki.eu/index.php/LCD_monitor_and_LCD_TV_Solution_(RGB)#vga4cpc
Yep. I had test screen appearing on power off after a second in earlier version but it was causing some issues, so I switched it off and did not fix yet.
I also noticed that weird screen on CPC start that reset fixes. That is some more serious issue, looks like some race condition but I did not manage to found yet why it happens. I will keep looking.
Thanks for noticing the issue with mounting holes. That should be easy to fix.
Scanlines should be easy to add... instead of doubling each row I would just put every second row black?
The case looks awesome! It that case 3d printed? Is there a chance you would share the design?
this is cool...finally a converter that works!..gonna have to get one...
i wonder if this could be simplified with something like an ESP32 WROVER and its ADCs and inbuilt comparators... i know it can output 64 colour VGA..
Quote from: gregg on 23:24, 13 November 24Yep. I had test screen appearing on power off after a second in earlier version but it was causing some issues, so I switched it off and did not fix yet.
would turning black/off be a possibility? Test screen after power on is fine, but if I turn off the CPC it's a bit misleading to see the last frame.
Quote from: gregg on 23:24, 13 November 24Scanlines should be easy to add... instead of doubling each row I would just put every second row black?
It's worth giving it a try. Or maybe half brightness? Of course that would require another resistor per colour and another PCB revision.
Quote from: gregg on 23:24, 13 November 24The case looks awesome! It that case 3d printed? Is there a chance you would share the design?
Sure. The one you see in the picture is a special one as I pass through the power and can turn on/off everything with a switch. I also made another version which is just the case for the converter without any additions. I did not test it yet though... I'll make a test print today and share it.
Quote from: gregg on 23:24, 13 November 24Is there a chance you would share the design?
Find attached the STL. I'm not 100% sure that it will fit as I can't test it as my converter is already fully assembled and I don't want to tear it apart again. But I think it should be fine.
One version for the top of the case is for the pure PCB and the other is the one I used which offers options to add a power connector, power outlet and a switch. Not sure if anyone else will use it as I designed it for the components I already had.
For the cords I also made some strain reliefs. I am absolutely not sure if that is a good design but it works for me. Put the cable through the hole before soldering it internally (check that it has the right size - there are 3 different diameters). Adjust the length so there is not too much cable inside and then press the little part into the slot - this should keep the cable in place and secure the internal soldering from any accidental ripping.
Quote from: Brocky on 03:08, 14 November 24this is cool...finally a converter that works!..gonna have to get one...
i wonder if this could be simplified with something like an ESP32 WROVER and its ADCs and inbuilt comparators... i know it can output 64 colour VGA..
im just looking at the pinout on the rpi pico... it seems it has 3 ADCs... wouldnt they be perfect to read the RGB values from the CPC instead of the dedicated comparators?
the ADCs will be able to determine the levels and you can code them appropriately...
https://microcontrollerslab.com/raspberry-pi-pico-adc-tutorial/ (https://microcontrollerslab.com/raspberry-pi-pico-adc-tutorial/)
im gonna have to grab a few picos to play with!
EDIT: never mind ..found the answer "First I wanted to use ADCs in RP2040, but they are just too slow."
96 clock cycles x (1 / 48MHz) = 2 μs per sample (500kS/s). for one conversion..we need 3x that... :(
ESP32 ADCs are not up to the task either :(
Unfortunately ADCs in pico are just too slow. I wasn't able to read samples fast enough with them. Actually that was also quite hard to find fast enough comparators that were cheap in the same time.
But if you find any way to do it without comparators, that would be great. It would simplify the design a lot.
got some comparators on the way!..
atm it seems theres no "cheap" mcu that has fast enough ADCs.. or if they do, they only have 1!
ive just finished making up a vga4cpc board, (and i streamed building it on youtube!)
it works great in Pinball Dreams, i havent had a chance to test ghost n goblins yet :D
one "demo" i seen that had issues is the 128k wonderboy remake, it uses a strange resolution
@gregg are you able to look into supporting this one please? see attached (cant find it on cpcpower)
ive got another 2 boards to make up... one for a friend, one to sell..and ill have 2 spare PCBs left if anyone needs one
@gregg you might want to start a new thread with VGA4CPC in the title, this is a great little board and it deserves more attention!
next step is to work out if i can put it IN the CPC and power it..
Quote from: Brocky on 13:03, 20 February 25it works great in Pinball Dreams, i havent had a chance to test ghost n goblins yet :D
Very nice. BTW, Relentless is known having weirdness with various displays. Did you test it as well?
Quote from: dodogildo on 13:44, 20 February 25Quote from: Brocky on 13:03, 20 February 25it works great in Pinball Dreams, i havent had a chance to test ghost n goblins yet :D
Very nice. BTW, Relentless is known having weirdness with various displays. Did you test it as well?
I did when I built it. It works very well.
@Brocky I will take a look at Wonderboy. Looking at the videos I think it does scroll in some not-so-standard way. I only implemented the case when hsync is reduced from 4us to 3us. That is the most popular one, but not the only one possible. Looking at the videos on YT the border is shaking a lot so I guess hsync is reduced even more. I will confirm it, but if it is true, then I will need to find a way to handle it. The trick I am using right now will no longer work, so that would be a cool challenge to fix it.
@Brocky When you said about putting it inside to power it, actually I was thinking about one more option - make it smaller but with two plugs mounted on the board that would go to video out and power in on the back (of course the board would have to be different for each Amstrad model). It would be like flat board that plugs on the back of Amstrad to both ports and on other side it would have vga socket and the power input where you would connect Amstrad power supply and it would power both - this board and Amstrad.
i was thinkin of wiring it directly to the video connector pins on the cpc board.. and 5v to the picos pins.. (that way both original monitor, if i ever get one, and vga monitor can work side by side)
i was thinking about cutting a hole in the back of the cpc to plug VGA in..between the cpc board and disk drive... only problem.. i need access to that reset switch to reset the vga4cpc board as it sometimes doesnt detect a change eg when ya switch off the cpc, the vga4cpc board will continue to show the last screen and not detect when the cpc is switched back on, hitting reset finds the signal..
i guess i could also rewire the reset button to move it to the cpc case...i may not even need to do that if the board is powered down/up with the CPC..
i already have added a rom switch on the back, im not scared to cut a hole in the back of the 6128 case.. its pretty rough as it is anyways..
@Brocky I tested Wonderboy and IMO looks as expected. It is not really smooth (not as smooth as relentless), but when I recorded it in slow motion it scrolls exactly the same amount in each frame. I checked it with oscilloscope and it uses exactly the same technique as Relentless - hsync switching between 4us and 3us. I also checked videos online and Wonderboy looks exactly the same.
Could you make a video how it looks for you and maybe as some point of reference how it should look like? I don't have an original Amstrad monitor to compare.
Quote from: gregg on 22:45, 22 February 25@Brocky I tested Wonderboy and IMO looks as expected. It is not really smooth (not as smooth as relentless), but when I recorded it in slow motion it scrolls exactly the same amount in each frame. I checked it with oscilloscope and it uses exactly the same technique as Relentless - hsync switching between 4us and 3us. I also checked videos online and Wonderboy looks exactly the same.
Could you make a video how it looks for you and maybe as some point of reference how it should look like? I don't have an original Amstrad monitor to compare.
interesting....
ill get a screenshot of what im seeing a bit later
very interesting....
i just finished making up another 2.5 vga4cpc boards (0.5 coz im missing a pico and vga connector!)
but... wonderboy worked fine on these 2 new ones!
with the first one.. its was splitting the scanlines.. displayed half on one side of the screen and half on the other...yet everything else worked fine...
i even switched between 50 and 60hz modes and was gettin the same thing.... but the new ones are fine?! weird!.. i may need to recheck the soldering on the first one...
There is also an existing problem that sometimes it was switching to such a weird state especially when turning on Amstrad but resetting the board helped. I am just trying to debug it again now, but no luck so far. But if you say it is a constant issue and reset does not help, then potential reason may be a bad solder on one of the pico pins related to VSync generated internally from CSync, so check the solder on Pico's pins: 10, 14 and 29.
Quote from: gregg on 23:53, 23 February 25There is also an existing problem that sometimes it was switching to such a weird state especially when turning on Amstrad but resetting the board helped. I am just trying to debug it again now, but no luck so far. But if you say it is a constant issue and reset does not help, then potential reason may be a bad solder on one of the pico pins related to VSync generated internally from CSync, so check the solder on Pico's pins: 10, 14 and 29.
all good now after a touch up of the picos pins...they are really finicky to solder right...(doesnt help my eyes aint what they used to be!)
@eto i tried printing the case you posted above, but im having issues pluging in the usb cable the the recessed usb port on the pico..
just a heads up for anyone wanting to print it.. may need to cut a wider hole..
seems like it maybe somewhat still monitor dependent,
eg, with my old VGA CRT monitor, the eagle on pinball dreams looked fine, yet on my LCD monitor, the eagle has the split scan lines and shimmer...
but for the most part it helps in alot of games where there is trouble with other converters..