Let's explore, tweak, repair and benchmark some old, e-waste-grade computer hardware and have some fun!
DISCLAIMER: The content of this channel is meant for entertainment only. This is just my hobby and I am not an expert, so please don't consider any of the content as a tutorial.
God, what an amazing project! Thank you for all your efforts and for making it open source right from the get-go! I wonder how new of a CPU this strategy would work on. Socket 754 does not seem to have HOLD/STPCLK or anything similar.
Core 2 duo has a STPCLK pin but I think the socket is SMD so it will be tricky to reach the pin. I think the best systems for this would be Socket A Athlons and early Pentium 4s.
Hmm good question. Perhaps the bus is floating so the card reads random noise from the floating bus. If the faulty RAM is completely broken, then it might as well not touch the output bus, which would result in the same type of random noise.
That's quite interesting, though it's a bit more tricky for a couple of reasons: (i) The ADCs on the Pico are not fast enough for VGA, so you would need an external ADC chip, like the TVP7002. (ii) Then you would have to reduce the color bits a bit because you would run out of GPIOs on the Pico. But other than that it shouldn't need too many changes on the firmware side.
Love it! This got me thinking. Since MDA/CGA/EGA and other TTL signals are digital, what would it take to get them to directly output to "modern" digital displays using "modern" inputs (DVI-D, HDMI, DP)? Right now you would need to convert TTL to analog (using this or similar adapters), then connect that to something like an OSSC, GBS Control, etc., which converts the analog signal back to digital (plus upscaling). Basically, you're going from digital, to analog, back to digital again. So the adapter I am referring to would cut out the "middle man" and just have digital to digital. Mind you, not an engineer by any stretch of the imagination and I might not be explaining it correctly.
It should be possible to output a more modern digital video signal straight from the Pico. DVI or DP should be possible, I have not looked into them in detail. The biggest challenge is the TTL sampling part, but once this is taken care of I think making a variant that can output a digital signal is the next step.
Prince of Persia - we had a CGA card which had the two modes swapped. I remember it that way always 😅 and I eventually found out it was not but it was definitely in the late 90s as we didn't have Internet in the house till then. I wonder if anyone else has memories like that?
the only thing i would add would be buffering for hercules and redrawing the image either in interlaced or progressive mode each line twice if you have spare cpu cycles to recognize hercules that could also remove artigacting completly because you could draw the screen at intiger dividable clocks but if the microcontroller board can't handle buffering the signal and drawing it back in real time then i guess we stuck at widescreen mode :]
Actually, it is these specific games that look strange in Hercules mode, because they don't actually support proper Hercules mode. Instead they will produce this stretched image, and they expect the user to fix the aspect ratio on the CRT monitor (see @alexloktionoff6833 's comments). Hercules mode text actually looks all right.
Actually, it is these specific games that look stretched in Hercules mode, because they don't actually support proper Hercules mode. Instead they will produce this stretched image, and they expect the user to fix the aspect ratio on the CRT monitor (see @alexloktionoff6833 's comments). Hercules mode text actually looks fine.
Those vertical stripes. I had the same issue in my old UXGA LCD with VGA signal. I tried to change pixel clock in menu but it didn't worked as i hoped.
The code is really clean and clear! It shows how much work and thought have gone into this, supporting all the different modes. Bravo! Thanks for sharing :)
Thanks! It could have been a lot nicer if the Pico had slightly faster main cores. For example the brown color fix is currently handled in the VGA PIo because the main core isn't fast enough to handle an additional if (Color == Dark Yellow) { Color = Brown: }.
This is such good work, congratulations! Looks like a a great low-cost option for using these cards. I guess another pcb order is in my near future :) Kudos
Yeah I will give it a try. My only concern is the IC, not sure there is an equivalent through-hole part, but there should be some compatible alternatives.
(edited) Sharing an idea - to increase the amount of cards that can have "perfect image" displayed, could the set_sys_clock_khz() in the pico C sdk be used to set a clock that allows the target pixel clocks numbers to be reached more accurately? In particular the case where some sampling artifacts remain. One way of reaching additional values for pixel clock is to vary the PI pico clock speed, I believe. A crude way is to add two buttons for "fine adjustment", that increase/decrease the pico clock by 1 Mhz. Another way is to overclock the pico so that one NOP is a finer grained unit, I believe, e.g. from 270 to 290.4 MHz. A third option is setting the PICO_FREQ (referencing its name in the code) to a value that numerically allows, in combination with the clock divider feature used, to reach certain desired values in pixel clock with minimal error. I'm thinking of minimizing the sum of squared error over some common target pixel clock values. This would likely allow you to sample more accurately.
Yes, adjusting the Pico's clock should remove the artifacts if you can't get rid of them any other way. I could add a button combination that allows you to tune that too.
@@scrap_computing The pico supports some frequencies that are close to integer multiples of the EGA pixel clock. In particular 260.0 is 0.112 off and 178.8 is just 0.027. Perhaps the 260.0 one is fast enough for this software and will allow improving the sampling. In other word using DPICO_FREQ=260000 in the cmake command.
(edited) Autotuning - Perhaps a search in software for the card's physical pixel clock is possible by searching a range and measuring the statistical variance of the pixels in the output image. The frequency with the lowest pixel variance is then the optimal one. The underlying assumption is that the lowest variance corresponds to the least noise in the image. This requires a still image to be displayed during themeasurement. In this method each pixel's numeric value is read. The different RGB channels can have their variance calculated separately, and then added up. This final sum is the value to minimize across the different clock values.
(edited) Although I believe the above works in theory, it does require pixel values to be available, which they don't appear to be due to the nature of VGA? It's not clear to me if something similar would be possible with the VGA line logic. Perhaps a Running Variance can be computed across all lines for a couple of frames (8 perhaps), and that value is then minimized over the different pixel clock values. More specifically, could the value of X in pio_sm_put_blocking(VGAPio, VGASM, X) be used to compute the Running Variance? A rough pseudo code can be: display an image, set a candidate pixel clock, for some short time (say 250ms), compute the Running Variance in the line writing logic and store it. After the variance is stored for all candidates, choose the candidate with lowest numerical value for the Running Variance as the optimal candidate. A potential speedup is to use a binary search. An additional speedup is to first use large steps and after some iterations with the binary search use small steps.
The issue is that the fastest detection loop in a PIO takes 2 instructions, one `jmp pin` and one `jmp x--`, this is already 7.2ns. So if we try to measure the time a pixel is found "ON" our measurement will be a multiple of 7.2ns. But what we need is a resolution of about 0.001ns.
I am not sure I fully understand what you are describing. The pixel clock detection is for the TTL side, not the VGA side. On the VGA side we just generate the expected VGA pixel clock and we are done.
@@scrap_computing Oh, I didn't take that into account. In those terms it would be like we set a candidate clock for the TTL side then measure on the VGA side how good it is, and not necessarily output any VGA signal while measuring. The TTL side then runs at normal speed and the VGA side is not doing significantly more than before, just aggregating some numbers. It would sort of be replacing the VGA side with a "instrumentation side"while determining the best candidate clock. Possibly a "please wait" banner or so could be displayed while this logic runs.
Ah OK I think I got it now. But how would you reliably measure how good the pixels "look"? The adapter can't tell if the noise is coming from bad sampling or from the actual input. Anyway, adjusting the pixel clock is not such a big deal. As long as you don't constantly swap cards you would only need to adjust it once per mode.
Prehistoric and PrinceOfPersia do not use original HGC modes, but tweak card to more like EGA timings. Can you show original HGC text and 720x348 graphics mode?
@@scrap_computing exactly, this is tweaking HGC to ease and kinda share graphics routines and bitmaps. They make hgc output 80 bytes per row and 200 lines, users had to use hor/vert knobs of monitor to stretch video full screen.
This is amazing! Thank you so much for making and sharing this! I will be making one for sure! One question: are you sure the 74LS245 is the right part? It looks like you're powering it with 3.3v but then you have 5v inputs and I don't know if that's how it's supposed to work. I know there is a part that designed to go from 3.3v to 5v the way you want to... yeah I think the SN74LVC245AN is what you're looking for. It should be a drop-in replacement but it's designed to be powered with 3.3v and takes TTL/CMOS as input and outputs LVTTL. I think it comes in a version that has the same SMD footprint. But I'll hopefully get a chance to make one soon either way! Thanks again!
Oops good catch! I am indeed using the 74LVC245, but I couldn't find the right entry for it on kicad, so I used the LS part instead. I will update the BOM.
Think it would be possible to autodetect Hfreq through a counter in another state machine? Could see it require manual intervention on the cpu side due to varying pio frequency tho.
There may be a way, but I think it won't be very easy because the pixel clock frequency is quite comparable to the state machine frequency. So you may need multiple state machines running at different frequencies etc. But yeah, that would be really cool!
It is possible to use a female DE9 connector on the reverse side of the board with the current design and use a cable instead of plugging in directly? I currently have my Necroware MCE adaptor mounted to a serial port bracket inside my machine with a tiny IDC ribbon passthrough from my CGA card on the outside. It is quite an elegant solution.
I think they have the same pinout so you could use a female connector too. But I think the cable has to be quite short otherwise the signal does not get picked up properly.
@@scrap_computing Usually the pins are reversed left-to-right between the male and female connectors, which is why I mention maybe soldering it on the other side of the PCB, if there is clearance and the pins line up.
After watching the first two parts, I found myself wondering about putting it on an ISA card, but the serial port control is probably the better option.
The Turbo header on the motherboard is usually just 2 pins: turbo is either ON or OFF depending on whether it is sorted. The turbo switch is usually a 6-pin dual toggle-switch (3 + 3). One part of the switch goes to the MHz display and the other (just 2 pins out of 3 pins) connect to the motherboard header. So when you press the turbo switch you notify both the motherboard and the dipslay.
Very nice! The Pico is almost (but not quite) fast enough that it could actually be turned into an EGA card-with some help it probably could-but how many Tandys, Commodore 128s, and other PCs will this serve? Quite a few, I suspect! And it's going to cost less than any project involving its larger brother if you can resolve the last couple of issues. I'm excited for this project!
Maybe you could use two (or even more?) Picos and see if you could share the load between them. One could handle the ISA slot and forward data to the next one.
I don't want to be disrespectful but your voice reminds me a bit of professor Von Schlemmer from Adventures of Sonic the hedgehog, the video is good though
Would it be possible to transcode MDA/CGA/EGA directly to DVI? VGA is still quite flaky on LCD screens and capture devices. Would be nice to have the output in a modern-ish digital standard. I'm also wondering if it would be possible to repolace RAMDAC on a VGA card with DVI encoder.
Cool project! You may struggle with timing because every old EGA card seems to have slightly different pixel clock rates. There was no exact standard and when creating profiles for the RGB2HDMI project I often had to tweak things slightly from EGA to EGA card. Same for MDA vs Hercules cards .... Also slightly different even from text to graphics mode. It's akin to the auto timing stuff VGA LCD monitors have to employ as VGA cards all vary slightly as well.
Yeah getting it to sample the input perfectly will probably be an issue. I am actually synchronizing sampling per line so as long as it's not too off I may be able to get rid of the sampling artifacts. But yeah I definitely need to do more testing. Thanks for the feedback :)
The Pi Zero has a much faster main CPU but it is lacking the programmable PIO state machines of the Pico. These state machines run deterministically and give you cycle-accurate timings, which is required for sampling the input and generating the output that drives the VGA. For example, you can ask the PIO to generate a signal that is high for X nanoseconds and low for Y nanoseconds, and it will produce a perfect signal. As far as I know this can't be done with either the main ARM core of the Pico or the ARM cores of the Pi Zero, or any other faster Pis.
The RGB2HDMI project handles this with an external CPLD to perfectly synchronize and digitize the input signal, then you have all the power of the Pi Zero framebuffer to handle scaling and every custom digital video format imaginable. It's one of the most phenomenal solutions around for retro display and has no downsides outside of requiring a Pi Zero, SD card and the CPL hat (so costs more.)
As long as it does not use more than one core it should be possible. I think there is some project out there that drives a display port with a Pico. Funny enough the hardest part is not driving the display, but rather getting the input from MDA/CGA/EGA :)